Remove ConditionalTriggeredAbility and add trigger condition into triggered abilities (#13656)

* remove ConditionalTriggeredAbility

* a few small fixes

* merge fix

* simplify phrase handling

* add documentation

* a few text fixes

* update wording
This commit is contained in:
Evan Kranzler 2025-05-23 07:03:14 -04:00 committed by Failure
parent 7a63f352c9
commit 535f932ee3
47 changed files with 332 additions and 544 deletions

View file

@ -1,31 +1,26 @@
package mage.cards.a;
import java.util.UUID;
import mage.constants.SubType;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.condition.common.DidNotAttackThisTurnEnchantedCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DestroyAttachedToEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.watchers.common.AttackedThisTurnWatcher;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class Aggression extends CardImpl {
@ -45,27 +40,25 @@ public final class Aggression extends CardImpl {
TargetPermanent auraTarget = new TargetPermanent(filter);
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget);
this.addAbility(ability);
this.addAbility(new EnchantAbility(auraTarget));
// Enchanted creature has first strike and trample.
Ability ability2 = new SimpleStaticAbility(
new GainAbilityAttachedEffect(
FirstStrikeAbility.getInstance(),
AttachmentType.AURA));
ability2.addEffect(new GainAbilityAttachedEffect(
TrampleAbility.getInstance(),
AttachmentType.AURA).setText("and trample"));
this.addAbility(ability2);
Ability ability = new SimpleStaticAbility(
new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA)
);
ability.addEffect(new GainAbilityAttachedEffect(
TrampleAbility.getInstance(), AttachmentType.AURA
).setText("and trample"));
this.addAbility(ability);
// At the beginning of the end step of enchanted creature's controller, destroy that creature if it didn't attack this turn.
this.addAbility(new ConditionalTriggeredAbility(
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new DestroyAttachedToEffect("enchanted"),
TargetController.CONTROLLER_ATTACHED_TO),
DidNotAttackThisTurnEnchantedCondition.instance,
"At the beginning of the end step of enchanted creature's controller, destroy that creature if it didn't attack this turn."));
this.addAbility(new BeginningOfEndStepTriggeredAbility(
TargetController.CONTROLLER_ATTACHED_TO,
new ConditionalOneShotEffect(
new DestroyAttachedToEffect(""), DidNotAttackThisTurnEnchantedCondition.instance,
"destroy that creature if it didn't attack this turn"
), false
));
}
private Aggression(final Aggression card) {

View file

@ -4,7 +4,6 @@ import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -12,7 +11,7 @@ import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterArtifactPermanent;
import java.util.UUID;
@ -22,22 +21,22 @@ import java.util.UUID;
public final class BrazenBlademaster extends CardImpl {
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
StaticFilters.FILTER_PERMANENT_ARTIFACT, ComparisonType.MORE_THAN, 1, true);
new FilterArtifactPermanent("you control two or more artifacts"),
ComparisonType.MORE_THAN, 1, true
);
public BrazenBlademaster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.ORC);
this.subtype.add(SubType.PIRATE);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Whenever Brazen Blademaster attacks while you control two or more artifacts, it gets +2/+1 until end of turn.
this.addAbility(new ConditionalTriggeredAbility(
new AttacksTriggeredAbility(new BoostSourceEffect(2, 1, Duration.EndOfTurn), false),
condition,
"Whenever {this} attacks while you control two or more artifacts, it gets +2/+1 until end of turn."
));
this.addAbility(new AttacksTriggeredAbility(
new BoostSourceEffect(2, 1, Duration.EndOfTurn, "it")
).withTriggerCondition(condition));
}
private BrazenBlademaster(final BrazenBlademaster card) {

View file

@ -4,7 +4,6 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.OpponentsTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect;
import mage.abilities.hint.common.OpponentsTurnHint;
@ -39,10 +38,9 @@ public final class BreathOfTheSleepless extends CardImpl {
));
// Whenever you cast a creature spell during an opponent's turn, tap up to one target creature.
Ability ability = new ConditionalTriggeredAbility(new SpellCastControllerTriggeredAbility(
Ability ability = new SpellCastControllerTriggeredAbility(
new TapTargetEffect(), StaticFilters.FILTER_SPELL_A_CREATURE, false
), OpponentsTurnCondition.instance, "Whenever you cast a creature spell " +
"during an opponent's turn, tap up to one target creature.");
).withTriggerCondition(OpponentsTurnCondition.instance);
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability.addHint(OpponentsTurnHint.instance));
}

View file

