mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 03:22:00 -08: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
|
if (zEvent.getFromZone() == Zone.STACK
|
||||||
&& zEvent.getToZone() == Zone.GRAVEYARD
|
&& zEvent.getToZone() == Zone.GRAVEYARD
|
||||||
&& event.getSourceId() != null) {
|
&& 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());
|
Spell spell = game.getStack().getSpell(mor.getSourceId());
|
||||||
if (spell != null && spell.isInstantOrSorcery()) {
|
return spell != null && spell.isInstantOrSorcery();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
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…
Add table
Add a link
Reference in a new issue