diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/SmotheringAbomination.java b/Mage.Sets/src/mage/sets/battleforzendikar/SmotheringAbomination.java index 93158d66475..e7d2ec93608 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/SmotheringAbomination.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/SmotheringAbomination.java @@ -113,4 +113,3 @@ class SmotheringAbominationTriggeredAbility extends TriggeredAbilityImpl { return "Whenever you sacrifice a creature, " + super.getRule(); } } - diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java index 40475118a59..ec5fbc6e9ff 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java @@ -1,16 +1,16 @@ /* * Copyright 2011 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,7 +20,7 @@ * 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. @@ -28,6 +28,7 @@ package mage.sets.mirrodinbesieged; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -47,6 +48,7 @@ import mage.game.stack.Spell; import mage.players.Player; import mage.target.common.TargetCardInExile; import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; /** * @@ -87,14 +89,16 @@ class KnowledgePoolEffect1 extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player sourcePlayer = game.getPlayer(source.getControllerId()); - for (UUID playerId: sourcePlayer.getInRange()) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } + for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { - int amount = Math.min(3, player.getLibrary().size()); - for (int i = 0; i < amount; i++) { - player.getLibrary().removeFromTop(game).moveToExile(source.getSourceId(), "Knowledge Pool Exile", source.getSourceId(), game); - } + player.moveCardsToExile(player.getLibrary().getTopCards(game, 3), source, game, true, + CardUtil.getObjectExileZoneId(game, sourceObject), sourceObject.getIdName() + " (" + sourceObject.getZoneChangeCounter(game) + ")"); } } return true; @@ -129,7 +133,7 @@ class KnowledgePoolAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getZone() == Zone.HAND) { + if (event.getZone() == Zone.HAND) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null) { for (Effect effect : this.getEffects()) { @@ -159,12 +163,15 @@ class KnowledgePoolEffect2 extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); - if (spell != null) { - if (spell.moveToExile(source.getSourceId(), "Knowledge Pool Exile", source.getSourceId(), game)) { + MageObject sourceObject = game.getObject(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && spell != null && sourceObject != null) { + UUID exileZoneId = CardUtil.getObjectExileZoneId(game, sourceObject); + if (controller.moveCardsToExile(spell, source, game, true, exileZoneId, sourceObject.getIdName())) { Player player = game.getPlayer(spell.getControllerId()); - if (player != null && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with Knowledge Pool without paying that card's mana cost?", source, game)) { + if (player != null && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with " + sourceObject.getLogName() + " without paying that card's mana cost?", source, game)) { TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId()); - while (player.choose(Outcome.PlayForFree, game.getExile().getExileZone(source.getSourceId()), target, game)) { + while (player.choose(Outcome.PlayForFree, game.getExile().getExileZone(exileZoneId), target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null && !card.getId().equals(spell.getSourceId())) { game.getExile().removeCard(card, game); @@ -184,4 +191,4 @@ class KnowledgePoolEffect2 extends OneShotEffect { return new KnowledgePoolEffect2(this); } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java index 7c63a8447f1..e3cfc186491 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java @@ -400,4 +400,56 @@ public class ManifestTest extends CardTestPlayerBase { assertPermanentCount(playerB, "", 2); } + + /** + * I sacrificed a manifested face-down Smothering Abomination to Nantuko + * Husk and it made me draw a card. + * + */ + @Test + public void testDiesTriggeredAbilitiesOfManifestedCreatures() { + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); + + // Sacrifice a creature: Nantuko Husk gets +2/+2 until end of turn. + addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk", 1); + + // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library. + addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); + + // Devoid + // Flying + // At the beginning of your upkeep, sacrifice a creature + // Whenever you sacrifice a creature, draw a card. + addCard(Zone.LIBRARY, playerB, "Mountain", 1); + addCard(Zone.LIBRARY, playerB, "Smothering Abomination", 1); + addCard(Zone.LIBRARY, playerB, "Mountain", 1); + + skipInitShuffling(); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B},{T}, Sacrifice another creature"); + setChoice(playerB, "Silvercoat Lion"); + + activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice a creature"); + setChoice(playerB, ""); + + setStopAt(2, PhaseStep.END_TURN); + execute(); + + // no life gain + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertPermanentCount(playerB, "Qarsi High Priest", 1); + assertPermanentCount(playerB, "Nantuko Husk", 1); + + assertGraveyardCount(playerB, "Silvercoat Lion", 1); + assertGraveyardCount(playerB, "Smothering Abomination", 1); + + assertPowerToughness(playerB, "Nantuko Husk", 4, 4); + + assertHandCount(playerB, "Mountain", 1); + + } } diff --git a/Mage/src/mage/abilities/TriggeredAbilities.java b/Mage/src/mage/abilities/TriggeredAbilities.java index 599e44068c0..2a9d07b1c99 100644 --- a/Mage/src/mage/abilities/TriggeredAbilities.java +++ b/Mage/src/mage/abilities/TriggeredAbilities.java @@ -95,7 +95,7 @@ public class TriggeredAbilities extends ConcurrentHashMap