@ -3,7 +3,6 @@ package mage.cards.b;
import mage.MageInt;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.OpponentsTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.hint.common.OpponentsTurnHint;
import mage.abilities.keyword.FlashAbility;
@ -32,12 +31,9 @@ public final class BrinebornCutthroat extends CardImpl {
this.addAbility(FlashAbility.getInstance());
// Whenever you cast a spell during an opponent's turn, put a +1/+1 counter on Brineborn Cutthroat.
this.addAbility(new ConditionalTriggeredAbility(
new SpellCastControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false
), OpponentsTurnCondition.instance, "Whenever you cast a spell during an opponent's turn, " +
"put a +1/+1 counter on {this}."
).addHint(OpponentsTurnHint.instance));
this.addAbility(new SpellCastControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false
).withTriggerCondition(OpponentsTurnCondition.instance).addHint(OpponentsTurnHint.instance));
}
private BrinebornCutthroat(final BrinebornCutthroat card) {

View file

@ -4,8 +4,9 @@ import mage.MageInt;
import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.hint.Hint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -21,22 +22,22 @@ import java.util.UUID;
public final class BurningSunCavalry extends CardImpl {
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
new FilterControlledPermanent(SubType.DINOSAUR));
new FilterControlledPermanent(SubType.DINOSAUR, "you control a Dinosaur")
);
private static final Hint hint = new ConditionHint(condition, "You control a Dinosaur");
public BurningSunCavalry(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Burning Sun Cavalry attacks or blocks while you control a Dinosaur, Burning Sun Cavalry gets +1/+1 until end of turn.
this.addAbility(new ConditionalTriggeredAbility(
new AttacksOrBlocksTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), false),
condition,
"Whenever {this} attacks or blocks while you control a Dinosaur, {this} gets +1/+1 until end of turn."
));
this.addAbility(new AttacksOrBlocksTriggeredAbility(
new BoostSourceEffect(1, 1, Duration.EndOfTurn), false
).withTriggerCondition(condition).addHint(hint));
}
private BurningSunCavalry(final BurningSunCavalry card) {

View file

@ -1,25 +1,24 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.CaseAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.HellbentCondition;
import mage.abilities.condition.common.SolvedSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.abilities.effects.common.discard.DiscardHandControllerEffect;
import mage.abilities.hint.common.CaseSolvedHint;
import mage.constants.SubType;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* Case of the Crimson Pulse {2}{R}
* Enchantment - Case
@ -41,9 +40,8 @@ public final class CaseOfTheCrimsonPulse extends CardImpl {
initialAbility.addEffect(new DrawCardSourceControllerEffect(2).setText(", then draw two cards."));
// To solve -- You have no cards in hand.
// Solved -- At the beginning of your upkeep, discard your hand, then draw two cards.
Ability solvedAbility = new ConditionalTriggeredAbility(new BeginningOfUpkeepTriggeredAbility(
new DiscardHandControllerEffect()),
SolvedSourceCondition.SOLVED, null);
Ability solvedAbility = new BeginningOfUpkeepTriggeredAbility(new DiscardHandControllerEffect())
.withTriggerCondition(SolvedSourceCondition.SOLVED);
solvedAbility.addEffect(new DrawCardSourceControllerEffect(2).concatBy(", then"));
this.addAbility(new CaseAbility(initialAbility, HellbentCondition.instance, solvedAbility)

View file

@ -1,23 +1,18 @@
package mage.cards.c;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.CaseAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SolvedSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
import mage.abilities.hint.common.CaseSolvedHint;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.WatcherScope;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
@ -27,8 +22,11 @@ import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.watchers.Watcher;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
*
* @author DominionSpy
*/
public final class CaseOfTheRansackedLab extends CardImpl {
@ -51,10 +49,10 @@ public final class CaseOfTheRansackedLab extends CardImpl {
Ability initialAbility = new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1));
// To solve -- You've cast four or more instant and sorcery spells this turn.
// Solved -- Whenever you cast an instant or sorcery spell, draw a card.
Ability solvedAbility = new ConditionalTriggeredAbility(
new SpellCastControllerTriggeredAbility(new DrawCardSourceControllerEffect(1),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false),
SolvedSourceCondition.SOLVED, "");
Ability solvedAbility = new SpellCastControllerTriggeredAbility(
new DrawCardSourceControllerEffect(1),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
).withTriggerCondition(SolvedSourceCondition.SOLVED);
this.addAbility(new CaseAbility(initialAbility, CaseOfTheRansackedLabCondition.instance, solvedAbility)
.addHint(new CaseOfTheRansackedLabHint(CaseOfTheRansackedLabCondition.instance)),

View file

@ -1,33 +1,30 @@
package mage.cards.c;
import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.CaseAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SolvedSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.abilities.hint.common.CaseSolvedHint;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.constants.SubType;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
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.target.common.TargetCardInLibrary;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
*
* @author DominionSpy
*/
public final class CaseOfTheShatteredPact extends CardImpl {
@ -42,16 +39,14 @@ public final class CaseOfTheShatteredPact extends CardImpl {
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true));
// To solve -- There are five colors among permanents you control.
// Solved -- At the beginning of combat on your turn, target creature you control gains flying, double strike, and vigilance until end of turn.
TriggeredAbility triggeredAbility = new BeginningOfCombatTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance())
Ability solvedAbility = new BeginningOfCombatTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance())
.setText("target creature you control gains flying")
);
triggeredAbility.addEffect(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance())
).withTriggerCondition(SolvedSourceCondition.SOLVED);
solvedAbility.addEffect(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance())
.setText(", double strike,"));
triggeredAbility.addEffect(new GainAbilityTargetEffect(VigilanceAbility.getInstance())
solvedAbility.addEffect(new GainAbilityTargetEffect(VigilanceAbility.getInstance())
.setText("and vigilance until end of turn."));
triggeredAbility.addTarget(new TargetControlledCreaturePermanent());
Ability solvedAbility = new ConditionalTriggeredAbility(
triggeredAbility, SolvedSourceCondition.SOLVED, "");
solvedAbility.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(new CaseAbility(initialAbility, CaseOfTheShatteredPactCondition.instance, solvedAbility)
.addHint(new CaseOfTheShatteredPactHint(CaseOfTheShatteredPactCondition.instance)));

View file

@ -1,19 +1,21 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.CaseAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.CardsInControllerGraveyardCondition;
import mage.abilities.condition.common.SolvedSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.CopyTargetStackObjectEffect;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.abilities.hint.common.CaseSolvedHint;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SetTargetPointer;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureSpell;
import mage.filter.predicate.Predicates;
@ -42,9 +44,11 @@ public final class CaseOfTheShiftingVisage extends CardImpl {
// To solve There are fifteen or more cards in your graveyard.
Condition toSolveCondition = new CardsInControllerGraveyardCondition(15);
// Solved Whenever you cast a nonlegendary creature spell, copy that spell.
Ability solvedAbility = new ConditionalTriggeredAbility(new SpellCastControllerTriggeredAbility(
new CopyTargetStackObjectEffect(true).setText("copy that spell. <i>(The copy becomes a token.)</i>"), filter, false, SetTargetPointer.SPELL
), SolvedSourceCondition.SOLVED, null);
Ability solvedAbility = new SpellCastControllerTriggeredAbility(
new CopyTargetStackObjectEffect(true)
.setText("copy that spell. <i>(The copy becomes a token.)</i>"),
filter, false, SetTargetPointer.SPELL
).withTriggerCondition(SolvedSourceCondition.SOLVED);
this.addAbility(new CaseAbility(initialAbility, toSolveCondition, solvedAbility)
.addHint(new CaseOfTheShiftingVisageHint(toSolveCondition)));

View file

@ -1,7 +1,5 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
@ -10,16 +8,15 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.FormidableCondition;
import mage.abilities.condition.common.SolvedSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.effects.common.counter.DistributeCountersEffect;
import mage.abilities.hint.common.CaseSolvedHint;
import mage.abilities.keyword.TrampleAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
@ -28,8 +25,9 @@ import mage.game.permanent.Permanent;
import mage.target.common.TargetAttackingCreature;
import mage.target.common.TargetCreaturePermanentAmount;
import java.util.UUID;
/**
*
* @author DominionSpy
*/
public final class CaseOfTheTrampledGarden extends CardImpl {
@ -44,10 +42,9 @@ public final class CaseOfTheTrampledGarden extends CardImpl {
initialAbility.addTarget(new TargetCreaturePermanentAmount(2, StaticFilters.FILTER_CONTROLLED_CREATURES));
// To solve -- Creatures you control have total power 8 or greater.
// Solved -- Whenever you attack, put a +1/+1 counter on target attacking creature. It gains trample until end of turn.
Ability solvedAbility = new ConditionalTriggeredAbility(
new AttacksWithCreaturesTriggeredAbility(
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 1),
SolvedSourceCondition.SOLVED, "");
Ability solvedAbility = new AttacksWithCreaturesTriggeredAbility(
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 1
).withTriggerCondition(SolvedSourceCondition.SOLVED);
solvedAbility.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance())
.setText("it gains trample until end of turn"));
solvedAbility.addTarget(new TargetAttackingCreature());

View file

@ -4,9 +4,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.keyword.PartnerWithAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -33,11 +31,8 @@ public final class ChakramRetriever extends CardImpl {
this.addAbility(new PartnerWithAbility("Chakram Slinger"));
// Whenever you cast a spell during your turn, untap target creature.
Ability ability = new ConditionalTriggeredAbility(
new SpellCastControllerTriggeredAbility(new UntapTargetEffect(), false),
MyTurnCondition.instance,
"Whenever you cast a spell during your turn, untap target creature."
).addHint(MyTurnHint.instance);
Ability ability = new SpellCastControllerTriggeredAbility(new UntapTargetEffect(), false)
.withTriggerCondition(MyTurnCondition.instance);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}

View file

@ -2,11 +2,9 @@ package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.MonarchIsSourceControllerCondition;
import mage.abilities.costs.Cost;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.common.CardsInTargetPlayerHandCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
@ -14,6 +12,7 @@ import mage.abilities.effects.common.BecomesMonarchSourceEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.combat.TargetPlayerCantAttackYouEffect;
import mage.abilities.hint.common.MonarchHint;
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@ -40,16 +39,9 @@ public final class ChampionsOfMinasTirith extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new BecomesMonarchSourceEffect()).addHint(MonarchHint.instance));
// At the beginning of combat on each opponent's turn, if you're the monarch, that opponent may pay {X}, where X is the number of cards in their hand. If they don't, they can't attack you this combat.
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfCombatTriggeredAbility(
Zone.BATTLEFIELD,
TargetController.OPPONENT, new ChampionsOfMinasTirithEffect(),
false
),
MonarchIsSourceControllerCondition.instance,
"At the beginning of combat on each opponent's turn, if you're the monarch, that opponent may pay {X}, "
+ "where X is the number of cards in their hand. If they don't, they can't attack you this combat."
).addHint(MonarchHint.instance));
this.addAbility(new BeginningOfCombatTriggeredAbility(
TargetController.OPPONENT, new ChampionsOfMinasTirithEffect(), false
).withInterveningIf(MonarchIsSourceControllerCondition.instance).addHint(MonarchHint.instance));
}
private ChampionsOfMinasTirith(final ChampionsOfMinasTirith card) {
@ -66,6 +58,7 @@ class ChampionsOfMinasTirithEffect extends OneShotEffect {
ChampionsOfMinasTirithEffect() {
super(Outcome.Benefit);
staticText = "that opponent may pay {X}, where X is the number of cards in their hand. If they don't, they can't attack you this combat";
}
private ChampionsOfMinasTirithEffect(final ChampionsOfMinasTirithEffect effect) {

View file

@ -4,7 +4,6 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.common.FerociousCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.MenaceAbility;
@ -17,25 +16,24 @@ import mage.constants.SubType;
import java.util.UUID;
/**
*
* @author ciaccona007
*/
public final class CourageousGoblin extends CardImpl {
public CourageousGoblin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.GOBLIN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever this creature attacks while you control a creature with power 4 or greater, this creature gets +1/+0 and gains menace until end of turn.
Ability ability = new ConditionalTriggeredAbility(
new AttacksTriggeredAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), false),
FerociousCondition.instance,
"Whenever this creature attacks while you control a creature with power 4 or greater, this creature gets +1/+0 and gains menace until end of turn"
);
ability.addEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn));
Ability ability = new AttacksTriggeredAbility(
new BoostSourceEffect(1, 0, Duration.EndOfTurn).setText("{this} gets +1/+0"), false
).withTriggerCondition(FerociousCondition.instance);
ability.addEffect(new GainAbilitySourceEffect(
new MenaceAbility(false), Duration.EndOfTurn
).setText("and gains menace until end of turn"));
this.addAbility(ability);
}

