From cc59f9e2e83a7cea3f8b418dd6aca609510954fa Mon Sep 17 00:00:00 2001 From: theelk801 Date: Mon, 5 Jan 2026 21:22:50 -0500 Subject: [PATCH] [ECL] Implement Silvergill Mentor --- Mage.Sets/src/mage/cards/c/CausticExhale.java | 5 +- .../src/mage/cards/d/DispellingExhale.java | 5 +- Mage.Sets/src/mage/cards/m/MoltenExhale.java | 8 +- Mage.Sets/src/mage/cards/o/OsseousExhale.java | 5 +- .../src/mage/cards/p/PiercingExhale.java | 5 +- .../mage/cards/s/SarkhanDragonAscendant.java | 9 +- .../src/mage/cards/s/SilvergillMentor.java | 49 ++++++++ Mage.Sets/src/mage/sets/LorwynEclipsed.java | 1 + .../common/BeheldDragonCondition.java | 4 +- .../abilities/costs/common/BeholdCost.java | 46 ++++++++ .../costs/common/BeholdDragonCost.java | 109 ------------------ ...dDragonAbility.java => BeholdAbility.java} | 44 ++++--- .../main/java/mage/constants/BeholdType.java | 96 +++++++++++++++ .../token/MerfolkWhiteBlueToken.java | 29 +++++ Utils/mtg-cards-data.txt | 1 + 15 files changed, 268 insertions(+), 148 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SilvergillMentor.java create mode 100644 Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java delete mode 100644 Mage/src/main/java/mage/abilities/costs/common/BeholdDragonCost.java rename Mage/src/main/java/mage/abilities/keyword/{BeholdDragonAbility.java => BeholdAbility.java} (58%) create mode 100644 Mage/src/main/java/mage/constants/BeholdType.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/MerfolkWhiteBlueToken.java diff --git a/Mage.Sets/src/mage/cards/c/CausticExhale.java b/Mage.Sets/src/mage/cards/c/CausticExhale.java index e98d0568b03..f0cc9ac1646 100644 --- a/Mage.Sets/src/mage/cards/c/CausticExhale.java +++ b/Mage.Sets/src/mage/cards/c/CausticExhale.java @@ -1,11 +1,12 @@ package mage.cards.c; import mage.abilities.costs.OrCost; -import mage.abilities.costs.common.BeholdDragonCost; +import mage.abilities.costs.common.BeholdCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.common.TargetCreaturePermanent; @@ -22,7 +23,7 @@ public final class CausticExhale extends CardImpl { // As an additional cost to cast this spell, behold a Dragon or pay {1}. this.getSpellAbility().addCost(new OrCost( "behold a Dragon or pay {1}", - new BeholdDragonCost(), new GenericManaCost(1) + new BeholdCost(BeholdType.DRAGON), new GenericManaCost(1) )); // Target creature gets -3/-3 until end of turn. diff --git a/Mage.Sets/src/mage/cards/d/DispellingExhale.java b/Mage.Sets/src/mage/cards/d/DispellingExhale.java index 074f5564df7..6d2ba706f5e 100644 --- a/Mage.Sets/src/mage/cards/d/DispellingExhale.java +++ b/Mage.Sets/src/mage/cards/d/DispellingExhale.java @@ -4,9 +4,10 @@ import mage.abilities.condition.common.BeheldDragonCondition; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.CounterUnlessPaysEffect; -import mage.abilities.keyword.BeholdDragonAbility; +import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.TargetSpell; @@ -21,7 +22,7 @@ public final class DispellingExhale extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // As an additional cost to cast this spell, you may behold a Dragon. - this.addAbility(new BeholdDragonAbility()); + this.addAbility(new BeholdAbility(BeholdType.DRAGON)); // Counter target spell unless its controller pays {2}. If a Dragon was beheld, counter that spell unless its controller pays {4} instead. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( diff --git a/Mage.Sets/src/mage/cards/m/MoltenExhale.java b/Mage.Sets/src/mage/cards/m/MoltenExhale.java index 723885c7f30..f9022131811 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenExhale.java +++ b/Mage.Sets/src/mage/cards/m/MoltenExhale.java @@ -2,14 +2,12 @@ package mage.cards.m; import mage.abilities.Ability; import mage.abilities.common.PayMoreToCastAsThoughtItHadFlashAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; -import mage.abilities.costs.CostsImpl; -import mage.abilities.costs.common.BeholdDragonCost; +import mage.abilities.costs.common.BeholdCost; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.Target; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -25,7 +23,7 @@ public final class MoltenExhale extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}"); // You may cast this spell as though it had flash if you behold a Dragon as an additional cost to cast it. - Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new BeholdDragonCost(), + Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new BeholdCost(BeholdType.DRAGON), "you may cast this spell as though it had flash if you behold a Dragon as an additional cost to cast it."); Target target = new TargetCreatureOrPlaneswalker(); Effect effect = new DamageTargetEffect(4); diff --git a/Mage.Sets/src/mage/cards/o/OsseousExhale.java b/Mage.Sets/src/mage/cards/o/OsseousExhale.java index 5323451fb8a..8c58f52df89 100644 --- a/Mage.Sets/src/mage/cards/o/OsseousExhale.java +++ b/Mage.Sets/src/mage/cards/o/OsseousExhale.java @@ -4,9 +4,10 @@ import mage.abilities.condition.common.BeheldDragonCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.keyword.BeholdDragonAbility; +import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.common.TargetAttackingOrBlockingCreature; @@ -21,7 +22,7 @@ public final class OsseousExhale extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // As an additional cost to cast this spell, you may behold a Dragon. - this.addAbility(new BeholdDragonAbility()); + this.addAbility(new BeholdAbility(BeholdType.DRAGON)); // Osseous Exhale deals 5 damage to target attacking or blocking creature. If a Dragon was beheld, you gain 2 life. this.getSpellAbility().addEffect(new DamageTargetEffect(5)); diff --git a/Mage.Sets/src/mage/cards/p/PiercingExhale.java b/Mage.Sets/src/mage/cards/p/PiercingExhale.java index b9a1ef912a0..a6d0987b099 100644 --- a/Mage.Sets/src/mage/cards/p/PiercingExhale.java +++ b/Mage.Sets/src/mage/cards/p/PiercingExhale.java @@ -4,9 +4,10 @@ import mage.abilities.condition.common.BeheldDragonCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DamageWithPowerFromOneToAnotherTargetEffect; import mage.abilities.effects.keyword.SurveilEffect; -import mage.abilities.keyword.BeholdDragonAbility; +import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -22,7 +23,7 @@ public final class PiercingExhale extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); // As an additional cost to cast this spell, you may behold a Dragon. - this.addAbility(new BeholdDragonAbility()); + this.addAbility(new BeholdAbility(BeholdType.DRAGON)); // Target creature you control deals damage equal to its power to target creature or planeswalker. If a Dragon was beheld, surveil 2. this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java b/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java index 555e0f6c8c3..3ef97eadaae 100644 --- a/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java +++ b/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java @@ -4,7 +4,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.costs.common.BeholdDragonCost; +import mage.abilities.costs.common.BeholdCost; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.continuous.AddCardSubTypeSourceEffect; @@ -13,10 +13,7 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.constants.*; import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; @@ -42,7 +39,7 @@ public final class SarkhanDragonAscendant extends CardImpl { // When Sarkhan enters, you may behold a Dragon. If you do, create a Treasure token. this.addAbility(new EntersBattlefieldTriggeredAbility( - new DoIfCostPaid(new CreateTokenEffect(new TreasureToken()), new BeholdDragonCost()) + new DoIfCostPaid(new CreateTokenEffect(new TreasureToken()), new BeholdCost(BeholdType.DRAGON)) )); // Whenever a Dragon you control enters, put a +1/+1 counter on Sarkhan. Until end of turn, Sarkhan becomes a Dragon in addition to its other types and gains flying. diff --git a/Mage.Sets/src/mage/cards/s/SilvergillMentor.java b/Mage.Sets/src/mage/cards/s/SilvergillMentor.java new file mode 100644 index 00000000000..1d3432fbe59 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SilvergillMentor.java @@ -0,0 +1,49 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.OrCost; +import mage.abilities.costs.common.BeholdCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.BeholdType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.MerfolkWhiteBlueToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SilvergillMentor extends CardImpl { + + public SilvergillMentor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // As an additional cost to cast this spell, behold a Merfolk or pay {2}. + this.getSpellAbility().addCost(new OrCost( + "behold a Merfolk or pay {2}", + new BeholdCost(BeholdType.MERFOLK), new GenericManaCost(2) + )); + + // When this creature enters, create a 1/1 white and blue Merfolk creature token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new MerfolkWhiteBlueToken()))); + } + + private SilvergillMentor(final SilvergillMentor card) { + super(card); + } + + @Override + public SilvergillMentor copy() { + return new SilvergillMentor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/LorwynEclipsed.java b/Mage.Sets/src/mage/sets/LorwynEclipsed.java index 80497f7960e..af07bd667bc 100644 --- a/Mage.Sets/src/mage/sets/LorwynEclipsed.java +++ b/Mage.Sets/src/mage/sets/LorwynEclipsed.java @@ -56,6 +56,7 @@ public final class LorwynEclipsed extends ExpansionSet { cards.add(new SetCardInfo("Overgrown Tomb", 266, Rarity.RARE, mage.cards.o.OvergrownTomb.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Overgrown Tomb", 350, Rarity.RARE, mage.cards.o.OvergrownTomb.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Perfect Intimidation", 115, Rarity.UNCOMMON, mage.cards.p.PerfectIntimidation.class)); + cards.add(new SetCardInfo("Silvergill Mentor", 403, Rarity.UNCOMMON, mage.cards.s.SilvergillMentor.class)); cards.add(new SetCardInfo("Steam Vents", "348b", Rarity.RARE, mage.cards.s.SteamVents.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Steam Vents", 267, Rarity.RARE, mage.cards.s.SteamVents.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Steam Vents", 348, Rarity.RARE, mage.cards.s.SteamVents.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/condition/common/BeheldDragonCondition.java b/Mage/src/main/java/mage/abilities/condition/common/BeheldDragonCondition.java index ca7e543bbe2..a90b37d5815 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/BeheldDragonCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/BeheldDragonCondition.java @@ -2,7 +2,7 @@ package mage.abilities.condition.common; import mage.abilities.Ability; import mage.abilities.condition.Condition; -import mage.abilities.keyword.BeholdDragonAbility; +import mage.abilities.keyword.BeholdAbility; import mage.game.Game; import mage.util.CardUtil; @@ -16,7 +16,7 @@ public enum BeheldDragonCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - return CardUtil.checkSourceCostsTagExists(game, source, BeholdDragonAbility.BEHOLD_DRAGON_ACTIVATION_VALUE_KEY); + return CardUtil.checkSourceCostsTagExists(game, source, BeholdAbility.BEHOLD_ACTIVATION_VALUE_KEY); } @Override diff --git a/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java b/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java new file mode 100644 index 00000000000..ea8e31afb86 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java @@ -0,0 +1,46 @@ +package mage.abilities.costs.common; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.constants.BeholdType; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class BeholdCost extends CostImpl { + + private final BeholdType beholdType; + + public BeholdCost(BeholdType beholdType) { + super(); + this.beholdType = beholdType; + this.text = "behold " + beholdType.getDescription(); + } + + private BeholdCost(final BeholdCost cost) { + super(cost); + this.beholdType = cost.beholdType; + } + + @Override + public BeholdCost copy() { + return new BeholdCost(this); + } + + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + return beholdType.canBehold(controllerId, game, source); + } + + @Override + public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { + Player player = game.getPlayer(controllerId); + paid = player != null && beholdType.doBehold(player, game, source) != null; + return paid; + } +} diff --git a/Mage/src/main/java/mage/abilities/costs/common/BeholdDragonCost.java b/Mage/src/main/java/mage/abilities/costs/common/BeholdDragonCost.java deleted file mode 100644 index 3502a9a0888..00000000000 --- a/Mage/src/main/java/mage/abilities/costs/common/BeholdDragonCost.java +++ /dev/null @@ -1,109 +0,0 @@ -package mage.abilities.costs.common; - -import mage.abilities.Ability; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; -import mage.cards.Card; -import mage.cards.CardsImpl; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.TargetPermanent; -import mage.target.common.TargetCardInHand; - -import java.util.Optional; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public class BeholdDragonCost extends CostImpl { - - private static final FilterPermanent filterPermanent = new FilterControlledPermanent(SubType.DRAGON); - private static final FilterCard filterCard = new FilterCard("a Dragon card"); - - static { - filterCard.add(SubType.DRAGON.getPredicate()); - } - - public BeholdDragonCost() { - super(); - this.text = "behold a Dragon"; - } - - private BeholdDragonCost(final BeholdDragonCost cost) { - super(cost); - } - - @Override - public BeholdDragonCost copy() { - return new BeholdDragonCost(this); - } - - @Override - public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { - return Optional - .ofNullable(game.getPlayer(controllerId)) - .map(Player::getHand) - .map(cards -> cards.count(filterCard, game) > 0) - .orElse(false) - || game - .getBattlefield() - .contains(filterPermanent, controllerId, source, game, 1); - } - - @Override - public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { - Player player = game.getPlayer(controllerId); - if (player == null) { - paid = false; - return paid; - } - boolean hasPermanent = game - .getBattlefield() - .contains(filterPermanent, controllerId, source, game, 1); - boolean hasHand = player.getHand().count(filterCard, game) > 0; - boolean usePermanent; - if (hasPermanent && hasHand) { - usePermanent = player.chooseUse( - Outcome.Neutral, "Choose a Dragon you control or reveal one from your hand?", - null, "Choose controlled", "Reveal from hand", source, game); - } else if (hasPermanent) { - usePermanent = true; - } else if (hasHand) { - usePermanent = false; - } else { - paid = false; - return paid; - } - if (usePermanent) { - TargetPermanent target = new TargetPermanent(filterPermanent); - target.withNotTarget(true); - player.choose(Outcome.Neutral, target, source, game); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent == null) { - paid = false; - return paid; - } - game.informPlayers(player.getLogName() + " chooses to behold " + permanent.getLogName()); - paid = true; - return true; - } - TargetCard target = new TargetCardInHand(filterCard); - player.choose(Outcome.Neutral, player.getHand(), target, source, game); - Card card = game.getCard(target.getFirstTarget()); - if (card == null) { - paid = false; - return paid; - } - player.revealCards(source, new CardsImpl(card), game); - paid = true; - return paid; - } -} diff --git a/Mage/src/main/java/mage/abilities/keyword/BeholdDragonAbility.java b/Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java similarity index 58% rename from Mage/src/main/java/mage/abilities/keyword/BeholdDragonAbility.java rename to Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java index 9c9d6fd5bbc..66518784ee3 100644 --- a/Mage/src/main/java/mage/abilities/keyword/BeholdDragonAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java @@ -4,9 +4,8 @@ import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; import mage.abilities.costs.*; -import mage.abilities.costs.common.BeholdDragonCost; -import mage.abilities.costs.common.CollectEvidenceCost; -import mage.abilities.hint.common.EvidenceHint; +import mage.abilities.costs.common.BeholdCost; +import mage.constants.BeholdType; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; @@ -15,38 +14,47 @@ import mage.players.Player; /** * @author TheElk801 */ -public class BeholdDragonAbility extends StaticAbility implements OptionalAdditionalSourceCosts { +public class BeholdAbility extends StaticAbility implements OptionalAdditionalSourceCosts { - private static final String promptString = "Behold a Dragon"; - private static final String keywordText = "As an additional cost to cast this spell, you may behold a Dragon"; - private static final String reminderText = "Choose a Dragon you control or reveal a Dragon card from your hand."; + private static final String promptString = "Behold "; + private static final String keywordText = "As an additional cost to cast this spell, you may behold "; + private static final String reminderText = "Choose % you control or reveal % card from your hand."; private final String rule; - public static final String BEHOLD_DRAGON_ACTIVATION_VALUE_KEY = "beholdDragonActivation"; + public static final String BEHOLD_ACTIVATION_VALUE_KEY = "beholdActivation"; protected OptionalAdditionalCost additionalCost; - public static OptionalAdditionalCost makeCost() { - OptionalAdditionalCost cost = new OptionalAdditionalCostImpl(keywordText , reminderText, new BeholdDragonCost()); + public static OptionalAdditionalCost makeCost(BeholdType beholdType) { + OptionalAdditionalCost cost = new OptionalAdditionalCostImpl( + keywordText + beholdType.getDescription(), + String.format(reminderText, beholdType.getDescription()), + new BeholdCost(beholdType) + ); cost.setRepeatable(false); return cost; } - public BeholdDragonAbility( ) { + + private final BeholdType beholdType; + + public BeholdAbility(BeholdType beholdType) { super(Zone.STACK, null); - this.additionalCost = makeCost(); - this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText(); + this.beholdType = beholdType; + this.additionalCost = makeCost(beholdType); + this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText(); this.setRuleAtTheTop(true); } - private BeholdDragonAbility(final BeholdDragonAbility ability) { + private BeholdAbility(final BeholdAbility ability) { super(ability); + this.beholdType = ability.beholdType; this.rule = ability.rule; this.additionalCost = ability.additionalCost.copy(); } @Override - public BeholdDragonAbility copy() { - return new BeholdDragonAbility(this); + public BeholdAbility copy() { + return new BeholdAbility(this); } public void resetCost() { @@ -68,7 +76,7 @@ public class BeholdDragonAbility extends StaticAbility implements OptionalAdditi this.resetCost(); boolean canPay = additionalCost.canPay(ability, this, ability.getControllerId(), game); - if (!canPay || !player.chooseUse(Outcome.Exile, promptString + '?', ability, game)) { + if (!canPay || !player.chooseUse(Outcome.Exile, promptString + beholdType.getDescription() + '?', ability, game)) { return; } @@ -76,7 +84,7 @@ public class BeholdDragonAbility extends StaticAbility implements OptionalAdditi for (Cost cost : ((Costs) additionalCost)) { ability.getCosts().add(cost.copy()); } - ability.setCostsTag(BEHOLD_DRAGON_ACTIVATION_VALUE_KEY, null); + ability.setCostsTag(BEHOLD_ACTIVATION_VALUE_KEY, null); } @Override diff --git a/Mage/src/main/java/mage/constants/BeholdType.java b/Mage/src/main/java/mage/constants/BeholdType.java new file mode 100644 index 00000000000..c5d110da309 --- /dev/null +++ b/Mage/src/main/java/mage/constants/BeholdType.java @@ -0,0 +1,96 @@ +package mage.constants; + +import mage.abilities.Ability; +import mage.cards.Card; +import mage.cards.CardsImpl; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInHand; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public enum BeholdType { + DRAGON(SubType.DRAGON), + MERFOLK(SubType.MERFOLK); + + private final FilterPermanent filterPermanent; + private final FilterCard filterCard; + private final String description; + + BeholdType(SubType subType) { + this.filterPermanent = new FilterControlledPermanent(subType); + this.filterCard = new FilterCard(subType); + this.description = subType.getIndefiniteArticle() + ' ' + subType.getDescription(); + } + + public String getDescription() { + return description; + } + + public FilterCard getFilterCard() { + return filterCard; + } + + public FilterPermanent getFilterPermanent() { + return filterPermanent; + } + + public boolean canBehold(UUID controllerId, Game game, Ability source) { + return Optional + .ofNullable(game.getPlayer(controllerId)) + .map(Player::getHand) + .map(cards -> cards.count(this.getFilterCard(), game) > 0) + .orElse(false) + || game + .getBattlefield() + .contains(this.getFilterPermanent(), controllerId, source, game, 1); + } + + public Card doBehold(Player player, Game game, Ability source) { + boolean hasPermanent = game + .getBattlefield() + .contains(this.getFilterPermanent(), player.getId(), source, game, 1); + boolean hasHand = player.getHand().count(this.getFilterCard(), game) > 0; + boolean usePermanent; + if (hasPermanent && hasHand) { + usePermanent = player.chooseUse( + Outcome.Neutral, "Choose " + this.getDescription() + " you control or reveal one from your hand?", + null, "Choose controlled", "Reveal from hand", source, game); + } else if (hasPermanent) { + usePermanent = true; + } else if (hasHand) { + usePermanent = false; + } else { + return null; + } + if (usePermanent) { + TargetPermanent target = new TargetPermanent(this.getFilterPermanent()); + target.withNotTarget(true); + player.choose(Outcome.Neutral, target, source, game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent == null) { + return null; + } + game.informPlayers(player.getLogName() + " chooses to behold " + permanent.getLogName()); + return permanent; + } + TargetCard target = new TargetCardInHand(this.getFilterCard()); + player.choose(Outcome.Neutral, player.getHand(), target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card == null) { + return null; + } + player.revealCards(source, new CardsImpl(card), game); + return card; + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/MerfolkWhiteBlueToken.java b/Mage/src/main/java/mage/game/permanent/token/MerfolkWhiteBlueToken.java new file mode 100644 index 00000000000..c782d3c653f --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/MerfolkWhiteBlueToken.java @@ -0,0 +1,29 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author TheElk801 + */ +public final class MerfolkWhiteBlueToken extends TokenImpl { + + public MerfolkWhiteBlueToken() { + super("Merfolk Token", "1/1 white and blue Merfolk creature token"); + cardType.add(CardType.CREATURE); + color.setWhite(true); + color.setBlue(true); + subtype.add(SubType.MERFOLK); + power = new MageInt(1); + toughness = new MageInt(1); + } + + private MerfolkWhiteBlueToken(final MerfolkWhiteBlueToken token) { + super(token); + } + + public MerfolkWhiteBlueToken copy() { + return new MerfolkWhiteBlueToken(this); + } +} diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 41952ffe63c..cf752f1c13d 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -60868,6 +60868,7 @@ Bitterbloom Bearer|Lorwyn Eclipsed|352|M|{B}{B}|Creature - Faerie Rogue|1|1|Flas Formidable Speaker|Lorwyn Eclipsed|366|R|{2}{G}|Creature - Elf Druid|2|4|When this creature enters, you may discard a card. If you do, search your library for a creature card, reveal it, put it into your hand, then shuffle.${1}, {T}: Untap another target permanent.| Figure of Fable|Lorwyn Eclipsed|372|R|{G/W}|Creature - Kithkin|1|1|{G/W}: This creature becomes a Kithkin Scout with base power and toughness 2/3.${1}{G/W}{G/W}: If this creature is a Scout, it becomes a Kithkin Soldier with base power and toughness 4/5.${3}{G/W}{G/W}{G/W}: If this creature is a Soldier, it becomes a Kithkin Avatar with base power and toughness 7/8 and protection from each of your opponents.| High Perfect Morcant|Lorwyn Eclipsed|373|R|{2}{B}{G}|Legendary Creature - Elf Noble|4|4|Whenever High Perfect Morcant or another Elf you control enters, each opponent blights 1.$Tap three untapped Elves you control: Proliferate. Activate only as a sorcery.| +Silvergill Mentor|Lorwyn Eclipsed|403|U|{1}{U}|Creature - Merfolk Wizard|2|1|As an additional cost to cast this spell, behold a Merfolk or pay {2}.$When this creature enters, create a 1/1 white and blue Merfolk creature token.| Kirol, Attentive First-Year|Lorwyn Eclipsed|374|R|{1}{R/W}{R/W}|Legendary Creature - Vampire Cleric|3|3|Tap two untapped creatures you control: Copy target triggered ability you control. You may choose new targets for the copy. Activate only once each turn.| Greymond, Avacyn's Stalwart|Secret Lair Drop|143|M|{2}{W}{W}|Legendary Creature - Human Soldier|3|4|As Greymond, Avacyn's Stalwart enters, choose two abilities from among first strike, vigilance, and lifelink.$Humans you control have each of the chosen abilities.$As long as you control four or more Humans, Humans you control get +2/+2.| Hansk, Slayer Zealot|Secret Lair Drop|144|M|{2}{R}{G}|Legendary Creature - Human Archer|4|4|At the beginning of your upkeep, target opponent creates three Walker tokens.${T}: Hansk, Slayer Zealot deals 2 damage to target creature.$Whenever a Zombie an opponent controls dies, draw a card.|