From 27e30101399d62f3d8d92cf5b666d1320e529f74 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Sat, 3 Jun 2023 21:44:39 -0400 Subject: [PATCH] [LTR] Implement Fangorn, Tree Shepherd --- .../src/mage/cards/f/FangornTreeShepherd.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/cards/l/LeylineTyrant.java | 5 +- .../src/mage/cards/o/OmnathLocusOfMana.java | 54 ++---------- .../TheLordOfTheRingsTalesOfMiddleEarth.java | 1 + .../AttacksWithCreaturesTriggeredAbility.java | 10 +-- .../continuous/YouDontLoseManaEffect.java | 40 +++++++++ 6 files changed, 143 insertions(+), 54 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/f/FangornTreeShepherd.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/continuous/YouDontLoseManaEffect.java diff --git a/Mage.Sets/src/mage/cards/f/FangornTreeShepherd.java b/Mage.Sets/src/mage/cards/f/FangornTreeShepherd.java new file mode 100644 index 00000000000..32eb90e8830 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FangornTreeShepherd.java @@ -0,0 +1,87 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.effects.common.continuous.YouDontLoseManaEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FangornTreeShepherd extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.TREEFOLK); + + public FangornTreeShepherd(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.TREEFOLK); + this.power = new MageInt(4); + this.toughness = new MageInt(10); + + // Treefolk you control have vigilance. + this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect( + VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, filter + ))); + + // Whenever one or more Treefolk you control attack, add twice that much {G}. + this.addAbility(new AttacksWithCreaturesTriggeredAbility( + new FangornTreeShepherdEffect(), 1, filter + ).setTriggerPhrase("Whenever one or more Treefolk you control attack, ")); + + // You don't lose unspent green mana as steps and phases end. + this.addAbility(new SimpleStaticAbility(new YouDontLoseManaEffect(ManaType.GREEN))); + } + + private FangornTreeShepherd(final FangornTreeShepherd card) { + super(card); + } + + @Override + public FangornTreeShepherd copy() { + return new FangornTreeShepherd(this); + } +} + +class FangornTreeShepherdEffect extends OneShotEffect { + + FangornTreeShepherdEffect() { + super(Outcome.Benefit); + staticText = "add twice that much {G}"; + } + + private FangornTreeShepherdEffect(final FangornTreeShepherdEffect effect) { + super(effect); + } + + @Override + public FangornTreeShepherdEffect copy() { + return new FangornTreeShepherdEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + int amount = (Integer) getValue("attackers"); + if (player != null && amount > 0) { + player.getManaPool().addMana(Mana.GreenMana(2 * amount), game, source); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/l/LeylineTyrant.java b/Mage.Sets/src/mage/cards/l/LeylineTyrant.java index d2c5c948cfb..79ea7dd9264 100644 --- a/Mage.Sets/src/mage/cards/l/LeylineTyrant.java +++ b/Mage.Sets/src/mage/cards/l/LeylineTyrant.java @@ -2,6 +2,7 @@ package mage.cards.l; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.Cost; @@ -9,6 +10,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.YouDontLoseManaEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -18,7 +20,6 @@ import mage.players.Player; import mage.target.common.TargetAnyTarget; import java.util.UUID; -import mage.abilities.common.DiesSourceTriggeredAbility; /** * @author TheElk801 @@ -36,7 +37,7 @@ public final class LeylineTyrant extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // You don't lose unspent red mana as steps and phases end. - this.addAbility(new SimpleStaticAbility(new LeylineTyrantManaEffect())); + this.addAbility(new SimpleStaticAbility(new YouDontLoseManaEffect(ManaType.RED))); // When Leyline Tyrant dies, you may pay any amount of {R}. When you do, it deals that much damage to any target. this.addAbility(new DiesSourceTriggeredAbility(new LeylineTyrantDamageEffect())); diff --git a/Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java b/Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java index fd24c2a58ba..5b83fdf9971 100644 --- a/Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java +++ b/Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java @@ -1,26 +1,24 @@ - package mage.cards.o; -import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.ManaTypeInManaPoolCount; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.YouDontLoseManaEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.game.Game; -import mage.players.Player; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class OmnathLocusOfMana extends CardImpl { + private static final DynamicValue xValue = new ManaTypeInManaPoolCount(ManaType.GREEN); + public OmnathLocusOfMana(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.supertype.add(SuperType.LEGENDARY); @@ -30,12 +28,10 @@ public final class OmnathLocusOfMana extends CardImpl { this.toughness = new MageInt(1); // Green mana doesn't empty from your mana pool as steps and phases end. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OmnathRuleEffect())); + this.addAbility(new SimpleStaticAbility(new YouDontLoseManaEffect(ManaType.GREEN))); // Omnath, Locus of Mana gets +1/+1 for each green mana in your mana pool - DynamicValue boost = new ManaTypeInManaPoolCount(ManaType.GREEN); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(boost, boost, Duration.WhileOnBattlefield))); - + this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(xValue, xValue, Duration.WhileOnBattlefield))); } private OmnathLocusOfMana(final OmnathLocusOfMana card) { @@ -47,39 +43,3 @@ public final class OmnathLocusOfMana extends CardImpl { return new OmnathLocusOfMana(this); } } - -class OmnathRuleEffect extends ContinuousEffectImpl { - - public OmnathRuleEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "You don't lose unspent green mana as steps and phases end"; - } - - public OmnathRuleEffect(final OmnathRuleEffect effect) { - super(effect); - } - - @Override - public OmnathRuleEffect copy() { - return new OmnathRuleEffect(this); - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - player.getManaPool().addDoNotEmptyManaType(ManaType.GREEN); - } - return false; - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.RulesEffects; - } -} diff --git a/Mage.Sets/src/mage/sets/TheLordOfTheRingsTalesOfMiddleEarth.java b/Mage.Sets/src/mage/sets/TheLordOfTheRingsTalesOfMiddleEarth.java index f7bc6a03f05..0a787ed51fa 100644 --- a/Mage.Sets/src/mage/sets/TheLordOfTheRingsTalesOfMiddleEarth.java +++ b/Mage.Sets/src/mage/sets/TheLordOfTheRingsTalesOfMiddleEarth.java @@ -39,6 +39,7 @@ public final class TheLordOfTheRingsTalesOfMiddleEarth extends ExpansionSet { cards.add(new SetCardInfo("Eastfarthing Farmer", 8, Rarity.COMMON, mage.cards.e.EastfarthingFarmer.class)); cards.add(new SetCardInfo("Eowyn, Fearless Knight", 201, Rarity.RARE, mage.cards.e.EowynFearlessKnight.class)); cards.add(new SetCardInfo("Fall of Gil-galad", 165, Rarity.RARE, mage.cards.f.FallOfGilGalad.class)); + cards.add(new SetCardInfo("Fangorn, Tree Shepherd", 166, Rarity.RARE, mage.cards.f.FangornTreeShepherd.class)); cards.add(new SetCardInfo("Fire of Orthanc", 127, Rarity.COMMON, mage.cards.f.FireOfOrthanc.class)); cards.add(new SetCardInfo("Foray of Orcs", 128, Rarity.UNCOMMON, mage.cards.f.ForayOfOrcs.class)); cards.add(new SetCardInfo("Forest", 270, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/common/AttacksWithCreaturesTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksWithCreaturesTriggeredAbility.java index ac5ca2e90a2..3c853383efd 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksWithCreaturesTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksWithCreaturesTriggeredAbility.java @@ -3,8 +3,8 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -20,7 +20,7 @@ import java.util.stream.Collectors; */ public class AttacksWithCreaturesTriggeredAbility extends TriggeredAbilityImpl { - private final FilterCreaturePermanent filter; + private final FilterPermanent filter; private final int minAttackers; private final boolean setTargetPointer; @@ -28,15 +28,15 @@ public class AttacksWithCreaturesTriggeredAbility extends TriggeredAbilityImpl { this(effect, minAttackers, StaticFilters.FILTER_PERMANENT_CREATURES); } - public AttacksWithCreaturesTriggeredAbility(Effect effect, int minAttackers, FilterCreaturePermanent filter) { + public AttacksWithCreaturesTriggeredAbility(Effect effect, int minAttackers, FilterPermanent filter) { this(Zone.BATTLEFIELD, effect, minAttackers, filter); } - public AttacksWithCreaturesTriggeredAbility(Zone zone, Effect effect, int minAttackers, FilterCreaturePermanent filter) { + public AttacksWithCreaturesTriggeredAbility(Zone zone, Effect effect, int minAttackers, FilterPermanent filter) { this(zone, effect, minAttackers, filter, false); } - public AttacksWithCreaturesTriggeredAbility(Zone zone, Effect effect, int minAttackers, FilterCreaturePermanent filter, boolean setTargetPointer) { + public AttacksWithCreaturesTriggeredAbility(Zone zone, Effect effect, int minAttackers, FilterPermanent filter, boolean setTargetPointer) { super(zone, effect); this.filter = filter; this.minAttackers = minAttackers; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/YouDontLoseManaEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/YouDontLoseManaEffect.java new file mode 100644 index 00000000000..2646319f1da --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/YouDontLoseManaEffect.java @@ -0,0 +1,40 @@ +package mage.abilities.effects.common.continuous; + +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.*; +import mage.game.Game; +import mage.players.Player; + +/** + * @author TheElk801 + */ +public class YouDontLoseManaEffect extends ContinuousEffectImpl { + + private final ManaType manaType; + + public YouDontLoseManaEffect(ManaType manaType) { + super(Duration.WhileOnBattlefield, Layer.RulesEffects, SubLayer.NA, Outcome.Detriment); + staticText = "you don't lose unspent " + manaType + " mana as steps and phases end"; + this.manaType = manaType; + } + + private YouDontLoseManaEffect(final YouDontLoseManaEffect effect) { + super(effect); + this.manaType = effect.manaType; + } + + @Override + public YouDontLoseManaEffect copy() { + return new YouDontLoseManaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + player.getManaPool().addDoNotEmptyManaType(manaType); + } + return false; + } +} \ No newline at end of file