View file

@ -4,7 +4,6 @@ import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.IsMainPhaseCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.ReturnToHandSourceEffect;
@ -20,7 +19,7 @@ import java.util.UUID;
*/
public final class DovinsAcuity extends CardImpl {
private static final FilterSpell filter = new FilterSpell();
private static final FilterSpell filter = new FilterSpell("an instant spell");
static {
filter.add(CardType.INSTANT.getPredicate());
@ -35,13 +34,9 @@ public final class DovinsAcuity extends CardImpl {
this.addAbility(ability);
// Whenever you cast an instant spell during your main phase, you may return Dovin's Acuity to its owner's hand.
this.addAbility(new ConditionalTriggeredAbility(
new SpellCastControllerTriggeredAbility(
new ReturnToHandSourceEffect(true), filter, true
), IsMainPhaseCondition.YOUR,
"Whenever you cast an instant spell during your main phase, " +
"you may return {this} to its owner's hand."
));
this.addAbility(new SpellCastControllerTriggeredAbility(
new ReturnToHandSourceEffect(true), filter, true
).withTriggerCondition(IsMainPhaseCondition.YOUR).setTriggerPhrase("Whenever you cast an instant spell during your main phase, "));
}
private DovinsAcuity(final DovinsAcuity card) {
@ -52,4 +47,4 @@ public final class DovinsAcuity extends CardImpl {
public DovinsAcuity copy() {
return new DovinsAcuity(this);
}
}
}

View file

@ -3,8 +3,7 @@ package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.OnOpponentsTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.condition.common.OpponentsTurnCondition;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@ -31,14 +30,11 @@ public final class DreamSpoilers extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast a spell during an opponent's turn, up to one target creature an opponent controls gets -1/-1 until end of turn.
Ability ability = new ConditionalTriggeredAbility(
new SpellCastControllerTriggeredAbility(
new BoostTargetEffect(-1, -1, Duration.EndOfTurn), false
), OnOpponentsTurnCondition.instance, "Whenever you cast a spell during an opponent's "
+ "turn, up to one target creature an opponent controls gets -1/-1 until end of turn."
);
Ability ability = new SpellCastControllerTriggeredAbility(
new BoostTargetEffect(-1, -1, Duration.EndOfTurn), false
).withTriggerCondition(OpponentsTurnCondition.instance);
ability.addTarget(new TargetOpponentsCreaturePermanent(0, 1));
this.addAbility(ability);
}
@ -51,4 +47,4 @@ public final class DreamSpoilers extends CardImpl {
public DreamSpoilers copy() {
return new DreamSpoilers(this);
}
}
}

View file

@ -1,11 +1,9 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.OnOpponentsTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.condition.common.OpponentsTurnCondition;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@ -18,13 +16,12 @@ import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class DreamspoilerWitches extends CardImpl {
public DreamspoilerWitches(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.FAERIE);
this.subtype.add(SubType.WIZARD);
@ -33,9 +30,11 @@ public final class DreamspoilerWitches extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast a spell during an opponent's turn, you may have target creature get -1/-1 until end of turn.
Ability ability = new ConditionalTriggeredAbility(new SpellCastControllerTriggeredAbility(new BoostTargetEffect(-1, -1, Duration.EndOfTurn), true), OnOpponentsTurnCondition.instance,
"Whenever you cast a spell during an opponent's turn, you may have target creature get -1/-1 until end of turn.");
Ability ability = new SpellCastControllerTriggeredAbility(
new BoostTargetEffect(-1, -1, Duration.EndOfTurn), true
).withTriggerCondition(OpponentsTurnCondition.instance);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}

View file

