Something went wrong. Try again.
Starship Simulator Controls thoriumsim.com
Something went wrong. Try again.
3.4 kB · 108 lines
TypeScript
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109import { type Entity, System } from "@thorium/utils/ecs";
type DeckNodeMap = { [key: number]: NonNullable<Entity["components"]["shipMap"]>["deckNodes"][number] & { deckIndex: number; contents: { [inventoryTemplateName: string]: { count: number }; }; };};
const deckNodeCache = new Map<number, DeckNodeMap>();
export class PassengerMovementSystem extends System { static flightMode = ["nova"]; test(entity: Entity) { return !!(entity.components.passengerMovement && entity.components.position); } frequency = 5; update(entity: Entity, elapsed: number) { const elapsedRatio = elapsed / 1000; const { position, passengerMovement } = entity.components; if (!position || !passengerMovement) return; const { x, y, z, parentId } = position; if (parentId === null) return; const ship = this.ecs.getEntityById(parentId); if (!ship?.components.shipMap) return;
if (!deckNodeCache.has(ship.id)) { deckNodeCache.set( ship.id, ship.components.shipMap.deckNodes.reduce((acc: DeckNodeMap, node) => { acc[node.id] = node; return acc; }, {}), ); } const nextNode = deckNodeCache.get(ship.id)?.[ passengerMovement.nodePath[passengerMovement.nextNodeIndex] ]; if (!nextNode) { return; } const distanceToNext = Math.hypot(x - nextNode?.x, y - nextNode?.y); // Increment to the next node if (distanceToNext <= 0.1 && z === nextNode.deckIndex) { passengerMovement.nextNodeIndex++; if (passengerMovement.nextNodeIndex >= passengerMovement.nodePath.length) { // We've reached the end of the path, so we're done. entity.updateComponent("passengerMovement", { nodePath: [], nextNodeIndex: 0, }); passengerMovement.nodePath = []; passengerMovement.nextNodeIndex = 0; entity.updateComponent("position", { x: nextNode.x, y: nextNode.y, z: nextNode.deckIndex, });
if (entity.components.cargoContainer && entity.components.position?.parentId) { void this.ecs.triggerAction("cargoControl.containerArrived", { containerId: entity.id }); } return; } } // Move towards the next node const direction = Math.atan2(nextNode?.y - y, nextNode?.x - x); const velocity = Math.min( passengerMovement.movementMaxVelocity.x * passengerMovement.movementVelocityMultiplier, distanceToNext, ); const zVelocity = Math.min( passengerMovement.movementMaxVelocity.z * passengerMovement.movementVelocityMultiplier, nextNode.deckIndex - z, ); const newX = x + velocity * Math.cos(direction) * elapsedRatio; const newY = y + velocity * Math.sin(direction) * elapsedRatio; let newZ = z + zVelocity * elapsedRatio; if (Math.abs(newZ - nextNode.deckIndex) < 0.1) { // We've reached the next deck newZ = nextNode.deckIndex; }
entity.updateComponent("position", { x: newX, y: newY, z: newZ }); }}
export function findClosestNode( nodes: { id: number; x: number; y: number; deckIndex: number }[], { x, y, z }: { x: number; y: number; z: number },) { const node = nodes.reduce( ( acc: { distance3d: number; node: null | { id: number; x: number; y: number; deckIndex: number }; }, node, ) => { const distance3d = Math.hypot(node.x - x, node.y - y, node.deckIndex - z); if (distance3d < acc.distance3d) return { distance3d, node }; return acc; }, { distance3d: Number.POSITIVE_INFINITY, node: null }, ); return node.node;}