This post is about the CombatHeartBeat function. It's a function who's name is 100% certain due to a debugging left-over OSI left in there. It's a part of the combat system but an important one.
Related posts:
Swing Speed Code : http://forum.joinuo.com/viewtopic.php?f=32&t=328
Weapon Templates : http://forum.joinuo.com/viewtopic.php?f=32&t=495
Weapon Template : http://forum.joinuo.com/viewtopic.php?f=32&t=494
What's missing:
How damage is actually calculated.
How damage is absorbed.
(available per request)
The code sequence below is the CombatHeartBeat as far I was able to decode it.
Stuff between ' is understood for like 80%, all other code is 100%! Scout's Honor.
Per tick, per mobile (this=attacker mobile object):
1) Increase SwingCounter up to 1000
- Code: Select all
if(this->SwingCounter < 1000)
this->SwingCounter ++;
2) The Dead and Counselors are not allowed to execute an attack
3) 'Guard stuff'
4) 'Determine the Attackee'
5) Don't allow attacking The Invulnerables
6) Advance SwingCounter and/or SwingState
7) If SwingState remained the same or is lower than 2
Then no further action is taken this tick
- Code: Select all
OldSwingState = this->GetSwingState()
NewSwingState = this->AdvanceSwingState()
if(OldSwingState == NewSwingState)
return;
if(NewSwingState < 2)
return;
8) Verify if the Attack is in range (MinRange + MaxRange)
NOTE: MinRange does no longer exist in the data files but is still supported by the code
NOTE: MinRange was patched out by OSI on 1998-01-13 (The minimum range has been removed from all archery weapons.)
9) 'Unknown', I'm guessing the internal objects are updated
10) For Achery, 'missile creation'
NOTE: when the archer has no ammo, the following code is called:
- Code: Select all
this->ResetSwingState(1);
11) In case NewSwingState is 2 then again 'Animation Stuff'
And no further action!!!
---> Step 12 is therefor executed only in case NewSwingState equals 3
12) Calculate Combat Skill difference between Attacker and Attackee
13) Make an Invisible Attacker visible
14) Determine hit/miss (random against skill difference check)
15) [On hit]:
15.1) Chance for the attacker to advance Combat skill
15.2) Determine base damage (see my post about Reviewing Weapons)
15.3) Chance for the defender to advance Tactics skill
15.4) Pass [ishitting] event to the scripts
15.5) If a script modified the damage to 0 then execute [On miss]
('no scripts do that', but it can be done for sure)
15.6) Pass [mobishitting] event to the scripts
15.7) If the defender's GetSwingState returns 2 then 'Something is done'
!!!!! This is a check on the defender's swing state and is related with an animation
15.8) Apply the damage
16) [On miss]:
16.1) Chance for the defender to advance Combat skill
There are some intersting things ot shown, like NPC's see you even when you don't see them, this means your swing counter stats counting. This cannot be seen in-game but can be see by attaching a debugger to the uodemo.exe and tracking the memory state of the mobiles. I currently lack understanding of how the NPC AI actually works and I also lack the time to work on it, sorry. But I plan to, someday.
What's also important is that when a weapon is lifted and/or equipped (this includes weapons, shields, cloths) the SwingCounter is set to 0. Please refer to weapon.XXX.q files in the ../.rundir/weapon directory to know what OSI actually ment with weapons! Testing on live EA/UO servers has shown that this is still the case, believe it or not... This can also be seen in this video I made: http://download.joinuo.com/Video/Demo%20MemSpy%20&%20The%20Swing%20Counter.wmv