chore: refactor GameApp.ts into parts

This commit is contained in:
2026-03-11 18:21:51 -04:00
parent caa9d40cba
commit 5727cb0e88
19 changed files with 2322 additions and 1762 deletions

80
src/game/ui/presenters.ts Normal file
View File

@@ -0,0 +1,80 @@
import {
itemDefinitionsById,
moduleDefinitionsById,
recipeDefinitions,
} from "../data/catalog";
import { getShipCargoAmount } from "../state/inventory";
import type {
ShipInstance,
SolarSystemInstance,
StationInstance,
ViewLevel,
} from "../types";
export function getSelectionTitle(selection: ShipInstance[], selectedStation?: StationInstance) {
if (selectedStation) {
return selectedStation.definition.label;
}
if (selection.length === 0) {
return "No Selection";
}
if (selection.length === 1) {
return selection[0].definition.label;
}
return `${selection.length} Ships Selected`;
}
export function getSelectionDetails(
selection: ShipInstance[],
selectedStation: StationInstance | undefined,
systems: SolarSystemInstance[],
viewLevel: ViewLevel,
ships: ShipInstance[],
) {
if (selectedStation) {
return describeStation(selectedStation, ships);
}
if (selection.length === 0) {
return `Systems online: ${systems.map((system) => system.definition.label).join(", ")}\n\nOrders: Move, Patrol, Escort, Mine\nView: ${viewLevel}`;
}
return selection
.map(
(ship) =>
`${ship.definition.label}${ship.systemId}\nState: ${ship.state}${ship.dockedStationId ? ` @ ${ship.dockedStationId}` : ""}\nOrder: ${ship.order.kind}\nCargo: ${Math.round(getShipCargoAmount(ship))}/${ship.definition.cargoCapacity || 0} ${getItemLabel(ship.cargoItemId)}\nFuel: ${ship.fuel.toFixed(0)}/${ship.maxFuel}\nEnergy: ${ship.energy.toFixed(0)}/${ship.maxEnergy}\nHold Type: ${ship.definition.cargoKind ?? "none"}\nModules: ${ship.definition.modules.map(getModuleLabel).join(", ")}`,
)
.join("\n\n");
}
export function describeStation(station: StationInstance, ships: ShipInstance[]) {
const miners = ships.filter((ship) => ship.systemId === station.systemId && ship.order.kind === "mine").length;
const escorts = ships.filter((ship) => ship.systemId === station.systemId && ship.order.kind === "escort").length;
const patrols = ships.filter((ship) => ship.systemId === station.systemId && ship.order.kind === "patrol").length;
const activeRecipe = station.activeRecipeId
? recipeDefinitions.find((recipe) => recipe.id === station.activeRecipeId)
: undefined;
const refineryStatus =
station.definition.category === "refining"
? `Ore: ${Math.round(station.oreStored)}\nRefined: ${Math.round(station.refinedStock)}\nBatch: ${Math.round(station.activeBatch)}\nRecipe: ${activeRecipe?.label ?? "Idle"}\nTime Remaining: ${station.activeBatch > 0 ? `${station.processTimer.toFixed(1)}s` : "Idle"}\n`
: "";
const activity =
station.definition.category === "refining"
? `Refining ore for ${miners} mining ships`
: station.definition.category === "shipyard"
? `Maintaining ${patrols} patrol craft`
: station.definition.category === "farm"
? "Supplying agricultural goods"
: station.definition.category === "defense"
? `Coordinating ${escorts} escort wings`
: "Managing local trade traffic";
return `${station.definition.label}${station.systemId}\nRole: ${station.definition.category}\nActivity: ${activity}\nDocking: ${station.dockedShipIds.size}/${station.definition.dockingCapacity}\nFuel: ${station.fuel.toFixed(0)}/${station.maxFuel}\nEnergy: ${station.energy.toFixed(0)}/${station.maxEnergy}\nBulk Solid: ${Math.round(station.inventory["bulk-solid"])}\nContainer: ${Math.round(station.inventory.container)}\nManufactured: ${Math.round(station.inventory.manufactured)}\nModules: ${station.modules.map(getModuleLabel).join(", ")}\n${refineryStatus}Radius: ${station.definition.radius}`;
}
export function getItemLabel(itemId?: string) {
return itemId ? itemDefinitionsById.get(itemId)?.label ?? itemId : "None";
}
export function getModuleLabel(moduleId: string) {
return moduleDefinitionsById.get(moduleId)?.label ?? moduleId;
}