diff --git a/Mage.Sets/src/mage/sets/magic2010/Silence.java b/Mage.Sets/src/mage/sets/magic2010/Silence.java
index 4e406fbe936..4637cd9f97e 100644
--- a/Mage.Sets/src/mage/sets/magic2010/Silence.java
+++ b/Mage.Sets/src/mage/sets/magic2010/Silence.java
@@ -51,6 +51,7 @@ public class Silence extends CardImpl {
super(ownerId, 31, "Silence", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{W}");
this.expansionSetCode = "M10";
+ // Your opponents can't cast spells this turn. (Spells cast before this resolves are unaffected.)
this.getSpellAbility().addEffect(new SilenceEffect());
}
@@ -68,7 +69,7 @@ class SilenceEffect extends ContinuousRuleModifyingEffectImpl {
public SilenceEffect() {
super(Duration.EndOfTurn, Outcome.Benefit);
- staticText = "Your opponents can't cast spells this turn";
+ staticText = "Your opponents can't cast spells this turn. (Spells cast before this resolves are unaffected.)";
}
public SilenceEffect(final SilenceEffect effect) {
@@ -94,12 +95,14 @@ class SilenceEffect extends ContinuousRuleModifyingEffectImpl {
return null;
}
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == EventType.CAST_SPELL;
+ }
+
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
- if (event.getType() == EventType.CAST_SPELL && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
- return true;
- }
- return false;
+ return game.getOpponents(source.getControllerId()).contains(event.getPlayerId());
}
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SilenceTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SilenceTest.java
new file mode 100644
index 00000000000..80b18593084
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SilenceTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package org.mage.test.cards.continuous;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class SilenceTest extends CardTestPlayerBase {
+
+ @Test
+ public void testSilence() {
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
+ addCard(Zone.HAND, playerA, "Silence");
+
+ addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
+ addCard(Zone.HAND, playerB, "Silvercoat Lion", 1);
+
+ castSpell(2, PhaseStep.UPKEEP, playerA, "Silence");
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Silvercoat Lion");
+ setStopAt(2, PhaseStep.BEGIN_COMBAT);
+
+ execute();
+
+ assertGraveyardCount(playerA, "Silence", 1);
+
+ assertHandCount(playerB, "Silvercoat Lion", 1);
+ assertPermanentCount(playerB, "Silvercoat Lion", 0);
+ }
+
+}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java
index a5b1a67587b..71506a20563 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/IsochronScepterTest.java
@@ -142,4 +142,39 @@ public class IsochronScepterTest extends CardTestPlayerBase {
assertLife(playerB, 20);
}
+
+ /**
+ * Resolving a Silence cast from exile via Isochron Scepter during my opponent's upkeep does
+ * not prevent that opponent from casting spells that turn.
+ *
+ */
+
+ @Test
+ public void testSilence() {
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
+ addCard(Zone.HAND, playerA, "Isochron Scepter");
+ addCard(Zone.HAND, playerA, "Silence");
+
+ addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
+ addCard(Zone.HAND, playerB, "Silvercoat Lion", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Isochron Scepter");
+ addTarget(playerA, "Silence");
+
+ activateAbility(2, PhaseStep.UPKEEP, playerA, "{2},{T}:");
+ setChoice(playerA, "Yes");
+ setChoice(playerA, "Yes");
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Silvercoat Lion");
+
+ setStopAt(2, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPermanentCount(playerA, "Isochron Scepter", 1);
+ assertExileCount("Silence", 1);
+
+ assertHandCount(playerB, "Silvercoat Lion", 1);
+ assertPermanentCount(playerB, "Silvercoat Lion", 0);
+
+ }
}
diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java
index 0f76f9b5724..561f1facc32 100644
--- a/Mage/src/mage/abilities/effects/ContinuousEffects.java
+++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java
@@ -390,7 +390,16 @@ public class ContinuousEffects implements Serializable {
}
private boolean checkAbilityStillExists(Ability ability, ContinuousEffect effect, GameEvent event, Game game) {
- if (effect.getDuration().equals(Duration.OneUse) || effect.getDuration().equals(Duration.Custom) || ability.getSourceId() == null) { // needed for some special replacment effects (e.g. Undying) or commander replacement effect
+ switch(effect.getDuration()) { // effects with fixed duration don't need an object with the source ability (e.g. a silence cast with isochronic Scepter has no more a card object
+ case EndOfCombat:
+ case EndOfGame:
+ case EndOfStep:
+ case EndOfTurn:
+ case OneUse:
+ case Custom: // custom duration means the effect ends itself if needed
+ return true;
+ }
+ if (ability.getSourceId() == null) { // commander replacement effect
return true;
}
MageObject object;
diff --git a/Mage/src/mage/game/GameState.java b/Mage/src/mage/game/GameState.java
index 332ead3e168..8e82a48f4ff 100644
--- a/Mage/src/mage/game/GameState.java
+++ b/Mage/src/mage/game/GameState.java
@@ -840,6 +840,7 @@ public class GameState implements Serializable, Copyable {
values.clear();
zones.clear();
simultaneousEvents.clear();
+ copiedCards.clear();
permanentOrderNumber = 0;
}