Adapt system and planet managers to use common managers
This commit is contained in:
		
							parent
							
								
									d0993a427f
								
							
						
					
					
						commit
						40499415be
					
				| 
						 | 
				
			
			@ -3,7 +3,7 @@ import { ObjectId } from 'mongodb';
 | 
			
		|||
import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver';
 | 
			
		||||
import { getAllResources } from '../lib/db/resources';
 | 
			
		||||
import locationManager from '../lib/classes/managers/LocationManager';
 | 
			
		||||
import { Resource } from '../lib/classes/managers/ResourceManager';
 | 
			
		||||
import { Resource } from '../lib/classes/managers/abstract/ResourceManager';
 | 
			
		||||
 | 
			
		||||
const resourceTypes = await getAllResources();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ for(const key of planet.resources.resources) {
 | 
			
		|||
                </div>
 | 
			
		||||
                <div class="resourcebar-item-tooltip">
 | 
			
		||||
                    <div class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'avaliable')} - <span class="resourcebar-item-tooltip-avaliable">{Math.floor(res.amount).toString()}</span></div>
 | 
			
		||||
                    <div class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'production')} - <span class="resourcebar-item-tooltip-production">{res.perHourMiningRate.toString()}</span></div>
 | 
			
		||||
                    <div class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'production')} - <span class="resourcebar-item-tooltip-production">{res.perHourMiningRate?.toString() ?? "0"}</span></div>
 | 
			
		||||
                    <div class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'capacity')} - <span class="resourcebar-item-tooltip-capacity">{'21372137'}</span></div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ export default class Building {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        // research
 | 
			
		||||
        const playerResearch = this.manager.planet.manager.owner.research;
 | 
			
		||||
        const playerResearch = this.manager.planet.system.data.ownedBy.research;
 | 
			
		||||
        let playerResearchCanBuild = { canBuild: true, missing: "" };
 | 
			
		||||
        for(const researchReq of this.data.requirements.research) {
 | 
			
		||||
            if((playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0) < researchReq.level) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import DBShip from "../../types/db/DBShip";
 | 
			
		||||
import ShipManager from "./managers/ShipManager";
 | 
			
		||||
import SystemManager from "./managers/SystemManager";
 | 
			
		||||
import ShipManager from "./managers/abstract/ShipManager";
 | 
			
		||||
 | 
			
		||||
export default class Ship {
 | 
			
		||||
    manager: ShipManager;
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +14,7 @@ export default class Ship {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    async checkRequiredResources(): Promise<boolean> {
 | 
			
		||||
        const resources = await this.manager.planet.resources.calculateCurrentAvailableResources();
 | 
			
		||||
        const resources = await this.manager.manager.resources.calculateCurrentAvailableResources();
 | 
			
		||||
 | 
			
		||||
        const requirements = this.data.requirements.resources;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +34,8 @@ export default class Ship {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    async checkRequirements(): Promise<{ canBuild: boolean, error: string }> {
 | 
			
		||||
        const playerBuildings = this.manager.planet.buildings.buildings;
 | 
			
		||||
        if(!(this.manager.manager instanceof SystemManager)) {
 | 
			
		||||
            const playerBuildings = this.manager.manager.buildings.buildings;
 | 
			
		||||
            let playerBuildingsCanBuild = { canBuild: true, missing: "" };
 | 
			
		||||
            this.data.requirements.buildings.forEach((buildingReq: any) => {
 | 
			
		||||
                if((playerBuildings.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0) < buildingReq.level) {
 | 
			
		||||
| 
						 | 
				
			
			@ -45,9 +47,23 @@ export default class Ship {
 | 
			
		|||
                canBuild: false,
 | 
			
		||||
                error: playerBuildingsCanBuild.missing
 | 
			
		||||
            }
 | 
			
		||||
        } /*else { //TODO: check for structures requirements
 | 
			
		||||
            const structures = this.manager.manager.structures.structures;
 | 
			
		||||
            let playerStructuresCanBuild = { canBuild: true, missing: "" };
 | 
			
		||||
            this.data.requirements.structures.forEach((buildingReq: any) => {
 | 
			
		||||
                if((structures.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0) < buildingReq.level) {
 | 
			
		||||
                    playerStructuresCanBuild = { canBuild: false, missing: `${buildingReq.id} level ${buildingReq.level} required, found ${structures.filter((structure) => structure.data.id === buildingReq.id)[0]?.level ?? 0}` };
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            if(!playerStructuresCanBuild.canBuild) return {
 | 
			
		||||
                canBuild: false,
 | 
			
		||||
                error: playerStructuresCanBuild.missing
 | 
			
		||||
            }
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        // research
 | 
			
		||||
        const playerResearch = this.manager.planet.manager.owner.research;
 | 
			
		||||
        const playerResearch = this.manager.manager instanceof SystemManager ? this.manager.manager.data.ownedBy.research : this.manager.manager.system.data.ownedBy.research;
 | 
			
		||||
        let playerResearchCanBuild = { canBuild: true, missing: "" };
 | 
			
		||||
        for(const researchReq of this.data.requirements.research) {
 | 
			
		||||
            if(playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0 < researchReq.level) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,59 +12,59 @@ export default class Structure {
 | 
			
		|||
        this.level = level;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // async checkRequiredResources(level: number): Promise<boolean> {
 | 
			
		||||
    //     const resources = await this.manager.planet.resources.calculateCurrentAvailableResources();
 | 
			
		||||
    async checkRequiredResources(level: number): Promise<boolean> {
 | 
			
		||||
        const resources = await this.manager.system.resources.calculateCurrentAvailableResources();
 | 
			
		||||
 | 
			
		||||
    //     const requirements = this.data.requirements.resources;
 | 
			
		||||
        const requirements = this.data.requirements.resources;
 | 
			
		||||
 | 
			
		||||
    //     let canBuild = true;
 | 
			
		||||
        let canBuild = true;
 | 
			
		||||
 | 
			
		||||
    //     for(let res of requirements) {
 | 
			
		||||
    //         const resource = resources.find(r => r.id === res.id);
 | 
			
		||||
    //         if(!resource) return false;
 | 
			
		||||
        for(let res of requirements) {
 | 
			
		||||
            const resource = resources.find(r => r.id === res.id);
 | 
			
		||||
            if(!resource) return false;
 | 
			
		||||
 | 
			
		||||
    //         const required = Math.pow(this.data.multiplier, level) * res.amount;
 | 
			
		||||
            const required = Math.pow(this.data.multiplier, level) * res.amount;
 | 
			
		||||
 | 
			
		||||
    //         if(resource.amount < required) {
 | 
			
		||||
    //             canBuild = false;
 | 
			
		||||
    //             break;
 | 
			
		||||
    //         }
 | 
			
		||||
    //     }
 | 
			
		||||
            if(resource.amount < required) {
 | 
			
		||||
                canBuild = false;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    //     return canBuild;
 | 
			
		||||
    // }
 | 
			
		||||
        return canBuild;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // async checkRequirements(): Promise<{ canBuild: boolean, error: string }> {
 | 
			
		||||
    //     const playerBuildings = this.manager.buildings;
 | 
			
		||||
    //     let playerBuildingsCanBuild = { canBuild: true, missing: "" };
 | 
			
		||||
    //     this.data.requirements.buildings.forEach((buildingReq: any) => {
 | 
			
		||||
    //         if(playerBuildings.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0 < buildingReq.level) {
 | 
			
		||||
    //             playerBuildingsCanBuild = { canBuild: false, missing: `${buildingReq.id} level ${buildingReq.level} required, found ${playerBuildings.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0}` };
 | 
			
		||||
    //             return;
 | 
			
		||||
    //         }
 | 
			
		||||
    //     });
 | 
			
		||||
    //     if(!playerBuildingsCanBuild.canBuild) return {
 | 
			
		||||
    //         canBuild: false,
 | 
			
		||||
    //         error: playerBuildingsCanBuild.missing
 | 
			
		||||
    //     }
 | 
			
		||||
    async checkRequirements(): Promise<{ canBuild: boolean, error: string }> {
 | 
			
		||||
        const playerStructures = this.manager.structures;
 | 
			
		||||
        let playerStructuresCanBuild = { canBuild: true, missing: "" };
 | 
			
		||||
        this.data.requirements.structures.forEach((structureReq: any) => {
 | 
			
		||||
            if(playerStructures.filter((structure) => structure.data.id === structureReq.id)[0]?.level ?? 0 < structureReq.level) {
 | 
			
		||||
                playerStructuresCanBuild = { canBuild: false, missing: `${structureReq.id} level ${structureReq.level} required, found ${playerStructures.filter((structure) => structure.data.id === structureReq.id)[0]?.level ?? 0}` };
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        if(!playerStructuresCanBuild.canBuild) return {
 | 
			
		||||
            canBuild: false,
 | 
			
		||||
            error: playerStructuresCanBuild.missing
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    //     // research
 | 
			
		||||
    //     const playerResearch = this.manager.planet.manager.owner.research;
 | 
			
		||||
    //     let playerResearchCanBuild = { canBuild: true, missing: "" };
 | 
			
		||||
    //     for(const researchReq of this.data.requirements.research) {
 | 
			
		||||
    //         if((playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0) < researchReq.level) {
 | 
			
		||||
    //             playerResearchCanBuild = { canBuild: false, missing: `${researchReq.id} level ${researchReq.level} required, found ${playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0}` };
 | 
			
		||||
    //         }
 | 
			
		||||
    //     };
 | 
			
		||||
        // research
 | 
			
		||||
        const playerResearch = this.manager.system.data.ownedBy.research;
 | 
			
		||||
        let playerResearchCanBuild = { canBuild: true, missing: "" };
 | 
			
		||||
        for(const researchReq of this.data.requirements.research) {
 | 
			
		||||
            if((playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0) < researchReq.level) {
 | 
			
		||||
                playerResearchCanBuild = { canBuild: false, missing: `${researchReq.id} level ${researchReq.level} required, found ${playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0}` };
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
    //     if(!playerResearchCanBuild.canBuild) return {
 | 
			
		||||
    //         canBuild: false,
 | 
			
		||||
    //         error: playerResearchCanBuild.missing
 | 
			
		||||
    //     }
 | 
			
		||||
        if(!playerResearchCanBuild.canBuild) return {
 | 
			
		||||
            canBuild: false,
 | 
			
		||||
            error: playerResearchCanBuild.missing
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    //     return {
 | 
			
		||||
    //         canBuild: true,
 | 
			
		||||
    //         error: ""
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
        return {
 | 
			
		||||
            canBuild: true,
 | 
			
		||||
            error: ""
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,11 +3,12 @@ import MissionType from "../../../types/MissionType";
 | 
			
		|||
import DBFleet from "../../../types/db/DBFleet";
 | 
			
		||||
import { updateFleet } from "../../db/fleet";
 | 
			
		||||
import { Planet } from "./PlanetManager";
 | 
			
		||||
import SystemManager, { System } from "./SystemManager";
 | 
			
		||||
 | 
			
		||||
export type Fleet = {
 | 
			
		||||
    id: ObjectId,
 | 
			
		||||
    source: Planet,
 | 
			
		||||
    destination: Planet,
 | 
			
		||||
    source: Planet | SystemManager,
 | 
			
		||||
    destination: Planet | SystemManager,
 | 
			
		||||
    departureTime: Date,
 | 
			
		||||
    arrivalTime: Date,
 | 
			
		||||
    returning: boolean,
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +20,7 @@ export type Fleet = {
 | 
			
		|||
export default class FleetManager {
 | 
			
		||||
    data: Fleet;
 | 
			
		||||
 | 
			
		||||
    constructor(id: ObjectId, source: Planet, destination: Planet, departureTime: Date, arrivalTime: Date, returning: boolean, mission: MissionType, ships: Array<{ id: string, amount: number }>, cargo: Array<{ id: string, amount: number }>) {
 | 
			
		||||
    constructor(id: ObjectId, source: Planet | SystemManager, destination: Planet | SystemManager, departureTime: Date, arrivalTime: Date, returning: boolean, mission: MissionType, ships: Array<{ id: string, amount: number }>, cargo: Array<{ id: string, amount: number }>) {
 | 
			
		||||
        this.data = {
 | 
			
		||||
            id,
 | 
			
		||||
            source,
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +34,32 @@ export default class FleetManager {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    isSourcePlanet(): this is { data: { source: Planet } } {
 | 
			
		||||
        return 'resources' in this.data.source;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    isSourceSystem(): this is { data: { source: SystemManager } } {
 | 
			
		||||
        return 'structures' in this.data.source;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    isDestinationPlanet(): this is { data: { destination: Planet } } {
 | 
			
		||||
        return 'resources' in this.data.destination;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    isDestinationSystem(): this is { data: { destination: SystemManager } } {
 | 
			
		||||
        return 'structures' in this.data.destination;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getSourceOwner() {
 | 
			
		||||
        if(this.isSourcePlanet()) return this.data.source.system.data.ownedBy;
 | 
			
		||||
        if(this.isSourceSystem()) return this.data.source.data.ownedBy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getDestinationOwner() {
 | 
			
		||||
        if(this.isDestinationPlanet()) return this.data.destination.system.data.ownedBy;
 | 
			
		||||
        if(this.isDestinationSystem()) return this.data.destination.data.ownedBy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async checkStatus(): Promise<{ finished: boolean, fleet: Fleet }> {
 | 
			
		||||
        if(this.data.arrivalTime.getTime() < Date.now()) {
 | 
			
		||||
            const finished = await this.finish();
 | 
			
		||||
| 
						 | 
				
			
			@ -82,10 +109,13 @@ export default class FleetManager {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
        const source = this.data.source instanceof SystemManager ? this.data.source.data._id : this.data.source._id;
 | 
			
		||||
        const destination = this.data.destination instanceof SystemManager ? this.data.destination.data._id : this.data.destination._id;
 | 
			
		||||
 | 
			
		||||
        const data: DBFleet = {
 | 
			
		||||
            _id: this.data.id,
 | 
			
		||||
            source: this.data.source._id,
 | 
			
		||||
            destination: this.data.destination._id,
 | 
			
		||||
            source,
 | 
			
		||||
            destination,
 | 
			
		||||
            departureTime: this.data.departureTime,
 | 
			
		||||
            arrivalTime: this.data.arrivalTime,
 | 
			
		||||
            returning: this.data.returning,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,13 @@
 | 
			
		|||
import { ObjectId } from "mongodb";
 | 
			
		||||
import PlanetManager, { Planet } from "./PlanetManager";
 | 
			
		||||
import { getAllFleet } from "../../db/fleet";
 | 
			
		||||
import { getAllGalaxies } from "../../db/galaxies";
 | 
			
		||||
import { getSectorById } from "../../db/sectors";
 | 
			
		||||
import { getSystemById } from "../../db/systems";
 | 
			
		||||
import { getAllUsers } from "../../db/users";
 | 
			
		||||
import User from "../User";
 | 
			
		||||
import StructureManager from "./StructureManager";
 | 
			
		||||
import FleetManager from "./FleetManager";
 | 
			
		||||
import { getAllFleet } from "../../db/fleet";
 | 
			
		||||
import { Planet } from "./PlanetManager";
 | 
			
		||||
import SystemManager, { System } from "./SystemManager";
 | 
			
		||||
 | 
			
		||||
export type Galaxy = {
 | 
			
		||||
    _id: ObjectId,
 | 
			
		||||
| 
						 | 
				
			
			@ -24,16 +24,7 @@ export type Sector = {
 | 
			
		|||
    galaxy: Galaxy,
 | 
			
		||||
    name: string,
 | 
			
		||||
    expedition: null,
 | 
			
		||||
    systems: Array<System>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type System = {
 | 
			
		||||
    _id: ObjectId,
 | 
			
		||||
    sector: Sector,
 | 
			
		||||
    name: string,
 | 
			
		||||
    ownedBy: User,
 | 
			
		||||
    structures: StructureManager,
 | 
			
		||||
    planets: PlanetManager
 | 
			
		||||
    systems: Array<SystemManager>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LocationManager {
 | 
			
		||||
| 
						 | 
				
			
			@ -99,14 +90,16 @@ class LocationManager {
 | 
			
		|||
                        ownedBy: user,
 | 
			
		||||
                        //@ts-ignore
 | 
			
		||||
                        structures: null,
 | 
			
		||||
                        planets: new PlanetManager(user)
 | 
			
		||||
                        //@ts-ignore
 | 
			
		||||
                        resources: null,
 | 
			
		||||
                        //@ts-ignore
 | 
			
		||||
                        ships: null,
 | 
			
		||||
                        planets: []
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    systemObject.structures = await new StructureManager(systemObject).init(systemData.structures);
 | 
			
		||||
                    const s = await new SystemManager(systemObject).fillData(systemData);
 | 
			
		||||
 | 
			
		||||
                    await systemObject.planets.fillData(systemObject, systemData.planets);
 | 
			
		||||
 | 
			
		||||
                    sectorObject.systems.push(systemObject);
 | 
			
		||||
                    sectorObject.systems.push(s);
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                console.log(`Loaded ${sectorObject.systems.length} systems from sector ${sectorObject.name}`);
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +119,7 @@ class LocationManager {
 | 
			
		|||
            const userDB = users.find(u => u._id.equals(user.id));
 | 
			
		||||
            const mainPlanet = this.getPlanet(userDB?.mainPlanet as ObjectId);
 | 
			
		||||
 | 
			
		||||
            if(!mainPlanet) throw new Error("Main planet not found");
 | 
			
		||||
            if(!mainPlanet) throw new Error(`Main planet not found for user ${user.username} (${user.id})`);
 | 
			
		||||
 | 
			
		||||
            user.mainPlanet = mainPlanet;
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			@ -134,8 +127,8 @@ class LocationManager {
 | 
			
		|||
        const fleets = await getAllFleet();
 | 
			
		||||
        for(const fleet of fleets) {
 | 
			
		||||
            if(fleet.arrivalTime > currentTime) {
 | 
			
		||||
                const source = this.getPlanet(fleet.source);
 | 
			
		||||
                const destination = this.getPlanet(fleet.destination);
 | 
			
		||||
                const source = this.getPlanet(fleet.source) || this.getSystem(fleet.source);
 | 
			
		||||
                const destination = this.getPlanet(fleet.destination) || this.getSystem(fleet.destination);
 | 
			
		||||
                
 | 
			
		||||
                if(source && destination) this.fleet.push(new FleetManager(
 | 
			
		||||
                    fleet._id,
 | 
			
		||||
| 
						 | 
				
			
			@ -156,6 +149,30 @@ class LocationManager {
 | 
			
		|||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    findId(id: ObjectId) {
 | 
			
		||||
        let found: SystemManager | Planet | null = null;
 | 
			
		||||
 | 
			
		||||
        for(const galaxy of this.galaxies) {
 | 
			
		||||
            for(const sector of galaxy.sectors) {
 | 
			
		||||
                for(const system of sector.systems) {
 | 
			
		||||
                    if(system.data._id.equals(id)) {
 | 
			
		||||
                        found = system;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    for(const planet of system.planets) {
 | 
			
		||||
                        if(planet._id.equals(id)) {
 | 
			
		||||
                            found = planet;
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return found;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getGalaxy(_id: ObjectId) {
 | 
			
		||||
        return this.galaxies.find(galaxy => galaxy._id.equals(_id));
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -169,20 +186,20 @@ class LocationManager {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    getSystem(_id: ObjectId) {
 | 
			
		||||
        let foundSystem: System | undefined;
 | 
			
		||||
        let foundSystem: SystemManager | undefined;
 | 
			
		||||
        this.galaxies.find(galaxy => galaxy.sectors.find(sector => sector.systems.find(system => {
 | 
			
		||||
            if(system._id.equals(_id)) foundSystem = system
 | 
			
		||||
            if(system.data._id.equals(_id)) foundSystem = system
 | 
			
		||||
        })));
 | 
			
		||||
        return foundSystem
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getSystemsOwnedBy(id: ObjectId) {
 | 
			
		||||
        const systems: System[] = [];
 | 
			
		||||
        const systems: SystemManager[] = [];
 | 
			
		||||
 | 
			
		||||
        for(const galaxy of this.galaxies) {
 | 
			
		||||
            for(const sector of galaxy.sectors) {
 | 
			
		||||
                for(const system of sector.systems) {
 | 
			
		||||
                    if(system.ownedBy.id.equals(id)) systems.push(system);
 | 
			
		||||
                    if(system.data.ownedBy.id.equals(id)) systems.push(system);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -196,7 +213,7 @@ class LocationManager {
 | 
			
		|||
        for(const galaxy of this.galaxies) {
 | 
			
		||||
            for(const sector of galaxy.sectors) {
 | 
			
		||||
                for(const system of sector.systems) {
 | 
			
		||||
                    foundPlanet = system.planets.getPlanetById(_id);
 | 
			
		||||
                    foundPlanet = system.planets.find(planet => planet._id.equals(_id));
 | 
			
		||||
                    if(foundPlanet) break;
 | 
			
		||||
                }
 | 
			
		||||
                if(foundPlanet) break;
 | 
			
		||||
| 
						 | 
				
			
			@ -222,7 +239,17 @@ class LocationManager {
 | 
			
		|||
 | 
			
		||||
    async getAllFleetByUserId(userId: string) {
 | 
			
		||||
        await this.updateFleet();
 | 
			
		||||
        return userId === '' ? [] : this.fleet.filter(fleet => fleet.data.source.manager.owner.id.equals(userId) || fleet.data.destination.manager.owner.id.equals(userId));
 | 
			
		||||
        return userId === '' ? [] : this.fleet.filter(fleet => {
 | 
			
		||||
            let found = false;
 | 
			
		||||
 | 
			
		||||
            if(fleet.data.source instanceof SystemManager) found = fleet.data.source.data.ownedBy.id.equals(userId);
 | 
			
		||||
            else found = fleet.data.source.system.data.ownedBy.id.equals(userId);
 | 
			
		||||
 | 
			
		||||
            if(fleet.data.destination instanceof SystemManager) found = fleet.data.destination.data.ownedBy.id.equals(userId);
 | 
			
		||||
            else found = fleet.data.destination.system.data.ownedBy.id.equals(userId);
 | 
			
		||||
            
 | 
			
		||||
            return found;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addFleet(fleet: FleetManager) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,57 +1,15 @@
 | 
			
		|||
import { ObjectId } from "mongodb";
 | 
			
		||||
import BuildingManager from "./BuildingManager";
 | 
			
		||||
import { getPlanetById } from "../../db/planets";
 | 
			
		||||
import ResourceManager from "./ResourceManager";
 | 
			
		||||
import User from "../User";
 | 
			
		||||
import ShipManager from "./ShipManager";
 | 
			
		||||
import { System } from "./LocationManager";
 | 
			
		||||
import PlanetResourceManager from "./PlanetResourceManager";
 | 
			
		||||
import ShipManager from "./PlanetShipManager";
 | 
			
		||||
import SystemManager from "./SystemManager";
 | 
			
		||||
 | 
			
		||||
export type Planet = {
 | 
			
		||||
    _id: ObjectId;
 | 
			
		||||
    manager: PlanetManager;
 | 
			
		||||
    system: SystemManager;
 | 
			
		||||
    name: string;
 | 
			
		||||
    fields: number;
 | 
			
		||||
    resources: ResourceManager;
 | 
			
		||||
    resources: PlanetResourceManager;
 | 
			
		||||
    buildings: BuildingManager;
 | 
			
		||||
    ships: ShipManager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default class PlanetManager {
 | 
			
		||||
    planets: Array<Planet> = [];
 | 
			
		||||
    owner: User;
 | 
			
		||||
    system!: System;
 | 
			
		||||
 | 
			
		||||
    constructor(user: User) {
 | 
			
		||||
        this.owner = user;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fillData(system: System, planets: ObjectId[]) {
 | 
			
		||||
        this.system = system;
 | 
			
		||||
        await Promise.all(planets.map(async planetId => {
 | 
			
		||||
            const planet = await getPlanetById(planetId);
 | 
			
		||||
 | 
			
		||||
            const planetObject: Planet = {
 | 
			
		||||
                _id: planet._id,
 | 
			
		||||
                manager: this,
 | 
			
		||||
                name: planet.name,
 | 
			
		||||
                fields: planet.fields,
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                resources: null,
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                buildings: null,
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                ships: null
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            planetObject.resources = await new ResourceManager(planetObject).init(planet.resources);
 | 
			
		||||
            planetObject.buildings = await new BuildingManager(planetObject).init(planet.buildings);
 | 
			
		||||
            planetObject.ships = await new ShipManager(planetObject).init(planet.ships);
 | 
			
		||||
 | 
			
		||||
            this.planets.push(planetObject);
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getPlanetById(id: ObjectId) {
 | 
			
		||||
        return this.planets.find(planet => planet._id.equals(id));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,22 +1,13 @@
 | 
			
		|||
import DBResource from "../../../types/db/DBResource";
 | 
			
		||||
import { updatePlanetResources } from "../../db/planets";
 | 
			
		||||
import { getAllResources } from "../../db/resources";
 | 
			
		||||
import { Planet } from "./PlanetManager";
 | 
			
		||||
import ResourceManager from "./abstract/ResourceManager";
 | 
			
		||||
 | 
			
		||||
export type Resource = {
 | 
			
		||||
    id: string,
 | 
			
		||||
    amount: number,
 | 
			
		||||
    lastUpdated: Date,
 | 
			
		||||
    perHourMiningRate: number,
 | 
			
		||||
    data: DBResource
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default class ResourceManager {
 | 
			
		||||
    resources: Array<Resource> = [];
 | 
			
		||||
    resourcesDB: DBResource[] = [];
 | 
			
		||||
export default class PlanetResourceManager extends ResourceManager {
 | 
			
		||||
    planet: Planet;
 | 
			
		||||
 | 
			
		||||
    constructor(planet: Planet) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.planet = planet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -100,73 +91,6 @@ export default class ResourceManager {
 | 
			
		|||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getResourceById(resId: string) {
 | 
			
		||||
        return this.resources.find(res => res.id === resId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async calculateCurrentAvailableResources() {
 | 
			
		||||
        this.resources.forEach(res => {
 | 
			
		||||
            const timeDiff = Math.abs((new Date()).getTime() - res.lastUpdated.getTime());
 | 
			
		||||
            const hours = timeDiff / (1000 * 60 * 60);
 | 
			
		||||
            const amountToAdd = hours * res.perHourMiningRate;
 | 
			
		||||
            res.amount += amountToAdd;
 | 
			
		||||
            res.lastUpdated = new Date();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        await updatePlanetResources(this.planet._id, this.resources);
 | 
			
		||||
 | 
			
		||||
        return this.resources;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getDifference(resources: { id: string, amount: number }[]): Promise<Array<Resource>> {
 | 
			
		||||
        const currentResources = await this.calculateCurrentAvailableResources();
 | 
			
		||||
        const difference: Resource[] = [];
 | 
			
		||||
 | 
			
		||||
        currentResources.forEach(res => {
 | 
			
		||||
            const currentRes = resources.find(r => r.id === res.id);
 | 
			
		||||
            if(currentRes) difference.push({
 | 
			
		||||
                id: res.id,
 | 
			
		||||
                amount: res.amount - currentRes.amount,
 | 
			
		||||
                lastUpdated: res.lastUpdated,
 | 
			
		||||
                perHourMiningRate: res.perHourMiningRate,
 | 
			
		||||
                data: res.data
 | 
			
		||||
            });
 | 
			
		||||
            else difference.push(res);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return difference;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    add(resources: Resource[]) {
 | 
			
		||||
        for(const res of resources) {
 | 
			
		||||
            const resource = this.resources.find(r => r.id === res.id);
 | 
			
		||||
            if(resource) resource.amount += res.amount;
 | 
			
		||||
            else this.resources.push(res);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async updateAmount(resources: { id: string, amount: number }[]) {
 | 
			
		||||
        await this.calculateCurrentAvailableResources();
 | 
			
		||||
        for(const res of resources) {
 | 
			
		||||
            const resource = this.resources.find(r => r.id === res.id);
 | 
			
		||||
            if(resource) resource.amount += res.amount;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setAmount(resources: { id: string, amount: number }[]) {
 | 
			
		||||
        for(const res of resources) {
 | 
			
		||||
            const resource = this.resources.find(r => r.id === res.id);
 | 
			
		||||
            if(resource) resource.amount = res.amount;
 | 
			
		||||
            else this.resources.push({
 | 
			
		||||
                id: res.id,
 | 
			
		||||
                amount: res.amount,
 | 
			
		||||
                lastUpdated: new Date(),
 | 
			
		||||
                perHourMiningRate: 0,
 | 
			
		||||
                data: this.resourcesDB.find(r => r.id === res.id)
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
        await updatePlanetResources(this.planet._id, this.resources.map(res => {
 | 
			
		||||
            return {
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
import { updatePlanetShips } from "../../db/planets";
 | 
			
		||||
import { Planet } from "./PlanetManager";
 | 
			
		||||
import ShipManager from "./abstract/ShipManager";
 | 
			
		||||
 | 
			
		||||
export default class PlanetShipManager extends ShipManager {
 | 
			
		||||
    constructor(planet: Planet) {
 | 
			
		||||
        super(planet);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get manager() {
 | 
			
		||||
        return this._manager as Planet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
        await updatePlanetShips(this.manager._id, this.ships.map(ship => { return { id: ship.data.id, amount: ship.amount } }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,17 +1,15 @@
 | 
			
		|||
import { updatePlanetBuildings } from '../../db/planets';
 | 
			
		||||
import Building from '../Building';
 | 
			
		||||
import DBStructure from '../../../types/db/DBStructure';
 | 
			
		||||
import { System } from './LocationManager';
 | 
			
		||||
import { getAllStructures } from '../../db/structures';
 | 
			
		||||
import Structure from '../Structure';
 | 
			
		||||
import { updateSystemStructures } from '../../db/systems';
 | 
			
		||||
import Structure from '../Structure';
 | 
			
		||||
import SystemManager from './SystemManager';
 | 
			
		||||
 | 
			
		||||
export default class StructureManager {
 | 
			
		||||
    structures: Array<Structure> = [];
 | 
			
		||||
    structuresDB: Array<DBStructure> = []
 | 
			
		||||
    system: System;
 | 
			
		||||
    system: SystemManager;
 | 
			
		||||
 | 
			
		||||
    constructor(system: System) {
 | 
			
		||||
    constructor(system: SystemManager) {
 | 
			
		||||
        this.system = system;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +43,6 @@ export default class StructureManager {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
        await updateSystemStructures(this.system._id, this.structures.map(structure => { return { id: structure.data.id, level: structure.level } }));
 | 
			
		||||
        await updateSystemStructures(this.system.data._id, this.structures.map(structure => { return { id: structure.data.id, level: structure.level } }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
import { ObjectId } from "mongodb";
 | 
			
		||||
import DBSystem from "../../../types/db/DBSystem";
 | 
			
		||||
import { getPlanetById } from "../../db/planets";
 | 
			
		||||
import User from "../User";
 | 
			
		||||
import BuildingManager from "./BuildingManager";
 | 
			
		||||
import { Sector } from "./LocationManager";
 | 
			
		||||
import { Planet } from "./PlanetManager";
 | 
			
		||||
import PlanetResourceManager from "./PlanetResourceManager";
 | 
			
		||||
import PlanetShipManager from "./PlanetShipManager";
 | 
			
		||||
import StructureManager from "./StructureManager";
 | 
			
		||||
import SystemResourceManager from "./SystemResourceManager";
 | 
			
		||||
import SystemShipManager from "./SystemShipManager";
 | 
			
		||||
 | 
			
		||||
export type System = {
 | 
			
		||||
    _id: ObjectId,
 | 
			
		||||
    sector: Sector,
 | 
			
		||||
    name: string,
 | 
			
		||||
    ownedBy: User,
 | 
			
		||||
    structures: StructureManager,
 | 
			
		||||
    resources: SystemResourceManager,
 | 
			
		||||
    ships: SystemShipManager,
 | 
			
		||||
    planets: Planet[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default class SystemManager {
 | 
			
		||||
    planets: Planet[] = [];
 | 
			
		||||
    structures: StructureManager;
 | 
			
		||||
    resources: SystemResourceManager;
 | 
			
		||||
    ships: SystemShipManager;
 | 
			
		||||
    data: System;
 | 
			
		||||
 | 
			
		||||
    constructor(data: System) {
 | 
			
		||||
        this.data = data;
 | 
			
		||||
        this.structures = new StructureManager(this);
 | 
			
		||||
        this.resources = new SystemResourceManager(this);
 | 
			
		||||
        this.ships = new SystemShipManager(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fillData(systemData: DBSystem) {
 | 
			
		||||
        await this.structures.init(systemData.structures);
 | 
			
		||||
        await this.resources.init(systemData.resources);
 | 
			
		||||
        await this.ships.init(systemData.ships);
 | 
			
		||||
 | 
			
		||||
        await Promise.all(systemData.planets.map(async planetId => {
 | 
			
		||||
            const planet = await getPlanetById(planetId);
 | 
			
		||||
 | 
			
		||||
            const planetObject: Planet = {
 | 
			
		||||
                _id: planet._id,
 | 
			
		||||
                system: this,
 | 
			
		||||
                name: planet.name,
 | 
			
		||||
                fields: planet.fields,
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                resources: null,
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                buildings: null,
 | 
			
		||||
                //@ts-ignore
 | 
			
		||||
                ships: null
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            planetObject.resources = await new PlanetResourceManager(planetObject).init(planet.resources);
 | 
			
		||||
            planetObject.buildings = await new BuildingManager(planetObject).init(planet.buildings);
 | 
			
		||||
            planetObject.ships = await new PlanetShipManager(planetObject).init(planet.ships);
 | 
			
		||||
 | 
			
		||||
            this.planets.push(planetObject);
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addPlanet(planet: Planet) {
 | 
			
		||||
        this.planets.push(planet);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,88 @@
 | 
			
		|||
import { getAllResources } from "../../db/resources";
 | 
			
		||||
import { updateSystemResources } from "../../db/systems";
 | 
			
		||||
import SystemManager from "./SystemManager";
 | 
			
		||||
import ResourceManager from "./abstract/ResourceManager";
 | 
			
		||||
 | 
			
		||||
export default class SystemResourceManager extends ResourceManager {
 | 
			
		||||
    system: SystemManager;
 | 
			
		||||
 | 
			
		||||
    constructor(system: SystemManager) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.system = system;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async init(resourceData?: { id: string, amount: number }[]) {
 | 
			
		||||
        const resources = await getAllResources();
 | 
			
		||||
 | 
			
		||||
        this.resourcesDB = resources;
 | 
			
		||||
 | 
			
		||||
        if(!resourceData || resourceData.length === 0) {
 | 
			
		||||
            resourceData = [
 | 
			
		||||
                {
 | 
			
		||||
                    id: "coal",
 | 
			
		||||
                    amount: 11
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "iron",
 | 
			
		||||
                    amount: 22
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "gold",
 | 
			
		||||
                    amount: 33
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "water",
 | 
			
		||||
                    amount: 44
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "sulfuric-acid",
 | 
			
		||||
                    amount: 55
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "liquid-nitrogen",
 | 
			
		||||
                    amount: 66
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "hydrogen",
 | 
			
		||||
                    amount: 77
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "oxygen",
 | 
			
		||||
                    amount: 88
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "helium-3",
 | 
			
		||||
                    amount: 99
 | 
			
		||||
                }
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            await updateSystemResources(this.system.data._id, this.resources);
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        resourceData.forEach(resource => {
 | 
			
		||||
            const resFromDB = resources.find(res => res.id === resource.id);
 | 
			
		||||
            if(resFromDB) this.resources.push({
 | 
			
		||||
                id: resource.id,
 | 
			
		||||
                amount: resource.amount,
 | 
			
		||||
                lastUpdated: null,
 | 
			
		||||
                perHourMiningRate: null,
 | 
			
		||||
                data: resFromDB
 | 
			
		||||
            })
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
        await updateSystemResources(this.system.data._id, this.resources.map(res => {
 | 
			
		||||
            return {
 | 
			
		||||
                id: res.id,
 | 
			
		||||
                amount: res.amount,
 | 
			
		||||
                lastUpdated: res.lastUpdated,
 | 
			
		||||
                perHourMiningRate: res.perHourMiningRate
 | 
			
		||||
            }
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
import { updateSystemShips } from "../../db/systems";
 | 
			
		||||
import SystemManager from "./SystemManager";
 | 
			
		||||
import ShipManager from "./abstract/ShipManager";
 | 
			
		||||
 | 
			
		||||
export default class SystemShipManager extends ShipManager {
 | 
			
		||||
    constructor(system: SystemManager) {
 | 
			
		||||
        super(system);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get manager() {
 | 
			
		||||
        return this._manager as SystemManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
        await updateSystemShips(this.manager.data._id, this.ships.map(ship => { return { id: ship.data.id, amount: ship.amount } }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,92 @@
 | 
			
		|||
import DBResource from "../../../../types/db/DBResource";
 | 
			
		||||
 | 
			
		||||
export type Resource = {
 | 
			
		||||
    id: string,
 | 
			
		||||
    amount: number,
 | 
			
		||||
    lastUpdated: Date | null,
 | 
			
		||||
    perHourMiningRate: number | null,
 | 
			
		||||
    data: DBResource
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default abstract class ResourceManager {
 | 
			
		||||
    resources: Resource[] = [];
 | 
			
		||||
    resourcesDB: DBResource[] = [];
 | 
			
		||||
 | 
			
		||||
    abstract sync(): Promise<void>;
 | 
			
		||||
 | 
			
		||||
    getResourceById(resId: string) {
 | 
			
		||||
        return this.resources.find(res => res.id === resId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async calculateCurrentAvailableResources() {
 | 
			
		||||
        for(const res of this.resources) {
 | 
			
		||||
            if(!res.lastUpdated || !res.perHourMiningRate) continue;
 | 
			
		||||
 | 
			
		||||
            const timeDiff = Math.abs((new Date()).getTime() - res.lastUpdated.getTime());
 | 
			
		||||
            const hours = timeDiff / (1000 * 60 * 60);
 | 
			
		||||
            const amountToAdd = hours * res.perHourMiningRate;
 | 
			
		||||
            res.amount += amountToAdd;
 | 
			
		||||
            res.lastUpdated = new Date();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        await this.sync();
 | 
			
		||||
 | 
			
		||||
        return this.resources;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getDifference(resources: { id: string, amount: number }[]): Promise<Array<Resource>> {
 | 
			
		||||
        const currentResources = await this.calculateCurrentAvailableResources();
 | 
			
		||||
        const difference: Resource[] = [];
 | 
			
		||||
 | 
			
		||||
        currentResources.forEach(res => {
 | 
			
		||||
            const currentRes = resources.find(r => r.id === res.id);
 | 
			
		||||
            if(currentRes) difference.push({
 | 
			
		||||
                id: res.id,
 | 
			
		||||
                amount: res.amount - currentRes.amount,
 | 
			
		||||
                lastUpdated: res.lastUpdated,
 | 
			
		||||
                perHourMiningRate: res.perHourMiningRate,
 | 
			
		||||
                data: res.data
 | 
			
		||||
            });
 | 
			
		||||
            else difference.push(res);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return difference;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    add(resources: Resource[]) {
 | 
			
		||||
        for(const res of resources) {
 | 
			
		||||
            const resource = this.resources.find(r => r.id === res.id);
 | 
			
		||||
            if(resource) resource.amount += res.amount;
 | 
			
		||||
            else this.resources.push(res);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async updateAmount(resources: { id: string, amount: number }[]) {
 | 
			
		||||
        await this.calculateCurrentAvailableResources();
 | 
			
		||||
        for(const res of resources) {
 | 
			
		||||
            const resource = this.resources.find(r => r.id === res.id);
 | 
			
		||||
            if(resource) resource.amount += res.amount;
 | 
			
		||||
            else this.resources.push({
 | 
			
		||||
                id: res.id,
 | 
			
		||||
                amount: res.amount,
 | 
			
		||||
                lastUpdated: new Date(),
 | 
			
		||||
                perHourMiningRate: 0,
 | 
			
		||||
                data: this.resourcesDB.find(r => r.id === res.id) as DBResource
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setAmount(resources: { id: string, amount: number }[]) {
 | 
			
		||||
        for(const res of resources) {
 | 
			
		||||
            const resource = this.resources.find(r => r.id === res.id);
 | 
			
		||||
            if(resource) resource.amount = res.amount;
 | 
			
		||||
            else this.resources.push({
 | 
			
		||||
                id: res.id,
 | 
			
		||||
                amount: res.amount,
 | 
			
		||||
                lastUpdated: new Date(),
 | 
			
		||||
                perHourMiningRate: 0,
 | 
			
		||||
                data: this.resourcesDB.find(r => r.id === res.id) as DBResource
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +1,22 @@
 | 
			
		|||
import { Planet } from './PlanetManager';
 | 
			
		||||
import { updatePlanetBuildings, updatePlanetShips } from '../../db/planets';
 | 
			
		||||
import DBShip from '../../../types/db/DBShip';
 | 
			
		||||
import { getAllShips } from '../../db/ships';
 | 
			
		||||
import Ship from '../Ship';
 | 
			
		||||
import { Planet } from '../PlanetManager';
 | 
			
		||||
import DBShip from '../../../../types/db/DBShip';
 | 
			
		||||
import { getAllShips } from '../../../db/ships';
 | 
			
		||||
import Ship from '../../Ship';
 | 
			
		||||
import SystemManager from '../SystemManager';
 | 
			
		||||
 | 
			
		||||
export default class ShipManager {
 | 
			
		||||
export default abstract class ShipManager {
 | 
			
		||||
    ships: Array<Ship> = [];
 | 
			
		||||
    shipsDB: Array<DBShip> = []
 | 
			
		||||
    planet: Planet;
 | 
			
		||||
    shipsDB: Array<DBShip> = [];
 | 
			
		||||
    protected _manager: Planet | SystemManager;
 | 
			
		||||
 | 
			
		||||
    constructor(planet: Planet) {
 | 
			
		||||
        this.planet = planet;
 | 
			
		||||
    constructor(manager: Planet | SystemManager) {
 | 
			
		||||
        this._manager = manager;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    abstract sync(): Promise<void>;
 | 
			
		||||
 | 
			
		||||
    abstract get manager(): Planet | SystemManager;
 | 
			
		||||
 | 
			
		||||
    async init(shipData: { id: string, amount: number }[]) {
 | 
			
		||||
        this.shipsDB = await getAllShips();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,8 +60,4 @@ export default class ShipManager {
 | 
			
		|||
            if(findShip.amount <= 0) this.ships.splice(this.ships.indexOf(findShip), 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
        await updatePlanetShips(this.planet._id, this.ships.map(ship => { return { id: ship.data.id, amount: ship.amount } }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,3 +25,21 @@ export const updateSystemStructures = async (systemId: ObjectId, structures: Arr
 | 
			
		|||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const updateSystemResources = async (systemId: ObjectId, resources: Array<any>) => {
 | 
			
		||||
    const systems = await Systems();
 | 
			
		||||
    await systems.updateOne({ _id: systemId }, {
 | 
			
		||||
        $set: {
 | 
			
		||||
            resources
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const updateSystemShips = async (systemId: ObjectId, ships: Array<any>) => {
 | 
			
		||||
    const systems = await Systems();
 | 
			
		||||
    await systems.updateOne({ _id: systemId }, {
 | 
			
		||||
        $set: {
 | 
			
		||||
            ships
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    userPlanet.resources.update(resourcesAfter);
 | 
			
		||||
    userPlanet.resources.updateAmount(resourcesAfter.map(res => { return { id: res.id, amount: res.amount } }));
 | 
			
		||||
    userPlanet.buildings.addBuilding(building);
 | 
			
		||||
 | 
			
		||||
    await userPlanet.buildings.sync();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ import { Planet } from "../../../lib/classes/managers/PlanetManager";
 | 
			
		|||
import MissionType from "../../../types/MissionType";
 | 
			
		||||
import { getAllResources } from "../../../lib/db/resources";
 | 
			
		||||
import FleetManager from "../../../lib/classes/managers/FleetManager";
 | 
			
		||||
import SystemManager from "../../../lib/classes/managers/SystemManager";
 | 
			
		||||
 | 
			
		||||
export const POST: APIRoute = async({ request }) => {
 | 
			
		||||
    const response = await validateAccessToken(request);
 | 
			
		||||
| 
						 | 
				
			
			@ -47,14 +48,14 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const checkSource = checkPlanetId(body.source, 'source');
 | 
			
		||||
    const checkSource = checkPlanetOrSystemId(body.source, 'source');
 | 
			
		||||
    if(typeof checkSource.error !== "undefined") return new Response(JSON.stringify(checkSource), { status: checkSource.code });
 | 
			
		||||
 | 
			
		||||
    const checkDestination = checkPlanetId(body.destination, 'destination');
 | 
			
		||||
    const checkDestination = checkPlanetOrSystemId(body.destination, 'destination');
 | 
			
		||||
    if(typeof checkDestination.error !== "undefined") return new Response(JSON.stringify(checkDestination), { status: checkDestination.code });
 | 
			
		||||
    
 | 
			
		||||
    const source = checkSource.planet;
 | 
			
		||||
    const destination = checkDestination.planet;
 | 
			
		||||
    const source = checkSource.planetOrSystem;
 | 
			
		||||
    const destination = checkDestination.planetOrSystem;
 | 
			
		||||
 | 
			
		||||
    const shipsDB = await getAllShips();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +113,7 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkPlanetId(id: string, type: string) {
 | 
			
		||||
function checkPlanetOrSystemId(id: string, type: string) {
 | 
			
		||||
    if(typeof ObjectId === "undefined") return {
 | 
			
		||||
        code: 400,
 | 
			
		||||
        message: "Bad Request",
 | 
			
		||||
| 
						 | 
				
			
			@ -130,22 +131,22 @@ function checkPlanetId(id: string, type: string) {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const planet = locationManager.getPlanet(idToCheck);
 | 
			
		||||
    const planetOrSystem = locationManager.findId(idToCheck);
 | 
			
		||||
 | 
			
		||||
    if(!planet) return {
 | 
			
		||||
    if(!planetOrSystem) return {
 | 
			
		||||
        code: 404,
 | 
			
		||||
        message: "Not Found",
 | 
			
		||||
        error: `Non-existent planet provided in '${type}'`
 | 
			
		||||
        error: `Non-existent planet or system provided in '${type}'`
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        code: 200,
 | 
			
		||||
        message: "OK",
 | 
			
		||||
        planet
 | 
			
		||||
        planetOrSystem
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array<DBShip>, sourcePlanet: Planet) {
 | 
			
		||||
function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array<DBShip>, source: Planet | SystemManager) {
 | 
			
		||||
    if(typeof ships === "undefined") return {
 | 
			
		||||
        code: 400,
 | 
			
		||||
        message: "Bad Request",
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +178,7 @@ function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array
 | 
			
		|||
            error: "Ship amount for ID '" + ships[i].id + "' is not a non-negative integer at position " + i
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(ships[i].amount > (sourcePlanet.ships.getShipById(ships[i].id)?.amount ?? 0)) return {
 | 
			
		||||
        if(ships[i].amount > (source.ships.getShipById(ships[i].id)?.amount ?? 0)) return {
 | 
			
		||||
            code: 400,
 | 
			
		||||
            message: "Bad Request",
 | 
			
		||||
            error: "Not enough ships on planet with ID '" + ships[i].id + "' at position " + i
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +191,7 @@ function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{ id: string, amount: number }>, planet: Planet, missionType: MissionType) {
 | 
			
		||||
function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{ id: string, amount: number }>, source: Planet | SystemManager, missionType: MissionType) {
 | 
			
		||||
    if(missionType === "TRANSPORT" && cargo.length === 0) return {
 | 
			
		||||
        code: 400,
 | 
			
		||||
        message: "Bad Request",
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +205,7 @@ function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{
 | 
			
		|||
            error: "Missing resource ID at position " + i
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!planet.resources.resourcesDB.find(resource => resource.id === cargo[i].id)) return {
 | 
			
		||||
        if(!source.resources.resourcesDB.find(resource => resource.id === cargo[i].id)) return {
 | 
			
		||||
            code: 404,
 | 
			
		||||
            message: "Not Found",
 | 
			
		||||
            error: "Non-existent resource ID '" + cargo[i].id + "' at position " + i
 | 
			
		||||
| 
						 | 
				
			
			@ -222,23 +223,23 @@ function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{
 | 
			
		|||
            error: "Resource amount for ID '" + cargo[i].id + "' is not a non-negative integer at position " + i
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(cargo[i].amount > (planet.resources.resources.find(res => res.id === cargo[i].id)?.amount ?? 0)) return {
 | 
			
		||||
        if(cargo[i].amount > (source.resources.resources.find(res => res.id === cargo[i].id)?.amount ?? 0)) return {
 | 
			
		||||
            code: 400,
 | 
			
		||||
            message: "Bad Request",
 | 
			
		||||
            error: "Not enough resources on planet with ID '" + cargo[i].id + "' at position " + i
 | 
			
		||||
            error: "Not enough resources on planet or system with ID '" + cargo[i].id + "' at position " + i
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const totalCargoAvailable = {
 | 
			
		||||
        solid: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.solid ?? 0) * ship.amount, 0),
 | 
			
		||||
        liquid: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.liquid ?? 0) * ship.amount, 0),
 | 
			
		||||
        gas: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.gas ?? 0) * ship.amount, 0)
 | 
			
		||||
        solid: ships.reduce((acc, ship) => acc + (source.ships.shipsDB.find(s => s.id === ship.id)?.capacity.solid ?? 0) * ship.amount, 0),
 | 
			
		||||
        liquid: ships.reduce((acc, ship) => acc + (source.ships.shipsDB.find(s => s.id === ship.id)?.capacity.liquid ?? 0) * ship.amount, 0),
 | 
			
		||||
        gas: ships.reduce((acc, ship) => acc + (source.ships.shipsDB.find(s => s.id === ship.id)?.capacity.gas ?? 0) * ship.amount, 0)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const totalCargoUsed = {
 | 
			
		||||
        solid: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "solid" ? acc + resource.amount : acc, 0),
 | 
			
		||||
        liquid: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "liquid" ? acc + resource.amount : acc, 0),
 | 
			
		||||
        gas: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "gas" ? acc + resource.amount : acc, 0)
 | 
			
		||||
        solid: cargo.reduce((acc, resource) => source.resources.resourcesDB.find(res => res.id === resource.id)?.type === "solid" ? acc + resource.amount : acc, 0),
 | 
			
		||||
        liquid: cargo.reduce((acc, resource) => source.resources.resourcesDB.find(res => res.id === resource.id)?.type === "liquid" ? acc + resource.amount : acc, 0),
 | 
			
		||||
        gas: cargo.reduce((acc, resource) => source.resources.resourcesDB.find(res => res.id === resource.id)?.type === "gas" ? acc + resource.amount : acc, 0)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(totalCargoUsed.solid > totalCargoAvailable.solid) return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ export const GET: APIRoute = async ({ request }) => {
 | 
			
		|||
 | 
			
		||||
        response.push({
 | 
			
		||||
            planetId: planet._id,
 | 
			
		||||
            ownerId: playerPlanet.manager.owner.id,
 | 
			
		||||
            ownerId: playerPlanet.system.data.ownedBy.id,
 | 
			
		||||
            name: planet.name,
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ export const GET: APIRoute = async ({ params, request }) => {
 | 
			
		|||
        }), { status: 500 }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if(!planet.manager.owner.id.equals(user._id)) return new Response(
 | 
			
		||||
    if(!planet.system.data.ownedBy.id.equals(user._id)) return new Response(
 | 
			
		||||
        JSON.stringify({
 | 
			
		||||
            code: 403,
 | 
			
		||||
            message: "Forbidden"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const user = userPlanet.manager.owner;
 | 
			
		||||
    const user = userPlanet.system.data.ownedBy;
 | 
			
		||||
 | 
			
		||||
    if(!user.id.equals(userDB._id)) {
 | 
			
		||||
        return new Response(
 | 
			
		||||
| 
						 | 
				
			
			@ -139,15 +139,15 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
        )
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    userPlanet.resources.update(newResources);
 | 
			
		||||
    userPlanet.manager.owner.research.addResearch({
 | 
			
		||||
    userPlanet.resources.updateAmount(newResources.map(res => { return { id: res.id, amount: res.amount } }));
 | 
			
		||||
    user.research.addResearch({
 | 
			
		||||
        id: researchId,
 | 
			
		||||
        level: level + 1,
 | 
			
		||||
        data: research
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await userPlanet.resources.sync();
 | 
			
		||||
    await userPlanet.manager.owner.research.sync();
 | 
			
		||||
    await user.research.sync();
 | 
			
		||||
 | 
			
		||||
    return new Response(
 | 
			
		||||
        JSON.stringify({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    userPlanet.resources.update(resourcesAfter);
 | 
			
		||||
    userPlanet.resources.updateAmount(resourcesAfter.map(res => { return { id: res.id, amount: res.amount } }));
 | 
			
		||||
    userPlanet.ships.addShips(ship.data.id, amount);
 | 
			
		||||
 | 
			
		||||
    await userPlanet.ships.sync();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import locationManager from '../../lib/classes/managers/LocationManager';
 | 
			
		|||
import { getAllFleetByUser } from '../../lib/db/fleet';
 | 
			
		||||
import { getAllShips } from '../../lib/db/ships';
 | 
			
		||||
import { ObjectId } from 'mongodb';
 | 
			
		||||
import SystemManager from '../../lib/classes/managers/SystemManager';
 | 
			
		||||
 | 
			
		||||
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
 | 
			
		||||
const username = Astro.cookies.get('username')?.value ?? "";
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +48,7 @@ if(Astro.request.method === "POST") {
 | 
			
		|||
 | 
			
		||||
	const fleetData = {
 | 
			
		||||
		source: planet._id,
 | 
			
		||||
		destination: new ObjectId(form.get('destination-planet')?.toString() ?? ""),
 | 
			
		||||
		destination: form.get('toSystem') ? form.get('destination-system')?.toString() : form.get('destination-planet')?.toString(),
 | 
			
		||||
		mission: form.get('mission')?.toString() ?? "NULL",
 | 
			
		||||
		ships: ships.map(ship => {
 | 
			
		||||
			const amount = parseInt(form.get(`ship-amount-${ship.id}`)?.toString() ?? "0");
 | 
			
		||||
| 
						 | 
				
			
			@ -86,14 +87,20 @@ let friendly = 0;
 | 
			
		|||
let enemy = 0;
 | 
			
		||||
 | 
			
		||||
for(const system of userSystems) {
 | 
			
		||||
	for(const planet of system.planets.planets) {
 | 
			
		||||
	for(const planet of system.planets) {
 | 
			
		||||
		for(const f of fleet) {
 | 
			
		||||
			if(f.source.equals(planet._id)) own++;
 | 
			
		||||
			else if(f.destination.equals(planet._id)) {
 | 
			
		||||
			if(f.source.equals(planet._id) || f.source.equals(system.data._id)) own++;
 | 
			
		||||
			else if(f.destination.equals(planet._id) || f.destination.equals(system.data._id)) {
 | 
			
		||||
				if(f.mission === 'ATTACK') enemy++;
 | 
			
		||||
				else {
 | 
			
		||||
					const source = locationManager.getPlanet(f.source)?.manager.owner.id;
 | 
			
		||||
					const destination = locationManager.getPlanet(f.destination)?.manager.owner.id;
 | 
			
		||||
					const sourceObj = locationManager.findId(f.source);
 | 
			
		||||
					const destinationObj = locationManager.findId(f.destination);
 | 
			
		||||
 | 
			
		||||
					if(!sourceObj || !destinationObj) continue;
 | 
			
		||||
 | 
			
		||||
					const source = sourceObj instanceof SystemManager ? sourceObj.data.ownedBy.id : sourceObj.system.data.ownedBy.id;
 | 
			
		||||
					const destination = destinationObj instanceof SystemManager ? destinationObj.data.ownedBy.id : destinationObj.system.data.ownedBy.id;
 | 
			
		||||
 | 
			
		||||
					if(!source?.equals(destination)) friendly++;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -111,9 +118,9 @@ const sectorsList = galaxies.map(galaxy => {
 | 
			
		|||
				name: sector.name,
 | 
			
		||||
				systems: sector.systems.map(system => {
 | 
			
		||||
					return {
 | 
			
		||||
						_id: system._id,
 | 
			
		||||
						name: system.name,
 | 
			
		||||
						planets: system.planets.planets.map(planet => {
 | 
			
		||||
						_id: system.data._id,
 | 
			
		||||
						name: system.data.name,
 | 
			
		||||
						planets: system.planets.map(planet => {
 | 
			
		||||
							return {
 | 
			
		||||
								_id: planet._id,
 | 
			
		||||
								name: planet.name
 | 
			
		||||
| 
						 | 
				
			
			@ -137,9 +144,13 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
 | 
			
		|||
		<div class="fleet-status">
 | 
			
		||||
			<h2>Fleet status ({fleet.length} total | {own} own | {friendly} friendly | {enemy} enemy)</h2>
 | 
			
		||||
			<ul>
 | 
			
		||||
				{fleet.map(f => <li>
 | 
			
		||||
				{fleet.map(f => {
 | 
			
		||||
					const source = locationManager.findId(f.source);
 | 
			
		||||
					const destination = locationManager.findId(f.destination);
 | 
			
		||||
 | 
			
		||||
					return (<li>
 | 
			
		||||
					<div class="ship-cards">
 | 
			
		||||
						{locationManager.getPlanet(f.source)?.name ?? "?"} => {locationManager.getPlanet(f.destination)?.name ?? "?"} | {f.mission}{f.returning ? " (R)" : ""}<br />
 | 
			
		||||
						<span style={`${source instanceof SystemManager && "color:red;"}`}>{(source instanceof SystemManager ? source.data.name : source?.name) ?? "?"}</span> => <span style={`${destination instanceof SystemManager && "color:red;"}`}>{(destination instanceof SystemManager ? destination.data.name : destination?.name) ?? "?"}</span> | {f.mission}{f.returning ? " (R)" : ""}<br />
 | 
			
		||||
						Containing: {f.ships.map(s => {
 | 
			
		||||
							const ship = ships.find(ship => ship.id === s.id);
 | 
			
		||||
							return `${getName(lang, 'ships', s.id)} x${s.amount}`;
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +159,8 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
 | 
			
		|||
						Departured at: {f.departureTime.toISOString()} <br />
 | 
			
		||||
						Arrives: {f.arrivalTime.toISOString()} ({Math.floor((f.arrivalTime.getTime() - new Date().getTime()) / 1000)})
 | 
			
		||||
					</div>
 | 
			
		||||
				</li>)}
 | 
			
		||||
				</li>)
 | 
			
		||||
				})}
 | 
			
		||||
			</ul>
 | 
			
		||||
		</div>
 | 
			
		||||
	</label>
 | 
			
		||||
| 
						 | 
				
			
			@ -168,6 +180,7 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
 | 
			
		|||
			<label for="attack"><input type="radio" name="mission" value="ATTACK" id="attack" required />Attack</label>
 | 
			
		||||
			<label for="transport"><input type="radio" name="mission" value="TRANSPORT" id="transport" />Transport</label>
 | 
			
		||||
			<label for="transfer"><input type="radio" name="mission" value="TRANSFER" id="transfer" />Transfer</label>
 | 
			
		||||
			<label><input type="checkbox" name="toSystem" />Send to system</label>
 | 
			
		||||
			<hr />
 | 
			
		||||
			<h2>Send to:</h2>
 | 
			
		||||
			<div class="fleet-destination">
 | 
			
		||||
| 
						 | 
				
			
			@ -340,7 +353,7 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
 | 
			
		|||
		transition-timing-function: ease;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	input[type=checkbox] {
 | 
			
		||||
	#fleet-toggle {
 | 
			
		||||
  		position: absolute;
 | 
			
		||||
  	 	top: -9999px;
 | 
			
		||||
		left: -9999px;
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +366,7 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
 | 
			
		|||
		cursor: pointer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	input[type=checkbox]:checked ~ .fleet-status ul {
 | 
			
		||||
	#fleet-toggle:checked ~ .fleet-status ul {
 | 
			
		||||
		opacity: 1;
 | 
			
		||||
		height: auto;
 | 
			
		||||
		max-height: 1000px;
 | 
			
		||||
| 
						 | 
				
			
			@ -414,8 +427,9 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
 | 
			
		|||
	const destinationSector = document.getElementById('destination-sector');
 | 
			
		||||
	const destinationSystem = document.getElementById('destination-system');
 | 
			
		||||
	const destinationPlanet = document.getElementById('destination-planet');
 | 
			
		||||
	const toSystemCheckbox = document.querySelector('input[name="toSystem"]');
 | 
			
		||||
 | 
			
		||||
	if(!destinationGalaxy || !destinationSector || !destinationSystem || !destinationPlanet) {
 | 
			
		||||
	if(!destinationGalaxy || !destinationSector || !destinationSystem || !destinationPlanet || !toSystemCheckbox) {
 | 
			
		||||
		console.error('Could not find destination elements');
 | 
			
		||||
		return;
 | 
			
		||||
	};
 | 
			
		||||
| 
						 | 
				
			
			@ -508,6 +522,14 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
 | 
			
		|||
 | 
			
		||||
	destinationGalaxy.dispatchEvent(new Event('change'));
 | 
			
		||||
 | 
			
		||||
	toSystemCheckbox.addEventListener('change', () => {
 | 
			
		||||
		if(toSystemCheckbox.checked) {
 | 
			
		||||
			destinationPlanet.disabled = true;
 | 
			
		||||
		} else {
 | 
			
		||||
			destinationPlanet.disabled = false;
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const addNew = document.getElementById('cargo-add-new');
 | 
			
		||||
 | 
			
		||||
	addNew.addEventListener('click', () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ if(currentPlanet === undefined) {
 | 
			
		|||
	<NavBar loggedIn="true" active="overview" />
 | 
			
		||||
	<ResourceBar />
 | 
			
		||||
 | 
			
		||||
	<h1>{currentPlanet.name} in {currentPlanet.manager.system.name}</h1>
 | 
			
		||||
	<h1>{currentPlanet.name} in {currentPlanet.system.data.name}</h1>
 | 
			
		||||
</Layout>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,15 +41,18 @@ if(Astro.request.method === "POST") {
 | 
			
		|||
    <NavBar loggedIn="true" active="systemManager" />
 | 
			
		||||
    <ResourceBar />
 | 
			
		||||
 | 
			
		||||
    <h1>Selected system: {currentSystem.name} in {currentSystem.sector.name} in {currentSystem.sector.galaxy.name} <a href="/game/systemManager/select">(change)</a></h1>
 | 
			
		||||
    <h1>Selected system: {currentSystem.data.name} in {currentSystem.data.sector.name} in {currentSystem.data.sector.galaxy.name} <a href="/game/systemManager/select">(change)</a></h1>
 | 
			
		||||
    <div class="system-links">
 | 
			
		||||
        <a href="/game/systemManager">Overview</a>
 | 
			
		||||
        <a href="/game/systemManager/structures">System-wide structures</a>
 | 
			
		||||
        <a href="/game/systemManager/spaceStations">Space stations</a>
 | 
			
		||||
        <a href="/game/systemManager/asteroids">Asteroids</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="resources">
 | 
			
		||||
        <p>Resources: {currentSystem.resources.resources.map(r => `${r.id}: ${r.amount}`).join(", ")}</p>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="planet-list">
 | 
			
		||||
        {currentSystem.planets.planets.length === 0 ? <span>No planets in this sector</span> : currentSystem.planets.planets.map(planet => (
 | 
			
		||||
        {currentSystem.planets.length === 0 ? <span>No planets in this sector</span> : currentSystem.planets.map(planet => (
 | 
			
		||||
            <div class="planet-card">
 | 
			
		||||
                <h2>{planet.name}<div><form method="post"><input type="hidden" name="planetId" value={planet._id.toString()} /><input type="submit" value="Select" /></form></div></h2>
 | 
			
		||||
                <p>Fields: {planet.fields}</p>
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +73,10 @@ if(Astro.request.method === "POST") {
 | 
			
		|||
    </div>
 | 
			
		||||
</Layout>
 | 
			
		||||
<style>
 | 
			
		||||
    * {
 | 
			
		||||
        color: white;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    h1 {
 | 
			
		||||
        text-align: center;
 | 
			
		||||
        color: white;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +102,13 @@ if(Astro.request.method === "POST") {
 | 
			
		|||
        text-decoration: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .resources {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: row;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        margin-bottom: 1rem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .planet-list {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: row;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,8 @@ const systems = locationManager.getSystemsOwnedBy(checkUser._id);
 | 
			
		|||
    <div class="systems-list">
 | 
			
		||||
        {systems.map(system => (
 | 
			
		||||
            <div class="system-card">
 | 
			
		||||
                <h2>{system.name}</h2>
 | 
			
		||||
                <div><form method="post"><input type="hidden" name="systemId" value={system._id.toString()} /><input type="submit" value="Select" /></form></div>
 | 
			
		||||
                <h2>{system.data.name}</h2>
 | 
			
		||||
                <div><form method="post"><input type="hidden" name="systemId" value={system.data._id.toString()} /><input type="submit" value="Select" /></form></div>
 | 
			
		||||
            </div>
 | 
			
		||||
        ))}
 | 
			
		||||
    </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ if(Astro.request.method === "POST") {
 | 
			
		|||
 | 
			
		||||
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
 | 
			
		||||
 | 
			
		||||
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any>, energy: number } } = {};
 | 
			
		||||
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, structures: Array<any>, energy: number } } = {};
 | 
			
		||||
 | 
			
		||||
const structureList = currentSystem.structures.structuresDB;
 | 
			
		||||
for(const structure of structureList) {
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ for(const structure of structureList) {
 | 
			
		|||
			};
 | 
			
		||||
		}),
 | 
			
		||||
		research: structure.requirements.research,
 | 
			
		||||
		buildings: structure.requirements.buildings,
 | 
			
		||||
		structures: structure.requirements.structures,
 | 
			
		||||
		energy: structure.energy
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ for(const structure of structureList) {
 | 
			
		|||
    <NavBar loggedIn="true" active="systemManager" />
 | 
			
		||||
    <ResourceBar />
 | 
			
		||||
 | 
			
		||||
    <h1>Selected system: {currentSystem.name} <a href="/game/systemManager/select">(change)</a></h1>
 | 
			
		||||
    <h1>Selected system: {currentSystem.data.name} <a href="/game/systemManager/select">(change)</a></h1>
 | 
			
		||||
    <div class="system-links">
 | 
			
		||||
        <a href="/game/systemManager">Overview</a>
 | 
			
		||||
        <a href="/game/systemManager/structures">System-wide structures</a>
 | 
			
		||||
| 
						 | 
				
			
			@ -78,8 +78,8 @@ for(const structure of structureList) {
 | 
			
		|||
		<div id="structure-modal-details" data-structure-id="">
 | 
			
		||||
			<h3>Required resources</h3>
 | 
			
		||||
			<div class="structure-modal-text" id="structure-modal-req-resources">None</div>
 | 
			
		||||
			<h3>Required buildings</h3>
 | 
			
		||||
			<div class="structure-modal-text" id="structure-modal-req-buildings">None</div>
 | 
			
		||||
			<h3>Required structures</h3>
 | 
			
		||||
			<div class="structure-modal-text" id="structure-modal-req-structures">None</div>
 | 
			
		||||
			<h3>Required research</h3>
 | 
			
		||||
			<div class="structure-modal-text" id="structure-modal-req-research">None</div>
 | 
			
		||||
		</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +87,7 @@ for(const structure of structureList) {
 | 
			
		|||
    <div class="structure-list">
 | 
			
		||||
        {currentSystem.structures.structuresDB.map(structure => (
 | 
			
		||||
            <ItemCard
 | 
			
		||||
                category="structures"
 | 
			
		||||
                id={structure.id}
 | 
			
		||||
                name={getName(lang, 'structures', structure.id)}
 | 
			
		||||
                image={`/images/structures/${structure.id}.jpeg`}
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +176,7 @@ for(const structure of structureList) {
 | 
			
		|||
</style>
 | 
			
		||||
<script define:vars={{ modalSet, lang }}>
 | 
			
		||||
	const modalResources = document.getElementById("structure-modal-req-resources");
 | 
			
		||||
	const modalBuildings = document.getElementById("structure-modal-req-buildings");
 | 
			
		||||
	const modalStructures = document.getElementById("structure-modal-req-structures");
 | 
			
		||||
	const modalResearch = document.getElementById("structure-modal-req-research");
 | 
			
		||||
 | 
			
		||||
	document.querySelectorAll('.item-card-info-button').forEach((el) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -186,15 +187,15 @@ for(const structure of structureList) {
 | 
			
		|||
            modalDiv.style.display = 'block';
 | 
			
		||||
 | 
			
		||||
			const reqResources = modalSet[el.parentElement.parentElement.dataset.id]?.resources ?? [];
 | 
			
		||||
			const reqBuildings = modalSet[el.parentElement.parentElement.dataset.id]?.buildings ?? [];
 | 
			
		||||
			const reqStructures = modalSet[el.parentElement.parentElement.dataset.id]?.structures ?? [];
 | 
			
		||||
			const reqResearch = modalSet[el.parentElement.parentElement.dataset.id]?.research ?? [];
 | 
			
		||||
 | 
			
		||||
			modalResources.innerHTML = reqResources.length === 0 ? "None" : reqResources.map(resource => {
 | 
			
		||||
				return `${lang['resources'].find(r => r.id === resource.id).name}: ${resource.amount}`;
 | 
			
		||||
			}).join("<br />");
 | 
			
		||||
 | 
			
		||||
			modalBuildings.innerHTML = reqBuildings.length === 0 ? "None" : reqBuildings.map(building => {
 | 
			
		||||
				return `${lang['buildings'].find(b => b.id === building.id).name}: ${building.level}`;
 | 
			
		||||
			modalStructures.innerHTML = reqStructures.length === 0 ? "None" : reqStructures.map(structure => {
 | 
			
		||||
				return `${lang['structures'].find(s => s.id === structure.id).name}: ${structure.level}`;
 | 
			
		||||
			}).join("<br />");
 | 
			
		||||
 | 
			
		||||
			modalResearch.innerHTML = reqResearch.length === 0 ? "None" : reqResearch.map(research => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ export default interface DBStructure {
 | 
			
		|||
    id: string;
 | 
			
		||||
    description: string;
 | 
			
		||||
    requirements: {
 | 
			
		||||
        buildings: Array<{ id: string, level: number }>,
 | 
			
		||||
        structures: Array<{ id: string, level: number }>,
 | 
			
		||||
        research: Array<{ id: string, level: number }>,
 | 
			
		||||
        resources: Array<{ id: string, amount: number }>,
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,4 +9,12 @@ export default interface DBSystem {
 | 
			
		|||
        level: number
 | 
			
		||||
    }>;
 | 
			
		||||
    planets: Array<ObjectId>;
 | 
			
		||||
    resources: Array<{
 | 
			
		||||
        id: string,
 | 
			
		||||
        amount: number
 | 
			
		||||
    }>;
 | 
			
		||||
    ships: Array<{
 | 
			
		||||
        id: string,
 | 
			
		||||
        amount: number
 | 
			
		||||
    }>;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue