mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
refactor: fixed dies events support in single cards (part 4);
This commit is contained in:
parent
dc9f349828
commit
0689c56597
19 changed files with 159 additions and 37 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.common.DiscardedByOpponentTriggeredAbility;
|
import mage.abilities.common.DiscardedByOpponentTriggeredAbility;
|
||||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||||
|
|
@ -63,6 +65,7 @@ class AjanisLastStandTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
new CreateTokenEffect(new AvatarToken2()),
|
new CreateTokenEffect(new AvatarToken2()),
|
||||||
new SacrificeSourceCost()
|
new SacrificeSourceCost()
|
||||||
), false);
|
), false);
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AjanisLastStandTriggeredAbility(final AjanisLastStandTriggeredAbility ability) {
|
private AjanisLastStandTriggeredAbility(final AjanisLastStandTriggeredAbility ability) {
|
||||||
|
|
@ -98,4 +101,9 @@ class AjanisLastStandTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
+ "you may sacrifice {this}. "
|
+ "you may sacrifice {this}. "
|
||||||
+ "If you do, create a 4/4 white Avatar creature token with flying.";
|
+ "If you do, create a 4/4 white Avatar creature token with flying.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
|
@ -122,6 +123,7 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
super(Zone.BATTLEFIELD, effect, optional);
|
super(Zone.BATTLEFIELD, effect, optional);
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
setTriggerPhrase("Whenever " + filter.getMessage() + " dies, ");
|
setTriggerPhrase("Whenever " + filter.getMessage() + " dies, ");
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AthreosDiesCreatureTriggeredAbility(AthreosDiesCreatureTriggeredAbility ability) {
|
private AthreosDiesCreatureTriggeredAbility(AthreosDiesCreatureTriggeredAbility ability) {
|
||||||
|
|
@ -153,4 +155,9 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ class AthreosShroudVeiledTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
AthreosShroudVeiledTriggeredAbility() {
|
AthreosShroudVeiledTriggeredAbility() {
|
||||||
super(Zone.BATTLEFIELD, null, false);
|
super(Zone.BATTLEFIELD, null, false);
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AthreosShroudVeiledTriggeredAbility(final AthreosShroudVeiledTriggeredAbility ability) {
|
private AthreosShroudVeiledTriggeredAbility(final AthreosShroudVeiledTriggeredAbility ability) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
package mage.cards.a;
|
package mage.cards.a;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
|
|
@ -60,6 +61,7 @@ class AvacynsCollarTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
public AvacynsCollarTriggeredAbility() {
|
public AvacynsCollarTriggeredAbility() {
|
||||||
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken()));
|
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken()));
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private AvacynsCollarTriggeredAbility(final AvacynsCollarTriggeredAbility ability) {
|
private AvacynsCollarTriggeredAbility(final AvacynsCollarTriggeredAbility ability) {
|
||||||
|
|
@ -91,4 +93,9 @@ class AvacynsCollarTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever equipped creature dies, if it was a Human, create a 1/1 white Spirit creature token with flying.";
|
return "Whenever equipped creature dies, if it was a Human, create a 1/1 white Spirit creature token with flying.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package mage.cards.b;
|
package mage.cards.b;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.effects.common.discard.DiscardTargetEffect;
|
import mage.abilities.effects.common.discard.DiscardTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -41,6 +43,7 @@ class BereavementTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
BereavementTriggeredAbility() {
|
BereavementTriggeredAbility() {
|
||||||
super(Zone.BATTLEFIELD, new DiscardTargetEffect(1));
|
super(Zone.BATTLEFIELD, new DiscardTargetEffect(1));
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BereavementTriggeredAbility(final BereavementTriggeredAbility ability) {
|
private BereavementTriggeredAbility(final BereavementTriggeredAbility ability) {
|
||||||
|
|
@ -73,4 +76,9 @@ class BereavementTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever a green creature dies, its controller discards a card.";
|
return "Whenever a green creature dies, its controller discards a card.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ class CarthTheLionTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
super(Zone.BATTLEFIELD, new LookLibraryAndPickControllerEffect(
|
super(Zone.BATTLEFIELD, new LookLibraryAndPickControllerEffect(
|
||||||
7, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM));
|
7, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM));
|
||||||
setTriggerPhrase("Whenever {this} enters or a planeswalker you control dies, ");
|
setTriggerPhrase("Whenever {this} enters or a planeswalker you control dies, ");
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CarthTheLionTriggeredAbility(final CarthTheLionTriggeredAbility ability) {
|
private CarthTheLionTriggeredAbility(final CarthTheLionTriggeredAbility ability) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
|
|
||||||
package mage.cards.d;
|
package mage.cards.d;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
|
|
@ -25,7 +25,6 @@ public final class DeathsPresence extends CardImpl {
|
||||||
public DeathsPresence(UUID ownerId, CardSetInfo setInfo) {
|
public DeathsPresence(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{G}");
|
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{G}");
|
||||||
|
|
||||||
|
|
||||||
// Whenever a creature you control dies, put X +1/+1 counters on target creature you control, where X is the power of the creature that died.
|
// Whenever a creature you control dies, put X +1/+1 counters on target creature you control, where X is the power of the creature that died.
|
||||||
this.addAbility(new DeathsPresenceTriggeredAbility());
|
this.addAbility(new DeathsPresenceTriggeredAbility());
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +43,7 @@ class DeathsPresenceTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
public DeathsPresenceTriggeredAbility() {
|
public DeathsPresenceTriggeredAbility() {
|
||||||
super(Zone.BATTLEFIELD, null);
|
super(Zone.BATTLEFIELD, null);
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeathsPresenceTriggeredAbility(final DeathsPresenceTriggeredAbility ability) {
|
private DeathsPresenceTriggeredAbility(final DeathsPresenceTriggeredAbility ability) {
|
||||||
|
|
@ -80,4 +80,9 @@ class DeathsPresenceTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever a creature you control dies, put X +1/+1 counters on target creature you control, where X is the power of the creature that died.";
|
return "Whenever a creature you control dies, put X +1/+1 counters on target creature you control, where X is the power of the creature that died.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package mage.cards.d;
|
package mage.cards.d;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
|
import mage.MageObject;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||||
|
|
@ -67,6 +68,7 @@ class DiregrafCaptainTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public DiregrafCaptainTriggeredAbility() {
|
public DiregrafCaptainTriggeredAbility() {
|
||||||
super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), false);
|
super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), false);
|
||||||
this.addTarget(new TargetOpponent());
|
this.addTarget(new TargetOpponent());
|
||||||
|
this.setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiregrafCaptainTriggeredAbility(final DiregrafCaptainTriggeredAbility ability) {
|
private DiregrafCaptainTriggeredAbility(final DiregrafCaptainTriggeredAbility ability) {
|
||||||
|
|
@ -99,4 +101,9 @@ class DiregrafCaptainTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Whenever another Zombie you control dies, target opponent loses 1 life.";
|
return "Whenever another Zombie you control dies, target opponent loses 1 life.";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package mage.cards.x;
|
package mage.cards.x;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.common.AttacksTriggeredAbility;
|
import mage.abilities.common.AttacksTriggeredAbility;
|
||||||
import mage.abilities.common.delayed.WhenTargetDiesDelayedTriggeredAbility;
|
import mage.abilities.common.delayed.WhenTargetDiesDelayedTriggeredAbility;
|
||||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||||
|
|
@ -78,6 +80,7 @@ class XiraTheGoldenStingTriggeredAbility extends WhenTargetDiesDelayedTriggeredA
|
||||||
super(new DrawCardSourceControllerEffect(1), Duration.Custom, SetTargetPointer.NONE);
|
super(new DrawCardSourceControllerEffect(1), Duration.Custom, SetTargetPointer.NONE);
|
||||||
this.addEffect(new CreateTokenEffect(new XiraBlackInsectToken()).concatBy("and"));
|
this.addEffect(new CreateTokenEffect(new XiraBlackInsectToken()).concatBy("and"));
|
||||||
setTriggerPhrase("When that creature dies, if it has an egg counter on it, ");
|
setTriggerPhrase("When that creature dies, if it has an egg counter on it, ");
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private XiraTheGoldenStingTriggeredAbility(final XiraTheGoldenStingTriggeredAbility ability) {
|
private XiraTheGoldenStingTriggeredAbility(final XiraTheGoldenStingTriggeredAbility ability) {
|
||||||
|
|
@ -100,4 +103,9 @@ class XiraTheGoldenStingTriggeredAbility extends WhenTargetDiesDelayedTriggeredA
|
||||||
int zccdiff = game.getState().getZoneChangeCounter(mor.getSourceId()) - mor.getZoneChangeCounter();
|
int zccdiff = game.getState().getZoneChangeCounter(mor.getSourceId()) - mor.getZoneChangeCounter();
|
||||||
return zccdiff > 1 || zccdiff > 0 && game.getState().getZone(mor.getSourceId()) != Zone.GRAVEYARD;
|
return zccdiff > 1 || zccdiff > 0 && game.getState().getZone(mor.getSourceId()) != Zone.GRAVEYARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ public class ConniveTest extends CardTestPlayerBase {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||||
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
|
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
|
||||||
//
|
//
|
||||||
addCustomEffect_DestroyTarget(playerA);
|
addCustomEffect_TargetDestroy(playerA);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Razorclaw Bear", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Razorclaw Bear", 1);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||||
|
|
||||||
|
|
@ -267,7 +267,7 @@ public class ConniveTest extends CardTestPlayerBase {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||||
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
|
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
|
||||||
//
|
//
|
||||||
addCustomEffect_DestroyTarget(playerA);
|
addCustomEffect_TargetDestroy(playerA);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Razorclaw Bear", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Razorclaw Bear", 1);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||||
|
|
||||||
|
|
@ -323,7 +323,7 @@ public class ConniveTest extends CardTestPlayerBase {
|
||||||
//
|
//
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||||
//
|
//
|
||||||
addCustomEffect_DestroyTarget(playerA);
|
addCustomEffect_TargetDestroy(playerA);
|
||||||
|
|
||||||
// connive lion
|
// connive lion
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Change of Plans");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Change of Plans");
|
||||||
|
|
@ -350,7 +350,7 @@ public class ConniveTest extends CardTestPlayerBase {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Razorclaw Bear", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Razorclaw Bear", 1);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
|
||||||
//
|
//
|
||||||
addCustomEffect_DestroyTarget(playerA);
|
addCustomEffect_TargetDestroy(playerA);
|
||||||
|
|
||||||
// connive lion
|
// connive lion
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Change of Plans");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Change of Plans");
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ public class IncubateTest extends CardTestPlayerBase {
|
||||||
@Test
|
@Test
|
||||||
public void test_Transform_Custom() {
|
public void test_Transform_Custom() {
|
||||||
// target transform
|
// target transform
|
||||||
addCustomEffect_TransformTarget(playerA);
|
addCustomEffect_TargetTransform(playerA);
|
||||||
|
|
||||||
// Alluring Suitor, 2/3
|
// Alluring Suitor, 2/3
|
||||||
// Deadly Dancer, 3/3
|
// Deadly Dancer, 3/3
|
||||||
|
|
@ -74,7 +74,7 @@ public class IncubateTest extends CardTestPlayerBase {
|
||||||
@Test
|
@Test
|
||||||
public void test_Transform_IncubatorToken() {
|
public void test_Transform_IncubatorToken() {
|
||||||
// target transform
|
// target transform
|
||||||
addCustomEffect_TransformTarget(playerA);
|
addCustomEffect_TargetTransform(playerA);
|
||||||
|
|
||||||
// Incubate 3. (Create an Incubator token with three +1/+1 counters on it and “{2}: Transform this artifact.”
|
// Incubate 3. (Create an Incubator token with three +1/+1 counters on it and “{2}: Transform this artifact.”
|
||||||
// It transforms into a 0/0 Phyrexian artifact creature.)
|
// It transforms into a 0/0 Phyrexian artifact creature.)
|
||||||
|
|
@ -115,9 +115,9 @@ public class IncubateTest extends CardTestPlayerBase {
|
||||||
// use case: copy one side, can't tranform
|
// use case: copy one side, can't tranform
|
||||||
|
|
||||||
// target transform
|
// target transform
|
||||||
addCustomEffect_TransformTarget(playerA);
|
addCustomEffect_TargetTransform(playerA);
|
||||||
// target destroy
|
// target destroy
|
||||||
addCustomEffect_DestroyTarget(playerA);
|
addCustomEffect_TargetDestroy(playerA);
|
||||||
|
|
||||||
// Incubate 3. (Create an Incubator token with three +1/+1 counters on it and “{2}: Transform this artifact.”
|
// Incubate 3. (Create an Incubator token with three +1/+1 counters on it and “{2}: Transform this artifact.”
|
||||||
// It transforms into a 0/0 Phyrexian artifact creature.)
|
// It transforms into a 0/0 Phyrexian artifact creature.)
|
||||||
|
|
@ -169,9 +169,9 @@ public class IncubateTest extends CardTestPlayerBase {
|
||||||
// use case: copy one side, can't tranform
|
// use case: copy one side, can't tranform
|
||||||
|
|
||||||
// target transform
|
// target transform
|
||||||
addCustomEffect_TransformTarget(playerA);
|
addCustomEffect_TargetTransform(playerA);
|
||||||
// target destroy
|
// target destroy
|
||||||
addCustomEffect_DestroyTarget(playerA);
|
addCustomEffect_TargetDestroy(playerA);
|
||||||
|
|
||||||
// Incubate 3. (Create an Incubator token with three +1/+1 counters on it and “{2}: Transform this artifact.”
|
// Incubate 3. (Create an Incubator token with three +1/+1 counters on it and “{2}: Transform this artifact.”
|
||||||
// It transforms into a 0/0 Phyrexian artifact creature.)
|
// It transforms into a 0/0 Phyrexian artifact creature.)
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10);
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10);
|
||||||
//
|
//
|
||||||
addCustomEffect_TargetDamage(playerA, 3);
|
addCustomEffect_TargetDamage(playerA, 3);
|
||||||
addCustomEffect_DestroyTarget(playerA);
|
addCustomEffect_TargetDestroy(playerA);
|
||||||
|
|
||||||
checkCommandCardCount("before 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Birgi, God of Storytelling", 1);
|
checkCommandCardCount("before 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Birgi, God of Storytelling", 1);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.mage.test.cards.single.m19;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
|
public class AjanisLastStandTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_TriggerOnAlive() {
|
||||||
|
addCustomEffect_TargetDestroy(playerA);
|
||||||
|
|
||||||
|
// Whenever a creature or planeswalker you control dies, you may sacrifice Ajani's Last Stand.
|
||||||
|
// If you do, create a 4/4 white Avatar creature token with flying.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Ajani's Last Stand");
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears");
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy");
|
||||||
|
addTarget(playerA, "Grizzly Bears"); // to destroy
|
||||||
|
setChoice(playerA, true); // yes to sacrifice
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, "Ajani's Last Stand", 1);
|
||||||
|
assertGraveyardCount(playerA, "Grizzly Bears", 1);
|
||||||
|
assertTokenCount(playerA, "Avatar Token", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_NoTriggerOnSelfDies() {
|
||||||
|
addCustomEffect_AllDestroy(playerA);
|
||||||
|
|
||||||
|
// Whenever a creature or planeswalker you control dies, you may sacrifice Ajani's Last Stand.
|
||||||
|
// If you do, create a 4/4 white Avatar creature token with flying.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Ajani's Last Stand");
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears");
|
||||||
|
|
||||||
|
// destroy all without triggers (cause no sacrifice cost can be pay here)
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "all destroy");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, "Ajani's Last Stand", 1);
|
||||||
|
assertGraveyardCount(playerA, "Grizzly Bears", 1);
|
||||||
|
assertTokenCount(playerA, "Avatar Token", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -112,7 +112,7 @@ public class GluttonousHellkiteTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_CastWithSac_SacFullAndBlink() {
|
public void test_CastWithSac_SacFullAndBlink() {
|
||||||
addCustomEffect_BlinkTarget(playerA);
|
addCustomEffect_TargetBlink(playerA);
|
||||||
|
|
||||||
// When you cast this spell, each player sacrifices X creatures. Gluttonous Hellkite enters the battlefield
|
// When you cast this spell, each player sacrifices X creatures. Gluttonous Hellkite enters the battlefield
|
||||||
// with two +1/+1 counters on it for each creature sacrificed this way.
|
// with two +1/+1 counters on it for each creature sacrificed this way.
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,7 @@ public class SacrificeDiesTriggerTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_MultiModesDiesTrigger_ByDamage() {
|
public void test_MultiModesDiesTrigger_ByDamage() {
|
||||||
addCustomEffect_BlinkTarget(playerA);
|
addCustomEffect_TargetBlink(playerA);
|
||||||
|
|
||||||
// When Junji, the Midnight Sky dies, choose one —
|
// When Junji, the Midnight Sky dies, choose one —
|
||||||
// • Each opponent discards two cards and loses 2 life.
|
// • Each opponent discards two cards and loses 2 life.
|
||||||
|
|
@ -346,7 +346,7 @@ public class SacrificeDiesTriggerTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_MultiModesDiesTrigger_BySacrificeCost() {
|
public void test_MultiModesDiesTrigger_BySacrificeCost() {
|
||||||
addCustomEffect_BlinkTarget(playerA);
|
addCustomEffect_TargetBlink(playerA);
|
||||||
|
|
||||||
// When Junji, the Midnight Sky dies, choose one —
|
// When Junji, the Midnight Sky dies, choose one —
|
||||||
// • Each opponent discards two cards and loses 2 life.
|
// • Each opponent discards two cards and loses 2 life.
|
||||||
|
|
|
||||||
|
|
@ -318,9 +318,6 @@ public abstract class MageTestPlayerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add cost modification effect to the game (all cast cost will be increaded or decreased for controller)
|
* Add cost modification effect to the game (all cast cost will be increaded or decreased for controller)
|
||||||
*
|
|
||||||
* @param controller
|
|
||||||
* @param modificationAmount
|
|
||||||
*/
|
*/
|
||||||
protected void addCustomEffect_SpellCostModification(TestPlayer controller, int modificationAmount) {
|
protected void addCustomEffect_SpellCostModification(TestPlayer controller, int modificationAmount) {
|
||||||
Effect effect;
|
Effect effect;
|
||||||
|
|
@ -339,9 +336,6 @@ public abstract class MageTestPlayerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add target damage ability that can be called by text: "target damage xxx"
|
* Add target damage ability that can be called by text: "target damage xxx"
|
||||||
*
|
|
||||||
* @param controller
|
|
||||||
* @param damageAmount
|
|
||||||
*/
|
*/
|
||||||
protected void addCustomEffect_TargetDamage(TestPlayer controller, int damageAmount) {
|
protected void addCustomEffect_TargetDamage(TestPlayer controller, int damageAmount) {
|
||||||
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(damageAmount).setText("target damage " + damageAmount), new ManaCostsImpl<>(""));
|
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(damageAmount).setText("target damage " + damageAmount), new ManaCostsImpl<>(""));
|
||||||
|
|
@ -355,10 +349,8 @@ public abstract class MageTestPlayerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add target destroy ability that can be called by text "target destroy"
|
* Add target destroy ability that can be called by text "target destroy"
|
||||||
*
|
|
||||||
* @param controller
|
|
||||||
*/
|
*/
|
||||||
protected void addCustomEffect_DestroyTarget(TestPlayer controller) {
|
protected void addCustomEffect_TargetDestroy(TestPlayer controller) {
|
||||||
Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect().setText("target destroy"), new ManaCostsImpl<>(""));
|
Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect().setText("target destroy"), new ManaCostsImpl<>(""));
|
||||||
ability.addTarget(new TargetPermanent());
|
ability.addTarget(new TargetPermanent());
|
||||||
addCustomCardWithAbility(
|
addCustomCardWithAbility(
|
||||||
|
|
@ -369,11 +361,21 @@ public abstract class MageTestPlayerBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add target transform ability that can be called by text "target transform"
|
* Add all destroy ability that can be called by text "all destroy"
|
||||||
*
|
|
||||||
* @param controller
|
|
||||||
*/
|
*/
|
||||||
protected void addCustomEffect_TransformTarget(TestPlayer controller) {
|
protected void addCustomEffect_AllDestroy(TestPlayer controller) {
|
||||||
|
Ability ability = new SimpleActivatedAbility(new DestroyAllEffect(StaticFilters.FILTER_PERMANENT).setText("all destroy"), new ManaCostsImpl<>(""));
|
||||||
|
addCustomCardWithAbility(
|
||||||
|
"all destroy for " + controller.getName(),
|
||||||
|
controller,
|
||||||
|
ability
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add target transform ability that can be called by text "target transform"
|
||||||
|
*/
|
||||||
|
protected void addCustomEffect_TargetTransform(TestPlayer controller) {
|
||||||
Ability ability = new SimpleActivatedAbility(new TransformTargetEffect().setText("target transform"), new ManaCostsImpl<>(""));
|
Ability ability = new SimpleActivatedAbility(new TransformTargetEffect().setText("target transform"), new ManaCostsImpl<>(""));
|
||||||
ability.addTarget(new TargetPermanent());
|
ability.addTarget(new TargetPermanent());
|
||||||
addCustomCardWithAbility(
|
addCustomCardWithAbility(
|
||||||
|
|
@ -385,10 +387,8 @@ public abstract class MageTestPlayerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add target blink ability that can be called by text "target blink"
|
* Add target blink ability that can be called by text "target blink"
|
||||||
*
|
|
||||||
* @param controller
|
|
||||||
*/
|
*/
|
||||||
protected void addCustomEffect_BlinkTarget(TestPlayer controller) {
|
protected void addCustomEffect_TargetBlink(TestPlayer controller) {
|
||||||
Ability ability = new SimpleActivatedAbility(
|
Ability ability = new SimpleActivatedAbility(
|
||||||
new ExileThenReturnTargetEffect(true, true).setText("target blink"),
|
new ExileThenReturnTargetEffect(true, true).setText("target blink"),
|
||||||
new ManaCostsImpl<>("")
|
new ManaCostsImpl<>("")
|
||||||
|
|
@ -403,8 +403,6 @@ public abstract class MageTestPlayerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return target card to hand that can be called by text "return from ..."
|
* Return target card to hand that can be called by text "return from ..."
|
||||||
*
|
|
||||||
* @param controller
|
|
||||||
*/
|
*/
|
||||||
protected void addCustomEffect_ReturnFromAnyToHand(TestPlayer controller) {
|
protected void addCustomEffect_ReturnFromAnyToHand(TestPlayer controller) {
|
||||||
// graveyard
|
// graveyard
|
||||||
|
|
|
||||||
|
|
@ -1989,15 +1989,17 @@ public class VerifyCardDataTest {
|
||||||
card.getAbilities().stream()
|
card.getAbilities().stream()
|
||||||
.filter(a -> a instanceof TriggeredAbility)
|
.filter(a -> a instanceof TriggeredAbility)
|
||||||
.map(a -> (TriggeredAbility) a)
|
.map(a -> (TriggeredAbility) a)
|
||||||
|
.filter(a -> !a.isLeavesTheBattlefieldTrigger())
|
||||||
.filter(a -> a.getRule().contains("whenever") || a.getRule().contains("Whenever"))
|
.filter(a -> a.getRule().contains("whenever") || a.getRule().contains("Whenever"))
|
||||||
.filter(a -> a.getRule().contains("dies"))
|
.filter(a -> a.getRule().contains("dies"))
|
||||||
.filter(a -> !a.getRule().contains("with \"When")) // ignore token creating effects
|
.filter(a -> !a.getRule().contains("with \"When")) // ignore token creating effects
|
||||||
.filter(a -> !a.getRule().contains("gains \"When")) // ignore token creating effects
|
.filter(a -> !a.getRule().contains("gains \"When")) // ignore token creating effects
|
||||||
.filter(a -> !a.getRule().contains("and \"When")) // ignore token creating effects
|
.filter(a -> !a.getRule().contains("and \"When")) // ignore token creating effects
|
||||||
|
.filter(a -> !a.getRule().contains("dies while {this} is in your graveyard")) // ignore Boneyard Scourge
|
||||||
.filter(a -> !card.getName().equals("Massacre Girl") // delayed trigger fixed, but verify check can't find it
|
.filter(a -> !card.getName().equals("Massacre Girl") // delayed trigger fixed, but verify check can't find it
|
||||||
&& !card.getName().equals("Infested Thrinax")
|
&& !card.getName().equals("Infested Thrinax")
|
||||||
|
&& !card.getName().equals("Xira, the Golden Sting")
|
||||||
)
|
)
|
||||||
.filter(a -> !a.isLeavesTheBattlefieldTrigger())
|
|
||||||
.forEach(a -> {
|
.forEach(a -> {
|
||||||
fail(card, "abilities", "dies trigger must use setLeavesTheBattlefieldTrigger(true) and override isInUseableZone - " + a.getClass().getSimpleName());
|
fail(card, "abilities", "dies trigger must use setLeavesTheBattlefieldTrigger(true) and override isInUseableZone - " + a.getClass().getSimpleName());
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1256,6 +1256,9 @@ public abstract class AbilityImpl implements Ability {
|
||||||
|
|
||||||
return allEvents.stream().anyMatch(e -> {
|
return allEvents.stream().anyMatch(e -> {
|
||||||
// TODO: add more events with zone change logic (or make it event's param)?
|
// TODO: add more events with zone change logic (or make it event's param)?
|
||||||
|
// need research: is it ability's or event's task?
|
||||||
|
// - ability's task: code like ability.setLookBackInTime
|
||||||
|
// - event's task: code like current switch
|
||||||
switch (e.getType()) {
|
switch (e.getType()) {
|
||||||
case DESTROYED_PERMANENT:
|
case DESTROYED_PERMANENT:
|
||||||
case EXPLOITED_CREATURE:
|
case EXPLOITED_CREATURE:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package mage.abilities.common;
|
package mage.abilities.common;
|
||||||
|
|
||||||
|
import mage.MageObject;
|
||||||
import mage.MageObjectReference;
|
import mage.MageObjectReference;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
|
|
@ -35,6 +36,7 @@ public class DealtDamageAndDiedTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
this.setTargetPointer = setTargetPointer;
|
this.setTargetPointer = setTargetPointer;
|
||||||
setTriggerPhrase(getWhen() + CardUtil.addArticle(filter.getMessage()) + " dealt damage by {this} this turn dies, ");
|
setTriggerPhrase(getWhen() + CardUtil.addArticle(filter.getMessage()) + " dealt damage by {this} this turn dies, ");
|
||||||
|
setLeavesTheBattlefieldTrigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DealtDamageAndDiedTriggeredAbility(final DealtDamageAndDiedTriggeredAbility ability) {
|
protected DealtDamageAndDiedTriggeredAbility(final DealtDamageAndDiedTriggeredAbility ability) {
|
||||||
|
|
@ -55,6 +57,9 @@ public class DealtDamageAndDiedTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
// If Axelrod Gunnarson and a creature it dealt damage to are both put into a graveyard at the same time,
|
||||||
|
// Axelrod Gunnarson’s second ability will trigger.
|
||||||
|
// (2009-10-01)
|
||||||
if (((ZoneChangeEvent) event).isDiesEvent()) {
|
if (((ZoneChangeEvent) event).isDiesEvent()) {
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||||
if (filter.match(zEvent.getTarget(), game)) {
|
if (filter.match(zEvent.getTarget(), game)) {
|
||||||
|
|
@ -78,4 +83,9 @@ public class DealtDamageAndDiedTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
||||||
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue