diff --git a/src/data/worldmap.ts b/src/data/worldmap.ts index e030041..eb5a3ed 100644 --- a/src/data/worldmap.ts +++ b/src/data/worldmap.ts @@ -2,21 +2,81 @@ export default [ { type: 'oasis', resource: 'food', - distance: 1, + distance: [1, 2], }, { type: 'oasis', resource: 'wood', - distance: 1, + distance: [1, 2], }, { type: 'oasis', resource: 'stone', - distance: 1, + distance: [1, 2], }, { type: 'oasis', resource: 'iron', - distance: 1, + distance: [1, 2], + }, + { + type: 'oasis', + resource: 'food', + distance: [2, 3], + }, + { + type: 'oasis', + resource: 'wood', + distance: [2, 3], + }, + { + type: 'oasis', + resource: 'stone', + distance: [2, 3], + }, + { + type: 'oasis', + resource: 'iron', + distance: [2, 3], + }, + { + type: 'oasis', + resource: 'food', + distance: [3, 4], + }, + { + type: 'oasis', + resource: 'wood', + distance: [3, 4], + }, + { + type: 'oasis', + resource: 'stone', + distance: [3, 4], + }, + { + type: 'oasis', + resource: 'iron', + distance: [3, 4], + }, + { + type: 'oasis', + resource: 'food', + distance: [4, 5], + }, + { + type: 'oasis', + resource: 'wood', + distance: [4, 5], + }, + { + type: 'oasis', + resource: 'stone', + distance: [4, 5], + }, + { + type: 'oasis', + resource: 'iron', + distance: [4, 5], }, ]; diff --git a/src/missions.ts b/src/missions.ts index 090a2d2..6bbca31 100644 --- a/src/missions.ts +++ b/src/missions.ts @@ -37,6 +37,10 @@ function resolvePillageOasis(V: VillageState, region: OasisType) { } const unit = getUnitSource('soldier'); + const maxResources = region.distance * region.distance * 100; - V.resources[region.resource] += mission.unitCount * unit.behavior.caryingCapacity; + V.resources[region.resource] += Math.min( + mission.unitCount * unit.behavior.caryingCapacity, + maxResources + ); } diff --git a/src/types.ts b/src/types.ts index a82ceba..ab96169 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,12 @@ import type { Hex } from "./hexgrid"; +export interface Point { + x: number; + y: number; +} + + export type GameTab = 'village' | 'resources' | 'world'; @@ -92,6 +98,7 @@ export enum WORLDMAP_TYPES { interface BaseRegionType { id: number; type: WORLDMAP_TYPES; + distance: number; } diff --git a/src/utils.ts b/src/utils.ts index a3f7b32..495020e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import { WORLD_MAP_HEIGHT, WORLD_MAP_WIDTH } from "./constants"; import units from "./data/units"; -import { WORLDMAP_TYPES, type BuildingType, type CostType, type OasisType, type ProductionType, type ResourcesType } from "./types"; +import { WORLDMAP_TYPES, type BuildingType, type CostType, type OasisType, type Point, type ProductionType, type ResourcesType } from "./types"; import type { VillageState } from "./village"; @@ -200,3 +200,19 @@ export function getAdjacentWorldmapCells(cellIndex: number) { return cells.filter(c => c >= 0 && c < WORLD_MAP_WIDTH * WORLD_MAP_HEIGHT); } + + +export function distanceBetweenCells(a: Point, b: Point) { + return Math.sqrt( + Math.pow(b.x - a.x, 2) + + Math.pow(b.y - a.y, 2) + ); +} + + +export function indexToPoint(index: number): Point { + return { + x: index % WORLD_MAP_WIDTH, + y: index / WORLD_MAP_WIDTH, + }; +} diff --git a/src/village.ts b/src/village.ts index c54d642..dbe58be 100644 --- a/src/village.ts +++ b/src/village.ts @@ -4,7 +4,7 @@ import { createBuilding, createHero, createQuest } from "./create"; import worldmap from "./data/worldmap"; import { getTilesAtDistance, Hex } from "./hexgrid"; import { WORLDMAP_TYPES, type BuildingType, type CostType, type HeroType, type QuestType, type RegionType, type ResourcesType } from "./types"; -import { getAdjacentWorldmapCells, getKeysAsNumbers, shuffle } from "./utils"; +import { distanceBetweenCells, getAdjacentWorldmapCells, getKeysAsNumbers, indexToPoint, shuffle } from "./utils"; import { WORLD_MAP_HEIGHT, WORLD_MAP_WIDTH } from "./constants"; @@ -69,23 +69,32 @@ function getInitialOutsideBoard() { function getInitialWorldmap(): RegionType[] { - const board: RegionType[] = [] + const board: RegionType[] = []; + const centerIndex = Math.floor((WORLD_MAP_WIDTH * WORLD_MAP_HEIGHT) / 2); + const centerPoint = indexToPoint(centerIndex); + for (let i = 0; i < WORLD_MAP_WIDTH * WORLD_MAP_HEIGHT; i++) { board[i] = { id: i, type: WORLDMAP_TYPES.EMPTY, + distance: distanceBetweenCells(indexToPoint(i), centerPoint), }; } - const centerIndex = Math.floor((WORLD_MAP_WIDTH * WORLD_MAP_HEIGHT) / 2); board[centerIndex].type = WORLDMAP_TYPES.BOURGADE; const adj = shuffle(getAdjacentWorldmapCells(centerIndex)); - worldmap.forEach(c => { - const cellIndex = adj.pop() || 0; - board[cellIndex] = { + worldmap.forEach(region => { + const candidates = board.filter(c => + c.type !== WORLDMAP_TYPES.EMPTY + && c.distance >= region.distance[0] + && c.distance < region.distance[1] + ); + const cell = shuffle(candidates)[0]; + board[cell.id] = { type: WORLDMAP_TYPES.OASIS, - id: cellIndex, - resource: c.resource as keyof CostType, + id: cell.id, + resource: region.resource as keyof CostType, + distance: cell.distance, state: {}, }; });