bourgade/src/utils.ts

131 lines
3.6 KiB
TypeScript
Raw Normal View History

import units from "./data/units";
import type { BuildingType, CostType, ProductionType } from "./types";
import type { VillageState } from "./village";
function _reduceResources(acc: ProductionType, item: ProductionType): ProductionType {
return {
wood: acc.wood + item.wood,
stone: acc.stone + item.stone,
iron: acc.iron + item.iron,
food: acc.food + item.food,
};
}
export function getEmptyResources(): ProductionType {
return {
wood: 0,
stone: 0,
iron: 0,
food: 0,
};
}
export function getProduction(villageState: VillageState): ProductionType {
return villageState.buildings
.filter(b => b.behavior.production && b.level > 0)
.map(b => {
if (b.behavior.production) {
return b.behavior.production(villageState, b);
}
})
.reduce(_reduceResources, getEmptyResources());
}
export function getStorage(villageState: VillageState): ProductionType {
return villageState.buildings
.filter(b => b.behavior.storage && b.level > 0)
.map(b => {
if (b.behavior.storage) {
return b.behavior.storage(villageState, b);
}
})
.reduce(_reduceResources, getEmptyResources());
}
export function getBuilding(V: VillageState, buildingId: number): BuildingType {
2024-10-24 13:12:21 +00:00
const building = V.buildings.find(b => b.id === buildingId);
if (!building) {
throw new Error(`Cannot find building with id "${buildingId}"`);
}
return building;
}
export function getUnitSource(unitType: string) {
const unit = units.find(u => u.type === unitType);
if (unit === undefined) {
throw new Error(`Unknown unit type: "${unitType}"`);
}
return unit;
}
export function getKeysAsNumbers(dict: Object): Array<number> {
return Object.keys(dict).map(i => parseInt(i)).sort((a, b) => a - b);
}
/**
* Creates an array of shuffled values, using a version of the
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
*
* @since 0.1.0
* @category Array
* @param {Array} array The array to shuffle.
* @returns {Array} Returns the new shuffled array.
* @example
*
* shuffle([1, 2, 3, 4])
* // => [4, 1, 3, 2]
*/
export function shuffle<T>(array: Array<T>): Array<T> {
const length = array.length;
if (!length) {
return [];
}
let index = -1;
const lastIndex = length - 1;
const result = [ ...array ];
while (++index < length) {
const rand = index + Math.floor(Math.random() * (lastIndex - index + 1));
[ result[rand], result[index] ] = [ result[index], result[rand] ];
}
return result;
}
export function enqueueBuilding(V: VillageState, building: BuildingType) {
const ongoingUpgrades = V.queue.filter(q => q.id === building.id);
const level = building.level + 1 + ongoingUpgrades.length;
const remainingTime = 1000 * level;
V.queue.push({
id: building.id,
remainingTime,
});
}
export function getBuildingUpgradeCost(V: VillageState, building: BuildingType): CostType {
const ongoingUpgrades = V.queue.filter(q => q.id === building.id);
const level = building.level + ongoingUpgrades.length + 1;
return building.cost(level);
}
export function canPayBuildingCost(V: VillageState, building: BuildingType): boolean {
const cost = getBuildingUpgradeCost(V, building);
return !(
cost.wood > V.resources.wood
|| cost.stone > V.resources.stone
|| cost.iron > V.resources.iron
|| cost.food > V.resources.food
);
}