Create Unit class

This commit is contained in:
Evan
2024-11-10 11:06:09 -08:00
parent 3ac8dbddc5
commit 6a1a09c335
7 changed files with 61 additions and 55 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
import { Colord } from "colord"; import { Colord } from "colord";
import { Theme } from "../../../core/configuration/Config"; import { Theme } from "../../../core/configuration/Config";
import { Boat, BoatEvent, Cell, Game, Tile } from "../../../core/game/Game"; import { Unit, BoatEvent, Cell, Game, Tile } from "../../../core/game/Game";
import { bfs, dist } from "../../../core/Util"; import { bfs, dist } from "../../../core/Util";
import { Layer } from "./Layer"; import { Layer } from "./Layer";
import { EventBus } from "../../../core/EventBus"; import { EventBus } from "../../../core/EventBus";
@@ -10,7 +10,7 @@ export class UnitLayer implements Layer {
private context: CanvasRenderingContext2D private context: CanvasRenderingContext2D
private imageData: ImageData private imageData: ImageData
private boatToTrail = new Map<Boat, Set<Tile>>() private boatToTrail = new Map<Unit, Set<Tile>>()
private theme: Theme = null private theme: Theme = null
@@ -1,5 +1,5 @@
import { EventBus } from "../../../../core/EventBus"; import { EventBus } from "../../../../core/EventBus";
import { AllPlayers, Cell, Game, Player } from "../../../../core/game/Game"; import { AllPlayers, Cell, Game, Player, UnitType } from "../../../../core/game/Game";
import { ClientID } from "../../../../core/Schemas"; import { ClientID } from "../../../../core/Schemas";
import { and, bfs, dist, manhattanDist, manhattanDistWrapped, sourceDstOceanShore } from "../../../../core/Util"; import { and, bfs, dist, manhattanDist, manhattanDistWrapped, sourceDstOceanShore } from "../../../../core/Util";
import { ContextMenuEvent, MouseUpEvent } from "../../../InputHandler"; import { ContextMenuEvent, MouseUpEvent } from "../../../InputHandler";
@@ -305,7 +305,7 @@ export class RadialMenu implements Layer {
if (!tile.isLand()) { if (!tile.isLand()) {
return return
} }
if (myPlayer.boats().length >= this.game.config().boatMaxNumber()) { if (myPlayer.units(UnitType.TransportShip).length >= this.game.config().boatMaxNumber()) {
return return
} }
+3 -3
View File
@@ -1,5 +1,5 @@
import { PriorityQueue } from "@datastructures-js/priority-queue"; import { PriorityQueue } from "@datastructures-js/priority-queue";
import { Boat, Cell, Execution, MutableBoat, MutableGame, MutablePlayer, Player, PlayerID, TerraNullius, Tile, TileEvent } from "../game/Game"; import { Unit, Cell, Execution, MutableUnit, MutableGame, MutablePlayer, Player, PlayerID, TerraNullius, Tile, TileEvent, UnitType } from "../game/Game";
import { and, bfs, manhattanDistWrapped, sourceDstOceanShore } from "../Util"; import { and, bfs, manhattanDistWrapped, sourceDstOceanShore } from "../Util";
import { AttackExecution } from "./AttackExecution"; import { AttackExecution } from "./AttackExecution";
import { DisplayMessageEvent, MessageType } from "../../client/graphics/layers/EventsDisplay"; import { DisplayMessageEvent, MessageType } from "../../client/graphics/layers/EventsDisplay";
@@ -24,7 +24,7 @@ export class BoatAttackExecution implements Execution {
private currTileIndex: number = 0 private currTileIndex: number = 0
private boat: MutableBoat private boat: MutableUnit
private aStarPre: AStar private aStarPre: AStar
private aStarComplete: AStar private aStarComplete: AStar
@@ -48,7 +48,7 @@ export class BoatAttackExecution implements Execution {
this.attacker = mg.player(this.attackerID) this.attacker = mg.player(this.attackerID)
if (this.attacker.boats().length >= mg.config().boatMaxNumber()) { if (this.attacker.units(UnitType.TransportShip).length >= mg.config().boatMaxNumber()) {
mg.displayMessage(`No boats available, max ${mg.config().boatMaxNumber()}`, MessageType.WARN, this.attackerID) mg.displayMessage(`No boats available, max ${mg.config().boatMaxNumber()}`, MessageType.WARN, this.attackerID)
this.active = false this.active = false
this.attacker.addTroops(this.troops) this.attacker.addTroops(this.troops)
+13 -10
View File
@@ -25,6 +25,10 @@ export enum GameMap {
Mena Mena
} }
export enum UnitType {
TransportShip
}
export class Item { export class Item {
constructor(public readonly name: string, public readonly cost: Gold) { } constructor(public readonly name: string, public readonly cost: Gold) { }
} }
@@ -145,18 +149,17 @@ export interface Tile {
onShore(): boolean onShore(): boolean
} }
export interface Boat { export interface Unit {
type(): UnitType
troops(): number troops(): number
tile(): Tile tile(): Tile
owner(): Player owner(): Player
target(): Player | TerraNullius
isActive(): boolean isActive(): boolean
} }
export interface MutableBoat extends Boat { export interface MutableUnit extends Unit {
move(tile: Tile): void move(tile: Tile): void
owner(): MutablePlayer owner(): MutablePlayer
target(): MutablePlayer | TerraNullius
setTroops(troops: number): void setTroops(troops: number): void
delete(): void delete(): void
} }
@@ -175,7 +178,7 @@ export interface Player {
clientID(): ClientID clientID(): ClientID
id(): PlayerID id(): PlayerID
type(): PlayerType type(): PlayerType
boats(): Boat[] units(...types: UnitType[]): Unit[]
ownsTile(cell: Cell): boolean ownsTile(cell: Cell): boolean
isAlive(): boolean isAlive(): boolean
borderTiles(): ReadonlySet<Tile> borderTiles(): ReadonlySet<Tile>
@@ -216,14 +219,14 @@ export interface MutablePlayer extends Player {
relinquish(tile: Tile): void relinquish(tile: Tile): void
executions(): Execution[] executions(): Execution[]
neighbors(): (MutablePlayer | TerraNullius)[] neighbors(): (MutablePlayer | TerraNullius)[]
boats(): MutableBoat[] units(...types: UnitType[]): MutableUnit[]
incomingAllianceRequests(): MutableAllianceRequest[] incomingAllianceRequests(): MutableAllianceRequest[]
outgoingAllianceRequests(): MutableAllianceRequest[] outgoingAllianceRequests(): MutableAllianceRequest[]
alliances(): MutableAlliance[] alliances(): MutableAlliance[]
allianceWith(other: Player): MutableAlliance | null allianceWith(other: Player): MutableAlliance | null
breakAlliance(alliance: Alliance): void breakAlliance(alliance: Alliance): void
createAllianceRequest(recipient: Player): MutableAllianceRequest createAllianceRequest(recipient: Player): MutableAllianceRequest
addBoat(troops: number, tile: Tile, target: Player | TerraNullius): MutableBoat addBoat(troops: number, tile: Tile, target: Player | TerraNullius): MutableUnit
target(other: Player): void target(other: Player): void
targets(): MutablePlayer[] targets(): MutablePlayer[]
transitiveTargets(): MutablePlayer[] transitiveTargets(): MutablePlayer[]
@@ -263,7 +266,7 @@ export interface Game {
nations(): Nation[] nations(): Nation[]
config(): Config config(): Config
displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void
boats(): Boat[] boats(): Unit[]
} }
export interface MutableGame extends Game { export interface MutableGame extends Game {
@@ -272,7 +275,7 @@ export interface MutableGame extends Game {
players(): MutablePlayer[] players(): MutablePlayer[]
addPlayer(playerInfo: PlayerInfo, manpower: number): MutablePlayer addPlayer(playerInfo: PlayerInfo, manpower: number): MutablePlayer
executions(): Execution[] executions(): Execution[]
boats(): MutableBoat[] boats(): MutableUnit[]
} }
export class TileEvent implements GameEvent { export class TileEvent implements GameEvent {
@@ -284,7 +287,7 @@ export class PlayerEvent implements GameEvent {
} }
export class BoatEvent implements GameEvent { export class BoatEvent implements GameEvent {
constructor(public readonly boat: Boat, public oldTile: Tile) { } constructor(public readonly boat: Unit, public oldTile: Tile) { }
} }
export class AllianceRequestEvent implements GameEvent { export class AllianceRequestEvent implements GameEvent {
+6 -6
View File
@@ -1,7 +1,7 @@
import { info } from "console"; import { info } from "console";
import { Config } from "../configuration/Config"; import { Config } from "../configuration/Config";
import { EventBus } from "../EventBus"; import { EventBus } from "../EventBus";
import {Cell, Execution, MutableGame, Game, MutablePlayer, PlayerEvent, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Boat, BoatEvent, PlayerType, MutableAllianceRequest, AllianceRequestReplyEvent, AllianceRequestEvent, BrokeAllianceEvent, MutableAlliance, Alliance, AllianceExpiredEvent, Nation} from "./Game"; import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerEvent, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Unit, BoatEvent as UnitEvent, PlayerType, MutableAllianceRequest, AllianceRequestReplyEvent, AllianceRequestEvent, BrokeAllianceEvent, MutableAlliance, Alliance, AllianceExpiredEvent, Nation } from "./Game";
import { TerrainMap } from "./TerrainMapLoader"; import { TerrainMap } from "./TerrainMapLoader";
import { PlayerImpl } from "./PlayerImpl"; import { PlayerImpl } from "./PlayerImpl";
import { TerraNulliusImpl } from "./TerraNulliusImpl"; import { TerraNulliusImpl } from "./TerraNulliusImpl";
@@ -10,7 +10,7 @@ import {AllianceRequestImpl} from "./AllianceRequestImpl";
import { AllianceImpl } from "./AllianceImpl"; import { AllianceImpl } from "./AllianceImpl";
import { ClientID } from "../Schemas"; import { ClientID } from "../Schemas";
import { DisplayMessageEvent, MessageType } from "../../client/graphics/layers/EventsDisplay"; import { DisplayMessageEvent, MessageType } from "../../client/graphics/layers/EventsDisplay";
import {BoatImpl} from "./BoatImpl"; import { UnitImpl } from "./UnitImpl";
export function createGame(terrainMap: TerrainMap, eventBus: EventBus, config: Config): Game { export function createGame(terrainMap: TerrainMap, eventBus: EventBus, config: Config): Game {
return new GameImpl(terrainMap, eventBus, config) return new GameImpl(terrainMap, eventBus, config)
@@ -58,8 +58,8 @@ export class GameImpl implements MutableGame {
n.strength n.strength
)) ))
} }
boats(): BoatImpl[] { boats(): UnitImpl[] {
return Array.from(this._players.values()).flatMap(p => p._boats) return Array.from(this._players.values()).flatMap(p => p._units)
} }
nations(): Nation[] { nations(): Nation[] {
return this.nations_ return this.nations_
@@ -354,8 +354,8 @@ export class GameImpl implements MutableGame {
return false return false
} }
public fireBoatUpdateEvent(boat: Boat, oldTile: Tile) { public fireUnitUpdateEvent(boat: Unit, oldTile: Tile) {
this.eventBus.emit(new BoatEvent(boat, oldTile)) this.eventBus.emit(new UnitEvent(boat, oldTile))
} }
public breakAlliance(breaker: Player, alliance: Alliance) { public breakAlliance(breaker: Player, alliance: Alliance) {
+10 -9
View File
@@ -1,8 +1,8 @@
import { MutablePlayer, Tile, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance, Tick, TargetPlayerEvent, EmojiMessage, EmojiMessageEvent, AllPlayers, Gold } from "./Game"; import { MutablePlayer, Tile, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance, Tick, TargetPlayerEvent, EmojiMessage, EmojiMessageEvent, AllPlayers, Gold, UnitType } from "./Game";
import { ClientID } from "../Schemas"; import { ClientID } from "../Schemas";
import { processName, simpleHash } from "../Util"; import { processName, simpleHash } from "../Util";
import { CellString, GameImpl } from "./GameImpl"; import { CellString, GameImpl } from "./GameImpl";
import { BoatImpl } from "./BoatImpl"; import { UnitImpl } from "./UnitImpl";
import { TileImpl } from "./TileImpl"; import { TileImpl } from "./TileImpl";
import { TerraNulliusImpl } from "./TerraNulliusImpl"; import { TerraNulliusImpl } from "./TerraNulliusImpl";
import { MessageType } from "../../client/graphics/layers/EventsDisplay"; import { MessageType } from "../../client/graphics/layers/EventsDisplay";
@@ -29,7 +29,7 @@ export class PlayerImpl implements MutablePlayer {
public _borderTiles: Set<Tile> = new Set(); public _borderTiles: Set<Tile> = new Set();
public _boats: BoatImpl[] = []; public _units: UnitImpl[] = [];
public _tiles: Map<CellString, Tile> = new Map<CellString, Tile>(); public _tiles: Map<CellString, Tile> = new Map<CellString, Tile>();
private _name: string; private _name: string;
@@ -73,15 +73,16 @@ export class PlayerImpl implements MutablePlayer {
} }
addBoat(troops: number, tile: Tile, target: Player | TerraNullius): BoatImpl { addBoat(troops: number, tile: Tile): UnitImpl {
const b = new BoatImpl(this.gs, tile, troops, this, target as PlayerImpl | TerraNulliusImpl); const b = new UnitImpl(UnitType.TransportShip, this.gs, tile, troops, this);
this._boats.push(b); this._units.push(b);
this.gs.fireBoatUpdateEvent(b, b.tile()); this.gs.fireUnitUpdateEvent(b, b.tile());
return b; return b;
} }
boats(): BoatImpl[] { units(...types: UnitType[]): UnitImpl[] {
return this._boats; const ts = new Set(types)
return this._units.filter(u => ts.has(u.type()));
} }
sharesBorderWith(other: Player | TerraNullius): boolean { sharesBorderWith(other: Player | TerraNullius): boolean {
@@ -1,24 +1,28 @@
import {MutableBoat, Tile, TerraNullius} from "./Game"; import { MutableUnit, Tile, TerraNullius, UnitType } from "./Game";
import { GameImpl } from "./GameImpl"; import { GameImpl } from "./GameImpl";
import { PlayerImpl } from "./PlayerImpl"; import { PlayerImpl } from "./PlayerImpl";
import { TerraNulliusImpl } from "./TerraNulliusImpl"; import { TerraNulliusImpl } from "./TerraNulliusImpl";
export class BoatImpl implements MutableBoat { export class UnitImpl implements MutableUnit {
private _active = true; private _active = true;
constructor( constructor(
private _type: UnitType,
private g: GameImpl, private g: GameImpl,
private _tile: Tile, private _tile: Tile,
private _troops: number, private _troops: number,
private _owner: PlayerImpl, private _owner: PlayerImpl,
private _target: PlayerImpl | TerraNulliusImpl
) { } ) { }
type(): UnitType {
return this._type
}
move(tile: Tile): void { move(tile: Tile): void {
const oldTile = this._tile; const oldTile = this._tile;
this._tile = tile; this._tile = tile;
this.g.fireBoatUpdateEvent(this, oldTile); this.g.fireUnitUpdateEvent(this, oldTile);
} }
setTroops(troops: number): void { setTroops(troops: number): void {
this._troops = troops; this._troops = troops;
@@ -32,13 +36,11 @@ export class BoatImpl implements MutableBoat {
owner(): PlayerImpl { owner(): PlayerImpl {
return this._owner; return this._owner;
} }
target(): PlayerImpl | TerraNullius {
return this._target;
}
delete(): void { delete(): void {
this._owner._boats = this._owner._boats.filter(b => b != this); this._owner._units = this._owner._units.filter(b => b != this);
this._active = false; this._active = false;
this.g.fireBoatUpdateEvent(this, this._tile); this.g.fireUnitUpdateEvent(this, this._tile);
} }
isActive(): boolean { isActive(): boolean {
return this._active; return this._active;