refactor: fixed dies events support in single cards (part 2);

This commit is contained in:
Oleg Agafonov 2024-11-06 21:29:27 +04:00
parent 0f8416cfb1
commit c3343110f3
29 changed files with 114 additions and 11 deletions

View file

@ -53,7 +53,7 @@ class FalkenrathNobleTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), false);
this.addEffect(new GainLifeEffect(1));
this.addTarget(new TargetPlayer());
this.setLeavesTheBattlefieldTrigger(true);
setLeavesTheBattlefieldTrigger(true);
}
private FalkenrathNobleTriggeredAbility(final FalkenrathNobleTriggeredAbility ability) {

View file

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

View file

@ -49,7 +49,7 @@ class GravePactTriggeredAbility extends TriggeredAbilityImpl {
public GravePactTriggeredAbility() {
super(Zone.BATTLEFIELD, new GravePactEffect());
setTriggerPhrase("Whenever a creature you control dies, ");
setLeavesTheBattlefieldTrigger(true);
this.setLeavesTheBattlefieldTrigger(true);
}
private GravePactTriggeredAbility(final GravePactTriggeredAbility ability) {

View file

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

View file

@ -78,7 +78,7 @@ class KayaTheInexorableTriggeredAbility extends TriggeredAbilityImpl {
public KayaTheInexorableTriggeredAbility() {
super(Zone.ALL, null, false);
setLeavesTheBattlefieldTrigger(true);
this.setLeavesTheBattlefieldTrigger(true);
}
private KayaTheInexorableTriggeredAbility(KayaTheInexorableTriggeredAbility ability) {

View file

@ -1,6 +1,7 @@
package mage.cards.l;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
@ -56,6 +57,7 @@ class LuminousBroodmothTriggeredAbility extends TriggeredAbilityImpl {
LuminousBroodmothTriggeredAbility() {
super(Zone.BATTLEFIELD, new LuminousBroodmothEffect(), false);
setLeavesTheBattlefieldTrigger(true);
}
private LuminousBroodmothTriggeredAbility(final LuminousBroodmothTriggeredAbility ability) {
@ -97,6 +99,11 @@ class LuminousBroodmothTriggeredAbility extends TriggeredAbilityImpl {
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.";
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
}
}
class LuminousBroodmothEffect extends OneShotEffect {

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,7 @@
package mage.cards.r;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
@ -52,6 +53,7 @@ class RemembranceTriggeredAbility extends TriggeredAbilityImpl {
RemembranceTriggeredAbility() {
super(Zone.BATTLEFIELD, null, true);
setLeavesTheBattlefieldTrigger(true);
}
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, " +
"reveal it, put it into your hand, then shuffle.";
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
}
}

View file

@ -1,6 +1,7 @@
package mage.cards.r;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
@ -65,6 +66,7 @@ class RhukHexgoldNabberTriggeredAbility extends TriggeredAbilityImpl {
RhukHexgoldNabberTriggeredAbility() {
super(Zone.BATTLEFIELD, new RhukHexgoldNabberEffect(), true);
setLeavesTheBattlefieldTrigger(true);
}
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, " +
"you may attach all Equipment attached to that creature to {this}.";
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
} else {
return super.isInUseableZone(game, source, event);
}
}
}
class RhukHexgoldNabberEffect extends OneShotEffect {

View file

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

View file

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

View file

@ -146,6 +146,7 @@ class ShelobChildOfUngoliantTriggeredAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, effect);
this.addWatcher(new ShelobChildOfUngoliantWatcher());
this.setTriggerPhrase("Whenever another creature dealt damage this turn by a Spider you controlled dies, ");
setLeavesTheBattlefieldTrigger(true);
}
private ShelobChildOfUngoliantTriggeredAbility(final ShelobChildOfUngoliantTriggeredAbility ability) {

View file

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

View file

@ -1,5 +1,6 @@
package mage.cards.s;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
@ -68,6 +69,7 @@ class SporogenesisTriggeredAbility extends TriggeredAbilityImpl {
SporogenesisTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken(), new SporogenesisCount()), false);
setLeavesTheBattlefieldTrigger(true);
}
private SporogenesisTriggeredAbility(final SporogenesisTriggeredAbility ability) {
@ -104,6 +106,11 @@ class SporogenesisTriggeredAbility extends TriggeredAbilityImpl {
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.";
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
}
}
class SporogenesisCount implements DynamicValue {

View file

@ -54,6 +54,7 @@ class SyrKonradTheGrimTriggeredAbility extends TriggeredAbilityImpl {
SyrKonradTheGrimTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT));
setLeavesTheBattlefieldTrigger(true);
}
private SyrKonradTheGrimTriggeredAbility(final SyrKonradTheGrimTriggeredAbility ability) {

View file

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

View file

@ -62,6 +62,7 @@ class VerdantSuccessionTriggeredAbility extends TriggeredAbilityImpl {
VerdantSuccessionTriggeredAbility() {
super(Zone.BATTLEFIELD, null, true);
setLeavesTheBattlefieldTrigger(true);
}
private VerdantSuccessionTriggeredAbility(final VerdantSuccessionTriggeredAbility ability) {
@ -98,6 +99,11 @@ class VerdantSuccessionTriggeredAbility extends TriggeredAbilityImpl {
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.";
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
}
}
class VerdantSuccessionEffect extends OneShotEffect {

View file

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

View file

@ -1992,6 +1992,8 @@ public class VerifyCardDataTest {
.filter(a -> a.getRule().contains("whenever") || a.getRule().contains("Whenever"))
.filter(a -> a.getRule().contains("dies"))
.filter(a -> !a.getRule().contains("with \"When")) // ignore token creating effects
.filter(a -> !a.getRule().contains("gains \"When")) // ignore token creating effects
.filter(a -> !a.getRule().contains("and \"When")) // ignore token creating effects
.filter(a -> !a.isLeavesTheBattlefieldTrigger())
.forEach(a -> {
fail(card, "abilities", "dies trigger must use setLeavesTheBattlefieldTrigger(true) and override isInUseableZone - " + a.getClass().getSimpleName());

View file

@ -416,6 +416,8 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
@Override
public final void setLeavesTheBattlefieldTrigger(boolean leavesTheBattlefieldTrigger) {
this.leavesTheBattlefieldTrigger = leavesTheBattlefieldTrigger;
// TODO: replace override of isInUseableZone in dies only triggers by like "isDiesOnlyTrigger" here
}
@Override

View file

@ -21,7 +21,7 @@ public class GodEternalDiesTriggeredAbility extends TriggeredAbilityImpl {
public GodEternalDiesTriggeredAbility() {
super(Zone.ALL, null, true);
this.setLeavesTheBattlefieldTrigger(true);
setLeavesTheBattlefieldTrigger(true);
}
private GodEternalDiesTriggeredAbility(GodEternalDiesTriggeredAbility ability) {

View file

@ -26,7 +26,7 @@ public class PutIntoGraveFromBattlefieldAllTriggeredAbility extends TriggeredAbi
public PutIntoGraveFromBattlefieldAllTriggeredAbility(Effect effect, boolean optional, FilterPermanent filter, boolean setTargetPointer, boolean onlyToControllerGraveyard) {
super(Zone.BATTLEFIELD, effect, optional);
this.setLeavesTheBattlefieldTrigger(true);
setLeavesTheBattlefieldTrigger(true);
this.filter = filter;
this.onlyToControllerGraveyard = onlyToControllerGraveyard;
this.setTargetPointer = setTargetPointer;

View file

@ -21,7 +21,9 @@ public class ZoneChangeTriggeredAbility extends TriggeredAbilityImpl {
protected final Zone toZone;
public ZoneChangeTriggeredAbility(Zone fromZone, Zone toZone, Effect effect, String triggerPhrase, boolean optional) {
// fix 3
this(toZone == null ? Zone.ALL : toZone, fromZone, toZone, effect, triggerPhrase, optional);
//this(fromZone == null ? Zone.ALL : fromZone, fromZone, toZone, effect, triggerPhrase, optional);
}
public ZoneChangeTriggeredAbility(Zone worksInZone, Zone fromZone, Zone toZone, Effect effect, String triggerPhrase, boolean optional) {

View file

@ -27,7 +27,7 @@ public class UntilYourNextTurnDelayedTriggeredAbility extends DelayedTriggeredAb
public UntilYourNextTurnDelayedTriggeredAbility(TriggeredAbility ability) {
super(null, Duration.UntilYourNextTurn, false);
if (ability.isLeavesTheBattlefieldTrigger()) {
this.setLeavesTheBattlefieldTrigger(true);
setLeavesTheBattlefieldTrigger(true);
}
this.ability = ability;
}

View file

@ -40,7 +40,7 @@ public class ConditionalInterveningIfTriggeredAbility extends TriggeredAbilityIm
public ConditionalInterveningIfTriggeredAbility(TriggeredAbility ability, Condition condition, String text) {
super(ability.getZone(), null);
if (ability.isLeavesTheBattlefieldTrigger()) {
this.setLeavesTheBattlefieldTrigger(true);
setLeavesTheBattlefieldTrigger(true);
}
this.ability = ability;
this.condition = condition;

View file

@ -46,7 +46,7 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl {
}
if (ability.isLeavesTheBattlefieldTrigger()) {
this.setLeavesTheBattlefieldTrigger(true);
setLeavesTheBattlefieldTrigger(true);
}
}
setTriggerPhrase(generateTriggerPhrase());