Changeset View
Standalone View
binaries/data/mods/public/gui/session/unit_actions.js
Show First 20 Lines • Show All 1,005 Lines • ▼ Show 20 Lines | "none": | ||||
}, | }, | ||||
"specificness": 100, | "specificness": 100, | ||||
}, | }, | ||||
}; | }; | ||||
/** | /** | ||||
* Info and actions for the entity commands | * Info and actions for the entity commands | ||||
* Currently displayed in the bottom of the central panel | * Currently displayed in the bottom of the central panel | ||||
*/ | */ | ||||
var g_EntityCommands = | var g_EntityCommands = | ||||
{ | { | ||||
bb: linter complaining about indent | |||||
"unload-all": { | "unload-all": { | ||||
"getInfo": function(entStates) | "getInfo": function(entStates) | ||||
{ | { | ||||
let count = 0; | let count = 0; | ||||
for (let entState of entStates) | for (let entState of entStates) | ||||
if (entState.garrisonHolder) | if (entState.garrisonHolder) | ||||
count += entState.garrisonHolder.entities.length; | count += entState.garrisonHolder.entities.length; | ||||
▲ Show 20 Lines • Show All 427 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
let playerState = g_SimState.players[entState.player]; | let playerState = g_SimState.players[entState.player]; | ||||
if (playerState && playerState.controlsAll) | if (playerState && playerState.controlsAll) | ||||
return false; | return false; | ||||
if (entState.resourceSupply && entState.resourceSupply.killBeforeGather) | if (entState.resourceSupply && entState.resourceSupply.killBeforeGather) | ||||
return translate("The entity has to be killed before it can be gathered from"); | return translate("The entity has to be killed before it can be gathered from"); | ||||
// Keep in sync with Controllability.js-component. | |||||
if (entState.capturePoints && entState.capturePoints[entState.player] < entState.maxCapturePoints / 2) | if (entState.capturePoints && entState.capturePoints[entState.player] < entState.maxCapturePoints / 2) | ||||
return translate("You cannot destroy this entity as you own less than half the capture points"); | return translate("You cannot destroy this entity as you own less than half the capture points"); | ||||
if (!entState.identity.canDelete) | if (entState.controllability && !entState.controllability.Deletable) | ||||
Done Inline ActionsShould we return undeletable when there is no controllability component? Freagarach: Should we return `undeletable` when there is no controllability component? | |||||
return translate("This entity is undeletable"); | return translate("This entity is undeletable"); | ||||
return false; | return false; | ||||
} | } | ||||
function DrawTargetMarker(target) | function DrawTargetMarker(target) | ||||
{ | { | ||||
Engine.GuiInterfaceCall("AddTargetMarker", { | Engine.GuiInterfaceCall("AddTargetMarker", { | ||||
Show All 20 Lines | |||||
function getActionInfo(action, target, selection) | function getActionInfo(action, target, selection) | ||||
{ | { | ||||
let simState = GetSimState(); | let simState = GetSimState(); | ||||
// If the selection doesn't exist, no action | // If the selection doesn't exist, no action | ||||
if (!GetEntityState(selection[0])) | if (!GetEntityState(selection[0])) | ||||
return { "possible": false }; | return { "possible": false }; | ||||
if (!target) // TODO move these non-target actions to an object like unit_actions.js | if (!target) // TODO move these non-target actions to an object like unit_actions.js | ||||
Done Inline ActionsThis prevents restricting the move order,,, Freagarach: This prevents restricting the move order,,, | |||||
Done Inline ActionsIt seems to me you could just put the controllable check in this function. Then you don't have to add it everywhere, and you can still restrict the move order. wraitii: It seems to me you could just put the controllable check in this function. Then you don't have… | |||||
Done Inline ActionsFilter the entities which cannot be controlled? Freagarach: Filter the entities which cannot be controlled? | |||||
Done Inline ActionsYeah that would probably do the trick. I can't foresee a good reason why it wouldn't work, but maybe there's one wraitii: Yeah that would probably do the trick. I can't foresee a good reason why it wouldn't work, but… | |||||
Done Inline ActionsWell, there is quite a performance impact,,, (50 - 300 µs per tick.) Freagarach: Well, there is quite a performance impact,,, (50 - 300 µs per tick.) | |||||
Done Inline ActionsHow is that different when doing it in the orders? We're still iterating over all entities in the loop below. It's fine if you have to repeat the code a few times for different code paths. wraitii: How is that different when doing it in the orders? We're still iterating over all entities in… | |||||
Done Inline ActionsIt is different because one has to do it twice now ^^ Freagarach: It is different because one has to do it twice now ^^ | |||||
{ | { | ||||
if (action == "set-rallypoint") | if (action == "set-rallypoint") | ||||
{ | { | ||||
let cursor = ""; | let cursor = ""; | ||||
let data = { "command": "walk" }; | let data = { "command": "walk" }; | ||||
if (Engine.HotkeyIsPressed("session.attackmove")) | if (Engine.HotkeyIsPressed("session.attackmove")) | ||||
{ | { | ||||
data.command = "attack-walk"; | data.command = "attack-walk"; | ||||
Show All 21 Lines | function getActionInfo(action, target, selection) | ||||
// Look at the first targeted entity | // Look at the first targeted entity | ||||
// (TODO: maybe we eventually want to look at more, and be more context-sensitive? | // (TODO: maybe we eventually want to look at more, and be more context-sensitive? | ||||
// e.g. prefer to attack an enemy unit, even if some friendly units are closer to the mouse) | // e.g. prefer to attack an enemy unit, even if some friendly units are closer to the mouse) | ||||
let targetState = GetEntityState(target); | let targetState = GetEntityState(target); | ||||
if (!targetState) | if (!targetState) | ||||
return { "possible": false }; | return { "possible": false }; | ||||
// Check if any entities in the selection can do some of the available actions with target | // Check if any entities in the selection can do some of the available actions with target | ||||
Done Inline ActionsI wonder if we could compute only if we need it. something like; let simState = null; if (selection.some(s => { if (!entState || !entState.identity.controllable) return false; return (g_UnitActions[action] && g_UnitActions[action].getActionInfo); })) let simState = GetSimState(); But that requires going through the loop twice. Maybe it's faster than getting the simstate dunno. Stan: I wonder if we could compute only if we need it.
something like;
```lang=js
let simState =… | |||||
Done Inline ActionsIt's quite likely that we'll have at least one entity with a GetActionInfo, particularly if we have man entities, so I think it's a pessimisation in general. wraitii: It's quite likely that we'll have at least one entity with a GetActionInfo, particularly if we… | |||||
Done Inline ActionsSimstate costs between 1 and 5 microseconds. Freagarach: Simstate costs between 1 and 5 microseconds. | |||||
for (let entityID of selection) | for (let entityID of selection) | ||||
{ | { | ||||
let entState = GetEntityState(entityID); | let entState = GetEntityState(entityID); | ||||
if (!entState) | if (!entState) | ||||
continue; | continue; | ||||
if (g_UnitActions[action] && g_UnitActions[action].getActionInfo) | if (g_UnitActions[action] && g_UnitActions[action].getActionInfo) | ||||
{ | { | ||||
let r = g_UnitActions[action].getActionInfo(entState, targetState, simState); | let r = g_UnitActions[action].getActionInfo(entState, targetState, simState); | ||||
if (r && r.possible) // return true if it's possible for one of the entities | if (r && r.possible) // return true if it's possible for one of the entities | ||||
return r; | return r; | ||||
} | } | ||||
} | } | ||||
return { "possible": false }; | return { "possible": false }; | ||||
} | } |
linter complaining about indent