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 @@ -187,8 +187,8 @@ // Called when being told to walk as part of a formation "Order.FormationWalk": function(msg) { - // Let players move captured domestic animals around - if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret()) + // Turrets can't move around. + if (this.IsTurret() || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -234,8 +234,7 @@ // (these will switch the unit out of formation mode) "Order.Stop": function(msg) { - // We have no control over non-domestic animals. - if (this.IsAnimal() && !this.IsDomestic()) + if (this.IsUncontrollable) { this.FinishOrder(); return; @@ -254,8 +253,8 @@ }, "Order.Walk": function(msg) { - // Let players move captured domestic animals around - if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret()) + // Turrets can't walk. + if (this.IsTurret() || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -278,8 +277,8 @@ }, "Order.WalkAndFight": function(msg) { - // Let players move captured domestic animals around - if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret()) + // Turrets can't move. + if (this.IsTurret() || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -303,8 +302,8 @@ "Order.WalkToTarget": function(msg) { - // Let players move captured domestic animals around - if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret()) + // Turrets can't move. + if (this.IsTurret() || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -335,7 +334,7 @@ "Order.PickupUnit": function(msg) { var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); - if (!cmpGarrisonHolder || cmpGarrisonHolder.IsFull()) + if (!cmpGarrisonHolder || cmpGarrisonHolder.IsFull() || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -365,7 +364,7 @@ }, "Order.Guard": function(msg) { - if (!this.AddGuard(this.order.data.target)) + if (!this.AddGuard(this.order.data.target) || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -386,7 +385,7 @@ "Order.Attack": function(msg) { // Check the target is alive - if (!this.TargetIsAlive(this.order.data.target)) + if (!this.TargetIsAlive(this.order.data.target) || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -445,7 +444,7 @@ }, "Order.Patrol": function(msg) { - if (this.IsAnimal() || this.IsTurret()) + if (this.IsTurret() || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -462,7 +461,7 @@ "Order.Heal": function(msg) { // Check the target is alive - if (!this.TargetIsAlive(this.order.data.target)) + if (!this.TargetIsAlive(this.order.data.target) || this.IsUncontrollable()) { this.FinishOrder(); return; @@ -494,6 +493,12 @@ }, "Order.Gather": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + // If the target is still alive, we need to kill it first if (this.MustKillGatherTarget(this.order.data.target)) { @@ -533,10 +538,22 @@ }, "Order.GatherNearPosition": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + this.SetNextState("INDIVIDUAL.GATHER.WALKING"); }, "Order.ReturnResource": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + // Check if the dropsite is already in range if (this.CheckTargetRange(this.order.data.target, IID_ResourceGatherer) && this.CanReturnResource(this.order.data.target, true)) { @@ -560,6 +577,12 @@ }, "Order.Trade": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + // We must check if this trader has both markets in case it was a back-to-work order var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader); if (!cmpTrader || !cmpTrader.HasBothMarkets()) @@ -574,6 +597,12 @@ }, "Order.Repair": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + // Try to move within range if (this.CheckTargetRange(this.order.data.target, IID_Builder)) this.SetNextState("INDIVIDUAL.REPAIR.REPAIRING"); @@ -582,6 +611,12 @@ }, "Order.Garrison": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + if (this.IsTurret()) { this.SetNextState("IDLE"); @@ -606,6 +641,12 @@ }, "Order.Ungarrison": function() { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + this.FinishOrder(); this.isGarrisoned = false; }, @@ -615,16 +656,34 @@ }, "Order.Pack": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + if (this.CanPack()) this.SetNextState("INDIVIDUAL.PACKING"); }, "Order.Unpack": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + if (this.CanUnpack()) this.SetNextState("INDIVIDUAL.UNPACKING"); }, "Order.CancelPack": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); if (cmpPack && cmpPack.IsPacking() && !cmpPack.IsPacked()) cmpPack.CancelPack(); @@ -632,6 +691,12 @@ }, "Order.CancelUnpack": function(msg) { + if (this.IsUncontrollable()) + { + this.FinishOrder(); + return; + } + var cmpPack = Engine.QueryInterface(this.entity, IID_Pack); if (cmpPack && cmpPack.IsPacking() && cmpPack.IsPacked()) cmpPack.CancelPack(); @@ -3165,6 +3230,12 @@ return cmpIdentity && cmpIdentity.HasClass("Domestic"); }; +UnitAI.prototype.IsUncontrollable = function() +{ + let cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); + return cmpIdentity && cmpIdentity.HasClass("Uncontrollable"); +}; + UnitAI.prototype.IsHealer = function() { return Engine.QueryInterface(this.entity, IID_Heal); 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 @@ -72,6 +72,7 @@ AddMock(unit, IID_Identity, { GetClassesList: function() { return []; }, + HasClass: function() { return false; }, }); AddMock(unit, IID_Ownership, { @@ -227,6 +228,7 @@ AddMock(unit + i, IID_Identity, { GetClassesList: function() { return []; }, + HasClass: function() { return false; }, }); AddMock(unit + i, IID_Ownership, {