Implement colonization mechanic

This commit is contained in:
Aelita4 2025-02-07 11:11:35 +01:00
parent 848f2c37dc
commit e3be290d3d
Signed by: Aelita4
GPG Key ID: E44490C2025906C1
5 changed files with 164 additions and 4 deletions

View File

@ -10,7 +10,17 @@ import getDistanceBetween from "../../utils/getDistanceBetween";
import { getRandomInRange, weightedRandom } from "../../utils/math";
import { Sector } from "./LocationManager";
import { Planet } from "./PlanetManager";
import SystemManager from "./SystemManager";
import SystemManager, { System } from "./SystemManager";
import DBSystem from "../../../types/db/DBSystem";
import { addPlanetToSystem, createSystem, getSystemById } from "../../db/systems";
import DBPlanet from "../../../types/db/DBPlanet";
import { createPlanet } from "../../db/planets";
import PlanetResourceManager from "./PlanetResourceManager";
import BuildingManager from "./BuildingManager";
import PlanetShipManager from "./PlanetShipManager";
import PlanetDefenseManager from "./PlanetDefenseManager";
import PlanetEnergyManager from "./PlanetEnergyManager";
import { addSystemToSector } from "../../db/sectors";
export type Fleet = {
id: ObjectId,
@ -256,6 +266,136 @@ export default class FleetManager {
await this.initiateReturn();
return false;
case 'COLONIZE':
const destination = this.data.destination as Sector | SystemManager;
if(destination instanceof SystemManager) {
if(!destination.data.ownedBy.id.equals(this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id)) {
throw new Error("Cannot colonize system owned by other player.");
}
const planetData: DBPlanet = {
_id: new ObjectId(),
name: `Planet 1`,
owner: destination.data.ownedBy.id,
fields: 40,
resources: [],
buildings: [],
ships: [],
defenses: []
}
await createPlanet(planetData);
await addPlanetToSystem(destination.data._id, planetData._id);
const planetObject: Planet = {
_id: planetData._id,
system: destination,
name: planetData.name,
fields: planetData.fields,
//@ts-ignore
resources: null,
//@ts-ignore
buildings: null,
//@ts-ignore
ships: null,
//@ts-ignore
defenses: null,
//@ts-ignore
energy: null
}
planetObject.resources = await new PlanetResourceManager(planetObject).init(planetData.resources);
planetObject.buildings = await new BuildingManager(planetObject).init(planetData.buildings);
planetObject.ships = await new PlanetShipManager(planetObject).init(planetData.ships);
planetObject.defenses = await new PlanetDefenseManager(planetObject).init(planetData.defenses);
planetObject.energy = new PlanetEnergyManager(planetObject).update();
for(const ship of this.data.ships) {
if(ship.id === "colonizing-ship") continue;
planetObject.ships.addShips(ship.id, ship.amount);
}
planetObject.resources.setAmount(this.data.cargo);
destination.planets.push(planetObject);
await sendMail(
null,
this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id,
this.data.arrivalTime,
"New planet colonized",
`Your fleet has found a suitable planet for colonization in ${destination.data.name} system.\n
All the ships and resources have been used to establish a new colony.`
);
} else {
const systemData: DBSystem = {
_id: new ObjectId(),
name: `System ${destination.systems.length + 1}`,
ownedBy: this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id,
planets: [],
structures: [],
resources: [],
ships: [],
defenses: [],
asteroids: []
}
const planetData: DBPlanet = {
_id: new ObjectId(),
name: `Planet 1`,
owner: systemData.ownedBy,
fields: 40,
resources: [],
buildings: [],
ships: [],
defenses: []
}
systemData.planets.push(planetData._id);
await createSystem(systemData);
await createPlanet(planetData);
await addPlanetToSystem(systemData._id, planetData._id);
await addSystemToSector(destination._id, systemData._id);
const systemObject: System = {
_id: systemData._id,
sector: destination,
name: systemData.name,
ownedBy: this.data.source instanceof SystemManager ? this.data.source.data.ownedBy : this.data.source.system.data.ownedBy,
//@ts-ignore
structures: null,
//@ts-ignore
resources: null,
//@ts-ignore
ships: null,
//@ts-ignore
defenses: null,
planets: [],
asteroids: []
}
const systemManager = await new SystemManager(systemObject).fillData(systemData);
const planet = systemManager.planets.find(p => p._id.equals(planetData._id));
if(!planet) throw new Error("FATAL: Planet was not created properly in system manager.");
for(const ship of this.data.ships) {
if(ship.id === "colonizing-ship") continue;
planet.ships.addShips(ship.id, ship.amount);
}
planet.resources.setAmount(this.data.cargo);
destination.systems.push(systemManager);
await sendMail(
null,
this.data.source instanceof SystemManager ? this.data.source.data.ownedBy.id : this.data.source.system.data.ownedBy.id,
this.data.arrivalTime,
"New system colonized",
`Your fleet has settled on a planet ${planet.name} in a new system ${systemManager.data.name} in ${destination.name} sector.\n
All the ships and resources have been used to establish a new colony.`
);
}
return true;
}
}
}

View File

@ -18,6 +18,15 @@ export const createSystem = async (system: DBSystem) => {
return await systems.insertOne(system);
}
export const addPlanetToSystem = async (systemId: ObjectId, planetId: ObjectId) => {
const systems = await Systems();
await systems.updateOne({ _id: systemId }, {
$push: {
planets: planetId
}
});
}
export const updateSystemStructures = async (systemId: ObjectId, structures: Array<{ id: string, level: number }>) => {
const systems = await Systems();
await systems.updateOne({ _id: systemId }, {

View File

@ -69,6 +69,13 @@ export const POST: APIRoute = async({ request }) => {
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 === "COLONIZE") {
const destinationSector = checkSectorId(body.destination);
if(typeof destinationSector.error !== "undefined") {
const destinationSystem = checkPlanetOrSystemId(body.destination, 'destination');
if(typeof destinationSystem.error !== "undefined") return new Response(JSON.stringify(destinationSystem), { status: destinationSystem.code });
dest = destinationSystem.planetOrSystem;
} else 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 });

View File

@ -33,8 +33,11 @@ if(Astro.request.method === "POST") {
}
});
const destination = form.get('mission') === "EXPEDITION" ?
form.get('destination-sector')?.toString() :
const destination = form.get('mission') === "EXPEDITION" || form.get('mission') === "COLONIZE" ?
form.get('toSystem') ?
form.get('destination-system')?.toString() :
form.get('destination-sector')?.toString()
:
form.get('toSystem') ?
form.get('destination-system')?.toString() :
form.get('destination-planet')?.toString();
@ -170,6 +173,7 @@ const sectorsList = galaxies.map(galaxy => {
<label for="transfer"><input type="radio" name="mission" value="TRANSFER" id="transfer" />Transfer</label>
<label for="expedition"><input type="radio" name="mission" value="EXPEDITION" id="expedition" />Expedition</label>
<label for="spy"><input type="radio" name="mission" value="SPY" id="spy" />Spying</label>
<label for="colonize"><input type="radio" name="mission" value="COLONIZE" id="colonize" />Colonize</label>
<label><input type="checkbox" name="toSystem" />Send to system</label>
<hr />
<h2>Send to</h2>

View File

@ -1,3 +1,3 @@
type MissionType = "TRANSPORT" | "ATTACK" | "TRANSFER" | "EXPEDITION" | "MINE" | "SPY";
type MissionType = "TRANSPORT" | "ATTACK" | "TRANSFER" | "EXPEDITION" | "MINE" | "SPY" | "COLONIZE";
export default MissionType;