diff --git a/Mage.Sets/src/mage/cards/d/DraconicRoar.java b/Mage.Sets/src/mage/cards/d/DraconicRoar.java
index 2868e31525..d4eda4e9eb 100644
--- a/Mage.Sets/src/mage/cards/d/DraconicRoar.java
+++ b/Mage.Sets/src/mage/cards/d/DraconicRoar.java
@@ -1,23 +1,17 @@
package mage.cards.d;
import mage.abilities.Ability;
-import mage.abilities.costs.CostAdjuster;
-import mage.abilities.costs.common.RevealTargetFromHandCost;
+import mage.abilities.condition.common.RevealedOrControlledDragonCondition;
+import mage.abilities.costs.common.RevealDragonFromHandCost;
import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.DamageTargetEffect;
-import mage.abilities.effects.common.InfoEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
-import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreaturePermanent;
-import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher;
import java.util.UUID;
@@ -30,14 +24,11 @@ public final class DraconicRoar extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
// As an additional cost to cast Draconic Roar, you may reveal a Dragon card from your hand.
- this.getSpellAbility().addEffect(new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand"));
- this.getSpellAbility().setCostAdjuster(DraconicRoarAdjuster.instance);
+ this.getSpellAbility().addCost(new RevealDragonFromHandCost());
// Draconic Roar deals 3 damage to target creature. If you revealed a Dragon card or controlled a Dragon as you cast Draconic Roar, Draconic Roar deals 3 damage to that creature's controller.
- this.getSpellAbility().addEffect(new DamageTargetEffect(3));
- this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DraconicRoarEffect());
- this.getSpellAbility().addWatcher(new DragonOnTheBattlefieldWhileSpellWasCastWatcher());
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
private DraconicRoar(final DraconicRoar card) {
@@ -50,34 +41,15 @@ public final class DraconicRoar extends CardImpl {
}
}
-enum DraconicRoarAdjuster implements CostAdjuster {
- instance;
-
- private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)");
-
- static {
- filter.add(SubType.DRAGON.getPredicate());
- }
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- Player controller = game.getPlayer(ability.getControllerId());
- if (controller != null) {
- if (controller.getHand().count(filter, game) > 0) {
- ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter)));
- }
- }
- }
-}
-
class DraconicRoarEffect extends OneShotEffect {
- public DraconicRoarEffect() {
+ DraconicRoarEffect() {
super(Outcome.Benefit);
- this.staticText = "If you revealed a Dragon card or controlled a Dragon as you cast {this}, {this} deals 3 damage to that creature's controller";
+ staticText = "{this} deals 3 damage to target creature. If you revealed a Dragon card or controlled " +
+ "a Dragon as you cast this spell, {this} deals 3 damage to that creature’s controller.";
}
- public DraconicRoarEffect(final DraconicRoarEffect effect) {
+ private DraconicRoarEffect(final DraconicRoarEffect effect) {
super(effect);
}
@@ -88,21 +60,18 @@ class DraconicRoarEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class);
- if (watcher != null && watcher.castWithConditionTrue(source.getId())) {
- Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
- if (permanent != null) {
- Player player = game.getPlayer(permanent.getControllerId());
- if (player != null) {
- player.damage(3, source.getSourceId(), source, game);
- }
- }
- }
+ Permanent permanent = game.getPermanent(source.getFirstTarget());
+ if (permanent == null) {
+ return false;
+ }
+ permanent.damage(3, source.getSourceId(), source, game);
+ if (!RevealedOrControlledDragonCondition.instance.apply(game, source)) {
return true;
}
- return false;
+ Player player = game.getPlayer(permanent.getControllerId());
+ if (player != null) {
+ player.damage(3, source.getSourceId(), source, game);
+ }
+ return true;
}
}
-
diff --git a/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java b/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java
index 7f5685292e..45bbca867a 100644
--- a/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java
+++ b/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java
@@ -1,28 +1,15 @@
-
package mage.cards.d;
-import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.condition.Condition;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.CostAdjuster;
-import mage.abilities.costs.common.RevealTargetFromHandCost;
-import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
-import mage.abilities.effects.ContinuousRuleModifyingEffect;
+import mage.abilities.condition.common.RevealedOrControlledDragonCondition;
+import mage.abilities.costs.common.RevealDragonFromHandCost;
+import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.CantBeCounteredSourceEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
-import mage.abilities.effects.common.InfoEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Zone;
-import mage.filter.FilterCard;
-import mage.filter.common.FilterControlledPermanent;
-import mage.game.Game;
-import mage.game.stack.Spell;
-import mage.players.Player;
-import mage.target.common.TargetCardInHand;
import java.util.UUID;
@@ -35,20 +22,19 @@ public final class DragonlordsPrerogative extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}{U}");
// As an additional cost to cast Dragonlord's Prerogative, you may reveal a Dragon card from your hand.
- this.getSpellAbility().addEffect(new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand"));
- this.getSpellAbility().setCostAdjuster(DragonlordsPrerogativeAdjuster.instance);
+ this.getSpellAbility().addCost(new RevealDragonFromHandCost());
// If you revealed a Dragon card or controlled a Dragon as you cast Dragonlord's Prerogative, Dragonlord's Prerogative can't be countered.
- Condition condition = new DragonlordsPrerogativeCondition();
- ContinuousRuleModifyingEffect cantBeCountered = new CantBeCounteredSourceEffect();
- ConditionalContinuousRuleModifyingEffect conditionalCantBeCountered = new ConditionalContinuousRuleModifyingEffect(cantBeCountered, condition);
- conditionalCantBeCountered.setText("
If you revealed a Dragon card or controlled a Dragon as you cast {this}, this spell can't be countered");
- Ability ability = new SimpleStaticAbility(Zone.STACK, conditionalCantBeCountered);
- this.addAbility(ability);
+ this.addAbility(new SimpleStaticAbility(
+ Zone.STACK,
+ new ConditionalContinuousEffect(
+ new CantBeCounteredSourceEffect(), RevealedOrControlledDragonCondition.instance,
+ "if you revealed a Dragon card or controlled a Dragon as you cast this spell, this spell can't be countered"
+ )
+ ));
// Draw four cards.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(4));
-
}
private DragonlordsPrerogative(final DragonlordsPrerogative card) {
@@ -60,49 +46,3 @@ public final class DragonlordsPrerogative extends CardImpl {
return new DragonlordsPrerogative(this);
}
}
-
-enum DragonlordsPrerogativeAdjuster implements CostAdjuster {
- instance;
- private static final FilterCard filter = new FilterCard("a Dragon card from your hand");
-
- static {
- filter.add(SubType.DRAGON.getPredicate());
- }
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- Player controller = game.getPlayer(ability.getControllerId());
- if (controller != null) {
- if (controller.getHand().count(filter, game) > 0) {
- ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter)));
- }
- }
- }
-}
-
-class DragonlordsPrerogativeCondition implements Condition {
-
- private static final FilterControlledPermanent filter = new FilterControlledPermanent("Dragon");
-
- static {
- filter.add(SubType.DRAGON.getPredicate());
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- boolean applies = false;
- Spell spell = game.getStack().getSpell(source.getSourceId());
- if (spell != null && spell.getSpellAbility() != null) {
- for (Cost cost : spell.getSpellAbility().getCosts()) {
- if (cost instanceof RevealTargetFromHandCost) {
- applies = !cost.getTargets().isEmpty();
- break;
- }
- }
- }
- if (!applies) {
- applies = game.getBattlefield().countAll(filter, source.getControllerId(), game) > 0;
- }
- return applies;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/f/FoulTongueInvocation.java b/Mage.Sets/src/mage/cards/f/FoulTongueInvocation.java
index ae3abe2fbe..8f5a396031 100644
--- a/Mage.Sets/src/mage/cards/f/FoulTongueInvocation.java
+++ b/Mage.Sets/src/mage/cards/f/FoulTongueInvocation.java
@@ -1,24 +1,15 @@
-
package mage.cards.f;
-import mage.abilities.Ability;
-import mage.abilities.costs.CostAdjuster;
-import mage.abilities.costs.common.RevealTargetFromHandCost;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.condition.common.RevealedOrControlledDragonCondition;
+import mage.abilities.costs.common.RevealDragonFromHandCost;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.SacrificeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.filter.FilterCard;
import mage.filter.StaticFilters;
-import mage.game.Game;
-import mage.players.Player;
import mage.target.TargetPlayer;
-import mage.target.common.TargetCardInHand;
-import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher;
import java.util.UUID;
@@ -31,14 +22,17 @@ public final class FoulTongueInvocation extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}");
// As an additional cost to cast Foul-Tongue Invocation, you may reveal a Dragon card from your hand.
- this.getSpellAbility().addEffect(new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand"));
- this.getSpellAbility().setCostAdjuster(FoulTongueInvocationAdjuster.instance);
+ this.getSpellAbility().addCost(new RevealDragonFromHandCost());
// Target player sacrifices a creature. If you revealed a Dragon card or controlled a Dragon as you cast Foul-Tongue Invocation, you gain 4 life.
+ this.getSpellAbility().addEffect(new SacrificeEffect(
+ StaticFilters.FILTER_PERMANENT_CREATURE, 1, "target player"
+ ));
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new GainLifeEffect(4), RevealedOrControlledDragonCondition.instance,
+ "If you revealed a Dragon card or controlled a Dragon as you cast this spell, you gain 4 life."
+ ));
this.getSpellAbility().addTarget(new TargetPlayer());
- this.getSpellAbility().addEffect(new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "target player"));
- this.getSpellAbility().addEffect(new FoulTongueInvocationEffect());
- this.getSpellAbility().addWatcher(new DragonOnTheBattlefieldWhileSpellWasCastWatcher());
}
private FoulTongueInvocation(final FoulTongueInvocation card) {
@@ -50,52 +44,3 @@ public final class FoulTongueInvocation extends CardImpl {
return new FoulTongueInvocation(this);
}
}
-
-enum FoulTongueInvocationAdjuster implements CostAdjuster {
- instance;
- private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)");
-
- static {
- filter.add(SubType.DRAGON.getPredicate());
- }
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- Player controller = game.getPlayer(ability.getControllerId());
- if (controller != null) {
- if (controller.getHand().count(filter, game) > 0) {
- ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter)));
- }
- }
- }
-}
-
-class FoulTongueInvocationEffect extends OneShotEffect {
-
- public FoulTongueInvocationEffect() {
- super(Outcome.Benefit);
- this.staticText = "If you revealed a Dragon card or controlled a Dragon as you cast {this}, you gain 4 life";
- }
-
- public FoulTongueInvocationEffect(final FoulTongueInvocationEffect effect) {
- super(effect);
- }
-
- @Override
- public FoulTongueInvocationEffect copy() {
- return new FoulTongueInvocationEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class);
- if (watcher != null && watcher.castWithConditionTrue(source.getId())) {
- controller.gainLife(4, game, source);
- }
- return true;
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java b/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java
index 4e511f34ce..a2bf9f2314 100644
--- a/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java
+++ b/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java
@@ -1,40 +1,26 @@
-
package mage.cards.o;
-import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
-import mage.abilities.TriggeredAbilityImpl;
-import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.costs.common.RevealTargetFromHandCost;
-import mage.abilities.effects.Effect;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.InfoEffect;
+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;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.filter.FilterCard;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
-import mage.target.common.TargetCardInHand;
+import mage.constants.CardType;
+import mage.constants.SubType;
import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class OratorOfOjutai extends CardImpl {
- private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)");
-
- static {
- filter.add(SubType.DRAGON.getPredicate());
- }
-
public OratorOfOjutai(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add(SubType.BIRD);
@@ -47,22 +33,14 @@ public final class OratorOfOjutai extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// As an additional cost to cast Orator of Ojutai, you may reveal a Dragon card from your hand.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand")));
+ 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 OratorOfOjutaiTriggeredAbility(new OratorOfOjutaiEffect()), new DragonOnTheBattlefieldWhileSpellWasCastWatcher());
- }
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- if (ability.getAbilityType() == AbilityType.SPELL) {
- Player controller = game.getPlayer(ability.getControllerId());
- if (controller != null) {
- if (controller.getHand().count(filter, game) > 0) {
- ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter)));
- }
- }
- }
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)),
+ RevealedOrControlledDragonCondition.instance, "When {this} enters the battlefield, " +
+ "if you revealed a Dragon card or controlled a Dragon as you cast this spell, draw a card."
+ ), new DragonOnTheBattlefieldWhileSpellWasCastWatcher());
}
private OratorOfOjutai(final OratorOfOjutai card) {
@@ -74,73 +52,3 @@ public final class OratorOfOjutai extends CardImpl {
return new OratorOfOjutai(this);
}
}
-
-class OratorOfOjutaiTriggeredAbility extends TriggeredAbilityImpl {
-
- public OratorOfOjutaiTriggeredAbility(Effect effect) {
- super(Zone.BATTLEFIELD, effect, false);
- }
-
- public OratorOfOjutaiTriggeredAbility(final OratorOfOjutaiTriggeredAbility ability) {
- super(ability);
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- //Intervening if must be checked
- Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(getSourceId());
- DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class);
- return event.getTargetId().equals(getSourceId())
- && watcher != null
- && watcher.castWithConditionTrue(sourcePermanent.getSpellAbility().getId());
- }
-
- @Override
- public String getRule() {
- return "When {this} enters the battlefield, " + super.getRule();
- }
-
- @Override
- public OratorOfOjutaiTriggeredAbility copy() {
- return new OratorOfOjutaiTriggeredAbility(this);
- }
-}
-
-class OratorOfOjutaiEffect extends OneShotEffect {
-
- public OratorOfOjutaiEffect() {
- super(Outcome.Benefit);
- this.staticText = "If you revealed a Dragon card or controlled a Dragon as you cast {this}, draw a card";
- }
-
- public OratorOfOjutaiEffect(final OratorOfOjutaiEffect effect) {
- super(effect);
- }
-
- @Override
- public OratorOfOjutaiEffect copy() {
- return new OratorOfOjutaiEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- //Intervening if is checked again on resolution
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (sourcePermanent != null) {
- DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class);
- if (watcher != null && watcher.castWithConditionTrue(sourcePermanent.getSpellAbility().getId())) {
- controller.drawCards(1, source, game);
- return true;
- }
- }
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java b/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java
index 53c976f313..710508cadd 100644
--- a/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java
+++ b/Mage.Sets/src/mage/cards/s/ScaleguardSentinels.java
@@ -1,39 +1,24 @@
-
package mage.cards.s;
-import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
-import mage.abilities.condition.Condition;
-import mage.abilities.costs.common.RevealTargetFromHandCost;
-import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.condition.common.RevealedOrControlledDragonCondition;
+import mage.abilities.costs.common.RevealDragonFromHandCost;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AbilityType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
-import mage.filter.FilterCard;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
-import mage.target.common.TargetCardInHand;
import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ScaleguardSentinels extends CardImpl {
- private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)");
-
- static {
- filter.add(SubType.DRAGON.getPredicate());
- }
-
public ScaleguardSentinels(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}");
this.subtype.add(SubType.HUMAN);
@@ -42,26 +27,16 @@ public final class ScaleguardSentinels extends CardImpl {
this.toughness = new MageInt(3);
// As an additional cost to cast Scaleguard Sentinels, you may reveal a Dragon card from your hand.
- this.getSpellAbility().addEffect(new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand"));
+ this.getSpellAbility().addCost(new RevealDragonFromHandCost());
// Scaleguard Sentinels enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast Scaleguard Sentinels.
- this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), true),
- ScaleguardSentinelsCondition.instance,
- "{this} enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast {this}.", ""),
- new DragonOnTheBattlefieldWhileSpellWasCastWatcher());
-
- }
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- if (ability.getAbilityType() == AbilityType.SPELL) {
- Player controller = game.getPlayer(ability.getControllerId());
- if (controller != null) {
- if (controller.getHand().count(filter, game) > 0) {
- ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, 1, filter)));
- }
- }
- }
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
+ RevealedOrControlledDragonCondition.instance, "{this} enters the battlefield " +
+ "with a +1/+1 counter on it if you revealed a Dragon card " +
+ "or controlled a Dragon as you cast this spell.", ""
+ ), new DragonOnTheBattlefieldWhileSpellWasCastWatcher()
+ );
}
private ScaleguardSentinels(final ScaleguardSentinels card) {
@@ -73,18 +48,3 @@ public final class ScaleguardSentinels extends CardImpl {
return new ScaleguardSentinels(this);
}
}
-
-enum ScaleguardSentinelsCondition implements Condition {
-
- instance;
-
- @Override
- public boolean apply(Game game, Ability source) {
- Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId());
- if (sourcePermanent != null) {
- DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class);
- return (watcher != null && watcher.castWithConditionTrue(sourcePermanent.getSpellAbility().getId()));
- }
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/s/SilumgarsScorn.java b/Mage.Sets/src/mage/cards/s/SilumgarsScorn.java
index 93779841e0..d922fd4596 100644
--- a/Mage.Sets/src/mage/cards/s/SilumgarsScorn.java
+++ b/Mage.Sets/src/mage/cards/s/SilumgarsScorn.java
@@ -1,65 +1,38 @@
-
package mage.cards.s;
-import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.common.RevealTargetFromHandCost;
+import mage.abilities.condition.common.RevealedOrControlledDragonCondition;
+import mage.abilities.costs.common.RevealDragonFromHandCost;
import mage.abilities.costs.mana.GenericManaCost;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.CounterTargetEffect;
+import mage.abilities.effects.common.CounterUnlessPaysEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.AbilityType;
import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.SubType;
-import mage.filter.FilterCard;
-import mage.game.Game;
-import mage.game.stack.StackObject;
-import mage.players.Player;
import mage.target.TargetSpell;
-import mage.target.common.TargetCardInHand;
-import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class SilumgarsScorn extends CardImpl {
- private static final FilterCard filter = new FilterCard("a Dragon card from your hand (you don't have to)");
-
- static {
- filter.add(SubType.DRAGON.getPredicate());
- }
-
public SilumgarsScorn(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}{U}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}{U}");
// As an additional cost to cast Silumgar's Scorn, you may reveal a Dragon card from your hand.
- this.getSpellAbility().addEffect(new InfoEffect("as an additional cost to cast this spell, you may reveal a Dragon card from your hand"));
-
+ this.getSpellAbility().addCost(new RevealDragonFromHandCost());
+
// Counter target spell unless its controller pays {1}. If you revealed a Dragon card or controlled a Dragon as you cast Silumgar's Scorn, counter that spell instead.
- this.getSpellAbility().addEffect(new SilumgarsScornCounterEffect());
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new CounterTargetEffect(), new CounterUnlessPaysEffect(new GenericManaCost(1)),
+ RevealedOrControlledDragonCondition.instance, "counter target spell unless its controller pays {1}. " +
+ "If you revealed a Dragon card or controlled a Dragon as you cast this spell, counter that spell instead"
+ ));
this.getSpellAbility().addTarget(new TargetSpell());
- this.getSpellAbility().addWatcher(new DragonOnTheBattlefieldWhileSpellWasCastWatcher());
-
}
-
- @Override
- public void adjustCosts(Ability ability, Game game) {
- if (ability.getAbilityType() == AbilityType.SPELL) {
- Player controller = game.getPlayer(ability.getControllerId());
- if (controller != null) {
- if (controller.getHand().count(filter, game) > 0) {
- ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0,1, filter)));
- }
- }
- }
- }
-
private SilumgarsScorn(final SilumgarsScorn card) {
super(card);
}
@@ -69,48 +42,3 @@ public final class SilumgarsScorn extends CardImpl {
return new SilumgarsScorn(this);
}
}
-
-class SilumgarsScornCounterEffect extends OneShotEffect {
-
- public SilumgarsScornCounterEffect() {
- super(Outcome.Detriment);
- staticText = "
Counter target spell unless its controller pays {1}. If you revealed a Dragon card or controlled a Dragon as you cast {this}, counter that spell instead";
- }
-
- public SilumgarsScornCounterEffect(final SilumgarsScornCounterEffect effect) {
- super(effect);
- }
-
- @Override
- public SilumgarsScornCounterEffect copy() {
- return new SilumgarsScornCounterEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- StackObject spell = game.getStack().getStackObject(targetPointer.getFirst(game, source));
- if (spell != null) {
- Player player = game.getPlayer(spell.getControllerId());
- if (player != null) {
- DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class);
- boolean condition = watcher != null && watcher.castWithConditionTrue(source.getId());
- if (!condition) {
- for (Cost cost: source.getCosts()) {
- if (cost instanceof RevealTargetFromHandCost) {
- condition = ((RevealTargetFromHandCost)cost).getNumberRevealedCards() > 0;
- }
- }
- }
- if (condition) {
- return game.getStack().counter(spell.getId(), source, game);
- }
- if (!(player.chooseUse(Outcome.Benefit, "Would you like to pay {1} to prevent counter effect?", source, game) &&
- new GenericManaCost(1).pay(source, game, source, spell.getControllerId(), false))) {
- return game.getStack().counter(spell.getId(), source, game);
- }
- }
- }
- return true;
- }
-
-}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RevealedOrControlledDragonTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RevealedOrControlledDragonTest.java
new file mode 100644
index 0000000000..04a5a806da
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/additional/RevealedOrControlledDragonTest.java
@@ -0,0 +1,181 @@
+package org.mage.test.cards.cost.additional;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author TheElk801
+ */
+public class RevealedOrControlledDragonTest extends CardTestPlayerBase {
+ private static final String dragon = "Shivan Dragon";
+ private static final String roar = "Draconic Roar";
+ private static final String lion = "Silvercoat Lion";
+ private static final String orator = "Orator of Ojutai";
+ private static final String sentinels = "Scaleguard Sentinels";
+
+ public void addDragonToHand(String cardName) {
+ addCard(Zone.HAND, playerA, dragon);
+ addCard(Zone.HAND, playerA, cardName);
+ }
+
+ public void addDragonToBattlefield(String cardName) {
+ addCard(Zone.BATTLEFIELD, playerA, dragon);
+ addCard(Zone.HAND, playerA, cardName);
+ }
+
+ @Test
+ public void testRoarHand() {
+ addDragonToHand(roar);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
+ addCard(Zone.BATTLEFIELD, playerA, lion);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, roar, lion);
+ setChoice(playerA, dragon);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, lion, 1);
+ assertGraveyardCount(playerA, roar, 1);
+ assertLife(playerA, 20 - 3);
+ }
+
+ @Test
+ public void testRoarBattlefield() {
+ addDragonToBattlefield(roar);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
+ addCard(Zone.BATTLEFIELD, playerA, lion);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, roar, lion);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, lion, 1);
+ assertGraveyardCount(playerA, roar, 1);
+ assertLife(playerA, 20 - 3);
+ }
+
+ @Test
+ public void testRoarFalse() {
+ addCard(Zone.HAND, playerA, roar);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
+ addCard(Zone.BATTLEFIELD, playerA, lion);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, roar, lion);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, lion, 1);
+ assertGraveyardCount(playerA, roar, 1);
+ assertLife(playerA, 20);
+ }
+
+ @Test
+ public void testOratorHand() {
+ addDragonToHand(orator);
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, orator);
+ setChoice(playerA, dragon);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, orator, 1);
+ assertHandCount(playerA, 1 + 1);
+ }
+
+ @Test
+ public void testOratorBattlefield() {
+ addDragonToBattlefield(orator);
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, orator);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, orator, 1);
+ assertHandCount(playerA, 1);
+ }
+
+ @Test
+ public void testOratorFalse() {
+ addCard(Zone.HAND, playerA, orator);
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, orator);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, orator, 1);
+ assertHandCount(playerA, 0);
+ }
+
+ @Test
+ public void testSentinelsHand() {
+ addDragonToHand(sentinels);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sentinels);
+ setChoice(playerA, dragon);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, sentinels, 1);
+ assertCounterCount(playerA, sentinels, CounterType.P1P1, 1);
+ }
+
+ @Test
+ public void testSentinelsBattlefield() {
+ addDragonToBattlefield(sentinels);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sentinels);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, sentinels, 1);
+ assertCounterCount(playerA, sentinels, CounterType.P1P1, 1);
+ }
+
+ @Test
+ public void testSentinelsFalse() {
+ addCard(Zone.HAND, playerA, sentinels);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sentinels);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, sentinels, 1);
+ assertCounterCount(playerA, sentinels, CounterType.P1P1, 0);
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/condition/common/RevealedOrControlledDragonCondition.java b/Mage/src/main/java/mage/abilities/condition/common/RevealedOrControlledDragonCondition.java
new file mode 100644
index 0000000000..8658e5897b
--- /dev/null
+++ b/Mage/src/main/java/mage/abilities/condition/common/RevealedOrControlledDragonCondition.java
@@ -0,0 +1,30 @@
+package mage.abilities.condition.common;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.Condition;
+import mage.abilities.costs.common.RevealDragonFromHandCost;
+import mage.constants.AbilityType;
+import mage.game.Game;
+import mage.watchers.common.DragonOnTheBattlefieldWhileSpellWasCastWatcher;
+
+/**
+ * @author TheElk801
+ */
+public enum RevealedOrControlledDragonCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ if (source.getAbilityType() == AbilityType.SPELL) {
+ return source
+ .getCosts()
+ .stream()
+ .filter(RevealDragonFromHandCost.class::isInstance)
+ .map(RevealDragonFromHandCost.class::cast)
+ .anyMatch(RevealDragonFromHandCost::isRevealedOrControlled);
+ }
+ DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher
+ = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class);
+ return watcher != null && watcher.checkCondition(source, game);
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/costs/common/RevealDragonFromHandCost.java b/Mage/src/main/java/mage/abilities/costs/common/RevealDragonFromHandCost.java
new file mode 100644
index 0000000000..26c0112f3c
--- /dev/null
+++ b/Mage/src/main/java/mage/abilities/costs/common/RevealDragonFromHandCost.java
@@ -0,0 +1,58 @@
+package mage.abilities.costs.common;
+
+import mage.abilities.Ability;
+import mage.abilities.costs.Cost;
+import mage.constants.SubType;
+import mage.filter.FilterCard;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.Game;
+import mage.target.common.TargetCardInHand;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public class RevealDragonFromHandCost extends RevealTargetFromHandCost {
+
+ private static final FilterCard filter = new FilterCard("a Dragon card from your hand");
+ private static final FilterPermanent filter2 = new FilterControlledPermanent(SubType.DRAGON);
+
+ static {
+ filter.add(SubType.DRAGON.getPredicate());
+ }
+
+ private boolean revealedOrControlled = false;
+
+ public RevealDragonFromHandCost() {
+ super(new TargetCardInHand(0, 1, filter));
+ }
+
+ private RevealDragonFromHandCost(final RevealDragonFromHandCost cost) {
+ super(cost);
+ this.revealedOrControlled = cost.revealedOrControlled;
+ }
+
+ @Override
+ public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
+ return true;
+ }
+
+ @Override
+ public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
+ super.pay(ability, game, source, controllerId, noMana, costToPay);
+ revealedOrControlled = numberCardsRevealed > 0
+ || game.getBattlefield().count(filter2, source.getSourceId(), controllerId, game) > 0;
+ return paid = true;
+ }
+
+ @Override
+ public RevealDragonFromHandCost copy() {
+ return new RevealDragonFromHandCost(this);
+ }
+
+ public boolean isRevealedOrControlled() {
+ return revealedOrControlled;
+ }
+}
diff --git a/Mage/src/main/java/mage/watchers/common/DragonOnTheBattlefieldWhileSpellWasCastWatcher.java b/Mage/src/main/java/mage/watchers/common/DragonOnTheBattlefieldWhileSpellWasCastWatcher.java
index 0d5ee938bd..d33cdc0f1a 100644
--- a/Mage/src/main/java/mage/watchers/common/DragonOnTheBattlefieldWhileSpellWasCastWatcher.java
+++ b/Mage/src/main/java/mage/watchers/common/DragonOnTheBattlefieldWhileSpellWasCastWatcher.java
@@ -1,10 +1,9 @@
package mage.watchers.common;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.common.RevealTargetFromHandCost;
-import mage.constants.SubType;
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.costs.common.RevealDragonFromHandCost;
import mage.constants.WatcherScope;
-import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
@@ -12,16 +11,13 @@ import mage.watchers.Watcher;
import java.util.HashSet;
import java.util.Set;
-import java.util.UUID;
/**
* @author LevelX2
*/
public class DragonOnTheBattlefieldWhileSpellWasCastWatcher extends Watcher {
- private static final FilterPermanent filter = new FilterPermanent(SubType.DRAGON, "Dragons");
-
- private final Set castWithDragonOnTheBattlefield = new HashSet<>();
+ private final Set castWithDragonOnTheBattlefield = new HashSet<>();
public DragonOnTheBattlefieldWhileSpellWasCastWatcher() {
super(WatcherScope.GAME);
@@ -29,28 +25,22 @@ public class DragonOnTheBattlefieldWhileSpellWasCastWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
- if (event.getType() == GameEvent.EventType.SPELL_CAST) {
- // targetId is the unique ID of the spell
- Spell spell = game.getState().getStack().getSpell(event.getTargetId());
- // revealed a Dragon card or controlled a Dragon as you cast the spell
- if (spell != null) {
- boolean revealedOrOnBattlefield = false;
- if (spell.getSpellAbility() != null) {
- for (Cost cost : spell.getSpellAbility().getCosts()) {
- if (cost instanceof RevealTargetFromHandCost) {
- revealedOrOnBattlefield = ((RevealTargetFromHandCost) cost).getNumberRevealedCards() > 0;
- break;
- }
- }
- }
- if (!revealedOrOnBattlefield) {
- revealedOrOnBattlefield = game.getBattlefield().countAll(filter, spell.getControllerId(), game) > 0;
- }
- if (revealedOrOnBattlefield) {
- castWithDragonOnTheBattlefield.add(spell.getId());
- }
-
- }
+ if (event.getType() != GameEvent.EventType.SPELL_CAST) {
+ return;
+ }
+ // targetId is the unique ID of the spell
+ Spell spell = game.getSpell(event.getTargetId());
+ // revealed a Dragon card or controlled a Dragon as you cast the spell
+ if (spell != null
+ && spell
+ .getSpellAbility()
+ .getCosts()
+ .stream()
+ .filter(RevealDragonFromHandCost.class::isInstance)
+ .map(RevealDragonFromHandCost.class::cast)
+ .anyMatch(RevealDragonFromHandCost::isRevealedOrControlled)) {
+ castWithDragonOnTheBattlefield.add(new MageObjectReference(spell.getCard(), game, 0));
+ castWithDragonOnTheBattlefield.add(new MageObjectReference(spell.getCard(), game, 1));
}
}
@@ -60,7 +50,9 @@ public class DragonOnTheBattlefieldWhileSpellWasCastWatcher extends Watcher {
castWithDragonOnTheBattlefield.clear();
}
- public boolean castWithConditionTrue(UUID spellId) {
- return castWithDragonOnTheBattlefield.contains(spellId);
+ public boolean checkCondition(Ability source, Game game) {
+ return castWithDragonOnTheBattlefield
+ .stream()
+ .anyMatch(mor -> mor.refersTo(source.getSourceObject(game), game));
}
}