bourgade/src/update.ts

91 lines
3.1 KiB
TypeScript
Raw Normal View History

import { produce } from 'immer';
import { getBuilding, getProduction, getStorage, getUnitSource } from './utils';
import village, { type VillageState } from "./village";
import type { ProductionType } from './types';
let lastFrame: number;
export default function update(timestamp: number) {
if (!lastFrame) {
lastFrame = timestamp;
return;
}
const delta = timestamp - lastFrame;
village.update(state => {
2024-11-04 18:43:03 +01:00
if (state.victory) {
return state;
}
return produce(state, (V: VillageState) => {
// Advance building construction.
if (V.queue.length) {
V.queue[0].remainingTime -= delta;
if (V.queue[0].remainingTime <= 0) {
const building = getBuilding(V, V.queue[0].id);
building.level++;
V.queue.shift();
}
}
// Make all buildings produce and consume.
const productionPerMinute = getProduction(V);
const storage = getStorage(V);
Object.keys(productionPerMinute).forEach((key) => {
const resource = key as keyof ProductionType;
const outputPerMinute = productionPerMinute[resource];
const outputPerMilisecond = outputPerMinute / 60.0 / 1000.0;
V.resources[resource] += outputPerMilisecond * delta;
if (V.resources[resource] > storage[resource]) {
V.resources[resource] = storage[resource];
}
2024-10-23 11:59:50 +02:00
else if (V.resources[resource] < 0) {
V.resources[resource] = 0;
}
});
// Recruit units.
V.buildings.forEach(b => {
if (!b.state.recruitment || !b.state.recruitment.count) {
return;
}
const recruitment = b.state.recruitment;
recruitment.elapsedTime += delta;
const timeToRecruit = b.behavior.units?.recruitmentTime(V, b) * 1000;
if (recruitment.elapsedTime >= timeToRecruit) {
const unitType = b.behavior.units?.type || '';
if (!V.units.hasOwnProperty(unitType)) {
V.units[unitType] = 0;
}
V.units[unitType]++;
recruitment.count--;
recruitment.elapsedTime = (recruitment.count === 0) ? 0 : timeToRecruit - recruitment.elapsedTime;
}
});
// Make philosophers produce culture.
const philosopher = getUnitSource('philosopher');
const outputPerMinute = philosopher.behavior.culturePerMinute;
const outputPerMilisecond = outputPerMinute / 60.0 / 1000.0;
2024-11-04 18:43:03 +01:00
V.resources.culture += outputPerMilisecond * delta * (V.units.philosopher || 0);
// Check if the game is won.
if (V.resources.culture >= 2000) {
2024-11-04 18:43:03 +01:00
V.victory = true;
}
return V;
});
});
lastFrame = timestamp;
}