diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java index 3a2ae135ac..f1f4274047 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java @@ -971,7 +971,7 @@ public class ComputerPlayer6 extends ComputerPlayer implements Player { List killers = CombatUtil.canKillOpponent(game, attackersList, possibleBlockers, defender); if (!killers.isEmpty()) { for (Permanent attacker : killers) { - attackingPlayer.declareAttacker(attacker.getId(), defenderId, game); + attackingPlayer.declareAttacker(attacker.getId(), defenderId, game, false); } return; } @@ -1133,7 +1133,7 @@ public class ComputerPlayer6 extends ComputerPlayer implements Player { safeToAttack = false; } if (safeToAttack) { - attackingPlayer.declareAttacker(attacker.getId(), defenderId, game); + attackingPlayer.declareAttacker(attacker.getId(), defenderId, game, false); } } } @@ -1240,7 +1240,7 @@ public class ComputerPlayer6 extends ComputerPlayer implements Player { UUID defenderId = game.getOpponents(playerId).iterator().next(); for (CombatGroup group : engagement.getGroups()) { for (UUID attackerId : group.getAttackers()) { - sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim); + sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim, false); } } sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId)); diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 58d7fa0e51..43dbb55564 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -1254,12 +1254,12 @@ public class ComputerPlayer extends PlayerImpl implements Player { CombatSimulator combat = simulateAttack(attackers, blockers, opponentId, game); if (combat.rating > 2) { for (CombatGroupSimulator group: combat.groups) { - this.declareAttacker(group.attackers.get(0).id, group.defenderId, game); + this.declareAttacker(group.attackers.get(0).id, group.defenderId, game, false); } } } for (Permanent attacker: actualAttackers) { - this.declareAttacker(attacker.getId(), opponentId, game); + this.declareAttacker(attacker.getId(), opponentId, game, false); } } diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java index 19d5b887d8..c737e45ca7 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java @@ -201,7 +201,7 @@ public class ComputerPlayerMCTS extends ComputerPlayer implements Player { Combat combat = root.getCombat(); UUID opponentId = game.getCombat().getDefenders().iterator().next(); for (UUID attackerId: combat.getAttackers()) { - this.declareAttacker(attackerId, opponentId, game); + this.declareAttacker(attackerId, opponentId, game, false); } } diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSNode.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSNode.java index 3705b35e61..b3e2a16e49 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSNode.java +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSNode.java @@ -159,7 +159,7 @@ public class MCTSNode { Game sim = game.copy(); MCTSPlayer simPlayer = (MCTSPlayer) sim.getPlayer(player.getId()); for (UUID attackerId: attack) { - simPlayer.declareAttacker(attackerId, defenderId, sim); + simPlayer.declareAttacker(attackerId, defenderId, sim, false); } sim.resume(); children.add(new MCTSNode(this, sim, sim.getCombat())); diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java index 6008c61935..a6735f6103 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java @@ -602,7 +602,7 @@ public class ComputerPlayer2 extends ComputerPlayer implements Player { UUID defenderId = game.getOpponents(playerId).iterator().next(); for (CombatGroup group: engagement.getGroups()) { for (UUID attackerId: group.getAttackers()) { - sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim); + sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim, false); } } sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId)); @@ -651,16 +651,18 @@ public class ComputerPlayer2 extends ComputerPlayer implements Player { @Override public void selectAttackers(Game game, UUID attackingPlayerId) { - if (logger.isDebugEnabled() && (combat == null || combat.getGroups().isEmpty())) + if (logger.isDebugEnabled() && (combat == null || combat.getGroups().isEmpty())) { logger.debug("not attacking"); + } if (combat != null) { UUID opponentId = game.getCombat().getDefenders().iterator().next(); for (UUID attackerId: combat.getAttackers()) { - this.declareAttacker(attackerId, opponentId, game); + this.declareAttacker(attackerId, opponentId, game, false); if (logger.isDebugEnabled()) { Permanent p = game.getPermanent(attackerId); - if (p != null) + if (p != null) { logger.debug("attacking with:" + p.getName()); + } } } } diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java index 2046f08005..2d8d109fe2 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java @@ -319,7 +319,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { UUID defenderId = game.getOpponents(attackerId).iterator().next(); for (CombatGroup group: engagement.getGroups()) { for (UUID attackId: group.getAttackers()) { - sim.getPlayer(attackerId).declareAttacker(attackId, defenderId, sim); + sim.getPlayer(attackerId).declareAttacker(attackId, defenderId, sim, false); } } sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, attackerId, attackerId)); diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index 7d53273e8c..21855c3cfb 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -668,7 +668,7 @@ public class HumanPlayer extends PlayerImpl { possibleDefender = defenders; } if (possibleDefender.size() == 1) { - declareAttacker(attackerId, defenders.iterator().next(), game); + declareAttacker(attackerId, defenders.iterator().next(), game, true); return true; } else { @@ -683,7 +683,7 @@ public class HumanPlayer extends PlayerImpl { } } if (chooseTarget(Outcome.Damage, target, null, game)) { - declareAttacker(attackerId, response.getUUID(), game); + declareAttacker(attackerId, response.getUUID(), game, true); return true; } } diff --git a/Mage/src/mage/game/combat/Combat.java b/Mage/src/mage/game/combat/Combat.java index 034f30ffbb..3d80a1840e 100644 --- a/Mage/src/mage/game/combat/Combat.java +++ b/Mage/src/mage/game/combat/Combat.java @@ -232,16 +232,16 @@ public class Combat implements Serializable, Copyable { creaturesForcedToAttack.put(creature.getId(), defendersForcedToAttack); if (defendersForcedToAttack.isEmpty()) { if (defenders.size() == 1) { - player.declareAttacker(creature.getId(), defenders.iterator().next(), game); + player.declareAttacker(creature.getId(), defenders.iterator().next(), game, false); } else { TargetDefender target = new TargetDefender(defenders, creature.getId()); target.setRequired(true); if (player.chooseTarget(Outcome.Damage, target, null, game)) { - player.declareAttacker(creature.getId(), target.getFirstTarget(), game); + player.declareAttacker(creature.getId(), target.getFirstTarget(), game, false); } } } else { - player.declareAttacker(creature.getId(), defendersForcedToAttack.iterator().next(), game); + player.declareAttacker(creature.getId(), defendersForcedToAttack.iterator().next(), game, false); } } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index 47b20c922a..75903526a0 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -325,7 +325,7 @@ public interface Player extends MageItem, Copyable { void construct(Tournament tournament, Deck deck); void pickCard(List cards, Deck deck, Draft draft); - void declareAttacker(UUID attackerId, UUID defenderId, Game game); + void declareAttacker(UUID attackerId, UUID defenderId, Game game, boolean allowUndo); void declareBlocker(UUID defenderId, UUID blockerId, UUID attackerId, Game game); List getAvailableAttackers(Game game); List getAvailableBlockers(Game game); diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 0e678e5b36..4cc5435acb 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -1650,8 +1650,10 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public void declareAttacker(UUID attackerId, UUID defenderId, Game game) { - setStoredBookmark(game.bookmarkState()); // makes it possible to UNDO a declared attacker with costs from e.g. Propaganda + public void declareAttacker(UUID attackerId, UUID defenderId, Game game, boolean allowUndo) { + if (allowUndo) { + setStoredBookmark(game.bookmarkState()); // makes it possible to UNDO a declared attacker with costs from e.g. Propaganda + } Permanent attacker = game.getPermanent(attackerId); if (attacker != null && attacker.canAttack(game) && attacker.getControllerId().equals(playerId)) { if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARE_ATTACKER, defenderId, attackerId, playerId))) {