diff --git a/binaries/data/mods/public/simulation/components/Attack.js b/binaries/data/mods/public/simulation/components/Attack.js index 190ec1ec2b..3a43208159 100644 --- a/binaries/data/mods/public/simulation/components/Attack.js +++ b/binaries/data/mods/public/simulation/components/Attack.js @@ -455,6 +455,10 @@ Attack.prototype.StartAttacking = function(target, type, callerIID) if (!this.CanAttack(target, [type])) return false; + let cmpResistance = Engine.QueryInterface(target, IID_Resistance); + if (!cmpResistance || !cmpResistance.AddAttacker(this.entity)) + return false; + let timings = this.GetTimers(type); let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); @@ -496,6 +500,10 @@ Attack.prototype.StopAttacking = function(reason) cmpTimer.CancelTimer(this.timer); delete this.timer; + let cmpResistance = Engine.QueryInterface(this.target, IID_Resistance); + if (cmpResistance) + cmpResistance.RemoveAttacker(this.entity); + delete this.target; let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); @@ -539,10 +547,7 @@ Attack.prototype.Attack = function(type, lateness) this.PerformAttack(type, this.target); if (!this.target) - { - this.StopAttacking("TargetInvalidated"); return; - } // We check the range after the attack to facilitate chasing. if (!this.IsTargetInRange(this.target, type)) diff --git a/binaries/data/mods/public/simulation/components/Resistance.js b/binaries/data/mods/public/simulation/components/Resistance.js index 8d0fea058c..77f2be6c0a 100644 --- a/binaries/data/mods/public/simulation/components/Resistance.js +++ b/binaries/data/mods/public/simulation/components/Resistance.js @@ -73,6 +73,7 @@ Resistance.prototype.Schema = Resistance.prototype.Init = function() { this.invulnerable = false; + this.attackers = new Set(); }; Resistance.prototype.IsInvulnerable = function() @@ -80,6 +81,28 @@ Resistance.prototype.IsInvulnerable = function() return this.invulnerable; }; +/** + * @param {number} attacker - The entity ID of the attacker to add. + * @return {boolean} - Whether the attacker was added sucessfully. + */ +Resistance.prototype.AddAttacker = function(attacker) +{ + if (this.attackers.has(attacker)) + return false; + + this.attackers.add(attacker); + return true; +}; + +/** + * @param {number} attacker - The entity ID of the attacker to remove. + * @return {boolean} - Whether the attacker was attacking us previously. + */ +Resistance.prototype.RemoveAttacker = function(attacker) +{ + return this.attackers.delete(attacker); +}; + Resistance.prototype.SetInvulnerability = function(invulnerability) { this.invulnerable = invulnerability; @@ -151,4 +174,11 @@ Resistance.prototype.GetResistanceOfForm = function(entityForm) return ret; }; +Resistance.prototype.OnOwnershipChanged = function(msg) +{ + if (msg.to === INVALID_PLAYER) + for (let attacker of this.attackers) + Engine.QueryInterface(attacker, IID_Attack)?.StopAttacking("TargetInvalidated"); +}; + Engine.RegisterComponentType(IID_Resistance, "Resistance", Resistance); diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js index 9a4d6b0fc3..55504a1bd3 100644 --- a/binaries/data/mods/public/simulation/components/UnitAI.js +++ b/binaries/data/mods/public/simulation/components/UnitAI.js @@ -2156,9 +2156,6 @@ UnitAI.prototype.UnitFsmSpec = { this.SetNextState("FINDINGNEWTARGET"); }, - // TODO: respond to target deaths immediately, rather than waiting - // until the next Timer event - "Attacked": function(msg) { if (this.order.data.attackType == "Capture" && (this.GetStance().targetAttackersAlways || !this.order.data.force) && this.order.data.target != msg.data.attacker && this.GetBestAttackAgainst(msg.data.attacker, true) != "Capture") diff --git a/binaries/data/mods/public/simulation/templates/special/filter/mirage.xml b/binaries/data/mods/public/simulation/templates/special/filter/mirage.xml index 13dc304870..9a4247458e 100644 --- a/binaries/data/mods/public/simulation/templates/special/filter/mirage.xml +++ b/binaries/data/mods/public/simulation/templates/special/filter/mirage.xml @@ -24,6 +24,7 @@ +