@ -3,17 +3,16 @@ package mage.cards.e;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.costs.Cost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.common.GetXValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseOpponentEffect;
import mage.abilities.effects.common.RemoveAllCountersSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@ -43,12 +42,10 @@ public final class EnergyVortex extends CardImpl {
));
// At the beginning of the chosen player's upkeep, Energy Vortex deals 3 damage to that player unless they pay {1} for each vortex counter on Energy Vortex.
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(
TargetController.ANY, new EnergyVortexEffect(), false
), EnergyVortexCondition.instance, "At the beginning of the chosen player's upkeep, " +
"{this} deals 3 damage to that player unless they pay {1} for each vortex counter on {this}."
));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
TargetController.ANY, new EnergyVortexEffect(), false
).withTriggerCondition(EnergyVortexCondition.instance)
.setTriggerPhrase("At the beginning of the chosen player's upkeep, "));
// {X}: Put X vortex counters on Energy Vortex. Activate this ability only during your upkeep.
this.addAbility(new ActivateIfConditionActivatedAbility(
@ -78,12 +75,18 @@ enum EnergyVortexCondition implements Condition {
public boolean apply(Game game, Ability source) {
return game.getActivePlayerId().equals(game.getState().getValue(source.getSourceId().toString() + ChooseOpponentEffect.VALUE_KEY));
}
@Override
public String toString() {
return "";
}
}
class EnergyVortexEffect extends OneShotEffect {
EnergyVortexEffect() {
super(Outcome.Benefit);
staticText = "{this} deals 3 damage to that player unless they pay {1} for each vortex counter on {this}";
}
private EnergyVortexEffect(final EnergyVortexEffect effect) {
@ -104,9 +107,7 @@ class EnergyVortexEffect extends OneShotEffect {
}
int counters = permanent.getCounters(game).getCount(CounterType.VORTEX);
Cost cost = ManaUtil.createManaCost(counters, false);
if (cost.pay(source, game, source, player.getId(), false)) {
return true;
}
return player.damage(3, source.getSourceId(), source, game) > 0;
return cost.pay(source, game, source, player.getId(), false)
|| player.damage(3, source.getSourceId(), source, game) > 0;
}
}

View file

@ -3,9 +3,7 @@ package mage.cards.e;
import mage.ObjectColor;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.hint.common.MyTurnHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -32,11 +30,9 @@ public final class EyesOfTheWisent extends CardImpl {
this.subtype.add(SubType.ELEMENTAL);
// Whenever an opponent casts a blue spell during your turn, you may create a 4/4 green Elemental creature token.
this.addAbility(new ConditionalTriggeredAbility(
new SpellCastOpponentTriggeredAbility(new CreateTokenEffect(new Elemental44GreenToken()), filter, true),
MyTurnCondition.instance,
"Whenever an opponent casts a blue spell during your turn, you may create a 4/4 green Elemental creature token."
).addHint(MyTurnHint.instance));
this.addAbility(new SpellCastOpponentTriggeredAbility(
new CreateTokenEffect(new Elemental44GreenToken()), filter, true
).withTriggerCondition(MyTurnCondition.instance));
}
private EyesOfTheWisent(final EyesOfTheWisent card) {

View file

@ -1,9 +1,7 @@
package mage.cards.f;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.OnOpponentsTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.condition.common.OpponentsTurnCondition;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -13,19 +11,18 @@ import mage.constants.SubType;
import java.util.UUID;
/**
*
* @author Styxo
*/
public final class FaerieTauntings extends CardImpl {
public FaerieTauntings(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.KINDRED,CardType.ENCHANTMENT},"{2}{B}");
super(ownerId, setInfo, new CardType[]{CardType.KINDRED, CardType.ENCHANTMENT}, "{2}{B}");
this.subtype.add(SubType.FAERIE);
// Whenever you cast a spell during an opponent's turn, you may have each opponent lose 1 life
this.addAbility(new ConditionalTriggeredAbility(new SpellCastControllerTriggeredAbility(new LoseLifeOpponentsEffect(1), true), OnOpponentsTurnCondition.instance,
"Whenever you cast a spell during an opponent's turn, you may have each opponent lose 1 life."));
this.addAbility(new SpellCastControllerTriggeredAbility(
new LoseLifeOpponentsEffect(1), true
).withTriggerCondition(OpponentsTurnCondition.instance));
}
private FaerieTauntings(final FaerieTauntings card) {
@ -36,4 +33,4 @@ public final class FaerieTauntings extends CardImpl {
public FaerieTauntings copy() {
return new FaerieTauntings(this);
}
}
}

View file

@ -1,11 +1,9 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.OnOpponentsTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.condition.common.OpponentsTurnCondition;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@ -17,7 +15,6 @@ import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
*
* @author Markedagain
*/
public final class GlenElendraPranksters extends CardImpl {
@ -31,11 +28,11 @@ public final class GlenElendraPranksters extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast a spell during an opponent's turn, you may return target creature you control to its owner's hand.
Ability ability = new ConditionalTriggeredAbility(
new SpellCastControllerTriggeredAbility(new ReturnToHandTargetEffect(), true), OnOpponentsTurnCondition.instance,
"Whenever you cast a spell during an opponent's turn, you may return target creature you control to its owner's hand."
);
Ability ability = new SpellCastControllerTriggeredAbility(
new ReturnToHandTargetEffect(), true
).withTriggerCondition(OpponentsTurnCondition.instance);
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}

View file

@ -4,7 +4,6 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.common.DeliriumCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
@ -31,12 +30,12 @@ public final class HandThatFeeds extends CardImpl {
this.toughness = new MageInt(2);
// Delirium -- Whenever Hand That Feeds attacks while there are four or more card types among cards in your graveyard, it gets +2/+0 and gains menace until end of turn.
Ability ability = new ConditionalTriggeredAbility(
new AttacksTriggeredAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn)),
DeliriumCondition.instance, "Whenever {this} attacks while there are four or more " +
"card types among cards in your graveyard, it gets +2/+0 and gains menace until end of turn."
);
ability.addEffect(new GainAbilitySourceEffect(new MenaceAbility(false), Duration.EndOfTurn));
Ability ability = new AttacksTriggeredAbility(
new BoostSourceEffect(2, 0, Duration.EndOfTurn).setText("it gets +2/+0")
).withTriggerCondition(DeliriumCondition.instance);
ability.addEffect(new GainAbilitySourceEffect(
new MenaceAbility(false), Duration.EndOfTurn
).setText("and gains menace until end of turn"));
this.addAbility(ability.setAbilityWord(AbilityWord.DELIRIUM).addHint(CardTypesInGraveyardCount.YOU.getHint()));
}

View file

@ -4,9 +4,7 @@ import mage.MageInt;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.common.WerewolfFrontTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -31,11 +29,9 @@ public final class HermitOfTheNatterknolls extends CardImpl {
this.secondSideCardClazz = mage.cards.l.LoneWolfOfTheNatterknolls.class;
// Whenever an opponent casts a spell during your turn, draw a card.
this.addAbility(new ConditionalTriggeredAbility(
new SpellCastOpponentTriggeredAbility(new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_SPELL_A, false),
MyTurnCondition.instance,
"Whenever an opponent casts a spell during your turn, draw a card."
).addHint(MyTurnHint.instance));
this.addAbility(new SpellCastOpponentTriggeredAbility(
new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_SPELL_A, false
).withTriggerCondition(MyTurnCondition.instance));
// At the beginning of each upkeep, if no spells were cast last turn, transform Hermit of the Natterknolls.
this.addAbility(new TransformAbility());

View file

@ -1,25 +1,23 @@
package mage.cards.i;
import java.util.UUID;
import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.condition.common.DidNotAttackThisTurnEnchantedCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DamageAttachedControllerEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.watchers.common.AttackedThisTurnWatcher;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class Insubordination extends CardImpl {
@ -33,16 +31,16 @@ public final class Insubordination extends CardImpl {
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(auraTarget);
this.addAbility(ability);
this.addAbility(new EnchantAbility(auraTarget));
// At the beginning of the end step of enchanted creature's controller, Insubordination deals 2 damage to that player unless that creature attacked this turn.
this.addAbility(new ConditionalTriggeredAbility(
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new DamageAttachedControllerEffect(2),
TargetController.CONTROLLER_ATTACHED_TO),
DidNotAttackThisTurnEnchantedCondition.instance,
"At the beginning of the end step of enchanted creature's controller, {this} deals 2 damage to that player unless that creature attacked this turn."));
this.addAbility(new BeginningOfEndStepTriggeredAbility(
TargetController.CONTROLLER_ATTACHED_TO,
new ConditionalOneShotEffect(
new DamageAttachedControllerEffect(2), DidNotAttackThisTurnEnchantedCondition.instance,
"{this} deals 2 damage to that player unless that creature attacked this turn"
), false
).setTriggerPhrase("At the beginning of the end step of enchanted creature's controller, "));
}
private Insubordination(final Insubordination card) {

View file

@ -5,7 +5,6 @@ import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.SourceHasCountersCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
@ -38,10 +37,9 @@ public final class IronApprentice extends CardImpl {
), "with a +1/+1 counter on it"));
// When Iron Apprentice dies, if it had counters on it, put those counters on target creature you control.
Ability ability = new ConditionalTriggeredAbility(
new DiesSourceTriggeredAbility(new IronApprenticeEffect()), SourceHasCountersCondition.instance,
"When {this} dies, if it had counters on it, put those counters on target creature you control."
);
Ability ability = new DiesSourceTriggeredAbility(new IronApprenticeEffect())
.withTriggerCondition(SourceHasCountersCondition.instance)
.setTriggerPhrase("When {this} dies, if it had counters on it, ");
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}

View file

