Add asteroids module
This commit is contained in:
		
							parent
							
								
									ebec253e50
								
							
						
					
					
						commit
						75d936b78a
					
				| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
import Asteroid from '../../../types/Asteroid';
 | 
			
		||||
import SystemManager from './SystemManager';
 | 
			
		||||
import { updateSystemAsteroids } from '../../db/systems';
 | 
			
		||||
 | 
			
		||||
export default class AsteroidManager {
 | 
			
		||||
    asteroids: Array<Asteroid> = [];
 | 
			
		||||
    system: SystemManager;
 | 
			
		||||
 | 
			
		||||
    constructor(system: SystemManager) {
 | 
			
		||||
        this.system = system;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init(asteroids: Array<Asteroid>) {
 | 
			
		||||
        this.asteroids = asteroids;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
        await updateSystemAsteroids(this.system.data._id, this.asteroids);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +20,8 @@ export type Fleet = {
 | 
			
		|||
    returning: boolean,
 | 
			
		||||
    mission: MissionType,
 | 
			
		||||
    ships: Array<{ id: string, amount: number }>,
 | 
			
		||||
    cargo: Array<{ id: string, amount: number }>
 | 
			
		||||
    cargo: Array<{ id: string, amount: number }>,
 | 
			
		||||
    additionalData?: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type BattleFleet = {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +34,7 @@ export type BattleFleet = {
 | 
			
		|||
export default class FleetManager {
 | 
			
		||||
    data: Fleet;
 | 
			
		||||
 | 
			
		||||
    constructor(id: ObjectId, source: Planet | SystemManager, destination: Planet | SystemManager | Sector, 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 | Sector, departureTime: Date, arrivalTime: Date, returning: boolean, mission: MissionType, ships: Array<{ id: string, amount: number }>, cargo: Array<{ id: string, amount: number }>, additionalData?: string) {
 | 
			
		||||
        this.data = {
 | 
			
		||||
            id,
 | 
			
		||||
            source,
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +44,8 @@ export default class FleetManager {
 | 
			
		|||
            returning,
 | 
			
		||||
            mission,
 | 
			
		||||
            ships,
 | 
			
		||||
            cargo
 | 
			
		||||
            cargo,
 | 
			
		||||
            additionalData
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +150,30 @@ export default class FleetManager {
 | 
			
		|||
                case 'EXPEDITION':
 | 
			
		||||
                    await this.expeditionResults();
 | 
			
		||||
 | 
			
		||||
                    return false;
 | 
			
		||||
                case 'MINE':
 | 
			
		||||
                    const system = this.data.destination as SystemManager;
 | 
			
		||||
                    const asteroid = system.asteroids.asteroids.find(a => a.id.equals(this.data.additionalData ?? ""));
 | 
			
		||||
                    if(!asteroid) throw new Error("Asteroid not found.");
 | 
			
		||||
                    for(const res of asteroid.resources) {
 | 
			
		||||
                        const resource = this.data.cargo.find(r => r.id === res.id);
 | 
			
		||||
                        if(!resource) this.data.cargo.push(res);
 | 
			
		||||
                        else resource.amount += res.amount;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    await this.initiateReturn();
 | 
			
		||||
                    await sendMail(
 | 
			
		||||
                        null,
 | 
			
		||||
                        this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id,
 | 
			
		||||
                        this.data.arrivalTime,
 | 
			
		||||
                        "Asteroid mined",
 | 
			
		||||
                        `Your fleet has arrived at AS-${this.data.additionalData} asteroid.\n
 | 
			
		||||
                        Following resources were added to the cargo inventory:\n${asteroid.resources.map(r => `${r.id} - ${r.amount}`).join('\n')}\n
 | 
			
		||||
                        Fleet will return at ${this.data.arrivalTime}`
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                    system.asteroids.asteroids = system.asteroids.asteroids.filter(a => !a.id.equals(asteroid.id));
 | 
			
		||||
                    await system.asteroids.sync();
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -467,7 +493,8 @@ export default class FleetManager {
 | 
			
		|||
            returning: this.data.returning,
 | 
			
		||||
            mission: this.data.mission,
 | 
			
		||||
            ships: this.data.ships,
 | 
			
		||||
            cargo: this.data.cargo
 | 
			
		||||
            cargo: this.data.cargo,
 | 
			
		||||
            additionalData: this.data.additionalData
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await updateFleet(data);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,7 +94,8 @@ class LocationManager {
 | 
			
		|||
                        resources: null,
 | 
			
		||||
                        //@ts-ignore
 | 
			
		||||
                        ships: null,
 | 
			
		||||
                        planets: []
 | 
			
		||||
                        planets: [],
 | 
			
		||||
                        asteroids: [],
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    const s = await new SystemManager(systemObject).fillData(systemData);
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +140,8 @@ class LocationManager {
 | 
			
		|||
                    fleet.returning,
 | 
			
		||||
                    fleet.mission,
 | 
			
		||||
                    fleet.ships,
 | 
			
		||||
                    fleet.cargo
 | 
			
		||||
                    fleet.cargo,
 | 
			
		||||
                    fleet.additionalData
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import { ObjectId } from "mongodb";
 | 
			
		||||
import { ObjectId, UUID } from "mongodb";
 | 
			
		||||
import DBSystem from "../../../types/db/DBSystem";
 | 
			
		||||
import { getPlanetById } from "../../db/planets";
 | 
			
		||||
import User from "../User";
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +14,8 @@ import PlanetDefenseManager from "./PlanetDefenseManager";
 | 
			
		|||
import SystemDefenseManager from "./SystemDefenseManager";
 | 
			
		||||
import SystemEnergyManager from "./SystemEnergyManager";
 | 
			
		||||
import PlanetEnergyManager from "./PlanetEnergyManager";
 | 
			
		||||
import AsteroidManager from "./AsteroidManager";
 | 
			
		||||
import Asteroid from "../../../types/Asteroid";
 | 
			
		||||
 | 
			
		||||
export type System = {
 | 
			
		||||
    _id: ObjectId,
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +27,7 @@ export type System = {
 | 
			
		|||
    ships: SystemShipManager,
 | 
			
		||||
    defenses: SystemDefenseManager,
 | 
			
		||||
    planets: Planet[];
 | 
			
		||||
    asteroids: Asteroid[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default class SystemManager {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +37,7 @@ export default class SystemManager {
 | 
			
		|||
    ships: SystemShipManager;
 | 
			
		||||
    defenses: SystemDefenseManager;
 | 
			
		||||
    energy: SystemEnergyManager;
 | 
			
		||||
    asteroids: AsteroidManager;
 | 
			
		||||
    data: System;
 | 
			
		||||
 | 
			
		||||
    constructor(data: System) {
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +47,7 @@ export default class SystemManager {
 | 
			
		|||
        this.ships = new SystemShipManager(this);
 | 
			
		||||
        this.defenses = new SystemDefenseManager(this);
 | 
			
		||||
        this.energy = new SystemEnergyManager(this);
 | 
			
		||||
        this.asteroids = new AsteroidManager(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fillData(systemData: DBSystem) {
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +55,7 @@ export default class SystemManager {
 | 
			
		|||
        await this.resources.init(systemData.resources);
 | 
			
		||||
        await this.ships.init(systemData.ships);
 | 
			
		||||
        await this.defenses.init(systemData.defenses);
 | 
			
		||||
        this.asteroids.init(systemData.asteroids);
 | 
			
		||||
        this.energy.update();
 | 
			
		||||
 | 
			
		||||
        await Promise.all(systemData.planets.map(async planetId => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
import { ObjectId } from "mongodb";
 | 
			
		||||
import { Systems } from "./mongodb";
 | 
			
		||||
import DBSystem from "../../types/db/DBSystem";
 | 
			
		||||
import Asteroid from "../../types/Asteroid";
 | 
			
		||||
 | 
			
		||||
export const getAllSystems = async () => {
 | 
			
		||||
    return await (await Systems()).find({}).toArray() as DBSystem[];
 | 
			
		||||
| 
						 | 
				
			
			@ -52,3 +53,12 @@ export const updateSystemDefenses = async (systemId: ObjectId, defenses: Array<a
 | 
			
		|||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const updateSystemAsteroids = async (systemId: ObjectId, asteroids: Array<Asteroid>) => {
 | 
			
		||||
    const systems = await Systems();
 | 
			
		||||
    await systems.updateOne({ _id: systemId }, {
 | 
			
		||||
        $set: {
 | 
			
		||||
            asteroids
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
export default function parseParams(url: string) {
 | 
			
		||||
    const rawParams = url.split("?")[1]?.split("&");
 | 
			
		||||
    if(typeof rawParams === "undefined") return [];
 | 
			
		||||
    if(typeof rawParams === "undefined") return {};
 | 
			
		||||
    const params: { [key: string]: any } = {};
 | 
			
		||||
    for(const rawParam of rawParams) {
 | 
			
		||||
        const k = rawParam.split("=")[0];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import { APIRoute } from "astro";
 | 
			
		||||
import validateAccessToken from "../../../lib/utils/validateAccessToken";
 | 
			
		||||
import { getUserByAccessToken } from "../../../lib/db/users";
 | 
			
		||||
import { ObjectId } from "mongodb";
 | 
			
		||||
import { ObjectId, UUID } from "mongodb";
 | 
			
		||||
import locationManager from "../../../lib/classes/managers/LocationManager";
 | 
			
		||||
import { getAllShips } from "../../../lib/db/ships";
 | 
			
		||||
import DBShip from "../../../types/db/DBShip";
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let body: { source: string, destination: string, ships: Array<{ id: string, amount: number }>, cargo: Array<{ id: string, amount: number }>, mission: MissionType };
 | 
			
		||||
    let body: { source: string, destination: string, ships: Array<{ id: string, amount: number }>, cargo: Array<{ id: string, amount: number }>, mission: MissionType, currentSystem?: string };
 | 
			
		||||
    try {
 | 
			
		||||
        body = await request.json()
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
| 
						 | 
				
			
			@ -64,11 +64,16 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
    const checkCargoBody = checkCargo(body.cargo, body.ships, source, body.mission);
 | 
			
		||||
    if(typeof checkCargoBody.error !== "undefined") return new Response(JSON.stringify(checkCargoBody), { status: checkCargoBody.code });
 | 
			
		||||
 | 
			
		||||
    let dest;
 | 
			
		||||
    let dest, additionalData;
 | 
			
		||||
    if(body.mission === "EXPEDITION") {
 | 
			
		||||
        const destinationSector = checkSectorId(body.destination);
 | 
			
		||||
        if(typeof destinationSector.error !== "undefined") return new Response(JSON.stringify(destinationSector), { status: destinationSector.code });
 | 
			
		||||
        dest = destinationSector.sector;
 | 
			
		||||
    } else if(body.mission === "MINE") {
 | 
			
		||||
        const checkAsteroid = checkAsteroidId(body.destination, body.currentSystem ?? "");
 | 
			
		||||
        if(typeof checkAsteroid.error !== "undefined") return new Response(JSON.stringify(checkAsteroid), { status: checkAsteroid.code });
 | 
			
		||||
        dest = checkAsteroid.system;
 | 
			
		||||
        additionalData = checkAsteroid.asteroid;
 | 
			
		||||
    } else {
 | 
			
		||||
        const checkDestination = checkPlanetOrSystemId(body.destination, 'destination');
 | 
			
		||||
        if(typeof checkDestination.error !== "undefined") return new Response(JSON.stringify(checkDestination), { status: checkDestination.code });
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +91,8 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
        false,
 | 
			
		||||
        body.mission,
 | 
			
		||||
        body.ships,
 | 
			
		||||
        body.cargo
 | 
			
		||||
        body.cargo,
 | 
			
		||||
        body.mission === "MINE" ? additionalData?.id.toString() : ""
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const resourceDiff = await source.resources.getDifference(body.cargo.map(c => ({ id: c.id, amount: c.amount })));
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +129,7 @@ export const POST: APIRoute = async({ request }) => {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function checkPlanetOrSystemId(id: string, type: string) {
 | 
			
		||||
    if(typeof ObjectId === "undefined") return {
 | 
			
		||||
    if(typeof id === "undefined") return {
 | 
			
		||||
        code: 400,
 | 
			
		||||
        message: "Bad Request",
 | 
			
		||||
        error: `Missing '${type}' in body`
 | 
			
		||||
| 
						 | 
				
			
			@ -155,8 +161,66 @@ function checkPlanetOrSystemId(id: string, type: string) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkAsteroidId(id: string, systemId: string) {
 | 
			
		||||
    if(typeof id === "undefined") return {
 | 
			
		||||
        code: 400,
 | 
			
		||||
        message: "Bad Request",
 | 
			
		||||
        error: `Missing 'destination' in body`
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(systemId === "") return {
 | 
			
		||||
        code: 400,
 | 
			
		||||
        message: "Bad Request",
 | 
			
		||||
        error: "Missing 'currentSystem' in body"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let idToCheck;
 | 
			
		||||
    try {
 | 
			
		||||
        idToCheck = new UUID(id);
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
        return {
 | 
			
		||||
            code: 400,
 | 
			
		||||
            message: "Bad Request",
 | 
			
		||||
            error: `Invalid UUID in 'destination'`
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let systemObjectId;
 | 
			
		||||
    try {
 | 
			
		||||
        systemObjectId = new ObjectId(systemId);
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
        return {
 | 
			
		||||
            code: 400,
 | 
			
		||||
            message: "Bad Request",
 | 
			
		||||
            error: "Invalid ID in 'currentSystem'"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const system = locationManager.getSystem(systemObjectId);
 | 
			
		||||
 | 
			
		||||
    if(!system) return {
 | 
			
		||||
        code: 404,
 | 
			
		||||
        message: "Not Found",
 | 
			
		||||
        error: `Non-existent system provided in 'currentSystem'`
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const asteroid = system.asteroids.asteroids.find(asteroid => asteroid.id.equals(idToCheck));
 | 
			
		||||
    if(!asteroid) return {
 | 
			
		||||
        code: 404,
 | 
			
		||||
        message: "Not Found",
 | 
			
		||||
        error: "Non-existent asteroid provided in 'destination'"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        code: 200,
 | 
			
		||||
        message: "OK",
 | 
			
		||||
        asteroid,
 | 
			
		||||
        system
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkSectorId(id: string) {
 | 
			
		||||
    if(typeof ObjectId === "undefined") return {
 | 
			
		||||
    if(typeof id === "undefined") return {
 | 
			
		||||
        code: 400,
 | 
			
		||||
        message: "Bad Request",
 | 
			
		||||
        error: "Missing 'sector' in body"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
import { type APIRoute } from "astro";
 | 
			
		||||
import validateAccessToken from "../../../../lib/utils/validateAccessToken";
 | 
			
		||||
import { getUserByAccessToken } from "../../../../lib/db/users";
 | 
			
		||||
import locationManager from "../../../../lib/classes/managers/LocationManager";
 | 
			
		||||
import { ObjectId, UUID } from "mongodb";
 | 
			
		||||
import Asteroid from "../../../../types/Asteroid";
 | 
			
		||||
 | 
			
		||||
export const POST: APIRoute = async({ request }) => {
 | 
			
		||||
    const response = await validateAccessToken(request);
 | 
			
		||||
    if(response instanceof Response) return response;
 | 
			
		||||
 | 
			
		||||
    const user = await getUserByAccessToken(response);
 | 
			
		||||
    if(user === null) {
 | 
			
		||||
        return new Response(
 | 
			
		||||
            JSON.stringify({
 | 
			
		||||
                code: 401,
 | 
			
		||||
                message: "Unauthorized"
 | 
			
		||||
            }), { status: 401 }
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const cookies = request.headers.get("Cookie")?.split(";").map((x) => x.trim().split("=")) ?? [];
 | 
			
		||||
    const systemId = cookies.filter((x) => x[0] === "currentSystem")[0]?.[1];
 | 
			
		||||
 | 
			
		||||
    const userSystem = locationManager.getSystem(new ObjectId(systemId));
 | 
			
		||||
    
 | 
			
		||||
    if(!userSystem) {
 | 
			
		||||
        return new Response(
 | 
			
		||||
            JSON.stringify({
 | 
			
		||||
                code: 400,
 | 
			
		||||
                message: "Bad Request",
 | 
			
		||||
                error: "Invalid system ID"
 | 
			
		||||
            }), { status: 400 }
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(userSystem.asteroids.asteroids.length >= 5) {
 | 
			
		||||
        return new Response(
 | 
			
		||||
            JSON.stringify({
 | 
			
		||||
                code: 400,
 | 
			
		||||
                message: "Bad Request",
 | 
			
		||||
                error: "You have reached the maximum number of asteroids in this system"
 | 
			
		||||
            }), { status: 400 }
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const asteroidUUID = new UUID();
 | 
			
		||||
    const asteroid: Asteroid = {
 | 
			
		||||
        id: asteroidUUID,
 | 
			
		||||
        name: `AS-${asteroidUUID}`,
 | 
			
		||||
        resources: [
 | 
			
		||||
            {
 | 
			
		||||
                id: "coal",
 | 
			
		||||
                amount: Math.floor(Math.random() * 100) + 1
 | 
			
		||||
            }, {
 | 
			
		||||
                id: "iron",
 | 
			
		||||
                amount: Math.floor(Math.random() * 100) + 1
 | 
			
		||||
            }, {
 | 
			
		||||
                id: "gold",
 | 
			
		||||
                amount: Math.floor(Math.random() * 100) + 1
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    userSystem.asteroids.asteroids.push(asteroid);
 | 
			
		||||
    await userSystem.asteroids.sync();
 | 
			
		||||
 | 
			
		||||
    return new Response(
 | 
			
		||||
        JSON.stringify({
 | 
			
		||||
            code: 200,
 | 
			
		||||
            message: "OK",
 | 
			
		||||
            asteroid
 | 
			
		||||
        }), { status: 200 }
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
---
 | 
			
		||||
import { ObjectId } from "mongodb";
 | 
			
		||||
import LoggedIn from "../../../../layouts/LoggedIn.astro";
 | 
			
		||||
import locationManager from "../../../../lib/classes/managers/LocationManager";
 | 
			
		||||
 | 
			
		||||
const { token, lang } = Astro.locals;
 | 
			
		||||
 | 
			
		||||
const currentSystemId = Astro.cookies.get('currentSystem')?.value ?? null;
 | 
			
		||||
if(currentSystemId === null) return Astro.redirect('/game/systemManager/select');
 | 
			
		||||
 | 
			
		||||
const currentSystem = locationManager.getSystem(new ObjectId(currentSystemId));
 | 
			
		||||
if(currentSystem === undefined) {
 | 
			
		||||
    Astro.cookies.delete('currentSystem');
 | 
			
		||||
    return Astro.redirect('/game/systemManager/select');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const discoveredAsteroids = currentSystem.asteroids.asteroids;
 | 
			
		||||
---
 | 
			
		||||
<LoggedIn id="systemManager" title="System Manager">
 | 
			
		||||
    <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>
 | 
			
		||||
        <a href="/game/systemManager/spaceStations">Space stations</a>
 | 
			
		||||
        <a href="/game/systemManager/asteroids">Asteroids</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div>
 | 
			
		||||
        <h2>Avaliable asteroids <button id="scan">Scan for new</button></h2>
 | 
			
		||||
        <div>
 | 
			
		||||
            {discoveredAsteroids.map((asteroid) => <div>
 | 
			
		||||
                <h3>{asteroid.name} <a href={`/game/systemManager/asteroids/send?dest=${asteroid.id}`}>Send</a></h3>
 | 
			
		||||
                <h4>Resources left: </h4>
 | 
			
		||||
                {asteroid.resources.map((resource) => <div><p>{resource.id} - {resource.amount}</p></div>)}
 | 
			
		||||
            </div>)}
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</LoggedIn>
 | 
			
		||||
<style>
 | 
			
		||||
* {
 | 
			
		||||
	color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 a {
 | 
			
		||||
    color: lime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
button, a {
 | 
			
		||||
    color: white;
 | 
			
		||||
    background-color: #555;
 | 
			
		||||
    padding: 0.5rem;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    border: none;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.system-links {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    margin-bottom: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.system-links a {
 | 
			
		||||
    color: white;
 | 
			
		||||
    background-color: #555;
 | 
			
		||||
    padding: 0.5rem;
 | 
			
		||||
    margin: 0 1rem;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
<script>
 | 
			
		||||
async function scan() {
 | 
			
		||||
    await fetch('/api/system/asteroids/scan', {
 | 
			
		||||
        method: 'POST',
 | 
			
		||||
        headers: {
 | 
			
		||||
            'Content-Type': 'application/json',
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    window.location.reload();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
document.getElementById('scan')?.addEventListener('click', scan);
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,165 @@
 | 
			
		|||
---
 | 
			
		||||
import { ObjectId } from "mongodb";
 | 
			
		||||
import ItemCard from "../../../../components/ItemCard.astro";
 | 
			
		||||
import LoggedIn from "../../../../layouts/LoggedIn.astro";
 | 
			
		||||
import locationManager from "../../../../lib/classes/managers/LocationManager";
 | 
			
		||||
import { getName, getObj } from "../../../../lib/utils/langDriver";
 | 
			
		||||
import parseParams from "../../../../lib/utils/parseParams";
 | 
			
		||||
import { getAllSystems } from "../../../../lib/db/systems";
 | 
			
		||||
 | 
			
		||||
const { user, token, lang } = Astro.locals;
 | 
			
		||||
 | 
			
		||||
const currentSystemId = Astro.cookies.get('currentSystem')?.value ?? null;
 | 
			
		||||
if(currentSystemId === null) return Astro.redirect('/game/systemManager/select');
 | 
			
		||||
 | 
			
		||||
const currentSystem = locationManager.getSystem(new ObjectId(currentSystemId));
 | 
			
		||||
if(currentSystem === undefined) {
 | 
			
		||||
    Astro.cookies.delete('currentSystem');
 | 
			
		||||
    return Astro.redirect('/game/systemManager/select');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if(Astro.request.method === "POST") {
 | 
			
		||||
    const form = await Astro.request.formData();
 | 
			
		||||
 | 
			
		||||
	const source = form.get('toSystem') ?
 | 
			
		||||
			form.get('source-system')?.toString() :
 | 
			
		||||
			form.get('source-planet')?.toString();
 | 
			
		||||
 | 
			
		||||
	const fleetData = {
 | 
			
		||||
		source,
 | 
			
		||||
		destination: form.get('asteroid-id')?.toString(),
 | 
			
		||||
		mission: "MINE",
 | 
			
		||||
		ships: [{ id: "asteroid-miner", amount: 1 }],
 | 
			
		||||
		cargo: [],
 | 
			
		||||
        currentSystem: form.get('current-system')?.toString()
 | 
			
		||||
	}
 | 
			
		||||
    
 | 
			
		||||
	const response = await fetch(`${Astro.url.origin}/api/fleet/send`, {
 | 
			
		||||
		method: 'POST',
 | 
			
		||||
		headers: {
 | 
			
		||||
			'Content-Type': 'application/json',
 | 
			
		||||
			'Authorization': `Bearer ${token}`
 | 
			
		||||
		},
 | 
			
		||||
		body: JSON.stringify(fleetData)
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	console.log(await response.json());
 | 
			
		||||
	
 | 
			
		||||
	return Astro.redirect('/game/systemManager/asteroids');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const params = parseParams(Astro.request.url);
 | 
			
		||||
 | 
			
		||||
const systems = locationManager.getSystemsOwnedBy(user.id).map(sys => { return { id: sys.data._id, name: sys.data.name, hasAsteroidMiner: sys.ships.ships.find(ship => ship.data.id === "asteroid-miner") !== undefined, planets: sys.planets.map(planet => { return { id: planet._id, name: planet.name, hasAsteroidMiner: planet.ships.ships.find(ship => ship.data.id === "asteroid-miner") !== undefined } }) } });
 | 
			
		||||
---
 | 
			
		||||
<LoggedIn id="systemManager" title="System Manager">
 | 
			
		||||
    <h1><a href="/game/systemManager/asteroids"><= go back</a>Sending</h1>
 | 
			
		||||
    <form method="post">
 | 
			
		||||
        <input type="hidden" name="asteroid-id" value={params.dest} />
 | 
			
		||||
        <input type="hidden" name="current-system" value={currentSystemId} />
 | 
			
		||||
        <label><input type="checkbox" name="fromSystem" />Send from system</label>
 | 
			
		||||
        <h3>System</h3>
 | 
			
		||||
        <select id="source-system" name="source-system"></select>
 | 
			
		||||
        <h3>Planet</h3>
 | 
			
		||||
        <select id="source-planet" name="source-planet"></select>
 | 
			
		||||
        <hr />
 | 
			
		||||
        <button type="submit">Send fleet</button>
 | 
			
		||||
    </form>
 | 
			
		||||
</LoggedIn>
 | 
			
		||||
<style>
 | 
			
		||||
* {
 | 
			
		||||
	color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 a {
 | 
			
		||||
    color: lime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
button {
 | 
			
		||||
    color: white;
 | 
			
		||||
    background-color: #555;
 | 
			
		||||
    padding: 0.5rem;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    border: none;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.system-links {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    margin-bottom: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a {
 | 
			
		||||
    color: white;
 | 
			
		||||
    background-color: #555;
 | 
			
		||||
    padding: 0.5rem;
 | 
			
		||||
    margin: 0 1rem;
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
select {
 | 
			
		||||
	width: 10rem;
 | 
			
		||||
	height: 3rem;
 | 
			
		||||
	color: black;
 | 
			
		||||
	background-color: darkgray;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
<script define:vars={{ systems }}>
 | 
			
		||||
const sourceSystem = document.getElementById('source-system');
 | 
			
		||||
const sourcePlanet = document.getElementById('source-planet');
 | 
			
		||||
const fromSystemCheckbox = document.querySelector('input[name="fromSystem"]');
 | 
			
		||||
 | 
			
		||||
if(!sourceSystem || !sourcePlanet || !fromSystemCheckbox) {
 | 
			
		||||
    console.error('Could not find all elements');
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
for(const system of systems) {
 | 
			
		||||
	const opt = document.createElement('option');
 | 
			
		||||
	opt.value = system.id;
 | 
			
		||||
	opt.innerText = system.hasAsteroidMiner ? system.name : `${system.name} (no miner)`;
 | 
			
		||||
	sourceSystem.appendChild(opt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sourceSystem.addEventListener('change', () => {
 | 
			
		||||
	const system = systems.find(system => system.id === sourceSystem.value);
 | 
			
		||||
	if(!system) {
 | 
			
		||||
		sourcePlanet.innerHTML = '';
 | 
			
		||||
		const opt = document.createElement('option');
 | 
			
		||||
		opt.value = '';
 | 
			
		||||
		opt.innerText = 'No planets';
 | 
			
		||||
		sourcePlanet.appendChild(opt);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sourcePlanet.innerHTML = '';
 | 
			
		||||
		
 | 
			
		||||
	for(const planet of system.planets) {
 | 
			
		||||
		const opt = document.createElement('option');
 | 
			
		||||
		opt.value = planet.id;
 | 
			
		||||
		opt.innerText = planet.hasAsteroidMiner ? planet.name : `${planet.name} (no miner)`;
 | 
			
		||||
		sourcePlanet.appendChild(opt);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(sourcePlanet.children.length === 0) {
 | 
			
		||||
		const opt = document.createElement('option');
 | 
			
		||||
		opt.value = '';
 | 
			
		||||
		opt.innerText = 'No planets';
 | 
			
		||||
		sourcePlanet.appendChild(opt);
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
sourceSystem.dispatchEvent(new Event('change'));
 | 
			
		||||
 | 
			
		||||
fromSystemCheckbox.addEventListener('change', () => {
 | 
			
		||||
	sourcePlanet.disabled = fromSystemCheckbox.checked;
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
import { UUID } from "mongodb";
 | 
			
		||||
 | 
			
		||||
export default interface Asteroid {
 | 
			
		||||
    id: UUID;
 | 
			
		||||
    name: string;
 | 
			
		||||
    resources: {
 | 
			
		||||
        id: string;
 | 
			
		||||
        amount: number;
 | 
			
		||||
    }[];
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
type MissionType = "TRANSPORT" | "ATTACK" | "TRANSFER" | "EXPEDITION";
 | 
			
		||||
type MissionType = "TRANSPORT" | "ATTACK" | "TRANSFER" | "EXPEDITION" | "MINE";
 | 
			
		||||
 | 
			
		||||
export default MissionType;
 | 
			
		||||
| 
						 | 
				
			
			@ -11,4 +11,5 @@ export default interface DBFleet {
 | 
			
		|||
    mission: MissionType;
 | 
			
		||||
    ships: Array<{ id: string, amount: number }>;
 | 
			
		||||
    cargo: Array<{ id: string, amount: number }>;
 | 
			
		||||
    additionalData?: string;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import { ObjectId } from "mongodb";
 | 
			
		||||
import { ObjectId, UUID } from "mongodb";
 | 
			
		||||
 | 
			
		||||
export default interface DBSystem {
 | 
			
		||||
    _id: ObjectId;
 | 
			
		||||
| 
						 | 
				
			
			@ -21,4 +21,12 @@ export default interface DBSystem {
 | 
			
		|||
        id: string,
 | 
			
		||||
        amount: number
 | 
			
		||||
    }>;
 | 
			
		||||
    asteroids: Array<{
 | 
			
		||||
        id: UUID,
 | 
			
		||||
        name: string,
 | 
			
		||||
        resources: Array<{
 | 
			
		||||
            id: string,
 | 
			
		||||
            amount: number
 | 
			
		||||
        }>
 | 
			
		||||
    }>;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue