[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.
This commit is contained in:
Susucre 2023-07-01 18:53:31 +02:00 committed by GitHub
parent 44928e65f7
commit 496faaf5cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 152 additions and 0 deletions

View file

@ -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);
}
}

View file

@ -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));

View file

@ -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";
}
}

View file

@ -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;
}
}

View file

@ -46,4 +46,8 @@ public class PermanentsSacrificedWatcher extends Watcher {
public List<Permanent> getThisTurnSacrificedPermanents(UUID playerId) {
return sacrificedPermanents.get(playerId);
}
public int getThisTurnSacrificedPermanents() {
return sacrificedPermanents.values().stream().mapToInt(permanents -> permanents.size()).sum();
}
}