From 230d1d37bdc2e6d493bc2bcd40126d1b742c078d Mon Sep 17 00:00:00 2001 From: Neil Gentleman Date: Sun, 22 Nov 2015 12:28:14 -0800 Subject: [PATCH] fix Grinning Totem, Thada Adel, Commune with Lava opponent was able to cast the exiled cards also changed Knacksaw Clique to use the same templating as Ornate Kanzashi --- .../betrayersofkamigawa/OrnateKanzashi.java | 12 +++-- .../sets/dragonsoftarkir/CommuneWithLava.java | 6 +-- .../mage/sets/shadowmoor/KnacksawClique.java | 48 ++++++++----------- .../mage/sets/timeshifted/GrinningTotem.java | 18 +------ .../sets/worldwake/ThadaAdelAcquisitor.java | 3 +- .../cards/single/mir/GrinningTotemTest.java | 24 ++++++++++ Mage/src/mage/players/Player.java | 4 +- 7 files changed, 59 insertions(+), 56 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrnateKanzashi.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrnateKanzashi.java index 504916c8d76..29b2018d772 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrnateKanzashi.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrnateKanzashi.java @@ -79,6 +79,7 @@ public class OrnateKanzashi extends CardImpl { } } + class OrnateKanzashiEffect extends OneShotEffect { public OrnateKanzashiEffect() { @@ -98,14 +99,14 @@ class OrnateKanzashiEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); - MageObject sourceObject = game.getObject(source.getSourceId()); + MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null && opponent != null) { if (opponent.getLibrary().size() > 0) { Library library = opponent.getLibrary(); Card card = library.getFromTop(game); if (card != null) { opponent.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getName(), source.getSourceId(), game, Zone.LIBRARY, true); - ContinuousEffect effect = new OrnateKanzashiCastFromExileEffect(card.getId()); + ContinuousEffect effect = new OrnateKanzashiCastFromExileEffect(); effect.setTargetPointer(new FixedTarget(card.getId())); game.addEffect(effect, source); } @@ -118,7 +119,7 @@ class OrnateKanzashiEffect extends OneShotEffect { class OrnateKanzashiCastFromExileEffect extends AsThoughEffectImpl { - public OrnateKanzashiCastFromExileEffect(UUID cardId) { + public OrnateKanzashiCastFromExileEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); staticText = "You may play that card from exile this turn"; } @@ -139,6 +140,7 @@ class OrnateKanzashiCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); + return source.getControllerId().equals(affectedControllerId) + && objectId.equals(getTargetPointer().getFirst(game, source)); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java index 89fe50de8f2..a820a9d6938 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java @@ -151,10 +151,8 @@ class CommuneWithLavaMayPlayEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (targetPointer.getTargets(game, source).contains(sourceId)) { - return game.getState().getZone(sourceId).equals(Zone.EXILED); - } - return false; + return source.getControllerId().equals(affectedControllerId) + && getTargetPointer().getTargets(game, source).contains(sourceId); } } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/KnacksawClique.java b/Mage.Sets/src/mage/sets/shadowmoor/KnacksawClique.java index 24e5ea3e54c..a0d6be1d305 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/KnacksawClique.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/KnacksawClique.java @@ -29,11 +29,13 @@ package mage.sets.shadowmoor; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.UntapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; @@ -45,14 +47,14 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.players.Library; import mage.players.Player; import mage.target.common.TargetOpponent; -import mage.util.CardUtil; +import mage.target.targetpointer.FixedTarget; /** * * @author jeffwadsworth - */ public class KnacksawClique extends CardImpl { @@ -104,16 +106,17 @@ class KnacksawCliqueEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player opponent = game.getPlayer(source.getFirstTarget()); - if (opponent != null) { - Player you = game.getPlayer(source.getControllerId()); - UUID exileId = CardUtil.getCardExileZoneId(game, source); - Card card = opponent.getLibrary().getFromTop(game); - if (card != null - && you != null) { - card.moveToExile(exileId, "Knacksaw Clique", source.getSourceId(), game); - if (card.getSpellAbility() != null) { - game.addEffect(new KnacksawCliqueCastFromExileEffect(card.getId(), exileId), source); + Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject != null && opponent != null) { + if (opponent.getLibrary().size() > 0) { + Library library = opponent.getLibrary(); + Card card = library.getFromTop(game); + if (card != null) { + opponent.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getName(), source.getSourceId(), game, Zone.LIBRARY, true); + ContinuousEffect effect = new KnacksawCliqueCastFromExileEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); } } return true; @@ -124,20 +127,13 @@ class KnacksawCliqueEffect extends OneShotEffect { class KnacksawCliqueCastFromExileEffect extends AsThoughEffectImpl { - private final UUID cardId; - private final UUID exileId; - - public KnacksawCliqueCastFromExileEffect(UUID cardId, UUID exileId) { + public KnacksawCliqueCastFromExileEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); staticText = "Until end of turn, you may play that card"; - this.cardId = cardId; - this.exileId = exileId; } public KnacksawCliqueCastFromExileEffect(final KnacksawCliqueCastFromExileEffect effect) { super(effect); - this.cardId = effect.cardId; - this.exileId = effect.exileId; } @Override @@ -152,12 +148,8 @@ class KnacksawCliqueCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (sourceId.equals(this.cardId) && source.getControllerId().equals(affectedControllerId)) { - Card card = game.getCard(this.cardId); - if (card != null && game.getState().getExile().getExileZone(exileId).contains(cardId)) { - return true; - } - } - return false; + return source.getControllerId().equals(affectedControllerId) + && sourceId.equals(getTargetPointer().getFirst(game, source)); + } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/timeshifted/GrinningTotem.java b/Mage.Sets/src/mage/sets/timeshifted/GrinningTotem.java index 5ae1263948b..90a16a1c35b 100644 --- a/Mage.Sets/src/mage/sets/timeshifted/GrinningTotem.java +++ b/Mage.Sets/src/mage/sets/timeshifted/GrinningTotem.java @@ -32,7 +32,6 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.Condition; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -166,10 +165,8 @@ class GrinningTotemMayPlayEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (targetPointer.getTargets(game, source).contains(sourceId)) { - return game.getState().getZone(sourceId).equals(Zone.EXILED); - } - return false; + return source.getControllerId().equals(affectedControllerId) + && sourceId.equals(getTargetPointer().getFirst(game, source)); } } @@ -211,17 +208,6 @@ class GrinningTotemDelayedTriggeredAbility extends DelayedTriggeredAbility { } } - -class GrinningTotemYouHaveNotPlayedCondition implements Condition { - - @Override - public boolean apply(Game game, Ability source) { - ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); - return zone.getCards(game).size() > 0; - } - -} - class GrinningTotemPutIntoGraveyardEffect extends OneShotEffect { public GrinningTotemPutIntoGraveyardEffect() { diff --git a/Mage.Sets/src/mage/sets/worldwake/ThadaAdelAcquisitor.java b/Mage.Sets/src/mage/sets/worldwake/ThadaAdelAcquisitor.java index 409950b8a77..55124b98a13 100644 --- a/Mage.Sets/src/mage/sets/worldwake/ThadaAdelAcquisitor.java +++ b/Mage.Sets/src/mage/sets/worldwake/ThadaAdelAcquisitor.java @@ -147,6 +147,7 @@ class ThadaAdelPlayFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - return sourceId.equals(getTargetPointer().getFirst(game, source)) && game.getState().getZone(sourceId) == Zone.EXILED; + return source.getControllerId().equals(affectedControllerId) + && sourceId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java new file mode 100644 index 00000000000..7fe14040e45 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mir/GrinningTotemTest.java @@ -0,0 +1,24 @@ +package org.mage.test.cards.single.mir; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class GrinningTotemTest extends CardTestPlayerBase { + + @Test + public void testCardsGoToGraveyard() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, "Grinning Totem"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}, Sacrifice {this}: Search target opponent's library for a card and exile it", playerB); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, 1); // Grinning Totem + assertGraveyardCount(playerB, 1); // the exiled Mountain + } + +} diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index dce42de2d67..8ff08946832 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -649,7 +649,7 @@ public interface Player extends MageItem, Copyable { boolean moveCards(Set cards, Zone toZone, Ability source, Game game); /** - * Iniversal method to move cards from one zone to another. Do not mix + * Universal method to move cards from one zone to another. Do not mix * objects from different from zones to move. * * @param cards @@ -659,7 +659,7 @@ public interface Player extends MageItem, Copyable { * @param tapped tha cards are tapped on the battlefield * @param faceDown the cards are face down in the to zone * @param byOwner the card is moved (or put onto battlefield) by the owner - * of the card and if target zone is battlefield controlls the permanent + * of the card and if target zone is battlefield controls the permanent * (instead of the controller of the source) * @param appliedEffects * @return