diff --git a/TODO.txt b/TODO.txt index 685cbac41..b9ff657d0 100644 --- a/TODO.txt +++ b/TODO.txt @@ -98,6 +98,7 @@ * BUG: attacks speed up DONE 9/6/2024 * rebalance income DONE 9/7/2024 * Make fake humans +* BUG: when clicking on enemy sometimes boat goes all the way around --- v3 Release diff --git a/src/client/ClientGame.ts b/src/client/ClientGame.ts index e370d1ecd..cc706cfce 100644 --- a/src/client/ClientGame.ts +++ b/src/client/ClientGame.ts @@ -1,5 +1,5 @@ import {Executor} from "../core/execution/ExecutionManager"; -import {Cell, MutableGame, PlayerEvent, PlayerID, MutablePlayer, TileEvent, Player, Game, BoatEvent, Tile} from "../core/Game"; +import {Cell, MutableGame, PlayerEvent, PlayerID, MutablePlayer, TileEvent, Player, Game, BoatEvent, Tile, PlayerType} from "../core/Game"; import {createGame} from "../core/GameImpl"; import {EventBus} from "../core/EventBus"; import {Config} from "../core/configuration/Config"; @@ -248,7 +248,7 @@ export class ClientGame { if (enemyShoreDists.length > 0 && bordersOcean) { enemyShoreClosest = enemyShoreDists[0].dist } - if (enemyShoreClosest < borderTileClosest / 4) { + if (enemyShoreClosest < borderTileClosest / 6) { this.sendBoatAttackIntent(targetID, enemyShoreDists[0].tile.cell(), this.gs.config().boatAttackAmount(this.myPlayer, owner)) } else { this.sendAttackIntent(targetID, cell, this.gs.config().attackAmount(this.myPlayer, owner)) @@ -275,7 +275,7 @@ export class ClientGame { type: "spawn", clientID: this.id, name: this.playerName, - isBot: false, + playerType: PlayerType.Human, x: cell.x, y: cell.y }) diff --git a/src/client/graphics/NameRenderer.ts b/src/client/graphics/NameRenderer.ts index eb84eaed1..d6adb3e96 100644 --- a/src/client/graphics/NameRenderer.ts +++ b/src/client/graphics/NameRenderer.ts @@ -1,4 +1,4 @@ -import {Cell, Game, Player} from "../../core/Game" +import {Cell, Game, Player, PlayerType} from "../../core/Game" import {PseudoRandom} from "../../core/PseudoRandom" import {calculateBoundingBox} from "../../core/Util" import {Theme} from "../../core/configuration/Config" @@ -85,7 +85,7 @@ export class NameRenderer { isVisible(render: RenderInfo, min: Cell, max: Cell): boolean { const ratio = (max.x - min.x) / Math.max(20, (render.boundingBox.max.x - render.boundingBox.min.x)) - if (render.player.isBot()) { + if (render.player.type() == PlayerType.Bot) { if (ratio > 35) { return false } diff --git a/src/core/Game.ts b/src/core/Game.ts index 90aa59dc5..500893859 100644 --- a/src/core/Game.ts +++ b/src/core/Game.ts @@ -26,6 +26,12 @@ export enum TerrainType { Ocean } +export enum PlayerType { + Bot = "BOT", + Human = "HUMAN", + FakeHuman = "FAKEHUMAN", +} + export interface ExecutionView { isActive(): boolean owner(): Player @@ -41,7 +47,7 @@ export interface Execution extends ExecutionView { export class PlayerInfo { constructor( public readonly name: string, - public readonly isBot: boolean, + public readonly playerType: PlayerType, // null if bot. public readonly clientID: ClientID | null, public readonly id: PlayerID @@ -95,7 +101,7 @@ export interface Player { name(): string clientID(): ClientID id(): PlayerID - isBot(): boolean + type(): PlayerType troops(): number boats(): Boat[] ownsTile(cell: Cell): boolean diff --git a/src/core/GameImpl.ts b/src/core/GameImpl.ts index 87ff0af30..7b971eed2 100644 --- a/src/core/GameImpl.ts +++ b/src/core/GameImpl.ts @@ -1,6 +1,6 @@ import {Config} from "./configuration/Config"; import {EventBus} from "./EventBus"; -import {Cell, Execution, MutableGame, Game, MutablePlayer, PlayerEvent, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Boat, MutableBoat, BoatEvent, TerrainType} from "./Game"; +import {Cell, Execution, MutableGame, Game, MutablePlayer, PlayerEvent, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Boat, MutableBoat, BoatEvent, TerrainType, PlayerType} from "./Game"; import {ClientID} from "./Schemas"; import {Terrain, TerrainMap} from "./TerrainMapLoader"; import {simpleHash} from "./Util"; @@ -179,8 +179,8 @@ export class PlayerImpl implements MutablePlayer { return this.playerInfo.id } - isBot(): boolean { - return this.playerInfo.isBot + type(): PlayerType { + return this.playerInfo.playerType } setName(name: string) { @@ -348,7 +348,7 @@ export class GameImpl implements MutableGame { if (this._ticks % 100 == 0) { let hash = 1; this._players.forEach(p => { - if (!p.info().isBot) { + if (p.type() == PlayerType.Human) { console.log(`${p.toString()}`) } hash += p.hash() diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index 3017c50cf..602dd2ca1 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -1,4 +1,5 @@ import {z} from 'zod'; +import {PlayerType} from './Game'; export type GameID = string export type ClientID = string @@ -24,6 +25,8 @@ export type ClientIntentMessage = z.infer export type ClientJoinMessage = z.infer export type ClientLeaveMessage = z.infer +const PlayerTypeSchema = z.nativeEnum(PlayerType); + // TODO: create Cell schema export interface Lobby { @@ -53,7 +56,7 @@ export const AttackIntentSchema = BaseIntentSchema.extend({ export const SpawnIntentSchema = BaseIntentSchema.extend({ type: z.literal('spawn'), name: z.string(), - isBot: z.boolean(), + playerType: PlayerTypeSchema, x: z.number(), y: z.number(), }) diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 2508bf5a1..079b203d2 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -1,4 +1,4 @@ -import {Player, PlayerInfo, TerrainType, TerraNullius, Tile} from "../Game"; +import {Player, PlayerInfo, PlayerType, TerrainType, TerraNullius, Tile} from "../Game"; import {within} from "../Util"; import {Config, Theme} from "./Config"; import {pastelTheme} from "./PastelTheme"; @@ -67,7 +67,7 @@ export class DefaultConfig implements Config { } attackAmount(attacker: Player, defender: Player | TerraNullius) { - if (attacker.isBot()) { + if (attacker.type() == PlayerType.Bot) { return attacker.troops() / 20 } else { return attacker.troops() / 5 @@ -75,7 +75,7 @@ export class DefaultConfig implements Config { } startTroops(playerInfo: PlayerInfo): number { - if (playerInfo.isBot) { + if (playerInfo.playerType == PlayerType.Bot) { return 10000 } return 10000 diff --git a/src/core/execution/BotSpawner.ts b/src/core/execution/BotSpawner.ts index c0d5b18a7..124a2582b 100644 --- a/src/core/execution/BotSpawner.ts +++ b/src/core/execution/BotSpawner.ts @@ -1,4 +1,4 @@ -import {Cell, Game, Tile, TileEvent} from "../Game"; +import {Cell, Game, PlayerType, Tile, TileEvent} from "../Game"; import {PseudoRandom} from "../PseudoRandom"; import {SpawnIntent} from "../Schemas"; import {bfs, dist as dist, manhattanDist} from "../Util"; @@ -40,7 +40,7 @@ export class BotSpawner { return { type: 'spawn', name: botName, - isBot: true, + playerType: PlayerType.Bot, x: tile.cell().x, y: tile.cell().y }; diff --git a/src/core/execution/ExecutionManager.ts b/src/core/execution/ExecutionManager.ts index 2b27e64a2..5327ff58e 100644 --- a/src/core/execution/ExecutionManager.ts +++ b/src/core/execution/ExecutionManager.ts @@ -33,7 +33,7 @@ export class Executor { ) } else if (intent.type == "spawn") { return new SpawnExecution( - new PlayerInfo(intent.name, intent.isBot, intent.clientID, this.random.nextID()), + new PlayerInfo(intent.name, intent.playerType, intent.clientID, this.random.nextID()), new Cell(intent.x, intent.y) ) } else if (intent.type == "boat") { diff --git a/src/core/execution/SpawnExecution.ts b/src/core/execution/SpawnExecution.ts index 899db5201..61df3fea7 100644 --- a/src/core/execution/SpawnExecution.ts +++ b/src/core/execution/SpawnExecution.ts @@ -1,4 +1,4 @@ -import {Cell, Execution, MutableGame, MutablePlayer, PlayerInfo} from "../Game" +import {Cell, Execution, MutableGame, MutablePlayer, PlayerInfo, PlayerType} from "../Game" import {BotExecution} from "./BotExecution" import {PlayerExecution} from "./PlayerExecution" import {getSpawnCells} from "./Util" @@ -41,7 +41,7 @@ export class SpawnExecution implements Execution { player.conquer(this.mg.tile(c)) }) this.mg.addExecution(new PlayerExecution(player.id())) - if (player.isBot()) { + if (player.type() == PlayerType.Bot) { this.mg.addExecution(new BotExecution(player)) } this.active = false