Complete universe model migration
This commit is contained in:
@@ -20,10 +20,17 @@ export function describeSelectable(world: WorldState | undefined, item: Selectab
|
||||
return world.stations.get(item.id)?.label ?? item.id;
|
||||
}
|
||||
if (item.kind === "node") {
|
||||
return item.id;
|
||||
const node = world.nodes.get(item.id);
|
||||
return node ? `${node.itemId} source` : item.id;
|
||||
}
|
||||
if (item.kind === "celestial") {
|
||||
return `${world.celestials.get(item.id)?.kind ?? "celestial"} ${item.id}`;
|
||||
const celestial = world.celestials.get(item.id);
|
||||
if (!celestial) {
|
||||
return item.id;
|
||||
}
|
||||
|
||||
return describeCelestialPathWithinSystem(world, celestial.systemId, celestial.id)
|
||||
?? `${world.systems.get(celestial.systemId)?.label ?? celestial.systemId} / ${celestial.kind}`;
|
||||
}
|
||||
if (item.kind === "claim") {
|
||||
return `claim ${item.id}`;
|
||||
@@ -113,9 +120,7 @@ export function describeHoverLabel(world: WorldState | undefined, item: Selectab
|
||||
return item.id;
|
||||
}
|
||||
|
||||
const anchorPath = node.celestialId
|
||||
? describeCelestialPathWithinSystem(world, node.systemId, node.celestialId)
|
||||
: undefined;
|
||||
const anchorPath = describeAnchorPathWithinSystem(world, node.systemId, node.anchorId);
|
||||
return anchorPath ? `${anchorPath} / ${node.itemId}` : `${node.systemId} / ${node.itemId}`;
|
||||
}
|
||||
|
||||
@@ -135,16 +140,16 @@ export function describeHoverLabel(world: WorldState | undefined, item: Selectab
|
||||
|
||||
if (item.kind === "claim") {
|
||||
const claim = world.claims.get(item.id);
|
||||
const anchorPath = claim?.celestialId
|
||||
? describeCelestialPathWithinSystem(world, claim.systemId, claim.celestialId)
|
||||
const anchorPath = claim
|
||||
? describeAnchorPathWithinSystem(world, claim.systemId, claim.anchorId)
|
||||
: undefined;
|
||||
return anchorPath ? `${anchorPath} claim` : `Claim ${item.id}`;
|
||||
}
|
||||
|
||||
if (item.kind === "construction-site") {
|
||||
const site = world.constructionSites.get(item.id);
|
||||
const anchorPath = site?.celestialId
|
||||
? describeCelestialPathWithinSystem(world, site.systemId, site.celestialId)
|
||||
const anchorPath = site
|
||||
? describeAnchorPathWithinSystem(world, site.systemId, site.anchorId)
|
||||
: undefined;
|
||||
const siteLabel = site ? (site.blueprintId ?? site.targetDefinitionId) : item.id;
|
||||
return anchorPath ? `${anchorPath} / ${siteLabel}` : `Construction ${siteLabel}`;
|
||||
@@ -210,20 +215,74 @@ export function resolveFocusedCelestialId(world: WorldState | undefined, selecte
|
||||
return selected.id;
|
||||
}
|
||||
if (selected.kind === "ship") {
|
||||
return world.ships.get(selected.id)?.spatialState.currentCelestialId ?? world.ships.get(selected.id)?.celestialId ?? undefined;
|
||||
const ship = world.ships.get(selected.id);
|
||||
return ship?.spatialState.currentAnchorId && world.celestials.has(ship.spatialState.currentAnchorId)
|
||||
? ship.spatialState.currentAnchorId
|
||||
: (ship?.anchorId && world.celestials.has(ship.anchorId) ? ship.anchorId : undefined);
|
||||
}
|
||||
if (selected.kind === "station") {
|
||||
return world.stations.get(selected.id)?.celestialId ?? undefined;
|
||||
const station = world.stations.get(selected.id);
|
||||
return station?.anchorId && world.celestials.has(station.anchorId) ? station.anchorId : undefined;
|
||||
}
|
||||
if (selected.kind === "claim") {
|
||||
return world.claims.get(selected.id)?.celestialId ?? undefined;
|
||||
const claim = world.claims.get(selected.id);
|
||||
return claim && world.celestials.has(claim.anchorId) ? claim.anchorId : undefined;
|
||||
}
|
||||
if (selected.kind === "construction-site") {
|
||||
return world.constructionSites.get(selected.id)?.celestialId ?? undefined;
|
||||
const site = world.constructionSites.get(selected.id);
|
||||
return site && world.celestials.has(site.anchorId) ? site.anchorId : undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function resolveFocusedAnchorId(world: WorldState | undefined, selectedItems: Selectable[]): string | undefined {
|
||||
if (!world || selectedItems.length !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const selected = selectedItems[0];
|
||||
if (selected.kind === "node") {
|
||||
return world.nodes.get(selected.id)?.anchorId;
|
||||
}
|
||||
if (selected.kind === "ship") {
|
||||
const ship = world.ships.get(selected.id);
|
||||
return ship?.spatialState.currentAnchorId
|
||||
?? ship?.anchorId
|
||||
?? resolveFocusedCelestialId(world, selectedItems);
|
||||
}
|
||||
if (selected.kind === "station") {
|
||||
const station = world.stations.get(selected.id);
|
||||
return station?.anchorId
|
||||
?? resolveFocusedCelestialId(world, selectedItems);
|
||||
}
|
||||
if (selected.kind === "claim") {
|
||||
const claim = world.claims.get(selected.id);
|
||||
return claim?.anchorId
|
||||
?? resolveFocusedCelestialId(world, selectedItems);
|
||||
}
|
||||
if (selected.kind === "construction-site") {
|
||||
const site = world.constructionSites.get(selected.id);
|
||||
return site?.anchorId
|
||||
?? resolveFocusedCelestialId(world, selectedItems);
|
||||
}
|
||||
if (selected.kind === "celestial") {
|
||||
if (world.anchors.has(selected.id)) {
|
||||
return selected.id;
|
||||
}
|
||||
|
||||
const orbitBackedAnchor = [...world.anchors.values()].find((anchor) => anchor.orbitReferenceId === selected.id);
|
||||
return orbitBackedAnchor?.id;
|
||||
}
|
||||
if (selected.kind === "planet") {
|
||||
return `${selected.systemId}-planet-${selected.planetIndex + 1}`;
|
||||
}
|
||||
if (selected.kind === "moon") {
|
||||
return `${selected.systemId}-planet-${selected.planetIndex + 1}-moon-${selected.moonIndex + 1}`;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function describeOrbitalParent(world: WorldState | undefined, systemId?: string, anchor?: OrbitalAnchor): string {
|
||||
if (!world || !systemId) {
|
||||
return "unknown";
|
||||
@@ -330,23 +389,31 @@ export function describeShipState(world: WorldState | undefined, ship: ShipSnaps
|
||||
return baseState;
|
||||
}
|
||||
|
||||
const destinationNodeId = ship.spatialState.destinationNodeId ?? ship.spatialState.transit?.destinationNodeId;
|
||||
if (!destinationNodeId) {
|
||||
const destinationAnchorId = ship.spatialState.destinationAnchorId ?? ship.spatialState.transit?.destinationAnchorId;
|
||||
if (!destinationAnchorId) {
|
||||
return baseState;
|
||||
}
|
||||
|
||||
const destinationCelestial = world.celestials.get(destinationNodeId);
|
||||
if (!destinationCelestial) {
|
||||
return `${baseState} -> ${destinationNodeId}`;
|
||||
}
|
||||
|
||||
const destinationAnchor = destinationAnchorId ? world.anchors.get(destinationAnchorId) : undefined;
|
||||
if (baseState === "warping" || baseState === "spooling-warp") {
|
||||
const destinationPath = describeCelestialPathWithinSystem(world, destinationCelestial.systemId, destinationNodeId);
|
||||
return `${baseState} -> ${destinationPath ?? destinationNodeId}`;
|
||||
const destinationSystemId = destinationAnchor?.systemId ?? ship.spatialState.currentSystemId ?? ship.systemId;
|
||||
const destinationPath = describeAnchorPathWithinSystem(
|
||||
world,
|
||||
destinationSystemId,
|
||||
destinationAnchorId,
|
||||
);
|
||||
return `${baseState} -> ${destinationPath ?? destinationAnchorId}`;
|
||||
}
|
||||
|
||||
const destinationSystem = world.systems.get(destinationCelestial.systemId);
|
||||
return `${baseState} -> ${destinationSystem?.label ?? destinationCelestial.systemId}`;
|
||||
const destinationSystemId = destinationAnchor?.systemId
|
||||
?? ship.spatialState.currentSystemId
|
||||
?? ship.systemId;
|
||||
const destinationSystem = world.systems.get(destinationSystemId);
|
||||
if (!destinationSystem) {
|
||||
return `${baseState} -> ${destinationAnchorId}`;
|
||||
}
|
||||
|
||||
return `${baseState} -> ${destinationSystem.label}`;
|
||||
}
|
||||
|
||||
export function describeShipObjective(objective: string): string {
|
||||
@@ -406,8 +473,8 @@ export function describeShipLocation(world: WorldState | undefined, ship: ShipSn
|
||||
if (ship.dockedStationId) {
|
||||
const station = world.stations.get(ship.dockedStationId);
|
||||
if (station) {
|
||||
const anchorPath = station.celestialId
|
||||
? describeCelestialPathWithinSystem(world, station.systemId, station.celestialId)
|
||||
const anchorPath = station.anchorId
|
||||
? describeAnchorPathWithinSystem(world, station.systemId, station.anchorId)
|
||||
: undefined;
|
||||
return {
|
||||
system: systemLabel,
|
||||
@@ -416,11 +483,11 @@ export function describeShipLocation(world: WorldState | undefined, ship: ShipSn
|
||||
}
|
||||
}
|
||||
|
||||
const currentCelestialId = ship.spatialState.currentCelestialId ?? ship.celestialId;
|
||||
if (currentCelestialId) {
|
||||
const celestialPath = describeCelestialPathWithinSystem(world, systemId, currentCelestialId);
|
||||
if (celestialPath) {
|
||||
return { system: systemLabel, local: celestialPath };
|
||||
const currentAnchorId = ship.spatialState.currentAnchorId ?? ship.anchorId;
|
||||
if (currentAnchorId) {
|
||||
const anchorPath = describeAnchorPathWithinSystem(world, systemId, currentAnchorId);
|
||||
if (anchorPath) {
|
||||
return { system: systemLabel, local: anchorPath };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,9 +513,9 @@ export function describeActiveSpace(
|
||||
return activeSystem.label;
|
||||
}
|
||||
|
||||
const celestialId = resolveFocusedCelestialId(world, selectedItems);
|
||||
if (celestialId) {
|
||||
const localPath = describeCelestialPathWithinSystem(world, activeSystem.id, celestialId);
|
||||
const anchorId = resolveFocusedAnchorId(world, selectedItems);
|
||||
if (anchorId) {
|
||||
const localPath = describeAnchorPathWithinSystem(world, activeSystem.id, anchorId);
|
||||
return localPath
|
||||
? `${activeSystem.label} / ${localPath}`
|
||||
: activeSystem.label;
|
||||
@@ -472,10 +539,9 @@ export function describeCelestialPathWithinSystem(world: WorldState, systemId: s
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (celestial.parentNodeId) {
|
||||
const parentPath = describeCelestialPathWithinSystem(world, systemId, celestial.parentNodeId);
|
||||
const segment = describeCelestialSegment(system, celestial);
|
||||
return parentPath ? `${parentPath}/${segment}` : segment;
|
||||
const anchorId = resolveAnchorIdForCelestial(world, celestialId);
|
||||
if (anchorId) {
|
||||
return describeAnchorPathWithinSystem(world, systemId, anchorId);
|
||||
}
|
||||
|
||||
if (celestial.kind === "star") {
|
||||
@@ -485,6 +551,60 @@ export function describeCelestialPathWithinSystem(world: WorldState, systemId: s
|
||||
return describeCelestialSegment(system, celestial);
|
||||
}
|
||||
|
||||
export function describeAnchorPathWithinSystem(world: WorldState, systemId: string, anchorId: string, celestialId?: string | null): string | undefined {
|
||||
const anchor = world.anchors.get(anchorId);
|
||||
if (anchor?.parentAnchorId) {
|
||||
const parentPath = describeAnchorPathWithinSystem(world, systemId, anchor.parentAnchorId);
|
||||
const segment = describeAnchorSegment(anchor);
|
||||
return parentPath ? `${parentPath}/${segment}` : segment;
|
||||
}
|
||||
|
||||
if (celestialId) {
|
||||
return describeCelestialPathWithinSystem(world, systemId, celestialId);
|
||||
}
|
||||
|
||||
if (!anchor) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return describeAnchorSegment(anchor);
|
||||
}
|
||||
|
||||
function describeAnchorSegment(anchor: { kind: string; id: string; orbitReferenceId?: string | null }): string {
|
||||
if (anchor.orbitReferenceId) {
|
||||
return describeAnchorOrbitReference(anchor.orbitReferenceId);
|
||||
}
|
||||
|
||||
if (anchor.kind === "resource-node") {
|
||||
return anchor.id;
|
||||
}
|
||||
|
||||
return anchor.kind.replace(/-/g, " ");
|
||||
}
|
||||
|
||||
function resolveAnchorIdForCelestial(world: WorldState, celestialId: string): string | undefined {
|
||||
return world.anchors.has(celestialId) ? celestialId : undefined;
|
||||
}
|
||||
|
||||
function describeAnchorOrbitReference(referenceId: string): string {
|
||||
const lagrangeMatch = referenceId.match(/(l[1-5])$/i);
|
||||
if (lagrangeMatch) {
|
||||
return lagrangeMatch[1].toUpperCase();
|
||||
}
|
||||
|
||||
const moonMatch = referenceId.match(/moon-(\d+)$/i);
|
||||
if (moonMatch) {
|
||||
return `Moon ${moonMatch[1]}`;
|
||||
}
|
||||
|
||||
const planetMatch = referenceId.match(/planet-(\d+)$/i);
|
||||
if (planetMatch) {
|
||||
return `Planet ${planetMatch[1]}`;
|
||||
}
|
||||
|
||||
return referenceId;
|
||||
}
|
||||
|
||||
function describeCelestialSegment(system: SystemSnapshot, celestial: CelestialSnapshot): string {
|
||||
const moonMatch = celestial.id.match(/-planet-(\d+)-moon-(\d+)$/);
|
||||
if (moonMatch) {
|
||||
|
||||
Reference in New Issue
Block a user