mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Instead of storing a single flat list of positions and data per building, RallyPoint now stores them keyed by player ID. This lets mutual allies independently set and display rally points on each other's structures. The GUI now allows selecting allied buildings with a rally point and only shows the viewing player's own rally point data. GuiInterface gets an OnUpdate handler to keep displayed positions in sync when rally point targets move. GetRallyPointCommands now takes raw position and data arrays instead of a component reference. The network command field is also renamed from "entities" to "structures". Fixes #3115
172 lines
3.9 KiB
JavaScript
172 lines
3.9 KiB
JavaScript
// Returns an array of commands suitable for ProcessCommand() based on the rally point data.
|
|
// This assumes that the rally point has a valid position.
|
|
function GetRallyPointCommands(rallyPos, data, spawnedEnts)
|
|
{
|
|
const ret = [];
|
|
for (let i = 0; i < rallyPos.length; ++i)
|
|
{
|
|
// Look and see if there is a command in the rally point data, otherwise just walk there.
|
|
let command = data[i]?.command ?? "walk";
|
|
|
|
// If a target was set and the target no longer exists, or no longer
|
|
// has a valid position, then just walk to the rally point.
|
|
if (data[i]?.target)
|
|
{
|
|
const cmpPosition = Engine.QueryInterface(data[i].target, IID_Position);
|
|
if (!cmpPosition || !cmpPosition.IsInWorld())
|
|
{
|
|
if (command == "gather")
|
|
command = "gather-near-position";
|
|
else if (command == "collect-treasure")
|
|
command = "collect-treasure-near-position";
|
|
else if (command == "attack")
|
|
command = "attack-walk";
|
|
else
|
|
command = "walk";
|
|
}
|
|
}
|
|
|
|
switch (command)
|
|
{
|
|
case "gather":
|
|
ret.push({
|
|
"type": "gather",
|
|
"entities": spawnedEnts,
|
|
"target": data[i].target,
|
|
"queued": true
|
|
});
|
|
break;
|
|
case "gather-near-position":
|
|
ret.push({
|
|
"type": "gather-near-position",
|
|
"entities": spawnedEnts,
|
|
"x": rallyPos[i].x,
|
|
"z": rallyPos[i].z,
|
|
"resourceType": data[i].resourceType,
|
|
"resourceTemplate": data[i].resourceTemplate,
|
|
"queued": true
|
|
});
|
|
break;
|
|
case "repair":
|
|
case "build":
|
|
ret.push({
|
|
"type": "repair",
|
|
"entities": spawnedEnts,
|
|
"target": data[i].target,
|
|
"queued": true,
|
|
"autocontinue": i == rallyPos.length - 1
|
|
});
|
|
break;
|
|
case "occupy-turret":
|
|
ret.push({
|
|
"type": "occupy-turret",
|
|
"entities": spawnedEnts,
|
|
"target": data[i].target,
|
|
"queued": true
|
|
});
|
|
break;
|
|
case "garrison":
|
|
ret.push({
|
|
"type": "garrison",
|
|
"entities": spawnedEnts,
|
|
"target": data[i].target,
|
|
"queued": true
|
|
});
|
|
break;
|
|
case "attack-walk":
|
|
ret.push({
|
|
"type": "attack-walk",
|
|
"entities": spawnedEnts,
|
|
"x": rallyPos[i].x,
|
|
"z": rallyPos[i].z,
|
|
"targetClasses": data[i].targetClasses,
|
|
"queued": true
|
|
});
|
|
break;
|
|
case "patrol":
|
|
ret.push({
|
|
"type": "patrol",
|
|
"entities": spawnedEnts,
|
|
"x": rallyPos[i].x,
|
|
"z": rallyPos[i].z,
|
|
"target": data[i].target,
|
|
"targetClasses": data[i].targetClasses,
|
|
"queued": true
|
|
});
|
|
break;
|
|
case "attack":
|
|
ret.push({
|
|
"type": "attack",
|
|
"entities": spawnedEnts,
|
|
"target": data[i].target,
|
|
"allowCapture": data[i].allowCapture,
|
|
"queued": true,
|
|
});
|
|
break;
|
|
case "trade":
|
|
ret.push({
|
|
"type": "setup-trade-route",
|
|
"entities": spawnedEnts,
|
|
"source": data[i].source,
|
|
"target": data[i].target,
|
|
"route": undefined,
|
|
"queued": true
|
|
});
|
|
break;
|
|
case "collect-treasure":
|
|
ret.push({
|
|
"type": "collect-treasure",
|
|
"entities": spawnedEnts,
|
|
"target": data[i].target,
|
|
"queued": true
|
|
});
|
|
break;
|
|
case "collect-treasure-near-position":
|
|
ret.push({
|
|
"type": "collect-treasure-near-position",
|
|
"entities": spawnedEnts,
|
|
"x": rallyPos[i].x,
|
|
"z": rallyPos[i].z,
|
|
"queued": true
|
|
});
|
|
break;
|
|
default:
|
|
ret.push({
|
|
"type": "walk",
|
|
"entities": spawnedEnts,
|
|
"x": rallyPos[i].x,
|
|
"z": rallyPos[i].z,
|
|
"queued": true
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
|
|
// special case: trade route with waypoints
|
|
// (we do not modify the RallyPoint before, as we want it to be displayed with all way-points)
|
|
if (ret.length > 1 && ret[ret.length-1].type == "setup-trade-route")
|
|
{
|
|
let route = [];
|
|
const waypoints = ret.length - 1;
|
|
|
|
for (let i = 0; i < waypoints; ++i)
|
|
{
|
|
if (ret[i].type != "walk")
|
|
{
|
|
route = undefined;
|
|
break;
|
|
}
|
|
route.push({ "x": ret[i].x, "z": ret[i].z });
|
|
}
|
|
|
|
if (route && route.length > 0)
|
|
{
|
|
ret.splice(0, waypoints);
|
|
ret[0].route = route;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Engine.RegisterGlobal("GetRallyPointCommands", GetRallyPointCommands);
|