mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +00:00
* Feather, the Redeemed - fixed that it returns to hand re-casted/blinked cards;
This commit is contained in:
parent
648026ac0b
commit
735d2a16a2
2 changed files with 123 additions and 4 deletions
|
@ -167,11 +167,9 @@ class FeatherTheRedeemedEffect extends ReplacementEffectImpl {
|
|||
if (zEvent.getFromZone() == Zone.STACK
|
||||
&& zEvent.getToZone() == Zone.GRAVEYARD
|
||||
&& event.getSourceId() != null) {
|
||||
if (event.getSourceId().equals(event.getTargetId())) {
|
||||
if (event.getSourceId().equals(event.getTargetId()) && mor.getZoneChangeCounter() == game.getState().getZoneChangeCounter(event.getSourceId())) {
|
||||
Spell spell = game.getStack().getSpell(mor.getSourceId());
|
||||
if (spell != null && spell.isInstantOrSorcery()) {
|
||||
return true;
|
||||
}
|
||||
return spell != null && spell.isInstantOrSorcery();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
package org.mage.test.cards.abilities.other;
|
||||
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneAllEffect;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class FeatherTheRedeemedTest extends CardTestPlayerBase {
|
||||
|
||||
// Feather, the Redeemed {R}{W}{W}
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void test_ExileSpellWithReturnAtTheEnd() {
|
||||
// cast bolt, put to exile, return to hand
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Feather, the Redeemed");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 2);
|
||||
|
||||
// cast and put to exile
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Grizzly Bears");
|
||||
checkPermanentCount("turn 1", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Grizzly Bears", 1);
|
||||
checkExileCount("turn 1", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", 1);
|
||||
checkHandCardCount("turn 1", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
|
||||
// return to hand at the next end step
|
||||
checkExileCount("turn 1 after", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
checkHandCardCount("turn 1 after", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 1);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ExileSpellAndRecastWithReturnAtTheEnd() {
|
||||
// cast bolt, put to exile, cast from exile, put to exile, return to hand
|
||||
addCustomCardWithAbility("cast from exile", playerA, new SimpleStaticAbility(
|
||||
new PlayFromNotOwnHandZoneAllEffect(StaticFilters.FILTER_CARD, Zone.EXILED, false, TargetController.ANY, Duration.WhileOnBattlefield)
|
||||
));
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Feather, the Redeemed");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 3);
|
||||
|
||||
// cast and put to exile
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Grizzly Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("turn 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 3 - 1);
|
||||
checkExileCount("turn 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 1);
|
||||
checkHandCardCount("turn 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
|
||||
// cast from exile and put to exile again
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Grizzly Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("turn 1 recast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 3 - 2);
|
||||
checkExileCount("turn 1 recast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 1);
|
||||
checkHandCardCount("turn 1 recast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
|
||||
// return to hand at the next end step
|
||||
setChoice(playerA, "At the beginning of the next end step"); // two triggeres from two cast (card's code adds two same effects on each trigger)
|
||||
checkExileCount("turn 1 after", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
checkHandCardCount("turn 1 after", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 1);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ExileSpellAndRecastWithoutReturn() {
|
||||
// cast bolt, put to exile, cast from exile with different target, put to graveyard, not return
|
||||
addCustomCardWithAbility("cast from exile", playerA, new SimpleStaticAbility(
|
||||
new PlayFromNotOwnHandZoneAllEffect(StaticFilters.FILTER_CARD, Zone.EXILED, false, TargetController.ANY, Duration.WhileOnBattlefield)
|
||||
));
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Feather, the Redeemed");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 3);
|
||||
|
||||
// cast and put to exile
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Grizzly Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("turn 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 3 - 1);
|
||||
checkExileCount("turn 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 1);
|
||||
checkHandCardCount("turn 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
|
||||
// cast from exile to target player (without trigger) and put to graveyard
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("turn 1 recast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 3 - 1); // no changes
|
||||
checkLife("turn 1 recast", 1, PhaseStep.PRECOMBAT_MAIN, playerB, 20 - 3);
|
||||
checkExileCount("turn 1 recast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
checkHandCardCount("turn 1 recast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
|
||||
// not return to hand at the next end step
|
||||
checkExileCount("turn 1 after", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
checkHandCardCount("turn 1 after", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", 0);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue