From f96a1532bf2bab4ea83a5f878007c3aa5487fc8b Mon Sep 17 00:00:00 2001 From: Mark Langen Date: Sat, 8 Apr 2017 20:03:23 -0600 Subject: [PATCH] Add Approach of the Second Sun [AKH] + test --- .../mage/cards/a/ApproachOfTheSecondSun.java | 127 ++++++++++++++++++ Mage.Sets/src/mage/sets/Amonkhet.java | 1 + .../akh/ApproachOfTheSecondSunTest.java | 66 +++++++++ 3 files changed, 194 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/akh/ApproachOfTheSecondSunTest.java diff --git a/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java b/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java new file mode 100644 index 00000000000..53231bad015 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java @@ -0,0 +1,127 @@ +package mage.cards.a; + +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.watchers.Watcher; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author stravant + */ +public class ApproachOfTheSecondSun extends CardImpl { + + public ApproachOfTheSecondSun(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{6}{W}"); + + getSpellAbility().addEffect(new ApproachOfTheSecondSunEffect()); + getSpellAbility().addWatcher(new ApproachOfTheSecondSunWatcher()); + } + + public ApproachOfTheSecondSun(final ApproachOfTheSecondSun card) { + super(card); + } + + @Override + public ApproachOfTheSecondSun copy() { + return new ApproachOfTheSecondSun(this); + } +} + +class ApproachOfTheSecondSunEffect extends OneShotEffect { + public ApproachOfTheSecondSunEffect() { + super(Outcome.Win); + this.staticText = + "If you cast {this} from you hand and you cast another spell named {this} this game, you win the game. " + + "If not, you gain 7 life and put {this} back into your library as the seventh card from the top."; + } + + public ApproachOfTheSecondSunEffect(final ApproachOfTheSecondSunEffect effect) { + super(effect); + } + + @Override + public ApproachOfTheSecondSunEffect copy() { + return new ApproachOfTheSecondSunEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + ApproachOfTheSecondSunWatcher watcher = + (ApproachOfTheSecondSunWatcher) game.getState().getWatchers().get("approachOfTheSecondSunWatcher", source.getControllerId()); + if (watcher != null && watcher.getApproachesCast() > 1) { + // Win the game + controller.won(game); + } else { + // Gain 7 life and put this back into library. + controller.gainLife(7, game); + + // Put this into the library as the 7th from the top + List top6 = new ArrayList<>(); + // Cut the top 6 cards off into a temporary array + for (int i = 0; i < 6 && controller.getLibrary().hasCards(); ++i) { + top6.add(controller.getLibrary().removeFromTop(game)); + } + // Put this card (if the ability came from an ApproachOfTheSecondSun spell card) on top + Card sourceCard = game.getCard(source.getSourceId()); + if (sourceCard != null) { + controller.getLibrary().putOnTop(sourceCard, game); + } + + // put the top 6 we took earlier back on top (going in reverse order this time to get them back + // on top in the proper order) + for (int i = top6.size() - 1; i >= 0; --i) { + controller.getLibrary().putOnTop(top6.get(i), game); + } + } + return true; + } + return false; + } +} + + +class ApproachOfTheSecondSunWatcher extends Watcher { + private int approachesCast = 0; + + public ApproachOfTheSecondSunWatcher() { + super("approachOfTheSecondSunWatcher", WatcherScope.PLAYER); + } + + public ApproachOfTheSecondSunWatcher(final ApproachOfTheSecondSunWatcher watcher) { + super(watcher); + approachesCast = watcher.approachesCast; + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.SPELL_CAST && event.getPlayerId().equals(this.getControllerId())) { + ++approachesCast; + } + } + + public int getApproachesCast() { + return approachesCast; + } + + @Override + public ApproachOfTheSecondSunWatcher copy() { + return new ApproachOfTheSecondSunWatcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Amonkhet.java b/Mage.Sets/src/mage/sets/Amonkhet.java index 569e8b1da7a..126d0590552 100644 --- a/Mage.Sets/src/mage/sets/Amonkhet.java +++ b/Mage.Sets/src/mage/sets/Amonkhet.java @@ -66,6 +66,7 @@ public class Amonkhet extends ExpansionSet { this.ratioBoosterSpecialLand = 144; cards.add(new SetCardInfo("Ahn-Crop Crasher", 117, Rarity.UNCOMMON, mage.cards.a.AhnCropCrasher.class)); + cards.add(new SetCardInfo("Approach of the Second Sun", 4, Rarity.RARE, mage.cards.a.ApproachOfTheSecondSun.class)); cards.add(new SetCardInfo("Ancient Crab", 40, Rarity.COMMON, mage.cards.a.AncientCrab.class)); cards.add(new SetCardInfo("Angel of Sanctions", 1, Rarity.MYTHIC, mage.cards.a.AngelOfSanctions.class)); cards.add(new SetCardInfo("Angler Drake", 41, Rarity.UNCOMMON, mage.cards.a.AnglerDrake.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/akh/ApproachOfTheSecondSunTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/akh/ApproachOfTheSecondSunTest.java new file mode 100644 index 00000000000..f191378107c --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/akh/ApproachOfTheSecondSunTest.java @@ -0,0 +1,66 @@ +package org.mage.test.cards.single.akh; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author stravant + */ +public class ApproachOfTheSecondSunTest extends CardTestPlayerBase { + @Test + public void testWinGametest() { + removeAllCardsFromLibrary(playerA); + addCard(Zone.HAND, playerA, "Approach of the Second Sun", 2); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 14); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Approach of the Second Sun"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Approach of the Second Sun"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 27); + assertLibraryCount(playerA, 1); // 1 approach in graveyard (The one that won the game) + assertGraveyardCount(playerA, 1); // 1 approach put back into library + assertHandCount(playerA, 0); // No aproaches left in hand + assertResult(playerA, GameResult.WON); + } + + @Test + public void testDontCountOpponentCast() { + addCard(Zone.HAND, playerA, "Approach of the Second Sun"); + addCard(Zone.HAND, playerB, "Approach of the Second Sun"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 7); + addCard(Zone.BATTLEFIELD, playerB, "Plains", 7); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Approach of the Second Sun"); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Approach of the Second Sun"); + + setStopAt(2, PhaseStep.END_TURN); + execute(); + + assertResult(playerA, GameResult.DRAW); + assertLife(playerA, 27); + assertLife(playerB, 27); + } + + @Test + public void testRightPositionInDeck() { + removeAllCardsFromLibrary(playerA); + addCard(Zone.LIBRARY, playerA, "Plains", 6); + addCard(Zone.HAND, playerA, "Approach of the Second Sun", 1); + addCard(Zone.HAND, playerA, "Concentrate", 2); + addCard(Zone.BATTLEFIELD, playerA, "Tundra", 15); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Approach of the Second Sun"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Concentrate"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Concentrate"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 27); + assertLibraryCount(playerA, "Approach of the Second Sun", 1); // 1 approach put back into library in the right place + assertLibraryCount(playerA, 1); + assertResult(playerA, GameResult.DRAW); + } +}