Merge pull request #13088 from magefree/wrong-dies-triggers-fix-2

Dies triggers fixes and improves (bugs like "no trigger on sacrifice cost")
This commit is contained in:
Oleg Agafonov 2024-11-30 17:56:16 +04:00 committed by GitHub
commit 52c4675d97
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
156 changed files with 1338 additions and 408 deletions

View file

@ -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 sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -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 sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -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) {

View file

@ -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 sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -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 sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -65,6 +65,7 @@ class BridgeFromBelowAbility extends TriggeredAbilityImpl {
this.filter = filter; this.filter = filter;
this.withInterveningIf(SourceInGraveyardCondition.instance); this.withInterveningIf(SourceInGraveyardCondition.instance);
setTriggerPhrase(filter.getMessage()); setTriggerPhrase(filter.getMessage());
setLeavesTheBattlefieldTrigger(true); // it's not required for Bridge from Below, but better to keep same code style and verify pass
} }
private BridgeFromBelowAbility(final BridgeFromBelowAbility ability) { private BridgeFromBelowAbility(final BridgeFromBelowAbility ability) {

View file

@ -1,4 +1,3 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import java.util.UUID;
@ -39,6 +38,7 @@ public final class CallerOfTheClaw extends CardImpl {
// Flash // Flash
this.addAbility(FlashAbility.getInstance()); this.addAbility(FlashAbility.getInstance());
// When Caller of the Claw enters the battlefield, create a 2/2 green Bear creature token for each nontoken creature put into your graveyard from the battlefield this turn. // When Caller of the Claw enters the battlefield, create a 2/2 green Bear creature token for each nontoken creature put into your graveyard from the battlefield this turn.
this.getSpellAbility().addWatcher(new CallerOfTheClawWatcher()); this.getSpellAbility().addWatcher(new CallerOfTheClawWatcher());
Effect effect = new CreateTokenEffect(new BearToken(), new CallerOfTheClawDynamicValue()); Effect effect = new CreateTokenEffect(new BearToken(), new CallerOfTheClawDynamicValue());

View file

@ -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) {

View file

@ -122,10 +122,10 @@ class ChainerNightmareAdeptWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST) { if (event.getType() == GameEvent.EventType.SPELL_CAST) {
if (event.getAdditionalReference() == null) { if (event.getApprovingObject() == null) {
return; return;
} }
morMap.computeIfAbsent(event.getAdditionalReference().getApprovingMageObjectReference(), m -> new HashMap<>()) morMap.computeIfAbsent(event.getApprovingObject().getApprovingMageObjectReference(), m -> new HashMap<>())
.compute(event.getPlayerId(), (u, i) -> i == null ? 0 : Integer.sum(i, -1)); .compute(event.getPlayerId(), (u, i) -> i == null ? 0 : Integer.sum(i, -1));
} }
} }

View file

@ -150,10 +150,10 @@ class ChandraHopesBeaconWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST if (event.getType() != GameEvent.EventType.SPELL_CAST
|| event.getAdditionalReference() == null) { || event.getApprovingObject() == null) {
return; return;
} }
MageObjectReference mor = event.getAdditionalReference().getApprovingMageObjectReference(); MageObjectReference mor = event.getApprovingObject().getApprovingMageObjectReference();
Spell spell = game.getSpell(event.getTargetId()); Spell spell = game.getSpell(event.getTargetId());
if (mor == null || spell == null) { if (mor == null || spell == null) {
return; return;

View file

@ -194,10 +194,10 @@ class ChissGoriaForgeTyrantWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getAdditionalReference() == null) { if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getApprovingObject() == null) {
return; return;
} }
MageObjectReference mor = event.getAdditionalReference().getApprovingMageObjectReference(); MageObjectReference mor = event.getApprovingObject().getApprovingMageObjectReference();
Spell spell = game.getSpell(event.getTargetId()); Spell spell = game.getSpell(event.getTargetId());
if (mor == null || spell == null) { if (mor == null || spell == null) {
return; return;

View file

@ -33,7 +33,7 @@ public final class Chronozoa extends CardImpl {
// Vanishing 3 (This permanent enters the battlefield with three time counters on it. At the beginning of your upkeep, remove a time counter from it. When the last is removed, sacrifice it.) // Vanishing 3 (This permanent enters the battlefield with three time counters on it. At the beginning of your upkeep, remove a time counter from it. When the last is removed, sacrifice it.)
this.addAbility(new VanishingAbility(3)); this.addAbility(new VanishingAbility(3));
// When Chronozoa is put into a graveyard from play, if it had no time counters on it, create two tokens that are copies of it. // When Chronozoa dies, if it had no time counters on it, create two tokens that are copies of it.
Effect effect = new CreateTokenCopySourceEffect(2); Effect effect = new CreateTokenCopySourceEffect(2);
effect.setText("create two tokens that are copies of it"); effect.setText("create two tokens that are copies of it");
this.addAbility(new ConditionalInterveningIfTriggeredAbility(new DiesSourceTriggeredAbility(effect, false), this.addAbility(new ConditionalInterveningIfTriggeredAbility(new DiesSourceTriggeredAbility(effect, false),

View file

@ -237,15 +237,15 @@ class CoramTheUndertakerWatcher extends Watcher {
cardsAllowedToBePlayedOrCast.add(new MageObjectReference(mainCard, game)); cardsAllowedToBePlayedOrCast.add(new MageObjectReference(mainCard, game));
return; return;
} }
if (event.getAdditionalReference() == null if (event.getApprovingObject() == null
|| !MageIdentifier.CoramTheUndertakerWatcher.equals(event.getAdditionalReference().getApprovingAbility().getIdentifier())) { || !MageIdentifier.CoramTheUndertakerWatcher.equals(event.getApprovingObject().getApprovingAbility().getIdentifier())) {
return; return;
} }
if (event.getType() == GameEvent.EventType.LAND_PLAYED) { if (event.getType() == GameEvent.EventType.LAND_PLAYED) {
landPlayedForSource.add(event.getAdditionalReference().getApprovingMageObjectReference()); landPlayedForSource.add(event.getApprovingObject().getApprovingMageObjectReference());
} }
if (event.getType() == GameEvent.EventType.SPELL_CAST) { if (event.getType() == GameEvent.EventType.SPELL_CAST) {
spellCastForSource.add(event.getAdditionalReference().getApprovingMageObjectReference()); spellCastForSource.add(event.getApprovingObject().getApprovingMageObjectReference());
} }
} }

View file

@ -226,7 +226,7 @@ class CourtOfLocthwainWatcher extends Watcher {
&& event.getPlayerId() != null) { && event.getPlayerId() != null) {
decrementCastAvailable( decrementCastAvailable(
event.getPlayerId(), event.getPlayerId(),
event.getAdditionalReference().getApprovingMageObjectReference() event.getApprovingObject().getApprovingMageObjectReference()
); );
} }
} }

View file

@ -54,6 +54,7 @@ class DaxosBlessedByTheSunAbility extends TriggeredAbilityImpl {
DaxosBlessedByTheSunAbility() { DaxosBlessedByTheSunAbility() {
super(Zone.BATTLEFIELD, new GainLifeEffect(1)); super(Zone.BATTLEFIELD, new GainLifeEffect(1));
setLeavesTheBattlefieldTrigger(true);
} }
private DaxosBlessedByTheSunAbility(DaxosBlessedByTheSunAbility ability) { private DaxosBlessedByTheSunAbility(DaxosBlessedByTheSunAbility ability) {

View file

@ -62,6 +62,7 @@ class DeathTyrantTriggeredAbility extends TriggeredAbilityImpl {
DeathTyrantTriggeredAbility() { DeathTyrantTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new ZombieToken())); super(Zone.BATTLEFIELD, new CreateTokenEffect(new ZombieToken()));
setTriggerPhrase("Whenever an attacking creature you control or a blocking creature an opponent controls dies, "); setTriggerPhrase("Whenever an attacking creature you control or a blocking creature an opponent controls dies, ");
setLeavesTheBattlefieldTrigger(true);
} }
private DeathTyrantTriggeredAbility(final DeathTyrantTriggeredAbility ability) { private DeathTyrantTriggeredAbility(final DeathTyrantTriggeredAbility ability) {
@ -94,7 +95,7 @@ class DeathTyrantTriggeredAbility extends TriggeredAbilityImpl {
} }
@Override @Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game); return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} }
} }

View file

