From 5e891f50c0871c35711a8dbc6d4d652b7efddd18 Mon Sep 17 00:00:00 2001 From: "Alex W. Jackson" Date: Fri, 14 Oct 2022 01:07:14 -0400 Subject: [PATCH] Refactor PutCards to address issue #9643 (#9644) --- .../LookLibraryAndPickControllerEffect.java | 4 +- .../common/LookLibraryControllerEffect.java | 17 +----- .../main/java/mage/constants/PutCards.java | 58 +++++++++++++++++++ .../main/java/mage/game/events/GameEvent.java | 3 +- Mage/src/main/java/mage/game/stack/Spell.java | 27 +-------- .../main/java/mage/game/stack/SpellStack.java | 4 +- .../java/mage/game/stack/StackAbility.java | 2 +- .../java/mage/game/stack/StackObject.java | 2 +- 8 files changed, 69 insertions(+), 48 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java index c9027aa18b..343eff44af 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java @@ -144,8 +144,8 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff } protected boolean actionWithPickedCards(Game game, Ability source, Player player, Cards pickedCards, Cards otherCards) { - boolean result = moveCards(game, source, player, pickedCards, putPickedCards); - result |= moveCards(game, source, player, otherCards, putLookedCards); + boolean result = putPickedCards.moveCards(player, pickedCards, source, game); + result |= putLookedCards.moveCards(player, otherCards, source, game); return result; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java index e4c3e95357..7144a064bd 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryControllerEffect.java @@ -82,22 +82,7 @@ public class LookLibraryControllerEffect extends OneShotEffect { } protected boolean actionWithLookedCards(Game game, Ability source, Player player, Cards cards) { - return moveCards(game, source, player, cards, putLookedCards); - } - - protected static boolean moveCards(Game game, Ability source, Player player, Cards cards, PutCards putCards) { - switch (putCards) { - case TOP_ANY: - return player.putCardsOnTopOfLibrary(cards, game, source, true); - case BOTTOM_ANY: - return player.putCardsOnBottomOfLibrary(cards, game, source, true); - case BOTTOM_RANDOM: - return player.putCardsOnBottomOfLibrary(cards, game, source, false); - case BATTLEFIELD_TAPPED: - return player.moveCards(cards.getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); - default: - return player.moveCards(cards, putCards.getZone(), source, game); - } + return putLookedCards.moveCards(player, cards, source, game); } @Override diff --git a/Mage/src/main/java/mage/constants/PutCards.java b/Mage/src/main/java/mage/constants/PutCards.java index e5c1edabaf..e471d9e3d3 100644 --- a/Mage/src/main/java/mage/constants/PutCards.java +++ b/Mage/src/main/java/mage/constants/PutCards.java @@ -1,5 +1,12 @@ package mage.constants; +import mage.abilities.Ability; +import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.game.Game; +import mage.players.Player; + /** * * @author awjackson @@ -46,4 +53,55 @@ public enum PutCards { String message = owner ? messageOwner : messageYour; return withOrder ? message + order : message; } + + public boolean moveCard(Player player, Card card, Ability source, Game game, String description) { + switch (this) { + case TOP_OR_BOTTOM: + if (player.chooseUse(Outcome.Neutral, + "Put the " + description + " on the top or bottom of its owner's library?", + null, "Top", "Bottom", source, game + )) { + return player.putCardsOnTopOfLibrary(new CardsImpl(card), game, source, true); + } else { + return player.putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, true); + } + case TOP_ANY: + return player.putCardsOnTopOfLibrary(new CardsImpl(card), game, source, true); + case BOTTOM_ANY: + return player.putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, true); + case BOTTOM_RANDOM: + return player.putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, false); + case BATTLEFIELD_TAPPED: + return player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); + case BATTLEFIELD: + case EXILED: + case HAND: + case GRAVEYARD: + return player.moveCards(card, this.zone, source, game); + default: + throw new UnsupportedOperationException("Missing case for " + this.name() + "in PutCards.moveCard"); + } + } + + public boolean moveCards(Player player, Cards cards, Ability source, Game game) { + switch (this) { + case TOP_OR_BOTTOM: + throw new UnsupportedOperationException("PutCards.TOP_OR_BOTTOM does not support moving multiple cards"); + case TOP_ANY: + return player.putCardsOnTopOfLibrary(cards, game, source, true); + case BOTTOM_ANY: + return player.putCardsOnBottomOfLibrary(cards, game, source, true); + case BOTTOM_RANDOM: + return player.putCardsOnBottomOfLibrary(cards, game, source, false); + case BATTLEFIELD_TAPPED: + return player.moveCards(cards.getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); + case BATTLEFIELD: + case EXILED: + case HAND: + case GRAVEYARD: + return player.moveCards(cards, this.zone, source, game); + default: + throw new UnsupportedOperationException("Missing case for " + this.name() + "in PutCards.moveCards"); + } + } } diff --git a/Mage/src/main/java/mage/game/events/GameEvent.java b/Mage/src/main/java/mage/game/events/GameEvent.java index 1fc51a081d..8c32bbdd68 100644 --- a/Mage/src/main/java/mage/game/events/GameEvent.java +++ b/Mage/src/main/java/mage/game/events/GameEvent.java @@ -65,7 +65,8 @@ public class GameEvent implements Serializable { //player events /* ZONE_CHANGE targetId id of the zone changing object - sourceId sourceId of the ability with the object moving effect (WARNING, can be null if it move of fizzled spells) + sourceId sourceId of the ability with the object moving effect + WARNING: can be null if moved by game rules (e.g. draw in draw step, discard in cleanup step, fizzled spell) playerId controller of the moved object amount not used for this event flag not used for this event diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index a427124353..ef1511192e 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -417,7 +417,7 @@ public class Spell extends StackObjectImpl implements Card { } @Override - public void counter(Ability source, Game game, PutCards zone) { + public void counter(Ability source, Game game, PutCards putCard) { // source can be null for fizzled spells, don't use that code in your ZONE_CHANGE watchers/triggers: // event.getSourceId().equals // TODO: fizzled spells are no longer considered "countered" as of current rules; may need refactor @@ -429,30 +429,7 @@ public class Spell extends StackObjectImpl implements Card { } Player player = game.getPlayer(source == null ? getControllerId() : source.getControllerId()); if (player != null) { - switch (zone) { - case TOP_OR_BOTTOM: - if (player.chooseUse(Outcome.Detriment, - "Put the countered spell on the top or bottom of its owner's library?", - null, "Top", "Bottom", source, game - )) { - player.putCardsOnTopOfLibrary(new CardsImpl(card), game, source, false); - } else { - player.putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, false); - } - break; - case TOP_ANY: - player.putCardsOnTopOfLibrary(new CardsImpl(card), game, source, false); - break; - case BOTTOM_ANY: - case BOTTOM_RANDOM: - player.putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, false); - break; - case BATTLEFIELD_TAPPED: - player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); - break; - default: - player.moveCards(card, zone.getZone(), source, game); - } + putCard.moveCard(player, card, source, game, "countered spell"); } } diff --git a/Mage/src/main/java/mage/game/stack/SpellStack.java b/Mage/src/main/java/mage/game/stack/SpellStack.java index 853622efd7..2be7261dab 100644 --- a/Mage/src/main/java/mage/game/stack/SpellStack.java +++ b/Mage/src/main/java/mage/game/stack/SpellStack.java @@ -62,7 +62,7 @@ public class SpellStack extends ArrayDeque { return counter(objectId, source, game, PutCards.GRAVEYARD); } - public boolean counter(UUID objectId, Ability source, Game game, PutCards zone) { + public boolean counter(UUID objectId, Ability source, Game game, PutCards putCard) { StackObject stackObject = getStackObject(objectId); MageObject sourceObject = game.getObject(source); if (stackObject != null && sourceObject != null) { @@ -82,7 +82,7 @@ public class SpellStack extends ArrayDeque { if (!(stackObject instanceof Spell)) { // spells are removed from stack by the card movement this.remove(stackObject, game); } - stackObject.counter(source, game, zone); + stackObject.counter(source, game, putCard); if (!game.isSimulation()) { game.informPlayers(counteredObjectName + " is countered by " + sourceObject.getLogName()); } diff --git a/Mage/src/main/java/mage/game/stack/StackAbility.java b/Mage/src/main/java/mage/game/stack/StackAbility.java index 451fcdbf08..d0f9baffb8 100644 --- a/Mage/src/main/java/mage/game/stack/StackAbility.java +++ b/Mage/src/main/java/mage/game/stack/StackAbility.java @@ -109,7 +109,7 @@ public class StackAbility extends StackObjectImpl implements Ability { } @Override - public void counter(Ability source, Game game, PutCards zone) { + public void counter(Ability source, Game game, PutCards putCard) { //20100716 - 603.8 if (ability instanceof StateTriggeredAbility) { ((StateTriggeredAbility) ability).counter(game); diff --git a/Mage/src/main/java/mage/game/stack/StackObject.java b/Mage/src/main/java/mage/game/stack/StackObject.java index 4a9228b1a0..7c183e78a2 100644 --- a/Mage/src/main/java/mage/game/stack/StackObject.java +++ b/Mage/src/main/java/mage/game/stack/StackObject.java @@ -24,7 +24,7 @@ public interface StackObject extends MageObject, Controllable { */ void counter(Ability source, Game game); - void counter(Ability source, Game game, PutCards zone); + void counter(Ability source, Game game, PutCards putCard); Ability getStackAbility();