diff --git a/res/cardsfolder/a/ancient_grudge.txt b/res/cardsfolder/a/ancient_grudge.txt index 1ecab2e5a26..067690a2553 100644 --- a/res/cardsfolder/a/ancient_grudge.txt +++ b/res/cardsfolder/a/ancient_grudge.txt @@ -2,8 +2,8 @@ Name:Ancient Grudge ManaCost:1 R Types:Instant Text:no text +K:Flashback G A:SP$ Destroy | Cost$ 1 R | ValidTgts$ Artifact | TgtPrompt$ Select target artifact. | SpellDescription$ Destroy target artifact. -A:SP$ Destroy | Cost$ G | ValidTgts$ Artifact | TgtPrompt$ Select target artifact. | Flashback$ True | CostDesc$ Flashback G | SpellDescription$ (You may cast this card from your graveyard for its flashback cost. Then exile it.) SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/ancient_grudge.jpg Oracle:Destroy target artifact.\nFlashback {G} (You may cast this card from your graveyard for its flashback cost. Then exile it.) diff --git a/res/cardsfolder/m/mystical_teachings.txt b/res/cardsfolder/m/mystical_teachings.txt index f751eaeb3d5..deb5438012d 100644 --- a/res/cardsfolder/m/mystical_teachings.txt +++ b/res/cardsfolder/m/mystical_teachings.txt @@ -2,7 +2,7 @@ Name:Mystical Teachings ManaCost:3 U Types:Instant Text:no text -K:Flashback:5 B +K:Flashback 5 B A:SP$ ChangeZone | Cost$ 3 U | ChangeType$ Instant,Card.withFlash | ChangeNum$ 1 | Origin$ Library | Destination$ Hand | Shuffle$ True | SpellDescription$ Search your library for an instant card or a card with flash, reveal it, and put it into your hand. Then shuffle your library. SVar:RemAIDeck:True SVar:Rarity:Common diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index ec9917925f5..67dd2a66765 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -2402,7 +2402,7 @@ public class Card extends GameEntity implements Comparable { || (kw.get(i).startsWith("Dredge") && !sb.toString().contains("Dredge")) || (kw.get(i).startsWith("Madness") && !sb.toString().contains("Madness")) || (kw.get(i).startsWith("CARDNAME is ") && !sb.toString().contains("CARDNAME is ")) - || (kw.get(i).equals("Flashback") && !sb.toString().contains("Flashback")) + || kw.get(i).startsWith("Flashback") || (kw.get(i).startsWith("Recover") && !sb.toString().contains("Recover"))) { sb.append(kw.get(i).replace(":", " ")).append("\r\n"); } diff --git a/src/main/java/forge/ComputerUtil.java b/src/main/java/forge/ComputerUtil.java index d6c1e92f6b1..789286c25f1 100644 --- a/src/main/java/forge/ComputerUtil.java +++ b/src/main/java/forge/ComputerUtil.java @@ -51,9 +51,33 @@ public class ComputerUtil { if (af != null && af.getAPI().equals("Counter")) { continue; } - sa.setActivatingPlayer(AllZone.getComputerPlayer()); - if (canBePlayedAndPayedByAI(sa)) { + Card source = sa.getSourceCard(); + + boolean flashb = false; + + //Flashback + if (source.isInZone(Constant.Zone.Graveyard) && sa.isSpell() && (source.isInstant() || source.isSorcery())) { + for(String keyword : source.getKeyword()) { + if (keyword.startsWith("Flashback")) { + SpellAbility flashback = sa.copy(); + flashback.setActivatingPlayer(AllZone.getComputerPlayer()); + flashback.setFlashBackAbility(true); + if (!keyword.equals("Flashback")) {//there is a flashback cost (and not the cards cost) + final Cost fbCost = new Cost(keyword.substring(10), source.getName(), false); + flashback.setPayCosts(fbCost); + } + if (canBePlayedAndPayedByAI(flashback)) { + handlePlayingSpellAbility(flashback); + + return false; + } + flashb = true; + } + } + } + + if ((!flashb || source.hasStartOfKeyword("May be played")) && canBePlayedAndPayedByAI(sa)) { handlePlayingSpellAbility(sa); return false; diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index c0a5e86139a..831800f9d29 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -1783,14 +1783,26 @@ public class GameAction { // for uncastables like lotus bloom, check if manaCost is blank sa.setActivatingPlayer(human); if (sa.canPlay() && (!sa.isSpell() || !sa.getManaCost().equals(""))) { - if (c.hasKeyword("Flashback") && c.isInZone(Constant.Zone.Graveyard) - && c.getSpells().get(0).equals(sa) && !c.hasStartOfKeyword("May be played")) { - SpellAbility flashback = sa.copy(); - flashback.setSourceCard(c); - flashback.setFlashBackAbility(true); - choices.add(flashback.toString()); - map.put(flashback.toString(), flashback); - } else { + + boolean flashb = false; + + //check for flashback keywords + if (c.isInZone(Constant.Zone.Graveyard) && sa.isSpell() && (c.isInstant() || c.isSorcery())) { + for(String keyword : c.getKeyword()) { + if (keyword.startsWith("Flashback")) { + SpellAbility flashback = sa.copy(); + flashback.setFlashBackAbility(true); + if (!keyword.equals("Flashback")) {//there is a flashback cost (and not the cards cost) + final Cost fbCost = new Cost(keyword.substring(10), c.getName(), false); + flashback.setPayCosts(fbCost); + } + choices.add(flashback.toString()); + map.put(flashback.toString(), flashback); + flashb = true; + } + } + } + if (!flashb || c.hasStartOfKeyword("May be played")) { choices.add(sa.toString()); map.put(sa.toString(), sa); } diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index cc3dcb55cc2..a774f498252 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -2615,7 +2615,7 @@ public class CardFactoryUtil { } if (sa.isSpell() && !zone.is(Zone.Battlefield) && (c.hasStartOfKeyword("May be played") - || (c.hasKeyword("Flashback") && zone.is(Zone.Graveyard))) + || (c.hasStartOfKeyword("Flashback") && zone.is(Zone.Graveyard))) && restrictZone.equals(Zone.Hand)) { return true; } diff --git a/src/main/java/forge/card/spellability/SpellAbilityRestriction.java b/src/main/java/forge/card/spellability/SpellAbilityRestriction.java index 81d83bb14c4..149010b752a 100644 --- a/src/main/java/forge/card/spellability/SpellAbilityRestriction.java +++ b/src/main/java/forge/card/spellability/SpellAbilityRestriction.java @@ -183,8 +183,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { if (!sa.isSpell() || cardZone.is(Zone.Battlefield) || !this.getZone().equals(Zone.Hand)) { return false; } else if (!c.hasStartOfKeyword("May be played") - && !(c.hasKeyword("Flashback") && cardZone.is(Zone.Graveyard) - && c.getSpells().get(0).equals(sa))) { + && !(c.hasStartOfKeyword("Flashback") && cardZone.is(Zone.Graveyard))) { return false; } }