diff --git a/Mage.Client/release/config/config.xml b/Mage.Client/release/config/config.xml
deleted file mode 100644
index 90e6c3ab63..0000000000
--- a/Mage.Client/release/config/config.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Mage.Sets/src/mage/sets/darkascension/GrafdiggersCage.java b/Mage.Sets/src/mage/sets/darkascension/GrafdiggersCage.java
index bb19f19a1d..34f664c788 100644
--- a/Mage.Sets/src/mage/sets/darkascension/GrafdiggersCage.java
+++ b/Mage.Sets/src/mage/sets/darkascension/GrafdiggersCage.java
@@ -35,13 +35,13 @@ import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
-import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
/**
@@ -88,19 +88,17 @@ class GrafdiggersCageEffect extends ContinuousRuleModifyingEffectImpl {
}
@Override
- public boolean apply(Game game, Ability source) {
- return true;
+ public boolean checksEventType(GameEvent event, Game game) {
+ return EventType.ZONE_CHANGE.equals(event.getType());
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- if (event instanceof ZoneChangeEvent) {
- ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- if (zEvent.getToZone() == Zone.BATTLEFIELD && (zEvent.getFromZone() == Zone.GRAVEYARD || zEvent.getFromZone() == Zone.LIBRARY)) {
- Card card = game.getCard(zEvent.getTargetId());
- if (card != null && card.getCardType().contains(CardType.CREATURE)) {
- return true;
- }
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ if (zEvent.getToZone() == Zone.BATTLEFIELD && (zEvent.getFromZone() == Zone.GRAVEYARD || zEvent.getFromZone() == Zone.LIBRARY)) {
+ Card card = game.getCard(zEvent.getTargetId());
+ if (card != null && card.getCardType().contains(CardType.CREATURE)) {
+ return true;
}
}
return false;
@@ -124,20 +122,19 @@ class GrafdiggersCageEffect2 extends ContinuousRuleModifyingEffectImpl {
return new GrafdiggersCageEffect2(this);
}
- @Override
- public boolean apply(Game game, Ability source) {
- return true;
- }
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.CAST_SPELL;
+ }
+
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- if (event.getType() == GameEvent.EventType.CAST_SPELL) {
- Card card = game.getCard(event.getSourceId());
- if (card != null) {
- Zone zone = game.getState().getZone(card.getId());
- if (zone != null && (zone == Zone.GRAVEYARD || zone == Zone.LIBRARY)) {
- return true;
- }
+ Card card = game.getCard(event.getSourceId());
+ if (card != null) {
+ Zone zone = game.getState().getZone(card.getId());
+ if (zone != null && (zone == Zone.GRAVEYARD || zone == Zone.LIBRARY)) {
+ return true;
}
}
return false;
diff --git a/Mage.Sets/src/mage/sets/returntoravnica/SphinxOfTheChimes.java b/Mage.Sets/src/mage/sets/returntoravnica/SphinxOfTheChimes.java
index 7e4bc01d44..aba60a810f 100644
--- a/Mage.Sets/src/mage/sets/returntoravnica/SphinxOfTheChimes.java
+++ b/Mage.Sets/src/mage/sets/returntoravnica/SphinxOfTheChimes.java
@@ -114,8 +114,8 @@ class TargetTwoNonLandCardsWithSameNameInHand extends TargetCardInHand {
@Override
public Set possibleTargets(UUID sourceControllerId, Game game) {
- Set newPossibleTargets = new HashSet();
- Set possibleTargets = new HashSet();
+ Set newPossibleTargets = new HashSet<>();
+ Set possibleTargets = new HashSet<>();
Player player = game.getPlayer(sourceControllerId);
for (Card card : player.getHand().getCards(filter, game)) {
possibleTargets.add(card.getId());
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/GrafdiggersCageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/GrafdiggersCageTest.java
index da1fdc81a9..e30fda6c78 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/GrafdiggersCageTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/GrafdiggersCageTest.java
@@ -12,9 +12,14 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class GrafdiggersCageTest extends CardTestPlayerBase {
@Test
- public void testCard() {
+ public void testCard1() {
+ // Creature cards can't enter the battlefield from graveyards or libraries.
+ // Players can't cast cards in graveyards or libraries.
addCard(Zone.BATTLEFIELD, playerA, "Grafdigger's Cage");
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
+
+ // Put two 1/1 white Spirit creature tokens with flying onto the battlefield.
+ // Flashback {1}{B}
addCard(Zone.GRAVEYARD, playerA, "Lingering Souls");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback {1}{B}");
@@ -28,7 +33,7 @@ public class GrafdiggersCageTest extends CardTestPlayerBase {
}
@Test
- public void testCard1() {
+ public void testCard2() {
addCard(Zone.BATTLEFIELD, playerA, "Grafdigger's Cage");
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
addCard(Zone.HAND, playerA, "Rise from the Grave", 1);
@@ -44,5 +49,34 @@ public class GrafdiggersCageTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Craw Wurm", 1);
assertGraveyardCount(playerA, "Rise from the Grave", 1);
}
+
+ /**
+ * With a Grafdigger's Cage in play you can still announce Cabal Therapy and pay it's flashback cost - resulting
+ * in a sacrificed creature (and any triggers along with that) and a Cabal Therapy still in the graveyard.
+ *
+ * Don't get me wrong, I love sacrificing 2-3 Veteran Explorer to the same Cabal Therapy, but it's just not all that fair.
+ *
+ * Same thing goes for cards like Ethersworn Canonist, assuming that the flashback isn't the first non-artifact spell for the turn.
+ */
+ @Test
+ public void testCard3() {
+ // Creature cards can't enter the battlefield from graveyards or libraries.
+ // Players can't cast cards in graveyards or libraries.
+ addCard(Zone.BATTLEFIELD, playerA, "Grafdigger's Cage");
+ addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 2);
+
+ // Name a nonland card. Target player reveals his or her hand and discards all cards with that name.
+ // Flashback-Sacrifice a creature. (You may cast this card from your graveyard for its flashback cost. Then exile it.)
+ addCard(Zone.GRAVEYARD, playerA, "Cabal Therapy");
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback");
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ assertPermanentCount(playerA, "Silvercoat Lion", 2);
+ assertGraveyardCount(playerA, "Cabal Therapy", 1);
+ }
+
}
diff --git a/Mage/src/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveControllerEffect.java b/Mage/src/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveControllerEffect.java
index 0b82869926..94836d9094 100644
--- a/Mage/src/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveControllerEffect.java
+++ b/Mage/src/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveControllerEffect.java
@@ -31,7 +31,6 @@ package mage.abilities.effects.common;
import mage.constants.Outcome;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;