diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java index 9e546689c8b..6b7c74587a8 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java @@ -45,8 +45,11 @@ public final class CardImageUtils { pathCache.put(card, filePath); return filePath; } + + log.warn("Token image file not found. Set: " + card.getSet() + " Token Set Code: " + card.getTokenSetCode() + " Name: " + card.getName() + " File path: " + filePath); + } else { + log.warn("Trying to get token path for non token card. Set: " + card.getSet() + " Set Code: " + card.getTokenSetCode() + " Name: " + card.getName()); } - log.warn("Token image file not found: " + card.getSet() + " - " + card.getTokenSetCode() + " - " + card.getName()); return null; } diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java index 5d599003ab1..818cb7c3c68 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java @@ -430,7 +430,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ { } stackObject.resolve(game); if (stackObject instanceof StackAbility) { - game.getStack().remove(stackObject); + game.getStack().remove(stackObject, game); } game.applyEffects(); game.getPlayers().resetPassed(); @@ -968,7 +968,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ { // swallow e.printStackTrace(); } finally { - if(scanner != null) { + if (scanner != null) { scanner.close(); } } diff --git a/Mage.Sets/src/mage/cards/n/NorinTheWary.java b/Mage.Sets/src/mage/cards/n/NorinTheWary.java index ae1b4096d65..137003d4635 100644 --- a/Mage.Sets/src/mage/cards/n/NorinTheWary.java +++ b/Mage.Sets/src/mage/cards/n/NorinTheWary.java @@ -48,7 +48,7 @@ import mage.game.events.GameEvent.EventType; public class NorinTheWary extends CardImpl { public NorinTheWary(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WARRIOR); @@ -94,7 +94,7 @@ class NorinTheWaryTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return new StringBuilder("When a player casts a spell or a creature attacks, ").append(super.getRule()).toString(); + return "When a player casts a spell or a creature attacks, " + super.getRule(); } @Override diff --git a/Mage.Sets/src/mage/cards/u/UndeadLeotau.java b/Mage.Sets/src/mage/cards/u/UndeadLeotau.java index eca1df7fb9d..869e786d9f7 100644 --- a/Mage.Sets/src/mage/cards/u/UndeadLeotau.java +++ b/Mage.Sets/src/mage/cards/u/UndeadLeotau.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.u; import java.util.UUID; @@ -37,8 +36,8 @@ import mage.abilities.keyword.UnearthAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; /** @@ -47,21 +46,22 @@ import mage.constants.Zone; */ public class UndeadLeotau extends CardImpl { - public UndeadLeotau (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}"); + public UndeadLeotau(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}"); this.subtype.add(SubType.ZOMBIE); this.subtype.add(SubType.CAT); this.power = new MageInt(3); this.toughness = new MageInt(4); - + // {R}: Undead Leotau gets +1/-1 until end of turn. - // Unearth {2}{B} this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(+1, -1, Duration.EndOfTurn), new ManaCostsImpl("{R}"))); + + // Unearth {2}{B} this.addAbility(new UnearthAbility(new ManaCostsImpl("{2}{B}"))); } - public UndeadLeotau (final UndeadLeotau card) { + public UndeadLeotau(final UndeadLeotau card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/v/VoiceOfAll.java b/Mage.Sets/src/mage/cards/v/VoiceOfAll.java index 9dd44dcb4bf..0574407e6da 100644 --- a/Mage.Sets/src/mage/cards/v/VoiceOfAll.java +++ b/Mage.Sets/src/mage/cards/v/VoiceOfAll.java @@ -37,8 +37,8 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; /** @@ -48,17 +48,18 @@ import mage.constants.Zone; public class VoiceOfAll extends CardImpl { public VoiceOfAll(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.subtype.add(SubType.ANGEL); this.power = new MageInt(2); this.toughness = new MageInt(2); // Flying this.addAbility(FlyingAbility.getInstance()); - + // As Voice of All enters the battlefield, choose a color. this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Benefit))); - + + // Voice of All has protection from the chosen color. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ProtectionChosenColorSourceEffect())); } @@ -70,4 +71,4 @@ public class VoiceOfAll extends CardImpl { public VoiceOfAll copy() { return new VoiceOfAll(this); } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java index 628e9b71530..3953a7bec09 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/PhantasmalImageTest.java @@ -6,14 +6,11 @@ import mage.constants.PhaseStep; import mage.constants.Zone; import mage.game.permanent.Permanent; import org.junit.Assert; - -import org.junit.Test; -import org.mage.test.serverside.base.CardTestPlayerBase; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import org.junit.Ignore; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; /** * @author noxx @@ -179,6 +176,9 @@ public class PhantasmalImageTest extends CardTestPlayerBase { @Test public void testCopyEntersTapped() { addCard(Zone.BATTLEFIELD, playerA, "Island", 2); + // You may have Phantasmal Image enter the battlefield as a copy of any creature + // on the battlefield, except it's an Illusion in addition to its other types and + // it gains "When this creature becomes the target of a spell or ability, sacrifice it." addCard(Zone.HAND, playerA, "Phantasmal Image"); addCard(Zone.BATTLEFIELD, playerB, "Geralf's Messenger"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/redirect/HarmsWayRedirectDamageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/redirect/HarmsWayRedirectDamageTest.java index d7cd0eab5b9..6114dd3cf37 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/redirect/HarmsWayRedirectDamageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/redirect/HarmsWayRedirectDamageTest.java @@ -7,8 +7,7 @@ import org.mage.test.serverside.base.CardTestPlayerBase; /** * Harm's Way: The next 2 damage that a source of your choice would deal to you - * and/or permanents you control this turn is dealt to any target - * instead. + * and/or permanents you control this turn is dealt to any target instead. * * @author noxx */ @@ -23,7 +22,7 @@ public class HarmsWayRedirectDamageTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Lightning Bolt"); addCard(Zone.BATTLEFIELD, playerA, "Mountain"); - addCard(Zone.HAND, playerB, "Harm's Way"); + addCard(Zone.HAND, playerB, "Harm's Way"); // Instant {W} addCard(Zone.BATTLEFIELD, playerB, "Plains"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB); @@ -33,6 +32,9 @@ public class HarmsWayRedirectDamageTest extends CardTestPlayerBase { setStopAt(1, PhaseStep.END_TURN); execute(); + assertGraveyardCount(playerA, "Lightning Bolt", 1); + assertGraveyardCount(playerB, "Harm's Way", 1); + // 2 damage was redirected back assertLife(playerA, 18); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/BrutalExpulsionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/BrutalExpulsionTest.java index 1fa4024618e..37abafb2386 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/BrutalExpulsionTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/BrutalExpulsionTest.java @@ -29,7 +29,6 @@ package org.mage.test.cards.single.bfz; import mage.constants.PhaseStep; import mage.constants.Zone; -import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 4f3ae196a25..94694570623 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -157,6 +157,8 @@ public abstract class AbilityImpl implements Ability { public void newId() { if (!(this instanceof MageSingleton)) { this.id = UUID.randomUUID(); +// this.sourceObject = null; +// this.sourceObjectZoneChangeCounter = -1; } getEffects().newId(); } @@ -1211,7 +1213,7 @@ public abstract class AbilityImpl implements Ability { @Override public Permanent getSourcePermanentIfItStillExists(Game game) { - if (sourceObject == null) { + if (sourceObject == null || !sourceObject.getId().equals(getSourceId())) { setSourceObject(game.getObject(getSourceId()), game); } if (sourceObject instanceof Permanent) { diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java index 5f692b1a264..f1ef74cdc04 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java @@ -63,7 +63,7 @@ public class ExileFromStackCost extends CostImpl { } String spellName = spellToExile.getName(); if (spellToExile.isCopy()) { - game.getStack().remove(spellToExile); + game.getStack().remove(spellToExile, game); } else { spellToExile.moveToExile(null, "", ability.getSourceId(), game); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java index f1b8a2238f6..2ec9169c65f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeRegeneratedSourceEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common; +import java.util.Objects; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; @@ -36,8 +37,6 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import java.util.Objects; - /** * * @author jeffwadsworth @@ -67,6 +66,17 @@ public class CantBeRegeneratedSourceEffect extends ContinuousRuleModifyingEffect return event.getType() == EventType.REGENERATE; } + @Override + public void init(Ability source, Game game) { + super.init(source, game); //To change body of generated methods, choose Tools | Templates. + if (duration.isOnlyValidIfNoZoneChange()) { + // If source permanent is no longer onto battlefield discard the effect + if (source.getSourcePermanentIfItStillExists(game) == null) { + discard(); + } + } + } + @Override public boolean applies(GameEvent event, Ability source, Game game) { return Objects.equals(source.getSourceId(), event.getTargetId()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/DestroySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DestroySourceEffect.java index d3bae2ecd35..f3a62ed2319 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DestroySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DestroySourceEffect.java @@ -63,7 +63,7 @@ public class DestroySourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = source.getSourcePermanentIfItStillExists(game); if (permanent != null) { permanent.destroy(source.getSourceId(), game, noRegen); return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/FightTargetSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FightTargetSourceEffect.java index a97b997d289..1f78bbbe680 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/FightTargetSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/FightTargetSourceEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; @@ -50,21 +51,19 @@ public class FightTargetSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent originalPermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (originalPermanent != null) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - // only if target is legal the effect will be applied - if (source.getTargets().get(0).isLegal(source, game)) { - Permanent creature1 = game.getPermanent(source.getTargets().get(0).getFirstTarget()); - // 20110930 - 701.10 - if (creature1 != null && sourcePermanent != null) { - if (creature1.isCreature() && sourcePermanent.isCreature()) { - return sourcePermanent.fight(creature1, source, game); - } + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null) { + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + Permanent creature1 = game.getPermanent(getTargetPointer().getFirst(game, source)); + // 20110930 - 701.10 + if (creature1 != null && sourcePermanent != null) { + if (creature1.isCreature() && sourcePermanent.isCreature()) { + return sourcePermanent.fight(creature1, source, game); } } - if (!game.isSimulation()) - game.informPlayers(originalPermanent.getLogName() + ": Fighting effect has been fizzled."); + if (!game.isSimulation()) { + game.informPlayers(sourceObject.getLogName() + ": Fighting effect has been fizzled."); + } } return false; } @@ -83,4 +82,3 @@ public class FightTargetSourceEffect extends OneShotEffect { } } - diff --git a/Mage/src/main/java/mage/abilities/effects/common/FlipSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FlipSourceEffect.java index aaa46793726..697a83b2a96 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/FlipSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/FlipSourceEffect.java @@ -8,11 +8,9 @@ import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.Token; import mage.players.Player; - /** * @author Loki */ @@ -33,14 +31,15 @@ public class FlipSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = source.getSourcePermanentIfItStillExists(game); Player controller = game.getPlayer(source.getControllerId()); if (permanent != null && controller != null) { if (permanent.flip(game)) { ContinuousEffect effect = new ConditionalContinuousEffect(new CopyTokenEffect(flipToken), FlippedCondition.instance, ""); game.addEffect(effect, source); - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(new StringBuilder(controller.getLogName()).append(" flips ").append(permanent.getName()).toString()); + } return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PhaseOutSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PhaseOutSourceEffect.java index 1df8ff9ff37..3672fd66b1e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PhaseOutSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PhaseOutSourceEffect.java @@ -5,7 +5,6 @@ */ package mage.abilities.effects.common; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; @@ -34,9 +33,8 @@ public class PhaseOutSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - MageObject sourceObject = source.getSourceObjectIfItStillExists(game); - if (sourceObject instanceof Permanent) { - Permanent permanent = (Permanent) sourceObject; + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (permanent != null) { return permanent.phaseOut(game); } return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java index c1f0ade0747..eab8e27cfdf 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToSourceEffect.java @@ -54,6 +54,17 @@ public class PreventDamageToSourceEffect extends PreventionEffectImpl { return new PreventDamageToSourceEffect(this); } + @Override + public void init(Ability source, Game game) { + super.init(source, game); //To change body of generated methods, choose Tools | Templates. + if (duration.isOnlyValidIfNoZoneChange()) { + // If source permanent is no longer onto battlefield discard the effect + if (source.getSourcePermanentIfItStillExists(game) == null) { + discard(); + } + } + } + @Override public boolean apply(Game game, Ability source) { return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java index 6ba78d9a7ba..327233b1b8e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java @@ -28,12 +28,18 @@ package mage.abilities.effects.common; import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HasteAbility; import mage.cards.Card; +import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.targetpointer.FixedTarget; /** * @@ -43,21 +49,25 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect private boolean tapped; private boolean ownerControl; + private boolean haste; public ReturnSourceFromGraveyardToBattlefieldEffect() { this(false); } public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped) { - super(Outcome.PutCreatureInPlay); - this.tapped = tapped; - setText(); + this(tapped, true); } public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped, boolean ownerControl) { + this(tapped, ownerControl, false); + } + + public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped, boolean ownerControl, boolean haste) { super(Outcome.PutCreatureInPlay); this.tapped = tapped; this.ownerControl = ownerControl; + this.haste = haste; setText(); } @@ -65,6 +75,7 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect super(effect); this.tapped = effect.tapped; this.ownerControl = effect.ownerControl; + this.haste = effect.haste; } @Override @@ -89,6 +100,14 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect } if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null); + if (haste) { + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + } + } } return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderOwnerControlSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderOwnerControlSourceEffect.java index 1f5b793fafc..ea3939f1b91 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderOwnerControlSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderOwnerControlSourceEffect.java @@ -33,6 +33,7 @@ import mage.cards.Card; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; +import mage.players.Player; /** * @@ -81,16 +82,17 @@ public class ReturnToBattlefieldUnderOwnerControlSourceEffect extends OneShotEff @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); Card card = game.getCard(source.getSourceId()); - if (card != null) { + if (controller != null && card != null) { // return only from public zones switch (game.getState().getZone(card.getId())) { case EXILED: case COMMAND: case GRAVEYARD: if (zoneChangeCounter < 0 || game.getState().getZoneChangeCounter(card.getId()) == zoneChangeCounter) { - Zone currentZone = game.getState().getZone(card.getId()); - if (card.putOntoBattlefield(game, currentZone, source.getSourceId(), card.getOwnerId(), tapped)) { + + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null)) { if (attacking) { game.getCombat().addAttackingCreature(card.getId(), game); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java index ad80dffa498..94117fc3eb4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java @@ -103,7 +103,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect { } } for (UUID copyId : copyIds) { - game.getStack().remove(game.getSpell(copyId)); + game.getStack().remove(game.getSpell(copyId), game); } return controller.moveCards(cards, Zone.HAND, source, game); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/TapSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/TapSourceEffect.java index e510ae4844c..10b26d0099c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/TapSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/TapSourceEffect.java @@ -63,10 +63,7 @@ public class TapSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - permanent = game.getPermanentEntering(source.getSourceId()); - } + Permanent permanent = source.getSourcePermanentIfItStillExists(game); if (permanent != null) { if (withoutTrigger) { permanent.setTapped(true); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java index 4e871839bbb..c9245e98340 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java @@ -92,6 +92,13 @@ public class GainAbilitySourceEffect extends ContinuousEffectImpl implements Sou @Override public void init(Ability source, Game game) { super.init(source, game); + if (!onCard && Duration.WhileOnBattlefield != duration) { + // If source permanent is no longer onto battlefield discard the effect + if (source.getSourcePermanentIfItStillExists(game) == null) { + discard(); + return; + } + } if (affectedObjectsSet) { Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilitySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilitySourceEffect.java index bbb09b1281d..6f5d03f33b2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilitySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilitySourceEffect.java @@ -12,38 +12,50 @@ import mage.constants.Outcome; import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; + /** * * @author Noahsark */ -public class LoseAbilitySourceEffect extends ContinuousEffectImpl{ +public class LoseAbilitySourceEffect extends ContinuousEffectImpl { protected Ability ability; - public LoseAbilitySourceEffect(Ability ability){ + public LoseAbilitySourceEffect(Ability ability) { this(ability, Duration.WhileOnBattlefield); } - public LoseAbilitySourceEffect(Ability ability, Duration duration){ + public LoseAbilitySourceEffect(Ability ability, Duration duration) { super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.LoseAbility); this.ability = ability; staticText = "{this} loses " + ability.getRule() + ' ' + duration.toString(); } - public LoseAbilitySourceEffect(final LoseAbilitySourceEffect effect){ + public LoseAbilitySourceEffect(final LoseAbilitySourceEffect effect) { super(effect); this.ability = effect.ability.copy(); } @Override - public LoseAbilitySourceEffect copy(){ + public LoseAbilitySourceEffect copy() { return new LoseAbilitySourceEffect(this); } @Override - public boolean apply(Game game, Ability source){ + public void init(Ability source, Game game) { + super.init(source, game); //To change body of generated methods, choose Tools | Templates. + if (duration.isOnlyValidIfNoZoneChange()) { + // If source permanent is no longer onto battlefield discard the effect + if (source.getSourcePermanentIfItStillExists(game) == null) { + discard(); + } + } + } + + @Override + public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null){ + if (permanent != null) { // 112.10 while (permanent.getAbilities().remove(ability)) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java index c1170ddc95d..af89fd318e1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseCreatureTypeSourceEffect.java @@ -69,6 +69,17 @@ public class LoseCreatureTypeSourceEffect extends ContinuousEffectImpl implement return new LoseCreatureTypeSourceEffect(this); } + @Override + public void init(Ability source, Game game) { + super.init(source, game); //To change body of generated methods, choose Tools | Templates. + if (duration.isOnlyValidIfNoZoneChange()) { + // If source permanent is no longer onto battlefield discard the effect + if (source.getSourcePermanentIfItStillExists(game) == null) { + discard(); + } + } + } + @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { if (dynamicValue.calculate(game, source, this) >= lessThan) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessSourceEffect.java index a13e3178d6b..adcd4b7dfba 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessSourceEffect.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,19 +20,19 @@ * 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 mage.abilities.effects.common.continuous; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffectImpl; import mage.game.Game; import mage.game.permanent.Permanent; @@ -55,14 +55,29 @@ public class SwitchPowerToughnessSourceEffect extends ContinuousEffectImpl { return new SwitchPowerToughnessSourceEffect(this); } + @Override + public void init(Ability source, Game game) { + super.init(source, game); //To change body of generated methods, choose Tools | Templates. + if (duration.isOnlyValidIfNoZoneChange()) { + // If source permanent is no longer onto battlefield discard the effect + if (source.getSourcePermanentIfItStillExists(game) == null) { + discard(); + } + } + } + @Override public boolean apply(Game game, Ability source) { - Permanent target = game.getPermanent(source.getSourceId()); - if (target != null) { - int power = target.getPower().getValue(); - target.getPower().setValue(target.getToughness().getValue()); - target.getToughness().setValue(power); + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + if (sourcePermanent != null) { + int power = sourcePermanent.getPower().getValue(); + sourcePermanent.getPower().setValue(sourcePermanent.getToughness().getValue()); + sourcePermanent.getToughness().setValue(power); return true; + } else { + if (duration.isOnlyValidIfNoZoneChange()) { + discard(); + } } return false; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveAllCountersSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveAllCountersSourceEffect.java index 10b24748f45..3697e18b01c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveAllCountersSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveAllCountersSourceEffect.java @@ -39,7 +39,7 @@ import mage.game.permanent.Permanent; * @author TheElk801 */ public class RemoveAllCountersSourceEffect extends OneShotEffect { - + private final CounterType counterType; public RemoveAllCountersSourceEffect(CounterType counterType) { @@ -55,13 +55,13 @@ public class RemoveAllCountersSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if(permanent != null) { - int count = permanent.getCounters(game).getCount(counterType); - permanent.removeCounters(counterType.getName(), count, game); - return true; - } - return false; + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (permanent != null) { + int count = permanent.getCounters(game).getCount(counterType); + permanent.removeCounters(counterType.getName(), count, game); + return true; + } + return false; } @Override diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCounterSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCounterSourceEffect.java index 2e4feb8c523..35fa7df1f58 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCounterSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCounterSourceEffect.java @@ -56,7 +56,7 @@ public class RemoveCounterSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = source.getSourcePermanentIfItStillExists(game); if (permanent != null) { int toRemove = Math.min(counter.getCount(), permanent.getCounters(game).getCount(counter.getName())); if (toRemove > 0) { @@ -67,18 +67,20 @@ public class RemoveCounterSourceEffect extends OneShotEffect { } return true; } - Card card = game.getCard(source.getSourceId()); - if (card != null) { - int toRemove = Math.min(counter.getCount(), card.getCounters(game).getCount(counter.getName())); - if (toRemove > 0) { - card.removeCounters(counter.getName(), toRemove, game); - if (!game.isSimulation()) { - game.informPlayers("Removed " + toRemove + ' ' + counter.getName() - + " counter from " + card.getLogName() - + " (" + card.getCounters(game).getCount(counter.getName()) + " left)"); + if (!(source.getSourceObject(game) instanceof Permanent)) { + Card card = game.getCard(source.getSourceId()); + if (card != null) { + int toRemove = Math.min(counter.getCount(), card.getCounters(game).getCount(counter.getName())); + if (toRemove > 0) { + card.removeCounters(counter.getName(), toRemove, game); + if (!game.isSimulation()) { + game.informPlayers("Removed " + toRemove + ' ' + counter.getName() + + " counter from " + card.getLogName() + + " (" + card.getCounters(game).getCount(counter.getName()) + " left)"); + } } + return true; } - return true; } return false; } diff --git a/Mage/src/main/java/mage/abilities/keyword/UnearthAbility.java b/Mage/src/main/java/mage/abilities/keyword/UnearthAbility.java index 239706abad4..b43eb548597 100644 --- a/Mage/src/main/java/mage/abilities/keyword/UnearthAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/UnearthAbility.java @@ -35,7 +35,6 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileSourceEffect; import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.TimingRule; @@ -63,9 +62,8 @@ import mage.game.events.ZoneChangeEvent; public class UnearthAbility extends ActivatedAbilityImpl { public UnearthAbility(ManaCosts costs) { - super(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(), costs); + super(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(false, true, true), costs); this.timing = TimingRule.SORCERY; - this.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom)); this.addEffect(new CreateDelayedTriggeredAbilityEffect(new UnearthDelayedTriggeredAbility())); this.addEffect(new UnearthLeavesBattlefieldEffect()); } diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java index db7017c9ea2..57c4c9427d6 100644 --- a/Mage/src/main/java/mage/cards/CardImpl.java +++ b/Mage/src/main/java/mage/cards/CardImpl.java @@ -55,6 +55,7 @@ import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.filter.predicate.mageobject.NamePredicate; import mage.filter.predicate.mageobject.PowerPredicate; import mage.game.*; +import mage.game.command.CommandObject; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; @@ -618,14 +619,18 @@ public abstract class CardImpl extends MageObjectImpl implements Card { stackObject = game.getStack().getSpell(getId()); } if (stackObject != null) { - removed = game.getStack().remove(stackObject); + removed = game.getStack().remove(stackObject, game); lkiObject = stackObject; } break; case COMMAND: - lkiObject = game.getObject(objectId); + for (CommandObject commandObject : game.getState().getCommand()) { + if (commandObject.getId().equals(objectId)) { + lkiObject = commandObject; + } + } if (lkiObject != null) { - removed = game.getState().getCommand().remove(game.getObject(objectId)); + removed = game.getState().getCommand().remove((CommandObject) lkiObject); } break; case OUTSIDE: diff --git a/Mage/src/main/java/mage/constants/Duration.java b/Mage/src/main/java/mage/constants/Duration.java index c2d827c989b..e23951b8e12 100644 --- a/Mage/src/main/java/mage/constants/Duration.java +++ b/Mage/src/main/java/mage/constants/Duration.java @@ -5,21 +5,23 @@ package mage.constants; * @author North */ public enum Duration { - OneUse(""), - EndOfGame("for the rest of the game"), - WhileOnBattlefield(""), - WhileOnStack(""), - WhileInGraveyard(""), - EndOfTurn("until end of turn"), - UntilYourNextTurn("until your next turn"), - EndOfCombat("until end of combat"), - EndOfStep("until end of phase step"), - Custom(""); + OneUse("", true), + EndOfGame("for the rest of the game", false), + WhileOnBattlefield("", false), + WhileOnStack("", false), + WhileInGraveyard("", false), + EndOfTurn("until end of turn", true), + UntilYourNextTurn("until your next turn", true), + EndOfCombat("until end of combat", true), + EndOfStep("until end of phase step", true), + Custom("", true); private final String text; + private final boolean onlyValidIfNoZoneChange; // defines if an effect lasts only if the source has not chnaged zone since init of the effect - Duration(String text) { + Duration(String text, boolean onlyValidIfNoZoneChange) { this.text = text; + this.onlyValidIfNoZoneChange = onlyValidIfNoZoneChange; } @Override @@ -27,4 +29,8 @@ public enum Duration { return text; } + public boolean isOnlyValidIfNoZoneChange() { + return onlyValidIfNoZoneChange; + } + } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 0149ae16909..98730a7dc58 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -328,12 +328,15 @@ public abstract class GameImpl implements Game, Serializable { MageObject object; if (state.getBattlefield().containsPermanent(objectId)) { object = state.getBattlefield().getPermanent(objectId); - state.setZone(objectId, Zone.BATTLEFIELD); // why is this neccessary? + // state.setZone(objectId, Zone.BATTLEFIELD); // why is this neccessary? return object; } + if (getPermanentsEntering().containsKey(objectId)) { + return getPermanentEntering(objectId); + } for (StackObject item : state.getStack()) { if (item.getId().equals(objectId)) { - state.setZone(objectId, Zone.STACK); // why is this neccessary? + // state.setZone(objectId, Zone.STACK); // why is this neccessary? return item; } if (item.getSourceId().equals(objectId) && item instanceof Spell) { @@ -1421,7 +1424,7 @@ public abstract class GameImpl implements Game, Serializable { top.resolve(this); } finally { if (top != null) { - state.getStack().remove(top); // seems partly redundant because move card from stack to grave is already done and the stack removed + state.getStack().remove(top, this); // seems partly redundant because move card from stack to grave is already done and the stack removed rememberLKI(top.getSourceId(), Zone.STACK, top); checkInfiniteLoop(top.getSourceId()); if (!getTurn().isEndTurnRequested()) { @@ -2581,10 +2584,10 @@ public abstract class GameImpl implements Game, Serializable { it.remove(); } } - + if (addPlaneAgain) { boolean addedAgain = false; - for (Player aplayer : state.getPlayers().values()) { + for (Player aplayer : state.getPlayers().values()) { if (!aplayer.hasLeft() && !addedAgain) { addedAgain = true; Plane plane = Plane.getRandomPlane(); diff --git a/Mage/src/main/java/mage/game/GameState.java b/Mage/src/main/java/mage/game/GameState.java index d10618d2de3..2e59a19dc01 100644 --- a/Mage/src/main/java/mage/game/GameState.java +++ b/Mage/src/main/java/mage/game/GameState.java @@ -685,7 +685,11 @@ public class GameState implements Serializable, Copyable { } public void setZone(UUID id, Zone zone) { - zones.put(id, zone); + if (zone == null) { + zones.remove(id); + } else { + zones.put(id, zone); + } } public void addSimultaneousEvent(GameEvent event, Game game) { diff --git a/Mage/src/main/java/mage/game/ZonesHandler.java b/Mage/src/main/java/mage/game/ZonesHandler.java index 9a145c862dc..c14b2da8842 100644 --- a/Mage/src/main/java/mage/game/ZonesHandler.java +++ b/Mage/src/main/java/mage/game/ZonesHandler.java @@ -134,12 +134,15 @@ public final class ZonesHandler { case STACK: // There should never be more than one card here. for (Card card : cards.getCards(game)) { + Spell spell; if (info instanceof ZoneChangeInfo.Stack && ((ZoneChangeInfo.Stack) info).spell != null) { - game.getStack().push(((ZoneChangeInfo.Stack) info).spell); + spell = ((ZoneChangeInfo.Stack) info).spell; } else { - game.getStack().push( - new Spell(card, card.getSpellAbility().copy(), card.getOwnerId(), event.getFromZone())); + spell = new Spell(card, card.getSpellAbility().copy(), card.getOwnerId(), event.getFromZone()); } + game.getStack().push(spell); + game.getState().setZone(spell.getId(), Zone.STACK); + game.getState().setZone(card.getId(), Zone.STACK); } break; case BATTLEFIELD: diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index 5a5d4103ec6..adb17ec7ac9 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -410,7 +410,7 @@ public class Spell extends StackObjImpl implements Card { } } else { // Copied spell, only remove from stack - game.getStack().remove(this); + game.getStack().remove(this, game); } } @@ -772,7 +772,7 @@ public class Spell extends StackObjImpl implements Card { @Override public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, List appliedEffects) { if (this.isCopiedSpell()) { - game.getStack().remove(this); + game.getStack().remove(this, game); return true; } return this.card.moveToExile(exileId, name, sourceId, game, appliedEffects); diff --git a/Mage/src/main/java/mage/game/stack/SpellStack.java b/Mage/src/main/java/mage/game/stack/SpellStack.java index ed0bf563879..aa8246d0c5d 100644 --- a/Mage/src/main/java/mage/game/stack/SpellStack.java +++ b/Mage/src/main/java/mage/game/stack/SpellStack.java @@ -67,15 +67,16 @@ public class SpellStack extends ArrayDeque { if (top != null) { if (contains(top)) { logger.warn("StackObject was still on the stack after resoving" + top.getName()); - this.remove(top); + this.remove(top, game); } } } } - public boolean remove(StackObject object) { + public boolean remove(StackObject object, Game game) { for (StackObject spell : this) { if (spell.getId().equals(object.getId())) { + game.getState().setZone(spell.getId(), null); return super.remove(spell); } } @@ -107,7 +108,7 @@ public class SpellStack extends ArrayDeque { } if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, sourceId, stackObject.getControllerId()))) { if (!(stackObject instanceof Spell)) { // spells are removed from stack by the card movement - this.remove(stackObject); + this.remove(stackObject, game); } stackObject.counter(sourceId, game, zone, owner, zoneDetail); if (!game.isSimulation()) { diff --git a/Mage/src/main/java/mage/game/stack/StackAbility.java b/Mage/src/main/java/mage/game/stack/StackAbility.java index da87c5d3fb5..74038eb306f 100644 --- a/Mage/src/main/java/mage/game/stack/StackAbility.java +++ b/Mage/src/main/java/mage/game/stack/StackAbility.java @@ -101,14 +101,14 @@ public class StackAbility extends StackObjImpl implements Ability { public boolean resolve(Game game) { if (ability.getTargets().stillLegal(ability, game) || !canFizzle()) { boolean result = ability.resolve(game); - game.getStack().remove(this); + game.getStack().remove(this, game); return result; } if (!game.isSimulation()) { game.informPlayers("Ability has been fizzled: " + getRule()); } counter(null, game); - game.getStack().remove(this); + game.getStack().remove(this, game); return false; } diff --git a/Mage/src/main/java/mage/game/turn/Turn.java b/Mage/src/main/java/mage/game/turn/Turn.java index 3463487e455..221c771ea07 100644 --- a/Mage/src/main/java/mage/game/turn/Turn.java +++ b/Mage/src/main/java/mage/game/turn/Turn.java @@ -284,7 +284,7 @@ public class Turn implements Serializable { if (stackObject instanceof Spell) { ((Spell) stackObject).moveToExile(null, "", source.getSourceId(), game); } else { - game.getStack().remove(stackObject); // stack ability + game.getStack().remove(stackObject, game); // stack ability } } // 2) All attacking and blocking creatures are removed from combat. diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index d799973b6a1..0e1136188e7 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -3687,7 +3687,7 @@ public abstract class PlayerImpl implements Player, Serializable { final Spell spell = (Spell) card; if (spell.isCopiedSpell()) { // Copied spell, only remove from stack - game.getStack().remove(spell); + game.getStack().remove(spell, game); } } game.informPlayers(this.getLogName() + " moves " + (withName ? card.getLogName() + (card.isCopy() ? " (Copy)" : "") : "a card face down") + ' '