Refactor runtime bootstrap and ship control flows

This commit is contained in:
2026-04-03 01:12:26 -04:00
parent 0bb72bee35
commit 706e1cda8f
129 changed files with 9588 additions and 3548 deletions

View File

@@ -22,6 +22,7 @@ import type {
WorldState,
PovLevel,
} from "./viewerTypes";
import type { ViewerOrderContextMenuTarget } from "./ui/stores/viewerOrderContextMenu";
export interface ViewerInteractionContext {
renderer: THREE.WebGLRenderer;
@@ -65,6 +66,8 @@ export interface ViewerInteractionContext {
updatePanels: () => void;
focusOnSelection: (selection: Selectable) => void;
updateGamePanel: (mode: string) => void;
openOrderContextMenu: (x: number, y: number, target: ViewerOrderContextMenuTarget) => void;
closeOrderContextMenu: () => void;
historyController: ViewerHistoryWindowController;
}
@@ -143,6 +146,7 @@ export class ViewerInteractionController {
};
readonly onClick = (event: MouseEvent) => {
this.context.closeOrderContextMenu();
if (this.context.getSuppressClickSelection()) {
this.context.setSuppressClickSelection(false);
return;
@@ -157,6 +161,23 @@ export class ViewerInteractionController {
this.context.updatePanels();
};
readonly onContextMenu = (event: MouseEvent) => {
event.preventDefault();
this.context.closeOrderContextMenu();
const picked = this.pickSelectableAtClientPosition(event.clientX, event.clientY);
if (!picked) {
return;
}
const target = this.buildOrderContextTarget(picked);
if (!target) {
return;
}
this.context.openOrderContextMenu(event.clientX, event.clientY, target);
};
readonly onOpsStripClick = (event: MouseEvent) => {
const target = event.target;
if (!(target instanceof HTMLElement)) {
@@ -370,4 +391,69 @@ export class ViewerInteractionController {
return selection.kind === "system" && selection.id !== this.context.getActiveSystemId();
}
private buildOrderContextTarget(selection: Selectable): ViewerOrderContextMenuTarget | null {
const world = this.context.getWorld();
if (!world) {
return null;
}
switch (selection.kind) {
case "ship": {
const ship = world.ships.get(selection.id);
return ship ? {
selection,
label: ship.name,
systemId: ship.systemId,
targetPosition: ship.localPosition,
} : null;
}
case "station": {
const station = world.stations.get(selection.id);
return station ? {
selection,
label: station.label,
systemId: station.systemId,
targetPosition: station.localPosition,
} : null;
}
case "node": {
const node = world.nodes.get(selection.id);
return node ? {
selection,
label: node.itemId,
systemId: node.systemId,
itemId: node.itemId,
targetPosition: node.localPosition,
} : null;
}
case "celestial": {
const celestial = world.celestials.get(selection.id);
return celestial ? {
selection,
label: selection.id,
systemId: celestial.systemId,
targetPosition: celestial.orbitalAnchor,
} : null;
}
case "construction-site": {
const site = world.constructionSites.get(selection.id);
return site ? {
selection,
label: site.blueprintId ?? site.targetDefinitionId ?? site.id,
systemId: site.systemId,
} : null;
}
case "system": {
const system = world.systems.get(selection.id);
return system ? {
selection,
label: system.label,
systemId: system.id,
} : null;
}
default:
return null;
}
}
}