From e6d509b66cfb7c7a7b5928a9ef0ddaec84c6bc2b Mon Sep 17 00:00:00 2001 From: evanpelle Date: Wed, 18 Sep 2024 19:37:26 -0700 Subject: [PATCH] add logic break alliance. break alliance makes you traitor --- TODO.txt | 5 ++++- src/core/execution/AllianceRequestExecution.ts | 6 +++++- src/core/execution/AttackExecution.ts | 16 +++++++++++++++- src/core/game/Game.ts | 6 +++--- src/core/game/GameImpl.ts | 10 ++++++++++ src/core/game/PlayerImpl.ts | 14 ++++++++++++++ 6 files changed, 51 insertions(+), 6 deletions(-) diff --git a/TODO.txt b/TODO.txt index 6e11cac0a..b992201da 100644 --- a/TODO.txt +++ b/TODO.txt @@ -115,7 +115,10 @@ * game mobile friendly DONE 9/16/2024 * UI: basic win condition & popup DONE 9/16/2024 * right click popup alliance option DONE 9/17/2024 -* BUG: can't ally same person twice +* BUG: can't ally same person twice DONE 9/18/2024 +* break alliance makes you a traitor +* add traitor icon +* alert play when they become traitor * make fake humans easier * click alliance sends alliance request * notification for alliance request diff --git a/src/core/execution/AllianceRequestExecution.ts b/src/core/execution/AllianceRequestExecution.ts index cafdc613f..44dbb53ef 100644 --- a/src/core/execution/AllianceRequestExecution.ts +++ b/src/core/execution/AllianceRequestExecution.ts @@ -15,7 +15,11 @@ export class AllianceRequestExecution implements Execution { } tick(ticks: number): void { - this.mg.createAllianceRequest(this.requestor, this.recipient) + if (this.requestor.alliedWith(this.recipient)) { + console.warn('already allied') + } else { + this.mg.createAllianceRequest(this.requestor, this.recipient) + } this.active = false } diff --git a/src/core/execution/AttackExecution.ts b/src/core/execution/AttackExecution.ts index 9c304827c..73269db88 100644 --- a/src/core/execution/AttackExecution.ts +++ b/src/core/execution/AttackExecution.ts @@ -1,10 +1,11 @@ import {PriorityQueue} from "@datastructures-js/priority-queue"; -import {Cell, Execution, MutableGame, MutablePlayer, PlayerID, TerrainType, TerraNullius, Tile} from "../game/Game"; +import {Cell, Execution, MutableGame, MutablePlayer, Player, PlayerID, TerrainType, TerraNullius, Tile} from "../game/Game"; import {PseudoRandom} from "../PseudoRandom"; import {manhattanDist} from "../Util"; import {Terrain} from "../game/TerrainMapLoader"; export class AttackExecution implements Execution { + private breakAlliance = false private active: boolean = true; private toConquer: PriorityQueue = new PriorityQueue((a: TileContainer, b: TileContainer) => { if (a.priority == b.priority) { @@ -83,6 +84,14 @@ export class AttackExecution implements Execution { } else { this.refreshToConquer() } + + if (this.target.isPlayer()) { + if (this._owner.alliedWith(this.target)) { + // No updates should happen in init. + this.breakAlliance = true + } + } + } private refreshToConquer() { @@ -100,6 +109,11 @@ export class AttackExecution implements Execution { if (ticks < this.mg.config().numSpawnPhaseTurns()) { return } + if (this.breakAlliance) { + this.breakAlliance = false + alert('set player traitor') + this._owner.breakAllianceWith(this.target as Player) + } let numTilesPerTick = this.mg.config().attackTilesPerTick(this._owner, this.target, this.border.size + this.random.nextInt(0, 5)) // console.log(`num tiles per tick: ${numTilesPerTick}`) diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index a0a6078b6..12ca46afe 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -128,7 +128,6 @@ export interface Player { boats(): Boat[] ownsTile(cell: Cell): boolean isAlive(): boolean - executions(): ExecutionView[] borderTiles(): ReadonlySet isPlayer(): this is Player neighbors(): (Player | TerraNullius)[] @@ -140,6 +139,7 @@ export interface Player { alliances(): Alliance[] alliedWith(other: Player): boolean pendingAllianceRequestWith(other: Player): boolean + isTraitor(): boolean toString(): string } @@ -156,6 +156,7 @@ export interface MutablePlayer extends Player { incomingAllianceRequests(): MutableAllianceRequest[] outgoingAllianceRequests(): MutableAllianceRequest[] alliances(): MutableAlliance[] + breakAllianceWith(other: Player): void addBoat(troops: number, tile: Tile, target: Player | TerraNullius): MutableBoat } @@ -185,8 +186,7 @@ export interface MutableGame extends Game { players(): MutablePlayer[] addPlayer(playerInfo: PlayerInfo, troops: number): MutablePlayer executions(): Execution[] - removeInactiveExecutions(): void - removeExecution(exec: Execution): void + // todo move to player. createAllianceRequest(requestor: Player, recipient: Player): MutableAllianceRequest } diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts index 5b89946cf..cfaaead73 100644 --- a/src/core/game/GameImpl.ts +++ b/src/core/game/GameImpl.ts @@ -316,4 +316,14 @@ export class GameImpl implements MutableGame { this.eventBus.emit(new BoatEvent(boat, oldTile)) } + public breakAlliance(breaker: Player, other: Player) { + const breakerSet = new Set(breaker.alliances()) + const alliances = other.alliances().filter(a => breakerSet.has(a)) + if (alliances.length != 1) { + throw new Error('must have exactly one alliance') + } + this.alliances_ = this.alliances_.filter(a => a != alliances[0]) + // TODO emit event. + } + } \ No newline at end of file diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index f84966251..51426884e 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -5,9 +5,12 @@ import {CellString, GameImpl} from "./GameImpl"; import {BoatImpl} from "./BoatImpl"; import {TileImpl} from "./TileImpl"; import {TerraNulliusImpl} from "./TerraNulliusImpl"; +import {threadId} from "worker_threads"; export class PlayerImpl implements MutablePlayer { + private isTraitor_ = false + public _borderTiles: Set = new Set(); public _boats: BoatImpl[] = []; @@ -130,6 +133,17 @@ export class PlayerImpl implements MutablePlayer { } + isTraitor(): boolean { + return this.isTraitor_ + } + + breakAllianceWith(other: Player): void { + if (!this.alliedWith(other)) { + throw new Error('cannot break alliance, already allied') + } + this.isTraitor_ = true + this.gs.breakAlliance(this, other) + } hash(): number { return simpleHash(this.id()) * (this.troops() + this.numTilesOwned());