@ -5,7 +5,6 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue;
import mage.abilities.effects.Effect;
@ -55,9 +54,10 @@ public final class JenovaAncientCalamity extends CardImpl {
this.addAbility(ability);
// Whenever a Mutant you control dies during your turn, draw cards equal to its power.
this.addAbility(new ConditionalTriggeredAbility(new DiesCreatureTriggeredAbility(
new DrawCardSourceControllerEffect(JenovaAncientCalamityValue.instance), false, filter
), MyTurnCondition.instance, "Whenever a Mutant you control dies during your turn, draw cards equal to its power."));
this.addAbility(new DiesCreatureTriggeredAbility(
new DrawCardSourceControllerEffect(JenovaAncientCalamityValue.instance)
.setText("draw cards equal to its power"), false, filter
).withTriggerCondition(MyTurnCondition.instance));
}
private JenovaAncientCalamity(final JenovaAncientCalamity card) {

View file

@ -3,7 +3,6 @@ package mage.cards.k;
import mage.MageInt;
import mage.abilities.common.LoseLifeTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.common.SavedLifeLossValue;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.FlyingAbility;
@ -38,10 +37,10 @@ public final class KefkaRulerOfRuin extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever an opponent loses life during your turn, you draw that many cards.
this.addAbility(new ConditionalTriggeredAbility(new LoseLifeTriggeredAbility(
new DrawCardSourceControllerEffect(SavedLifeLossValue.MANY),
this.addAbility(new LoseLifeTriggeredAbility(
new DrawCardSourceControllerEffect(SavedLifeLossValue.MANY, true),
TargetController.OPPONENT, false, false
), MyTurnCondition.instance, "Whenever an opponent loses life during your turn, you draw that many cards."));
).withTriggerCondition(MyTurnCondition.instance));
}
private KefkaRulerOfRuin(final KefkaRulerOfRuin card) {

View file

@ -4,9 +4,7 @@ import mage.MageInt;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.common.WerewolfBackTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.hint.common.MyTurnHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -30,11 +28,9 @@ public final class LoneWolfOfTheNatterknolls extends CardImpl {
this.nightCard = true;
// Whenever an opponent cast a spell during your turn, draw two cards.
this.addAbility(new ConditionalTriggeredAbility(
new SpellCastOpponentTriggeredAbility(new DrawCardSourceControllerEffect(2), StaticFilters.FILTER_SPELL_A, false),
MyTurnCondition.instance,
"Whenever an opponent casts a spell during your turn, draw two cards."
).addHint(MyTurnHint.instance));
this.addAbility(new SpellCastOpponentTriggeredAbility(
new DrawCardSourceControllerEffect(2), StaticFilters.FILTER_SPELL_A, false
).withTriggerCondition(MyTurnCondition.instance));
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Lone Wolf of the Natterknolls.
this.addAbility(new WerewolfBackTriggeredAbility());

View file

@ -1,11 +1,9 @@
package mage.cards.m;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.combat.ReselectDefenderAttackedByTargetEffect;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.mana.BlueManaAbility;
@ -15,26 +13,25 @@ import mage.constants.CardType;
import mage.constants.PhaseStep;
import mage.target.common.TargetAttackingCreature;
import java.util.UUID;
/**
*
* @author Xanderhall
*/
public final class MisleadingSignpost extends CardImpl {
private static final Condition condition = new IsStepCondition(PhaseStep.DECLARE_ATTACKERS, false);
public MisleadingSignpost(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}");
// Flash
this.addAbility(FlashAbility.getInstance());
// When Misleading Signpost enters the battlefield during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking.
Ability ability = new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new ReselectDefenderAttackedByTargetEffect(true), true),
new IsStepCondition(PhaseStep.DECLARE_ATTACKERS, false),
"When {this} enters during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. "
+ "<i>(It can't attack its controller or their permanents)</i>");
Ability ability = new EntersBattlefieldTriggeredAbility(
new ReselectDefenderAttackedByTargetEffect(true), true
).withTriggerCondition(condition);
ability.addTarget(new TargetAttackingCreature());
this.addAbility(ability);

View file

@ -1,34 +1,29 @@
package mage.cards.n;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.WinGameSourceControllerEffect;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class NowIKnowMyABCs extends CardImpl {
public NowIKnowMyABCs(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{U}");
// At the beginning of your upkeep, if you control permanents with names that include all twenty-six letters of the English alphabet, you win the game.
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(new WinGameSourceControllerEffect()),
new NowIKnowMyABCsCondition(),
"At the beginning of your upkeep, if you control permanents with names that include all twenty-six letters of the English alphabet, you win the game."));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new WinGameSourceControllerEffect()).withInterveningIf(NowIKnowMyABCsCondition.instance));
}
private NowIKnowMyABCs(final NowIKnowMyABCs card) {
@ -41,10 +36,8 @@ public final class NowIKnowMyABCs extends CardImpl {
}
}
class NowIKnowMyABCsCondition implements Condition {
public NowIKnowMyABCsCondition() {
}
enum NowIKnowMyABCsCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {

View file

@ -3,7 +3,6 @@ package mage.cards.p;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.common.FerociousCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.counter.DistributeCountersEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
@ -31,11 +30,9 @@ public final class PicnicRuiner extends AdventureCard {
this.toughness = new MageInt(2);
// Whenever Picnic Ruiner attacks while you control a creature with power 4 or greater, Picnic Ruiner gains double strike until end of turn.
this.addAbility(new ConditionalTriggeredAbility(
new AttacksTriggeredAbility(new GainAbilitySourceEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn), false),
FerociousCondition.instance,
"Whenever {this} attacks while you control a creature with power 4 or greater, {this} gains double strike until end of turn."
));
this.addAbility(new AttacksTriggeredAbility(
new GainAbilitySourceEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn), false
).withTriggerCondition(FerociousCondition.instance));
// Stolen Goodies
// Distribute three +1/+1 counters among any number of target creatures you control.

View file

@ -3,8 +3,8 @@ package mage.cards.p;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.combat.ReselectDefenderAttackedByTargetEffect;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
@ -21,6 +21,8 @@ import java.util.UUID;
*/
public final class PortalMage extends CardImpl {
private static final Condition condition = new IsStepCondition(PhaseStep.DECLARE_ATTACKERS, false);
public PortalMage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
@ -33,11 +35,9 @@ public final class PortalMage extends CardImpl {
this.addAbility(FlashAbility.getInstance());
// When Portal Mage enters the battlefield during the declare attackers step, you may reselect which player or planeswalker target attacking creature is attacking.
Ability ability = new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new ReselectDefenderAttackedByTargetEffect(true), true),
new IsStepCondition(PhaseStep.DECLARE_ATTACKERS, false),
"When {this} enters during the declare attackers step, you may reselect which player or permanent target attacking creature is attacking. "
+ "<i>(It can't attack its controller or their permanents)</i>");
Ability ability = new EntersBattlefieldTriggeredAbility(
new ReselectDefenderAttackedByTargetEffect(true), true
).withTriggerCondition(condition);
ability.addTarget(new TargetAttackingCreature());
this.addAbility(ability);
}

View file

