diff --git a/Mage.Sets/src/mage/cards/d/DreamDevourer.java b/Mage.Sets/src/mage/cards/d/DreamDevourer.java index 56729e8ff75..e36428c2910 100644 --- a/Mage.Sets/src/mage/cards/d/DreamDevourer.java +++ b/Mage.Sets/src/mage/cards/d/DreamDevourer.java @@ -8,10 +8,8 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.ForetellAbility; -import mage.cards.Card; +import mage.cards.*; import mage.constants.SubType; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -86,12 +84,38 @@ class DreamDevourerAddAbilityEffect extends ContinuousEffectImpl { return false; } for (Card card : controller.getHand().getCards(filter, game)) { - String costText = CardUtil.reduceCost(card.getSpellAbility().getManaCostsToPay(), 2).getText(); - game.getState().setValue(card.getId().toString() + "Foretell Cost", costText); - ForetellAbility foretellAbility = new ForetellAbility(card, costText); - foretellAbility.setSourceId(card.getId()); - foretellAbility.setControllerId(card.getOwnerId()); - game.getState().addOtherAbility(card, foretellAbility); + ForetellAbility foretellAbility = null; + if (card instanceof SplitCard) { + String leftHalfCost = CardUtil.reduceCost(((SplitCard) card).getLeftHalfCard().getManaCost(), 2).getText(); + String rightHalfCost = CardUtil.reduceCost(((SplitCard) card).getRightHalfCard().getManaCost(), 2).getText(); + foretellAbility = new ForetellAbility(card, leftHalfCost, rightHalfCost); + } else if (card instanceof ModalDoubleFacesCard) { + ModalDoubleFacesCardHalf leftHalfCard = ((ModalDoubleFacesCard) card).getLeftHalfCard(); + // If front side of MDFC is land, do nothing as Dream Devourer does not apply to lands + // MDFC cards in hand are considered lands if front side is land + if (!leftHalfCard.isLand()) { + String leftHalfCost = CardUtil.reduceCost(leftHalfCard.getManaCost(), 2).getText(); + ModalDoubleFacesCardHalf rightHalfCard = ((ModalDoubleFacesCard) card).getRightHalfCard(); + if (rightHalfCard.isLand()) { + foretellAbility = new ForetellAbility(card, leftHalfCost); + } else { + String rightHalfCost = CardUtil.reduceCost(rightHalfCard.getManaCost(), 2).getText(); + foretellAbility = new ForetellAbility(card, leftHalfCost, rightHalfCost); + } + } + } else if (card instanceof AdventureCard) { + String creatureCost = CardUtil.reduceCost(card.getMainCard().getManaCost(), 2).getText(); + String spellCost = CardUtil.reduceCost(((AdventureCard) card).getSpellCard().getManaCost(), 2).getText(); + foretellAbility = new ForetellAbility(card, creatureCost, spellCost); + } else { + String costText = CardUtil.reduceCost(card.getManaCost(), 2).getText(); + foretellAbility = new ForetellAbility(card, costText); + } + if (foretellAbility != null) { + foretellAbility.setSourceId(card.getId()); + foretellAbility.setControllerId(card.getOwnerId()); + game.getState().addOtherAbility(card, foretellAbility); + } } return true; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/DreamDevourerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/DreamDevourerTest.java index 5b2de6ee0aa..6fc0d298cad 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/DreamDevourerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/DreamDevourerTest.java @@ -61,4 +61,148 @@ public class DreamDevourerTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Grizzly Bears", 2); } + + @Test + public void testSplitCard() { + removeAllCardsFromHand(playerA); + + addCard(Zone.BATTLEFIELD, playerA, "Dream Devourer"); + addCard(Zone.BATTLEFIELD, playerA, "Underground Sea", 5); + addCard(Zone.HAND, playerA, "Discovery // Dispersal", 2); + + checkPlayableAbility("normal cast left side", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Discovery", true); + checkPlayableAbility("normal cast right side", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Dispersal", true); + checkPlayableAbility("foretell exile", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell", true); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + checkExileCount("after foretell", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discovery // Dispersal", 2); + + checkPlayableAbility("foretell cast left side", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {U/B}", true); + checkPlayableAbility("foretell cast right side", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {1}{U}{B}", true); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {U/B}"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {1}{U}{B}"); + waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN); + checkExileCount("after foretell cast", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Discovery // Dispersal", 0); + + setStopAt(3, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + } + + @Test + public void testMDFCLand() { + removeAllCardsFromHand(playerA); + + addCard(Zone.BATTLEFIELD, playerA, "Dream Devourer"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6); + addCard(Zone.HAND, playerA, "Akoum Warrior", 1); + + checkPlayableAbility("normal cast left side", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Akoum Warrior", true); + checkPlayableAbility("play land right side", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Akoum Teeth", true); + checkPlayableAbility("foretell exile", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell", true); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + checkExileCount("after foretell", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1); + + // Check that cost reduction worked (Foretell cost should be {3}{R}) + activateManaAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}", 2); + + checkPlayableAbility("foretell cast left side", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Foretell {3}{R}", true); + checkPlayableAbility("play foretold land", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Play Akoum Teeth", false); + activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Foretell {3}{R}"); + waitStackResolved(3, PhaseStep.POSTCOMBAT_MAIN); + checkPermanentCount("after foretell cast", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Akoum Warrior", 1); + checkExileCount("after foretell cast", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Akoum Warrior", 0); + + setStrictChooseMode(true); + setStopAt(3, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Akoum Warrior", 1); + } + + @Test + public void testMDFCNonland() { + removeAllCardsFromHand(playerA); + + addCard(Zone.BATTLEFIELD, playerA, "Dream Devourer"); + addCard(Zone.BATTLEFIELD, playerA, "City of Brass", 4); + addCard(Zone.HAND, playerA, "Jorn, God of Winter", 2); + + checkPlayableAbility("normal cast left side", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Jorn", true); + checkPlayableAbility("normal cast right side", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Kaldring", true); + checkPlayableAbility("foretell exile", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell", true); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + checkExileCount("after foretell", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Jorn, God of Winter", 2); + + checkPlayableAbility("foretell cast left side", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {G}", true); + checkPlayableAbility("foretell cast right side", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {U}{B}", true); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {G}"); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {U}{B}"); + waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN); + checkPermanentCount("after foretell cast", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Jorn, God of Winter", 1); + checkPermanentCount("after foretell cast", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Kaldring, the Rimestaff", 1); + checkExileCount("after foretell cast", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Jorn, God of Winter", 0); + + setStopAt(3, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Jorn, God of Winter", 1); + assertPermanentCount(playerA, "Kaldring, the Rimestaff", 1); + } + + @Test + public void testAdventureCard() { + removeAllCardsFromHand(playerA); + + addCard(Zone.BATTLEFIELD, playerA, "Dream Devourer"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 6); + addCard(Zone.HAND, playerA, "Lonesome Unicorn", 2); + + checkPlayableAbility("creature cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lone", true); + checkPlayableAbility("adventure cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Rider", true); + checkPlayableAbility("foretell exile", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell", true); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + checkExileCount("after foretell", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lonesome Unicorn", 2); + + checkPlayableAbility("foretell creature cast", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {2}{W}", true); + checkPlayableAbility("foretell adventure cast", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {W}", true); + checkPlayableAbility("creature cast", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lone", false); + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {W}"); + waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN); + + // Check that the creature is playable from adventure zone after casting with Foretell + checkPlayableAbility("creature cast after foretell", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lone", true); + + // Tap 2 lands to verify cost reduction worked + activateManaAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {W}", 2); + activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Foretell {2}{W}"); + waitStackResolved(3, PhaseStep.POSTCOMBAT_MAIN); + checkPermanentCount("after foretell cast", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lonesome Unicorn", 1); + checkPermanentCount("after foretell cast", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Knight", 1); + + activateAbility(5, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lonesome Unicorn"); + waitStackResolved(5, PhaseStep.PRECOMBAT_MAIN); + checkPermanentCount("after adventure cast", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Lonesome Unicorn", 2); + checkExileCount("after foretell cast", 5, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lonesome Unicorn", 0); + + setStrictChooseMode(true); + setStopAt(5, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, "Lonesome Unicorn", 2); + assertPermanentCount(playerA, "Knight", 1); + } } diff --git a/Mage/src/main/java/mage/abilities/keyword/ForetellAbility.java b/Mage/src/main/java/mage/abilities/keyword/ForetellAbility.java index dfd7437e637..58e849d72d0 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ForetellAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ForetellAbility.java @@ -15,9 +15,7 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.cards.Card; -import mage.cards.ModalDoubleFacesCard; -import mage.cards.SplitCard; +import mage.cards.*; import mage.constants.*; import mage.game.ExileZone; import mage.game.Game; @@ -34,16 +32,22 @@ import java.util.UUID; public class ForetellAbility extends SpecialAction { private final String foretellCost; + private final String foretellSplitCost; private final Card card; public ForetellAbility(Card card, String foretellCost) { + this(card, foretellCost, null); + } + + public ForetellAbility(Card card, String foretellCost, String foretellSplitCost) { super(Zone.HAND); this.foretellCost = foretellCost; + this.foretellSplitCost = foretellSplitCost; this.card = card; this.usesStack = Boolean.FALSE; this.addCost(new GenericManaCost(2)); // exile the card and it can't be cast the turn it was foretold - this.addEffect(new ForetellExileEffect(card, foretellCost)); + this.addEffect(new ForetellExileEffect(card, foretellCost, foretellSplitCost)); // look at face-down card anytime addSubAbility(new SimpleStaticAbility(Zone.ALL, new ForetellLookAtCardEffect())); this.setRuleVisible(true); @@ -53,6 +57,7 @@ public class ForetellAbility extends SpecialAction { private ForetellAbility(ForetellAbility ability) { super(ability); this.foretellCost = ability.foretellCost; + this.foretellSplitCost = ability.foretellSplitCost; this.card = ability.card; } @@ -83,17 +88,20 @@ public class ForetellAbility extends SpecialAction { private final Card card; String foretellCost; + String foretellSplitCost; - public ForetellExileEffect(Card card, String foretellCost) { + public ForetellExileEffect(Card card, String foretellCost, String foretellSplitCost) { super(Outcome.Neutral); this.card = card; this.foretellCost = foretellCost; + this.foretellSplitCost = foretellSplitCost; } public ForetellExileEffect(final ForetellExileEffect effect) { super(effect); this.card = effect.card; this.foretellCost = effect.foretellCost; + this.foretellSplitCost = effect.foretellSplitCost; } @Override @@ -106,17 +114,19 @@ public class ForetellAbility extends SpecialAction { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && card != null) { + UUID mainCardId = card.getMainCard().getId(); // retrieve the exileId of the foretold card - UUID exileId = CardUtil.getExileZoneId(card.getId().toString() + "foretellAbility", game); + UUID exileId = CardUtil.getExileZoneId(mainCardId.toString() + "foretellAbility", game); // foretell turn number shows up on exile window Effect effect = new ExileTargetEffect(exileId, " Foretell Turn Number: " + game.getTurnNum()); // remember turn number it was cast - game.getState().setValue(card.getId().toString() + "Foretell Turn Number", game.getTurnNum()); + game.getState().setValue(mainCardId.toString() + "Foretell Turn Number", game.getTurnNum()); // remember the foretell cost - game.getState().setValue(card.getId().toString() + "Foretell Cost", foretellCost); + game.getState().setValue(mainCardId.toString() + "Foretell Cost", foretellCost); + game.getState().setValue(mainCardId.toString() + "Foretell Split Cost", foretellSplitCost); // exile the card face-down effect.setTargetPointer(new FixedTarget(card.getId())); @@ -153,16 +163,16 @@ public class ForetellAbility extends SpecialAction { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { if (affectedControllerId.equals(source.getControllerId())) { Card card = game.getCard(objectId); - if (card != null - && CardUtil.getExileZoneId(card.getId().toString() + "foretellAbility", game) != null) { + if (card != null) { MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject == null) { return false; } - UUID exileId = CardUtil.getExileZoneId(card.getId().toString() + "foretellAbility", game); + UUID mainCardId = card.getMainCard().getId(); + UUID exileId = CardUtil.getExileZoneId(mainCardId.toString() + "foretellAbility", game); ExileZone exile = game.getExile().getExileZone(exileId); return exile != null - && exile.contains(card.getId()); + && exile.contains(mainCardId); } } return false; @@ -187,16 +197,80 @@ public class ForetellAbility extends SpecialAction { @Override public boolean apply(Game game, Ability source) { Card card = mor.getCard(game); - if (card != null - && game.getState().getZone(card.getId()) == Zone.EXILED) { - String foretellCost = (String) game.getState().getValue(card.getId().toString() + "Foretell Cost"); - Ability ability = new ForetellCostAbility(foretellCost); - ability.setSourceId(card.getId()); - ability.setControllerId(source.getControllerId()); - game.getState().addOtherAbility(card, ability); - } else { - discard(); + if (card != null) { + UUID mainCardId = card.getMainCard().getId(); + if (game.getState().getZone(mainCardId) == Zone.EXILED) { + String foretellCost = (String) game.getState().getValue(mainCardId.toString() + "Foretell Cost"); + String foretellSplitCost = (String) game.getState().getValue(mainCardId.toString() + "Foretell Split Cost"); + if (card instanceof SplitCard) { + if (foretellCost != null) { + SplitCardHalf leftHalfCard = ((SplitCard) card).getLeftHalfCard(); + ForetellCostAbility ability = new ForetellCostAbility(foretellCost); + ability.setSourceId(leftHalfCard.getId()); + ability.setControllerId(source.getControllerId()); + ability.setSpellAbilityType(leftHalfCard.getSpellAbility().getSpellAbilityType()); + ability.setAbilityName(leftHalfCard.getName()); + game.getState().addOtherAbility(leftHalfCard, ability); + } + if (foretellSplitCost != null) { + SplitCardHalf rightHalfCard = ((SplitCard) card).getRightHalfCard(); + ForetellCostAbility ability = new ForetellCostAbility(foretellSplitCost); + ability.setSourceId(rightHalfCard.getId()); + ability.setControllerId(source.getControllerId()); + ability.setSpellAbilityType(rightHalfCard.getSpellAbility().getSpellAbilityType()); + ability.setAbilityName(rightHalfCard.getName()); + game.getState().addOtherAbility(rightHalfCard, ability); + } + } else if (card instanceof ModalDoubleFacesCard) { + if (foretellCost != null) { + ModalDoubleFacesCardHalf leftHalfCard = ((ModalDoubleFacesCard) card).getLeftHalfCard(); + ForetellCostAbility ability = new ForetellCostAbility(foretellCost); + ability.setSourceId(leftHalfCard.getId()); + ability.setControllerId(source.getControllerId()); + ability.setSpellAbilityType(leftHalfCard.getSpellAbility().getSpellAbilityType()); + ability.setAbilityName(leftHalfCard.getName()); + game.getState().addOtherAbility(leftHalfCard, ability); + } + if (foretellSplitCost != null) { + ModalDoubleFacesCardHalf rightHalfCard = ((ModalDoubleFacesCard) card).getRightHalfCard(); + ForetellCostAbility ability = new ForetellCostAbility(foretellSplitCost); + ability.setSourceId(rightHalfCard.getId()); + ability.setControllerId(source.getControllerId()); + ability.setSpellAbilityType(rightHalfCard.getSpellAbility().getSpellAbilityType()); + ability.setAbilityName(rightHalfCard.getName()); + game.getState().addOtherAbility(rightHalfCard, ability); + } + } else if (card instanceof AdventureCard) { + if (foretellCost != null) { + Card creatureCard = card.getMainCard(); + ForetellCostAbility ability = new ForetellCostAbility(foretellCost); + ability.setSourceId(creatureCard.getId()); + ability.setControllerId(source.getControllerId()); + ability.setSpellAbilityType(creatureCard.getSpellAbility().getSpellAbilityType()); + ability.setAbilityName(creatureCard.getName()); + game.getState().addOtherAbility(creatureCard, ability); + } + if (foretellSplitCost != null) { + Card spellCard = ((AdventureCard) card).getSpellCard(); + ForetellCostAbility ability = new ForetellCostAbility(foretellSplitCost); + ability.setSourceId(spellCard.getId()); + ability.setControllerId(source.getControllerId()); + ability.setSpellAbilityType(spellCard.getSpellAbility().getSpellAbilityType()); + ability.setAbilityName(spellCard.getName()); + game.getState().addOtherAbility(spellCard, ability); + } + } else if (foretellCost != null) { + ForetellCostAbility ability = new ForetellCostAbility(foretellCost); + ability.setSourceId(card.getId()); + ability.setControllerId(source.getControllerId()); + ability.setSpellAbilityType(card.getSpellAbility().getSpellAbilityType()); + ability.setAbilityName(card.getName()); + game.getState().addOtherAbility(card, ability); + } + return true; + } } + discard(); return true; } @@ -230,21 +304,22 @@ public class ForetellAbility extends SpecialAction { if (super.canActivate(playerId, game).canActivate()) { Card card = game.getCard(getSourceId()); if (card != null) { + UUID mainCardId = card.getMainCard().getId(); // Card must be in the exile zone - if (game.getState().getZone(card.getId()) != Zone.EXILED) { + if (game.getState().getZone(mainCardId) != Zone.EXILED) { return ActivationStatus.getFalse(); } // Card must be Foretold - if (game.getState().getValue(card.getId().toString() + "Foretell Turn Number") == null - && game.getState().getValue(card.getId().toString() + "foretellAbility") == null) { + if (game.getState().getValue(mainCardId.toString() + "Foretell Turn Number") == null + && game.getState().getValue(mainCardId + "foretellAbility") == null) { return ActivationStatus.getFalse(); } // Can't be cast if the turn it was Foretold is the same - if ((int) game.getState().getValue(card.getId().toString() + "Foretell Turn Number") == game.getTurnNum()) { + if ((int) game.getState().getValue(mainCardId.toString() + "Foretell Turn Number") == game.getTurnNum()) { return ActivationStatus.getFalse(); } // Check that the card is actually in the exile zone (ex: Oblivion Ring exiles it after it was Foretold, etc) - UUID exileId = (UUID) game.getState().getValue(card.getId().toString() + "foretellAbility"); + UUID exileId = (UUID) game.getState().getValue(mainCardId.toString() + "foretellAbility"); ExileZone exileZone = game.getState().getExile().getExileZone(exileId); if (exileZone != null && exileZone.isEmpty()) { @@ -262,6 +337,12 @@ public class ForetellAbility extends SpecialAction { } else if (((ModalDoubleFacesCard) card).getRightHalfCard().getName().equals(abilityName)) { return ((ModalDoubleFacesCard) card).getRightHalfCard().getSpellAbility().canActivate(playerId, game); } + } else if (card instanceof AdventureCard) { + if (card.getMainCard().getName().equals(abilityName)) { + return card.getMainCard().getSpellAbility().canActivate(playerId, game); + } else if (((AdventureCard) card).getSpellCard().getName().equals(abilityName)) { + return ((AdventureCard) card).getSpellCard().getSpellAbility().canActivate(playerId, game); + } } return card.getSpellAbility().canActivate(playerId, game); } @@ -287,6 +368,12 @@ public class ForetellAbility extends SpecialAction { } else if (((ModalDoubleFacesCard) card).getRightHalfCard().getName().equals(abilityName)) { spellAbilityCopy = ((ModalDoubleFacesCard) card).getRightHalfCard().getSpellAbility().copy(); } + } else if (card instanceof AdventureCard) { + if (card.getMainCard().getName().equals(abilityName)) { + spellAbilityCopy = card.getMainCard().getSpellAbility().copy(); + } else if (((AdventureCard) card).getSpellCard().getName().equals(abilityName)) { + spellAbilityCopy = ((AdventureCard) card).getSpellCard().getSpellAbility().copy(); + } } else { spellAbilityCopy = card.getSpellAbility().copy(); } @@ -320,7 +407,28 @@ public class ForetellAbility extends SpecialAction { @Override public String getRule(boolean all) { - return ""; + StringBuilder sbRule = new StringBuilder("Foretell"); + if (!costs.isEmpty()) { + sbRule.append("—"); + } else { + sbRule.append(' '); + } + if (!manaCosts.isEmpty()) { + sbRule.append(manaCosts.getText()); + } + if (!costs.isEmpty()) { + if (!manaCosts.isEmpty()) { + sbRule.append(", "); + } + sbRule.append(costs.getText()); + sbRule.append('.'); + } + if (abilityName != null) { + sbRule.append(' '); + sbRule.append(abilityName); + } + sbRule.append(" (You may cast this card from exile for its foretell cost.)"); + return sbRule.toString(); } /**