Index: binaries/data/mods/public/gui/session/selection_panels.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_panels.js
+++ binaries/data/mods/public/gui/session/selection_panels.js
@@ -921,6 +921,45 @@
}
};
+g_SelectionPanels.PrefAttack = {
+ "getMaxNumberOfItems": function()
+ {
+ return 4;
+ },
+ "getItems": function(entStates)
+ {
+ if (entStates.some(state => !state.attack))
+ return [];
+
+ let items = ["Default"];
+ for (let entState of entStates)
+ items = items.concat(Object.keys(entState.attack).filter(
+ type => items.indexOf(type) == -1
+ ));
+
+ // No point in showing only "Default" and one extra attack type.
+ return items.length > 2 ? items : "";
+ },
+ "setupButton": function(data)
+ {
+ let entIds = data.unitEntStates.map(state => state.id);
+ data.button.onPress = function() { performPrefAttack(entIds, data.item); };
+
+ data.button.tooltip = getPrefAttackDisplayName(data.item) + "\n" +
+ "[font=\"sans-13\"]" + getPrefAttackTooltip(data.item) + "[/font]";
+
+ data.guiSelection.hidden = !Engine.GuiInterfaceCall("IsPrefAttackSelected", {
+ "ents": entIds,
+ "prefAttack": data.item
+ });
+ data.icon.sprite = "stretched:session/icons/attacks/" + data.item.toLowerCase() + ".png";
+ data.button.enabled = controlsPlayer(data.player);
+
+ setPanelObjectPosition(data.button, data.i, data.rowLength);
+ return true;
+ }
+};
+
g_SelectionPanels.Training = {
"getMaxNumberOfItems": function()
{
@@ -1162,7 +1201,8 @@
"Garrison", // More important than Formation, as you want to see the garrisoned units in ships
"Alert",
"Formation",
- "Stance", // Normal together with formation
+ "PrefAttack", // Normal together with formation and stance.
+ "Stance", // Normal together with formation and preferred attack.
// RIGHT PANE
"Gate", // Must always be shown on gates
Index: binaries/data/mods/public/gui/session/selection_panels_helpers.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_panels_helpers.js
+++ binaries/data/mods/public/gui/session/selection_panels_helpers.js
@@ -87,6 +87,41 @@
}
}
+function getPrefAttackDisplayName(name)
+{
+ switch (name)
+ {
+ case "Default":
+ return translateWithContext("attack type", "Default");
+ case "Capture":
+ return translateWithContext("attack type", "Capture");
+ case "Ranged":
+ return translateWithContext("attack type", "Ranged");
+ case "Melee":
+ return translateWithContext("attack type", "Melee");
+ default:
+ warn("Internationalization: Unexpected attack type found: " + name);
+ return name;
+ }
+}
+
+function getPrefAttackTooltip(name)
+{
+ switch (name)
+ {
+ case "Default":
+ return translateWithContext("attack type", "Let the unit decide.");
+ case "Capture":
+ return translateWithContext("attack type", "Prefer Capture attack.");
+ case "Ranged":
+ return translateWithContext("attack type", "Prefer Ranged attack.");
+ case "Melee":
+ return translateWithContext("attack type", "Prefer Melee attack.");
+ default:
+ return "";
+ }
+}
+
/**
* Format entity count/limit message for the tooltip
*/
@@ -290,6 +325,18 @@
});
}
+function performPrefAttack(entities, prefAttackType)
+{
+ if (!entities)
+ return;
+
+ Engine.PostNetworkCommand({
+ "type": "prefAttackType",
+ "entities": entities,
+ "name": prefAttackType
+ });
+}
+
function lockGate(lock)
{
Engine.PostNetworkCommand({
Index: binaries/data/mods/public/gui/session/selection_panels_left/attack_panel.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/gui/session/selection_panels_left/attack_panel.xml
@@ -0,0 +1,16 @@
+
+
+
Index: binaries/data/mods/public/gui/session/session.xml
===================================================================
--- binaries/data/mods/public/gui/session/session.xml
+++ binaries/data/mods/public/gui/session/session.xml
@@ -120,7 +120,7 @@