@ -4,7 +4,6 @@ import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -23,7 +22,7 @@ import java.util.UUID;
*/
public final class PugnaciousHammerskull extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.DINOSAUR);
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.DINOSAUR, "you don't control another Dinosaur");
static {
filter.add(AnotherPredicate.instance);
@ -40,10 +39,9 @@ public final class PugnaciousHammerskull extends CardImpl {
this.toughness = new MageInt(6);
// Whenever Pugnacious Hammerskull attacks while you don't control another Dinosaur, put a stun counter on it.
this.addAbility(new ConditionalTriggeredAbility(
new AttacksTriggeredAbility(new AddCountersSourceEffect(CounterType.STUN.createInstance())), condition,
"Whenever {this} attacks while you don't control another Dinosaur, put a stun counter on it."
));
this.addAbility(new AttacksTriggeredAbility(
new AddCountersSourceEffect(CounterType.STUN.createInstance()).setText("put a stun counter on it")
).withTriggerCondition(condition));
}
private PugnaciousHammerskull(final PugnaciousHammerskull card) {

View file

@ -11,7 +11,6 @@ import mage.abilities.costs.Costs;
import mage.abilities.costs.CostsImpl;
import mage.abilities.costs.common.RemoveCounterCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
@ -44,11 +43,10 @@ public final class QuilledGreatwurm extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// Whenever a creature you control deals combat damage during your turn, put that many +1/+1 counters on it.
this.addAbility(new ConditionalTriggeredAbility(new DealsDamageToAnyTriggeredAbility(
Zone.BATTLEFIELD, new AddCountersTargetEffect(
CounterType.P1P1.createInstance(), SavedDamageValue.MANY
), StaticFilters.FILTER_CONTROLLED_A_CREATURE, SetTargetPointer.PERMANENT, true, false
), MyTurnCondition.instance, "Whenever a creature you control deals combat damage during your turn, put that many +1/+1 counters on it"));
this.addAbility(new DealsDamageToAnyTriggeredAbility(
Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance(), SavedDamageValue.MANY),
StaticFilters.FILTER_CONTROLLED_A_CREATURE, SetTargetPointer.PERMANENT, true, false
).withTriggerCondition(MyTurnCondition.instance));
// You may cast this card from your graveyard by removing six counters from among creatures you control in addition to paying its other costs.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new QuilledGreatwurmEffect()).setIdentifier(MageIdentifier.QuilledGreatwurmAlternateCast));

View file

@ -3,7 +3,6 @@ package mage.cards.r;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.common.FerociousCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.mana.GreenManaAbility;
@ -35,11 +34,9 @@ public final class RubyDaringTracker extends CardImpl {
this.addAbility(HasteAbility.getInstance());
// Whenever Ruby, Daring Tracker attacks while you control a creature with power 4 or greater, Ruby gets +2/+2 until end of turn.
this.addAbility(new ConditionalTriggeredAbility(
new AttacksTriggeredAbility(new BoostSourceEffect(2, 2, Duration.EndOfTurn), false),
FerociousCondition.instance,
"Whenever {this} attacks while you control a creature with power 4 or greater, {this} gets +2/+2 until end of turn."
));
this.addAbility(new AttacksTriggeredAbility(
new BoostSourceEffect(2, 2, Duration.EndOfTurn), false
).withTriggerCondition(FerociousCondition.instance));
// {T}: Add {R} or {G}.
this.addAbility(new RedManaAbility());

View file

@ -4,7 +4,6 @@ import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.hint.ConditionHint;
import mage.abilities.hint.Hint;
@ -13,7 +12,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TokenPredicate;
import java.util.UUID;
@ -22,8 +23,13 @@ import java.util.UUID;
*/
public final class SeasonedWarrenguard extends CardImpl {
private static final Condition condition
= new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_CREATURE_TOKEN, true);
private static final FilterPermanent filter = new FilterControlledPermanent("you control a token");
static {
filter.add(TokenPredicate.TRUE);
}
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, true);
private static final Hint hint = new ConditionHint(condition, "You control a token");
public SeasonedWarrenguard(UUID ownerId, CardSetInfo setInfo) {
@ -35,10 +41,9 @@ public final class SeasonedWarrenguard extends CardImpl {
this.toughness = new MageInt(2);
// Whenever Seasoned Warrenguard attacks while you control a token, Seasoned Warrenguard gets +2/+0 until end of turn.
this.addAbility(new ConditionalTriggeredAbility(
new AttacksTriggeredAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn)),
condition, "Whenever {this} attacks while you control a token, {this} gets +2/+0 until end of turn"
).addHint(hint));
this.addAbility(new AttacksTriggeredAbility(
new BoostSourceEffect(2, 0, Duration.EndOfTurn)
).withTriggerCondition(condition).addHint(hint));
}
private SeasonedWarrenguard(final SeasonedWarrenguard card) {

View file

@ -8,7 +8,6 @@ import mage.abilities.condition.Condition;
import mage.abilities.condition.common.AttachedToMatchesFilterCondition;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.common.SavedDamageValue;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.common.AttachEffect;
@ -35,7 +34,6 @@ import java.util.UUID;
public final class TheAetherspark extends CardImpl {
private static final Condition condition = new AttachedToMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_CREATURE);
private static final String rule = "Whenever equipped creature deals combat damage during your turn, put that many loyalty counters on {this}.";
public TheAetherspark(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.PLANESWALKER}, "{4}");
@ -47,12 +45,10 @@ public final class TheAetherspark extends CardImpl {
// As long as The Aetherspark is attached to a creature, The Aetherspark can't be attacked and has "Whenever equipped creature deals combat damage during your turn, put that many loyalty counters on The Aetherspark."
Ability ability = new SimpleStaticAbility(new TheAethersparkEffect());
ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(
new ConditionalTriggeredAbility(
new DealsCombatDamageEquippedTriggeredAbility(new AddCountersSourceEffect(
CounterType.LOYALTY.createInstance(0), SavedDamageValue.MANY
)), MyTurnCondition.instance, rule
)
), condition, "and has \"" + rule + "\""));
new DealsCombatDamageEquippedTriggeredAbility(new AddCountersSourceEffect(
CounterType.LOYALTY.createInstance(0), SavedDamageValue.MANY
)).withTriggerCondition(MyTurnCondition.instance)
), condition, "and has \"Whenever equipped creature deals combat damage during your turn, put that many loyalty counters on {this}.\""));
this.addAbility(ability);
// +1: Attach The Aetherspark to up to one target creature you control. Put a +1/+1 counter on that creature.

View file

