Index: binaries/data/mods/public/gui/session/unit_commands.js =================================================================== --- binaries/data/mods/public/gui/session/unit_commands.js +++ binaries/data/mods/public/gui/session/unit_commands.js @@ -135,7 +135,10 @@ let playerStates = GetSimState().players; let playerState = playerStates[Engine.GetPlayerID()]; - if (g_IsObserver || entStates.every(entState => controlsPlayer(entState.player))) + // Always show selection. + setupUnitPanel("Selection", entStates, playerStates[entStates[0].player]); + + if (g_IsObserver || entStates.every(entState => controlsPlayer(entState.player) && (!entState.unitAI || entState.unitAI.isControllable))) { for (let guiName of g_PanelsOrder) { 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 @@ -351,6 +351,7 @@ "canPatrol": cmpUnitAI.CanPatrol(), "selectableStances": cmpUnitAI.GetSelectableStances(), "isIdle": cmpUnitAI.IsIdle(), + "isControllable": cmpUnitAI.IsControllable(), }; let cmpGuard = Engine.QueryInterface(ent, IID_Guard); 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 @@ -24,6 +24,9 @@ "" + "" + "" + + "" + + "" + + "" + "" + "" + "" + @@ -187,8 +190,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.FinishOrder(); return; @@ -234,13 +237,6 @@ // (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()) - { - this.FinishOrder(); - return; - } - // Stop moving immediately. this.StopMoving(); this.FinishOrder(); @@ -254,8 +250,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.FinishOrder(); return; @@ -280,8 +276,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.FinishOrder(); return; @@ -307,8 +303,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.FinishOrder(); return; @@ -455,7 +451,7 @@ }, "Order.Patrol": function(msg) { - if (this.IsAnimal() || this.IsTurret()) + if (this.IsTurret()) { this.FinishOrder(); return; @@ -3232,6 +3228,7 @@ this.isGarrisoned = false; this.isIdle = false; this.finishedOrder = false; // used to find if all formation members finished the order + this.isControllable = this.template.Controllable == "true"; this.heldPosition = undefined; @@ -3340,6 +3337,20 @@ return (state == "WALKING"); }; +UnitAI.prototype.IsControllable = function() +{ + return this.isControllable; +}; + +/** + * Set whether the entity is controllable. + * @param {boolean} bool - Q.e.d. + */ +UnitAI.prototype.SetControllable = function(bool) +{ + this.isControllable = bool; +}; + /** * Return true if the current order is WalkAndFight or Patrol. */ Index: binaries/data/mods/public/simulation/helpers/Commands.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Commands.js +++ binaries/data/mods/public/simulation/helpers/Commands.js @@ -877,6 +877,21 @@ } /** + * Sends a GUI notification about entities that can't be controlled. + * @param {number} player - The player-ID of the player that needs to receive this message. + */ +function notifyOrderFailure(player) +{ + let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); + cmpGUIInterface.PushNotification({ + "type": "text", + "players": [player], + "message": markForTranslation("Some unit(s) can't be controlled."), + "translateMessage": true + }); +} + +/** * Get some information about the formations used by entities. * The entities must have a UnitAI component. */ @@ -1660,12 +1675,20 @@ /** * Check if player can control this entity - * returns: true if the entity is valid and owned by the player - * or control all units is activated, else false + * @param {number} entity - The ID of the entity. + * @param {number} player - The ID of the player. + * @param {boolean} controlAll - Whether the controlAll-cheat is enabled. + * @return {boolean} - Whether the entity can be controlled. */ function CanControlUnit(entity, player, controlAll) { - return IsOwnedByPlayer(player, entity) || controlAll; + let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); + let CanBeControlled = IsOwnedByPlayer(player, entity) && + cmpUnitAI && cmpUnitAI.IsControllable() || !cmpUnitAI || + controlAll; + if (!CanBeControlled) + notifyOrderFailure(player); + return CanBeControlled; } /** Index: binaries/data/mods/public/simulation/templates/template_bird.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_bird.xml +++ binaries/data/mods/public/simulation/templates/template_bird.xml @@ -26,6 +26,7 @@ false false false + false 1000.0 10.0 10000 Index: binaries/data/mods/public/simulation/templates/template_formation.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_formation.xml +++ binaries/data/mods/public/simulation/templates/template_formation.xml @@ -64,6 +64,7 @@ 12.0 true true + true true Index: binaries/data/mods/public/simulation/templates/template_unit.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit.xml +++ binaries/data/mods/public/simulation/templates/template_unit.xml @@ -119,6 +119,7 @@ false true true + true false