From 6fd6417d0b487075338ff3f50e53f91d78a3cd21 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Thu, 16 May 2024 16:22:48 -0400 Subject: [PATCH] rework and fix Stand or Fall --- Mage.Sets/src/mage/cards/s/StandOrFall.java | 113 ++++++++---------- .../common/combat/CantBlockAllEffect.java | 14 +-- 2 files changed, 48 insertions(+), 79 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/StandOrFall.java b/Mage.Sets/src/mage/cards/s/StandOrFall.java index e284771469e..8fb67bd5f92 100644 --- a/Mage.Sets/src/mage/cards/s/StandOrFall.java +++ b/Mage.Sets/src/mage/cards/s/StandOrFall.java @@ -3,8 +3,7 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.common.BeginningOfCombatTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.RestrictionEffect; -import mage.abilities.effects.common.combat.CantBlockTargetEffect; +import mage.abilities.effects.common.combat.CantBlockAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -13,28 +12,28 @@ import mage.constants.Outcome; import mage.constants.TargetController; import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.filter.predicate.permanent.PermanentReferenceInCollectionPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; -import mage.target.common.TargetOpponent; -import mage.target.targetpointer.FixedTarget; import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; /** - * @author LevelX2 & L_J + * @author xenohedron */ public final class StandOrFall extends CardImpl { public StandOrFall(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); - // At the beginning of combat on your turn, separate all creatures defending player controls into two piles. Only creatures in the pile of that player’s choice can block this turn. + // At the beginning of combat on your turn, for each defending player, separate all creatures that player controls into two piles and that player chooses one. Only creatures in the chosen piles can block this turn. this.addAbility(new BeginningOfCombatTriggeredAbility(new StandOrFallEffect(), TargetController.YOU, false)); } @@ -52,7 +51,8 @@ class StandOrFallEffect extends OneShotEffect { StandOrFallEffect() { super(Outcome.Detriment); - this.staticText = "separate all creatures that player controls into two piles and that player chooses one. Only creatures in the chosen piles can block this turn"; + this.staticText = "for each defending player, separate all creatures that player controls into two piles and that player chooses one." + + " Only creatures in the chosen piles can block this turn"; } private StandOrFallEffect(final StandOrFallEffect effect) { @@ -66,65 +66,46 @@ class StandOrFallEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - // 802.2. As the combat phase starts, the attacking player doesn’t choose an opponent to become the defending player. - // Instead, all the attacking player’s opponents are defending players during the combat phase. - // - // 802.2a Any rule, object, or effect that refers to a “defending player” refers to one specific defending player, not to all of the defending players. - // If an ability of an attacking creature refers to a defending player, or a spell or ability refers to both an attacking creature and a defending player, - // then unless otherwise specified, the defending player it’s referring to is the player that creature was attacking at the time it became an attacking - // creature that combat, or the controller of the planeswalker that creature was attacking at the time it became an attacking creature that combat. If a spell or ability - // could apply to multiple attacking creatures, the appropriate defending player is individually determined for each of those attacking creatures. - // If there are multiple defending players that could be chosen, the controller of the spell or ability chooses one. - // - // https://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/756140-stand-or-fall-mechanics Player player = game.getPlayer(source.getControllerId()); - Set opponents = game.getOpponents(source.getControllerId()); - if (!opponents.isEmpty()) { - Player targetPlayer = game.getPlayer(opponents.iterator().next()); - if (opponents.size() > 1) { - TargetOpponent targetOpponent = new TargetOpponent(true); - if (player != null && player.chooseTarget(Outcome.Neutral, targetOpponent, source, game)) { - targetPlayer = game.getPlayer(targetOpponent.getFirstTarget()); - game.informPlayers(player.getLogName() + " chose " + targetPlayer.getLogName() + " as the defending player"); - } - } - - if (player != null && targetPlayer != null) { - int count = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURES, targetPlayer.getId(), game); - TargetCreaturePermanent creatures = new TargetCreaturePermanent(0, count, new FilterCreaturePermanent("creatures to put in the first pile"), true); - List pile1 = new ArrayList<>(); - creatures.setRequired(false); - if (player.choose(Outcome.Neutral, creatures, source, game)) { - List targets = creatures.getTargets(); - for (UUID targetId : targets) { - Permanent p = game.getPermanent(targetId); - if (p != null) { - pile1.add(p); - } - } - } - List pile2 = new ArrayList<>(); - for (Permanent p : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, targetPlayer.getId(), game)) { - if (!pile1.contains(p)) { - pile2.add(p); - } - } - - boolean choice = targetPlayer.choosePile(outcome, "Choose which pile can block this turn.", pile1, pile2, game); - List chosenPile = choice ? pile2 : pile1; - List otherPile = choice ? pile1 : pile2; - for (Permanent permanent : chosenPile) { - if (permanent != null) { - RestrictionEffect effect = new CantBlockTargetEffect(Duration.EndOfTurn); - effect.setText(""); - effect.setTargetPointer(new FixedTarget(permanent, game)); - game.addEffect(effect, source); - } - } - game.informPlayers("Creatures that can block this turn: " + otherPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", "))); - return true; - } + if (player == null) { + return false; } - return false; + List canBlock = new ArrayList<>(); + for (UUID oppId : game.getOpponents(source.getControllerId())) { + Player opponent = game.getPlayer(oppId); + if (opponent == null) { + continue; + } + FilterCreaturePermanent opponentFilter = new FilterCreaturePermanent(); + opponentFilter.add(new ControllerIdPredicate(oppId)); + TargetCreaturePermanent creatures = new TargetCreaturePermanent(0, Integer.MAX_VALUE, opponentFilter, true); + creatures.setRequired(false); + List pile1 = new ArrayList<>(); + if (player.choose(Outcome.Neutral, creatures, source, game)) { + List targets = creatures.getTargets(); + for (UUID targetId : targets) { + Permanent p = game.getPermanent(targetId); + if (p != null) { + pile1.add(p); + } + } + } + List pile2 = new ArrayList<>(); + for (Permanent p : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, opponent.getId(), game)) { + if (!pile1.contains(p)) { + pile2.add(p); + } + } + boolean choice = opponent.choosePile(outcome, "Choose which pile can block this turn.", pile1, pile2, game); + canBlock.addAll(choice ? pile1 : pile2); + } + FilterCreaturePermanent filterRestriction = new FilterCreaturePermanent(); + filterRestriction.add(Predicates.not(new PermanentReferenceInCollectionPredicate(canBlock, game))); + game.addEffect(new CantBlockAllEffect(filterRestriction, Duration.EndOfTurn), source); + game.informPlayers("Creatures that can block this turn: " + canBlock + .stream() + .map(Permanent::getLogName) + .collect(Collectors.joining(", "))); + return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAllEffect.java index 89948ae2908..c43ac208b46 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAllEffect.java @@ -1,7 +1,6 @@ package mage.abilities.effects.common.combat; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.effects.RestrictionEffect; import mage.constants.Duration; import mage.filter.common.FilterCreaturePermanent; @@ -18,6 +17,7 @@ public class CantBlockAllEffect extends RestrictionEffect { public CantBlockAllEffect(FilterCreaturePermanent filter, Duration duration) { super(duration); this.filter = filter; + this.staticText = filter.getMessage() + " can't block" + (duration == Duration.EndOfTurn ? " this turn" : ""); } protected CantBlockAllEffect(final CantBlockAllEffect effect) { @@ -40,16 +40,4 @@ public class CantBlockAllEffect extends RestrictionEffect { return new CantBlockAllEffect(this); } - @Override - public String getText(Mode mode) { - if (staticText != null && !staticText.isEmpty()) { - return staticText; - } - StringBuilder sb = new StringBuilder(); - sb.append(filter.getMessage()).append(" can't block"); - if (this.duration == Duration.EndOfTurn) { - sb.append(" this turn"); - } - return sb.toString(); - } }