From 56f41243ca525e0cc60f34704c52d6d30f77971f Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 3 Jun 2015 19:35:05 +0200 Subject: [PATCH] * Keranos, God of Storms - Fixed that it's triggered ability triggered not only on the first card drawn on the turn. --- .../journeyintonyx/KeranosGodOfStorms.java | 73 ++++++++++-- .../mage/sets/planeshift/ForsakenCity.java | 2 +- .../single/ths/KeranosGodOfStormsTest.java | 105 ++++++++++++++++++ 3 files changed, 171 insertions(+), 9 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/ths/KeranosGodOfStormsTest.java diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/KeranosGodOfStorms.java b/Mage.Sets/src/mage/sets/journeyintonyx/KeranosGodOfStorms.java index 8f18a5ff389..3175e4c5d0b 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/KeranosGodOfStorms.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/KeranosGodOfStorms.java @@ -27,6 +27,9 @@ */ package mage.sets.journeyintonyx; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; @@ -43,13 +46,17 @@ import mage.cards.CardImpl; import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.ColoredManaSymbol; +import mage.constants.PhaseStep; import mage.constants.Rarity; +import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreatureOrPlayer; +import mage.watchers.Watcher; +import mage.watchers.common.CardsDrawnDuringDrawStepWatcher; /** * @@ -77,7 +84,7 @@ public class KeranosGodOfStorms extends CardImpl { // Reveal the first card you draw on each of your turns. // Whenever you reveal a land card this way, draw a card. // Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player. - this.addAbility(new KeranosGodOfStormsTriggeredAbility()); + this.addAbility(new KeranosGodOfStormsTriggeredAbility(), new CardsDrawnDuringTurnWatcher()); } @@ -94,15 +101,12 @@ public class KeranosGodOfStorms extends CardImpl { class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl { - private int lastTriggeredTurn; - KeranosGodOfStormsTriggeredAbility() { super(Zone.BATTLEFIELD, new InfoEffect(""), false); } KeranosGodOfStormsTriggeredAbility(final KeranosGodOfStormsTriggeredAbility ability) { super(ability); - this.lastTriggeredTurn = ability.lastTriggeredTurn; } @Override @@ -113,13 +117,16 @@ class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.DREW_CARD && event.getPlayerId().equals(this.getControllerId())) { - if (game.getActivePlayerId().equals(this.getControllerId()) && this.lastTriggeredTurn != game.getTurnNum()) { + if (game.getActivePlayerId().equals(this.getControllerId())) { + CardsDrawnDuringTurnWatcher watcher = (CardsDrawnDuringTurnWatcher) game.getState().getWatchers().get("CardsDrawnDuringTurn"); + if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) != 1) { + return false; + } Card card = game.getCard(event.getTargetId()); Player controller = game.getPlayer(this.getControllerId()); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(this.getSourceId()); + Permanent sourcePermanent = (Permanent) getSourceObject(game); if (card != null && controller != null && sourcePermanent != null) { - lastTriggeredTurn = game.getTurnNum(); - controller.revealCards(sourcePermanent.getName(), new CardsImpl(card), game); + controller.revealCards(sourcePermanent.getIdName(), new CardsImpl(card), game); this.getTargets().clear(); this.getEffects().clear(); if (card.getCardType().contains(CardType.LAND)) { @@ -140,3 +147,53 @@ class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl { return "Reveal the first card you draw on each of your turns. Whenever you reveal a land card this way, draw a card. Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player."; } } + +class CardsDrawnDuringTurnWatcher extends Watcher { + + private final Map amountOfCardsDrawnThisTurn = new HashMap<>(); + + public CardsDrawnDuringTurnWatcher() { + super("CardsDrawnDuringTurn", WatcherScope.GAME); + } + + public CardsDrawnDuringTurnWatcher(final CardsDrawnDuringTurnWatcher watcher) { + super(watcher); + for (Entry entry : watcher.amountOfCardsDrawnThisTurn.entrySet()) { + amountOfCardsDrawnThisTurn.put(entry.getKey(), entry.getValue()); + } + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DREW_CARD) { + UUID playerId = event.getPlayerId(); + if (playerId != null) { + Integer amount = amountOfCardsDrawnThisTurn.get(playerId); + if (amount == null) { + amount = 1; + } else { + amount++; + } + amountOfCardsDrawnThisTurn.put(playerId, amount); + } + } + } + + public int getAmountCardsDrawn(UUID playerId) { + Integer amount = amountOfCardsDrawnThisTurn.get(playerId); + if (amount != null) { + return amount; + } + return 0; + } + + @Override + public void reset() { + amountOfCardsDrawnThisTurn.clear(); + } + + @Override + public CardsDrawnDuringTurnWatcher copy() { + return new CardsDrawnDuringTurnWatcher(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/planeshift/ForsakenCity.java b/Mage.Sets/src/mage/sets/planeshift/ForsakenCity.java index 0a39f721f27..bcf4d89300b 100644 --- a/Mage.Sets/src/mage/sets/planeshift/ForsakenCity.java +++ b/Mage.Sets/src/mage/sets/planeshift/ForsakenCity.java @@ -62,7 +62,7 @@ public class ForsakenCity extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid(new UntapSourceEffect(), new ExileFromHandCost(new TargetCardInHand(filter))), TargetController.YOU, true)); // {T}: Add one mana of any color to your mana pool. - this.addAbility(new AnyColorManaAbility()); + this.addAbility(new AnyColorManaAbility()); } public ForsakenCity(final ForsakenCity card) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/KeranosGodOfStormsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/KeranosGodOfStormsTest.java new file mode 100644 index 00000000000..99cc3c7b74f --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/KeranosGodOfStormsTest.java @@ -0,0 +1,105 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.single.ths; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class KeranosGodOfStormsTest extends CardTestPlayerBase { + + @Test + public void testKeranosNormal() { + // Reveal the first card you draw on each of your turns. + // Whenever you reveal a land card this way, draw a card. + // Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player. + addCard(Zone.BATTLEFIELD, playerB, "Keranos, God of Storms"); // {3}{U}{R} + // Look at target player's hand. + // Draw a card. + addCard(Zone.LIBRARY, playerB, "Silvercoat Lion", 3); + skipInitShuffling(); + + addTarget(playerB, playerA); // damage from Keranos trigger + + setStopAt(2, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerB, "Keranos, God of Storms", 1); + + assertHandCount(playerB, "Silvercoat Lion", 1); // 1 Lion from the draw and 1 Lion from Peek + + assertLife(playerA, 17); + assertLife(playerB, 20); + + } + + /** + * Keranos, God of Storms, will look at the first card drawn after he is + * played, not the first card drawn each turn. + * + * My opponent, draws, plays Keranos, then plays Stroke of Genius. Keranos + * triggers on the first card for Stroke of Genius. + */ + @Test + public void testKeranosCastAfterFirstDraw() { + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerB, "Island", 5); + // Reveal the first card you draw on each of your turns. + // Whenever you reveal a land card this way, draw a card. + // Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player. + addCard(Zone.HAND, playerB, "Keranos, God of Storms"); // {3}{U}{R} + // Look at target player's hand. + // Draw a card. + addCard(Zone.HAND, playerB, "Peek"); + + addCard(Zone.LIBRARY, playerB, "Silvercoat Lion", 3); + skipInitShuffling(); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Keranos, God of Storms"); + castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Peek", playerA); // you won't do damage because it's not the first draw this turn - Draw in draw phase was the first + addTarget(playerB, playerA); // not needed if it works correct + + setStopAt(2, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerB, "Keranos, God of Storms", 1); + assertGraveyardCount(playerB, "Peek", 1); + + assertHandCount(playerB, "Silvercoat Lion", 2); // 1 Lion from the draw and 1 Lion from Peek + + assertLife(playerA, 20); + assertLife(playerB, 20); + + } + +}