From 41b8f5788324d0cfe444eeb5d3dc189bdec9cb2b Mon Sep 17 00:00:00 2001 From: Thorsten Hacke Date: Sun, 7 Sep 2025 23:51:16 +0200 Subject: [PATCH] fix Shared Fate to respect range of influence correctly (#13839) * change opponents filter to check oponents of drawing player instead of cards controller * check for player and controller range --- Mage.Sets/src/mage/cards/s/SharedFate.java | 35 ++++++++++++++-------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SharedFate.java b/Mage.Sets/src/mage/cards/s/SharedFate.java index c66c6ee93e8..85a6b70e521 100644 --- a/Mage.Sets/src/mage/cards/s/SharedFate.java +++ b/Mage.Sets/src/mage/cards/s/SharedFate.java @@ -8,15 +8,21 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.FilterPlayer; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.other.PlayerIdPredicate; import mage.game.ExileZone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.players.PlayerList; -import mage.target.common.TargetOpponent; +import mage.target.Target; +import mage.target.TargetPlayer; import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -74,13 +80,25 @@ class SharedFateReplacementEffect extends ReplacementEffectImpl { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Player playerToDraw = game.getPlayer(event.getPlayerId()); Player controller = game.getPlayer(source.getControllerId()); - PlayerList playersInRange = game.getState().getPlayersInRange(source.getControllerId(), game); + PlayerList playersInControllerRange = game.getState().getPlayersInRange(source.getControllerId(), game); + // Check if the player currently drawing is in range of the source if (sourcePermanent == null || playerToDraw == null || controller == null - || !playersInRange.contains(playerToDraw.getId())) { + || !playersInControllerRange.contains(playerToDraw.getId())) { return false; } - TargetOpponent target = new TargetOpponent(true); + + // Create opponent filter list manually because otherwise opponent check prevents controller of this to be valid + PlayerList playersInPlayerRange = game.getState().getPlayersInRange(playerToDraw.getId(), game); + FilterPlayer filter = new FilterPlayer("opponent"); + List opponentPredicates = new ArrayList<>(); + for (UUID opponentId : game.getOpponents(playerToDraw.getId())) { + if (playersInPlayerRange.contains(opponentId) && playersInControllerRange.contains(opponentId)) { + opponentPredicates.add(new PlayerIdPredicate(opponentId)); + } + } + filter.add(Predicates.or(opponentPredicates)); + Target target = new TargetPlayer(1, 1, true, filter); if (!playerToDraw.choose(Outcome.DrawCard, target, source, game)) { return false; } @@ -90,15 +108,6 @@ class SharedFateReplacementEffect extends ReplacementEffectImpl { return false; } - if (!playersInRange.contains(chosenPlayer.getId())) { - game.informPlayers( - "Nothing exiled. " + playerToDraw.getLogName() - + " chose to exile from " + chosenPlayer.getLogName() + "'s library. " - + "That player is outside of " + controller.getLogName() + "'s range of influence." - ); - return false; - } - game.informPlayers(playerToDraw.getLogName() + " chose to exile from " + chosenPlayer.getLogName() + "' library."); Card card = chosenPlayer.getLibrary().getFromTop(game);