Adapt system and planet managers to use common managers

This commit is contained in:
Aelita4 2024-11-14 14:43:34 +01:00
parent d0993a427f
commit 40499415be
Signed by: Aelita4
GPG Key ID: E44490C2025906C1
29 changed files with 606 additions and 302 deletions

View File

@ -3,7 +3,7 @@ import { ObjectId } from 'mongodb';
import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver';
import { getAllResources } from '../lib/db/resources';
import locationManager from '../lib/classes/managers/LocationManager';
import { Resource } from '../lib/classes/managers/ResourceManager';
import { Resource } from '../lib/classes/managers/abstract/ResourceManager';
const resourceTypes = await getAllResources();
@ -46,7 +46,7 @@ for(const key of planet.resources.resources) {
</div>
<div class="resourcebar-item-tooltip">
<div class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'avaliable')} - <span class="resourcebar-item-tooltip-avaliable">{Math.floor(res.amount).toString()}</span></div>
<div class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'production')} - <span class="resourcebar-item-tooltip-production">{res.perHourMiningRate.toString()}</span></div>
<div class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'production')} - <span class="resourcebar-item-tooltip-production">{res.perHourMiningRate?.toString() ?? "0"}</span></div>
<div class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'capacity')} - <span class="resourcebar-item-tooltip-capacity">{'21372137'}</span></div>
</div>
</div>

View File

