From f1fefb0d59436d082497290e1b508584fee6d35f Mon Sep 17 00:00:00 2001 From: BetaSteward Date: Thu, 8 Mar 2012 13:54:31 -0500 Subject: [PATCH] 2 DKA --- .../darkascension/CurseOfMisfortunes.java | 133 +++++++++++++++ .../darkascension/SuddenDisappearance.java | 107 +++++++++++++ .../test/cards/TestCurseOfBloodletting.java | 31 ---- .../mage/test/cards/TestCurseOfEchoes.java | 30 ---- .../test/cards/TestCurseOfExhaustion.java | 51 ------ .../mage/test/cards/TestCurseOfThirst.java | 44 ----- .../java/org/mage/test/cards/TestCurses.java | 151 ++++++++++++++++++ .../test/cards/TestSuddenDisappearance.java | 62 +++++++ .../base/impl/CardTestPlayerAPIImpl.java | 2 +- .../effects/common/ReturnFromExileEffect.java | 2 +- Mage/src/mage/game/GameImpl.java | 5 +- .../mage/game/permanent/PermanentCard.java | 35 +--- 12 files changed, 463 insertions(+), 190 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/darkascension/CurseOfMisfortunes.java create mode 100644 Mage.Sets/src/mage/sets/darkascension/SuddenDisappearance.java delete mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfBloodletting.java delete mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfEchoes.java delete mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfExhaustion.java delete mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfThirst.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/TestCurses.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/TestSuddenDisappearance.java diff --git a/Mage.Sets/src/mage/sets/darkascension/CurseOfMisfortunes.java b/Mage.Sets/src/mage/sets/darkascension/CurseOfMisfortunes.java new file mode 100644 index 00000000000..90da346d449 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darkascension/CurseOfMisfortunes.java @@ -0,0 +1,133 @@ +/* + * 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 mage.sets.darkascension; + +import java.util.UUID; +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.abilities.Ability; +import mage.abilities.common.OnEventTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author BetaSteward + */ +public class CurseOfMisfortunes extends CardImpl { + + public CurseOfMisfortunes(UUID ownerId) { + super(ownerId, 56, "Curse of Misfortunes", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}"); + this.expansionSetCode = "DKA"; + this.subtype.add("Aura"); + this.subtype.add("Curse"); + + this.color.setBlack(true); + + // Enchant player + TargetPlayer auraTarget = new TargetPlayer(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Constants.Outcome.Detriment)); + this.addAbility(new EnchantAbility(auraTarget.getTargetName())); + + // At the beginning of your upkeep, you may search your library for a Curse card that doesn't have the same name as a Curse attached to enchanted player, put it onto the battlefield attached to that player, then shuffle your library. + this.addAbility(new OnEventTriggeredAbility(GameEvent.EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new CurseOfMisfortunesEffect(), true)); + } + + public CurseOfMisfortunes(final CurseOfMisfortunes card) { + super(card); + } + + @Override + public CurseOfMisfortunes copy() { + return new CurseOfMisfortunes(this); + } +} + +class CurseOfMisfortunesEffect extends OneShotEffect { + + public CurseOfMisfortunesEffect() { + super(Constants.Outcome.Detriment); + staticText = "you may search your library for a Curse card that doesn't have the same name as a Curse attached to enchanted player, put it onto the battlefield attached to that player, then shuffle your library"; + } + + public CurseOfMisfortunesEffect(final CurseOfMisfortunesEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + FilterCard filter = new FilterCard("Curse card that doesn't have the same name as a Curse attached to enchanted player"); + filter.getSubtype().add("Curse"); + Permanent enchantment = game.getPermanent(source.getSourceId()); + if (enchantment != null && enchantment.getAttachedTo() != null) { + Player targetPlayer = game.getPlayer(enchantment.getAttachedTo()); + Player player = game.getPlayer(source.getControllerId()); + if (player != null && targetPlayer != null) { + // get the names of attached Curses + for (UUID attachmentId: targetPlayer.getAttachments()) { + Permanent attachment = game.getPermanent(attachmentId); + if (attachment != null && attachment.getSubtype().contains("Curse")) { + filter.getName().add(attachment.getName()); + filter.setNotName(true); + } + } + + TargetCardInLibrary targetCard = new TargetCardInLibrary(filter); + targetCard.setRequired(true); + if (player.searchLibrary(targetCard, game)) { + Card card = game.getCard(targetCard.getFirstTarget()); + if (card != null) { + player.shuffleLibrary(game); + card.putOntoBattlefield(game, Constants.Zone.LIBRARY, source.getSourceId(), source.getControllerId()); + return targetPlayer.addAttachment(card.getId(), game); + } + } + player.shuffleLibrary(game); + } + } + return false; + } + + @Override + public CurseOfMisfortunesEffect copy() { + return new CurseOfMisfortunesEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/darkascension/SuddenDisappearance.java b/Mage.Sets/src/mage/sets/darkascension/SuddenDisappearance.java new file mode 100644 index 00000000000..5a8e14635f8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darkascension/SuddenDisappearance.java @@ -0,0 +1,107 @@ +/* + * 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 mage.sets.darkascension; + +import java.util.List; +import java.util.UUID; +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Outcome; +import mage.Constants.Rarity; +import mage.abilities.Ability; +import mage.abilities.common.delayed.AtEndOfTurnDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromExileEffect; +import mage.cards.CardImpl; +import mage.filter.common.FilterNonlandPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPlayer; + +/** + * + * @author BetaSteward + */ +public class SuddenDisappearance extends CardImpl { + + public SuddenDisappearance(UUID ownerId) { + super(ownerId, 23, "Sudden Disappearance", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{5}{W}"); + this.expansionSetCode = "DKA"; + + this.color.setWhite(true); + + // Exile all nonland permanents target player controls. Return the exiled cards to the battlefield under their owner's control at the beginning of the next end step. + this.getSpellAbility().addEffect(new SuddenDisappearanceEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + + } + + public SuddenDisappearance(final SuddenDisappearance card) { + super(card); + } + + @Override + public SuddenDisappearance copy() { + return new SuddenDisappearance(this); + } +} + +class SuddenDisappearanceEffect extends OneShotEffect { + + private static FilterNonlandPermanent filter = new FilterNonlandPermanent(); + + public SuddenDisappearanceEffect() { + super(Outcome.Exile); + } + + public SuddenDisappearanceEffect(final SuddenDisappearanceEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + List perms = game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget()); + if (perms.size() > 0) { + for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget())) { + permanent.moveToExile(source.getSourceId(), "Sudden Disappearance", source.getSourceId(), game); + } + AtEndOfTurnDelayedTriggeredAbility delayedAbility = new AtEndOfTurnDelayedTriggeredAbility(new ReturnFromExileEffect(source.getSourceId(), Constants.Zone.BATTLEFIELD)); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + game.addDelayedTriggeredAbility(delayedAbility); + return true; + } + return false; + } + + @Override + public SuddenDisappearanceEffect copy() { + return new SuddenDisappearanceEffect(this); + } + +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfBloodletting.java b/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfBloodletting.java deleted file mode 100644 index 1482d0e04fc..00000000000 --- a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfBloodletting.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.mage.test.cards; - -import mage.Constants; -import org.junit.Test; -import org.mage.test.serverside.base.CardTestPlayerBase; - -/** - * - * @author BetaSteward - */ -public class TestCurseOfBloodletting extends CardTestPlayerBase { - - @Test - public void testCard1() { - addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 7); - addCard(Constants.Zone.HAND, playerA, "Curse of Bloodletting"); - addCard(Constants.Zone.HAND, playerA, "Lightning Bolt", 2); - - castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Bloodletting", playerB); - castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); - castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerA); - - - setStopAt(1, Constants.PhaseStep.END_TURN); - execute(); - - assertLife(playerA, 17); - assertLife(playerB, 14); - } - -} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfEchoes.java b/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfEchoes.java deleted file mode 100644 index ef0f2d08688..00000000000 --- a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfEchoes.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.mage.test.cards; - -import mage.Constants; -import org.junit.Test; -import org.mage.test.serverside.base.CardTestPlayerBase; - -/** - * - * @author BetaSteward - */ -public class TestCurseOfEchoes extends CardTestPlayerBase { - - @Test - public void testCard1() { - addCard(Constants.Zone.BATTLEFIELD, playerA, "Island", 5); - addCard(Constants.Zone.BATTLEFIELD, playerB, "Island", 5); - addCard(Constants.Zone.HAND, playerA, "Curse of Echoes"); - addCard(Constants.Zone.HAND, playerB, "Jace's Ingenuity"); - - castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Echoes", playerB); - castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerB, "Jace's Ingenuity"); - - setStopAt(1, Constants.PhaseStep.END_TURN); - execute(); - - assertHandCount(playerA, 3); - assertHandCount(playerB, 3); - } - -} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfExhaustion.java b/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfExhaustion.java deleted file mode 100644 index e4a26340364..00000000000 --- a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfExhaustion.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.mage.test.cards; - -import mage.Constants; -import org.junit.Ignore; -import org.junit.Test; -import org.mage.test.serverside.base.CardTestPlayerBase; - -/** - * - * @author BetaSteward - */ -public class TestCurseOfExhaustion extends CardTestPlayerBase { - - @Test - public void testCard1() { - addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains", 4); - addCard(Constants.Zone.HAND, playerA, "Curse of Exhaustion"); - addCard(Constants.Zone.BATTLEFIELD, playerB, "Mountain", 2); - addCard(Constants.Zone.HAND, playerB, "Lightning Bolt", 2); - - castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Exhaustion", playerB); - castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA); - castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA); - - - setStopAt(1, Constants.PhaseStep.END_TURN); - execute(); - - assertLife(playerB, 20); - assertLife(playerA, 17); - } - - @Test - public void testCard2() { - addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 4); - addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains", 2); - addCard(Constants.Zone.HAND, playerA, "Curse of Exhaustion"); - addCard(Constants.Zone.HAND, playerA, "Lightning Bolt", 2); - - castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Exhaustion", playerB); - castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); - castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); - - - setStopAt(1, Constants.PhaseStep.END_TURN); - execute(); - - assertLife(playerA, 20); - assertLife(playerB, 14); - } -} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfThirst.java b/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfThirst.java deleted file mode 100644 index 173eea2729f..00000000000 --- a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurseOfThirst.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.mage.test.cards; - -import mage.Constants; -import org.junit.Test; -import org.mage.test.serverside.base.CardTestPlayerBase; - -/** - * - * @author BetaSteward - */ -public class TestCurseOfThirst extends CardTestPlayerBase { - - @Test - public void testCard1() { - addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 5); - addCard(Constants.Zone.HAND, playerA, "Curse of Thirst"); - - castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Thirst", playerB); - - setStopAt(2, Constants.PhaseStep.DRAW); - execute(); - - assertLife(playerA, 20); - assertLife(playerB, 19); - } - - @Test - public void testCard2() { - addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 5); - addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 5); - addCard(Constants.Zone.HAND, playerA, "Curse of Thirst"); - addCard(Constants.Zone.HAND, playerA, "Curse of Bloodletting"); - - castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Bloodletting", playerB); - castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Thirst", playerB); - - setStopAt(2, Constants.PhaseStep.DRAW); - execute(); - - assertLife(playerA, 20); - assertLife(playerB, 16); - } - -} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/TestCurses.java b/Mage.Tests/src/test/java/org/mage/test/cards/TestCurses.java new file mode 100644 index 00000000000..b2bf7a014c8 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/TestCurses.java @@ -0,0 +1,151 @@ +package org.mage.test.cards; + +import mage.Constants; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author BetaSteward + */ +public class TestCurses extends CardTestPlayerBase { + + @Test + public void testCurseOfBloodletting() { + addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 7); + addCard(Constants.Zone.HAND, playerA, "Curse of Bloodletting"); + addCard(Constants.Zone.HAND, playerA, "Lightning Bolt", 2); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Bloodletting", playerB); + castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); + castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerA); + + + setStopAt(1, Constants.PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 17); + assertLife(playerB, 14); + } + + @Test + public void testCurseOfEchoes() { + addCard(Constants.Zone.BATTLEFIELD, playerA, "Island", 5); + addCard(Constants.Zone.BATTLEFIELD, playerB, "Island", 5); + addCard(Constants.Zone.HAND, playerA, "Curse of Echoes"); + addCard(Constants.Zone.HAND, playerB, "Jace's Ingenuity"); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Echoes", playerB); + castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerB, "Jace's Ingenuity"); + + setStopAt(1, Constants.PhaseStep.END_TURN); + execute(); + + assertHandCount(playerA, 3); + assertHandCount(playerB, 3); + } + + @Test + public void testCurseOfExhaustion1() { + addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Constants.Zone.HAND, playerA, "Curse of Exhaustion"); + addCard(Constants.Zone.BATTLEFIELD, playerB, "Mountain", 2); + addCard(Constants.Zone.HAND, playerB, "Lightning Bolt", 2); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Exhaustion", playerB); + castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA); + castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA); + + + setStopAt(1, Constants.PhaseStep.END_TURN); + execute(); + + assertLife(playerB, 20); + assertLife(playerA, 17); + } + + @Test + public void testCurseOfExhaustion2() { + addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 4); + addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Constants.Zone.HAND, playerA, "Curse of Exhaustion"); + addCard(Constants.Zone.HAND, playerA, "Lightning Bolt", 2); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Exhaustion", playerB); + castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); + castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); + + + setStopAt(1, Constants.PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 14); + } + + @Test + public void testCurseOfThirst1() { + addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 5); + addCard(Constants.Zone.HAND, playerA, "Curse of Thirst"); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Thirst", playerB); + + setStopAt(2, Constants.PhaseStep.DRAW); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 19); + } + + @Test + public void testCurseOfThirst2() { + addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 5); + addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 5); + addCard(Constants.Zone.HAND, playerA, "Curse of Thirst"); + addCard(Constants.Zone.HAND, playerA, "Curse of Bloodletting"); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Bloodletting", playerB); + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Thirst", playerB); + + setStopAt(2, Constants.PhaseStep.DRAW); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 16); + } + + @Test + public void testCurseOfMisfortune1() { + removeAllCardsFromLibrary(playerA); + addCard(Constants.Zone.LIBRARY, playerA, "Curse of Misfortunes", 2); + addCard(Constants.Zone.HAND, playerA, "Curse of Misfortunes"); + addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 5); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Misfortunes", playerB); + + setStopAt(3, Constants.PhaseStep.DRAW); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + assertPermanentCount(playerA, "Curse of Misfortunes", 1); + } + + @Test + public void testCurseOfMisfortune2() { + removeAllCardsFromLibrary(playerA); + addCard(Constants.Zone.LIBRARY, playerA, "Curse of Bloodletting", 2); + addCard(Constants.Zone.HAND, playerA, "Curse of Misfortunes"); + addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 5); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Misfortunes", playerB); + + setStopAt(3, Constants.PhaseStep.DRAW); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + assertPermanentCount(playerA, "Curse of Misfortunes", 1); + assertPermanentCount(playerA, "Curse of Bloodletting", 1); } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/TestSuddenDisappearance.java b/Mage.Tests/src/test/java/org/mage/test/cards/TestSuddenDisappearance.java new file mode 100644 index 00000000000..41728ec89f5 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/TestSuddenDisappearance.java @@ -0,0 +1,62 @@ +package org.mage.test.cards; + +import junit.framework.Assert; +import mage.Constants; +import mage.filter.Filter; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TestSuddenDisappearance extends CardTestPlayerBase { + + @Test + public void testCard() { + addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains", 6); + addCard(Constants.Zone.HAND, playerA, "Sudden Disappearance"); + addCard(Constants.Zone.BATTLEFIELD, playerB, "Air Elemental", 1); + addCard(Constants.Zone.BATTLEFIELD, playerB, "Horned Turtle", 4); + addCard(Constants.Zone.BATTLEFIELD, playerB, "Altar of the Lost", 1); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Sudden Disappearance", playerB); + + setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + assertPermanentCount(playerB, "Air Elemental", 0); + assertPermanentCount(playerB, "Horned Turtle", 0); + assertPermanentCount(playerB, "Altar of the Lost", 0); + assertExileCount("Air Elemental", 1); + assertExileCount("Horned Turtle", 4); + assertExileCount("Altar of the Lost", 1); + } + + + @Test + public void testCard1() { + addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains", 6); + addCard(Constants.Zone.HAND, playerA, "Sudden Disappearance"); + addCard(Constants.Zone.BATTLEFIELD, playerB, "Air Elemental", 1); + addCard(Constants.Zone.BATTLEFIELD, playerB, "Horned Turtle", 4); + addCard(Constants.Zone.BATTLEFIELD, playerB, "Altar of the Lost", 1); + + castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Sudden Disappearance", playerB); + + setStopAt(2, Constants.PhaseStep.UPKEEP); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + assertPermanentCount(playerB, "Air Elemental", 1); + assertPermanentCount(playerB, "Horned Turtle", 4); + assertPermanentCount(playerB, "Altar of the Lost", 1); + assertExileCount("Air Elemental", 0); + assertExileCount("Horned Turtle", 0); + assertExileCount("Altar of the Lost", 0); + } + +} 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 6fd89526536..65dfc07b5b3 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 @@ -260,7 +260,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement */ public void assertLife(Player player, int life) throws AssertionError { int actual = currentGame.getPlayer(player.getId()).getLife(); - Assert.assertEquals("Life amounts are not equal", life, actual); + Assert.assertEquals("Life amounts are not equal for player " + player.getName(), life, actual); } /** diff --git a/Mage/src/mage/abilities/effects/common/ReturnFromExileEffect.java b/Mage/src/mage/abilities/effects/common/ReturnFromExileEffect.java index 385077f24bb..5c2ad4dad2d 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnFromExileEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnFromExileEffect.java @@ -78,7 +78,7 @@ public class ReturnFromExileEffect extends OneShotEffect @Override public boolean apply(Game game, Ability source) { - ExileZone exile = game.getExile().getExileZone(exileId); + ExileZone exile = game.getExile().getExileZone(exileId).copy(); if (exile != null) { for (UUID cardId: exile) { Card card = game.getCard(cardId); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index fb2c8c2f910..0be5a33945d 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -190,6 +190,9 @@ public abstract class GameImpl> implements Game, Serializa @Override public void loadCards(Set cards, UUID ownerId) { for (Card card: cards) { + if (card instanceof PermanentCard) { + card = ((PermanentCard)card).getCard(); + } card.setOwnerId(ownerId); gameCards.put(card.getId(), card); state.addCard(card); @@ -1314,7 +1317,7 @@ public abstract class GameImpl> implements Game, Serializa for (PermanentCard card : battlefield) { setZone(card.getId(), Zone.BATTLEFIELD); card.setOwnerId(ownerId); - PermanentCard permanent = new PermanentCard(card, ownerId); + PermanentCard permanent = new PermanentCard(card.getCard(), ownerId); getBattlefield().addPermanent(permanent); permanent.entersBattlefield(permanent.getId(), this); ((PermanentImpl)permanent).removeSummoningSickness(); diff --git a/Mage/src/mage/game/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java index dd3f8dc0a31..39a228fddac 100644 --- a/Mage/src/mage/game/permanent/PermanentCard.java +++ b/Mage/src/mage/game/permanent/PermanentCard.java @@ -170,37 +170,10 @@ public class PermanentCard extends PermanentImpl { } } -// public void checkPermanentOnlyTriggers(ZoneChangeEvent event, Game game) { -// // we only want to trigger abilities that are not on the underlying card ie. have been added by another effect -// // or we want to trigger abilities that only trigger on leaving the battlefield -// // card abilities will get triggered later when the card hits the new zone -// List triggered = new ArrayList(); -// for (TriggeredAbility ability : abilities.getTriggeredAbilities(event.getFromZone())) { -// if (!card.getAbilities().containsKey(ability.getId())) { -// if (ability.checkTrigger(event, game)) { -// triggered.add(ability.getId()); -// ability.trigger(game, controllerId); -// } -// } else if (ability instanceof ZoneChangeTriggeredAbility && event.getFromZone() == Zone.BATTLEFIELD) { -// ZoneChangeTriggeredAbility zcAbility = (ZoneChangeTriggeredAbility) ability; -// if (zcAbility.getToZone() == null) { -// if (ability.checkTrigger(event, game)) { -// triggered.add(ability.getId()); -// ability.trigger(game, controllerId); -// } -// } -// } -// } -// for (TriggeredAbility ability : abilities.getTriggeredAbilities(event.getToZone())) { -// if (!card.getAbilities().containsKey(ability.getId())) { -// if (!triggered.contains(ability.getId()) && ability.checkTrigger(event, game)) { -// ability.trigger(game, controllerId); -// } -// } -// } -// } - - + public Card getCard() { + return card; + } + @Override public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) { Zone fromZone = game.getState().getZone(objectId);