@ -2,9 +2,8 @@ package mage.cards.t;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.InspiredAbility;
@ -22,6 +21,8 @@ import java.util.UUID;
*/
public final class TheNinthDoctor extends CardImpl {
private static final Condition condition = new IsStepCondition(PhaseStep.UNTAP);
public TheNinthDoctor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{R}");
this.supertype.add(SuperType.LEGENDARY);
@ -33,9 +34,9 @@ public final class TheNinthDoctor extends CardImpl {
this.addAbility(HasteAbility.getInstance());
// Into the TARDIS Whenever The Ninth Doctor becomes untapped during your untap step, you get an additional upkeep step after this step.
TriggeredAbilityImpl ability = new InspiredAbility(new TheNinthDoctorEffect(), false, false).setTriggerPhrase("Whenever {this} becomes untapped during your untap step, ");
ability.withFlavorWord("Into the TARDIS");
this.addAbility(new ConditionalTriggeredAbility(ability, new IsStepCondition(PhaseStep.UNTAP), ""));
this.addAbility(new InspiredAbility(new TheNinthDoctorEffect(), false, false)
.withTriggerCondition(condition)
.withFlavorWord("Into the TARDIS"));
}
private TheNinthDoctor(final TheNinthDoctor card) {

View file

@ -6,7 +6,6 @@ import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.common.DrawCardControllerTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.OpponentsTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.effects.common.UntapTargetEffect;
@ -52,12 +51,9 @@ public final class TheWatcherInTheWater extends CardImpl {
this.addAbility(ability);
// Whenever you draw a card during an opponent's turn, create a 1/1 blue Tentacle creature token.
this.addAbility(new ConditionalTriggeredAbility(
new DrawCardControllerTriggeredAbility(
new CreateTokenEffect(new TentacleToken()), false
), OpponentsTurnCondition.instance, "Whenever you draw a card " +
"during an opponent's turn, create a 1/1 blue Tentacle creature token."
));
this.addAbility(new DrawCardControllerTriggeredAbility(
new CreateTokenEffect(new TentacleToken()), false
).withTriggerCondition(OpponentsTurnCondition.instance));
// Whenever a Tentacle you control dies, untap up to one target Kraken and put a stun counter on up to one target nonland permanent.
ability = new DiesCreatureTriggeredAbility(new UntapTargetEffect(), false, filter);

View file

@ -4,7 +4,6 @@ import mage.MageInt;
import mage.abilities.common.GainLifeControllerTriggeredAbility;
import mage.abilities.common.LoseLifeTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@ -12,8 +11,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
@ -34,13 +31,14 @@ public final class VampireScrivener extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever you gain life during your turn, put a +1/+1 counter on Vampire Scrivener.
this.addAbility(new ConditionalTriggeredAbility(new GainLifeControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance())), MyTurnCondition.instance,
"Whenever you gain life during your turn, put a +1/+1 counter on {this}."
));
this.addAbility(new GainLifeControllerTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance())
).withTriggerCondition(MyTurnCondition.instance));
// Whenever you lose life during your turn, put a +1/+1 counter on Vampire Scrivener.
this.addAbility(new VampireScrivenerTriggeredAbility());
this.addAbility(new LoseLifeTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance())
).withTriggerCondition(MyTurnCondition.instance));
}
private VampireScrivener(final VampireScrivener card) {
@ -52,26 +50,3 @@ public final class VampireScrivener extends CardImpl {
return new VampireScrivener(this);
}
}
class VampireScrivenerTriggeredAbility extends LoseLifeTriggeredAbility {
VampireScrivenerTriggeredAbility() {
super(new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
setTriggerPhrase("Whenever you lose life during your turn, ");
}
private VampireScrivenerTriggeredAbility(final VampireScrivenerTriggeredAbility ability) {
super(ability);
}
@Override
public VampireScrivenerTriggeredAbility copy() {
return new VampireScrivenerTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return game.isActivePlayer(getControllerId()) && super.checkTrigger(event, game);
}
}

View file

@ -4,11 +4,9 @@ import mage.MageInt;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.common.CountersSourceCount;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -35,10 +33,9 @@ public final class VogarNecropolisTyrant extends CardImpl {
this.addAbility(new MenaceAbility(false));
// Whenever another creature dies during your turn, put a +1/+1 counter on Vogar, Necropolis Tyrant.
this.addAbility(new ConditionalTriggeredAbility(
new DiesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, true),
MyTurnCondition.instance, "Whenever another creature dies during your turn, put a +1/+1 counter on {this}."
).addHint(MyTurnHint.instance));
this.addAbility(new DiesCreatureTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, true
).withTriggerCondition(MyTurnCondition.instance));
// When Vogar dies, draw a card for each +1/+1 counter on it.
this.addAbility(new DiesSourceTriggeredAbility(

View file

@ -4,7 +4,6 @@ import mage.MageInt;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.hint.common.CreaturesYouControlHint;
import mage.abilities.hint.common.MyTurnHint;
@ -14,7 +13,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
import mage.game.permanent.token.VoiceOfResurgenceToken;
@ -33,17 +31,14 @@ public final class VoiceOfResurgence extends CardImpl {
this.toughness = new MageInt(2);
// Whenever an opponent casts a spell during your turn or when Voice of Resurgence dies, create a green and white Elemental creature token with "This creature's power and toughness are each equal to the number of creatures you control."
OrTriggeredAbility ability = new OrTriggeredAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new VoiceOfResurgenceToken()),
new ConditionalTriggeredAbility(
new SpellCastOpponentTriggeredAbility(null, StaticFilters.FILTER_SPELL_A, false),
MyTurnCondition.instance,
"Whenever an opponent casts a spell during your turn, "),
new DiesSourceTriggeredAbility(null, false));
OrTriggeredAbility ability = new OrTriggeredAbility(
Zone.BATTLEFIELD, new CreateTokenEffect(new VoiceOfResurgenceToken()),
new SpellCastOpponentTriggeredAbility(null, StaticFilters.FILTER_SPELL_A, false)
.withTriggerCondition(MyTurnCondition.instance),
new DiesSourceTriggeredAbility(null, false)
);
ability.setLeavesTheBattlefieldTrigger(true);
ability.addHint(MyTurnHint.instance);
ability.addHint(CreaturesYouControlHint.instance);
this.addAbility(ability);
this.addAbility(ability.addHint(MyTurnHint.instance).addHint(CreaturesYouControlHint.instance));
}
private VoiceOfResurgence(final VoiceOfResurgence card) {
@ -56,4 +51,3 @@ public final class VoiceOfResurgence extends CardImpl {
}
}

View file

