Index: binaries/data/config/default.cfg =================================================================== --- binaries/data/config/default.cfg +++ binaries/data/config/default.cfg @@ -283,6 +283,7 @@ patrol = "P" ; Modifier to patrol a unit repair = "J" ; Modifier to repair when clicking on building/mechanical unit queue = Shift ; Modifier to queue unit orders instead of replacing +meta = Alt ; Modifier to order only one entity in selection. batchtrain = Shift ; Modifier to train units in batches massbarter = Shift ; Modifier to barter bunch of resources masstribute = Shift ; Modifier to tribute bunch of resources Index: binaries/data/mods/public/gui/session/input.js =================================================================== --- binaries/data/mods/public/gui/session/input.js +++ binaries/data/mods/public/gui/session/input.js @@ -185,10 +185,9 @@ return undefined; } -function getActionInfo(action, target) +function getActionInfo(action, target, selection) { var simState = GetSimState(); - var selection = g_Selection.toList(); // If the selection doesn't exist, no action var entState = GetEntityState(selection[0]); @@ -1139,15 +1138,38 @@ if (!controlsPlayer(g_ViewedPlayer)) return false; - var selection = g_Selection.toList(); - // If shift is down, add the order to the unit's order queue instead // of running it immediately + var meta = Engine.HotkeyIsPressed("session.meta"); var queued = Engine.HotkeyIsPressed("session.queue"); var target = Engine.GetTerrainAtScreenPoint(ev.x, ev.y); if (unitActions[action.type] && unitActions[action.type].execute) + { + let selection = g_Selection.toList(); + if (meta) + { + // pick the first unit that can do this order. + let i = 0; + for (; i < selection.length;) + { + let actionTarget = action.target; + if (unitActions[action.type].preSelectedActionCheck && unitActions[action.type].preSelectedActionCheck(actionTarget, [selection[i]])) + break; + else if (unitActions[action.type].hotkeyActionCheck && unitActions[action.type].hotkeyActionCheck(actionTarget, [selection[i]])) + break; + else if (unitActions[action.type].actionCheck && unitActions[action.type].actionCheck(actionTarget, [selection[i]])) + break; + i++; + } + if (i != selection.length) + { + selection = [selection[i]]; + g_Selection.removeList(selection); + } + } return unitActions[action.type].execute(target, action, selection, queued); + } error("Invalid action.type " + action.type); return false; Index: binaries/data/mods/public/gui/session/unit_actions.js =================================================================== --- binaries/data/mods/public/gui/session/unit_actions.js +++ binaries/data/mods/public/gui/session/unit_actions.js @@ -58,7 +58,7 @@ }, "actionCheck": function(target, selection) { - if (!someUnitAI(selection) || !getActionInfo("move", target).possible) + if (!someUnitAI(selection) || !getActionInfo("move", target, selection).possible) return false; return { "type": "move" }; @@ -100,7 +100,7 @@ { if (!someUnitAI(selection) || !Engine.HotkeyIsPressed("session.attackmove") || - !getActionInfo("attack-move", target).possible) + !getActionInfo("attack-move", target, selection).possible) return false; return { @@ -142,9 +142,9 @@ }) }; }, - "actionCheck": function(target) + "actionCheck": function(target, selection) { - if (!getActionInfo("capture", target).possible) + if (!getActionInfo("capture", target, selection).possible) return false; return { @@ -187,10 +187,10 @@ }) }; }, - "hotkeyActionCheck": function(target) + "hotkeyActionCheck": function(target, selection) { if (!Engine.HotkeyIsPressed("session.attack") || - !getActionInfo("attack", target).possible) + !getActionInfo("attack", target, selection).possible) return false; return { @@ -199,9 +199,9 @@ "target": target }; }, - "actionCheck": function(target) + "actionCheck": function(target, selection) { - if (!getActionInfo("attack", target).possible) + if (!getActionInfo("attack", target, selection).possible) return false; return { @@ -238,7 +238,7 @@ { if (!someUnitAI(selection) || !Engine.HotkeyIsPressed("session.patrol") || - !getActionInfo("patrol", target).possible) + !getActionInfo("patrol", target, selection).possible) return false; return { "type": "patrol", @@ -246,9 +246,9 @@ "target": target }; }, - "preSelectedActionCheck" : function(target) + "preSelectedActionCheck" : function(target, selection) { - if (preSelectedAction != ACTION_PATROL || !getActionInfo("patrol", target).possible) + if (preSelectedAction != ACTION_PATROL || !getActionInfo("patrol", target, selection).possible) return false; return { "type": "patrol", @@ -295,9 +295,9 @@ return { "possible": true }; }, - "actionCheck": function(target) + "actionCheck": function(target, selection) { - if (!getActionInfo("heal", target).possible) + if (!getActionInfo("heal", target, selection).possible) return false; return { @@ -336,9 +336,9 @@ return { "possible": true }; }, - "actionCheck": function(target) + "actionCheck": function(target, selection) { - if (!getActionInfo("build", target).possible) + if (!getActionInfo("build", target, selection).possible) return false; return { @@ -378,12 +378,12 @@ return { "possible": true }; }, - "preSelectedActionCheck" : function(target) + "preSelectedActionCheck" : function(target, selection) { if (preSelectedAction != ACTION_REPAIR) return false; - if (getActionInfo("repair", target).possible) + if (getActionInfo("repair", target, selection).possible) return { "type": "repair", "cursor": "action-repair", @@ -396,10 +396,10 @@ "target": null }; }, - "hotkeyActionCheck": function(target) + "hotkeyActionCheck": function(target, selection) { if (!Engine.HotkeyIsPressed("session.repair") || - !getActionInfo("repair", target).possible) + !getActionInfo("repair", target, selection).possible) return false; return { @@ -408,9 +408,9 @@ "target": target }; }, - "actionCheck": function(target) + "actionCheck": function(target, selection) { - if (!getActionInfo("repair", target).possible) + if (!getActionInfo("repair", target, selection).possible) return false; return { @@ -454,9 +454,9 @@ "cursor": "action-gather-" + resource }; }, - "actionCheck": function(target) + "actionCheck": function(target, selection) { - let actionInfo = getActionInfo("gather", target); + let actionInfo = getActionInfo("gather", target, selection); if (!actionInfo.possible) return false; @@ -514,9 +514,9 @@ "cursor": "action-return-" + carriedType }; }, - "actionCheck": function(target) + "actionCheck": function(target, selection) { - let actionInfo = getActionInfo("returnresource", target); + let actionInfo = getActionInfo("returnresource", target, selection); if (!actionInfo.possible) return false; @@ -606,9 +606,9 @@ "tooltip": tooltip }; }, - "actionCheck": function(target) + "actionCheck": function(target, selection) { - let actionInfo = getActionInfo("setup-trade-route", target); + let actionInfo = getActionInfo("setup-trade-route", target, selection); if (!actionInfo.possible) return false; @@ -667,12 +667,12 @@ "tooltip": tooltip }; }, - "preSelectedActionCheck": function(target) + "preSelectedActionCheck": function(target, selection) { if (preSelectedAction != ACTION_GARRISON) return false; - let actionInfo = getActionInfo("garrison", target); + let actionInfo = getActionInfo("garrison", target, selection); if (!actionInfo.possible) return { "type": "none", @@ -687,9 +687,9 @@ "target": target }; }, - "hotkeyActionCheck": function(target) + "hotkeyActionCheck": function(target, selection) { - let actionInfo = getActionInfo("garrison", target); + let actionInfo = getActionInfo("garrison", target, selection); if (!Engine.HotkeyIsPressed("session.garrison") || !actionInfo.possible) return false; @@ -732,12 +732,12 @@ return { "possible": true }; }, - "preSelectedActionCheck" : function(target) + "preSelectedActionCheck" : function(target, selection) { if (preSelectedAction != ACTION_GUARD) return false; - if (getActionInfo("guard", target).possible) + if (getActionInfo("guard", target, selection).possible) return { "type": "guard", "cursor": "action-guard", @@ -750,10 +750,10 @@ "target": null }; }, - "hotkeyActionCheck": function(target) + "hotkeyActionCheck": function(target, selection) { if (!Engine.HotkeyIsPressed("session.guard") || - !getActionInfo("guard", target).possible) + !getActionInfo("guard", target, selection).possible) return false; return { @@ -786,7 +786,7 @@ "hotkeyActionCheck": function(target, selection) { if (!Engine.HotkeyIsPressed("session.guard") || - !getActionInfo("remove-guard", target).possible || + !getActionInfo("remove-guard", target, selection).possible || !someGuarding(selection)) return false; @@ -961,7 +961,7 @@ if (someUnitAI(selection) || !someRallyPoints(selection)) return false; - let actionInfo = getActionInfo("set-rallypoint", target); + let actionInfo = getActionInfo("set-rallypoint", target, selection); if (!actionInfo.possible) return false; @@ -1003,7 +1003,7 @@ "actionCheck": function(target, selection) { if (someUnitAI(selection) || !someRallyPoints(selection) || - !getActionInfo("unset-rallypoint", target).possible) + !getActionInfo("unset-rallypoint", target, selection).possible) return false; return {