@ -49,7 +49,7 @@ export default class Building {
}
// research
const playerResearch = this.manager.planet.manager.owner.research;
const playerResearch = this.manager.planet.system.data.ownedBy.research;
let playerResearchCanBuild = { canBuild: true, missing: "" };
for(const researchReq of this.data.requirements.research) {
if((playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0) < researchReq.level) {

View File

@ -1,5 +1,6 @@
import DBShip from "../../types/db/DBShip";
import ShipManager from "./managers/ShipManager";
import SystemManager from "./managers/SystemManager";
import ShipManager from "./managers/abstract/ShipManager";
export default class Ship {
manager: ShipManager;
@ -13,7 +14,7 @@ export default class Ship {
}
async checkRequiredResources(): Promise<boolean> {
const resources = await this.manager.planet.resources.calculateCurrentAvailableResources();
const resources = await this.manager.manager.resources.calculateCurrentAvailableResources();
const requirements = this.data.requirements.resources;
@ -33,7 +34,8 @@ export default class Ship {
}
async checkRequirements(): Promise<{ canBuild: boolean, error: string }> {
const playerBuildings = this.manager.planet.buildings.buildings;
if(!(this.manager.manager instanceof SystemManager)) {
const playerBuildings = this.manager.manager.buildings.buildings;
let playerBuildingsCanBuild = { canBuild: true, missing: "" };
this.data.requirements.buildings.forEach((buildingReq: any) => {
if((playerBuildings.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0) < buildingReq.level) {
@ -45,9 +47,23 @@ export default class Ship {
canBuild: false,
error: playerBuildingsCanBuild.missing
}
} /*else { //TODO: check for structures requirements
const structures = this.manager.manager.structures.structures;
let playerStructuresCanBuild = { canBuild: true, missing: "" };
this.data.requirements.structures.forEach((buildingReq: any) => {
if((structures.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0) < buildingReq.level) {
playerStructuresCanBuild = { canBuild: false, missing: `${buildingReq.id} level ${buildingReq.level} required, found ${structures.filter((structure) => structure.data.id === buildingReq.id)[0]?.level ?? 0}` };
return;
}
});
if(!playerStructuresCanBuild.canBuild) return {
canBuild: false,
error: playerStructuresCanBuild.missing
}
}*/
// research
const playerResearch = this.manager.planet.manager.owner.research;
const playerResearch = this.manager.manager instanceof SystemManager ? this.manager.manager.data.ownedBy.research : this.manager.manager.system.data.ownedBy.research;
let playerResearchCanBuild = { canBuild: true, missing: "" };
for(const researchReq of this.data.requirements.research) {
if(playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0 < researchReq.level) {

View File

@ -12,59 +12,59 @@ export default class Structure {
this.level = level;
}
// async checkRequiredResources(level: number): Promise<boolean> {
// const resources = await this.manager.planet.resources.calculateCurrentAvailableResources();
async checkRequiredResources(level: number): Promise<boolean> {
const resources = await this.manager.system.resources.calculateCurrentAvailableResources();
// const requirements = this.data.requirements.resources;
const requirements = this.data.requirements.resources;
// let canBuild = true;
let canBuild = true;
// for(let res of requirements) {
// const resource = resources.find(r => r.id === res.id);
// if(!resource) return false;
for(let res of requirements) {
const resource = resources.find(r => r.id === res.id);
if(!resource) return false;
// const required = Math.pow(this.data.multiplier, level) * res.amount;
const required = Math.pow(this.data.multiplier, level) * res.amount;
// if(resource.amount < required) {
// canBuild = false;
// break;
// }
// }
if(resource.amount < required) {
canBuild = false;
break;
}
}
// return canBuild;
// }
return canBuild;
}
// async checkRequirements(): Promise<{ canBuild: boolean, error: string }> {
// const playerBuildings = this.manager.buildings;
// let playerBuildingsCanBuild = { canBuild: true, missing: "" };
// this.data.requirements.buildings.forEach((buildingReq: any) => {
// if(playerBuildings.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0 < buildingReq.level) {
// playerBuildingsCanBuild = { canBuild: false, missing: `${buildingReq.id} level ${buildingReq.level} required, found ${playerBuildings.filter((building) => building.data.id === buildingReq.id)[0]?.level ?? 0}` };
// return;
// }
// });
// if(!playerBuildingsCanBuild.canBuild) return {
// canBuild: false,
// error: playerBuildingsCanBuild.missing
// }
async checkRequirements(): Promise<{ canBuild: boolean, error: string }> {
const playerStructures = this.manager.structures;
let playerStructuresCanBuild = { canBuild: true, missing: "" };
this.data.requirements.structures.forEach((structureReq: any) => {
if(playerStructures.filter((structure) => structure.data.id === structureReq.id)[0]?.level ?? 0 < structureReq.level) {
playerStructuresCanBuild = { canBuild: false, missing: `${structureReq.id} level ${structureReq.level} required, found ${playerStructures.filter((structure) => structure.data.id === structureReq.id)[0]?.level ?? 0}` };
return;
}
});
if(!playerStructuresCanBuild.canBuild) return {
canBuild: false,
error: playerStructuresCanBuild.missing
}
// // research
// const playerResearch = this.manager.planet.manager.owner.research;
// let playerResearchCanBuild = { canBuild: true, missing: "" };
// for(const researchReq of this.data.requirements.research) {
// if((playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0) < researchReq.level) {
// playerResearchCanBuild = { canBuild: false, missing: `${researchReq.id} level ${researchReq.level} required, found ${playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0}` };
// }
// };
// research
const playerResearch = this.manager.system.data.ownedBy.research;
let playerResearchCanBuild = { canBuild: true, missing: "" };
for(const researchReq of this.data.requirements.research) {
if((playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0) < researchReq.level) {
playerResearchCanBuild = { canBuild: false, missing: `${researchReq.id} level ${researchReq.level} required, found ${playerResearch.research.find((research) => research.id === researchReq.id)?.level ?? 0}` };
}
};
// if(!playerResearchCanBuild.canBuild) return {
// canBuild: false,
// error: playerResearchCanBuild.missing
// }
if(!playerResearchCanBuild.canBuild) return {
canBuild: false,
error: playerResearchCanBuild.missing
}
// return {
// canBuild: true,
// error: ""
// }
// }
return {
canBuild: true,
error: ""
}
}
}

View File

@ -3,11 +3,12 @@ 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";
export type Fleet = {
id: ObjectId,
source: Planet,
destination: Planet,
source: Planet | SystemManager,
destination: Planet | SystemManager,
departureTime: Date,
arrivalTime: Date,
returning: boolean,
@ -19,7 +20,7 @@ export type Fleet = {
export default class FleetManager {
data: Fleet;
constructor(id: ObjectId, source: Planet, destination: Planet, 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, departureTime: Date, arrivalTime: Date, returning: boolean, mission: MissionType, ships: Array<{ id: string, amount: number }>, cargo: Array<{ id: string, amount: number }>) {
this.data = {
id,
source,
@ -33,6 +34,32 @@ export default class FleetManager {
}
}
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();
@ -82,10 +109,13 @@ export default class FleetManager {
}
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: this.data.source._id,
destination: this.data.destination._id,
source,
destination,
departureTime: this.data.departureTime,
arrivalTime: this.data.arrivalTime,
returning: this.data.returning,

View File

@ -1,13 +1,13 @@
import { ObjectId } from "mongodb";
import PlanetManager, { Planet } from "./PlanetManager";
import { getAllFleet } from "../../db/fleet";
import { getAllGalaxies } from "../../db/galaxies";
import { getSectorById } from "../../db/sectors";
import { getSystemById } from "../../db/systems";
import { getAllUsers } from "../../db/users";
import User from "../User";
import StructureManager from "./StructureManager";
import FleetManager from "./FleetManager";
import { getAllFleet } from "../../db/fleet";
import { Planet } from "./PlanetManager";
import SystemManager, { System } from "./SystemManager";
export type Galaxy = {
_id: ObjectId,
@ -24,16 +24,7 @@ export type Sector = {
galaxy: Galaxy,
name: string,
expedition: null,
systems: Array<System>
}
export type System = {
_id: ObjectId,
sector: Sector,
name: string,
ownedBy: User,
structures: StructureManager,
planets: PlanetManager
systems: Array<SystemManager>
}
class LocationManager {
@ -99,14 +90,16 @@ class LocationManager {
ownedBy: user,
//@ts-ignore
structures: null,
planets: new PlanetManager(user)
//@ts-ignore
resources: null,
//@ts-ignore
ships: null,
planets: []
};
systemObject.structures = await new StructureManager(systemObject).init(systemData.structures);
const s = await new SystemManager(systemObject).fillData(systemData);
await systemObject.planets.fillData(systemObject, systemData.planets);
sectorObject.systems.push(systemObject);
sectorObject.systems.push(s);
};
console.log(`Loaded ${sectorObject.systems.length} systems from sector ${sectorObject.name}`);
@ -126,7 +119,7 @@ class LocationManager {
const userDB = users.find(u => u._id.equals(user.id));
const mainPlanet = this.getPlanet(userDB?.mainPlanet as ObjectId);
if(!mainPlanet) throw new Error("Main planet not found");
if(!mainPlanet) throw new Error(`Main planet not found for user ${user.username} (${user.id})`);
user.mainPlanet = mainPlanet;
};
@ -134,8 +127,8 @@ class LocationManager {
const fleets = await getAllFleet();
for(const fleet of fleets) {
if(fleet.arrivalTime > currentTime) {
const source = this.getPlanet(fleet.source);
const destination = this.getPlanet(fleet.destination);
const source = this.getPlanet(fleet.source) || this.getSystem(fleet.source);
const destination = this.getPlanet(fleet.destination) || this.getSystem(fleet.destination);
if(source && destination) this.fleet.push(new FleetManager(
fleet._id,
@ -156,6 +149,30 @@ class LocationManager {
return this;
}
findId(id: ObjectId) {
let found: SystemManager | Planet | null = null;
for(const galaxy of this.galaxies) {
for(const sector of galaxy.sectors) {
for(const system of sector.systems) {
if(system.data._id.equals(id)) {
found = system;
break;
}
for(const planet of system.planets) {
if(planet._id.equals(id)) {
found = planet;
break;
}
}
}
}
}
return found;
}
getGalaxy(_id: ObjectId) {
return this.galaxies.find(galaxy => galaxy._id.equals(_id));
}
@ -169,20 +186,20 @@ class LocationManager {
}
getSystem(_id: ObjectId) {
let foundSystem: System | undefined;
let foundSystem: SystemManager | undefined;
this.galaxies.find(galaxy => galaxy.sectors.find(sector => sector.systems.find(system => {
if(system._id.equals(_id)) foundSystem = system
if(system.data._id.equals(_id)) foundSystem = system
})));
return foundSystem
}
getSystemsOwnedBy(id: ObjectId) {
const systems: System[] = [];
const systems: SystemManager[] = [];
for(const galaxy of this.galaxies) {
for(const sector of galaxy.sectors) {
for(const system of sector.systems) {
if(system.ownedBy.id.equals(id)) systems.push(system);
if(system.data.ownedBy.id.equals(id)) systems.push(system);
}
}
}
@ -196,7 +213,7 @@ class LocationManager {
for(const galaxy of this.galaxies) {
for(const sector of galaxy.sectors) {
for(const system of sector.systems) {
foundPlanet = system.planets.getPlanetById(_id);
foundPlanet = system.planets.find(planet => planet._id.equals(_id));
if(foundPlanet) break;
}
if(foundPlanet) break;
@ -222,7 +239,17 @@ class LocationManager {
async getAllFleetByUserId(userId: string) {
await this.updateFleet();
return userId === '' ? [] : this.fleet.filter(fleet => fleet.data.source.manager.owner.id.equals(userId) || fleet.data.destination.manager.owner.id.equals(userId));
return userId === '' ? [] : this.fleet.filter(fleet => {
let found = false;
if(fleet.data.source instanceof SystemManager) found = fleet.data.source.data.ownedBy.id.equals(userId);
else found = fleet.data.source.system.data.ownedBy.id.equals(userId);
if(fleet.data.destination instanceof SystemManager) found = fleet.data.destination.data.ownedBy.id.equals(userId);
else found = fleet.data.destination.system.data.ownedBy.id.equals(userId);
return found;
});
}
addFleet(fleet: FleetManager) {

View File

@ -1,57 +1,15 @@
import { ObjectId } from "mongodb";
import BuildingManager from "./BuildingManager";
import { getPlanetById } from "../../db/planets";
import ResourceManager from "./ResourceManager";
import User from "../User";
import ShipManager from "./ShipManager";
import { System } from "./LocationManager";
import PlanetResourceManager from "./PlanetResourceManager";
import ShipManager from "./PlanetShipManager";
import SystemManager from "./SystemManager";
export type Planet = {
_id: ObjectId;
manager: PlanetManager;
system: SystemManager;
name: string;
fields: number;
resources: ResourceManager;
resources: PlanetResourceManager;
buildings: BuildingManager;
ships: ShipManager;
}
export default class PlanetManager {
planets: Array<Planet> = [];
owner: User;
system!: System;
constructor(user: User) {
this.owner = user;
}
async fillData(system: System, planets: ObjectId[]) {
this.system = system;
await Promise.all(planets.map(async planetId => {
const planet = await getPlanetById(planetId);
const planetObject: Planet = {
_id: planet._id,
manager: this,
name: planet.name,
fields: planet.fields,
//@ts-ignore
resources: null,
//@ts-ignore
buildings: null,
//@ts-ignore
ships: null
}
planetObject.resources = await new ResourceManager(planetObject).init(planet.resources);
planetObject.buildings = await new BuildingManager(planetObject).init(planet.buildings);
planetObject.ships = await new ShipManager(planetObject).init(planet.ships);
this.planets.push(planetObject);
}));
}
getPlanetById(id: ObjectId) {
return this.planets.find(planet => planet._id.equals(id));
}
}

View File

@ -1,22 +1,13 @@
import DBResource from "../../../types/db/DBResource";
import { updatePlanetResources } from "../../db/planets";
import { getAllResources } from "../../db/resources";
import { Planet } from "./PlanetManager";
import ResourceManager from "./abstract/ResourceManager";
export type Resource = {
id: string,
amount: number,
lastUpdated: Date,
perHourMiningRate: number,
data: DBResource
}
export default class ResourceManager {
resources: Array<Resource> = [];
resourcesDB: DBResource[] = [];
export default class PlanetResourceManager extends ResourceManager {
planet: Planet;
constructor(planet: Planet) {
super();
this.planet = planet;
}
@ -100,73 +91,6 @@ export default class ResourceManager {
return this;
}
getResourceById(resId: string) {
return this.resources.find(res => res.id === resId);
}
async calculateCurrentAvailableResources() {
this.resources.forEach(res => {
const timeDiff = Math.abs((new Date()).getTime() - res.lastUpdated.getTime());
const hours = timeDiff / (1000 * 60 * 60);
const amountToAdd = hours * res.perHourMiningRate;
res.amount += amountToAdd;
res.lastUpdated = new Date();
});
await updatePlanetResources(this.planet._id, this.resources);
return this.resources;
}
async getDifference(resources: { id: string, amount: number }[]): Promise<Array<Resource>> {
const currentResources = await this.calculateCurrentAvailableResources();
const difference: Resource[] = [];
currentResources.forEach(res => {
const currentRes = resources.find(r => r.id === res.id);
if(currentRes) difference.push({
id: res.id,
amount: res.amount - currentRes.amount,
lastUpdated: res.lastUpdated,
perHourMiningRate: res.perHourMiningRate,
data: res.data
});
else difference.push(res);
});
return difference;
}
add(resources: Resource[]) {
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount += res.amount;
else this.resources.push(res);
}
}
async updateAmount(resources: { id: string, amount: number }[]) {
await this.calculateCurrentAvailableResources();
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount += res.amount;
}
}
setAmount(resources: { id: string, amount: number }[]) {
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount = res.amount;
else this.resources.push({
id: res.id,
amount: res.amount,
lastUpdated: new Date(),
perHourMiningRate: 0,
data: this.resourcesDB.find(r => r.id === res.id)
});
}
}
async sync() {
await updatePlanetResources(this.planet._id, this.resources.map(res => {
return {

View File

@ -0,0 +1,17 @@
import { updatePlanetShips } from "../../db/planets";
import { Planet } from "./PlanetManager";
import ShipManager from "./abstract/ShipManager";
export default class PlanetShipManager extends ShipManager {
constructor(planet: Planet) {
super(planet);
}
get manager() {
return this._manager as Planet;
}
async sync() {
await updatePlanetShips(this.manager._id, this.ships.map(ship => { return { id: ship.data.id, amount: ship.amount } }));
}
}

View File

@ -1,17 +1,15 @@
import { updatePlanetBuildings } from '../../db/planets';
import Building from '../Building';
import DBStructure from '../../../types/db/DBStructure';
import { System } from './LocationManager';
import { getAllStructures } from '../../db/structures';
import Structure from '../Structure';
import { updateSystemStructures } from '../../db/systems';
import Structure from '../Structure';
import SystemManager from './SystemManager';
export default class StructureManager {
structures: Array<Structure> = [];
structuresDB: Array<DBStructure> = []
system: System;
system: SystemManager;
constructor(system: System) {
constructor(system: SystemManager) {
this.system = system;
}
@ -45,6 +43,6 @@ export default class StructureManager {
}
async sync() {
await updateSystemStructures(this.system._id, this.structures.map(structure => { return { id: structure.data.id, level: structure.level } }));
await updateSystemStructures(this.system.data._id, this.structures.map(structure => { return { id: structure.data.id, level: structure.level } }));
}
}

View File

@ -0,0 +1,73 @@
import { ObjectId } from "mongodb";
import DBSystem from "../../../types/db/DBSystem";
import { getPlanetById } from "../../db/planets";
import User from "../User";
import BuildingManager from "./BuildingManager";
import { Sector } from "./LocationManager";
import { Planet } from "./PlanetManager";
import PlanetResourceManager from "./PlanetResourceManager";
import PlanetShipManager from "./PlanetShipManager";
import StructureManager from "./StructureManager";
import SystemResourceManager from "./SystemResourceManager";
import SystemShipManager from "./SystemShipManager";
export type System = {
_id: ObjectId,
sector: Sector,
name: string,
ownedBy: User,
structures: StructureManager,
resources: SystemResourceManager,
ships: SystemShipManager,
planets: Planet[];
}
export default class SystemManager {
planets: Planet[] = [];
structures: StructureManager;
resources: SystemResourceManager;
ships: SystemShipManager;
data: System;
constructor(data: System) {
this.data = data;
this.structures = new StructureManager(this);
this.resources = new SystemResourceManager(this);
this.ships = new SystemShipManager(this);
}
async fillData(systemData: DBSystem) {
await this.structures.init(systemData.structures);
await this.resources.init(systemData.resources);
await this.ships.init(systemData.ships);
await Promise.all(systemData.planets.map(async planetId => {
const planet = await getPlanetById(planetId);
const planetObject: Planet = {
_id: planet._id,
system: this,
name: planet.name,
fields: planet.fields,
//@ts-ignore
resources: null,
//@ts-ignore
buildings: null,
//@ts-ignore
ships: null
}
planetObject.resources = await new PlanetResourceManager(planetObject).init(planet.resources);
planetObject.buildings = await new BuildingManager(planetObject).init(planet.buildings);
planetObject.ships = await new PlanetShipManager(planetObject).init(planet.ships);
this.planets.push(planetObject);
}));
return this;
}
addPlanet(planet: Planet) {
this.planets.push(planet);
}
}

View File

@ -0,0 +1,88 @@
import { getAllResources } from "../../db/resources";
import { updateSystemResources } from "../../db/systems";
import SystemManager from "./SystemManager";
import ResourceManager from "./abstract/ResourceManager";
export default class SystemResourceManager extends ResourceManager {
system: SystemManager;
constructor(system: SystemManager) {
super();
this.system = system;
}
async init(resourceData?: { id: string, amount: number }[]) {
const resources = await getAllResources();
this.resourcesDB = resources;
if(!resourceData || resourceData.length === 0) {
resourceData = [
{
id: "coal",
amount: 11
},
{
id: "iron",
amount: 22
},
{
id: "gold",
amount: 33
},
{
id: "water",
amount: 44
},
{
id: "sulfuric-acid",
amount: 55
},
{
id: "liquid-nitrogen",
amount: 66
},
{
id: "hydrogen",
amount: 77
},
{
id: "oxygen",
amount: 88
},
{
id: "helium-3",
amount: 99
}
];
await updateSystemResources(this.system.data._id, this.resources);
}
resourceData.forEach(resource => {
const resFromDB = resources.find(res => res.id === resource.id);
if(resFromDB) this.resources.push({
id: resource.id,
amount: resource.amount,
lastUpdated: null,
perHourMiningRate: null,
data: resFromDB
})
});
return this;
}
async sync() {
await updateSystemResources(this.system.data._id, this.resources.map(res => {
return {
id: res.id,
amount: res.amount,
lastUpdated: res.lastUpdated,
perHourMiningRate: res.perHourMiningRate
}
}));
}
}

View File

@ -0,0 +1,17 @@
import { updateSystemShips } from "../../db/systems";
import SystemManager from "./SystemManager";
import ShipManager from "./abstract/ShipManager";
export default class SystemShipManager extends ShipManager {
constructor(system: SystemManager) {
super(system);
}
get manager() {
return this._manager as SystemManager;
}
async sync() {
await updateSystemShips(this.manager.data._id, this.ships.map(ship => { return { id: ship.data.id, amount: ship.amount } }));
}
}

View File

@ -0,0 +1,92 @@
import DBResource from "../../../../types/db/DBResource";
export type Resource = {
id: string,
amount: number,
lastUpdated: Date | null,
perHourMiningRate: number | null,
data: DBResource
}
export default abstract class ResourceManager {
resources: Resource[] = [];
resourcesDB: DBResource[] = [];
abstract sync(): Promise<void>;
getResourceById(resId: string) {
return this.resources.find(res => res.id === resId);
}
async calculateCurrentAvailableResources() {
for(const res of this.resources) {
if(!res.lastUpdated || !res.perHourMiningRate) continue;
const timeDiff = Math.abs((new Date()).getTime() - res.lastUpdated.getTime());
const hours = timeDiff / (1000 * 60 * 60);
const amountToAdd = hours * res.perHourMiningRate;
res.amount += amountToAdd;
res.lastUpdated = new Date();
};
await this.sync();
return this.resources;
}
async getDifference(resources: { id: string, amount: number }[]): Promise<Array<Resource>> {
const currentResources = await this.calculateCurrentAvailableResources();
const difference: Resource[] = [];
currentResources.forEach(res => {
const currentRes = resources.find(r => r.id === res.id);
if(currentRes) difference.push({
id: res.id,
amount: res.amount - currentRes.amount,
lastUpdated: res.lastUpdated,
perHourMiningRate: res.perHourMiningRate,
data: res.data
});
else difference.push(res);
});
return difference;
}
add(resources: Resource[]) {
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount += res.amount;
else this.resources.push(res);
}
}
async updateAmount(resources: { id: string, amount: number }[]) {
await this.calculateCurrentAvailableResources();
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount += res.amount;
else this.resources.push({
id: res.id,
amount: res.amount,
lastUpdated: new Date(),
perHourMiningRate: 0,
data: this.resourcesDB.find(r => r.id === res.id) as DBResource
});
}
}
setAmount(resources: { id: string, amount: number }[]) {
for(const res of resources) {
const resource = this.resources.find(r => r.id === res.id);
if(resource) resource.amount = res.amount;
else this.resources.push({
id: res.id,
amount: res.amount,
lastUpdated: new Date(),
perHourMiningRate: 0,
data: this.resourcesDB.find(r => r.id === res.id) as DBResource
});
}
}
}

View File

@ -1,18 +1,22 @@
import { Planet } from './PlanetManager';
import { updatePlanetBuildings, updatePlanetShips } from '../../db/planets';
import DBShip from '../../../types/db/DBShip';
import { getAllShips } from '../../db/ships';
import Ship from '../Ship';
import { Planet } from '../PlanetManager';
import DBShip from '../../../../types/db/DBShip';
import { getAllShips } from '../../../db/ships';
import Ship from '../../Ship';
import SystemManager from '../SystemManager';
export default class ShipManager {
export default abstract class ShipManager {
ships: Array<Ship> = [];
shipsDB: Array<DBShip> = []
planet: Planet;
shipsDB: Array<DBShip> = [];
protected _manager: Planet | SystemManager;
constructor(planet: Planet) {
this.planet = planet;
constructor(manager: Planet | SystemManager) {
this._manager = manager;
}
abstract sync(): Promise<void>;
abstract get manager(): Planet | SystemManager;
async init(shipData: { id: string, amount: number }[]) {
this.shipsDB = await getAllShips();
@ -56,8 +60,4 @@ export default class ShipManager {
if(findShip.amount <= 0) this.ships.splice(this.ships.indexOf(findShip), 1);
}
}
async sync() {
await updatePlanetShips(this.planet._id, this.ships.map(ship => { return { id: ship.data.id, amount: ship.amount } }));
}
}

View File

@ -25,3 +25,21 @@ export const updateSystemStructures = async (systemId: ObjectId, structures: Arr
}
});
}
export const updateSystemResources = async (systemId: ObjectId, resources: Array<any>) => {
const systems = await Systems();
await systems.updateOne({ _id: systemId }, {
$set: {
resources
}
});
}
export const updateSystemShips = async (systemId: ObjectId, ships: Array<any>) => {
const systems = await Systems();
await systems.updateOne({ _id: systemId }, {
$set: {
ships
}
});
}

View File

@ -94,7 +94,7 @@ export const POST: APIRoute = async({ request }) => {
}
});
userPlanet.resources.update(resourcesAfter);
userPlanet.resources.updateAmount(resourcesAfter.map(res => { return { id: res.id, amount: res.amount } }));
userPlanet.buildings.addBuilding(building);
await userPlanet.buildings.sync();

View File

@ -9,6 +9,7 @@ import { Planet } from "../../../lib/classes/managers/PlanetManager";
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";
export const POST: APIRoute = async({ request }) => {
const response = await validateAccessToken(request);
@ -47,14 +48,14 @@ export const POST: APIRoute = async({ request }) => {
)
}
const checkSource = checkPlanetId(body.source, 'source');
const checkSource = checkPlanetOrSystemId(body.source, 'source');
if(typeof checkSource.error !== "undefined") return new Response(JSON.stringify(checkSource), { status: checkSource.code });
const checkDestination = checkPlanetId(body.destination, 'destination');
const checkDestination = checkPlanetOrSystemId(body.destination, 'destination');
if(typeof checkDestination.error !== "undefined") return new Response(JSON.stringify(checkDestination), { status: checkDestination.code });
const source = checkSource.planet;
const destination = checkDestination.planet;
const source = checkSource.planetOrSystem;
const destination = checkDestination.planetOrSystem;
const shipsDB = await getAllShips();
@ -112,7 +113,7 @@ export const POST: APIRoute = async({ request }) => {
)
}
function checkPlanetId(id: string, type: string) {
function checkPlanetOrSystemId(id: string, type: string) {
if(typeof ObjectId === "undefined") return {
code: 400,
message: "Bad Request",
@ -130,22 +131,22 @@ function checkPlanetId(id: string, type: string) {
}
}
const planet = locationManager.getPlanet(idToCheck);
const planetOrSystem = locationManager.findId(idToCheck);
if(!planet) return {
if(!planetOrSystem) return {
code: 404,
message: "Not Found",
error: `Non-existent planet provided in '${type}'`
error: `Non-existent planet or system provided in '${type}'`
}
return {
code: 200,
message: "OK",
planet
planetOrSystem
}
}
function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array<DBShip>, sourcePlanet: Planet) {
function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array<DBShip>, source: Planet | SystemManager) {
if(typeof ships === "undefined") return {
code: 400,
message: "Bad Request",
@ -177,7 +178,7 @@ function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array
error: "Ship amount for ID '" + ships[i].id + "' is not a non-negative integer at position " + i
}
if(ships[i].amount > (sourcePlanet.ships.getShipById(ships[i].id)?.amount ?? 0)) return {
if(ships[i].amount > (source.ships.getShipById(ships[i].id)?.amount ?? 0)) return {
code: 400,
message: "Bad Request",
error: "Not enough ships on planet with ID '" + ships[i].id + "' at position " + i
@ -190,7 +191,7 @@ function checkShips(ships: Array<{ id: string, amount: number }>, shipsDB: Array
}
}
function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{ id: string, amount: number }>, planet: Planet, missionType: MissionType) {
function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{ id: string, amount: number }>, source: Planet | SystemManager, missionType: MissionType) {
if(missionType === "TRANSPORT" && cargo.length === 0) return {
code: 400,
message: "Bad Request",
@ -204,7 +205,7 @@ function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{
error: "Missing resource ID at position " + i
}
if(!planet.resources.resourcesDB.find(resource => resource.id === cargo[i].id)) return {
if(!source.resources.resourcesDB.find(resource => resource.id === cargo[i].id)) return {
code: 404,
message: "Not Found",
error: "Non-existent resource ID '" + cargo[i].id + "' at position " + i
@ -222,23 +223,23 @@ function checkCargo(cargo: Array<{ id: string, amount: number }>, ships: Array<{
error: "Resource amount for ID '" + cargo[i].id + "' is not a non-negative integer at position " + i
}
if(cargo[i].amount > (planet.resources.resources.find(res => res.id === cargo[i].id)?.amount ?? 0)) return {
if(cargo[i].amount > (source.resources.resources.find(res => res.id === cargo[i].id)?.amount ?? 0)) return {
code: 400,
message: "Bad Request",
error: "Not enough resources on planet with ID '" + cargo[i].id + "' at position " + i
error: "Not enough resources on planet or system with ID '" + cargo[i].id + "' at position " + i
}
}
const totalCargoAvailable = {
solid: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.solid ?? 0) * ship.amount, 0),
liquid: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.liquid ?? 0) * ship.amount, 0),
gas: ships.reduce((acc, ship) => acc + (planet.ships.shipsDB.find(s => s.id === ship.id)?.capacity.gas ?? 0) * ship.amount, 0)
solid: ships.reduce((acc, ship) => acc + (source.ships.shipsDB.find(s => s.id === ship.id)?.capacity.solid ?? 0) * ship.amount, 0),
liquid: ships.reduce((acc, ship) => acc + (source.ships.shipsDB.find(s => s.id === ship.id)?.capacity.liquid ?? 0) * ship.amount, 0),
gas: ships.reduce((acc, ship) => acc + (source.ships.shipsDB.find(s => s.id === ship.id)?.capacity.gas ?? 0) * ship.amount, 0)
}
const totalCargoUsed = {
solid: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "solid" ? acc + resource.amount : acc, 0),
liquid: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "liquid" ? acc + resource.amount : acc, 0),
gas: cargo.reduce((acc, resource) => planet.resources.resourcesDB.find(res => res.id === resource.id)?.type === "gas" ? acc + resource.amount : acc, 0)
solid: cargo.reduce((acc, resource) => source.resources.resourcesDB.find(res => res.id === resource.id)?.type === "solid" ? acc + resource.amount : acc, 0),
liquid: cargo.reduce((acc, resource) => source.resources.resourcesDB.find(res => res.id === resource.id)?.type === "liquid" ? acc + resource.amount : acc, 0),
gas: cargo.reduce((acc, resource) => source.resources.resourcesDB.find(res => res.id === resource.id)?.type === "gas" ? acc + resource.amount : acc, 0)
}
if(totalCargoUsed.solid > totalCargoAvailable.solid) return {

View File

@ -15,7 +15,7 @@ export const GET: APIRoute = async ({ request }) => {
response.push({
planetId: planet._id,
ownerId: playerPlanet.manager.owner.id,
ownerId: playerPlanet.system.data.ownedBy.id,
name: planet.name,
})
});

View File

@ -35,7 +35,7 @@ export const GET: APIRoute = async ({ params, request }) => {
}), { status: 500 }
);
if(!planet.manager.owner.id.equals(user._id)) return new Response(
if(!planet.system.data.ownedBy.id.equals(user._id)) return new Response(
JSON.stringify({
code: 403,
message: "Forbidden"

View File

@ -43,7 +43,7 @@ export const POST: APIRoute = async({ request }) => {
)
}
const user = userPlanet.manager.owner;
const user = userPlanet.system.data.ownedBy;
if(!user.id.equals(userDB._id)) {
return new Response(
@ -139,15 +139,15 @@ export const POST: APIRoute = async({ request }) => {
)
}
userPlanet.resources.update(newResources);
userPlanet.manager.owner.research.addResearch({
userPlanet.resources.updateAmount(newResources.map(res => { return { id: res.id, amount: res.amount } }));
user.research.addResearch({
id: researchId,
level: level + 1,
data: research
});
await userPlanet.resources.sync();
await userPlanet.manager.owner.research.sync();
await user.research.sync();
return new Response(
JSON.stringify({

View File

@ -115,7 +115,7 @@ export const POST: APIRoute = async({ request }) => {
}
});
userPlanet.resources.update(resourcesAfter);
userPlanet.resources.updateAmount(resourcesAfter.map(res => { return { id: res.id, amount: res.amount } }));
userPlanet.ships.addShips(ship.data.id, amount);
await userPlanet.ships.sync();

View File

@ -8,6 +8,7 @@ import locationManager from '../../lib/classes/managers/LocationManager';
import { getAllFleetByUser } from '../../lib/db/fleet';
import { getAllShips } from '../../lib/db/ships';
import { ObjectId } from 'mongodb';
import SystemManager from '../../lib/classes/managers/SystemManager';
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
@ -47,7 +48,7 @@ if(Astro.request.method === "POST") {
const fleetData = {
source: planet._id,
destination: new ObjectId(form.get('destination-planet')?.toString() ?? ""),
destination: form.get('toSystem') ? form.get('destination-system')?.toString() : form.get('destination-planet')?.toString(),
mission: form.get('mission')?.toString() ?? "NULL",
ships: ships.map(ship => {
const amount = parseInt(form.get(`ship-amount-${ship.id}`)?.toString() ?? "0");
@ -86,14 +87,20 @@ let friendly = 0;
let enemy = 0;
for(const system of userSystems) {
for(const planet of system.planets.planets) {
for(const planet of system.planets) {
for(const f of fleet) {
if(f.source.equals(planet._id)) own++;
else if(f.destination.equals(planet._id)) {
if(f.source.equals(planet._id) || f.source.equals(system.data._id)) own++;
else if(f.destination.equals(planet._id) || f.destination.equals(system.data._id)) {
if(f.mission === 'ATTACK') enemy++;
else {
const source = locationManager.getPlanet(f.source)?.manager.owner.id;
const destination = locationManager.getPlanet(f.destination)?.manager.owner.id;
const sourceObj = locationManager.findId(f.source);
const destinationObj = locationManager.findId(f.destination);
if(!sourceObj || !destinationObj) continue;
const source = sourceObj instanceof SystemManager ? sourceObj.data.ownedBy.id : sourceObj.system.data.ownedBy.id;
const destination = destinationObj instanceof SystemManager ? destinationObj.data.ownedBy.id : destinationObj.system.data.ownedBy.id;
if(!source?.equals(destination)) friendly++;
}
}
@ -111,9 +118,9 @@ const sectorsList = galaxies.map(galaxy => {
name: sector.name,
systems: sector.systems.map(system => {
return {
_id: system._id,
name: system.name,
planets: system.planets.planets.map(planet => {
_id: system.data._id,
name: system.data.name,
planets: system.planets.map(planet => {
return {
_id: planet._id,
name: planet.name
@ -137,9 +144,13 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
<div class="fleet-status">
<h2>Fleet status ({fleet.length} total | {own} own | {friendly} friendly | {enemy} enemy)</h2>
<ul>
{fleet.map(f => <li>
{fleet.map(f => {
const source = locationManager.findId(f.source);
const destination = locationManager.findId(f.destination);
return (<li>
<div class="ship-cards">
{locationManager.getPlanet(f.source)?.name ?? "?"} =&gt; {locationManager.getPlanet(f.destination)?.name ?? "?"} | {f.mission}{f.returning ? " (R)" : ""}<br />
<span style={`${source instanceof SystemManager && "color:red;"}`}>{(source instanceof SystemManager ? source.data.name : source?.name) ?? "?"}</span> =&gt; <span style={`${destination instanceof SystemManager && "color:red;"}`}>{(destination instanceof SystemManager ? destination.data.name : destination?.name) ?? "?"}</span> | {f.mission}{f.returning ? " (R)" : ""}<br />
Containing: {f.ships.map(s => {
const ship = ships.find(ship => ship.id === s.id);
return `${getName(lang, 'ships', s.id)} x${s.amount}`;
@ -148,7 +159,8 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
Departured at: {f.departureTime.toISOString()} <br />
Arrives: {f.arrivalTime.toISOString()} ({Math.floor((f.arrivalTime.getTime() - new Date().getTime()) / 1000)})
</div>
</li>)}
</li>)
})}
</ul>
</div>
</label>
@ -168,6 +180,7 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
<label for="attack"><input type="radio" name="mission" value="ATTACK" id="attack" required />Attack</label>
<label for="transport"><input type="radio" name="mission" value="TRANSPORT" id="transport" />Transport</label>
<label for="transfer"><input type="radio" name="mission" value="TRANSFER" id="transfer" />Transfer</label>
<label><input type="checkbox" name="toSystem" />Send to system</label>
<hr />
<h2>Send to:</h2>
<div class="fleet-destination">
@ -340,7 +353,7 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
transition-timing-function: ease;
}
input[type=checkbox] {
#fleet-toggle {
position: absolute;
top: -9999px;
left: -9999px;
@ -353,7 +366,7 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
cursor: pointer;
}
input[type=checkbox]:checked ~ .fleet-status ul {
#fleet-toggle:checked ~ .fleet-status ul {
opacity: 1;
height: auto;
max-height: 1000px;
@ -414,8 +427,9 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
const destinationSector = document.getElementById('destination-sector');
const destinationSystem = document.getElementById('destination-system');
const destinationPlanet = document.getElementById('destination-planet');
const toSystemCheckbox = document.querySelector('input[name="toSystem"]');
if(!destinationGalaxy || !destinationSector || !destinationSystem || !destinationPlanet) {
if(!destinationGalaxy || !destinationSector || !destinationSystem || !destinationPlanet || !toSystemCheckbox) {
console.error('Could not find destination elements');
return;
};
@ -508,6 +522,14 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
destinationGalaxy.dispatchEvent(new Event('change'));
toSystemCheckbox.addEventListener('change', () => {
if(toSystemCheckbox.checked) {
destinationPlanet.disabled = true;
} else {
destinationPlanet.disabled = false;
}
});
const addNew = document.getElementById('cargo-add-new');
addNew.addEventListener('click', () => {

View File

@ -26,7 +26,7 @@ if(currentPlanet === undefined) {
<NavBar loggedIn="true" active="overview" />
<ResourceBar />
<h1>{currentPlanet.name} in {currentPlanet.manager.system.name}</h1>
<h1>{currentPlanet.name} in {currentPlanet.system.data.name}</h1>
</Layout>
<style>

View File

@ -41,15 +41,18 @@ if(Astro.request.method === "POST") {
<NavBar loggedIn="true" active="systemManager" />
<ResourceBar />
<h1>Selected system: {currentSystem.name} in {currentSystem.sector.name} in {currentSystem.sector.galaxy.name} <a href="/game/systemManager/select">(change)</a></h1>
<h1>Selected system: {currentSystem.data.name} in {currentSystem.data.sector.name} in {currentSystem.data.sector.galaxy.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 class="resources">
<p>Resources: {currentSystem.resources.resources.map(r => `${r.id}: ${r.amount}`).join(", ")}</p>
</div>
<div class="planet-list">
{currentSystem.planets.planets.length === 0 ? <span>No planets in this sector</span> : currentSystem.planets.planets.map(planet => (
{currentSystem.planets.length === 0 ? <span>No planets in this sector</span> : currentSystem.planets.map(planet => (
<div class="planet-card">
<h2>{planet.name}<div><form method="post"><input type="hidden" name="planetId" value={planet._id.toString()} /><input type="submit" value="Select" /></form></div></h2>
<p>Fields: {planet.fields}</p>
@ -70,6 +73,10 @@ if(Astro.request.method === "POST") {
</div>
</Layout>
<style>
* {
color: white;
}
h1 {
text-align: center;
color: white;
@ -95,6 +102,13 @@ if(Astro.request.method === "POST") {
text-decoration: none;
}
.resources {
display: flex;
flex-direction: row;
justify-content: center;
margin-bottom: 1rem;
}
.planet-list {
display: flex;
flex-direction: row;

View File

@ -36,8 +36,8 @@ const systems = locationManager.getSystemsOwnedBy(checkUser._id);
<div class="systems-list">
{systems.map(system => (
<div class="system-card">
<h2>{system.name}</h2>
<div><form method="post"><input type="hidden" name="systemId" value={system._id.toString()} /><input type="submit" value="Select" /></form></div>
<h2>{system.data.name}</h2>
<div><form method="post"><input type="hidden" name="systemId" value={system.data._id.toString()} /><input type="submit" value="Select" /></form></div>
</div>
))}
</div>

View File

@ -46,7 +46,7 @@ if(Astro.request.method === "POST") {
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any>, energy: number } } = {};
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, structures: Array<any>, energy: number } } = {};
const structureList = currentSystem.structures.structuresDB;
for(const structure of structureList) {
@ -58,7 +58,7 @@ for(const structure of structureList) {
};
}),
research: structure.requirements.research,
buildings: structure.requirements.buildings,
structures: structure.requirements.structures,
energy: structure.energy
};
}
@ -67,7 +67,7 @@ for(const structure of structureList) {
<NavBar loggedIn="true" active="systemManager" />
<ResourceBar />
<h1>Selected system: {currentSystem.name} <a href="/game/systemManager/select">(change)</a></h1>
<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>
@ -78,8 +78,8 @@ for(const structure of structureList) {
<div id="structure-modal-details" data-structure-id="">
<h3>Required resources</h3>
<div class="structure-modal-text" id="structure-modal-req-resources">None</div>
<h3>Required buildings</h3>
<div class="structure-modal-text" id="structure-modal-req-buildings">None</div>
<h3>Required structures</h3>
<div class="structure-modal-text" id="structure-modal-req-structures">None</div>
<h3>Required research</h3>
<div class="structure-modal-text" id="structure-modal-req-research">None</div>
</div>
@ -87,6 +87,7 @@ for(const structure of structureList) {
<div class="structure-list">
{currentSystem.structures.structuresDB.map(structure => (
<ItemCard
category="structures"
id={structure.id}
name={getName(lang, 'structures', structure.id)}
image={`/images/structures/${structure.id}.jpeg`}
@ -175,7 +176,7 @@ for(const structure of structureList) {
</style>
<script define:vars={{ modalSet, lang }}>
const modalResources = document.getElementById("structure-modal-req-resources");
const modalBuildings = document.getElementById("structure-modal-req-buildings");
const modalStructures = document.getElementById("structure-modal-req-structures");
const modalResearch = document.getElementById("structure-modal-req-research");
document.querySelectorAll('.item-card-info-button').forEach((el) => {
@ -186,15 +187,15 @@ for(const structure of structureList) {
modalDiv.style.display = 'block';
const reqResources = modalSet[el.parentElement.parentElement.dataset.id]?.resources ?? [];
const reqBuildings = modalSet[el.parentElement.parentElement.dataset.id]?.buildings ?? [];
const reqStructures = modalSet[el.parentElement.parentElement.dataset.id]?.structures ?? [];
const reqResearch = modalSet[el.parentElement.parentElement.dataset.id]?.research ?? [];
modalResources.innerHTML = reqResources.length === 0 ? "None" : reqResources.map(resource => {
return `${lang['resources'].find(r => r.id === resource.id).name}: ${resource.amount}`;
}).join("<br />");
modalBuildings.innerHTML = reqBuildings.length === 0 ? "None" : reqBuildings.map(building => {
return `${lang['buildings'].find(b => b.id === building.id).name}: ${building.level}`;
modalStructures.innerHTML = reqStructures.length === 0 ? "None" : reqStructures.map(structure => {
return `${lang['structures'].find(s => s.id === structure.id).name}: ${structure.level}`;
}).join("<br />");
modalResearch.innerHTML = reqResearch.length === 0 ? "None" : reqResearch.map(research => {

View File

@ -5,7 +5,7 @@ export default interface DBStructure {
id: string;
description: string;
requirements: {
buildings: Array<{ id: string, level: number }>,
structures: Array<{ id: string, level: number }>,
research: Array<{ id: string, level: number }>,
resources: Array<{ id: string, amount: number }>,
};

View File

@ -9,4 +9,12 @@ export default interface DBSystem {
level: number
}>;
planets: Array<ObjectId>;
resources: Array<{
id: string,
amount: number
}>;
ships: Array<{
id: string,
amount: number
}>;
}