Index: ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js +++ ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js @@ -3588,25 +3588,27 @@ * Call when the current order has been completed (or failed). * Removes the current order from the queue, and processes the * next one (if any). Returns false and defaults to IDLE - * if there are no remaining orders. + * if there are no remaining orders or if the unit is not + * inWorld and not garrisoned (thus usually waiting to be destroyed). */ UnitAI.prototype.FinishOrder = function() { if (!this.orderQueue.length) { - var stack = new Error().stack.trimRight().replace(/^/mg, ' '); // indent each line - var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); - var template = cmpTemplateManager.GetCurrentTemplateName(this.entity); + let stack = new Error().stack.trimRight().replace(/^/mg, ' '); // indent each line + let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); + let template = cmpTemplateManager.GetCurrentTemplateName(this.entity); error("FinishOrder called for entity " + this.entity + " (" + template + ") when order queue is empty\n" + stack); } this.orderQueue.shift(); this.order = this.orderQueue[0]; - if (this.orderQueue.length) + 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} + { "type": "Order."+this.order.type, "data": this.order.data } ); Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); @@ -3619,29 +3621,26 @@ // Otherwise we've successfully processed a new order return true; } - else - { - this.SetNextState("IDLE"); - Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); + this.SetNextState("IDLE"); - // Check if there are queued formation orders - if (this.IsFormationMember()) + Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); + + // Check if there are queued formation orders + if (this.IsFormationMember()) + { + let cmpUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI); + if (cmpUnitAI) { - let cmpUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI); - if (cmpUnitAI) - { - // Inform the formation controller that we finished this task - this.finishedOrder = true; - // We don't want to carry out the default order - // if there are still queued formation orders left - if (cmpUnitAI.GetOrders().length > 1) - return true; - } + // Inform the formation controller that we finished this task + this.finishedOrder = true; + // We don't want to carry out the default order + // if there are still queued formation orders left + if (cmpUnitAI.GetOrders().length > 1) + return true; } - - return false; } + return false; }; /**