Page MenuHomeWildfire Games

Continuous damage after hit detection
Needs ReviewPublic

Authored by Mate-86 on Jan 23 2018, 9:14 PM.

Details

Reviewers
None
Group Reviewers
Restricted Owners Package(Owns No Changed Paths)
Trac Tickets
#1912
Summary

Discussion about the requirement can be read in the Trac ticket.
@fatherbushido suggested to follow this approach: "flaming projectile 'ignites' (or a poisonous one poisons) the target which suffers damage for a while regardless of running away."

Nice nomenclature defined on DOTA wiki which I'd follow in this patch.

This Diff is in progress. If you like the approach I can extend it with melee and ranged splash attacks. Sound or animation would be nice because right now it's not that obvious why the unit is being damaged over time.

Test Plan

Testing scenarios:

  • ranged point attack
  • ranged splash attack
  • melee attack
  • attack without continuous damage

Would be nice to add some unit tests too.

Diff Detail

Repository
rP 0 A.D. Public Repository
Lint
Lint Skipped
Unit
Unit Tests Skipped
Build Status
Buildable 4651
Build 8101: Vulcan BuildJenkins

Unit TestsFailed

TimeTest
0 msJenkins > cxxtest_debug.xml::[failed-to-read]
Failed to read test report file /mnt/data/jenkins-phabricator/workspace/differential/cxxtest_debug.xml org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog. at org.dom4j.io.SAXReader.read(SAXReader.java:482)
0 msJenkins > cxxtest_release.xml::[failed-to-read]
Failed to read test report file /mnt/data/jenkins-phabricator/workspace/differential/cxxtest_release.xml org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog. at org.dom4j.io.SAXReader.read(SAXReader.java:482)

Event Timeline

Mate-86 created this revision.Jan 23 2018, 9:14 PM
Mate-86 edited the summary of this revision. (Show Details)Jan 23 2018, 9:19 PM
Stan added a subscriber: Stan.EditedJan 23 2018, 9:19 PM

Maybe what you could do is make a bleeding particle ? then set a variant that would show it up. That variant would imply a different group tag in the unit like:

<group>
    <variant name="Healthy" frequency="1"/>
    <variant name="Bleeding"> 
        <props>
            <prop actor="particles/blood_particle.xml"/>
        </props>
    </variant>
    <variant name="Poisoned"> 
        <props>
            <prop actor="particles/poison_particle.xml"/>
        </props>
    </variant> 
    <variant name="Bleeding-Poisoned"> 
        <props>
            <prop actor="particles/poison_particle.xml"/>
            <prop actor="particles/blood_particle.xml"/>
        </props>
    </variant> 
</group>
In D1252#68353, @Stan wrote:

Any updates @Mate-86 ?

Hi Stan, let me double check in the upcoming days. Is that ok?

Stan added a comment.Jan 1 2019, 11:19 AM

Of course ! Was merely checking whether you were still interested, as it's a cool feature !

Stan added a reviewer: Restricted Owners Package.Jan 9 2019, 9:54 AM
Mate-86 edited the summary of this revision. (Show Details)Jan 13 2019, 8:12 PM
Vulcan added a subscriber: Vulcan.Jan 13 2019, 9:15 PM

Build is unstable, some tests have failed - The Moirai have given mortals hearts that can endure.

