Index: binaries/data/mods/public/simulation/components/Attack.js
===================================================================
--- binaries/data/mods/public/simulation/components/Attack.js
+++ binaries/data/mods/public/simulation/components/Attack.js
@@ -2,6 +2,23 @@
var g_AttackTypes = ["Melee", "Ranged", "Capture"];
+Attack.prototype.statusEffectsSchema =
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "";
+
Attack.prototype.bonusesSchema =
"" +
"" +
@@ -187,6 +204,7 @@
"" +
"" +
"" +
+ Attack.prototype.statusEffectsSchema +
Attack.prototype.bonusesSchema +
Attack.prototype.preferredClassesSchema +
Attack.prototype.restrictedClassesSchema +
@@ -577,7 +595,8 @@
"bonus": this.GetBonusTemplate(type),
"isSplash": false,
"attackerOwner": attackerOwner,
- "attackImpactSound": attackImpactSound
+ "attackImpactSound": attackImpactSound,
+ "statusEffects": this.template[type].StatusEffects
};
if (this.template[type].Splash)
{
Index: binaries/data/mods/public/simulation/components/Damage.js
===================================================================
--- binaries/data/mods/public/simulation/components/Damage.js
+++ binaries/data/mods/public/simulation/components/Damage.js
@@ -93,6 +93,7 @@
* @param {Vector3D} data.direction - the unit vector defining the direction.
* @param {Object} data.bonus - the attack bonus template from the attacker.
* @param {string} data.attackImpactSound - the name of the sound emited on impact.
+ * @param {Object} data.statusEffects - status effects eg. poisoning, burning etc.
* ***When splash damage***
* @param {boolean} data.friendlyFire - a flag indicating if allied entities are also damaged.
* @param {number} data.radius - the radius of the splash damage.
@@ -136,6 +137,12 @@
data.multiplier = GetDamageBonus(data.target, data.bonus);
this.CauseDamage(data);
cmpProjectileManager.RemoveProjectile(data.projectileId);
+
+ // Do the status change, eg. poisoning, burning etc.
+ let cmpStatus = Engine.QueryInterface(data.target, IID_Status);
+ if (cmpStatus && data.statusEffects)
+ cmpStatus.StartEffect(data.statusEffects);
+
return;
}
@@ -160,6 +167,7 @@
"attackerOwner": data.attackerOwner
});
cmpProjectileManager.RemoveProjectile(data.projectileId);
+
break;
}
};
@@ -236,7 +244,7 @@
* @param {Object} data - the data passed by the caller.
* @param {Object} data.strengths - data in the form of { 'hack': number, 'pierce': number, 'crush': number }.
* @param {number} data.target - the entity id of the target.
- * @param {number} data.attacker - the entity id og the attacker.
+ * @param {number} data.attacker - the entity id of the attacker.
* @param {number} data.multiplier - the damage multiplier.
* @param {string} data.type - the type of damage.
* @param {number} data.attackerOwner - the player id of the attacker.
Index: binaries/data/mods/public/simulation/components/Status.js
===================================================================
--- binaries/data/mods/public/simulation/components/Status.js
+++ binaries/data/mods/public/simulation/components/Status.js
@@ -0,0 +1,40 @@
+function Status() {}
+
+Status.prototype.Init = function()
+{
+ this.isBurning = false;
+}
+
+Status.prototype.StartEffect = function(statusEffects)
+{
+ if (!statusEffects || !statusEffects.Burn)
+ return;
+
+ // TODO: multiple burning attack may reset the duration
+ if (this.isBurning)
+ return;
+
+ this.isBurning = true;
+
+ let effect = statusEffects.Burn;
+ this.duration = +effect.Duration;
+ this.damage = +effect.Damage;
+
+ let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+ this.timer = cmpTimer.SetInterval(this.entity, IID_Status, "ExecuteEffect", 0, +effect.Interval, null);
+}
+
+Status.prototype.ExecuteEffect = function()
+{
+ let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+ if (cmpTimer.GetTime(this.timer) > this.duration)
+ {
+ cmpTimer.CancelTimer(this.timer);
+ return;
+ }
+
+ let cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
+ cmpHealth.Reduce(this.damage);
+};
+
+Engine.RegisterComponentType(IID_Status, "Status", Status);
Index: binaries/data/mods/public/simulation/components/interfaces/Status.js
===================================================================
--- binaries/data/mods/public/simulation/components/interfaces/Status.js
+++ binaries/data/mods/public/simulation/components/interfaces/Status.js
@@ -0,0 +1 @@
+Engine.RegisterInterface("Status");
Index: binaries/data/mods/public/simulation/components/tests/test_Damage.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_Damage.js
+++ binaries/data/mods/public/simulation/components/tests/test_Damage.js
@@ -12,6 +12,7 @@
Engine.LoadComponentScript("interfaces/Loot.js");
Engine.LoadComponentScript("interfaces/Player.js");
Engine.LoadComponentScript("interfaces/Promotion.js");
+Engine.LoadComponentScript("interfaces/Status.js");
Engine.LoadComponentScript("interfaces/TechnologyManager.js");
Engine.LoadComponentScript("interfaces/Timer.js");
Engine.LoadComponentScript("Attack.js");
Index: binaries/data/mods/public/simulation/components/tests/test_Status.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_Status.js
+++ binaries/data/mods/public/simulation/components/tests/test_Status.js
@@ -0,0 +1,48 @@
+Engine.LoadComponentScript("interfaces/Health.js");
+Engine.LoadComponentScript("interfaces/Status.js");
+Engine.LoadComponentScript("interfaces/Timer.js");
+
+Engine.LoadComponentScript("Status.js");
+Engine.LoadComponentScript("Timer.js");
+
+function testStatusChange()
+{
+ let target = 42;
+ let attacker = 43;
+
+ let cmpStatus = ConstructComponent(target, "Status");
+ let cmpTimer = ConstructComponent(SYSTEM_ENTITY, "Timer");
+ let statusEffects = {
+ "Burn": {
+ "Duration": 20000,
+ "Interval": 10000,
+ "Damage": 1
+ }
+ };
+
+ let health = 10;
+
+ AddMock(target, IID_Health, {
+ "Reduce": (amount) => { health -= amount; }
+ });
+
+ // damage scheduled: 0 sec, 10 sec, 20 sec
+ cmpStatus.StartEffect(statusEffects);
+
+ cmpTimer.OnUpdate({ turnLength: 1 });
+ TS_ASSERT_EQUALS(health, 9); // 1 sec
+
+ cmpTimer.OnUpdate({ turnLength: 8 });
+ TS_ASSERT_EQUALS(health, 9); // 9 sec
+
+ cmpTimer.OnUpdate({ turnLength: 1 });
+ TS_ASSERT_EQUALS(health, 8); // 10 sec
+
+ cmpTimer.OnUpdate({ turnLength: 10 });
+ TS_ASSERT_EQUALS(health, 7); // 20 sec
+
+ cmpTimer.OnUpdate({ turnLength: 10 });
+ TS_ASSERT_EQUALS(health, 7); // 30 sec
+}
+
+testStatusChange();
Index: binaries/data/mods/public/simulation/templates/template_structure.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure.xml
+++ binaries/data/mods/public/simulation/templates/template_structure.xml
@@ -1,5 +1,6 @@
+
1
Index: binaries/data/mods/public/simulation/templates/template_unit.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit.xml
+++ binaries/data/mods/public/simulation/templates/template_unit.xml
@@ -1,5 +1,6 @@
+
1
Index: binaries/data/mods/public/simulation/templates/units/iber_champion_cavalry.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/units/iber_champion_cavalry.xml
+++ binaries/data/mods/public/simulation/templates/units/iber_champion_cavalry.xml
@@ -4,6 +4,13 @@
5
15
+
+
+ 50000
+ 1000
+ 1
+
+