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 @@ -23,6 +23,10 @@ if (this.holder) return false; + let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); + if (cmpUnitAI) + cmpUnitAI.SetGarrisoned(true); + this.holder = entity; return true; }; @@ -32,6 +36,10 @@ */ Garrisonable.prototype.UnGarrison = function() { + let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); + if (cmpUnitAI) + cmpUnitAI.SetGarrisoned(false); + delete this.holder; }; 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 @@ -626,7 +626,7 @@ this.SetNextState("IDLE"); return; } - else if (this.IsGarrisoned()) + else if (this.isGarrisoned) { if (this.IsAnimal()) this.SetNextState("ANIMAL.GARRISON.GARRISONED"); @@ -649,7 +649,7 @@ "Order.Ungarrison": function() { this.FinishOrder(); - this.isGarrisoned = false; + delete this.isGarrisoned; }, "Order.Cheer": function(msg) { @@ -3102,8 +3102,16 @@ return true; } - if (this.IsGarrisoned()) + // Called when autogarrisoning. + if (this.isGarrisoned) + { + if (this.IsTurret()) + { + this.SetNextState("IDLE"); + return true; + } return false; + } if (this.CanGarrison(target)) if (this.CheckGarrisonRange(target)) @@ -3111,7 +3119,6 @@ var cmpGarrisonHolder = Engine.QueryInterface(target, IID_GarrisonHolder); if (cmpGarrisonHolder.Garrison(this.entity)) { - this.isGarrisoned = true; this.SetImmobile(true); if (this.formationController) @@ -3448,7 +3455,6 @@ this.orderQueue = []; // current order is at the front of the list this.order = undefined; // always == this.orderQueue[0] this.formationController = INVALID_ENTITY; // entity with IID_Formation that we belong to - this.isGarrisoned = false; this.isIdle = false; this.isImmobile = false; // True if the unit is currently unable to move (garrisoned,...) @@ -3505,14 +3511,22 @@ return this.isIdle; }; +/** + * Whether the entity is garrisoned (according to UnitAI). + * This is only called from outside UnitAI for performance reasons, + * if in the future it should return anything else than just the member, + * all calls to this.isGarrisoned here in UnitAI ought to be updated. + * + * @return {boolean} Whether the entity is garrisoned. + */ UnitAI.prototype.IsGarrisoned = function() { - return this.isGarrisoned; + return !!this.isGarrisoned; }; -UnitAI.prototype.SetGarrisoned = function() +UnitAI.prototype.SetGarrisoned = function(garrisoned) { - this.isGarrisoned = true; + this.isGarrisoned = garrisoned; }; UnitAI.prototype.GetGarrisonHolder = function() @@ -3845,7 +3859,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.isGarrisoned || this.IsFormationController() || cmpPosition && cmpPosition.IsInWorld())) { let ret = this.UnitFsm.ProcessMessage(this, @@ -4040,7 +4054,7 @@ this.UpdateWorkOrders(type); } - let garrisonHolder = this.IsGarrisoned() && type != "Ungarrison" ? this.GetGarrisonHolder() : null; + 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 @@ -4141,7 +4155,7 @@ if (this.workOrders.length == 0) return false; - if (this.IsGarrisoned()) + if (this.isGarrisoned) { let cmpGarrisonHolder = Engine.QueryInterface(this.GetGarrisonHolder(), IID_GarrisonHolder); if (!cmpGarrisonHolder || !cmpGarrisonHolder.PerformEject([this.entity], false)) @@ -5287,7 +5301,7 @@ { // May happen if an order arrives on the same turn the unit is garrisoned // in that case, just forget the order as this will lead to an infinite loop - if (this.IsGarrisoned() && !this.IsTurret() && type != "Ungarrison") + if (this.isGarrisoned && !this.IsTurret() && type != "Ungarrison") return; this.ReplaceOrder(type, data); } @@ -5522,7 +5536,7 @@ */ UnitAI.prototype.Ungarrison = function() { - if (this.IsGarrisoned()) + if (this.isGarrisoned) { this.SetImmobile(false); this.AddOrder("Ungarrison", null, false); @@ -5534,7 +5548,6 @@ */ UnitAI.prototype.Autogarrison = function(target) { - this.isGarrisoned = true; this.PushOrderFront("Garrison", { "target": target }); }; Index: binaries/data/mods/public/simulation/components/tests/test_Garrisonable.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_Garrisonable.js +++ binaries/data/mods/public/simulation/components/tests/test_Garrisonable.js @@ -1,4 +1,5 @@ Engine.LoadComponentScript("interfaces/Garrisonable.js"); +Engine.LoadComponentScript("interfaces/UnitAI.js"); Engine.LoadComponentScript("Garrisonable.js"); const garrisonHolderID = 1; 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 @@ -78,8 +78,6 @@ cmpNewUnitAI.SetGuardOf(guarded); } } - if (cmpUnitAI.IsGarrisoned()) - cmpNewUnitAI.SetGarrisoned(); } let cmpPromotion = Engine.QueryInterface(oldEnt, IID_Promotion);