Compare commits
5 Commits
12f022150c
...
14f399659e
Author | SHA1 | Date |
---|---|---|
|
14f399659e | |
|
4fb4a19b0b | |
|
db7abbb997 | |
|
bf54589069 | |
|
f6a27eec59 |
|
@ -2,12 +2,13 @@ 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";
|
||||
import { Sector } from "./LocationManager";
|
||||
import { getRandomInRange, weightedRandom } from "../../utils/math";
|
||||
import { getAllShips } from "../../db/ships";
|
||||
import getDistanceBetween from "../../utils/getDistanceBetween";
|
||||
import { getRandomInRange, weightedRandom } from "../../utils/math";
|
||||
import { Sector } from "./LocationManager";
|
||||
import { Planet } from "./PlanetManager";
|
||||
import SystemManager from "./SystemManager";
|
||||
|
||||
export type Fleet = {
|
||||
id: ObjectId,
|
||||
|
@ -21,6 +22,13 @@ export type Fleet = {
|
|||
cargo: Array<{ id: string, amount: number }>
|
||||
}
|
||||
|
||||
export type BattleFleet = {
|
||||
id: string,
|
||||
hitpoints: number,
|
||||
attack: number,
|
||||
defense: number
|
||||
}
|
||||
|
||||
export default class FleetManager {
|
||||
data: Fleet;
|
||||
|
||||
|
@ -94,7 +102,12 @@ export default class FleetManager {
|
|||
} else {
|
||||
switch(this.data.mission) {
|
||||
case 'ATTACK':
|
||||
return false;
|
||||
if(!("expedition" in this.data.destination)) {
|
||||
const enemyShips = this.data.destination.ships.ships;
|
||||
return await this.battleResults(enemyShips.map(ship => { return { id: ship.data.id, amount: ship.amount } }));
|
||||
} else {
|
||||
throw new Error("Cannot attack sector.");
|
||||
}
|
||||
case 'TRANSPORT':
|
||||
await (this.data.destination as Planet | SystemManager).resources.updateAmount(this.data.cargo);
|
||||
await (this.data.destination as Planet | SystemManager).resources.sync();
|
||||
|
@ -139,23 +152,150 @@ export default class FleetManager {
|
|||
}
|
||||
}
|
||||
|
||||
async initiateReturn() {
|
||||
async initiateReturn(isByPlayer: boolean = false) {
|
||||
this.data.returning = true;
|
||||
this.data.departureTime = new Date(this.data.arrivalTime);
|
||||
this.data.arrivalTime = new Date(this.data.departureTime.getTime() + 1000 * 30);
|
||||
const elapsedTime = Date.now() - this.data.departureTime.getTime();
|
||||
this.data.departureTime = isByPlayer ? new Date() : new Date(this.data.arrivalTime);
|
||||
const travelTime = getDistanceBetween(this.data.destination, this.data.source);
|
||||
this.data.arrivalTime = new Date(this.data.departureTime.getTime() + (isByPlayer ? elapsedTime : 1000 * travelTime));
|
||||
await this.sync();
|
||||
}
|
||||
|
||||
private async sendMail(description: string) {
|
||||
private async sendMail(title: string, description: string) {
|
||||
await sendMail(
|
||||
null,
|
||||
this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id,
|
||||
this.data.arrivalTime,
|
||||
"Expedition Results",
|
||||
title,
|
||||
description
|
||||
);
|
||||
}
|
||||
|
||||
async battleResults(enemyFleet: { id: string, amount: number }[]) {
|
||||
const allShips = await getAllShips();
|
||||
|
||||
const playerStats = this.data.ships.reduce((acc, ship) => {
|
||||
const dbShip = allShips.find(s => s.id === ship.id);
|
||||
if(!dbShip) return acc;
|
||||
acc.attack += dbShip.structure.attack * ship.amount;
|
||||
acc.defense += dbShip.structure.defense * ship.amount;
|
||||
acc.hitpoints += dbShip.structure.hitpoints * ship.amount;
|
||||
return acc;
|
||||
}, { attack: 0, defense: 0, hitpoints: 0 });
|
||||
|
||||
const enemyStats = enemyFleet.reduce((acc, ship) => {
|
||||
const dbShip = allShips.find(s => s.id === ship.id);
|
||||
if(!dbShip) return acc;
|
||||
acc.attack += dbShip.structure.attack * ship.amount;
|
||||
acc.defense += dbShip.structure.defense * ship.amount;
|
||||
acc.hitpoints += dbShip.structure.hitpoints * ship.amount;
|
||||
return acc;
|
||||
}, { attack: 0, defense: 0, hitpoints: 0 });
|
||||
|
||||
const playerShipsStructure: BattleFleet[] = [];
|
||||
for(const playerShip of this.data.ships) {
|
||||
for(let i = 0; i < playerShip.amount; i++) playerShipsStructure.push({
|
||||
id: playerShip.id,
|
||||
hitpoints: allShips.find(s => s.id === playerShip.id)?.structure.hitpoints ?? 0,
|
||||
attack: allShips.find(s => s.id === playerShip.id)?.structure.attack ?? 0,
|
||||
defense: allShips.find(s => s.id === playerShip.id)?.structure.defense ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
const enemyShipsStructure: BattleFleet[] = [];
|
||||
for(const enemyShip of enemyFleet) {
|
||||
for(let i = 0; i < enemyShip.amount; i++) enemyShipsStructure.push({
|
||||
id: enemyShip.id,
|
||||
hitpoints: allShips.find(s => s.id === enemyShip.id)?.structure.hitpoints ?? 0,
|
||||
attack: allShips.find(s => s.id === enemyShip.id)?.structure.attack ?? 0,
|
||||
defense: allShips.find(s => s.id === enemyShip.id)?.structure.defense ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
if(playerStats.attack > enemyStats.defense * 2 && playerStats.defense > enemyStats.attack * 2) {
|
||||
enemyShipsStructure.forEach((_, index) => enemyShipsStructure.splice(index, 1));
|
||||
} else if(enemyStats.attack > playerStats.defense * 2 && enemyStats.defense > playerStats.attack * 2) {
|
||||
playerShipsStructure.forEach((_, index) => playerShipsStructure.splice(index, 1));
|
||||
} else {
|
||||
roundLoop: for(let i = 0; i < 3; i++) {
|
||||
for(const playerShip of playerShipsStructure) {
|
||||
const enemyShip = enemyShipsStructure[Math.floor(Math.random() * enemyShipsStructure.length)];
|
||||
|
||||
if(!enemyShip) break roundLoop;
|
||||
const typeCount = playerShipsStructure.filter(s => s.id === playerShip.id).length;
|
||||
const additionalShipAttack = typeCount > 1 ? Math.floor(Math.random() * typeCount) * playerShip.attack : 0;
|
||||
const playerDamage = Math.max(0, (playerShip.attack + additionalShipAttack) - enemyShip.defense);
|
||||
enemyShip.hitpoints -= playerDamage;
|
||||
}
|
||||
|
||||
for(const enemyShip of enemyShipsStructure) {
|
||||
const playerShip = playerShipsStructure[Math.floor(Math.random() * playerShipsStructure.length)];
|
||||
|
||||
if(!playerShip) break roundLoop;
|
||||
const typeCount = enemyShipsStructure.filter(s => s.id === enemyShip.id).length;
|
||||
const additionalShipAttack = typeCount > 1 ? Math.floor(Math.random() * typeCount) * enemyShip.attack : 0;
|
||||
const enemyDamage = Math.max(0, (enemyShip.attack + additionalShipAttack) - playerShip.defense);
|
||||
playerShip.hitpoints -= enemyDamage;
|
||||
}
|
||||
|
||||
playerShipsStructure.forEach((ship, index) => {
|
||||
if(ship.hitpoints <= 0) playerShipsStructure.splice(index, 1);
|
||||
});
|
||||
|
||||
enemyShipsStructure.forEach((ship, index) => {
|
||||
if(ship.hitpoints <= 0) enemyShipsStructure.splice(index, 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const playerBalance = playerStats.defense - enemyStats.attack;
|
||||
const enemyBalance = enemyStats.defense - playerStats.attack;
|
||||
|
||||
const playerShipsLeft = playerShipsStructure.reduce((acc, ship) => { acc[ship.id] = (acc[ship.id] ?? 0) + 1; return acc }, {} as { [key: string]: number });
|
||||
const enemyShipsLeft = enemyShipsStructure.reduce((acc, ship) => { acc[ship.id] = (acc[ship.id] ?? 0) + 1; return acc }, {} as { [key: string]: number });
|
||||
|
||||
const resourcesStolen: { id: string, amount: number }[] = [];
|
||||
|
||||
const previousShips = JSON.parse(JSON.stringify(this.data.ships)) as Array<{ id: string, amount: number }>;
|
||||
if(playerShipsStructure.length > 0) {
|
||||
this.data.ships = Object.keys(playerShipsLeft).map(id => { return { id, amount: playerShipsLeft[id] } });
|
||||
if(playerBalance > enemyBalance) {
|
||||
const enemyResources = await (this.data.destination as Planet | SystemManager).resources;
|
||||
await enemyResources.calculateCurrentAvailableResources();
|
||||
let cargoSpaceFree = this.data.ships.reduce((acc, ship) => {
|
||||
const dbShip = allShips.find(s => s.id === ship.id);
|
||||
if(!dbShip) return acc;
|
||||
return acc + dbShip.capacity.solid * ship.amount;
|
||||
}, 0);
|
||||
|
||||
for(const res of enemyResources.resources) {
|
||||
if(cargoSpaceFree <= 0) break;
|
||||
const amount = Math.min(Math.floor(Math.random() * res.amount), cargoSpaceFree);
|
||||
cargoSpaceFree -= amount;
|
||||
this.data.cargo.push({ id: res.id, amount });
|
||||
resourcesStolen.push({ id: res.id, amount });
|
||||
enemyResources.setAmount([{ id: res.id, amount: res.amount - amount }]);
|
||||
};
|
||||
}
|
||||
|
||||
await this.initiateReturn();
|
||||
} else this.data.ships = [];
|
||||
|
||||
await this.sendMail(
|
||||
`Battle Results (${playerBalance > enemyBalance ? "Victory" : playerBalance < enemyBalance ? "Defeat" : "Draw"})`,
|
||||
`Results of battle at ${(this.data.destination instanceof SystemManager ? this.data.destination.data.name : this.data.destination.name)}:\n
|
||||
Player ships:\n${previousShips.map(ship => `${ship.amount} ${ship.id}`).join('\n')}\n
|
||||
Enemy ships:\n${enemyFleet.map(ship => `${ship.amount} ${ship.id}`).join('\n')}\n\n
|
||||
Player stats: ${playerStats.hitpoints} HP, ${playerStats.attack} ATK, ${playerStats.defense} DEF\n
|
||||
Enemy stats: ${enemyStats.hitpoints} HP, ${enemyStats.attack} ATK, ${enemyStats.defense} DEF\n\n
|
||||
Player ships left:\n${Object.keys(playerShipsLeft).map(key => `${key} - ${playerShipsLeft[key]}`).join('\n')}\n
|
||||
Enemy ships left:\n${Object.keys(enemyShipsLeft).map(key => `${key} - ${enemyShipsLeft[key]}`).join('\n')}\n
|
||||
${playerBalance > enemyBalance ? `Resources stolen:\n${resourcesStolen.map(res => `${res.id} - ${res.amount}`).join('\n')}` : ""}`
|
||||
);
|
||||
|
||||
return !(playerShipsStructure.length > 0);
|
||||
}
|
||||
|
||||
async expeditionResults() {
|
||||
const expeditionRandom = Math.random(); //TODO: make use of "expedition" from DBSector
|
||||
|
||||
|
@ -169,7 +309,7 @@ export default class FleetManager {
|
|||
|
||||
if(expeditionRandom < 0.02) { // 2% chance; lost all ships, black hole
|
||||
this.data.ships = [];
|
||||
await this.sendMail(`Your expedition to ${(this.data.destination as Sector).name} sector encountered a black hole. All ships were lost.`);
|
||||
await this.sendMail("Expedition Results", `Your expedition to ${(this.data.destination as Sector).name} sector encountered a black hole. All ships were lost.`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -184,7 +324,7 @@ export default class FleetManager {
|
|||
else ship.amount += s.amount;
|
||||
}
|
||||
|
||||
await this.sendMail(`Your expedition to ${(this.data.destination as Sector).name} sector encountered abandoned shipyard. Following ships were added to the fleet:\n${ships.map(s => `${s.id} - ${s.amount}`).join(', ')}`);
|
||||
await this.sendMail("Expedition Results", `Your expedition to ${(this.data.destination as Sector).name} sector encountered abandoned shipyard. Following ships were added to the fleet:\n${ships.map(s => `${s.id} - ${s.amount}`).join(', ')}`);
|
||||
await this.initiateReturn();
|
||||
return;
|
||||
}
|
||||
|
@ -216,16 +356,19 @@ export default class FleetManager {
|
|||
else resource.amount += res.amount;
|
||||
}
|
||||
|
||||
await this.sendMail(`Your expedition to ${(this.data.destination as Sector).name} sector encountered resource-rich asteroid. Following resources were added to the cargo inventory:\n${resources.map(r => `${r.id} - ${r.amount}`).join('\n')}`);
|
||||
await this.sendMail("Expedition Results", `Your expedition to ${(this.data.destination as Sector).name} sector encountered resource-rich asteroid. Following resources were added to the cargo inventory:\n${resources.map(r => `${r.id} - ${r.amount}`).join('\n')}`);
|
||||
await this.initiateReturn();
|
||||
return;
|
||||
}
|
||||
|
||||
if(expeditionRandom < 0.35) { // 15% chance; pirates/aliens
|
||||
//TODO: implement fight mechanic
|
||||
const pirates: { id: string, amount: number }[] = [
|
||||
{ id: 'fighter', amount: getRandomInRange(0, 100) + valueAdded },
|
||||
{ id: 'transporter', amount: getRandomInRange(0, 100) + valueAdded }
|
||||
];
|
||||
|
||||
await this.sendMail(`Your expedition to ${(this.data.destination as Sector).name} sector encountered drunk pirates. After attempting to communicate with them, they attacked your fleet.`)
|
||||
await this.initiateReturn();
|
||||
await this.sendMail("Expedition Results", `Your expedition to ${(this.data.destination as Sector).name} sector encountered drunk pirates. After attempting to communicate with them, they attacked your fleet.`)
|
||||
await this.battleResults(pirates);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -273,12 +416,12 @@ export default class FleetManager {
|
|||
else resource.amount += res.amount;
|
||||
}
|
||||
|
||||
await this.sendMail(`Your expedition to ${(this.data.destination as Sector).name} sector encountered resource-rich rouge planet. Your fleet could not extract all resources. Following resources were added to the cargo inventory:\n${addedResources.map(r => `${r.id} - ${r.amount}`).join('\n')}`);
|
||||
await this.sendMail("Expedition Results", `Your expedition to ${(this.data.destination as Sector).name} sector encountered resource-rich rouge planet. Your fleet could not extract all resources. Following resources were added to the cargo inventory:\n${addedResources.map(r => `${r.id} - ${r.amount}`).join('\n')}`);
|
||||
await this.initiateReturn();
|
||||
return;
|
||||
}
|
||||
|
||||
await this.sendMail(`Your expedition to ${(this.data.destination as Sector).name} sector scanned the sector for a long time, yet it haven't found anything.`);
|
||||
await this.sendMail("Expedition Results", `Your expedition to ${(this.data.destination as Sector).name} sector scanned the sector for a long time, yet it haven't found anything.`);
|
||||
await this.initiateReturn();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
import { Sector } from "../classes/managers/LocationManager";
|
||||
import { Planet } from "../classes/managers/PlanetManager";
|
||||
import SystemManager from "../classes/managers/SystemManager";
|
||||
|
||||
const PLANET_TO_SYSTEM = 120;
|
||||
const BETWEEN_PLANETS = 300;
|
||||
const BETWEEN_SYSTEMS = 1000;
|
||||
const BETWEEN_SECTORS = 10000;
|
||||
const BETWEEN_GALAXIES = 100000;
|
||||
|
||||
export default function getDistanceBetween(a: Planet | SystemManager | Sector, b: Planet | SystemManager | Sector) {
|
||||
if("fields" in a) { // a is planet
|
||||
// b is planet
|
||||
if("fields" in b) {
|
||||
// same planet
|
||||
if(a._id.equals(b._id)) return 0;
|
||||
// same system
|
||||
if(a.system.data._id.equals(b.system.data._id)) return BETWEEN_PLANETS;
|
||||
// same sector
|
||||
if(a.system.data.sector._id.equals(b.system.data.sector._id)) return BETWEEN_PLANETS + BETWEEN_SYSTEMS;
|
||||
// same galaxy
|
||||
if(a.system.data.sector.galaxy._id.equals(b.system.data.sector.galaxy._id)) return BETWEEN_PLANETS + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return BETWEEN_PLANETS + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
// b is system
|
||||
else if("planets" in b) {
|
||||
// same system
|
||||
if(a.system.data._id.equals(b.data._id)) return PLANET_TO_SYSTEM;
|
||||
// same sector
|
||||
if(a.system.data.sector._id.equals(b.data.sector._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS;
|
||||
// same galaxy
|
||||
if(a.system.data.sector.galaxy._id.equals(b.data.sector.galaxy._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
// b is sector
|
||||
else {
|
||||
// same sector
|
||||
if(a.system.data.sector._id.equals(b._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS;
|
||||
// same galaxy
|
||||
if(a.system.data.sector.galaxy._id.equals(b.galaxy._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
} else if("planets" in a) { // a is system
|
||||
// b is planet
|
||||
if("fields" in b) {
|
||||
// same system
|
||||
if(a.data._id.equals(b.system.data._id)) return PLANET_TO_SYSTEM;
|
||||
// same sector
|
||||
if(a.data.sector._id.equals(b.system.data.sector._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS;
|
||||
// same galaxy
|
||||
if(a.data.sector.galaxy._id.equals(b.system.data.sector.galaxy._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
// b is system
|
||||
else if("planets" in b) {
|
||||
// same system
|
||||
if(a.data._id.equals(b.data._id)) return 0;
|
||||
// same sector
|
||||
if(a.data.sector._id.equals(b.data.sector._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS;
|
||||
// same galaxy
|
||||
if(a.data.sector.galaxy._id.equals(b.data.sector.galaxy._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
// b is sector
|
||||
else {
|
||||
// same sector
|
||||
if(a.data.sector._id.equals(b._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS;
|
||||
// same galaxy
|
||||
if(a.data.sector.galaxy._id.equals(b.galaxy._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
} else { // a is sector
|
||||
// b is planet
|
||||
if("fields" in b) {
|
||||
// same sector
|
||||
if(a._id.equals(b.system.data.sector._id)) return BETWEEN_PLANETS + BETWEEN_SYSTEMS;
|
||||
// same galaxy
|
||||
if(a.galaxy._id.equals(b.system.data.sector.galaxy._id)) return BETWEEN_PLANETS + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return BETWEEN_PLANETS + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
// b is system
|
||||
else if("planets" in b) {
|
||||
// same sector
|
||||
if(a._id.equals(b.data.sector._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS;
|
||||
// same galaxy
|
||||
if(a.galaxy._id.equals(b.data.sector.galaxy._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
// b is sector
|
||||
else {
|
||||
// same sector
|
||||
if(a._id.equals(b._id)) return 0;
|
||||
// same galaxy
|
||||
if(a.galaxy._id.equals(b.galaxy._id)) return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS;
|
||||
// different galaxy
|
||||
return PLANET_TO_SYSTEM + BETWEEN_SYSTEMS + BETWEEN_SECTORS + BETWEEN_GALAXIES;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import { APIRoute } from "astro";
|
||||
import { ObjectId } from "mongodb";
|
||||
import locationManager from "../../../lib/classes/managers/LocationManager";
|
||||
import { getUserByAccessToken } from "../../../lib/db/users";
|
||||
import validateAccessToken from "../../../lib/utils/validateAccessToken";
|
||||
|
||||
export const POST: APIRoute = async({ request }) => {
|
||||
const response = await validateAccessToken(request);
|
||||
if(response instanceof Response) return response;
|
||||
|
||||
const userDB = await getUserByAccessToken(response);
|
||||
if(userDB === null) {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
code: 401,
|
||||
message: "Unauthorized"
|
||||
}), { status: 401 }
|
||||
)
|
||||
}
|
||||
|
||||
const user = locationManager.getUser(userDB._id);
|
||||
if(!user) {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
code: 401,
|
||||
message: "Unauthorized"
|
||||
}), { status: 401 }
|
||||
)
|
||||
}
|
||||
|
||||
let body: { id: string };
|
||||
try {
|
||||
body = await request.json()
|
||||
} catch(e) {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
code: 400,
|
||||
message: "Bad Request",
|
||||
error: "Invalid JSON body"
|
||||
}), { status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
let id;
|
||||
try {
|
||||
id = new ObjectId(body.id);
|
||||
} catch(e) {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
code: 400,
|
||||
message: "Bad Request",
|
||||
error: "Invalid ID format"
|
||||
}), { status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
const fleet = locationManager.fleet.find(fleet => fleet.data.id.equals(id));
|
||||
if(!fleet) {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
code: 404,
|
||||
message: "Not Found",
|
||||
error: "Fleet not found"
|
||||
}), { status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
fleet.data.arrivalTime = new Date();
|
||||
await fleet.initiateReturn(true);
|
||||
await fleet.sync();
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
code: 200,
|
||||
message: "OK"
|
||||
}), { status: 200 }
|
||||
)
|
||||
}
|
|
@ -10,6 +10,7 @@ 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";
|
||||
import getDistanceBetween from "../../../lib/utils/getDistanceBetween";
|
||||
|
||||
export const POST: APIRoute = async({ request }) => {
|
||||
const response = await validateAccessToken(request);
|
||||
|
@ -74,12 +75,14 @@ export const POST: APIRoute = async({ request }) => {
|
|||
dest = checkDestination.planetOrSystem;
|
||||
}
|
||||
|
||||
const flightTime = getDistanceBetween(source, dest);
|
||||
|
||||
const fleetManager = new FleetManager(
|
||||
new ObjectId(),
|
||||
source,
|
||||
dest,
|
||||
new Date(),
|
||||
new Date(Date.now() + 1000 * 30), //TODO: calculate time based on distance
|
||||
new Date(Date.now() + 1000 * flightTime),
|
||||
false,
|
||||
body.mission,
|
||||
body.ships,
|
||||
|
|
|
@ -11,6 +11,7 @@ const { token, user, lang } = Astro.locals;
|
|||
const active: SystemManager | Planet = Astro.locals.active;
|
||||
|
||||
const ships = await getAllShips();
|
||||
const url = Astro.url.origin;
|
||||
|
||||
if(Astro.request.method === "POST") {
|
||||
const form = await Astro.request.formData();
|
||||
|
@ -132,7 +133,8 @@ const sectorsList = galaxies.map(galaxy => {
|
|||
}).join(', ')} <br />
|
||||
Cargo: {typeof f.cargo === "undefined" || f.cargo.length === 0 ? <>None</> : f.cargo.map(c => `${c.amount} ${getName(lang, 'resources', c.id)}`).join(', ')} <br />
|
||||
Departured at: {f.departureTime.toISOString()} <br />
|
||||
Arrives: {f.arrivalTime.toISOString()} ({Math.floor((f.arrivalTime.getTime() - new Date().getTime()) / 1000)})
|
||||
Arrives: {f.arrivalTime.toISOString()} ({Math.floor((f.arrivalTime.getTime() - new Date().getTime()) / 1000)}) <br />
|
||||
<button class="revert" style={`${f.returning && "display: none;"}`} data-id={f._id.toString()}>Revert</button>
|
||||
</div>
|
||||
</li>)
|
||||
})}
|
||||
|
@ -324,7 +326,8 @@ label {
|
|||
color: black;
|
||||
}
|
||||
</style>
|
||||
<script define:vars={{ lang, sectorsList }}>
|
||||
<script define:vars={{ lang, sectorsList, url }}>
|
||||
const revertButtons = document.querySelectorAll('.revert');
|
||||
const destinationGalaxy = document.getElementById('destination-galaxy');
|
||||
const destinationSector = document.getElementById('destination-sector');
|
||||
const destinationSystem = document.getElementById('destination-system');
|
||||
|
@ -332,10 +335,24 @@ label {
|
|||
const toSystemCheckbox = document.querySelector('input[name="toSystem"]');
|
||||
const sendAllButtons = document.querySelectorAll('.cargo-sendall');
|
||||
|
||||
if(!destinationGalaxy || !destinationSector || !destinationSystem || !destinationPlanet || !toSystemCheckbox || !sendAllButtons) {
|
||||
if(!revertButtons || !destinationGalaxy || !destinationSector || !destinationSystem || !destinationPlanet || !toSystemCheckbox || !sendAllButtons) {
|
||||
console.error('Could not find all elements');
|
||||
return;
|
||||
};
|
||||
|
||||
revertButtons.forEach(revBut => revBut.addEventListener('click', async evt => {
|
||||
await fetch(`${url}/api/fleet/revert`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: evt.target.dataset.id
|
||||
})
|
||||
});
|
||||
|
||||
window.location.reload();
|
||||
}));
|
||||
|
||||
destinationGalaxy.addEventListener('change', () => {
|
||||
const galaxy = sectorsList.find(galaxy => galaxy._id === destinationGalaxy.value);
|
||||
|
|
|
@ -80,10 +80,48 @@ if(Astro.request.method === "POST") {
|
|||
|
||||
<Layout title="Login">
|
||||
<NavBar loggedIn="false" active="login" />
|
||||
<form method="POST">
|
||||
<input type="text" name="username" placeholder="username" /><br />
|
||||
<input type="password" name="password" placeholder="password" /><br />
|
||||
<input type="submit" value="login" />
|
||||
{ error !== "" ? <p style="color: red;">{error}</p> : "" }
|
||||
<form method="POST" class="login-form">
|
||||
<input class="login-input" type="text" name="username" placeholder="username" /><br />
|
||||
<input class="login-input" type="password" name="password" placeholder="password" /><br />
|
||||
<input class="login-submit" type="submit" value="login" />
|
||||
<p style="color: red;">{error}</p>
|
||||
</form>
|
||||
</Layout>
|
||||
</Layout>
|
||||
<style>
|
||||
.login-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 50px;
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
red,
|
||||
blue
|
||||
);
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
width: 300px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.login-input {
|
||||
margin: 5px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.login-submit {
|
||||
margin: 5px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -103,15 +103,52 @@ if(Astro.request.method === "POST") {
|
|||
}
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title="Register">
|
||||
<NavBar loggedIn="false" active="register" />
|
||||
<form method="POST">
|
||||
<input type="text" name="username" placeholder="username" /><br />
|
||||
<input type="email" name="email" placeholder="email" /><br />
|
||||
<input type="password" name="password" placeholder="password" /><br />
|
||||
<input type="password" name="password2" placeholder="password2" /><br />
|
||||
<input type="submit" value="register" />
|
||||
{ error !== "" ? <p style="color: red;">{error}</p> : "" }
|
||||
<form method="POST" class="register-form">
|
||||
<input class="register-input" type="text" name="username" placeholder="username" /><br />
|
||||
<input class="register-input" type="email" name="email" placeholder="email" /><br />
|
||||
<input class="register-input" type="password" name="password" placeholder="password" /><br />
|
||||
<input class="register-input" type="password" name="password2" placeholder="password2" /><br />
|
||||
<input class="register-submit" type="submit" value="register" />
|
||||
<p style="color: red;">{error}</p>
|
||||
</form>
|
||||
</Layout>
|
||||
</Layout>
|
||||
<style>
|
||||
.register-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 50px;
|
||||
background: linear-gradient(
|
||||
to bottom right,
|
||||
blue,
|
||||
red
|
||||
);
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
width: 300px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.register-input {
|
||||
margin: 5px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.register-submit {
|
||||
margin: 5px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue