diff --git a/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java b/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java index f5345fe00d1..271ed678260 100644 --- a/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java +++ b/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java @@ -1,13 +1,14 @@ package mage.cards.k; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.AsThoughEffectImpl; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.cards.Card; import mage.cards.CardImpl; @@ -16,9 +17,9 @@ import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; import mage.watchers.Watcher; @@ -43,7 +44,7 @@ public final class KaradorGhostChieftain extends CardImpl { // During each of your turns, you may cast one creature card from your graveyard. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new KaradorGhostChieftainContinuousEffect()), + new KaradorGhostChieftainCastFromGraveyardEffect()), new KaradorGhostChieftainWatcher()); } @@ -94,46 +95,11 @@ class KaradorGhostChieftainCostReductionEffect extends CostModificationEffectImp } } -class KaradorGhostChieftainContinuousEffect extends ContinuousEffectImpl { - - KaradorGhostChieftainContinuousEffect() { - super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit); - staticText = "During each of your turns, you may cast one creature card from your graveyard"; - } - - KaradorGhostChieftainContinuousEffect(final KaradorGhostChieftainContinuousEffect effect) { - super(effect); - } - - @Override - public KaradorGhostChieftainContinuousEffect copy() { - return new KaradorGhostChieftainContinuousEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - if (game.getActivePlayerId() == null - || !game.isActivePlayer(player.getId())) { - return false; - } - for (Card card : player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)) { - ContinuousEffect effect = new KaradorGhostChieftainCastFromGraveyardEffect(); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); - } - return true; - } - return false; - } -} - class KaradorGhostChieftainCastFromGraveyardEffect extends AsThoughEffectImpl { KaradorGhostChieftainCastFromGraveyardEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may cast one creature card from your graveyard"; + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.PutCreatureInPlay); + staticText = "During each of your turns, you may cast one creature card from your graveyard"; } KaradorGhostChieftainCastFromGraveyardEffect(final KaradorGhostChieftainCastFromGraveyardEffect effect) { @@ -152,18 +118,21 @@ class KaradorGhostChieftainCastFromGraveyardEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (source.isControlledBy(affectedControllerId) + && Zone.GRAVEYARD.equals(game.getState().getZone(objectId)) + ) { Card objectCard = game.getCard(objectId); - if (objectCard != null - && objectCard.getId().equals(getTargetPointer().getFirst(game, source)) + Permanent sourceObject = game.getPermanent(source.getSourceId()); // needs to be onto the battlefield + if (objectCard != null + && sourceObject != null + && objectCard.isOwnedBy(source.getControllerId()) && objectCard.isCreature() && objectCard.getSpellAbility() != null - && affectedControllerId != null - && objectCard.getSpellAbility().spellCanBeActivatedRegularlyNow(affectedControllerId, game)) { - if (affectedControllerId.equals(source.getControllerId())) { + && objectCard.getSpellAbility().spellCanBeActivatedRegularlyNow(affectedControllerId, game)) { KaradorGhostChieftainWatcher watcher - = game.getState().getWatcher(KaradorGhostChieftainWatcher.class, source.getSourceId()); + = game.getState().getWatcher(KaradorGhostChieftainWatcher.class); return watcher != null - && !watcher.isAbilityUsed(); + && !watcher.isAbilityUsed(new MageObjectReference(sourceObject, game)); } } return false; @@ -172,10 +141,10 @@ class KaradorGhostChieftainCastFromGraveyardEffect extends AsThoughEffectImpl { class KaradorGhostChieftainWatcher extends Watcher { - private boolean abilityUsed = false; + private final Set usedFrom = new HashSet<>(); KaradorGhostChieftainWatcher() { - super(WatcherScope.CARD); + super(WatcherScope.GAME); } @Override @@ -184,7 +153,10 @@ class KaradorGhostChieftainWatcher extends Watcher { && event.getZone() == Zone.GRAVEYARD) { Spell spell = (Spell) game.getObject(event.getTargetId()); if (spell.isCreature()) { - abilityUsed = true; + MageObjectReference mor = event.getAdditionalReference(); // permitting source + if (mor != null) { + usedFrom.add(mor); + } } } } @@ -192,10 +164,10 @@ class KaradorGhostChieftainWatcher extends Watcher { @Override public void reset() { super.reset(); - abilityUsed = false; + usedFrom.clear(); } - public boolean isAbilityUsed() { - return abilityUsed; + public boolean isAbilityUsed(MageObjectReference mor) { + return usedFrom.contains(mor); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/KaradorGhostChieftainTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/KaradorGhostChieftainTest.java index ecea23e6ded..3c5ab55aad2 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/KaradorGhostChieftainTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/KaradorGhostChieftainTest.java @@ -14,10 +14,12 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase { @Test public void castReducedTwo() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); - addCard(Zone.BATTLEFIELD, playerA, "Island", 5); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 2); // Karador, Ghost Chieftain costs {1} less to cast for each creature card in your graveyard. // During each of your turns, you may cast one creature card from your graveyard. @@ -26,7 +28,7 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Karador, Ghost Chieftain"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - assertTappedCount("Island", false, 2); + assertAllCommandsUsed(); assertPermanentCount(playerA, "Karador, Ghost Chieftain", 1); } @@ -41,10 +43,11 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase { */ @Test public void castReducedSeven() { + setStrictChooseMode(true); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); - addCard(Zone.BATTLEFIELD, playerA, "Island", 5); addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 7); // Karador, Ghost Chieftain costs {1} less to cast for each creature card in your graveyard. // During each of your turns, you may cast one creature card from your graveyard. @@ -53,8 +56,41 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Karador, Ghost Chieftain"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - assertTappedCount("Island", false, 5); + assertAllCommandsUsed(); assertPermanentCount(playerA, "Karador, Ghost Chieftain", 1); } + + @Test + public void castCastTwiceFromGraveyard() { + setStrictChooseMode(true); + + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 7); + + // Exile target creature you control, then return that card to the battlefield under your control. + addCard(Zone.HAND, playerA, "Cloudshift");// Instant {W} + // Karador, Ghost Chieftain costs {1} less to cast for each creature card in your graveyard. + // During each of your turns, you may cast one creature card from your graveyard. + addCard(Zone.HAND, playerA, "Karador, Ghost Chieftain");// {5}{B}{G}{W} + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Karador, Ghost Chieftain"); + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion"); + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cloudshift", "Karador, Ghost Chieftain"); + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion"); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Silvercoat Lion", 2); + assertGraveyardCount(activePlayer, "Cloudshift", 1); + + assertPermanentCount(playerA, "Karador, Ghost Chieftain", 1); + } }