From 2d2df14ae3a146442f11ab8e89e3cebf69393ac7 Mon Sep 17 00:00:00 2001 From: Evan Date: Sat, 7 Dec 2024 09:45:39 -0800 Subject: [PATCH] add GameConfig to Game --- src/client/GameRunner.ts | 50 ++++++++++++------------- src/client/HostLobbyModal.ts | 4 +- src/client/JoinPrivateLobbyModal.ts | 12 +++--- src/client/Main.ts | 2 +- src/client/PublicLobby.ts | 4 +- src/client/SinglePlayerModal.ts | 4 +- src/client/graphics/layers/UILayer.ts | 22 +++++------ src/core/configuration/Config.ts | 4 +- src/core/configuration/DefaultConfig.ts | 6 +-- src/core/configuration/DevConfig.ts | 10 ++--- src/core/execution/AttackExecution.ts | 3 -- src/core/execution/BotExecution.ts | 5 --- src/core/execution/ExecutionManager.ts | 4 +- src/core/execution/PlayerExecution.ts | 4 -- src/core/game/Game.ts | 3 +- src/core/game/GameImpl.ts | 19 +++++++--- 16 files changed, 77 insertions(+), 79 deletions(-) diff --git a/src/client/GameRunner.ts b/src/client/GameRunner.ts index b2d79ffd0..4f3b18c9a 100644 --- a/src/client/GameRunner.ts +++ b/src/client/GameRunner.ts @@ -1,11 +1,11 @@ import { Executor } from "../core/execution/ExecutionManager"; -import { Cell, MutableGame, PlayerEvent, PlayerID, MutablePlayer, TileEvent, Player, Game, UnitEvent, Tile, PlayerType, GameMap, Difficulty } from "../core/game/Game"; +import { Cell, MutableGame, PlayerEvent, PlayerID, MutablePlayer, TileEvent, Player, Game, UnitEvent, Tile, PlayerType, GameMap, Difficulty, GameType } from "../core/game/Game"; import { createGame } from "../core/game/GameImpl"; import { EventBus } from "../core/EventBus"; import { Config, getConfig } from "../core/configuration/Config"; import { createRenderer, GameRenderer } from "./graphics/GameRenderer"; import { InputHandler, MouseUpEvent, ZoomEvent, DragEvent, MouseDownEvent } from "./InputHandler" -import { ClientID, ClientIntentMessageSchema, ClientJoinMessageSchema, ClientMessageSchema, GameID, Intent, ServerMessage, ServerMessageSchema, ServerSyncMessage, Turn } from "../core/Schemas"; +import { ClientID, ClientIntentMessageSchema, ClientJoinMessageSchema, ClientMessageSchema, GameConfig, GameID, Intent, ServerMessage, ServerMessageSchema, ServerSyncMessage, Turn } from "../core/Schemas"; import { loadTerrainMap, TerrainMapImpl } from "../core/game/TerrainMapLoader"; import { and, bfs, dist, manhattanDist } from "../core/Util"; import { WinCheckExecution } from "../core/execution/WinCheckExecution"; @@ -17,7 +17,7 @@ import { WorkerClient } from "../core/worker/WorkerClient"; export interface LobbyConfig { - isLocal: boolean + gameType: GameType playerName: () => string gameID: GameID ip: string | null @@ -25,19 +25,21 @@ export interface LobbyConfig { difficulty: Difficulty | null } -export interface GameConfig { - map: GameMap - difficulty: Difficulty - clientID: ClientID, - gameID: GameID, -} - export function joinLobby(lobbyConfig: LobbyConfig, onjoin: () => void): () => void { const clientID = uuidv4() const playerID = uuidv4() const eventBus = new EventBus() const config = getConfig() - const transport = new Transport(lobbyConfig.isLocal, eventBus, lobbyConfig.gameID, lobbyConfig.ip, clientID, playerID, config, lobbyConfig.playerName) + const transport = new Transport( + lobbyConfig.gameType == GameType.Singleplayer, + eventBus, + lobbyConfig.gameID, + lobbyConfig.ip, + clientID, + playerID, + config, + lobbyConfig.playerName + ) const onconnect = () => { console.log(`Joined game lobby ${lobbyConfig.gameID}`); @@ -48,13 +50,11 @@ export function joinLobby(lobbyConfig: LobbyConfig, onjoin: () => void): () => v console.log('lobby: game started') onjoin() const gameConfig = { - map: message.config?.gameMap || lobbyConfig.map, + gameMap: message.config?.gameMap || lobbyConfig.map, difficulty: message.config?.difficulty || lobbyConfig.difficulty, - clientID: clientID, - gameID: lobbyConfig.gameID, - ip: lobbyConfig.ip, + gameType: lobbyConfig.gameType } - createClientGame(gameConfig, eventBus, transport).then(r => r.start()) + createClientGame(gameConfig, eventBus, transport, lobbyConfig.gameID, clientID).then(r => r.start()) }; } transport.connect(onconnect, onmessage) @@ -65,30 +65,30 @@ export function joinLobby(lobbyConfig: LobbyConfig, onjoin: () => void): () => v } -export async function createClientGame(gameConfig: GameConfig, eventBus: EventBus, transport: Transport): Promise { +export async function createClientGame(gameConfig: GameConfig, eventBus: EventBus, transport: Transport, gameID: GameID, clientID: ClientID): Promise { const config = getConfig() - const terrainMap = await loadTerrainMap(gameConfig.map) + const terrainMap = await loadTerrainMap(gameConfig.gameMap) - let game = createGame(terrainMap, eventBus, config) + let game = createGame(terrainMap, eventBus, config, gameConfig) - const worker = new WorkerClient(game, gameConfig.map) + const worker = new WorkerClient(game, gameConfig.gameMap) console.log('going to init path finder') await worker.initialize() console.log('inited path finder') const canvas = createCanvas() - let gameRenderer = createRenderer(canvas, game, eventBus, gameConfig.clientID) + let gameRenderer = createRenderer(canvas, game, eventBus, clientID) console.log(`creating private game got difficulty: ${gameConfig.difficulty}`) return new GameRunner( - gameConfig, + clientID, eventBus, game, gameRenderer, new InputHandler(canvas, eventBus), - new Executor(game, gameConfig.difficulty, gameConfig.gameID, worker), + new Executor(game, gameID, worker), transport, ) } @@ -106,7 +106,7 @@ export class GameRunner { private hasJoined = false constructor( - private gameConfig: GameConfig, + private clientID: ClientID, private eventBus: EventBus, private gs: Game, private renderer: GameRenderer, @@ -187,7 +187,7 @@ export class GameRunner { private playerEvent(event: PlayerEvent) { console.log('received new player event!') - if (event.player.clientID() == this.gameConfig.clientID) { + if (event.player.clientID() == this.clientID) { console.log('setting name') this.myPlayer = event.player } diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts index b2c09afd9..ee52675a5 100644 --- a/src/client/HostLobbyModal.ts +++ b/src/client/HostLobbyModal.ts @@ -1,6 +1,6 @@ import { LitElement, html, css } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { Difficulty, GameMap } from '../core/game/Game'; +import { Difficulty, GameMap, GameType } from '../core/game/Game'; import { Lobby } from '../core/Schemas'; @customElement('host-lobby-modal') @@ -146,7 +146,7 @@ export class HostLobbyModal extends LitElement { }).then(() => { this.dispatchEvent(new CustomEvent('join-lobby', { detail: { - singlePlayer: false, + gameType: GameType.Private, lobby: { id: this.lobbyId, }, diff --git a/src/client/JoinPrivateLobbyModal.ts b/src/client/JoinPrivateLobbyModal.ts index 81004fed0..1ffb21336 100644 --- a/src/client/JoinPrivateLobbyModal.ts +++ b/src/client/JoinPrivateLobbyModal.ts @@ -1,6 +1,6 @@ -import {LitElement, html, css} from 'lit'; -import {customElement, property, state, query} from 'lit/decorators.js'; -import {GameMap} from '../core/game/Game'; +import { LitElement, html, css } from 'lit'; +import { customElement, property, state, query } from 'lit/decorators.js'; +import { GameMap, GameType } from '../core/game/Game'; @customElement('join-private-lobby-modal') export class JoinPrivateLobbyModal extends LitElement { @@ -138,7 +138,7 @@ export class JoinPrivateLobbyModal extends LitElement { this.hasJoined = false this.message = "" this.dispatchEvent(new CustomEvent('leave-lobby', { - detail: {lobby: this.lobbyIdInput.value}, + detail: { lobby: this.lobbyIdInput.value }, bubbles: true, composed: true })); @@ -171,8 +171,8 @@ export class JoinPrivateLobbyModal extends LitElement { this.hasJoined = true this.dispatchEvent(new CustomEvent('join-lobby', { detail: { - lobby: {id: lobbyId}, - singlePlayer: false, + lobby: { id: lobbyId }, + gameType: GameType.Private, map: GameMap.World, }, bubbles: true, diff --git a/src/client/Main.ts b/src/client/Main.ts index 064154065..010303384 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -74,7 +74,7 @@ class Client { } this.gameStop = joinLobby( { - isLocal: event.detail.singlePlayer, + gameType: event.detail.gameType, playerName: (): string => this.usernameInput.getCurrentUsername(), gameID: lobby.id, ip: clientIP, diff --git a/src/client/PublicLobby.ts b/src/client/PublicLobby.ts index 06d360d06..77eac8ad0 100644 --- a/src/client/PublicLobby.ts +++ b/src/client/PublicLobby.ts @@ -1,7 +1,7 @@ import { LitElement, html, css } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { Lobby } from "../core/Schemas"; -import { Difficulty, GameMap } from '../core/game/Game'; +import { Difficulty, GameMap, GameType } from '../core/game/Game'; @customElement('public-lobby') export class PublicLobby extends LitElement { @@ -111,7 +111,7 @@ export class PublicLobby extends LitElement { this.dispatchEvent(new CustomEvent('join-lobby', { detail: { lobby: lobby, - singlePlayer: false, + gameType: GameType.Public, map: GameMap.World, difficulty: Difficulty.Medium, }, diff --git a/src/client/SinglePlayerModal.ts b/src/client/SinglePlayerModal.ts index fc1ff9326..c67ca2e64 100644 --- a/src/client/SinglePlayerModal.ts +++ b/src/client/SinglePlayerModal.ts @@ -1,6 +1,6 @@ import { LitElement, html, css } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { Difficulty, GameMap } from '../core/game/Game'; +import { Difficulty, GameMap, GameType } from '../core/game/Game'; @customElement('single-player-modal') export class SinglePlayerModal extends LitElement { @@ -125,7 +125,7 @@ export class SinglePlayerModal extends LitElement { console.log(`Starting single player game with map: ${GameMap[this.selectedMap]}`); this.dispatchEvent(new CustomEvent('join-lobby', { detail: { - singlePlayer: true, + gameType: GameType.Singleplayer, lobby: { id: "LOCAL", }, diff --git a/src/client/graphics/layers/UILayer.ts b/src/client/graphics/layers/UILayer.ts index d6efb4fe7..1dd791a42 100644 --- a/src/client/graphics/layers/UILayer.ts +++ b/src/client/graphics/layers/UILayer.ts @@ -1,13 +1,13 @@ -import {GameEnv, Theme} from "../../../core/configuration/Config"; -import {EventBus} from "../../../core/EventBus"; -import {WinEvent} from "../../../core/execution/WinCheckExecution"; -import {AllianceRequest, AllianceRequestReplyEvent, Game, Player} from "../../../core/game/Game"; -import {ClientID} from "../../../core/Schemas"; -import {ContextMenuEvent} from "../../InputHandler"; -import {Layer} from "./Layer"; -import {TransformHandler} from "../TransformHandler"; -import {MessageType} from "./EventsDisplay"; -import {SendBreakAllianceIntentEvent} from "../../Transport"; +import { GameEnv, Theme } from "../../../core/configuration/Config"; +import { EventBus } from "../../../core/EventBus"; +import { WinEvent } from "../../../core/execution/WinCheckExecution"; +import { AllianceRequest, AllianceRequestReplyEvent, Game, Player } from "../../../core/game/Game"; +import { ClientID } from "../../../core/Schemas"; +import { ContextMenuEvent } from "../../InputHandler"; +import { Layer } from "./Layer"; +import { TransformHandler } from "../TransformHandler"; +import { MessageType } from "./EventsDisplay"; +import { SendBreakAllianceIntentEvent } from "../../Transport"; interface MenuOption { label: string; @@ -38,7 +38,7 @@ export class UILayer implements Layer { const barHeight = 15; const barBackgroundWidth = this.transformHandler.width(); - const ratio = this.game.ticks() / this.game.config().numSpawnPhaseTurns() + const ratio = this.game.ticks() / this.game.config().numSpawnPhaseTurns(this.game.gameConfig().gameType) // Draw bar background context.fillStyle = 'rgba(0, 0, 0, 0.5)'; diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts index a5fd68024..efae9d73c 100644 --- a/src/core/configuration/Config.ts +++ b/src/core/configuration/Config.ts @@ -1,4 +1,4 @@ -import { Gold, Player, PlayerID, PlayerInfo, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game"; +import { GameType, Gold, Player, PlayerID, PlayerInfo, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game"; import { Colord, colord } from "colord"; import { devConfig } from "./DevConfig"; import { defaultConfig } from "./DefaultConfig"; @@ -32,7 +32,7 @@ export interface Config { lobbyLifetime(): number numBots(): number spawnNPCs(): boolean - numSpawnPhaseTurns(): number + numSpawnPhaseTurns(gameType: GameType): number startManpower(playerInfo: PlayerInfo): number populationIncreaseRate(player: Player): number diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 7b19ef888..280491637 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -1,4 +1,4 @@ -import { Gold, Player, PlayerInfo, PlayerType, TerrainType, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game"; +import { GameType, Gold, Player, PlayerInfo, PlayerType, TerrainType, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game"; import { GameID } from "../Schemas"; import { assertNever, distSort, manhattanDist, simpleHash, within } from "../Util"; import { Config, Theme } from "./Config"; @@ -140,8 +140,8 @@ export class DefaultConfig implements Config { boatMaxDistance(): number { return 500 } - numSpawnPhaseTurns(): number { - return 100 + numSpawnPhaseTurns(gameType: GameType): number { + return gameType == GameType.Singleplayer ? 100 : 200 } numBots(): number { return 400 diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts index c5f4be13a..107b4ba5a 100644 --- a/src/core/configuration/DevConfig.ts +++ b/src/core/configuration/DevConfig.ts @@ -1,4 +1,4 @@ -import { Player, PlayerInfo, UnitInfo, UnitType } from "../game/Game"; +import { GameType, Player, PlayerInfo, UnitInfo, UnitType } from "../game/Game"; import { DefaultConfig } from "./DefaultConfig"; export const devConfig = new class extends DefaultConfig { @@ -15,10 +15,10 @@ export const devConfig = new class extends DefaultConfig { percentageTilesOwnedToWin(): number { return 95 } - numSpawnPhaseTurns(): number { - return 40 - // return 100 - } + // numSpawnPhaseTurns(gameType: GameType): number { + // return 40 + // // return 100 + // } gameCreationRate(): number { return 10 * 1000 } diff --git a/src/core/execution/AttackExecution.ts b/src/core/execution/AttackExecution.ts index a1f059f34..99ee62188 100644 --- a/src/core/execution/AttackExecution.ts +++ b/src/core/execution/AttackExecution.ts @@ -112,9 +112,6 @@ export class AttackExecution implements Execution { if (!this.active) { return } - if (ticks < this.mg.config().numSpawnPhaseTurns()) { - return - } const alliance = this._owner.allianceWith(this.target as Player) if (this.breakAlliance && alliance != null) { this.breakAlliance = false diff --git a/src/core/execution/BotExecution.ts b/src/core/execution/BotExecution.ts index 508022dc2..7ffc3f297 100644 --- a/src/core/execution/BotExecution.ts +++ b/src/core/execution/BotExecution.ts @@ -26,11 +26,6 @@ export class BotExecution implements Execution { } tick(ticks: number) { - - if (ticks < this.mg.config().numSpawnPhaseTurns()) { - return - } - if (!this.bot.isAlive()) { this.active = false return diff --git a/src/core/execution/ExecutionManager.ts b/src/core/execution/ExecutionManager.ts index 20c3a16b9..059537b9f 100644 --- a/src/core/execution/ExecutionManager.ts +++ b/src/core/execution/ExecutionManager.ts @@ -34,7 +34,7 @@ export class Executor { // private random = new PseudoRandom(999) private random: PseudoRandom = null - constructor(private gs: Game, private difficulty: Difficulty, private gameID: GameID, private workerClient: WorkerClient) { + constructor(private gs: Game, private gameID: GameID, private workerClient: WorkerClient) { // Add one to avoid id collisions with bots. this.random = new PseudoRandom(simpleHash(gameID) + 1) } @@ -127,7 +127,7 @@ export class Executor { this.random.nextID() ), nation.cell, - nation.strength * this.difficulty + nation.strength * this.gs.gameConfig().difficulty )) } return execs diff --git a/src/core/execution/PlayerExecution.ts b/src/core/execution/PlayerExecution.ts index db7a5535d..29118918b 100644 --- a/src/core/execution/PlayerExecution.ts +++ b/src/core/execution/PlayerExecution.ts @@ -28,10 +28,6 @@ export class PlayerExecution implements Execution { } tick(ticks: number) { - if (ticks < this.config.numSpawnPhaseTurns()) { - return - } - this.player.units().forEach(u => { const tileOwner = u.tile().owner() if (u.info().territoryBound) { diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index f7e65d9a6..8882d8766 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -1,6 +1,6 @@ import { Config } from "../configuration/Config" import { GameEvent } from "../EventBus" -import { ClientID, GameID } from "../Schemas" +import { ClientID, GameConfig, GameID } from "../Schemas" import { MessageType } from "../../client/graphics/layers/EventsDisplay" import { SearchNode } from "../pathfinding/AStar" @@ -306,6 +306,7 @@ export interface Game { addExecution(...exec: Execution[]): void nations(): Nation[] config(): Config + gameConfig(): GameConfig displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void units(...types: UnitType[]): Unit[] unitInfo(type: UnitType): UnitInfo diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts index 61f05631c..70a7df122 100644 --- a/src/core/game/GameImpl.ts +++ b/src/core/game/GameImpl.ts @@ -8,12 +8,12 @@ import { TerraNulliusImpl } from "./TerraNulliusImpl"; import { TileImpl } from "./TileImpl"; import { AllianceRequestImpl } from "./AllianceRequestImpl"; import { AllianceImpl } from "./AllianceImpl"; -import { ClientID } from "../Schemas"; +import { ClientID, GameConfig } from "../Schemas"; import { DisplayMessageEvent, MessageType } from "../../client/graphics/layers/EventsDisplay"; import { UnitImpl } from "./UnitImpl"; -export function createGame(terrainMap: TerrainMapImpl, eventBus: EventBus, config: Config): Game { - return new GameImpl(terrainMap, eventBus, config) +export function createGame(terrainMap: TerrainMapImpl, eventBus: EventBus, config: Config, gameConfig: GameConfig): Game { + return new GameImpl(terrainMap, eventBus, config, gameConfig) } export type CellString = string @@ -40,7 +40,12 @@ export class GameImpl implements MutableGame { private _terrainMiniMap: TerrainMap = null - constructor(private _terrainMap: TerrainMapImpl, public eventBus: EventBus, private _config: Config) { + constructor( + private _terrainMap: TerrainMapImpl, + public eventBus: EventBus, + private _config: Config, + private _gameConfig: GameConfig, + ) { this._terraNullius = new TerraNulliusImpl(this) this._width = _terrainMap.width(); this._height = _terrainMap.height(); @@ -65,6 +70,10 @@ export class GameImpl implements MutableGame { }) } + gameConfig(): GameConfig { + return this._gameConfig + } + addFallout(tile: Tile) { const ti = tile as TileImpl if (tile.hasOwner()) { @@ -143,7 +152,7 @@ export class GameImpl implements MutableGame { } inSpawnPhase(): boolean { - return this._ticks <= this.config().numSpawnPhaseTurns() + return this._ticks <= this.config().numSpawnPhaseTurns(this._gameConfig.gameType) } ticks(): number {