diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 0f3a3a4ab2..85b2f05274 100644
--- a/binaries/data/config/default.cfg
+++ b/binaries/data/config/default.cfg
@@ -314,6 +314,7 @@ stop = "H" ; Stop the current action
backtowork = "Y" ; The unit will go back to work
unload = "U" ; Unload garrisoned units when a building/mechanical unit is selected
unloadturrets = "U" ; Unload turreted units.
+leaveturret = "U" ; Leave turret point.
move = "" ; Modifier to move to a point instead of another action (e.g. gather)
attack = Ctrl ; Modifier to attack instead of another action (e.g. capture)
attackmove = Ctrl ; Modifier to attackmove when clicking on a point
diff --git a/binaries/data/mods/public/art/textures/cursors/action-occupy-turret-disabled.png b/binaries/data/mods/public/art/textures/cursors/action-occupy-turret-disabled.png
new file mode 100644
index 0000000000..cd25ef5d0d
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/cursors/action-occupy-turret-disabled.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:598e44ccdd87d714d419cc1b2ead9e25fc71b71ab301832dd88a2e72f36dbd1d
+size 4836
diff --git a/binaries/data/mods/public/art/textures/cursors/action-occupy-turret-disabled.txt b/binaries/data/mods/public/art/textures/cursors/action-occupy-turret-disabled.txt
new file mode 100644
index 0000000000..2fb73a07ec
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/cursors/action-occupy-turret-disabled.txt
@@ -0,0 +1 @@
+1 1
diff --git a/binaries/data/mods/public/art/textures/cursors/action-occupy-turret.png b/binaries/data/mods/public/art/textures/cursors/action-occupy-turret.png
new file mode 100644
index 0000000000..f79365d2d4
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/cursors/action-occupy-turret.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1bde4196602617782c0ce1cf36b81991fe6dd913a3c1b06d52ef3f784e466470
+size 2207
diff --git a/binaries/data/mods/public/art/textures/cursors/action-occupy-turret.txt b/binaries/data/mods/public/art/textures/cursors/action-occupy-turret.txt
new file mode 100644
index 0000000000..2fb73a07ec
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/cursors/action-occupy-turret.txt
@@ -0,0 +1 @@
+1 1
diff --git a/binaries/data/mods/public/art/textures/ui/session/icons/leave-turret.png b/binaries/data/mods/public/art/textures/ui/session/icons/leave-turret.png
new file mode 100644
index 0000000000..c4aa2996dd
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/ui/session/icons/leave-turret.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ad14ec13318de15761ce9aaccc7e3fd8857699c9e75567f674753d8a3dd04b95
+size 9520
diff --git a/binaries/data/mods/public/art/textures/ui/session/icons/occupy-turret.png b/binaries/data/mods/public/art/textures/ui/session/icons/occupy-turret.png
new file mode 100644
index 0000000000..028e0d598d
--- /dev/null
+++ b/binaries/data/mods/public/art/textures/ui/session/icons/occupy-turret.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d2843ad9bbccf741f072c7bad74280899ea5e8ad3cd9db145757271cf89e191b
+size 9576
diff --git a/binaries/data/mods/public/gui/hotkeys/spec/ingame.json b/binaries/data/mods/public/gui/hotkeys/spec/ingame.json
index 2eb149b1a6..a2ba8dad4a 100644
--- a/binaries/data/mods/public/gui/hotkeys/spec/ingame.json
+++ b/binaries/data/mods/public/gui/hotkeys/spec/ingame.json
@@ -31,6 +31,10 @@
"name": "Unload Turrets",
"desc": "Unload turreted units."
},
+ "session.leaveturret": {
+ "name": "Leave Turret Point",
+ "desc": "Order an entity to leave a turret point."
+ },
"session.unloadtype": {
"name": "Unload unit type",
"desc": "Modifier to unload all units of type."
diff --git a/binaries/data/mods/public/gui/session/hotkeys/misc.xml b/binaries/data/mods/public/gui/session/hotkeys/misc.xml
index baf90329bf..6687a1fe4a 100644
--- a/binaries/data/mods/public/gui/session/hotkeys/misc.xml
+++ b/binaries/data/mods/public/gui/session/hotkeys/misc.xml
@@ -36,6 +36,10 @@
unloadAllTurrets();
+
+
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 8682fdbb7b..0b11d31797 100644
--- a/binaries/data/mods/public/gui/session/input.js
+++ b/binaries/data/mods/public/gui/session/input.js
@@ -17,6 +17,7 @@ const ACTION_GARRISON = 1;
const ACTION_REPAIR = 2;
const ACTION_GUARD = 3;
const ACTION_PATROL = 4;
+const ACTION_OCCUPY_TURRET = 5;
var preSelectedAction = ACTION_NONE;
const INPUT_NORMAL = 0;
diff --git a/binaries/data/mods/public/gui/session/selection_panels_helpers.js b/binaries/data/mods/public/gui/session/selection_panels_helpers.js
index a82541ddca..9e983a2683 100644
--- a/binaries/data/mods/public/gui/session/selection_panels_helpers.js
+++ b/binaries/data/mods/public/gui/session/selection_panels_helpers.js
@@ -487,6 +487,20 @@ function unloadAllTurrets()
});
}
+function leaveTurretPoints()
+{
+ let entities = g_Selection.toList().filter(entity => {
+ let entState = GetEntityState(entity);
+ return entState && entState.turretable &&
+ entState.turretable.holder != INVALID_ENTITY;
+ });
+
+ Engine.PostNetworkCommand({
+ "type": "leave-turret",
+ "entities": entities
+ });
+}
+
function backToWork()
{
Engine.PostNetworkCommand({
diff --git a/binaries/data/mods/public/gui/session/unit_actions.js b/binaries/data/mods/public/gui/session/unit_actions.js
index 4ae494cbb1..e4a9e22df6 100644
--- a/binaries/data/mods/public/gui/session/unit_actions.js
+++ b/binaries/data/mods/public/gui/session/unit_actions.js
@@ -730,10 +730,9 @@ var g_UnitActions =
},
"preSelectedActionCheck": function(target, selection)
{
- return preSelectedAction == ACTION_GARRISON &&
- (this.actionCheck(target, selection) || {
+ return preSelectedAction == ACTION_OCCUPY_TURRET && (this.actionCheck(target, selection) || {
"type": "none",
- "cursor": "action-garrison-disabled",
+ "cursor": "action-occupy-turret-disabled",
"target": null
});
},
@@ -747,9 +746,10 @@ var g_UnitActions =
let actionInfo = getActionInfo("occupy-turret", target, selection);
return actionInfo.possible && {
"type": "occupy-turret",
- "cursor": "action-garrison",
+ "cursor": "action-occupy-turret",
"tooltip": actionInfo.tooltip,
- "target": target
+ "target": target,
+ "firstAbleEntity": actionInfo.entity
};
},
"specificness": 21,
@@ -1421,7 +1421,8 @@ var g_EntityCommands =
"garrison": {
"getInfo": function(entStates)
{
- if (entStates.every(entState => !entState.unitAI || entState.turretParent || false))
+ if (entStates.every(entState => !entState.garrisonable ||
+ entState.garrisonable.holder != INVALID_ENTITY))
return false;
return {
@@ -1439,6 +1440,28 @@ var g_EntityCommands =
"allowedPlayers": ["Player"]
},
+ "occupy-turret": {
+ "getInfo": function(entStates)
+ {
+ if (entStates.every(entState => !entState.turretable ||
+ entState.turretable.holder != INVALID_ENTITY))
+ return false;
+
+ return {
+ "tooltip": colorizeHotkey("%(hotkey)s" + " ", "session.occupyturret") +
+ translate("Order the selected units to occupy a turret point."),
+ "icon": "occupy-turret.png",
+ "enabled": true
+ };
+ },
+ "execute": function()
+ {
+ inputState = INPUT_PRESELECTEDACTION;
+ preSelectedAction = ACTION_OCCUPY_TURRET;
+ },
+ "allowedPlayers": ["Player"]
+ },
+
"leave-turret": {
"getInfo": function(entStates)
{
@@ -1449,21 +1472,13 @@ var g_EntityCommands =
return {
"tooltip": translate("Unload"),
- "icon": "garrison-out.png",
+ "icon": "leave-turret.png",
"enabled": true
};
},
"execute": function(entStates)
{
- if (!entStates.length)
- return;
-
- Engine.PostNetworkCommand({
- "type": "leave-turret",
- "entities": entStates.filter(entState => entState.turretable &&
- entState.turretable.holder != INVALID_ENTITY ||
- !entState.turretable.ejectable).map(entState => entState.id)
- });
+ leaveTurretPoints();
},
"allowedPlayers": ["Player"]
},
diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js
index ec732c22ce..ae929ed609 100644
--- a/binaries/data/mods/public/simulation/components/UnitAI.js
+++ b/binaries/data/mods/public/simulation/components/UnitAI.js
@@ -5425,6 +5425,9 @@ UnitAI.prototype.Attack = function(target, allowCapture = true, queued = false,
*/
UnitAI.prototype.Garrison = function(target, queued, pushFront)
{
+ // Not allowed to garrison when occupying a turret, at the moment.
+ if (this.isGarrisoned)
+ return;
if (target == this.entity)
return;
if (!this.CanGarrison(target))