From b3fdc167a8b3159ed1fd647b5dd680c89d6ee6fc Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 13 Jun 2015 09:35:37 +0200 Subject: [PATCH] * The Mimeoplasm - Fixed that if a Mimeoplasm was copied (e.g. by Clone) that not the target copied by Mimeoplasm was copied but instead the Mimeoplasm itself. --- .../mage/sets/commander/TheMimeoplasm.java | 22 +++-- .../test/cards/copy/TheMimeoplasmTest.java | 97 +++++++++++++++++++ .../java/org/mage/test/player/TestPlayer.java | 52 ++++++++-- .../abilities/effects/common/CopyEffect.java | 5 +- 4 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/copy/TheMimeoplasmTest.java diff --git a/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java b/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java index de4556bc487..0397ca4cff8 100644 --- a/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java +++ b/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java @@ -36,6 +36,8 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CopyEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; @@ -94,31 +96,33 @@ class TheMimeoplasmEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { + if (controller != null && permanent != null) { if (new CardsInAllGraveyardsCount(new FilterCreatureCard()).calculate(game, source, this) >= 2) { - if (player.chooseUse(Outcome.Benefit, "Do you want to exile two creature cards from graveyards?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Do you want to exile two creature cards from graveyards?", game)) { TargetCardInGraveyard targetCopy = new TargetCardInGraveyard(new FilterCreatureCard("creature card to become a copy of")); - TargetCardInGraveyard targetCounters = new TargetCardInGraveyard(new FilterCreatureCard("creature card for additional +1/+1 counters")); - if (player.choose(Outcome.Copy, targetCopy, source.getSourceId(), game)) { + TargetCardInGraveyard targetCounters = new TargetCardInGraveyard(new FilterCreatureCard("creature card to determine amount of additional +1/+1 counters")); + if (controller.choose(Outcome.Copy, targetCopy, source.getSourceId(), game)) { Card cardToCopy = game.getCard(targetCopy.getFirstTarget()); if (cardToCopy != null) { - player.moveCardToExileWithInfo(cardToCopy, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); - if (player.choose(Outcome.Copy, targetCounters, source.getSourceId(), game)) { + if (controller.choose(Outcome.Copy, targetCounters, source.getSourceId(), game)) { Card cardForCounters = game.getCard(targetCounters.getFirstTarget()); if (cardForCounters != null) { - player.moveCardToExileWithInfo(cardForCounters, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); + Cards cardsToExile = new CardsImpl(); + cardsToExile.add(cardToCopy); + cardsToExile.add(cardForCounters); + controller.moveCards(cardsToExile, Zone.GRAVEYARD, Zone.EXILED, source, game); CopyEffect copyEffect = new CopyEffect(Duration.Custom, cardToCopy, source.getSourceId()); game.addEffect(copyEffect, source); permanent.addCounters(CounterType.P1P1.createInstance(cardForCounters.getPower().getValue()), game); - return true; } } } } } } + return true; } return false; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/TheMimeoplasmTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/TheMimeoplasmTest.java new file mode 100644 index 00000000000..5ef499da439 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/TheMimeoplasmTest.java @@ -0,0 +1,97 @@ +/* + * 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.copy; + +import mage.abilities.keyword.FlyingAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class TheMimeoplasmTest extends CardTestPlayerBase { + + /** + * I cast either Phyrexian Metamorph or Phantasmal Image and copied The + * Mimeoplasm which was copying a Primeval Titan, but my clone became + * another Mimeoplasm, so it exiled two creatures from graveyards and cloned + * one of those instead. + * + * Copying cards that are copy of other cards copies the original, rather + * than the copy. + * To wit, when The Mimeoplasm is out (and lets say is a copy of Elvish + * Mystic), and someone then plays Clone choosing to enter as the cloned + * Elvish Mystic, they are incorrectly getting The Mimeoplasm instead. + * + */ + @Test + public void testCloneMimeoplasm() { + // As The Mimeoplasm enters the battlefield, you may exile two creature cards from graveyards. + // If you do, it enters the battlefield as a copy of one of those cards with a number of additional +1/+1 counters on it equal to the power of the other card. + addCard(Zone.HAND, playerA, "The Mimeoplasm", 1); // {2}{G}{U}{B} + + addCard(Zone.HAND, playerA, "Clone", 1); // {3}{U} + + addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion", 1); // 2/2 + addCard(Zone.GRAVEYARD, playerB, "Aven Riftwatcher", 1); // 2/3 + + addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); + addCard(Zone.BATTLEFIELD, playerA, "Island", 7); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + + + castSpell(1,PhaseStep.PRECOMBAT_MAIN, playerA, "The Mimeoplasm"); + setChoice(playerA, "Aven Riftwatcher"); + setChoice(playerA, "Silvercoat Lion"); + + castSpell(1,PhaseStep.PRECOMBAT_MAIN, playerA, "Clone"); + setChoice(playerA, "Aven Riftwatcher"); + + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertHandCount(playerA, "Clone", 0); + + assertLife(playerA, 24); + assertLife(playerB, 20); + + assertPermanentCount(playerA, "Aven Riftwatcher", 2); + assertPowerToughness(playerA, "Aven Riftwatcher", 4, 5); + assertPowerToughness(playerA, "Aven Riftwatcher", 2, 3); + + assertGraveyardCount(playerB, 0); + + + } +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 4f99f385689..be7c65487a0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -29,6 +29,7 @@ package org.mage.test.player; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -91,6 +92,7 @@ import mage.target.TargetPermanent; import mage.target.TargetPlayer; import mage.target.TargetSource; import mage.target.TargetSpell; +import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCreaturePermanentAmount; @@ -604,17 +606,53 @@ public class TestPlayer implements Player { } } } + if (target instanceof TargetCardInGraveyard) { + TargetCardInGraveyard targetCardInGraveyard = ((TargetCardInGraveyard) target); + Set possibleTargets = new HashSet<>(); + for(UUID playerId: this.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) { + possibleTargets.addAll(player.getGraveyard()); + } + } + + for (String choose2 : choices) { + String[] targetList = choose2.split("\\^"); + boolean targetFound = false; + for (UUID targetId : possibleTargets) { + MageObject targetObject = game.getObject(targetId); + if (targetObject != null) { + for (String targetName : targetList) { + if (targetObject.getName().equals(targetName)) { + List alreadyTargetted = targetCardInGraveyard.getTargets(); + if (targetCardInGraveyard.canTarget(targetObject.getId(), game)) { + if (alreadyTargetted != null && !alreadyTargetted.contains(targetObject.getId())) { + targetCardInGraveyard.add(targetObject.getId(), game); + choices.remove(choose2); + targetFound = true; + } + } + } + } + if (targetFound && targetCardInGraveyard.isChosen()) { + choices.remove(choose2); + return true; + } + } + } + } + } if (target instanceof TargetSource) { Set possibleTargets; TargetSource t = ((TargetSource) target); possibleTargets = t.possibleTargets(sourceId, computerPlayer.getId(), game); - for (UUID targetId : possibleTargets) { - MageObject targetObject = game.getObject(targetId); - if (targetObject != null) { - for (String choose2 : choices) { - String[] targetList = choose2.split("\\^"); - boolean targetFound = false; - for (String targetName : targetList) { + for (String choose2 : choices) { + String[] targetList = choose2.split("\\^"); + boolean targetFound = false; + for (String targetName : targetList) { + for (UUID targetId : possibleTargets) { + MageObject targetObject = game.getObject(targetId); + if (targetObject != null) { if (targetObject.getName().equals(targetName)) { List alreadyTargetted = target.getTargets(); if (t.canTarget(targetObject.getId(), game)) { diff --git a/Mage/src/mage/abilities/effects/common/CopyEffect.java b/Mage/src/mage/abilities/effects/common/CopyEffect.java index 9560f3e6bfd..9d1194fda2a 100644 --- a/Mage/src/mage/abilities/effects/common/CopyEffect.java +++ b/Mage/src/mage/abilities/effects/common/CopyEffect.java @@ -67,7 +67,7 @@ public class CopyEffect extends ContinuousEffectImpl { public CopyEffect(Duration duration, MageObject target, UUID sourceId) { super(duration, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature); - this.target = target; + this.target = target; this.sourceId = sourceId; } @@ -81,6 +81,9 @@ public class CopyEffect extends ContinuousEffectImpl { @Override public void init(Ability source, Game game) { super.init(source, game); + if (!(target instanceof Permanent) && (target instanceof Card)) { + this.target = new PermanentCard((Card)target, source.getControllerId(), game); + } affectedObjectList.add(new MageObjectReference(getSourceId(), game)); }