From 496faaf5cb9ff47066178d08e9cb6e252bd7454a Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Sat, 1 Jul 2023 18:53:31 +0200 Subject: [PATCH] [LTR] Implement The Balrog, Durin's Bane (#10515) * [LTR] Implement The Balrog, Durin's Bane I could use someone more experienced for this card: Should the watcher `PermanentsSacrificedWatcher` be initialized locally in the card's class, or is a global initializing in GameImpl.java alright? I went for the latter for now, as my base for implementing the static cost reduction was Blood for the Blood God! * apply review * no longer instantiate watcher on every game. --- .../src/mage/cards/t/TheBalrogDurinsBane.java | 79 +++++++++++++++++++ .../TheLordOfTheRingsTalesOfMiddleEarth.java | 1 + .../PermanentsSacrificedThisTurnCount.java | 40 ++++++++++ .../PermanentsSacrificedThisTurnHint.java | 28 +++++++ .../common/PermanentsSacrificedWatcher.java | 4 + 5 files changed, 152 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TheBalrogDurinsBane.java create mode 100644 Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsSacrificedThisTurnCount.java create mode 100644 Mage/src/main/java/mage/abilities/hint/common/PermanentsSacrificedThisTurnHint.java diff --git a/Mage.Sets/src/mage/cards/t/TheBalrogDurinsBane.java b/Mage.Sets/src/mage/cards/t/TheBalrogDurinsBane.java new file mode 100644 index 00000000000..70f07c591a2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheBalrogDurinsBane.java @@ -0,0 +1,79 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.PermanentsSacrificedThisTurnCount; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; +import mage.abilities.hint.common.PermanentsSacrificedThisTurnHint; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.target.TargetPermanent; +import mage.watchers.common.PermanentsSacrificedWatcher; + +import java.util.UUID; + +/** + * + * @author Susucr + */ +public final class TheBalrogDurinsBane extends CardImpl { + + private static final FilterCreaturePermanent filterNonLegendary + = new FilterCreaturePermanent("except by legendary creatures"); + + static { + filterNonLegendary.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); + } + + public TheBalrogDurinsBane(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.AVATAR); + this.subtype.add(SubType.DEMON); + this.power = new MageInt(7); + this.toughness = new MageInt(5); + + // This spell costs {1} less to cast for each permanent sacrificed this turn. + this.addAbility( + new SimpleStaticAbility( + Zone.ALL, + new SpellCostReductionSourceEffect(PermanentsSacrificedThisTurnCount.instance) + .setText("this spell costs {1} less to cast for each permanent sacrificed this turn") + ).addHint(PermanentsSacrificedThisTurnHint.instance).setRuleAtTheTop(true), + new PermanentsSacrificedWatcher() + ); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // The Balrog, Durin's Bane can't be blocked except by legendary creatures. + this.addAbility(new SimpleEvasionAbility((new CantBeBlockedByCreaturesSourceEffect( + filterNonLegendary, Duration.WhileOnBattlefield + )))); + + // When The Balrog dies, destroy target artifact or creature an opponent controls. + Ability ability = new DiesSourceTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE)); + this.addAbility(ability); + } + + private TheBalrogDurinsBane(final TheBalrogDurinsBane card) { + super(card); + } + + @Override + public TheBalrogDurinsBane copy() { + return new TheBalrogDurinsBane(this); + } +} diff --git a/Mage.Sets/src/mage/sets/TheLordOfTheRingsTalesOfMiddleEarth.java b/Mage.Sets/src/mage/sets/TheLordOfTheRingsTalesOfMiddleEarth.java index 01e20bea27a..a678183288a 100644 --- a/Mage.Sets/src/mage/sets/TheLordOfTheRingsTalesOfMiddleEarth.java +++ b/Mage.Sets/src/mage/sets/TheLordOfTheRingsTalesOfMiddleEarth.java @@ -251,6 +251,7 @@ public final class TheLordOfTheRingsTalesOfMiddleEarth extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 266, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swarming of Moria", 150, Rarity.COMMON, mage.cards.s.SwarmingOfMoria.class)); cards.add(new SetCardInfo("Tale of Tinuviel", 34, Rarity.UNCOMMON, mage.cards.t.TaleOfTinuviel.class)); + cards.add(new SetCardInfo("The Balrog, Durin's Bane", 195, Rarity.RARE, mage.cards.t.TheBalrogDurinsBane.class)); cards.add(new SetCardInfo("The Balrog, Flame of Udun", 297, Rarity.RARE, mage.cards.t.TheBalrogFlameOfUdun.class)); cards.add(new SetCardInfo("The Bath Song", 40, Rarity.UNCOMMON, mage.cards.t.TheBathSong.class)); cards.add(new SetCardInfo("The Battle of Bywater", 2, Rarity.RARE, mage.cards.t.TheBattleOfBywater.class)); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsSacrificedThisTurnCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsSacrificedThisTurnCount.java new file mode 100644 index 00000000000..51700c964c6 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsSacrificedThisTurnCount.java @@ -0,0 +1,40 @@ + +package mage.abilities.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.game.Game; +import mage.watchers.common.PermanentsSacrificedWatcher; + +/** + * @author Susucr + */ +public enum PermanentsSacrificedThisTurnCount implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + PermanentsSacrificedWatcher watcher = game.getState().getWatcher(PermanentsSacrificedWatcher.class); + if (watcher != null) { + return watcher.getThisTurnSacrificedPermanents(); + } + return 0; + } + + @Override + public PermanentsSacrificedThisTurnCount copy() { + return PermanentsSacrificedThisTurnCount.instance; + } + + @Override + public String toString() { + return "X"; + } + + @Override + public String getMessage() { + return "permanents sacrificed this turn"; + } + +} diff --git a/Mage/src/main/java/mage/abilities/hint/common/PermanentsSacrificedThisTurnHint.java b/Mage/src/main/java/mage/abilities/hint/common/PermanentsSacrificedThisTurnHint.java new file mode 100644 index 00000000000..5786ddfe5d3 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/hint/common/PermanentsSacrificedThisTurnHint.java @@ -0,0 +1,28 @@ +package mage.abilities.hint.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.PermanentsSacrificedThisTurnCount; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.game.Game; + +/** + * @author Susucr + */ +public enum PermanentsSacrificedThisTurnHint implements Hint { + instance; + + private static final Hint hint = new ValueHint( + "Permanents sacrificed this turn", PermanentsSacrificedThisTurnCount.instance + ); + + @Override + public String getText(Game game, Ability ability) { + return hint.getText(game, ability); + } + + @Override + public PermanentsSacrificedThisTurnHint copy() { + return this; + } +} diff --git a/Mage/src/main/java/mage/watchers/common/PermanentsSacrificedWatcher.java b/Mage/src/main/java/mage/watchers/common/PermanentsSacrificedWatcher.java index 913802815cc..fb3e83d95f0 100644 --- a/Mage/src/main/java/mage/watchers/common/PermanentsSacrificedWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/PermanentsSacrificedWatcher.java @@ -46,4 +46,8 @@ public class PermanentsSacrificedWatcher extends Watcher { public List getThisTurnSacrificedPermanents(UUID playerId) { return sacrificedPermanents.get(playerId); } + + public int getThisTurnSacrificedPermanents() { + return sacrificedPermanents.values().stream().mapToInt(permanents -> permanents.size()).sum(); + } }