From 0fa4c2d3246c01a5cc950744d72d44244c984ea5 Mon Sep 17 00:00:00 2001 From: Colin Redman Date: Wed, 1 Aug 2018 05:33:51 -0600 Subject: [PATCH] Implemented Aminatou, the Fateshifter --- .../mage/cards/a/AminatouTheFateShifter.java | 183 ++++++++++++++++++ Mage.Sets/src/mage/sets/Commander2018.java | 1 + .../src/main/java/mage/constants/SubType.java | 7 +- 3 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java diff --git a/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java b/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java new file mode 100644 index 00000000000..64533667f53 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AminatouTheFateShifter.java @@ -0,0 +1,183 @@ +package mage.cards.a; + +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetForSourceEffect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.Choice; +import mage.choices.ChoiceLeftOrRight; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.other.OwnerPredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.players.PlayerList; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInHand; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +public class AminatouTheFateShifter extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("permanent you own"); + + static { + filter.add(new OwnerPredicate(TargetController.YOU)); + filter.add(new AnotherPredicate()); + } + + public AminatouTheFateShifter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{W}{U}{B}"); + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.AMINATOU); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); + + // +1: Draw a card, then put a card from your hand on top of your library. + Ability ability = new LoyaltyAbility(new AminatouPlusEffect(), +1); + this.addAbility(ability); + + // -1: Exile another target permanent you own, then return it to the battlefield under your control. + ability = new LoyaltyAbility(new ExileTargetForSourceEffect(), -1); + ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + + // -6: Choose left or right. Each player gains control of all nonland permanents other than Aminatou, the + // Fateshifter controlled by the next player in the chosen direction. + ability = new LoyaltyAbility(new AminatouUltimateEffect(), -6); + this.addAbility(ability); + } + public AminatouTheFateShifter(final AminatouTheFateShifter card) { + super(card); + } + + @Override + public AminatouTheFateShifter copy() { + return new AminatouTheFateShifter(this); + } +} + +class AminatouPlusEffect extends OneShotEffect { + public AminatouPlusEffect() { + super(Outcome.DrawCard); + staticText = "draw a card, then put a card from your hand on top of your library"; + } + + public AminatouPlusEffect(final AminatouPlusEffect effect) { + super(effect); + } + + @Override + public AminatouPlusEffect copy() { + return new AminatouPlusEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + player.drawCards(1, game); + putOnLibrary(player, source, game); + return true; + } + return false; + } + + private boolean putOnLibrary(Player player, Ability source, Game game) { + TargetCardInHand target = new TargetCardInHand(); + if (target.canChoose(source.getSourceId(), player.getId(), game)) { + player.chooseTarget(Outcome.ReturnToHand, target, source, game); + Card card = player.getHand().get(target.getFirstTarget(), game); + if (card != null) { + return player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.HAND, true, false); + } + } + return false; + } +} + +class AminatouUltimateEffect extends OneShotEffect { + public AminatouUltimateEffect (){ + super(Outcome.Benefit); + staticText = "Choose left or right. Each player gains control of all nonland permanents other than Aminatou," + + " the Fateshifter controlled by the next player in the chosen direction."; + } + + public AminatouUltimateEffect(final AminatouUltimateEffect effect) { + super(effect); + } + + @Override + public AminatouUltimateEffect copy(){return new AminatouUltimateEffect(this);} + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Choice choice = new ChoiceLeftOrRight(); + if (!controller.choose(Outcome.Neutral, choice, game)) { + return false; + } + boolean left = choice.getChoice().equals("Left"); + PlayerList playerList = game.getState().getPlayerList().copy(); + // set playerlist to controller + while (!playerList.get().equals(source.getControllerId())) { + playerList.getNext(); + } + UUID currentPlayer = playerList.get(); + UUID nextPlayer; + UUID firstNextPlayer = null; + while (!getNextPlayerInDirection(left, playerList, game).equals(firstNextPlayer)) { + nextPlayer = playerList.get(); + if (nextPlayer == null) { + return false; + } + // skip players out of range + if (!game.getState().getPlayersInRange(controller.getId(), game).contains(nextPlayer)){ + continue; + } + // save first next player to check for iteration stop + if (firstNextPlayer == null) { + firstNextPlayer = nextPlayer; + } + FilterNonlandPermanent nextPlayerNonlandPermanentsFilter = new FilterNonlandPermanent(); + nextPlayerNonlandPermanentsFilter.add(new ControllerIdPredicate(nextPlayer)); + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(nextPlayerNonlandPermanentsFilter, game)) { + if (permanent.getId().equals(source.getSourceId())){ + continue; + } + ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame, currentPlayer); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + } + currentPlayer = nextPlayer; + } + return true; + } + return false; + } + + private UUID getNextPlayerInDirection(boolean left, PlayerList playerList, Game game) { + UUID nextPlayerId; + if (left) { + nextPlayerId = playerList.getNext(); + } else { + nextPlayerId = playerList.getPrevious(); + } + return nextPlayerId; + } +} + diff --git a/Mage.Sets/src/mage/sets/Commander2018.java b/Mage.Sets/src/mage/sets/Commander2018.java index 98b2701e391..7f1aeea8b0b 100644 --- a/Mage.Sets/src/mage/sets/Commander2018.java +++ b/Mage.Sets/src/mage/sets/Commander2018.java @@ -27,6 +27,7 @@ public final class Commander2018 extends ExpansionSet { cards.add(new SetCardInfo("Ajani's Chosen", 61, Rarity.RARE, mage.cards.a.AjanisChosen.class)); cards.add(new SetCardInfo("Akoum Refuge", 231, Rarity.UNCOMMON, mage.cards.a.AkoumRefuge.class)); cards.add(new SetCardInfo("Akroma's Vengeance", 62, Rarity.RARE, mage.cards.a.AkromasVengeance.class)); + cards.add(new SetCardInfo("Amninatou, the Fateshifter", 37, Rarity.MYTHIC, mage.cards.a.AminatouTheFateShifter.class)); cards.add(new SetCardInfo("Ancient Stone Idol", 53, Rarity.RARE, mage.cards.a.AncientStoneIdol.class)); cards.add(new SetCardInfo("Arcane Sanctum", 232, Rarity.UNCOMMON, mage.cards.a.ArcaneSanctum.class)); cards.add(new SetCardInfo("Archetype of Imagination", 81, Rarity.UNCOMMON, mage.cards.a.ArchetypeOfImagination.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 745320babd8..22248b501e1 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -1,12 +1,12 @@ package mage.constants; +import mage.util.SubTypeList; + import java.util.Arrays; import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; -import mage.util.SubTypeList; - public enum SubType { //205.3k Instants and sorceries share their lists of subtypes; these subtypes are called spell types. @@ -363,6 +363,7 @@ public enum SubType { ZUBERA("Zubera", SubTypeSet.CreatureType), // Planeswalker AJANI("Ajani", SubTypeSet.PlaneswalkerType), + AMINATOU("Aminatou", SubTypeSet.PlaneswalkerType), ANGRATH("Angrath", SubTypeSet.PlaneswalkerType), ARLINN("Arlinn", SubTypeSet.PlaneswalkerType), ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType), @@ -458,8 +459,6 @@ public enum SubType { return null; } - ; - public SubTypeSet getSubTypeSet() { return subTypeSet; }