Linter detected issues:
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
|  23|  23| 	let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|  24|  24| 	let turnLength = cmpTimer.GetLatestTurnLength();
|  25|  25| 	return new Vector3D(
|  26|    |-			(curPos.x * (turnLength - lateness) + prevPos.x * lateness) / turnLength,
|    |  26|+		(curPos.x * (turnLength - lateness) + prevPos.x * lateness) / turnLength,
|  27|  27| 			0,
|  28|  28| 			(curPos.z * (turnLength - lateness) + prevPos.z * lateness) / turnLength);
|  29|  29| };
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
|  24|  24| 	let turnLength = cmpTimer.GetLatestTurnLength();
|  25|  25| 	return new Vector3D(
|  26|  26| 			(curPos.x * (turnLength - lateness) + prevPos.x * lateness) / turnLength,
|  27|    |-			0,
|    |  27|+		0,
|  28|  28| 			(curPos.z * (turnLength - lateness) + prevPos.z * lateness) / turnLength);
|  29|  29| };
|  30|  30| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
|  25|  25| 	return new Vector3D(
|  26|  26| 			(curPos.x * (turnLength - lateness) + prevPos.x * lateness) / turnLength,
|  27|  27| 			0,
|  28|    |-			(curPos.z * (turnLength - lateness) + prevPos.z * lateness) / turnLength);
|    |  28|+		(curPos.z * (turnLength - lateness) + prevPos.z * lateness) / turnLength);
|  29|  29| };
|  30|  30| 
|  31|  31| /**
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
| 111| 111| 
| 112| 112| 	// Do this first in case the direct hit kills the target
| 113| 113| 	if (data.isSplash)
| 114|    |-	{
|    | 114|+	
| 115| 115| 		this.CauseSplashDamage({
| 116| 116| 			"attacker": data.attacker,
| 117| 117| 			"origin": Vector2D.from3D(data.position),
| 124| 124| 			"type": data.type,
| 125| 125| 			"attackerOwner": data.attackerOwner
| 126| 126| 		});
| 127|    |-	}
|    | 127|+	
| 128| 128| 
| 129| 129| 	let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager);
| 130| 130| 
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'else'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Damage.js
| 214| 214| 				damageMultiplier = 0;
| 215| 215| 		}
| 216| 216| 		else // In case someone calls this function with an invalid shape.
| 217|    |-		{
|    | 217|+		
| 218| 218| 			warn("The " + data.shape + " splash damage shape is not implemented!");
| 219|    |-		}
|    | 219|+		
| 220| 220| 
| 221| 221| 		if (data.splashBonus)
| 222| 222| 			damageMultiplier *= GetDamageBonus(ent, data.splashBonus);
|    | [NORMAL] ESLintBear (spaced-comment):
|    | Expected space or tab after '//' in comment.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Attack.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Attack.js
| 507| 507| 
| 508| 508| 		let horizSpeed = +this.template[type].ProjectileSpeed;
| 509| 509| 		let gravity = +this.template[type].Gravity;
| 510|    |-		//horizSpeed /= 2; gravity /= 2; // slow it down for testing
|    | 510|+		// horizSpeed /= 2; gravity /= 2; // slow it down for testing
| 511| 511| 
| 512| 512| 		let cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
| 513| 513| 		if (!cmpPosition || !cmpPosition.IsInWorld())
|    | [NORMAL] ESLintBear (no-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Attack.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Attack.js
| 556| 556| 		let launchPoint = selfPosition.clone();
| 557| 557| 		// TODO: remove this when all the ranged unit templates are updated with Projectile/Launchpoint
| 558| 558| 		launchPoint.y += 3;
| 559|    |-		
|    | 559|+
| 560| 560| 		let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
| 561| 561| 		if (cmpVisual)
| 562| 562| 		{
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'else'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Attack.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/simulation/components/Attack.js
| 629| 629| 			});
| 630| 630| 	}
| 631| 631| 	else
| 632|    |-	{
|    | 632|+	
| 633| 633| 		// Melee attack - hurt the target immediately
| 634| 634| 		cmpDamage.CauseDamage({
| 635| 635| 			"strengths": this.GetAttackStrengths(type),
| 639| 639| 			"type": type,
| 640| 640| 			"attackerOwner": attackerOwner
| 641| 641| 		});
| 642|    |-	}
|    | 642|+	
| 643| 643| };
| 644| 644| 
| 645| 645| /**

binaries/data/mods/public/simulation/components/Attack.js
| 497| ·»   let·cmpDamage·=·Engine.QueryInterface(SYSTEM_ENTITY,·IID_Damage);
|    | [NORMAL] ESLintBear (no-mixed-spaces-and-tabs):
|    | Mixed spaces and tabs.

binaries/data/mods/public/simulation/components/Attack.js
| 604| »   »   cmpTimer.SetTimeout(SYSTEM_ENTITY,·IID_Damage,·"MissileHit",·timeToTarget·*·1000·+·+this.template.Ranged.Delay,·data);
|    | [NORMAL] JSHintBear:
|    | Confusing plusses.
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/differential/962/

Stan added a comment.Jan 13 2019, 11:08 PM

@Mate-86 So no more work on it for a while ? :)

Hi @Stan ! Currently I'm working on fixing the failed build. Apart from that I need your or someone else's help to check the current solution is good. It works for the range attack only but if you like it then I can extend it to melee and splash attack too. What do you think? :)

Angen added a subscriber: Angen.Jan 14 2019, 10:03 PM

some suggestions

binaries/data/mods/public/simulation/components/Attack.js
592

might want to change into function similar to GetAttackStrengths(type) or GetRange(type) to be able apply bonuses from auras and so on

and to ensure it is number +this.template.Ranged.Continuous.Interval or +this.template[type].Continuous.Interval second looks nicer

Angen added inline comments.Jan 14 2019, 10:16 PM
binaries/data/mods/public/simulation/components/Damage.js
260

this exists just in case of ranged attack, test for existence or add everywhere as parameter

Stan added a comment.Jan 14 2019, 11:20 PM

Good news !

This is a bit out of scope but maybe it would be nice to add some tests if possible ?