Add an oasis pillaging move.
This commit is contained in:
parent
149a6b47f9
commit
2dffb2dcac
@ -1,7 +1,27 @@
|
||||
<script lang="ts">
|
||||
import moves from "../moves";
|
||||
import type { OasisType } from "../types";
|
||||
import { getRemainingUnitCount } from "../utils";
|
||||
import village from "../village";
|
||||
|
||||
export let region: OasisType;
|
||||
|
||||
|
||||
let numberOfUnits = 0;
|
||||
$: maximumUnits = getRemainingUnitCount($village, 'soldier');
|
||||
$: if (numberOfUnits > maximumUnits) {
|
||||
numberOfUnits = maximumUnits || 0;
|
||||
}
|
||||
|
||||
|
||||
function setMaxUnits() {
|
||||
numberOfUnits = maximumUnits;
|
||||
}
|
||||
|
||||
|
||||
function pillage() {
|
||||
moves.pillage(region.state.index, numberOfUnits);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
@ -10,10 +30,31 @@
|
||||
Oasis
|
||||
(→ { region.distance })
|
||||
</h2>
|
||||
{ #if region.state.mission }
|
||||
<div>
|
||||
<button>Pillage</button>
|
||||
<button>Conquer</button>
|
||||
<p>{ region.state.mission.unitCount } soldiers are on a mission here.</p>
|
||||
<p>Remaining: { Math.ceil(region.state.mission.remainingTime / 1000) }</p>
|
||||
</div>
|
||||
{ :else }
|
||||
<div>
|
||||
<input
|
||||
type="range"
|
||||
name="units"
|
||||
min="0"
|
||||
max={ maximumUnits }
|
||||
bind:value={ numberOfUnits }
|
||||
/>
|
||||
<input
|
||||
type="number"
|
||||
name="units"
|
||||
min="0"
|
||||
max={ maximumUnits }
|
||||
bind:value={ numberOfUnits }
|
||||
/>
|
||||
<button on:click={ setMaxUnits }>↑</button>
|
||||
<button on:click={ pillage } disabled={ numberOfUnits === 0 }>Pillage</button>
|
||||
</div>
|
||||
{ /if }
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import units from "../data/units";
|
||||
import { getRemainingUnitCount } from "../utils";
|
||||
import village from "../village";
|
||||
|
||||
$: currentUnits = Object.entries($village.units).map(([type, count]) => {
|
||||
@ -17,6 +18,6 @@
|
||||
|
||||
<section>
|
||||
{ #each currentUnits as unit }
|
||||
<p>{ unit.name }: { unit.count }</p>
|
||||
<p>{ unit.name }: { getRemainingUnitCount($village, unit.type) } / { unit.count }</p>
|
||||
{ /each }
|
||||
</section>
|
||||
|
31
src/missions.ts
Normal file
31
src/missions.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import type { OasisType, RegionType } from "./types";
|
||||
import type { VillageState } from "./village";
|
||||
|
||||
|
||||
export function resolveMission(V: VillageState, region: RegionType) {
|
||||
const mission = region.state.mission;
|
||||
if (!mission) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mission.type) {
|
||||
case 'pillage':
|
||||
if (region.type === 'oasis') {
|
||||
resolvePillageOasis(V, region);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown mission type: "${ mission.type }"`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function resolvePillageOasis(V: VillageState, region: OasisType) {
|
||||
const mission = region.state.mission;
|
||||
if (!mission) {
|
||||
return;
|
||||
}
|
||||
|
||||
V.resources[region.resource] += mission.unitCount * 40;
|
||||
delete region.state.mission;
|
||||
}
|
@ -4,6 +4,7 @@ import village, { type VillageState } from '../village';
|
||||
import build from './build';
|
||||
import upgradeBuilding from './upgradeBuilding';
|
||||
import recruitUnits from './recruitUnits';
|
||||
import pillage from './pillage';
|
||||
|
||||
|
||||
// Encapsulates a move function into a store update, where the data is made
|
||||
@ -31,5 +32,6 @@ export function makeMove(move: (...args: any[]) => boolean) {
|
||||
export default {
|
||||
build: makeMove(build),
|
||||
upgradeBuilding: makeMove(upgradeBuilding),
|
||||
pillage: makeMove(pillage),
|
||||
recruitUnits: makeMove(recruitUnits),
|
||||
};
|
||||
|
24
src/moves/pillage.ts
Normal file
24
src/moves/pillage.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { getRemainingUnitCount } from "../utils";
|
||||
import type { VillageState } from "../village";
|
||||
|
||||
|
||||
export default function pillage(V: VillageState, regionIndex: number, soldiersCount: number) {
|
||||
if (soldiersCount > getRemainingUnitCount(V, 'soldier')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const region = V.worldmap[regionIndex];
|
||||
|
||||
if (region.state.mission) {
|
||||
return false;
|
||||
}
|
||||
|
||||
region.state.mission = {
|
||||
type: 'pillage',
|
||||
unitType: 'soldier',
|
||||
unitCount: soldiersCount,
|
||||
remainingTime: region.distance * 10 * 1000,
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
12
src/types.ts
12
src/types.ts
@ -64,12 +64,18 @@ export interface UnitType {
|
||||
}
|
||||
|
||||
|
||||
export interface MissionType {
|
||||
type: string;
|
||||
unitType: string;
|
||||
unitCount: number;
|
||||
remainingTime: number;
|
||||
}
|
||||
|
||||
interface BaseRegionType {
|
||||
distance: number;
|
||||
state: {
|
||||
mission?: {
|
||||
type: string;
|
||||
};
|
||||
index: number;
|
||||
mission?: MissionType;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { produce } from 'immer';
|
||||
|
||||
import { CULTURE_TO_WIN } from './constants';
|
||||
import { resolveMission } from './missions';
|
||||
import type { ProductionType } from './types';
|
||||
import { getProduction, getStorage, shuffle } from './utils';
|
||||
import village, { type VillageState } from "./village";
|
||||
@ -32,6 +33,19 @@ export default function update(timestamp: number) {
|
||||
}
|
||||
});
|
||||
|
||||
// Advance missions.
|
||||
V.worldmap.forEach(region => {
|
||||
if (!region.state.mission) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mission = region.state.mission;
|
||||
mission.remainingTime -= delta;
|
||||
if (mission.remainingTime <= 0) {
|
||||
resolveMission(V, region);
|
||||
}
|
||||
});
|
||||
|
||||
// Make all buildings and units produce and consume.
|
||||
const productionPerMinute = getProduction(V);
|
||||
const storage = getStorage(V);
|
||||
|
10
src/utils.ts
10
src/utils.ts
@ -1,5 +1,5 @@
|
||||
import units from "./data/units";
|
||||
import type { BuildingType, CostType, ProductionType, ResourcesType } from "./types";
|
||||
import type { BuildingType, CostType, MissionType, ProductionType, ResourcesType } from "./types";
|
||||
import type { VillageState } from "./village";
|
||||
|
||||
|
||||
@ -88,6 +88,14 @@ export function getUnitSource(unitType: string) {
|
||||
}
|
||||
|
||||
|
||||
export function getRemainingUnitCount(V: VillageState, unitType: string) {
|
||||
let total = V.units[unitType] || 0;
|
||||
const missions = V.worldmap.filter(r => r.state.mission?.unitType === unitType).map(r => r.state.mission);
|
||||
missions.forEach(m => total -= m?.unitCount || 0);
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
export function getKeysAsNumbers(dict: Object): Array<number> {
|
||||
return Object.keys(dict).map(i => parseInt(i)).sort((a, b) => a - b);
|
||||
}
|
||||
|
@ -66,11 +66,13 @@ function getInitialOutsideBoard() {
|
||||
|
||||
|
||||
function getInitialWorldmap(): RegionType[] {
|
||||
return worldmap.map(r => {
|
||||
return worldmap.map((r, index) => {
|
||||
const region = r as RegionType;
|
||||
return {
|
||||
...region,
|
||||
state: {},
|
||||
state: {
|
||||
index,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user