@ -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 sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -1,6 +1,8 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
@ -91,6 +93,7 @@ class DiabolicServitudeCreatureDiesTriggeredAbility extends TriggeredAbilityImpl
public DiabolicServitudeCreatureDiesTriggeredAbility() { public DiabolicServitudeCreatureDiesTriggeredAbility() {
super(Zone.BATTLEFIELD, new DiabolicServitudeExileCreatureEffect(), false); super(Zone.BATTLEFIELD, new DiabolicServitudeExileCreatureEffect(), false);
setLeavesTheBattlefieldTrigger(true);
} }
private DiabolicServitudeCreatureDiesTriggeredAbility(final DiabolicServitudeCreatureDiesTriggeredAbility ability) { private DiabolicServitudeCreatureDiesTriggeredAbility(final DiabolicServitudeCreatureDiesTriggeredAbility ability) {
@ -123,6 +126,11 @@ class DiabolicServitudeCreatureDiesTriggeredAbility extends TriggeredAbilityImpl
public String getRule() { public String getRule() {
return "When the creature put onto the battlefield with {this} dies, exile it and return {this} to its owner's hand."; return "When the creature put onto the battlefield with {this} dies, exile it and return {this} to its owner's hand.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class DiabolicServitudeExileCreatureEffect extends OneShotEffect { class DiabolicServitudeExileCreatureEffect extends OneShotEffect {

View file

@ -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 sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -53,6 +53,7 @@ class DreadhoundTriggeredAbility extends TriggeredAbilityImpl {
public DreadhoundTriggeredAbility() { public DreadhoundTriggeredAbility() {
super(Zone.BATTLEFIELD, new LoseLifeOpponentsEffect(1)); super(Zone.BATTLEFIELD, new LoseLifeOpponentsEffect(1));
setTriggerPhrase("Whenever a creature dies or a creature card is put into a graveyard from a library, "); setTriggerPhrase("Whenever a creature dies or a creature card is put into a graveyard from a library, ");
setLeavesTheBattlefieldTrigger(true);
} }
private DreadhoundTriggeredAbility(final DreadhoundTriggeredAbility ability) { private DreadhoundTriggeredAbility(final DreadhoundTriggeredAbility ability) {

View file

@ -1,5 +1,6 @@
package mage.cards.e; package mage.cards.e;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
@ -97,6 +98,7 @@ class EndlessEvilBounceAbility extends TriggeredAbilityImpl {
public EndlessEvilBounceAbility() { public EndlessEvilBounceAbility() {
super(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(false, true)); super(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(false, true));
setLeavesTheBattlefieldTrigger(true);
} }
private EndlessEvilBounceAbility(final EndlessEvilBounceAbility effect) { private EndlessEvilBounceAbility(final EndlessEvilBounceAbility effect) {
@ -126,4 +128,9 @@ class EndlessEvilBounceAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "When enchanted creature dies, if that creature was a Horror, return {this} to its owner's hand."; return "When enchanted creature dies, if that creature was a Horror, return {this} to its owner's hand.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -3,6 +3,7 @@ package mage.cards.e;
import java.util.UUID; import java.util.UUID;
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.effects.Effect; import mage.abilities.effects.Effect;
@ -65,6 +66,7 @@ class EnigmaSphinxTriggeredAbility extends TriggeredAbilityImpl {
public EnigmaSphinxTriggeredAbility(Effect effect, boolean optional) { public EnigmaSphinxTriggeredAbility(Effect effect, boolean optional) {
super(Zone.ALL, effect, optional); super(Zone.ALL, effect, optional);
setTriggerPhrase("When {this} is put into your graveyard from the battlefield, "); setTriggerPhrase("When {this} is put into your graveyard from the battlefield, ");
setLeavesTheBattlefieldTrigger(true);
} }
private EnigmaSphinxTriggeredAbility(final EnigmaSphinxTriggeredAbility ability) { private EnigmaSphinxTriggeredAbility(final EnigmaSphinxTriggeredAbility ability) {
@ -94,6 +96,11 @@ class EnigmaSphinxTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class EnigmaSphinxEffect extends OneShotEffect { class EnigmaSphinxEffect extends OneShotEffect {

View file

@ -201,9 +201,9 @@ class EvelynTheCovetousWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if ((event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.LAND_PLAYED) if ((event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.LAND_PLAYED)
&& event.getAdditionalReference() != null) { && event.getApprovingObject() != null) {
usedMap.computeIfAbsent( usedMap.computeIfAbsent(
event.getAdditionalReference() event.getApprovingObject()
.getApprovingMageObjectReference(), .getApprovingMageObjectReference(),
x -> new HashSet<>() x -> new HashSet<>()
).add(event.getPlayerId()); ).add(event.getPlayerId());

View file

@ -1,6 +1,8 @@
package mage.cards.f; package mage.cards.f;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.AbilityImpl;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect; import mage.abilities.effects.common.LoseLifeTargetEffect;
@ -51,6 +53,7 @@ class FalkenrathNobleTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), false); super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), false);
this.addEffect(new GainLifeEffect(1)); this.addEffect(new GainLifeEffect(1));
this.addTarget(new TargetPlayer()); this.addTarget(new TargetPlayer());
setLeavesTheBattlefieldTrigger(true);
} }
private FalkenrathNobleTriggeredAbility(final FalkenrathNobleTriggeredAbility ability) { private FalkenrathNobleTriggeredAbility(final FalkenrathNobleTriggeredAbility ability) {
@ -87,4 +90,9 @@ class FalkenrathNobleTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever {this} or another creature dies, target player loses 1 life and you gain 1 life."; return "Whenever {this} or another creature dies, target player loses 1 life and you gain 1 life.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -1,7 +1,6 @@
package mage.cards.f; package mage.cards.f;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.CantBlockAbility; import mage.abilities.common.CantBlockAbility;
@ -132,10 +131,10 @@ class FlameskullWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST if (event.getType() != GameEvent.EventType.SPELL_CAST
|| event.getAdditionalReference() == null) { || event.getApprovingObject() == null) {
return; return;
} }
MageObjectReference mor = event.getAdditionalReference().getApprovingMageObjectReference(); MageObjectReference mor = event.getApprovingObject().getApprovingMageObjectReference();
Spell spell = game.getSpell(event.getTargetId()); Spell spell = game.getSpell(event.getTargetId());
if (mor == null || spell == null) { if (mor == null || spell == null) {
return; return;

View file

@ -91,7 +91,7 @@ class GaleaKindlerOfHopeTriggeredAbility extends TriggeredAbilityImpl {
if (!isControlledBy(event.getPlayerId()) if (!isControlledBy(event.getPlayerId())
|| event.getZone() != Zone.LIBRARY || event.getZone() != Zone.LIBRARY
|| !event || !event
.getAdditionalReference() .getApprovingObject()
.getApprovingMageObjectReference() .getApprovingMageObjectReference()
.refersTo(this.getSourceObject(game), game)) { .refersTo(this.getSourceObject(game), game)) {
return false; return false;

View file

@ -162,7 +162,7 @@ class GlimpseTheCosmosWatcher extends Watcher {
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.CAST_SPELL if (event.getType() == GameEvent.EventType.CAST_SPELL
&& event.hasApprovingIdentifier(MageIdentifier.GlimpseTheCosmosWatcher)) { && event.hasApprovingIdentifier(MageIdentifier.GlimpseTheCosmosWatcher)) {
Ability approvingAbility = event.getAdditionalReference().getApprovingAbility(); Ability approvingAbility = event.getApprovingObject().getApprovingAbility();
if (approvingAbility != null if (approvingAbility != null
&& approvingAbility.getSourceId().equals(event.getSourceId())) { && approvingAbility.getSourceId().equals(event.getSourceId())) {
sourceCards.add(game.getCard(event.getSourceId())); sourceCards.add(game.getCard(event.getSourceId()));

View file

@ -2,6 +2,8 @@
package mage.cards.g; package mage.cards.g;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
@ -53,6 +55,7 @@ class GraveBetrayalTriggeredAbility extends TriggeredAbilityImpl {
public GraveBetrayalTriggeredAbility() { public GraveBetrayalTriggeredAbility() {
super(Zone.BATTLEFIELD, null); super(Zone.BATTLEFIELD, null);
setLeavesTheBattlefieldTrigger(true);
} }
private GraveBetrayalTriggeredAbility(final GraveBetrayalTriggeredAbility ability) { private GraveBetrayalTriggeredAbility(final GraveBetrayalTriggeredAbility ability) {
@ -92,6 +95,11 @@ class GraveBetrayalTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a creature you don't control dies, return it to the battlefield under your control with an additional +1/+1 counter on it at the beginning of the next end step. That creature is a black Zombie in addition to its other colors and types."; return "Whenever a creature you don't control dies, return it to the battlefield under your control with an additional +1/+1 counter on it at the beginning of the next end step. That creature is a black Zombie in addition to its other colors and types.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class GraveBetrayalEffect extends OneShotEffect { class GraveBetrayalEffect extends OneShotEffect {
@ -125,7 +133,6 @@ class GraveBetrayalEffect extends OneShotEffect {
} }
return false; return false;
} }
} }
class GraveBetrayalReplacementEffect extends ReplacementEffectImpl { class GraveBetrayalReplacementEffect extends ReplacementEffectImpl {

View file

@ -1,5 +1,6 @@
package mage.cards.g; package mage.cards.g;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -29,7 +30,6 @@ public final class GravePact extends CardImpl {
public GravePact(UUID ownerId, CardSetInfo setInfo) { public GravePact(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}{B}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}{B}");
// Whenever a creature you control dies, each other player sacrifices a creature. // Whenever a creature you control dies, each other player sacrifices a creature.
this.addAbility(new GravePactTriggeredAbility()); this.addAbility(new GravePactTriggeredAbility());
} }
@ -49,6 +49,7 @@ class GravePactTriggeredAbility extends TriggeredAbilityImpl {
public GravePactTriggeredAbility() { public GravePactTriggeredAbility() {
super(Zone.BATTLEFIELD, new GravePactEffect()); super(Zone.BATTLEFIELD, new GravePactEffect());
setTriggerPhrase("Whenever a creature you control dies, "); setTriggerPhrase("Whenever a creature you control dies, ");
this.setLeavesTheBattlefieldTrigger(true);
} }
private GravePactTriggeredAbility(final GravePactTriggeredAbility ability) { private GravePactTriggeredAbility(final GravePactTriggeredAbility ability) {
@ -74,6 +75,11 @@ class GravePactTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class GravePactEffect extends OneShotEffect { class GravePactEffect extends OneShotEffect {

View file

@ -48,6 +48,7 @@ class GutterGrimeTriggeredAbility extends TriggeredAbilityImpl {
public GutterGrimeTriggeredAbility() { public GutterGrimeTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.SLIME.createInstance()), false); super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.SLIME.createInstance()), false);
this.addEffect(new GutterGrimeEffect()); this.addEffect(new GutterGrimeEffect());
setLeavesTheBattlefieldTrigger(true);
} }
private GutterGrimeTriggeredAbility(final GutterGrimeTriggeredAbility ability) { private GutterGrimeTriggeredAbility(final GutterGrimeTriggeredAbility ability) {
@ -83,6 +84,11 @@ class GutterGrimeTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a nontoken creature you control dies, put a slime counter on {this}, then create a green Ooze creature token with \"This creature's power and toughness are each equal to the number of slime counters on {this}.\""; return "Whenever a nontoken creature you control dies, put a slime counter on {this}, then create a green Ooze creature token with \"This creature's power and toughness are each equal to the number of slime counters on {this}.\"";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class GutterGrimeEffect extends OneShotEffect { class GutterGrimeEffect extends OneShotEffect {

View file

@ -1,6 +1,7 @@
package mage.cards.h; package mage.cards.h;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -51,6 +52,7 @@ class HatefulEidolonTriggeredAbility extends TriggeredAbilityImpl {
HatefulEidolonTriggeredAbility() { HatefulEidolonTriggeredAbility() {
super(Zone.BATTLEFIELD, null, false); super(Zone.BATTLEFIELD, null, false);
setLeavesTheBattlefieldTrigger(true);
} }
private HatefulEidolonTriggeredAbility(final HatefulEidolonTriggeredAbility ability) { private HatefulEidolonTriggeredAbility(final HatefulEidolonTriggeredAbility ability) {
@ -105,4 +107,9 @@ class HatefulEidolonTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever an enchanted creature dies, draw a card for each " return "Whenever an enchanted creature dies, draw a card for each "
+ "Aura you controlled that was attached to it."; + "Aura you controlled that was attached to it.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -185,7 +185,7 @@ class HaukensInsightWatcher extends Watcher {
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.LAND_PLAYED) { if (event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.LAND_PLAYED) {
if (event.hasApprovingIdentifier(MageIdentifier.HaukensInsightWatcher)) { if (event.hasApprovingIdentifier(MageIdentifier.HaukensInsightWatcher)) {
usedFrom.add(event.getAdditionalReference().getApprovingMageObjectReference()); usedFrom.add(event.getApprovingObject().getApprovingMageObjectReference());
} }
} }
} }

View file

@ -173,12 +173,12 @@ class HedonistsTroveWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST if (event.getType() != GameEvent.EventType.SPELL_CAST
|| event.getAdditionalReference() == null) { || event.getApprovingObject() == null) {
return; return;
} }
playerMap playerMap
.computeIfAbsent(event.getPlayerId(), x -> new HashSet<>()) .computeIfAbsent(event.getPlayerId(), x -> new HashSet<>())
.add(event.getAdditionalReference().getApprovingMageObjectReference()); .add(event.getApprovingObject().getApprovingMageObjectReference());
playerMap.get(event.getPlayerId()).removeIf(Objects::isNull); playerMap.get(event.getPlayerId()).removeIf(Objects::isNull);
} }

View file

@ -224,7 +224,7 @@ class IanMalcolmChaoticianWatcher extends Watcher {
if (event.getType() == GameEvent.EventType.SPELL_CAST && if (event.getType() == GameEvent.EventType.SPELL_CAST &&
event.hasApprovingIdentifier(MageIdentifier.IanMalcolmChaoticianWatcher)) { event.hasApprovingIdentifier(MageIdentifier.IanMalcolmChaoticianWatcher)) {
usedMap.computeIfAbsent( usedMap.computeIfAbsent(
event.getAdditionalReference() event.getApprovingObject()
.getApprovingMageObjectReference(), .getApprovingMageObjectReference(),
x -> new HashSet<>() x -> new HashSet<>()
).add(event.getPlayerId()); ).add(event.getPlayerId());

View file

@ -211,10 +211,10 @@ class IdolOfEnduranceWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST) { if (event.getType() == GameEvent.EventType.SPELL_CAST) {
if (event.getAdditionalReference() == null) { if (event.getApprovingObject() == null) {
return; return;
} }
morMap.computeIfAbsent(event.getAdditionalReference().getApprovingMageObjectReference(), m -> new HashMap<>()) morMap.computeIfAbsent(event.getApprovingObject().getApprovingMageObjectReference(), m -> new HashMap<>())
.compute(event.getPlayerId(), (u, i) -> i == null ? 0 : Integer.sum(i, -1)); .compute(event.getPlayerId(), (u, i) -> i == null ? 0 : Integer.sum(i, -1));
} }
} }

View file

@ -1,7 +1,9 @@
package mage.cards.i; package mage.cards.i;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.SavedDamageValue; import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
@ -55,6 +57,7 @@ class InfestedThrinaxTriggeredAbility extends DelayedTriggeredAbility {
InfestedThrinaxTriggeredAbility() { InfestedThrinaxTriggeredAbility() {
super(new CreateTokenEffect(new SaprolingToken(), SavedDamageValue.MUCH), Duration.EndOfTurn, false, false); super(new CreateTokenEffect(new SaprolingToken(), SavedDamageValue.MUCH), Duration.EndOfTurn, false, false);
setLeavesTheBattlefieldTrigger(true);
} }
private InfestedThrinaxTriggeredAbility(final InfestedThrinaxTriggeredAbility ability) { private InfestedThrinaxTriggeredAbility(final InfestedThrinaxTriggeredAbility ability) {
@ -89,4 +92,9 @@ class InfestedThrinaxTriggeredAbility extends DelayedTriggeredAbility {
return "Whenever a nontoken creature you control dies, " + return "Whenever a nontoken creature you control dies, " +
"create a number of 1/1 green Saproling creature tokens equal to that creature's power."; "create a number of 1/1 green Saproling creature tokens equal to that creature's power.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -94,6 +94,7 @@ class JerrenCorruptedBishopTriggeredAbility extends TriggeredAbilityImpl {
JerrenCorruptedBishopTriggeredAbility() { JerrenCorruptedBishopTriggeredAbility() {
super(Zone.BATTLEFIELD, new LoseLifeSourceControllerEffect(1)); super(Zone.BATTLEFIELD, new LoseLifeSourceControllerEffect(1));
this.addEffect(new CreateTokenEffect(new HumanToken())); this.addEffect(new CreateTokenEffect(new HumanToken()));
setLeavesTheBattlefieldTrigger(true);
} }
private JerrenCorruptedBishopTriggeredAbility(final JerrenCorruptedBishopTriggeredAbility ability) { private JerrenCorruptedBishopTriggeredAbility(final JerrenCorruptedBishopTriggeredAbility ability) {

View file

@ -123,7 +123,7 @@ class KaghaShadowArchdruidWatcher extends Watcher {
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if ((GameEvent.EventType.SPELL_CAST.equals(event.getType()) || GameEvent.EventType.LAND_PLAYED.equals(event.getType())) if ((GameEvent.EventType.SPELL_CAST.equals(event.getType()) || GameEvent.EventType.LAND_PLAYED.equals(event.getType()))
&& event.hasApprovingIdentifier(MageIdentifier.KaghaShadowArchdruidWatcher)) { && event.hasApprovingIdentifier(MageIdentifier.KaghaShadowArchdruidWatcher)) {
usedFrom.add(event.getAdditionalReference().getApprovingMageObjectReference()); usedFrom.add(event.getApprovingObject().getApprovingMageObjectReference());
} }
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event; ZoneChangeEvent zEvent = (ZoneChangeEvent) event;

View file

@ -44,6 +44,7 @@ class KarmicJusticeTriggeredAbility extends TriggeredAbilityImpl {
KarmicJusticeTriggeredAbility() { KarmicJusticeTriggeredAbility() {
super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true); super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true);
this.setLeavesTheBattlefieldTrigger(true);
} }
private KarmicJusticeTriggeredAbility(final KarmicJusticeTriggeredAbility ability) { private KarmicJusticeTriggeredAbility(final KarmicJusticeTriggeredAbility ability) {

View file

@ -78,6 +78,7 @@ class KayaTheInexorableTriggeredAbility extends TriggeredAbilityImpl {
public KayaTheInexorableTriggeredAbility() { public KayaTheInexorableTriggeredAbility() {
super(Zone.ALL, null, false); super(Zone.ALL, null, false);
this.setLeavesTheBattlefieldTrigger(true);
} }
private KayaTheInexorableTriggeredAbility(KayaTheInexorableTriggeredAbility ability) { private KayaTheInexorableTriggeredAbility(KayaTheInexorableTriggeredAbility ability) {
@ -107,22 +108,6 @@ class KayaTheInexorableTriggeredAbility extends TriggeredAbilityImpl {
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
Permanent sourcePermanent = null;
if (game.getState().getZone(getSourceId()) == Zone.BATTLEFIELD) {
sourcePermanent = game.getPermanent(getSourceId());
} else {
if (game.checkShortLivingLKI(getSourceId(), Zone.BATTLEFIELD)) {
sourcePermanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD);
}
}
if (sourcePermanent == null) {
return false;
}
return hasSourceObjectAbility(game, sourcePermanent, event);
}
@Override @Override
public KayaTheInexorableTriggeredAbility copy() { public KayaTheInexorableTriggeredAbility copy() {
return new KayaTheInexorableTriggeredAbility(this); return new KayaTheInexorableTriggeredAbility(this);

View file

@ -60,6 +60,7 @@ class KayasGhostformTriggeredAbility extends TriggeredAbilityImpl {
KayasGhostformTriggeredAbility() { KayasGhostformTriggeredAbility() {
super(Zone.ALL, new ReturnToBattlefieldUnderYourControlAttachedEffect(), false); super(Zone.ALL, new ReturnToBattlefieldUnderYourControlAttachedEffect(), false);
setLeavesTheBattlefieldTrigger(true);
} }
private KayasGhostformTriggeredAbility(final KayasGhostformTriggeredAbility ability) { private KayasGhostformTriggeredAbility(final KayasGhostformTriggeredAbility ability) {

View file

@ -178,9 +178,9 @@ class KessDissidentMageWatcher extends Watcher {
&& event.hasApprovingIdentifier(MageIdentifier.KessDissidentMageWatcher)) { && event.hasApprovingIdentifier(MageIdentifier.KessDissidentMageWatcher)) {
Spell spell = (Spell) game.getObject(event.getTargetId()); Spell spell = (Spell) game.getObject(event.getTargetId());
if (spell != null) { if (spell != null) {
allowingObjects.add(event.getAdditionalReference().getApprovingMageObjectReference()); allowingObjects.add(event.getApprovingObject().getApprovingMageObjectReference());
castSpells.put(new MageObjectReference(spell.getMainCard().getId(), game), castSpells.put(new MageObjectReference(spell.getMainCard().getId(), game),
event.getAdditionalReference().getApprovingAbility().getSourceId()); event.getApprovingObject().getApprovingAbility().getSourceId());
} }
} }
} }

View file

@ -170,7 +170,7 @@ class KotoseTheSilentSpiderWatcher extends Watcher {
morMap.values().removeIf(Set::isEmpty); morMap.values().removeIf(Set::isEmpty);
return; return;
} }
if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getAdditionalReference() == null) { if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getApprovingObject() == null) {
return; return;
} }
Spell spell = game.getSpell(event.getTargetId()); Spell spell = game.getSpell(event.getTargetId());
@ -178,7 +178,7 @@ class KotoseTheSilentSpiderWatcher extends Watcher {
return; return;
} }
morMap.getOrDefault( morMap.getOrDefault(
event.getAdditionalReference().getApprovingMageObjectReference(), Collections.emptySet() event.getApprovingObject().getApprovingMageObjectReference(), Collections.emptySet()
).removeIf(set -> set ).removeIf(set -> set
.stream() .stream()
.anyMatch(mor -> mor.getSourceId().equals(spell.getMainCard().getId()) .anyMatch(mor -> mor.getSourceId().equals(spell.getMainCard().getId())

View file

@ -222,10 +222,10 @@ class LobeliaDefenderOfBagEndWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.PLAY_LAND) { if (event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.PLAY_LAND) {
if (event.getAdditionalReference() == null) { if (event.getApprovingObject() == null) {
return; return;
} }
morMap.computeIfAbsent(event.getAdditionalReference().getApprovingMageObjectReference(), m -> new HashMap<>()) morMap.computeIfAbsent(event.getApprovingObject().getApprovingMageObjectReference(), m -> new HashMap<>())
.compute(event.getPlayerId(), (u, i) -> i == null ? 0 : Integer.sum(i, -1)); .compute(event.getPlayerId(), (u, i) -> i == null ? 0 : Integer.sum(i, -1));
} }
} }

View file

@ -1,6 +1,7 @@
package mage.cards.l; package mage.cards.l;
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.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -56,6 +57,7 @@ class LuminousBroodmothTriggeredAbility extends TriggeredAbilityImpl {
LuminousBroodmothTriggeredAbility() { LuminousBroodmothTriggeredAbility() {
super(Zone.BATTLEFIELD, new LuminousBroodmothEffect(), false); super(Zone.BATTLEFIELD, new LuminousBroodmothEffect(), false);
setLeavesTheBattlefieldTrigger(true);
} }
private LuminousBroodmothTriggeredAbility(final LuminousBroodmothTriggeredAbility ability) { private LuminousBroodmothTriggeredAbility(final LuminousBroodmothTriggeredAbility ability) {
@ -97,6 +99,11 @@ class LuminousBroodmothTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever a creature you control without flying dies, " return "Whenever a creature you control without flying dies, "
+ "return it to the battlefield under its owner's control with a flying counter on it."; + "return it to the battlefield under its owner's control with a flying counter on it.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class LuminousBroodmothEffect extends OneShotEffect { class LuminousBroodmothEffect extends OneShotEffect {

View file

@ -70,6 +70,7 @@ class LyndeCheerfulTormentorCurseDiesTriggeredAbility extends TriggeredAbilityIm
new LyndeCheerfulTormentorReturnCurseEffect() new LyndeCheerfulTormentorReturnCurseEffect()
) )
)); ));
setLeavesTheBattlefieldTrigger(true);
} }
private LyndeCheerfulTormentorCurseDiesTriggeredAbility(final LyndeCheerfulTormentorCurseDiesTriggeredAbility ability) { private LyndeCheerfulTormentorCurseDiesTriggeredAbility(final LyndeCheerfulTormentorCurseDiesTriggeredAbility ability) {
@ -102,8 +103,8 @@ class LyndeCheerfulTormentorCurseDiesTriggeredAbility extends TriggeredAbilityIm
} }
@Override @Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game); return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} }
@Override @Override

View file

@ -148,14 +148,14 @@ class MaestrosAscendancyWatcher extends Watcher {
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST if (event.getType() == GameEvent.EventType.SPELL_CAST
&& event.hasApprovingIdentifier(MageIdentifier.MaestrosAscendencyAlternateCast) && event.hasApprovingIdentifier(MageIdentifier.MaestrosAscendencyAlternateCast)
&& event.getAdditionalReference() != null) { && event.getApprovingObject() != null) {
playerMap.computeIfAbsent( playerMap.computeIfAbsent(
event.getAdditionalReference() event.getApprovingObject()
.getApprovingMageObjectReference(), .getApprovingMageObjectReference(),
x -> new HashSet<>() x -> new HashSet<>()
).add(event.getPlayerId()); ).add(event.getPlayerId());
spellMap.computeIfAbsent( spellMap.computeIfAbsent(
event.getAdditionalReference() event.getApprovingObject()
.getApprovingMageObjectReference(), .getApprovingMageObjectReference(),
x -> new HashSet<>() x -> new HashSet<>()
).add(new MageObjectReference(event.getTargetId(), game)); ).add(new MageObjectReference(event.getTargetId(), game));

View file

@ -2,6 +2,7 @@ package mage.cards.m;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
@ -59,6 +60,7 @@ class MagusOfTheBridgeTriggeredAbility extends TriggeredAbilityImpl {
public MagusOfTheBridgeTriggeredAbility() { public MagusOfTheBridgeTriggeredAbility() {
super(Zone.BATTLEFIELD, new ExileSourceEffect()); super(Zone.BATTLEFIELD, new ExileSourceEffect());
setTriggerPhrase("When a creature is put into an opponent's graveyard from the battlefield, "); setTriggerPhrase("When a creature is put into an opponent's graveyard from the battlefield, ");
setLeavesTheBattlefieldTrigger(true);
} }
private MagusOfTheBridgeTriggeredAbility(final MagusOfTheBridgeTriggeredAbility ability) { private MagusOfTheBridgeTriggeredAbility(final MagusOfTheBridgeTriggeredAbility ability) {
@ -86,4 +88,9 @@ class MagusOfTheBridgeTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -117,11 +117,11 @@ class MarchOfRecklessJoyWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getAdditionalReference() == null) { if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getApprovingObject() == null) {
return; return;
} }
morMap.compute(event morMap.compute(event
.getAdditionalReference() .getApprovingObject()
.getApprovingMageObjectReference(), .getApprovingMageObjectReference(),
CardUtil::setOrIncrementValue CardUtil::setOrIncrementValue
); );

View file

@ -3,6 +3,7 @@ package mage.cards.m;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
@ -67,6 +68,7 @@ class MarchesaTheBlackRoseTriggeredAbility extends TriggeredAbilityImpl {
public MarchesaTheBlackRoseTriggeredAbility() { public MarchesaTheBlackRoseTriggeredAbility() {
super(Zone.BATTLEFIELD, new MarchesaTheBlackRoseEffect()); super(Zone.BATTLEFIELD, new MarchesaTheBlackRoseEffect());
setTriggerPhrase("Whenever a creature you control with a +1/+1 counter on it dies, "); setTriggerPhrase("Whenever a creature you control with a +1/+1 counter on it dies, ");
setLeavesTheBattlefieldTrigger(true);
} }
private MarchesaTheBlackRoseTriggeredAbility(final MarchesaTheBlackRoseTriggeredAbility ability) { private MarchesaTheBlackRoseTriggeredAbility(final MarchesaTheBlackRoseTriggeredAbility ability) {
@ -100,6 +102,11 @@ class MarchesaTheBlackRoseTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class MarchesaTheBlackRoseEffect extends OneShotEffect { class MarchesaTheBlackRoseEffect extends OneShotEffect {

View file

@ -1,6 +1,7 @@
package mage.cards.m; package mage.cards.m;
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.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
@ -165,6 +166,7 @@ class MariTheKillingQuillCreatureDiesAbility extends TriggeredAbilityImpl {
public MariTheKillingQuillCreatureDiesAbility() { public MariTheKillingQuillCreatureDiesAbility() {
super(Zone.BATTLEFIELD, new MariTheKillingQuillExileCreatureEffect(), false); super(Zone.BATTLEFIELD, new MariTheKillingQuillExileCreatureEffect(), false);
setLeavesTheBattlefieldTrigger(true);
} }
private MariTheKillingQuillCreatureDiesAbility(final MariTheKillingQuillCreatureDiesAbility ability) { private MariTheKillingQuillCreatureDiesAbility(final MariTheKillingQuillCreatureDiesAbility ability) {
@ -202,6 +204,11 @@ class MariTheKillingQuillCreatureDiesAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a creature an opponent controls dies, exile it with a hit counter on it."; return "Whenever a creature an opponent controls dies, exile it with a hit counter on it.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class MariTheKillingQuillExileCreatureEffect extends OneShotEffect { class MariTheKillingQuillExileCreatureEffect extends OneShotEffect {

View file

@ -1,5 +1,6 @@
package mage.cards.m; package mage.cards.m;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
@ -50,6 +51,7 @@ class MartyrsBondTriggeredAbility extends TriggeredAbilityImpl {
public MartyrsBondTriggeredAbility() { public MartyrsBondTriggeredAbility() {
super(Zone.BATTLEFIELD, new MartyrsBondEffect()); super(Zone.BATTLEFIELD, new MartyrsBondEffect());
setLeavesTheBattlefieldTrigger(true);
} }
private MartyrsBondTriggeredAbility(final MartyrsBondTriggeredAbility ability) { private MartyrsBondTriggeredAbility(final MartyrsBondTriggeredAbility ability) {
@ -88,6 +90,10 @@ class MartyrsBondTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever {this} or another nonland permanent you control is put into a graveyard from the battlefield, each opponent sacrifices a permanent that shares a card type with it."; return "Whenever {this} or another nonland permanent you control is put into a graveyard from the battlefield, each opponent sacrifices a permanent that shares a card type with it.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class MartyrsBondEffect extends OneShotEffect { class MartyrsBondEffect extends OneShotEffect {

View file

@ -1,8 +1,10 @@
package mage.cards.m; package mage.cards.m;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.effects.common.continuous.BoostAllEffect;
@ -77,6 +79,7 @@ class MassacreGirlDelayedTriggeredAbility extends DelayedTriggeredAbility {
MassacreGirlDelayedTriggeredAbility() { MassacreGirlDelayedTriggeredAbility() {
super(new BoostAllEffect(-1, -1, Duration.EndOfTurn, true), Duration.EndOfTurn, false); super(new BoostAllEffect(-1, -1, Duration.EndOfTurn, true), Duration.EndOfTurn, false);
setLeavesTheBattlefieldTrigger(true);
} }
private MassacreGirlDelayedTriggeredAbility(final MassacreGirlDelayedTriggeredAbility ability) { private MassacreGirlDelayedTriggeredAbility(final MassacreGirlDelayedTriggeredAbility ability) {
@ -103,4 +106,9 @@ class MassacreGirlDelayedTriggeredAbility extends DelayedTriggeredAbility {
public String getRule() { public String getRule() {
return "Whenever a creature dies this turn, each creature other than {this} gets -1/-1 until end of turn"; return "Whenever a creature dies this turn, each creature other than {this} gets -1/-1 until end of turn";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -2,6 +2,7 @@ package mage.cards.m;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
@ -52,6 +53,7 @@ class MassacreWurmTriggeredAbility extends TriggeredAbilityImpl {
MassacreWurmTriggeredAbility() { MassacreWurmTriggeredAbility() {
super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(2)); super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(2));
setTriggerPhrase("Whenever a creature an opponent controls dies, "); setTriggerPhrase("Whenever a creature an opponent controls dies, ");
setLeavesTheBattlefieldTrigger(true);
} }
private MassacreWurmTriggeredAbility(final MassacreWurmTriggeredAbility ability) { private MassacreWurmTriggeredAbility(final MassacreWurmTriggeredAbility ability) {
@ -81,4 +83,9 @@ class MassacreWurmTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -79,6 +79,7 @@ class MillicentRestlessRevenantTriggeredAbility extends TriggeredAbilityImpl {
MillicentRestlessRevenantTriggeredAbility() { MillicentRestlessRevenantTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken())); super(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken()));
setLeavesTheBattlefieldTrigger(true);
} }
private MillicentRestlessRevenantTriggeredAbility(final MillicentRestlessRevenantTriggeredAbility ability) { private MillicentRestlessRevenantTriggeredAbility(final MillicentRestlessRevenantTriggeredAbility ability) {
@ -124,8 +125,12 @@ class MillicentRestlessRevenantTriggeredAbility extends TriggeredAbilityImpl {
} }
@Override @Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game); if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} else {
return super.isInUseableZone(game, sourceObject, event);
}
} }
@Override @Override

View file

@ -4,6 +4,8 @@ package mage.cards.m;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
@ -60,6 +62,7 @@ class MimicVatTriggeredAbility extends TriggeredAbilityImpl {
MimicVatTriggeredAbility() { MimicVatTriggeredAbility() {
super(Zone.BATTLEFIELD, new MimicVatEffect(), true); super(Zone.BATTLEFIELD, new MimicVatEffect(), true);
setLeavesTheBattlefieldTrigger(true);
} }
private MimicVatTriggeredAbility(final MimicVatTriggeredAbility ability) { private MimicVatTriggeredAbility(final MimicVatTriggeredAbility ability) {
@ -105,6 +108,11 @@ class MimicVatTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return AbilityWord.IMPRINT.formatWord() + "Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with {this} to its owner's graveyard."; return AbilityWord.IMPRINT.formatWord() + "Whenever a nontoken creature dies, you may exile that card. If you do, return each other card exiled with {this} to its owner's graveyard.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class MimicVatEffect extends OneShotEffect { class MimicVatEffect extends OneShotEffect {

View file

@ -3,6 +3,7 @@ package mage.cards.m;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
@ -47,6 +48,7 @@ class MolderBeastTriggeredAbility extends TriggeredAbilityImpl {
public MolderBeastTriggeredAbility() { public MolderBeastTriggeredAbility() {
super(Zone.BATTLEFIELD, new BoostSourceEffect(2, 0, Duration.EndOfTurn), false); super(Zone.BATTLEFIELD, new BoostSourceEffect(2, 0, Duration.EndOfTurn), false);
setLeavesTheBattlefieldTrigger(true);
} }
private MolderBeastTriggeredAbility(final MolderBeastTriggeredAbility ability) { private MolderBeastTriggeredAbility(final MolderBeastTriggeredAbility ability) {
@ -74,4 +76,9 @@ class MolderBeastTriggeredAbility extends TriggeredAbilityImpl {
public MolderBeastTriggeredAbility copy() { public MolderBeastTriggeredAbility copy() {
return new MolderBeastTriggeredAbility(this); return new MolderBeastTriggeredAbility(this);
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -146,8 +146,8 @@ class MuldrothaTheGravetideWatcher extends Watcher {
private void addPermanentTypes(GameEvent event, Card mageObject, Game game) { private void addPermanentTypes(GameEvent event, Card mageObject, Game game) {
if (mageObject != null if (mageObject != null
&& event.getAdditionalReference() != null && event.getApprovingObject() != null
&& MageIdentifier.MuldrothaTheGravetideWatcher.equals(event.getAdditionalReference().getApprovingAbility().getIdentifier())) { && MageIdentifier.MuldrothaTheGravetideWatcher.equals(event.getApprovingObject().getApprovingAbility().getIdentifier())) {
UUID playerId = null; UUID playerId = null;
if (mageObject instanceof Spell) { if (mageObject instanceof Spell) {
playerId = ((Spell) mageObject).getControllerId(); playerId = ((Spell) mageObject).getControllerId();
@ -155,10 +155,10 @@ class MuldrothaTheGravetideWatcher extends Watcher {
playerId = ((Permanent) mageObject).getControllerId(); playerId = ((Permanent) mageObject).getControllerId();
} }
if (playerId != null) { if (playerId != null) {
Set<CardType> permanentTypes = sourcePlayedPermanentTypes.get(event.getAdditionalReference().getApprovingMageObjectReference()); Set<CardType> permanentTypes = sourcePlayedPermanentTypes.get(event.getApprovingObject().getApprovingMageObjectReference());
if (permanentTypes == null) { if (permanentTypes == null) {
permanentTypes = EnumSet.noneOf(CardType.class); permanentTypes = EnumSet.noneOf(CardType.class);
sourcePlayedPermanentTypes.put(event.getAdditionalReference().getApprovingMageObjectReference(), permanentTypes); sourcePlayedPermanentTypes.put(event.getApprovingObject().getApprovingMageObjectReference(), permanentTypes);
} }
Set<CardType> typesNotCast = EnumSet.noneOf(CardType.class); Set<CardType> typesNotCast = EnumSet.noneOf(CardType.class);
for (CardType cardType : mageObject.getCardType(game)) { for (CardType cardType : mageObject.getCardType(game)) {

View file

@ -51,6 +51,7 @@ class MycoidShepherdTriggeredAbility extends TriggeredAbilityImpl {
public MycoidShepherdTriggeredAbility() { public MycoidShepherdTriggeredAbility() {
super(Zone.BATTLEFIELD, new GainLifeEffect(5), true); super(Zone.BATTLEFIELD, new GainLifeEffect(5), true);
setLeavesTheBattlefieldTrigger(true);
} }
private MycoidShepherdTriggeredAbility(final MycoidShepherdTriggeredAbility ability) { private MycoidShepherdTriggeredAbility(final MycoidShepherdTriggeredAbility ability) {
@ -91,4 +92,9 @@ class MycoidShepherdTriggeredAbility extends TriggeredAbilityImpl {
public MycoidShepherdTriggeredAbility copy() { public MycoidShepherdTriggeredAbility copy() {
return new MycoidShepherdTriggeredAbility(this); return new MycoidShepherdTriggeredAbility(this);
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -121,7 +121,7 @@ class NashiMoonSagesScionWatcher extends Watcher {
morMap.values().removeIf(Set::isEmpty); morMap.values().removeIf(Set::isEmpty);
return; return;
} }
if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getAdditionalReference() == null) { if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getApprovingObject() == null) {
return; return;
} }
Spell spell = game.getSpell(event.getTargetId()); Spell spell = game.getSpell(event.getTargetId());
@ -129,7 +129,7 @@ class NashiMoonSagesScionWatcher extends Watcher {
return; return;
} }
morMap.getOrDefault( morMap.getOrDefault(
event.getAdditionalReference().getApprovingMageObjectReference(), Collections.emptySet() event.getApprovingObject().getApprovingMageObjectReference(), Collections.emptySet()
).removeIf(set -> set ).removeIf(set -> set
.stream() .stream()
.anyMatch(mor -> mor.getSourceId().equals(spell.getMainCard().getId()) .anyMatch(mor -> mor.getSourceId().equals(spell.getMainCard().getId())

View file

@ -3,6 +3,7 @@ package mage.cards.n;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
@ -55,6 +56,7 @@ class NecroskitterTriggeredAbility extends TriggeredAbilityImpl {
public NecroskitterTriggeredAbility() { public NecroskitterTriggeredAbility() {
super(Zone.BATTLEFIELD, new ReturnToBattlefieldUnderYourControlTargetEffect(), true); super(Zone.BATTLEFIELD, new ReturnToBattlefieldUnderYourControlTargetEffect(), true);
setLeavesTheBattlefieldTrigger(true);
} }
private NecroskitterTriggeredAbility(final NecroskitterTriggeredAbility ability) { private NecroskitterTriggeredAbility(final NecroskitterTriggeredAbility ability) {
@ -92,4 +94,9 @@ class NecroskitterTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a creature an opponent controls with a -1/-1 counter on it dies, you may return that card to the battlefield under your control."; return "Whenever a creature an opponent controls with a -1/-1 counter on it dies, you may return that card to the battlefield under your control.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -3,6 +3,7 @@ package mage.cards.n;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.costs.mana.ColoredManaCost; import mage.abilities.costs.mana.ColoredManaCost;
import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.DoIfCostPaid;
@ -55,6 +56,7 @@ class NetherTraitorTriggeredAbility extends TriggeredAbilityImpl {
NetherTraitorTriggeredAbility(){ NetherTraitorTriggeredAbility(){
super(Zone.GRAVEYARD, new DoIfCostPaid(new ReturnSourceFromGraveyardToBattlefieldEffect(), new ColoredManaCost(ColoredManaSymbol.B))); super(Zone.GRAVEYARD, new DoIfCostPaid(new ReturnSourceFromGraveyardToBattlefieldEffect(), new ColoredManaCost(ColoredManaSymbol.B)));
setLeavesTheBattlefieldTrigger(true);
} }
private NetherTraitorTriggeredAbility(final NetherTraitorTriggeredAbility ability) { private NetherTraitorTriggeredAbility(final NetherTraitorTriggeredAbility ability) {
@ -94,4 +96,9 @@ class NetherTraitorTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever another creature is put into your graveyard from the battlefield, you may pay {B}. If you do, return {this} from your graveyard to the battlefield."; return "Whenever another creature is put into your graveyard from the battlefield, you may pay {B}. If you do, return {this} from your graveyard to the battlefield.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -1,5 +1,6 @@
package mage.cards.n; package mage.cards.n;
import mage.MageObject;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
@ -72,6 +73,7 @@ class NimDeathmantleTriggeredAbility extends TriggeredAbilityImpl {
NimDeathmantleTriggeredAbility() { NimDeathmantleTriggeredAbility() {
super(Zone.BATTLEFIELD, new NimDeathmantleEffect(), false); super(Zone.BATTLEFIELD, new NimDeathmantleEffect(), false);
setLeavesTheBattlefieldTrigger(true);
} }
private NimDeathmantleTriggeredAbility(final NimDeathmantleTriggeredAbility ability) { private NimDeathmantleTriggeredAbility(final NimDeathmantleTriggeredAbility ability) {
@ -108,6 +110,11 @@ class NimDeathmantleTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {4}. If you do, return that card to the battlefield and attach {this} to it."; return "Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {4}. If you do, return that card to the battlefield and attach {this} to it.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class NimDeathmantleEffect extends OneShotEffect { class NimDeathmantleEffect extends OneShotEffect {

View file

@ -136,7 +136,7 @@ class OneWithTheMultiverseWatcher extends Watcher {
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST if (event.getType() == GameEvent.EventType.SPELL_CAST
&& event.hasApprovingIdentifier(MageIdentifier.OneWithTheMultiverseWatcher)) { && event.hasApprovingIdentifier(MageIdentifier.OneWithTheMultiverseWatcher)) {
usedFrom.add(event.getAdditionalReference().getApprovingMageObjectReference()); usedFrom.add(event.getApprovingObject().getApprovingMageObjectReference());
} }
} }

View file

@ -1,6 +1,7 @@
package mage.cards.o; package mage.cards.o;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.LifelinkAbility;
@ -51,6 +52,7 @@ class OrahSkyclaveHierophantTriggeredAbility extends TriggeredAbilityImpl {
OrahSkyclaveHierophantTriggeredAbility() { OrahSkyclaveHierophantTriggeredAbility() {
super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect()); super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect());
setLeavesTheBattlefieldTrigger(true);
} }
private OrahSkyclaveHierophantTriggeredAbility(final OrahSkyclaveHierophantTriggeredAbility ability) { private OrahSkyclaveHierophantTriggeredAbility(final OrahSkyclaveHierophantTriggeredAbility ability) {
@ -94,4 +96,9 @@ class OrahSkyclaveHierophantTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever {this} or another Cleric you control dies, return target Cleric card " + return "Whenever {this} or another Cleric you control dies, return target Cleric card " +
"with lesser mana value from your graveyard to the battlefield."; "with lesser mana value from your graveyard to the battlefield.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -70,6 +70,7 @@ class PatronOfTheVeinCreatureDiesTriggeredAbility extends TriggeredAbilityImpl {
public PatronOfTheVeinCreatureDiesTriggeredAbility() { public PatronOfTheVeinCreatureDiesTriggeredAbility() {
super(Zone.BATTLEFIELD, new PatronOfTheVeinExileCreatureEffect(), false); super(Zone.BATTLEFIELD, new PatronOfTheVeinExileCreatureEffect(), false);
setLeavesTheBattlefieldTrigger(true);
} }
private PatronOfTheVeinCreatureDiesTriggeredAbility(final PatronOfTheVeinCreatureDiesTriggeredAbility ability) { private PatronOfTheVeinCreatureDiesTriggeredAbility(final PatronOfTheVeinCreatureDiesTriggeredAbility ability) {
@ -107,6 +108,11 @@ class PatronOfTheVeinCreatureDiesTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a creature an opponent controls dies, exile it and put a +1/+1 counter on each Vampire you control."; return "Whenever a creature an opponent controls dies, exile it and put a +1/+1 counter on each Vampire you control.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class PatronOfTheVeinExileCreatureEffect extends OneShotEffect { class PatronOfTheVeinExileCreatureEffect extends OneShotEffect {

View file

@ -64,6 +64,7 @@ class PeltCollectorTriggeredAbility extends TriggeredAbilityImpl {
PeltCollectorTriggeredAbility() { PeltCollectorTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance())); super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
setLeavesTheBattlefieldTrigger(true);
} }
private PeltCollectorTriggeredAbility(PeltCollectorTriggeredAbility ability) { private PeltCollectorTriggeredAbility(PeltCollectorTriggeredAbility ability) {

View file

@ -44,9 +44,7 @@ public final class PhantasmalImage extends CardImpl {
this.power = new MageInt(0); this.power = new MageInt(0);
this.toughness = new MageInt(0); this.toughness = new MageInt(0);
// You may have Phantasmal Image enter the battlefield as a copy of any creature // You may have Phantasmal Image enter the battlefield as a copy of any creature on the battlefield, except it's an Illusion in addition to its other types and it has "When this creature becomes the target of a spell or ability, sacrifice it."
// on the battlefield, except it's an Illusion in addition to its other types and
// it has "When this creature becomes the target of a spell or ability, sacrifice it."
Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, phantasmalImageApplier); Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, phantasmalImageApplier);
effect.setText(effectText); effect.setText(effectText);
this.addAbility(new EntersBattlefieldAbility(effect, true)); this.addAbility(new EntersBattlefieldAbility(effect, true));

View file

@ -1,5 +1,6 @@
package mage.cards.p; package mage.cards.p;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
@ -97,6 +98,7 @@ class PiasRevolutionTriggeredAbility extends TriggeredAbilityImpl {
public PiasRevolutionTriggeredAbility() { public PiasRevolutionTriggeredAbility() {
super(Zone.BATTLEFIELD, new PiasRevolutionReturnEffect(), false); super(Zone.BATTLEFIELD, new PiasRevolutionReturnEffect(), false);
setTriggerPhrase("Whenever a nontoken artifact is put into your graveyard from the battlefield, "); setTriggerPhrase("Whenever a nontoken artifact is put into your graveyard from the battlefield, ");
setLeavesTheBattlefieldTrigger(true);
} }
private PiasRevolutionTriggeredAbility(final PiasRevolutionTriggeredAbility ability) { private PiasRevolutionTriggeredAbility(final PiasRevolutionTriggeredAbility ability) {
@ -127,4 +129,9 @@ class PiasRevolutionTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -1,5 +1,6 @@
package mage.cards.p; package mage.cards.p;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -40,6 +41,7 @@ class ProperBurialTriggeredAbility extends TriggeredAbilityImpl {
public ProperBurialTriggeredAbility() { public ProperBurialTriggeredAbility() {
super(Zone.BATTLEFIELD, null); super(Zone.BATTLEFIELD, null);
setLeavesTheBattlefieldTrigger(true);
} }
private ProperBurialTriggeredAbility(final ProperBurialTriggeredAbility ability) { private ProperBurialTriggeredAbility(final ProperBurialTriggeredAbility ability) {
@ -76,4 +78,9 @@ class ProperBurialTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a creature you control dies, you gain life equal to that creature's toughness."; return "Whenever a creature you control dies, you gain life equal to that creature's toughness.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -57,6 +57,7 @@ class PsychomancerTriggeredAbility extends TriggeredAbilityImpl {
this.setTriggerPhrase("Whenever {this} or another nontoken artifact you control is put " + this.setTriggerPhrase("Whenever {this} or another nontoken artifact you control is put " +
"into a graveyard from the battlefield or is put into exile from the battlefield, "); "into a graveyard from the battlefield or is put into exile from the battlefield, ");
this.withFlavorWord("Harbinger of Despair"); this.withFlavorWord("Harbinger of Despair");
this.setLeavesTheBattlefieldTrigger(true);
} }
private PsychomancerTriggeredAbility(final PsychomancerTriggeredAbility ability) { private PsychomancerTriggeredAbility(final PsychomancerTriggeredAbility ability) {

View file

@ -62,6 +62,7 @@ class PurgatoryTriggeredAbility extends TriggeredAbilityImpl {
PurgatoryTriggeredAbility() { PurgatoryTriggeredAbility() {
super(Zone.BATTLEFIELD, new PurgatoryExileEffect(), false); super(Zone.BATTLEFIELD, new PurgatoryExileEffect(), false);
setLeavesTheBattlefieldTrigger(true);
} }
private PurgatoryTriggeredAbility(final PurgatoryTriggeredAbility ability) { private PurgatoryTriggeredAbility(final PurgatoryTriggeredAbility ability) {
@ -103,6 +104,11 @@ class PurgatoryTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a nontoken creature is put into your graveyard from the battlefield, exile that card."; return "Whenever a nontoken creature is put into your graveyard from the battlefield, exile that card.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class PurgatoryExileEffect extends OneShotEffect { class PurgatoryExileEffect extends OneShotEffect {

View file

@ -159,12 +159,12 @@ class RadiantScrollwielderWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getAdditionalReference() == null) { if (event.getType() != GameEvent.EventType.SPELL_CAST || event.getApprovingObject() == null) {
return; return;
} }
morMap.put( morMap.put(
new MageObjectReference(event.getSourceId(), game), new MageObjectReference(event.getSourceId(), game),
event.getAdditionalReference().getApprovingMageObjectReference() event.getApprovingObject().getApprovingMageObjectReference()
); );
} }

View file

@ -1,6 +1,7 @@
package mage.cards.r; package mage.cards.r;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -52,6 +53,7 @@ class RemembranceTriggeredAbility extends TriggeredAbilityImpl {
RemembranceTriggeredAbility() { RemembranceTriggeredAbility() {
super(Zone.BATTLEFIELD, null, true); super(Zone.BATTLEFIELD, null, true);
setLeavesTheBattlefieldTrigger(true);
} }
private RemembranceTriggeredAbility(final RemembranceTriggeredAbility ability) { private RemembranceTriggeredAbility(final RemembranceTriggeredAbility ability) {
@ -92,4 +94,9 @@ class RemembranceTriggeredAbility extends TriggeredAbilityImpl {
"you may search your library for a card with the same name as that creature, " + "you may search your library for a card with the same name as that creature, " +
"reveal it, put it into your hand, then shuffle."; "reveal it, put it into your hand, then shuffle.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -63,6 +63,7 @@ class ReyhanLastOfTheAbzanTriggeredAbility extends TriggeredAbilityImpl {
public ReyhanLastOfTheAbzanTriggeredAbility() { public ReyhanLastOfTheAbzanTriggeredAbility() {
super(Zone.BATTLEFIELD, null, true); super(Zone.BATTLEFIELD, null, true);
setLeavesTheBattlefieldTrigger(true);
} }
private ReyhanLastOfTheAbzanTriggeredAbility(final ReyhanLastOfTheAbzanTriggeredAbility ability) { private ReyhanLastOfTheAbzanTriggeredAbility(final ReyhanLastOfTheAbzanTriggeredAbility ability) {

View file

@ -1,6 +1,7 @@
package mage.cards.r; package mage.cards.r;
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.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -65,6 +66,7 @@ class RhukHexgoldNabberTriggeredAbility extends TriggeredAbilityImpl {
RhukHexgoldNabberTriggeredAbility() { RhukHexgoldNabberTriggeredAbility() {
super(Zone.BATTLEFIELD, new RhukHexgoldNabberEffect(), true); super(Zone.BATTLEFIELD, new RhukHexgoldNabberEffect(), true);
setLeavesTheBattlefieldTrigger(true);
} }
private RhukHexgoldNabberTriggeredAbility(final RhukHexgoldNabberTriggeredAbility ability) { private RhukHexgoldNabberTriggeredAbility(final RhukHexgoldNabberTriggeredAbility ability) {
@ -110,6 +112,15 @@ class RhukHexgoldNabberTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever an equipped creature you control other than {this} attacks or dies, " + return "Whenever an equipped creature you control other than {this} attacks or dies, " +
"you may attach all Equipment attached to that creature to {this}."; "you may attach all Equipment attached to that creature to {this}.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} else {
return super.isInUseableZone(game, sourceObject, event);
}
}
} }
class RhukHexgoldNabberEffect extends OneShotEffect { class RhukHexgoldNabberEffect extends OneShotEffect {

View file

@ -1,6 +1,7 @@
package mage.cards.r; package mage.cards.r;
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;
@ -70,6 +71,7 @@ class RienneAngelOfRebirthTriggeredAbility extends TriggeredAbilityImpl {
RienneAngelOfRebirthTriggeredAbility() { RienneAngelOfRebirthTriggeredAbility() {
super(Zone.BATTLEFIELD, new RienneAngelOfRebirthEffect(), false); super(Zone.BATTLEFIELD, new RienneAngelOfRebirthEffect(), false);
setLeavesTheBattlefieldTrigger(true);
} }
private RienneAngelOfRebirthTriggeredAbility(final RienneAngelOfRebirthTriggeredAbility ability) { private RienneAngelOfRebirthTriggeredAbility(final RienneAngelOfRebirthTriggeredAbility ability) {
@ -109,6 +111,11 @@ class RienneAngelOfRebirthTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever another multicolored creature you control dies, " + return "Whenever another multicolored creature you control dies, " +
"return it to its owner's hand at the beginning of the next end step."; "return it to its owner's hand at the beginning of the next end step.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class RienneAngelOfRebirthEffect extends OneShotEffect { class RienneAngelOfRebirthEffect extends OneShotEffect {

View file

@ -1,5 +1,6 @@
package mage.cards.s; package mage.cards.s;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -40,6 +41,7 @@ class SacredGroundTriggeredAbility extends TriggeredAbilityImpl {
SacredGroundTriggeredAbility() { SacredGroundTriggeredAbility() {
super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect()); super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect());
setLeavesTheBattlefieldTrigger(true);
} }
private SacredGroundTriggeredAbility(final SacredGroundTriggeredAbility ability) { private SacredGroundTriggeredAbility(final SacredGroundTriggeredAbility ability) {
@ -75,4 +77,9 @@ class SacredGroundTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a spell or ability an opponent controls causes a land to be put into your graveyard from the battlefield, return that card to the battlefield."; return "Whenever a spell or ability an opponent controls causes a land to be put into your graveyard from the battlefield, return that card to the battlefield.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -4,6 +4,7 @@ package mage.cards.s;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
@ -46,9 +47,11 @@ public final class Sangromancer extends CardImpl {
} }
class SangromancerFirstTriggeredAbility extends TriggeredAbilityImpl { class SangromancerFirstTriggeredAbility extends TriggeredAbilityImpl {
SangromancerFirstTriggeredAbility() { SangromancerFirstTriggeredAbility() {
super(Zone.BATTLEFIELD, new GainLifeEffect(3), true); super(Zone.BATTLEFIELD, new GainLifeEffect(3), true);
setTriggerPhrase("Whenever a creature an opponent controls dies, "); setTriggerPhrase("Whenever a creature an opponent controls dies, ");
setLeavesTheBattlefieldTrigger(true);
} }
private SangromancerFirstTriggeredAbility(final SangromancerFirstTriggeredAbility ability) { private SangromancerFirstTriggeredAbility(final SangromancerFirstTriggeredAbility ability) {
@ -75,6 +78,11 @@ class SangromancerFirstTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class SangromancerSecondTriggeredAbility extends TriggeredAbilityImpl { class SangromancerSecondTriggeredAbility extends TriggeredAbilityImpl {

View file

@ -1,6 +1,7 @@
package mage.cards.s; package mage.cards.s;
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.effects.common.ReturnToHandTargetEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect;
@ -56,6 +57,7 @@ class ScrapTrawlerTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, new ReturnToHandTargetEffect()); super(Zone.BATTLEFIELD, new ReturnToHandTargetEffect());
getEffects().get(0).setText("return to your hand target artifact card in your graveyard with lesser mana value"); getEffects().get(0).setText("return to your hand target artifact card in your graveyard with lesser mana value");
setTriggerPhrase("Whenever {this} or another artifact you control is put into a graveyard from the battlefield, "); setTriggerPhrase("Whenever {this} or another artifact you control is put into a graveyard from the battlefield, ");
setLeavesTheBattlefieldTrigger(true);
} }
private ScrapTrawlerTriggeredAbility(final ScrapTrawlerTriggeredAbility ability) { private ScrapTrawlerTriggeredAbility(final ScrapTrawlerTriggeredAbility ability) {
@ -90,4 +92,9 @@ class ScrapTrawlerTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -1,6 +1,7 @@
package mage.cards.s; package mage.cards.s;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -45,12 +46,13 @@ class ScrapheapTriggeredAbility extends TriggeredAbilityImpl {
return new ScrapheapTriggeredAbility(this); return new ScrapheapTriggeredAbility(this);
} }
private ScrapheapTriggeredAbility(final ScrapheapTriggeredAbility ability){
super(ability);
}
public ScrapheapTriggeredAbility(){ public ScrapheapTriggeredAbility(){
super(Zone.BATTLEFIELD, new GainLifeEffect(1)); super(Zone.BATTLEFIELD, new GainLifeEffect(1));
setLeavesTheBattlefieldTrigger(true);
}
private ScrapheapTriggeredAbility(final ScrapheapTriggeredAbility ability){
super(ability);
} }
@Override @Override
@ -76,4 +78,9 @@ class ScrapheapTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever an artifact or enchantment is put into your graveyard from the battlefield, you gain 1 life."; return "Whenever an artifact or enchantment is put into your graveyard from the battlefield, you gain 1 life.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -2,6 +2,7 @@ package mage.cards.s;
import mage.MageInt; import mage.MageInt;
import mage.MageItem; import mage.MageItem;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.keyword.SurveilEffect; import mage.abilities.effects.keyword.SurveilEffect;
import mage.abilities.keyword.MenaceAbility; import mage.abilities.keyword.MenaceAbility;
@ -53,6 +54,7 @@ class SeerOfStolenSightTriggeredAbility extends TriggeredAbilityImpl {
SeerOfStolenSightTriggeredAbility() { SeerOfStolenSightTriggeredAbility() {
super(Zone.BATTLEFIELD, new SurveilEffect(1)); super(Zone.BATTLEFIELD, new SurveilEffect(1));
setTriggerPhrase("Whenever one or more artifacts and/or creatures you control are put into a graveyard from the battlefield, "); setTriggerPhrase("Whenever one or more artifacts and/or creatures you control are put into a graveyard from the battlefield, ");
setLeavesTheBattlefieldTrigger(true);
} }
private SeerOfStolenSightTriggeredAbility(final SeerOfStolenSightTriggeredAbility ability) { private SeerOfStolenSightTriggeredAbility(final SeerOfStolenSightTriggeredAbility ability) {
@ -85,4 +87,9 @@ class SeerOfStolenSightTriggeredAbility extends TriggeredAbilityImpl {
.map(Controllable::getControllerId) .map(Controllable::getControllerId)
.anyMatch(this::isControlledBy); .anyMatch(this::isControlledBy);
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -142,10 +142,10 @@ class SerpentsSoulJarWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST) { if (event.getType() == GameEvent.EventType.SPELL_CAST) {
if (event.getAdditionalReference() == null) { if (event.getApprovingObject() == null) {
return; return;
} }
morMap.computeIfAbsent(event.getAdditionalReference().getApprovingMageObjectReference(), m -> new HashMap<>()) morMap.computeIfAbsent(event.getApprovingObject().getApprovingMageObjectReference(), m -> new HashMap<>())
.compute(event.getPlayerId(), (u, i) -> i == null ? 0 : Integer.sum(i, -1)); .compute(event.getPlayerId(), (u, i) -> i == null ? 0 : Integer.sum(i, -1));
return; return;
} }

View file

@ -193,7 +193,7 @@ class SerraParagonWatcher extends Watcher {
|| event.getType() == GameEvent.EventType.LAND_PLAYED) || event.getType() == GameEvent.EventType.LAND_PLAYED)
&& event.hasApprovingIdentifier(MageIdentifier.SerraParagonWatcher)) { && event.hasApprovingIdentifier(MageIdentifier.SerraParagonWatcher)) {
map.computeIfAbsent( map.computeIfAbsent(
event.getAdditionalReference() event.getApprovingObject()
.getApprovingMageObjectReference(), .getApprovingMageObjectReference(),
x -> new HashSet<>() x -> new HashSet<>()
).add(event.getPlayerId()); ).add(event.getPlayerId());

View file

@ -59,6 +59,7 @@ class ShardOfTheVoidDragonTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2))); super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)));
setTriggerPhrase("Whenever an artifact is put into a graveyard from the battlefield or is put into exile from the battlefield, "); setTriggerPhrase("Whenever an artifact is put into a graveyard from the battlefield or is put into exile from the battlefield, ");
withFlavorWord("Matter Absorption"); withFlavorWord("Matter Absorption");
setLeavesTheBattlefieldTrigger(true);
} }
private ShardOfTheVoidDragonTriggeredAbility(final ShardOfTheVoidDragonTriggeredAbility ability) { private ShardOfTheVoidDragonTriggeredAbility(final ShardOfTheVoidDragonTriggeredAbility ability) {

View file

@ -1,6 +1,7 @@
package mage.cards.s; package mage.cards.s;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
@ -145,6 +146,7 @@ class ShelobChildOfUngoliantTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, effect); super(Zone.BATTLEFIELD, effect);
this.addWatcher(new ShelobChildOfUngoliantWatcher()); this.addWatcher(new ShelobChildOfUngoliantWatcher());
this.setTriggerPhrase("Whenever another creature dealt damage this turn by a Spider you controlled dies, "); this.setTriggerPhrase("Whenever another creature dealt damage this turn by a Spider you controlled dies, ");
setLeavesTheBattlefieldTrigger(true);
} }
private ShelobChildOfUngoliantTriggeredAbility(final ShelobChildOfUngoliantTriggeredAbility ability) { private ShelobChildOfUngoliantTriggeredAbility(final ShelobChildOfUngoliantTriggeredAbility ability) {
@ -185,6 +187,11 @@ class ShelobChildOfUngoliantTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class ShelobChildOfUngoliantEffect extends OneShotEffect { class ShelobChildOfUngoliantEffect extends OneShotEffect {

View file

@ -1,5 +1,6 @@
package mage.cards.s; package mage.cards.s;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -40,6 +41,7 @@ class SlagstoneRefineryTriggeredAbility extends TriggeredAbilityImpl {
SlagstoneRefineryTriggeredAbility() { SlagstoneRefineryTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new PowerstoneToken(), 1, true)); super(Zone.BATTLEFIELD, new CreateTokenEffect(new PowerstoneToken(), 1, true));
setLeavesTheBattlefieldTrigger(true);
} }
private SlagstoneRefineryTriggeredAbility(final SlagstoneRefineryTriggeredAbility ability) { private SlagstoneRefineryTriggeredAbility(final SlagstoneRefineryTriggeredAbility ability) {
@ -79,4 +81,9 @@ class SlagstoneRefineryTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever {this} or another nontoken artifact you control is put into a graveyard from the battlefield " + return "Whenever {this} or another nontoken artifact you control is put into a graveyard from the battlefield " +
"or is put into exile from the battlefield, create a tapped Powerstone token."; "or is put into exile from the battlefield, create a tapped Powerstone token.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -2,6 +2,8 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
@ -56,6 +58,7 @@ class SlayersPlateTriggeredAbility extends TriggeredAbilityImpl {
public SlayersPlateTriggeredAbility() { public SlayersPlateTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken())); super(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken()));
setLeavesTheBattlefieldTrigger(true);
} }
private SlayersPlateTriggeredAbility(final SlayersPlateTriggeredAbility ability) { private SlayersPlateTriggeredAbility(final SlayersPlateTriggeredAbility ability) {
@ -87,4 +90,9 @@ class SlayersPlateTriggeredAbility 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 sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -1,5 +1,6 @@
package mage.cards.s; package mage.cards.s;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
@ -68,6 +69,7 @@ class SporogenesisTriggeredAbility extends TriggeredAbilityImpl {
SporogenesisTriggeredAbility() { SporogenesisTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken(), new SporogenesisCount()), false); super(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken(), new SporogenesisCount()), false);
setLeavesTheBattlefieldTrigger(true);
} }
private SporogenesisTriggeredAbility(final SporogenesisTriggeredAbility ability) { private SporogenesisTriggeredAbility(final SporogenesisTriggeredAbility ability) {
@ -104,6 +106,11 @@ class SporogenesisTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a creature with a fungus counter on it dies, create a 1/1 green Saproling creature token for each fungus counter on that creature."; return "Whenever a creature with a fungus counter on it dies, create a 1/1 green Saproling creature token for each fungus counter on that creature.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class SporogenesisCount implements DynamicValue { class SporogenesisCount implements DynamicValue {

View file

@ -54,6 +54,7 @@ class SyrKonradTheGrimTriggeredAbility extends TriggeredAbilityImpl {
SyrKonradTheGrimTriggeredAbility() { SyrKonradTheGrimTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT)); super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT));
setLeavesTheBattlefieldTrigger(true);
} }
private SyrKonradTheGrimTriggeredAbility(final SyrKonradTheGrimTriggeredAbility ability) { private SyrKonradTheGrimTriggeredAbility(final SyrKonradTheGrimTriggeredAbility ability) {
@ -95,8 +96,8 @@ class SyrKonradTheGrimTriggeredAbility extends TriggeredAbilityImpl {
} }
@Override @Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game); return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} }
@Override @Override

View file

@ -67,6 +67,7 @@ class TaekoThePatientAvalancheTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, new ScryEffect(1, false)); super(Zone.BATTLEFIELD, new ScryEffect(1, false));
this.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance()).concatBy("and")); this.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance()).concatBy("and"));
this.setTriggerPhrase("Whenever another creature you control leaves the battlefield, if it didn't die, "); this.setTriggerPhrase("Whenever another creature you control leaves the battlefield, if it didn't die, ");
setLeavesTheBattlefieldTrigger(true);
} }
private TaekoThePatientAvalancheTriggeredAbility(final TaekoThePatientAvalancheTriggeredAbility ability) { private TaekoThePatientAvalancheTriggeredAbility(final TaekoThePatientAvalancheTriggeredAbility ability) {

View file

@ -3,6 +3,7 @@ package mage.cards.t;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
@ -71,6 +72,7 @@ class TheScorpionGodTriggeredAbility extends TriggeredAbilityImpl {
public TheScorpionGodTriggeredAbility() { public TheScorpionGodTriggeredAbility() {
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false); super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false);
setLeavesTheBattlefieldTrigger(true);
} }
private TheScorpionGodTriggeredAbility(final TheScorpionGodTriggeredAbility ability) { private TheScorpionGodTriggeredAbility(final TheScorpionGodTriggeredAbility ability) {
@ -105,6 +107,11 @@ class TheScorpionGodTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a creature with a -1/-1 counter on it dies, draw a card."; return "Whenever a creature with a -1/-1 counter on it dies, draw a card.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class TheScorpionGodEffect extends OneShotEffect { class TheScorpionGodEffect extends OneShotEffect {

View file

@ -112,6 +112,7 @@ class TheSkullsporeNexusTrigger extends TriggeredAbilityImpl {
TheSkullsporeNexusTrigger() { TheSkullsporeNexusTrigger() {
super(Zone.BATTLEFIELD, null, false); super(Zone.BATTLEFIELD, null, false);
setLeavesTheBattlefieldTrigger(true);
} }
private TheSkullsporeNexusTrigger(final TheSkullsporeNexusTrigger ability) { private TheSkullsporeNexusTrigger(final TheSkullsporeNexusTrigger ability) {
@ -170,8 +171,8 @@ class TheSkullsporeNexusTrigger extends TriggeredAbilityImpl {
} }
@Override @Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game); return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} }
} }

View file

@ -3,6 +3,7 @@ package mage.cards.t;
import java.util.UUID; import java.util.UUID;
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.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
@ -65,6 +66,7 @@ class TianaShipsCaretakerTriggeredAbility extends TriggeredAbilityImpl {
TianaShipsCaretakerTriggeredAbility() { TianaShipsCaretakerTriggeredAbility() {
super(Zone.BATTLEFIELD, new TianaShipsCaretakerEffect(), true); super(Zone.BATTLEFIELD, new TianaShipsCaretakerEffect(), true);
setTriggerPhrase("Whenever an Aura or Equipment you control is put into a graveyard from the battlefield, "); setTriggerPhrase("Whenever an Aura or Equipment you control is put into a graveyard from the battlefield, ");
setLeavesTheBattlefieldTrigger(true);
} }
private TianaShipsCaretakerTriggeredAbility(final TianaShipsCaretakerTriggeredAbility ability) { private TianaShipsCaretakerTriggeredAbility(final TianaShipsCaretakerTriggeredAbility ability) {
@ -98,6 +100,11 @@ class TianaShipsCaretakerTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class TianaShipsCaretakerEffect extends OneShotEffect { class TianaShipsCaretakerEffect extends OneShotEffect {

View file

@ -124,10 +124,10 @@ class UnluckyWitnessWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST if (event.getType() != GameEvent.EventType.SPELL_CAST
|| event.getAdditionalReference() == null) { || event.getApprovingObject() == null) {
return; return;
} }
MageObjectReference mor = event.getAdditionalReference().getApprovingMageObjectReference(); MageObjectReference mor = event.getApprovingObject().getApprovingMageObjectReference();
Spell spell = game.getSpell(event.getTargetId()); Spell spell = game.getSpell(event.getTargetId());
if (mor == null || spell == null) { if (mor == null || spell == null) {
return; return;

View file

@ -62,6 +62,7 @@ class VerdantSuccessionTriggeredAbility extends TriggeredAbilityImpl {
VerdantSuccessionTriggeredAbility() { VerdantSuccessionTriggeredAbility() {
super(Zone.BATTLEFIELD, null, true); super(Zone.BATTLEFIELD, null, true);
setLeavesTheBattlefieldTrigger(true);
} }
private VerdantSuccessionTriggeredAbility(final VerdantSuccessionTriggeredAbility ability) { private VerdantSuccessionTriggeredAbility(final VerdantSuccessionTriggeredAbility ability) {
@ -98,6 +99,11 @@ class VerdantSuccessionTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever a green nontoken creature dies, that creature's controller may search their library for a card with the same name as that creature, put it onto the battlefield, then shuffle."; return "Whenever a green nontoken creature dies, that creature's controller may search their library for a card with the same name as that creature, put it onto the battlefield, then shuffle.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }
class VerdantSuccessionEffect extends OneShotEffect { class VerdantSuccessionEffect extends OneShotEffect {

View file

@ -114,7 +114,7 @@ class VesuvanShapeshifterEffect extends OneShotEffect {
if (copyFromCreature != null) { if (copyFromCreature != null) {
game.copyPermanent(Duration.Custom, copyFromCreature, copyToCreature.getId(), source, new VesuvanShapeShifterFaceUpCopyApplier()); game.copyPermanent(Duration.Custom, copyFromCreature, copyToCreature.getId(), source, new VesuvanShapeShifterFaceUpCopyApplier());
source.getTargets().clear(); source.getTargets().clear();
game.processAction(); // needed to get effects ready if copy happens in replacment and the copied abilities react of the same event (e.g. turn face up) game.processAction(); // needed to get effects ready if copy happens in replacement and the copied abilities react of the same event (e.g. turn face up)
return true; return true;
} }
} }

View file

@ -3,6 +3,7 @@ package mage.cards.v;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -48,6 +49,7 @@ class VillageCannibalsTriggeredAbility extends TriggeredAbilityImpl {
public VillageCannibalsTriggeredAbility() { public VillageCannibalsTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance())); super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
setTriggerPhrase("Whenever another Human creature dies, "); setTriggerPhrase("Whenever another Human creature dies, ");
setLeavesTheBattlefieldTrigger(true);
} }
private VillageCannibalsTriggeredAbility(final VillageCannibalsTriggeredAbility ability) { private VillageCannibalsTriggeredAbility(final VillageCannibalsTriggeredAbility ability) {
@ -74,4 +76,9 @@ class VillageCannibalsTriggeredAbility extends TriggeredAbilityImpl {
return permanent != null && permanent.isCreature(game) && permanent.hasSubtype(SubType.HUMAN, game) return permanent != null && permanent.isCreature(game) && permanent.hasSubtype(SubType.HUMAN, game)
&& !permanent.getId().equals(this.getSourceId()); && !permanent.getId().equals(this.getSourceId());
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

View file

@ -57,6 +57,7 @@ class VindictiveVampireTriggeredAbility extends TriggeredAbilityImpl {
public VindictiveVampireTriggeredAbility(Zone zone, Effect effect) { public VindictiveVampireTriggeredAbility(Zone zone, Effect effect) {
super(zone, effect, false); super(zone, effect, false);
setTriggerPhrase("Whenever another creature you control dies, "); setTriggerPhrase("Whenever another creature you control dies, ");
setLeavesTheBattlefieldTrigger(true);
} }
private VindictiveVampireTriggeredAbility(final VindictiveVampireTriggeredAbility ability) { private VindictiveVampireTriggeredAbility(final VindictiveVampireTriggeredAbility ability) {
@ -69,17 +70,8 @@ class VindictiveVampireTriggeredAbility extends TriggeredAbilityImpl {
} }
@Override @Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
Permanent sourcePermanent; return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
if (game.getState().getZone(getSourceId()) == Zone.BATTLEFIELD) {
sourcePermanent = game.getPermanent(getSourceId());
} else {
sourcePermanent = (Permanent) game.getPermanentOrLKIBattlefield(getSourceId());
}
if (sourcePermanent == null) {
return false;
}
return hasSourceObjectAbility(game, sourcePermanent, event);
} }
@Override @Override

View file

@ -3,6 +3,8 @@
package mage.cards.v; package mage.cards.v;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.Card; import mage.cards.Card;
@ -40,8 +42,10 @@ public final class ViridianRevel extends CardImpl {
} }
class ViridianRevelTriggeredAbility extends TriggeredAbilityImpl { class ViridianRevelTriggeredAbility extends TriggeredAbilityImpl {
ViridianRevelTriggeredAbility() { ViridianRevelTriggeredAbility() {
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), true); super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), true);
setLeavesTheBattlefieldTrigger(true);
} }
private ViridianRevelTriggeredAbility(final ViridianRevelTriggeredAbility ability) { private ViridianRevelTriggeredAbility(final ViridianRevelTriggeredAbility ability) {
@ -75,4 +79,9 @@ class ViridianRevelTriggeredAbility extends TriggeredAbilityImpl {
public String getRule() { public String getRule() {
return "Whenever an artifact is put into an opponent's graveyard from the battlefield, you may draw a card."; return "Whenever an artifact is put into an opponent's graveyard from the battlefield, you may draw a card.";
} }
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
} }

Some files were not shown because too many files have changed in this diff Show more