*.js
*.log
node_modules/
+*.db
"icon" string,
"totalSpace" int,
"usedSpace" int,
- "gold" int,
- "ore" int,
- "logs" int,
- "bushels" int,
+ "credits" int,
+ "alloys" int,
+ "energy" int,
+ "food" int,
"population" int,
"soliders" int,
"attackers" int,
CREATE TABLE IF NOT EXISTS "buildings" (
"slug" text,
"display" text UNIQUE,
- "gold" int,
- "ore" int,
- "logs" int,
+ "credits" int,
+ "alloys" int,
+ "energy" int,
"land" int,
"time" int,
PRIMARY KEY("slug")
CREATE TABLE IF NOT EXISTS "units" (
"slug" ,
"display" ,
- "gold" ,
- "bushels" ,
+ "credits" ,
+ "food" ,
"population" ,
"soldiers" ,
"attackers" ,
</div>
<div class="row">
<div class="col" id="info-bar">
- <span><b>Gold:</b> 10,000,0000</span>
- <span><b>Ore:</b> 10,000,000</span>
- <span><b>Logs:</b> 10,000,0000</span>
+ <span><b>Credits:</b> 10,000,0000</span>
+ <span><b>Alloys:</b> 10,000,000</span>
+ <span><b>Food:</b> 10,000,0000</span>
+ <span><b>Energy:</b> 10,000,0000</span>
</div>
</div>
</div>
--green-bg: #193818;
--green-border: #32821c;
--red-border: #821c1c;
+ --red-bg: #381818;
}
input {
color: var(--border);
}
.danger {
- background-color: #381818;
+ background-color: var(--red-bg);
border-color: var(--red-border);
}
.danger::after {
color: #821c1c
}
+.danger-text {
+ color: var(--red-border);
+}
+.success-text {
+ color: var(--green-border);
+}
.success {
background-color: var(--green-bg);
border-color: var(--green-border);
justify-content: space-evenly;
}
+#info-bar > span {
+ display: inline-block;
+ line-height: 1.5rem;
+}
+#info-bar b {
+ --aug-border-all: 1px;
+ --aug-border-bg: var(--border);
+ display: inline-block;
+ line-height: 2rem;
+ width: 30px;
+ text-align: center;
+ background-color: #0d2329;
+ cursor: default;
+}
+
#overworld-map {
width: auto;
margin: 0 auto;
#sector-selector select {
margin-left: 20px;
}
+
+.cost-display {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+}
+.cost-display > div {
+ margin: 0 0.5rem;
+}
+.rate-of-change.success-text::before {
+ content: '\25B2 ';
+}
+.rate-of-change.danger::before {
+ content: '\25BC ';
+}
import { createBullBoard } from '@bull-board/api';
import { BullAdapter } from '@bull-board/api/bullAdapter';
import _ from 'lodash';
-import { renderMailroom, renderMessage } from './render/mail';
+import { renderCost } from './render/costs';
+import {renderMailroom, renderMessage} from './render/mail';
+import {topbar} from './render/topbar';
const server = new HttpServer(config.API_PORT);
const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token);
const city = await cityRepo.getUsersCity(account.id);
- return renderKingomOverview(city, account);
+ const usage = {
+ foodUsagePerTick: await cityRepo.foodUsagePerTick(city),
+ foodProductionPerTick: await cityRepo.foodProductionPerTick(city),
+ energyUsagePerTick: 0,
+ energyProductionPerTick: 0
+ }
+
+ return renderKingomOverview({
+ ...city,
+ ...usage
+ }, account) + topbar({...city, ...usage});
});
server.get<{}, string>('/poll/construction', async req => {
const buildings = await cityRepo.buildingRepository.list();
const buildQueues = await cityRepo.getBuildQueues(account.id);
- return renderLandDevelopment(city, buildings, buildQueues);
+ const usage = {
+ foodUsagePerTick: await cityRepo.foodUsagePerTick(city),
+ foodProductionPerTick: await cityRepo.foodProductionPerTick(city),
+ energyUsagePerTick: 0,
+ energyProductionPerTick: 0
+ }
+ return renderLandDevelopment(city, buildings, buildQueues) + topbar({...city, ...usage});
});
server.get<{}, string>('/poll/unit-training', async req => {
const unitTrainingQueues = await cityRepo.getUnitTrainingQueues(account.id);
const units = await cityRepo.unitRepository.list();
+ const usage = {
+ foodUsagePerTick: await cityRepo.foodUsagePerTick(city),
+ foodProductionPerTick: await cityRepo.foodProductionPerTick(city),
+ energyUsagePerTick: 0,
+ energyProductionPerTick: 0
+ }
- return renderUnitTraining(city, units, unitTrainingQueues);
+ return renderUnitTraining(city, units, unitTrainingQueues) + topbar({
+ ...city,
+ ...usage
+ });
});
server.post<{body: {sector: string}}, string>('/poll/map', async req => {
}
}
- console.log('Checking cities in sector', sector);
+ const usage = {
+ foodUsagePerTick: await cityRepo.foodUsagePerTick(city),
+ foodProductionPerTick: await cityRepo.foodProductionPerTick(city),
+ energyUsagePerTick: 0,
+ energyProductionPerTick: 0
+ }
- return renderOverworldMap(await cityRepo.findAllInSector(sector), city, sector);
+ return renderOverworldMap(await cityRepo.findAllInSector(sector), city, sector) + topbar({
+ ...city,
+ ...usage
+ });
});
server.get<{}, string>('/poll/mailroom', async req => {
const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token);
+ const city = await cityRepo.getUsersCity(account.id);
- return renderMailroom(await mailRepo.listReceivedMessages(account.id));
+ const usage = {
+ foodUsagePerTick: await cityRepo.foodUsagePerTick(city),
+ foodProductionPerTick: await cityRepo.foodProductionPerTick(city),
+ energyUsagePerTick: 0,
+ energyProductionPerTick: 0
+ }
+
+ return renderMailroom(await mailRepo.listReceivedMessages(account.id)) + topbar({
+ ...city,
+ ...usage
+ });
});
}
}, string>('/cost/construction', async req => {
const amount = parseInt(req.body.amount.trim(), 10);
- console.log('checking amount', amount);
if(isNaN(amount) || amount < 1) {
return '';
throw new NotFoundError(`Invalid building type ${req.body.building_type}`, ERROR_CODE.INVALID_BUILDING);
}
- return JSON.stringify({
- gold: building.gold * amount,
- ore: building.ore * amount,
- logs: building.logs * amount,
+ const cost = {
+ credits: building.credits * amount,
+ alloys: building.alloys * amount,
+ energy: building.energy * amount,
land: building.land * amount,
time: building.time
- });
+ };
+
+ return renderCost(cost);
});
server.post<{
}
}, string>('/cost/training', async req => {
const amount = parseInt(req.body.amount, 10);
- const unit = await cityRepo.unitRepository.findBySlug(req.body.type);
+ if(isNaN(amount) || amount < 1) {
+ return '';
+ }
+
+ const unit = await cityRepo.unitRepository.findBySlug(req.body.type);
if(!unit) {
throw new NotFoundError(`Invalid unit type ${req.body.type}`, ERROR_CODE.INVALID_UNIT);
}
- return JSON.stringify({
+ return renderCost({
population: unit.population * amount,
soldiers: unit.soldiers * amount,
attackers: unit.attackers * amount,
defenders: unit.defenders * amount,
- gold: unit.gold * amount,
- bushels: unit.bushels * amount
+ credits: unit.credits * amount,
+ food: unit.food * amount,
+ time: unit.time * amount
});
});
building_type: string,
}
}, void>('/build', async req => {
- const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token);
- const city = await cityRepo.getUsersCity(account.id);
+ const account = await accountRepo.validate(req.authInfo.accountId, req.authInfo.token);
+ const city = await cityRepo.getUsersCity(account.id);
- const amount = parseInt(req.body.amount, 10);
- const building = await cityRepo.buildingRepository.findBySlug(req.body.building_type);
+ const amount = parseInt(req.body.amount, 10);
+ const building = await cityRepo.buildingRepository.findBySlug(req.body.building_type);
- if(!building) {
- throw new NotFoundError(`Invalid building type ${req.body.building_type}`, ERROR_CODE.INVALID_BUILDING);
- }
+ if(!building) {
+ throw new NotFoundError(`Invalid building type ${req.body.building_type}`, ERROR_CODE.INVALID_BUILDING);
+ }
- const queueData = await cityRepo.buildBuilding(building, amount ,city);
+ const queueData = await cityRepo.buildBuilding(building, amount, city);
construction.trigger(queueData, { delay: queueData.due });
}, 'reload-construction-queue');
--- /dev/null
+type Cost = {
+ credits: number,
+ time: number,
+ alloys?: number,
+ energy?: number,
+ land?: number,
+ food?: number,
+ population?: number,
+ soldiers?: number
+ attackers?: number,
+ defenders?: number
+}
+
+function lineItem(display: string, value: number): string {
+ return `
+ <div>
+ <b>${display}:</b>
+ <span class="text">${value.toLocaleString()}</span>
+ </div>
+ `;
+}
+
+export function renderCost(cost: Cost): string {
+ const costAsArray = [];
+
+ costAsArray.push(lineItem('Credits', cost.credits));
+ costAsArray.push(lineItem('Time', cost.time));
+
+ if(cost.alloys) {
+ costAsArray.push(lineItem('Alloys', cost.alloys));
+ }
+ if(cost.food) {
+ costAsArray.push(lineItem('Food', cost.food));
+ }
+ if(cost.energy) {
+ costAsArray.push(lineItem('Energy', cost.energy));
+ }
+ if(cost.land) {
+ costAsArray.push(lineItem('Space', cost.land));
+ }
+ if(cost.population) {
+ costAsArray.push(lineItem('Pop', cost.population));
+ }
+ if(cost.soldiers) {
+ costAsArray.push(lineItem('Soldiers', cost.soldiers));
+ }
+ if(cost.attackers) {
+ costAsArray.push(lineItem('Attackers', cost.attackers));
+ }
+ if(cost.defenders) {
+ costAsArray.push(lineItem('Defenders', cost.defenders));
+ }
+
+
+ return `<div class="cost-display">${costAsArray.join("")}</div>`;
+}
import { Account } from "../repository/accounts";
import { CityWithLocation } from "../repository/city";
import * as _ from 'lodash';
-import { topbar } from "./topbar";
-export function renderKingomOverview(city: CityWithLocation, account: Account): string {
+type Usage = {
+ foodUsagePerTick: number;
+ foodProductionPerTick: number;
+ energyUsagePerTick: number;
+ energyProductionPerTick: number;
+}
+
+export function renderKingomOverview(city: CityWithLocation & Usage, account: Account): string {
+ const foodRateOfChange = city.foodProductionPerTick - city.foodUsagePerTick;
+ const energyRateOfChange = city.energyProductionPerTick - city.energyUsagePerTick;
return `
<div hx-trigger="every 600s" hx-get="/poll/overview">
- <h2 data-augmented-ui="tl-clip bl-clip none">Kingdom Overview</h2>
+ <h2 data-augmented-ui="tl-clip bl-clip none">Overview</h2>
<table>
<tr>
- <th>Lord</th>
+ <th>Captain</th>
<td>${account.username}</td>
<th>Population</th>
<td>${city.population.toLocaleString()}/${_.max([city.farms * 70, city.population])}</td>
</tr>
<tr>
- <th>Land</th>
+ <th>Space</th>
<td>${city.totalSpace.toLocaleString()} (${Math.ceil(city.usedSpace/city.totalSpace * 100)}% used)</td>
<th>Soldiers</th>
<td>${city.soldiers.toLocaleString()}</td>
</tr>
<tr>
<th>Location</th>
- <td>${city.sector_id} - (${city.location_x},${city.location_y})</td>
+ <td>Sector ${city.sector_id} - (${city.location_x},${city.location_y})</td>
<th>Attackers</th>
<td>${city.attackers.toLocaleString()}</td>
</tr>
<tr>
- <th>Gold</th>
- <td>${city.gold.toLocaleString()}</td>
+ <th>Credits</th>
+ <td>${city.credits.toLocaleString()}</td>
<th>Defenders</th>
<td>${city.defenders.toLocaleString()}</td>
</tr>
<tr>
- <th>Ore</th>
- <td>${city.ore.toLocaleString()}</td>
+ <th>Alloys</th>
+ <td>${city.alloys.toLocaleString()}</td>
<th>Special Attackers</th>
<td>${city.sp_attackers.toLocaleString()}</td>
</tr>
<tr>
- <th>Logs</th>
- <td>${city.logs.toLocaleString()}</td>
+ <th>Energy</th>
+ <td>${city.energy.toLocaleString()} (<span class="rate-of-change ${energyRateOfChange < 0 ? 'danger-text' : 'success-text'}">${energyRateOfChange.toLocaleString()}</span>)</td>
<th>Special Defenders</th>
<td>${city.sp_defenders.toLocaleString()}</td>
</tr>
<tr>
- <th>Bushels</th>
- <td>${city.bushels.toLocaleString()}</td>
+ <th>Food</th>
+ <td>${city.food.toLocaleString()} (<span class="rate-of-change ${foodRateOfChange < 0 ? 'danger-text' : 'success-text'}">${foodRateOfChange.toLocaleString()}</span>)</td>
</tr>
</table>
</div>
- ${topbar(city)}`;
+ `;
}
import { CityWithLocation } from "../repository/city";
import { Building } from '../repository/buildings';
import _ from "lodash";
-import { topbar } from "./topbar";
function progressBar(current, max): string {
const percent = Math.ceil((current/max) * 100);
<h2 data-augmented-ui="tl-clip bl-clip none">Construction</h2>
<table>
<tr>
- <th>Free Land</th>
+ <th>Type</th>
<th>Current</th>
- <td colspan="2">${(city.totalSpace - city.usedSpace).toLocaleString()} (${Math.ceil(freeSpace/city.totalSpace * 100)}% available)</td>
+ <th>Space Available: ${(city.totalSpace - city.usedSpace).toLocaleString()} (${Math.ceil(freeSpace/city.totalSpace * 100)}% available)</th>
+ <th width="200">Cost</th>
</tr>
${
buildings.map(building => {
<input type="hidden" name="building_type" value="${building.slug}">
<button type="submit">Build</button>
</form>
- <span id="${building.slug}-cost"></span>
</td>
+ <td id="${building.slug}-cost"></td>
</tr>
`;
}).join("\n")
</table>
</div>
`;
- return html + queues + topbar(city);
-}
\ No newline at end of file
+ return html + queues;
+}
import { DateTime } from "luxon";
import { MessageWithNames } from "../repository/mail";
-import { topbar } from "./topbar";
export function renderMailroom(mail: MessageWithNames[]): string {
return `
</tr>
</table>
`;
-}
\ No newline at end of file
+}
import { DateTime } from "luxon";
import { Account } from "../repository/accounts";
import { ArmyQueueWithAttackedOwner } from "../repository/army";
-import { City, CityRepository, CityWithLocation } from "../repository/city";
-import { topbar } from "./topbar";
+import { CityRepository, CityWithLocation } from "../repository/city";
import { AVAILABLE_SECTORS } from '../config';
-import {initArray} from "../lib/util";
const cityRepo = new CityRepository();
</form>
`;
- return html + topbar(yourCity);
+ return html;
}
import { City } from "../repository/city";
-export function topbar(city: City): string {
+type Usage = {
+ foodUsagePerTick: number;
+ foodProductionPerTick: number;
+ energyUsagePerTick: number;
+ energyProductionPerTick: number;
+}
+
+
+export function topbar(city: City & Usage): string {
+ const foodRateOfChange = city.foodProductionPerTick - city.foodUsagePerTick;
+ const energyRateOfChange = city.energyProductionPerTick - city.energyUsagePerTick;
const oob = `
<div class="col" id="info-bar" hx-swap-oob="true">
- <span><b>Gold:</b> ${city.gold.toLocaleString()}</span>
- <span><b>Ore:</b> ${city.ore.toLocaleString()}</span>
- <span><b>Logs:</b> ${city.logs.toLocaleString()}</span>
+ <span>
+ <b data-augmented-ui="all-hex border" title="Credits">₡</b>
+ <span class="text">${city.credits.toLocaleString()}</span>
+ </span>
+ <span>
+ <b data-augmented-ui="all-hex border" title="Alloys">A</b>
+ <span class="text">${city.alloys.toLocaleString()}</span>
+ </span>
+ <span>
+ <b data-augmented-ui="all-hex border" title="Food">F</b>
+ <span class="text">
+ ${city.food.toLocaleString()}
+ <span class="rate-of-change ${foodRateOfChange < 0 ? 'danger-text': 'success-text'}">${foodRateOfChange.toLocaleString()}</span>
+ </span>
+ </span>
+ <span>
+ <b data-augmented-ui="all-hex border" title="Energy">E</b>
+ <span class="text">
+ ${city.energy.toLocaleString()}
+ <span class="rate-of-change ${energyRateOfChange < 0 ? 'danger-text': 'success-text'}">${energyRateOfChange.toLocaleString()}</span>
+ </span>
+ </span>
</div>
`;
return oob;
-}
\ No newline at end of file
+}
import { CityWithLocation } from "../repository/city";
import { UnitTrainingQueue } from "../repository/training-queue";
import { Unit } from "../repository/unit";
-import { topbar } from "./topbar";
function progressBar(current, max): string {
const percent = Math.ceil((current/max) * 100);
<th>Unit</th>
<th>Avail.</td>
<th></th>
+ <th width="200">Cost</th>
</tr>
<tr>
<th>Soldiers</th>
<td>${city.population}</td>
<td>
<form hx-post="/units">
- <input type="number" name="amount" size="6" max="${city.population}" hx-trigger="change" hx-post="/cost/training" hx-target="#${unit.soldiers.slug}-cost">
+ <input type="number" name="amount" size="6" max="${city.population}" hx-trigger="keyup" hx-post="/cost/training" hx-target="#${unit.soldiers.slug}-cost">
<input type="hidden" name="type" value="${unit.soldiers.slug}">
<button type="submit" ${city.population ? '' : 'disabled'}>Train</button>
</form>
- <span id="${unit.soldiers.slug}-cost"></span>
</td>
+ <td id="${unit.soldiers.slug}-cost"></span>
</tr>
<tr>
<th>Attackers</th>
<input type="hidden" name="type" value="${unit.attackers.slug}">
<button type="submit" ${city.soldiers ? '' : 'disabled'}>Train</button>
</form>
- <span id="${unit.attackers.slug}-cost"></span>
</td>
+ <td id="${unit.attackers.slug}-cost"></span>
</tr>
<tr>
<th>Defenders</th>
<input type="hidden" name="type" value="${unit.defenders.slug}">
<button type="submit" ${city.soldiers ? '' : 'disabled'}>Train</button>
</form>
- <span id="${unit.defenders.slug}-cost"></span>
</td>
+ <td id="${unit.defenders.slug}-cost"></td>
</tr>
<tr>
<th>Special Attackers</th>
</form>
<span id="${unit.sp_attackers.slug}-cost"></span>
</td>
+ <td id="${unit.sp_attackers.slug}-cost"></td>
</tr>
<tr>
<th>Special Defenders</th>
<input type="hidden" name="type" value="${unit.sp_defenders.slug}">
<button type="submit" ${city.defenders ? '': 'disabled'}>Train</button>
</form>
- <span id="${unit.sp_defenders.slug}-cost"></span>
</td>
+ <td id="${unit.sp_defenders.slug}-cost"></td>
</tr>
</table>
`;
</div>
`;
- return html + queues + topbar(city);
-}
\ No newline at end of file
+ return html + queues;
+}
export type Building = {
slug: string;
display: string;
- gold: number;
- ore: number;
- logs: number;
+ credits: number;
+ alloys: number;
+ energy: number;
land: number;
time: number;
}
async list(): Promise<Building[]> {
return this.FindAll();
}
-}
\ No newline at end of file
+}
owner: string;
totalSpace: number;
usedSpace: number;
- gold: number;
- ore: number;
- logs: number;
- bushels: number;
+ credits: number;
+ alloys: number;
+ energy: number;
+ food: number;
population: number;
soldiers: number;
attackers: number;
owner: accountId,
totalSpace: 100,
usedSpace: 0,
- gold: 10000,
- ore: 10000,
- logs: 10000,
- bushels: 10000,
+ credits: 10000,
+ alloys: 10000,
+ energy: 10000,
+ food: 10000,
population: 1000,
soldiers: 100,
attackers: 0,
throw new InsufficientResourceError('land', building.land, freeSpace);
}
- if(city.gold < building.gold) {
- throw new InsufficientResourceError('gold', building.gold, city.gold);
+ if(city.credits < building.credits) {
+ throw new InsufficientResourceError('credits', building.credits, city.credits);
}
- if(city.ore < building.ore) {
- throw new InsufficientResourceError('ore', building.ore, city.ore);
+ if(city.alloys < building.alloys) {
+ throw new InsufficientResourceError('alloys', building.alloys, city.alloys);
}
- if(city.logs < building.logs) {
- throw new InsufficientResourceError('logs', building.logs, city.logs);
+ if(city.energy < building.energy) {
+ throw new InsufficientResourceError('energy', building.energy, city.energy);
}
city.usedSpace += (building.land * amount);
- city.gold -= (building.gold * amount);
- city.ore -= (building.ore * amount);
- city.logs -= (building.logs * amount);
+ city.credits -= (building.credits * amount);
+ city.alloys -= (building.alloys * amount);
+ city.energy -= (building.energy * amount);
await this.save(city);
}
async train(unit: Unit, amount: number, city: City): Promise<UnitTrainingQueue> {
- if(city.gold < unit.gold) {
- throw new InsufficientResourceError('gold', unit.gold, city.gold);
+ if(city.credits < unit.credits) {
+ throw new InsufficientResourceError('credits', unit.credits, city.credits);
}
- if(city.bushels < unit.bushels) {
- throw new InsufficientResourceError('bushels', unit.bushels, city.bushels);
+ if(city.food < unit.food) {
+ throw new InsufficientResourceError('food', unit.food, city.food);
}
if(city.population < coalesce(unit.population, 0)) {
// ok they have everything, lets update their city
// and create the entry in the training queue
- city.gold -= unit.gold * amount;
- city.bushels -= unit.bushels * amount;
+ city.credits -= unit.credits * amount;
+ city.food -= unit.food * amount;
city.population -= coalesce(unit.population, 0) * amount;
city.soldiers -= coalesce(unit.soldiers, 0) * amount;
city.attackers -= coalesce(unit.attackers, 0) * amount;
return power
}
+ async foodProductionPerTick(city: City): Promise<number> {
+ // eventually we should supply the warehouse formula
+ // to calculate the max amount of food created per tick
+ return _.max([
+ city.population + _.round(city.farms * 50)
+ ])
+ }
+
+ async foodUsagePerTick(city: City): Promise<number> {
+ return (
+ (city.soldiers * 0.5) +
+ (city.population * 0.25) +
+ (city.attackers * 0.75) +
+ (city.attackers * 0.75) +
+ (city.sp_attackers * 1.3) +
+ (city.sp_defenders * 1.3)
+ )
+ }
+
+ async energyProductionPerTic(city: City): Promise<number> {
+ return 0;
+ }
+
+ async energyUsagePerTick(city: City): Promise<number> {
+ return 0;
+ }
+
async attack(attacker: CityWithLocation, attacked: CityWithLocation, army: Army): Promise<ArmyQueue> {
// validate the user has enough of a military!
if(attacker.soldiers < army.soldiers) {
export type Unit = {
slug: string;
display: string;
- gold: number;
- bushels: number;
+ credits: number;
+ food: number;
population: number;
soldiers: number;
attackers: number;
async list(): Promise<Unit[]> {
return this.FindAll();
}
-}
\ No newline at end of file
+}
defenders: Math.floor(attacked.defenders * 0.05),
sp_attackers: Math.floor(attacked.sp_attackers * 0.05),
sp_defenders: Math.floor(attacked.sp_defenders * 0.05),
- gold: Math.floor(attacked.gold * 0.2),
- logs: Math.floor(attacked.logs * 0.2),
- ore: Math.floor(attacked.ore * 0.2),
+ credits: Math.floor(attacked.credits * 0.2),
+ energy: Math.floor(attacked.energy * 0.2),
+ alloys: Math.floor(attacked.alloys * 0.2),
land: Math.floor(attacked.totalSpace * 0.15),
};
// ok you have everything, lets return you home
- attacker.gold += defenderLosses.gold;
- attacker.logs += defenderLosses.gold;
- attacker.ore += defenderLosses.ore;
+ attacker.credits += defenderLosses.credits;
+ attacker.energy += defenderLosses.credits;
+ attacker.alloys += defenderLosses.alloys;
attacker.totalSpace += defenderLosses.land;
attacker.soldiers += (army.soldiers - attackerLosses.soldiers);
attacked.defenders -= defenderLosses.defenders;
attacked.sp_attackers -= defenderLosses.sp_attackers;
attacked.sp_defenders -= defenderLosses.sp_defenders;
- attacked.gold -= defenderLosses.gold;
- attacked.logs -= defenderLosses.logs;
- attacked.ore -= defenderLosses.ore;
+ attacked.credits -= defenderLosses.credits;
+ attacked.energy -= defenderLosses.energy;
+ attacked.alloys -= defenderLosses.alloys;
attacked.totalSpace -= defenderLosses.land;
await Promise.all([
You pillaged:
<table>
<tr>
- <th>Gold</th><td>${defenderLosses.gold}</td>
+ <th>Credits</th><td>${defenderLosses.credits}</td>
</tr>
<tr>
- <th>Logs</th><td>${defenderLosses.logs}</td>
+ <th>Energy</th><td>${defenderLosses.energy}</td>
</tr>
<tr>
- <th>Ore</th><td>${defenderLosses.ore}</td>
+ <th>Alloys</th><td>${defenderLosses.alloys}</td>
</tr>
<tr>
- <th>Land</th><td>${defenderLosses.land}</td>
+ <th>Space</th><td>${defenderLosses.land}</td>
</tr>
</table?>
You Lost:
<table>
<tr>
- <th>Gold</th><td>${defenderLosses.gold}</td>
+ <th>Credits</th><td>${defenderLosses.credits}</td>
</tr>
<tr>
- <th>Logs</th><td>${defenderLosses.logs}</td>
+ <th>Energy</th><td>${defenderLosses.energy}</td>
</tr>
<tr>
- <th>Ore</th><td>${defenderLosses.ore}</td>
+ <th>Alloys</th><td>${defenderLosses.alloys}</td>
</tr>
<tr>
- <th>Land</th><td>${defenderLosses.land}</td>
+ <th>Space</th><td>${defenderLosses.land}</td>
</tr>
<tr>
<th>Soldiers</th><td>${attackerLosses.soldiers}</td>
]);
}
-});
\ No newline at end of file
+});
// +population*1.1 is where we take into account farms for bonus food production
let sql = `update cities set
- gold = gold + population * 2,
- bushels = round(
+ credits = credits + population * 2,
+ food = round(
max(
- bushels - (
+ food - (
(soldiers*0.5)+
(population*0.25)+
(attackers*0.75)+
),
population = max(
min(
- population + round(coalesce(bushels/bushels, 0) * population*0.08),
+ population + round(coalesce(food/food, 0) * population*0.08),
farms * 70
),
population
}, { delay: 60000 * nextTickAt});
}
-});
\ No newline at end of file
+});