import type { DataContext } from "../utils/DataContext" ; import { FlightDataModel } from "../classes/FlightDataModel" ; import randomWords from "@thorium/random-words" ; import { pubsub } from "../utils/pubsub" ; import { thoriumPath } from "../utils/appPaths" ; import fs from "fs/promises" ; import { spawnShip } from "../spawners/ship" ; import type ShipPlugin from "../classes/Plugins/Ship" ; import type StationComplementPlugin from "../classes/Plugins/StationComplement" ; import { generateIncrementedName } from "../utils/generateIncrementedName" ; import { getFlights } from "../utils/getFlights" ; import type BasePlugin from "../classes/Plugins" ; interface FlightStartShips { shipTemplate : { pluginId : string ; shipId : string ; } ; shipName : string ; crewCount : number ; theme ? : { pluginId : string ; themeId : string ; } ; stationComplement ? : { pluginId : string ; stationId : string ; } ; missionName ? : { pluginId : string ; missionId : string ; } ; /**
     * The Name or ID of the starting point of the mission
     * in the universe.
     */ startingPoint ? : { pluginId : string ; startingPointId : string ; } ; } export const flightInputs = { flightStart : async ( context , { flightName , ships , } ) => { if ( context . flight ) return context . flight ; const flightData = await getFlights ( ) ; flightName = generateIncrementedName ( flightName || randomWords ( 3 ) . join ( "-" ) , flightData . map ( f => f . name ) ) ; context . flight = new FlightDataModel ( { name : flightName , initialLoad : true , entities : [ ] , serverDataModel : context . server , } , { path : `/flights/${ flightName }.flight` } ) ; context . flight . initEcs ( context . server ) ; const activePlugins = context . server . plugins . filter ( p => p . active ) ; context . flight . pluginIds = activePlugins . map ( p => p . id ) ; for ( const ship of ships ) { const shipTemplate = activePlugins . reduce ( ( acc , plugin ) => { if ( acc ) return acc ; if ( plugin . id !== ship . shipTemplate . pluginId ) return acc ; return ( plugin . aspects . ships . find ( pluginShip => pluginShip . name === ship . shipTemplate . shipId ) || null ) ; } , null ) ; if ( ! shipTemplate ) continue ; const shipEntity = spawnShip ( shipTemplate , { name : ship . shipName , position : { x : 0 , y : 0 , z : 0 } , tags : [ "player" ] , } ) ; shipEntity . addComponent ( "isPlayerShip" ) ; let theme = ship . theme || null ; if ( ! theme ) { theme = activePlugins . reduce ( ( acc , plugin ) => { if ( acc ) return acc ; const theme = plugin . aspects ?. themes ?. [ 0 ] ; if ( ! theme ) return null ; return { pluginId : plugin . id , themeId : theme . name } ; } , null ) ; } if ( theme ) { shipEntity . addComponent ( "theme" , theme ) ; } let stationComplement = getStationComplement ( activePlugins , ship ) ; shipEntity . addComponent ( "stationComplement" , { stations : stationComplement ?. stations . map ( s => ( { ... s , logo : stationComplement ?. toJSON ( ) ?. assets [ `${ s . name }-logo` ] || "" , cards : s . cards . map ( c => { return { ... c , icon : stationComplement ?. toJSON ( ) ?. assets [ `${ s . name }-${ c . name }-icon` ] , } ; } ) , } ) ) || [ ] , } ) ; context . flight . ecs . addEntity ( shipEntity ) ; } context . server . activeFlightName = flightName ; pubsub . publish ( "flight" ) ; return context . flight ; } , flightLoad ( context , params ) { if ( context . flight ) return context . flight ; context . flight = new FlightDataModel ( { entities : [ ] , initialLoad : false , serverDataModel : context . server , } , { path : `/flights/${ params . flightName }.flight` } ) ; context . flight . initEcs ( context . server ) ; context . server . activeFlightName = params . flightName ; pubsub . publish ( "flight" ) ; return context . flight ; } , flightPause ( context ) { if ( context . flight ) { context . flight . paused = true ; } pubsub . publish ( "flight" ) ; return context . flight ; } , flightResume ( context ) { if ( context . flight ) { context . flight . paused = false ; } pubsub . publish ( "flight" ) ; return context . flight ; } , flightReset ( context ) { context . flight ?. reset ( ) ; pubsub . publish ( "flight" ) ; return context . flight ; } , flightStop ( context ) { if ( ! context . flight ) return null ; context . flight . paused = false ; context . flight . writeFile ( ) ; context . flight = null ; context . server . activeFlightName = null ; pubsub . publish ( "flight" ) ; return null ; } , async flightDelete ( context , { flightName } ) { if ( context . flight ?. name === flightName ) { context . flight = null ; context . server . activeFlightName = null ; } try { await fs . unlink ( `${ thoriumPath }/flights/${ flightName }.flight` ) ; } catch { } pubsub . publish ( "flight" ) ; pubsub . publish ( "flights" ) ; return null ; } , } ; function getStationComplement ( activePlugins , ship ) { let stationComplement = activePlugins . reduce ( ( acc , plugin ) => { if ( acc ) return acc ; if ( ship . stationComplement && plugin . id !== ship . stationComplement . pluginId ) return acc ; if ( ship . stationComplement ) { return ( plugin . aspects . stationComplements . find ( pluginStationComplement => pluginStationComplement . name === ship . stationComplement ?. stationId ) || null ) ; } return null ; } , null ) ; if ( ! stationComplement ) { stationComplement = activePlugins . reduce ( ( acc , plugin ) => { if ( acc ) return acc ; if ( ! plugin . default ) return acc ; return ( plugin . aspects . stationComplements . find ( pluginStationComplement => pluginStationComplement . stationCount === ship . crewCount ) || null ) ; } , null ) ; } return stationComplement ; }