mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 14:50:44 +00:00
game kind of working with GameView
This commit is contained in:
@@ -74,7 +74,7 @@ export async function createClientGame(lobbyConfig: LobbyConfig, gameConfig: Gam
|
||||
const config = getConfig(gameConfig)
|
||||
|
||||
const terrainMap = await loadTerrainMap(gameConfig.gameMap);
|
||||
const gameView = new GameView(terrainMap.map)
|
||||
const gameView = new GameView(config, terrainMap.map)
|
||||
|
||||
const worker = new WorkerClient(lobbyConfig.gameID, gameConfig)
|
||||
await worker.initialize()
|
||||
|
||||
@@ -36,7 +36,7 @@ export class UILayer implements Layer {
|
||||
const barHeight = 15;
|
||||
const barBackgroundWidth = this.transformHandler.width();
|
||||
|
||||
const ratio = this.game.ticks() / this.game.config().numSpawnPhaseTurns(this.game.config().gameConfig().gameType)
|
||||
const ratio = this.game.ticks() / this.game.config().numSpawnPhaseTurns()
|
||||
|
||||
// Draw bar background
|
||||
context.fillStyle = 'rgba(0, 0, 0, 0.5)';
|
||||
|
||||
@@ -2,10 +2,10 @@ import { getConfig } from "./configuration/Config";
|
||||
import { EventBus } from "./EventBus";
|
||||
import { Executor } from "./execution/ExecutionManager";
|
||||
import { WinCheckExecution } from "./execution/WinCheckExecution";
|
||||
import { Game, MutableGame, MutableTile, Tile, TileEvent } from "./game/Game";
|
||||
import { Game, MutableGame, MutableTile, PlayerID, Tile, TileEvent } from "./game/Game";
|
||||
import { createGame } from "./game/GameImpl";
|
||||
import { loadTerrainMap } from "./game/TerrainMapLoader";
|
||||
import { GameUpdateViewData } from "./GameView";
|
||||
import { GameUpdateViewData, PlayerViewData } from "./GameView";
|
||||
import { GameConfig, Turn } from "./Schemas";
|
||||
|
||||
export async function createGameRunner(gameID: string, gameConfig: GameConfig, callBack: (gu: GameUpdateViewData) => void): Promise<GameRunner> {
|
||||
@@ -63,9 +63,12 @@ export class GameRunner {
|
||||
this.game.executeNextTick()
|
||||
|
||||
this.callBack({
|
||||
tick: this.game.ticks(),
|
||||
units: this.game.units().map(u => u.toViewData()),
|
||||
tileUpdates: this.updatedTiles.map(t => t.toViewData()),
|
||||
players: this.game.players().map(p => p.toViewData())
|
||||
players: Object.fromEntries(
|
||||
this.game.players().map(p => [p.id(), p.toViewData()])
|
||||
) as Record<PlayerID, PlayerViewData>
|
||||
})
|
||||
|
||||
this.isExecuting = false
|
||||
|
||||
+52
-48
@@ -2,6 +2,7 @@ import { MessageType, Player, Tile, Unit } from './game/Game';
|
||||
import { Config } from "./configuration/Config";
|
||||
import { Alliance, AllianceRequest, AllPlayers, Cell, DefenseBonus, EmojiMessage, Execution, ExecutionView, Game, Gold, MutableTile, Nation, PlayerID, PlayerInfo, PlayerType, Relation, TerrainMap, TerrainTile, TerrainType, TerraNullius, Tick, UnitInfo, UnitType } from "./game/Game";
|
||||
import { ClientID } from "./Schemas";
|
||||
import { TerraNulliusImpl } from './game/TerraNulliusImpl';
|
||||
|
||||
export interface ViewSerializable<T> {
|
||||
toViewData(): T;
|
||||
@@ -21,24 +22,29 @@ export interface TileViewData extends ViewData<TileViewData> {
|
||||
}
|
||||
|
||||
export class TileView {
|
||||
|
||||
constructor(private game: GameView, private data: TileViewData, private _terrain: TerrainTile) { }
|
||||
|
||||
type(): TerrainType {
|
||||
return this._terrain.type()
|
||||
}
|
||||
owner(): Player | TerraNullius {
|
||||
return this.game.player(this.data.owner)
|
||||
if (!this.hasOwner()) {
|
||||
return new TerraNulliusImpl()
|
||||
}
|
||||
return this.game.player(this.data?.owner)
|
||||
}
|
||||
hasOwner(): boolean {
|
||||
return this.data.owner != null
|
||||
return this.data?.owner != undefined
|
||||
}
|
||||
isBorder(): boolean {
|
||||
return this.data.isBorder
|
||||
return this.data?.isBorder
|
||||
}
|
||||
cell(): Cell {
|
||||
return new Cell(this.data.x, this.data.y)
|
||||
return this._terrain.cell()
|
||||
}
|
||||
hasFallout(): boolean {
|
||||
return this.data.hasFallout
|
||||
return this.data?.hasFallout
|
||||
}
|
||||
terrain(): TerrainTile {
|
||||
return this._terrain
|
||||
@@ -109,8 +115,11 @@ export interface PlayerViewData extends ViewData<PlayerViewData> {
|
||||
targetTroopRatio: number
|
||||
}
|
||||
|
||||
export class PlayerView {
|
||||
constructor(private game: Game, private data: PlayerViewData) { }
|
||||
export class PlayerView implements Player {
|
||||
constructor(private game: GameView, private data: PlayerViewData) { }
|
||||
lastTileChange(): Tick {
|
||||
return 0
|
||||
}
|
||||
name(): string {
|
||||
return this.data.name
|
||||
}
|
||||
@@ -129,7 +138,7 @@ export class PlayerView {
|
||||
isAlive(): boolean {
|
||||
return this.data.isAlive
|
||||
}
|
||||
isPlayer(): this is PlayerView {
|
||||
isPlayer(): this is Player {
|
||||
return true
|
||||
}
|
||||
numTilesOwned(): number {
|
||||
@@ -217,95 +226,90 @@ export class PlayerView {
|
||||
}
|
||||
|
||||
export interface GameUpdateViewData extends ViewData<GameUpdateViewData> {
|
||||
tick: number
|
||||
units: UnitViewData[]
|
||||
players: PlayerViewData[]
|
||||
players: Record<PlayerID, PlayerViewData>
|
||||
tileUpdates: TileViewData[]
|
||||
}
|
||||
|
||||
export class GameView {
|
||||
private lastGameUpdate: GameUpdateViewData
|
||||
private data: GameUpdateViewData
|
||||
private tiles: TileViewData[][] = []
|
||||
|
||||
constructor(private _terrainMap: TerrainMap) { }
|
||||
executions(): ExecutionView[] {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
executeNextTick(): void {
|
||||
throw new Error("Method not implemented.");
|
||||
constructor(private _config: Config, private _terrainMap: TerrainMap) {
|
||||
this.tiles = Array(_terrainMap.width()).fill(null).map(() => Array(_terrainMap.height()).fill(null));
|
||||
this.data = {
|
||||
tick: 0,
|
||||
units: [],
|
||||
tileUpdates: [],
|
||||
players: {}
|
||||
}
|
||||
}
|
||||
|
||||
public update(gu: GameUpdateViewData) {
|
||||
this.lastGameUpdate = gu
|
||||
this.data = gu
|
||||
gu.tileUpdates.forEach(tu => {
|
||||
this.tiles[tu.x][tu.y] = tu
|
||||
})
|
||||
}
|
||||
|
||||
recentlyUpdatedTiles(): TileView[] {
|
||||
return this.lastGameUpdate.tileUpdates.map(tu => new TileView(this, tu, this._terrainMap.terrain(new Cell(tu.x, tu.y))))
|
||||
return this.data.tileUpdates.map(tu => new TileView(this, tu, this._terrainMap.terrain(new Cell(tu.x, tu.y))))
|
||||
}
|
||||
|
||||
player(id: PlayerID): Player {
|
||||
throw new Error("Method not implemented.");
|
||||
if (id in this.data.players) {
|
||||
return new PlayerView(this, this.data.players[id])
|
||||
}
|
||||
throw Error(`player id ${id} not found`)
|
||||
}
|
||||
playerByClientID(id: ClientID): Player | null {
|
||||
throw new Error("Method not implemented.");
|
||||
return null
|
||||
}
|
||||
hasPlayer(id: PlayerID): boolean {
|
||||
throw new Error("Method not implemented.");
|
||||
return false
|
||||
}
|
||||
players(): Player[] {
|
||||
throw new Error("Method not implemented.");
|
||||
return []
|
||||
}
|
||||
tile(cell: Cell): Tile {
|
||||
throw new Error("Method not implemented.");
|
||||
return new TileView(this, this.tiles[cell.x][cell.y], this._terrainMap.terrain(cell))
|
||||
}
|
||||
isOnMap(cell: Cell): boolean {
|
||||
throw new Error("Method not implemented.");
|
||||
return this._terrainMap.isOnMap(cell)
|
||||
}
|
||||
width(): number {
|
||||
throw new Error("Method not implemented.");
|
||||
return this._terrainMap.width()
|
||||
}
|
||||
height(): number {
|
||||
throw new Error("Method not implemented.");
|
||||
return this._terrainMap.height()
|
||||
}
|
||||
numLandTiles(): number {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
forEachTile(fn: (tile: Tile) => void): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
terraNullius(): TerraNullius {
|
||||
throw new Error("Method not implemented.");
|
||||
for (let x = 0; x < this._terrainMap.width(); x++) {
|
||||
for (let y = 0; y < this._terrainMap.height(); y++) {
|
||||
fn(this.tile(new Cell(x, y)))
|
||||
}
|
||||
}
|
||||
}
|
||||
ticks(): Tick {
|
||||
throw new Error("Method not implemented.");
|
||||
return this.data.tick
|
||||
}
|
||||
inSpawnPhase(): boolean {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
addExecution(...exec: Execution[]): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
nations(): Nation[] {
|
||||
throw new Error("Method not implemented.");
|
||||
return this.data.tick <= this._config.numSpawnPhaseTurns()
|
||||
}
|
||||
config(): Config {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void {
|
||||
throw new Error("Method not implemented.");
|
||||
return this._config
|
||||
}
|
||||
units(...types: UnitType[]): Unit[] {
|
||||
throw new Error("Method not implemented.");
|
||||
return []
|
||||
}
|
||||
unitInfo(type: UnitType): UnitInfo {
|
||||
throw new Error("Method not implemented.");
|
||||
return this._config.unitInfo(type)
|
||||
}
|
||||
terrainMap(): TerrainMap {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
terrainMiniMap(): TerrainMap {
|
||||
throw new Error("Method not implemented.");
|
||||
return this._terrainMap
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ export interface Config {
|
||||
percentageTilesOwnedToWin(): number
|
||||
numBots(): number
|
||||
spawnNPCs(): boolean
|
||||
numSpawnPhaseTurns(gameType: GameType): number
|
||||
numSpawnPhaseTurns(): number
|
||||
|
||||
startManpower(playerInfo: PlayerInfo): number
|
||||
populationIncreaseRate(player: Player): number
|
||||
|
||||
@@ -178,8 +178,8 @@ export class DefaultConfig implements Config {
|
||||
boatMaxDistance(): number {
|
||||
return 500
|
||||
}
|
||||
numSpawnPhaseTurns(gameType: GameType): number {
|
||||
return gameType == GameType.Singleplayer ? 100 : 300
|
||||
numSpawnPhaseTurns(): number {
|
||||
return this._gameConfig.gameType == GameType.Singleplayer ? 100 : 300
|
||||
}
|
||||
numBots(): number {
|
||||
return 400
|
||||
|
||||
@@ -18,8 +18,8 @@ export class DevConfig extends DefaultConfig {
|
||||
super(sc, gc);
|
||||
}
|
||||
|
||||
numSpawnPhaseTurns(gameType: GameType): number {
|
||||
return gameType == GameType.Singleplayer ? 40 : 200
|
||||
numSpawnPhaseTurns(): number {
|
||||
return this.gameConfig().gameType == GameType.Singleplayer ? 40 : 200
|
||||
// return 100
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +159,7 @@ export interface TerrainMap {
|
||||
neighbors(terrainTile: TerrainTile): TerrainTile[]
|
||||
width(): number
|
||||
height(): number
|
||||
isOnMap(cell: Cell): boolean
|
||||
}
|
||||
|
||||
export interface TerrainTile extends SearchNode {
|
||||
|
||||
@@ -47,7 +47,7 @@ export class GameImpl implements MutableGame {
|
||||
public eventBus: EventBus,
|
||||
private _config: Config,
|
||||
) {
|
||||
this._terraNullius = new TerraNulliusImpl(this)
|
||||
this._terraNullius = new TerraNulliusImpl()
|
||||
this._width = _terrainMap.width();
|
||||
this._height = _terrainMap.height();
|
||||
this._numLandTiles = _terrainMap.numLandTiles
|
||||
@@ -145,7 +145,7 @@ export class GameImpl implements MutableGame {
|
||||
}
|
||||
|
||||
inSpawnPhase(): boolean {
|
||||
return this._ticks <= this.config().numSpawnPhaseTurns(this.config().gameConfig().gameType)
|
||||
return this._ticks <= this.config().numSpawnPhaseTurns()
|
||||
}
|
||||
|
||||
ticks(): number {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import {ClientID} from "../Schemas";
|
||||
import {TerraNullius, Cell, Tile, PlayerID} from "./Game";
|
||||
import {GameImpl} from "./GameImpl";
|
||||
import { ClientID } from "../Schemas";
|
||||
import { TerraNullius, Cell, Tile, PlayerID } from "./Game";
|
||||
import { GameImpl } from "./GameImpl";
|
||||
|
||||
|
||||
export class TerraNulliusImpl implements TerraNullius {
|
||||
public tiles: Map<Cell, Tile> = new Map<Cell, Tile>();
|
||||
|
||||
|
||||
constructor(private gs: GameImpl) {
|
||||
constructor() {
|
||||
}
|
||||
clientID(): ClientID {
|
||||
return "TERRA_NULLIUS_CLIENT_ID"
|
||||
@@ -20,5 +20,5 @@ export class TerraNulliusImpl implements TerraNullius {
|
||||
ownsTile(cell: Cell): boolean {
|
||||
return this.tiles.has(cell);
|
||||
}
|
||||
isPlayer(): false {return false as const;}
|
||||
isPlayer(): false { return false as const; }
|
||||
}
|
||||
|
||||
@@ -85,6 +85,9 @@ export class TerrainMapImpl implements TerrainMap {
|
||||
public nationMap: NationMap
|
||||
constructor(
|
||||
) { }
|
||||
isOnMap(cell: Cell): boolean {
|
||||
return cell.x >= 0 && cell.x < this.tiles.length && cell.y >= 0 && cell.y < this.tiles[0].length
|
||||
}
|
||||
|
||||
neighbors(terrainTile: TerrainTile): TerrainTile[] {
|
||||
return (terrainTile as TerrainTileImpl).neighbors();
|
||||
|
||||
Reference in New Issue
Block a user