@ -66,10 +66,35 @@ public interface TriggeredAbility extends Ability {
*/
TriggeredAbility withRuleTextReplacement(boolean replaceRuleText);
/**
* 603.4. A triggered ability may read "When/Whenever/At [trigger event], if [condition], [effect]."
* When the trigger event occurs, the ability checks whether the stated condition is true.
* The ability triggers only if it is; otherwise it does nothing. If the ability triggers,
* it checks the stated condition again as it resolves. If the condition isn't true at that time,
* the ability is removed from the stack and does nothing. Note that this mirrors the check for legal targets.
* This rule is referred to as the "intervening 'if' clause" rule.
* (The word "if" has only its normal English meaning anywhere else in the text of a card;
* this rule only applies to an "if" that immediately follows a trigger condition.)
*
* @param condition the condition to be checked
* @return
*/
TriggeredAbility withInterveningIf(Condition condition);
boolean checkInterveningIfClause(Game game);
/**
* Unlike intervening if, this is for a condition that's checked only on trigger and not also on resolution.
*
* @param condition the condition to be checked
* @return
*/
TriggeredAbility withTriggerCondition(Condition condition);
Condition getTriggerCondition();
boolean checkTriggerCondition(Game game);
boolean isOptional();
TriggeredAbility setOptional();

View file

@ -27,6 +27,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
private boolean optional;
private Condition interveningIfCondition;
private Condition triggerCondition;
private boolean leavesTheBattlefieldTrigger;
private int triggerLimitEachTurn = Integer.MAX_VALUE; // for "triggers only once|twice each turn"
private int triggerLimitEachGame = Integer.MAX_VALUE; // for "triggers only once|twice"
@ -57,6 +58,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
super(ability);
this.optional = ability.optional;
this.interveningIfCondition = ability.interveningIfCondition;
this.triggerCondition = ability.triggerCondition;
this.leavesTheBattlefieldTrigger = ability.leavesTheBattlefieldTrigger;
this.triggerLimitEachTurn = ability.triggerLimitEachTurn;
this.triggerLimitEachGame = ability.triggerLimitEachGame;
@ -69,7 +71,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
@Override
public void trigger(Game game, UUID controllerId, GameEvent triggeringEvent) {
//20091005 - 603.4
if (checkInterveningIfClause(game)) {
if (checkInterveningIfClause(game) && checkTriggerCondition(game)) {
updateTurnCount(game);
updateGameCount(game);
game.addTriggeredAbility(this, triggeringEvent);
@ -228,6 +230,28 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
return interveningIfCondition == null || interveningIfCondition.apply(game, this);
}
@Override
public TriggeredAbility withTriggerCondition(Condition condition) {
this.triggerCondition = condition;
if (this.triggerPhrase != null && !condition.toString().isEmpty()) {
this.setTriggerPhrase(
this.triggerPhrase.substring(0, this.triggerPhrase.length() - 2) + ' ' +
(condition.toString().startsWith("during") ? "" : "while ") + condition + ", "
);
}
return this;
}
@Override
public Condition getTriggerCondition() {
return triggerCondition;
}
@Override
public boolean checkTriggerCondition(Game game) {
return triggerCondition == null || triggerCondition.apply(game, this);
}
@Override
public boolean resolve(Game game) {
if (!checkInterveningIfClause(game)) {

View file

@ -1,6 +1,7 @@
package mage.abilities.common;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.condition.CompoundCondition;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SolvedSourceCondition;
@ -8,7 +9,6 @@ import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.decorator.ConditionalAsThoughEffect;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.decorator.ConditionalReplacementEffect;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
@ -63,13 +63,13 @@ public class CaseAbility extends SimpleStaticAbility {
* The "Solved" ability must be one of the following:
* <ul>
* <li>{@link ConditionalActivatedAbility} using the condition {@link SolvedSourceCondition}.SOLVED</li>
* <li>{@link ConditionalTriggeredAbility} using the condition {@link SolvedSourceCondition}.SOLVED</li>
* <li>{@link TriggeredAbility} using the condition {@link SolvedSourceCondition}.SOLVED</li>
* <li>{@link SimpleStaticAbility} with only {@link ConditionalAsThoughEffect} or {@link ConditionalContinuousEffect} effects</li>
* </ul>
*
* @param initialAbility The ability that a Case has at all times
* @param initialAbility The ability that a Case has at all times
* @param toSolveCondition The condition to be checked when solving
* @param solvedAbility The ability that a solved Case has
* @param solvedAbility The ability that a solved Case has
*/
public CaseAbility(Ability initialAbility, Condition toSolveCondition, Ability solvedAbility) {
super(Zone.ALL, null);
@ -81,22 +81,28 @@ public class CaseAbility extends SimpleStaticAbility {
addSubAbility(new CaseSolveAbility(toSolveCondition));
if (solvedAbility instanceof ConditionalActivatedAbility) {
((ConditionalActivatedAbility) solvedAbility).hideCondition();
} else if (!(solvedAbility instanceof ConditionalTriggeredAbility)) {
if (solvedAbility instanceof SimpleStaticAbility) {
for (Effect effect : solvedAbility.getEffects()) {
if (!(effect instanceof ConditionalContinuousEffect ||
effect instanceof ConditionalAsThoughEffect ||
effect instanceof ConditionalReplacementEffect)) {
throw new IllegalArgumentException("Wrong code usage: solvedAbility must be one of ConditionalActivatedAbility, " +
"ConditionalTriggeredAbility, or StaticAbility with conditional effects.");
}
if (!(solvedAbility instanceof ConditionalActivatedAbility)) {
if (solvedAbility instanceof TriggeredAbility) {
if (!(((TriggeredAbility) solvedAbility).getTriggerCondition() instanceof SolvedSourceCondition)) {
throw new IllegalArgumentException("Wrong code usage: if solvedAbility is a TriggeredAbility it must have SolvedSourceCondition as its trigger condition");
}
} else {
throw new IllegalArgumentException("Wrong code usage: solvedAbility must be one of ConditionalActivatedAbility, " +
"ConditionalTriggeredAbility, or StaticAbility with conditional effects.");
if (solvedAbility instanceof SimpleStaticAbility) {
for (Effect effect : solvedAbility.getEffects()) {
if (!(effect instanceof ConditionalContinuousEffect ||
effect instanceof ConditionalAsThoughEffect ||
effect instanceof ConditionalReplacementEffect)) {
throw new IllegalArgumentException("Wrong code usage: solvedAbility must be one of ConditionalActivatedAbility, " +
"TriggeredAbility, or StaticAbility with conditional effects.");
}
}
} else {
throw new IllegalArgumentException("Wrong code usage: solvedAbility must be one of ConditionalActivatedAbility, " +
"TriggeredAbility, or StaticAbility with conditional effects.");
}
}
} else {
((ConditionalActivatedAbility) solvedAbility).hideCondition();
}
addSubAbility(solvedAbility.withFlavorWord("Solved")); // TODO: Technically this shouldn't be italicized
}

View file

@ -17,6 +17,6 @@ public enum OpponentsTurnCondition implements Condition {
@Override
public String toString() {
return "if it's an opponent's turn";
return "during an opponent's turn";
}
}

View file

@ -1,143 +0,0 @@
package mage.abilities.decorator;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Modes;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.condition.Condition;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.hint.Hint;
import mage.constants.EffectType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.util.CardUtil;
import mage.watchers.Watcher;
import java.util.ArrayList;
import java.util.List;
/**
* Adds condition to {@link mage.abilities.effects.ContinuousEffect}. Acts as
* decorator.
*
* @author noahg
*/
public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
protected TriggeredAbility ability;
protected Condition condition;
protected String abilityText;
/**
* Triggered ability with a condition. Set the optionality for the trigger
* ability itself.
*
* @param ability
* @param condition
* @param text explicit rule text for the ability, if null or empty, the
* rule text generated by the triggered ability itself is used.
*/
public ConditionalTriggeredAbility(TriggeredAbility ability, Condition condition, String text) {
super(ability.getZone(), null);
this.ability = ability;
this.condition = condition;
this.abilityText = text;
if (ability.isLeavesTheBattlefieldTrigger()) {
this.setLeavesTheBattlefieldTrigger(true);
}
}
protected ConditionalTriggeredAbility(final ConditionalTriggeredAbility triggered) {
super(triggered);
this.ability = triggered.ability.copy();
this.condition = triggered.condition;
this.abilityText = triggered.abilityText;
}
@Override
public ConditionalTriggeredAbility copy() {
return new ConditionalTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return ability.checkEventType(event, game);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
ability.setSourceId(this.getSourceId());
ability.setControllerId(this.getControllerId());
return ability.checkTrigger(event, game) && condition.apply(game, this);
}
@Override
public String getRule() {
if (abilityText == null || abilityText.isEmpty()) {
return ability.getRule();
}
return (flavorWord != null ? CardUtil.italicizeWithEmDash(flavorWord) : "") +
(abilityWord != null ? abilityWord.formatWord() : "") +
abilityText + (abilityText.endsWith(".") || abilityText.endsWith("\"") || abilityText.endsWith(">") ? "" : ".");
}
@Override
public Effects getEffects() {
return ability.getEffects();
}
@Override
public void addEffect(Effect effect) {
ability.addEffect(effect);
}
@Override
public Modes getModes() {
return ability.getModes();
}
@Override
public List<Watcher> getWatchers() {
return ability.getWatchers();
}
@Override
public void addWatcher(Watcher watcher) {
ability.addWatcher(watcher);
}
@Override
public List<Hint> getHints() {
List<Hint> res = new ArrayList<>(super.getHints());
res.addAll(ability.getHints());
return res;
}
@Override
public Effects getEffects(Game game, EffectType effectType) {
return ability.getEffects(game, effectType);
}
@Override
public boolean isOptional() {
return ability.isOptional();
}
@Override
public Ability withFlavorWord(String flavorWord) {
ability.withFlavorWord(flavorWord);
return this;
}
@Override
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
if (isLeavesTheBattlefieldTrigger()) {
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} else {
return super.isInUseableZone(game, sourceObject, event);
}
}
}

View file

@ -93,7 +93,7 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl {
for (Effect e : getEffects()) { //Add effects to the sub-abilities so that they can set target pointers
ability.addEffect(e);
}
if (ability.checkEventType(event, game) && ability.checkTrigger(event, game)) {
if (ability.checkEventType(event, game) && ability.checkTrigger(event, game) && ability.checkTriggerCondition(game)) {
toRet = true;
}
ability.getEffects().clear(); //Remove afterwards, ensures that they remain synced even with copying