From 1654f73f43d947d8c775d580026cf81587943eec Mon Sep 17 00:00:00 2001 From: Evan Date: Mon, 4 Nov 2024 19:45:31 -0800 Subject: [PATCH] require gold to buy items --- .../graphics/layers/radial/BuildMenu.ts | 52 +++++++++++++------ src/core/execution/AttackExecution.ts | 1 - src/core/execution/NukeExecution.ts | 9 +++- src/core/game/Game.ts | 8 +++ 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/client/graphics/layers/radial/BuildMenu.ts b/src/client/graphics/layers/radial/BuildMenu.ts index 7d06b6483..6d42f920b 100644 --- a/src/client/graphics/layers/radial/BuildMenu.ts +++ b/src/client/graphics/layers/radial/BuildMenu.ts @@ -1,22 +1,20 @@ import { LitElement, html, css } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { EventBus } from '../../../../core/EventBus'; -import { Cell, Game, Player } from '../../../../core/game/Game'; +import { Cell, Game, Item, Items, Player } from '../../../../core/game/Game'; import { SendNukeIntentEvent } from '../../../Transport'; import nukeIcon from '../../../../../resources/images/NukeIconWhite.svg'; import goldCoinIcon from '../../../../../resources/images/GoldCoinIcon.svg'; import { renderNumber } from '../../Utils'; interface BuildItem { - id: string; - name: string; + item: Item icon: string; - cost: number; } const buildTable: BuildItem[][] = [ [ - { id: 'nuke', name: 'Nuke', icon: nukeIcon, cost: 1_000_000 }, + { item: Items.Nuke, icon: nukeIcon }, // { id: 'battleship', name: 'Battleship', icon: '🚢', cost: 500, buildTime: 20 } ] ]; @@ -24,11 +22,10 @@ const buildTable: BuildItem[][] = [ @customElement('build-menu') export class BuildMenu extends LitElement { public game: Game; - public eventBus: EventBus + public eventBus: EventBus; - - private myPlayer: Player - private clickedCell: Cell + private myPlayer: Player; + private clickedCell: Cell; static styles = css` :host { @@ -72,15 +69,27 @@ export class BuildMenu extends LitElement { margin: 8px; padding: 10px; } - .build-button:hover { + .build-button:not(:disabled):hover { background-color: #3A3A3A; transform: scale(1.05); border-color: #666; } - .build-button:active { + .build-button:not(:disabled):active { background-color: #4A4A4A; transform: scale(0.95); } + .build-button:disabled { + background-color: #1A1A1A; + border-color: #333; + cursor: not-allowed; + opacity: 0.7; + } + .build-button:disabled img { + opacity: 0.5; + } + .build-button:disabled .build-cost { + color: #FF4444; + } .build-icon { font-size: 40px; margin-bottom: 5px; @@ -128,6 +137,10 @@ export class BuildMenu extends LitElement { @state() private _hidden = true; + private canAfford(item: BuildItem): boolean { + return this.myPlayer && this.myPlayer.gold() >= item.item.cost; + } + public onBuildSelected: (item: BuildItem) => void = () => { this.eventBus.emit(new SendNukeIntentEvent(this.myPlayer, this.clickedCell, null)) this.hideMenu() @@ -139,11 +152,16 @@ export class BuildMenu extends LitElement { ${buildTable.map(row => html`
${row.map(item => html` - @@ -160,8 +178,8 @@ export class BuildMenu extends LitElement { } showMenu(player: Player, clickedCell: Cell) { - this.myPlayer = player - this.clickedCell = clickedCell + this.myPlayer = player; + this.clickedCell = clickedCell; this._hidden = false; this.requestUpdate(); } diff --git a/src/core/execution/AttackExecution.ts b/src/core/execution/AttackExecution.ts index 7608b7732..a1f059f34 100644 --- a/src/core/execution/AttackExecution.ts +++ b/src/core/execution/AttackExecution.ts @@ -2,7 +2,6 @@ import { PriorityQueue } from "@datastructures-js/priority-queue"; import { Cell, Execution, MutableGame, MutablePlayer, Player, PlayerID, TerrainType, TerraNullius, Tile } from "../game/Game"; import { PseudoRandom } from "../PseudoRandom"; import { manhattanDist } from "../Util"; -import { Terrain } from "../game/TerrainMapLoader"; export class AttackExecution implements Execution { private breakAlliance = false diff --git a/src/core/execution/NukeExecution.ts b/src/core/execution/NukeExecution.ts index d135a4a33..7b004159a 100644 --- a/src/core/execution/NukeExecution.ts +++ b/src/core/execution/NukeExecution.ts @@ -1,4 +1,4 @@ -import { Cell, Execution, MutableGame, MutablePlayer, PlayerID, Tile } from "../game/Game"; +import { Cell, Execution, Items, MutableGame, MutablePlayer, PlayerID, Tile } from "../game/Game"; import { PseudoRandom } from "../PseudoRandom"; import { bfs, dist, euclideanDist, manhattanDist } from "../Util"; @@ -26,6 +26,13 @@ export class NukeExecution implements Execution { } tick(ticks: number): void { + if (this.sender.gold() < Items.Nuke.cost) { + console.warn(`player ${this.sender} insufficient gold for nuke`) + this.active = false + return + } + this.sender.removeGold(Items.Nuke.cost) + const rand = new PseudoRandom(this.mg.ticks()) const tile = this.mg.tile(this.cell) const toDestroy = bfs(tile, (n: Tile) => { diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index 47b7759e1..ddfae6680 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -25,6 +25,14 @@ export enum GameMap { Mena } +export class Item { + constructor(public readonly name: string, public readonly cost: Gold) { } +} + +export const Items = { + Nuke: new Item("Nuke", 1_000_000), +} as const; + export class Nation { constructor( public readonly name: string,