Compare commits
No commits in common. "fbe48f925d7a53557c2e715403f1bfc2085661a6" and "6c18870b6b9c21692d658b030d4359267865a616" have entirely different histories.
fbe48f925d
...
6c18870b6b
Binary file not shown.
Before Width: | Height: | Size: 873 B |
@ -1,57 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import moves from "../moves";
|
|
||||||
import type { BuildingType } from "../types";
|
import type { BuildingType } from "../types";
|
||||||
import { canPayBuildingCost } from "../utils";
|
|
||||||
import village from "../village";
|
|
||||||
|
|
||||||
export let building: BuildingType;
|
export let building: BuildingType;
|
||||||
|
|
||||||
|
|
||||||
$: isUpgrading = $village.queue.find(q => q.id === building.id);
|
|
||||||
$: canUpgrade = canPayBuildingCost($village, building);
|
|
||||||
|
|
||||||
|
|
||||||
function upgradeBuilding() {
|
|
||||||
moves.upgradeBuilding(building.id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<p>{ building.name }</p>
|
||||||
<p>{ building.name }</p>
|
<p>{ building.level }</p>
|
||||||
<p>
|
|
||||||
<button
|
|
||||||
class="level"
|
|
||||||
class:can-upgrade={ canUpgrade }
|
|
||||||
class:is-upgrading={ isUpgrading }
|
|
||||||
on:click|stopPropagation={ upgradeBuilding }
|
|
||||||
>
|
|
||||||
{ building.level }
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.level {
|
|
||||||
aspect-ratio: 1;
|
|
||||||
background-color: hsl(208, 100%, 97%);
|
|
||||||
border: 0.4em solid hsl(0, 0%, 45%);
|
|
||||||
border-radius: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
box-shadow: 0 0 0.2em black;
|
|
||||||
color: hsl(0, 0%, 10%);
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.level.can-upgrade {
|
|
||||||
border-color: hsl(90, 99%, 36%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.level.is-upgrading {
|
|
||||||
border-color: hsl(56, 99%, 43%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.level:hover.can-upgrade {
|
|
||||||
border-color: hsl(90, 99%, 36%);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
import Queue from "./Queue.svelte";
|
import Queue from "./Queue.svelte";
|
||||||
import Resources from "./Resources.svelte";
|
import Resources from "./Resources.svelte";
|
||||||
import Units from "./Units.svelte";
|
import Units from "./Units.svelte";
|
||||||
import Victory from "./Victory.svelte";
|
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
@ -54,7 +53,6 @@
|
|||||||
<section class="overlay">
|
<section class="overlay">
|
||||||
<BuildingCreator />
|
<BuildingCreator />
|
||||||
<BuildingPanel />
|
<BuildingPanel />
|
||||||
<Victory />
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -28,10 +28,6 @@
|
|||||||
{ Math.floor($village.resources.food) } / { capacity.food }
|
{ Math.floor($village.resources.food) } / { capacity.food }
|
||||||
({ production.food >= 0 ? '+' : '' }{ production.food })
|
({ production.food >= 0 ? '+' : '' }{ production.food })
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<img src="/img/icons/culture.png" alt="Culture" />
|
|
||||||
{ Math.floor($village.resources.culture) }
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import village from "../village";
|
|
||||||
|
|
||||||
|
|
||||||
function restart() {
|
|
||||||
village.reset();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{ #if $village.victory }
|
|
||||||
<section>
|
|
||||||
<h1>Victory!</h1>
|
|
||||||
<div>
|
|
||||||
<button on:click={ restart }>Play again</button>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{ /if }
|
|
||||||
|
|
||||||
<style>
|
|
||||||
section {
|
|
||||||
background-color: hsl(0, 0%, 10%, 0.9);
|
|
||||||
display: grid;
|
|
||||||
place-items: center;
|
|
||||||
height: 100vh;
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,4 +1,4 @@
|
|||||||
import { canPayBuildingCost, enqueueBuilding, getBuildingUpgradeCost } from "../utils";
|
import { enqueueBuilding } from "../utils";
|
||||||
import type { VillageState } from "../village";
|
import type { VillageState } from "../village";
|
||||||
|
|
||||||
|
|
||||||
@ -8,12 +8,20 @@ export default function upgradeBuilding(V: VillageState, buildingId: number) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canPayBuildingCost(V, building)) {
|
const ongoingUpgrades = V.queue.filter(q => q.id === building.id);
|
||||||
|
const level = building.level + 1 + ongoingUpgrades.length;
|
||||||
|
|
||||||
|
const cost = building.cost(level);
|
||||||
|
|
||||||
|
if (
|
||||||
|
cost.wood > V.resources.wood
|
||||||
|
|| cost.stone > V.resources.stone
|
||||||
|
|| cost.iron > V.resources.iron
|
||||||
|
|| cost.food > V.resources.food
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cost = getBuildingUpgradeCost(V, building);
|
|
||||||
|
|
||||||
V.resources.wood -= cost.wood;
|
V.resources.wood -= cost.wood;
|
||||||
V.resources.stone -= cost.stone;
|
V.resources.stone -= cost.stone;
|
||||||
V.resources.iron -= cost.iron;
|
V.resources.iron -= cost.iron;
|
||||||
|
@ -15,11 +15,6 @@ export interface CostType {
|
|||||||
export type ProductionType = CostType;
|
export type ProductionType = CostType;
|
||||||
|
|
||||||
|
|
||||||
export interface ResourcesType extends CostType {
|
|
||||||
culture: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export interface BuildingSource {
|
export interface BuildingSource {
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
type: string;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { produce } from 'immer';
|
import { produce } from 'immer';
|
||||||
|
|
||||||
import { getBuilding, getProduction, getStorage, getUnitSource } from './utils';
|
import { getBuilding, getProduction, getStorage } from './utils';
|
||||||
import village, { type VillageState } from "./village";
|
import village, { type VillageState } from "./village";
|
||||||
import type { ProductionType } from './types';
|
import type { ProductionType } from './types';
|
||||||
|
|
||||||
@ -17,10 +17,6 @@ export default function update(timestamp: number) {
|
|||||||
const delta = timestamp - lastFrame;
|
const delta = timestamp - lastFrame;
|
||||||
|
|
||||||
village.update(state => {
|
village.update(state => {
|
||||||
if (state.victory) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
return produce(state, (V: VillageState) => {
|
return produce(state, (V: VillageState) => {
|
||||||
// Advance building construction.
|
// Advance building construction.
|
||||||
if (V.queue.length) {
|
if (V.queue.length) {
|
||||||
@ -71,17 +67,6 @@ export default function update(timestamp: number) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Make philosophers produce culture.
|
|
||||||
const philosopher = getUnitSource('philosopher');
|
|
||||||
const outputPerMinute = philosopher.behavior.culturePerMinute;
|
|
||||||
const outputPerMilisecond = outputPerMinute / 60.0 / 1000.0;
|
|
||||||
V.resources.culture += outputPerMilisecond * delta * (V.units.philosopher || 0);
|
|
||||||
|
|
||||||
// Check if the game is won.
|
|
||||||
if (V.resources.culture >= 2) {
|
|
||||||
V.victory = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return V;
|
return V;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
21
src/utils.ts
21
src/utils.ts
@ -1,5 +1,5 @@
|
|||||||
import units from "./data/units";
|
import units from "./data/units";
|
||||||
import type { BuildingType, CostType, ProductionType } from "./types";
|
import type { BuildingType, ProductionType } from "./types";
|
||||||
import type { VillageState } from "./village";
|
import type { VillageState } from "./village";
|
||||||
|
|
||||||
|
|
||||||
@ -109,22 +109,3 @@ export function enqueueBuilding(V: VillageState, building: BuildingType) {
|
|||||||
remainingTime,
|
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,7 @@ import { writable } from "svelte/store";
|
|||||||
|
|
||||||
import { createBuilding } from "./create";
|
import { createBuilding } from "./create";
|
||||||
import { getTilesAtDistance, Hex } from "./hexgrid";
|
import { getTilesAtDistance, Hex } from "./hexgrid";
|
||||||
import type { BuildingType, ResourcesType } from "./types";
|
import type { BuildingType } from "./types";
|
||||||
import { getKeysAsNumbers, shuffle } from "./utils";
|
import { getKeysAsNumbers, shuffle } from "./utils";
|
||||||
|
|
||||||
|
|
||||||
@ -24,11 +24,16 @@ export interface VillageState {
|
|||||||
units: {
|
units: {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
},
|
},
|
||||||
resources: ResourcesType;
|
resources: {
|
||||||
|
wood: number;
|
||||||
|
stone: number;
|
||||||
|
iron: number;
|
||||||
|
food: number;
|
||||||
|
culture: number;
|
||||||
|
};
|
||||||
villageTiles: Board;
|
villageTiles: Board;
|
||||||
outsideTiles: Board;
|
outsideTiles: Board;
|
||||||
queue: QueuedBuilding[];
|
queue: QueuedBuilding[];
|
||||||
victory: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +89,6 @@ function getInitialState() {
|
|||||||
villageTiles: getInitialVillageBoard(),
|
villageTiles: getInitialVillageBoard(),
|
||||||
outsideTiles: getInitialOutsideBoard(),
|
outsideTiles: getInitialOutsideBoard(),
|
||||||
queue: [],
|
queue: [],
|
||||||
victory: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the Town hall.
|
// Create the Town hall.
|
||||||
@ -124,12 +128,4 @@ function getInitialState() {
|
|||||||
const village = writable<VillageState>(getInitialState());
|
const village = writable<VillageState>(getInitialState());
|
||||||
|
|
||||||
|
|
||||||
function reset() {
|
export default village;
|
||||||
village.set(getInitialState());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...village,
|
|
||||||
reset,
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user