combine Player & MutablePlayer interfaces

This commit is contained in:
evanpelle
2025-01-23 11:08:53 -08:00
committed by Evan
parent 4034d11015
commit 7d15c0c065
30 changed files with 169 additions and 174 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
import { Game, Player, Cell, NameViewData, MutablePlayer } from '../../core/game/Game';
import { Game, Player, Cell, NameViewData } from '../../core/game/Game';
import { calculateBoundingBox, within } from '../../core/Util';
export interface Point {
@@ -15,7 +15,7 @@ export interface Rectangle {
export function placeName(game: Game, player: MutablePlayer): NameViewData {
export function placeName(game: Game, player: Player): NameViewData {
const boundingBox = player.largestClusterBoundingBox ?? calculateBoundingBox(game, player.borderTiles());
+4 -4
View File
@@ -1,5 +1,5 @@
import { PriorityQueue } from "@datastructures-js/priority-queue";
import { Cell, Execution, MutableGame, MutablePlayer, Player, PlayerID, PlayerType, TerrainType, TerraNullius } from "../game/Game";
import { Cell, Execution, MutableGame, Player, PlayerID, PlayerType, TerrainType, TerraNullius } from "../game/Game";
import { PseudoRandom } from "../PseudoRandom";
import { MessageType } from '../game/Game';
import { renderNumber } from "../../client/Utils";
@@ -20,8 +20,8 @@ export class AttackExecution implements Execution {
});
private random = new PseudoRandom(123)
private _owner: MutablePlayer
private target: MutablePlayer | TerraNullius
private _owner: Player
private target: Player | TerraNullius
private mg: MutableGame
@@ -227,7 +227,7 @@ export class AttackExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return this._owner
}
+3 -3
View File
@@ -1,4 +1,4 @@
import { Cell, Execution, MutableGame, MutablePlayer, MutableUnit, PlayerID, TerrainType, Unit, UnitType } from "../game/Game";
import { Cell, Execution, MutableGame, Player, MutableUnit, PlayerID, TerrainType, Unit, UnitType } from "../game/Game";
import { PathFinder } from "../pathfinding/PathFinding";
import { PathFindResultType } from "../pathfinding/AStar";
import { PseudoRandom } from "../PseudoRandom";
@@ -10,7 +10,7 @@ import { TileRef } from "../game/GameMap";
export class BattleshipExecution implements Execution {
private random: PseudoRandom
private _owner: MutablePlayer
private _owner: Player
private active = true
private battleship: MutableUnit = null
private mg: MutableGame = null
@@ -110,7 +110,7 @@ export class BattleshipExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return this._owner
}
+3 -3
View File
@@ -1,4 +1,4 @@
import { Cell, Execution, MutableGame, MutablePlayer, Player, PlayerID, PlayerInfo, PlayerType, TerraNullius } from "../game/Game"
import { Cell, Execution, MutableGame, Player, PlayerType, TerraNullius } from "../game/Game"
import { PseudoRandom } from "../PseudoRandom"
import { simpleHash } from "../Util";
import { AttackExecution } from "./AttackExecution";
@@ -12,7 +12,7 @@ export class BotExecution implements Execution {
private neighborsTerraNullius = true
constructor(private bot: MutablePlayer) {
constructor(private bot: Player) {
this.random = new PseudoRandom(simpleHash(bot.id()))
this.attackRate = this.random.nextInt(10, 50)
}
@@ -99,7 +99,7 @@ export class BotExecution implements Execution {
))
}
owner(): MutablePlayer {
owner(): Player {
return this.bot
}
+3 -3
View File
@@ -1,10 +1,10 @@
import { consolex } from "../Consolex";
import { Execution, MutableGame, MutablePlayer, MutableUnit, PlayerID, UnitType } from "../game/Game";
import { Execution, MutableGame, Player, MutableUnit, PlayerID, UnitType } from "../game/Game";
import { TileRef } from "../game/GameMap";
export class CityExecution implements Execution {
private player: MutablePlayer
private player: Player
private mg: MutableGame
private city: MutableUnit
private active: boolean = true
@@ -32,7 +32,7 @@ export class CityExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+3 -3
View File
@@ -1,10 +1,10 @@
import { consolex } from "../Consolex";
import { Cell, DefenseBonus, Execution, MutableGame, MutablePlayer, MutableUnit, PlayerID, UnitType } from "../game/Game";
import { Cell, DefenseBonus, Execution, MutableGame, Player, MutableUnit, PlayerID, UnitType } from "../game/Game";
import { manhattanDistFN, TileRef } from "../game/GameMap";
export class DefensePostExecution implements Execution {
private player: MutablePlayer
private player: Player
private mg: MutableGame
private post: MutableUnit
private active: boolean = true
@@ -42,7 +42,7 @@ export class DefensePostExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+3 -3
View File
@@ -1,4 +1,4 @@
import { Cell, Execution, MutableGame, MutablePlayer, MutableUnit, PlayerID, TerrainType, UnitType } from "../game/Game";
import { Cell, Execution, MutableGame, Player, MutableUnit, PlayerID, TerrainType, UnitType } from "../game/Game";
import { PathFinder } from "../pathfinding/PathFinding";
import { PathFindResultType } from "../pathfinding/AStar";
import { PseudoRandom } from "../PseudoRandom";
@@ -9,7 +9,7 @@ import { TileRef } from "../game/GameMap";
export class DestroyerExecution implements Execution {
private random: PseudoRandom
private _owner: MutablePlayer
private _owner: Player
private active = true
private destroyer: MutableUnit = null
private mg: MutableGame = null
@@ -118,7 +118,7 @@ export class DestroyerExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return this._owner
}
+4 -4
View File
@@ -1,10 +1,10 @@
import { consolex } from "../Consolex";
import { Execution, MutableGame, MutablePlayer, PlayerID } from "../game/Game";
import { Execution, MutableGame, Player, PlayerID } from "../game/Game";
export class DonateExecution implements Execution {
private sender: MutablePlayer
private recipient: MutablePlayer
private sender: Player
private recipient: Player
private active = true
@@ -33,7 +33,7 @@ export class DonateExecution implements Execution {
this.active = false
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+4 -4
View File
@@ -1,10 +1,10 @@
import { consolex } from "../Consolex";
import { AllPlayers, Execution, MutableGame, MutablePlayer, PlayerID, PlayerType, UnitType } from "../game/Game";
import { AllPlayers, Execution, MutableGame, Player, PlayerID, PlayerType, UnitType } from "../game/Game";
export class EmojiExecution implements Execution {
private requestor: MutablePlayer
private recipient: MutablePlayer | typeof AllPlayers
private requestor: Player
private recipient: Player | typeof AllPlayers
private active = true
@@ -32,7 +32,7 @@ export class EmojiExecution implements Execution {
this.active = false
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerInfo, TerraNullius, PlayerType, Alliance, UnitType } from "../game/Game";
import { Cell, Execution, MutableGame, Game, Player, PlayerInfo, TerraNullius, PlayerType, Alliance, UnitType } from "../game/Game";
import { AttackIntent, BoatAttackIntentSchema, GameID, Intent, Turn } from "../Schemas";
import { AttackExecution } from "./AttackExecution";
import { SpawnExecution } from "./SpawnExecution";
+3 -3
View File
@@ -1,4 +1,4 @@
import { AllianceRequest, Cell, Difficulty, Execution, MutableGame, MutablePlayer, Player, PlayerInfo, PlayerType, Relation, TerrainType, TerraNullius, UnitType } from "../game/Game"
import { AllianceRequest, Cell, Difficulty, Execution, MutableGame, Player, PlayerInfo, PlayerType, Relation, TerrainType, TerraNullius, UnitType } from "../game/Game"
import { PseudoRandom } from "../PseudoRandom"
import { AttackExecution } from "./AttackExecution";
import { TransportShipExecution } from "./TransportShipExecution";
@@ -24,7 +24,7 @@ export class FakeHumanExecution implements Execution {
private active = true
private random: PseudoRandom;
private mg: MutableGame
private player: MutablePlayer = null
private player: Player = null
private enemy: Player | null = null
@@ -476,7 +476,7 @@ export class FakeHumanExecution implements Execution {
return this.mg.bfs(tile, andFN((gm, t) => gm.isLand(t), manhattanDistFN(tile, 10))).size < 50
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+3 -3
View File
@@ -1,12 +1,12 @@
import { consolex } from "../Consolex";
import { Cell, Execution, MutableGame, MutablePlayer, MutableUnit, Player, PlayerID, UnitType } from "../game/Game";
import { Cell, Execution, MutableGame, Player, MutableUnit, PlayerID, UnitType } from "../game/Game";
import { TileRef } from "../game/GameMap";
export class MissileSiloExecution implements Execution {
private active = true
private mg: MutableGame
private player: MutablePlayer
private player: Player
private silo: MutableUnit
constructor(
@@ -31,7 +31,7 @@ export class MissileSiloExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+4 -4
View File
@@ -1,5 +1,5 @@
import { nextTick } from "process";
import { Cell, Execution, MutableGame, MutablePlayer, PlayerID, MutableUnit, UnitType, Player, TerraNullius } from "../game/Game";
import { Cell, Execution, MutableGame, Player, PlayerID, MutableUnit, UnitType, TerraNullius } from "../game/Game";
import { PathFinder } from "../pathfinding/PathFinding";
import { PathFindResultType } from "../pathfinding/AStar";
import { PseudoRandom } from "../PseudoRandom";
@@ -8,7 +8,7 @@ import { TileRef } from "../game/GameMap";
export class NukeExecution implements Execution {
private player: MutablePlayer
private player: Player
private active = true
@@ -76,7 +76,7 @@ export class NukeExecution implements Execution {
const ratio = Object.fromEntries(
this.mg.players().map(p => [p.id(), (p.troops() + p.workers()) / p.numTilesOwned()])
)
const attacked = new Map<MutablePlayer, number>()
const attacked = new Map<Player, number>()
for (const tile of toDestroy) {
const owner = this.mg.owner(tile)
if (owner.isPlayer()) {
@@ -116,7 +116,7 @@ export class NukeExecution implements Execution {
this.nuke.delete(false)
}
owner(): MutablePlayer {
owner(): Player {
return this.player
}
+4 -4
View File
@@ -1,5 +1,5 @@
import { Config } from "../configuration/Config"
import { Execution, MutableGame, MutablePlayer, Player, PlayerID, TerraNullius, UnitType } from "../game/Game"
import { Execution, MutableGame, Player, PlayerID, TerraNullius, UnitType } from "../game/Game"
import { calculateBoundingBox, getMode, inscribed, simpleHash } from "../Util"
import { GameImpl } from "../game/GameImpl"
import { consolex } from "../Consolex"
@@ -9,7 +9,7 @@ export class PlayerExecution implements Execution {
private readonly ticksPerClusterCalc = 20
private player: MutablePlayer
private player: Player
private config: Config
private lastCalc = 0
private mg: MutableGame
@@ -168,7 +168,7 @@ export class PlayerExecution implements Execution {
consolex.warn('mode player is null')
}
for (const tile of tiles) {
(modePlayer as MutablePlayer).conquer(tile)
(modePlayer as Player).conquer(tile)
}
}
@@ -201,7 +201,7 @@ export class PlayerExecution implements Execution {
return clusters
}
owner(): MutablePlayer {
owner(): Player {
return this.player
}
+3 -3
View File
@@ -1,4 +1,4 @@
import { AllPlayers, Cell, Execution, MutableGame, MutablePlayer, MutableUnit, Player, PlayerID, TerrainType, UnitType } from "../game/Game";
import { AllPlayers, Cell, Execution, MutableGame, Player, MutableUnit, PlayerID, TerrainType, UnitType } from "../game/Game";
import { PathFinder } from "../pathfinding/PathFinding";
import { PathFindResultType } from "../pathfinding/AStar";
import { PseudoRandom } from "../PseudoRandom";
@@ -114,7 +114,7 @@ export class PortExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return null
}
@@ -126,7 +126,7 @@ export class PortExecution implements Execution {
return false
}
player(): MutablePlayer {
player(): Player {
return this.port.owner()
}
@@ -1,9 +1,9 @@
import { consolex } from "../Consolex";
import { Execution, MutableGame, MutablePlayer, PlayerID } from "../game/Game";
import { Execution, MutableGame, Player, PlayerID } from "../game/Game";
export class SetTargetTroopRatioExecution implements Execution {
private player: MutablePlayer
private player: Player
private active = true
@@ -23,7 +23,7 @@ export class SetTargetTroopRatioExecution implements Execution {
this.active = false
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+3 -3
View File
@@ -1,4 +1,4 @@
import { Execution, MutableGame, MutablePlayer, MutableUnit, Unit, UnitType } from "../game/Game";
import { Execution, MutableGame, Player, MutableUnit, Unit, UnitType } from "../game/Game";
import { PathFinder } from "../pathfinding/PathFinding";
import { PathFindResultType } from "../pathfinding/AStar";
import { consolex } from "../Consolex";
@@ -10,7 +10,7 @@ export class ShellExecution implements Execution {
private pathFinder: PathFinder
private shell: MutableUnit
constructor(private spawn: TileRef, private _owner: MutablePlayer, private ownerUnit: Unit, private target: MutableUnit) {
constructor(private spawn: TileRef, private _owner: Player, private ownerUnit: Unit, private target: MutableUnit) {
}
@@ -53,7 +53,7 @@ export class ShellExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return null
}
isActive(): boolean {
+2 -2
View File
@@ -1,4 +1,4 @@
import { Cell, Execution, MutableGame, MutablePlayer, PlayerInfo, PlayerType } from "../game/Game"
import { Cell, Execution, MutableGame, Player, PlayerInfo, PlayerType } from "../game/Game"
import { TileRef } from "../game/GameMap"
import { BotExecution } from "./BotExecution"
import { PlayerExecution } from "./PlayerExecution"
@@ -44,7 +44,7 @@ export class SpawnExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return null
}
isActive(): boolean {
+4 -4
View File
@@ -1,9 +1,9 @@
import { Execution, MutableGame, MutablePlayer, PlayerID } from "../game/Game";
import { Execution, MutableGame, Player, PlayerID } from "../game/Game";
export class TargetPlayerExecution implements Execution {
private requestor: MutablePlayer
private target: MutablePlayer
private requestor: Player
private target: Player
private active = true
@@ -23,7 +23,7 @@ export class TargetPlayerExecution implements Execution {
this.active = false
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+3 -3
View File
@@ -1,6 +1,6 @@
import { MessageType } from '../game/Game';
import { renderNumber } from "../../client/Utils";
import { AllPlayers, Cell, Execution, MutableGame, MutablePlayer, MutableUnit, Player, PlayerID, UnitType } from "../game/Game";
import { AllPlayers, Cell, Execution, MutableGame, MutableUnit, Player, PlayerID, UnitType } from "../game/Game";
import { PathFinder } from "../pathfinding/PathFinding";
import { PathFindResultType } from "../pathfinding/AStar";
import { distSortUnit } from "../Util";
@@ -11,7 +11,7 @@ export class TradeShipExecution implements Execution {
private active = true
private mg: MutableGame
private origOwner: MutablePlayer
private origOwner: Player
private tradeShip: MutableUnit
private index = 0
private wasCaptured = false
@@ -116,7 +116,7 @@ export class TradeShipExecution implements Execution {
this.index++
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+4 -4
View File
@@ -1,4 +1,4 @@
import { Unit, Cell, Execution, MutableUnit, MutableGame, MutablePlayer, Player, PlayerID, TerraNullius, UnitType, TerrainType } from "../game/Game";
import { Unit, Cell, Execution, MutableUnit, MutableGame, Player, PlayerID, TerraNullius, UnitType, TerrainType } from "../game/Game";
import { AttackExecution } from "./AttackExecution";
import { MessageType } from '../game/Game';
import { PathFinder } from "../pathfinding/PathFinding";
@@ -17,8 +17,8 @@ export class TransportShipExecution implements Execution {
private active = true
private mg: MutableGame
private attacker: MutablePlayer
private target: MutablePlayer | TerraNullius
private attacker: Player
private target: Player | TerraNullius
// TODO make private
public path: TileRef[]
@@ -133,7 +133,7 @@ export class TransportShipExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return this.attacker
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { EventBus, GameEvent } from "../EventBus"
import { Execution, MutableGame, MutablePlayer, Player, PlayerID } from "../game/Game"
import { Execution, MutableGame, Player, PlayerID } from "../game/Game"
export class WinEvent implements GameEvent {
constructor(public readonly winner: Player) { }
@@ -33,7 +33,7 @@ export class WinCheckExecution implements Execution {
}
}
owner(): MutablePlayer {
owner(): Player {
return null
}
@@ -1,11 +1,11 @@
import { consolex } from "../../Consolex";
import {AllianceRequest, Execution, MutableGame, MutablePlayer, Player, PlayerID} from "../../game/Game";
import {AllianceRequest, Execution, MutableGame, Player, PlayerID} from "../../game/Game";
export class AllianceRequestExecution implements Execution {
private active = true
private mg: MutableGame = null
private requestor: MutablePlayer;
private recipient: MutablePlayer
private requestor: Player;
private recipient: Player
constructor(private requestorID: PlayerID, private recipientID: PlayerID) { }
@@ -26,7 +26,7 @@ export class AllianceRequestExecution implements Execution {
this.active = false
}
owner(): MutablePlayer {
owner(): Player {
return null
}
@@ -1,11 +1,11 @@
import { consolex } from "../../Consolex";
import { AllianceRequest, Execution, MutableGame, MutablePlayer, Player, PlayerID } from "../../game/Game";
import { AllianceRequest, Execution, MutableGame, Player, PlayerID } from "../../game/Game";
export class AllianceRequestReplyExecution implements Execution {
private active = true
private mg: MutableGame = null
private requestor: MutablePlayer;
private recipient: MutablePlayer
private requestor: Player;
private recipient: Player
constructor(private requestorID: PlayerID, private recipientID: PlayerID, private accept: boolean) { }
@@ -35,7 +35,7 @@ export class AllianceRequestReplyExecution implements Execution {
this.active = false
}
owner(): MutablePlayer {
owner(): Player {
return null
}
@@ -1,10 +1,10 @@
import { consolex } from "../../Consolex";
import { AllianceRequest, Execution, MutableGame, MutablePlayer, Player, PlayerID } from "../../game/Game";
import { AllianceRequest, Execution, MutableGame, Player, PlayerID } from "../../game/Game";
export class BreakAllianceExecution implements Execution {
private active = true
private requestor: MutablePlayer;
private recipient: MutablePlayer
private requestor: Player;
private recipient: Player
private mg: MutableGame
constructor(private requestorID: PlayerID, private recipientID: PlayerID) { }
@@ -31,7 +31,7 @@ export class BreakAllianceExecution implements Execution {
this.active = false
}
owner(): MutablePlayer {
owner(): Player {
return null
}
+3 -3
View File
@@ -1,4 +1,4 @@
import {MutableAlliance, MutableGame, MutablePlayer, Player, Tick} from "./Game";
import {MutableAlliance, MutableGame, Player, Tick} from "./Game";
import {GameImpl} from "./GameImpl";
import {PlayerImpl} from "./PlayerImpl";
@@ -17,11 +17,11 @@ export class AllianceImpl implements MutableAlliance {
return this.requestor_
}
requestor(): MutablePlayer {
requestor(): Player {
return this.requestor_
}
recipient(): MutablePlayer {
recipient(): Player {
return this.recipient_
}
+4 -4
View File
@@ -1,16 +1,16 @@
import { AllianceRequestUpdate, GameUpdateType, MutableAllianceRequest, MutablePlayer, Player, Tick } from "./Game";
import { AllianceRequestUpdate, GameUpdateType, MutableAllianceRequest, Player, Tick } from "./Game";
import { GameImpl } from "./GameImpl";
export class AllianceRequestImpl implements MutableAllianceRequest {
constructor(private requestor_: MutablePlayer, private recipient_: MutablePlayer, private tickCreated: number, private game: GameImpl) { }
constructor(private requestor_: Player, private recipient_: Player, private tickCreated: number, private game: GameImpl) { }
requestor(): MutablePlayer {
requestor(): Player {
return this.requestor_;
}
recipient(): MutablePlayer {
recipient(): Player {
return this.recipient_;
}
+64 -69
View File
@@ -130,7 +130,7 @@ export interface ExecutionView {
export interface Execution extends ExecutionView {
init(mg: MutableGame, ticks: number): void
tick(ticks: number): void
owner(): MutablePlayer
owner(): Player
}
export interface AllianceRequest {
@@ -142,8 +142,8 @@ export interface AllianceRequest {
export interface MutableAllianceRequest extends AllianceRequest {
accept(): void
reject(): void
requestor(): MutablePlayer
recipient(): MutablePlayer
requestor(): Player
recipient(): Player
}
export interface Alliance {
@@ -155,7 +155,7 @@ export interface Alliance {
export interface MutableAlliance extends Alliance {
expire(): void
other(player: Player): MutablePlayer
other(player: Player): Player
}
export class PlayerInfo {
@@ -189,7 +189,7 @@ export interface Unit {
export interface MutableUnit extends Unit {
move(tile: TileRef): void
owner(): MutablePlayer
owner(): Player
setTroops(troops: number): void
info(): UnitInfo
delete(displayerMessage?: boolean): void
@@ -205,6 +205,7 @@ export interface TerraNullius {
}
export interface Player {
// Basic Info
smallID(): number
info(): PlayerInfo
name(): string
@@ -212,75 +213,30 @@ export interface Player {
clientID(): ClientID
id(): PlayerID
type(): PlayerType
units(...types: UnitType[]): Unit[]
isAlive(): boolean
borderTiles(): ReadonlySet<TileRef>
isPlayer(): this is Player
numTilesOwned(): number
sharesBorderWith(other: Player | TerraNullius): boolean
incomingAllianceRequests(): AllianceRequest[]
outgoingAllianceRequests(): AllianceRequest[]
alliances(): Alliance[]
allies(): Player[]
isAlliedWith(other: Player): boolean
allianceWith(other: Player): Alliance | null
// Includes recent requests that are in cooldown
// TODO: why can't I have "canSendAllyRequest" function instead?
recentOrPendingAllianceRequestWith(other: Player): boolean
// How this player feels about other player.
relation(other: Player): Relation
// Sorted from most hated to most liked
allRelationsSorted(): { player: Player, relation: Relation }[]
transitiveTargets(): Player[]
isTraitor(): boolean
canTarget(other: Player): boolean
toString(): string
canSendEmoji(recipient: Player | typeof AllPlayers): boolean
outgoingEmojis(): EmojiMessage[]
canDonate(recipient: Player): boolean
gold(): Gold
// Population = troops + workers
population(): number
workers(): number
// Number between 0, 1
targetTroopRatio(): number
troops(): number
// If can build returns the spawn tile, false otherwise
canBuild(type: UnitType, targetTile: TileRef): TileRef | false
lastTileChange(): Tick
}
export interface MutablePlayer extends Player {
// State & Properties
isAlive(): boolean
isTraitor(): boolean
largestClusterBoundingBox: { min: Cell, max: Cell } | null
// Targets for this player
targets(): Player[]
// Targets of player and all allies.
neighbors(): (Player | TerraNullius)[]
lastTileChange(): Tick
// Territory
tiles(): ReadonlySet<TileRef>
borderTiles(): ReadonlySet<TileRef>
numTilesOwned(): number
conquer(tile: TileRef): void
relinquish(tile: TileRef): void
executions(): Execution[]
neighbors(): (MutablePlayer | TerraNullius)[]
units(...types: UnitType[]): MutableUnit[]
incomingAllianceRequests(): MutableAllianceRequest[]
outgoingAllianceRequests(): MutableAllianceRequest[]
alliances(): MutableAlliance[]
allies(): MutablePlayer[]
allianceWith(other: Player): MutableAlliance | null
breakAlliance(alliance: Alliance): void
createAllianceRequest(recipient: Player): MutableAllianceRequest
updateRelation(other: Player, delta: number): void
decayRelations(): void
target(other: Player): void
targets(): MutablePlayer[]
transitiveTargets(): MutablePlayer[]
sendEmoji(recipient: Player | typeof AllPlayers, emoji: string): void
donate(recipient: MutablePlayer, troops: number): void
// Resources & Population
gold(): Gold
population(): number
workers(): number
troops(): number
targetTroopRatio(): number
addGold(toAdd: Gold): void
removeGold(toRemove: Gold): void
addWorkers(toAdd: number): void
removeWorkers(toRemove: number): void
setTargetTroopRatio(target: number): void
@@ -288,9 +244,48 @@ export interface MutablePlayer extends Player {
addTroops(troops: number): void
removeTroops(troops: number): number
// Units
units(...types: UnitType[]): MutableUnit[]
canBuild(type: UnitType, targetTile: TileRef): TileRef | false
buildUnit(type: UnitType, troops: number, tile: TileRef): MutableUnit
captureUnit(unit: MutableUnit): void
// Relations & Diplomacy
neighbors(): (Player | TerraNullius)[]
sharesBorderWith(other: Player | TerraNullius): boolean
relation(other: Player): Relation
allRelationsSorted(): { player: Player, relation: Relation }[]
updateRelation(other: Player, delta: number): void
decayRelations(): void
// Alliances
incomingAllianceRequests(): MutableAllianceRequest[]
outgoingAllianceRequests(): MutableAllianceRequest[]
alliances(): MutableAlliance[]
allies(): Player[]
isAlliedWith(other: Player): boolean
allianceWith(other: Player): MutableAlliance | null
recentOrPendingAllianceRequestWith(other: Player): boolean
breakAlliance(alliance: Alliance): void
createAllianceRequest(recipient: Player): MutableAllianceRequest
// Targeting
canTarget(other: Player): boolean
target(other: Player): void
targets(): Player[]
transitiveTargets(): Player[]
// Communication
canSendEmoji(recipient: Player | typeof AllPlayers): boolean
outgoingEmojis(): EmojiMessage[]
sendEmoji(recipient: Player | typeof AllPlayers, emoji: string): void
// Trading
canDonate(recipient: Player): boolean
donate(recipient: Player, troops: number): void
// Misc
executions(): Execution[]
toUpdate(): PlayerUpdate
}
@@ -322,11 +317,11 @@ export interface Game extends GameMap {
}
export interface MutableGame extends Game {
player(id: PlayerID): MutablePlayer
playerByClientID(id: ClientID): MutablePlayer | null
players(): MutablePlayer[]
allPlayers(): MutablePlayer[]
addPlayer(playerInfo: PlayerInfo, manpower: number): MutablePlayer
player(id: PlayerID): Player
playerByClientID(id: ClientID): Player | null
players(): Player[]
allPlayers(): Player[]
addPlayer(playerInfo: PlayerInfo, manpower: number): Player
executions(): Execution[]
units(...types: UnitType[]): MutableUnit[]
addTileDefenseBonus(tile: TileRef, unit: Unit, amount: number): DefenseBonus
+8 -8
View File
@@ -1,5 +1,5 @@
import { Config } from "../configuration/Config";
import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerID, PlayerInfo, Player, TerraNullius, Unit, MutableAllianceRequest, Alliance, Nation, UnitType, UnitInfo, DefenseBonus, GameUpdate, GameUpdateType, AllPlayers, GameUpdates, TerrainType, EmojiMessage } from "./Game";
import { Cell, Execution, MutableGame, Game, PlayerID, PlayerInfo, Player, TerraNullius, Unit, MutableAllianceRequest, Alliance, Nation, UnitType, UnitInfo, DefenseBonus, GameUpdate, GameUpdateType, AllPlayers, GameUpdates, TerrainType, EmojiMessage } from "./Game";
import { NationMap } from "./TerrainMapLoader";
import { PlayerImpl } from "./PlayerImpl";
import { TerraNulliusImpl } from "./TerraNulliusImpl";
@@ -120,7 +120,7 @@ export class GameImpl implements MutableGame {
return this.nations_
}
createAllianceRequest(requestor: MutablePlayer, recipient: MutablePlayer): MutableAllianceRequest {
createAllianceRequest(requestor: Player, recipient: Player): MutableAllianceRequest {
if (requestor.isAlliedWith(recipient)) {
consolex.log('cannot request alliance, already allied')
return
@@ -240,11 +240,11 @@ export class GameImpl implements MutableGame {
this.execs = activeExecs
}
players(): MutablePlayer[] {
players(): Player[] {
return Array.from(this._players.values()).filter(p => p.isAlive())
}
allPlayers(): MutablePlayer[] {
allPlayers(): Player[] {
return Array.from(this._players.values())
}
@@ -262,11 +262,11 @@ export class GameImpl implements MutableGame {
}
playerView(id: PlayerID): MutablePlayer {
playerView(id: PlayerID): Player {
return this.player(id)
}
addPlayer(playerInfo: PlayerInfo, manpower: number): MutablePlayer {
addPlayer(playerInfo: PlayerInfo, manpower: number): Player {
let player = new PlayerImpl(this, this.nextPlayerID, playerInfo, manpower)
this._playersBySmallID.push(player)
this.nextPlayerID++
@@ -274,14 +274,14 @@ export class GameImpl implements MutableGame {
return player
}
player(id: PlayerID | null): MutablePlayer {
player(id: PlayerID | null): Player {
if (!this._players.has(id)) {
throw new Error(`Player with id ${id} not found`)
}
return this._players.get(id)
}
playerByClientID(id: ClientID): MutablePlayer | null {
playerByClientID(id: ClientID): Player | null {
for (const [pID, player] of this._players) {
if (player.clientID() == id) {
return player
+10 -10
View File
@@ -1,4 +1,4 @@
import { MutablePlayer, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance, Tick, AllPlayers, Gold, UnitType, Unit, MutableUnit, Relation, PlayerUpdate, GameUpdateType, EmojiMessage } from "./Game";
import { Player, PlayerInfo, PlayerID, PlayerType, TerraNullius, Cell, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance, Tick, AllPlayers, Gold, UnitType, Unit, MutableUnit, Relation, PlayerUpdate, GameUpdateType, EmojiMessage } from "./Game";
import { ClientID } from "../Schemas";
import { assertNever, closestOceanShoreFromPlayer, distSortUnit, simpleHash, sourceDstOceanShore, within } from "../Util";
import { CellString, GameImpl } from "./GameImpl";
@@ -18,7 +18,7 @@ class Donation {
constructor(public readonly recipient: Player, public readonly tick: Tick) { }
}
export class PlayerImpl implements MutablePlayer {
export class PlayerImpl implements Player {
public _lastTileChange: number = 0
@@ -138,8 +138,8 @@ export class PlayerImpl implements MutablePlayer {
return this._borderTiles;
}
neighbors(): (MutablePlayer | TerraNullius)[] {
const ns: Set<(MutablePlayer | TerraNullius)> = new Set();
neighbors(): (Player | TerraNullius)[] {
const ns: Set<(Player | TerraNullius)> = new Set();
for (const border of this.borderTiles()) {
for (const neighbor of this.mg.map().neighbors(border)) {
if (this.mg.map().isLake(neighbor)) {
@@ -153,7 +153,7 @@ export class PlayerImpl implements MutablePlayer {
return Array.from(ns);
}
isPlayer(): this is MutablePlayer { return true as const; }
isPlayer(): this is Player { return true as const; }
setTroops(troops: number) { this._troops = Math.floor(troops); }
conquer(tile: TileRef) { this.mg.conquer(this, tile); }
relinquish(tile: TileRef) {
@@ -180,7 +180,7 @@ export class PlayerImpl implements MutablePlayer {
return this.mg.alliances_.filter(a => a.requestor() == this || a.recipient() == this)
}
allies(): MutablePlayer[] {
allies(): Player[] {
return this.alliances().map(a => a.other(this))
}
@@ -231,7 +231,7 @@ export class PlayerImpl implements MutablePlayer {
if (this.isAlliedWith(recipient)) {
throw new Error(`cannot create alliance request, already allies`)
}
return this.mg.createAllianceRequest(this, recipient as MutablePlayer)
return this.mg.createAllianceRequest(this, recipient as Player)
}
relation(other: Player): Relation {
@@ -310,10 +310,10 @@ export class PlayerImpl implements MutablePlayer {
.map(t => t.target as PlayerImpl)
}
transitiveTargets(): MutablePlayer[] {
transitiveTargets(): Player[] {
const ts = this.alliances().map(a => a.other(this)).flatMap(ally => ally.targets())
ts.push(...this.targets())
return [...new Set(ts)] as MutablePlayer[]
return [...new Set(ts)] as Player[]
}
sendEmoji(recipient: Player | typeof AllPlayers, emoji: string): void {
@@ -361,7 +361,7 @@ export class PlayerImpl implements MutablePlayer {
return true
}
donate(recipient: MutablePlayer, troops: number): void {
donate(recipient: Player, troops: number): void {
this.sentDonations.push(new Donation(recipient, this.mg.ticks()))
recipient.addTroops(this.removeTroops(troops))
this.mg.displayMessage(`Sent ${renderTroops(troops)} troops to ${recipient.name()}`, MessageType.INFO, this.id())