diff --git a/Mage.Sets/src/mage/cards/d/DreamLeash.java b/Mage.Sets/src/mage/cards/d/DreamLeash.java index b557bd4bf4d..a68a361904d 100644 --- a/Mage.Sets/src/mage/cards/d/DreamLeash.java +++ b/Mage.Sets/src/mage/cards/d/DreamLeash.java @@ -12,6 +12,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; @@ -73,4 +74,10 @@ class DreamLeashTarget extends TargetPermanent { return false; } + // See ruling: https://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/253345-dream-leash + @Override + public boolean stillLegalTarget(UUID id, Ability source, Game game) { + Permanent permanent = game.getPermanent(id); + return permanent != null && StaticFilters.FILTER_PERMANENT.match(permanent, game); + } } diff --git a/Mage.Sets/src/mage/cards/e/EnthrallingHold.java b/Mage.Sets/src/mage/cards/e/EnthrallingHold.java index fa28c52a398..f1a53c0a3fa 100644 --- a/Mage.Sets/src/mage/cards/e/EnthrallingHold.java +++ b/Mage.Sets/src/mage/cards/e/EnthrallingHold.java @@ -12,6 +12,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; @@ -27,7 +28,7 @@ public final class EnthrallingHold extends CardImpl { public EnthrallingHold(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}"); - + this.subtype.add(SubType.AURA); // Enchant creature @@ -77,4 +78,10 @@ class EnthrallingHoldTarget extends TargetCreaturePermanent { return false; } + // See ruling: https://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/253345-dream-leash + @Override + public boolean stillLegalTarget(UUID id, Ability source, Game game) { + Permanent permanent = game.getPermanent(id); + return permanent != null && StaticFilters.FILTER_PERMANENT_CREATURE.match(permanent, game); + } } \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/m21/EnthrallingHoldTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/m21/EnthrallingHoldTest.java new file mode 100644 index 00000000000..a322395590a --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/m21/EnthrallingHoldTest.java @@ -0,0 +1,79 @@ +package org.mage.test.cards.single.m21; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class EnthrallingHoldTest extends CardTestPlayerBase { + + @Test + public void testTappedTarget_untapped_doesNotFizzle() { + // Traxos, Scourge of Kroog enters the battlefield tapped and doesn't untap during your untap step. + addCard(Zone.BATTLEFIELD, playerB, "Traxos, Scourge of Kroog"); + + addCard(Zone.BATTLEFIELD, playerA, "Island", 6); + /* + * {3}{U}{U} + * Enchant creature + * You can't choose an untapped creature as this spell's target as you cast it. + * You control enchanted creature. + */ + addCard(Zone.HAND, playerA, "Enthralling Hold"); + /* + * {U} + * You may tap or untap target artifact, creature, or land. + */ + addCard(Zone.HAND, playerA, "Twiddle"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Enthralling Hold", "Traxos, Scourge of Kroog"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Twiddle", "Traxos, Scourge of Kroog"); + + setChoice(playerA, "Yes"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_COMBAT); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerB, "Traxos, Scourge of Kroog", 0); + assertPermanentCount(playerA, "Traxos, Scourge of Kroog", 1); + assertPermanentCount(playerA, "Enthralling Hold", 1); + } + + @Test + public void testTappedTarget_becomesIllegal_fizzles() { + // Traxos, Scourge of Kroog enters the battlefield tapped and doesn't untap during your untap step. + addCard(Zone.BATTLEFIELD, playerB, "Traxos, Scourge of Kroog"); + + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + addCard(Zone.BATTLEFIELD, playerA, "Island", 2); + /* + * {3}{U}{U} + * Enchant creature + * You can't choose an untapped creature as this spell's target as you cast it. + * You control enchanted creature. + */ + addCard(Zone.HAND, playerA, "Enthralling Hold"); + /* + * {1}{B} + * Destroy target nonblack creature + */ + addCard(Zone.HAND, playerA, "Doom Blade"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Enthralling Hold", "Traxos, Scourge of Kroog"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Doom Blade", "Traxos, Scourge of Kroog"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_COMBAT); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerB, "Traxos, Scourge of Kroog", 0); + assertPermanentCount(playerA, "Traxos, Scourge of Kroog", 0); + + assertGraveyardCount(playerB, "Traxos, Scourge of Kroog", 1); + assertGraveyardCount(playerA, "Enthralling Hold", 1); + assertGraveyardCount(playerA, "Doom Blade", 1); + } +} diff --git a/Mage/src/main/java/mage/target/Target.java b/Mage/src/main/java/mage/target/Target.java index 267c97558be..87c6e89c07b 100644 --- a/Mage/src/main/java/mage/target/Target.java +++ b/Mage/src/main/java/mage/target/Target.java @@ -52,6 +52,8 @@ public interface Target extends Serializable { boolean canTarget(UUID id, Ability source, Game game); + boolean stillLegalTarget(UUID id, Ability source, Game game); + boolean canTarget(UUID playerId, UUID id, Ability source, Game game); boolean isLegal(Ability source, Game game); diff --git a/Mage/src/main/java/mage/target/TargetImpl.java b/Mage/src/main/java/mage/target/TargetImpl.java index 9d0eaebd0d3..c7e656c70eb 100644 --- a/Mage/src/main/java/mage/target/TargetImpl.java +++ b/Mage/src/main/java/mage/target/TargetImpl.java @@ -12,7 +12,14 @@ import mage.game.events.GameEvent.EventType; import mage.players.Player; import mage.util.RandomUtil; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; /** * @author BetaSteward_at_googlemail.com @@ -337,7 +344,7 @@ public abstract class TargetImpl implements Target { illegalTargets.add(targetId); continue; } - if (!canTarget(targetId, source, game)) { + if (!stillLegalTarget(targetId, source, game)) { illegalTargets.add(targetId); } } @@ -473,6 +480,11 @@ public abstract class TargetImpl implements Target { return null; } + @Override + public boolean stillLegalTarget(UUID id, Ability source, Game game) { + return canTarget(id, source, game); + } + @Override public void setNotTarget(boolean notTarget) { this.notTarget = notTarget;