- Joined
- May 9, 2014
- Messages
- 1,823
I had thought about the damage detection system attempting to detect damage from the high-end to the low end of the spectrum, particularly high-end. As it has been established, the EVENT_UNIT_DAMAGED fires before the unit is actually damaged, and to detect when the unit will actually be damaged, we would use a life change event for the unit.
It has been reported that life change events won't work for units with lots of health due to inaccuracy of floats in warcraft (I'm not really verbose in the inner workings of floats). One way of distinguishing when a unit has a huge amount of health is getting the approximate damage by subtracting the unit's current health by the difference of the unit's current health and actual damage. We then check for the disparities between the approximate damage and actual damage. When the float error springs up, set the current life of the unit to just one hit point above the damage and configure the life change event to detect when the unit has health not equal to 1.00 (I used a variable).
After doing that, restore the health of the unit to its' expected health.
In Pseudo-code:
EDIT:
I've also discovered that when used correctly, TriggerRegisterUnitStateEvent(GREATER_THAN, LESS_THAN) will always run, which is how I got to (apparently) fix my problem here.
To find out how the actual code runs, you can check this map:
Make sure to check only Damage Detection
It has been reported that life change events won't work for units with lots of health due to inaccuracy of floats in warcraft (I'm not really verbose in the inner workings of floats). One way of distinguishing when a unit has a huge amount of health is getting the approximate damage by subtracting the unit's current health by the difference of the unit's current health and actual damage. We then check for the disparities between the approximate damage and actual damage. When the float error springs up, set the current life of the unit to just one hit point above the damage and configure the life change event to detect when the unit has health not equal to 1.00 (I used a variable).
After doing that, restore the health of the unit to its' expected health.
In Pseudo-code:
Code:
unit target = GetTriggerUnit()
// The final health to be applied later on...
real finalH = 0.
real damage = GetEventDamage()
// The approximation derived from subtracting currLife - dmg from currLife...
// Used to detect extremely huge hit points.
real approxDmg = 0.
real curL = GetWidgetLife(target)
finalH = curL - damage
approxDmg = curL - (curL - damage)
if damage != approxDmg then
if curL - damage == curL - approxDmg then
// Resolve the float error by adding 64 (to guarantee a unique real)
curL = damage + 64
SetWidgetLife(target, curL)
// Due to the odd behaviour of unit health in real, this will help you detect damage...
curL = GetWidgetLife(target) - damage
endif
else
curL = curL - damage
endif
TriggerRegisterUnitStateEvent(trig, target, UNIT_STATE_LIFE, GREATER_THAN, currLife)
TriggerRegisterUnitStateEvent(trig, target, UNIT_STATE_LIFE, LESS_THAN, currLife)
EDIT:
I've also discovered that when used correctly, TriggerRegisterUnitStateEvent(GREATER_THAN, LESS_THAN) will always run, which is how I got to (apparently) fix my problem here.
To find out how the actual code runs, you can check this map:
Make sure to check only Damage Detection
Attachments
Last edited: