From 8d7087d859c51a94d74afa5d6010d4f73cb0e917 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 11 Mar 2015 13:24:11 +0100 Subject: [PATCH] Fixed initialisation of targetPointer in BoostEquippedEffect (fixes #790). --- .../betrayersofkamigawa/UmezawasJitte.java | 5 +- .../abilities/flicker/CloudshiftTest.java | 82 ++++++++++++++++++- .../java/org/mage/test/player/TestPlayer.java | 10 +-- .../base/impl/CardTestPlayerAPIImpl.java | 28 +++---- .../continuous/BoostEquippedEffect.java | 2 +- 5 files changed, 105 insertions(+), 22 deletions(-) diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/UmezawasJitte.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/UmezawasJitte.java index 200e9dadc36..e40a0a35633 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/UmezawasJitte.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/UmezawasJitte.java @@ -65,7 +65,10 @@ public class UmezawasJitte extends CardImpl { this.addAbility(new UmezawasJitteAbility()); // Remove a charge counter from Umezawa's Jitte: Choose one Equipped creature gets +2/+2 until end of turn; or target creature gets -1/-1 until end of turn; or you gain 2 life. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2, Duration.EndOfTurn), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance())); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new BoostEquippedEffect(2, 2, Duration.EndOfTurn), + new RemoveCountersSourceCost(CounterType.CHARGE.createInstance())); Mode mode = new Mode(); mode.getEffects().add(new BoostTargetEffect(-1, -1, Duration.EndOfTurn)); mode.getTargets().add(new TargetCreaturePermanent()); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java index 8ec19f6c964..5ac2192d326 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java @@ -5,6 +5,7 @@ import mage.abilities.keyword.IntimidateAbility; import mage.abilities.keyword.LifelinkAbility; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.counters.CounterType; import mage.game.permanent.Permanent; import org.junit.Assert; import org.junit.Test; @@ -73,7 +74,8 @@ public class CloudshiftTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); addCard(Zone.BATTLEFIELD, playerA, "Bonesplitter"); - + + // Exile target creature you control, then return that card to the battlefield under your control. addCard(Zone.HAND, playerA, "Cloudshift"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {1}", "Silvercoat Lion"); @@ -147,4 +149,82 @@ public class CloudshiftTest extends CardTestPlayerBase { assertLife(playerA, 27); // 5 from the first with Giant Growth + 2 from the second bear. } + /* + I had a Stoneforge Mystic equipped with a Umesawa's Jitte. I activated Jitte 4 times to make + Stoneforge Mystic 9/10. My opponent put into play a Flickerwisp with his AEther Vial and + targeted my Stoneforge Mystic. At the end of my turn, Stoneforge Mystic came back as a 9/10, + before going down to 1/2 normally once my turn ended. + */ + @Test + public void testDontApplyEffectToNewInstanceOfPreviousEquipedPermanent() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Umezawa's Jitte"); + + // Exile target creature you control, then return that card to the battlefield under your control. + addCard(Zone.HAND, playerA, "Cloudshift"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Silvercoat Lion"); + + attack(3, playerA, "Silvercoat Lion"); + + activateAbility(3, PhaseStep.END_COMBAT, playerA, "Remove a charge counter from {this}: Choose one —
&bull Equipped creature gets"); + setModeChoice(playerA, "1"); + castSpell(3, PhaseStep.END_COMBAT, playerA, "Cloudshift", "Silvercoat Lion", "Remove a charge counter from"); + + setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + Permanent Umezawa = getPermanent("Umezawa's Jitte", playerA.getId()); + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA.getId()); + + assertLife(playerA, 20); + assertLife(playerB, 18); + assertCounterCount("Umezawa's Jitte", CounterType.CHARGE, 1); + assertPermanentCount(playerA,"Silvercoat Lion", 1); + assertGraveyardCount(playerA,"Cloudshift", 1); + Assert.assertTrue(silvercoatLion.getAttachments().isEmpty()); + Assert.assertTrue("Umezawa must not be connected to Silvercoat Lion",Umezawa.getAttachedTo() == null); + assertPowerToughness(playerA, "Silvercoat Lion", 2, 2); + + } + + @Test + public void testDontApplyEffectToNewInstanceOfPreviousEquipedPermanentFlickerwisp() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Umezawa's Jitte"); + + + addCard(Zone.BATTLEFIELD, playerB, "Plains", 3); + // Flying + // When Flickerwisp enters the battlefield, exile another target permanent. Return that + // card to the battlefield under its owner's control at the beginning of the next end step. + addCard(Zone.HAND, playerB, "Flickerwisp"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Silvercoat Lion"); + + attack(3, playerA, "Silvercoat Lion"); + + activateAbility(4, PhaseStep.DRAW, playerA, "Remove a charge counter from {this}: Choose one —
&bull Equipped creature gets"); + setModeChoice(playerA, "1"); + castSpell(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Flickerwisp"); + addTarget(playerB, "Silvercoat Lion"); + + setStopAt(4, PhaseStep.END_TURN); + execute(); + + Permanent Umezawa = getPermanent("Umezawa's Jitte", playerA.getId()); + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA.getId()); + + assertLife(playerA, 20); + assertLife(playerB, 18); + assertCounterCount("Umezawa's Jitte", CounterType.CHARGE, 1); + assertPermanentCount(playerA,"Silvercoat Lion", 1); + assertPermanentCount(playerB,"Flickerwisp", 1); + Assert.assertTrue(silvercoatLion.getAttachments().isEmpty()); + Assert.assertTrue("Umezawa must not be connected to Silvercoat Lion",Umezawa.getAttachedTo() == null); + assertPowerToughness(playerA, "Silvercoat Lion", 2, 2); + + } } 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 f336540ccf7..60200155aed 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 @@ -125,7 +125,7 @@ public class TestPlayer extends ComputerPlayer { if (action.getAction().startsWith("activate:")) { String command = action.getAction(); command = command.substring(command.indexOf("activate:") + 9); - String[] groups = command.split(";"); + String[] groups = command.split("\\$"); if (!checkSpellOnStackCondition(groups, game) || !checkSpellOnTopOfStackCondition(groups, game)) { break; } @@ -148,7 +148,7 @@ public class TestPlayer extends ComputerPlayer { if (action.getAction().startsWith("manaActivate:")) { String command = action.getAction(); command = command.substring(command.indexOf("manaActivate:") + 13); - String[] groups = command.split(";"); + String[] groups = command.split("$"); List manaPerms = this.getAvailableManaProducers(game); for (Permanent perm: manaPerms) { for (Ability manaAbility: perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) { @@ -176,7 +176,7 @@ public class TestPlayer extends ComputerPlayer { if (action.getAction().startsWith("addCounters:")) { String command = action.getAction(); command = command.substring(command.indexOf("addCounters:") + 12); - String[] groups = command.split(";"); + String[] groups = command.split("$"); for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) { if (permanent.getName().equals(groups[0])) { Counter counter = new Counter(groups[1], Integer.parseInt(groups[2])); @@ -204,7 +204,7 @@ public class TestPlayer extends ComputerPlayer { } String command = action.getAction(); command = command.substring(command.indexOf("attack:") + 7); - String[] groups = command.split(";"); + String[] groups = command.split("$"); for (int i = 1; i < groups.length; i++) { String group = groups[i]; if (group.startsWith("planeswalker=")) { @@ -234,7 +234,7 @@ public class TestPlayer extends ComputerPlayer { if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("block:")) { String command = action.getAction(); command = command.substring(command.indexOf("block:") + 6); - String[] groups = command.split(";"); + String[] groups = command.split("$"); FilterCreatureForCombatBlock filterBlocker = new FilterCreatureForCombatBlock(); filterBlocker.add(new NamePredicate(groups[0])); filterBlocker.add(Predicates.not(new BlockingPredicate())); 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 f87e3eabfde..62fd2d86d1f 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 @@ -697,11 +697,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, Player target) { - player.addAction(turnNum, step, "activate:Cast " + cardName + ";targetPlayer=" + target.getName()); + player.addAction(turnNum, step, "activate:Cast " + cardName + "$targetPlayer=" + target.getName()); } public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) { - player.addAction(turnNum, step, "activate:Cast " + cardName + ";target=" + targetName); + player.addAction(turnNum, step, "activate:Cast " + cardName + "$target=" + targetName); } public enum StackClause { @@ -736,19 +736,19 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement */ public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack, StackClause clause) { if (StackClause.WHILE_ON_STACK.equals(clause)) { - player.addAction(turnNum, step, "activate:Cast " + cardName + ";target=" + targetName + ";spellOnStack=" + spellOnStack); + player.addAction(turnNum, step, "activate:Cast " + cardName + "$target=" + targetName + "$spellOnStack=" + spellOnStack); } else { - player.addAction(turnNum, step, "activate:Cast " + cardName + ";target=" + targetName + ";!spellOnStack=" + spellOnStack); + player.addAction(turnNum, step, "activate:Cast " + cardName + "$target=" + targetName + "$!spellOnStack=" + spellOnStack); } } public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack, String spellOnTopOfStack) { - String action = "activate:Cast " + cardName + ";target=" + targetName; + String action = "activate:Cast " + cardName + "$target=" + targetName; if (spellOnStack != null && !spellOnStack.isEmpty()) { - action += ";spellOnStack=" + spellOnStack; + action += "$spellOnStack=" + spellOnStack; } if (spellOnTopOfStack != null && !spellOnTopOfStack.isEmpty()) { - action += ";spellOnTopOfStack=" + spellOnTopOfStack; + action += "$spellOnTopOfStack=" + spellOnTopOfStack; } player.addAction(turnNum, step, action); } @@ -762,26 +762,26 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, Player target) { - player.addAction(turnNum, step, "activate:" + ability + ";targetPlayer=" + target.getName()); + player.addAction(turnNum, step, "activate:" + ability + "$targetPlayer=" + target.getName()); } public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName) { - player.addAction(turnNum, step, "activate:" + ability + ";target=" + targetName); + player.addAction(turnNum, step, "activate:" + ability + "$target=" + targetName); } public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack) { StringBuilder sb = new StringBuilder("activate:").append(ability); if (targetName != null && !targetName.isEmpty()) { - sb.append(";target=" ).append(targetName); + sb.append("$target=" ).append(targetName); } if (spellOnStack != null && !spellOnStack.isEmpty()) { - sb.append(";spellOnStack=").append(spellOnStack); + sb.append("$spellOnStack=").append(spellOnStack); } player.addAction(turnNum, step, sb.toString()); } public void addCounters(int turnNum, PhaseStep step, TestPlayer player, String cardName, CounterType type, int count) { - player.addAction(turnNum, step, "addCounters:" + cardName + ";" + type.getName() + ";" + count); + player.addAction(turnNum, step, "addCounters:" + cardName + "$" + type.getName() + "$" + count); } public void attack(int turnNum, TestPlayer player, String attacker) { @@ -789,11 +789,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } public void attack(int turnNum, TestPlayer player, String attacker, String planeswalker) { - player.addAction(turnNum, PhaseStep.DECLARE_ATTACKERS, new StringBuilder("attack:").append(attacker).append(";planeswalker=").append(planeswalker).toString()); + player.addAction(turnNum, PhaseStep.DECLARE_ATTACKERS, new StringBuilder("attack:").append(attacker).append("$planeswalker=").append(planeswalker).toString()); } public void block(int turnNum, TestPlayer player, String blocker, String attacker) { - player.addAction(turnNum, PhaseStep.DECLARE_BLOCKERS, "block:"+blocker+";"+attacker); + player.addAction(turnNum, PhaseStep.DECLARE_BLOCKERS, "block:"+blocker+"$"+attacker); } /** diff --git a/Mage/src/mage/abilities/effects/common/continuous/BoostEquippedEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BoostEquippedEffect.java index da25d7e5585..dd3150b62e2 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BoostEquippedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BoostEquippedEffect.java @@ -85,13 +85,13 @@ public class BoostEquippedEffect extends ContinuousEffectImpl { @Override public void init(Ability source, Game game) { - super.init(source, game); if (fixedTarget) { Permanent equipment = game.getPermanent(source.getSourceId()); if (equipment != null && equipment.getAttachedTo() != null) { this.setTargetPointer(new FixedTarget(equipment.getAttachedTo())); } } + super.init(source, game); // inits the target pointer so call it after setting the targetPointer } @Override