Implement basic energy system
This commit is contained in:
parent
b1e17b16d3
commit
d4dcc1e759
Binary file not shown.
After Width: | Height: | Size: 399 B |
|
@ -74,6 +74,13 @@ const listOfElements: Array<NavElement> = [{
|
|||
url: "/game",
|
||||
show: "loggedInOnly",
|
||||
position: "bottom"
|
||||
}, {
|
||||
id: "energy",
|
||||
title: getName(lang, "general", "nav-energy"),
|
||||
type: "simple",
|
||||
url: "/game/energy",
|
||||
show: "loggedInOnly",
|
||||
position: "bottom"
|
||||
}, {
|
||||
id: "buildings",
|
||||
title: getName(lang, "general", "nav-buildings"),
|
||||
|
|
|
@ -53,8 +53,21 @@ if(!(planet instanceof SystemManager)) {
|
|||
}
|
||||
---
|
||||
<div id="resourcebar">
|
||||
<!-- Energy: <span class={`${planet.energy.consumption > planet.energy.production ? "prod-full" : planet.energy.consumption >= (planet.energy.production * 0.9) ? "prod-almost-full" : ""}`}>{planet.energy.consumption}/{planet.energy.production}</span> -->
|
||||
<div class="resourcebar-item">
|
||||
<Image src="/images/resources/energy.png" alt="energy" class="icon" width={32} height={32} />
|
||||
<div class="text">
|
||||
<span class="line1"><!--{getName(lang, 'resources', 'energy')}-->Energy</span>
|
||||
<span class={`line2 ${planet.energy.consumption > planet.energy.production ? "prod-full" : planet.energy.consumption >= (planet.energy.production * 0.9) ? "prod-almost-full" : ""}`}>{planet.energy.consumption}/{planet.energy.production}</span>
|
||||
</div>
|
||||
<div class="resourcebar-item-tooltip">
|
||||
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'production')}</span><span class={`resourcebar-item-tooltip-amount`}>{planet.energy.production}</span>
|
||||
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'consumption')}</span><span class="resourcebar-item-tooltip-amount">{planet.energy.consumption}</span>
|
||||
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'balance')}</span><span class={`resourcebar-item-tooltip-amount ${planet.energy.consumption > planet.energy.production ? "prod-full" : planet.energy.consumption >= (planet.energy.production * 0.9) ? "prod-almost-full" : ""}`}>{planet.energy.production - planet.energy.consumption}</span>
|
||||
</div>
|
||||
</div>
|
||||
{resourceArray.map(res =>
|
||||
<div class="resourcebar-item"
|
||||
<div class="resourcebar-item resourcebar-iterable"
|
||||
data-res-type={resourceTypes.find(x => x.id === res.id)?.type ?? "solid"}
|
||||
data-res-id={res.id}
|
||||
data-res-amount={res.amount}
|
||||
|
@ -227,7 +240,7 @@ if(!(planet instanceof SystemManager)) {
|
|||
}
|
||||
|
||||
function init() {
|
||||
const resourcebarItems = document.getElementById('resourcebar')?.querySelectorAll('.resourcebar-item');
|
||||
const resourcebarItems = document.getElementById('resourcebar')?.querySelectorAll('.resourcebar-iterable');
|
||||
resourcebarItems?.forEach((item: any) => {
|
||||
const resourceAmount = parseFloat(item.dataset.resAmount ?? '0');
|
||||
const miningRate = parseInt(item.dataset.resMiningRate ?? '0') / 3600;
|
||||
|
|
|
@ -5,11 +5,13 @@ export default class Building {
|
|||
manager: BuildingManager
|
||||
data: DBBuilding;
|
||||
level: number;
|
||||
activePercent: number = 100;
|
||||
|
||||
constructor(manager: BuildingManager, data: DBBuilding, level: number) {
|
||||
constructor(manager: BuildingManager, data: DBBuilding, level: number, activePercent?: number) {
|
||||
this.manager = manager;
|
||||
this.data = data;
|
||||
this.level = level;
|
||||
if(activePercent !== undefined) this.activePercent = activePercent;
|
||||
}
|
||||
|
||||
async checkRequiredResources(level: number): Promise<boolean> {
|
||||
|
@ -38,7 +40,7 @@ export default class Building {
|
|||
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) {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import { Planet } from "./PlanetManager";
|
||||
import EnergyManager from "./abstract/EnergyManager";
|
||||
|
||||
export default class PlanetEnergyManager extends EnergyManager {
|
||||
constructor(system: Planet) {
|
||||
super(system);
|
||||
}
|
||||
|
||||
get manager() {
|
||||
return this._manager as Planet;
|
||||
}
|
||||
|
||||
update() {
|
||||
const buildings = this.manager.buildings.buildings;
|
||||
|
||||
this.production = 0;
|
||||
this.consumption = 0;
|
||||
|
||||
for(const building of buildings) {
|
||||
if(building.data.category === "power-plants") {
|
||||
this.production += (building.data.energy * building.level);
|
||||
} else {
|
||||
this.consumption += (building.data.energy * building.level);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import PlanetResourceManager from "./PlanetResourceManager";
|
|||
import ShipManager from "./PlanetShipManager";
|
||||
import SystemManager from "./SystemManager";
|
||||
import PlanetDefenseManager from "./PlanetDefenseManager";
|
||||
import PlanetEnergyManager from "./PlanetEnergyManager";
|
||||
|
||||
export type Planet = {
|
||||
_id: ObjectId;
|
||||
|
@ -14,4 +15,5 @@ export type Planet = {
|
|||
buildings: BuildingManager;
|
||||
ships: ShipManager;
|
||||
defenses: PlanetDefenseManager;
|
||||
energy: PlanetEnergyManager;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import EnergyManager from "./abstract/EnergyManager";
|
||||
import SystemManager from "./SystemManager";
|
||||
|
||||
export default class SystemEnergyManager extends EnergyManager {
|
||||
constructor(system: SystemManager) {
|
||||
super(system);
|
||||
}
|
||||
|
||||
get manager() {
|
||||
return this._manager as SystemManager;
|
||||
}
|
||||
|
||||
update() {
|
||||
const structures = this.manager.structures.structures;
|
||||
|
||||
for(const structure of structures) {
|
||||
if(structure.data.id === "dyson-sphere") {
|
||||
this.production += (structure.data.energy * structure.level);
|
||||
} else {
|
||||
this.consumption += (structure.data.energy * structure.level);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@ import SystemResourceManager from "./SystemResourceManager";
|
|||
import SystemShipManager from "./SystemShipManager";
|
||||
import PlanetDefenseManager from "./PlanetDefenseManager";
|
||||
import SystemDefenseManager from "./SystemDefenseManager";
|
||||
import SystemEnergyManager from "./SystemEnergyManager";
|
||||
import PlanetEnergyManager from "./PlanetEnergyManager";
|
||||
|
||||
export type System = {
|
||||
_id: ObjectId,
|
||||
|
@ -31,6 +33,7 @@ export default class SystemManager {
|
|||
resources: SystemResourceManager;
|
||||
ships: SystemShipManager;
|
||||
defenses: SystemDefenseManager;
|
||||
energy: SystemEnergyManager;
|
||||
data: System;
|
||||
|
||||
constructor(data: System) {
|
||||
|
@ -39,6 +42,7 @@ export default class SystemManager {
|
|||
this.resources = new SystemResourceManager(this);
|
||||
this.ships = new SystemShipManager(this);
|
||||
this.defenses = new SystemDefenseManager(this);
|
||||
this.energy = new SystemEnergyManager(this);
|
||||
}
|
||||
|
||||
async fillData(systemData: DBSystem) {
|
||||
|
@ -46,6 +50,7 @@ export default class SystemManager {
|
|||
await this.resources.init(systemData.resources);
|
||||
await this.ships.init(systemData.ships);
|
||||
await this.defenses.init(systemData.defenses);
|
||||
this.energy.update();
|
||||
|
||||
await Promise.all(systemData.planets.map(async planetId => {
|
||||
const planet = await getPlanetById(planetId);
|
||||
|
@ -62,13 +67,16 @@ export default class SystemManager {
|
|||
//@ts-ignore
|
||||
ships: null,
|
||||
//@ts-ignore
|
||||
defenses: null
|
||||
defenses: null,
|
||||
//@ts-ignore
|
||||
energy: 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);
|
||||
planetObject.defenses = await new PlanetDefenseManager(planetObject).init(planet.defenses);
|
||||
planetObject.energy = new PlanetEnergyManager(planetObject).update();
|
||||
|
||||
this.planets.push(planetObject);
|
||||
}));
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import { Planet } from "../PlanetManager";
|
||||
import SystemManager from "../SystemManager";
|
||||
|
||||
export default abstract class EnergyManager {
|
||||
protected _manager: Planet | SystemManager;
|
||||
production: number = 0;
|
||||
consumption: number = 0;
|
||||
|
||||
constructor(manager: Planet | SystemManager) {
|
||||
this._manager = manager;
|
||||
}
|
||||
|
||||
abstract update(): this;
|
||||
}
|
|
@ -115,6 +115,7 @@ export const POST: APIRoute = async({ request }) => {
|
|||
|
||||
await userPlanet.buildings.sync();
|
||||
await userPlanet.resources.sync();
|
||||
userPlanet.energy.update();
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
---
|
||||
import LoggedIn from '../../layouts/LoggedIn.astro';
|
||||
import { Planet } from '../../lib/classes/managers/PlanetManager';
|
||||
import SystemManager from '../../lib/classes/managers/SystemManager';
|
||||
|
||||
const { token, lang } = Astro.locals;
|
||||
const active: SystemManager | Planet = Astro.locals.active;
|
||||
|
||||
if(active instanceof SystemManager) {
|
||||
return Astro.redirect('/game');
|
||||
}
|
||||
|
||||
if(Astro.request.method === "POST") {
|
||||
const body = await Astro.request.formData();
|
||||
|
||||
for(const [key, value] of body.entries()) {
|
||||
console.log(key, value);
|
||||
}
|
||||
|
||||
return Astro.redirect('/game/energy');
|
||||
}
|
||||
|
||||
const buildingsList = {
|
||||
"mines": active.buildings.buildings.filter(building => building.data.category === "mines"),
|
||||
"powerPlants": active.buildings.buildings.filter(building => building.data.category === "power-plants"),
|
||||
"utilities": active.buildings.buildings.filter(building => building.data.category === "utilities"),
|
||||
"storage": active.buildings.buildings.filter(building => building.data.category === "storage")
|
||||
}
|
||||
---
|
||||
<LoggedIn id="energy" title="Energy">
|
||||
<form method="post" class="form-container">
|
||||
<table>
|
||||
<tr class="table-col-header">
|
||||
<th>Building name</th>
|
||||
<th>Level</th>
|
||||
<th>Production %</th>
|
||||
<th>Production per hour</th>
|
||||
<th>Energy usage</th>
|
||||
</tr>
|
||||
<tr><td colspan="5" class="table-separator">Mines</td></tr>
|
||||
{buildingsList.mines.map(building => <tr>
|
||||
<td>{building.data.id}</td>
|
||||
<td>{building.level}</td>
|
||||
<td><select name={`percent_${building.data.id}`}>
|
||||
<option value="100" {...{ selected: (building.activePercent ?? 100) === 100 }}>100%</option>
|
||||
<option value="90" {...{ selected: (building.activePercent ?? 100) === 90 }}>90%</option>
|
||||
<option value="80" {...{ selected: (building.activePercent ?? 100) === 80 }}>80%</option>
|
||||
<option value="70" {...{ selected: (building.activePercent ?? 100) === 70 }}>70%</option>
|
||||
<option value="60" {...{ selected: (building.activePercent ?? 100) === 60 }}>60%</option>
|
||||
<option value="50" {...{ selected: (building.activePercent ?? 100) === 50 }}>50%</option>
|
||||
<option value="40" {...{ selected: (building.activePercent ?? 100) === 40 }}>40%</option>
|
||||
<option value="30" {...{ selected: (building.activePercent ?? 100) === 30 }}>30%</option>
|
||||
<option value="20" {...{ selected: (building.activePercent ?? 100) === 20 }}>20%</option>
|
||||
<option value="10" {...{ selected: (building.activePercent ?? 100) === 10 }}>10%</option>
|
||||
<option value="0" {...{ selected: (building.activePercent ?? 100) === 0 }}>0%</option>
|
||||
</select></td>
|
||||
<td>15</td>
|
||||
<td class="red">-{building.level * building.data.energy}</td>
|
||||
</tr>)}
|
||||
<tr><td colspan="5" class="table-separator">Power plants</td></tr>
|
||||
{buildingsList.powerPlants.map(building => <tr>
|
||||
<td>{building.data.id}</td>
|
||||
<td>{building.level}</td>
|
||||
<td><select name={`percent_${building.data.id}`}>
|
||||
<option value="100" {...{ selected: (building.activePercent ?? 100) === 100 }}>100%</option>
|
||||
<option value="90" {...{ selected: (building.activePercent ?? 100) === 90 }}>90%</option>
|
||||
<option value="80" {...{ selected: (building.activePercent ?? 100) === 80 }}>80%</option>
|
||||
<option value="70" {...{ selected: (building.activePercent ?? 100) === 70 }}>70%</option>
|
||||
<option value="60" {...{ selected: (building.activePercent ?? 100) === 60 }}>60%</option>
|
||||
<option value="50" {...{ selected: (building.activePercent ?? 100) === 50 }}>50%</option>
|
||||
<option value="40" {...{ selected: (building.activePercent ?? 100) === 40 }}>40%</option>
|
||||
<option value="30" {...{ selected: (building.activePercent ?? 100) === 30 }}>30%</option>
|
||||
<option value="20" {...{ selected: (building.activePercent ?? 100) === 20 }}>20%</option>
|
||||
<option value="10" {...{ selected: (building.activePercent ?? 100) === 10 }}>10%</option>
|
||||
<option value="0" {...{ selected: (building.activePercent ?? 100) === 0 }}>0%</option>
|
||||
</select></td>
|
||||
<td></td>
|
||||
<td class="green">+{building.level * building.data.energy}</td>
|
||||
</tr>)}
|
||||
<tr><td colspan="5" class="table-separator">Utilities</td></tr>
|
||||
{buildingsList.utilities.map(building => <tr>
|
||||
<td>{building.data.id}</td>
|
||||
<td>{building.level}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="red">-{building.level * building.data.energy}</td>
|
||||
</tr>)}
|
||||
<tr><td colspan="5" class="table-separator">Storage</td></tr>
|
||||
{buildingsList.storage.map(building => <tr>
|
||||
<td>{building.data.id}</td>
|
||||
<td>{building.level}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="red">-{building.level * building.data.energy}</td>
|
||||
</tr>)}
|
||||
</table>
|
||||
<input type="submit" value="Save" class="save-button" />
|
||||
</form>
|
||||
</LoggedIn>
|
||||
<style>
|
||||
.form-container {
|
||||
width: fit-content;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.green {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.table-col-header {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.table-separator {
|
||||
background-color: #222;
|
||||
font-weight: 1000;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.table-col-header th {
|
||||
border: 1px solid white;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
tr {
|
||||
color: white;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px;
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
.form-container .save-button {
|
||||
flex-grow: 1;
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
background-color: #444;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
|
@ -6,7 +6,7 @@ export default interface DBPlanet {
|
|||
owner: ObjectId; // shouldn't be here
|
||||
fields: number;
|
||||
resources: Array<{ id: string, amount: number, lastUpdated: Date, perHourMiningRate: number }>;
|
||||
buildings: Array<{ id: string, level: number }>;
|
||||
buildings: Array<{ id: string, level: number, activePercent?: number }>;
|
||||
ships: Array<{ id: string, amount: number }>;
|
||||
defenses: Array<{ id: string, amount: number }>;
|
||||
}
|
Loading…
Reference in New Issue