diff --git a/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java b/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java index b6d2080d926..c08d049a122 100644 --- a/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java +++ b/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java @@ -29,9 +29,6 @@ package mage.sets.zendikar; import java.util.Set; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; @@ -42,6 +39,9 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardHandAllEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; @@ -131,7 +131,7 @@ class ChandraAblazeEffect2 extends OneShotEffect { public ChandraAblazeEffect2() { super(Outcome.Damage); - this.staticText = "If a red card is discarded this way, Chandra Ablaze deals 4 damage to target creature or player"; + this.staticText = "If a red card is discarded this way, {this} deals 4 damage to target creature or player"; } public ChandraAblazeEffect2(final ChandraAblazeEffect2 effect) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DiscardTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DiscardTest.java new file mode 100644 index 00000000000..b2e908f6218 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DiscardTest.java @@ -0,0 +1,72 @@ +/* + * 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.abilities.keywords; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ + +public class DiscardTest extends CardTestPlayerBase { + + /* + * If Rest in Peace is in play, every card going to the graveyard goes to exile intead. + * If a card is discarded while Rest in Peace is on the battlefield, abilities that function + * when a card is discarded (such as madness) still work, even though that card never reaches + * a graveyard. + */ + + @Test + public void testRestInPeaceAndCycle() { + // Check that Lion goes to graveyard from evoke ability + // Check that evoke does not trigger again to sacrifice Shriekmaw if it's exhumed + + addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); + addCard(Zone.HAND, playerA, "Tranquil Thicket"); + + addCard(Zone.BATTLEFIELD, playerB, "Rest in Peace", 1); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cycling {G} ({G},Discard {this}: Draw a card.)"); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertHandCount(playerA, "Tranquil Thicket", 0); + assertExileCount("Tranquil Thicket", 1); + assertHandCount(playerA, 1); // the card drawn by Cycling + } + +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 43fcfc32fb6..b627d332d20 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -26,6 +26,8 @@ import org.mage.test.serverside.base.MageTestPlayerBase; import java.util.List; import java.util.UUID; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; /** * API for test initialization and asserting the test results. @@ -557,6 +559,20 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement Assert.assertEquals("(Hand) Card counts are not equal ", count, actual); } + /** + * Assert card count in player's hand. + * + * @param player {@link Player} who's hand should be counted. + * @param cardName Name of the cards that should be counted. + * @param count Expected count. + */ + public void assertHandCount(Player player, String cardName, int count) throws AssertionError { + FilterCard filter = new FilterCard(); + filter.add(new NamePredicate(cardName)); + int actual = currentGame.getPlayer(player.getId()).getHand().count(filter, player.getId(), currentGame); + Assert.assertEquals("(Hand) Card counts for card " + cardName + " are not equal ", count, actual); + } + /** * Assert card count in player's graveyard. * diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 0a7b5857308..1b4c450ce8d 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -609,8 +609,26 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean discard(Card card, Ability source, Game game) { //20100716 - 701.7 - if (card != null - && card.moveToZone(Zone.GRAVEYARD, source==null?null:source.getSourceId(), game, false)) { + /* 701.7. Discard # + 701.7a To discard a card, move it from its owner’s hand to that player’s graveyard. + 701.7b By default, effects that cause a player to discard a card allow the affected + player to choose which card to discard. Some effects, however, require a random + discard or allow another player to choose which card is discarded. + 701.7c If a card is discarded, but an effect causes it to be put into a hidden zone + instead of into its owner’s graveyard without being revealed, all values of that + card’s characteristics are considered to be undefined. + TODOD: + If a card is discarded this way to pay a cost that specifies a characteristic + about the discarded card, that cost payment is illegal; the game returns to + the moment before the cost was paid (see rule 717, "Handling Illegal Actions"). + */ + if (card != null) { + /* If a card is discarded while Rest in Peace is on the battlefield, abilities that function + * when a card is discarded (such as madness) still work, even though that card never reaches + * a graveyard. In addition, spells or abilities that check the characteristics of a discarded + * card (such as Chandra Ablaze's first ability) can find that card in exile. */ + // So discard is also successful if card is moved to another zone by replacement effect! + card.moveToZone(Zone.GRAVEYARD, source==null?null:source.getSourceId(), game, false); game.informPlayers(new StringBuilder(name).append(" discards ").append(card.getName()).toString()); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, card.getId(), source==null?null:source.getId(), playerId)); return true;