diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index e2d3d14ee..5d216f29b 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -1608,11 +1608,10 @@ export class PlayerImpl implements Player { player: Player, treatAFKFriendly: boolean = false, ): boolean { - if (this.type() === PlayerType.Bot) { - // Bots are not affected by immunity + if (this.type() !== PlayerType.Human) { + // Only human attackers respect PVP immunity return !this.isFriendly(player, treatAFKFriendly); } - // Humans and Nations respect immunity return !player.isImmune() && !this.isFriendly(player, treatAFKFriendly); } diff --git a/tests/Attack.test.ts b/tests/Attack.test.ts index a376de974..da7ec9a2a 100644 --- a/tests/Attack.test.ts +++ b/tests/Attack.test.ts @@ -542,4 +542,82 @@ describe("Attack immunity", () => { expect(exec.isActive()).toBe(false); expect(playerA.units(UnitType.TransportShip)).toHaveLength(0); }); + + test("Nation can attack human during PVP immunity", async () => { + const nationInfo = new PlayerInfo( + "nation", + PlayerType.Nation, + null, + "nation_id", + ); + const nation = addPlayerToGame(nationInfo, game, game.ref(15, 0)); + game.executeNextTick(); + game.executeNextTick(); + + // Nation attacks playerA during PVP immunity - should succeed + game.addExecution(new AttackExecution(null, nation, "playerA_id", null)); + game.executeNextTick(); + expect(nation.outgoingAttacks()).toHaveLength(1); + }); + + test("Bot can attack human during PVP immunity", async () => { + const botInfo = new PlayerInfo("bot", PlayerType.Bot, null, "bot_id"); + const bot = addPlayerToGame(botInfo, game, game.ref(15, 0)); + game.executeNextTick(); + game.executeNextTick(); + + // Bot attacks playerA during PVP immunity - should succeed + game.addExecution(new AttackExecution(null, bot, "playerA_id", null)); + game.executeNextTick(); + expect(bot.outgoingAttacks()).toHaveLength(1); + }); + + test("Nation can attack nation during PVP immunity", async () => { + const nationAInfo = new PlayerInfo( + "nationA", + PlayerType.Nation, + null, + "nationA_id", + ); + const nationA = addPlayerToGame(nationAInfo, game, game.ref(15, 0)); + + const nationBInfo = new PlayerInfo( + "nationB", + PlayerType.Nation, + null, + "nationB_id", + ); + addPlayerToGame(nationBInfo, game, game.ref(15, 15)); + game.executeNextTick(); + game.executeNextTick(); + + // Nation A attacks Nation B during PVP immunity - should succeed + game.addExecution(new AttackExecution(null, nationA, "nationB_id", null)); + game.executeNextTick(); + expect(nationA.outgoingAttacks()).toHaveLength(1); + }); + + test("Nation cannot attack allied human during PVP immunity", async () => { + const nationInfo = new PlayerInfo( + "nation", + PlayerType.Nation, + null, + "nation_id", + ); + const nation = addPlayerToGame(nationInfo, game, game.ref(15, 0)); + game.executeNextTick(); + game.executeNextTick(); + + // Create alliance between nation and playerA + const allianceRequest = nation.createAllianceRequest(playerA); + if (allianceRequest) { + allianceRequest.accept(); + } + expect(nation.isAlliedWith(playerA)).toBe(true); + + // Nation tries to attack allied playerA during immunity - should be blocked by friendliness + game.addExecution(new AttackExecution(null, nation, "playerA_id", null)); + game.executeNextTick(); + expect(nation.outgoingAttacks()).toHaveLength(0); + }); });