diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/HarvesterOfSoulsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/HarvesterOfSoulsTest.java index 7f1e00812f1..783f04b37c8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/HarvesterOfSoulsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/HarvesterOfSoulsTest.java @@ -24,9 +24,12 @@ public class HarvesterOfSoulsTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Day of Judgment", 1); addCard(Zone.HAND, playerA, "Thatcher Revolt", 1); + // Creature - Demon 5/5 {4}{B}{B} + // Deathtouch // Whenever another nontoken creature dies, you may draw a card. addCard(Zone.BATTLEFIELD, playerA, "Harvester of Souls", 1); + // Creature - Wurm 6/4 {4}{G}{G} addCard(Zone.BATTLEFIELD, playerA, "Craw Wurm", 1); // Whenever Arrogant Bloodlord blocks or becomes blocked by a creature with power 1 or less, destroy Arrogant Bloodlord at end of combat. addCard(Zone.BATTLEFIELD, playerB, "Arrogant Bloodlord", 1); @@ -42,7 +45,7 @@ public class HarvesterOfSoulsTest extends CardTestPlayerBase { assertLife(playerA, 20); assertLife(playerB, 20); - assertHandCount(playerA, 2); + assertHandCount(playerA, 2); // draw a card for Harvester and Craw Wurm assertHandCount(playerB, 0); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/state/SynodCenturionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/state/SynodCenturionTest.java index fee51299c4c..27043288f72 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/state/SynodCenturionTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/state/SynodCenturionTest.java @@ -7,7 +7,6 @@ package org.mage.test.cards.triggers.state; import mage.constants.PhaseStep; import mage.constants.Zone; -import mage.counters.CounterType; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -51,6 +50,7 @@ public class SynodCenturionTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Plains", 6); addCard(Zone.BATTLEFIELD, playerA, "Bottle Gnomes"); addCard(Zone.HAND, playerA, "Cloudshift"); + // When you control no other artifacts, sacrifice Synod Centurion. addCard(Zone.HAND, playerA, "Synod Centurion"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Synod Centurion"); 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 22a6c90582c..67d85968b81 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 @@ -387,15 +387,22 @@ public class TestPlayer extends ComputerPlayer { String[] targetList = targetDefinition.split("\\^"); boolean targetFound = false; for (String targetName: targetList) { - boolean allowCopy = true; - if (targetName.endsWith("[no copy]")) { - allowCopy = false; - targetName = targetName.substring(0, targetName.length()-9); + 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 (Permanent permanent : game.getBattlefield().getAllActivePermanents((FilterPermanent)target.getFilter(), game)) { if (permanent.getName().equals(targetName) || (permanent.getName()+"-"+permanent.getExpansionSetCode()).equals(targetName)) { if (((TargetPermanent)target).canTarget(source == null ? this.getId(): source.getControllerId(), permanent.getId(), source, game) && !target.getTargets().contains(permanent.getId())) { - if (!permanent.isCopy() || allowCopy) { + if ((permanent.isCopy() && !originOnly) || (!permanent.isCopy() && !copyOnly )) { target.add(permanent.getId(), game); targetFound = true; break; 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 8c19c2b95a9..5f0ae2f5ea5 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 @@ -861,7 +861,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement * e.g. "creatureName1^creatureName2" * you can qualify the target additional by setcode * e.g. "creatureName-M15" - * you can add [no copy] to prohibite targets that are copied + * you can add [no copy] to the end of the target name to prohibite targets that are copied + * you can add [only copy] to the end of the target name to allow only targets that are copies */ public void addTarget(TestPlayer player, String target) { player.addTarget(target); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 1c3275e7e2d..b679d5acc35 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1207,7 +1207,6 @@ public abstract class GameImpl implements Game, Serializable { if (!getTurn().isEndTurnRequested()) { while (state.hasSimultaneousEvents()) { state.handleSimultaneousEvent(this); - checkTriggered(); } } } @@ -1356,6 +1355,15 @@ public abstract class GameImpl implements Game, Serializable { state.addDelayedTriggeredAbility(newAbility); } + /** + * 116.5. Each time a player would get priority, the game first performs all applicable state-based actions as a single event (see rule 704, + * “State-Based Actions”), then repeats this process until no state-based actions are performed. Then triggered abilities are put on the stack + * (see rule 603, “Handling Triggered Abilities”). These steps repeat in order until no further state-based actions are performed and no abilities + * trigger. Then the player who would have received priority does so. + * + * @return + */ + @Override public boolean checkStateAndTriggered() { boolean trigger = !getTurn().isEndTurnRequested(); @@ -1419,6 +1427,13 @@ public abstract class GameImpl implements Game, Serializable { return played; } + /** + * 116.5. Each time a player would get priority, the game first performs all applicable state-based actions as a single event (see rule 704, + * “State-Based Actions”), then repeats this process until no state-based actions are performed. Then triggered abilities are put on the stack + * (see rule 603, “Handling Triggered Abilities”). These steps repeat in order until no further state-based actions are performed and no abilities + * trigger. Then the player who would have received priority does so. + * @return + */ protected boolean checkStateBasedActions() { boolean somethingHappened = false; diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 18de6258c90..438a26ded31 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -240,7 +240,6 @@ public class Spell implements StackObject, Card { card.getCardType().add(CardType.CREATURE); card.getSubtype().remove("Aura"); } - game.getState().handleSimultaneousEvent(game); return ability.resolve(game); } if (bestow) {