Something went wrong. Try again.
Starship Simulator Controls thoriumsim.com
Something went wrong. Try again.
5.6 kB · 167 lines
TypeScript
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168import type { Sound } from "@thorium/ecs-components/sound";import { generateIncrementedName } from "@thorium/utils/generateIncrementedName";import type { Kelvin, KelvinPerSecond, MegaWatt } from "@thorium/utils/unitTypes";import z from "zod";
import type BasePlugin from "..";import { Aspect } from "../Aspect";import type { ShipSystemFlags, ShipSystemTypes } from "./shipSystemTypes";
const systemPlugins: Record<string, typeof BaseShipSystemPlugin> = {};export function registerSystem(name: string, sys: typeof BaseShipSystemPlugin) { systemPlugins[name] = sys;}
export const baseShipSystemSchema = z.object({ name: z.string(), description: z.string(), tags: z.string().array(), allowMultiple: z.boolean(), powerLevels: z.number().array(), powerActivated: z.boolean(), connectedBatteryType: z.enum(["none", "capacity", "output", "median"]), powerToHeat: z.number(), heatDissipationRate: z.number(), nominalHeat: z.number(), maxSafeHeat: z.number(), maxHeat: z.number(), coolantVolume: z.number(), coolantTransferRate: z.number(), coolantConsumptionRate: z.number(), offlineEfficiency: z.number(), onlineEfficiency: z.number(), overloadDamageMultiplier: z.number(), minSignature: z.number(), maxSignature: z.number(), signatureSpike: z.number(), signatureSpikeDuration: z.number(), entropyMultiplier: z.number(),});
/** * The base class to use when creating system plugins * * Eventually this will include generic properties for power, heat, and efficiency */export default class BaseShipSystemPlugin extends Aspect { static flags: ShipSystemFlags[] = ["damage", "heat", "power"]; static flightModes = ["nova", "legacy"]; apiVersion = "shipSystems/v1" as const; kind = "shipSystems" as const; name: string; description: string; type: keyof typeof ShipSystemTypes; tags: string[]; /** * Extend the subclass to include the specific images and sound effects * for this system */ assets: Record<string, string[]>;
soundEffects?: Record<string, Sound[]>;
allowMultiple: boolean;
/////////// // Power // /////////// /** * The power levels for a system. If no entries are provided, the system will operate * without any power. The lowest entry is the minimum amount of power required to * make this system operate in megawatts. The highest is the maximum threshold of power * usage for safely using this system in megawatts **/ powerLevels: MegaWatt[]; /** Whether the system is connected to reactor power */ powerActivated: boolean; /** What type, of the available batteries, should this system connect itself to? */ connectedBatteryType: "none" | "capacity" | "output" | "median";
////////// // Heat // ////////// /** * The rate at which heat can transfer in or out. * Heat generated by this entity isn't bound by this number */ powerToHeat: KelvinPerSecond;
/** * The standard heat level. When plotted, this * represents the very bottom of the heat bar. */ nominalHeat: Kelvin;
/** * The temperature at which this system starts experiencing * efficiency decreases due to overheating. */ maxSafeHeat: Kelvin;
/** * The maximum possible temperature. Represents the very top * of the heat bar graph. */ maxHeat: Kelvin;
/** * How much volume the coolant takes up in this system in m^3. * This affects both how fast systems heat up and how quickly * they cool down when attached to the coolant loop. **/ coolantVolume: number;
coolantTransferRate: number; coolantConsumptionRate: number; //////////// // Damage // //////////// offlineEfficiency: number; onlineEfficiency: number; overloadDamageMultiplier: number; minSignature: number; maxSignature: number; signatureSpike: number; signatureSpikeDuration: number; entropyMultiplier: number;
constructor(params: Partial<BaseShipSystemPlugin>, plugin: BasePlugin) { const name = generateIncrementedName( params.name || `New ${params.type}`, plugin.aspects.shipSystems.map((sys) => sys.name), ); super({ name, ...params }, { kind: "shipSystems" }, plugin); this.name = name || ""; this.type = params.type || "generic"; this.description = params.description || ""; this.tags = params.tags || []; this.assets = params.assets || {}; this.soundEffects = params.soundEffects; this.allowMultiple = params.allowMultiple ?? false; this.powerLevels = params.powerLevels || [5, 20]; this.powerActivated = params.powerActivated ?? true; this.connectedBatteryType = params.connectedBatteryType || "none"; this.powerToHeat = params.powerToHeat || 0.1; this.nominalHeat = params.nominalHeat || 295.37; this.maxSafeHeat = params.maxSafeHeat || 1000; this.maxHeat = params.maxHeat || 2500; this.coolantVolume = params.coolantVolume || 100; this.offlineEfficiency = params.offlineEfficiency || 0.5; this.onlineEfficiency = params.onlineEfficiency || 0.8; this.overloadDamageMultiplier = params.overloadDamageMultiplier || 0.015; this.minSignature = params.minSignature || 0; this.maxSignature = params.maxSignature || 1; this.signatureSpike = params.signatureSpike || 2; this.signatureSpikeDuration = params.signatureSpikeDuration || 5; // This provides about 15% damage to all systems over the course of a 2.5 hour mission this.entropyMultiplier = params.entropyMultiplier || 0.00025;
this.coolantTransferRate = params.coolantTransferRate || 1; this.coolantConsumptionRate = params.coolantConsumptionRate || 1; if (this.constructor.name === "BaseShipSystemPlugin") { if (systemPlugins[this.type]) { return new systemPlugins[this.type](params, plugin); } } }}