Index: binaries/data/mods/public/maps/scripts/TriggerHelper.js =================================================================== --- binaries/data/mods/public/maps/scripts/TriggerHelper.js +++ binaries/data/mods/public/maps/scripts/TriggerHelper.js @@ -185,7 +185,7 @@ cmpOwnership.SetOwner(owner); let cmpGarrisonable = Engine.QueryInterface(ent, IID_Garrisonable); - if (cmpGarrisonable && cmpGarrisonable.Autogarrison(entity)) + if (cmpGarrisonable && cmpGarrisonable.Garrison(entity)) entities.push(ent); else error("failed to garrison entity " + ent + " (" + template + ") inside " + entity); Index: binaries/data/mods/public/simulation/components/GarrisonHolder.js =================================================================== --- binaries/data/mods/public/simulation/components/GarrisonHolder.js +++ binaries/data/mods/public/simulation/components/GarrisonHolder.js @@ -561,7 +561,7 @@ { let cmpGarrisonable = Engine.QueryInterface(ent, IID_Garrisonable); if (cmpGarrisonable) - cmpGarrisonable.Autogarrison(this.entity); + cmpGarrisonable.Garrison(this.entity); } this.initGarrison = undefined; }; Index: binaries/data/mods/public/simulation/components/Garrisonable.js =================================================================== --- binaries/data/mods/public/simulation/components/Garrisonable.js +++ binaries/data/mods/public/simulation/components/Garrisonable.js @@ -45,6 +45,14 @@ }; /** + * @return {boolean} - Whether we're garrisoned. + */ +Garrisonable.prototype.IsGarrisoned = function() +{ + return !!this.holder; +}; + +/** * @param {number} target - The entity ID to check. * @return {boolean} - Whether we can garrison. */ @@ -103,22 +111,6 @@ }; /** - * Called on game init when the entity was part of init garrison. - * @param {number} target - The entityID to autogarrison. - * @return {boolean} - Whether garrisoning succeeded. - */ -Garrisonable.prototype.Autogarrison = function(target) -{ - if (!this.Garrison(target)) - return false; - - let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); - if (cmpUnitAI) - cmpUnitAI.Autogarrison(target); - return true; -}; - -/** * @param {boolean} forced - Optionally whether the spawning is forced. * @param {boolean} renamed - Optionally whether the ungarrisoning is due to renaming. * @return {boolean} - Whether the ungarrisoning succeeded. Index: binaries/data/mods/public/simulation/components/GuiInterface.js =================================================================== --- binaries/data/mods/public/simulation/components/GuiInterface.js +++ binaries/data/mods/public/simulation/components/GuiInterface.js @@ -1857,7 +1857,11 @@ GuiInterface.prototype.IdleUnitFilter = function(unit, idleClasses, excludeUnits) { let cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI); - if (!cmpUnitAI || !cmpUnitAI.IsIdle() || cmpUnitAI.IsTurret()) + if (!cmpUnitAI || !cmpUnitAI.IsIdle()) + return { "idle": false }; + + let cmpGarrisonable = Engine.QueryInterface(unit, IID_Garrisonable); + if (cmpGarrisonable && cmpGarrisonable.IsGarrisoned()) return { "idle": false }; let cmpIdentity = Engine.QueryInterface(unit, IID_Identity); Index: binaries/data/mods/public/simulation/components/ProductionQueue.js =================================================================== --- binaries/data/mods/public/simulation/components/ProductionQueue.js +++ binaries/data/mods/public/simulation/components/ProductionQueue.js @@ -693,7 +693,7 @@ let cmpGarrisonable = Engine.QueryInterface(ent, IID_Garrisonable); // Temporary owner affectation needed for GarrisonHolder checks. cmpNewOwnership.SetOwnerQuiet(cmpOwnership.GetOwner()); - garrisoned = cmpGarrisonable && cmpGarrisonable.Autogarrison(this.entity); + garrisoned = cmpGarrisonable && cmpGarrisonable.Garrison(this.entity); cmpNewOwnership.SetOwnerQuiet(INVALID_PLAYER); } 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 @@ -582,19 +582,15 @@ }, "Order.Garrison": function(msg) { - if (!this.AbleToMove()) - { - // Garrisoned turrets (unable to move) go IDLE. - this.SetNextState("IDLE"); - return ACCEPT_ORDER; - } - if (this.isGarrisoned) { - this.SetNextState("INDIVIDUAL.GARRISON.GARRISONED"); + this.SetNextState("INDIVIDUAL.GARRISON.GARRISONING"); return ACCEPT_ORDER; } + if (!this.AbleToMove()) + return this.FinishOrder(); + // Also pack when we are in range. if (this.CanPack()) { @@ -603,7 +599,7 @@ } if (this.CheckGarrisonRange(msg.data.target)) - this.SetNextState("INDIVIDUAL.GARRISON.GARRISONED"); + this.SetNextState("INDIVIDUAL.GARRISON.GARRISONING"); else this.SetNextState("INDIVIDUAL.GARRISON.APPROACHING"); return ACCEPT_ORDER; @@ -3236,7 +3232,7 @@ return; if (this.CheckGarrisonRange(this.order.data.target)) - this.SetNextState("GARRISONED"); + this.SetNextState("GARRISONING"); else { // Unable to reach the target, try again (or follow if it is a moving target) @@ -3251,7 +3247,7 @@ }, }, - "GARRISONED": { + "GARRISONING": { "enter": function() { let target = this.order.data.target; let cmpGarrisonable = Engine.QueryInterface(this.entity, IID_Garrisonable); @@ -3280,13 +3276,8 @@ this.SetDefaultAnimationVariant(); } - if (this.IsTurret()) - { - this.SetNextState("IDLE"); - return true; - } - - return false; + this.FinishOrder(); + return true; }, "leave": function() { @@ -3627,7 +3618,7 @@ { // Switch to a virgin state to let states execute their leave handlers. // Except if garrisoned or (un)packing, in which case we only clear the order queue. - if (this.isGarrisoned || this.IsPacking()) + if (this.IsPacking()) { this.orderQueue.length = Math.min(this.orderQueue.length, 1); Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); @@ -3874,7 +3865,7 @@ this.order = this.orderQueue[0]; let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); - if (this.orderQueue.length && (this.isGarrisoned || this.IsFormationController() || + if (this.orderQueue.length && (this.IsFormationController() || cmpPosition && cmpPosition.IsInWorld())) { let ret = this.UnitFsm.ProcessMessage(this, @@ -4049,8 +4040,6 @@ this.UpdateWorkOrders(type); } - let garrisonHolder = this.isGarrisoned && type != "Ungarrison" ? this.GetGarrisonHolder() : null; - // Do not replace packing/unpacking unless it is cancel order. // TODO: maybe a better way of doing this would be to use priority levels if (this.IsPacking() && type != "CancelPack" && type != "CancelUnpack" && type != "Stop") @@ -4094,9 +4083,6 @@ this.PushOrder(type, data); } - if (garrisonHolder) - this.PushOrder("Garrison", { "target": garrisonHolder }); - Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() }); }; @@ -5599,14 +5585,6 @@ }; /** - * Adds a garrison order for units that are already garrisoned in the garrison holder. - */ -UnitAI.prototype.Autogarrison = function(target) -{ - this.PushOrderFront("Garrison", { "target": target }); -}; - -/** * Adds gather order to the queue, forced by the player * until the target is reached */ Index: binaries/data/mods/public/simulation/helpers/Transform.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Transform.js +++ binaries/data/mods/public/simulation/helpers/Transform.js @@ -258,7 +258,7 @@ let cmpGarrisonable = Engine.QueryInterface(ent, IID_Garrisonable); if (!cmpGarrisonable) continue; - cmpGarrisonable.Autogarrison(newEnt); + cmpGarrisonable.Garrison(newEnt); } }