diff --git a/Mage.Sets/src/mage/cards/k/KindleTheInnerFlame.java b/Mage.Sets/src/mage/cards/k/KindleTheInnerFlame.java new file mode 100644 index 00000000000..3885b370b2b --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KindleTheInnerFlame.java @@ -0,0 +1,55 @@ +package mage.cards.k; + +import mage.abilities.Ability; +import mage.abilities.costs.common.BeholdCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.keyword.FlashbackAbility; +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; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KindleTheInnerFlame extends CardImpl { + + public KindleTheInnerFlame(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.KINDRED, CardType.SORCERY}, "{3}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + + // Create a token that's a copy of target creature you control, except it has haste and "At the beginning of the end step, sacrifice this token." + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect().addAdditionalAbilities( + HasteAbility.getInstance(), + new BeginningOfEndStepTriggeredAbility( + TargetController.NEXT, new SacrificeSourceEffect(), false + ) + ).setText("create a token that's a copy of target creature you control, " + + "except it has haste and \"At the beginning of the end step, sacrifice this token.\"")); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + + // Flashback--{1}{R}, Behold three Elementals. + Ability ability = new FlashbackAbility(this, new ManaCostsImpl<>("{1}{R}")); + ability.addCost(new BeholdCost(BeholdType.ELEMENTAL, 3)); + this.addAbility(ability); + } + + private KindleTheInnerFlame(final KindleTheInnerFlame card) { + super(card); + } + + @Override + public KindleTheInnerFlame copy() { + return new KindleTheInnerFlame(this); + } +} diff --git a/Mage.Sets/src/mage/sets/LorwynEclipsed.java b/Mage.Sets/src/mage/sets/LorwynEclipsed.java index 9ac84a3e94b..2f2a50a39bd 100644 --- a/Mage.Sets/src/mage/sets/LorwynEclipsed.java +++ b/Mage.Sets/src/mage/sets/LorwynEclipsed.java @@ -191,6 +191,7 @@ public final class LorwynEclipsed extends ExpansionSet { cards.add(new SetCardInfo("Island", 275, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", 280, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Keep Out", 19, Rarity.COMMON, mage.cards.k.KeepOut.class)); + cards.add(new SetCardInfo("Kindle the Inner Flame", 147, Rarity.UNCOMMON, mage.cards.k.KindleTheInnerFlame.class)); cards.add(new SetCardInfo("Kinsbaile Aspirant", 21, Rarity.UNCOMMON, mage.cards.k.KinsbaileAspirant.class)); cards.add(new SetCardInfo("Kinscaer Sentry", 22, Rarity.RARE, mage.cards.k.KinscaerSentry.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kinscaer Sentry", 300, Rarity.RARE, mage.cards.k.KinscaerSentry.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 09aa2d7a216..dd8231df109 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/BeholdAndExileCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/BeholdAndExileCost.java @@ -36,7 +36,7 @@ public class BeholdAndExileCost extends CostImpl { @Override public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { - return beholdType.canBehold(controllerId, game, source); + return beholdType.canBehold(controllerId, 1, game, source); } @Override @@ -46,7 +46,7 @@ public class BeholdAndExileCost extends CostImpl { paid = false; return paid; } - Card card = beholdType.doBehold(player, game, source); + Card card = beholdType.beholdOne(player, game, source); if (card == null) { paid = false; return paid; 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 ea8e31afb86..ba6101324da 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java @@ -6,6 +6,7 @@ import mage.abilities.costs.CostImpl; import mage.constants.BeholdType; import mage.game.Game; import mage.players.Player; +import mage.util.CardUtil; import java.util.UUID; @@ -15,16 +16,27 @@ import java.util.UUID; public class BeholdCost extends CostImpl { private final BeholdType beholdType; + private final int amount; public BeholdCost(BeholdType beholdType) { + this(beholdType, 1); + } + + public BeholdCost(BeholdType beholdType, int amount) { super(); this.beholdType = beholdType; - this.text = "behold " + beholdType.getDescription(); + this.amount = amount; + this.text = "behold " + ( + amount > 1 + ? CardUtil.numberToText(amount) + ' ' + beholdType.getSubType().getPluralName() + : beholdType.getDescription() + ); } private BeholdCost(final BeholdCost cost) { super(cost); this.beholdType = cost.beholdType; + this.amount = cost.amount; } @Override @@ -34,13 +46,13 @@ public class BeholdCost extends CostImpl { @Override public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { - return beholdType.canBehold(controllerId, game, source); + return beholdType.canBehold(controllerId, amount, 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; + paid = player != null && beholdType.doBehold(player, amount, game, source).size() == amount; return paid; } } diff --git a/Mage/src/main/java/mage/constants/BeholdType.java b/Mage/src/main/java/mage/constants/BeholdType.java index 82b57822cec..3e2508d7528 100644 --- a/Mage/src/main/java/mage/constants/BeholdType.java +++ b/Mage/src/main/java/mage/constants/BeholdType.java @@ -1,7 +1,9 @@ package mage.constants; +import mage.MageObject; import mage.abilities.Ability; import mage.cards.Card; +import mage.cards.Cards; import mage.cards.CardsImpl; import mage.filter.FilterCard; import mage.filter.FilterPermanent; @@ -12,9 +14,12 @@ import mage.players.Player; import mage.target.TargetCard; 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.stream.Collectors; /** * @author TheElk801 @@ -29,18 +34,16 @@ public enum BeholdType { private final FilterPermanent filterPermanent; private final FilterCard filterCard; + private final SubType subType; private final String description; BeholdType(SubType subType) { this.filterPermanent = new FilterControlledPermanent(subType); this.filterCard = new FilterCard(subType); + this.subType = subType; this.description = subType.getIndefiniteArticle() + ' ' + subType.getDescription(); } - public String getDescription() { - return description; - } - public FilterCard getFilterCard() { return filterCard; } @@ -49,18 +52,65 @@ public enum BeholdType { return filterPermanent; } - public boolean canBehold(UUID controllerId, Game game, Ability source) { + public SubType getSubType() { + return subType; + } + + public String getDescription() { + return description; + } + + public boolean canBehold(UUID controllerId, int amount, Game game, Ability source) { return Optional .ofNullable(game.getPlayer(controllerId)) .map(Player::getHand) - .map(cards -> cards.count(this.getFilterCard(), game) > 0) - .orElse(false) - || game + .map(cards -> cards.count(this.getFilterCard(), game)) + .orElse(0) + + game .getBattlefield() - .contains(this.getFilterPermanent(), controllerId, source, game, 1); + .count(this.getFilterPermanent(), controllerId, source, game) >= amount; } - public Card doBehold(Player player, Game game, Ability source) { + public Cards doBehold(Player player, int amount, Game game, Ability source) { + if (amount == 1) { + return new CardsImpl(beholdOne(player, game, source)); + } + Cards cards = new CardsImpl(); + TargetPermanent targetPermanent = new TargetPermanent(0, amount, this.getFilterPermanent(), true); + targetPermanent.withChooseHint("to behold"); + player.choose(Outcome.Neutral, targetPermanent, source, game); + cards.addAll(targetPermanent.getTargets()); + if (cards.size() < amount) { + TargetCard targetCard = new TargetCardInHand( + 0, amount - cards.size(), filterCard + ).withChooseHint("to reveal and behold"); + player.choose(Outcome.Neutral, player.getHand(), targetCard, source, game); + cards.addAll(targetCard.getTargets()); + player.revealCards(source, new CardsImpl(targetCard.getTargets()), game); + } + String permMessage = CardUtil.concatWithAnd(cards + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .map(MageObject::getLogName) + .collect(Collectors.toList())); + String handMessage = CardUtil.concatWithAnd(cards + .getCards(game) + .stream() + .filter(card -> Zone.HAND.match(game.getState().getZone(card.getId()))) + .map(MageObject::getLogName) + .collect(Collectors.toList())); + if (!permMessage.isEmpty() && handMessage.isEmpty()) { + game.informPlayers(player.getLogName() + " chooses to behold " + permMessage + " from the battlefield"); + } else if (permMessage.isEmpty() && !handMessage.isEmpty()) { + game.informPlayers(player.getLogName() + " chooses to behold " + permMessage + " from their hand"); + } else { + game.informPlayers(player.getLogName() + " chooses to behold " + permMessage + " from the battlefield and " + permMessage + " from their hand"); + } + return cards; + } + + public Card beholdOne(Player player, Game game, Ability source) { boolean hasPermanent = game .getBattlefield() .contains(this.getFilterPermanent(), player.getId(), source, game, 1);