mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
refactor: fixed dies events support in single cards (part 7, related to #13089, continue from #13088);
This commit is contained in:
parent
b571080260
commit
8af7a492c8
7 changed files with 162 additions and 1 deletions
|
|
@ -83,6 +83,9 @@ class NadierAgentOfTheDuskenelEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
// For Nadier's second ability, use its power from when it was last on the battlefield to determine
|
||||
// how many tokens to create.
|
||||
// (2020-11-10)
|
||||
Object obj = getValue("permanentLeftBattlefield");
|
||||
if (!(obj instanceof Permanent)) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ class ThreeTreeScribeTriggeredAbility extends TriggeredAbilityImpl {
|
|||
super(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
|
||||
this.setTriggerPhrase("Whenever {this} or another creature you control leaves the battlefield without dying, ");
|
||||
this.addTarget(new TargetControlledCreaturePermanent());
|
||||
setLeavesTheBattlefieldTrigger(true);
|
||||
}
|
||||
|
||||
private ThreeTreeScribeTriggeredAbility(final ThreeTreeScribeTriggeredAbility ability) {
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ class LeavesTheBattlefieldAttachedTriggeredAbility extends ZoneChangeTriggeredAb
|
|||
|
||||
public LeavesTheBattlefieldAttachedTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken()), "When enchanted creature leaves the battlefield, ", Boolean.FALSE);
|
||||
setLeavesTheBattlefieldTrigger(true);
|
||||
}
|
||||
|
||||
private LeavesTheBattlefieldAttachedTriggeredAbility(final LeavesTheBattlefieldAttachedTriggeredAbility ability) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
package org.mage.test.cards.single.cmr;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
|
||||
public class NadierAgentOfTheDuskenelTest extends CardTestCommanderDuelBase {
|
||||
|
||||
@Test
|
||||
public void test_DieAnother() {
|
||||
addCustomEffect_TargetDestroy(playerA);
|
||||
|
||||
// Whenever a token you control leaves the battlefield, put a +1/+1 counter on Nadier, Agent of the Duskenel.
|
||||
// When Nadier leaves the battlefield, create a number of 1/1 green Elf Warrior creature tokens equal to its power.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Nadier, Agent of the Duskenel", 1);
|
||||
//
|
||||
// {5}, {T}: Create a 1/1 colorless Insect artifact creature token with flying named Wasp.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "The Hive", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
|
||||
// prepare token
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{5}, {T}: Create");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wasp", 1);
|
||||
|
||||
// on leaves non-token -- nothing to happen
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "The Hive");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
checkGraveyardCount("on non-token", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "The Hive", 1);
|
||||
checkStackSize("on non-token - no triggers", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 0);
|
||||
|
||||
// on leaves token - must trigger
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "Wasp");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("on token", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wasp", 0);
|
||||
checkPermanentCounters("on token - must trigger", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Nadier, Agent of the Duskenel", CounterType.P1P1, 1);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_DieItself() {
|
||||
addCustomEffect_TargetDestroy(playerA, 2);
|
||||
|
||||
// Whenever a token you control leaves the battlefield, put a +1/+1 counter on Nadier, Agent of the Duskenel.
|
||||
// When Nadier leaves the battlefield, create a number of 1/1 green Elf Warrior creature tokens equal to its power.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Nadier, Agent of the Duskenel", 1);
|
||||
//
|
||||
// {5}, {T}: Create a 1/1 colorless Insect artifact creature token with flying named Wasp.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "The Hive", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
|
||||
// prepare token
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{5}, {T}: Create");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wasp", 1);
|
||||
|
||||
// on leaves token and itself -- must x2 triggers:
|
||||
// * one with counter to fizzle
|
||||
// * one with new token
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "Wasp^Nadier, Agent of the Duskenel");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
checkStackSize("must triggers x2", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 2);
|
||||
setChoice(playerA, "Whenever a token you control leaves"); // x2 triggers from Nadier
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "The Hive", 1);
|
||||
assertPermanentCount(playerA, "Wasp", 0);
|
||||
assertGraveyardCount(playerA, "Nadier, Agent of the Duskenel", 1);
|
||||
assertPermanentCount(playerA, "Elf Warrior Token", 3);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package org.mage.test.cards.single.khm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class ValorOfTheWorthyTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void test_DieTarget() {
|
||||
addCustomEffect_TargetDestroy(playerA);
|
||||
|
||||
// Enchant creature
|
||||
// Enchanted creature gets +1/+1.
|
||||
// When enchanted creature leaves the battlefield, create a 1/1 white Spirit creature token with flying.
|
||||
addCard(Zone.HAND, playerA, "Valor of the Worthy"); // {W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
|
||||
|
||||
// attach
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Valor of the Worthy", "Grizzly Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
checkPT("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 2 + 1, 2 + 1);
|
||||
|
||||
// destroy target - must trigger
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy");
|
||||
addTarget(playerA, "Grizzly Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1); // resolve destroy
|
||||
checkStackObject("must trigger on destroy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "When enchanted creature leaves the battlefield", 1);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertTokenCount(playerA, "Spirit Token", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_DieItself() {
|
||||
addCustomEffect_TargetDestroy(playerA, 2);
|
||||
|
||||
// Enchant creature
|
||||
// Enchanted creature gets +1/+1.
|
||||
// When enchanted creature leaves the battlefield, create a 1/1 white Spirit creature token with flying.
|
||||
addCard(Zone.HAND, playerA, "Valor of the Worthy"); // {W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
|
||||
|
||||
// attach
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Valor of the Worthy", "Grizzly Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
checkPT("prepare", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears", 2 + 1, 2 + 1);
|
||||
|
||||
// destroy all - must trigger anyway
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy");
|
||||
addTarget(playerA, "Valor of the Worthy^Grizzly Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1); // resolve destroy
|
||||
checkStackObject("must trigger on destroy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "When enchanted creature leaves the battlefield", 1);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertTokenCount(playerA, "Spirit Token", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -2021,10 +2021,12 @@ public class VerifyCardDataTest {
|
|||
boolean isPutToGraveAbility = rules.contains("put into")
|
||||
&& rules.contains("graveyard")
|
||||
&& rules.contains("from the battlefield");
|
||||
boolean isLeavesBattlefield = rules.contains("leaves the battlefield");
|
||||
isLeavesBattlefield = false; // TODO: remove and fix all bad cards
|
||||
if (triggeredAbility.isLeavesTheBattlefieldTrigger()) {
|
||||
// TODO: add check for wrongly enabled settings too?
|
||||
} else {
|
||||
if (isDiesAbility || isPutToGraveAbility) {
|
||||
if (isDiesAbility || isPutToGraveAbility || isLeavesBattlefield) {
|
||||
fail(card, "abilities", "dies related trigger must use setLeavesTheBattlefieldTrigger(true) and possibly override isInUseableZone - "
|
||||
+ triggeredAbility.getClass().getSimpleName());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl {
|
|||
this.filter = filter;
|
||||
this.setTargetPointer = setTargetPointer;
|
||||
setTriggerPhrase("Whenever " + filter.getMessage() + " leaves the battlefield, ");
|
||||
setLeavesTheBattlefieldTrigger(true);
|
||||
}
|
||||
|
||||
protected LeavesBattlefieldAllTriggeredAbility(final LeavesBattlefieldAllTriggeredAbility ability) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue