Page 1 of 3
Disable dynamic EMP time
Posted: 18 Aug 2009, 10:19
by TheFatController
Request for BA and i'm sure other modders may appreciate it.
Can we please get a weapon flag which disables the fact that EMP weapons are more effective against damaged units and if enabled they just do the flat EMP Time which you assigned the weapon.
Currently damaged units get stung with masses of extra EMP time and for some reason this is the engine default.
Thanks
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 10:34
by Otherside
+1 i dislike this feature it makes EMP harder to balance and dont particularly like the behaviour
It should be a flag
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 11:25
by Master-Athmos
Yeah - it simply needs to compare emp damage against a unit's max health instead of comparing it with the current health left...
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 11:47
by imbaczek
please put a little bit more thought into it and come up with a really generic solution so this problem will be solved for the widest range of games possible.
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 11:52
by TheFatController
imbaczek wrote:please put a little bit more thought into it and come up with a really generic solution so this problem will be solved for the widest range of games possible.
Is this directed at my post?
The most generic solution would be you define EMP time as 6 seconds and the enemy gets stunned for 6 seconds.
The weird unintuitive solution is you define EMP time as 6 seconds and the enemy gets stunned from 6 to 30+ seconds depending on its current health.
The second is how it currently works

Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 11:59
by hoijui
you cant calculate with seconds only, as first you have to stunn-away the health, which is not messured in seconds.
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 12:06
by TheFatController
Yes you stun away the health then the unit gets stunned for the EMP time you defined in the weapon defs.
This already gives an advantage to stunning low health units without adding heaps of EMP time.
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 13:54
by imbaczek
TFC: i posted this because both the proposed solution and what currently exists doesn't feel general enough. i can imagine several other ways of paralyzing units and am contemplating removing of paralyze damage from the engine altogether, keeping only paralyze status controllable by lua and giving mod devs more undeserved work

Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 14:08
by TheFatController
Sounds good imo
Ideally however there'd still be a standard way for widgets to monitor paralyze damage, paralyze health and time if it was gadget controlled rather than a mess of sendtounsynced type calls being necessary.
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 14:49
by Forboding Angel
I hate the current behavior with such a passion...
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 15:18
by TheFatController
Forboding Angel wrote:I hate the current behavior with such a passion...
Also this, a quick fix would be ideal to allow a weapon tdf to use fix time rather than dynamic time...
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 20:02
by Argh
This can almost certainly be fixed, with something like this:
Code: Select all
function gadget:UnitPreDamaged(unitID, unitDefID, unitTeam, damage, paralyzer, weaponID, attackerID, attackerDefID, attackerTeam)
if paralyzer then
if immuneToParalyzer[unitDefID] then
return 0
else
local h,mH,pD,cP,bP = Spring.GetUnitHealth(unitID)
Spring.SetUnitHealth(unitID,{h,cP,mH * WeaponDefs[weaponID].paralyzeTime,bP})
end
else
return damage
end
end
I just don't know how paralyzeTime's formula works, in terms of how much paralysis is removed every second.
Lemme run something real quick, I'll put out a corrected version.
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 20:13
by Pxtl
Can somebody explain, in detail, what the current logic is?
I always assumed it was "unit paralyze health = current health - current paralyze damage" and where paralyze health is less than zero, the unit is stunned... and unit regens X paralyze health per second. Maximum paralyze damage is regen-rate * max seconds. Something like that?
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 20:36
by Argh
It doesn't seem to work anything like expected. Something very strange is going on here.
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 20:46
by Argh
Ok, now I'll have to read the source to be sure, but it appears that until the
damage value of the Paralyzer > current Health, Units aren't paralyzed at all. IOW, the previous paralyzerDamage isn't even being taken into consideration!
<tests>
Confirmed.
Code: Select all
if paralyzer then
local h,mH,pD,cP,bP = Spring.GetUnitHealth(unitID)
Spring.Echo("h = "..h,"mH = "..mH,"pD = "..pD,"cP = "..cP,"bP = "..bP)
--Spring.SetUnitHealth(unitID,{h,cP,mH * 2,bP})
return 2 * h
end
Result? Approximately 8 seconds of paralysis,
on the first hit- i.e. paralyzers all of a sudden work like they're supposed to, and stun every time.
So the only thing left is to adjust the value by which h is being multiplied. I'll test that and make sure.
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 20:59
by Tobi
Each unit has a value paralyzeDamage, which is always clamped to be >= 0.
On getting hit by a paralyzation weapon (any weapon with paralyzeTime != 0), paralyzeDamage is increased with the applicable damage [based on armor type], multiplied by flanking bonus [if enabled]. ParalizeDamage is upper bounded by health+maxHealth*0.025*paralyzeTime.
Each slow update (every 16 frames) paralyzeDamage is decreased with maxHealth * (16/30/40) = maxHealth*0.025*16/30.
If paralyzeDamage becomes higher than the unit's current health, the unit becomes stunned. If paralyzeDamage becomes lower than the unit's current health, the unit becomes unstunned.
This means paralyzeTime correctly expresses max paralyze time. (If paralizeTime = 1 then paralyzeDamage-health is bounded by maxHealth*0.025, which will have been removed after 2 SlowUpdates (= approx 1 second.)
Also it means that if a stunned unit is continuously being damaged with more than 0.025*maxHealth DPS, it will stay stunned. (This is the amount of DPS that would kill the unit in 40 seconds. [That is where the 0.025=1/40 comes from as far as I can see.])
One thing that is clearly wrong, is that paralyzeDamage is upper bounded by a function of the current weapon's paralyzeTime. That means, for example, after paralyzing a unit first with a weapon with 30s paralyzeTime, hitting it for even a tiny bit with a weapon with 1s paralyzeTime will cancel 29s worth of paralyzeDamage.
EDIT:
To make it a bit saner, I would suggest decoupling current health and paralyzeDamage, and just defining a unit as stunned iff paralyzeDamage >= maxHealth, and fixing this last bug.
I'll actually try to do this now.
Also the unit's target priority for a paralyzer is multiplied by 4 if health-paralyzeDamage < maxHealth * 0.09.. (less likely to be targeted by paralyzer if it's stunned or within ~9% of becoming stunned). I wonder why this isn't just when paralyzeDamage >= health...
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 21:15
by Argh
IMO, that whole setup's screwy- the whole "damage" concept causes more weirdness than it's worth.
But that Lua I just wrote can effectively make paralyze work correctly (imo):
Code: Select all
if paralyzer then
local h,mH,pD,cP,bP = Spring.GetUnitHealth(unitID)
return 0.25 * h + pD
end
There ya go- no more cancellation, and paralysis stacks. The 0.25 * h is roughly 1 second, it can be whatever you want- throw in per-stunner custom values, random values, whatever.
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 21:26
by Tobi
You'll still have the bug I described unless you fix it by resetting paralyzeDamage in UnitDamaged. (So also it won't stack, because the engine keeps clamping it.)
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 21:52
by lurker
Tobi wrote:One thing that is clearly wrong, is that paralyzeDamage is upper bounded by a function of the current weapon's paralyzeTime. That means, for example, after paralyzing a unit first with a weapon with 30s paralyzeTime, hitting it for even a tiny bit with a weapon with 1s paralyzeTime will cancel 29s worth of paralyzeDamage.
I thought I put in something to stop paralyzeDamage dropping the time when from an inferior paralyzer. It only worked for undamaged units maybe?
This seems like a good place to ask, does anyone at all want the "current health" behavior?
Re: Disable dynamic EMP time
Posted: 18 Aug 2009, 22:29
by Tobi
Nah, it was clamping paralyzeDamage (property of the unit) instead of damage (the to-be-added value), so it would always cancel paralyzeTime of a longer duration paralyzer.
Code: Select all
const float maxParaDmg = health + (maxHealth * 0.025f * (float)paralyzeTime);
//...
paralyzeDamage = std::min(paralyzeDamage, maxParaDmg);