Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dies triggers fixes and improves (bugs like "no trigger on sacrifice cost") #13088

Merged
merged 12 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Mage.Sets/src/mage/cards/a/AjanisLastStand.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package mage.cards.a;

import java.util.UUID;

import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.DiscardedByOpponentTriggeredAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
Expand Down Expand Up @@ -63,6 +65,7 @@ public AjanisLastStandTriggeredAbility() {
new CreateTokenEffect(new AvatarToken2()),
new SacrificeSourceCost()
), false);
setLeavesTheBattlefieldTrigger(true);
}

private AjanisLastStandTriggeredAbility(final AjanisLastStandTriggeredAbility ability) {
Expand Down Expand Up @@ -98,4 +101,9 @@ public String getRule() {
+ "you may sacrifice {this}. "
+ "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);
}
}
7 changes: 7 additions & 0 deletions Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mage.cards.a;

import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
Expand Down Expand Up @@ -122,6 +123,7 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, effect, optional);
this.filter = filter;
setTriggerPhrase("Whenever " + filter.getMessage() + " dies, ");
setLeavesTheBattlefieldTrigger(true);
}

private AthreosDiesCreatureTriggeredAbility(AthreosDiesCreatureTriggeredAbility ability) {
Expand Down Expand Up @@ -153,4 +155,9 @@ public boolean checkTrigger(GameEvent event, Game game) {
}
return true;
}

@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}
1 change: 1 addition & 0 deletions Mage.Sets/src/mage/cards/a/AthreosShroudVeiled.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class AthreosShroudVeiledTriggeredAbility extends TriggeredAbilityImpl {

AthreosShroudVeiledTriggeredAbility() {
super(Zone.BATTLEFIELD, null, false);
setLeavesTheBattlefieldTrigger(true);
}

private AthreosShroudVeiledTriggeredAbility(final AthreosShroudVeiledTriggeredAbility ability) {
Expand Down
7 changes: 7 additions & 0 deletions Mage.Sets/src/mage/cards/a/AvacynsCollar.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

package mage.cards.a;

import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
Expand Down Expand Up @@ -60,6 +61,7 @@ class AvacynsCollarTriggeredAbility extends TriggeredAbilityImpl {

public AvacynsCollarTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SpiritWhiteToken()));
setLeavesTheBattlefieldTrigger(true);
}

private AvacynsCollarTriggeredAbility(final AvacynsCollarTriggeredAbility ability) {
Expand Down Expand Up @@ -91,4 +93,9 @@ public boolean checkTrigger(GameEvent event, Game game) {
public String getRule() {
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);
}
}
8 changes: 8 additions & 0 deletions Mage.Sets/src/mage/cards/b/Bereavement.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package mage.cards.b;

import java.util.UUID;

