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
@@ -236,7 +236,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.
@@ -258,6 +258,11 @@
if (targetState.killed)
this.TargetKilled(data.attacker, data.target, data.attackerOwner);
+ // do the status change, eg. poisoning
+ let cmpStatus = Engine.QueryInterface(data.target, IID_Status);
+ if (cmpStatus)
+ cmpStatus.StartEffect(data.attacker);
+
Engine.PostMessage(data.target, MT_Attacked, { "attacker": data.attacker, "target": data.target, "type": data.type, "damage": -targetState.change, "attackerOwner": data.attackerOwner });
};
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,42 @@
+function Status() {}
+
+Status.prototype.Init = function()
+{
+ this.isPoisoned = false;
+}
+
+Status.prototype.StartEffect = function(attacker)
+{
+ let cmpStatusEffects = Engine.QueryInterface(attacker, IID_StatusEffects);
+
+ if (!cmpStatusEffects || !cmpStatusEffects.poison)
+ return;
+
+ // TODO: multiple poision attacks may reset the duration
+ if (this.isPoisoned)
+ return;
+
+ this.isPoisoned = true;
+
+ let poison = cmpStatusEffects.poison;
+ this.duration = poison.duration;
+ this.damage = poison.damage;
+
+ let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+ this.timer = cmpTimer.SetInterval(this.entity, IID_Status, "ExecuteEffect", 0, poison.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/StatusEffects.js
===================================================================
--- binaries/data/mods/public/simulation/components/StatusEffects.js
+++ binaries/data/mods/public/simulation/components/StatusEffects.js
@@ -0,0 +1,30 @@
+function StatusEffects() {}
+
+StatusEffects.prototype.Schema =
+ "Handling effects like poisioning or burning attached to an entity." +
+ "" +
+ "" +
+ "2000" +
+ "200" +
+ "5" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "";
+
+StatusEffects.prototype.Init = function()
+{
+ this.poison = {};
+ this.poison.duration = +this.template.Poison.Duration;
+ this.poison.interval = +this.template.Poison.Interval;
+ this.poison.damage = +this.template.Poison.Damage;
+};
+
+Engine.RegisterComponentType(IID_StatusEffects, "StatusEffects", StatusEffects);
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/interfaces/StatusEffects.js
===================================================================
--- binaries/data/mods/public/simulation/components/interfaces/StatusEffects.js
+++ binaries/data/mods/public/simulation/components/interfaces/StatusEffects.js
@@ -0,0 +1 @@
+Engine.RegisterInterface("StatusEffects");
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,50 @@
+Engine.LoadComponentScript("interfaces/Health.js");
+Engine.LoadComponentScript("interfaces/Status.js");
+Engine.LoadComponentScript("interfaces/Timer.js");
+Engine.LoadComponentScript("interfaces/StatusEffects.js");
+
+Engine.LoadComponentScript("Status.js");
+Engine.LoadComponentScript("Timer.js");
+Engine.LoadComponentScript("StatusEffects.js");
+
+function testStatusChange()
+{
+ let target = 42;
+ let attacker = 43;
+
+ let cmpStatus = ConstructComponent(target, "Status");
+ let cmpTimer = ConstructComponent(SYSTEM_ENTITY, "Timer");
+ let cmpStatusEffects = ConstructComponent(attacker, "StatusEffects", {
+ "Poison": {
+ "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(attacker);
+
+ 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_unit.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit.xml
+++ binaries/data/mods/public/simulation/templates/template_unit.xml
@@ -1,5 +1,13 @@
+
+
+
+ 5000
+ 1000
+ 1
+
+
1