From a8d8f4e6219b77f3537feb80bf789e6caa92f860 Mon Sep 17 00:00:00 2001 From: dilnu Date: Sun, 2 Feb 2020 18:51:05 -0500 Subject: [PATCH 1/4] Add tests to debug issues with Bonecrusher Giant https://github.com/magefree/mage/issues/6158 --- .../mage/test/cards/copy/CopySpellTest.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java index e3d6030976b..bfb1a229a48 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java @@ -77,6 +77,68 @@ public class CopySpellTest extends CardTestPlayerBase { assertAbility(playerB, "Silvercoat Lion", FlyingAbility.getInstance(), false); } + @Test + public void BonecrusherGiantChangeTargetsTo() { + addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, "Barkshell Blessing"); + + castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); + setChoice(playerA, "Yes"); + setChoice(playerA, "Yes"); + addTarget(playerA, "Grizzly Bears"); + addTarget(playerA, "Bonecrusher Giant"); + + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPowerToughness(playerA, "Bonecrusher Giant", 6, 5); + assertPowerToughness(playerA, "Grizzly Bears", 4, 4); + assertPowerToughness(playerA, "Savannah Lions", 2, 1); + assertLife(playerA, 18); + } + + @Test + public void BonecrusherGiantChangeTargetsFrom() { + addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, "Barkshell Blessing"); + + castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); + setChoice(playerA, "Yes"); + setChoice(playerA, "Yes"); + addTarget(playerA, "Bonecrusher Giant"); + addTarget(playerA, "Grizzly Bears"); + + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPowerToughness(playerA, "Bonecrusher Giant", 6, 5); + assertPowerToughness(playerA, "Grizzly Bears", 4, 4); + assertPowerToughness(playerA, "Savannah Lions", 2, 1); + assertLife(playerA, 18); + } + + @Test + public void BonecrusherGiantControl() { + addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, "Barkshell Blessing"); + + castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); + addTarget(playerA, "Bonecrusher Giant"); + + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPowerToughness(playerA, "Bonecrusher Giant", 6, 5); + assertLife(playerA, 18); + } + /* * Reported bug: "Silverfur Partisan and fellow wolves did not trigger off * of copies of Strength of Arms made by Zada, Hedron Grinder. Not sure From b6af571779e5b375403f0f1816b6b83934a0e195 Mon Sep 17 00:00:00 2001 From: dilnu Date: Sun, 2 Feb 2020 18:53:52 -0500 Subject: [PATCH 2/4] Only fire one Targetted event per target This specifically addresses changing the target of a spell or ability on the stack. Fixes https://github.com/magefree/mage/issues/6158 --- .../mage/test/cards/copy/CopySpellTest.java | 41 +------------------ .../java/mage/game/stack/StackObjImpl.java | 14 ++++--- Mage/src/main/java/mage/target/Target.java | 2 + .../src/main/java/mage/target/TargetImpl.java | 15 +++++-- 4 files changed, 22 insertions(+), 50 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java index bfb1a229a48..0856e2ee7ec 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java @@ -78,7 +78,7 @@ public class CopySpellTest extends CardTestPlayerBase { } @Test - public void BonecrusherGiantChangeTargetsTo() { + public void BonecrusherGiantChangeTargets() { addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); @@ -100,45 +100,6 @@ public class CopySpellTest extends CardTestPlayerBase { assertLife(playerA, 18); } - @Test - public void BonecrusherGiantChangeTargetsFrom() { - addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); - addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); - addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); - addCard(Zone.BATTLEFIELD, playerA, "Plains"); - addCard(Zone.HAND, playerA, "Barkshell Blessing"); - - castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); - setChoice(playerA, "Yes"); - setChoice(playerA, "Yes"); - addTarget(playerA, "Bonecrusher Giant"); - addTarget(playerA, "Grizzly Bears"); - - setStopAt(1, PhaseStep.PRECOMBAT_MAIN); - execute(); - - assertPowerToughness(playerA, "Bonecrusher Giant", 6, 5); - assertPowerToughness(playerA, "Grizzly Bears", 4, 4); - assertPowerToughness(playerA, "Savannah Lions", 2, 1); - assertLife(playerA, 18); - } - - @Test - public void BonecrusherGiantControl() { - addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); - addCard(Zone.BATTLEFIELD, playerA, "Plains"); - addCard(Zone.HAND, playerA, "Barkshell Blessing"); - - castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); - addTarget(playerA, "Bonecrusher Giant"); - - setStopAt(1, PhaseStep.PRECOMBAT_MAIN); - execute(); - - assertPowerToughness(playerA, "Bonecrusher Giant", 6, 5); - assertLife(playerA, 18); - } - /* * Reported bug: "Silverfur Partisan and fellow wolves did not trigger off * of copies of Strength of Arms made by Zada, Hedron Grinder. Not sure diff --git a/Mage/src/main/java/mage/game/stack/StackObjImpl.java b/Mage/src/main/java/mage/game/stack/StackObjImpl.java index 6b38b76acbc..8d7130458ac 100644 --- a/Mage/src/main/java/mage/game/stack/StackObjImpl.java +++ b/Mage/src/main/java/mage/game/stack/StackObjImpl.java @@ -151,6 +151,7 @@ public abstract class StackObjImpl implements StackObject { */ private Target chooseNewTarget(Player targetController, Ability ability, Mode mode, Target target, boolean forceChange, FilterPermanent filterNewTarget, Game game) { Target newTarget = target.copy(); + newTarget.setEventReporting(false); if (!targetController.getId().equals(getControllerId())) { newTarget.setTargetController(targetController.getId()); // target controller for the change is different from spell controller newTarget.setAbilityController(getControllerId()); @@ -199,6 +200,7 @@ public abstract class StackObjImpl implements StackObject { } else { // build a target definition with exactly one possible target to select that replaces old target Target tempTarget = target.copy(); + tempTarget.setEventReporting(false); if (target instanceof TargetAmount) { ((TargetAmount) tempTarget).setAmountDefinition(StaticValue.get(target.getTargetAmount(targetId))); } @@ -215,7 +217,7 @@ public abstract class StackObjImpl implements StackObject { if (!tempTarget.chooseTarget(outcome, getControllerId(), ability, game)) { if (targetController.chooseUse(Outcome.Benefit, "No target object selected. Reset to original target?", ability, game)) { // use previous target no target was selected - newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); + newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, true); } else { again = true; } @@ -225,12 +227,12 @@ public abstract class StackObjImpl implements StackObject { if (targetController.isHuman()) { if (targetController.chooseUse(Outcome.Benefit, "This target was already selected from origin spell. Reset to original target?", ability, game)) { // use previous target no target was selected - newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); + newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, true); } else { again = true; } } else { - newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); + newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, true); } } else if (!target.canTarget(getControllerId(), tempTarget.getFirstTarget(), ability, game)) { if (targetController.isHuman()) { @@ -238,7 +240,7 @@ public abstract class StackObjImpl implements StackObject { again = true; } else { // keep the old - newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); + newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, true); } } else if (newTarget.getFirstTarget() != null && filterNewTarget != null) { Permanent newTargetPermanent = game.getPermanent(newTarget.getFirstTarget()); @@ -248,14 +250,14 @@ public abstract class StackObjImpl implements StackObject { } } else { // valid target was selected, add it to the new target definition - newTarget.addTarget(tempTarget.getFirstTarget(), target.getTargetAmount(targetId), ability, game, false); + newTarget.addTarget(tempTarget.getFirstTarget(), target.getTargetAmount(targetId), ability, game, true); } } } while (again && targetController.canRespond()); } } // keep the target else { - newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); + newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, true); } } return newTarget; diff --git a/Mage/src/main/java/mage/target/Target.java b/Mage/src/main/java/mage/target/Target.java index a9b7d45ec04..ec2a5aa573c 100644 --- a/Mage/src/main/java/mage/target/Target.java +++ b/Mage/src/main/java/mage/target/Target.java @@ -136,4 +136,6 @@ public interface Target extends Serializable { void setTargetAmount(UUID targetId, int amount, Game game); Target withChooseHint(String chooseHint); + + void setEventReporting(boolean shouldReport); } diff --git a/Mage/src/main/java/mage/target/TargetImpl.java b/Mage/src/main/java/mage/target/TargetImpl.java index 438bbb35ada..bbd85908cfe 100644 --- a/Mage/src/main/java/mage/target/TargetImpl.java +++ b/Mage/src/main/java/mage/target/TargetImpl.java @@ -37,6 +37,7 @@ public abstract class TargetImpl implements Target { protected int targetTag; // can be set if other target check is needed (AnotherTargetPredicate) protected String chooseHint = null; // UI choose hints after target name + protected boolean shouldReportEvents = true; @Override public abstract TargetImpl copy(); @@ -65,6 +66,7 @@ public abstract class TargetImpl implements Target { this.abilityController = target.abilityController; this.targetTag = target.targetTag; this.chooseHint = target.chooseHint; + this.shouldReportEvents = target.shouldReportEvents; } @Override @@ -213,12 +215,12 @@ public abstract class TargetImpl implements Target { //20100423 - 113.3 if (getMaxNumberOfTargets() == 0 || targets.size() < getMaxNumberOfTargets()) { if (!targets.containsKey(id)) { - if (source != null && !skipEvent) { + if (source != null && !skipEvent && shouldReportEvents) { if (!game.replaceEvent(GameEvent.getEvent(EventType.TARGET, id, source.getSourceId(), source.getControllerId()))) { targets.put(id, 0); rememberZoneChangeCounter(id, game); chosen = targets.size() >= getNumberOfTargets(); - if (!skipEvent) { + if (!skipEvent && shouldReportEvents) { game.addSimultaneousEvent(GameEvent.getEvent(EventType.TARGETED, id, source.getSourceId(), source.getControllerId())); } } @@ -251,12 +253,12 @@ public abstract class TargetImpl implements Target { if (targets.containsKey(id)) { amount += targets.get(id); } - if (source != null && !skipEvent) { + if (source != null && !skipEvent && shouldReportEvents) { if (!game.replaceEvent(GameEvent.getEvent(EventType.TARGET, id, source.getSourceId(), source.getControllerId()))) { targets.put(id, amount); rememberZoneChangeCounter(id, game); chosen = targets.size() >= getNumberOfTargets(); - if (!skipEvent) { + if (!skipEvent && shouldReportEvents) { game.fireEvent(GameEvent.getEvent(EventType.TARGETED, id, source.getSourceId(), source.getControllerId())); } } @@ -551,4 +553,9 @@ public abstract class TargetImpl implements Target { this.chooseHint = chooseHint; return this; } + + @Override + public void setEventReporting(boolean shouldReport) { + this.shouldReportEvents = shouldReport; + } } From fc46c0b288b4bff4fac3f9cc78bc5e6feb022b6a Mon Sep 17 00:00:00 2001 From: dilnu Date: Mon, 3 Feb 2020 18:01:36 -0500 Subject: [PATCH 3/4] Turn on strict mode for the test and Add documentation for the cards in the test. --- .../mage/test/cards/copy/CopySpellTest.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java index 0856e2ee7ec..e43903d8eab 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java @@ -79,20 +79,32 @@ public class CopySpellTest extends CardTestPlayerBase { @Test public void BonecrusherGiantChangeTargets() { + // 4/3 Creature + // Whenever Bonecrusher Giant becomes the target of a spell, Bonecrusher Giant deals 2 damage to that spell's + // controller. addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); + // 2/2 Creature addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + // 2/1 Creature addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); addCard(Zone.BATTLEFIELD, playerA, "Plains"); + // Target creature gets +2/+2 until end of turn. + // Conspire (As you cast this spell, you may tap two untapped creatures you control that share a color with it. + // When you do, copy it and you may choose a new target for the copy.) addCard(Zone.HAND, playerA, "Barkshell Blessing"); castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); - setChoice(playerA, "Yes"); - setChoice(playerA, "Yes"); addTarget(playerA, "Grizzly Bears"); + setChoice(playerA, "Yes"); + setChoice(playerA, "Grizzly Bears"); + setChoice(playerA, "Savannah Lions"); + setChoice(playerA, "Yes"); addTarget(playerA, "Bonecrusher Giant"); - setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_COMBAT); execute(); + assertAllCommandsUsed(); assertPowerToughness(playerA, "Bonecrusher Giant", 6, 5); assertPowerToughness(playerA, "Grizzly Bears", 4, 4); From 6d005bae1d4239501b57fee693dc614f621d77e4 Mon Sep 17 00:00:00 2001 From: dilnu Date: Thu, 6 Feb 2020 18:55:33 -0500 Subject: [PATCH 4/4] Add tests by JayDi85 and fix TestPlayer's Targetting code so it triggers Targetted Events. --- .../mage/test/cards/copy/CopySpellTest.java | 102 ++++++++++++++---- .../java/org/mage/test/player/TestPlayer.java | 14 +-- 2 files changed, 88 insertions(+), 28 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java index e43903d8eab..c780fbef4ca 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java @@ -78,38 +78,98 @@ public class CopySpellTest extends CardTestPlayerBase { } @Test - public void BonecrusherGiantChangeTargets() { - // 4/3 Creature - // Whenever Bonecrusher Giant becomes the target of a spell, Bonecrusher Giant deals 2 damage to that spell's - // controller. + public void BonecrusherGiantChangeTargets_BoneTargetBoth() { + // Whenever Bonecrusher Giant becomes the target of a spell, Bonecrusher Giant deals 2 damage to that spell’s controller. addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); - // 2/2 Creature - addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); - // 2/1 Creature - addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); - addCard(Zone.BATTLEFIELD, playerA, "Plains"); + // // Target creature gets +2/+2 until end of turn. - // Conspire (As you cast this spell, you may tap two untapped creatures you control that share a color with it. - // When you do, copy it and you may choose a new target for the copy.) + // Conspire (As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose a new target for the copy.) addCard(Zone.HAND, playerA, "Barkshell Blessing"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); - addTarget(playerA, "Grizzly Bears"); - setChoice(playerA, "Yes"); - setChoice(playerA, "Grizzly Bears"); - setChoice(playerA, "Savannah Lions"); - setChoice(playerA, "Yes"); - addTarget(playerA, "Bonecrusher Giant"); + setChoice(playerA, "Yes"); // use Conspire + addTarget(playerA, "Bonecrusher Giant"); // target bone + setChoice(playerA, "Grizzly Bears"); // pay for conspire + setChoice(playerA, "Savannah Lions"); // pay for conspire + setChoice(playerA, "When you pay"); // Put Conspire on the stack first. + setChoice(playerA, "No"); // both spells target bone setStrictChooseMode(true); - setStopAt(1, PhaseStep.END_COMBAT); + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); execute(); assertAllCommandsUsed(); - assertPowerToughness(playerA, "Bonecrusher Giant", 6, 5); - assertPowerToughness(playerA, "Grizzly Bears", 4, 4); + assertPowerToughness(playerA, "Bonecrusher Giant", 4 + 2 * 2, 3 + 2 * 2); + assertPowerToughness(playerA, "Grizzly Bears", 2, 2); assertPowerToughness(playerA, "Savannah Lions", 2, 1); - assertLife(playerA, 18); + assertLife(playerA, 20 - 2 * 2); // bone trigger from both spells + } + + @Test + public void BonecrusherGiantChangeTargets_BoneTargetFirst() { + // Whenever Bonecrusher Giant becomes the target of a spell, Bonecrusher Giant deals 2 damage to that spell’s controller. + addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); + // + // Target creature gets +2/+2 until end of turn. + // Conspire (As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose a new target for the copy.) + addCard(Zone.HAND, playerA, "Barkshell Blessing"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); + + castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); + setChoice(playerA, "Yes"); // use Conspire + addTarget(playerA, "Bonecrusher Giant"); // target bone + setChoice(playerA, "Grizzly Bears"); // pay for conspire + setChoice(playerA, "Savannah Lions"); // pay for conspire + setChoice(playerA, "When you pay"); // Put Conspire on the stack first. + setChoice(playerA, "Yes"); // new target for copy: bear + addTarget(playerA, "Grizzly Bears"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + assertAllCommandsUsed(); + + assertPowerToughness(playerA, "Bonecrusher Giant", 4 + 2, 3 + 2); + assertPowerToughness(playerA, "Grizzly Bears", 2 + 2, 2 + 2); + assertPowerToughness(playerA, "Savannah Lions", 2, 1); + assertLife(playerA, 20 - 2); // one trigger + } + + @Test + public void BonecrusherGiantChangeTargets_BoneTargetSecond() { + // Whenever Bonecrusher Giant becomes the target of a spell, Bonecrusher Giant deals 2 damage to that spell’s controller. + addCard(Zone.BATTLEFIELD, playerA, "Bonecrusher Giant"); + // + // Target creature gets +2/+2 until end of turn. + // Conspire (As you cast this spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose a new target for the copy.) + addCard(Zone.HAND, playerA, "Barkshell Blessing"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears"); + addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions"); + + castSpell(1, PhaseStep.UPKEEP, playerA, "Barkshell Blessing"); + setChoice(playerA, "Yes"); // use Conspire + addTarget(playerA, "Grizzly Bears"); // target bear + setChoice(playerA, "Grizzly Bears"); // pay for conspire + setChoice(playerA, "Savannah Lions"); // pay for conspire + setChoice(playerA, "Yes"); // new target for copy: bone + addTarget(playerA, "Bonecrusher Giant"); + // setChoice(playerA, "When {this} becomes the target of a spell"); // must be one trigger from bone, not two + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + assertAllCommandsUsed(); + + assertPowerToughness(playerA, "Bonecrusher Giant", 4 + 2, 3 + 2); + assertPowerToughness(playerA, "Grizzly Bears", 2 + 2, 2 + 2); + assertPowerToughness(playerA, "Savannah Lions", 2, 1); + assertLife(playerA, 20 - 2); // one trigger } /* 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 1c2a68c2414..f5736810ca9 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 @@ -1883,7 +1883,7 @@ public class TestPlayer implements Player { for (Player player : game.getPlayers().values()) { if (player.getName().equals(playerName) && target.canTarget(computerPlayer.getId(), player.getId(), source, game)) { - target.add(player.getId(), game); + target.addTarget(player.getId(), source, game); targets.remove(targetDefinition); return true; } @@ -1932,7 +1932,7 @@ public class TestPlayer implements Player { if (isObjectHaveTargetNameOrAlias(permanent, targetName) || (permanent.getName() + '-' + permanent.getExpansionSetCode()).equals(targetName)) { // TODO: remove exp code search? if (target.canTarget(abilityControllerId, permanent.getId(), source, game) && !target.getTargets().contains(permanent.getId())) { if ((permanent.isCopy() && !originOnly) || (!permanent.isCopy() && !copyOnly)) { - target.add(permanent.getId(), game); + target.addTarget(permanent.getId(), source, game); targetFound = true; break; // return to for (String targetName } @@ -1957,7 +1957,7 @@ public class TestPlayer implements Player { for (Card card : computerPlayer.getHand().getCards(((TargetCardInHand) target.getOriginalTarget()).getFilter(), game)) { if (isObjectHaveTargetNameOrAlias(card, targetName) || (card.getName() + '-' + card.getExpansionSetCode()).equals(targetName)) { // TODO: remove set code search? if (target.canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) { - target.add(card.getId(), game); + target.addTarget(card.getId(), source, game); targetFound = true; break; // return to for (String targetName } @@ -1982,7 +1982,7 @@ public class TestPlayer implements Player { for (Card card : game.getExile().getCards(targetFull.getFilter(), game)) { if (isObjectHaveTargetNameOrAlias(card, targetName) || (card.getName() + '-' + card.getExpansionSetCode()).equals(targetName)) { // TODO: remove set code search? if (target.canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) { - target.add(card.getId(), game); + target.addTarget(card.getId(), source, game); targetFound = true; break; // return to for (String targetName } @@ -2057,7 +2057,7 @@ public class TestPlayer implements Player { for (Card card : player.getGraveyard().getCards(targetFull.getFilter(), game)) { if (isObjectHaveTargetNameOrAlias(card, targetName) || (card.getName() + '-' + card.getExpansionSetCode()).equals(targetName)) { // TODO: remove set code search? if (target.canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) { - target.add(card.getId(), game); + target.addTarget(card.getId(), source, game); targetFound = true; break IterateGraveyards; // return to for (String targetName } @@ -2084,7 +2084,7 @@ public class TestPlayer implements Player { for (StackObject stackObject : game.getStack()) { if (isObjectHaveTargetNameOrAlias(stackObject, targetName)) { if (target.canTarget(abilityControllerId, stackObject.getId(), source, game) && !target.getTargets().contains(stackObject.getId())) { - target.add(stackObject.getId(), game); + target.addTarget(stackObject.getId(), source, game); targetFound = true; break; // return to for (String targetName } @@ -2133,7 +2133,7 @@ public class TestPlayer implements Player { for (String targetName : targetList) { for (Card card : cards.getCards(game)) { if (isObjectHaveTargetNameOrAlias(card, targetName) && !target.getTargets().contains(card.getId())) { - target.add(card.getId(), game); + target.addTarget(card.getId(), source, game); targetFound = true; break; }