What is the best way to go about receiving feedback about what stage a Mobile's Swing Timer is currently at? For example, if the mobile is halfway through its timer, such mobile will display some time of feedback. I have looked in the Mobile core and I believe the NextCombatTime property that gets compared to Core.TickCount in the combat timer is the best place to start.

-Thanks.
 
I think that timer in the Mobile is the best place to do it. Basically what happens is that at every specified interval the mobile sends an emote (message above the head) that states what step the mobile is in completing it's on swing method. The emote can probably be replaced with graphics, effects to indicate when a mobile is about to hit.

It's messy but and not efficient (I am aware that using floating points creates extra overhead) but my lack of coding knowledge prevents me from optimizing it further. For anyone interested it is attached below except for the properties and private member variables that you will have to add where you see fit.

Code:
	private class CombatTimer : Timer
		{
			private readonly Mobile _Mobile;

			public CombatTimer(Mobile m)
				: base(TimeSpan.FromSeconds(0.0), TimeSpan.FromSeconds(0.01), 0)
			{
				_Mobile = m;

				if (!_Mobile._Player && _Mobile._Dex <= 100)
				{
					Priority = TimerPriority.FiftyMS;
				}
			}

			protected override void OnTick()
			{  
                if (Core.TickCount - _Mobile._NextCombatTimeOneThird >= 0 && Core.TickCount - _Mobile._NextCombatTimeOneHalf <= 0 && _Mobile.NextCombatOneThird == false)
                {
                    _Mobile.Emote("One Third Charged");
                    _Mobile.NextCombatOneThird = true;
                }

                if (Core.TickCount - _Mobile._NextCombatTimeOneHalf >= 0 && Core.TickCount - _Mobile._NextCombatTimeTwoThird <= 0 && _Mobile.NextCombatOneHalf == false)
                {
                    _Mobile.Emote("One Half Charged");
                    _Mobile.NextCombatOneHalf = true;
                }

                if (Core.TickCount - _Mobile._NextCombatTimeTwoThird >= 0 && Core.TickCount - _Mobile._NextCombatTime <= 0 && _Mobile.NextCombatTwoThird == false)
                {
                    _Mobile.Emote("Two Third Charged");
                    _Mobile.NextCombatTwoThird = true;
                }

                if (Core.TickCount - _Mobile._NextCombatTime >= 0 && _Mobile.NextCombatReady == false)
                {
                    _Mobile.Emote("Full Charged");
                    _Mobile.NextCombatReady = true;
                }

                if (Core.TickCount - _Mobile._NextCombatTime >= 0)
				{                  
                    Mobile combatant = _Mobile.Combatant;

					// If no combatant, wrong map, one of us is a ghost, or cannot see, or deleted, then stop combat
					if (combatant == null || combatant._Deleted || _Mobile._Deleted || combatant._Map != _Mobile._Map ||
						!combatant.Alive || !_Mobile.Alive || !_Mobile.CanSee(combatant) || combatant.IsDeadBondedPet ||
						_Mobile.IsDeadBondedPet)
					{
						_Mobile.Combatant = null;
						return;
					}

					IWeapon weapon = _Mobile.Weapon;

					if (!_Mobile.InRange(combatant, weapon.MaxRange))
					{
						return;
					}

					if (_Mobile.InLOS(combatant))
					{
						weapon.OnBeforeSwing(_Mobile, combatant); //OnBeforeSwing for checking in regards to being hidden and whatnot
						_Mobile.RevealingAction();
                        _Mobile.LastCombatTime = (int)weapon.OnSwing(_Mobile, null).TotalMilliseconds;
                        _Mobile._NextCombatTime = Core.TickCount + (int)weapon.OnSwing(_Mobile, combatant).TotalMilliseconds;
                        _Mobile._NextCombatTimeOneThird = Core.TickCount + _Mobile.LastCombatTime / 3;
                        _Mobile._NextCombatTimeOneHalf = Core.TickCount + _Mobile.LastCombatTime / 2;
                        _Mobile._NextCombatTimeTwoThird = Core.TickCount + _Mobile.LastCombatTime / 3 * 2;
                        _Mobile.NextCombatOneThird = false;
                        _Mobile.NextCombatOneHalf = false;
                        _Mobile.NextCombatTwoThird = false;
                        _Mobile.NextCombatReady = false;
                    }                  
                }
            }
		}
 
What are you trying to accomplish? Maybe we can give some feedback on other approaches. Modifying the core shouldn't be needed for most things, and it can make keeping up to date with changes in ServUO difficult.
 
Thanks for following up Norman. You have been really active in the forums and it's very refreshing to see how strong the ServUO community is. My main goal is creating feedback information for swing speed. With stock UO there is no way of telling what stage a mobile is at after it swings. I simply added feedback info in the on tick method. If there is a better way to do it without modifying the core I am all ears. I assumed it would be easier to modify the core as I want feedback for all mobiles in the game.

Also, I am not terribly familiar with Git, but doesn't using GIt make life easier when making large number of changes? Thanks again!
 
Git makes life easier when integrating your changes with others. As ServUO is a constantly moving target, we recommend using git to stay up to date and contribute changes when you like to.

If you want to do this for every mobile, then I suppose Moble.cs is the place to do it. If you want to share this with the community, our just to make things easier oh yourself in the long run, I would recommend adding a combat swing event to EventSink.cs with the swing duration included in the event structure. That way you can respond to every swing by just hooking an event.
 
Back