bourgade/src/village.ts

128 lines
3.0 KiB
TypeScript
Raw Normal View History

import { writable } from "svelte/store";
2024-10-23 08:36:03 +00:00
import buildings from "./buildings";
import { createBuilding } from "./create";
import type { Building } from "./types";
import { getTilesAtDistance, Hex } from "./hexgrid";
import { getKeysAsNumbers, shuffle } from "./utils";
type Board = {
[key: number]: {
[key: number]: number;
}
}
interface QueuedBuilding {
id: number;
remainingTime: number;
}
export interface VillageState {
buildings: Building[];
resources: {
wood: number;
stone: number;
iron: number;
food: number;
culture: number;
};
villageTiles: Board;
outsideTiles: Board;
queue: QueuedBuilding[];
}
export const DEFAULT_TILE = -1;
export const VILLAGE_TILE = -2;
function getInitialVillageBoard() {
const board: Board = {
0: { 0: DEFAULT_TILE },
};
for (let i = 1; i <= 2; i++) {
getTilesAtDistance(i).forEach(tile => {
if (board[tile.y] === undefined) {
board[tile.y] = {};
}
board[tile.y][tile.x] = DEFAULT_TILE;
});
}
return board;
}
function getInitialOutsideBoard() {
const board: Board = {
0: { 0: VILLAGE_TILE },
};
for (let i = 1; i <= 2; i++) {
getTilesAtDistance(i).forEach(tile => {
if (board[tile.y] === undefined) {
board[tile.y] = {};
}
board[tile.y][tile.x] = DEFAULT_TILE;
});
}
return board;
}
function getInitialState() {
const state: VillageState = {
buildings: [],
resources: {
wood: 60,
stone: 60,
iron: 60,
food: 50,
culture: 0,
},
villageTiles: getInitialVillageBoard(),
outsideTiles: getInitialOutsideBoard(),
queue: [],
};
// Create the Town hall.
const townhall = createBuilding('townhall');
state.villageTiles[0][0] = townhall.id;
state.buildings.push(townhall);
// Create all the resource buildings.
const resourceBuildingTypes: Array<string> = shuffle([
'woodcutter', 'woodcutter', 'woodcutter', 'woodcutter',
'mine', 'mine', 'mine', 'mine',
'pit', 'pit', 'pit', 'pit',
'field', 'field', 'field', 'field', 'field', 'field',
]);
getKeysAsNumbers(state.outsideTiles).forEach(y => {
getKeysAsNumbers(state.outsideTiles[y]).forEach(x => {
if (state.outsideTiles[y][x] !== DEFAULT_TILE) {
return;
}
const type = resourceBuildingTypes.pop();
if (type === undefined) {
throw new Error("Not enough building types for outside resource buildings");
}
const newBuilding = createBuilding(type);
newBuilding.tile = new Hex(x, y);
state.outsideTiles[y][x] = newBuilding.id;
state.buildings.push(newBuilding);
});
});
return state;
}
const village = writable<VillageState>(getInitialState());
export default village;