From 3e0f305e0b8938e5f4693eb79a8cb4aed5801bc0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 25 Apr 2022 19:27:26 -0400 Subject: [PATCH] [NCC] Implemented Gavel of the Righteous --- .../src/mage/cards/a/AngelheartVial.java | 8 +- .../src/mage/cards/g/GavelOfTheRighteous.java | 89 +++++++++++++++++++ .../src/mage/sets/NewCapennaCommander.java | 1 + .../common/RemoveCountersSourceCost.java | 58 ++++++++++-- .../common/CountersSourceCount.java | 18 +++- 5 files changed, 159 insertions(+), 15 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/g/GavelOfTheRighteous.java diff --git a/Mage.Sets/src/mage/cards/a/AngelheartVial.java b/Mage.Sets/src/mage/cards/a/AngelheartVial.java index eae17868045..c02b3c43049 100644 --- a/Mage.Sets/src/mage/cards/a/AngelheartVial.java +++ b/Mage.Sets/src/mage/cards/a/AngelheartVial.java @@ -1,7 +1,6 @@ package mage.cards.a; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleActivatedAbility; @@ -21,14 +20,15 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class AngelheartVial extends CardImpl { public AngelheartVial(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); // Whenever you're dealt damage, you may put that many charge counters on Angelheart Vial. this.addAbility(new AngelheartVialTriggeredAbility()); @@ -36,7 +36,7 @@ public final class AngelheartVial extends CardImpl { // {2}, {tap}, Remove four charge counters from Angelheart Vial: You gain 2 life and draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); - ability.addCost(new RemoveCountersSourceCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(4)))); + ability.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(4))); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GavelOfTheRighteous.java b/Mage.Sets/src/mage/cards/g/GavelOfTheRighteous.java new file mode 100644 index 00000000000..46ac2dac38c --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GavelOfTheRighteous.java @@ -0,0 +1,89 @@ +package mage.cards.g; + +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.OrCost; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.game.Game; + +import java.util.*; +import java.util.stream.IntStream; + +/** + * @author TheElk801 + */ +public final class GavelOfTheRighteous extends CardImpl { + + private static final DynamicValue xValue = new CountersSourceCount(null); + + public GavelOfTheRighteous(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + this.subtype.add(SubType.EQUIPMENT); + + // At the beginning of combat on your turn, put a charge counter on Gavel of the Righteous. + this.addAbility(new BeginningOfCombatTriggeredAbility( + new AddCountersSourceEffect(CounterType.CHARGE.createInstance()), TargetController.YOU, false + )); + + // Equipped creature gets +1/+1 for each counter on Gavel of the Righteous. + this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(xValue, xValue))); + + // As long as Gavel of the Righteous has four or more counters on it, equipped creature has double strike. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new GainAbilityAttachedEffect(DoubleStrikeAbility.getInstance(), AttachmentType.EQUIPMENT), + GavelOfTheRighteousCondition.instance, "as long as {this} has four " + + "or more counters on it, equipped creature has double strike" + ))); + + // Equip—Pay {3} or remove a counter from Gavel of the Righteous. + this.addAbility(new EquipAbility( + Outcome.BoostCreature, + new OrCost( + "Pay {3} or remove a counter from {this}", + new GenericManaCost(3), new RemoveCountersSourceCost(null) + ) + )); + } + + private GavelOfTheRighteous(final GavelOfTheRighteous card) { + super(card); + } + + @Override + public GavelOfTheRighteous copy() { + return new GavelOfTheRighteous(this); + } +} + +enum GavelOfTheRighteousCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return Optional.of(source.getSourcePermanentIfItStillExists(game)) + .filter(Objects::nonNull) + .map(permanent -> permanent.getCounters(game)) + .map(HashMap::values) + .map(Collection::stream) + .map(x -> x.mapToInt(Counter::getCount)) + .map(IntStream::sum) + .orElse(0) >= 4; + } +} diff --git a/Mage.Sets/src/mage/sets/NewCapennaCommander.java b/Mage.Sets/src/mage/sets/NewCapennaCommander.java index 7351ec279da..5e7e36411bb 100644 --- a/Mage.Sets/src/mage/sets/NewCapennaCommander.java +++ b/Mage.Sets/src/mage/sets/NewCapennaCommander.java @@ -129,6 +129,7 @@ public final class NewCapennaCommander extends ExpansionSet { cards.add(new SetCardInfo("Gahiji, Honored One", 340, Rarity.MYTHIC, mage.cards.g.GahijiHonoredOne.class)); cards.add(new SetCardInfo("Game Trail", 405, Rarity.RARE, mage.cards.g.GameTrail.class)); cards.add(new SetCardInfo("Garruk's Uprising", 292, Rarity.UNCOMMON, mage.cards.g.GarruksUprising.class)); + cards.add(new SetCardInfo("Gavel of the Righteous", 83, Rarity.RARE, mage.cards.g.GavelOfTheRighteous.class)); cards.add(new SetCardInfo("Gavony Township", 406, Rarity.RARE, mage.cards.g.GavonyTownship.class)); cards.add(new SetCardInfo("Generous Gift", 201, Rarity.UNCOMMON, mage.cards.g.GenerousGift.class)); cards.add(new SetCardInfo("Ghostly Pilferer", 223, Rarity.RARE, mage.cards.g.GhostlyPilferer.class)); diff --git a/Mage/src/main/java/mage/abilities/costs/common/RemoveCountersSourceCost.java b/Mage/src/main/java/mage/abilities/costs/common/RemoveCountersSourceCost.java index d041d2368b5..593ffe442cc 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/RemoveCountersSourceCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/RemoveCountersSourceCost.java @@ -3,12 +3,19 @@ package mage.abilities.costs.common; import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.constants.Outcome; import mage.counters.Counter; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; import mage.util.CardUtil; +import mage.util.RandomUtil; +import java.util.Iterator; +import java.util.Set; import java.util.UUID; /** @@ -20,15 +27,18 @@ public class RemoveCountersSourceCost extends CostImpl { private final String name; public RemoveCountersSourceCost(Counter counter) { - this.amount = counter.getCount(); - this.name = counter.getName(); - this.text = new StringBuilder("remove ").append((amount == 1 ? CounterType.findArticle(counter.getName()) : CardUtil.numberToText(amount))) - .append(' ').append(name).append(" counter").append((amount != 1 ? "s" : "")) + this.amount = counter != null ? counter.getCount() : 1; + this.name = counter != null ? counter.getName() : ""; + this.text = new StringBuilder("remove ") + .append((amount == 1 ? CounterType.findArticle(counter.getName()) : CardUtil.numberToText(amount))) + .append(name.isEmpty() ? "" : (' ' + name)) + .append(" counter") + .append((amount != 1 ? "s" : "")) .append(" from {this}").toString(); } - public RemoveCountersSourceCost(RemoveCountersSourceCost cost) { + private RemoveCountersSourceCost(RemoveCountersSourceCost cost) { super(cost); this.amount = cost.amount; this.name = cost.name; @@ -42,9 +52,41 @@ public class RemoveCountersSourceCost extends CostImpl { @Override public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && permanent.getCounters(game).getCount(name) >= amount) { - permanent.removeCounters(name, amount, source, game); + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (player == null || permanent == null) { + return paid; + } + String toRemove; + if (name.isEmpty()) { + Set toChoose = permanent.getCounters(game).keySet(); + switch (toChoose.size()) { + case 0: + return paid; + case 1: + toRemove = RandomUtil.randomFromCollection(toChoose); + break; + case 2: + Iterator iterator = toChoose.iterator(); + String choice1 = iterator.next(); + String choice2 = iterator.next(); + toRemove = player.chooseUse( + Outcome.UnboostCreature, "Choose a type of counter to remove", + null, choice1, choice2, source, game + ) ? choice1 : choice2; + break; + default: + Choice choice = new ChoiceImpl(true); + choice.setChoices(toChoose); + choice.setMessage("Choose a type of counter to remove"); + player.choose(Outcome.UnboostCreature, choice, game); + toRemove = choice.getChoice(); + } + } else { + toRemove = name; + } + if (permanent.getCounters(game).getCount(toRemove) >= amount) { + permanent.removeCounters(toRemove, amount, source, game); this.paid = true; } return paid; diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CountersSourceCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CountersSourceCount.java index d974ff9c622..718268aa598 100644 --- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CountersSourceCount.java +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CountersSourceCount.java @@ -3,6 +3,7 @@ package mage.abilities.dynamicvalue.common; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; +import mage.counters.Counter; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; @@ -15,14 +16,25 @@ public class CountersSourceCount implements DynamicValue { this.counterType = counterType; } - public CountersSourceCount(final CountersSourceCount countersCount) { + protected CountersSourceCount(final CountersSourceCount countersCount) { this.counterType = countersCount.counterType; } @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { Permanent permanent = sourceAbility.getSourcePermanentOrLKI(game); - return permanent != null ? permanent.getCounters(game).getCount(counterType) : 0; + if (permanent == null) { + return 0; + } + return counterType != null + ? permanent + .getCounters(game) + .getCount(counterType) + : permanent + .getCounters(game) + .values() + .stream() + .mapToInt(Counter::getCount).sum(); } @Override @@ -37,6 +49,6 @@ public class CountersSourceCount implements DynamicValue { @Override public String getMessage() { - return counterType + " counter on {this}"; + return (counterType != null ? counterType.toString() + ' ' : "") + "counter on {this}"; } }