160 lines
7.0 KiB
TypeScript
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);
|
|
}
|
|
} |