import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.cards.CardImpl;
Expand Down Expand Up @@ -41,6 +43,7 @@ class BereavementTriggeredAbility extends TriggeredAbilityImpl {

BereavementTriggeredAbility() {
super(Zone.BATTLEFIELD, new DiscardTargetEffect(1));
setLeavesTheBattlefieldTrigger(true);
}

private BereavementTriggeredAbility(final BereavementTriggeredAbility ability) {
Expand Down Expand Up @@ -73,4 +76,9 @@ public boolean checkTrigger(GameEvent event, Game game) {
public String getRule() {
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);
}
}
1 change: 1 addition & 0 deletions Mage.Sets/src/mage/cards/b/BridgeFromBelow.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class BridgeFromBelowAbility extends TriggeredAbilityImpl {
this.filter = filter;
this.withInterveningIf(SourceInGraveyardCondition.instance);
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) {
Expand Down
2 changes: 1 addition & 1 deletion Mage.Sets/src/mage/cards/c/CallerOfTheClaw.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

package mage.cards.c;

import java.util.UUID;
Expand Down Expand Up @@ -39,6 +38,7 @@ public CallerOfTheClaw(UUID ownerId, CardSetInfo setInfo) {

// Flash
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.
this.getSpellAbility().addWatcher(new CallerOfTheClawWatcher());
Effect effect = new CreateTokenEffect(new BearToken(), new CallerOfTheClawDynamicValue());
Expand Down
1 change: 1 addition & 0 deletions Mage.Sets/src/mage/cards/c/CarthTheLion.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public CarthTheLionTriggeredAbility() {
super(Zone.BATTLEFIELD, new LookLibraryAndPickControllerEffect(
7, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM));
setTriggerPhrase("Whenever {this} enters or a planeswalker you control dies, ");
setLeavesTheBattlefieldTrigger(true);
}

private CarthTheLionTriggeredAbility(final CarthTheLionTriggeredAbility ability) {
Expand Down
4 changes: 2 additions & 2 deletions Mage.Sets/src/mage/cards/c/ChainerNightmareAdept.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ class ChainerNightmareAdeptWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
if (event.getAdditionalReference() == null) {
if (event.getApprovingObject() == null) {
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));
}
}
Expand Down
4 changes: 2 additions & 2 deletions Mage.Sets/src/mage/cards/c/ChandraHopesBeacon.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ class ChandraHopesBeaconWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST
|| event.getAdditionalReference() == null) {
|| event.getApprovingObject() == null) {
return;
}
MageObjectReference mor = event.getAdditionalReference().getApprovingMageObjectReference();
MageObjectReference mor = event.getApprovingObject().getApprovingMageObjectReference();
Spell spell = game.getSpell(event.getTargetId());
if (mor == null || spell == null) {
return;
Expand Down
4 changes: 2 additions & 2 deletions Mage.Sets/src/mage/cards/c/ChissGoriaForgeTyrant.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,10 @@ class ChissGoriaForgeTyrantWatcher extends Watcher {

@Override
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;
}
MageObjectReference mor = event.getAdditionalReference().getApprovingMageObjectReference();
MageObjectReference mor = event.getApprovingObject().getApprovingMageObjectReference();
Spell spell = game.getSpell(event.getTargetId());
if (mor == null || spell == null) {
return;
Expand Down
2 changes: 1 addition & 1 deletion Mage.Sets/src/mage/cards/c/Chronozoa.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public Chronozoa(UUID ownerId, CardSetInfo setInfo) {
// 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));

// 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.setText("create two tokens that are copies of it");
this.addAbility(new ConditionalInterveningIfTriggeredAbility(new DiesSourceTriggeredAbility(effect, false),
Expand Down
8 changes: 4 additions & 4 deletions Mage.Sets/src/mage/cards/c/CoramTheUndertaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,15 @@ public void watch(GameEvent event, Game game) {
cardsAllowedToBePlayedOrCast.add(new MageObjectReference(mainCard, game));
return;
}
if (event.getAdditionalReference() == null
|| !MageIdentifier.CoramTheUndertakerWatcher.equals(event.getAdditionalReference().getApprovingAbility().getIdentifier())) {
if (event.getApprovingObject() == null
|| !MageIdentifier.CoramTheUndertakerWatcher.equals(event.getApprovingObject().getApprovingAbility().getIdentifier())) {
return;
}
if (event.getType() == GameEvent.EventType.LAND_PLAYED) {
landPlayedForSource.add(event.getAdditionalReference().getApprovingMageObjectReference());
landPlayedForSource.add(event.getApprovingObject().getApprovingMageObjectReference());
}
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
spellCastForSource.add(event.getAdditionalReference().getApprovingMageObjectReference());
spellCastForSource.add(event.getApprovingObject().getApprovingMageObjectReference());
}
}

Expand Down
2 changes: 1 addition & 1 deletion Mage.Sets/src/mage/cards/c/CourtOfLocthwain.java
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public void watch(GameEvent event, Game game) {
&& event.getPlayerId() != null) {
decrementCastAvailable(
event.getPlayerId(),
event.getAdditionalReference().getApprovingMageObjectReference()
event.getApprovingObject().getApprovingMageObjectReference()
);
}
}
Expand Down
1 change: 1 addition & 0 deletions Mage.Sets/src/mage/cards/d/DaxosBlessedByTheSun.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class DaxosBlessedByTheSunAbility extends TriggeredAbilityImpl {

DaxosBlessedByTheSunAbility() {
super(Zone.BATTLEFIELD, new GainLifeEffect(1));
setLeavesTheBattlefieldTrigger(true);
}

private DaxosBlessedByTheSunAbility(DaxosBlessedByTheSunAbility ability) {
Expand Down
5 changes: 3 additions & 2 deletions Mage.Sets/src/mage/cards/d/DeathTyrant.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class DeathTyrantTriggeredAbility extends TriggeredAbilityImpl {
DeathTyrantTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new ZombieToken()));
setTriggerPhrase("Whenever an attacking creature you control or a blocking creature an opponent controls dies, ");
setLeavesTheBattlefieldTrigger(true);
}

private DeathTyrantTriggeredAbility(final DeathTyrantTriggeredAbility ability) {
Expand Down Expand Up @@ -94,7 +95,7 @@ public boolean checkTrigger(GameEvent event, Game game) {
}

@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}
11 changes: 8 additions & 3 deletions Mage.Sets/src/mage/cards/d/DeathsPresence.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@


package mage.cards.d;

import java.util.UUID;

import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
Expand All @@ -25,7 +25,6 @@ public final class DeathsPresence extends CardImpl {
public DeathsPresence(UUID ownerId, CardSetInfo setInfo) {
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.
this.addAbility(new DeathsPresenceTriggeredAbility());
}
Expand All @@ -44,6 +43,7 @@ class DeathsPresenceTriggeredAbility extends TriggeredAbilityImpl {

public DeathsPresenceTriggeredAbility() {
super(Zone.BATTLEFIELD, null);
setLeavesTheBattlefieldTrigger(true);
}

private DeathsPresenceTriggeredAbility(final DeathsPresenceTriggeredAbility ability) {
Expand Down Expand Up @@ -80,4 +80,9 @@ public boolean checkTrigger(GameEvent event, Game game) {
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.";
}

@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}
8 changes: 8 additions & 0 deletions Mage.Sets/src/mage/cards/d/DiabolicServitude.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package mage.cards.d;

import java.util.UUID;

import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
Expand Down Expand Up @@ -91,6 +93,7 @@ class DiabolicServitudeCreatureDiesTriggeredAbility extends TriggeredAbilityImpl

public DiabolicServitudeCreatureDiesTriggeredAbility() {
super(Zone.BATTLEFIELD, new DiabolicServitudeExileCreatureEffect(), false);
setLeavesTheBattlefieldTrigger(true);
}

private DiabolicServitudeCreatureDiesTriggeredAbility(final DiabolicServitudeCreatureDiesTriggeredAbility ability) {
Expand Down Expand Up @@ -123,6 +126,11 @@ public boolean checkTrigger(GameEvent event, Game game) {
public String getRule() {
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 {
Expand Down
9 changes: 8 additions & 1 deletion Mage.Sets/src/mage/cards/d/DiregrafCaptain.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mage.cards.d;

import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.LoseLifeTargetEffect;
Expand Down Expand Up @@ -67,6 +68,7 @@ class DiregrafCaptainTriggeredAbility extends TriggeredAbilityImpl {
public DiregrafCaptainTriggeredAbility() {
super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), false);
this.addTarget(new TargetOpponent());
this.setLeavesTheBattlefieldTrigger(true);
}

private DiregrafCaptainTriggeredAbility(final DiregrafCaptainTriggeredAbility ability) {
Expand Down Expand Up @@ -99,4 +101,9 @@ public DiregrafCaptainTriggeredAbility copy() {
public String getRule() {
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);
}
}
1 change: 1 addition & 0 deletions Mage.Sets/src/mage/cards/d/Dreadhound.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class DreadhoundTriggeredAbility extends TriggeredAbilityImpl {
public DreadhoundTriggeredAbility() {
super(Zone.BATTLEFIELD, new LoseLifeOpponentsEffect(1));
setTriggerPhrase("Whenever a creature dies or a creature card is put into a graveyard from a library, ");
setLeavesTheBattlefieldTrigger(true);
}

private DreadhoundTriggeredAbility(final DreadhoundTriggeredAbility ability) {
Expand Down
7 changes: 7 additions & 0 deletions Mage.Sets/src/mage/cards/e/EndlessEvil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package mage.cards.e;

import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
Expand Down Expand Up @@ -97,6 +98,7 @@ class EndlessEvilBounceAbility extends TriggeredAbilityImpl {

public EndlessEvilBounceAbility() {
super(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(false, true));
setLeavesTheBattlefieldTrigger(true);
}

private EndlessEvilBounceAbility(final EndlessEvilBounceAbility effect) {
Expand Down Expand Up @@ -126,4 +128,9 @@ public boolean checkTrigger(GameEvent event, Game game) {
public String getRule() {
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);
}
}
Loading