From 214b688fdb11dea13d3b81bfd2a61eceec7839cd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 21 Jul 2021 21:09:07 -0400 Subject: [PATCH] Update effects and abilities which involve tapping permanents for mana (#7679) Abilities which use trigger from or replace tapping for mana now save the permanent in case it leaves the battlefield. fixes #7671, fixes #7770 * Merge fix and additional comments, Winter's Night fixed Co-authored-by: Oleg Agafonov --- Mage.Sets/src/mage/cards/b/BubblingMuck.java | 35 ++-- Mage.Sets/src/mage/cards/c/ChaosMoon.java | 94 +++++----- Mage.Sets/src/mage/cards/c/Contamination.java | 21 ++- Mage.Sets/src/mage/cards/c/CryptGhast.java | 21 +-- Mage.Sets/src/mage/cards/d/DampingSphere.java | 22 ++- Mage.Sets/src/mage/cards/d/DeepWater.java | 23 +-- Mage.Sets/src/mage/cards/d/Desolation.java | 103 ++++++----- .../src/mage/cards/d/DictateOfKarametra.java | 3 +- .../src/mage/cards/e/ExtraplanarLens.java | 3 +- .../src/mage/cards/f/ForbiddenOrchard.java | 48 ++---- .../src/mage/cards/f/ForsakenMonument.java | 13 +- .../src/mage/cards/g/GauntletOfPower.java | 161 ++++++------------ .../src/mage/cards/h/HallOfGemstone.java | 80 ++++----- Mage.Sets/src/mage/cards/h/HarvestMage.java | 34 ++-- Mage.Sets/src/mage/cards/h/HighTide.java | 36 ++-- .../src/mage/cards/i/InfernalDarkness.java | 79 ++------- .../src/mage/cards/m/ManaReflection.java | 12 +- Mage.Sets/src/mage/cards/m/ManaWeb.java | 73 ++++---- .../src/mage/cards/n/NakedSingularity.java | 117 +++++++------ .../src/mage/cards/n/NirkanaRevenant.java | 35 ++-- .../mage/cards/n/NissaWhoShakesTheWorld.java | 15 +- .../src/mage/cards/n/NyxbloomAncient.java | 3 +- Mage.Sets/src/mage/cards/p/PaleMoon.java | 21 +-- Mage.Sets/src/mage/cards/p/PriceOfGlory.java | 68 ++------ .../src/mage/cards/p/PulseOfLlanowar.java | 30 +--- Mage.Sets/src/mage/cards/r/RealityTwist.java | 105 ++++++------ Mage.Sets/src/mage/cards/r/RegalBehemoth.java | 53 ++---- .../src/mage/cards/r/RitualOfSubdual.java | 18 +- Mage.Sets/src/mage/cards/s/SavageFirecat.java | 36 ++-- Mage.Sets/src/mage/cards/s/StormCauldron.java | 19 ++- .../src/mage/cards/t/TreasureNabber.java | 29 ++-- .../mage/cards/v/VorinclexVoiceOfHunger.java | 37 ++-- Mage.Sets/src/mage/cards/w/WintersNight.java | 35 ++-- Mage.Sets/src/mage/cards/z/ZhurTaaDruid.java | 31 ++-- .../cards/replacement/ManaReflectionTest.java | 24 ++- .../single/iko/KinnanBonderProdigyTest.java | 35 ++++ .../cards/triggers/StormCauldronTest.java | 16 ++ .../common/TapForManaAllTriggeredAbility.java | 37 ++-- .../TapForManaAllTriggeredManaAbility.java | 37 ++-- .../TapLandForManaAllTriggeredAbility.java | 69 -------- ...TapLandForManaAllTriggeredManaAbility.java | 57 ------- .../mana/AddManaOfAnyTypeProducedEffect.java | 161 +++++++++--------- .../abilities/effects/mana/ManaEffect.java | 4 +- .../java/mage/abilities/mana/ManaOptions.java | 17 +- .../mageobject/ChosenColorPredicate.java | 31 ++++ .../main/java/mage/game/events/ManaEvent.java | 7 +- .../mage/game/events/TappedForManaEvent.java | 25 +++ 47 files changed, 884 insertions(+), 1149 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/iko/KinnanBonderProdigyTest.java create mode 100644 Mage/src/main/java/mage/filter/predicate/mageobject/ChosenColorPredicate.java create mode 100644 Mage/src/main/java/mage/game/events/TappedForManaEvent.java diff --git a/Mage.Sets/src/mage/cards/b/BubblingMuck.java b/Mage.Sets/src/mage/cards/b/BubblingMuck.java index aa6157e4ee..637eff3352 100644 --- a/Mage.Sets/src/mage/cards/b/BubblingMuck.java +++ b/Mage.Sets/src/mage/cards/b/BubblingMuck.java @@ -1,11 +1,8 @@ - package mage.cards.b; -import java.util.UUID; import mage.Mana; -import mage.abilities.effects.Effect; -import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect; import mage.abilities.mana.DelayedTriggeredManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -13,21 +10,21 @@ import mage.constants.CardType; import mage.constants.ColoredManaSymbol; import mage.constants.Duration; import mage.constants.SubType; -import mage.filter.common.FilterLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author spjspj */ public final class BubblingMuck extends CardImpl { public BubblingMuck(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); // Until end of turn, whenever a player taps a Swamp for mana, that player adds {B}. this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new BubblingMuckTriggeredAbility())); @@ -45,18 +42,12 @@ public final class BubblingMuck extends CardImpl { class BubblingMuckTriggeredAbility extends DelayedTriggeredManaAbility { - private static final FilterLandPermanent filter = new FilterLandPermanent("Swamp"); - - static { - filter.add(SubType.SWAMP.getPredicate()); - } - - public BubblingMuckTriggeredAbility() { + BubblingMuckTriggeredAbility() { super(new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.B), "their"), Duration.EndOfTurn, false); this.usesStack = false; } - public BubblingMuckTriggeredAbility(BubblingMuckTriggeredAbility ability) { + private BubblingMuckTriggeredAbility(BubblingMuckTriggeredAbility ability) { super(ability); } @@ -67,14 +58,12 @@ class BubblingMuckTriggeredAbility extends DelayedTriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (filter.match(land, getSourceId(), getControllerId(), game)) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(land.getControllerId())); - } - return true; + Permanent land = ((TappedForManaEvent) event).getPermanent(); + if (land == null || !land.hasSubtype(SubType.SWAMP, game)) { + return false; } - return false; + getEffects().setTargetPointer(new FixedTarget(land.getControllerId())); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/c/ChaosMoon.java b/Mage.Sets/src/mage/cards/c/ChaosMoon.java index 426f250d58..262bebbf48 100644 --- a/Mage.Sets/src/mage/cards/c/ChaosMoon.java +++ b/Mage.Sets/src/mage/cards/c/ChaosMoon.java @@ -1,35 +1,32 @@ - package mage.cards.c; -import java.util.UUID; - import mage.Mana; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.Effect; -import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; -import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect; import mage.abilities.mana.DelayedTriggeredManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author L_J */ public final class ChaosMoon extends CardImpl { @@ -38,7 +35,7 @@ public final class ChaosMoon extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); // At the beginning of each upkeep, count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ChaosMoonEffect(), TargetController.ANY, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ChaosMoonEffect(), TargetController.ANY, false)); } private ChaosMoon(final ChaosMoon card) { @@ -59,12 +56,16 @@ class ChaosMoonEffect extends OneShotEffect { filter.add(new ColorPredicate(ObjectColor.RED)); } - public ChaosMoonEffect() { + ChaosMoonEffect() { super(Outcome.Neutral); - this.staticText = "count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type"; + this.staticText = "count the number of permanents. If the number is odd, " + + "until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, " + + "that player adds {R} (in addition to the mana the land produces). If the number is even, " + + "until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, " + + "that Mountain produces colorless mana instead of any other type"; } - public ChaosMoonEffect(final ChaosMoonEffect effect) { + private ChaosMoonEffect(final ChaosMoonEffect effect) { super(effect); } @@ -76,37 +77,33 @@ class ChaosMoonEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - int permanentsInPlay = new PermanentsOnBattlefieldCount().calculate(game, source, null); - // Odd - if (permanentsInPlay % 2 != 0) { - game.addEffect(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), source); - new CreateDelayedTriggeredAbilityEffect(new ChaosMoonOddTriggeredAbility()).apply(game, source); - } // Even - else { - game.addEffect(new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter, false), source); - game.addEffect(new ChaosMoonEvenReplacementEffect(), source); - } - return true; + if (player == null) { + return false; } - return false; + int permanentsInPlay = game.getBattlefield().count( + StaticFilters.FILTER_PERMANENT, source.getSourceId(), source.getControllerId(), game + ); + // Odd + if (permanentsInPlay % 2 != 0) { + game.addEffect(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), source); + new CreateDelayedTriggeredAbilityEffect(new ChaosMoonOddTriggeredAbility()).apply(game, source); + } // Even + else { + game.addEffect(new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter, false), source); + game.addEffect(new ChaosMoonEvenReplacementEffect(), source); + } + return true; } } class ChaosMoonOddTriggeredAbility extends DelayedTriggeredManaAbility { - private static final FilterLandPermanent filter = new FilterLandPermanent("Mountain"); - - static { - filter.add(SubType.MOUNTAIN.getPredicate()); - } - - public ChaosMoonOddTriggeredAbility() { + ChaosMoonOddTriggeredAbility() { super(new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.R), "their"), Duration.EndOfTurn, false); this.usesStack = false; } - public ChaosMoonOddTriggeredAbility(ChaosMoonOddTriggeredAbility ability) { + private ChaosMoonOddTriggeredAbility(ChaosMoonOddTriggeredAbility ability) { super(ability); } @@ -117,14 +114,12 @@ class ChaosMoonOddTriggeredAbility extends DelayedTriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (filter.match(land, getSourceId(), getControllerId(), game)) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(land.getControllerId())); - } - return true; + Permanent land = ((TappedForManaEvent) event).getPermanent(); + if (land == null || !land.hasSubtype(SubType.MOUNTAIN, game)) { + return false; } - return false; + this.getEffects().setTargetPointer(new FixedTarget(land.getControllerId())); + return true; } @Override @@ -140,18 +135,12 @@ class ChaosMoonOddTriggeredAbility extends DelayedTriggeredManaAbility { class ChaosMoonEvenReplacementEffect extends ReplacementEffectImpl { - private static final FilterLandPermanent filter = new FilterLandPermanent("Mountain"); - - static { - filter.add(SubType.MOUNTAIN.getPredicate()); - } - ChaosMoonEvenReplacementEffect() { super(Duration.EndOfTurn, Outcome.Neutral); staticText = "Until end of turn, if a Mountain is tapped for mana, it produces colorless mana instead of any other type."; } - ChaosMoonEvenReplacementEffect(final ChaosMoonEvenReplacementEffect effect) { + private ChaosMoonEvenReplacementEffect(final ChaosMoonEvenReplacementEffect effect) { super(effect); } @@ -180,10 +169,7 @@ class ChaosMoonEvenReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && permanent.isLand(game)) { - return filter.match(permanent, game); - } - return false; + Permanent land = ((TappedForManaEvent) event).getPermanent(); + return land != null && land.hasSubtype(SubType.MOUNTAIN, game); } } diff --git a/Mage.Sets/src/mage/cards/c/Contamination.java b/Mage.Sets/src/mage/cards/c/Contamination.java index 5bdaa34fec..154fcb2d82 100644 --- a/Mage.Sets/src/mage/cards/c/Contamination.java +++ b/Mage.Sets/src/mage/cards/c/Contamination.java @@ -1,8 +1,5 @@ - package mage.cards.c; -import java.util.UUID; - import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -13,15 +10,18 @@ import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + +import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; + /** - * * @author emerald000 */ public final class Contamination extends CardImpl { @@ -30,8 +30,11 @@ public final class Contamination extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); // At the beginning of your upkeep, sacrifice Contamination unless you sacrifice a creature. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect( - new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT))), TargetController.YOU, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost( + new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT) + )), TargetController.YOU, false) + ); // If a land is tapped for mana, it produces {B} instead of any other type and amount. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ContaminationReplacementEffect())); @@ -54,7 +57,7 @@ class ContaminationReplacementEffect extends ReplacementEffectImpl { staticText = "If a land is tapped for mana, it produces {B} instead of any other type and amount"; } - ContaminationReplacementEffect(final ContaminationReplacementEffect effect) { + private ContaminationReplacementEffect(final ContaminationReplacementEffect effect) { super(effect); } @@ -83,7 +86,7 @@ class ContaminationReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); return permanent != null && permanent.isLand(game); } } diff --git a/Mage.Sets/src/mage/cards/c/CryptGhast.java b/Mage.Sets/src/mage/cards/c/CryptGhast.java index 8bb21bda4e..8ea4de2135 100644 --- a/Mage.Sets/src/mage/cards/c/CryptGhast.java +++ b/Mage.Sets/src/mage/cards/c/CryptGhast.java @@ -1,6 +1,5 @@ package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.Mana; import mage.abilities.effects.mana.BasicManaEffect; @@ -11,14 +10,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** - * * @author Plopman */ public final class CryptGhast extends CardImpl { @@ -49,18 +48,12 @@ public final class CryptGhast extends CardImpl { class CryptGhastTriggeredAbility extends TriggeredManaAbility { - private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("Swamp"); - - static { - filter.add(SubType.SWAMP.getPredicate()); - } - - public CryptGhastTriggeredAbility() { + CryptGhastTriggeredAbility() { super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.BlackMana(1)), false); this.usesStack = false; } - public CryptGhastTriggeredAbility(CryptGhastTriggeredAbility ability) { + private CryptGhastTriggeredAbility(CryptGhastTriggeredAbility ability) { super(ability); } @@ -71,8 +64,8 @@ class CryptGhastTriggeredAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId()); - return filter.match(land, this.getSourceId(), this.getControllerId(), game); + Permanent land = ((TappedForManaEvent) event).getPermanent(); + return land != null && land.isControlledBy(getControllerId()) && land.hasSubtype(SubType.SWAMP, game); } @Override diff --git a/Mage.Sets/src/mage/cards/d/DampingSphere.java b/Mage.Sets/src/mage/cards/d/DampingSphere.java index f5644682ac..c00393eaf6 100644 --- a/Mage.Sets/src/mage/cards/d/DampingSphere.java +++ b/Mage.Sets/src/mage/cards/d/DampingSphere.java @@ -1,6 +1,5 @@ package mage.cards.d; -import mage.MageObject; import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -8,11 +7,16 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.cost.SpellsCostIncreasingAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; import mage.filter.FilterCard; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; +import mage.game.permanent.Permanent; import mage.util.CardUtil; import mage.watchers.common.CastSpellLastTurnWatcher; @@ -27,10 +31,10 @@ public final class DampingSphere extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // If a land is tapped for two or more mana, it produces {C} instead of any other type and amount. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DampingSphereReplacementEffect())); + this.addAbility(new SimpleStaticAbility(new DampingSphereReplacementEffect())); // Each spell a player casts costs {1} more to cast for each other spell that player has cast this turn. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DampingSphereIncreasementAllEffect()), new CastSpellLastTurnWatcher()); + this.addAbility(new SimpleStaticAbility(new DampingSphereIncreasementAllEffect()), new CastSpellLastTurnWatcher()); } private DampingSphere(final DampingSphere card) { @@ -50,7 +54,7 @@ class DampingSphereReplacementEffect extends ReplacementEffectImpl { staticText = "If a land is tapped for two or more mana, it produces {C} instead of any other type and amount"; } - DampingSphereReplacementEffect(final DampingSphereReplacementEffect effect) { + private DampingSphereReplacementEffect(final DampingSphereReplacementEffect effect) { super(effect); } @@ -79,10 +83,10 @@ class DampingSphereReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - MageObject mageObject = game.getPermanentOrLKIBattlefield(event.getSourceId()); - ManaEvent manaEvent = (ManaEvent) event; + TappedForManaEvent manaEvent = (TappedForManaEvent) event; + Permanent land = manaEvent.getPermanent(); Mana mana = manaEvent.getMana(); - return mageObject != null && mageObject.isLand(game) && mana.count() > 1; + return land != null && land.isLand(game) && mana.count() > 1; } } @@ -93,7 +97,7 @@ class DampingSphereIncreasementAllEffect extends SpellsCostIncreasingAllEffect { this.staticText = "Each spell a player casts costs {1} more to cast for each other spell that player has cast this turn"; } - DampingSphereIncreasementAllEffect(DampingSphereIncreasementAllEffect effect) { + private DampingSphereIncreasementAllEffect(DampingSphereIncreasementAllEffect effect) { super(effect); } diff --git a/Mage.Sets/src/mage/cards/d/DeepWater.java b/Mage.Sets/src/mage/cards/d/DeepWater.java index 784f1e111e..4bff927cf3 100644 --- a/Mage.Sets/src/mage/cards/d/DeepWater.java +++ b/Mage.Sets/src/mage/cards/d/DeepWater.java @@ -1,8 +1,5 @@ - package mage.cards.d; -import java.util.UUID; - import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -13,15 +10,15 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** - * * @author L_J */ public final class DeepWater extends CardImpl { @@ -30,8 +27,7 @@ public final class DeepWater extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}"); // {U}: Until end of turn, if you tap a land you control for mana, it produces {U} instead of any other type. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DeepWaterReplacementEffect(), new ManaCostsImpl("{U}")); - this.addAbility(ability); + this.addAbility(new SimpleActivatedAbility(new DeepWaterReplacementEffect(), new ManaCostsImpl("{U}"))); } private DeepWater(final DeepWater card) { @@ -46,14 +42,12 @@ public final class DeepWater extends CardImpl { class DeepWaterReplacementEffect extends ReplacementEffectImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(); - DeepWaterReplacementEffect() { super(Duration.EndOfTurn, Outcome.Neutral); staticText = "Until end of turn, if you tap a land you control for mana, it produces {U} instead of any other type"; } - DeepWaterReplacementEffect(final DeepWaterReplacementEffect effect) { + private DeepWaterReplacementEffect(final DeepWaterReplacementEffect effect) { super(effect); } @@ -82,10 +76,7 @@ class DeepWaterReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && permanent.isLand(game)) { - return filter.match(permanent, game); - } - return false; + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.isLand(game) && permanent.isControlledBy(source.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/d/Desolation.java b/Mage.Sets/src/mage/cards/d/Desolation.java index 555b54b836..df4346bd95 100644 --- a/Mage.Sets/src/mage/cards/d/Desolation.java +++ b/Mage.Sets/src/mage/cards/d/Desolation.java @@ -6,19 +6,17 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; import mage.watchers.Watcher; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; +import java.util.*; /** * @author L_J @@ -28,9 +26,11 @@ public final class Desolation extends CardImpl { public Desolation(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}"); - // At the beginning of each end step, each player who tapped a land for mana this turn sacrifices a land. Desolation deals 2 damage to each player who sacrificed a Plains this way. - BeginningOfEndStepTriggeredAbility ability = new BeginningOfEndStepTriggeredAbility(new DesolationEffect(), TargetController.ANY, false); - this.addAbility(ability, new DesolationWatcher()); + // At the beginning of each end step, each player who tapped a land for mana this + // turn sacrifices a land. Desolation deals 2 damage to each player who sacrificed a Plains this way. + this.addAbility(new BeginningOfEndStepTriggeredAbility( + new DesolationEffect(), TargetController.ANY, false + ), new DesolationWatcher()); } private Desolation(final Desolation card) { @@ -45,47 +45,49 @@ public final class Desolation extends CardImpl { class DesolationEffect extends OneShotEffect { - private static final FilterPermanent filterPlains = new FilterPermanent(); - - static { - filterPlains.add(SubType.PLAINS.getPredicate()); - } - - public DesolationEffect() { + DesolationEffect() { super(Outcome.Damage); - this.staticText = "each player who tapped a land for mana this turn sacrifices a land. {this} deals 2 damage to each player who sacrificed a Plains this way"; + this.staticText = "each player who tapped a land for mana this turn sacrifices a land. " + + "{this} deals 2 damage to each player who sacrificed a Plains this way"; } - public DesolationEffect(DesolationEffect copy) { + private DesolationEffect(DesolationEffect copy) { super(copy); } @Override public boolean apply(Game game, Ability source) { DesolationWatcher watcher = game.getState().getWatcher(DesolationWatcher.class); - if (watcher != null) { - for (UUID playerId : watcher.getPlayersTappedForMana()) { - Player player = game.getPlayer(playerId); - if (player != null) { - FilterControlledPermanent filter = new FilterControlledPermanent("land"); - filter.add(CardType.LAND.getPredicate()); - filter.add(new ControllerIdPredicate(playerId)); - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); - if (target.canChoose(source.getSourceId(), player.getId(), game)) { - player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - permanent.sacrifice(source, game); - if (filterPlains.match(permanent, game)) { - player.damage(2, source.getSourceId(), source, game); - } - } - } - } - } - return true; + if (watcher == null) { + return false; } - return false; + List permanents = new ArrayList<>(); + for (UUID playerId : watcher.getPlayersTappedForMana()) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + TargetPermanent target = new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND); + target.setNotTarget(true); + if (!target.canChoose(source.getSourceId(), player.getId(), game)) { + continue; + } + player.choose(Outcome.Sacrifice, target, source.getSourceId(), game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanents.add(permanent); + } + } + for (Permanent permanent : permanents) { + Player player = game.getPlayer(permanent.getControllerId()); + if (permanent != null + && permanent.sacrifice(source, game) + && permanent.hasSubtype(SubType.PLAINS, game) + && player != null) { + player.damage(2, source.getSourceId(), source, game); + } + } + return true; } @Override @@ -98,25 +100,19 @@ class DesolationWatcher extends Watcher { private final Set tappedForManaThisTurnPlayers = new HashSet<>(); - public DesolationWatcher() { + DesolationWatcher() { super(WatcherScope.GAME); } - @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.UNTAP_STEP_PRE) { - reset(); + if (event.getType() != GameEvent.EventType.TAPPED_FOR_MANA + && !game.inCheckPlayableState()) { + return; } - if (event.getType() == GameEvent.EventType.TAPPED_FOR_MANA - && !game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA - UUID playerId = event.getPlayerId(); - if (playerId != null) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); // need only info about permanent - if (permanent != null && permanent.isLand(game)) { - tappedForManaThisTurnPlayers.add(playerId); - } - } + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + if (permanent != null) { + tappedForManaThisTurnPlayers.add(permanent.getControllerId()); } } @@ -129,5 +125,4 @@ class DesolationWatcher extends Watcher { super.reset(); tappedForManaThisTurnPlayers.clear(); } - } diff --git a/Mage.Sets/src/mage/cards/d/DictateOfKarametra.java b/Mage.Sets/src/mage/cards/d/DictateOfKarametra.java index 1a5fbc3aff..b2991d43f7 100644 --- a/Mage.Sets/src/mage/cards/d/DictateOfKarametra.java +++ b/Mage.Sets/src/mage/cards/d/DictateOfKarametra.java @@ -1,4 +1,3 @@ - package mage.cards.d; import java.util.UUID; @@ -20,9 +19,9 @@ public final class DictateOfKarametra extends CardImpl { public DictateOfKarametra(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}{G}"); - // Flash this.addAbility(FlashAbility.getInstance()); + // Whenever a player taps a land for mana, that player adds one mana of any type that land produced. this.addAbility(new TapForManaAllTriggeredManaAbility( new AddManaOfAnyTypeProducedEffect(), diff --git a/Mage.Sets/src/mage/cards/e/ExtraplanarLens.java b/Mage.Sets/src/mage/cards/e/ExtraplanarLens.java index e4fefe95b1..71baafc456 100644 --- a/Mage.Sets/src/mage/cards/e/ExtraplanarLens.java +++ b/Mage.Sets/src/mage/cards/e/ExtraplanarLens.java @@ -20,6 +20,7 @@ import mage.filter.common.FilterLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetLandPermanent; @@ -113,7 +114,7 @@ class ExtraplanarLensTriggeredAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent landTappedForMana = game.getPermanentOrLKIBattlefield(event.getSourceId()); // need only info about permanent + Permanent landTappedForMana = ((TappedForManaEvent) event).getPermanent(); // need only info about permanent Permanent extraplanarLens = game.getPermanent(getSourceId()); if (extraplanarLens != null && landTappedForMana != null diff --git a/Mage.Sets/src/mage/cards/f/ForbiddenOrchard.java b/Mage.Sets/src/mage/cards/f/ForbiddenOrchard.java index e16e4fa2ad..06399dd258 100644 --- a/Mage.Sets/src/mage/cards/f/ForbiddenOrchard.java +++ b/Mage.Sets/src/mage/cards/f/ForbiddenOrchard.java @@ -1,35 +1,5 @@ -/* - * - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - * - */ package mage.cards.f; -import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.CreateTokenTargetEffect; import mage.abilities.mana.AnyColorManaAbility; @@ -39,11 +9,14 @@ import mage.constants.CardType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.events.TappedForManaEvent; +import mage.game.permanent.Permanent; import mage.game.permanent.token.SpiritToken; import mage.target.common.TargetOpponent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class ForbiddenOrchard extends CardImpl { @@ -70,12 +43,12 @@ public final class ForbiddenOrchard extends CardImpl { class ForbiddenOrchardTriggeredAbility extends TriggeredAbilityImpl { - public ForbiddenOrchardTriggeredAbility() { + ForbiddenOrchardTriggeredAbility() { super(Zone.BATTLEFIELD, new CreateTokenTargetEffect(new SpiritToken())); this.addTarget(new TargetOpponent()); } - public ForbiddenOrchardTriggeredAbility(final ForbiddenOrchardTriggeredAbility ability) { + private ForbiddenOrchardTriggeredAbility(final ForbiddenOrchardTriggeredAbility ability) { super(ability); } @@ -86,10 +59,14 @@ class ForbiddenOrchardTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA + // it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA + if (game.inCheckPlayableState()) { return false; } - return event.getSourceId().equals(getSourceId()); + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null + && permanent == getSourcePermanentOrLKI(game) + && isControlledBy(event.getPlayerId()); } @Override @@ -101,5 +78,4 @@ class ForbiddenOrchardTriggeredAbility extends TriggeredAbilityImpl { public ForbiddenOrchardTriggeredAbility copy() { return new ForbiddenOrchardTriggeredAbility(this); } - } diff --git a/Mage.Sets/src/mage/cards/f/ForsakenMonument.java b/Mage.Sets/src/mage/cards/f/ForsakenMonument.java index 0c14e320f3..2e6e43cf05 100644 --- a/Mage.Sets/src/mage/cards/f/ForsakenMonument.java +++ b/Mage.Sets/src/mage/cards/f/ForsakenMonument.java @@ -18,7 +18,7 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.ColorlessPredicate; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import java.util.UUID; @@ -80,12 +80,11 @@ class ForsakenMonumentTriggeredManaAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - ManaEvent mEvent = (ManaEvent) event; - if (permanent == null || !mEvent.getPlayerId().equals(getControllerId())) { - return false; - } - return mEvent.getMana().getColorless() > 0; + TappedForManaEvent mEvent = (TappedForManaEvent) event; + Permanent permanent = mEvent.getPermanent(); + return permanent != null + && isControlledBy(event.getPlayerId()) + && mEvent.getMana().getColorless() > 0; } @Override diff --git a/Mage.Sets/src/mage/cards/g/GauntletOfPower.java b/Mage.Sets/src/mage/cards/g/GauntletOfPower.java index 858b4af280..70f1d14a09 100644 --- a/Mage.Sets/src/mage/cards/g/GauntletOfPower.java +++ b/Mage.Sets/src/mage/cards/g/GauntletOfPower.java @@ -5,20 +5,22 @@ import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.ChooseColorEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.mana.AddManaChosenColorEffect; import mage.abilities.effects.mana.ManaEffect; import mage.abilities.mana.TriggeredManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterPermanent; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.ChosenColorPredicate; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; @@ -32,10 +34,11 @@ import java.util.UUID; */ public final class GauntletOfPower extends CardImpl { - private static final FilterLandPermanent filter = new FilterLandPermanent("a basic land"); + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creatures of the chosen color"); static { - filter.add(SuperType.BASIC.getPredicate()); + filter.add(ChosenColorPredicate.TRUE); } public GauntletOfPower(UUID ownerId, CardSetInfo setInfo) { @@ -43,11 +46,14 @@ public final class GauntletOfPower extends CardImpl { // As Gauntlet of Power enters the battlefield, choose a color. this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); + // Creatures of the chosen color get +1/+1. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GauntletOfPowerBoostEffect())); + this.addAbility(new SimpleStaticAbility(new BoostAllEffect( + 1, 1, Duration.WhileOnBattlefield, filter, false + ))); // Whenever a basic land is tapped for mana of the chosen color, its controller adds one mana of that color. - this.addAbility(new GauntletOfPowerTapForManaAllTriggeredAbility(new GauntletOfPowerManaEffect2(), filter, SetTargetPointer.PERMANENT)); + this.addAbility(new GauntletOfPowerTapForManaAllTriggeredAbility()); } private GauntletOfPower(final GauntletOfPower card) { @@ -60,55 +66,14 @@ public final class GauntletOfPower extends CardImpl { } } -class GauntletOfPowerBoostEffect extends ContinuousEffectImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); - - public GauntletOfPowerBoostEffect() { - super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.BoostCreature); - staticText = "Creatures of the chosen color get +1/+1"; - } - - public GauntletOfPowerBoostEffect(final GauntletOfPowerBoostEffect effect) { - super(effect); - } - - @Override - public GauntletOfPowerBoostEffect copy() { - return new GauntletOfPowerBoostEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - ObjectColor color = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); - if (color != null) { - for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - if (perm.getColor(game).contains(color)) { - perm.addPower(1); - perm.addToughness(1); - } - } - } - return true; - } - -} - class GauntletOfPowerTapForManaAllTriggeredAbility extends TriggeredManaAbility { - private final FilterPermanent filter; - private final SetTargetPointer setTargetPointer; - - public GauntletOfPowerTapForManaAllTriggeredAbility(ManaEffect effect, FilterPermanent filter, SetTargetPointer setTargetPointer) { - super(Zone.BATTLEFIELD, effect, false); - this.filter = filter; - this.setTargetPointer = setTargetPointer; + GauntletOfPowerTapForManaAllTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddManaChosenColorEffect(), false); } - public GauntletOfPowerTapForManaAllTriggeredAbility(GauntletOfPowerTapForManaAllTriggeredAbility ability) { + private GauntletOfPowerTapForManaAllTriggeredAbility(GauntletOfPowerTapForManaAllTriggeredAbility ability) { super(ability); - this.filter = ability.filter.copy(); - this.setTargetPointer = ability.setTargetPointer; } @Override @@ -118,42 +83,27 @@ class GauntletOfPowerTapForManaAllTriggeredAbility extends TriggeredManaAbility @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) { - ManaEvent mEvent = (ManaEvent) event; - ObjectColor color = (ObjectColor) game.getState().getValue(getSourceId() + "_color"); - if (color != null) { - Mana mana = mEvent.getMana(); - boolean colorFits = false; - if (color.isBlack() && mana.getBlack() > 0) { - colorFits = true; - } else if (color.isBlue() && mana.getBlue() > 0) { - colorFits = true; - } else if (color.isGreen() && mana.getGreen() > 0) { - colorFits = true; - } else if (color.isWhite() && mana.getWhite() > 0) { - colorFits = true; - } else if (color.isRed() && mana.getRed() > 0) { - colorFits = true; - } - if (colorFits) { - - for (Effect effect : getEffects()) { - effect.setValue("mana", mEvent.getMana()); - } - switch (setTargetPointer) { - case PERMANENT: - getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game)); - break; - case PLAYER: - getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getControllerId())); - break; - } - return true; - } - } + TappedForManaEvent mEvent = (TappedForManaEvent) event; + Permanent permanent = mEvent.getPermanent(); + if (permanent == null || !permanent.isLand() || !permanent.isBasic()) { + return false; } - return false; + ObjectColor color = (ObjectColor) game.getState().getValue(getSourceId() + "_color"); + if (color == null) { + return false; + } + Mana mana = mEvent.getMana(); + if ((!color.isBlack() || mana.getBlack() < 1) + && (!color.isBlue() || mana.getBlue() < 1) + && (!color.isGreen() || mana.getGreen() < 1) + && (!color.isWhite() || mana.getWhite() < 1) + && (!color.isRed() || mana.getRed() < 1)) { + return false; + } + + getEffects().setValue("mana", mEvent.getMana()); + getEffects().setTargetPointer(new FixedTarget(permanent, game)); + return true; } @Override @@ -170,12 +120,12 @@ class GauntletOfPowerTapForManaAllTriggeredAbility extends TriggeredManaAbility class GauntletOfPowerManaEffect2 extends ManaEffect { - public GauntletOfPowerManaEffect2() { + GauntletOfPowerManaEffect2() { super(); staticText = "its controller adds one additional mana of that color"; } - public GauntletOfPowerManaEffect2(final GauntletOfPowerManaEffect2 effect) { + private GauntletOfPowerManaEffect2(final GauntletOfPowerManaEffect2 effect) { super(effect); } @@ -191,27 +141,28 @@ class GauntletOfPowerManaEffect2 extends ManaEffect { @Override public List getNetMana(Game game, Ability source) { List netMana = new ArrayList<>(); - if (game != null) { - Mana mana = (Mana) getValue("mana"); - if (mana != null) { - netMana.add(mana.copy()); - } + if (game == null) { + return netMana; } + Mana mana = (Mana) getValue("mana"); + if (mana == null) { + return netMana; + } + netMana.add(mana.copy()); return netMana; } @Override public Mana produceMana(Game game, Ability source) { - if (game != null) { - Permanent land = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); - if (land != null) { - Mana mana = (Mana) getValue("mana"); - if (mana != null) { - return mana.copy(); - } - } + if (game == null) { + return new Mana(); } - return new Mana(); + Permanent land = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); + Mana mana = (Mana) getValue("mana"); + if (land == null || mana == null) { + return new Mana(); + } + return mana.copy(); } @Override diff --git a/Mage.Sets/src/mage/cards/h/HallOfGemstone.java b/Mage.Sets/src/mage/cards/h/HallOfGemstone.java index 42f22fb105..dddf161874 100644 --- a/Mage.Sets/src/mage/cards/h/HallOfGemstone.java +++ b/Mage.Sets/src/mage/cards/h/HallOfGemstone.java @@ -12,6 +12,7 @@ import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.util.CardUtil; @@ -30,7 +31,6 @@ public final class HallOfGemstone extends CardImpl { // At the beginning of each player's upkeep, that player chooses a color. Until end of turn, lands tapped for mana produce mana of the chosen color instead of any other color. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new HallOfGemstoneEffect(), TargetController.ACTIVE, false)); - } private HallOfGemstone(final HallOfGemstone card) { @@ -50,7 +50,7 @@ class HallOfGemstoneEffect extends ReplacementEffectImpl { staticText = "that player chooses a color. Until end of turn, lands tapped for mana produce mana of the chosen color instead of any other color"; } - HallOfGemstoneEffect(final HallOfGemstoneEffect effect) { + private HallOfGemstoneEffect(final HallOfGemstoneEffect effect) { super(effect); } @@ -69,50 +69,50 @@ class HallOfGemstoneEffect extends ReplacementEffectImpl { super.init(source, game); Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); Permanent mageObject = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (player != null && mageObject != null) { - ChoiceColor choice = new ChoiceColor(); - if (!player.choose(outcome, choice, game)) { - discard(); - return; - } - if (!game.isSimulation()) { - game.informPlayers(mageObject.getLogName() + ": " + player.getLogName() + " has chosen " + choice.getChoice()); - } - game.getState().setValue(mageObject.getId() + "_color", choice.getColor()); - mageObject.addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen color: " + choice.getChoice()), game); + if (player == null || mageObject == null) { + return; } + ChoiceColor choice = new ChoiceColor(); + if (!player.choose(outcome, choice, game)) { + discard(); + return; + } + game.informPlayers(mageObject.getLogName() + ": " + player.getLogName() + " has chosen " + choice.getChoice()); + game.getState().setValue(mageObject.getId() + "_color", choice.getColor()); + mageObject.addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen color: " + choice.getChoice()), game); } @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { ObjectColor colorChosen = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); - if (colorChosen != null) { - ManaEvent manaEvent = (ManaEvent) event; - Mana mana = manaEvent.getMana(); - // 8/23/2016 Colorless mana added to a player's mana pool isn't affected. - int genericAmount = mana.getGeneric(); - int colorlessAmount = mana.getColorless(); - int coloredAmount = mana.countColored(); - switch (colorChosen.getOneColoredManaSymbol()) { - case W: - mana.setToMana(Mana.WhiteMana(coloredAmount)); - break; - case U: - mana.setToMana(Mana.BlueMana(coloredAmount)); - break; - case B: - mana.setToMana(Mana.BlackMana(coloredAmount)); - break; - case R: - mana.setToMana(Mana.RedMana(coloredAmount)); - break; - case G: - mana.setToMana(Mana.GreenMana(coloredAmount)); - break; - } - mana.setGeneric(genericAmount); - mana.setColorless(colorlessAmount); + if (colorChosen == null) { + return false; } + ManaEvent manaEvent = (ManaEvent) event; + Mana mana = manaEvent.getMana(); + // 8/23/2016 Colorless mana added to a player's mana pool isn't affected. + int genericAmount = mana.getGeneric(); + int colorlessAmount = mana.getColorless(); + int coloredAmount = mana.countColored(); + switch (colorChosen.getOneColoredManaSymbol()) { + case W: + mana.setToMana(Mana.WhiteMana(coloredAmount)); + break; + case U: + mana.setToMana(Mana.BlueMana(coloredAmount)); + break; + case B: + mana.setToMana(Mana.BlackMana(coloredAmount)); + break; + case R: + mana.setToMana(Mana.RedMana(coloredAmount)); + break; + case G: + mana.setToMana(Mana.GreenMana(coloredAmount)); + break; + } + mana.setGeneric(genericAmount); + mana.setColorless(colorlessAmount); return false; } @@ -123,7 +123,7 @@ class HallOfGemstoneEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); return permanent != null && permanent.isLand(game); } } diff --git a/Mage.Sets/src/mage/cards/h/HarvestMage.java b/Mage.Sets/src/mage/cards/h/HarvestMage.java index 3bc13c5fed..a36dbaa41e 100644 --- a/Mage.Sets/src/mage/cards/h/HarvestMage.java +++ b/Mage.Sets/src/mage/cards/h/HarvestMage.java @@ -1,11 +1,10 @@ package mage.cards.h; -import java.util.UUID; import mage.MageInt; import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ReplacementEffectImpl; @@ -13,19 +12,18 @@ import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; +import mage.constants.SubType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; -import mage.target.common.TargetCardInHand; + +import java.util.UUID; /** - * * @author L_J */ public final class HarvestMage extends CardImpl { @@ -38,9 +36,9 @@ public final class HarvestMage extends CardImpl { this.toughness = new MageInt(1); // {G}, {T}, Discard a card: Until end of turn, if you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HarvestMageReplacementEffect(), new ManaCostsImpl("{G}")); + SimpleActivatedAbility ability = new SimpleActivatedAbility(new HarvestMageReplacementEffect(), new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); - ability.addCost(new DiscardTargetCost(new TargetCardInHand())); + ability.addCost(new DiscardCardCost()); this.addAbility(ability); } @@ -56,14 +54,12 @@ public final class HarvestMage extends CardImpl { class HarvestMageReplacementEffect extends ReplacementEffectImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(); - HarvestMageReplacementEffect() { super(Duration.EndOfTurn, Outcome.Neutral); staticText = "Until end of turn, if you tap a land for mana, it produces one mana of a color of your choice instead of any other type and amount"; } - HarvestMageReplacementEffect(final HarvestMageReplacementEffect effect) { + private HarvestMageReplacementEffect(final HarvestMageReplacementEffect effect) { super(effect); } @@ -84,11 +80,10 @@ class HarvestMageReplacementEffect extends ReplacementEffectImpl { if (game != null && game.inCheckPlayableState()) { mana.setToMana(new Mana(0, 0, 0, 0, 0, 0, 1, 0)); return false; - } else { - new AddManaOfAnyColorEffect().apply(game, source); - mana.setToMana(new Mana(0, 0, 0, 0, 0, 0, 0, 0)); - return true; } + new AddManaOfAnyColorEffect().apply(game, source); + mana.setToMana(new Mana(0, 0, 0, 0, 0, 0, 0, 0)); + return true; } @Override @@ -98,10 +93,7 @@ class HarvestMageReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && permanent.isLand(game)) { - return filter.match(permanent, game); - } - return false; + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.isLand(game) && permanent.isControlledBy(source.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/h/HighTide.java b/Mage.Sets/src/mage/cards/h/HighTide.java index f09289773c..02baa76e6c 100644 --- a/Mage.Sets/src/mage/cards/h/HighTide.java +++ b/Mage.Sets/src/mage/cards/h/HighTide.java @@ -1,11 +1,8 @@ - package mage.cards.h; -import java.util.UUID; import mage.Mana; -import mage.abilities.effects.Effect; -import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect; import mage.abilities.mana.DelayedTriggeredManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -13,25 +10,24 @@ import mage.constants.CardType; import mage.constants.ColoredManaSymbol; import mage.constants.Duration; import mage.constants.SubType; -import mage.filter.common.FilterLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author Plopman */ public final class HighTide extends CardImpl { public HighTide(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); // Until end of turn, whenever a player taps an Island for mana, that player adds {U}. this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new HighTideTriggeredAbility())); - } private HighTide(final HighTide card) { @@ -46,18 +42,12 @@ public final class HighTide extends CardImpl { class HighTideTriggeredAbility extends DelayedTriggeredManaAbility { - private static final FilterLandPermanent filter = new FilterLandPermanent("Island"); - - static { - filter.add(SubType.ISLAND.getPredicate()); - } - - public HighTideTriggeredAbility() { + HighTideTriggeredAbility() { super(new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.U), "their"), Duration.EndOfTurn, false); this.usesStack = false; } - public HighTideTriggeredAbility(HighTideTriggeredAbility ability) { + private HighTideTriggeredAbility(HighTideTriggeredAbility ability) { super(ability); } @@ -68,14 +58,12 @@ class HighTideTriggeredAbility extends DelayedTriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (land != null && filter.match(land, game)) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(land.getControllerId())); - } - return true; + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + if (permanent == null || !permanent.hasSubtype(SubType.ISLAND, game)) { + return false; } - return false; + getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId())); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/i/InfernalDarkness.java b/Mage.Sets/src/mage/cards/i/InfernalDarkness.java index 991a7315ec..cd96477d77 100644 --- a/Mage.Sets/src/mage/cards/i/InfernalDarkness.java +++ b/Mage.Sets/src/mage/cards/i/InfernalDarkness.java @@ -1,13 +1,9 @@ - package mage.cards.i; -import java.util.UUID; -import mage.MageObject; import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; +import mage.abilities.costs.CompositeCost; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ReplacementEffectImpl; @@ -17,14 +13,15 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; -import mage.players.Player; +import mage.game.events.TappedForManaEvent; +import mage.game.permanent.Permanent; + +import java.util.UUID; /** - * * @author spjspj */ public final class InfernalDarkness extends CardImpl { @@ -33,11 +30,12 @@ public final class InfernalDarkness extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); // Cumulative upkeep-Pay {B} and 1 life. - this.addAbility(new CumulativeUpkeepAbility(new InfernalDarknessCost())); + this.addAbility(new CumulativeUpkeepAbility(new CompositeCost( + new ManaCostsImpl<>("{B}"), new PayLifeCost(1), "pay {B} and 1 life" + ))); // If a land is tapped for mana, it produces {B} instead of any other type. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfernalDarknessReplacementEffect())); - + this.addAbility(new SimpleStaticAbility(new InfernalDarknessReplacementEffect())); } private InfernalDarkness(final InfernalDarkness card) { @@ -50,59 +48,6 @@ public final class InfernalDarkness extends CardImpl { } } -class InfernalDarknessCost extends CostImpl { - - ManaCostsImpl manaCost = new ManaCostsImpl("{B}"); - Cost lifeCost = new PayLifeCost(1); - - public InfernalDarknessCost() { - this.text = "Pay {B} and 1 life"; - } - - public InfernalDarknessCost(InfernalDarknessCost cost) { - super(cost); - this.manaCost = cost.manaCost; - this.lifeCost = cost.lifeCost; - } - - @Override - public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { - - Player player = game.getPlayer(controllerId); - if (player == null) { - return false; - } - - paid = false; - - manaCost.clearPaid(); - if (manaCost.pay(ability, game, source, player.getId(), false) - && player.canPayLifeCost(ability) - && player.getLife() >= 1 - && lifeCost.pay(ability, game, source, player.getId(), false)) { - paid = true; - } - - return paid; - } - - @Override - public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { - Player player = game.getPlayer(controllerId); - if (player != null - && player.canPayLifeCost(ability) - && player.getLife() >= 1) { - return true; - } - return false; - } - - @Override - public InfernalDarknessCost copy() { - return new InfernalDarknessCost(this); - } -} - class InfernalDarknessReplacementEffect extends ReplacementEffectImpl { InfernalDarknessReplacementEffect() { @@ -110,7 +55,7 @@ class InfernalDarknessReplacementEffect extends ReplacementEffectImpl { staticText = "If a land is tapped for mana, it produces {B} instead of any other type"; } - InfernalDarknessReplacementEffect(final InfernalDarknessReplacementEffect effect) { + private InfernalDarknessReplacementEffect(final InfernalDarknessReplacementEffect effect) { super(effect); } @@ -139,7 +84,7 @@ class InfernalDarknessReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - MageObject mageObject = game.getPermanentOrLKIBattlefield(event.getSourceId()); - return mageObject != null && mageObject.isLand(game); + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.isLand(game); } } diff --git a/Mage.Sets/src/mage/cards/m/ManaReflection.java b/Mage.Sets/src/mage/cards/m/ManaReflection.java index 4d27f4b98e..51792dc9a4 100644 --- a/Mage.Sets/src/mage/cards/m/ManaReflection.java +++ b/Mage.Sets/src/mage/cards/m/ManaReflection.java @@ -6,7 +6,10 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.ManaType; +import mage.constants.Outcome; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; @@ -23,7 +26,7 @@ public final class ManaReflection extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}{G}"); // If you tap a permanent for mana, it produces twice as much of that mana instead. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ManaReflectionReplacementEffect())); + this.addAbility(new SimpleStaticAbility(new ManaReflectionReplacementEffect())); } private ManaReflection(final ManaReflection card) { @@ -43,7 +46,7 @@ class ManaReflectionReplacementEffect extends ReplacementEffectImpl { staticText = "If you tap a permanent for mana, it produces twice as much of that mana instead"; } - ManaReflectionReplacementEffect(ManaReflectionReplacementEffect effect) { + private ManaReflectionReplacementEffect(ManaReflectionReplacementEffect effect) { super(effect); } @@ -83,8 +86,7 @@ class ManaReflectionReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getPlayerId().equals(source.getControllerId()) - && game.getPermanentOrLKIBattlefield(event.getSourceId()) != null; + return source.isControlledBy(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/m/ManaWeb.java b/Mage.Sets/src/mage/cards/m/ManaWeb.java index 1732303ae8..4e1709a9cc 100644 --- a/Mage.Sets/src/mage/cards/m/ManaWeb.java +++ b/Mage.Sets/src/mage/cards/m/ManaWeb.java @@ -1,9 +1,5 @@ - package mage.cards.m; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.OneShotEffect; @@ -14,11 +10,15 @@ import mage.constants.CardType; import mage.constants.ManaType; import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.common.FilterLandPermanent; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; + +import java.util.Collections; +import java.util.Set; +import java.util.UUID; /** * @author spjspj @@ -44,13 +44,14 @@ public final class ManaWeb extends CardImpl { class ManaWebTriggeredAbility extends TriggeredAbilityImpl { - public ManaWebTriggeredAbility() { + ManaWebTriggeredAbility() { super(Zone.BATTLEFIELD, new ManaWebeffect(), false); } - private static final String staticText = "Whenever a land an opponent controls is tapped for mana, tap all lands that player controls that could produce any type of mana that land could produce."; + private static final String staticText = "Whenever a land an opponent controls is tapped for mana, " + + "tap all lands that player controls that could produce any type of mana that land could produce."; - public ManaWebTriggeredAbility(ManaWebTriggeredAbility ability) { + private ManaWebTriggeredAbility(ManaWebTriggeredAbility ability) { super(ability); } @@ -61,17 +62,18 @@ class ManaWebTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { + // it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA if (game.inCheckPlayableState()) { return false; } - if (game.getOpponents(controllerId).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && permanent.isLand(game)) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getSourceId())); - return true; - } + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + if (permanent == null + || !permanent.isLand(game) + || !game.getOpponents(permanent.getControllerId()).contains(getControllerId())) { + return false; } - return false; + this.getEffects().setValue("tappedPermanent", permanent); + return true; } @Override @@ -87,14 +89,11 @@ class ManaWebTriggeredAbility extends TriggeredAbilityImpl { class ManaWebeffect extends OneShotEffect { - private static final FilterLandPermanent filter = new FilterLandPermanent("an opponent taps a land"); - - public ManaWebeffect() { + ManaWebeffect() { super(Outcome.Tap); - staticText = "Whenever a land an opponent controls is tapped for mana, tap all lands that player controls that could produce any type of mana that land could produce."; } - public ManaWebeffect(final ManaWebeffect effect) { + private ManaWebeffect(final ManaWebeffect effect) { super(effect); } @@ -105,23 +104,21 @@ class ManaWebeffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null) { - Set manaTypesSource = AnyColorLandsProduceManaAbility.getManaTypesFromPermanent(permanent, game); - boolean tappedLands = false; - for (Permanent opponentPermanent : game.getBattlefield().getActivePermanents(filter, permanent.getControllerId(), game)) { - if (Objects.equals(opponentPermanent.getControllerId(), permanent.getControllerId())) { - Set manaTypes = AnyColorLandsProduceManaAbility.getManaTypesFromPermanent(opponentPermanent, game); - for (ManaType manaType : manaTypes) { - if (manaTypesSource.contains(manaType)) { - tappedLands = opponentPermanent.tap(source, game) || tappedLands; - break; - } - } - } - } - return tappedLands; + Permanent permanent = (Permanent) getValue("tappedPermanent"); + if (permanent == null) { + return false; } - return false; + Set manaTypesSource = AnyColorLandsProduceManaAbility.getManaTypesFromPermanent(permanent, game); + boolean tappedLands = false; + for (Permanent opponentPermanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, + permanent.getControllerId(), source.getSourceId(), game + )) { + Set manaTypes = AnyColorLandsProduceManaAbility.getManaTypesFromPermanent(opponentPermanent, game); + if (!Collections.disjoint(manaTypes, manaTypesSource)) { + opponentPermanent.tap(source, game); + } + } + return tappedLands; } } diff --git a/Mage.Sets/src/mage/cards/n/NakedSingularity.java b/Mage.Sets/src/mage/cards/n/NakedSingularity.java index 61bcea645e..25a7e00a9d 100644 --- a/Mage.Sets/src/mage/cards/n/NakedSingularity.java +++ b/Mage.Sets/src/mage/cards/n/NakedSingularity.java @@ -10,10 +10,13 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.choices.Choice; import mage.choices.ChoiceColor; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -31,7 +34,7 @@ public final class NakedSingularity extends CardImpl { this.addAbility(new CumulativeUpkeepAbility(new GenericManaCost(3))); // If tapped for mana, Plains produce {R}, Islands produce {G}, Swamps produce {W}, Mountains produce {U}, and Forests produce {B} instead of any other type. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new NakedSingularityEffect())); + this.addAbility(new SimpleStaticAbility(new NakedSingularityEffect())); } private NakedSingularity(final NakedSingularity card) { @@ -48,10 +51,11 @@ class NakedSingularityEffect extends ReplacementEffectImpl { NakedSingularityEffect() { super(Duration.WhileOnBattlefield, Outcome.Neutral); - staticText = "If tapped for mana, Plains produce {R}, Islands produce {G}, Swamps produce {W}, Mountains produce {U}, and Forests produce {B} instead of any other type"; + staticText = "If tapped for mana, Plains produce {R}, Islands produce {G}, Swamps produce {W}, " + + "Mountains produce {U}, and Forests produce {B} instead of any other type"; } - NakedSingularityEffect(final NakedSingularityEffect effect) { + private NakedSingularityEffect(final NakedSingularityEffect effect) { super(effect); } @@ -67,57 +71,58 @@ class NakedSingularityEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { + TappedForManaEvent manaEvent = (TappedForManaEvent) event; Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Permanent permanent = game.getPermanent(event.getSourceId()); - Choice choice = new ChoiceColor(true); - choice.getChoices().clear(); - choice.setMessage("Pick a color to produce"); - if (permanent.hasSubtype(SubType.PLAINS, game)) { - choice.getChoices().add("Red"); - } - if (permanent.hasSubtype(SubType.ISLAND, game)) { - choice.getChoices().add("Green"); - } - if (permanent.hasSubtype(SubType.SWAMP, game)) { - choice.getChoices().add("White"); - } - if (permanent.hasSubtype(SubType.MOUNTAIN, game)) { - choice.getChoices().add("Blue"); - } - if (permanent.hasSubtype(SubType.FOREST, game)) { - choice.getChoices().add("Black"); - } - String chosenColor; - if (choice.getChoices().size() == 1) { - chosenColor = choice.getChoices().iterator().next(); - } else { - controller.choose(Outcome.PutManaInPool, choice, game); - chosenColor = choice.getChoice(); - } - if (chosenColor == null) { - return false; - } - ManaEvent manaEvent = (ManaEvent) event; - Mana mana = manaEvent.getMana(); - int amount = mana.count(); - switch (chosenColor) { - case "White": - mana.setToMana(Mana.WhiteMana(amount)); - break; - case "Blue": - mana.setToMana(Mana.BlueMana(amount)); - break; - case "Black": - mana.setToMana(Mana.BlackMana(amount)); - break; - case "Red": - mana.setToMana(Mana.RedMana(amount)); - break; - case "Green": - mana.setToMana(Mana.GreenMana(amount)); - break; - } + Permanent permanent = manaEvent.getPermanent(); + if (controller == null || permanent == null) { + return false; + } + Choice choice = new ChoiceColor(true); + choice.getChoices().clear(); + choice.setMessage("Pick a color to produce"); + if (permanent.hasSubtype(SubType.PLAINS, game)) { + choice.getChoices().add("Red"); + } + if (permanent.hasSubtype(SubType.ISLAND, game)) { + choice.getChoices().add("Green"); + } + if (permanent.hasSubtype(SubType.SWAMP, game)) { + choice.getChoices().add("White"); + } + if (permanent.hasSubtype(SubType.MOUNTAIN, game)) { + choice.getChoices().add("Blue"); + } + if (permanent.hasSubtype(SubType.FOREST, game)) { + choice.getChoices().add("Black"); + } + String chosenColor; + if (choice.getChoices().size() == 1) { + chosenColor = choice.getChoices().iterator().next(); + } else { + controller.choose(Outcome.PutManaInPool, choice, game); + chosenColor = choice.getChoice(); + } + if (chosenColor == null) { + return false; + } + Mana mana = manaEvent.getMana(); + int amount = mana.count(); + switch (chosenColor) { + case "White": + mana.setToMana(Mana.WhiteMana(amount)); + break; + case "Blue": + mana.setToMana(Mana.BlueMana(amount)); + break; + case "Black": + mana.setToMana(Mana.BlackMana(amount)); + break; + case "Red": + mana.setToMana(Mana.RedMana(amount)); + break; + case "Green": + mana.setToMana(Mana.GreenMana(amount)); + break; } return false; } @@ -129,7 +134,7 @@ class NakedSingularityEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); return permanent != null && (permanent.hasSubtype(SubType.PLAINS, game) || permanent.hasSubtype(SubType.ISLAND, game) diff --git a/Mage.Sets/src/mage/cards/n/NirkanaRevenant.java b/Mage.Sets/src/mage/cards/n/NirkanaRevenant.java index dea3e416b5..0908b2da04 100644 --- a/Mage.Sets/src/mage/cards/n/NirkanaRevenant.java +++ b/Mage.Sets/src/mage/cards/n/NirkanaRevenant.java @@ -1,13 +1,11 @@ - package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.Mana; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.mana.TriggeredManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -15,20 +13,20 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class NirkanaRevenant extends CardImpl { public NirkanaRevenant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.SHADE); @@ -39,7 +37,9 @@ public final class NirkanaRevenant extends CardImpl { this.addAbility(new NirkanaRevenantTriggeredAbility()); // {B}: Nirkana Revenant gets +1/+1 until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{B}"))); + this.addAbility(new SimpleActivatedAbility( + new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{B}") + )); } private NirkanaRevenant(final NirkanaRevenant card) { @@ -53,18 +53,12 @@ public final class NirkanaRevenant extends CardImpl { } class NirkanaRevenantTriggeredAbility extends TriggeredManaAbility { - - private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("Swamp"); - static { - filter.add(SubType.SWAMP.getPredicate()); - } - public NirkanaRevenantTriggeredAbility() { + NirkanaRevenantTriggeredAbility() { super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.BlackMana(1)), false); - this.usesStack = false; } - public NirkanaRevenantTriggeredAbility(NirkanaRevenantTriggeredAbility ability) { + private NirkanaRevenantTriggeredAbility(final NirkanaRevenantTriggeredAbility ability) { super(ability); } @@ -75,8 +69,11 @@ class NirkanaRevenantTriggeredAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId()); - return land != null && filter.match(land, this.getSourceId(), this.getControllerId(), game); + if (!isControlledBy(event.getPlayerId())) { + return false; + } + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.hasSubtype(SubType.SWAMP, game); } @Override @@ -86,6 +83,6 @@ class NirkanaRevenantTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever you tap a Swamp for mana, add {B}."; + return "Whenever you tap a Swamp for mana, add an additional {B}."; } } diff --git a/Mage.Sets/src/mage/cards/n/NissaWhoShakesTheWorld.java b/Mage.Sets/src/mage/cards/n/NissaWhoShakesTheWorld.java index e225bf8c73..3f85834cac 100644 --- a/Mage.Sets/src/mage/cards/n/NissaWhoShakesTheWorld.java +++ b/Mage.Sets/src/mage/cards/n/NissaWhoShakesTheWorld.java @@ -25,6 +25,7 @@ import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.command.emblems.NissaWhoShakesTheWorldEmblem; import mage.game.events.GameEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.game.permanent.token.TokenImpl; import mage.target.TargetPermanent; @@ -87,15 +88,8 @@ public final class NissaWhoShakesTheWorld extends CardImpl { class NissaWhoShakesTheWorldTriggeredAbility extends TriggeredManaAbility { - private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("Forest"); - - static { - filter.add(SubType.FOREST.getPredicate()); - } - NissaWhoShakesTheWorldTriggeredAbility() { super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.GreenMana(1)), false); - this.usesStack = false; } private NissaWhoShakesTheWorldTriggeredAbility(final NissaWhoShakesTheWorldTriggeredAbility ability) { @@ -109,8 +103,11 @@ class NissaWhoShakesTheWorldTriggeredAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent land = game.getPermanentOrLKIBattlefield(event.getTargetId()); - return land != null && filter.match(land, this.getSourceId(), this.getControllerId(), game); + if (!isControlledBy(event.getPlayerId())) { + return false; + } + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.hasSubtype(SubType.FOREST, game); } @Override diff --git a/Mage.Sets/src/mage/cards/n/NyxbloomAncient.java b/Mage.Sets/src/mage/cards/n/NyxbloomAncient.java index 13207b0079..87dd4246ab 100644 --- a/Mage.Sets/src/mage/cards/n/NyxbloomAncient.java +++ b/Mage.Sets/src/mage/cards/n/NyxbloomAncient.java @@ -92,8 +92,7 @@ class NyxbloomAncientReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getPlayerId().equals(source.getControllerId()) - && game.getPermanentOrLKIBattlefield(event.getSourceId()) != null; + return source.isControlledBy(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/p/PaleMoon.java b/Mage.Sets/src/mage/cards/p/PaleMoon.java index 48a5f4e42a..bcf7a2e3e3 100644 --- a/Mage.Sets/src/mage/cards/p/PaleMoon.java +++ b/Mage.Sets/src/mage/cards/p/PaleMoon.java @@ -1,8 +1,5 @@ - package mage.cards.p; -import java.util.UUID; - import mage.Mana; import mage.abilities.Ability; import mage.abilities.effects.ReplacementEffectImpl; @@ -11,20 +8,21 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.filter.common.FilterLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** - * * @author L_J */ public final class PaleMoon extends CardImpl { public PaleMoon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Until end of turn, if a player taps a nonbasic land for mana, it produces colorless mana instead of any other type. this.getSpellAbility().addEffect(new PaleMoonReplacementEffect()); @@ -42,14 +40,12 @@ public final class PaleMoon extends CardImpl { class PaleMoonReplacementEffect extends ReplacementEffectImpl { - private static final FilterLandPermanent filter = FilterLandPermanent.nonbasicLands(); - PaleMoonReplacementEffect() { super(Duration.EndOfTurn, Outcome.Neutral); staticText = "Until end of turn, if a player taps a nonbasic land for mana, it produces colorless mana instead of any other type"; } - PaleMoonReplacementEffect(final PaleMoonReplacementEffect effect) { + private PaleMoonReplacementEffect(final PaleMoonReplacementEffect effect) { super(effect); } @@ -78,10 +74,7 @@ class PaleMoonReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && permanent.isLand(game)) { - return filter.match(permanent, game); - } - return false; + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.isLand(game) && !permanent.isBasic(); } } diff --git a/Mage.Sets/src/mage/cards/p/PriceOfGlory.java b/Mage.Sets/src/mage/cards/p/PriceOfGlory.java index f6c14910e6..b3e94df9ec 100644 --- a/Mage.Sets/src/mage/cards/p/PriceOfGlory.java +++ b/Mage.Sets/src/mage/cards/p/PriceOfGlory.java @@ -1,20 +1,19 @@ package mage.cards.p; -import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** * @author cbt33, Loki (Heartbeat of Spring) */ @@ -39,37 +38,36 @@ public final class PriceOfGlory extends CardImpl { class PriceOfGloryAbility extends TriggeredAbilityImpl { - private static final String staticText = "Whenever a player taps a land for mana, if it's not that player's turn, destroy that land."; + private static final String staticText = "Whenever a player taps a land for mana, " + + "if it's not that player's turn, destroy that land."; - public PriceOfGloryAbility() { - super(Zone.BATTLEFIELD, new PriceOfGloryEffect()); + PriceOfGloryAbility() { + super(Zone.BATTLEFIELD, new DestroyTargetEffect()); } - public PriceOfGloryAbility(PriceOfGloryAbility ability) { + private PriceOfGloryAbility(final PriceOfGloryAbility ability) { super(ability); } @Override public boolean checkEventType(GameEvent event, Game game) { - if (game.inCheckPlayableState()) { - return false; - } return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA; } @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent == null) { + // it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA + if (game.inCheckPlayableState()) { return false; } - if (permanent.isLand(game) - && game.getState().getPlayersInRange(controllerId, game).contains(permanent.getControllerId()) - && !permanent.isControlledBy(game.getActivePlayerId())) { // intervening if clause - getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game)); - return true; + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + if (permanent == null + || !permanent.isLand(game) + || game.isActivePlayer(event.getPlayerId())) { + return false; } - return false; + getEffects().setTargetPointer(new FixedTarget(permanent, game)); + return true; } @Override @@ -82,33 +80,3 @@ class PriceOfGloryAbility extends TriggeredAbilityImpl { return staticText; } } - -class PriceOfGloryEffect extends OneShotEffect { - - public PriceOfGloryEffect() { - super(Outcome.DestroyPermanent); - staticText = "if it's not that player's turn, destroy that land."; - } - - public PriceOfGloryEffect(final PriceOfGloryEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Permanent land = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (land != null && !land.isControlledBy(game.getActivePlayerId())) { // intervening if clause has to be checked again - land.destroy(source, game, false); - } - return true; - } - return false; - } - - @Override - public PriceOfGloryEffect copy() { - return new PriceOfGloryEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/p/PulseOfLlanowar.java b/Mage.Sets/src/mage/cards/p/PulseOfLlanowar.java index f22455c29d..654a883dd1 100644 --- a/Mage.Sets/src/mage/cards/p/PulseOfLlanowar.java +++ b/Mage.Sets/src/mage/cards/p/PulseOfLlanowar.java @@ -1,8 +1,5 @@ - package mage.cards.p; -import java.util.UUID; - import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -11,18 +8,17 @@ import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SuperType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** - * * @author L_J */ public final class PulseOfLlanowar extends CardImpl { @@ -31,7 +27,7 @@ public final class PulseOfLlanowar extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); // If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PulseOfLlanowarReplacementEffect())); + this.addAbility(new SimpleStaticAbility(new PulseOfLlanowarReplacementEffect())); } private PulseOfLlanowar(final PulseOfLlanowar card) { @@ -46,17 +42,12 @@ public final class PulseOfLlanowar extends CardImpl { class PulseOfLlanowarReplacementEffect extends ReplacementEffectImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent(); - static { - filter.add(SuperType.BASIC.getPredicate()); - } - PulseOfLlanowarReplacementEffect() { super(Duration.WhileOnBattlefield, Outcome.Neutral); staticText = "If a basic land you control is tapped for mana, it produces mana of a color of your choice instead of any other type"; } - PulseOfLlanowarReplacementEffect(final PulseOfLlanowarReplacementEffect effect) { + private PulseOfLlanowarReplacementEffect(final PulseOfLlanowarReplacementEffect effect) { super(effect); } @@ -74,8 +65,8 @@ class PulseOfLlanowarReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { ManaEvent manaEvent = (ManaEvent) event; Mana mana = manaEvent.getMana(); - new AddManaOfAnyColorEffect(mana.count()).apply(game,source); - mana.setToMana(new Mana(0, 0, 0, 0,0, 0,0,0)); + new AddManaOfAnyColorEffect(mana.count()).apply(game, source); + mana.setToMana(new Mana(0, 0, 0, 0, 0, 0, 0, 0)); return true; } @@ -86,10 +77,7 @@ class PulseOfLlanowarReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && permanent.isLand(game)) { - return filter.match(permanent, game); - } - return false; + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.isLand(game) && permanent.isControlledBy(source.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/r/RealityTwist.java b/Mage.Sets/src/mage/cards/r/RealityTwist.java index 4e97b55cde..4308ac7893 100644 --- a/Mage.Sets/src/mage/cards/r/RealityTwist.java +++ b/Mage.Sets/src/mage/cards/r/RealityTwist.java @@ -10,10 +10,13 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.choices.Choice; import mage.choices.ChoiceColor; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -31,7 +34,7 @@ public final class RealityTwist extends CardImpl { this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}{U}{U}"))); // If tapped for mana, Plains produce {R}, Swamps produce {G}, Mountains produce {W}, and Forests produce {B} instead of any other type. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RealityTwistEffect())); + this.addAbility(new SimpleStaticAbility(new RealityTwistEffect())); } private RealityTwist(final RealityTwist card) { @@ -48,10 +51,11 @@ class RealityTwistEffect extends ReplacementEffectImpl { RealityTwistEffect() { super(Duration.WhileOnBattlefield, Outcome.Neutral); - staticText = "If tapped for mana, Plains produce {R}, Swamps produce {G}, Mountains produce {W}, and Forests produce {B} instead of any other type"; + staticText = "If tapped for mana, Plains produce {R}, Swamps produce {G}, " + + "Mountains produce {W}, and Forests produce {B} instead of any other type"; } - RealityTwistEffect(final RealityTwistEffect effect) { + private RealityTwistEffect(final RealityTwistEffect effect) { super(effect); } @@ -67,51 +71,52 @@ class RealityTwistEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { + TappedForManaEvent manaEvent = (TappedForManaEvent) event; Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Permanent permanent = game.getPermanent(event.getSourceId()); - Choice choice = new ChoiceColor(true); - choice.getChoices().clear(); - choice.setMessage("Pick a color to produce"); - if (permanent.hasSubtype(SubType.PLAINS, game)) { - choice.getChoices().add("Red"); - } - if (permanent.hasSubtype(SubType.SWAMP, game)) { - choice.getChoices().add("Green"); - } - if (permanent.hasSubtype(SubType.MOUNTAIN, game)) { - choice.getChoices().add("White"); - } - if (permanent.hasSubtype(SubType.FOREST, game)) { - choice.getChoices().add("Black"); - } - String chosenColor; - if (choice.getChoices().size() == 1) { - chosenColor = choice.getChoices().iterator().next(); - } else { - controller.choose(Outcome.PutManaInPool, choice, game); - chosenColor = choice.getChoice(); - } - if (chosenColor == null) { - return false; - } - ManaEvent manaEvent = (ManaEvent) event; - Mana mana = manaEvent.getMana(); - int amount = mana.count(); - switch (chosenColor) { - case "White": - mana.setToMana(Mana.WhiteMana(amount)); - break; - case "Black": - mana.setToMana(Mana.BlackMana(amount)); - break; - case "Red": - mana.setToMana(Mana.RedMana(amount)); - break; - case "Green": - mana.setToMana(Mana.GreenMana(amount)); - break; - } + Permanent permanent = manaEvent.getPermanent(); + if (controller == null || permanent == null) { + return false; + } + Choice choice = new ChoiceColor(true); + choice.getChoices().clear(); + choice.setMessage("Pick a color to produce"); + if (permanent.hasSubtype(SubType.PLAINS, game)) { + choice.getChoices().add("Red"); + } + if (permanent.hasSubtype(SubType.SWAMP, game)) { + choice.getChoices().add("Green"); + } + if (permanent.hasSubtype(SubType.MOUNTAIN, game)) { + choice.getChoices().add("White"); + } + if (permanent.hasSubtype(SubType.FOREST, game)) { + choice.getChoices().add("Black"); + } + String chosenColor; + if (choice.getChoices().size() == 1) { + chosenColor = choice.getChoices().iterator().next(); + } else { + controller.choose(Outcome.PutManaInPool, choice, game); + chosenColor = choice.getChoice(); + } + if (chosenColor == null) { + return false; + } + Mana mana = manaEvent.getMana(); + int amount = mana.count(); + switch (chosenColor) { + case "White": + mana.setToMana(Mana.WhiteMana(amount)); + break; + case "Black": + mana.setToMana(Mana.BlackMana(amount)); + break; + case "Red": + mana.setToMana(Mana.RedMana(amount)); + break; + case "Green": + mana.setToMana(Mana.GreenMana(amount)); + break; } return false; } @@ -123,7 +128,7 @@ class RealityTwistEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); return permanent != null && (permanent.hasSubtype(SubType.PLAINS, game) || permanent.hasSubtype(SubType.SWAMP, game) diff --git a/Mage.Sets/src/mage/cards/r/RegalBehemoth.java b/Mage.Sets/src/mage/cards/r/RegalBehemoth.java index 23d9066268..d7cf1cc91f 100644 --- a/Mage.Sets/src/mage/cards/r/RegalBehemoth.java +++ b/Mage.Sets/src/mage/cards/r/RegalBehemoth.java @@ -1,13 +1,9 @@ - package mage.cards.r; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.effects.common.BecomesMonarchSourceEffect; -import mage.abilities.effects.mana.ManaEffect; +import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.keyword.TrampleAbility; import mage.abilities.mana.TriggeredManaAbility; import mage.cards.CardImpl; @@ -15,16 +11,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class RegalBehemoth extends CardImpl { @@ -38,15 +32,12 @@ public final class RegalBehemoth extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); + // When Regal Behemoth enters the battlefield, you become the monarch. this.addAbility(new EntersBattlefieldTriggeredAbility(new BecomesMonarchSourceEffect(), false)); // Whenever you tap a land for mana while you're the monarch, add one mana of any color. - ManaEffect manaEffect = new AddManaOfAnyColorEffect(); - manaEffect.setText("add one mana of any color (in addition to the mana the land produces)."); - ManaEffect effect = manaEffect; - this.addAbility(new RegalBehemothTriggeredManaAbility( - effect, new FilterControlledLandPermanent("you tap a land"))); + this.addAbility(new RegalBehemothTriggeredManaAbility()); } private RegalBehemoth(final RegalBehemoth card) { @@ -61,16 +52,12 @@ public final class RegalBehemoth extends CardImpl { class RegalBehemothTriggeredManaAbility extends TriggeredManaAbility { - private final FilterPermanent filter; - - public RegalBehemothTriggeredManaAbility(ManaEffect effect, FilterPermanent filter) { - super(Zone.BATTLEFIELD, effect); - this.filter = filter; + RegalBehemothTriggeredManaAbility() { + super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect()); } - public RegalBehemothTriggeredManaAbility(RegalBehemothTriggeredManaAbility ability) { + private RegalBehemothTriggeredManaAbility(RegalBehemothTriggeredManaAbility ability) { super(ability); - this.filter = ability.filter.copy(); } @Override @@ -80,21 +67,11 @@ class RegalBehemothTriggeredManaAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getMonarchId() != null - && isControlledBy(game.getMonarchId())) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null - && getControllerId() != null - && filter.match(permanent, getSourceId(), getControllerId(), game)) { - ManaEvent mEvent = (ManaEvent) event; - for (Effect effect : getEffects()) { - effect.setValue("mana", mEvent.getMana()); - effect.setTargetPointer(new FixedTarget(permanent, game)); - } - return true; - } + if (!isControlledBy(game.getMonarchId()) || !isControlledBy(event.getPlayerId())) { + return false; } - return false; + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.isLand(game); } @Override @@ -103,7 +80,7 @@ class RegalBehemothTriggeredManaAbility extends TriggeredManaAbility { } @Override - public String getTriggerPhrase() { - return "Whenever you tap a land for mana while you're the monarch, " ; + public String getRule() { + return "Whenever you tap a land for mana while you're the monarch, add one mana of any color."; } } diff --git a/Mage.Sets/src/mage/cards/r/RitualOfSubdual.java b/Mage.Sets/src/mage/cards/r/RitualOfSubdual.java index 377f33f839..0b81209ec9 100644 --- a/Mage.Sets/src/mage/cards/r/RitualOfSubdual.java +++ b/Mage.Sets/src/mage/cards/r/RitualOfSubdual.java @@ -1,8 +1,5 @@ - package mage.cards.r; -import java.util.UUID; -import mage.MageObject; import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -14,13 +11,15 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; +import mage.game.permanent.Permanent; + +import java.util.UUID; /** - * * @author L_J */ public final class RitualOfSubdual extends CardImpl { @@ -32,8 +31,7 @@ public final class RitualOfSubdual extends CardImpl { this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{2}"))); // If a land is tapped for mana, it produces colorless mana instead of any other type. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RitualOfSubdualReplacementEffect())); - + this.addAbility(new SimpleStaticAbility(new RitualOfSubdualReplacementEffect())); } private RitualOfSubdual(final RitualOfSubdual card) { @@ -53,7 +51,7 @@ class RitualOfSubdualReplacementEffect extends ReplacementEffectImpl { staticText = "If a land is tapped for mana, it produces colorless mana instead of any other type."; } - RitualOfSubdualReplacementEffect(final RitualOfSubdualReplacementEffect effect) { + private RitualOfSubdualReplacementEffect(final RitualOfSubdualReplacementEffect effect) { super(effect); } @@ -82,7 +80,7 @@ class RitualOfSubdualReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - MageObject mageObject = game.getPermanentOrLKIBattlefield(event.getSourceId()); - return mageObject != null && mageObject.isLand(game); + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.isLand(game); } } diff --git a/Mage.Sets/src/mage/cards/s/SavageFirecat.java b/Mage.Sets/src/mage/cards/s/SavageFirecat.java index 70ab7dbb45..6c2e30542c 100644 --- a/Mage.Sets/src/mage/cards/s/SavageFirecat.java +++ b/Mage.Sets/src/mage/cards/s/SavageFirecat.java @@ -1,11 +1,8 @@ - package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.keyword.TrampleAbility; @@ -17,16 +14,18 @@ import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** - * * @author cbt33 */ public final class SavageFirecat extends CardImpl { public SavageFirecat(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); this.subtype.add(SubType.ELEMENTAL); this.subtype.add(SubType.CAT); @@ -37,11 +36,13 @@ public final class SavageFirecat extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Savage Firecat enters the battlefield with seven +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(7)))); + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(7)), + "with seven +1/+1 counters on it" + )); // Whenever you tap a land for mana, remove a +1/+1 counter from Savage Firecat. - this.addAbility(new SavageFirecatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P1.createInstance()))); - + this.addAbility(new SavageFirecatTriggeredAbility()); } private SavageFirecat(final SavageFirecat card) { @@ -56,17 +57,17 @@ public final class SavageFirecat extends CardImpl { class SavageFirecatTriggeredAbility extends TriggeredAbilityImpl { - public SavageFirecatTriggeredAbility(Effect effect) { - super(Zone.BATTLEFIELD, effect, false); + SavageFirecatTriggeredAbility() { + super(Zone.BATTLEFIELD, new RemoveCounterSourceEffect(CounterType.P1P1.createInstance()), false); } - public SavageFirecatTriggeredAbility(final SavageFirecatTriggeredAbility ability) { + private SavageFirecatTriggeredAbility(final SavageFirecatTriggeredAbility ability) { super(ability); } @Override public SavageFirecatTriggeredAbility copy() { - return new SavageFirecatTriggeredAbility(this); + return new SavageFirecatTriggeredAbility(this); } @Override @@ -76,17 +77,16 @@ class SavageFirecatTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA + // it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA + if (game.inCheckPlayableState()) { return false; } - - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - return permanent != null && permanent.isLand(game) && event.getPlayerId().equals(this.controllerId); + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null && permanent.isLand(game) && isControlledBy(event.getPlayerId()); } - + @Override public String getRule() { return "Whenever you tap a land for mana, remove a +1/+1 counter from {this}"; } - } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/StormCauldron.java b/Mage.Sets/src/mage/cards/s/StormCauldron.java index 0f42371311..8571988895 100644 --- a/Mage.Sets/src/mage/cards/s/StormCauldron.java +++ b/Mage.Sets/src/mage/cards/s/StormCauldron.java @@ -1,33 +1,34 @@ - package mage.cards.s; -import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.TapLandForManaAllTriggeredAbility; -import mage.abilities.effects.Effect; +import mage.abilities.common.TapForManaAllTriggeredAbility; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.effects.common.continuous.PlayAdditionalLandsAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SetTargetPointer; import mage.constants.Zone; +import mage.filter.StaticFilters; + +import java.util.UUID; /** - * * @author Quercitron */ public final class StormCauldron extends CardImpl { public StormCauldron(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); // Each player may play an additional land during each of their turns. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayAdditionalLandsAllEffect())); // Whenever a land is tapped for mana, return it to its owner's hand. - Effect effect = new ReturnToHandTargetEffect(); - effect.setText("return it to its owner's hand"); - this.addAbility(new TapLandForManaAllTriggeredAbility(effect, false, true, true)); + this.addAbility(new TapForManaAllTriggeredAbility( + new ReturnToHandTargetEffect().setText("return it to its owner's hand"), + StaticFilters.FILTER_LAND_A, SetTargetPointer.PERMANENT + )); } private StormCauldron(final StormCauldron card) { diff --git a/Mage.Sets/src/mage/cards/t/TreasureNabber.java b/Mage.Sets/src/mage/cards/t/TreasureNabber.java index b285e52ac1..a2703bb638 100644 --- a/Mage.Sets/src/mage/cards/t/TreasureNabber.java +++ b/Mage.Sets/src/mage/cards/t/TreasureNabber.java @@ -9,6 +9,7 @@ import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTargets; @@ -45,32 +46,34 @@ public final class TreasureNabber extends CardImpl { class TreasureNabberAbility extends TriggeredAbilityImpl { - public TreasureNabberAbility() { + TreasureNabberAbility() { super(Zone.BATTLEFIELD, new TreasureNabberEffect()); } - public TreasureNabberAbility(TreasureNabberAbility ability) { + private TreasureNabberAbility(TreasureNabberAbility ability) { super(ability); } @Override public boolean checkEventType(GameEvent event, Game game) { - if (game.inCheckPlayableState()) { - return false; - } return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA; } @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getOpponents(controllerId).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null && permanent.isArtifact(game)) { - getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game)); - return true; - } + // it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA + if (game.inCheckPlayableState()) { + return false; } - return false; + if (!game.getOpponents(controllerId).contains(event.getPlayerId())) { + return false; + } + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + if (permanent == null || !permanent.isArtifact(game)) { + return false; + } + getEffects().setTargetPointer(new FixedTarget(permanent, game)); + return true; } @Override @@ -93,7 +96,7 @@ class TreasureNabberEffect extends ContinuousEffectImpl { this.staticText = "gain control of that artifact until the end of your next turn"; } - TreasureNabberEffect(final TreasureNabberEffect effect) { + private TreasureNabberEffect(final TreasureNabberEffect effect) { super(effect); this.fixedTargets = effect.fixedTargets; } diff --git a/Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java b/Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java index 0b419d7fb1..a53ff67f35 100644 --- a/Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java +++ b/Mage.Sets/src/mage/cards/v/VorinclexVoiceOfHunger.java @@ -1,28 +1,25 @@ package mage.cards.v; -import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.TapForManaAllTriggeredManaAbility; import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; -import mage.abilities.effects.mana.ManaEffect; import mage.abilities.effects.mana.AddManaOfAnyTypeProducedEffect; +import mage.abilities.effects.mana.ManaEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SetTargetPointer; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author BetaSteward */ public final class VorinclexVoiceOfHunger extends CardImpl { @@ -62,11 +59,11 @@ public final class VorinclexVoiceOfHunger extends CardImpl { class VorinclexTriggeredAbility2 extends TriggeredAbilityImpl { - public VorinclexTriggeredAbility2() { + VorinclexTriggeredAbility2() { super(Zone.BATTLEFIELD, new DontUntapInControllersNextUntapStepTargetEffect()); } - public VorinclexTriggeredAbility2(VorinclexTriggeredAbility2 ability) { + private VorinclexTriggeredAbility2(final VorinclexTriggeredAbility2 ability) { super(ability); } @@ -77,17 +74,19 @@ class VorinclexTriggeredAbility2 extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA + // it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA + if (game.inCheckPlayableState()) { return false; - } - if (game.getOpponents(getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null && permanent.isLand(game)) { - getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game)); - return true; - } } - return false; + if (!game.getOpponents(getControllerId()).contains(event.getPlayerId())) { + return false; + } + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + if (permanent == null || !permanent.isLand(game)) { + return false; + } + getEffects().setTargetPointer(new FixedTarget(permanent, game)); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/w/WintersNight.java b/Mage.Sets/src/mage/cards/w/WintersNight.java index c9fa67c5a3..4fcf52146c 100644 --- a/Mage.Sets/src/mage/cards/w/WintersNight.java +++ b/Mage.Sets/src/mage/cards/w/WintersNight.java @@ -1,13 +1,9 @@ - package mage.cards.w; -import java.util.UUID; -import mage.abilities.Ability; +import mage.abilities.common.TapForManaAllTriggeredAbility; import mage.abilities.common.TapForManaAllTriggeredManaAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.mana.AddManaOfAnyTypeProducedEffect; import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; -import mage.abilities.effects.mana.ManaEffect; +import mage.abilities.effects.mana.AddManaOfAnyTypeProducedEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -15,31 +11,36 @@ import mage.constants.SetTargetPointer; import mage.constants.SuperType; import mage.filter.common.FilterLandPermanent; +import java.util.UUID; + /** - * * @author L_J */ public final class WintersNight extends CardImpl { - + private static final FilterLandPermanent filter = new FilterLandPermanent("a player taps a snow land"); - + static { filter.add(SuperType.SNOW.getPredicate()); } public WintersNight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}{G}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{G}{W}"); addSuperType(SuperType.WORLD); // Whenever a player taps a snow land for mana, that player adds one mana of any type that land produced. // That land doesn't untap during its controller's next untap step. - ManaEffect effect = new AddManaOfAnyTypeProducedEffect(); - effect.setText("that player adds one mana of any type that land produced"); - Ability ability = new TapForManaAllTriggeredManaAbility(effect, filter, SetTargetPointer.PERMANENT); - Effect effect2 = new DontUntapInControllersNextUntapStepTargetEffect(); - effect2.setText("That land doesn't untap during its controller's next untap step"); - ability.addEffect(effect2); - this.addAbility(ability); + this.addAbility(new TapForManaAllTriggeredManaAbility( + new AddManaOfAnyTypeProducedEffect().setText("that player adds one mana of any type that land produced"), + filter, + SetTargetPointer.PERMANENT + )); + + this.addAbility(new TapForManaAllTriggeredAbility( + new DontUntapInControllersNextUntapStepTargetEffect().setText("that land doesn't untap during its controller's next untap step"), + filter, + SetTargetPointer.PERMANENT + )); } private WintersNight(final WintersNight card) { diff --git a/Mage.Sets/src/mage/cards/z/ZhurTaaDruid.java b/Mage.Sets/src/mage/cards/z/ZhurTaaDruid.java index d779b1a58e..2f2b8259b1 100644 --- a/Mage.Sets/src/mage/cards/z/ZhurTaaDruid.java +++ b/Mage.Sets/src/mage/cards/z/ZhurTaaDruid.java @@ -1,7 +1,5 @@ - package mage.cards.z; -import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.common.DamagePlayersEffect; @@ -14,16 +12,18 @@ import mage.constants.TargetController; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; +import mage.game.events.TappedForManaEvent; +import mage.game.permanent.Permanent; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class ZhurTaaDruid extends CardImpl { public ZhurTaaDruid(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}"); this.subtype.add(SubType.HUMAN, SubType.DRUID); this.power = new MageInt(1); @@ -31,9 +31,9 @@ public final class ZhurTaaDruid extends CardImpl { // {T}: Add {G}. this.addAbility(new GreenManaAbility()); + // Whenever you tap Zhur-Taa Druid for mana, it deals 1 damage to each opponent. this.addAbility(new ZhurTaaDruidAbility()); - } private ZhurTaaDruid(final ZhurTaaDruid card) { @@ -48,25 +48,29 @@ public final class ZhurTaaDruid extends CardImpl { class ZhurTaaDruidAbility extends TriggeredAbilityImpl { - public ZhurTaaDruidAbility() { - super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT, "it")); + ZhurTaaDruidAbility() { + super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT)); } - public ZhurTaaDruidAbility(final ZhurTaaDruidAbility ability) { + private ZhurTaaDruidAbility(final ZhurTaaDruidAbility ability) { super(ability); } @Override public boolean checkEventType(GameEvent event, Game game) { - if (game.inCheckPlayableState()) { - return false; - } return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA; } @Override public boolean checkTrigger(GameEvent event, Game game) { - return event.getSourceId().equals(getSourceId()); + // it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA + if (game.inCheckPlayableState()) { + return false; + } + Permanent permanent = ((TappedForManaEvent) event).getPermanent(); + return permanent != null + && permanent == getSourcePermanentOrLKI(game) + && isControlledBy(event.getPlayerId()); } @Override @@ -78,5 +82,4 @@ class ZhurTaaDruidAbility extends TriggeredAbilityImpl { public ZhurTaaDruidAbility copy() { return new ZhurTaaDruidAbility(this); } - } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ManaReflectionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ManaReflectionTest.java index 7ff304ebdf..c1a2e946e3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ManaReflectionTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/ManaReflectionTest.java @@ -8,6 +8,7 @@ import mage.counters.CounterType; import org.junit.Assert; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; + import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions; import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions; @@ -58,7 +59,7 @@ public class ManaReflectionTest extends CardTestPlayerBase { assertManaPool(playerA, ManaType.GREEN, 2); } - + @Test public void ManaReflectionWithGoblinClearcutterTest() { // If you tap a permanent for mana, it produces twice as much of that mana instead. @@ -66,10 +67,10 @@ public class ManaReflectionTest extends CardTestPlayerBase { // {T}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G}. addCard(Zone.BATTLEFIELD, playerA, "Goblin Clearcutter"); addCard(Zone.BATTLEFIELD, playerA, "Forest"); - + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); execute(); - + ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); assertDuplicatedManaOptions(manaOptions); @@ -79,5 +80,20 @@ public class ManaReflectionTest extends CardTestPlayerBase { assertManaOptions("{R}{R}{G}{G}{G}{G}{G}{G}", manaOptions); assertManaOptions("{G}{G}{G}{G}{G}{G}{G}{G}", manaOptions); } - + + @Test + public void ManaReflectionWithHavenwoodBattlegroundTest() { + // If you tap a permanent for mana, it produces twice as much of that mana instead. + addCard(Zone.BATTLEFIELD, playerA, "Mana Reflection"); + // {T}, Sacrifice Havenwood Battleground: Add {G}{G}. + addCard(Zone.BATTLEFIELD, playerA, "Havenwood Battleground"); + addCard(Zone.BATTLEFIELD, playerA, "Upwelling"); // Prevent mana from emptying before we can check it + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice"); + + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertManaPool(playerA, ManaType.GREEN, 4); + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/KinnanBonderProdigyTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/KinnanBonderProdigyTest.java new file mode 100644 index 0000000000..1a6dd26502 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/KinnanBonderProdigyTest.java @@ -0,0 +1,35 @@ +package org.mage.test.cards.single.iko; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class KinnanBonderProdigyTest extends CardTestPlayerBase { + + private static final String kinnan = "Kinnan, Bonder Prodigy"; + private static final String egg = "Golden Egg"; + private static final String hovermyr = "Hovermyr"; + + @Test + public void testSacrificedPermanent() { + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + addCard(Zone.BATTLEFIELD, playerA, kinnan); + addCard(Zone.BATTLEFIELD, playerA, egg); + addCard(Zone.HAND, playerA, hovermyr); + + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hovermyr); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, hovermyr, 1); + assertPermanentCount(playerA, egg, 0); + assertGraveyardCount(playerA, egg, 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/StormCauldronTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/StormCauldronTest.java index 228983b70a..2345625cd3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/StormCauldronTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/StormCauldronTest.java @@ -10,6 +10,22 @@ import org.mage.test.serverside.base.CardTestPlayerBase; */ public class StormCauldronTest extends CardTestPlayerBase { + @Test + public void testRegular() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerA, "Storm Cauldron", 1); + + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertHandCount(playerA, "Mountain", 1); + assertPermanentCount(playerA, "Mountain", 0); + } + /** * With Storm Cauldron in play (owned by opponent), I sacced Crystal Vein * for 2 mana... except it got returned to my hand, which shouldn't happen. diff --git a/Mage/src/main/java/mage/abilities/common/TapForManaAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/TapForManaAllTriggeredAbility.java index aafc5ff424..ca588d70d8 100644 --- a/Mage/src/main/java/mage/abilities/common/TapForManaAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/TapForManaAllTriggeredAbility.java @@ -8,11 +8,12 @@ import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** + * Non mana triggered ability (use case: you must apply non mana effects on mana taps like gain life) * * @author LevelX2 */ @@ -41,26 +42,26 @@ public class TapForManaAllTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA + // it's non mana triggered ability, so ignore it on checking, see TAPPED_FOR_MANA + if (game.inCheckPlayableState()) { return false; } - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (filter.match(permanent, getSourceId(), getControllerId(), game)) { - ManaEvent mEvent = (ManaEvent) event; - for(Effect effect:getEffects()) { - effect.setValue("mana", mEvent.getMana()); - } - switch(setTargetPointer) { - case PERMANENT: - getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game)); - break; - case PLAYER: - getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getControllerId())); - break; - } - return true; + TappedForManaEvent manaEvent = ((TappedForManaEvent) event); + Permanent permanent = manaEvent.getPermanent(); + if (permanent == null || !filter.match(permanent, getSourceId(), getControllerId(), game)) { + return false; } - return false; + getEffects().setValue("mana", manaEvent.getMana()); + getEffects().setValue("tappedPermanent", permanent); + switch (setTargetPointer) { + case PERMANENT: + getEffects().setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game))); + break; + case PLAYER: + getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId())); + break; + } + return true; } @Override diff --git a/Mage/src/main/java/mage/abilities/common/TapForManaAllTriggeredManaAbility.java b/Mage/src/main/java/mage/abilities/common/TapForManaAllTriggeredManaAbility.java index 894300f9e9..8ddf18e7ad 100644 --- a/Mage/src/main/java/mage/abilities/common/TapForManaAllTriggeredManaAbility.java +++ b/Mage/src/main/java/mage/abilities/common/TapForManaAllTriggeredManaAbility.java @@ -1,7 +1,5 @@ - package mage.abilities.common; -import mage.abilities.effects.Effect; import mage.abilities.effects.mana.ManaEffect; import mage.abilities.mana.TriggeredManaAbility; import mage.constants.SetTargetPointer; @@ -9,15 +7,15 @@ import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** + * Mana triggered ability (use case: you must produce new mana on mana taps) * * @author LevelX2 */ - public class TapForManaAllTriggeredManaAbility extends TriggeredManaAbility { private final FilterPermanent filter; @@ -42,23 +40,22 @@ public class TapForManaAllTriggeredManaAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (filter.match(permanent, getSourceId(), getControllerId(), game)) { - ManaEvent mEvent = (ManaEvent) event; - for(Effect effect:getEffects()) { - effect.setValue("mana", mEvent.getMana()); - switch(setTargetPointer) { - case PERMANENT: - effect.setTargetPointer(new FixedTarget(permanent, game)); - break; - case PLAYER: - effect.setTargetPointer(new FixedTarget(permanent.getControllerId())); - break; - } - } - return true; + TappedForManaEvent manaEvent = ((TappedForManaEvent) event); + Permanent permanent = manaEvent.getPermanent(); + if (permanent == null || !filter.match(permanent, getSourceId(), getControllerId(), game)) { + return false; } - return false; + getEffects().setValue("mana", manaEvent.getMana()); + getEffects().setValue("tappedPermanent", permanent); + switch (setTargetPointer) { + case PERMANENT: + getEffects().setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game))); + break; + case PLAYER: + getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId())); + break; + } + return true; } @Override diff --git a/Mage/src/main/java/mage/abilities/common/TapLandForManaAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/TapLandForManaAllTriggeredAbility.java index 68aa3686b2..e69de29bb2 100644 --- a/Mage/src/main/java/mage/abilities/common/TapLandForManaAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/TapLandForManaAllTriggeredAbility.java @@ -1,69 +0,0 @@ - -package mage.abilities.common; - -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; - -/** - * - * @author Quercitron - */ -public class TapLandForManaAllTriggeredAbility extends TriggeredAbilityImpl { - - private final boolean setTargetPointer; - private final boolean landMustExists; - - public TapLandForManaAllTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer, boolean landMustExists) { - super(Zone.BATTLEFIELD, effect, optional); - this.setTargetPointer = setTargetPointer; - this.landMustExists = landMustExists; - } - - public TapLandForManaAllTriggeredAbility(final TapLandForManaAllTriggeredAbility ability) { - super(ability); - this.setTargetPointer = ability.setTargetPointer; - this.landMustExists = ability.landMustExists; - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (game.inCheckPlayableState()) { // Ignored - see GameEvent.TAPPED_FOR_MANA - return false; - } - - Permanent permanent; - if (landMustExists) { - permanent = game.getPermanent(event.getSourceId()); - } else { - permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - } - - if (permanent != null && permanent.isLand(game)) { - if (setTargetPointer) { - getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game)); - } - return true; - } - return false; - } - - @Override - public TapLandForManaAllTriggeredAbility copy() { - return new TapLandForManaAllTriggeredAbility(this); - } - - @Override - public String getTriggerPhrase() { - return "Whenever a land is tapped for mana, "; - } -} diff --git a/Mage/src/main/java/mage/abilities/common/TapLandForManaAllTriggeredManaAbility.java b/Mage/src/main/java/mage/abilities/common/TapLandForManaAllTriggeredManaAbility.java index 0f5d7d9129..e69de29bb2 100644 --- a/Mage/src/main/java/mage/abilities/common/TapLandForManaAllTriggeredManaAbility.java +++ b/Mage/src/main/java/mage/abilities/common/TapLandForManaAllTriggeredManaAbility.java @@ -1,57 +0,0 @@ - - -package mage.abilities.common; - -import mage.abilities.effects.mana.ManaEffect; -import mage.abilities.mana.TriggeredManaAbility; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; - -/** - * - * @author LevelX2 - */ -public class TapLandForManaAllTriggeredManaAbility extends TriggeredManaAbility { - - private final boolean setTargetPointer; - - public TapLandForManaAllTriggeredManaAbility(ManaEffect manaEffect, boolean optional, boolean setTargetPointer) { - super(Zone.BATTLEFIELD, manaEffect, optional); - this.setTargetPointer = setTargetPointer; - } - - public TapLandForManaAllTriggeredManaAbility(final TapLandForManaAllTriggeredManaAbility ability) { - super(ability); - this.setTargetPointer = ability.setTargetPointer; - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TAPPED_FOR_MANA; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && permanent.isLand(game)) { - if (setTargetPointer) { - getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game)); - } - return true; - } - return false; - } - - @Override - public TapLandForManaAllTriggeredManaAbility copy() { - return new TapLandForManaAllTriggeredManaAbility(this); - } - - @Override - public String getTriggerPhrase() { - return "Whenever a player taps a land for mana, "; - } -} diff --git a/Mage/src/main/java/mage/abilities/effects/mana/AddManaOfAnyTypeProducedEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/AddManaOfAnyTypeProducedEffect.java index 16d37675c4..6cfc9cd994 100644 --- a/Mage/src/main/java/mage/abilities/effects/mana/AddManaOfAnyTypeProducedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/mana/AddManaOfAnyTypeProducedEffect.java @@ -27,7 +27,7 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect { @Override public Player getPlayer(Game game, Ability source) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + Permanent permanent = (Permanent) getValue("tappedPermanent"); if (permanent != null) { return game.getPlayer(permanent.getControllerId()); } @@ -38,25 +38,26 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect { public List getNetMana(Game game, Ability source) { List netMana = new ArrayList<>(); Mana types = (Mana) this.getValue("mana"); - if (types != null) { - if (types.getBlack() > 0) { - netMana.add(Mana.BlackMana(1)); - } - if (types.getRed() > 0) { - netMana.add(Mana.RedMana(1)); - } - if (types.getBlue() > 0) { - netMana.add(Mana.BlueMana(1)); - } - if (types.getGreen() > 0) { - netMana.add(Mana.GreenMana(1)); - } - if (types.getWhite() > 0) { - netMana.add(Mana.WhiteMana(1)); - } - if (types.getColorless() > 0) { - netMana.add(Mana.ColorlessMana(1)); - } + if (types == null) { + return netMana; + } + if (types.getBlack() > 0) { + netMana.add(Mana.BlackMana(1)); + } + if (types.getRed() > 0) { + netMana.add(Mana.RedMana(1)); + } + if (types.getBlue() > 0) { + netMana.add(Mana.BlueMana(1)); + } + if (types.getGreen() > 0) { + netMana.add(Mana.GreenMana(1)); + } + if (types.getWhite() > 0) { + netMana.add(Mana.WhiteMana(1)); + } + if (types.getColorless() > 0) { + netMana.add(Mana.ColorlessMana(1)); } return netMana; } @@ -64,68 +65,69 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect { @Override public Mana produceMana(Game game, Ability source) { Mana newMana = new Mana(); - if (game != null) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null) { - Player targetController = game.getPlayer(permanent.getControllerId()); - Mana types = (Mana) this.getValue("mana"); - if (targetController == null || types == null) { - return newMana; - } + if (game == null) { + return newMana; + } + Permanent permanent = (Permanent) this.getValue("tappedPermanent"); + Mana types = (Mana) this.getValue("mana"); + if (permanent == null || types == null) { + return newMana; + } + Player targetController = game.getPlayer(permanent.getControllerId()); + if (targetController == null) { + return newMana; + } - Choice choice = new ChoiceColor(true); - choice.getChoices().clear(); - choice.setMessage("Pick the type of mana to produce"); - if (types.getBlack() > 0) { - choice.getChoices().add("Black"); - } - if (types.getRed() > 0) { - choice.getChoices().add("Red"); - } - if (types.getBlue() > 0) { - choice.getChoices().add("Blue"); - } - if (types.getGreen() > 0) { - choice.getChoices().add("Green"); - } - if (types.getWhite() > 0) { - choice.getChoices().add("White"); - } - if (types.getColorless() > 0) { - choice.getChoices().add("Colorless"); - } + Choice choice = new ChoiceColor(true); + choice.getChoices().clear(); + choice.setMessage("Pick the type of mana to produce"); + if (types.getWhite() > 0) { + choice.getChoices().add("White"); + } + if (types.getBlue() > 0) { + choice.getChoices().add("Blue"); + } + if (types.getBlack() > 0) { + choice.getChoices().add("Black"); + } + if (types.getRed() > 0) { + choice.getChoices().add("Red"); + } + if (types.getGreen() > 0) { + choice.getChoices().add("Green"); + } + if (types.getColorless() > 0) { + choice.getChoices().add("Colorless"); + } - if (!choice.getChoices().isEmpty()) { - if (choice.getChoices().size() == 1) { - choice.setChoice(choice.getChoices().iterator().next()); - } else { - if (!targetController.choose(outcome, choice, game)) { - return newMana; - } - } + if (choice.getChoices().isEmpty()) { + return newMana; + } + if (choice.getChoices().size() != 1 + && !targetController.choose(outcome, choice, game)) { + return newMana; + } + choice.setChoice(choice.getChoices().iterator().next()); - switch (choice.getChoice()) { - case "Black": - newMana.setBlack(1); - break; - case "Blue": - newMana.setBlue(1); - break; - case "Red": - newMana.setRed(1); - break; - case "Green": - newMana.setGreen(1); - break; - case "White": - newMana.setWhite(1); - break; - case "Colorless": - newMana.setColorless(1); - break; - } - } - } + switch (choice.getChoice()) { + case "White": + newMana.setWhite(1); + break; + case "Blue": + newMana.setBlue(1); + break; + case "Black": + newMana.setBlack(1); + break; + case "Red": + newMana.setRed(1); + break; + case "Green": + newMana.setGreen(1); + break; + case "Colorless": + newMana.setColorless(1); + break; } return newMana; } @@ -134,5 +136,4 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect { public AddManaOfAnyTypeProducedEffect copy() { return new AddManaOfAnyTypeProducedEffect(this); } - } diff --git a/Mage/src/main/java/mage/abilities/effects/mana/ManaEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/ManaEffect.java index 2d0b493b30..e2b3ab9749 100644 --- a/Mage/src/main/java/mage/abilities/effects/mana/ManaEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/mana/ManaEffect.java @@ -8,8 +8,8 @@ import mage.constants.AbilityType; import mage.constants.ManaType; import mage.constants.Outcome; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.players.Player; import java.util.ArrayList; @@ -133,7 +133,7 @@ public abstract class ManaEffect extends OneShotEffect { */ public void checkToFirePossibleEvents(Mana mana, Game game, Ability source) { if (source.getAbilityType() == AbilityType.MANA && source.hasTapCost()) { - ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, source.getSourceId(), source, source.getControllerId(), mana); + ManaEvent event = new TappedForManaEvent(source.getSourceId(), source, source.getControllerId(), mana, game); if (!game.replaceEvent(event)) { game.fireEvent(event); } diff --git a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java index 7909e98679..53a4577ecb 100644 --- a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java +++ b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java @@ -1,19 +1,16 @@ package mage.abilities.mana; +import mage.ConditionalMana; import mage.Mana; import mage.abilities.Ability; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ManaEvent; +import mage.game.events.TappedForManaEvent; import mage.players.Player; import org.apache.log4j.Logger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import mage.ConditionalMana; +import java.util.*; /** * @author BetaSteward_at_googlemail.com @@ -128,7 +125,7 @@ public class ManaOptions extends ArrayList { */ private boolean checkManaReplacementAndTriggeredMana(Ability ability, Game game, Mana mana) { if (ability.hasTapCost()) { - ManaEvent event = new ManaEvent(GameEvent.EventType.TAPPED_FOR_MANA, ability.getSourceId(), ability, ability.getControllerId(), mana); + ManaEvent event = new TappedForManaEvent(ability.getSourceId(), ability, ability.getControllerId(), mana, game); if (game.replaceEvent(event)) { return false; } @@ -415,7 +412,7 @@ public class ManaOptions extends ArrayList { if (manaToAdd != null && (manaToAdd.countColored() > 0 || manaToAdd.getAny() > 0) && manaToAdd.count() > 0 && onlyManaCosts) { repeatable = true; // only replace to any with mana costs only will be repeated if able } - + for (Mana payCombination : ManaOptions.getPossiblePayCombinations(cost, currentMana)) { Mana currentManaCopy = currentMana.copy(); // copy start mana because in iteration it will be updated while (currentManaCopy.includesMana(payCombination)) { // loop for multiple usage if possible @@ -553,7 +550,7 @@ public class ManaOptions extends ArrayList { public boolean removeEqualMana(Mana manaToRemove) { boolean result = false; - for (Iterator iterator = this.iterator(); iterator.hasNext();) { + for (Iterator iterator = this.iterator(); iterator.hasNext(); ) { Mana next = iterator.next(); if (next.equalManaValue(manaToRemove)) { iterator.remove(); @@ -630,7 +627,7 @@ public class ManaOptions extends ArrayList { StringBuilder sb = new StringBuilder(); sb.append('['); - for (;;) { + for (; ; ) { Mana mana = it.next(); sb.append(mana.toString()); if (mana instanceof ConditionalMana) { diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenColorPredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenColorPredicate.java new file mode 100644 index 0000000000..77a920369f --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/ChosenColorPredicate.java @@ -0,0 +1,31 @@ +package mage.filter.predicate.mageobject; + +import mage.MageObject; +import mage.ObjectColor; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public enum ChosenColorPredicate implements ObjectSourcePlayerPredicate> { + TRUE(true), FALSE(false); + + private final boolean value; + + ChosenColorPredicate(boolean value) { + this.value = value; + } + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + ObjectColor color = (ObjectColor) game.getState().getValue(input.getSourceId() + "_color"); + return color != null && input.getObject().getColor(game).shares(color) == value; + } + + @Override + public String toString() { + return "Chosen subtype"; + } +} diff --git a/Mage/src/main/java/mage/game/events/ManaEvent.java b/Mage/src/main/java/mage/game/events/ManaEvent.java index d0d34a95d3..dfcb10e1f1 100644 --- a/Mage/src/main/java/mage/game/events/ManaEvent.java +++ b/Mage/src/main/java/mage/game/events/ManaEvent.java @@ -1,13 +1,11 @@ - - package mage.game.events; -import java.util.UUID; import mage.Mana; import mage.abilities.Ability; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public class ManaEvent extends GameEvent { @@ -22,5 +20,4 @@ public class ManaEvent extends GameEvent { public Mana getMana() { return mana; } - } diff --git a/Mage/src/main/java/mage/game/events/TappedForManaEvent.java b/Mage/src/main/java/mage/game/events/TappedForManaEvent.java new file mode 100644 index 0000000000..0d9344b244 --- /dev/null +++ b/Mage/src/main/java/mage/game/events/TappedForManaEvent.java @@ -0,0 +1,25 @@ +package mage.game.events; + +import mage.Mana; +import mage.abilities.Ability; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class TappedForManaEvent extends ManaEvent { + + private final Permanent permanent; + + public TappedForManaEvent(UUID targetId, Ability source, UUID playerId, Mana mana, Game game) { + super(EventType.TAPPED_FOR_MANA, targetId, source, playerId, mana); + this.permanent = source.getSourcePermanentOrLKI(game); + } + + public Permanent getPermanent() { + return permanent; + } +}