From 45c61417ec47372168c51e68ab151e9bcd52a102 Mon Sep 17 00:00:00 2001 From: Neil Gentleman Date: Fri, 6 Nov 2015 20:08:11 -0800 Subject: [PATCH 1/5] fix Goblin Mutant & Stinkdrinker Bandit --- Mage.Sets/src/mage/sets/iceage/GoblinMutant.java | 3 ++- Mage.Sets/src/mage/sets/morningtide/StinkdrinkerBandit.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/iceage/GoblinMutant.java b/Mage.Sets/src/mage/sets/iceage/GoblinMutant.java index 2ca5bdcf9c..b1b2b82243 100644 --- a/Mage.Sets/src/mage/sets/iceage/GoblinMutant.java +++ b/Mage.Sets/src/mage/sets/iceage/GoblinMutant.java @@ -64,7 +64,8 @@ public class GoblinMutant extends CardImpl { super(ownerId, 188, "Goblin Mutant", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.expansionSetCode = "ICE"; this.subtype.add("Goblin"); - + this.subtype.add("Mutant"); + this.power = new MageInt(5); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/sets/morningtide/StinkdrinkerBandit.java b/Mage.Sets/src/mage/sets/morningtide/StinkdrinkerBandit.java index b73d31f4b2..82fecdc17a 100644 --- a/Mage.Sets/src/mage/sets/morningtide/StinkdrinkerBandit.java +++ b/Mage.Sets/src/mage/sets/morningtide/StinkdrinkerBandit.java @@ -67,7 +67,7 @@ public class StinkdrinkerBandit extends CardImpl { this.subtype.add("Rogue"); this.power = new MageInt(2); - this.toughness = new MageInt(2); + this.toughness = new MageInt(1); // Prowl {1}, {B} (You may cast this for its prowl cost if you dealt combat damage to a player this turn with a Goblin or Rogue.) this.addAbility(new ProwlAbility(this, "{1}{B}")); From 492637544aee164f7281c827474182d20af66afe Mon Sep 17 00:00:00 2001 From: Neil Gentleman Date: Fri, 6 Nov 2015 20:53:43 -0800 Subject: [PATCH 2/5] Terraformer, Elsewhere Flask: use ChoiceBasicLandType avoiding repetition of the basic land types everywhere --- Mage.Sets/src/mage/sets/ravnica/Terraformer.java | 16 +++++----------- .../src/mage/sets/shadowmoor/ElsewhereFlask.java | 16 +++++----------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/Mage.Sets/src/mage/sets/ravnica/Terraformer.java b/Mage.Sets/src/mage/sets/ravnica/Terraformer.java index 13e1244601..9e1325f929 100644 --- a/Mage.Sets/src/mage/sets/ravnica/Terraformer.java +++ b/Mage.Sets/src/mage/sets/ravnica/Terraformer.java @@ -27,7 +27,6 @@ */ package mage.sets.ravnica; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; @@ -41,7 +40,8 @@ import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.WhiteManaAbility; import mage.cards.CardImpl; -import mage.choices.ChoiceImpl; +import mage.choices.Choice; +import mage.choices.ChoiceBasicLandType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -103,15 +103,9 @@ class TerraformerEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - ChoiceImpl choices = new ChoiceImpl(true); - Set choicesSet = choices.getChoices(); - choicesSet.add("Forest"); - choicesSet.add("Plains"); - choicesSet.add("Mountain"); - choicesSet.add("Island"); - choicesSet.add("Swamp"); - if (player.choose(Outcome.Neutral, choices, game)) { - game.getState().setValue(source.getSourceId().toString() + "_Terraformer", choices.getChoice()); + Choice choice = new ChoiceBasicLandType(); + if (player.choose(Outcome.Neutral, choice, game)) { + game.getState().setValue(source.getSourceId().toString() + "_Terraformer", choice.getChoice()); } game.addEffect(new TerraformerContinuousEffect(), source); return true; diff --git a/Mage.Sets/src/mage/sets/shadowmoor/ElsewhereFlask.java b/Mage.Sets/src/mage/sets/shadowmoor/ElsewhereFlask.java index ae8d945447..b370c7dc87 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/ElsewhereFlask.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/ElsewhereFlask.java @@ -27,7 +27,6 @@ */ package mage.sets.shadowmoor; -import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -42,7 +41,8 @@ import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.WhiteManaAbility; import mage.cards.CardImpl; -import mage.choices.ChoiceImpl; +import mage.choices.Choice; +import mage.choices.ChoiceBasicLandType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -103,15 +103,9 @@ class ElsewhereFlaskEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - ChoiceImpl choices = new ChoiceImpl(true); - Set choicesSet = choices.getChoices(); - choicesSet.add("Forest"); - choicesSet.add("Plains"); - choicesSet.add("Mountain"); - choicesSet.add("Island"); - choicesSet.add("Swamp"); - if (player.choose(Outcome.Neutral, choices, game)) { - game.getState().setValue(source.getSourceId().toString() + "_ElsewhereFlask", choices.getChoice()); + Choice choice = new ChoiceBasicLandType(); + if (player.choose(Outcome.Neutral, choice, game)) { + game.getState().setValue(source.getSourceId().toString() + "_ElsewhereFlask", choice.getChoice()); } game.addEffect(new ElsewhereFlaskContinuousEffect(), source); return true; From 8af7526acc109f5df3bc9389869fd568506f3669 Mon Sep 17 00:00:00 2001 From: Neil Gentleman Date: Sat, 7 Nov 2015 00:54:53 -0800 Subject: [PATCH 3/5] Assembly-Worker doesn't give counters --- Mage.Sets/src/mage/sets/timespiral/AssemblyWorker.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/timespiral/AssemblyWorker.java b/Mage.Sets/src/mage/sets/timespiral/AssemblyWorker.java index 221de05930..95ad4df289 100644 --- a/Mage.Sets/src/mage/sets/timespiral/AssemblyWorker.java +++ b/Mage.Sets/src/mage/sets/timespiral/AssemblyWorker.java @@ -32,12 +32,12 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.target.TargetPermanent; @@ -63,7 +63,7 @@ public class AssemblyWorker extends CardImpl { this.toughness = new MageInt(2); // {tap}: Target Assembly-Worker creature gets +1/+1 until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new TapSourceCost()); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } From cad96e192791e419ac846be1f67c852f9df06760 Mon Sep 17 00:00:00 2001 From: Neil Gentleman Date: Sat, 7 Nov 2015 02:49:55 -0800 Subject: [PATCH 4/5] fix ActivatedAbilityUsedThisTurnWatcher ClassCastException Chronatog Totem and Groundling Pouncer were breaking when trying to play spells with convoke: java.lang.ClassCastException: mage.game.stack.Spell cannot be cast to mage.game.stack.StackAbility mage.sets.timespiral.ActivatedAbilityUsedThisTurnWatcher.watch(ChronatogTotem.java:148) mage.watchers.Watchers.watch(Watchers.java:63) mage.game.GameState.handleEvent(GameState.java:665) mage.game.GameImpl.fireEvent(GameImpl.java:2286) mage.players.PlayerImpl.specialAction(PlayerImpl.java:1094) mage.players.PlayerImpl.activateAbility(PlayerImpl.java:1133) mage.player.human.HumanPlayer.activateAbility(HumanPlayer.java:1219) mage.player.human.HumanPlayer.specialManaAction(HumanPlayer.java:1209) mage.player.human.HumanPlayer.playManaHandling(HumanPlayer.java:791) mage.player.human.HumanPlayer.playMana(HumanPlayer.java:769) mage.abilities.costs.mana.ManaCostsImpl.pay(ManaCostsImpl.java:135) mage.abilities.AbilityImpl.activate(AbilityImpl.java:394) mage.game.stack.Spell.activate(Spell.java:128) mage.players.PlayerImpl.cast(PlayerImpl.java:969) (...) --- .../mage/sets/eventide/GroundlingPouncer.java | 123 ++++++++---------- .../mage/sets/timespiral/ChronatogTotem.java | 122 +++++++++-------- 2 files changed, 110 insertions(+), 135 deletions(-) diff --git a/Mage.Sets/src/mage/sets/eventide/GroundlingPouncer.java b/Mage.Sets/src/mage/sets/eventide/GroundlingPouncer.java index 79141ba5cc..9d6f8aa0df 100644 --- a/Mage.Sets/src/mage/sets/eventide/GroundlingPouncer.java +++ b/Mage.Sets/src/mage/sets/eventide/GroundlingPouncer.java @@ -27,32 +27,28 @@ */ package mage.sets.eventide; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.condition.Condition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; +import mage.abilities.costs.Cost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.effects.Effect; +import mage.abilities.effects.Effects; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; -import mage.constants.AbilityType; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.EffectType; import mage.constants.Rarity; -import mage.constants.WatcherScope; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AbilityPredicate; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.stack.StackAbility; -import mage.game.stack.StackObject; -import mage.watchers.Watcher; /** * @@ -61,7 +57,11 @@ import mage.watchers.Watcher; */ public class GroundlingPouncer extends CardImpl { - private String rule = "{this} gets +1/+3 and gains flying until end of turn. Activate this ability only once each turn and only if an opponent controls a creature with flying."; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } public GroundlingPouncer(UUID ownerId) { super(ownerId, 154, "Groundling Pouncer", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{G/U}"); @@ -72,12 +72,14 @@ public class GroundlingPouncer extends CardImpl { this.toughness = new MageInt(1); // {GU}: Groundling Pouncer gets +1/+3 and gains flying until end of turn. Activate this ability only once each turn and only if an opponent controls a creature with flying. - Condition condition = new GroundingPouncerCondition(); - Effect effect = new BoostSourceEffect(1, 3, Duration.EndOfTurn); - Effect effect2 = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, false, true); - Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{G/U}"), condition, rule); - ability.addEffect(effect2); - this.addAbility(ability, new ActivatedAbilityUsedThisTurnWatcher()); + Ability ability = new GroundlingPouncerAbility( + Zone.BATTLEFIELD, + new BoostSourceEffect(1, 3, Duration.EndOfTurn), + new ManaCostsImpl("{G/U}"), + new OpponentControlsPermanentCondition(filter), + "{G/U}: {this} gets +1/+3 and gains flying until end of turn. Activate this ability only once each turn and only if an opponent controls a creature with flying."); + ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn, false, true)); + this.addAbility(ability); } @@ -91,69 +93,48 @@ public class GroundlingPouncer extends CardImpl { } } -class GroundingPouncerCondition implements Condition { +class GroundlingPouncerAbility extends LimitedTimesPerTurnActivatedAbility { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + private static final Effects emptyEffects = new Effects(); - static { - filter.add(new AbilityPredicate(FlyingAbility.class)); + private final Condition condition; + private final String ruleText; + + public GroundlingPouncerAbility(Zone zone, Effect effect, Cost cost, Condition condition, String rule) { + super(zone, effect, cost); + this.condition = condition; + this.ruleText = rule; + } + + public GroundlingPouncerAbility(GroundlingPouncerAbility ability) { + super(ability); + this.condition = ability.condition; + this.ruleText = ability.ruleText; } @Override - public boolean apply(Game game, Ability source) { - ActivatedAbilityUsedThisTurnWatcher watcher = (ActivatedAbilityUsedThisTurnWatcher) game.getState().getWatchers().get("ActivatedAbilityUsedThisTurn"); - for (UUID opponentId : game.getOpponents(source.getControllerId())) { - if (game.getBattlefield().countAll(filter, opponentId, game) > 0 && !watcher.getActivatedThisTurn().contains(source.getSourceId())) { - return true; - } + public Effects getEffects(Game game, EffectType effectType) { + if (!condition.apply(game, this)) { + return emptyEffects; } - return false; + return super.getEffects(game, effectType); } @Override - public String toString() { - return "once each turn and only if an opponent controls a flying creature"; - } -} - -class ActivatedAbilityUsedThisTurnWatcher extends Watcher { - - public Set activatedThisTurn = new HashSet<>(); - - public ActivatedAbilityUsedThisTurnWatcher() { - super("ActivatedAbilityUsedThisTurn", WatcherScope.GAME); - } - - public ActivatedAbilityUsedThisTurnWatcher(final ActivatedAbilityUsedThisTurnWatcher watcher) { - super(watcher); - this.activatedThisTurn.addAll(watcher.activatedThisTurn); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { - StackObject stackObject = game.getStack().getStackObject(event.getTargetId()); - if (stackObject != null) { - StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getTargetId()); - if (stackAbility != null && stackAbility.getAbilityType() == AbilityType.ACTIVATED) { - this.activatedThisTurn.add(stackAbility.getOriginalId()); - } - } - } - } - - public Set getActivatedThisTurn() { - return this.activatedThisTurn; - } - - @Override - public ActivatedAbilityUsedThisTurnWatcher copy() { - return new ActivatedAbilityUsedThisTurnWatcher(this); - } - - @Override - public void reset() { - super.reset(); - this.activatedThisTurn.clear(); + public boolean canActivate(UUID playerId, Game game) { + if (!condition.apply(game, this)) { + return false; + } + return super.canActivate(playerId, game); + } + + @Override + public GroundlingPouncerAbility copy() { + return new GroundlingPouncerAbility(this); + } + + @Override + public String getRule() { + return ruleText; } } diff --git a/Mage.Sets/src/mage/sets/timespiral/ChronatogTotem.java b/Mage.Sets/src/mage/sets/timespiral/ChronatogTotem.java index 35c67c7ff6..492a19ee6c 100644 --- a/Mage.Sets/src/mage/sets/timespiral/ChronatogTotem.java +++ b/Mage.Sets/src/mage/sets/timespiral/ChronatogTotem.java @@ -27,35 +27,29 @@ */ package mage.sets.timespiral; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; +import mage.abilities.costs.Cost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.Effects; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.turn.SkipNextTurnSourceEffect; import mage.abilities.mana.BlueManaAbility; import mage.cards.CardImpl; -import mage.constants.AbilityType; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.EffectType; import mage.constants.Rarity; -import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; -import mage.game.stack.StackAbility; -import mage.game.stack.StackObject; -import mage.watchers.Watcher; /** * @@ -74,14 +68,13 @@ public class ChronatogTotem extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new ChronatogTotemToken(), "", Duration.EndOfTurn), new ManaCostsImpl<>("{1}{U}"))); // {0}: Chronatog Totem gets +3/+3 until end of turn. You skip your next turn. Activate this ability only once each turn and only if Chronatog Totem is a creature. - Ability ability = new ConditionalActivatedAbility( + Ability ability = new ChronatogTotemAbility( Zone.BATTLEFIELD, new BoostSourceEffect(3, 3, Duration.EndOfTurn), new ManaCostsImpl<>("{0}"), - new ChronatogTotemCondition(), - "{0}: {this} gets +3/+3 until end of turn. You skip your next turn. Activate this ability only once each turn and only if {this} is a creature"); + new ChronatogTotemCondition()); ability.addEffect(new SkipNextTurnSourceEffect()); - this.addAbility(ability, new ActivatedAbilityUsedThisTurnWatcher()); + this.addAbility(ability); } public ChronatogTotem(final ChronatogTotem card) { @@ -94,6 +87,52 @@ public class ChronatogTotem extends CardImpl { } } +class ChronatogTotemAbility extends LimitedTimesPerTurnActivatedAbility { + + private static final Effects emptyEffects = new Effects(); + + private final Condition condition; + + public ChronatogTotemAbility(Zone zone, Effect effect, Cost cost, Condition condition) { + super(zone, effect, cost); + this.condition = condition; + } + + public ChronatogTotemAbility(ChronatogTotemAbility ability) { + super(ability); + this.condition = ability.condition; + } + + @Override + public Effects getEffects(Game game, EffectType effectType) { + if (!condition.apply(game, this)) { + return emptyEffects; + } + return super.getEffects(game, effectType); + } + + @Override + public boolean canActivate(UUID playerId, Game game) { + if (!condition.apply(game, this)) { + return false; + } + return super.canActivate(playerId, game); + } + + @Override + public ChronatogTotemAbility copy() { + return new ChronatogTotemAbility(this); + } + + @Override + public String getRule() { + StringBuilder sb = new StringBuilder(super.getRule()); + sb.deleteCharAt(sb.length() - 1); // remove last '.' + sb.append(" and only if ").append(condition.toString()).append("."); + return sb.toString(); + } +} + class ChronatogTotemToken extends Token { ChronatogTotemToken() { @@ -111,60 +150,15 @@ class ChronatogTotemCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - ActivatedAbilityUsedThisTurnWatcher watcher = (ActivatedAbilityUsedThisTurnWatcher) game.getState().getWatchers().get("ActivatedAbilityUsedThisTurn"); - if (!watcher.getActivatedThisTurn().contains(source.getOriginalId())) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { - return permanent.getCardType().contains(CardType.CREATURE); - } + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + return permanent.getCardType().contains(CardType.CREATURE); } return false; } @Override public String toString() { - return "once each turn and only if an opponent controls a flying creature"; + return "{this} is a creature"; } } - -class ActivatedAbilityUsedThisTurnWatcher extends Watcher { - - public Set activatedThisTurn = new HashSet<>(0); - - ActivatedAbilityUsedThisTurnWatcher() { - super("ActivatedAbilityUsedThisTurn", WatcherScope.GAME); - } - - ActivatedAbilityUsedThisTurnWatcher(final ActivatedAbilityUsedThisTurnWatcher watcher) { - super(watcher); - this.activatedThisTurn.addAll(watcher.activatedThisTurn); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == EventType.ACTIVATED_ABILITY) { - StackObject stackObject = game.getStack().getStackObject(event.getTargetId()); - if (stackObject != null) { - StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getTargetId()); - if (stackAbility != null && stackAbility.getAbilityType() == AbilityType.ACTIVATED) { - this.activatedThisTurn.add(stackAbility.getOriginalId()); - } - } - } - } - - public Set getActivatedThisTurn() { - return Collections.unmodifiableSet(this.activatedThisTurn); - } - - @Override - public ActivatedAbilityUsedThisTurnWatcher copy() { - return new ActivatedAbilityUsedThisTurnWatcher(this); - } - - @Override - public void reset() { - super.reset(); - this.activatedThisTurn.clear(); - } -} \ No newline at end of file From a6fc9e8299bec50892149e8d14182c51a7e5b8c8 Mon Sep 17 00:00:00 2001 From: Neil Gentleman Date: Sat, 7 Nov 2015 04:00:58 -0800 Subject: [PATCH 5/5] update Bog Gnarr to match Glade Gnarr re: 456c405c11cac3789155adc06662a79225758136 --- .../src/mage/sets/apocalypse/BogGnarr.java | 58 ++++--------------- 1 file changed, 11 insertions(+), 47 deletions(-) diff --git a/Mage.Sets/src/mage/sets/apocalypse/BogGnarr.java b/Mage.Sets/src/mage/sets/apocalypse/BogGnarr.java index efc75cfd61..560c89d024 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/BogGnarr.java +++ b/Mage.Sets/src/mage/sets/apocalypse/BogGnarr.java @@ -31,25 +31,26 @@ package mage.sets.apocalypse; import java.util.UUID; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SpellCastAllTriggeredAbility; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.stack.Spell; /** * @author Loki */ public class BogGnarr extends CardImpl { + private static final FilterSpell filter = new FilterSpell("a black spell"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + public BogGnarr(UUID ownerId) { super(ownerId, 76, "Bog Gnarr", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{G}"); this.expansionSetCode = "APC"; @@ -57,7 +58,9 @@ public class BogGnarr extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); - this.addAbility(new BogGnarrTriggeredAbility()); + + // Whenever a player casts a black spell, Bog Gnarr gets +2/+2 until end of turn. + this.addAbility(new SpellCastAllTriggeredAbility(new BoostSourceEffect(2, 2, Duration.EndOfTurn), filter, false)); } public BogGnarr(final BogGnarr card) { @@ -68,43 +71,4 @@ public class BogGnarr extends CardImpl { public BogGnarr copy() { return new BogGnarr(this); } - } - -class BogGnarrTriggeredAbility extends TriggeredAbilityImpl { - - private static final FilterCard filter = new FilterCard("a black spell"); - - static { - filter.add(new ColorPredicate(ObjectColor.BLACK)); - } - - public BogGnarrTriggeredAbility() { - super(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), false); - } - - public BogGnarrTriggeredAbility(final BogGnarrTriggeredAbility ability) { - super(ability); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.SPELL_CAST; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Spell spell = game.getStack().getSpell(event.getTargetId()); - return spell != null && filter.match(spell, game); - } - - @Override - public String getRule() { - return "Whenever a player casts " + filter.getMessage() + ", " + super.getRule(); - } - - @Override - public BogGnarrTriggeredAbility copy() { - return new BogGnarrTriggeredAbility(this); - } -} \ No newline at end of file