diff --git a/src/game/TerritoryManager.ts b/src/game/TerritoryManager.ts index 95552ca..6c5a70a 100644 --- a/src/game/TerritoryManager.ts +++ b/src/game/TerritoryManager.ts @@ -1,5 +1,4 @@ import {playerManager} from "./player/PlayerManager"; -import {territoryRenderingManager} from "../renderer/manager/TerritoryRenderingManager"; import {playerNameRenderingManager} from "../renderer/manager/PlayerNameRenderingManager"; import {gameMap} from "./GameData"; import {TerritoryTransaction} from "./transaction/TerritoryTransaction"; @@ -105,15 +104,14 @@ class TerritoryManager { * Clears a tile. * @see TerritoryManager.conquer * @param tile The tile to clear - * @param transaction The transaction to apply the clearing to + * @param transaction The transaction to apply the clearing to, requires to have null as the attacker */ clear(tile: number, transaction: TerritoryTransaction): void { const owner = this.tileOwners[tile]; if (owner !== this.OWNER_NONE) { this.tileOwners[tile] = this.OWNER_NONE; playerManager.getPlayer(owner).removeTile(tile, transaction); - //TODO: integrate this with the transaction system - territoryRenderingManager.clear(tile); + transaction.setTerritory(tile); } } } diff --git a/src/game/player/SpawnManager.ts b/src/game/player/SpawnManager.ts index 6b26155..62716c8 100644 --- a/src/game/player/SpawnManager.ts +++ b/src/game/player/SpawnManager.ts @@ -8,7 +8,6 @@ import {clientPlayer, playerManager} from "./PlayerManager"; import {SpawnRequestPacket} from "../../network/protocol/packet/game/SpawnRequestPacket"; import {gameTicker} from "../GameTicker"; import {TerritoryTransaction} from "../transaction/TerritoryTransaction"; -import {playerNameRenderingManager} from "../../renderer/manager/PlayerNameRenderingManager"; class SpawnManager { spawnPoints: number[]; @@ -162,13 +161,17 @@ class SpawnManager { if (pixels.length === 0) { return false; //Invalid spawn point } - const transaction = new TerritoryTransaction(playerManager.getPlayer(player), null); + if (this.spawnData[player]) { - this.spawnData[player].pixels.forEach(pixel => territoryManager.clear(pixel, transaction)); + const clearTransaction = new TerritoryTransaction(null, playerManager.getPlayer(player)); + this.spawnData[player].pixels.forEach(pixel => territoryManager.clear(pixel, clearTransaction)); this.spawnPoints.push(...this.spawnData[player].blockedPoints); this.spawnData[player].blockedPoints.forEach(point => this.backupPoints.splice(this.backupPoints.indexOf(point), 1)); + clearTransaction.apply(); } + const transaction = new TerritoryTransaction(playerManager.getPlayer(player), null); + const data = new SpawnData(); data.blockedPoints = this.spawnPoints.filter(point => Math.abs(point % gameMap.width - tile % gameMap.width) <= 4 && Math.abs(Math.floor(point / gameMap.width) - Math.floor(tile / gameMap.width)) <= 4); data.pixels = pixels; @@ -177,9 +180,6 @@ class SpawnManager { this.backupPoints.push(...data.blockedPoints); this.spawnData[player] = data; - transaction.addExecutor(function (this: TerritoryTransaction) { - playerNameRenderingManager.getPlayerData(this.player).validatePosition(); //Old name position is invalid, but wasn't captured by another player - }); transaction.apply(); //This intentionally ignores the "target" pixels return true; } diff --git a/src/game/transaction/TerritoryTransaction.ts b/src/game/transaction/TerritoryTransaction.ts index 1cd53df..3383042 100644 --- a/src/game/transaction/TerritoryTransaction.ts +++ b/src/game/transaction/TerritoryTransaction.ts @@ -1,8 +1,11 @@ import {Transaction} from "./Transaction"; import {Player} from "../player/Player"; import {getTransactionExecutors, registerTransactionType} from "./TransactionExecutors"; +import {InvalidArgumentException} from "../../util/Exceptions"; +//TODO: Do border calculations when transaction is applied (we currently paint some border tiles multiple times) export class TerritoryTransaction extends Transaction { + protected readonly attacker: Player | null; protected readonly defendant: Player | null; protected readonly territoryQueue: Array = []; protected readonly borderQueue: Array = []; @@ -12,8 +15,18 @@ export class TerritoryTransaction extends Transaction { protected defendantNamePos: number = 0; protected defendantNamePosSize: number = -1; - constructor(attacker: Player, defendant: Player | null) { - super(attacker); + /** + * Create a new territory transaction. + * @param attacker The player that is attacking, or null if the territory is being cleared. + * @param defendant The player that is being attacked, or null if the territory is being claimed. + * @throws InvalidArgumentException if both attacker and defendant are null + */ + constructor(attacker: Player | null, defendant: Player | null) { + if (!attacker && !defendant) { + throw new InvalidArgumentException("Both attacker and defendant are null"); + } + super(attacker ?? defendant as Player); + this.attacker = attacker; this.defendant = defendant; this.addExecutor(...getTransactionExecutors(TerritoryTransaction)); } diff --git a/src/renderer/layer/TerritoryRenderer.ts b/src/renderer/layer/TerritoryRenderer.ts index 0bbf0a7..0f3d3a9 100644 --- a/src/renderer/layer/TerritoryRenderer.ts +++ b/src/renderer/layer/TerritoryRenderer.ts @@ -25,4 +25,6 @@ class TerritoryRenderer extends CachedLayer { export const territoryRenderer = new TerritoryRenderer(); mapTransformHandler.scale.register(territoryRenderer.onMapScale); -mapTransformHandler.move.register(territoryRenderer.onMapMove); \ No newline at end of file +mapTransformHandler.move.register(territoryRenderer.onMapMove); + +import("../manager/TerritoryRenderingManager"); \ No newline at end of file diff --git a/src/renderer/manager/PlayerNameRenderingManager.ts b/src/renderer/manager/PlayerNameRenderingManager.ts index 6b1dbe6..f952669 100644 --- a/src/renderer/manager/PlayerNameRenderingManager.ts +++ b/src/renderer/manager/PlayerNameRenderingManager.ts @@ -299,8 +299,8 @@ export class PlayerNameRenderingData { export const playerNameRenderingManager = new PlayerNameRenderingManager(); registerTransactionExecutor(TerritoryTransaction, function (this: TerritoryTransaction) { - if (this.namePosSize > 0) { - playerNameRenderingManager.getPlayerData(this.player).addPosition(this.namePosSize, this.namePos); + if (this.attacker && this.namePosSize > 0) { + playerNameRenderingManager.getPlayerData(this.attacker).addPosition(this.namePosSize, this.namePos); } if (this.defendant && this.defendantNamePosSize > -1) { diff --git a/src/renderer/manager/TerritoryRenderingManager.ts b/src/renderer/manager/TerritoryRenderingManager.ts index 4357804..9e1a697 100644 --- a/src/renderer/manager/TerritoryRenderingManager.ts +++ b/src/renderer/manager/TerritoryRenderingManager.ts @@ -14,13 +14,15 @@ import {TerritoryTransaction} from "../../game/transaction/TerritoryTransaction" * 2. The tile can become an inner tile of the player's territory. * 3. A neighboring tile can become a border tile of the player's territory. */ -class TerritoryRenderingManager { +export class TerritoryRenderingManager { /** - * Clear the tile at the given index. - * @param tile index of the tile + * Clear the tiles at the given indices. + * @param tiles the tiles to clear */ - clear(tile: number): void { - territoryRenderer.context.clearRect(tile % gameMap.width, Math.floor(tile / gameMap.width), 1, 1); + clearTiles(tiles: number[]): void { + for (const tile of tiles) { + territoryRenderer.context.clearRect(tile % gameMap.width, Math.floor(tile / gameMap.width), 1, 1); + } } /** @@ -76,6 +78,10 @@ registerTransactionExecutor(TerritoryTransaction, function (this: TerritoryTrans territoryRenderingManager.paintTiles(this.defendantBorderQueue, getSetting("theme").getBorderColor(this.defendant.baseColor)); } - territoryRenderingManager.paintTiles(this.borderQueue, getSetting("theme").getBorderColor(this.player.baseColor)); - territoryRenderingManager.paintTiles(this.territoryQueue, getSetting("theme").getTerritoryColor(this.player.baseColor)); + if (this.attacker) { + territoryRenderingManager.paintTiles(this.borderQueue, getSetting("theme").getBorderColor(this.attacker.baseColor)); + territoryRenderingManager.paintTiles(this.territoryQueue, getSetting("theme").getTerritoryColor(this.attacker.baseColor)); + } else { + territoryRenderingManager.clearTiles(this.territoryQueue); + } }); \ No newline at end of file