From d7ae1c51c984fd7991e95a6f0f67ec7624a3f448 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Mon, 7 Mar 2016 18:30:58 +0100 Subject: [PATCH] Added test. --- .../sets/magic2011/CaptivatingVampire.java | 41 +++--- .../test/cards/copy/ProgenitorMimicTest.java | 124 +++++++++++++----- .../java/org/mage/test/player/TestPlayer.java | 13 ++ .../abilities/costs/common/TapTargetCost.java | 5 +- 4 files changed, 126 insertions(+), 57 deletions(-) diff --git a/Mage.Sets/src/mage/sets/magic2011/CaptivatingVampire.java b/Mage.Sets/src/mage/sets/magic2011/CaptivatingVampire.java index ca43463c03d..c64555e37d8 100644 --- a/Mage.Sets/src/mage/sets/magic2011/CaptivatingVampire.java +++ b/Mage.Sets/src/mage/sets/magic2011/CaptivatingVampire.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,22 +20,14 @@ * 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.magic2011; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -44,6 +36,13 @@ import mage.abilities.costs.common.TapTargetCost; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; @@ -77,7 +76,10 @@ public class CaptivatingVampire extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); + // Other Vampire creatures you control get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter1, true))); + + // Tap five untapped Vampires you control: Gain control of target creature. It becomes a Vampire in addition to its other types. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CaptivatingVampireEffect(), new TapTargetCost(new TargetControlledCreaturePermanent(5, 5, filter2, true))); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -97,7 +99,7 @@ public class CaptivatingVampire extends CardImpl { class CaptivatingVampireEffect extends ContinuousEffectImpl { public CaptivatingVampireEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); + super(Duration.Custom, Outcome.Detriment); staticText = "Gain control of target creature. It becomes a Vampire in addition to its other types"; } @@ -112,7 +114,7 @@ class CaptivatingVampireEffect extends ContinuousEffectImpl { @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent != null) { switch (layer) { case ControlChangingEffects_2: @@ -122,12 +124,15 @@ class CaptivatingVampireEffect extends ContinuousEffectImpl { break; case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { - permanent.getSubtype().add("Vampire"); + if (!permanent.getSubtype().contains("Vampire")) { + permanent.getSubtype().add("Vampire"); + } } break; } return true; } + discard(); return false; } @@ -138,7 +143,7 @@ class CaptivatingVampireEffect extends ContinuousEffectImpl { @Override public boolean hasLayer(Layer layer) { - return layer == Layer.ControlChangingEffects_2 || layer == layer.TypeChangingEffects_4; + return layer == Layer.ControlChangingEffects_2 || layer == Layer.TypeChangingEffects_4; } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/ProgenitorMimicTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/ProgenitorMimicTest.java index c1b7b322e87..47b0eff5afd 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/ProgenitorMimicTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/ProgenitorMimicTest.java @@ -1,7 +1,9 @@ package org.mage.test.cards.copy; + import mage.constants.CardType; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.filter.Filter; import mage.game.permanent.Permanent; import mage.game.permanent.PermanentToken; import org.junit.Assert; @@ -36,43 +38,49 @@ public class ProgenitorMimicTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Runeclaw Bear", 1); assertPermanentCount(playerB, "Runeclaw Bear", 2); - int tokens = 0; + int tokens = 0; int nonTokens = 0; for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) { if (permanent.getControllerId().equals(playerB.getId())) { if (permanent.getCardType().contains(CardType.CREATURE)) { if (permanent instanceof PermanentToken) { - tokens++; + tokens++; } else { - nonTokens++; + nonTokens++; } } } } - Assert.assertEquals("Only one non token permanent ",1, nonTokens); - Assert.assertEquals("Only one token permanent ",1, tokens); - } - - /** - * If you have Progenitor Mimic copy a creature it gets all of the abilities plus "At the beginning of upkeep - * if this creature isn't a token, put a token that's a copy of this creature". - * Up to this point everything works correctly. - * - * If you then summon another mimic and have it be a copy of the first mimic it should have "At the beginning of - * upkeep if this creature isn't a token, put a token that's a copy of this creature" two times. The second mimic - * would then make two copies and the first mimic would make one copy every turn. Right now the second mimc only - * makes one copy per turn. - * - * 706.9a Some copy effects cause the copy to gain an ability as part of the copying process. This ability becomes - * part of the copiable values for the copy, along with any other abilities that were copied. - * Example: Quirion Elves enters the battlefield and an Unstable Shapeshifter copies it. The copiable values of the - * Shapeshifter now match those of the Elves, except that the Shapeshifter also has the ability “Whenever a creature - * enters the battlefield, Unstable Shapeshifter becomes a copy of that creature and gains this ability.” Then a Clone - * enters the battlefield as a copy of the Unstable Shapeshifter. The Clone copies the new copiable values of the - * Shapeshifter, including the ability that the Shapeshifter gave itself when it copied the Elves. + Assert.assertEquals("Only one non token permanent ", 1, nonTokens); + Assert.assertEquals("Only one token permanent ", 1, tokens); + } + /** + * If you have Progenitor Mimic copy a creature it gets all of the abilities + * plus "At the beginning of upkeep if this creature isn't a token, put a + * token that's a copy of this creature". Up to this point everything works + * correctly. + * + * If you then summon another mimic and have it be a copy of the first mimic + * it should have "At the beginning of upkeep if this creature isn't a + * token, put a token that's a copy of this creature" two times. The second + * mimic would then make two copies and the first mimic would make one copy + * every turn. Right now the second mimc only makes one copy per turn. + * + * 706.9a Some copy effects cause the copy to gain an ability as part of the + * copying process. This ability becomes part of the copiable values for the + * copy, along with any other abilities that were copied. Example: Quirion + * Elves enters the battlefield and an Unstable Shapeshifter copies it. The + * copiable values of the Shapeshifter now match those of the Elves, except + * that the Shapeshifter also has the ability “Whenever a creature enters + * the battlefield, Unstable Shapeshifter becomes a copy of that creature + * and gains this ability.” Then a Clone enters the battlefield as a copy of + * the Unstable Shapeshifter. The Clone copies the new copiable values of + * the Shapeshifter, including the ability that the Shapeshifter gave itself + * when it copied the Elves. + * */ @Test public void testTwoMimic() { @@ -81,7 +89,7 @@ public class ProgenitorMimicTest extends CardTestPlayerBase { // Return target permanent you control to its owner's hand. You gain 4 life. addCard(Zone.HAND, playerA, "Narrow Escape"); - // You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield except + // You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield except // it gains "At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield // that's a copy of this creature." addCard(Zone.HAND, playerB, "Progenitor Mimic", 2); @@ -90,9 +98,9 @@ public class ProgenitorMimicTest extends CardTestPlayerBase { castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Progenitor Mimic"); setChoice(playerB, "Runeclaw Bear"); - + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Narrow Escape", "Runeclaw Bear"); - + // Begin of upkeep 1 token added castSpell(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Progenitor Mimic"); setChoice(playerB, "Runeclaw Bear"); @@ -107,27 +115,71 @@ public class ProgenitorMimicTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Narrow Escape", 1); assertPermanentCount(playerA, "Runeclaw Bear", 0); assertHandCount(playerA, "Runeclaw Bear", 1); - + assertPermanentCount(playerB, "Runeclaw Bear", 6); - int tokens = 0; + int tokens = 0; int nonTokens = 0; for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) { if (permanent.getControllerId().equals(playerB.getId())) { if (permanent.getCardType().contains(CardType.CREATURE)) { if (permanent instanceof PermanentToken) { - tokens++; + tokens++; } else { - nonTokens++; + nonTokens++; } } } } - Assert.assertEquals("Two non token permanents ",2, nonTokens); - Assert.assertEquals("Four token permanents",4, tokens); - } - - + Assert.assertEquals("Two non token permanents ", 2, nonTokens); + Assert.assertEquals("Four token permanents", 4, tokens); + } + + /** + * In a Commander FFA game, I controlled 5 vampires (one of which was + * Captivating Vampire). My opponent cast Progenitor Mimic, copying + * Captivating Vampire. I used the ability of my Captivating Vampire to gain + * control of his Mimic/Vampire but the buff didn't switch control. His + * other vampire still got the buff even after I gained control of the + * Mimic/Vampire. + * + * Did not get to see if the Mimic/Vampire produced tokens on the right side + * of the field (my side) as the game ended just after my turn. + */ + @Test + public void testChangeControl() { + // Other Vampire creatures you control get +1/+1. + // Tap five untapped Vampires you control: Gain control of target creature. It becomes a Vampire in addition to its other types. + addCard(Zone.BATTLEFIELD, playerA, "Captivating Vampire", 1); // 2/2 + // Lifelink + addCard(Zone.BATTLEFIELD, playerA, "Child of Night", 4); // 2/1 + + // You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield except + // it gains "At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield + // that's a copy of this creature." + addCard(Zone.HAND, playerB, "Progenitor Mimic", 1); + addCard(Zone.BATTLEFIELD, playerB, "Island", 3); + addCard(Zone.BATTLEFIELD, playerB, "Forest", 3); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Progenitor Mimic"); + setChoice(playerB, "Captivating Vampire"); + + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Tap five untapped Vampire", "Captivating Vampire[only copy]"); + setChoice(playerA, "Captivating Vampire"); + setChoice(playerA, "Child of Night"); + setChoice(playerA, "Child of Night"); + setChoice(playerA, "Child of Night"); + setChoice(playerA, "Child of Night"); + + setStopAt(2, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Captivating Vampire", 2); + assertPowerToughness(playerA, "Captivating Vampire", 3, 3, Filter.ComparisonScope.All); // +1 from the other Captivating Vampire + assertPowerToughness(playerA, "Child of Night", 4, 3, Filter.ComparisonScope.All); // +2 from the two Captivating Vampire + + } + } 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 7964f09a4e1..0f00d30abd2 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 @@ -318,10 +318,23 @@ public class TestPlayer implements Player { } } } else { + boolean originOnly = false; + boolean copyOnly = false; + if (targetName.endsWith("]")) { + if (targetName.endsWith("[no copy]")) { + originOnly = true; + targetName = targetName.substring(0, targetName.length() - 9); + } + if (targetName.endsWith("[only copy]")) { + copyOnly = true; + targetName = targetName.substring(0, targetName.length() - 11); + } + } for (UUID id : currentTarget.possibleTargets(ability.getSourceId(), ability.getControllerId(), game)) { if (!currentTarget.getTargets().contains(id)) { MageObject object = game.getObject(id); if (object != null + && ((object.isCopy() && !originOnly) || (!object.isCopy() && !copyOnly)) && ((!targetName.isEmpty() && object.getName().startsWith(targetName)) || (targetName.isEmpty() && object.getName().isEmpty()))) { if (currentTarget.getNumberOfTargets() == 1) { currentTarget.clearChosen(); diff --git a/Mage/src/main/java/mage/abilities/costs/common/TapTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/TapTargetCost.java index 38d2c5c4207..7f6eedbd100 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/TapTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/TapTargetCost.java @@ -27,7 +27,6 @@ */ package mage.abilities.costs.common; -import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.Cost; @@ -52,7 +51,7 @@ public class TapTargetCost extends CostImpl { this.text = new StringBuilder("Tap ") .append((target.getTargetName().startsWith("a ") || target.getTargetName().startsWith("an ") || target.getTargetName().startsWith("another")) - ? "" : CardUtil.numberToText(target.getMaxNumberOfTargets()) + " ") + ? "" : CardUtil.numberToText(target.getMaxNumberOfTargets()) + " ") .append(target.getTargetName()).toString(); } @@ -64,7 +63,7 @@ public class TapTargetCost extends CostImpl { @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { if (target.choose(Outcome.Tap, controllerId, sourceId, game)) { - for (UUID targetId : (List) target.getTargets()) { + for (UUID targetId : target.getTargets()) { Permanent permanent = game.getPermanent(targetId); if (permanent == null) { return false;