Index: binaries/data/mods/public/simulation/components/Resistance.js
===================================================================
--- binaries/data/mods/public/simulation/components/Resistance.js
+++ binaries/data/mods/public/simulation/components/Resistance.js
@@ -2,7 +2,6 @@
/**
* Builds a RelaxRNG schema of possible attack effects.
- * ToDo: Resistance to StatusEffects.
*
* @return {string} - RelaxNG schema string.
*/
@@ -22,6 +21,23 @@
"" +
"" +
"" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
"" +
"";
};
@@ -122,6 +138,16 @@
if (template.Capture)
ret.Capture = ApplyValueModificationsToEntity("Resistance/" + entityForm + "/Capture", +this.template[entityForm].Capture, this.entity);
+ if (template.ApplyStatus)
+ {
+ ret.ApplyStatus = {};
+ for (let effect in template.ApplyStatus)
+ ret.ApplyStatus[effect] = {
+ "duration": ApplyValueModificationsToEntity("Resistance/" + entityForm + "/ApplyStatus/" + effect + "/Duration", +(template.ApplyStatus[effect].Duration || 1), this.entity),
+ "blockChance": ApplyValueModificationsToEntity("Resistance/" + entityForm + "/ApplyStatus/" + effect + "/BlockChance", +(template.ApplyStatus[effect].BlockChance || 0), this.entity)
+ };
+ }
+
return ret;
};
Index: binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js
===================================================================
--- binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js
+++ binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js
@@ -142,7 +142,7 @@
return;
if (status.Damage || status.Capture)
- Attacking.HandleAttackEffects(statusName, status, this.entity, status.source.entity, status.source.owner);
+ Attacking.HandleAttackEffects(this.entity, statusName, status, status.source.entity, status.source.owner);
if (!status.Duration)
return;
Index: binaries/data/mods/public/simulation/components/tests/test_Resistance.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_Resistance.js
+++ binaries/data/mods/public/simulation/components/tests/test_Resistance.js
@@ -10,6 +10,7 @@
Engine.LoadComponentScript("interfaces/Promotion.js");
Engine.LoadComponentScript("interfaces/Resistance.js");
Engine.LoadComponentScript("interfaces/StatisticsTracker.js");
+Engine.LoadComponentScript("interfaces/StatusEffectsReceiver.js");
Engine.LoadComponentScript("Resistance.js");
class testResistance
@@ -26,8 +27,9 @@
Reset(schema = {})
{
this.cmpResistance = ConstructComponent(this.EntityID, "Resistance", schema);
- DeleteMock(this.EntityID, IID_Health);
DeleteMock(this.EntityID, IID_Capturable);
+ DeleteMock(this.EntityID, IID_Health);
+ DeleteMock(this.EntityID, IID_StatusEffectsReceiver);
DeleteMock(this.EntityID, IID_Identity);
}
@@ -148,6 +150,101 @@
TS_ASSERT_EQUALS(spy._called, 1);
}
+ TestStatusEffectsResistancesApplies()
+ {
+ // Test duration reduction.
+ let durationFactor = 0.5;
+ let statusName = "statusName";
+ this.Reset({
+ "Entity": {
+ "ApplyStatus": {
+ [statusName]: {
+ "Duration": durationFactor
+ }
+ }
+ }
+ });
+
+ let duration = 10;
+ let attackData = {
+ "ApplyStatus": {
+ [statusName]: {
+ "Duration": duration
+ }
+ }
+ };
+
+ let cmpStatusEffectsReceiver = AddMock(this.EntityID, IID_StatusEffectsReceiver, {
+ "ApplyStatus": (effectData, __, ___) => {
+ TS_ASSERT_EQUALS(effectData[statusName].Duration, duration * durationFactor);
+ return { "inflictedStatuses": Object.keys(effectData) };
+ }
+ });
+ let spy = new Spy(cmpStatusEffectsReceiver, "ApplyStatus");
+
+ Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID);
+ TS_ASSERT_EQUALS(spy._called, 1);
+
+ // Test blocking.
+ this.Reset({
+ "Entity": {
+ "ApplyStatus": {
+ [statusName]: {
+ "BlockChance": "1"
+ }
+ }
+ }
+ });
+
+ cmpStatusEffectsReceiver = AddMock(this.EntityID, IID_StatusEffectsReceiver, {
+ "ApplyStatus": (effectData, __, ___) => {
+ TS_ASSERT_UNEVAL_EQUALS(effectData, {});
+ return { "inflictedStatuses": Object.keys(effectData) };
+ }
+ });
+
+ Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID);
+
+ // Test multiple resistances.
+ let reducedStatusName = "reducedStatus";
+ let blockedStatusName = "blockedStatus";
+ this.Reset({
+ "Entity": {
+ "ApplyStatus": {
+ [reducedStatusName]: {
+ "Duration": durationFactor
+ },
+ [blockedStatusName]: {
+ "BlockChance": "1"
+ }
+ }
+ }
+ });
+
+ attackData = {
+ "ApplyStatus": {
+ [reducedStatusName]: {
+ "Duration": duration
+ },
+ [blockedStatusName]: {
+ "Duration": duration
+ }
+ }
+ };
+
+ cmpStatusEffectsReceiver = AddMock(this.EntityID, IID_StatusEffectsReceiver, {
+ "ApplyStatus": (effectData, __, ___) => {
+ TS_ASSERT_EQUALS(effectData[reducedStatusName].Duration, duration * durationFactor);
+ TS_ASSERT_UNEVAL_EQUALS(Object.keys(effectData), [reducedStatusName]);
+ return { "inflictedStatuses": Object.keys(effectData) };
+ }
+ });
+ spy = new Spy(cmpStatusEffectsReceiver, "ApplyStatus");
+
+ Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID);
+ TS_ASSERT_EQUALS(spy._called, 1);
+ }
+
TestResistanceAndBonus()
{
let resistanceValue = 2;
@@ -246,5 +343,6 @@
cmp.TestBonus();
cmp.TestDamageResistanceApplies();
cmp.TestCaptureResistanceApplies();
+cmp.TestStatusEffectsResistancesApplies();
cmp.TestResistanceAndBonus();
cmp.TestMultipleEffects();
Index: binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js
+++ binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js
@@ -19,7 +19,7 @@
let statusName;
let Attacking = {
- "HandleAttackEffects": (_, attackData) => {
+ "HandleAttackEffects": (_, __, attackData) => {
for (let type in attackData.Damage)
dealtDamage += attackData.Damage[type];
}
Index: binaries/data/mods/public/simulation/helpers/Attacking.js
===================================================================
--- binaries/data/mods/public/simulation/helpers/Attacking.js
+++ binaries/data/mods/public/simulation/helpers/Attacking.js
@@ -196,8 +196,30 @@
if (cmpHealth)
total /= 0.1 + 0.9 * cmpHealth.GetHitpoints() / cmpHealth.GetMaxHitpoints();
}
- else if (effectType == "StatusEffect")
- return effectData[effectType];
+ else if (effectType == "ApplyStatus")
+ {
+ if (!resistanceStrengths.ApplyStatus)
+ return effectData[effectType];
+
+ let result = {};
+ for (let statusEffect in effectData[effectType])
+ {
+ if (!resistanceStrengths.ApplyStatus[statusEffect])
+ {
+ result[statusEffect] = effectData[effectType][statusEffect];
+ continue;
+ }
+
+ if (randBool(resistanceStrengths.ApplyStatus[statusEffect].blockChance))
+ continue;
+
+ result[statusEffect] = effectData[effectType][statusEffect];
+
+ if (effectData[effectType][statusEffect].Duration)
+ result[statusEffect].Duration = effectData[effectType][statusEffect].Duration * resistanceStrengths.ApplyStatus[statusEffect].duration;
+ }
+ return result;
+ }
return total * bonusMultiplier;
};
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
@@ -8,6 +8,12 @@
1
1
+
+
+ 0.5
+ 1
+
+
Index: binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged.xml
+++ binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged.xml
@@ -16,6 +16,52 @@
1.5
0
+
+
+ StatusEffect's name 1
+ Extend
+ Some bogus bonus tooltip describing the effect of the modifiers. This speeds up the entity but halves the health and resource gathering speed.
+ 15000
+
+
+ UnitMotion/WalkSpeed
+ Unit
+ 20
+
+
+ Health/Max ResourceGatherer/BaseSpeed
+ Unit Structure
+ 0.5
+
+
+
+
+ StatusEffect's name 2
+ You've been poissoned!
+ Replace
+ 10000
+ 1000
+
+ 1
+
+
+
+ StatusEffect's name 3
+ Stack
+ Some bogus bonus tooltip describing the effect of the modifiers. This increases the armour permanently.
+ 1000
+
+ 1
+
+
+
+ Armour/Hack Armour/Pierce Armour/Crush
+ Unit
+ 20
+
+
+
+
10.0
0.0
750