AstroCol/src/lib/classes/managers/FleetManager.ts

160 lines
7.0 KiB
TypeScript

import { ObjectId } from "mongodb";
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";
import { sendMail } from "../../db/mails";
export type Fleet = {
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 }>
}
export default class FleetManager {
data: Fleet;
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,
destination,
departureTime,
arrivalTime,
returning,
mission,
ships,
cargo
}
}
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();
return { finished, fleet: this.data };
}
return { finished: false, fleet: this.data };
}
async finish() {
if(this.data.returning) {
for(const ship of this.data.ships) {
this.data.source.ships.addShips(ship.id, ship.amount);
}
await this.data.source.resources.updateAmount(this.data.cargo);
await this.data.source.ships.sync();
await this.data.source.resources.sync();
await sendMail(
null,
this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id,
this.data.arrivalTime,
"Fleet Returned",
`Your fleet from ${this.data.destination instanceof SystemManager ? `${this.data.destination.data.name} system` : `planet ${this.data.destination.name}`} has returned.\n
Ships: ${this.data.ships.map(ship => `${ship.amount} ${ship.id}`).join(', ')}\n
Cargo: ${this.data.cargo.length > 0 ? this.data.cargo.map(cargo => `${cargo.amount} ${cargo.id}`).join(', ') : 'None'}`
);
return true;
} else {
switch(this.data.mission) {
case 'ATTACK':
return false;
case 'TRANSPORT':
await this.data.destination.resources.updateAmount(this.data.cargo);
await this.data.destination.resources.sync();
const cargo = JSON.parse(JSON.stringify(this.data.cargo)) as Array<{ id: string, amount: number }>;
this.data.cargo = [];
const arrived = new Date(this.data.arrivalTime);
await this.initiateReturn();
await sendMail(
null,
this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id,
arrived,
"Fleet Arrived",
`Your fleet has arrived at ${this.data.destination instanceof SystemManager ? `${this.data.destination.data.name} system` : `planet ${this.data.destination.name}`}.\n
Ships: ${this.data.ships.map(ship => `${ship.amount} ${ship.id}`).join(', ')}\n
Cargo delivered: ${cargo.length > 0 ? cargo.map(cargo => `${cargo.amount} ${cargo.id}`).join(', ') : 'None'}\n
Fleet will return at ${this.data.arrivalTime}`
);
return false;
case 'TRANSFER':
await this.data.destination.resources.updateAmount(this.data.cargo);
await this.data.destination.resources.sync();
for(const ship of this.data.ships) {
this.data.destination.ships.addShips(ship.id, ship.amount);
}
await this.data.destination.ships.sync();
await sendMail(
null,
this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id,
this.data.arrivalTime,
"Fleet Arrived",
`Your fleet has arrived at ${this.data.destination instanceof SystemManager ? `${this.data.destination.data.name} system` : `planet ${this.data.destination.name}`}.\n
Ships: ${this.data.ships.map(ship => `${ship.amount} ${ship.id}`).join(', ')}\n
Cargo delivered: ${this.data.cargo.length > 0 ? this.data.cargo.map(cargo => `${cargo.amount} ${cargo.id}`).join(', ') : 'None'}\n
Ships will stay at the destination.`
);
return true;
}
}
}
async initiateReturn() {
this.data.returning = true;
this.data.departureTime = new Date(this.data.arrivalTime);
this.data.arrivalTime = new Date(this.data.departureTime.getTime() + 1000 * 30);
await this.sync();
}
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,
destination,
departureTime: this.data.departureTime,
arrivalTime: this.data.arrivalTime,
returning: this.data.returning,
mission: this.data.mission,
ships: this.data.ships,
cargo: this.data.cargo
}
await updateFleet(data);
}
}