-
-
Notifications
You must be signed in to change notification settings - Fork 22
Add main camera system #743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
9904869
d4f750d
c2dd8c5
0488566
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import type BasePlugin from ".."; | ||
| import BaseShipSystemPlugin, { registerSystem } from "./BaseSystem"; | ||
| import type { ShipSystemFlags } from "./shipSystemTypes"; | ||
|
|
||
| export default class MainCameraPlugin extends BaseShipSystemPlugin { | ||
| static flags: ShipSystemFlags[] = []; | ||
| type = "mainCamera" as const; | ||
| fov: number; | ||
|
|
||
| constructor(params: Partial<MainCameraPlugin>, plugin: BasePlugin) { | ||
| super(params, plugin); | ||
| this.fov = params.fov ?? 45; | ||
| } | ||
| } | ||
| registerSystem("mainCamera", MainCameraPlugin); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| import { pubsub } from "@thorium/.server/init/pubsub"; | ||
| import { t } from "@thorium/.server/init/t"; | ||
| import inputAuth from "@thorium/utils/.server/inputAuth"; | ||
| import { z } from "zod"; | ||
| import { | ||
| getShipSystem, | ||
| getShipSystemForInput, | ||
| pluginFilter, | ||
| systemInput, | ||
| } from "../utils"; | ||
| import type MainCameraPlugin from "@thorium/.server/classes/Plugins/ShipSystems/MainCamera"; | ||
|
|
||
| export const mainCamera = t.router({ | ||
| get: t.procedure | ||
| .input(systemInput) | ||
| .filter(pluginFilter) | ||
| .request(({ ctx, input }) => { | ||
| const system = getShipSystem({ input, ctx }); | ||
|
|
||
| if (system.type !== "mainCamera") | ||
| throw new Error("System is not Main Camera"); | ||
|
|
||
| return system as MainCameraPlugin; | ||
| }), | ||
| update: t.procedure | ||
| .input( | ||
| z.object({ | ||
| pluginId: z.string(), | ||
| systemId: z.string(), | ||
| shipPluginId: z.string().optional(), | ||
| shipId: z.string().optional(), | ||
| fov: z.number().min(10).max(120).optional(), | ||
| }), | ||
| ) | ||
| .send(({ ctx, input }) => { | ||
| inputAuth(ctx); | ||
| const [system, override] = getShipSystemForInput<"mainCamera">( | ||
| ctx, | ||
| input, | ||
| ); | ||
| const shipSystem = override || system; | ||
|
|
||
| if (typeof input.fov !== "undefined") { | ||
| shipSystem.fov = input.fov; | ||
| } | ||
|
|
||
| pubsub.publish.plugin.systems.get({ | ||
| pluginId: input.pluginId, | ||
| }); | ||
| if (input.shipPluginId && input.shipId) { | ||
| pubsub.publish.plugin.ship.get({ | ||
| pluginId: input.shipPluginId, | ||
| shipId: input.shipId, | ||
| }); | ||
| } | ||
|
|
||
| return shipSystem; | ||
| }), | ||
| }); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,33 @@ | ||||||
| const colorBars = [ | ||||||
| "#ffffff", | ||||||
| "#ffff00", | ||||||
| "#00ffff", | ||||||
| "#00ff00", | ||||||
| "#ff00ff", | ||||||
| "#ff0000", | ||||||
| "#0000ff", | ||||||
| ]; | ||||||
|
|
||||||
| export function NoSignal() { | ||||||
| return ( | ||||||
| <div className="w-full h-full bg-black flex items-center justify-center"> | ||||||
| <div className="w-full"> | ||||||
| <div className="flex h-16"> | ||||||
| {colorBars.map((color) => ( | ||||||
| <div | ||||||
| key={color} | ||||||
| className="flex-1" | ||||||
| style={{ backgroundColor: color }} | ||||||
| /> | ||||||
| ))} | ||||||
| </div> | ||||||
| <span className="block text-white text-3xl tracking-[0.3em] font-bold text-center mt-4 uppercase"> | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's not use the
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| No Signal Found | ||||||
| </span> | ||||||
| <p className="text-white/60 text-sm tracking-widest text-center mt-2 uppercase"> | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case you couldn't tell, I really don't like uppercase.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| Main Camera System Missing | ||||||
| </p> | ||||||
| </div> | ||||||
| </div> | ||||||
| ); | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,6 +2,22 @@ import { t } from "@thorium/.server/init/t"; | |||||
| import { z } from "zod"; | ||||||
|
|
||||||
| export const viewscreen = t.router({ | ||||||
| camera: t.procedure | ||||||
| .input(z.object({ shipId: z.number() })) | ||||||
| .autoPublish([], () => null) | ||||||
| .request(({ ctx, input }) => { | ||||||
| if (!ctx.flight?.ecs) return null; | ||||||
| for (const [, entity] of ctx.flight.ecs.entities) { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be better. We cache entities by component using
Suggested change
|
||||||
| if ( | ||||||
| entity.components.isShipSystem?.type === "mainCamera" && | ||||||
| entity.components.isShipSystem?.shipId === input.shipId && | ||||||
| entity.components.isMainCamera | ||||||
| ) { | ||||||
| return { fov: entity.components.isMainCamera.fov }; | ||||||
| } | ||||||
| } | ||||||
| return null; | ||||||
| }), | ||||||
| system: t.procedure | ||||||
| .input(z.object({ clientId: z.string() })) | ||||||
| .autoPublish([], () => null) | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { z } from "zod"; | ||
|
|
||
| export const isMainCamera = z | ||
| .object({ | ||
| fov: z.number().default(45), | ||
| }) | ||
| .default({}); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| import { q } from "@thorium/context/AppContext"; | ||
| import Input from "@thorium/ui/Input"; | ||
| import { useContext, useReducer } from "react"; | ||
| import { useParams } from "react-router"; | ||
| import { ShipPluginIdContext } from "@thorium/context/ShipSystemOverrideContext"; | ||
| import { OverrideResetButton } from "../OverrideResetButton"; | ||
| import { Navigate } from "@thorium/components/Navigate"; | ||
|
|
||
| export default function MainCameraConfig() { | ||
| const { pluginId, systemId, shipId } = useParams() as { | ||
| pluginId: string; | ||
| systemId: string; | ||
| shipId: string; | ||
| }; | ||
| const shipPluginId = useContext(ShipPluginIdContext); | ||
|
|
||
| const [system] = q.plugin.systems.mainCamera.get.useNetRequest({ | ||
| pluginId, | ||
| systemId, | ||
| shipId, | ||
| shipPluginId, | ||
| }); | ||
| const [rekey, setRekey] = useReducer(() => Math.random(), Math.random()); | ||
| const key = `${systemId}${rekey}`; | ||
| if (!system) return <Navigate to={`/config/${pluginId}/systems`} />; | ||
|
|
||
| return ( | ||
| <fieldset key={key} className="flex-1 overflow-y-auto"> | ||
| <div className="flex flex-wrap"> | ||
| <div className="flex-1 pr-4"> | ||
| <div className="pb-2 flex"> | ||
| <Input | ||
| label="Viewscreen FOV" | ||
| labelHidden={false} | ||
| type="number" | ||
| inputMode="numeric" | ||
| min={10} | ||
| max={120} | ||
| defaultValue={system.fov} | ||
| helperText="Vertical field of view for the viewscreen display (degrees)" | ||
| onBlur={(e: any) => { | ||
| const val = Number(e.target.value); | ||
| if (!Number.isNaN(val) && val >= 10 && val <= 120) { | ||
| q.plugin.systems.mainCamera.update.netSend({ | ||
| pluginId, | ||
| systemId, | ||
| shipId, | ||
| shipPluginId, | ||
| fov: val, | ||
| }); | ||
| } | ||
| }} | ||
| /> | ||
| <OverrideResetButton | ||
| property="fov" | ||
| setRekey={setRekey} | ||
| className="mt-6" | ||
| /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </fieldset> | ||
| ); | ||
| } |


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we might want to include damage on here. The view screen being damaged will happen in missions I'm sure, and we should give the crew the ability to repair it themselves.
Not sure about power — is it worth an extra bar of power for such a minor system? I don't know.