diff --git a/app/.server/classes/FlightDataModel.ts b/app/.server/classes/FlightDataModel.ts index fd168924..f0a95dce 100644 --- a/app/.server/classes/FlightDataModel.ts +++ b/app/.server/classes/FlightDataModel.ts @@ -3,9 +3,9 @@ import path from "node:path"; import RAPIER from "@thorium-sim/rapier3d-node"; import { initECS } from "@thorium/.server/classes/initECS"; import { DataStore, type DataStoreOptions } from "@thorium/utils/.server/db-fs"; -import { processTriggers } from "@thorium/utils/.server/evaluateEntityQuery"; import { executeBlocks } from "@thorium/utils/.server/executeBlocks"; import { loadGltf } from "@thorium/utils/.server/loadGltf"; +import { processTriggers } from "@thorium/utils/.server/processTriggers"; import { ECS, Entity } from "@thorium/utils/ecs"; import randomWords from "@thorium/utils/random-words"; import { ConvexHull } from "@thorium/utils/starmap/ConvexHull.js"; diff --git a/app/.server/systems/__test__/ExocompSystem.test.ts b/app/.server/systems/__test__/ExocompSystem.test.ts index 02882bb7..049a5dbd 100644 --- a/app/.server/systems/__test__/ExocompSystem.test.ts +++ b/app/.server/systems/__test__/ExocompSystem.test.ts @@ -5,8 +5,8 @@ import { PassengerMovementSystem } from "@thorium/.server/systems/PassengerMovem import { createMockDataContext } from "@thorium/utils/.server/createMockDataContext"; import { DataStore } from "@thorium/utils/.server/db-fs"; import { testDataStoreProps } from "@thorium/utils/.server/db-fs/testDataStoreProps"; -import { processTriggers } from "@thorium/utils/.server/evaluateEntityQuery"; import { executeBlocks } from "@thorium/utils/.server/executeBlocks"; +import { processTriggers } from "@thorium/utils/.server/processTriggers"; import { Entity } from "@thorium/utils/ecs"; import ECS from "@thorium/utils/ecs/ecs"; import { aroundEach, beforeEach, describe, expect, it } from "vitest"; diff --git a/app/.server/systems/__test__/ReactorHeatSystem.test.ts b/app/.server/systems/__test__/ReactorHeatSystem.test.ts index 58773aba..fc6abac3 100644 --- a/app/.server/systems/__test__/ReactorHeatSystem.test.ts +++ b/app/.server/systems/__test__/ReactorHeatSystem.test.ts @@ -2,8 +2,8 @@ import { DeckNode } from "@thorium/.server/classes/Plugins/Ship/Deck"; import { createMockDataContext } from "@thorium/utils/.server/createMockDataContext"; import { DataStore } from "@thorium/utils/.server/db-fs"; import { testDataStoreProps } from "@thorium/utils/.server/db-fs/testDataStoreProps"; -import { processTriggers } from "@thorium/utils/.server/evaluateEntityQuery"; import { executeBlocks } from "@thorium/utils/.server/executeBlocks"; +import { processTriggers } from "@thorium/utils/.server/processTriggers"; import { ECS, Entity } from "@thorium/utils/ecs"; import { aroundEach, beforeEach, describe, expect, it } from "vitest"; diff --git a/app/bunServer.ts b/app/bunServer.ts index 3b5d61af..09c47c86 100644 --- a/app/bunServer.ts +++ b/app/bunServer.ts @@ -11,8 +11,8 @@ import { router } from "@thorium/.server/init/router"; import { DataStore } from "@thorium/utils/.server/db-fs"; import { bunDataStoreProps, setBasePath } from "@thorium/utils/.server/db-fs/bunDataStoreProps"; import { loadPlugins } from "@thorium/utils/.server/db-fs/loadPlugins"; -import { processTriggers } from "@thorium/utils/.server/evaluateEntityQuery"; import { notifyActions, notifyEvents } from "@thorium/utils/.server/notifyActions"; +import { processTriggers } from "@thorium/utils/.server/processTriggers"; import { snapshot } from "@thorium/utils/.server/snapshot"; import { vanity } from "@thorium/utils/.server/vanity"; import { liveQueryPlugin } from "@thorium/utils/live-query/.server/adapters/hono-adapter"; diff --git a/app/cards/Sensors/data.server.ts b/app/cards/Sensors/data.server.ts index ec7225fc..ad4fec7c 100644 --- a/app/cards/Sensors/data.server.ts +++ b/app/cards/Sensors/data.server.ts @@ -106,6 +106,15 @@ export const sensors = t.router({ type: scanTypes, }), ) + .output( + z.object({ + scanId: z.number(), + shipId: z.number(), + target: z.number(), + type: scanTypes, + }), + ) + .meta({ event: true }) .send(({ ctx, input }) => { const sensorsSystem = getShipSystem(ctx.ecs, { systemType: "sensors", @@ -123,6 +132,7 @@ export const sensors = t.router({ }); ctx.flight?.ecs.addEntity(scanEntity); pubsub.publish.sensors.scans({ shipId: input.shipId }); + return { ...input, scanId: scanEntity.id }; }), scanCancel: t.procedure .input( @@ -130,6 +140,13 @@ export const sensors = t.router({ scanId: z.number(), }), ) + .output( + z.object({ + scanId: z.number(), + shipId: z.number().optional(), + }), + ) + .meta({ event: true }) .send(({ ctx, input }) => { const shipId = ctx.ecs.getEntityById(input.scanId)?.components.scan?.parentId; if (shipId) { @@ -143,9 +160,12 @@ export const sensors = t.router({ if (shipId) { pubsub.publish.sensors.scans({ shipId }); } + return { scanId: input.scanId, shipId }; }), selectContact: t.procedure .input(z.object({ shipId: z.number(), contactId: z.number().nullable() })) + .output(z.object({ shipId: z.number(), contactId: z.number().nullable() })) + .meta({ event: true }) .send(({ ctx, input }) => { const sensors = getShipSystem(ctx.ecs, { systemType: "sensors", @@ -158,6 +178,7 @@ export const sensors = t.router({ shipId: input.shipId, systemId: sensors.id, }); + return input; }), sendProcessedData: t.procedure @@ -168,8 +189,16 @@ export const sensors = t.router({ flash: z.boolean().optional(), }), ) + .output( + z.object({ + shipId: z.number(), + data: z.string(), + flash: z.boolean().optional(), + }), + ) + .meta({ event: true, action: true }) .send(({ ctx, input }) => { - if (!input.data) return; + if (!input.data.trim()) throw new Error("Data cannot be empty"); const sensorsSys = getShipSystem(ctx.ecs, { systemType: "sensors", shipId: input.shipId, @@ -209,6 +238,7 @@ export const sensors = t.router({ shipId: input.shipId, systemId: sensorsSys.id, }); + return input; }), removeProcessedData: t.procedure diff --git a/app/cards/Sensors/index.tsx b/app/cards/Sensors/index.tsx index 2029bc89..a06e7dc2 100644 --- a/app/cards/Sensors/index.tsx +++ b/app/cards/Sensors/index.tsx @@ -129,7 +129,7 @@ function Scans({ cardLoaded }: { cardLoaded: boolean }) { const [scans] = q.sensors.scans.useNetRequest({ shipId }); if (scans.length === 0) return null; return ( -
+
{scans.map((s) => ( @@ -347,7 +347,7 @@ function SensorsScannableObject({
- + {hasWaypoint ? null : ( - ) : null} -

- ))} +
+
+

Events

+
+ {events.map((e, i) => ( +
+

{e.name}

+ {Object.entries(e.values).map(([key, value]) => ( +

+ {key}: {value} +

+ ))} + {choosing ? ( + + ) : null} +
+ ))} +
-

Actions

-
- {actions.map((e, i) => ( -

- {e.name} - {JSON.stringify(e.values)} - {choosing ? ( - - ) : null} -

- ))} +
+

Actions

+
+ {actions.map((e, i) => ( +
+

{e.name}

+ {Object.entries(e.values).map(([key, value]) => ( +

+ {key}: {value} +

+ ))} + {choosing ? ( + + ) : null} +
+ ))} +
); diff --git a/app/routes/station/Effects/index.tsx b/app/routes/station/Effects/index.tsx index a5564832..93629e17 100644 --- a/app/routes/station/Effects/index.tsx +++ b/app/routes/station/Effects/index.tsx @@ -161,6 +161,10 @@ const Effects = () => { switch (payload.name) { case RadarZoomEvent.name: window.dispatchEvent(new RadarZoomEvent(payload.payload)); + break; + case RadarTiltEvent.name: + window.dispatchEvent(new RadarTiltEvent(payload.payload)); + break; } } }, []); diff --git a/app/utils/.server/evaluateEntityQuery.ts b/app/utils/.server/evaluateEntityQuery.ts index 0b1a41df..97f52bc0 100644 --- a/app/utils/.server/evaluateEntityQuery.ts +++ b/app/utils/.server/evaluateEntityQuery.ts @@ -424,36 +424,3 @@ export async function triggerStep(step: Entity) { }); } } - -export async function processTriggers(ecs: ECS, event?: { event: string; values: any }) { - const triggers = [...(ecs.componentCache.get("isTrigger") || [])]; - if (!triggers) return; - for (const trigger of triggers) { - if (!trigger.components.isTrigger || !trigger.components.isTrigger.active) continue; - const { conditions, blocks, stepId, localVariables, callReturnBlocks } = - trigger.components.isTrigger; - const match = evaluateTriggerCondition(ecs, conditions, event); - if (match) { - trigger.updateComponent("isTrigger", { - triggeredAt: new Date(), - ...(trigger.components.isTrigger.multiple ? {} : { active: false }), - }); - await executeBlocks( - ecs, - blocks.map((action) => { - if (action.action === "timeline.advance") { - return { - ...action, - values: { - ...action.values, - stepId: stepId, - }, - }; - } - return action; - }), - { stepId, localVariables, theResult: match, callReturnBlocks }, - ); - } - } -} diff --git a/app/utils/.server/executeBlocks.test.ts b/app/utils/.server/executeBlocks.test.ts index 92850e69..f3687a34 100644 --- a/app/utils/.server/executeBlocks.test.ts +++ b/app/utils/.server/executeBlocks.test.ts @@ -3,8 +3,8 @@ import { TimerSystem } from "@thorium/.server/systems/TimerSystem"; import { createMockDataContext } from "@thorium/utils/.server/createMockDataContext"; import { DataStore } from "@thorium/utils/.server/db-fs"; import { testDataStoreProps } from "@thorium/utils/.server/db-fs/testDataStoreProps"; -import { processTriggers } from "@thorium/utils/.server/evaluateEntityQuery"; import { executeBlocks } from "@thorium/utils/.server/executeBlocks"; +import { processTriggers } from "@thorium/utils/.server/processTriggers"; import { Entity } from "@thorium/utils/ecs"; import { expect, it, aroundEach } from "vitest"; diff --git a/app/utils/.server/executeBlocks.ts b/app/utils/.server/executeBlocks.ts index 99f3683b..7e20d81d 100644 --- a/app/utils/.server/executeBlocks.ts +++ b/app/utils/.server/executeBlocks.ts @@ -91,7 +91,6 @@ export async function executeBlocks( } case "IfCondition": { let response = true; - for (const condition of block.conditions) { if (!evaluateCondition(condition, localVariables, ecs)) { response = false; diff --git a/app/utils/.server/processTriggers.ts b/app/utils/.server/processTriggers.ts new file mode 100644 index 00000000..a16ba477 --- /dev/null +++ b/app/utils/.server/processTriggers.ts @@ -0,0 +1,36 @@ +import { evaluateTriggerCondition } from "@thorium/utils/.server/evaluateEntityQuery"; +import { executeBlocks } from "@thorium/utils/.server/executeBlocks"; +import type { ECS } from "@thorium/utils/ecs"; + +export async function processTriggers(ecs: ECS, event?: { event: string; values: any }) { + const triggers = [...(ecs.componentCache.get("isTrigger") || [])]; + if (!triggers) return; + for (const trigger of triggers) { + if (!trigger.components.isTrigger || !trigger.components.isTrigger.active) continue; + const { conditions, blocks, stepId, localVariables, callReturnBlocks } = + trigger.components.isTrigger; + const match = evaluateTriggerCondition(ecs, conditions, event); + if (match) { + trigger.updateComponent("isTrigger", { + triggeredAt: new Date(), + ...(trigger.components.isTrigger.multiple ? {} : { active: false }), + }); + await executeBlocks( + ecs, + blocks.map((action) => { + if (action.action === "timeline.advance") { + return { + ...action, + values: { + ...action.values, + stepId: stepId, + }, + }; + } + return action; + }), + { stepId, localVariables, theResult: match, callReturnBlocks }, + ); + } + } +} diff --git a/app/utils/.server/triggerAction.ts b/app/utils/.server/triggerAction.ts index 000394b4..f6e9146c 100644 --- a/app/utils/.server/triggerAction.ts +++ b/app/utils/.server/triggerAction.ts @@ -1,7 +1,7 @@ import { DataContext } from "@thorium/.server/DataContext"; import { router, type AllSends, type SendInputs } from "@thorium/.server/init/router"; -import { processTriggers } from "@thorium/utils/.server/evaluateEntityQuery"; import { notifyActions, notifyEvents } from "@thorium/utils/.server/notifyActions"; +import { processTriggers } from "@thorium/utils/.server/processTriggers"; import { callProcedure } from "@thorium/utils/live-query/.server/router"; import { DataStore } from "./db-fs";