mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-24 13:52:45 +00:00
in progress
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Executor } from "../core/execution/ExecutionManager";
|
||||
import { Cell, MutableGame, PlayerID, MutablePlayer, TileEvent, Player, Game, UnitEvent, Tile, PlayerType, GameMap, Difficulty, GameType } from "../core/game/Game";
|
||||
import { Cell, MutableGame, PlayerID, GameMap, Difficulty, GameType } from "../core/game/Game";
|
||||
import { createGame } from "../core/game/GameImpl";
|
||||
import { EventBus } from "../core/EventBus";
|
||||
import { createRenderer, GameRenderer } from "./graphics/GameRenderer";
|
||||
|
||||
@@ -2,15 +2,8 @@ import { LitElement, html, css } from 'lit';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { EventBus } from "../../../core/EventBus";
|
||||
import {
|
||||
AllianceExpiredEvent,
|
||||
AllianceRequestEvent,
|
||||
AllianceRequestReplyEvent,
|
||||
AllPlayers,
|
||||
BrokeAllianceEvent, DisplayMessageEvent, EmojiMessageEvent,
|
||||
Game,
|
||||
MessageType,
|
||||
Player, TargetPlayerEvent,
|
||||
UnitEvent
|
||||
} from "../../../core/game/Game";
|
||||
import { ClientID } from "../../../core/Schemas";
|
||||
import { Layer } from "./Layer";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { EventBus } from "../../../core/EventBus";
|
||||
import { WinEvent } from "../../../core/execution/WinCheckExecution";
|
||||
import { AllianceRequest, AllianceRequestReplyEvent, Game, Player } from "../../../core/game/Game";
|
||||
import { Player } from "../../../core/game/Game";
|
||||
import { ClientID } from "../../../core/Schemas";
|
||||
import { Layer } from "./Layer";
|
||||
import { TransformHandler } from "../TransformHandler";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Colord } from "colord";
|
||||
import { Theme } from "../../../core/configuration/Config";
|
||||
import { Unit, UnitEvent, Cell, Game, Tile, UnitType, Player } from "../../../core/game/Game";
|
||||
import { Unit, Cell, Game, Tile, UnitType, Player } from "../../../core/game/Game";
|
||||
import { bfs, dist, euclDist } from "../../../core/Util";
|
||||
import { Layer } from "./Layer";
|
||||
import { EventBus } from "../../../core/EventBus";
|
||||
@@ -76,7 +76,7 @@ export class UnitLayer implements Layer {
|
||||
this.canvas.width = this.game.width();
|
||||
this.canvas.height = this.game.height();
|
||||
for (const unit of this.game.units()) {
|
||||
this.onUnitEvent(new UnitEvent(unit, unit.tile()))
|
||||
// this.onUnitEvent(new UnitEvent(unit, unit.tile()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,22 +176,22 @@ export class UnitLayer implements Layer {
|
||||
|
||||
}
|
||||
|
||||
private handleTradeShipEvent(event: UnitEvent) {
|
||||
const rel = this.relationship(event.unit)
|
||||
bfs(event.oldTile, euclDist(event.oldTile, 3)).forEach(t => {
|
||||
private handleTradeShipEvent(unit: Unit) {
|
||||
const rel = this.relationship(unit)
|
||||
bfs(unit.oldTile, euclDist(unit.oldTile, 3)).forEach(t => {
|
||||
this.clearCell(t.cell());
|
||||
});
|
||||
if (event.unit.isActive()) {
|
||||
bfs(event.unit.tile(), dist(event.unit.tile(), 2))
|
||||
.forEach(t => this.paintCell(t.cell(), rel, this.theme.territoryColor(event.unit.owner().info()), 255));
|
||||
if (unit.isActive()) {
|
||||
bfs(unit.tile(), dist(unit.tile(), 2))
|
||||
.forEach(t => this.paintCell(t.cell(), rel, this.theme.territoryColor(unit.owner().info()), 255));
|
||||
}
|
||||
if (event.unit.isActive()) {
|
||||
bfs(event.unit.tile(), dist(event.unit.tile(), 1))
|
||||
.forEach(t => this.paintCell(t.cell(), rel, this.theme.borderColor(event.unit.owner().info()), 255));
|
||||
if (unit.isActive()) {
|
||||
bfs(unit.tile(), dist(unit.tile(), 1))
|
||||
.forEach(t => this.paintCell(t.cell(), rel, this.theme.borderColor(unit.owner().info()), 255));
|
||||
}
|
||||
}
|
||||
|
||||
private handleBoatEvent(event: UnitEvent) {
|
||||
private handleBoatEvent(event: Unit) {
|
||||
const rel = this.relationship(event.unit)
|
||||
if (!this.boatToTrail.has(event.unit)) {
|
||||
this.boatToTrail.set(event.unit, new Set<Tile>());
|
||||
|
||||
+5
-10
@@ -3,7 +3,7 @@ import { getConfig } from "./configuration/Config";
|
||||
import { EventBus } from "./EventBus";
|
||||
import { Executor } from "./execution/ExecutionManager";
|
||||
import { WinCheckExecution } from "./execution/WinCheckExecution";
|
||||
import { Cell, DisplayMessageEvent, Game, MessageType, MutableGame, MutableTile, Player, PlayerID, Tile, TileEvent, UnitType } from "./game/Game";
|
||||
import { Cell, DisplayMessageEvent, Game, MessageType, MutableGame, MutableTile, Player, PlayerID, Tile, UnitType } from "./game/Game";
|
||||
import { createGame } from "./game/GameImpl";
|
||||
import { loadTerrainMap } from "./game/TerrainMapLoader";
|
||||
import { GameUpdateViewData, NameViewData, packTileData, PlayerActions, PlayerViewData } from "./GameView";
|
||||
@@ -13,9 +13,8 @@ import { and, bfs, dist, targetTransportTile } from "./Util";
|
||||
export async function createGameRunner(gameID: string, gameConfig: GameConfig, callBack: (gu: GameUpdateViewData) => void): Promise<GameRunner> {
|
||||
const config = getConfig(gameConfig)
|
||||
const terrainMap = await loadTerrainMap(gameConfig.gameMap);
|
||||
const eventBus = new EventBus()
|
||||
const game = createGame(terrainMap.map, terrainMap.miniMap, eventBus, config)
|
||||
const gr = new GameRunner(game as MutableGame, eventBus, new Executor(game, gameID), callBack)
|
||||
const game = createGame(terrainMap.map, terrainMap.miniMap, config)
|
||||
const gr = new GameRunner(game as MutableGame, new Executor(game, gameID), callBack)
|
||||
gr.init()
|
||||
return gr
|
||||
}
|
||||
@@ -31,21 +30,17 @@ export class GameRunner {
|
||||
|
||||
constructor(
|
||||
public game: MutableGame,
|
||||
private eventBus: EventBus,
|
||||
private execManager: Executor,
|
||||
private callBack: (gu: GameUpdateViewData) => void
|
||||
) {
|
||||
}
|
||||
|
||||
init() {
|
||||
this.eventBus.on(TileEvent, (e) => {
|
||||
this.updatedTiles.add(e.tile as MutableTile)
|
||||
})
|
||||
this.game.addExecution(...this.execManager.spawnBots(this.game.config().numBots()))
|
||||
if (this.game.config().spawnNPCs()) {
|
||||
this.game.addExecution(...this.execManager.fakeHumanExecutions())
|
||||
}
|
||||
this.game.addExecution(new WinCheckExecution(this.eventBus))
|
||||
this.game.addExecution(new WinCheckExecution())
|
||||
this.tickInterval = setInterval(() => this.executeNextTick(), 10)
|
||||
}
|
||||
|
||||
@@ -169,7 +164,7 @@ export class GameRunner {
|
||||
}
|
||||
// TODO: fix event bus
|
||||
if (tile.owner().isPlayer() && myPlayer.isAlliedWith(tile.owner() as Player)) {
|
||||
this.eventBus.emit(new DisplayMessageEvent("Cannot attack ally", MessageType.WARN))
|
||||
// this.eventBus.emit(new DisplayMessageEvent("Cannot attack ally", MessageType.WARN))
|
||||
return false
|
||||
}
|
||||
if (!tile.terrain().isLand()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { consolex } from "../Consolex";
|
||||
import {Cell, Game, PlayerType, Tile, TileEvent} from "../game/Game";
|
||||
import {Cell, Game, PlayerType, Tile} from "../game/Game";
|
||||
import {PseudoRandom} from "../PseudoRandom";
|
||||
import {GameID, SpawnIntent} from "../Schemas";
|
||||
import {bfs, dist as dist, manhattanDist, simpleHash} from "../Util";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerInfo, TerraNullius, Tile, PlayerType, Alliance, AllianceRequestReplyEvent, Difficulty, UnitType } from "../game/Game";
|
||||
import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerInfo, TerraNullius, Tile, PlayerType, Alliance, UnitType } from "../game/Game";
|
||||
import { AttackIntent, BoatAttackIntentSchema, GameID, Intent, Turn } from "../Schemas";
|
||||
import { AttackExecution } from "./AttackExecution";
|
||||
import { SpawnExecution } from "./SpawnExecution";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Unit, Cell, Execution, MutableUnit, MutableGame, MutablePlayer, Player, PlayerID, TerraNullius, Tile, TileEvent, UnitType, TerrainType } from "../game/Game";
|
||||
import { Unit, Cell, Execution, MutableUnit, MutableGame, MutablePlayer, Player, PlayerID, TerraNullius, Tile, UnitType, TerrainType } from "../game/Game";
|
||||
import { and, bfs, manhattanDistWrapped, sourceDstOceanShore, targetTransportTile } from "../Util";
|
||||
import { AttackExecution } from "./AttackExecution";
|
||||
import { MessageType } from '../game/Game';
|
||||
|
||||
@@ -11,7 +11,7 @@ export class WinCheckExecution implements Execution {
|
||||
|
||||
private mg: MutableGame
|
||||
|
||||
constructor(private eventBus: EventBus) {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
init(mg: MutableGame, ticks: number) {
|
||||
@@ -28,7 +28,7 @@ export class WinCheckExecution implements Execution {
|
||||
}
|
||||
const max = sorted[0]
|
||||
if (max.numTilesOwned() / this.mg.terrainMap().numLandTiles() * 100 > this.mg.config().percentageTilesOwnedToWin()) {
|
||||
this.eventBus.emit(new WinEvent(max))
|
||||
this.mg.setWinner(max)
|
||||
this.active = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MutableAllianceRequest, MutablePlayer, Player, Tick } from "./Game";
|
||||
import { AllianceRequestUpdate, GameUpdateType, MutableAllianceRequest, MutablePlayer, Player, Tick } from "./Game";
|
||||
import { GameImpl } from "./GameImpl";
|
||||
|
||||
|
||||
@@ -25,4 +25,13 @@ export class AllianceRequestImpl implements MutableAllianceRequest {
|
||||
this.game.rejectAllianceRequest(this)
|
||||
}
|
||||
|
||||
toUpdate(): AllianceRequestUpdate {
|
||||
return {
|
||||
type: GameUpdateType.AllianceRequest,
|
||||
requestorID: this.requestor_.smallID(),
|
||||
recipientID: this.recipient_.smallID(),
|
||||
createdAt: this.tickCreated,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+95
-23
@@ -10,6 +10,11 @@ export type Gold = number
|
||||
|
||||
export const AllPlayers = "AllPlayers" as const;
|
||||
|
||||
export interface MapPos {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
|
||||
export enum Difficulty {
|
||||
Easy = "Easy",
|
||||
Medium = "Medium",
|
||||
@@ -89,6 +94,13 @@ export class Cell {
|
||||
this.strRepr = `Cell[${this.x},${this.y}]`
|
||||
}
|
||||
|
||||
pos(): MapPos {
|
||||
return {
|
||||
x: this.x,
|
||||
y: this.y
|
||||
}
|
||||
}
|
||||
|
||||
toString(): string { return this.strRepr }
|
||||
}
|
||||
|
||||
@@ -150,6 +162,7 @@ export class PlayerInfo {
|
||||
public readonly playerType: PlayerType,
|
||||
// null if bot.
|
||||
public readonly clientID: ClientID | null,
|
||||
// TODO: make player id the small id
|
||||
public readonly id: PlayerID
|
||||
) { }
|
||||
}
|
||||
@@ -199,6 +212,7 @@ export interface MutableTile extends Tile, ViewSerializable<TileViewData> {
|
||||
borders(other: Player | TerraNullius): boolean
|
||||
neighborsWrapped(): Tile[]
|
||||
defenseBonuses(): DefenseBonus[]
|
||||
toUpdate(isBorderOnly: boolean): TileUpdate
|
||||
}
|
||||
|
||||
export interface Unit {
|
||||
@@ -354,47 +368,105 @@ export interface MutableGame extends Game {
|
||||
units(...types: UnitType[]): MutableUnit[]
|
||||
addTileDefenseBonus(tile: Tile, unit: Unit, amount: number): DefenseBonus
|
||||
removeTileDefenseBonus(bonus: DefenseBonus): void
|
||||
addFallout(tile: Tile)
|
||||
addFallout(tile: Tile): void
|
||||
setWinner(winner: Player): void
|
||||
}
|
||||
|
||||
export class TileEvent implements GameEvent {
|
||||
constructor(public readonly tile: Tile, public readonly borderOnlyChange: boolean = false) { }
|
||||
export enum GameUpdateType {
|
||||
Tile,
|
||||
Unit,
|
||||
DisplayEvent,
|
||||
AllianceRequest,
|
||||
AllianceRequestReply,
|
||||
BrokeAlliance,
|
||||
AllianceExpired,
|
||||
TargetPlayer,
|
||||
EmojiUpdate,
|
||||
WinUpdate
|
||||
}
|
||||
|
||||
export class UnitEvent implements GameEvent {
|
||||
constructor(public readonly unit: Unit, public oldTile: Tile) { }
|
||||
export type GameUpdate = TileUpdate
|
||||
| UnitUpdate
|
||||
| AllianceRequestUpdate
|
||||
| AllianceRequestReplyUpdate
|
||||
| BrokeAllianceUpdate
|
||||
| AllianceExpiredUpdate
|
||||
| DisplayMessageEvent
|
||||
| TargetPlayerUpdate
|
||||
| EmojiUpdate
|
||||
| WinUpdate
|
||||
|
||||
export interface TileUpdate {
|
||||
type: GameUpdateType.Tile
|
||||
owner: number
|
||||
pos: MapPos
|
||||
isBorder: boolean
|
||||
borderOnlyChange: boolean
|
||||
hasFallout: boolean
|
||||
hasDefenseBonus: boolean
|
||||
}
|
||||
|
||||
export class AllianceRequestEvent implements GameEvent {
|
||||
constructor(public readonly allianceRequest: AllianceRequest) { }
|
||||
export interface UnitUpdate {
|
||||
type: GameUpdateType.Unit
|
||||
unitType: UnitType
|
||||
troops: number
|
||||
id: number
|
||||
ownerID: number
|
||||
pos: MapPos
|
||||
oldPos: MapPos
|
||||
isActive: boolean
|
||||
health?: boolean
|
||||
}
|
||||
|
||||
export class AllianceRequestReplyEvent implements GameEvent {
|
||||
constructor(public readonly allianceRequest: AllianceRequest, public readonly accepted: boolean) { }
|
||||
export interface AllianceRequestUpdate {
|
||||
type: GameUpdateType.AllianceRequest
|
||||
requestorID: number,
|
||||
recipientID: number,
|
||||
createdAt: Tick,
|
||||
}
|
||||
|
||||
export class BrokeAllianceEvent implements GameEvent {
|
||||
constructor(public readonly traitor: Player, public readonly betrayed: Player) { }
|
||||
export interface AllianceRequestReplyUpdate {
|
||||
type: GameUpdateType.AllianceRequestReply
|
||||
request: AllianceRequestUpdate
|
||||
accepted: boolean
|
||||
}
|
||||
|
||||
export class AllianceExpiredEvent implements GameEvent {
|
||||
constructor(public readonly player1: Player, public readonly player2: Player) { }
|
||||
export interface BrokeAllianceUpdate {
|
||||
type: GameUpdateType.BrokeAlliance
|
||||
traitorID: number
|
||||
betrayedID: number
|
||||
}
|
||||
|
||||
export class TargetPlayerEvent implements GameEvent {
|
||||
constructor(public readonly player: Player, public readonly target: Player) { }
|
||||
export interface AllianceExpiredUpdate {
|
||||
type: GameUpdateType.AllianceExpired
|
||||
player1: number
|
||||
player2: number
|
||||
}
|
||||
|
||||
export class EmojiMessageEvent implements GameEvent {
|
||||
constructor(public readonly message: EmojiMessage) { }
|
||||
export interface TargetPlayerUpdate {
|
||||
type: GameUpdateType.TargetPlayer
|
||||
playerID: number
|
||||
targetID: number
|
||||
}
|
||||
|
||||
export class DisplayMessageEvent implements GameEvent {
|
||||
constructor(
|
||||
public readonly message: string,
|
||||
public readonly type: MessageType,
|
||||
public readonly playerID: PlayerID | null = null
|
||||
) { }
|
||||
export interface EmojiUpdate {
|
||||
type: GameUpdateType.EmojiUpdate
|
||||
message: string
|
||||
senderID: number
|
||||
recipientID: number | typeof AllPlayers
|
||||
createdAt: Tick
|
||||
}
|
||||
|
||||
export interface DisplayMessageEvent {
|
||||
type: GameUpdateType.DisplayEvent
|
||||
message: string
|
||||
messageType: MessageType
|
||||
playerID: number | null
|
||||
}
|
||||
|
||||
export interface WinUpdate {
|
||||
type: GameUpdateType.WinUpdate
|
||||
winnerID: number,
|
||||
}
|
||||
|
||||
export enum MessageType {
|
||||
|
||||
+75
-22
@@ -1,7 +1,5 @@
|
||||
import { info } from "console";
|
||||
import { Config } from "../configuration/Config";
|
||||
import { EventBus } from "../EventBus";
|
||||
import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Unit, UnitEvent as UnitEvent, PlayerType, MutableAllianceRequest, AllianceRequestReplyEvent, AllianceRequestEvent, BrokeAllianceEvent, MutableAlliance, Alliance, AllianceExpiredEvent, Nation, UnitType, UnitInfo, TerrainMap, DefenseBonus, MutableTile } from "./Game";
|
||||
import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerID, PlayerInfo, Player, TerraNullius, Tile, Unit, MutableAllianceRequest, Alliance, Nation, UnitType, UnitInfo, TerrainMap, DefenseBonus, MutableTile, GameUpdate, GameUpdateType, AllPlayers } from "./Game";
|
||||
import { TerrainMapImpl } from "./TerrainMapLoader";
|
||||
import { PlayerImpl } from "./PlayerImpl";
|
||||
import { TerraNulliusImpl } from "./TerraNulliusImpl";
|
||||
@@ -10,12 +8,12 @@ import { AllianceRequestImpl } from "./AllianceRequestImpl";
|
||||
import { AllianceImpl } from "./AllianceImpl";
|
||||
import { ClientID, GameConfig } from "../Schemas";
|
||||
import { MessageType } from './Game';
|
||||
import { DisplayMessageEvent } from './Game';
|
||||
import { UnitImpl } from "./UnitImpl";
|
||||
import { consolex } from "../Consolex";
|
||||
import { string } from "zod";
|
||||
|
||||
export function createGame(terrainMap: TerrainMapImpl, miniMap: TerrainMap, eventBus: EventBus, config: Config): Game {
|
||||
return new GameImpl(terrainMap, miniMap, eventBus, config)
|
||||
export function createGame(terrainMap: TerrainMapImpl, miniMap: TerrainMap, config: Config): Game {
|
||||
return new GameImpl(terrainMap, miniMap, config)
|
||||
}
|
||||
|
||||
export type CellString = string
|
||||
@@ -43,11 +41,11 @@ export class GameImpl implements MutableGame {
|
||||
private nextPlayerID = 1
|
||||
private _nextUnitID = 1
|
||||
|
||||
private updates: GameUpdate[] = []
|
||||
|
||||
constructor(
|
||||
private _terrainMap: TerrainMapImpl,
|
||||
private _miniMap: TerrainMap,
|
||||
public eventBus: EventBus,
|
||||
private _config: Config,
|
||||
) {
|
||||
this._terraNullius = new TerraNulliusImpl()
|
||||
@@ -81,20 +79,20 @@ export class GameImpl implements MutableGame {
|
||||
throw Error(`cannot set fallout, tile ${tile} has owner`)
|
||||
}
|
||||
ti._hasFallout = true
|
||||
this.eventBus.emit(new TileEvent(tile))
|
||||
this.updates.push(ti.toUpdate(false))
|
||||
}
|
||||
|
||||
addTileDefenseBonus(tile: Tile, unit: Unit, amount: number): DefenseBonus {
|
||||
const df = { unit: unit, tile: tile, amount: amount };
|
||||
(tile as TileImpl)._defenseBonuses.push(df)
|
||||
this.eventBus.emit(new TileEvent(tile))
|
||||
this.updates.push((tile as TileImpl).toUpdate())
|
||||
return df
|
||||
}
|
||||
|
||||
removeTileDefenseBonus(bonus: DefenseBonus): void {
|
||||
const t = bonus.tile as TileImpl
|
||||
t._defenseBonuses = t._defenseBonuses.filter(db => db != bonus)
|
||||
this.eventBus.emit(new TileEvent(bonus.tile))
|
||||
this.updates.push(t.toUpdate())
|
||||
}
|
||||
|
||||
units(...types: UnitType[]): UnitImpl[] {
|
||||
@@ -124,7 +122,7 @@ export class GameImpl implements MutableGame {
|
||||
}
|
||||
const ar = new AllianceRequestImpl(requestor, recipient, this._ticks, this)
|
||||
this.allianceRequests.push(ar)
|
||||
this.eventBus.emit(new AllianceRequestEvent(ar))
|
||||
this.updates.push(ar.toUpdate())
|
||||
return ar
|
||||
}
|
||||
|
||||
@@ -133,13 +131,22 @@ export class GameImpl implements MutableGame {
|
||||
const alliance = new AllianceImpl(this, request.requestor() as PlayerImpl, request.recipient() as PlayerImpl, this._ticks)
|
||||
this.alliances_.push(alliance);
|
||||
(request.requestor() as PlayerImpl).pastOutgoingAllianceRequests.push(request)
|
||||
this.eventBus.emit(new AllianceRequestReplyEvent(request, true))
|
||||
this.updates.push({
|
||||
type: GameUpdateType.AllianceRequestReply,
|
||||
request: request.toUpdate(),
|
||||
accepted: true,
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
rejectAllianceRequest(request: AllianceRequestImpl) {
|
||||
this.allianceRequests = this.allianceRequests.filter(ar => ar != request);
|
||||
(request.requestor() as PlayerImpl).pastOutgoingAllianceRequests.push(request)
|
||||
this.eventBus.emit(new AllianceRequestReplyEvent(request, false))
|
||||
this.updates.push({
|
||||
type: GameUpdateType.AllianceRequestReply,
|
||||
request: request.toUpdate(),
|
||||
accepted: true
|
||||
})
|
||||
}
|
||||
|
||||
hasPlayer(id: PlayerID): boolean {
|
||||
@@ -348,7 +355,7 @@ export class GameImpl implements MutableGame {
|
||||
owner._lastTileChange = this._ticks
|
||||
this.updateBorders(tile)
|
||||
tileImpl._hasFallout = false
|
||||
this.eventBus.emit(new TileEvent(tile))
|
||||
this.updates.push((tile as TileImpl).toUpdate())
|
||||
}
|
||||
|
||||
relinquish(tile: Tile) {
|
||||
@@ -368,7 +375,9 @@ export class GameImpl implements MutableGame {
|
||||
|
||||
tileImpl._owner = this._terraNullius
|
||||
this.updateBorders(tile)
|
||||
this.eventBus.emit(new TileEvent(tile))
|
||||
this.updates.push(
|
||||
(tile as TileImpl).toUpdate()
|
||||
)
|
||||
}
|
||||
|
||||
private updateBorders(tile: Tile) {
|
||||
@@ -377,7 +386,7 @@ export class GameImpl implements MutableGame {
|
||||
tile.neighbors().forEach(t => tiles.push(t as TileImpl))
|
||||
|
||||
for (const t of tiles) {
|
||||
this.eventBus.emit(new TileEvent(t, true))
|
||||
this.updates.push(t.toUpdate(true))
|
||||
if (!t.hasOwner()) {
|
||||
t._isBorder = false
|
||||
continue
|
||||
@@ -405,8 +414,16 @@ export class GameImpl implements MutableGame {
|
||||
return false
|
||||
}
|
||||
|
||||
public fireUnitUpdateEvent(boat: Unit, oldTile: Tile) {
|
||||
this.eventBus.emit(new UnitEvent(boat, oldTile))
|
||||
public fireUnitUpdateEvent(unit: Unit, oldTile: Tile) {
|
||||
this.updates.push((unit as UnitImpl).toUpdate(oldTile))
|
||||
}
|
||||
|
||||
target(targeter: Player, target: Player) {
|
||||
this.updates.push({
|
||||
type: GameUpdateType.TargetPlayer,
|
||||
playerID: targeter.smallID(),
|
||||
targetID: target.smallID(),
|
||||
})
|
||||
}
|
||||
|
||||
public breakAlliance(breaker: Player, alliance: Alliance) {
|
||||
@@ -429,7 +446,12 @@ export class GameImpl implements MutableGame {
|
||||
throw new Error(`must have exactly one alliance, have ${alliances.length}`)
|
||||
}
|
||||
this.alliances_ = this.alliances_.filter(a => a != alliances[0])
|
||||
this.eventBus.emit(new BrokeAllianceEvent(breaker, other))
|
||||
this.updates.push({
|
||||
type: GameUpdateType.BrokeAlliance,
|
||||
traitorID: breaker.smallID(),
|
||||
betrayedID: other.smallID()
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
public expireAlliance(alliance: Alliance) {
|
||||
@@ -439,7 +461,30 @@ export class GameImpl implements MutableGame {
|
||||
throw new Error(`cannot expire alliance: must have exactly one alliance, have ${alliances.length}`)
|
||||
}
|
||||
this.alliances_ = this.alliances_.filter(a => a != alliances[0])
|
||||
this.eventBus.emit(new AllianceExpiredEvent(alliance.requestor(), alliance.recipient()))
|
||||
this.updates.push({
|
||||
type: GameUpdateType.AllianceExpired,
|
||||
player1: alliance.requestor().smallID(),
|
||||
player2: alliance.recipient().smallID()
|
||||
})
|
||||
}
|
||||
|
||||
sendEmojiUpdate(sender: Player, recipient: Player | typeof AllPlayers, emoji: string): void {
|
||||
const recipientID = recipient === AllPlayers ? recipient : recipient.smallID();
|
||||
|
||||
this.updates.push({
|
||||
type: GameUpdateType.EmojiUpdate,
|
||||
message: emoji,
|
||||
senderID: sender.smallID(),
|
||||
recipientID: recipientID,
|
||||
createdAt: this._ticks
|
||||
})
|
||||
}
|
||||
|
||||
setWinner(winner: Player): void {
|
||||
this.updates.push({
|
||||
type: GameUpdateType.WinUpdate,
|
||||
winnerID: winner.smallID()
|
||||
})
|
||||
}
|
||||
|
||||
public terrainMap(): TerrainMapImpl {
|
||||
@@ -451,7 +496,15 @@ export class GameImpl implements MutableGame {
|
||||
}
|
||||
|
||||
displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void {
|
||||
this.eventBus.emit(new DisplayMessageEvent(message, type, playerID))
|
||||
let id = null
|
||||
if (playerID != null) {
|
||||
id = this.player(playerID).smallID()
|
||||
}
|
||||
this.updates.push({
|
||||
type: GameUpdateType.DisplayEvent,
|
||||
messageType: type,
|
||||
message: message,
|
||||
playerID: id
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MutablePlayer, Tile, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance, Tick, TargetPlayerEvent, EmojiMessage, EmojiMessageEvent, AllPlayers, Gold, UnitType, Unit, MutableUnit, Relation, MutableTile } from "./Game";
|
||||
import { MutablePlayer, Tile, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance, Tick, EmojiMessage, AllPlayers, Gold, UnitType, Unit, MutableUnit, Relation, MutableTile } from "./Game";
|
||||
import { ClientID } from "../Schemas";
|
||||
import { assertNever, bfs, closestOceanShoreFromPlayer, dist, distSortUnit, manhattanDist, manhattanDistWrapped, processName, simpleHash, sourceDstOceanShore, within } from "../Util";
|
||||
import { CellString, GameImpl } from "./GameImpl";
|
||||
@@ -6,7 +6,7 @@ import { UnitImpl } from "./UnitImpl";
|
||||
import { TileImpl } from "./TileImpl";
|
||||
import { MessageType } from './Game';
|
||||
import { renderTroops } from "../../client/Utils";
|
||||
import { PlayerViewData, ViewData, ViewSerializable } from "../GameView";
|
||||
import { PlayerViewData } from "../GameView";
|
||||
|
||||
interface Target {
|
||||
tick: Tick
|
||||
@@ -291,7 +291,7 @@ export class PlayerImpl implements MutablePlayer {
|
||||
|
||||
target(other: Player): void {
|
||||
this.targets_.push({ tick: this.gs.ticks(), target: other })
|
||||
this.gs.eventBus.emit(new TargetPlayerEvent(this, other))
|
||||
this.gs.target(this, other)
|
||||
}
|
||||
|
||||
targets(): PlayerImpl[] {
|
||||
@@ -312,7 +312,7 @@ export class PlayerImpl implements MutablePlayer {
|
||||
}
|
||||
const msg = new EmojiMessage(this, recipient, emoji, this.gs.ticks())
|
||||
this.outgoingEmojis_.push(msg)
|
||||
this.gs.eventBus.emit(new EmojiMessageEvent(msg))
|
||||
this.gs.sendEmojiUpdate(this, recipient, emoji)
|
||||
}
|
||||
|
||||
outgoingEmojis(): EmojiMessage[] {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Tile, Cell, TerrainType, Player, TerraNullius, MutablePlayer, TerrainTile, DefenseBonus, MutableTile } from "./Game";
|
||||
import { Tile, Cell, TerrainType, Player, TerraNullius, MutablePlayer, TerrainTile, DefenseBonus, MutableTile, TileUpdate, GameUpdateType } from "./Game";
|
||||
import { SearchNode } from "../pathfinding/AStar";
|
||||
import { TerrainTileImpl } from "./TerrainMapLoader";
|
||||
import { GameImpl } from "./GameImpl";
|
||||
@@ -24,13 +24,21 @@ export class TileImpl implements MutableTile {
|
||||
) { }
|
||||
|
||||
toViewData(): TileViewData {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
toUpdate(borderOnlyChange: boolean = false): TileUpdate {
|
||||
return {
|
||||
x: this._cell.x,
|
||||
y: this._cell.y,
|
||||
smallID: this._owner.isPlayer() ? this._owner.smallID() : 0,
|
||||
type: GameUpdateType.Tile,
|
||||
pos: {
|
||||
x: this._cell.x,
|
||||
y: this._cell.y
|
||||
},
|
||||
owner: this._owner.isPlayer() ? this._owner.smallID() : 0,
|
||||
hasFallout: this._hasFallout,
|
||||
hasDefenseBonus: this.hasDefenseBonus(),
|
||||
isBorder: this.isBorder(),
|
||||
borderOnlyChange: borderOnlyChange
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MessageType } from './Game';
|
||||
import { GameUpdateType, MessageType, UnitUpdate } from './Game';
|
||||
import { UnitViewData, ViewData, ViewSerializable } from "../GameView";
|
||||
import { simpleHash, within } from "../Util";
|
||||
import { MutableUnit, Tile, TerraNullius, UnitType, Player, UnitInfo } from "./Game";
|
||||
@@ -22,6 +22,19 @@ export class UnitImpl implements MutableUnit {
|
||||
this._health = (this.g.unitInfo(_type).maxHealth ?? 2) / 2
|
||||
}
|
||||
|
||||
toUpdate(oldTile: Tile): UnitUpdate {
|
||||
return {
|
||||
type: GameUpdateType.Unit,
|
||||
unitType: this._type,
|
||||
id: this._id,
|
||||
troops: this._troops,
|
||||
ownerID: this._owner.smallID(),
|
||||
isActive: this._active,
|
||||
pos: this._tile.cell().pos(),
|
||||
oldPos: oldTile.cell().pos()
|
||||
}
|
||||
}
|
||||
|
||||
toViewData(): UnitViewData {
|
||||
return {
|
||||
id: this._id,
|
||||
|
||||
Reference in New Issue
Block a user