diff --git a/.gitattributes b/.gitattributes index 1dec0751b15..0ffba4e3354 100644 --- a/.gitattributes +++ b/.gitattributes @@ -912,6 +912,7 @@ res/cardsfolder/contagious_nim.txt -text svneol=native#text/plain res/cardsfolder/contemplation.txt -text svneol=native#text/plain res/cardsfolder/control_magic.txt -text svneol=native#text/plain res/cardsfolder/control_of_the_court.txt -text svneol=native#text/plain +res/cardsfolder/controvert.txt -text svneol=native#text/plain res/cardsfolder/convalescence.txt -text svneol=native#text/plain res/cardsfolder/convalescent_care.txt -text svneol=native#text/plain res/cardsfolder/convincing_mirage.txt -text svneol=native#text/plain @@ -2045,6 +2046,7 @@ res/cardsfolder/greener_pastures.txt -text svneol=native#text/plain res/cardsfolder/greenseeker.txt -text svneol=native#text/plain res/cardsfolder/greenweaver_druid.txt -text svneol=native#text/plain res/cardsfolder/griffin_sentinel.txt -text svneol=native#text/plain +res/cardsfolder/grim_harvest.txt -text svneol=native#text/plain res/cardsfolder/grim_monolith.txt -text svneol=native#text/plain res/cardsfolder/grim_poppet.txt -text svneol=native#text/plain res/cardsfolder/grim_tutor.txt -text svneol=native#text/plain @@ -2293,6 +2295,7 @@ res/cardsfolder/icatian_scout.txt -text svneol=native#text/plain res/cardsfolder/icatian_store.txt -text svneol=native#text/plain res/cardsfolder/icatian_town.txt -text svneol=native#text/plain res/cardsfolder/ice_storm.txt -text svneol=native#text/plain +res/cardsfolder/icefall.txt -text svneol=native#text/plain res/cardsfolder/ichor_rats.txt -text svneol=native#text/plain res/cardsfolder/ichor_slick.txt -text svneol=native#text/plain res/cardsfolder/ichorclaw_myr.txt -text svneol=native#text/plain @@ -2638,6 +2641,7 @@ res/cardsfolder/krosan_restorer.txt -text svneol=native#text/plain res/cardsfolder/krosan_war_chief.txt -text svneol=native#text/plain res/cardsfolder/krovikan_elementalist.txt -text svneol=native#text/plain res/cardsfolder/krovikan_horror.txt -text svneol=native#text/plain +res/cardsfolder/krovikan_rot.txt -text svneol=native#text/plain res/cardsfolder/krovikan_scoundrel.txt -text svneol=native#text/plain res/cardsfolder/kuldotha_forgemaster.txt -text svneol=native#text/plain res/cardsfolder/kuldotha_phoenix.txt -text svneol=native#text/plain @@ -3771,6 +3775,7 @@ res/cardsfolder/reprisal.txt -text svneol=native#text/plain res/cardsfolder/repulse.txt -text svneol=native#text/plain res/cardsfolder/rescind.txt -text svneol=native#text/plain res/cardsfolder/reset.txt -text svneol=native#text/plain +res/cardsfolder/resize.txt -text svneol=native#text/plain res/cardsfolder/respite.txt -text svneol=native#text/plain res/cardsfolder/restless_apparition.txt -text svneol=native#text/plain res/cardsfolder/restless_bones.txt -text svneol=native#text/plain @@ -4614,6 +4619,7 @@ res/cardsfolder/sunken_ruins.txt -text svneol=native#text/plain res/cardsfolder/sunlance.txt -text svneol=native#text/plain res/cardsfolder/sunpetal_grove.txt -text svneol=native#text/plain res/cardsfolder/sunrise_sovereign.txt -text svneol=native#text/plain +res/cardsfolder/suns_bounty.txt -text svneol=native#text/plain res/cardsfolder/sunscape_familiar.txt -text svneol=native#text/plain res/cardsfolder/sunscape_master.txt -text svneol=native#text/plain res/cardsfolder/sunspear_shikari.txt -text svneol=native#text/plain diff --git a/res/cardsfolder/controvert.txt b/res/cardsfolder/controvert.txt new file mode 100644 index 00000000000..a42b761a65a --- /dev/null +++ b/res/cardsfolder/controvert.txt @@ -0,0 +1,9 @@ +Name:Controvert +ManaCost:2 U U +Text:no text +A:SP$Counter | Cost$ 2 U U | Type$ Spell | SpellDescription$ Counter target spell. +K:Recover:2 U U +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/controvert.jpg +SetInfo:CSP|Uncommon|http://magiccards.info/scans/en/cs/30.jpg +End \ No newline at end of file diff --git a/res/cardsfolder/grim_harvest.txt b/res/cardsfolder/grim_harvest.txt new file mode 100644 index 00000000000..54784bb08db --- /dev/null +++ b/res/cardsfolder/grim_harvest.txt @@ -0,0 +1,10 @@ +Name:Grim Harvest +ManaCost:1 B +Types:Instant +Text:no text +A:SP$Retrieve | Cost$ 1 B | Tgt$ TgtC | SpellDescription$ Return target creature card from your graveyard to your hand. +K:Recover:2 B +SVar:Rarity:Common +SVar:Picture:http://www.wizards.com/global/images/magic/general/grim_harvest.jpg +SetInfo:CSP|Common|http://magiccards.info/scans/en/cs/58.jpg +End \ No newline at end of file diff --git a/res/cardsfolder/icefall.txt b/res/cardsfolder/icefall.txt new file mode 100644 index 00000000000..44b77400199 --- /dev/null +++ b/res/cardsfolder/icefall.txt @@ -0,0 +1,10 @@ +Name:Icefall +ManaCost: 2 R R +Types:Sorcery +Text:no text +A:SP$Destroy | Cost$ 2 R R | ValidTgts$ Artifact,Land | TgtPrompt$ Select target artifact or land. | SpellDescription$ Destroy target artifact or land. +K:Recover:R R +SVar:Rarity:Common +SVar:Picture:http://www.wizards.com/global/images/magic/general/icefall.jpg +SetInfo:CSP|Common|http://magiccards.info/scans/en/cs/85.jpg +End \ No newline at end of file diff --git a/res/cardsfolder/krovikan_rot.txt b/res/cardsfolder/krovikan_rot.txt new file mode 100644 index 00000000000..ce62f99dd6f --- /dev/null +++ b/res/cardsfolder/krovikan_rot.txt @@ -0,0 +1,10 @@ +Name:Krovikan Rot +ManaCost:2 B +Types:Instant +Text:no text +A:SP$Destroy | Cost$ 2 B | ValidTgts$ Creature.powerLE2 | TgtPrompt$ Select target creature with power 2 or less. | SpellDescription$ Destroy target creature with power 2 or less. +K:Recover:1 B B +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/krovikan_rot.jpg +SetInfo:CSP|Uncommon|http://magiccards.info/scans/en/cs/63.jpg +End \ No newline at end of file diff --git a/res/cardsfolder/resize.txt b/res/cardsfolder/resize.txt new file mode 100644 index 00000000000..f1d0f702c7d --- /dev/null +++ b/res/cardsfolder/resize.txt @@ -0,0 +1,10 @@ +Name:Resize +ManaCost:1 G +Types:Instant +Text:no text +A:SP$Pump | Cost$ 1 G | Tgt$ TgtC | NumAtt$ 3 | NumDef$ 3 | SpellDescription$ Target creature gets +3/+3 until end of turn. +K:Recover:1 G +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/resize.jpg +SetInfo:CSP|Uncommon|http://magiccards.info/scans/en/cs/117.jpg +End \ No newline at end of file diff --git a/res/cardsfolder/suns_bounty.txt b/res/cardsfolder/suns_bounty.txt new file mode 100644 index 00000000000..b7569f21a17 --- /dev/null +++ b/res/cardsfolder/suns_bounty.txt @@ -0,0 +1,10 @@ +Name:Sun's Bounty +ManaCost:1 W +Types:Instant +Text:no text +A:SP$GainLife | Cost$ 1 W | LifeAmount$ 4 | SpellDescription$ You gain 4 life. +K:Recover:1 W +SVar:Rarity:Common +SVar:Picture:http://www.wizards.com/global/images/magic/general/suns_bounty.jpg +SetInfo:CSP|Common|http://magiccards.info/scans/en/cs/18.jpg +End \ No newline at end of file diff --git a/src/forge/Card.java b/src/forge/Card.java index 32a3fd9cb3f..af9688dd418 100644 --- a/src/forge/Card.java +++ b/src/forge/Card.java @@ -870,12 +870,13 @@ public class Card extends MyObservable { // Add Keywords ArrayList kw = getKeyword(); - // Ripple + Dredge + Madness + CARDNAME is {color}. + // Ripple + Dredge + Madness + CARDNAME is {color} + Recover. for (int i = 0; i < kw.size(); i++) { if ((kw.get(i).startsWith("Ripple") && !sb.toString().contains("Ripple")) || (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).startsWith("CARDNAME is ") && !sb.toString().contains("CARDNAME is ")) + || (kw.get(i).startsWith("Recover") && !sb.toString().contains("Recover"))) { sb.append(kw.get(i).replace(":", " ")).append("\r\n"); } } @@ -915,6 +916,7 @@ public class Card extends MyObservable { } } + while (sb.toString().endsWith("\r\n")) { sb.delete(sb.lastIndexOf("\r\n"), sb.lastIndexOf("\r\n")+3); } diff --git a/src/forge/GameAction.java b/src/forge/GameAction.java index 30057046749..e2193dd6b99 100644 --- a/src/forge/GameAction.java +++ b/src/forge/GameAction.java @@ -62,6 +62,71 @@ public class GameAction { //must put card in OWNER's graveyard not controller's PlayerZone grave = AllZone.getZone(Constant.Zone.Graveyard, c.getOwner()); moveTo(grave, c); + + //Recover keyword + if(c.isType("Creature")) + { + for(final Card recoverable : grave.getCards()) + { + if(recoverable.hasStartOfKeyword("Recover")) + { + SpellAbility abRecover = new Ability(recoverable,"0") + { + @Override + public void resolve() + { + AllZone.GameAction.moveToHand(recoverable); + } + + @Override + public String getStackDescription() + { + StringBuilder SD = new StringBuilder(recoverable.getName()); + SD.append(" - Recover."); + + return SD.toString(); + } + }; + + String recoverCost = recoverable.getKeyword().get(recoverable.getKeywordPosition("Recover")).split(":")[1]; + Ability_Cost abCost = new Ability_Cost(recoverCost,recoverable.getName(),false); + abRecover.setPayCosts(abCost); + + StringBuilder question = new StringBuilder("Recover "); + question.append(recoverable.getName()); + question.append("("); + question.append(recoverable.getUniqueNumber()); + question.append(")"); + question.append("?"); + + boolean shouldRecoverForAI = false; + boolean shouldRecoverForHuman = false; + + if(c.getOwner().equals(AllZone.HumanPlayer)) + { + shouldRecoverForHuman = GameActionUtil.showYesNoDialog(recoverable, question.toString()); + } + else if(c.getOwner().equals(AllZone.ComputerPlayer)) + { + shouldRecoverForAI = ComputerUtil.canPayCost(abRecover); + } + + if(shouldRecoverForHuman) + { + AllZone.GameAction.playSpellAbility(abRecover); + } + else if(shouldRecoverForAI) + { + ComputerUtil.playStack(abRecover); + } + + if(!grave.hasChanged()) //If the controller declined Recovery or didn't pay the cost, exile the recoverable + { + AllZone.GameAction.exile(recoverable); + } + } + } + } } }