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 @@ -557,7 +557,12 @@ return; } - this.PushOrderFront("Attack", { "target": this.order.data.target, "force": !!this.order.data.force, "hunting": true, "allowCapture": false }); + this.PushOrderFront("Attack", { + "target": this.order.data.target, + "force": !!this.order.data.force, + "hunting": true, + "allowCapture": false + }); return; } @@ -788,11 +793,10 @@ this.FinishOrder(); return; } - else - { - this.SetNextState("GARRISON.APPROACHING"); - return; - } + + this.SetNextState("GARRISON.APPROACHING"); + return; + } this.SetNextState("GARRISON.GARRISONING"); @@ -824,7 +828,14 @@ } return; } - this.PushOrderFront("Attack", { "target": msg.data.target, "force": !!msg.data.force, "hunting": true, "allowCapture": false, "min": 0, "max": 10 }); + this.PushOrderFront("Attack", { + "target": msg.data.target, + "force": !!msg.data.force, + "hunting": true, + "allowCapture": false, + "min": 0, + "max": 10 + }); return; } @@ -1060,7 +1071,7 @@ }, }, - "GARRISON":{ + "GARRISON": { "APPROACHING": { "enter": function() { if (!this.MoveToGarrisonRange(this.order.data.target)) @@ -2042,8 +2053,8 @@ "Attacked": function(msg) { // If we are capturing and are attacked by something that we would not capture, attack that entity instead - 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") + 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") this.RespondToTargetedEntities([msg.data.attacker]); }, }, @@ -2201,7 +2212,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(); @@ -2843,7 +2854,7 @@ { // The building was already finished/fully repaired before we arrived; // let the ConstructionFinished handler handle this. - this.OnGlobalConstructionFinished({"entity": this.repairTarget, "newentity": this.repairTarget}); + this.OnGlobalConstructionFinished({ "entity": this.repairTarget, "newentity": this.repairTarget }); return true; } @@ -3141,7 +3152,7 @@ this.StopTimer(); this.ResetAnimation(); if (this.formationAnimationVariant) - this.SetAnimationVariant(this.formationAnimationVariant) + this.SetAnimationVariant(this.formationAnimationVariant); else this.SetDefaultAnimationVariant(); var cmpResistance = Engine.QueryInterface(this.entity, IID_Resistance); @@ -3362,12 +3373,15 @@ }, }, - "FLEEING": "INDIVIDUAL.FLEEING", // reuse the same fleeing behaviour for animals + // reuse the same fleeing behaviour for animals + "FLEEING": "INDIVIDUAL.FLEEING", - "COMBAT": "INDIVIDUAL.COMBAT", // reuse the same combat behaviour for animals + // reuse the same combat behaviour for animals + "COMBAT": "INDIVIDUAL.COMBAT", - "WALKING": "INDIVIDUAL.WALKING", // reuse the same walking behaviour for animals - // only used for domestic animals + // reuse the same walking behaviour for animals + // only used for domestic animals + "WALKING": "INDIVIDUAL.WALKING", // Reuse the same garrison behaviour for animals. "GARRISON": "INDIVIDUAL.GARRISON", @@ -3429,7 +3443,7 @@ UnitAI.prototype.IsAnimal = function() { - return (this.template.NaturalBehaviour ? true : false); + return this.template.NaturalBehaviour !== undefined; }; UnitAI.prototype.IsDangerousAnimal = function() @@ -3545,7 +3559,7 @@ { let index = this.GetCurrentState().indexOf("."); if (index != -1) - this.UnitFsm.SwitchToNextState(this, this.GetCurrentState().slice(0,index)); + this.UnitFsm.SwitchToNextState(this, this.GetCurrentState().slice(0, index)); this.Stop(false); } @@ -3601,7 +3615,10 @@ if (this.orderQueue[i].type != "PickupUnit" || this.orderQueue[i].data.target != msg.entity) continue; if (i == 0) - this.UnitFsm.ProcessMessage(this, {"type": "PickupCanceled", "data": msg}); + this.UnitFsm.ProcessMessage(this, { + "type": "PickupCanceled", + "data": msg + }); else this.orderQueue.splice(i, 1); Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); @@ -3688,7 +3705,7 @@ }; -//// FSM linkage functions //// +// FSM linkage functions // Setting the next state to the current state will leave/re-enter the top-most substate. UnitAI.prototype.SetNextState = function(state) @@ -3734,9 +3751,10 @@ let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); if (this.orderQueue.length && (this.IsGarrisoned() || cmpPosition && cmpPosition.IsInWorld())) { - let ret = this.UnitFsm.ProcessMessage(this, - { "type": "Order."+this.order.type, "data": this.order.data } - ); + let ret = this.UnitFsm.ProcessMessage(this, { + "type": "Order."+this.order.type, + "data": this.order.data + }); Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); @@ -3788,9 +3806,10 @@ if (this.orderQueue.length == 1) { this.order = order; - let ret = this.UnitFsm.ProcessMessage(this, - { "type": "Order."+this.order.type, "data": this.order.data } - ); + let ret = this.UnitFsm.ProcessMessage(this, { + "type": "Order."+this.order.type, + "data": this.order.data + }); // If the order was rejected then immediately take it off // and process the remaining queue @@ -3824,9 +3843,10 @@ { this.orderQueue.unshift(order); this.order = order; - let ret = this.UnitFsm.ProcessMessage(this, - { "type": "Order."+this.order.type, "data": this.order.data } - ); + let ret = this.UnitFsm.ProcessMessage(this, { + "type": "Order."+this.order.type, + "data": this.order.data + }); // If the order was rejected then immediately take it off again; // assume the previous active order is still valid (the short-lived @@ -3859,7 +3879,7 @@ continue; if (this.orderQueue[i].type == type) continue; - this.orderQueue.splice(i, 0, {"type": type, "data": data}); + this.orderQueue.splice(i, 0, { "type": type, "data": data }); Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); return; } @@ -4101,7 +4121,7 @@ if (data.timerRepeat === undefined) this.timer = undefined; - this.UnitFsm.ProcessMessage(this, {"type": "Timer", "data": data, "lateness": lateness}); + this.UnitFsm.ProcessMessage(this, { "type": "Timer", "data": data, "lateness": lateness }); }; /** @@ -4146,7 +4166,7 @@ // TODO: This is a bit inefficient since every unit listens to every // construction message - ideally we could scope it to only the one we're building - this.UnitFsm.ProcessMessage(this, {"type": "ConstructionFinished", "data": msg}); + this.UnitFsm.ProcessMessage(this, { "type": "ConstructionFinished", "data": msg }); }; UnitAI.prototype.OnGlobalEntityRenamed = function(msg) @@ -4177,33 +4197,33 @@ if (msg.fromStatusEffect) return; - this.UnitFsm.ProcessMessage(this, {"type": "Attacked", "data": msg}); + this.UnitFsm.ProcessMessage(this, { "type": "Attacked", "data": msg }); }; UnitAI.prototype.OnGuardedAttacked = function(msg) { - this.UnitFsm.ProcessMessage(this, {"type": "GuardedAttacked", "data": msg.data}); + this.UnitFsm.ProcessMessage(this, { "type": "GuardedAttacked", "data": msg.data }); }; UnitAI.prototype.OnHealthChanged = function(msg) { - this.UnitFsm.ProcessMessage(this, {"type": "HealthChanged", "from": msg.from, "to": msg.to}); + this.UnitFsm.ProcessMessage(this, { "type": "HealthChanged", "from": msg.from, "to": msg.to }); }; UnitAI.prototype.OnRangeUpdate = function(msg) { if (msg.tag == this.losRangeQuery) - this.UnitFsm.ProcessMessage(this, {"type": "LosRangeUpdate", "data": msg}); + this.UnitFsm.ProcessMessage(this, { "type": "LosRangeUpdate", "data": msg }); else if (msg.tag == this.losHealRangeQuery) - this.UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg}); + this.UnitFsm.ProcessMessage(this, { "type": "LosHealRangeUpdate", "data": msg }); }; UnitAI.prototype.OnPackFinished = function(msg) { - this.UnitFsm.ProcessMessage(this, {"type": "PackFinished", "packed": msg.packed}); + this.UnitFsm.ProcessMessage(this, { "type": "PackFinished", "packed": msg.packed }); }; -//// Helper functions to be called by the FSM //// +// Helper functions to be called by the FSM UnitAI.prototype.GetWalkSpeed = function() { @@ -4915,9 +4935,9 @@ UnitAI.prototype.AttackEntityInZone = function(ents) { var target = ents.find(target => - this.CanAttack(target) - && this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true)) - && (this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target)) + this.CanAttack(target) && + this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true)) && + (this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target)) ); if (!target) return false; @@ -4980,11 +5000,11 @@ // If we are guarding/escorting, don't abandon as long as the guarded unit is in target range of the attacker if (this.isGuardOf) { - var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI); + var cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI); var cmpAttack = Engine.QueryInterface(target, IID_Attack); if (cmpUnitAI && cmpAttack && cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type))) - return false; + return false; } // Stop if we're in hold-ground mode and it's too far from the holding point @@ -5022,7 +5042,7 @@ // If we are guarding/escorting, chase at least as long as the guarded unit is in target range of the attacker if (this.isGuardOf) { - let cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI); + let cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI); let cmpAttack = Engine.QueryInterface(target, IID_Attack); if (cmpUnitAI && cmpAttack && cmpAttack.GetAttackTypes().some(type => cmpUnitAI.CheckTargetAttackRange(this.isGuardOf, type))) @@ -5035,7 +5055,7 @@ return false; }; -//// External interface functions //// +// External interface functions UnitAI.prototype.SetFormationController = function(ent) { @@ -5191,8 +5211,7 @@ { if (this.isGuardOf == target && this.order && this.order.type == "Guard") return; - else - this.RemoveGuard(); + this.RemoveGuard(); } this.AddOrder("Guard", { "target": target, "force": false }, queued); @@ -5522,7 +5541,8 @@ if (this.IsFormationController()) this.CallMemberFunction("CancelSetupTradeRoute", [target]); -} +}; + /** * Adds trade order to the queue. Either walk to the first market, or * start a new route. Not forced, so it can be interrupted by attacks. @@ -5543,7 +5563,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)) { @@ -5824,11 +5844,11 @@ { var cmpIdentity = Engine.QueryInterface(targ, IID_Identity); var targetClasses = this.order.data.targetClasses; - if (targetClasses.attack && cmpIdentity - && !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack)) + if (targetClasses.attack && cmpIdentity && + !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack)) continue; - if (targetClasses.avoid && cmpIdentity - && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid)) + if (targetClasses.avoid && cmpIdentity && + MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid)) continue; // Only used by the AIs to prevent some choices of targets if (targetClasses.vetoEntities && targetClasses.vetoEntities[targ]) @@ -5850,11 +5870,11 @@ { var cmpIdentity = Engine.QueryInterface(targ, IID_Identity); var targetClasses = this.order.data.targetClasses; - if (cmpIdentity && targetClasses.attack - && !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack)) + if (cmpIdentity && targetClasses.attack && + !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack)) continue; - if (cmpIdentity && targetClasses.avoid - && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid)) + if (cmpIdentity && targetClasses.avoid && + MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid)) continue; // Only used by the AIs to prevent some choices of targets if (targetClasses.vetoEntities && targetClasses.vetoEntities[targ]) @@ -5996,7 +6016,7 @@ UnitAI.prototype.SetHeldPosition = function(x, z) { - this.heldPosition = {"x": x, "z": z}; + this.heldPosition = { "x": x, "z": z }; }; UnitAI.prototype.SetHeldPositionOnEntity = function(entity) @@ -6023,7 +6043,7 @@ return false; }; -//// Helper functions //// +// Helper functions /** * General getter for ranges. @@ -6042,7 +6062,7 @@ return undefined; return component.GetRange(type); -} +}; UnitAI.prototype.CanAttack = function(target) { @@ -6240,16 +6260,16 @@ return cmpPack && cmpPack.IsPacking(); }; -//// Formation specific functions //// +// Formation specific functions UnitAI.prototype.IsAttackingAsFormation = function() { var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); - return cmpAttack && cmpAttack.CanAttackAsFormation() - && this.GetCurrentState() == "FORMATIONCONTROLLER.COMBAT.ATTACKING"; + return cmpAttack && cmpAttack.CanAttackAsFormation() && + this.GetCurrentState() == "FORMATIONCONTROLLER.COMBAT.ATTACKING"; }; -//// Animal specific functions //// +// Animal specific functions UnitAI.prototype.MoveRandomly = function(distance) {