diff --git a/Mage.Sets/src/mage/cards/c/CausticExhale.java b/Mage.Sets/src/mage/cards/c/CausticExhale.java index f0cc9ac1646..bcd7d107352 100644 --- a/Mage.Sets/src/mage/cards/c/CausticExhale.java +++ b/Mage.Sets/src/mage/cards/c/CausticExhale.java @@ -6,8 +6,8 @@ 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.constants.SubType; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -23,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 BeholdCost(BeholdType.DRAGON), new GenericManaCost(1) + new BeholdCost(SubType.DRAGON), new GenericManaCost(1) )); // Target creature gets -3/-3 until end of turn. diff --git a/Mage.Sets/src/mage/cards/c/CelestialReunion.java b/Mage.Sets/src/mage/cards/c/CelestialReunion.java new file mode 100644 index 00000000000..562e93e26e7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CelestialReunion.java @@ -0,0 +1,248 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.StaticAbility; +import mage.abilities.costs.*; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.choices.ChoiceCreatureType; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.util.CardUtil; + +import java.util.*; + +/** + * @author TheElk801 + */ +public final class CelestialReunion extends CardImpl { + + public CelestialReunion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{G}"); + + // As an additional cost to cast this spell, you may choose a creature type and behold two creatures of that type. + this.addAbility(new CelestialReunionAbility()); + + // Search your library for a creature card with mana value X or less, reveal it, put it into your hand, then shuffle. If this spell's additional cost was paid and the revealed card is the chosen type, put that card onto the battlefield instead of putting it into your hand. + this.getSpellAbility().addEffect(new CelestialReunionEffect()); + } + + private CelestialReunion(final CelestialReunion card) { + super(card); + } + + @Override + public CelestialReunion copy() { + return new CelestialReunion(this); + } +} + +class CelestialReunionAbility extends StaticAbility implements OptionalAdditionalSourceCosts { + + private final String rule; + + public static final String CELESTIAL_REUNION_ACTIVATION_VALUE_KEY = "beholdActivation"; + + protected OptionalAdditionalCost additionalCost; + + public static OptionalAdditionalCost makeCost() { + OptionalAdditionalCost cost = new OptionalAdditionalCostImpl( + "As an additional cost to cast this spell, you may choose a creature type and behold two creatures of that type", + "Choose a creature you control or reveal a creature card from your hand of the chosen type.", + new CelestialReunionCost() + ); + cost.setRepeatable(false); + return cost; + } + + public CelestialReunionAbility() { + super(Zone.STACK, null); + this.additionalCost = makeCost(); + this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText(); + this.setRuleAtTheTop(true); + } + + private CelestialReunionAbility(final CelestialReunionAbility ability) { + super(ability); + this.rule = ability.rule; + this.additionalCost = ability.additionalCost.copy(); + } + + @Override + public CelestialReunionAbility copy() { + return new CelestialReunionAbility(this); + } + + public void resetCost() { + if (additionalCost != null) { + additionalCost.reset(); + } + } + + @Override + public void addOptionalAdditionalCosts(Ability ability, Game game) { + if (!(ability instanceof SpellAbility)) { + return; + } + + Player player = game.getPlayer(ability.getControllerId()); + if (player == null) { + return; + } + + this.resetCost(); + boolean canPay = additionalCost.canPay(ability, this, ability.getControllerId(), game); + if (!canPay || !player.chooseUse(Outcome.Exile, "Choose a creature type and behold two creatures of that type?", ability, game)) { + return; + } + + additionalCost.activate(); + for (Cost cost : ((Costs) additionalCost)) { + ability.getCosts().add(cost.copy()); + } + ability.setCostsTag(CELESTIAL_REUNION_ACTIVATION_VALUE_KEY, null); + } + + @Override + public String getCastMessageSuffix() { + return additionalCost.getCastSuffixMessage(0); + } + + @Override + public String getRule() { + return rule; + } + + static boolean checkCard(Card card, Game game, Ability source) { + return CardUtil + .checkSourceCostsTagExists(game, source, CELESTIAL_REUNION_ACTIVATION_VALUE_KEY) + && CardUtil + .castStream(source.getCosts(), CelestialReunionCost.class) + .map(CelestialReunionCost::getSubType) + .filter(Objects::nonNull) + .anyMatch(subType -> card.hasSubtype(subType, game)); + } +} + +class CelestialReunionCost extends CostImpl { + + private SubType subType = null; + + CelestialReunionCost() { + super(); + } + + private CelestialReunionCost(final CelestialReunionCost cost) { + super(cost); + this.subType = cost.subType; + } + + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + Set cards = Optional + .ofNullable(controllerId) + .map(game::getPlayer) + .map(Player::getHand) + .map(x -> x.getCards(StaticFilters.FILTER_CARD_CREATURE, game)) + .orElseGet(HashSet::new); + cards.addAll(game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CONTROLLED_CREATURE, controllerId, source, game)); + return CardUtil.checkAnyPairs(cards, (c1, c2) -> c1.shareCreatureTypes(game, c2)); + } + + @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; + } + ChoiceCreatureType choice = new ChoiceCreatureType(game, source); + player.choose(Outcome.Benefit, choice, game); + SubType subType = SubType.fromString(choice.getChoice()); + if (subType == null) { + paid = false; + return paid; + } + this.subType = subType; + this.paid = BeholdType.getBeholdType(subType).doBehold(player, 2, game, source).size() == 2; + return paid; + } + + @Override + public CelestialReunionCost copy() { + return new CelestialReunionCost(this); + } + + public SubType getSubType() { + return subType; + } +} + +class CelestialReunionEffect extends OneShotEffect { + + enum CelestialReunionPredicate implements ObjectSourcePlayerPredicate { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return input.getObject().getManaValue() <= GetXValue.instance.calculate(game, input.getSource(), null); + } + } + + private static final FilterCard filter = new FilterCreatureCard("creature card with mana value X or less"); + + static { + filter.add(CelestialReunionPredicate.instance); + } + + CelestialReunionEffect() { + super(Outcome.Benefit); + staticText = "search your library for a creature card with mana value X or less, reveal it, " + + "put it into your hand, then shuffle. If this spell's additional cost was paid and the revealed card " + + "is the chosen type, put that card onto the battlefield instead of putting it into your hand"; + } + + private CelestialReunionEffect(final CelestialReunionEffect effect) { + super(effect); + } + + @Override + public CelestialReunionEffect copy() { + return new CelestialReunionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + player.searchLibrary(target, source, game); + Card card = player.getLibrary().getCard(target.getFirstTarget(), game); + if (card == null) { + player.shuffleLibrary(source, game); + return true; + } + player.revealCards(source, new CardsImpl(card), game); + player.moveCards( + card, + CelestialReunionAbility.checkCard(card, game, source) ? Zone.BATTLEFIELD : Zone.HAND, + source, game + ); + player.shuffleLibrary(source, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfTheClachan.java b/Mage.Sets/src/mage/cards/c/ChampionOfTheClachan.java index f89c1578fb5..fe53d3e65c4 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionOfTheClachan.java +++ b/Mage.Sets/src/mage/cards/c/ChampionOfTheClachan.java @@ -9,7 +9,6 @@ import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; @@ -36,7 +35,7 @@ public final class ChampionOfTheClachan extends CardImpl { this.addAbility(FlashAbility.getInstance()); // As an additional cost to cast this spell, behold a Kithkin and exile it. - this.getSpellAbility().addCost(new BeholdAndExileCost(BeholdType.KITHKIN)); + this.getSpellAbility().addCost(new BeholdAndExileCost(SubType.KITHKIN)); // Other Kithkin you control get +1/+1. this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfThePath.java b/Mage.Sets/src/mage/cards/c/ChampionOfThePath.java index 543a9bc1b76..dcaa2ecb188 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionOfThePath.java +++ b/Mage.Sets/src/mage/cards/c/ChampionOfThePath.java @@ -9,7 +9,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnExiledCardToHandEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -42,7 +41,7 @@ public final class ChampionOfThePath extends CardImpl { this.toughness = new MageInt(3); // As an additional cost to cast this spell, behold an Elemental and exile it. - this.getSpellAbility().addCost(new BeholdAndExileCost(BeholdType.ELEMENTAL)); + this.getSpellAbility().addCost(new BeholdAndExileCost(SubType.ELEMENTAL)); // Whenever another Elemental you control enters, it deals damage equal to its power to each opponent. this.addAbility(new EntersBattlefieldAllTriggeredAbility(new ChampionOfThePathEffect(), filter)); diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfTheWeird.java b/Mage.Sets/src/mage/cards/c/ChampionOfTheWeird.java index 7b8ea6f6ed1..7cc6acc07e8 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionOfTheWeird.java +++ b/Mage.Sets/src/mage/cards/c/ChampionOfTheWeird.java @@ -11,7 +11,6 @@ import mage.abilities.effects.common.ReturnExiledCardToHandEffect; import mage.abilities.effects.keyword.BlightTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.SubType; import mage.target.common.TargetOpponent; @@ -32,7 +31,7 @@ public final class ChampionOfTheWeird extends CardImpl { this.toughness = new MageInt(5); // As an additional cost to cast this spell, behold a Goblin and exile it. - this.getSpellAbility().addCost(new BeholdAndExileCost(BeholdType.GOBLIN)); + this.getSpellAbility().addCost(new BeholdAndExileCost(SubType.GOBLIN)); // Pay 1 life, Blight 2: Target opponent blights 2. Activate only as a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(new BlightTargetEffect(2), new PayLifeCost(1)); diff --git a/Mage.Sets/src/mage/cards/c/ChampionsOfThePerfect.java b/Mage.Sets/src/mage/cards/c/ChampionsOfThePerfect.java index f23deb5c4db..4e51014b91b 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionsOfThePerfect.java +++ b/Mage.Sets/src/mage/cards/c/ChampionsOfThePerfect.java @@ -8,7 +8,6 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ReturnExiledCardToHandEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.StaticFilters; @@ -29,7 +28,7 @@ public final class ChampionsOfThePerfect extends CardImpl { this.toughness = new MageInt(6); // As an additional cost to cast this spell, behold an Elf and exile it. - this.getSpellAbility().addCost(new BeholdAndExileCost(BeholdType.ELF)); + this.getSpellAbility().addCost(new BeholdAndExileCost(SubType.ELF)); // Whenever you cast a creature spell, draw a card. this.addAbility(new SpellCastControllerTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/c/ChampionsOfTheShoal.java b/Mage.Sets/src/mage/cards/c/ChampionsOfTheShoal.java index ba183ebf826..c5380ff49bb 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionsOfTheShoal.java +++ b/Mage.Sets/src/mage/cards/c/ChampionsOfTheShoal.java @@ -12,7 +12,6 @@ import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.meta.OrTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -35,7 +34,7 @@ public final class ChampionsOfTheShoal extends CardImpl { this.toughness = new MageInt(6); // As an additional cost to cast this spell, behold a Merfolk and exile it. - this.getSpellAbility().addCost(new BeholdAndExileCost(BeholdType.MERFOLK)); + this.getSpellAbility().addCost(new BeholdAndExileCost(SubType.MERFOLK)); // Whenever this creature enters or becomes tapped, tap up to one target creature and put a stun counter on it. Ability ability = new OrTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/d/DispellingExhale.java b/Mage.Sets/src/mage/cards/d/DispellingExhale.java index 6d2ba706f5e..aea29b48e52 100644 --- a/Mage.Sets/src/mage/cards/d/DispellingExhale.java +++ b/Mage.Sets/src/mage/cards/d/DispellingExhale.java @@ -7,8 +7,8 @@ import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; +import mage.constants.SubType; import mage.target.TargetSpell; import java.util.UUID; @@ -22,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 BeholdAbility(BeholdType.DRAGON)); + this.addAbility(new BeholdAbility(SubType.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/k/KindleTheInnerFlame.java b/Mage.Sets/src/mage/cards/k/KindleTheInnerFlame.java index 3885b370b2b..5d87ff39227 100644 --- a/Mage.Sets/src/mage/cards/k/KindleTheInnerFlame.java +++ b/Mage.Sets/src/mage/cards/k/KindleTheInnerFlame.java @@ -10,7 +10,6 @@ import mage.abilities.keyword.HasteAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; @@ -40,7 +39,7 @@ public final class KindleTheInnerFlame extends CardImpl { // Flashback--{1}{R}, Behold three Elementals. Ability ability = new FlashbackAbility(this, new ManaCostsImpl<>("{1}{R}")); - ability.addCost(new BeholdCost(BeholdType.ELEMENTAL, 3)); + ability.addCost(new BeholdCost(SubType.ELEMENTAL, 3)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KinsbaileAspirant.java b/Mage.Sets/src/mage/cards/k/KinsbaileAspirant.java index 5398c187847..689a785c270 100644 --- a/Mage.Sets/src/mage/cards/k/KinsbaileAspirant.java +++ b/Mage.Sets/src/mage/cards/k/KinsbaileAspirant.java @@ -8,7 +8,6 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; @@ -31,7 +30,7 @@ public final class KinsbaileAspirant extends CardImpl { // As an additional cost to cast this spell, behold a Kithkin or pay {2}. this.getSpellAbility().addCost(new OrCost( - "behold a Kithkin or pay {2}", new BeholdCost(BeholdType.KITHKIN), new GenericManaCost(2) + "behold a Kithkin or pay {2}", new BeholdCost(SubType.KITHKIN), new GenericManaCost(2) )); // Whenever another creature you control enters, this creature gets +1/+1 until end of turn. diff --git a/Mage.Sets/src/mage/cards/l/LysAlanaDignitary.java b/Mage.Sets/src/mage/cards/l/LysAlanaDignitary.java index a6096da6d60..5ce4827d3a1 100644 --- a/Mage.Sets/src/mage/cards/l/LysAlanaDignitary.java +++ b/Mage.Sets/src/mage/cards/l/LysAlanaDignitary.java @@ -14,7 +14,6 @@ import mage.abilities.hint.Hint; import mage.abilities.mana.ActivateIfConditionManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -42,7 +41,7 @@ public final class LysAlanaDignitary extends CardImpl { // As an additional cost to cast this spell, behold an Elf or pay {2}. this.getSpellAbility().addCost(new OrCost( "behold an Elf or pay {2}", - new BeholdCost(BeholdType.ELF), new GenericManaCost(2) + new BeholdCost(SubType.ELF), new GenericManaCost(2) )); // {T}: Add {G}{G}. Activate only if there is an Elf card in your graveyard. diff --git a/Mage.Sets/src/mage/cards/m/MoltenExhale.java b/Mage.Sets/src/mage/cards/m/MoltenExhale.java index f9022131811..d9db0044fa9 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenExhale.java +++ b/Mage.Sets/src/mage/cards/m/MoltenExhale.java @@ -7,8 +7,8 @@ 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.constants.SubType; import mage.target.Target; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -23,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 BeholdCost(BeholdType.DRAGON), + Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new BeholdCost(SubType.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/m/MudbuttonCursetosser.java b/Mage.Sets/src/mage/cards/m/MudbuttonCursetosser.java index aab45cbcaed..22079c96207 100644 --- a/Mage.Sets/src/mage/cards/m/MudbuttonCursetosser.java +++ b/Mage.Sets/src/mage/cards/m/MudbuttonCursetosser.java @@ -10,7 +10,6 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SubType; @@ -43,7 +42,7 @@ public final class MudbuttonCursetosser extends CardImpl { // As an additional cost to cast this spell, behold a Goblin or pay {2}. this.getSpellAbility().addCost(new OrCost( "behold a Goblin or pay {2}", - new BeholdCost(BeholdType.GOBLIN), new GenericManaCost(2) + new BeholdCost(SubType.GOBLIN), new GenericManaCost(2) )); // This creature can't block. diff --git a/Mage.Sets/src/mage/cards/o/OsseousExhale.java b/Mage.Sets/src/mage/cards/o/OsseousExhale.java index 8c58f52df89..55f0c507d66 100644 --- a/Mage.Sets/src/mage/cards/o/OsseousExhale.java +++ b/Mage.Sets/src/mage/cards/o/OsseousExhale.java @@ -7,8 +7,8 @@ import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; +import mage.constants.SubType; import mage.target.common.TargetAttackingOrBlockingCreature; import java.util.UUID; @@ -22,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 BeholdAbility(BeholdType.DRAGON)); + this.addAbility(new BeholdAbility(SubType.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 a6d0987b099..500a7e270b0 100644 --- a/Mage.Sets/src/mage/cards/p/PiercingExhale.java +++ b/Mage.Sets/src/mage/cards/p/PiercingExhale.java @@ -7,8 +7,8 @@ import mage.abilities.effects.keyword.SurveilEffect; import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; +import mage.constants.SubType; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -23,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 BeholdAbility(BeholdType.DRAGON)); + this.addAbility(new BeholdAbility(SubType.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 3ef97eadaae..794949cb4a7 100644 --- a/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java +++ b/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java @@ -39,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 BeholdCost(BeholdType.DRAGON)) + new DoIfCostPaid(new CreateTokenEffect(new TreasureToken()), new BeholdCost(SubType.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 index 1d3432fbe59..31d44cf731e 100644 --- a/Mage.Sets/src/mage/cards/s/SilvergillMentor.java +++ b/Mage.Sets/src/mage/cards/s/SilvergillMentor.java @@ -8,7 +8,6 @@ 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; @@ -31,7 +30,7 @@ public final class SilvergillMentor extends CardImpl { // 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) + new BeholdCost(SubType.MERFOLK), new GenericManaCost(2) )); // When this creature enters, create a 1/1 white and blue Merfolk creature token. diff --git a/Mage.Sets/src/mage/cards/s/SoulbrightSeeker.java b/Mage.Sets/src/mage/cards/s/SoulbrightSeeker.java index beb0962f081..5f731fc0d31 100644 --- a/Mage.Sets/src/mage/cards/s/SoulbrightSeeker.java +++ b/Mage.Sets/src/mage/cards/s/SoulbrightSeeker.java @@ -1,6 +1,5 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.Mana; import mage.abilities.Ability; @@ -14,19 +13,18 @@ import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.hint.common.AbilityResolutionCountHint; import mage.abilities.keyword.TrampleAbility; -import mage.constants.SubType; -import mage.target.common.TargetControlledCreaturePermanent; -import mage.target.common.TargetCreaturePermanent; -import mage.watchers.common.AbilityResolvedWatcher; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.BeholdType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.watchers.common.AbilityResolvedWatcher; + +import java.util.UUID; /** - * * @author muz */ public final class SoulbrightSeeker extends CardImpl { @@ -41,8 +39,8 @@ public final class SoulbrightSeeker extends CardImpl { // As an additional cost to cast this spell, behold an Elemental or pay {2}. this.getSpellAbility().addCost(new OrCost("behold an Elemental or pay {2}", - new BeholdCost(BeholdType.ELEMENTAL), - new GenericManaCost(2) + new BeholdCost(SubType.ELEMENTAL), + new GenericManaCost(2) )); // {R}: Target creature you control gains trample until end of turn. If this is the third time this ability has resolved this turn, add {R}{R}{R}{R}. @@ -50,9 +48,9 @@ public final class SoulbrightSeeker extends CardImpl { TrampleAbility.getInstance(), Duration.EndOfTurn ), new ManaCostsImpl<>("{R}")); ability.addEffect( - new IfAbilityHasResolvedXTimesEffect( - Outcome.PutManaInPool, 3, new BasicManaEffect(Mana.RedMana(4)) - ).setText("If this is the third time this ability has resolved this turn, add {R}{R}{R}{R}") + new IfAbilityHasResolvedXTimesEffect( + Outcome.PutManaInPool, 3, new BasicManaEffect(Mana.RedMana(4)) + ).setText("If this is the third time this ability has resolved this turn, add {R}{R}{R}{R}") ); ability.addTarget(new TargetControlledCreaturePermanent()); ability.addHint(AbilityResolutionCountHint.instance); diff --git a/Mage.Sets/src/mage/sets/LorwynEclipsed.java b/Mage.Sets/src/mage/sets/LorwynEclipsed.java index 4f90ac7efa9..3a54d56bf5c 100644 --- a/Mage.Sets/src/mage/sets/LorwynEclipsed.java +++ b/Mage.Sets/src/mage/sets/LorwynEclipsed.java @@ -82,6 +82,8 @@ public final class LorwynEclipsed extends ExpansionSet { cards.add(new SetCardInfo("Burning Curiosity", 129, Rarity.COMMON, mage.cards.b.BurningCuriosity.class)); cards.add(new SetCardInfo("Catharsis", 209, Rarity.MYTHIC, mage.cards.c.Catharsis.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Catharsis", 292, Rarity.MYTHIC, mage.cards.c.Catharsis.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Celestial Reunion", 170, Rarity.MYTHIC, mage.cards.c.CelestialReunion.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Celestial Reunion", 326, Rarity.MYTHIC, mage.cards.c.CelestialReunion.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Champion of the Clachan", 353, Rarity.RARE, mage.cards.c.ChampionOfTheClachan.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Champion of the Clachan", 9, Rarity.RARE, mage.cards.c.ChampionOfTheClachan.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Champion of the Path", 130, Rarity.RARE, mage.cards.c.ChampionOfThePath.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/costs/common/BeholdAndExileCost.java b/Mage/src/main/java/mage/abilities/costs/common/BeholdAndExileCost.java index dd8231df109..ea6b7f2284b 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/BeholdAndExileCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/BeholdAndExileCost.java @@ -5,6 +5,7 @@ import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; import mage.cards.Card; import mage.constants.BeholdType; +import mage.constants.SubType; import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; @@ -18,9 +19,9 @@ public class BeholdAndExileCost extends CostImpl { private final BeholdType beholdType; - public BeholdAndExileCost(BeholdType beholdType) { + public BeholdAndExileCost(SubType subType) { super(); - this.beholdType = beholdType; + this.beholdType = BeholdType.getBeholdType(subType); this.text = "behold " + beholdType.getDescription() + " and exile it"; } diff --git a/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java b/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java index ba6101324da..8382c1c099b 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java @@ -4,6 +4,7 @@ import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; import mage.constants.BeholdType; +import mage.constants.SubType; import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; @@ -18,8 +19,12 @@ public class BeholdCost extends CostImpl { private final BeholdType beholdType; private final int amount; - public BeholdCost(BeholdType beholdType) { - this(beholdType, 1); + public BeholdCost(SubType subType) { + this(subType, 1); + } + + public BeholdCost(SubType subType, int amount) { + this(BeholdType.getBeholdType(subType), amount); } public BeholdCost(BeholdType beholdType, int amount) { @@ -28,8 +33,8 @@ public class BeholdCost extends CostImpl { this.amount = amount; this.text = "behold " + ( amount > 1 - ? CardUtil.numberToText(amount) + ' ' + beholdType.getSubType().getPluralName() - : beholdType.getDescription() + ? CardUtil.numberToText(amount) + ' ' + this.beholdType.getSubType().getPluralName() + : this.beholdType.getDescription() ); } diff --git a/Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java b/Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java index 2a381d00d19..2de66bd3768 100644 --- a/Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java @@ -7,6 +7,7 @@ import mage.abilities.costs.*; import mage.abilities.costs.common.BeholdCost; import mage.constants.BeholdType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -29,7 +30,7 @@ public class BeholdAbility extends StaticAbility implements OptionalAdditionalSo OptionalAdditionalCost cost = new OptionalAdditionalCostImpl( keywordText + beholdType.getDescription(), reminderText.replace("$$$", beholdType.getDescription()), - new BeholdCost(beholdType) + new BeholdCost(beholdType, 1) ); cost.setRepeatable(false); return cost; @@ -37,9 +38,9 @@ public class BeholdAbility extends StaticAbility implements OptionalAdditionalSo private final BeholdType beholdType; - public BeholdAbility(BeholdType beholdType) { + public BeholdAbility(SubType subType) { super(Zone.STACK, null); - this.beholdType = beholdType; + this.beholdType = BeholdType.getBeholdType(subType); this.additionalCost = makeCost(beholdType); this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText(); this.setRuleAtTheTop(true); diff --git a/Mage/src/main/java/mage/constants/BeholdType.java b/Mage/src/main/java/mage/constants/BeholdType.java index 3e2508d7528..ad1e9027cad 100644 --- a/Mage/src/main/java/mage/constants/BeholdType.java +++ b/Mage/src/main/java/mage/constants/BeholdType.java @@ -16,25 +16,24 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCardInHand; import mage.util.CardUtil; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; /** * @author TheElk801 */ -public enum BeholdType { - DRAGON(SubType.DRAGON), - GOBLIN(SubType.GOBLIN), - ELEMENTAL(SubType.ELEMENTAL), - ELF(SubType.ELF), - KITHKIN(SubType.KITHKIN), - MERFOLK(SubType.MERFOLK); +public class BeholdType { + + private static Map typeMap = new HashMap<>(); + + public static BeholdType getBeholdType(SubType subType) { + return typeMap.computeIfAbsent(subType, s -> new BeholdType(s)); + } private final FilterPermanent filterPermanent; private final FilterCard filterCard; private final SubType subType; + private final String description; BeholdType(SubType subType) {