Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/gui/session/input.js
Show First 20 Lines • Show All 293 Lines • ▼ Show 20 Lines | function tryPlaceBuilding(queued) | ||||
if (!updateBuildingPlacementPreview()) | if (!updateBuildingPlacementPreview()) | ||||
{ | { | ||||
// invalid location - don't build it | // invalid location - don't build it | ||||
// TODO: play a sound? | // TODO: play a sound? | ||||
return false; | return false; | ||||
} | } | ||||
var selection = g_Selection.toList(); | let selection = Engine.HotkeyIsPressed("session.orderone") && | ||||
popOneFromSelection({ "type": "construct", "target": placementSupport }) || g_Selection.toList(); | |||||
Engine.PostNetworkCommand({ | Engine.PostNetworkCommand({ | ||||
"type": "construct", | "type": "construct", | ||||
"template": placementSupport.template, | "template": placementSupport.template, | ||||
"x": placementSupport.position.x, | "x": placementSupport.position.x, | ||||
"z": placementSupport.position.z, | "z": placementSupport.position.z, | ||||
"angle": placementSupport.angle, | "angle": placementSupport.angle, | ||||
"actorSeed": placementSupport.actorSeed, | "actorSeed": placementSupport.actorSeed, | ||||
"entities": selection, | "entities": selection, | ||||
"autorepair": true, | "autorepair": true, | ||||
"autocontinue": true, | "autocontinue": true, | ||||
"queued": queued | "queued": queued | ||||
}); | }); | ||||
Engine.GuiInterfaceCall("PlaySound", { "name": "order_build", "entity": selection[0] }); | Engine.GuiInterfaceCall("PlaySound", { "name": "order_build", "entity": selection[0] }); | ||||
if (!queued) | if (!queued || !g_Selection.toList().length) | ||||
Stan: Why do we have to call tolist everywhere? Doesn't that mean the data structure is somewhat… | |||||
wraitiiAuthorUnsubmitted Done Inline ActionsIt probably is, but that's a problem for the day we refactor g_Selection (most likely making it into a JS class) wraitii: It probably is, but that's a problem for the day we refactor g_Selection (most likely making it… | |||||
placementSupport.Reset(); | placementSupport.Reset(); | ||||
else | else | ||||
placementSupport.RandomizeActorSeed(); | placementSupport.RandomizeActorSeed(); | ||||
return true; | return true; | ||||
} | } | ||||
function tryPlaceWall(queued) | function tryPlaceWall(queued) | ||||
{ | { | ||||
if (placementSupport.mode !== "wall") | if (placementSupport.mode !== "wall") | ||||
{ | { | ||||
error("tryPlaceWall expected 'wall', got '" + placementSupport.mode + "'"); | error("tryPlaceWall expected 'wall', got '" + placementSupport.mode + "'"); | ||||
return false; | return false; | ||||
} | } | ||||
var wallPlacementInfo = updateBuildingPlacementPreview(); // entities making up the wall (wall segments, towers, ...) | let wallPlacementInfo = updateBuildingPlacementPreview(); // entities making up the wall (wall segments, towers, ...) | ||||
if (!(wallPlacementInfo === false || typeof(wallPlacementInfo) === "object")) | if (!(wallPlacementInfo === false || typeof wallPlacementInfo === "object")) | ||||
{ | { | ||||
error("Invalid updateBuildingPlacementPreview return value: " + uneval(wallPlacementInfo)); | error("Invalid updateBuildingPlacementPreview return value: " + uneval(wallPlacementInfo)); | ||||
return false; | return false; | ||||
} | } | ||||
if (!wallPlacementInfo) | if (!wallPlacementInfo) | ||||
return false; | return false; | ||||
var selection = g_Selection.toList(); | let selection = Engine.HotkeyIsPressed("session.orderone") && | ||||
var cmd = { | popOneFromSelection({ "type": "construct", "target": placementSupport }) || g_Selection.toList(); | ||||
let cmd = { | |||||
"type": "construct-wall", | "type": "construct-wall", | ||||
"autorepair": true, | "autorepair": true, | ||||
"autocontinue": true, | "autocontinue": true, | ||||
"queued": queued, | "queued": queued, | ||||
"entities": selection, | "entities": selection, | ||||
"wallSet": placementSupport.wallSet, | "wallSet": placementSupport.wallSet, | ||||
"pieces": wallPlacementInfo.pieces, | "pieces": wallPlacementInfo.pieces, | ||||
"startSnappedEntity": wallPlacementInfo.startSnappedEnt, | "startSnappedEntity": wallPlacementInfo.startSnappedEnt, | ||||
"endSnappedEntity": wallPlacementInfo.endSnappedEnt, | "endSnappedEntity": wallPlacementInfo.endSnappedEnt, | ||||
}; | }; | ||||
// make sure that there's at least one non-tower entity getting built, to prevent silly edge cases where the start and end | // 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 | // 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) | // (this is somewhat non-ideal and hardcode-ish) | ||||
var hasWallSegment = false; | let hasWallSegment = false; | ||||
for (let piece of cmd.pieces) | for (let piece of cmd.pieces) | ||||
{ | { | ||||
if (piece.template != cmd.wallSet.templates.tower) // TODO: hardcode-ish :( | if (piece.template != cmd.wallSet.templates.tower) // TODO: hardcode-ish :( | ||||
{ | { | ||||
hasWallSegment = true; | hasWallSegment = true; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | case INPUT_BUILDING_CLICK: | ||||
case "mousebuttonup": | case "mousebuttonup": | ||||
if (ev.button == SDL_BUTTON_LEFT) | if (ev.button == SDL_BUTTON_LEFT) | ||||
{ | { | ||||
// If shift is down, let the player continue placing another of the same building | // If shift is down, let the player continue placing another of the same building | ||||
var queued = Engine.HotkeyIsPressed("session.queue"); | var queued = Engine.HotkeyIsPressed("session.queue"); | ||||
if (tryPlaceBuilding(queued)) | if (tryPlaceBuilding(queued)) | ||||
{ | { | ||||
if (queued) | if (queued && g_Selection.toList().length) | ||||
inputState = INPUT_BUILDING_PLACEMENT; | inputState = INPUT_BUILDING_PLACEMENT; | ||||
else | else | ||||
inputState = INPUT_NORMAL; | inputState = INPUT_NORMAL; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
inputState = INPUT_BUILDING_PLACEMENT; | inputState = INPUT_BUILDING_PLACEMENT; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | case INPUT_BUILDING_DRAG: | ||||
case "mousebuttonup": | case "mousebuttonup": | ||||
if (ev.button == SDL_BUTTON_LEFT) | if (ev.button == SDL_BUTTON_LEFT) | ||||
{ | { | ||||
// If shift is down, let the player continue placing another of the same structure. | // If shift is down, let the player continue placing another of the same structure. | ||||
var queued = Engine.HotkeyIsPressed("session.queue"); | var queued = Engine.HotkeyIsPressed("session.queue"); | ||||
if (tryPlaceBuilding(queued)) | if (tryPlaceBuilding(queued)) | ||||
{ | { | ||||
if (queued) | if (queued && g_Selection.toList().length) | ||||
inputState = INPUT_BUILDING_PLACEMENT; | inputState = INPUT_BUILDING_PLACEMENT; | ||||
else | else | ||||
inputState = INPUT_NORMAL; | inputState = INPUT_NORMAL; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
inputState = INPUT_BUILDING_PLACEMENT; | inputState = INPUT_BUILDING_PLACEMENT; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 377 Lines • ▼ Show 20 Lines | |||||
function doAction(action, ev) | function doAction(action, ev) | ||||
{ | { | ||||
if (!controlsPlayer(g_ViewedPlayer)) | if (!controlsPlayer(g_ViewedPlayer)) | ||||
return false; | return false; | ||||
return handleUnitAction(Engine.GetTerrainAtScreenPoint(ev.x, ev.y), action); | 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) | |||||
{ | |||||
Not Done Inline ActionsCool that it exists, but I think it will be clearer if you split this? Or is there a specific reason this is used here? Freagarach: Cool that it exists, but I think it will be clearer if you split this? Or is there a specific… | |||||
Done Inline Actionsah no I just remembered this and found it neat :p I agree that it's too unconventional to be really used, forgot I had actually left that one in. wraitii: ah no I just remembered this and found it neat :p
I agree that it's too unconventional to be… | |||||
g_Selection.removeList([unit]); | |||||
return [unit]; | |||||
} | |||||
return null; | |||||
} | |||||
function positionUnitsFreehandSelectionMouseMove(ev) | function positionUnitsFreehandSelectionMouseMove(ev) | ||||
{ | { | ||||
// Converting the input line into a List of points. | // Converting the input line into a List of points. | ||||
// For better performance the points must have a minimum distance to each other. | // For better performance the points must have a minimum distance to each other. | ||||
let target = Vector2D.from3D(Engine.GetTerrainAtScreenPoint(ev.x, ev.y)); | let target = Vector2D.from3D(Engine.GetTerrainAtScreenPoint(ev.x, ev.y)); | ||||
if (!g_FreehandSelection_InputLine.length || | if (!g_FreehandSelection_InputLine.length || | ||||
target.distanceToSquared(g_FreehandSelection_InputLine[g_FreehandSelection_InputLine.length - 1]) >= | target.distanceToSquared(g_FreehandSelection_InputLine[g_FreehandSelection_InputLine.length - 1]) >= | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | |||||
function handleUnitAction(target, action) | function handleUnitAction(target, action) | ||||
{ | { | ||||
if (!g_UnitActions[action.type] || !g_UnitActions[action.type].execute) | if (!g_UnitActions[action.type] || !g_UnitActions[action.type].execute) | ||||
{ | { | ||||
error("Invalid action.type " + action.type); | error("Invalid action.type " + action.type); | ||||
return false; | return false; | ||||
} | } | ||||
let selection = g_Selection.toList(); | let selection = Engine.HotkeyIsPressed("session.orderone") && | ||||
Not Done Inline ActionsYou can use your newly created function here as well. Freagarach: You can use your newly created function here as well. | |||||
if (Engine.HotkeyIsPressed("session.orderone")) | popOneFromSelection(action) || g_Selection.toList(); | ||||
{ | |||||
// 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); | |||||
} | |||||
} | |||||
// If the session.queue hotkey is down, add the order to the unit's order queue instead | // If the session.queue hotkey is down, add the order to the unit's order queue instead | ||||
// of running it immediately | // of running it immediately | ||||
return g_UnitActions[action.type].execute(target, action, selection, Engine.HotkeyIsPressed("session.queue")); | return g_UnitActions[action.type].execute(target, action, selection, Engine.HotkeyIsPressed("session.queue")); | ||||
} | } | ||||
function getEntityLimitAndCount(playerState, entType) | function getEntityLimitAndCount(playerState, entType) | ||||
{ | { | ||||
let ret = { | let ret = { | ||||
▲ Show 20 Lines • Show All 393 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
Why do we have to call tolist everywhere? Doesn't that mean the data structure is somewhat wrong?