[KHM] Dream Devourer - Fixed being unable to cast foretold MDFCs, split cards, and adventure cards (#7498)

* [KHM] Dream Devourer - Fixed being unable to cast foretold MDFCs, split cards, and adventure cards

* [KHM] Dream Devourer - Fixed mana costs and added check for MDFC lands

* [KHM] ForetellAbility - Add text when selecting which half of split card to cast

* Updated test for Dream Devourer
This commit is contained in:
Daniel Bomar 2021-02-04 16:27:51 -06:00 committed by GitHub
parent 22b07608b0
commit cd9c57fead
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 312 additions and 36 deletions

View file

@ -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,13 +84,39 @@ 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 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;
}
}

View file

@ -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);
}
}

View file

@ -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,18 +197,82 @@ 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);
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);
} else {
discard();
}
return true;
}
}
discard();
return true;
}
@Override
public ForetellAddCostEffect copy() {
@ -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(" <i>(You may cast this card from exile for its foretell cost.)</i>");
return sbRule.toString();
}
/**