Show a map of the outside of the village, with all the resource farms.
This commit is contained in:
parent
a47486973c
commit
756f2bc152
@ -5,3 +5,4 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<p>{ building.name }</p>
|
<p>{ building.name }</p>
|
||||||
|
<p>{ building.level }</p>
|
||||||
|
48
src/board/Outside.svelte
Normal file
48
src/board/Outside.svelte
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import gameTab from "../stores/gameTab";
|
||||||
|
import showBuildingPanel from "../stores/showBuildingPanel";
|
||||||
|
import { getBuilding, getKeysAsNumbers } from "../utils";
|
||||||
|
import village, { VILLAGE_TILE } from "../village";
|
||||||
|
import BuildingTile from "./BuildingTile.svelte";
|
||||||
|
import Tile from "./Tile.svelte";
|
||||||
|
|
||||||
|
|
||||||
|
function openBuildingPanel(buildingId: number) {
|
||||||
|
showBuildingPanel.set(buildingId);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="outside-map">
|
||||||
|
<div>
|
||||||
|
{ #each getKeysAsNumbers($village.outsideTiles) as y }
|
||||||
|
<div>
|
||||||
|
{ #each getKeysAsNumbers($village.outsideTiles[y]) as x }
|
||||||
|
{ #if $village.outsideTiles[y][x] >= 0 }
|
||||||
|
<Tile
|
||||||
|
onTileClick={ () => openBuildingPanel($village.outsideTiles[y][x]) }
|
||||||
|
>
|
||||||
|
<BuildingTile building={ getBuilding($village, $village.outsideTiles[y][x]) } />
|
||||||
|
</Tile>
|
||||||
|
{ :else if $village.outsideTiles[y][x] === VILLAGE_TILE }
|
||||||
|
<Tile
|
||||||
|
onTileClick={ () => gameTab.set('village') }
|
||||||
|
/>
|
||||||
|
{ /if }
|
||||||
|
{ /each }
|
||||||
|
</div>
|
||||||
|
{ /each }
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.outside-map {
|
||||||
|
display: grid;
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 0.8em;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outside-map > div {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,6 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Hex } from "../hexgrid";
|
import { Hex } from "../hexgrid";
|
||||||
import moves from "../moves";
|
|
||||||
import showBuildingCreator from "../stores/showBuildingCreator";
|
import showBuildingCreator from "../stores/showBuildingCreator";
|
||||||
import showBuildingPanel from "../stores/showBuildingPanel";
|
import showBuildingPanel from "../stores/showBuildingPanel";
|
||||||
import { getBuilding, getKeysAsNumbers } from "../utils";
|
import { getBuilding, getKeysAsNumbers } from "../utils";
|
||||||
@ -9,10 +8,6 @@
|
|||||||
import Tile from "./Tile.svelte";
|
import Tile from "./Tile.svelte";
|
||||||
|
|
||||||
|
|
||||||
function upgradeBuilding(id: number) {
|
|
||||||
moves.upgradeBuilding(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openBuildingCreator(tile: Hex) {
|
function openBuildingCreator(tile: Hex) {
|
||||||
showBuildingCreator.set(tile);
|
showBuildingCreator.set(tile);
|
||||||
}
|
}
|
||||||
@ -48,6 +43,7 @@
|
|||||||
.village-map {
|
.village-map {
|
||||||
display: grid;
|
display: grid;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
margin-top: 0.8em;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import type { Building } from "./types";
|
import type { Building, BuildingSource } from "./types";
|
||||||
import { getEmptyResources } from "./utils";
|
import { getEmptyResources } from "./utils";
|
||||||
import type { VillageState } from "./village";
|
import type { VillageState } from "./village";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
const buildings = [
|
||||||
'townhall': {
|
{
|
||||||
|
type: 'townhall',
|
||||||
name: 'Town Hall',
|
name: 'Town Hall',
|
||||||
|
autoBuilt: true,
|
||||||
cost: (level: number) => {
|
cost: (level: number) => {
|
||||||
return {
|
return {
|
||||||
wood: level * 10,
|
wood: level * 10,
|
||||||
@ -25,8 +27,10 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'woodcutter': {
|
{
|
||||||
|
type: 'woodcutter',
|
||||||
name: 'Woodcutter',
|
name: 'Woodcutter',
|
||||||
|
autoBuilt: true,
|
||||||
cost: (level: number) => {
|
cost: (level: number) => {
|
||||||
return {
|
return {
|
||||||
wood: level * 10,
|
wood: level * 10,
|
||||||
@ -48,8 +52,10 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'mine': {
|
{
|
||||||
|
type: 'mine',
|
||||||
name: 'Mine',
|
name: 'Mine',
|
||||||
|
autoBuilt: true,
|
||||||
cost: (level: number) => {
|
cost: (level: number) => {
|
||||||
return {
|
return {
|
||||||
wood: level * 10,
|
wood: level * 10,
|
||||||
@ -71,8 +77,10 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'pit': {
|
{
|
||||||
|
type: 'pit',
|
||||||
name: 'Pit',
|
name: 'Pit',
|
||||||
|
autoBuilt: true,
|
||||||
cost: (level: number) => {
|
cost: (level: number) => {
|
||||||
return {
|
return {
|
||||||
wood: level * 10,
|
wood: level * 10,
|
||||||
@ -94,8 +102,10 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'field': {
|
{
|
||||||
|
type: 'field',
|
||||||
name: 'Field',
|
name: 'Field',
|
||||||
|
autoBuilt: true,
|
||||||
cost: (level: number) => {
|
cost: (level: number) => {
|
||||||
return {
|
return {
|
||||||
wood: level * 10,
|
wood: level * 10,
|
||||||
@ -113,7 +123,8 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'warehouse': {
|
{
|
||||||
|
type: 'warehouse',
|
||||||
name: 'Warehouse',
|
name: 'Warehouse',
|
||||||
cost: (level: number) => {
|
cost: (level: number) => {
|
||||||
return {
|
return {
|
||||||
@ -136,7 +147,8 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'granary': {
|
{
|
||||||
|
type: 'granary',
|
||||||
name: 'Granary',
|
name: 'Granary',
|
||||||
cost: (level: number) => {
|
cost: (level: number) => {
|
||||||
return {
|
return {
|
||||||
@ -159,4 +171,5 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
];
|
||||||
|
export default buildings;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import buildings from "./buildings";
|
||||||
import { Hex } from "./hexgrid";
|
import { Hex } from "./hexgrid";
|
||||||
import type { Building, BuildingSource } from "./types";
|
import type { Building, BuildingSource } from "./types";
|
||||||
|
|
||||||
@ -5,9 +6,22 @@ import type { Building, BuildingSource } from "./types";
|
|||||||
let uid = 0;
|
let uid = 0;
|
||||||
|
|
||||||
|
|
||||||
export function createBuilding(building: BuildingSource): Building {
|
export function getBuildingSource(buildingType: string): BuildingSource {
|
||||||
|
const source: BuildingSource | undefined = buildings.find(b => b.type === buildingType);
|
||||||
|
|
||||||
|
if (source === undefined) {
|
||||||
|
throw new Error(`Unknown building type: "${buildingType}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return source
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function createBuilding(buildingType: string): Building {
|
||||||
|
const source: BuildingSource = getBuildingSource(buildingType);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...building,
|
...source,
|
||||||
id: uid++,
|
id: uid++,
|
||||||
level: 1,
|
level: 1,
|
||||||
tile: new Hex(0, 0),
|
tile: new Hex(0, 0),
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const constructible = buildings.filter(b => !b.autoBuilt);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{ #if $showBuildingCreator !== null }
|
{ #if $showBuildingCreator !== null }
|
||||||
@ -29,10 +31,10 @@
|
|||||||
</span>
|
</span>
|
||||||
</header>
|
</header>
|
||||||
<div class="buildings">
|
<div class="buildings">
|
||||||
{ #each Object.entries(buildings) as [type, building] }
|
{ #each constructible as building }
|
||||||
<div>
|
<div>
|
||||||
<p>{ building.name }</p>
|
<p>{ building.name }</p>
|
||||||
<button on:click={ () => build(type) }>Build</button>
|
<button on:click={ () => build(building.type) }>Build</button>
|
||||||
</div>
|
</div>
|
||||||
{ /each }
|
{ /each }
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
import BuildingCreator from "./BuildingCreator.svelte";
|
import BuildingCreator from "./BuildingCreator.svelte";
|
||||||
import Resources from "./Resources.svelte";
|
import Resources from "./Resources.svelte";
|
||||||
import BuildingPanel from "./BuildingPanel.svelte";
|
import BuildingPanel from "./BuildingPanel.svelte";
|
||||||
|
import Outside from "../board/Outside.svelte";
|
||||||
|
import Navigation from "./Navigation.svelte";
|
||||||
|
import type { GameTab } from "../types";
|
||||||
|
import gameTab from "../stores/gameTab";
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
@ -21,14 +25,23 @@
|
|||||||
cancelAnimationFrame(frame);
|
cancelAnimationFrame(frame);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function setTab(newTab: GameTab) {
|
||||||
|
gameTab.set(newTab);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="hud">
|
<section class="hud">
|
||||||
<header>
|
<header>
|
||||||
<Resources />
|
<Resources />
|
||||||
|
<Navigation { setTab } />
|
||||||
</header>
|
</header>
|
||||||
<div class="buildings">
|
<div class="">
|
||||||
|
{ #if $gameTab === 'village' }
|
||||||
<Village />
|
<Village />
|
||||||
|
{ :else if $gameTab === 'resources' }
|
||||||
|
<Outside />
|
||||||
|
{ /if }
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="overlay">
|
<section class="overlay">
|
||||||
@ -37,10 +50,6 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.buildings {
|
|
||||||
margin-top: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overlay {
|
.overlay {
|
||||||
left: 0;
|
left: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
20
src/hud/Navigation.svelte
Normal file
20
src/hud/Navigation.svelte
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { GameTab } from "../types";
|
||||||
|
|
||||||
|
export let setTab: (tab: GameTab) => void;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
<button
|
||||||
|
class="invisible"
|
||||||
|
on:click={ () => setTab('village') }
|
||||||
|
>
|
||||||
|
Village
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="invisible"
|
||||||
|
on:click={ () => setTab('resources') }
|
||||||
|
>
|
||||||
|
Resources
|
||||||
|
</button>
|
||||||
|
</nav>
|
@ -1,11 +1,11 @@
|
|||||||
import buildings from "../buildings";
|
import buildings from "../buildings";
|
||||||
import { createBuilding } from "../create";
|
import { createBuilding, getBuildingSource } from "../create";
|
||||||
import type { Hex } from "../hexgrid";
|
import type { Hex } from "../hexgrid";
|
||||||
import { DEFAULT_TILE, type VillageState } from "../village";
|
import { DEFAULT_TILE, type VillageState } from "../village";
|
||||||
|
|
||||||
|
|
||||||
export default function build(V: VillageState, buildingType: keyof typeof buildings, tile: Hex) {
|
export default function build(V: VillageState, buildingType: string, tile: Hex) {
|
||||||
const building = buildings[buildingType];
|
const building = getBuildingSource(buildingType);
|
||||||
const cost = building.cost(1);
|
const cost = building.cost(1);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -26,7 +26,7 @@ export default function build(V: VillageState, buildingType: keyof typeof buildi
|
|||||||
V.resources.iron -= cost.iron;
|
V.resources.iron -= cost.iron;
|
||||||
V.resources.food -= cost.food;
|
V.resources.food -= cost.food;
|
||||||
|
|
||||||
const newBuilding = createBuilding(building);
|
const newBuilding = createBuilding(buildingType);
|
||||||
newBuilding.tile = tile;
|
newBuilding.tile = tile;
|
||||||
|
|
||||||
V.buildings.push(newBuilding);
|
V.buildings.push(newBuilding);
|
||||||
|
5
src/stores/gameTab.ts
Normal file
5
src/stores/gameTab.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { writable } from "svelte/store";
|
||||||
|
import type { GameTab } from "../types";
|
||||||
|
|
||||||
|
|
||||||
|
export default writable<GameTab>('village');
|
@ -1,5 +1,9 @@
|
|||||||
import type { Hex } from "./hexgrid";
|
import type { Hex } from "./hexgrid";
|
||||||
|
|
||||||
|
|
||||||
|
export type GameTab = 'village' | 'resources';
|
||||||
|
|
||||||
|
|
||||||
export interface Cost {
|
export interface Cost {
|
||||||
wood: number;
|
wood: number;
|
||||||
stone: number;
|
stone: number;
|
||||||
@ -13,6 +17,8 @@ export type Production = Cost;
|
|||||||
|
|
||||||
export interface BuildingSource {
|
export interface BuildingSource {
|
||||||
name: string;
|
name: string;
|
||||||
|
type: string;
|
||||||
|
autoBuilt?: boolean;
|
||||||
cost: (level: number) => Cost;
|
cost: (level: number) => Cost;
|
||||||
behavior: {
|
behavior: {
|
||||||
production?: Function;
|
production?: Function;
|
||||||
|
@ -81,12 +81,12 @@ function getInitialState() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create the Town hall.
|
// Create the Town hall.
|
||||||
const townhall = createBuilding(buildings.townhall);
|
const townhall = createBuilding('townhall');
|
||||||
state.villageTiles[0][0] = townhall.id;
|
state.villageTiles[0][0] = townhall.id;
|
||||||
state.buildings.push(townhall);
|
state.buildings.push(townhall);
|
||||||
|
|
||||||
// Create all the resource buildings.
|
// Create all the resource buildings.
|
||||||
const resourceBuildingTypes: Array<keyof typeof buildings> = shuffle([
|
const resourceBuildingTypes: Array<string> = shuffle([
|
||||||
'woodcutter', 'woodcutter', 'woodcutter', 'woodcutter',
|
'woodcutter', 'woodcutter', 'woodcutter', 'woodcutter',
|
||||||
'mine', 'mine', 'mine', 'mine',
|
'mine', 'mine', 'mine', 'mine',
|
||||||
'pit', 'pit', 'pit', 'pit',
|
'pit', 'pit', 'pit', 'pit',
|
||||||
@ -102,7 +102,7 @@ function getInitialState() {
|
|||||||
if (type === undefined) {
|
if (type === undefined) {
|
||||||
throw new Error("Not enough building types for outside resource buildings");
|
throw new Error("Not enough building types for outside resource buildings");
|
||||||
}
|
}
|
||||||
const newBuilding = createBuilding(buildings[type]);
|
const newBuilding = createBuilding(type);
|
||||||
newBuilding.tile = new Hex(x, y);
|
newBuilding.tile = new Hex(x, y);
|
||||||
state.outsideTiles[y][x] = newBuilding.id;
|
state.outsideTiles[y][x] = newBuilding.id;
|
||||||
state.buildings.push(newBuilding);
|
state.buildings.push(newBuilding);
|
||||||
|
Loading…
Reference in New Issue
Block a user