diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java b/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java index 0a5b592bd9e..416209d7782 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java @@ -66,8 +66,6 @@ public class ProgenitorMimic extends CardImpl { this.expansionSetCode = "DGM"; this.subtype.add("Shapeshifter"); - this.color.setBlue(true); - this.color.setGreen(true); this.power = new MageInt(0); this.toughness = new MageInt(0); @@ -97,6 +95,7 @@ class ProgenitorMimicApplyToPermanent extends ApplyToPermanent { static { filter.add(Predicates.not(new TokenPredicate())); } + @Override public Boolean apply(Game game, Permanent permanent) { Ability ability = new ConditionalTriggeredAbility( @@ -127,26 +126,32 @@ class ProgenitorMimicCopyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent copyFromPermanent = null; - // retrieve the copied permanent of Progenitor Mimic + // handle copies of copies for (Effect effect : game.getState().getContinuousEffects().getLayeredEffects(game)) { if (effect instanceof CopyEffect) { CopyEffect copyEffect = (CopyEffect) effect; - // take the exiting copy effect of Progenitor Mimic + // there is another copy effect that our targetPermanent copies stats from if (copyEffect.getSourceId().equals(source.getSourceId())) { - MageObject object = ((CopyEffect) effect).getTarget(); - if (object instanceof Permanent) { - copyFromPermanent = (Permanent)object; + MageObject oldBluePrint = ((CopyEffect) effect).getTarget(); + if (oldBluePrint instanceof Permanent) { + // copy it and apply the applier if any + copyFromPermanent = (Permanent) oldBluePrint; } } } } - if (copyFromPermanent != null) { - EmptyToken token = new EmptyToken(); + if (copyFromPermanent == null) { + // if it was no copy of copy take the target itself + copyFromPermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + } + + if (copyFromPermanent != null) { + EmptyToken token = new EmptyToken(); CardUtil.copyTo(token).from(copyFromPermanent); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); - Permanent sourcePermanent = game.getPermanent(token.getLastAddedToken()); - if (sourcePermanent != null) { - game.copyPermanent(copyFromPermanent, sourcePermanent, source, new ProgenitorMimicApplyToPermanent()); + Permanent newPermanentToken = game.getPermanent(token.getLastAddedToken()); + if (newPermanentToken != null) { + game.copyPermanent(copyFromPermanent, newPermanentToken, source, null); return true; } } 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 4beda08367a..c1b7b322e87 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 @@ -27,8 +27,6 @@ public class ProgenitorMimicTest extends CardTestPlayerBase { castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Progenitor Mimic"); - castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Anaconda"); - setStopAt(4, PhaseStep.END_TURN); execute(); @@ -55,59 +53,81 @@ public class ProgenitorMimicTest extends CardTestPlayerBase { 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. -// /** -// * Tests Clone is sacrificed and only one effect is turned on -// */ -// @Test -// public void testCloneSacrifice() { -// addCard(Zone.BATTLEFIELD, playerA, "Bloodgift Demon", 1); -// -// addCard(Zone.HAND, playerA, "Diabolic Edict"); -// addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); -// -// addCard(Zone.HAND, playerB, "Clone"); -// addCard(Zone.BATTLEFIELD, playerB, "Island", 4); -// -// castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Clone"); -// castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Diabolic Edict", playerB); -// -// setStopAt(4, PhaseStep.END_TURN); -// execute(); -// -// assertPermanentCount(playerA, "Bloodgift Demon", 1); -// assertGraveyardCount(playerA, "Diabolic Edict", 1); -// assertPermanentCount(playerB, "Bloodgift Demon", 0); -// assertGraveyardCount(playerB, "Clone", 1); -// -// // 1 from draw steps + 2 from Demon -// assertHandCount(playerA, 3); -// // 2 from draw steps + no from Demon (should be sacrificed) -// assertHandCount(playerB, 2); -// -// assertLife(playerA, 18); -// assertLife(playerB, 20); -// } -// -// @Test -// public void testCard3() { -// addCard(Zone.BATTLEFIELD, playerA, "Island", 6); -// addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6); -// addCard(Zone.HAND, playerA, "Public Execution"); -// addCard(Zone.HAND, playerA, "Clone"); -// -// addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves"); -// addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm"); -// -// castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Public Executio", "Llanowar Elves"); -// castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Clone"); -// -// setStopAt(1, PhaseStep.END_TURN); -// execute(); -// -// assertPermanentCount(playerB, "Llanowar Elves", 0); -// assertPowerToughness(playerB, "Craw Wurm", 4, 4); -// assertPowerToughness(playerA, "Craw Wurm", 6, 4); -// } + */ + @Test + public void testTwoMimic() { + addCard(Zone.BATTLEFIELD, playerA, "Runeclaw Bear", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); + // 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 + // 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); + addCard(Zone.BATTLEFIELD, playerB, "Island", 3); + addCard(Zone.BATTLEFIELD, playerB, "Forest", 3); + + 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"); + + // Begin of upkeep 3 tokens added + setStopAt(6, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 24); + assertLife(playerB, 20); + + assertGraveyardCount(playerA, "Narrow Escape", 1); + assertPermanentCount(playerA, "Runeclaw Bear", 0); + assertHandCount(playerA, "Runeclaw Bear", 1); + + assertPermanentCount(playerB, "Runeclaw Bear", 6); + + 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++; + } else { + nonTokens++; + } + + } + } + } + + Assert.assertEquals("Two non token permanents ",2, nonTokens); + Assert.assertEquals("Four token permanents",4, tokens); + } + + } diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index b679d5acc35..6508fdb0a4b 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1285,46 +1285,47 @@ public abstract class GameImpl implements Game, Serializable { @Override public Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, Permanent copyToPermanent, Ability source, ApplyToPermanent applier) { - Permanent permanent = copyFromPermanent.copy(); - - //getState().addCard(permanent); - permanent.reset(this); - if (copyFromPermanent.isMorphed() || copyFromPermanent.isManifested()) { - MorphAbility.setPermanentToFaceDownCreature(permanent); - } - permanent.assignNewId(); - if (copyFromPermanent.isTransformed()) { - TransformAbility.transform(permanent, copyFromPermanent.getSecondCardFace(), this); - } - applier.apply(this, permanent); - - CopyEffect newEffect = new CopyEffect(duration, permanent, copyToPermanent.getId()); - newEffect.newId(); - newEffect.setApplier(applier); - Ability newAbility = source.copy(); - newEffect.init(newAbility, this); - + Permanent newBluePrint = null; // handle copies of copies for (Effect effect : getState().getContinuousEffects().getLayeredEffects(this)) { if (effect instanceof CopyEffect) { CopyEffect copyEffect = (CopyEffect) effect; // there is another copy effect that our targetPermanent copies stats from if (copyEffect.getSourceId().equals(copyFromPermanent.getId())) { - MageObject object = ((CopyEffect) effect).getTarget(); - if (object instanceof Permanent) { - // so we will use original card instead of target - Permanent original = (Permanent)object; - // copy it and apply changes we need - original = original.copy(); - applier.apply(this, original); - newEffect.setTarget(object); + MageObject oldBluePrint = ((CopyEffect) effect).getTarget(); + if (oldBluePrint instanceof Permanent) { + // copy it and apply the applier if any + newBluePrint = ((Permanent)oldBluePrint).copy(); } } } } + // if it was no copy of copy take the target itself + if (newBluePrint == null) { + newBluePrint = copyFromPermanent.copy(); + newBluePrint.reset(this); + //getState().addCard(permanent); + if (copyFromPermanent.isMorphed() || copyFromPermanent.isManifested()) { + MorphAbility.setPermanentToFaceDownCreature(newBluePrint); + } + newBluePrint.assignNewId(); + if (copyFromPermanent.isTransformed()) { + TransformAbility.transform(newBluePrint, copyFromPermanent.getSecondCardFace(), this); + } + } + if (applier != null) { + applier.apply(this, newBluePrint); + } + + CopyEffect newEffect = new CopyEffect(duration, newBluePrint, copyToPermanent.getId()); + newEffect.newId(); + newEffect.setApplier(applier); + Ability newAbility = source.copy(); + newEffect.init(newAbility, this); + state.addEffect(newEffect, newAbility); - return permanent; + return newBluePrint; } @Override diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 8cd2141f522..95e6da42ec5 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -209,7 +209,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { this.maxBlockedBy = 0; this.copy = false; } - + @Override public String getValue() { StringBuilder sb = threadLocalBuilder.get(); @@ -516,8 +516,9 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { if (!phasedIn) { if (!replaceEvent(EventType.PHASE_IN, game)) { this.phasedIn = true; - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(getLogName() + " phased in"); + } fireEvent(EventType.PHASED_IN, game); return true; } @@ -1345,4 +1346,4 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { fightTarget.damage(getPower().getValue(), getId(), game, false, true); return true; } -} + }