Add a building panel to upgrade them.

This commit is contained in:
Adrian 2024-10-24 15:12:21 +02:00
parent 5a7fb8ddcb
commit 25f281028c
7 changed files with 118 additions and 58 deletions

View File

@ -0,0 +1,7 @@
<script lang="ts">
import type { Building } from "../types";
export let building: Building;
</script>
<p>{ building.name }</p>

View File

@ -1,5 +1,4 @@
<script lang="ts">
export let empty = false;
export let onTileClick: () => void;
</script>
@ -7,10 +6,7 @@
class="invisible"
on:click={ onTileClick }
>
<div
class={ "hexagon" }
class:empty
>
<div class="hexagon">
<div class="content">
<slot></slot>
</div>
@ -18,70 +14,33 @@
</button>
<style>
/* Source: https://codepen.io/gpyne/pen/iElhp */
.hexagon {
aspect-ratio: 1;
background-color: hsl(220, 75%, 75%);
border-radius: 100%;
cursor: pointer;
display: inline-block;
font-size: 1.2vmin;
margin: -0.8em 2.7em;
position: relative;
height: 12em;
margin: -0.8em 0.2em;
text-align: center;
rotate: 90deg;
}
.hexagon,
.hexagon::before,
.hexagon::after {
width: 6.7em;
height: 11.6em;
border-radius: 20%/5%;
}
.hexagon::before {
background-color: inherit;
content: "";
position: absolute;
left: 0;
transform: rotate(-60deg);
}
.hexagon::after {
background-color: inherit;
content: "";
position: absolute;
left: 0;
transform: rotate(60deg);
}
.hexagon:nth-child(even) {
top: 5.9em;
position: relative;
}
.hexagon:hover {
background-color: hsl(60, 75%, 75%);
z-index: 105;
}
.hexagon:active {
background-color: hsl(60, 75%, 50%);
z-index: 110;
}
.hexagon.empty {
position: relative;
display: none;
width: 6.7em;
height: 11.6em;
margin: 0.1em 1.8em;
}
.hexagon.empty:nth-child(even) {
top: 5.9em;
}
.hexagon .content {
position: absolute;
display: grid;
top: 5%;
left: -40%;
font-size: 4vmin;
height: 90%;
height: 100%;
line-height: 1.2;
width: 180%;
z-index: 100;
width: 100%;
}
.hexagon .content > * {
margin: auto;
}

View File

@ -2,8 +2,10 @@
import { Hex } from "../hexgrid";
import moves from "../moves";
import showBuildingCreator from "../stores/showBuildingCreator";
import { getKeysAsNumbers } from "../utils";
import showBuildingPanel from "../stores/showBuildingPanel";
import { getBuilding, getKeysAsNumbers } from "../utils";
import village from "../village";
import BuildingTile from "./BuildingTile.svelte";
import Tile from "./Tile.svelte";
@ -11,10 +13,13 @@
moves.upgradeBuilding(id);
}
function openBuildingCreator(tile: Hex) {
showBuildingCreator.set(tile);
}
function openBuildingPanel(buildingId: number) {
showBuildingPanel.set(buildingId);
}
</script>
<section class="village-map">
@ -24,9 +29,9 @@
{ #each getKeysAsNumbers($village.villageTiles[y]) as x }
{ #if $village.villageTiles[y][x] >= 0 }
<Tile
onTileClick={ () => {} }
onTileClick={ () => openBuildingPanel($village.villageTiles[y][x]) }
>
<p>{ $village.buildings.find(b => b.id === $village.villageTiles[y][x])?.name }</p>
<BuildingTile building={ getBuilding($village, $village.villageTiles[y][x]) } />
</Tile>
{ :else }
<Tile

View File

@ -0,0 +1,74 @@
<script lang="ts">
import buildings from "../buildings";
import moves from "../moves";
import showBuildingPanel from "../stores/showBuildingPanel";
import { getBuilding } from "../utils";
import village from "../village";
function close() {
showBuildingPanel.set(null);
}
function upgrade() {
if ($showBuildingPanel === null) {
return;
}
if (moves.upgradeBuilding($showBuildingPanel)) {
close();
}
}
$: building = ($showBuildingPanel !== null) ? getBuilding($village, $showBuildingPanel) : null;
</script>
{ #if building !== null }
<section>
<div class="building-panel">
<header>
<h1>Building</h1>
<span class="close">
<button on:click={ close }>X</button>
</span>
</header>
<div class="building">
<div>
<p>{ building.name } ({ building.level })</p>
<button on:click={ () => upgrade() }>Upgrade</button>
</div>
</div>
</div>
</section>
{ /if }
<style>
section {
background-color: hsl(0, 0%, 10%, 0.8);
display: grid;
place-items: center;
height: 100vh;
left: 0;
position: absolute;
top: 0;
width: 100vw;
}
.building-panel {
background-color: hsl(0, 0%, 20%);
border: 0.2em solid grey;
border-radius: .4em;
width: 80%;
height: 60%;
}
.building-panel header {
position: relative;
}
.building-panel header .close {
position: absolute;
right: 1em;
top: 0;
}
</style>

View File

@ -5,6 +5,7 @@
import update from "../update";
import BuildingCreator from "./BuildingCreator.svelte";
import Resources from "./Resources.svelte";
import BuildingPanel from "./BuildingPanel.svelte";
onMount(() => {
@ -32,6 +33,7 @@
</section>
<section class="overlay">
<BuildingCreator />
<BuildingPanel />
</section>
<style>

View File

@ -0,0 +1,4 @@
import { writable } from "svelte/store";
export default writable<number | null>(null);

View File

@ -1,4 +1,4 @@
import type { Production } from "./types";
import type { Building, Production } from "./types";
import type { VillageState } from "./village";
@ -46,6 +46,15 @@ export function getStorage(villageState: VillageState): Production {
}
export function getBuilding(V: VillageState, buildingId: number): Building {
const building = V.buildings.find(b => b.id === buildingId);
if (!building) {
throw new Error(`Cannot find building with id "${buildingId}"`);
}
return building;
}
export function getKeysAsNumbers(dict: Object): Array<number> {
return Object.keys(dict).map(i => parseInt(i)).sort((a, b) => a - b);
}