Disable dynamic EMP time

Disable dynamic EMP time

Requests for features in the spring code.

Moderator: Moderators

User avatar
TheFatController
Balanced Annihilation Developer
Posts: 1177
Joined: 10 Dec 2006, 18:46

Disable dynamic EMP time

Post 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
User avatar
Otherside
Posts: 2296
Joined: 21 Feb 2006, 14:09

Re: Disable dynamic EMP time

Post by Otherside »

+1 i dislike this feature it makes EMP harder to balance and dont particularly like the behaviour

It should be a flag
Master-Athmos
Posts: 916
Joined: 27 Jun 2009, 01:32

Re: Disable dynamic EMP time

Post 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...
imbaczek
Posts: 3629
Joined: 22 Aug 2006, 16:19

Re: Disable dynamic EMP time

Post 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.
User avatar
TheFatController
Balanced Annihilation Developer
Posts: 1177
Joined: 10 Dec 2006, 18:46

Re: Disable dynamic EMP time

Post 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 :(
User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Disable dynamic EMP time

Post by hoijui »

you cant calculate with seconds only, as first you have to stunn-away the health, which is not messured in seconds.
User avatar
TheFatController
Balanced Annihilation Developer
Posts: 1177
Joined: 10 Dec 2006, 18:46

Re: Disable dynamic EMP time

Post 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.
imbaczek
Posts: 3629
Joined: 22 Aug 2006, 16:19

Re: Disable dynamic EMP time

Post 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 :P
User avatar
TheFatController
Balanced Annihilation Developer
Posts: 1177
Joined: 10 Dec 2006, 18:46

Re: Disable dynamic EMP time

Post 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.
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: Disable dynamic EMP time

Post by Forboding Angel »

I hate the current behavior with such a passion...
User avatar
TheFatController
Balanced Annihilation Developer
Posts: 1177
Joined: 10 Dec 2006, 18:46

Re: Disable dynamic EMP time

Post 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...
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Disable dynamic EMP time

Post 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.
Last edited by Argh on 18 Aug 2009, 20:24, edited 1 time in total.
User avatar
Pxtl
Posts: 6112
Joined: 23 Oct 2004, 01:43

Re: Disable dynamic EMP time

Post 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?
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Disable dynamic EMP time

Post by Argh »

It doesn't seem to work anything like expected. Something very strange is going on here.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Disable dynamic EMP time

Post 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.
Last edited by Argh on 18 Aug 2009, 21:06, edited 1 time in total.
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Disable dynamic EMP time

Post 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...
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Disable dynamic EMP time

Post 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.
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Disable dynamic EMP time

Post 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.)
User avatar
lurker
Posts: 3842
Joined: 08 Jan 2007, 06:13

Re: Disable dynamic EMP time

Post 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?
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Disable dynamic EMP time

Post 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);
Post Reply

Return to “Feature Requests”