diff --git a/src/client/graphics/layers/ControlPanel.ts b/src/client/graphics/layers/ControlPanel.ts index a811c7579..9d769f9b5 100644 --- a/src/client/graphics/layers/ControlPanel.ts +++ b/src/client/graphics/layers/ControlPanel.ts @@ -1,168 +1,197 @@ -import { LitElement, html } from 'lit'; -import { customElement, property, state } from 'lit/decorators.js'; -import { Layer } from './Layer'; -import { Game } from '../../../core/game/Game'; -import { ClientID } from '../../../core/Schemas'; -import { renderNumber, renderTroops } from '../../Utils'; -import { EventBus } from '../../../core/EventBus'; -import { UIState } from '../UIState'; -import { SendSetTargetTroopRatioEvent } from '../../Transport'; -import { GameView } from '../../../core/game/GameView'; +import { LitElement, html } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { Layer } from "./Layer"; +import { Game } from "../../../core/game/Game"; +import { ClientID } from "../../../core/Schemas"; +import { renderNumber, renderTroops } from "../../Utils"; +import { EventBus } from "../../../core/EventBus"; +import { UIState } from "../UIState"; +import { SendSetTargetTroopRatioEvent } from "../../Transport"; +import { GameView } from "../../../core/game/GameView"; -@customElement('control-panel') +@customElement("control-panel") export class ControlPanel extends LitElement implements Layer { - public game: GameView; - public clientID: ClientID; - public eventBus: EventBus; - public uiState: UIState; + public game: GameView; + public clientID: ClientID; + public eventBus: EventBus; + public uiState: UIState; - @state() - private attackRatio: number = .2; + @state() + private attackRatio: number = 0.2; - @state() - private targetTroopRatio = 1; + @state() + private targetTroopRatio = 1; - @state() - private currentTroopRatio = 1; + @state() + private currentTroopRatio = 1; - @state() - private _population: number; + @state() + private _population: number; - @state() - private _maxPopulation: number; + @state() + private _maxPopulation: number; - @state() - private popRate: number; + @state() + private popRate: number; - @state() - private _troops: number; + @state() + private _troops: number; - @state() - private _workers: number; + @state() + private _workers: number; - @state() - private _isVisible = false; + @state() + private _isVisible = false; - @state() - private _manpower: number = 0; + @state() + private _manpower: number = 0; - @state() - private _gold: number; + @state() + private _gold: number; - @state() - private _goldPerSecond: number; + @state() + private _goldPerSecond: number; - init() { - this.attackRatio = .20; - this.uiState.attackRatio = this.attackRatio; - this.currentTroopRatio = this.targetTroopRatio; + init() { + this.attackRatio = 0.2; + this.uiState.attackRatio = this.attackRatio; + this.currentTroopRatio = this.targetTroopRatio; + } + + tick() { + if (!this._isVisible && !this.game.inSpawnPhase()) { + this.setVisibile(true); } - tick() { - if (!this._isVisible && !this.game.inSpawnPhase()) { - this.setVisibile(true); - } - - const player = this.game.playerByClientID(this.clientID); - if (player == null || !player.isAlive()) { - this.setVisibile(false); - return; - } - - this._population = player.population(); - this._maxPopulation = this.game.config().maxPopulation(player); - this._gold = player.gold(); - this._troops = player.troops(); - this._workers = player.workers(); - this.popRate = this.game.config().populationIncreaseRate(player) * 10; - this._goldPerSecond = this.game.config().goldAdditionRate(player) * 10; - - this.currentTroopRatio = player.troops() / player.population(); + const player = this.game.playerByClientID(this.clientID); + if (player == null || !player.isAlive()) { + this.setVisibile(false); + return; } - onAttackRatioChange(newRatio: number) { - this.uiState.attackRatio = newRatio; - } + this._population = player.population(); + this._maxPopulation = this.game.config().maxPopulation(player); + this._gold = player.gold(); + this._troops = player.troops(); + this._workers = player.workers(); + this.popRate = this.game.config().populationIncreaseRate(player) * 10; + this._goldPerSecond = this.game.config().goldAdditionRate(player) * 10; - renderLayer(context: CanvasRenderingContext2D) { - // Render any necessary canvas elements - } + this.currentTroopRatio = player.troops() / player.population(); + } - shouldTransform(): boolean { - return false; - } + onAttackRatioChange(newRatio: number) { + this.uiState.attackRatio = newRatio; + } - setVisibile(visible: boolean) { - this._isVisible = visible; - this.requestUpdate(); - } + renderLayer(context: CanvasRenderingContext2D) { + // Render any necessary canvas elements + } - targetTroops(): number { - return this._manpower * this.targetTroopRatio; - } + shouldTransform(): boolean { + return false; + } - onTroopChange(newRatio: number) { - this.eventBus.emit(new SendSetTargetTroopRatioEvent(newRatio)); - } + setVisibile(visible: boolean) { + this._isVisible = visible; + this.requestUpdate(); + } - delta(): number { - const d = this._population - this.targetTroops(); - return d; - } + targetTroops(): number { + return this._manpower * this.targetTroopRatio; + } - render() { - return html` -
-
-
- Pop: - ${renderTroops(this._population)} / ${renderTroops(this._maxPopulation)} (+${renderTroops(this.popRate)}) -
-
- Gold: - ${renderNumber(this._gold)} (+${renderNumber(this._goldPerSecond)}) -
-
- -
- -
-
-
- { - this.targetTroopRatio = parseInt((e.target as HTMLInputElement).value) / 100; - this.onTroopChange(this.targetTroopRatio); + onTroopChange(newRatio: number) { + this.eventBus.emit(new SendSetTargetTroopRatioEvent(newRatio)); + } + + delta(): number { + const d = this._population - this.targetTroops(); + return d; + } + + render() { + return html` +
+ + +
+ +
+
+ { + this.targetTroopRatio = + parseInt((e.target as HTMLInputElement).value) / 100; + this.onTroopChange(this.targetTroopRatio); }} - class="absolute w-full top-3 m-0 opacity-0 cursor-pointer" - > -
- -
- -
-
-
- { - this.attackRatio = parseInt((e.target as HTMLInputElement).value) / 100; - this.onAttackRatioChange(this.attackRatio); + class="absolute w-full top-3 m-0 opacity-0 cursor-pointer" + /> +
+ +
+ +
+
+
+ { + this.attackRatio = + parseInt((e.target as HTMLInputElement).value) / 100; + this.onAttackRatioChange(this.attackRatio); }} - class="absolute w-full top-3 m-0 opacity-0 cursor-pointer" - > -
-
- `; - } - createRenderRoot() { - return this; // Disable shadow DOM to allow Tailwind styles - } -} \ No newline at end of file + class="absolute w-full top-3 m-0 opacity-0 cursor-pointer" + /> +
+
+ `; + } + createRenderRoot() { + return this; // Disable shadow DOM to allow Tailwind styles + } +} diff --git a/src/client/graphics/layers/OptionsMenu.ts b/src/client/graphics/layers/OptionsMenu.ts index 9e1050356..e3b400d4d 100644 --- a/src/client/graphics/layers/OptionsMenu.ts +++ b/src/client/graphics/layers/OptionsMenu.ts @@ -1,101 +1,111 @@ -import { LitElement, html } from 'lit'; -import { customElement, property, state } from 'lit/decorators.js'; -import { EventBus } from '../../../core/EventBus'; -import { PauseGameEvent } from '../../Transport'; -import { GameType } from '../../../core/game/Game'; -import { GameView } from '../../../core/game/GameView'; -import { Layer } from './Layer'; -import { GameUpdateType } from '../../../core/game/GameUpdates'; +import { LitElement, html } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { EventBus } from "../../../core/EventBus"; +import { PauseGameEvent } from "../../Transport"; +import { GameType } from "../../../core/game/Game"; +import { GameView } from "../../../core/game/GameView"; +import { Layer } from "./Layer"; +import { GameUpdateType } from "../../../core/game/GameUpdates"; -@customElement('options-menu') +@customElement("options-menu") export class OptionsMenu extends LitElement implements Layer { - public game: GameView; - public eventBus: EventBus; + public game: GameView; + public eventBus: EventBus; - @state() - private showPauseButton: boolean = true; + @state() + private showPauseButton: boolean = true; - @state() - private isPaused: boolean = false; + @state() + private isPaused: boolean = false; - @state() - private timer: number = 0; + @state() + private timer: number = 0; - private isVisible = false; + private isVisible = false; - private hasWinner = false; + private hasWinner = false; - private onExitButtonClick() { - window.location.reload(); + private onExitButtonClick() { + window.location.reload(); + } + + createRenderRoot() { + return this; + } + + private onPauseButtonClick() { + this.isPaused = !this.isPaused; + this.eventBus.emit(new PauseGameEvent(this.isPaused)); + } + + init() { + console.log("init called from OptionsMenu"); + this.showPauseButton = + this.game.config().gameConfig().gameType == GameType.Singleplayer; + this.isVisible = true; + this.requestUpdate(); + } + + tick() { + this.hasWinner = + this.hasWinner || + this.game.updatesSinceLastTick()[GameUpdateType.WinUpdate].length > 0; + if (this.game.inSpawnPhase()) { + this.timer = 0; + } else if (!this.hasWinner && this.game.ticks() % 10 == 0) { + this.timer++; } + this.isVisible = true; + this.requestUpdate(); + } - createRenderRoot() { - return this; + render() { + if (!this.isVisible) { + return html``; } - - private onPauseButtonClick() { - this.isPaused = !this.isPaused; - this.eventBus.emit(new PauseGameEvent(this.isPaused)); - } - - init() { - console.log('init called from OptionsMenu'); - this.showPauseButton = this.game.config().gameConfig().gameType == GameType.Singleplayer; - this.isVisible = true; - this.requestUpdate(); - } - - tick() { - this.hasWinner = this.hasWinner || this.game.updatesSinceLastTick()[GameUpdateType.WinUpdate].length > 0; - if (this.game.inSpawnPhase()) { - this.timer = 0; - } else if (!this.hasWinner && this.game.ticks() % 10 == 0) { - this.timer++; - } - this.isVisible = true; - this.requestUpdate(); - } - - render() { - if (!this.isVisible) { - return html``; - } - return html` -
-
-
- -
+ ${this.isPaused ? "▶" : "⏸"} + +
- ${this.timer} -
-
+ -
-
+ text-sm lg:text-xl" + @click=${this.onExitButtonClick} + aria-label="Exit game" + > + × + +
+ `; - } - -} \ No newline at end of file + } +} diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts index aa4403df4..ff4e9f11c 100644 --- a/src/core/configuration/DevConfig.ts +++ b/src/core/configuration/DevConfig.ts @@ -4,49 +4,47 @@ import { ServerConfig } from "./Config"; import { DefaultConfig, DefaultServerConfig } from "./DefaultConfig"; export class DevServerConfig extends DefaultServerConfig { - gameCreationRate(): number { - return 10 * 1000 - } - lobbyLifetime(): number { - return 10 * 1000 - } + gameCreationRate(): number { + return 10 * 1000; + } + lobbyLifetime(): number { + return 10 * 1000; + } } export class DevConfig extends DefaultConfig { + constructor(sc: ServerConfig, gc: GameConfig) { + super(sc, gc); + } - constructor(sc: ServerConfig, gc: GameConfig) { - super(sc, gc); - } + numSpawnPhaseTurns(): number { + return this.gameConfig().gameType == GameType.Singleplayer ? 20 : 100; + // return 100 + } - numSpawnPhaseTurns(): number { - return this.gameConfig().gameType == GameType.Singleplayer ? 40 : 100 - // return 100 - } + unitInfo(type: UnitType): UnitInfo { + const info = super.unitInfo(type); + const oldCost = info.cost; + info.cost = (p: Player) => oldCost(p) / 1000000000; + return info; + } - unitInfo(type: UnitType): UnitInfo { - const info = super.unitInfo(type) - const oldCost = info.cost - info.cost = (p: Player) => oldCost(p) / 1000000000 - return info - } + // percentageTilesOwnedToWin(): number { + // return 1 + // } - // percentageTilesOwnedToWin(): number { - // return 1 - // } + // populationIncreaseRate(player: Player): number { + // return this.maxPopulation(player) + // } - // populationIncreaseRate(player: Player): number { - // return this.maxPopulation(player) - // } - - // boatMaxDistance(): number { - // return 5000 - // } - - // numBots(): number { - // return 0 - // } - // spawnNPCs(): boolean { - // return false - // } + // boatMaxDistance(): number { + // return 5000 + // } + // numBots(): number { + // return 0 + // } + // spawnNPCs(): boolean { + // return false + // } }