From d275dd042b8c3f45e5ff7978cfc538e459cf731e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 27 Apr 2022 19:16:38 -0400 Subject: [PATCH] [NCC] Implemented Xander's Pact --- Mage.Sets/src/mage/cards/x/XandersPact.java | 126 ++++++++++++++++++ .../src/mage/sets/NewCapennaCommander.java | 1 + 2 files changed, 127 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/x/XandersPact.java diff --git a/Mage.Sets/src/mage/cards/x/XandersPact.java b/Mage.Sets/src/mage/cards/x/XandersPact.java new file mode 100644 index 00000000000..db9c911e034 --- /dev/null +++ b/Mage.Sets/src/mage/cards/x/XandersPact.java @@ -0,0 +1,126 @@ +package mage.cards.x; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.Costs; +import mage.abilities.costs.CostsImpl; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.asthought.CanPlayCardControllerEffect; +import mage.abilities.keyword.CasualtyAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class XandersPact extends CardImpl { + + public XandersPact(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}{B}"); + + // Casualty 2 + this.addAbility(new CasualtyAbility(this, 2)); + + // Each opponent exiles the top card of their library. You may cast spells from among those cards this turn. If you cast a spell this way, pay life equal to that spell's mana value rather than pay its mana cost. + this.getSpellAbility().addEffect(new XandersPactExileEffect()); + } + + private XandersPact(final XandersPact card) { + super(card); + } + + @Override + public XandersPact copy() { + return new XandersPact(this); + } +} + +class XandersPactExileEffect extends OneShotEffect { + + XandersPactExileEffect() { + super(Outcome.Benefit); + staticText = "each opponent exiles the top card of their library. You may cast spells " + + "from among those cards this turn. If you cast a spell this way, " + + "pay life equal to that spell's mana value rather than pay its mana cost"; + } + + private XandersPactExileEffect(final XandersPactExileEffect effect) { + super(effect); + } + + @Override + public XandersPactExileEffect copy() { + return new XandersPactExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Set cards = game + .getOpponents(source.getControllerId()) + .stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .map(Player::getLibrary) + .map(library -> library.getFromTop(game)) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + if (cards.isEmpty()) { + return false; + } + player.moveCards(cards, Zone.EXILED, source, game); + for (Card card : cards) { + game.addEffect(new XandersPactCastEffect(game, card), source); + } + return true; + } +} + +class XandersPactCastEffect extends CanPlayCardControllerEffect { + + XandersPactCastEffect(Game game, Card card) { + super(game, card.getMainCard().getId(), card.getZoneChangeCounter(game), Duration.EndOfTurn); + } + + private XandersPactCastEffect(final XandersPactCastEffect effect) { + super(effect); + } + + @Override + public XandersPactCastEffect copy() { + return new XandersPactCastEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (!super.applies(objectId, source, affectedControllerId, game)) { + return false; + } + Card cardToCheck = game.getCard(objectId); + if (cardToCheck.isLand(game)) { + return false; + } + Player controller = game.getPlayer(source.getControllerId()); + Costs newCosts = new CostsImpl<>(); + newCosts.add(new PayLifeCost(cardToCheck.getManaValue())); + newCosts.addAll(cardToCheck.getSpellAbility().getCosts()); + controller.setCastSourceIdWithAlternateMana(cardToCheck.getId(), null, newCosts); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/NewCapennaCommander.java b/Mage.Sets/src/mage/sets/NewCapennaCommander.java index cf69749ac5f..eca22a2ddb8 100644 --- a/Mage.Sets/src/mage/sets/NewCapennaCommander.java +++ b/Mage.Sets/src/mage/sets/NewCapennaCommander.java @@ -323,6 +323,7 @@ public final class NewCapennaCommander extends ExpansionSet { cards.add(new SetCardInfo("World Shaper", 323, Rarity.RARE, mage.cards.w.WorldShaper.class)); cards.add(new SetCardInfo("Wrexial, the Risen Deep", 359, Rarity.MYTHIC, mage.cards.w.WrexialTheRisenDeep.class)); cards.add(new SetCardInfo("Writ of Return", 42, Rarity.RARE, mage.cards.w.WritOfReturn.class)); + cards.add(new SetCardInfo("Xander's Pact", 43, Rarity.RARE, mage.cards.x.XandersPact.class)); cards.add(new SetCardInfo("Zndrsplt's Judgment", 240, Rarity.RARE, mage.cards.z.ZndrspltsJudgment.class)); cards.add(new SetCardInfo("Zurzoth, Chaos Rider", 278, Rarity.RARE, mage.cards.z.ZurzothChaosRider.class)); }