Index: binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- binaries/data/mods/public/simulation/components/UnitAI.js +++ binaries/data/mods/public/simulation/components/UnitAI.js @@ -193,6 +193,10 @@ // ignore }, + "TargetDeath": function() { + // ignore + }, + // Formation handlers: "FormationLeave": function(msg) { @@ -1997,6 +2001,8 @@ { let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); cmpAttack.PerformAttack(this.order.data.attackType, target); + if (!this.order) + return; } // Check we can still reach the target for the next attack @@ -2025,8 +2031,9 @@ this.SetNextState("FINDINGNEWTARGET"); }, - // TODO: respond to target deaths immediately, rather than waiting - // until the next Timer event + "TargetDeath": function(msg) { + this.SetNextState("COMBAT.FINDINGNEWTARGET"); + }, "Attacked": function(msg) { // If we are capturing and are attacked by something that we would not capture, attack that entity instead @@ -2189,7 +2196,7 @@ "MovementUpdate": function(msg) { // If it looks like the path is failing, and we are close enough (3 tiles) from wanted range // stop anyways. This avoids pathing for an unreachable goal and reduces lag considerably. - if (msg.likelyFailure || + if (msg.likelyFailure || msg.obstructed && this.RelaxedMaxRangeCheck(this.order.data, this.order.data.max + this.DefaultRelaxedMaxRange) || !msg.obstructed && this.CheckRange(this.order.data)) this.FinishOrder(); @@ -4182,6 +4189,12 @@ this.UnitFsm.ProcessMessage(this, {"type": "GuardedAttacked", "data": msg.data}); }; +UnitAI.prototype.OnTargetDeath = function(msg) +{ + if (this.order && this.order.data && this.order.data.target && this.order.data.target == msg.target) + this.UnitFsm.ProcessMessage(this, {"type": "TargetDeath", "target": msg.target}); +}; + UnitAI.prototype.OnHealthChanged = function(msg) { this.UnitFsm.ProcessMessage(this, {"type": "HealthChanged", "from": msg.from, "to": msg.to}); @@ -5563,7 +5576,7 @@ this.workOrders.length && this.workOrders[0].type == "Trade") { let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); - if (cmpTrader.HasBothMarkets() && + if (cmpTrader.HasBothMarkets() && (cmpTrader.GetFirstMarket() == target && cmpTrader.GetSecondMarket() == source || cmpTrader.GetFirstMarket() == source && cmpTrader.GetSecondMarket() == target)) { 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 @@ -339,7 +339,15 @@ let cmpLooter = Engine.QueryInterface(attacker, IID_Looter); if (cmpLooter) cmpLooter.Collect(target); + + Engine.BroadcastMessage(MT_TargetDeath, { "target": target }); }; +/** + * Message of the form { "target": entityID } + * sent from Damage component whenever a target dies. + */ +Engine.RegisterMessageType("TargetDeath"); + var AttackingInstance = new Attacking(); Engine.RegisterGlobal("Attacking", AttackingInstance);