1
0
forked from mirrors/0ad

Handle 'orderone' hotkey for constructing buildings and walls

This was missing in 62f07098ea.

Based on a patch by: luiko
Also reported by: serveurix
Tested by: Freagarach
Fixes #5750

Differential Revision: https://code.wildfiregames.com/D2172
This was SVN commit r23830.
This commit is contained in:
wraitii
2020-07-14 08:04:48 +00:00
parent 2eecb0f508
commit 4bed678194
3 changed files with 51 additions and 25 deletions
+29 -25
View File
@@ -299,7 +299,8 @@ function tryPlaceBuilding(queued)
return false;
}
var selection = g_Selection.toList();
let selection = Engine.HotkeyIsPressed("session.orderone") &&
popOneFromSelection({ "type": "construct", "target": placementSupport }) || g_Selection.toList();
Engine.PostNetworkCommand({
"type": "construct",
@@ -315,7 +316,7 @@ function tryPlaceBuilding(queued)
});
Engine.GuiInterfaceCall("PlaySound", { "name": "order_build", "entity": selection[0] });
if (!queued)
if (!queued || !g_Selection.toList().length)
placementSupport.Reset();
else
placementSupport.RandomizeActorSeed();
@@ -331,8 +332,8 @@ function tryPlaceWall(queued)
return false;
}
var wallPlacementInfo = updateBuildingPlacementPreview(); // entities making up the wall (wall segments, towers, ...)
if (!(wallPlacementInfo === false || typeof(wallPlacementInfo) === "object"))
let wallPlacementInfo = updateBuildingPlacementPreview(); // entities making up the wall (wall segments, towers, ...)
if (!(wallPlacementInfo === false || typeof wallPlacementInfo === "object"))
{
error("Invalid updateBuildingPlacementPreview return value: " + uneval(wallPlacementInfo));
return false;
@@ -341,8 +342,10 @@ function tryPlaceWall(queued)
if (!wallPlacementInfo)
return false;
var selection = g_Selection.toList();
var cmd = {
let selection = Engine.HotkeyIsPressed("session.orderone") &&
popOneFromSelection({ "type": "construct", "target": placementSupport }) || g_Selection.toList();
let cmd = {
"type": "construct-wall",
"autorepair": true,
"autocontinue": true,
@@ -357,7 +360,7 @@ function tryPlaceWall(queued)
// make sure that there's at least one non-tower entity getting built, to prevent silly edge cases where the start and end
// point are too close together for the algorithm to place a wall segment inbetween, and only the towers are being previewed
// (this is somewhat non-ideal and hardcode-ish)
var hasWallSegment = false;
let hasWallSegment = false;
for (let piece of cmd.pieces)
{
if (piece.template != cmd.wallSet.templates.tower) // TODO: hardcode-ish :(
@@ -584,7 +587,7 @@ function handleInputBeforeGui(ev, hoveredObject)
var queued = Engine.HotkeyIsPressed("session.queue");
if (tryPlaceBuilding(queued))
{
if (queued)
if (queued && g_Selection.toList().length)
inputState = INPUT_BUILDING_PLACEMENT;
else
inputState = INPUT_NORMAL;
@@ -750,7 +753,7 @@ function handleInputBeforeGui(ev, hoveredObject)
var queued = Engine.HotkeyIsPressed("session.queue");
if (tryPlaceBuilding(queued))
{
if (queued)
if (queued && g_Selection.toList().length)
inputState = INPUT_BUILDING_PLACEMENT;
else
inputState = INPUT_NORMAL;
@@ -1144,6 +1147,21 @@ function doAction(action, ev)
return handleUnitAction(Engine.GetTerrainAtScreenPoint(ev.x, ev.y), action);
}
function popOneFromSelection(action)
{
// Pick the first unit that can do this order.
let unit = g_Selection.find(entity =>
["preSelectedActionCheck", "hotkeyActionCheck", "actionCheck"].some(method =>
g_UnitActions[action.type][method] &&
g_UnitActions[action.type][method](action.target || undefined, [entity])
));
if (unit)
{
g_Selection.removeList([unit]);
return [unit];
}
return null;
}
function positionUnitsFreehandSelectionMouseMove(ev)
{
@@ -1236,22 +1254,8 @@ function handleUnitAction(target, action)
return false;
}
let selection = g_Selection.toList();
if (Engine.HotkeyIsPressed("session.orderone"))
{
// Pick the first unit that can do this order.
let unit = selection.find(entity =>
["preSelectedActionCheck", "hotkeyActionCheck", "actionCheck"].some(method =>
g_UnitActions[action.type][method] &&
g_UnitActions[action.type][method](action.target || undefined, [entity])
));
if (unit)
{
selection = [unit];
g_Selection.removeList(selection);
}
}
let selection = Engine.HotkeyIsPressed("session.orderone") &&
popOneFromSelection(action) || g_Selection.toList();
// If the session.queue hotkey is down, add the order to the unit's order queue instead
// of running it immediately
return g_UnitActions[action.type].execute(target, action, selection, Engine.HotkeyIsPressed("session.queue"));
@@ -390,6 +390,14 @@ EntitySelection.prototype.toList = function()
return ents;
};
EntitySelection.prototype.find = function(condition)
{
for (let ent in this.selected)
if (condition(ent))
return +ent;
return null;
};
EntitySelection.prototype.setHighlightList = function(ents)
{
var highlighted = {};
@@ -340,6 +340,20 @@ var g_UnitActions =
"specificness": 7,
},
// "Fake" action to check if an entity can be ordered to "construct"
// which is handled differently from repair as the target does not exist.
"construct":
{
"preSelectedActionCheck": function(target, selection)
{
let state = GetEntityState(selection[0]);
if (state && state.builder && target.constructor.name == "PlacementSupport")
return { "type": "construct" };
return false;
},
"specificness": 0,
},
"repair":
{
"execute": function(target, action, selection, queued)