* Some minor code clean up and a test.

This commit is contained in:
LevelX2 2020-07-10 09:06:25 +02:00
parent 15719fea0f
commit 40b7d723ef
5 changed files with 85 additions and 10 deletions

View file

@ -41,7 +41,9 @@ public final class FeatherTheRedeemed extends CardImpl {
// Flying // Flying
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
// Whenever you cast an instant or sorcery spell that targets a creature you control, exile that card instead of putting it into your graveyard as it resolves. If you do, return it to your hand at the beginning of the next end step. // Whenever you cast an instant or sorcery spell that targets a creature you control,
// exile that card instead of putting it into your graveyard as it resolves.
// If you do, return it to your hand at the beginning of the next end step.
this.addAbility(new FeatherTheRedeemedTriggeredAbility()); this.addAbility(new FeatherTheRedeemedTriggeredAbility());
} }

View file

@ -10,7 +10,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
/** /**
* *

View file

@ -34,7 +34,9 @@ public final class VeilOfSummer extends CardImpl {
public VeilOfSummer(UUID ownerId, CardSetInfo setInfo) { public VeilOfSummer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
// Draw a card if an opponent has cast a blue or black spell this turn. Spells you control can't be countered this turn. You and permanents you control gain hexproof from blue and from black until end of turn. // Draw a card if an opponent has cast a blue or black spell this turn.
// Spells you control can't be countered this turn. You and permanents you control
// gain hexproof from blue and from black until end of turn.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect( this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1), new DrawCardSourceControllerEffect(1),
VeilOfSummerCondition.instance, "Draw a card " + VeilOfSummerCondition.instance, "Draw a card " +

View file

@ -35,14 +35,20 @@ public class HideawayTest extends CardTestPlayerBase {
@Test @Test
public void testHideaway() { public void testHideaway() {
addCard(Zone.HAND, playerA, "Shelldock Isle"); addCard(Zone.HAND, playerA, "Shelldock Isle");
addCard(Zone.LIBRARY, playerA, "Silvercoat Lion");
skipInitShuffling();
this.playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shelldock Isle"); this.playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shelldock Isle");
setChoice(playerA, "Silvercoat Lion");
setStopAt(1, PhaseStep.BEGIN_COMBAT); setStopAt(1, PhaseStep.BEGIN_COMBAT);
setStrictChooseMode(true);
execute(); execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Shelldock Isle", 1); assertPermanentCount(playerA, "Shelldock Isle", 1);
assertExileCount(playerA, 1); assertExileCount(playerA, "Silvercoat Lion", 1);
for (Card card : currentGame.getExile().getAllCards(currentGame)) { for (Card card : currentGame.getExile().getAllCards(currentGame)) {
Assert.assertTrue("Exiled card is not face down", card.isFaceDown(currentGame)); Assert.assertTrue("Exiled card is not face down", card.isFaceDown(currentGame));
} }
@ -73,10 +79,15 @@ public class HideawayTest extends CardTestPlayerBase {
setChoice(playerA, "Ulamog, the Ceaseless Hunger"); setChoice(playerA, "Ulamog, the Ceaseless Hunger");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{G},"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{G},");
setChoice(playerA, "Yes"); // play Ghost Quarter
addTarget(playerA, "Dross Crocodile^Dross Crocodile"); addTarget(playerA, "Dross Crocodile^Dross Crocodile");
setStopAt(3, PhaseStep.BEGIN_COMBAT); setStopAt(3, PhaseStep.BEGIN_COMBAT);
setStrictChooseMode(true);
execute(); execute();
assertAllCommandsUsed();
assertExileCount("Dross Crocodile", 2); assertExileCount("Dross Crocodile", 2);
assertPermanentCount(playerA, "Mosswort Bridge", 1); assertPermanentCount(playerA, "Mosswort Bridge", 1);
@ -94,6 +105,9 @@ public class HideawayTest extends CardTestPlayerBase {
@Test @Test
public void testCannotPlayLandIfPlayedLand() { public void testCannotPlayLandIfPlayedLand() {
// Hideaway (This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library.)
// {tap}: Add {W}.
// {W}, {T}: You may play the exiled card without paying its mana cost if you attacked with three or more creatures this turn.
addCard(Zone.HAND, playerA, "Windbrisk Heights"); addCard(Zone.HAND, playerA, "Windbrisk Heights");
addCard(Zone.HAND, playerA, "Plains"); addCard(Zone.HAND, playerA, "Plains");
addCard(Zone.LIBRARY, playerA, "Ghost Quarter"); addCard(Zone.LIBRARY, playerA, "Ghost Quarter");
@ -112,9 +126,13 @@ public class HideawayTest extends CardTestPlayerBase {
attack(3, playerA, "Auriok Champion"); attack(3, playerA, "Auriok Champion");
activateAbility(3, PhaseStep.DECLARE_BLOCKERS, playerA, "{W},"); activateAbility(3, PhaseStep.DECLARE_BLOCKERS, playerA, "{W},");
setChoice(playerA, "Yes"); // play Ghost Quarter
setStopAt(3, PhaseStep.END_COMBAT); setStopAt(3, PhaseStep.END_COMBAT);
setStrictChooseMode(true);
execute(); execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Ghost Quarter", 0); assertPermanentCount(playerA, "Ghost Quarter", 0);
assertTapped("Windbrisk Heights", true); assertTapped("Windbrisk Heights", true);
@ -122,6 +140,9 @@ public class HideawayTest extends CardTestPlayerBase {
@Test @Test
public void testCannotPlayLandIfNotOwnTurn() { public void testCannotPlayLandIfNotOwnTurn() {
// Hideaway (This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library.)
// {T}: Add {G}.
// {G}, {T}: You may play the exiled card without paying its mana cost if creatures you control have total power 10 or greater.
addCard(Zone.HAND, playerA, "Mosswort Bridge"); addCard(Zone.HAND, playerA, "Mosswort Bridge");
addCard(Zone.LIBRARY, playerA, "Ghost Quarter"); addCard(Zone.LIBRARY, playerA, "Ghost Quarter");
skipInitShuffling(); skipInitShuffling();
@ -135,6 +156,7 @@ public class HideawayTest extends CardTestPlayerBase {
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{G},"); activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{G},");
setStopAt(2, PhaseStep.BEGIN_COMBAT); setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute(); execute();
assertPermanentCount(playerA, "Ghost Quarter", 0); assertPermanentCount(playerA, "Ghost Quarter", 0);
@ -158,13 +180,17 @@ public class HideawayTest extends CardTestPlayerBase {
attack(3, playerA, "Auriok Champion"); attack(3, playerA, "Auriok Champion");
activateAbility(3, PhaseStep.DECLARE_BLOCKERS, playerA, "{W},"); activateAbility(3, PhaseStep.DECLARE_BLOCKERS, playerA, "{W},");
setChoice(playerA, "Yes"); // play Ghost Quarter
setStopAt(3, PhaseStep.END_COMBAT); setStopAt(3, PhaseStep.END_COMBAT);
setStrictChooseMode(true);
execute(); execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Ghost Quarter", 1); assertPermanentCount(playerA, "Ghost Quarter", 1);
assertTapped("Windbrisk Heights", true); assertTapped("Windbrisk Heights", true);
Assert.assertEquals(playerA.getLandsPlayed(), 1); Assert.assertEquals(1, playerA.getLandsPlayed());
} }
@Test @Test
@ -188,13 +214,17 @@ public class HideawayTest extends CardTestPlayerBase {
attack(3, playerA, "Auriok Champion"); attack(3, playerA, "Auriok Champion");
activateAbility(3, PhaseStep.DECLARE_BLOCKERS, playerA, "{W},"); activateAbility(3, PhaseStep.DECLARE_BLOCKERS, playerA, "{W},");
setChoice(playerA, "Yes"); // play Ghost Quarter
setStopAt(3, PhaseStep.END_COMBAT); setStopAt(3, PhaseStep.END_COMBAT);
setStrictChooseMode(true);
execute(); execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Ghost Quarter", 1); assertPermanentCount(playerA, "Ghost Quarter", 1);
assertTapped("Windbrisk Heights", true); assertTapped("Windbrisk Heights", true);
Assert.assertEquals(playerA.getLandsPlayed(), 2); Assert.assertEquals(2, playerA.getLandsPlayed());
} }
/** /**
@ -204,7 +234,7 @@ public class HideawayTest extends CardTestPlayerBase {
* never the opponents is 20 or fewer * never the opponents is 20 or fewer
*/ */
@Test @Test
public void shelldockIsleHideawayConditionOwnLibrary() { public void testShelldockIsleHideawayConditionOwnLibrary() {
/* /*
Shelldock Isle Shelldock Isle
@ -224,9 +254,13 @@ public class HideawayTest extends CardTestPlayerBase {
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, sIsle); playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, sIsle);
setChoice(playerA, ulamog); setChoice(playerA, ulamog);
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}");
setChoice(playerA, "Yes"); // play Ulamog's Crusher
setStopAt(3, PhaseStep.BEGIN_COMBAT); setStopAt(3, PhaseStep.BEGIN_COMBAT);
setStrictChooseMode(true);
execute(); execute();
assertAllCommandsUsed();
assertTappedCount("Island", true, 1); assertTappedCount("Island", true, 1);
assertPermanentCount(playerA, sIsle, 1); assertPermanentCount(playerA, sIsle, 1);
@ -243,7 +277,7 @@ public class HideawayTest extends CardTestPlayerBase {
* NOTE: test is currently failing due to bug in code. see issue #3310 * NOTE: test is currently failing due to bug in code. see issue #3310
*/ */
@Test @Test
public void shelldockIsleHideawayConditionOpponentsLibrary() { public void testShelldockIsleHideawayConditionOpponentsLibrary() {
/* /*
Shelldock Isle Shelldock Isle
@ -265,6 +299,7 @@ public class HideawayTest extends CardTestPlayerBase {
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, sIsle); playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, sIsle);
setChoice(playerA, ulamog); setChoice(playerA, ulamog);
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}"); activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}");
setChoice(playerA, "Yes"); // play Ulamog's Crusher
setStopAt(3, PhaseStep.BEGIN_COMBAT); setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute(); execute();
@ -281,7 +316,7 @@ public class HideawayTest extends CardTestPlayerBase {
* blocking. * blocking.
*/ */
@Test @Test
public void blinkWatcherFortomorrow() { public void testBlinkWatcherForTomorrow() {
/* Hideaway (This permanent enters the battlefield tapped" and /* Hideaway (This permanent enters the battlefield tapped" and
"When this permanent enters the battlefield, look at the top four cards of "When this permanent enters the battlefield, look at the top four cards of
@ -316,4 +351,41 @@ public class HideawayTest extends CardTestPlayerBase {
assertExileCount(playerA, 2); assertExileCount(playerA, 2);
assertTapped("Watcher for Tomorrow", true); assertTapped("Watcher for Tomorrow", true);
} }
/**
* Possible bug with the Hideaway mechanic or with Watcher for Tomorrow. If
* it leaves the bf before Hideaway resolves you don't get to exile a card
* when the former eventually resolves, that shouldn't be the case.
*/
@Test
public void testWatcherForTomorrowLeft() {
// Hideaway
// When Watcher for Tomorrow leaves the battlefield, put the exiled card into its owner's hand.
addCard(Zone.HAND, playerA, "Watcher for Tomorrow"); // Creature 2/1 - {1}{U}
// Exile target creature you control, then return it to the battlefield under its owner's control.
// Rebound
addCard(Zone.HAND, playerA, "Ephemerate"); // Instant {W}
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 4);
skipInitShuffling();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Watcher for Tomorrow");
setChoice(playerA, "Silvercoat Lion");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Ephemerate", "Watcher for Tomorrow");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerA, "Watcher for Tomorrow", 1);
assertExileCount(playerA, "Ephemerate", 1);
assertHandCount(playerA, "Silvercoat Lion", 1);
assertExileCount(playerA, 2);
assertTapped("Watcher for Tomorrow", true);
}
} }

View file

@ -31,7 +31,7 @@ public class UnattachedTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
if (event.getSourceId().equals(this.getSourceId()) ) { if (event.getSourceId().equals(this.getSourceId()) ) {
getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId())); getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId(), game));
return true; return true;
} }
return false; return false;