in progress

This commit is contained in:
evanpelle
2025-01-08 19:32:31 -08:00
committed by Evan
parent 3dbe2784b9
commit 162b6dc349
15 changed files with 234 additions and 91 deletions
+1 -1
View File
@@ -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 -1
View File
@@ -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";
+12 -12
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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';
+2 -2
View File
@@ -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
}
}
+10 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
})
}
}
+4 -4
View File
@@ -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[] {
+12 -4
View File
@@ -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
}
}
+14 -1
View File
@@ -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,