From cdcda710c82ccdbc43f9161e6327933ca71a13a1 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 11 Jun 2025 16:27:35 -0400 Subject: [PATCH] people keep asking me if I'm refactoring ConditionalInterveningIfTriggeredAbility, and I haven't really had an answer. but now yeah, I'm thinking I'm refactoring ConditionalInterveningIfTriggeredAbility --- Mage.Sets/src/mage/cards/k/KavuTitan.java | 17 ++++---- Mage.Sets/src/mage/cards/o/OathOfChandra.java | 32 ++++++-------- Mage.Sets/src/mage/cards/o/OathOfLiliana.java | 26 ++++++----- .../src/mage/cards/o/ObscuraAscendancy.java | 39 ++++++++--------- .../src/mage/cards/o/ObsessiveSkinner.java | 21 ++++----- Mage.Sets/src/mage/cards/o/OchreJelly.java | 28 ++++++------ Mage.Sets/src/mage/cards/o/OgreSavant.java | 17 +++----- .../src/mage/cards/o/OldGrowthTroll.java | 24 ++++++----- Mage.Sets/src/mage/cards/o/OpalAcrolith.java | 28 ++++++------ Mage.Sets/src/mage/cards/o/OpalArchangel.java | 26 +++++------ Mage.Sets/src/mage/cards/o/OpalCaryatid.java | 25 +++++------ Mage.Sets/src/mage/cards/o/OpalChampion.java | 26 +++++------ Mage.Sets/src/mage/cards/o/OpalGargoyle.java | 26 +++++------ Mage.Sets/src/mage/cards/o/OpalGuardian.java | 26 +++++------ .../src/mage/cards/o/OpalLakeGatekeepers.java | 23 +++------- Mage.Sets/src/mage/cards/o/OpalTitan.java | 17 +++++--- Mage.Sets/src/mage/cards/o/Ophiomancer.java | 25 ++++++----- Mage.Sets/src/mage/cards/o/OracleOfBones.java | 18 ++++---- .../src/mage/cards/o/OranRiefRecluse.java | 20 ++++----- .../src/mage/cards/o/OratorOfOjutai.java | 8 +--- .../src/mage/cards/o/OrneryDilophosaur.java | 9 +--- Mage.Sets/src/mage/cards/o/Ornitharch.java | 16 +++---- .../src/mage/cards/o/OrvarTheAllForm.java | 23 +++++----- Mage.Sets/src/mage/cards/o/OsaiVultures.java | 27 ++++++------ .../src/mage/cards/o/OversoldCemetery.java | 19 ++++---- Mage.Sets/src/mage/cards/p/PacksongPup.java | 20 ++++----- .../src/mage/cards/p/PaladinOfAtonement.java | 20 ++++----- .../src/mage/cards/p/PalanisHatcher.java | 31 ++++++------- Mage.Sets/src/mage/cards/p/PaupersCage.java | 22 +++++----- Mage.Sets/src/mage/cards/p/Pestilence.java | 27 ++++++------ Mage.Sets/src/mage/cards/p/PestsOfHonor.java | 14 +++--- .../src/mage/cards/p/PhageTheUntouchable.java | 17 ++++---- Mage.Sets/src/mage/cards/p/PharagaxGiant.java | 16 +++---- .../src/mage/cards/p/PhyrexianMissionary.java | 7 +-- .../src/mage/cards/p/PhyrexianWarhorse.java | 19 +++----- Mage.Sets/src/mage/cards/p/PitKeeper.java | 38 ++++------------ .../src/mage/cards/p/PlanarCollapse.java | 35 +++++++-------- .../src/mage/cards/p/PlazaOfHarmony.java | 21 +++------ Mage.Sets/src/mage/cards/p/PolisCrusher.java | 19 +++----- .../src/mage/cards/p/PoppetStitcher.java | 26 +++++------ Mage.Sets/src/mage/cards/p/Portcullis.java | 42 ++++++------------ Mage.Sets/src/mage/cards/p/PouncingWurm.java | 24 +++++------ .../src/mage/cards/p/PrickleFaeries.java | 43 ++++--------------- .../src/mage/cards/p/ProftsEideticMemory.java | 33 +++++++------- .../src/mage/cards/p/ProgenitorMimic.java | 37 ++++++++-------- .../src/mage/cards/p/PromiseOfTomorrow.java | 19 ++++---- .../src/mage/cards/p/PromisingDuskmage.java | 20 +++++---- Mage.Sets/src/mage/cards/p/Pyrohemia.java | 27 ++++++------ Mage.Sets/src/mage/cards/q/QueenMarchesa.java | 19 +++----- .../common/DrewTwoOrMoreCardsCondition.java | 2 +- .../condition/common/MonstrousCondition.java | 15 +++---- .../RevealedOrControlledDragonCondition.java | 5 +++ .../cost/CastFromHandForFreeEffect.java | 7 ++- 53 files changed, 533 insertions(+), 658 deletions(-) diff --git a/Mage.Sets/src/mage/cards/k/KavuTitan.java b/Mage.Sets/src/mage/cards/k/KavuTitan.java index a60db4425a1..5e2a273fb83 100644 --- a/Mage.Sets/src/mage/cards/k/KavuTitan.java +++ b/Mage.Sets/src/mage/cards/k/KavuTitan.java @@ -1,7 +1,5 @@ - package mage.cards.k; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; @@ -13,18 +11,19 @@ import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.counters.CounterType; +import java.util.UUID; + /** - * * @author Backfir3 */ public final class KavuTitan extends CardImpl { public KavuTitan(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.KAVU); this.power = new MageInt(2); @@ -32,10 +31,12 @@ public final class KavuTitan extends CardImpl { // Kicker {2}{G} this.addAbility(new KickerAbility("{2}{G}")); + // If Kavu Titan was kicked, it enters with three +1/+1 counters on it and with trample. - Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), - KickedCondition.ONCE, - "If Kavu Titan was kicked, it enters with three +1/+1 counters on it and with trample.", ""); + Ability ability = new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), KickedCondition.ONCE, + "If {this} was kicked, it enters with three +1/+1 counters on it and with trample.", "" + ); ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/OathOfChandra.java b/Mage.Sets/src/mage/cards/o/OathOfChandra.java index d4c77f71cef..e7a3bd95a8d 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfChandra.java +++ b/Mage.Sets/src/mage/cards/o/OathOfChandra.java @@ -1,18 +1,12 @@ - package mage.cards.o; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -23,28 +17,30 @@ import mage.game.events.ZoneChangeEvent; import mage.target.common.TargetCreaturePermanent; import mage.watchers.Watcher; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class OathOfChandra extends CardImpl { public OathOfChandra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); this.supertype.add(SuperType.LEGENDARY); // When Oath of Chandra enters the battlefield, it deals 3 damage to target creature an opponent controls. - Effect effect = new DamageTargetEffect(3); - effect.setText("it deals 3 damage to target creature an opponent controls"); - Ability ability = new EntersBattlefieldTriggeredAbility(effect, false); + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(3, "it")); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); this.addAbility(ability); // At the beginning of each end step, if a planeswalker entered the battlefield under your control this turn, Oath of Chandra deals 2 damage to each opponent. - this.addAbility(new ConditionalInterveningIfTriggeredAbility(new BeginningOfEndStepTriggeredAbility( - TargetController.ANY, new DamagePlayersEffect(Outcome.Damage, StaticValue.get(2), TargetController.OPPONENT), - false), OathOfChandraCondition.instance, - "At the beginning of each end step, if a planeswalker entered the battlefield under your control this turn, {this} deals 2 damage to each opponent."), new OathOfChandraWatcher()); + this.addAbility(new BeginningOfEndStepTriggeredAbility( + TargetController.ANY, + new DamagePlayersEffect(Outcome.Damage, StaticValue.get(2), TargetController.OPPONENT), + false, OathOfChandraCondition.instance + ), new OathOfChandraWatcher()); } private OathOfChandra(final OathOfChandra card) { @@ -58,7 +54,6 @@ public final class OathOfChandra extends CardImpl { } enum OathOfChandraCondition implements Condition { - instance; @Override @@ -69,7 +64,7 @@ enum OathOfChandraCondition implements Condition { @Override public String toString() { - return "if a planeswalker entered the battlefield under your control this turn"; + return "a planeswalker entered the battlefield under your control this turn"; } } @@ -101,5 +96,4 @@ class OathOfChandraWatcher extends Watcher { public boolean enteredPlaneswalkerForPlayer(UUID playerId) { return players.contains(playerId); } - } diff --git a/Mage.Sets/src/mage/cards/o/OathOfLiliana.java b/Mage.Sets/src/mage/cards/o/OathOfLiliana.java index b47cf7e38c5..ceff40926e3 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfLiliana.java +++ b/Mage.Sets/src/mage/cards/o/OathOfLiliana.java @@ -1,16 +1,11 @@ - package mage.cards.o; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.SacrificeOpponentsEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -21,6 +16,10 @@ import mage.game.events.ZoneChangeEvent; import mage.game.permanent.token.ZombieToken; import mage.watchers.Watcher; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** * @author fireshoes */ @@ -31,14 +30,15 @@ public final class OathOfLiliana extends CardImpl { this.supertype.add(SuperType.LEGENDARY); // When Oath of Liliana enters the battlefield, each opponent sacrifices a creature. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE), false)); + this.addAbility(new EntersBattlefieldTriggeredAbility( + new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE) + )); // At the beginning of each end step, if a planeswalker entered the battlefield under your control this turn, create a 2/2 black Zombie creature token. - this.addAbility(new ConditionalInterveningIfTriggeredAbility(new BeginningOfEndStepTriggeredAbility( + this.addAbility(new BeginningOfEndStepTriggeredAbility( TargetController.ANY, new CreateTokenEffect(new ZombieToken()), - false), OathOfLilianaCondition.instance, - "At the beginning of each end step, if a planeswalker entered the battlefield under your control this turn, " - + "create a 2/2 black Zombie creature token."), new OathOfLilianaWatcher()); + false, OathOfLilianaCondition.instance + ), new OathOfLilianaWatcher()); } private OathOfLiliana(final OathOfLiliana card) { @@ -63,7 +63,7 @@ enum OathOfLilianaCondition implements Condition { @Override public String toString() { - return "if a planeswalker entered the battlefield under your control this turn"; + return "a planeswalker entered the battlefield under your control this turn"; } } @@ -95,6 +95,4 @@ class OathOfLilianaWatcher extends Watcher { public boolean enteredPlaneswalkerForPlayer(UUID playerId) { return players.contains(playerId); } - - } diff --git a/Mage.Sets/src/mage/cards/o/ObscuraAscendancy.java b/Mage.Sets/src/mage/cards/o/ObscuraAscendancy.java index de99ac113b5..5593e56ebc0 100644 --- a/Mage.Sets/src/mage/cards/o/ObscuraAscendancy.java +++ b/Mage.Sets/src/mage/cards/o/ObscuraAscendancy.java @@ -1,15 +1,11 @@ package mage.cards.o; -import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.effects.Effects; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; @@ -24,9 +20,11 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.Spirit22Token; import mage.game.stack.Spell; +import mage.util.CardUtil; + +import java.util.UUID; /** - * * @author weirddan455 */ public final class ObscuraAscendancy extends CardImpl { @@ -37,11 +35,11 @@ public final class ObscuraAscendancy extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{U}{B}"); // Whenever you cast a spell, if its mana value is equal to the number of soul counters on Obscura Ascendancy plus one, put a soul counter on Obscura Ascendancy, then create a 2/2 white Spirit creature token with flying. - SpellCastControllerTriggeredAbility triggeredAbility = new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.SOUL.createInstance()), false); - triggeredAbility.addEffect(new CreateTokenEffect(new Spirit22Token())); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(triggeredAbility, ObscuraAscendancyCondition.instance, - "Whenever you cast a spell, if its mana value is equal to 1 plus the number of soul counters on {this}, put a soul counter on {this}, then create a 2/2 white Spirit creature token with flying." - )); + Ability ability = new SpellCastControllerTriggeredAbility( + new AddCountersSourceEffect(CounterType.SOUL.createInstance()), false + ).withInterveningIf(ObscuraAscendancyCondition.instance); + ability.addEffect(new CreateTokenEffect(new Spirit22Token()).concatBy(", then")); + this.addAbility(ability); // As long as Obscura Ascendancy has five or more soul counters on it, Spirits you control get +3/+3. this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( @@ -67,15 +65,16 @@ enum ObscuraAscendancyCondition implements Condition { @Override public boolean apply(Game game, Ability source) { Permanent permanent = source.getSourcePermanentOrLKI(game); - if (permanent != null) { - Effects effects = source.getEffects(); - if (!effects.isEmpty()) { - Object spellCast = effects.get(0).getValue("spellCast"); - if (spellCast instanceof Spell) { - return ((Spell) spellCast).getManaValue() == permanent.getCounters(game).getCount(CounterType.SOUL) + 1; - } - } - } - return false; + return permanent != null + && CardUtil + .getEffectValueFromAbility(source, "spellCast", Spell.class) + .map(Spell::getManaValue) + .filter(x -> x == permanent.getCounters(game).getCount(CounterType.SOUL) + 1) + .isPresent(); + } + + @Override + public String toString() { + return "its mana value is equal to 1 plus the number of soul counters on {this}"; } } diff --git a/Mage.Sets/src/mage/cards/o/ObsessiveSkinner.java b/Mage.Sets/src/mage/cards/o/ObsessiveSkinner.java index 5d61c63a5d8..d469f876823 100644 --- a/Mage.Sets/src/mage/cards/o/ObsessiveSkinner.java +++ b/Mage.Sets/src/mage/cards/o/ObsessiveSkinner.java @@ -1,23 +1,23 @@ package mage.cards.o; -import java.util.UUID; - import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.DeliriumCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount; import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; import mage.counters.CounterType; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * @author fireshoes */ @@ -37,14 +37,11 @@ public final class ObsessiveSkinner extends CardImpl { // Delirium — At the beginning of each opponent's upkeep, if there are four or more card types among cards in your graveyard, // put a +1/+1 counter on target creature. - ability = new ConditionalInterveningIfTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(TargetController.OPPONENT, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false), - DeliriumCondition.instance, - "Delirium — At the beginning of each opponent's upkeep, if there are four or more card types among cards in your graveyard, " - + "put a +1/+1 counter on target creature."); + ability = new BeginningOfUpkeepTriggeredAbility( + TargetController.OPPONENT, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false + ).withInterveningIf(DeliriumCondition.instance); ability.addTarget(new TargetCreaturePermanent()); - ability.addHint(CardTypesInGraveyardCount.YOU.getHint()); - this.addAbility(ability); + this.addAbility(ability.setAbilityWord(AbilityWord.DELIRIUM).addHint(CardTypesInGraveyardCount.YOU.getHint())); } private ObsessiveSkinner(final ObsessiveSkinner card) { diff --git a/Mage.Sets/src/mage/cards/o/OchreJelly.java b/Mage.Sets/src/mage/cards/o/OchreJelly.java index 36dd3fc0234..f1972a64427 100644 --- a/Mage.Sets/src/mage/cards/o/OchreJelly.java +++ b/Mage.Sets/src/mage/cards/o/OchreJelly.java @@ -6,7 +6,6 @@ import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateTokenCopyTargetEffect; @@ -43,14 +42,11 @@ public final class OchreJelly extends CardImpl { this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P1.createInstance()))); // Split — When Ochre Jelly dies, if it had two or more +1/+1 counters on it, create a token that's a copy of it at the beginning of the next end step. That token enters the battlefield with half that many +1/+1 counters on it, rounded down. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new DiesSourceTriggeredAbility(new CreateDelayedTriggeredAbilityEffect( - new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new OchreJellyEffect()) - )), OchreJellyCondition.instance, CardUtil.italicizeWithEmDash("Split") - + "When {this} dies, if it had two or more +1/+1 counters on it, " - + "create a token that's a copy of it at the beginning of the next end step. " - + "The token enters the battlefield with half that many +1/+1 counters on it, rounded down." - )); + this.addAbility(new DiesSourceTriggeredAbility(new CreateDelayedTriggeredAbilityEffect( + new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new OchreJellyEffect()) + ).setText("create a token that's a copy of it at the beginning of the next end step. " + + "That token enters the battlefield with half that many +1/+1 counters on it, rounded down")) + .withInterveningIf(OchreJellyCondition.instance).withFlavorWord("Split")); } private OchreJelly(final OchreJelly card) { @@ -68,8 +64,10 @@ enum OchreJellyCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = (Permanent) source.getEffects().get(0).getValue("permanentLeftBattlefield"); - return permanent != null && permanent.getCounters(game).getCount(CounterType.P1P1) >= 2; + return CardUtil + .getEffectValueFromAbility(source, "permanentLeftBattlefield", Permanent.class) + .filter(permanent -> permanent.getCounters(game).getCount(CounterType.P1P1) >= 2) + .isPresent(); } } @@ -95,10 +93,8 @@ class OchreJellyEffect extends OneShotEffect { if (permanent == null) { return false; } - final int counters = permanent.getCounters(game).getCount(CounterType.P1P1) / 2; - CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(CounterType.P1P1, counters); - effect.setSavedPermanent(permanent); - effect.apply(game, source); - return true; + return new CreateTokenCopyTargetEffect( + CounterType.P1P1, permanent.getCounters(game).getCount(CounterType.P1P1) / 2 + ).setSavedPermanent(permanent).apply(game, source); } } diff --git a/Mage.Sets/src/mage/cards/o/OgreSavant.java b/Mage.Sets/src/mage/cards/o/OgreSavant.java index c75a9a291c3..9ae30f39e26 100644 --- a/Mage.Sets/src/mage/cards/o/OgreSavant.java +++ b/Mage.Sets/src/mage/cards/o/OgreSavant.java @@ -1,38 +1,35 @@ - package mage.cards.o; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbility; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.ManaWasSpentCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.ColoredManaSymbol; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author FenrisulfrX */ public final class OgreSavant extends CardImpl { public OgreSavant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); this.subtype.add(SubType.OGRE); this.subtype.add(SubType.WIZARD); this.power = new MageInt(3); this.toughness = new MageInt(2); //When Ogre Savant enters the battlefield, if {U} was spent to cast Ogre Savant, return target creature to its owner’s hand. - TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(),false); + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()) + .withInterveningIf(ManaWasSpentCondition.BLUE); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, ManaWasSpentCondition.BLUE, - "When {this} enters, if {U} was spent to cast it, return target creature to its owner's hand.")); + this.addAbility(ability); } private OgreSavant(final OgreSavant card) { diff --git a/Mage.Sets/src/mage/cards/o/OldGrowthTroll.java b/Mage.Sets/src/mage/cards/o/OldGrowthTroll.java index acf6b65c22b..32c382fa036 100644 --- a/Mage.Sets/src/mage/cards/o/OldGrowthTroll.java +++ b/Mage.Sets/src/mage/cards/o/OldGrowthTroll.java @@ -12,7 +12,6 @@ import mage.abilities.costs.Cost; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; @@ -53,13 +52,8 @@ public final class OldGrowthTroll extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // When Old-Growth Troll dies, if it was a creature, return it to the battlefield. It's an Aura enchantment with enchant Forest you control and "Enchanted Forest has '{T}: Add {G}{G}' and '{1}, {T}, Sacrifice this land: Create a 4/4 green Troll Warrior creature token with trample.'" - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new DiesSourceTriggeredAbility(new OldGrowthTrollReturnEffect()), - OldGrowthTrollCondition.instance, "When {this} dies, if it was a creature, " + - "return it to the battlefield. It's an Aura enchantment with enchant Forest you control " + - "and \"Enchanted Forest has '{T}: Add {G}{G}' and '{1}, {T}, Sacrifice this land: " + - "Create a tapped 4/4 green Troll Warrior creature token with trample.'\"" - )); + this.addAbility(new DiesSourceTriggeredAbility(new OldGrowthTrollReturnEffect()) + .withInterveningIf(OldGrowthTrollCondition.instance)); } private OldGrowthTroll(final OldGrowthTroll card) { @@ -77,8 +71,15 @@ enum OldGrowthTrollCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = (Permanent) source.getEffects().get(0).getValue("permanentLeftBattlefield"); - return permanent != null && permanent.isCreature(game); + return CardUtil + .getEffectValueFromAbility(source, "permanentLeftBattlefield", Permanent.class) + .filter(permanent -> permanent.isCreature(game)) + .isPresent(); + } + + @Override + public String toString() { + return "it was a creature"; } } @@ -92,6 +93,9 @@ class OldGrowthTrollReturnEffect extends OneShotEffect { private OldGrowthTrollReturnEffect(final OldGrowthTrollReturnEffect effect) { super(effect); + staticText = "return it to the battlefield. It's an Aura enchantment with enchant Forest you control " + + "and \"Enchanted Forest has '{T}: Add {G}{G}' and '{1}, {T}, Sacrifice this land: " + + "Create a tapped 4/4 green Troll Warrior creature token with trample.'\""; } @Override diff --git a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java index 3faf035927a..e3e580eb5d3 100644 --- a/Mage.Sets/src/mage/cards/o/OpalAcrolith.java +++ b/Mage.Sets/src/mage/cards/o/OpalAcrolith.java @@ -1,13 +1,11 @@ package mage.cards.o; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.BecomesEnchantmentSourceEffect; import mage.cards.CardImpl; @@ -15,35 +13,33 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterSpell; import mage.filter.StaticFilters; +import mage.filter.common.FilterEnchantmentPermanent; import mage.game.permanent.token.TokenImpl; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class OpalAcrolith extends CardImpl { - private static final FilterSpell filter = new FilterSpell("creature spell"); - - static { - filter.add(CardType.CREATURE.getPredicate()); - } + private static final Condition condition = new SourceMatchesFilterCondition( + new FilterEnchantmentPermanent("this permanent is an enchantment") + ); public OpalAcrolith(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // Whenever an opponent casts a creature spell, if Opal Acrolith is an enchantment, Opal Acrolith becomes a 2/4 Soldier creature. - TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalAcrolithToken(), null, Duration.WhileOnBattlefield), - filter, false); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT), - "Whenever an opponent casts a creature spell, if Opal Acrolith is an enchantment, Opal Acrolith becomes a 2/4 Soldier creature.")); + this.addAbility(new SpellCastOpponentTriggeredAbility( + new BecomesCreatureSourceEffect( + new OpalAcrolithToken(), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false + ).withInterveningIf(condition)); // {0}: Opal Acrolith becomes an enchantment. this.addAbility(new SimpleActivatedAbility(new BecomesEnchantmentSourceEffect(), new ManaCostsImpl<>("{0}"))); - } private OpalAcrolith(final OpalAcrolith card) { diff --git a/Mage.Sets/src/mage/cards/o/OpalArchangel.java b/Mage.Sets/src/mage/cards/o/OpalArchangel.java index 45a44a90a0b..90924a0154c 100644 --- a/Mage.Sets/src/mage/cards/o/OpalArchangel.java +++ b/Mage.Sets/src/mage/cards/o/OpalArchangel.java @@ -1,40 +1,41 @@ - package mage.cards.o; import mage.MageInt; -import mage.abilities.TriggeredAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceMatchesFilterCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; import mage.game.permanent.token.TokenImpl; import java.util.UUID; /** - * * @author LoneFox - * */ public final class OpalArchangel extends CardImpl { + private static final Condition condition = new SourceMatchesFilterCondition( + new FilterEnchantmentPermanent("this permanent is an enchantment") + ); + public OpalArchangel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}"); // When an opponent casts a creature spell, if Opal Archangel is an enchantment, Opal Archangel becomes a 5/5 Angel creature with flying and vigilance. - TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalArchangelToken(), null, Duration.WhileOnBattlefield), - new FilterCreatureSpell(), false); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT), - "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 5/5 Angel creature with flying and vigilance.")); + this.addAbility(new SpellCastOpponentTriggeredAbility( + new BecomesCreatureSourceEffect( + new OpalArchangelToken(), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false + ).withInterveningIf(condition)); } private OpalArchangel(final OpalArchangel card) { @@ -58,6 +59,7 @@ class OpalArchangelToken extends TokenImpl { this.addAbility(FlyingAbility.getInstance()); this.addAbility(VigilanceAbility.getInstance()); } + private OpalArchangelToken(final OpalArchangelToken token) { super(token); } diff --git a/Mage.Sets/src/mage/cards/o/OpalCaryatid.java b/Mage.Sets/src/mage/cards/o/OpalCaryatid.java index 21af43734ae..33b04a36c3c 100644 --- a/Mage.Sets/src/mage/cards/o/OpalCaryatid.java +++ b/Mage.Sets/src/mage/cards/o/OpalCaryatid.java @@ -1,38 +1,39 @@ - package mage.cards.o; import mage.MageInt; -import mage.abilities.TriggeredAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceMatchesFilterCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; import mage.game.permanent.token.TokenImpl; import java.util.UUID; /** - * * @author LoneFox - * */ public final class OpalCaryatid extends CardImpl { + private static final Condition condition = new SourceMatchesFilterCondition( + new FilterEnchantmentPermanent("this permanent is an enchantment") + ); + public OpalCaryatid(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); // When an opponent casts a creature spell, if Opal Caryatid is an enchantment, Opal Caryatid becomes a 2/2 Soldier creature. - TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalCaryatidSoldierToken(), null, Duration.WhileOnBattlefield), - new FilterCreatureSpell(), false); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT), - "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 2/2 Soldier creature.")); + this.addAbility(new SpellCastOpponentTriggeredAbility( + new BecomesCreatureSourceEffect( + new OpalCaryatidSoldierToken(), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false + ).withInterveningIf(condition)); } private OpalCaryatid(final OpalCaryatid card) { diff --git a/Mage.Sets/src/mage/cards/o/OpalChampion.java b/Mage.Sets/src/mage/cards/o/OpalChampion.java index f1b24cca13f..f99bb73367e 100644 --- a/Mage.Sets/src/mage/cards/o/OpalChampion.java +++ b/Mage.Sets/src/mage/cards/o/OpalChampion.java @@ -1,39 +1,40 @@ - package mage.cards.o; import mage.MageInt; -import mage.abilities.TriggeredAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceMatchesFilterCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; import mage.game.permanent.token.TokenImpl; import java.util.UUID; /** - * * @author LoneFox - * */ public final class OpalChampion extends CardImpl { + private static final Condition condition = new SourceMatchesFilterCondition( + new FilterEnchantmentPermanent("this permanent is an enchantment") + ); + public OpalChampion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // When an opponent casts a creature spell, if Opal Champion is an enchantment, Opal Champion becomes a 3/3 Knight creature with first strike. - TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalChampionKnight(), null, Duration.WhileOnBattlefield), - new FilterCreatureSpell(), false); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT), - "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 3/3 Knight creature with first strike.")); + this.addAbility(new SpellCastOpponentTriggeredAbility( + new BecomesCreatureSourceEffect( + new OpalChampionKnight(), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false + ).withInterveningIf(condition)); } private OpalChampion(final OpalChampion card) { @@ -56,6 +57,7 @@ class OpalChampionKnight extends TokenImpl { toughness = new MageInt(3); this.addAbility(FirstStrikeAbility.getInstance()); } + private OpalChampionKnight(final OpalChampionKnight token) { super(token); } diff --git a/Mage.Sets/src/mage/cards/o/OpalGargoyle.java b/Mage.Sets/src/mage/cards/o/OpalGargoyle.java index 584d69f6141..9757fd18216 100644 --- a/Mage.Sets/src/mage/cards/o/OpalGargoyle.java +++ b/Mage.Sets/src/mage/cards/o/OpalGargoyle.java @@ -1,39 +1,40 @@ - package mage.cards.o; import mage.MageInt; -import mage.abilities.TriggeredAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceMatchesFilterCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; import mage.game.permanent.token.TokenImpl; import java.util.UUID; /** - * * @author LoneFox - * */ public final class OpalGargoyle extends CardImpl { + private static final Condition condition = new SourceMatchesFilterCondition( + new FilterEnchantmentPermanent("this permanent is an enchantment") + ); + public OpalGargoyle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // When an opponent casts a creature spell, if Opal Gargoyle is an enchantment, Opal Gargoyle becomes a 2/2 Gargoyle creature with flying. - TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalGargoyleToken(), null, Duration.WhileOnBattlefield), - new FilterCreatureSpell(), false); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT), - "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 2/2 Gargoyle creature with flying.")); + this.addAbility(new SpellCastOpponentTriggeredAbility( + new BecomesCreatureSourceEffect( + new OpalGargoyleToken(), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false + ).withInterveningIf(condition)); } private OpalGargoyle(final OpalGargoyle card) { @@ -56,6 +57,7 @@ class OpalGargoyleToken extends TokenImpl { toughness = new MageInt(2); this.addAbility(FlyingAbility.getInstance()); } + private OpalGargoyleToken(final OpalGargoyleToken token) { super(token); } diff --git a/Mage.Sets/src/mage/cards/o/OpalGuardian.java b/Mage.Sets/src/mage/cards/o/OpalGuardian.java index 40053381d52..976391c2799 100644 --- a/Mage.Sets/src/mage/cards/o/OpalGuardian.java +++ b/Mage.Sets/src/mage/cards/o/OpalGuardian.java @@ -1,41 +1,42 @@ - package mage.cards.o; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.TriggeredAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceMatchesFilterCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureSpell; +import mage.filter.common.FilterEnchantmentPermanent; import mage.game.permanent.token.TokenImpl; import java.util.UUID; /** - * * @author LoneFox - * */ public final class OpalGuardian extends CardImpl { + private static final Condition condition = new SourceMatchesFilterCondition( + new FilterEnchantmentPermanent("this permanent is an enchantment") + ); + public OpalGuardian(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{W}{W}"); // When an opponent casts a creature spell, if Opal Guardian is an enchantment, Opal Guardian becomes a 3/4 Gargoyle creature with flying and protection from red. - TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new OpalGuardianGargoyle(), null, Duration.WhileOnBattlefield), - new FilterCreatureSpell(), false); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT), - "When an opponent casts a creature spell, if {this} is an enchantment, {this} becomes a 3/4 Gargoyle creature with flying and protection from red.")); + this.addAbility(new SpellCastOpponentTriggeredAbility( + new BecomesCreatureSourceEffect( + new OpalGuardianGargoyle(), null, Duration.WhileOnBattlefield + ), StaticFilters.FILTER_SPELL_A_CREATURE, false + ).withInterveningIf(condition)); } private OpalGuardian(final OpalGuardian card) { @@ -58,6 +59,7 @@ class OpalGuardianGargoyle extends TokenImpl { this.addAbility(FlyingAbility.getInstance()); this.addAbility(ProtectionAbility.from(ObjectColor.RED)); } + private OpalGuardianGargoyle(final OpalGuardianGargoyle token) { super(token); } diff --git a/Mage.Sets/src/mage/cards/o/OpalLakeGatekeepers.java b/Mage.Sets/src/mage/cards/o/OpalLakeGatekeepers.java index 9f9084899f1..67e8746074b 100644 --- a/Mage.Sets/src/mage/cards/o/OpalLakeGatekeepers.java +++ b/Mage.Sets/src/mage/cards/o/OpalLakeGatekeepers.java @@ -4,9 +4,8 @@ import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.common.GatesYouControlHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -19,17 +18,12 @@ import java.util.UUID; /** * @author LevelX2 */ - - public final class OpalLakeGatekeepers extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(); - - static { - filter.add(SubType.GATE.getPredicate()); - } - - private static final Condition gatesCondition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 1); + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterControlledPermanent(SubType.GATE, "you control two or more Gates"), + ComparisonType.MORE_THAN, 1 + ); public OpalLakeGatekeepers(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); @@ -40,11 +34,8 @@ public final class OpalLakeGatekeepers extends CardImpl { this.toughness = new MageInt(4); // When Opal Lake Gatekeepers enters the battlefield, if you control two or more Gates, you may draw a card. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), true), - gatesCondition, - "When Opal Lake Gatekeepers enters the battlefield, if you control two or more Gates, you may draw a card.") - .addHint(new ConditionHint(gatesCondition, "You control two or more Gates"))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), true) + .withInterveningIf(condition).addHint(GatesYouControlHint.instance)); } private OpalLakeGatekeepers(final OpalLakeGatekeepers card) { diff --git a/Mage.Sets/src/mage/cards/o/OpalTitan.java b/Mage.Sets/src/mage/cards/o/OpalTitan.java index 2f7e0167e9d..1a8d13d5b78 100644 --- a/Mage.Sets/src/mage/cards/o/OpalTitan.java +++ b/Mage.Sets/src/mage/cards/o/OpalTitan.java @@ -3,16 +3,16 @@ package mage.cards.o; import mage.MageObjectReference; import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.TriggeredAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceMatchesFilterCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; +import mage.filter.common.FilterEnchantmentPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.stack.Spell; @@ -24,15 +24,18 @@ import java.util.UUID; */ public final class OpalTitan extends CardImpl { + private static final Condition condition = new SourceMatchesFilterCondition( + new FilterEnchantmentPermanent("this permanent is an enchantment") + ); + public OpalTitan(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); // When an opponent casts a creature spell, if Opal Titan is an enchantment, Opal Titan becomes a 4/4 Giant creature with protection from each of that spell's colors. - TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, new OpalTitanBecomesCreatureEffect(), - StaticFilters.FILTER_SPELL_A_CREATURE, false, SetTargetPointer.SPELL); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT), - "When an opponent casts a creature spell, if Opal Titan is an enchantment, Opal Titan becomes a 4/4 Giant creature with protection from each of that spell's colors.")); - + this.addAbility(new SpellCastOpponentTriggeredAbility( + Zone.BATTLEFIELD, new OpalTitanBecomesCreatureEffect(), + StaticFilters.FILTER_SPELL_A_CREATURE, false, SetTargetPointer.SPELL + ).withInterveningIf(condition)); } private OpalTitan(final OpalTitan card) { diff --git a/Mage.Sets/src/mage/cards/o/Ophiomancer.java b/Mage.Sets/src/mage/cards/o/Ophiomancer.java index 4427d99cd68..ec9e127a3c1 100644 --- a/Mage.Sets/src/mage/cards/o/Ophiomancer.java +++ b/Mage.Sets/src/mage/cards/o/Ophiomancer.java @@ -1,24 +1,30 @@ - package mage.cards.o; -import java.util.UUID; import mage.MageInt; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; import mage.game.permanent.token.OphiomancerSnakeToken; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class Ophiomancer extends CardImpl { + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterCreaturePermanent(SubType.SNAKE, "you control no Snakes"), ComparisonType.EQUAL_TO, 0 + ); + public Ophiomancer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add(SubType.HUMAN); @@ -28,10 +34,9 @@ public final class Ophiomancer extends CardImpl { this.toughness = new MageInt(2); // At the beginning of each upkeep, if you control no Snakes, create a 1/1 black Snake creature token with deathtouch. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(TargetController.ANY, new CreateTokenEffect(new OphiomancerSnakeToken()), false), - new PermanentsOnTheBattlefieldCondition(new FilterCreaturePermanent(SubType.SNAKE, "no Snakes"), ComparisonType.EQUAL_TO, 0), - "At the beginning of each upkeep, if you control no Snakes, create a 1/1 black Snake creature token with deathtouch.")); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + TargetController.ANY, new CreateTokenEffect(new OphiomancerSnakeToken()), false + ).withInterveningIf(condition)); } private Ophiomancer(final Ophiomancer card) { diff --git a/Mage.Sets/src/mage/cards/o/OracleOfBones.java b/Mage.Sets/src/mage/cards/o/OracleOfBones.java index 67235fda3fb..37e594aae44 100644 --- a/Mage.Sets/src/mage/cards/o/OracleOfBones.java +++ b/Mage.Sets/src/mage/cards/o/OracleOfBones.java @@ -3,7 +3,6 @@ package mage.cards.o; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.TributeNotPaidCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.cost.CastFromHandForFreeEffect; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.TributeAbility; @@ -11,7 +10,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.StaticFilters; +import mage.filter.FilterCard; +import mage.filter.common.FilterInstantOrSorceryCard; import java.util.UUID; @@ -20,6 +20,8 @@ import java.util.UUID; */ public final class OracleOfBones extends CardImpl { + private static final FilterCard filter = new FilterInstantOrSorceryCard("an instant or sorcery spell"); + public OracleOfBones(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.MINOTAUR); @@ -30,18 +32,14 @@ public final class OracleOfBones extends CardImpl { // Haste this.addAbility(HasteAbility.getInstance()); + // Tribute 2 this.addAbility(new TributeAbility(2)); + // When Oracle of Bones enters the battlefield, if tribute wasn't paid, // you may cast an instant or sorcery card from your hand without paying its mana cost. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new CastFromHandForFreeEffect( - StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY - ), false), - TributeNotPaidCondition.instance, "When {this} enters, " + - "if tribute wasn't paid, you may cast an instant or " + - "sorcery spell from your hand without paying its mana cost." - )); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CastFromHandForFreeEffect(filter)) + .withInterveningIf(TributeNotPaidCondition.instance)); } private OracleOfBones(final OracleOfBones card) { diff --git a/Mage.Sets/src/mage/cards/o/OranRiefRecluse.java b/Mage.Sets/src/mage/cards/o/OranRiefRecluse.java index 526f453eafd..4a3bf001199 100644 --- a/Mage.Sets/src/mage/cards/o/OranRiefRecluse.java +++ b/Mage.Sets/src/mage/cards/o/OranRiefRecluse.java @@ -1,11 +1,9 @@ - package mage.cards.o; -import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.KickedCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.KickerAbility; @@ -14,24 +12,26 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; + +import java.util.UUID; /** - * * @author North */ public final class OranRiefRecluse extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with flying"); + private static final FilterPermanent filter = new FilterCreaturePermanent("creature with flying"); static { filter.add(new AbilityPredicate(FlyingAbility.class)); } public OranRiefRecluse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.SPIDER); this.power = new MageInt(1); @@ -44,9 +44,9 @@ public final class OranRiefRecluse extends CardImpl { this.addAbility(ReachAbility.getInstance()); // When Oran-Rief Recluse enters the battlefield, if it was kicked, destroy target creature with flying. - EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), false); - ability.addTarget(new TargetCreaturePermanent(filter)); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, KickedCondition.ONCE, "When {this} enters, if it was kicked, destroy target creature with flying.")); + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()).withInterveningIf(KickedCondition.ONCE); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); } private OranRiefRecluse(final OranRiefRecluse card) { diff --git a/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java b/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java index 4b85e8d5274..e142e06615b 100644 --- a/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java +++ b/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java @@ -4,7 +4,6 @@ import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.RevealedOrControlledDragonCondition; import mage.abilities.costs.common.RevealDragonFromHandCost; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.FlyingAbility; @@ -36,11 +35,8 @@ public final class OratorOfOjutai extends CardImpl { this.getSpellAbility().addCost(new RevealDragonFromHandCost()); // When Orator of Ojutai enters the battlefield, if you revealed a Dragon card or controlled a Dragon as you cast Orator of Ojutai, draw a card. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)), - RevealedOrControlledDragonCondition.instance, "When {this} enters, " + - "if you revealed a Dragon card or controlled a Dragon as you cast this spell, draw a card." - ), new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)) + .withInterveningIf(RevealedOrControlledDragonCondition.instance), new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); } private OratorOfOjutai(final OratorOfOjutai card) { diff --git a/Mage.Sets/src/mage/cards/o/OrneryDilophosaur.java b/Mage.Sets/src/mage/cards/o/OrneryDilophosaur.java index fce5c2b72cf..f56f5f3f092 100644 --- a/Mage.Sets/src/mage/cards/o/OrneryDilophosaur.java +++ b/Mage.Sets/src/mage/cards/o/OrneryDilophosaur.java @@ -3,7 +3,6 @@ package mage.cards.o; import mage.MageInt; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.condition.common.FerociousCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.hint.common.FerociousHint; import mage.abilities.keyword.DeathtouchAbility; @@ -31,12 +30,8 @@ public final class OrneryDilophosaur extends CardImpl { this.addAbility(DeathtouchAbility.getInstance()); // Whenever Ornery Dilophosaur attacks, if you control a creature with power 4 or greater, Ornery Dilophosaur gets +2/+2 until end of turn. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new AttacksTriggeredAbility( - new BoostSourceEffect(2, 2, Duration.EndOfTurn), false - ), FerociousCondition.instance, "Whenever {this} attacks, " + - "if you control a creature with power 4 or greater, {this} gets +2/+2 until end of turn." - ).addHint(FerociousHint.instance)); + this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(2, 2, Duration.EndOfTurn)) + .withInterveningIf(FerociousCondition.instance).addHint(FerociousHint.instance)); } private OrneryDilophosaur(final OrneryDilophosaur card) { diff --git a/Mage.Sets/src/mage/cards/o/Ornitharch.java b/Mage.Sets/src/mage/cards/o/Ornitharch.java index b23b8a2f31a..f620a3def22 100644 --- a/Mage.Sets/src/mage/cards/o/Ornitharch.java +++ b/Mage.Sets/src/mage/cards/o/Ornitharch.java @@ -1,12 +1,8 @@ - package mage.cards.o; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.TributeNotPaidCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TributeAbility; @@ -16,14 +12,15 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.game.permanent.token.BirdToken; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class Ornitharch extends CardImpl { public Ornitharch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); this.subtype.add(SubType.ARCHON); this.power = new MageInt(3); @@ -31,12 +28,13 @@ public final class Ornitharch extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); + // Tribute 2 this.addAbility(new TributeAbility(2)); + // When Ornitharch enters the battlefield, if tribute wasn't paid, create two 1/1 white Bird creature tokens with flying. - TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BirdToken(), 2), false); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, TributeNotPaidCondition.instance, - "When {this} enters, if tribute wasn't paid, create two 1/1 white Bird creature tokens with flying.")); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BirdToken(), 2)) + .withInterveningIf(TributeNotPaidCondition.instance)); } private Ornitharch(final Ornitharch card) { diff --git a/Mage.Sets/src/mage/cards/o/OrvarTheAllForm.java b/Mage.Sets/src/mage/cards/o/OrvarTheAllForm.java index 607d71b74cc..97c5a3c17b3 100644 --- a/Mage.Sets/src/mage/cards/o/OrvarTheAllForm.java +++ b/Mage.Sets/src/mage/cards/o/OrvarTheAllForm.java @@ -54,17 +54,11 @@ public final class OrvarTheAllForm extends CardImpl { this.addAbility(new ChangelingAbility()); // Whenever you cast an instant or sorcery spell, if it targets one or more other permanents you control, create a token that's a copy of one of those permanents. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new SpellCastControllerTriggeredAbility( - new OrvarTheAllFormEffect(), - StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, - false, SetTargetPointer.SPELL - ), - OrvarTheAllFormCondition.instance, - "Whenever you cast an instant or sorcery spell, " - + "if it targets one or more other permanents you control, " - + "create a token that's a copy of one of those permanents." - )); + this.addAbility( new SpellCastControllerTriggeredAbility( + new OrvarTheAllFormEffect(), + StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, + false, SetTargetPointer.SPELL + ).withInterveningIf(OrvarTheAllFormCondition.instance)); // When a spell or ability an opponent controls causes you to discard this card, create a token that's a copy of target permanent. Ability ability = new DiscardedByOpponentTriggeredAbility(new CreateTokenCopyTargetEffect()); @@ -109,12 +103,17 @@ enum OrvarTheAllFormCondition implements Condition { .map(Controllable::getControllerId) .anyMatch(source::isControlledBy); } + + @Override + public String toString() { + return "it targets one or more other permanents you control"; + } } class OrvarTheAllFormEffect extends OneShotEffect { OrvarTheAllFormEffect() { - super(Outcome.Benefit); + super(Outcome.Benefit);staticText="create a token that's a copy of one of those permanents."; } private OrvarTheAllFormEffect(final OrvarTheAllFormEffect effect) { diff --git a/Mage.Sets/src/mage/cards/o/OsaiVultures.java b/Mage.Sets/src/mage/cards/o/OsaiVultures.java index 878f35c85c8..4a43fe7f757 100644 --- a/Mage.Sets/src/mage/cards/o/OsaiVultures.java +++ b/Mage.Sets/src/mage/cards/o/OsaiVultures.java @@ -1,47 +1,48 @@ - package mage.cards.o; -import java.util.UUID; import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.common.MorbidCondition; import mage.abilities.costs.common.RemoveCountersSourceCost; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.hint.common.MorbidHint; import mage.abilities.keyword.FlyingAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.TargetController; -import mage.constants.Zone; import mage.counters.CounterType; +import java.util.UUID; + /** - * * @author LoneFox */ public final class OsaiVultures extends CardImpl { public OsaiVultures(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.subtype.add(SubType.BIRD); this.power = new MageInt(1); this.toughness = new MageInt(1); // Flying this.addAbility(FlyingAbility.getInstance()); + // At the beginning of each end step, if a creature died this turn, put a carrion counter on Osai Vultures. - this.addAbility(new ConditionalInterveningIfTriggeredAbility(new BeginningOfEndStepTriggeredAbility( - TargetController.ANY, new AddCountersSourceEffect(CounterType.CARRION.createInstance()), false), MorbidCondition.instance, - "At the beginning of each end step, if a creature died this turn, put a carrion counter on {this}.").addHint(MorbidHint.instance)); + this.addAbility(new BeginningOfEndStepTriggeredAbility( + TargetController.ANY, new AddCountersSourceEffect(CounterType.CARRION.createInstance()), false + ).withInterveningIf(MorbidCondition.instance).addHint(MorbidHint.instance)); + // Remove two carrion counters from Osai Vultures: Osai Vultures gets +1/+1 until end of turn. - this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), - new RemoveCountersSourceCost(CounterType.CARRION.createInstance(2)))); + this.addAbility(new SimpleActivatedAbility( + new BoostSourceEffect(1, 1, Duration.EndOfTurn), + new RemoveCountersSourceCost(CounterType.CARRION.createInstance(2)) + )); } private OsaiVultures(final OsaiVultures card) { diff --git a/Mage.Sets/src/mage/cards/o/OversoldCemetery.java b/Mage.Sets/src/mage/cards/o/OversoldCemetery.java index e913ac234ab..e7a28827a18 100644 --- a/Mage.Sets/src/mage/cards/o/OversoldCemetery.java +++ b/Mage.Sets/src/mage/cards/o/OversoldCemetery.java @@ -1,31 +1,34 @@ package mage.cards.o; -import java.util.UUID; -import mage.abilities.TriggeredAbility; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.Ability; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.CardsInControllerGraveyardCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.StaticFilters; import mage.target.common.TargetCardInGraveyard; +import java.util.UUID; + /** - * * @author fireshoes */ public final class OversoldCemetery extends CardImpl { + private static final Condition condition = new CardsInControllerGraveyardCondition(4, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD); + public OversoldCemetery(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); // At the beginning of your upkeep, if you have four or more creature cards in your graveyard, you may return target creature card from your graveyard to your hand. - TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), true); + Ability ability = new BeginningOfUpkeepTriggeredAbility( + new ReturnFromGraveyardToHandTargetEffect(), true + ).withInterveningIf(condition); ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE)); - CardsInControllerGraveyardCondition condition = new CardsInControllerGraveyardCondition(4, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, condition, "At the beginning of your upkeep, if you have four or more creature cards in your graveyard, you may return target creature card from your graveyard to your hand.")); + this.addAbility(ability); } private OversoldCemetery(final OversoldCemetery card) { diff --git a/Mage.Sets/src/mage/cards/p/PacksongPup.java b/Mage.Sets/src/mage/cards/p/PacksongPup.java index cdb22dbfbfd..81e5d8ab0db 100644 --- a/Mage.Sets/src/mage/cards/p/PacksongPup.java +++ b/Mage.Sets/src/mage/cards/p/PacksongPup.java @@ -1,16 +1,15 @@ package mage.cards.p; import mage.MageInt; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.hint.ConditionHint; import mage.abilities.hint.Hint; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -28,7 +27,7 @@ import java.util.UUID; */ public final class PacksongPup extends CardImpl { - private static final FilterPermanent filter = new FilterControlledPermanent(); + private static final FilterPermanent filter = new FilterControlledPermanent("you control another Wolf or Werewolf"); static { filter.add(AnotherPredicate.instance); @@ -39,7 +38,7 @@ public final class PacksongPup extends CardImpl { } private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter); - private static final Hint hint = new ConditionHint(condition, "You control another Wolf or Werewolf"); + private static final Hint hint = new ConditionHint(condition); public PacksongPup(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); @@ -49,15 +48,14 @@ public final class PacksongPup extends CardImpl { this.toughness = new MageInt(1); // At the beginning of combat on your turn, if you control another Wolf or Werewolf, put a +1/+1 counter on Packsong Pup. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new BeginningOfCombatTriggeredAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance()) - ), condition, "At the beginning of combat on your turn," + - " if you control another Wolf or Werewolf, put a +1/+1 counter on {this}" - ).addHint(hint)); + this.addAbility(new BeginningOfCombatTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()) + ).withInterveningIf(condition).addHint(hint)); // When Packsong Pup dies, you gain life equal to its power. - this.addAbility(new DiesSourceTriggeredAbility(new GainLifeEffect(SourcePermanentPowerValue.NOT_NEGATIVE).setText("you gain life equal to its power"))); + this.addAbility(new DiesSourceTriggeredAbility( + new GainLifeEffect(SourcePermanentPowerValue.NOT_NEGATIVE).setText("you gain life equal to its power") + )); } private PacksongPup(final PacksongPup card) { diff --git a/Mage.Sets/src/mage/cards/p/PaladinOfAtonement.java b/Mage.Sets/src/mage/cards/p/PaladinOfAtonement.java index c28eb82f0cc..df6715b1f03 100644 --- a/Mage.Sets/src/mage/cards/p/PaladinOfAtonement.java +++ b/Mage.Sets/src/mage/cards/p/PaladinOfAtonement.java @@ -1,15 +1,12 @@ - package mage.cards.p; -import java.util.UUID; import mage.MageInt; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.condition.common.LiveLostLastTurnCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.SourcePermanentToughnessValue; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -17,8 +14,9 @@ import mage.constants.SubType; import mage.constants.TargetController; import mage.counters.CounterType; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class PaladinOfAtonement extends CardImpl { @@ -32,14 +30,14 @@ public final class PaladinOfAtonement extends CardImpl { this.toughness = new MageInt(1); // At the beginning of each upkeep, if you lost life last turn, put a +1/+1 counter on Paladin of Atonement. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(TargetController.ANY, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false), - LiveLostLastTurnCondition.instance, - "At the beginning of each upkeep, if you lost life last turn, put a +1/+1 counter on {this}")); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + TargetController.ANY, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false + ).withInterveningIf(LiveLostLastTurnCondition.instance)); // When Paladin of Atonement dies, you gain life equal to it's toughness. - this.addAbility(new DiesSourceTriggeredAbility(new GainLifeEffect(SourcePermanentToughnessValue.instance, - "you gain life equal to its toughness"))); + this.addAbility(new DiesSourceTriggeredAbility(new GainLifeEffect( + SourcePermanentToughnessValue.instance, "you gain life equal to its toughness" + ))); } private PaladinOfAtonement(final PaladinOfAtonement card) { diff --git a/Mage.Sets/src/mage/cards/p/PalanisHatcher.java b/Mage.Sets/src/mage/cards/p/PalanisHatcher.java index cd85c033cd5..f454171794c 100644 --- a/Mage.Sets/src/mage/cards/p/PalanisHatcher.java +++ b/Mage.Sets/src/mage/cards/p/PalanisHatcher.java @@ -2,15 +2,15 @@ package mage.cards.p; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.SacrificeControllerEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.keyword.HasteAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -29,7 +29,10 @@ import java.util.UUID; public final class PalanisHatcher extends CardImpl { private static final FilterPermanent filter = new FilterPermanent(SubType.DINOSAUR, "Dinosaurs"); - private static final FilterControlledPermanent filterEgg = new FilterControlledPermanent(SubType.EGG, "egg"); + private static final FilterPermanent filterEgg = new FilterControlledPermanent(SubType.EGG, "an Egg"); + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterControlledPermanent(SubType.EGG, "you control one or more Eggs") + ); public PalanisHatcher(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}"); @@ -39,26 +42,18 @@ public final class PalanisHatcher extends CardImpl { this.toughness = new MageInt(3); // Other Dinosaurs you control have haste. - this.addAbility(new SimpleStaticAbility( - new GainAbilityControlledEffect( - HasteAbility.getInstance(), - Duration.WhileOnBattlefield, - filter, true - ) - )); + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true + ))); // When Palani's Hatcher enters the battlefield, create two 0/1 green Dinosaur Egg creature tokens. this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new DinosaurEggToken(), 2))); // At the beginning of combat on your turn, if you control one or more Eggs, sacrifice an Egg, then create a 3/3 green Dinosaur creature token. - Ability ability = new ConditionalInterveningIfTriggeredAbility( - new BeginningOfCombatTriggeredAbility( - new SacrificeControllerEffect(filterEgg, 1, "") - ), new PermanentsOnTheBattlefieldCondition(filterEgg), - "At the beginning of combat on your turn, if you control one or more Eggs, " - + "sacrifice an Egg, then create a 3/3 green Dinosaur creature token." - ); - ability.addEffect(new CreateTokenEffect(new DinosaurVanillaToken())); + Ability ability = new BeginningOfCombatTriggeredAbility( + new SacrificeControllerEffect(filterEgg, 1, "") + ).withInterveningIf(condition); + ability.addEffect(new CreateTokenEffect(new DinosaurVanillaToken()).concatBy(", then")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PaupersCage.java b/Mage.Sets/src/mage/cards/p/PaupersCage.java index 6995e5364bd..a8c58fbb0b0 100644 --- a/Mage.Sets/src/mage/cards/p/PaupersCage.java +++ b/Mage.Sets/src/mage/cards/p/PaupersCage.java @@ -1,33 +1,31 @@ - package mage.cards.p; -import java.util.UUID; -import mage.abilities.TriggeredAbility; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.CardsInHandCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.TargetController; +import java.util.UUID; + /** - * * @author fireshoes */ public final class PaupersCage extends CardImpl { + private static final Condition condition = new CardsInHandCondition(ComparisonType.FEWER_THAN, 3, TargetController.ACTIVE); + public PaupersCage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Paupers' Cage deals 2 damage to that player. - TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility( - TargetController.OPPONENT, new DamageTargetEffect(2), false); - CardsInHandCondition condition = new CardsInHandCondition(ComparisonType.FEWER_THAN, 3, TargetController.ACTIVE); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, condition, - "At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, {this} deals 2 damage to that player.")); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + TargetController.OPPONENT, new DamageTargetEffect(2), false + ).withInterveningIf(condition)); } private PaupersCage(final PaupersCage card) { diff --git a/Mage.Sets/src/mage/cards/p/Pestilence.java b/Mage.Sets/src/mage/cards/p/Pestilence.java index 4ebedff43af..90adfe9ea6a 100644 --- a/Mage.Sets/src/mage/cards/p/Pestilence.java +++ b/Mage.Sets/src/mage/cards/p/Pestilence.java @@ -1,36 +1,37 @@ - package mage.cards.p; -import java.util.UUID; -import mage.abilities.TriggeredAbility; -import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.common.CreatureCountCondition; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DamageEverythingEffect; import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.ComparisonType; import mage.constants.TargetController; -import mage.constants.Zone; -import mage.game.events.GameEvent; +import mage.filter.common.FilterCreaturePermanent; + +import java.util.UUID; /** - * * @author Backfir3 */ public final class Pestilence extends CardImpl { - private static final String ruleText = "At the beginning of the end step, if no creatures are on the battlefield, sacrifice {this}."; + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterCreaturePermanent("no creatures are on the battlefield"), ComparisonType.EQUAL_TO, 0 + ); public Pestilence(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); // At the beginning of the end step, if no creatures are on the battlefield, sacrifice Pestilence. - TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect()); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(triggered, new CreatureCountCondition(0, TargetController.ANY), ruleText)); + this.addAbility(new BeginningOfEndStepTriggeredAbility( + TargetController.NEXT, new SacrificeSourceEffect(), false, condition + )); // {B}: Pestilence deals 1 damage to each creature and each player. this.addAbility(new SimpleActivatedAbility(new DamageEverythingEffect(1), new ManaCostsImpl<>("{B}"))); diff --git a/Mage.Sets/src/mage/cards/p/PestsOfHonor.java b/Mage.Sets/src/mage/cards/p/PestsOfHonor.java index 9bc6f9bf106..f92da8d3c0c 100644 --- a/Mage.Sets/src/mage/cards/p/PestsOfHonor.java +++ b/Mage.Sets/src/mage/cards/p/PestsOfHonor.java @@ -1,10 +1,9 @@ package mage.cards.p; import mage.MageInt; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.abilities.condition.common.CelebrationCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AbilityWord; @@ -28,12 +27,11 @@ public final class PestsOfHonor extends CardImpl { this.toughness = new MageInt(2); // Celebration - At the beginning of combat on your turn, if two or more nonland permanents entered the battlefield under your control this turn, put a +1/+1 counter on Pests of Honor. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new BeginningOfCombatTriggeredAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance()) - ), CelebrationCondition.instance, "At the beginning of combat on your turn, if two or more " + - "nonland permanents entered the battlefield under your control this turn, put a +1/+1 counter on {this}." - ).addHint(CelebrationCondition.getHint()).setAbilityWord(AbilityWord.CELEBRATION), new PermanentsEnteredBattlefieldWatcher()); + this.addAbility(new BeginningOfCombatTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())) + .withInterveningIf(CelebrationCondition.instance) + .addHint(CelebrationCondition.getHint()) + .setAbilityWord(AbilityWord.CELEBRATION), new PermanentsEnteredBattlefieldWatcher() + ); } private PestsOfHonor(final PestsOfHonor card) { diff --git a/Mage.Sets/src/mage/cards/p/PhageTheUntouchable.java b/Mage.Sets/src/mage/cards/p/PhageTheUntouchable.java index 25d3b5b1889..fe6bc438e97 100644 --- a/Mage.Sets/src/mage/cards/p/PhageTheUntouchable.java +++ b/Mage.Sets/src/mage/cards/p/PhageTheUntouchable.java @@ -1,14 +1,13 @@ package mage.cards.p; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsCombatDamageToACreatureTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.InvertCondition; import mage.abilities.condition.common.CastFromHandSourcePermanentCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LoseGameSourceControllerEffect; import mage.abilities.effects.common.LoseGameTargetPlayerEffect; @@ -19,14 +18,17 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.watchers.common.CastFromHandWatcher; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class PhageTheUntouchable extends CardImpl { + private static final Condition condition = new InvertCondition(CastFromHandSourcePermanentCondition.instance, "you didn't cast it from your hand"); + public PhageTheUntouchable(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}{B}"); this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.AVATAR); this.subtype.add(SubType.MINION); @@ -35,11 +37,8 @@ public final class PhageTheUntouchable extends CardImpl { this.toughness = new MageInt(4); // When Phage the Untouchable enters the battlefield, if you didn't cast it from your hand, you lose the game. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new LoseGameSourceControllerEffect(), false), - new InvertCondition(CastFromHandSourcePermanentCondition.instance), - "When {this} enters, if you didn't cast it from your hand, you lose the game" - ), new CastFromHandWatcher()); + this.addAbility(new EntersBattlefieldTriggeredAbility(new LoseGameSourceControllerEffect()) + .withInterveningIf(condition), new CastFromHandWatcher()); // Whenever Phage deals combat damage to a creature, destroy that creature. It can't be regenerated. this.addAbility(new DealsCombatDamageToACreatureTriggeredAbility(new DestroyTargetEffect(true), false, true)); diff --git a/Mage.Sets/src/mage/cards/p/PharagaxGiant.java b/Mage.Sets/src/mage/cards/p/PharagaxGiant.java index 44f29cb312f..e92555a4cf1 100644 --- a/Mage.Sets/src/mage/cards/p/PharagaxGiant.java +++ b/Mage.Sets/src/mage/cards/p/PharagaxGiant.java @@ -1,12 +1,8 @@ - package mage.cards.p; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.TributeNotPaidCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.keyword.TributeAbility; import mage.cards.CardImpl; @@ -15,14 +11,15 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class PharagaxGiant extends CardImpl { public PharagaxGiant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); this.subtype.add(SubType.GIANT); this.power = new MageInt(3); @@ -30,10 +27,11 @@ public final class PharagaxGiant extends CardImpl { // Tribute 2 (As this creature enters the battlefield, an opponent of your choice may place two +1/+1 counters on it.) this.addAbility(new TributeAbility(2)); + // When Pharagax Giant enters the battlefield, if tribute wasn't paid, Pharagax Giant deals 5 damage to each opponent. - TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DamagePlayersEffect(5, TargetController.OPPONENT), false); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, TributeNotPaidCondition.instance, - "When {this} enters, if tribute wasn't paid, {this} deals 5 damage to each opponent.")); + this.addAbility(new EntersBattlefieldTriggeredAbility( + new DamagePlayersEffect(5, TargetController.OPPONENT) + ).withInterveningIf(TributeNotPaidCondition.instance)); } private PharagaxGiant(final PharagaxGiant card) { diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianMissionary.java b/Mage.Sets/src/mage/cards/p/PhyrexianMissionary.java index 158258ae21b..2a44de0a472 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianMissionary.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianMissionary.java @@ -4,7 +4,6 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.KickedCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.abilities.keyword.LifelinkAbility; @@ -38,11 +37,7 @@ public final class PhyrexianMissionary extends CardImpl { this.addAbility(LifelinkAbility.getInstance()); // When Phyrexian Missionary enters the battlefield, if it was kicked, return target creature card from your graveyard to your hand. - Ability ability = new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()), - KickedCondition.ONCE, "When {this} enters, if it was kicked, " + - "return target creature card from your graveyard to your hand." - ); + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()).withInterveningIf(KickedCondition.ONCE); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianWarhorse.java b/Mage.Sets/src/mage/cards/p/PhyrexianWarhorse.java index 9f9ef0e0be4..d393a074bd8 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianWarhorse.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianWarhorse.java @@ -1,6 +1,5 @@ package mage.cards.p; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -8,20 +7,20 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.common.KickedCondition; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.constants.Duration; -import mage.constants.SubType; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.StaticFilters; import mage.game.permanent.token.SoldierToken; +import java.util.UUID; + /** - * * @author weirddan455 */ public final class PhyrexianWarhorse extends CardImpl { @@ -38,16 +37,12 @@ public final class PhyrexianWarhorse extends CardImpl { this.addAbility(new KickerAbility("{W}")); // When Phyrexian Warhorse enters the battlefield, if it was kicked, create a 1/1 white Soldier creature token. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SoldierToken())), - KickedCondition.ONCE, - "When {this} enters, if it was kicked, create a 1/1 white Soldier creature token." - )); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SoldierToken())) + .withInterveningIf(KickedCondition.ONCE)); // {1}, Sacrifice another creature: Phyrexian Warhorse gets +2/+1 until end of turn. Ability ability = new SimpleActivatedAbility( - new BoostSourceEffect(2, 1, Duration.EndOfTurn), - new GenericManaCost(1) + new BoostSourceEffect(2, 1, Duration.EndOfTurn), new GenericManaCost(1) ); ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/p/PitKeeper.java b/Mage.Sets/src/mage/cards/p/PitKeeper.java index 8d31e68c894..d261db5bc13 100644 --- a/Mage.Sets/src/mage/cards/p/PitKeeper.java +++ b/Mage.Sets/src/mage/cards/p/PitKeeper.java @@ -1,28 +1,27 @@ package mage.cards.p; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.condition.common.CardsInControllerGraveyardCondition; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** - * * @author fireshoes */ public final class PitKeeper extends CardImpl { + private static final Condition condition = new CardsInControllerGraveyardCondition(4, StaticFilters.FILTER_CARD_CREATURES); + public PitKeeper(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.HUMAN); @@ -31,12 +30,9 @@ public final class PitKeeper extends CardImpl { this.toughness = new MageInt(1); // When Pit Keeper enters the battlefield, if you have four or more creature cards in your graveyard, you may return target creature card from your graveyard to your hand. - TriggeredAbility triggeredAbility = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true); - triggeredAbility.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - triggeredAbility, - new CreatureCardsInControllerGraveyardCondition(4), - "When {this} enters, if you have four or more creature cards in your graveyard, you may return target creature card from your graveyard to your hand.")); + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true).withInterveningIf(condition); + ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.addAbility(ability); } private PitKeeper(final PitKeeper card) { @@ -48,21 +44,3 @@ public final class PitKeeper extends CardImpl { return new PitKeeper(this); } } - -class CreatureCardsInControllerGraveyardCondition implements Condition { - - private int value; - - public CreatureCardsInControllerGraveyardCondition(int value) { - this.value = value; - } - - @Override - public boolean apply(Game game, Ability source) { - Player p = game.getPlayer(source.getControllerId()); - if (p != null && p.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game) >= value) { - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/p/PlanarCollapse.java b/Mage.Sets/src/mage/cards/p/PlanarCollapse.java index 96bfb43e1fc..ad33205a03d 100644 --- a/Mage.Sets/src/mage/cards/p/PlanarCollapse.java +++ b/Mage.Sets/src/mage/cards/p/PlanarCollapse.java @@ -1,34 +1,37 @@ - package mage.cards.p; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.TriggeredAbility; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.ComparisonType; import mage.filter.StaticFilters; -import mage.game.Game; +import mage.filter.common.FilterCreaturePermanent; + +import java.util.UUID; /** - * * @author Plopman */ public final class PlanarCollapse extends CardImpl { + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterCreaturePermanent("there are four or more creatures on the battlefield"), + ComparisonType.MORE_THAN, 3, false + ); + public PlanarCollapse(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // At the beginning of your upkeep, if there are four or more creatures on the battlefield, sacrifice Planar Collapse and destroy all creatures. They can't be regenerated. - TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceEffect()); - ability.addEffect(new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_CREATURE, true)); - PlanarCollapseCondition contition = new PlanarCollapseCondition(); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, contition, "At the beginning of your upkeep, if there are four or more creatures on the battlefield, sacrifice {this} and destroy all creatures. They can't be regenerated")); - + Ability ability = new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceEffect()).withInterveningIf(condition); + ability.addEffect(new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_CREATURE, true).concatBy("and")); + this.addAbility(ability); } private PlanarCollapse(final PlanarCollapse card) { @@ -39,12 +42,4 @@ public final class PlanarCollapse extends CardImpl { public PlanarCollapse copy() { return new PlanarCollapse(this); } - - static class PlanarCollapseCondition implements mage.abilities.condition.Condition { - - @Override - public boolean apply(Game game, Ability source) { - return game.getBattlefield().count(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source, game) >= 4; - } - } } diff --git a/Mage.Sets/src/mage/cards/p/PlazaOfHarmony.java b/Mage.Sets/src/mage/cards/p/PlazaOfHarmony.java index 71d652b53b7..9f59bf56dfe 100644 --- a/Mage.Sets/src/mage/cards/p/PlazaOfHarmony.java +++ b/Mage.Sets/src/mage/cards/p/PlazaOfHarmony.java @@ -3,9 +3,8 @@ package mage.cards.p; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.common.GatesYouControlHint; import mage.abilities.mana.AnyColorLandsProduceManaAbility; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; @@ -24,25 +23,19 @@ import java.util.UUID; */ public final class PlazaOfHarmony extends CardImpl { - private static final FilterPermanent filter = new FilterControlledPermanent(); private static final FilterPermanent filter2 = new FilterPermanent(SubType.GATE, "Gate"); - static { - filter.add(SubType.GATE.getPredicate()); - } - - private static final Condition condition - = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 1); + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterControlledPermanent(SubType.GATE, "you control two or more Gates"), + ComparisonType.MORE_THAN, 1 + ); public PlazaOfHarmony(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // When Plaza of Harmony enters the battlefield, if you control two or more Gates, you gain 3 life. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new GainLifeEffect(3)), - condition, "When {this} enters, " + - "if you control two or more Gates, you gain 3 life." - ).addHint(new ConditionHint(condition, "You control two or more Gates"))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(3)) + .withInterveningIf(condition).addHint(GatesYouControlHint.instance)); // {T}: Add {C}. this.addAbility(new ColorlessManaAbility()); diff --git a/Mage.Sets/src/mage/cards/p/PolisCrusher.java b/Mage.Sets/src/mage/cards/p/PolisCrusher.java index 1b615461828..83422c7208a 100644 --- a/Mage.Sets/src/mage/cards/p/PolisCrusher.java +++ b/Mage.Sets/src/mage/cards/p/PolisCrusher.java @@ -1,10 +1,9 @@ package mage.cards.p; import mage.MageInt; -import mage.abilities.TriggeredAbility; +import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.condition.common.MonstrousCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.MonstrosityAbility; import mage.abilities.keyword.ProtectionAbility; @@ -14,6 +13,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.FilterCard; +import mage.filter.FilterPermanent; import mage.filter.common.FilterEnchantmentCard; import mage.filter.common.FilterEnchantmentPermanent; import mage.target.TargetPermanent; @@ -27,11 +27,7 @@ import java.util.UUID; public final class PolisCrusher extends CardImpl { private static final FilterCard filterCard = new FilterEnchantmentCard("enchantments"); - private static final FilterEnchantmentPermanent filterPermanent = new FilterEnchantmentPermanent("enchantment that player controls"); - - static { - filterCard.add(CardType.ENCHANTMENT.getPredicate()); - } + private static final FilterPermanent filterPermanent = new FilterEnchantmentPermanent("enchantment that player controls"); public PolisCrusher(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{G}"); @@ -50,12 +46,11 @@ public final class PolisCrusher extends CardImpl { this.addAbility(new MonstrosityAbility("{4}{R}{G}", 3)); // Whenever Polis Crusher deals combat damage to a player, if Polis Crusher is monstrous, destroy target enchantment that player controls. - TriggeredAbility ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility( + new DestroyTargetEffect(), false, true + ).withInterveningIf(MonstrousCondition.instance); ability.addTarget(new TargetPermanent(filterPermanent)); - ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster()); - - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MonstrousCondition.instance, - "Whenever {this} deals combat damage to a player, if {this} is monstrous, destroy target enchantment that player controls.")); + this.addAbility(ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster())); } private PolisCrusher(final PolisCrusher card) { diff --git a/Mage.Sets/src/mage/cards/p/PoppetStitcher.java b/Mage.Sets/src/mage/cards/p/PoppetStitcher.java index 018254b646b..00b952d09a7 100644 --- a/Mage.Sets/src/mage/cards/p/PoppetStitcher.java +++ b/Mage.Sets/src/mage/cards/p/PoppetStitcher.java @@ -1,23 +1,25 @@ package mage.cards.p; import mage.MageInt; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; import mage.abilities.keyword.TransformAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SubType; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TokenPredicate; import mage.game.permanent.token.ZombieDecayedToken; import java.util.UUID; @@ -27,11 +29,15 @@ import java.util.UUID; */ public final class PoppetStitcher extends CardImpl { - private static final Condition condition = new PermanentsOnTheBattlefieldCondition( - StaticFilters.FILTER_CREATURE_TOKEN, ComparisonType.MORE_THAN, 2 - ); + private static final FilterPermanent filter = new FilterControlledPermanent("you control three or more creature tokens"); + + static { + filter.add(TokenPredicate.TRUE); + } + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 2); private static final Hint hint = new ValueHint( - "Creature tokens you control", new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CREATURE_TOKEN) + "Creature tokens you control", new PermanentsOnBattlefieldCount(filter) ); public PoppetStitcher(UUID ownerId, CardSetInfo setInfo) { @@ -52,12 +58,8 @@ public final class PoppetStitcher extends CardImpl { // At the beginning of your upkeep, if you control three or more creature tokens, you may transform Poppet Sticher. this.addAbility(new TransformAbility()); - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility( - new TransformSourceEffect(), true - ), condition, "At the beginning of your upkeep, " + - "if you control three or more creature tokens, you may transform {this}." - ).addHint(hint)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(), true) + .withInterveningIf(condition).addHint(hint)); } private PoppetStitcher(final PoppetStitcher card) { diff --git a/Mage.Sets/src/mage/cards/p/Portcullis.java b/Mage.Sets/src/mage/cards/p/Portcullis.java index a85b6c4c20a..2a67517e06c 100644 --- a/Mage.Sets/src/mage/cards/p/Portcullis.java +++ b/Mage.Sets/src/mage/cards/p/Portcullis.java @@ -2,11 +2,9 @@ package mage.cards.p; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; -import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; @@ -30,17 +28,19 @@ import java.util.UUID; */ public final class Portcullis extends CardImpl { + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterCreaturePermanent("there are two or more other creatures on the battlefield"), + ComparisonType.MORE_THAN, 1, false + ); + public Portcullis(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature. Return that card to the battlefield under its owner's control when Portcullis leaves the battlefield. - String rule = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature."; - String rule2 = " Return that card to the battlefield under its owner's control when {this} leaves the battlefield."; - TriggeredAbility ability = new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new PortcullisExileEffect(), - StaticFilters.FILTER_PERMANENT_A_CREATURE, false, SetTargetPointer.PERMANENT); - MoreThanXCreaturesOnBFCondition condition = new MoreThanXCreaturesOnBFCondition(2); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, condition, rule + rule2)); - + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new PortcullisExileEffect(), StaticFilters.FILTER_PERMANENT_A_CREATURE, + false, SetTargetPointer.PERMANENT + ).withInterveningIf(condition)); } private Portcullis(final Portcullis card) { @@ -53,28 +53,12 @@ public final class Portcullis extends CardImpl { } } -class MoreThanXCreaturesOnBFCondition implements Condition { - - protected final int value; - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures on field"); - - public MoreThanXCreaturesOnBFCondition(int value) { - this.value = value; - } - - @Override - public final boolean apply(Game game, Ability source) { - PermanentsOnBattlefieldCount amount = new PermanentsOnBattlefieldCount(filter); - int count = amount.calculate(game, source, null); - return count > value; - } -} - class PortcullisExileEffect extends OneShotEffect { PortcullisExileEffect() { super(Outcome.Exile); - this.staticText = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature"; + this.staticText = "exile that creature. Return that card to the battlefield " + + "under its owner's control when {this} leaves the battlefield"; } private PortcullisExileEffect(final PortcullisExileEffect effect) { @@ -139,6 +123,6 @@ class PortcullisReturnToBattlefieldTriggeredAbility extends DelayedTriggeredAbil @Override public String getRule() { - return "Return this card to the battlefield under its owner's control when Portcullis leaves the battlefield."; + return "Return this card to the battlefield under its owner's control when {this} leaves the battlefield."; } } diff --git a/Mage.Sets/src/mage/cards/p/PouncingWurm.java b/Mage.Sets/src/mage/cards/p/PouncingWurm.java index 03932a55579..eaa2a553e4c 100644 --- a/Mage.Sets/src/mage/cards/p/PouncingWurm.java +++ b/Mage.Sets/src/mage/cards/p/PouncingWurm.java @@ -1,12 +1,9 @@ - package mage.cards.p; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.KickedCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.HasteAbility; @@ -14,18 +11,19 @@ import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.counters.CounterType; +import java.util.UUID; + /** - * * @author Backfir3 */ public final class PouncingWurm extends CardImpl { public PouncingWurm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.WURM); this.power = new MageInt(3); @@ -33,12 +31,14 @@ public final class PouncingWurm extends CardImpl { // Kicker {2}{G} this.addAbility(new KickerAbility("{2}{G}")); + // If Pouncing Wurm was kicked, it enters with three +1/+1 counters on it and with haste. - Ability ability = new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3))), - KickedCondition.ONCE,"If Pouncing Wurm was kicked, it enters with three +1/+1 counters on it and with haste."); - ability.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield)); - this.addAbility(ability); + Ability ability = new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), KickedCondition.ONCE, + "If {this} was kicked, it enters with three +1/+1 counters on it and with haste.", "" + ); + ability.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield)); + this.addAbility(ability); } private PouncingWurm(final PouncingWurm card) { diff --git a/Mage.Sets/src/mage/cards/p/PrickleFaeries.java b/Mage.Sets/src/mage/cards/p/PrickleFaeries.java index a25a5ac2c23..525b6089461 100644 --- a/Mage.Sets/src/mage/cards/p/PrickleFaeries.java +++ b/Mage.Sets/src/mage/cards/p/PrickleFaeries.java @@ -1,24 +1,15 @@ package mage.cards.p; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.condition.common.CardsInHandCondition; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.FlyingAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.TargetController; -import mage.constants.Zone; -import mage.game.Game; -import mage.players.Player; +import mage.constants.*; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; import java.util.UUID; /** @@ -26,6 +17,8 @@ import java.util.UUID; */ public final class PrickleFaeries extends CardImpl { + private static final Condition condition = new CardsInHandCondition(ComparisonType.FEWER_THAN, 3, TargetController.ACTIVE); + public PrickleFaeries(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); @@ -39,13 +32,10 @@ public final class PrickleFaeries extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Prickle Faeries deals 2 damage to them. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility( - Zone.BATTLEFIELD, TargetController.OPPONENT, new DamageTargetEffect(2), - false - ), PrickleFaeriesCondition.instance, "At the beginning of each opponent's upkeep, " + - "if that player has two or fewer cards in hand, {this} deals 2 damage to them." - )); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + Zone.BATTLEFIELD, TargetController.OPPONENT, + new DamageTargetEffect(2, true, "them"), false + ).withInterveningIf(condition)); } private PrickleFaeries(final PrickleFaeries card) { @@ -57,18 +47,3 @@ public final class PrickleFaeries extends CardImpl { return new PrickleFaeries(this); } } - -enum PrickleFaeriesCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - return Optional - .ofNullable(game.getActivePlayerId()) - .map(game::getPlayer) - .filter(Objects::nonNull) - .map(Player::getHand) - .map(Set::size) - .orElse(0) <= 2; - } -} diff --git a/Mage.Sets/src/mage/cards/p/ProftsEideticMemory.java b/Mage.Sets/src/mage/cards/p/ProftsEideticMemory.java index 8797f7c4fa1..60e17d1518a 100644 --- a/Mage.Sets/src/mage/cards/p/ProftsEideticMemory.java +++ b/Mage.Sets/src/mage/cards/p/ProftsEideticMemory.java @@ -1,32 +1,33 @@ package mage.cards.p; -import java.util.UUID; - import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.DrewTwoOrMoreCardsCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.IntPlusDynamicValue; import mage.abilities.dynamicvalue.common.CardsDrawnThisTurnDynamicValue; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.constants.Duration; -import mage.constants.SuperType; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; import mage.counters.CounterType; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** - * * @author DominionSpy */ public final class ProftsEideticMemory extends CardImpl { + private static final DynamicValue xValue = new IntPlusDynamicValue(-1, CardsDrawnThisTurnDynamicValue.instance); + public ProftsEideticMemory(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); @@ -38,21 +39,17 @@ public final class ProftsEideticMemory extends CardImpl { // You have no maximum hand size. this.addAbility(new SimpleStaticAbility(new MaximumHandSizeControllerEffect( Integer.MAX_VALUE, Duration.WhileOnBattlefield, - MaximumHandSizeControllerEffect.HandSizeModification.SET))); + MaximumHandSizeControllerEffect.HandSizeModification.SET + ))); // At the beginning of combat on your turn, if you've drawn more than one card this turn, // put X +1/+1 counters on target creature you control, // where X is the number of cards you've drawn this turn minus one. - Ability ability = new ConditionalInterveningIfTriggeredAbility( - new BeginningOfCombatTriggeredAbility( - new AddCountersTargetEffect( - CounterType.P1P1.createInstance(), - new IntPlusDynamicValue(-1, CardsDrawnThisTurnDynamicValue.instance)) - ), - DrewTwoOrMoreCardsCondition.instance, - "At the beginning of combat on your turn, if you've drawn more than one card this turn, " + - "put X +1/+1 counters on target creature you control, " + - "where X is the number of cards you've drawn this turn minus one"); + Ability ability = new BeginningOfCombatTriggeredAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance(), xValue) + .setText("put X +1/+1 counters on target creature you control, " + + "where X is the number of cards you've drawn this turn minus one") + ).withInterveningIf(DrewTwoOrMoreCardsCondition.instance); ability.addTarget(new TargetControlledCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java b/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java index e671856f85f..9eb47ada682 100644 --- a/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java +++ b/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java @@ -1,37 +1,38 @@ - package mage.cards.p; -import java.util.UUID; import mage.MageInt; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceMatchesFilterCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.CopyPermanentEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.TokenPredicate; import mage.util.functions.AbilityCopyApplier; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class ProgenitorMimic extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("no Token"); + private static final FilterPermanent filter = new FilterCreaturePermanent("this creature isn't a token"); static { filter.add(TokenPredicate.FALSE); } + private static final Condition condition = new SourceMatchesFilterCondition(filter); + public ProgenitorMimic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{U}"); this.subtype.add(SubType.SHAPESHIFTER); this.power = new MageInt(0); @@ -40,18 +41,14 @@ public final class ProgenitorMimic extends CardImpl { // You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield // except it has "At the beginning of your upkeep, if this creature isn't a token, // create a token that's a copy of this creature." - Effect effect = new CreateTokenCopySourceEffect(); - effect.setText("create a token that's a copy of this creature"); - - AbilityCopyApplier applier = new AbilityCopyApplier( - new ConditionalInterveningIfTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(effect), - new SourceMatchesFilterCondition(filter), - "At the beginning of your upkeep, if this creature isn't a token, create a token that's a copy of this creature.") - ); - effect = new CopyPermanentEffect(applier); - effect.setText("as a copy of any creature on the battlefield except it has \"At the beginning of your upkeep, if this creature isn't a token, create a token that's a copy of this creature.\""); - this.addAbility(new EntersBattlefieldAbility(effect, true)); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(new AbilityCopyApplier( + new BeginningOfUpkeepTriggeredAbility( + new CreateTokenCopySourceEffect().setText("create a token that's a copy of this creature") + ).withInterveningIf(condition) + )).setText("as a copy of any creature on the battlefield except it has " + + "\"At the beginning of your upkeep, if this creature isn't a token, " + + "create a token that's a copy of this creature.\""), true + )); } private ProgenitorMimic(final ProgenitorMimic card) { diff --git a/Mage.Sets/src/mage/cards/p/PromiseOfTomorrow.java b/Mage.Sets/src/mage/cards/p/PromiseOfTomorrow.java index dea8fdf10dd..6dd75516b53 100644 --- a/Mage.Sets/src/mage/cards/p/PromiseOfTomorrow.java +++ b/Mage.Sets/src/mage/cards/p/PromiseOfTomorrow.java @@ -1,13 +1,13 @@ package mage.cards.p; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.abilities.Ability; import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.effects.common.ReturnFromExileForSourceEffect; import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -15,6 +15,7 @@ import mage.constants.ComparisonType; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; import java.util.UUID; @@ -24,7 +25,7 @@ import java.util.UUID; public final class PromiseOfTomorrow extends CardImpl { private static final Condition condition = new PermanentsOnTheBattlefieldCondition( - StaticFilters.FILTER_CONTROLLED_CREATURE, + new FilterControlledCreaturePermanent("you control no creatures"), ComparisonType.EQUAL_TO, 0, true ); @@ -38,12 +39,12 @@ public final class PromiseOfTomorrow extends CardImpl { )); // At the beginning of each end step, if you control no creatures, sacrifice Promise of Tomorrow and return all cards exiled with it to the battlefield under your control. - BeginningOfEndStepTriggeredAbility returnAbility = new BeginningOfEndStepTriggeredAbility(TargetController.ANY, new SacrificeSourceEffect(), false); - returnAbility.addEffect(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD)); - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - returnAbility, condition, "At the beginning of each end step, if you control no creatures, " + - "sacrifice {this} and return all cards exiled with it to the battlefield under your control." - )); + Ability ability = new BeginningOfEndStepTriggeredAbility( + TargetController.ANY, new SacrificeSourceEffect(), false, condition + ); + ability.addEffect(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD) + .setText("and return all cards exiled with it to the battlefield under your control")); + this.addAbility(ability); } private PromiseOfTomorrow(final PromiseOfTomorrow card) { diff --git a/Mage.Sets/src/mage/cards/p/PromisingDuskmage.java b/Mage.Sets/src/mage/cards/p/PromisingDuskmage.java index 3c4fec64340..6edd71de717 100644 --- a/Mage.Sets/src/mage/cards/p/PromisingDuskmage.java +++ b/Mage.Sets/src/mage/cards/p/PromisingDuskmage.java @@ -4,7 +4,6 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -13,6 +12,7 @@ import mage.constants.SubType; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.CardUtil; import java.util.UUID; @@ -30,11 +30,8 @@ public final class PromisingDuskmage extends CardImpl { this.toughness = new MageInt(3); // When Promising Duskmage dies, if it had a +1/+1 counter on it, draw a card. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(1)), - PromisingDuskmageCondition.instance, "When {this} dies, " + - "if it had a +1/+1 counter on it, draw a card." - )); + this.addAbility(new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(1)) + .withInterveningIf(PromisingDuskmageCondition.instance)); } private PromisingDuskmage(final PromisingDuskmage card) { @@ -52,7 +49,14 @@ enum PromisingDuskmageCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = (Permanent) source.getEffects().get(0).getValue("permanentLeftBattlefield"); - return permanent != null && permanent.getCounters(game).containsKey(CounterType.P1P1); + return CardUtil + .getEffectValueFromAbility(source, "permanentLeftBattlefield", Permanent.class) + .filter(permanent -> permanent.getCounters(game).containsKey(CounterType.P1P1)) + .isPresent(); + } + + @Override + public String toString() { + return "it had a +1/+1 counter on it"; } } diff --git a/Mage.Sets/src/mage/cards/p/Pyrohemia.java b/Mage.Sets/src/mage/cards/p/Pyrohemia.java index 5ebe14c9cdc..c161ce7991f 100644 --- a/Mage.Sets/src/mage/cards/p/Pyrohemia.java +++ b/Mage.Sets/src/mage/cards/p/Pyrohemia.java @@ -1,36 +1,37 @@ - package mage.cards.p; -import java.util.UUID; -import mage.abilities.TriggeredAbility; -import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.common.CreatureCountCondition; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DamageEverythingEffect; import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.ComparisonType; import mage.constants.TargetController; -import mage.constants.Zone; -import mage.game.events.GameEvent; +import mage.filter.common.FilterCreaturePermanent; + +import java.util.UUID; /** - * * @author fireshoes */ public final class Pyrohemia extends CardImpl { - private static final String ruleText = "At the beginning of the end step, if no creatures are on the battlefield, sacrifice {this}."; + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterCreaturePermanent("no creatures are on the battlefield"), ComparisonType.EQUAL_TO, 0 + ); public Pyrohemia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}"); // At the beginning of the end step, if no creatures are on the battlefield, sacrifice Pyrohemia. - TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect()); - this.addAbility(new ConditionalInterveningIfTriggeredAbility(triggered, new CreatureCountCondition(0, TargetController.ANY), ruleText)); + this.addAbility(new BeginningOfEndStepTriggeredAbility( + TargetController.NEXT, new SacrificeSourceEffect(), false, condition + )); // {R}: Pyrohemia deals 1 damage to each creature and each player. this.addAbility(new SimpleActivatedAbility(new DamageEverythingEffect(1), new ManaCostsImpl<>("{R}"))); diff --git a/Mage.Sets/src/mage/cards/q/QueenMarchesa.java b/Mage.Sets/src/mage/cards/q/QueenMarchesa.java index 1c4d74e037d..163c2a229b3 100644 --- a/Mage.Sets/src/mage/cards/q/QueenMarchesa.java +++ b/Mage.Sets/src/mage/cards/q/QueenMarchesa.java @@ -1,18 +1,15 @@ - package mage.cards.q; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.BecomesMonarchSourceEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.hint.common.MonarchHint; import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.HasteAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -21,8 +18,9 @@ import mage.constants.SuperType; import mage.game.Game; import mage.game.permanent.token.QueenMarchesaAssassinToken; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class QueenMarchesa extends CardImpl { @@ -44,10 +42,8 @@ public final class QueenMarchesa extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new BecomesMonarchSourceEffect()).addHint(MonarchHint.instance)); // At the beginning of your upkeep, if an opponent is the monarch, create a 1/1 black Assassin creature token with deathtouch and haste. - this.addAbility(new ConditionalInterveningIfTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new QueenMarchesaAssassinToken())), - OpponentIsMonarchCondition.instance, - "At the beginning of your upkeep, if an opponent is the monarch, create a 1/1 black Assassin creature token with deathtouch and haste.")); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new QueenMarchesaAssassinToken())) + .withInterveningIf(QueenMarchesaCondition.instance)); } private QueenMarchesa(final QueenMarchesa card) { @@ -60,9 +56,8 @@ public final class QueenMarchesa extends CardImpl { } } -enum OpponentIsMonarchCondition implements Condition { - - instance; +enum QueenMarchesaCondition implements Condition { + instance; @Override public boolean apply(Game game, Ability source) { diff --git a/Mage/src/main/java/mage/abilities/condition/common/DrewTwoOrMoreCardsCondition.java b/Mage/src/main/java/mage/abilities/condition/common/DrewTwoOrMoreCardsCondition.java index fb5fd5ceef3..f457ff9dc4a 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/DrewTwoOrMoreCardsCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/DrewTwoOrMoreCardsCondition.java @@ -19,6 +19,6 @@ public enum DrewTwoOrMoreCardsCondition implements Condition { @Override public String toString() { - return "you've drawn two or more cards this turn"; + return "you've drawn more than one card this turn"; } } diff --git a/Mage/src/main/java/mage/abilities/condition/common/MonstrousCondition.java b/Mage/src/main/java/mage/abilities/condition/common/MonstrousCondition.java index d52277a8171..5723bee4556 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/MonstrousCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/MonstrousCondition.java @@ -1,5 +1,3 @@ - - package mage.abilities.condition.common; import mage.abilities.Ability; @@ -7,21 +5,22 @@ import mage.abilities.condition.Condition; import mage.game.Game; import mage.game.permanent.Permanent; - /** * Checks if a Permanent is monstrous * * @author LevelX2 */ public enum MonstrousCondition implements Condition { - instance; + @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { - return permanent.isMonstrous(); - } - return false; + return permanent != null && permanent.isMonstrous(); + } + + @Override + public String toString() { + return "{this} is monstrous"; } } diff --git a/Mage/src/main/java/mage/abilities/condition/common/RevealedOrControlledDragonCondition.java b/Mage/src/main/java/mage/abilities/condition/common/RevealedOrControlledDragonCondition.java index 8658e5897bf..c13f4a2f6fc 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/RevealedOrControlledDragonCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/RevealedOrControlledDragonCondition.java @@ -27,4 +27,9 @@ public enum RevealedOrControlledDragonCondition implements Condition { = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class); return watcher != null && watcher.checkCondition(source, game); } + + @Override + public String toString() { + return "you revealed a Dragon card or controlled a Dragon as you cast this spell"; + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/CastFromHandForFreeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/CastFromHandForFreeEffect.java index 75b5b17d635..1e984c282c1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/CastFromHandForFreeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/CastFromHandForFreeEffect.java @@ -35,10 +35,9 @@ public class CastFromHandForFreeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - return CardUtil.castSpellWithAttributesForFree(controller, source, game, new CardsImpl(controller.getHand()), filter); + return controller != null && CardUtil.castSpellWithAttributesForFree( + controller, source, game, new CardsImpl(controller.getHand()), filter + ); } @Override