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 @@ -177,7 +177,7 @@ UnitAI.prototype.notifyToCheerInRange = 30; -// To reject an order, use 'return this.FinishOrder();' +const REJECT_ORDER = false; const ACCEPT_ORDER = true; // See ../helpers/FSM.js for some documentation of this FSM specification syntax @@ -248,7 +248,7 @@ // Called when being told to walk as part of a formation "Order.FormationWalk": function(msg) { if (!this.AbleToMove()) - return this.FinishOrder(); + return this.RejectOrder(); if (this.CanPack()) { @@ -256,12 +256,12 @@ // In that case we don't actually want to move, as that would unpack us. let cmpControllerAI = Engine.QueryInterface(this.GetFormationController(), IID_UnitAI); if (cmpControllerAI.IsIdle()) - return this.FinishOrder(); + return this.RejectOrder(); this.PushOrderFront("Pack", { "force": true }); + return ACCEPT_ORDER; } - else - this.SetNextState("FORMATIONMEMBER.WALKING"); - return ACCEPT_ORDER; + this.SetNextState("FORMATIONMEMBER.WALKING"); + return this.AcceptOrder(msg); }, // Special orders: @@ -269,17 +269,17 @@ "Order.LeaveFoundation": function(msg) { if (!this.WillMoveFromFoundation(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); msg.data.min = g_LeaveFoundationRange; this.SetNextState("INDIVIDUAL.WALKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, // Individual orders: - "Order.LeaveFormation": function() { + "Order.LeaveFormation": function(msg) { if (!this.IsFormationMember()) - return this.FinishOrder(); + return this.RejectOrder(); let cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation); if (cmpFormation) @@ -290,7 +290,7 @@ cmpFormation.RemoveMembers([this.entity]); cmpFormation.SetRearrange(true); } - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Stop": function(msg) { @@ -300,7 +300,7 @@ "Order.Walk": function(msg) { if (!this.AbleToMove()) - return this.FinishOrder(); + return this.RejectOrder(); if (this.CanPack()) { @@ -311,12 +311,12 @@ this.SetHeldPosition(msg.data.x, msg.data.z); msg.data.relaxed = true; this.SetNextState("INDIVIDUAL.WALKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.WalkAndFight": function(msg) { if (!this.AbleToMove()) - return this.FinishOrder(); + return this.RejectOrder(); if (this.CanPack()) { @@ -327,13 +327,13 @@ this.SetHeldPosition(msg.data.x, msg.data.z); msg.data.relaxed = true; this.SetNextState("INDIVIDUAL.WALKINGANDFIGHTING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.WalkToTarget": function(msg) { if (!this.AbleToMove()) - return this.FinishOrder(); + return this.RejectOrder(); if (this.CanPack()) { @@ -341,25 +341,24 @@ return ACCEPT_ORDER; } - if (this.CheckRange(msg.data)) - return this.FinishOrder(); + return this.RejectOrder(); msg.data.relaxed = true; this.SetNextState("INDIVIDUAL.WALKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.PickupUnit": function(msg) { let cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); if (!cmpGarrisonHolder || cmpGarrisonHolder.IsFull()) - return this.FinishOrder(); + return this.RejectOrder(); let range = cmpGarrisonHolder.GetLoadingRange(); msg.data.min = range.min; msg.data.max = range.max; if (this.CheckRange(msg.data)) - return this.FinishOrder(); + return this.RejectOrder(); // Check if we need to move // If the target can reach us and we are reasonably close, don't move. @@ -371,33 +370,33 @@ this.SetNextState("INDIVIDUAL.PICKUP.LOADING"); else this.SetNextState("INDIVIDUAL.PICKUP.APPROACHING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Guard": function(msg) { if (!this.AddGuard(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); if (!this.CheckTargetRangeExplicit(this.isGuardOf, 0, this.guardRange)) this.SetNextState("INDIVIDUAL.GUARD.ESCORTING"); else this.SetNextState("INDIVIDUAL.GUARD.GUARDING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Flee": function(msg) { this.SetNextState("INDIVIDUAL.FLEEING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Attack": function(msg) { let type = this.GetBestAttackAgainst(msg.data.target, msg.data.allowCapture); if (!type) - return this.FinishOrder(); + return this.RejectOrder(); msg.data.attackType = type; - this.RememberTargetPosition(); + this.RememberTargetPosition(msg); if (msg.data.hunting && this.orderQueue.length > 1 && this.orderQueue[1].type === "Gather") this.RememberTargetPosition(this.orderQueue[1].data); @@ -413,12 +412,12 @@ if (this.EnsureCorrectPackStateForAttack(false)) this.SetNextState("INDIVIDUAL.COMBAT.ATTACKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); } // If we're hunting, that's a special case where we should continue attacking our target. if (this.GetStance().respondStandGround && !msg.data.force && !msg.data.hunting || !this.AbleToMove()) - return this.FinishOrder(); + return this.RejectOrder(); if (this.CanPack()) { @@ -429,12 +428,12 @@ // If we're currently packing/unpacking, make sure we are packed, so we can move. if (this.EnsureCorrectPackStateForAttack(true)) this.SetNextState("INDIVIDUAL.COMBAT.APPROACHING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Patrol": function(msg) { if (!this.AbleToMove()) - return this.FinishOrder(); + return this.RejectOrder(); if (this.CanPack()) { @@ -445,35 +444,36 @@ msg.data.relaxed = true; this.SetNextState("INDIVIDUAL.PATROL.PATROLLING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Heal": function(msg) { if (!this.TargetIsAlive(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); // Healers can't heal themselves. if (msg.data.target == this.entity) - return this.FinishOrder(); + return this.RejectOrder(); if (this.CheckTargetRange(msg.data.target, IID_Heal)) { this.SetNextState("INDIVIDUAL.HEAL.HEALING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); } if (this.GetStance().respondStandGround && !msg.data.force) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("INDIVIDUAL.HEAL.APPROACHING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Gather": function(msg) { + return this.RejectOrder(); if (!this.CanGather(msg.data.target)) { this.SetNextState("INDIVIDUAL.GATHER.FINDINGNEWTARGET"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); } // If the unit is full go to the nearest dropsite instead of trying to gather. @@ -488,7 +488,7 @@ "type": msg.data.type }); // Players expect the unit to move, so walk to the target instead of trying to gather. - else if (!this.FinishOrder()) + else if (!this.OrderQueue.length) this.WalkToTarget(msg.data.target, false); return ACCEPT_ORDER; @@ -501,7 +501,7 @@ { // Oops, we can't attack at all - give up // TODO: should do something so the player knows why this failed - return this.FinishOrder(); + return this.RejectOrder(); } // The target was visible when this order was issued, // but could now be invisible again. @@ -513,7 +513,7 @@ this.PushOrderFront("Walk", msg.data.lastPos); } // We couldn't move there, or the target moved away - else if (!this.FinishOrder()) + else if (!this.OrderQueue.length) this.PushOrderFront("GatherNearPosition", { "x": msg.data.lastPos.x, "z": msg.data.lastPos.z, @@ -527,7 +527,7 @@ return ACCEPT_ORDER; } - this.RememberTargetPosition(); + this.RememberTargetPosition(msg); if (!msg.data.initPos) msg.data.initPos = msg.data.lastPos; @@ -535,14 +535,14 @@ this.SetNextState("INDIVIDUAL.GATHER.GATHERING"); else this.SetNextState("INDIVIDUAL.GATHER.APPROACHING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.GatherNearPosition": function(msg) { this.SetNextState("INDIVIDUAL.GATHER.WALKING"); msg.data.initPos = { 'x': msg.data.x, 'z': msg.data.z }; msg.data.relaxed = true; - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.ReturnResource": function(msg) { @@ -555,22 +555,21 @@ // Our next order should always be a Gather, // so just switch back to that order. - this.FinishOrder(); + return ACCEPT_ORDER; } - else - this.SetNextState("INDIVIDUAL.RETURNRESOURCE.APPROACHING"); - return ACCEPT_ORDER; + this.SetNextState("INDIVIDUAL.RETURNRESOURCE.APPROACHING"); + return this.AcceptOrder(msg); }, "Order.Trade": function(msg) { // We must check if this trader has both markets in case it was a back-to-work order. let cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); if (!cmpTrader || !cmpTrader.HasBothMarkets()) - return this.FinishOrder(); + return this.RejectOrder(); this.waypoints = []; this.SetNextState("TRADE.APPROACHINGMARKET"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Repair": function(msg) { @@ -578,12 +577,12 @@ this.SetNextState("INDIVIDUAL.REPAIR.REPAIRING"); else this.SetNextState("INDIVIDUAL.REPAIR.APPROACHING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Garrison": function(msg) { if (!this.AbleToMove()) - return this.FinishOrder(); + return this.RejectOrder(); // Also pack when we are in range. if (this.CanPack()) @@ -596,7 +595,7 @@ this.SetNextState("INDIVIDUAL.GARRISON.GARRISONING"); else this.SetNextState("INDIVIDUAL.GARRISON.APPROACHING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Ungarrison": function(msg) { @@ -609,37 +608,37 @@ }, "Order.Cheer": function(msg) { - return this.FinishOrder(); + return this.RejectOrder(); }, "Order.Pack": function(msg) { if (!this.CanPack()) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("INDIVIDUAL.PACKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Unpack": function(msg) { if (!this.CanUnpack()) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("INDIVIDUAL.UNPACKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.MoveToChasingPoint": function(msg) { // Overriden by the CHASING state. // Can however happen outside of it when renaming... // TODO: don't use an order for that behaviour. - return this.FinishOrder(); + return this.RejectOrder(); }, "Order.CollectTreasure": function(msg) { let cmpTreasureCollecter = Engine.QueryInterface(this.entity, IID_TreasureCollecter); if (!cmpTreasureCollecter || !cmpTreasureCollecter.CanCollect(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("COLLECTTREASURE"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.CollectTreasureNearPosition": function(msg) { @@ -648,7 +647,7 @@ this.CollectTreasure(nearbyTreasure, oldData.autocontinue, true); else this.SetNextState("COLLECTTREASURE"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, // States for the special entity representing a group of units moving in formation: @@ -657,53 +656,53 @@ "Order.Walk": function(msg) { this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); this.SetNextState("WALKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.WalkAndFight": function(msg) { this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); this.SetNextState("WALKINGANDFIGHTING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.MoveIntoFormation": function(msg) { this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); this.SetNextState("FORMING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, // Only used by other orders to walk there in formation. "Order.WalkToTargetRange": function(msg) { if (this.CheckRange(msg.data)) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("WALKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.WalkToTarget": function(msg) { if (this.CheckRange(msg.data)) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("WALKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.WalkToPointRange": function(msg) { if (this.CheckRange(msg.data)) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("WALKING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Patrol": function(msg) { this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]); this.SetNextState("PATROL.PATROLLING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Guard": function(msg) { this.CallMemberFunction("Guard", [msg.data.target, false]); Engine.QueryInterface(this.entity, IID_Formation).Disband(); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Stop": function(msg) { @@ -730,9 +729,9 @@ if (this.CanAttack(target) && this.CheckTargetVisible(target)) { this.SetNextState("COMBAT.APPROACHING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); } - return this.FinishOrder(); + return this.RejectOrder(); } this.CallMemberFunction("Attack", [target, allowCapture, false]); let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); @@ -740,22 +739,22 @@ this.SetNextState("COMBAT.ATTACKING"); else this.SetNextState("MEMBER"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Garrison": function(msg) { if (!Engine.QueryInterface(msg.data.target, IID_GarrisonHolder)) - return this.FinishOrder(); + return this.RejectOrder(); if (!this.CheckGarrisonRange(msg.data.target)) { if (!this.CheckTargetVisible(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("GARRISON.APPROACHING"); } else this.SetNextState("GARRISON.GARRISONING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Gather": function(msg) { @@ -771,17 +770,15 @@ this.PushOrderFront("Walk", msg.data.lastPos); } // We couldn't move there, or the target moved away + else if (this.OrderQueue.length == 1) + this.PushOrderFront("GatherNearPosition", { + "x": msg.data.lastPos.x, + "z": msg.data.lastPos.z, + "type": msg.data.type, + "template": msg.data.template + }); else - { - let data = msg.data; - if (!this.FinishOrder()) - this.PushOrderFront("GatherNearPosition", { - "x": data.lastPos.x, - "z": data.lastPos.z, - "type": data.type, - "template": data.template - }); - } + return this.RejectOrder(); return ACCEPT_ORDER; } this.PushOrderFront("Attack", { "target": msg.data.target, "force": !!msg.data.force, "hunting": true, "allowCapture": false, "min": 0, "max": 10 }); @@ -792,7 +789,7 @@ if (!this.CheckTargetRangeExplicit(msg.data.target, 0, 10)) { if (!this.CanGather(msg.data.target) || !this.CheckTargetVisible(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); // TODO: Should we issue a gather-near-position order // if the target isn't gatherable/doesn't exist anymore? if (!msg.data.secondTry) @@ -801,13 +798,13 @@ this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": 10 }); return ACCEPT_ORDER; } - return this.FinishOrder(); + return this.RejectOrder(); } this.CallMemberFunction("Gather", [msg.data.target, false]); this.SetNextState("MEMBER"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.GatherNearPosition": function(msg) { @@ -822,7 +819,7 @@ this.CallMemberFunction("GatherNearPosition", [msg.data.x, msg.data.z, msg.data.type, msg.data.template, false]); this.SetNextState("MEMBER"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Heal": function(msg) { @@ -830,7 +827,7 @@ if (!this.CheckTargetRangeExplicit(msg.data.target, 0, 10)) { if (!this.TargetIsAlive(msg.data.target) || !this.CheckTargetVisible(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); if (!msg.data.secondTry) { @@ -838,13 +835,13 @@ this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": 10 }); return ACCEPT_ORDER; } - return this.FinishOrder(); + return this.RejectOrder(); } this.CallMemberFunction("Heal", [msg.data.target, false]); this.SetNextState("MEMBER"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Repair": function(msg) { @@ -852,7 +849,7 @@ if (!this.CheckTargetRangeExplicit(msg.data.target, 0, 10)) { if (!this.TargetIsAlive(msg.data.target) || !this.CheckTargetVisible(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); if (!msg.data.secondTry) { @@ -860,13 +857,13 @@ this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": 10 }); return ACCEPT_ORDER; } - return this.FinishOrder(); + return this.RejectOrder(); } this.CallMemberFunction("Repair", [msg.data.target, msg.data.autocontinue, false]); this.SetNextState("MEMBER"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.ReturnResource": function(msg) { @@ -874,7 +871,7 @@ if (!this.CheckTargetRangeExplicit(msg.data.target, 0, 10)) { if (!this.CheckTargetVisible(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); if (!msg.data.secondTry) { @@ -882,27 +879,27 @@ this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": 10 }); return ACCEPT_ORDER; } - return this.FinishOrder(); + return this.RejectOrder(); } this.CallMemberFunction("ReturnResource", [msg.data.target, false]); this.SetNextState("MEMBER"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Pack": function(msg) { this.CallMemberFunction("Pack", [false]); this.SetNextState("MEMBER"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "Order.Unpack": function(msg) { this.CallMemberFunction("Unpack", [false]); this.SetNextState("MEMBER"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "IDLE": { @@ -1342,10 +1339,10 @@ // state forever and need to get out of foundations in that case) "Order.LeaveFoundation": function(msg) { if (!this.WillMoveFromFoundation(msg.data.target)) - return this.FinishOrder(); + return this.RejectOrder(); msg.data.min = g_LeaveFoundationRange; this.SetNextState("WALKINGTOPOINT"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "enter": function() { @@ -1495,13 +1492,13 @@ }, "IDLE": { - "Order.Cheer": function() { + "Order.Cheer": function(msg) { // Do not cheer if there is no cheering time and we are not idle yet. if (!this.cheeringTime || !this.isIdle) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("CHEERING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "enter": function() { @@ -1944,7 +1941,7 @@ "COMBAT": { "Order.LeaveFoundation": function(msg) { // Ignore the order as we're busy. - return this.FinishOrder(); + return this.RejectOrder(); }, "Attacked": function(msg) { @@ -2191,12 +2188,12 @@ }, "FINDINGNEWTARGET": { - "Order.Cheer": function() { + "Order.Cheer": function(msg) { if (!this.cheeringTime) - return this.FinishOrder(); + return this.RejectOrder(); this.SetNextState("CHEERING"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "enter": function() { @@ -2244,11 +2241,11 @@ "CHASING": { "Order.MoveToChasingPoint": function(msg) { if (this.CheckPointRangeExplicit(msg.data.x, msg.data.z, 0, msg.data.max)) - return this.FinishOrder(); + return this.RejectOrder(); msg.data.relaxed = true; this.StopTimer(); this.SetNextState("MOVINGTOPOINT"); - return ACCEPT_ORDER; + return this.AcceptOrder(msg); }, "enter": function() { if (!this.MoveToTargetAttackRange(this.order.data.target, this.order.data.attackType)) @@ -3858,7 +3855,6 @@ * next one (if any). Returns false and defaults to IDLE * if there are no remaining orders or if the unit is not * inWorld and not garrisoned (thus usually waiting to be destroyed). - * Must be called from inside the FSM. */ UnitAI.prototype.FinishOrder = function() { @@ -3871,19 +3867,21 @@ } this.orderQueue.shift(); - this.order = this.orderQueue[0]; let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); if (this.orderQueue.length && (this.isGarrisoned || this.IsFormationController() || cmpPosition && cmpPosition.IsInWorld())) { + let order = this.orderQueue[0]; let ret = this.UnitFsm.ProcessMessage(this, { - "type": "Order."+this.order.type, - "data": this.order.data + "type": "Order." + order.type, + "data": order.data }); - Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); + if (ret === REJECT_ORDER) + return this.FinishOrder(); + Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); return ret; } @@ -3895,7 +3893,7 @@ Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); - // Check if there are queued formation orders + // Check if there are queued formation orders. if (this.IsFormationMember()) { this.SetNextState("FORMATIONMEMBER.IDLE"); @@ -3915,21 +3913,41 @@ }; /** + * @param {Object} order - The order to accept. + * @return {boolean} - Whether we accepted the order. + */ +UnitAI.prototype.AcceptOrder = function(order) +{ + this.order = order; + return ACCEPT_ORDER; +}; + +/** + * @return {boolean} - Whether we rejected the order. + */ +UnitAI.prototype.RejectOrder = function() +{ + this.FinishOrder(); + return REJECT_ORDER; +}; + +/** * Add an order onto the back of the queue, * and execute it if we didn't already have an order. */ UnitAI.prototype.PushOrder = function(type, data) { - var order = { "type": type, "data": data }; + let order = { "type": type, "data": data }; this.orderQueue.push(order); if (this.orderQueue.length == 1) { - this.order = order; - this.UnitFsm.ProcessMessage(this, { - "type": "Order."+this.order.type, - "data": this.order.data + let ret = this.UnitFsm.ProcessMessage(this, { + "type": "Order." + order.type, + "data": order.data }); + if (ret === REJECT_ORDER) + return; } Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); @@ -3941,25 +3959,25 @@ */ UnitAI.prototype.PushOrderFront = function(type, data, ignorePacking = false) { - var order = { "type": type, "data": data }; + let order = { "type": type, "data": data }; // If current order is packing/unpacking then add new order after it. if (!ignorePacking && this.order && this.IsPacking()) { - var packingOrder = this.orderQueue.shift(); + let packingOrder = this.orderQueue.shift(); this.orderQueue.unshift(packingOrder, order); } else { this.orderQueue.unshift(order); - this.order = order; - this.UnitFsm.ProcessMessage(this, { - "type": "Order."+this.order.type, - "data": this.order.data + let ret = this.UnitFsm.ProcessMessage(this, { + "type": "Order." + order.type, + "data": order.data }); + if (ret === REJECT_ORDER) + return; } Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); - }; /** Index: binaries/data/mods/public/simulation/components/tests/test_UnitAI.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_UnitAI.js +++ binaries/data/mods/public/simulation/components/tests/test_UnitAI.js @@ -329,7 +329,7 @@ units.push(unit + i); - var unitAI = ConstructComponent(unit + i, "UnitAI", { "FormationController": "false", "DefaultStance": "aggressive" }); + let unitAI = ConstructComponent(unit + i, "UnitAI", { "FormationController": "false", "DefaultStance": "aggressive" }); AddMock(unit + i, IID_Identity, { "GetClassesList": function() { return []; }, @@ -345,6 +345,7 @@ "GetPosition2D": function() { return new Vector2D(); }, "GetRotation": function() { return { "y": 0 }; }, "IsInWorld": function() { return true; }, + "TurnTo": function() {} }); AddMock(unit + i, IID_UnitMotion, { @@ -429,16 +430,16 @@ controllerAI.Attack(enemy, []); - for (let ent of unitAIs) + for (let unitAI of unitAIs) TS_ASSERT_EQUALS(unitAI.fsmStateName, "INDIVIDUAL.COMBAT.ATTACKING"); controllerAI.MoveIntoFormation({ "name": "Circle" }); - // let all units be in position - for (let ent of unitAIs) - controllerFormation.SetWaitingOnController(ent); + // Let all units be in position. + for (let unitAI of unitAIs) + unitAI.OnMotionUpdate({}); - for (let ent of unitAIs) + for (let unitAI of unitAIs) TS_ASSERT_EQUALS(unitAI.fsmStateName, "INDIVIDUAL.COMBAT.ATTACKING"); controllerFormation.Disband();