From 76d445a6cb79cb32b8e816832ca35bc062d74993 Mon Sep 17 00:00:00 2001 From: Hellfish Date: Wed, 1 May 2013 14:23:29 +0000 Subject: [PATCH] *Added beginnings of ExileAndPay Cost (It currently assumes exactly *1* *creature* to exile from the *graveyard*. Good enough for the only card to use it. :P Will expand.) *Added Back from the Brink. --- .gitattributes | 2 + res/cardsfolder/b/back_from_the_brink.txt | 7 + src/main/java/forge/card/cost/Cost.java | 4 + .../java/forge/card/cost/CostExileAndPay.java | 160 ++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 res/cardsfolder/b/back_from_the_brink.txt create mode 100644 src/main/java/forge/card/cost/CostExileAndPay.java diff --git a/.gitattributes b/.gitattributes index ef1e24cd11a..8369f485e04 100644 --- a/.gitattributes +++ b/.gitattributes @@ -701,6 +701,7 @@ res/cardsfolder/a/azors_elocutors.txt -text res/cardsfolder/a/azure_drake.txt svneol=native#text/plain res/cardsfolder/a/azure_mage.txt svneol=native#text/plain res/cardsfolder/a/azusa_lost_but_seeking.txt svneol=native#text/plain +res/cardsfolder/b/back_from_the_brink.txt -text res/cardsfolder/b/back_to_basics.txt svneol=native#text/plain res/cardsfolder/b/back_to_nature.txt svneol=native#text/plain res/cardsfolder/b/backfire.txt svneol=native#text/plain @@ -13944,6 +13945,7 @@ src/main/java/forge/card/cost/Cost.java svneol=native#text/plain src/main/java/forge/card/cost/CostDamage.java -text src/main/java/forge/card/cost/CostDiscard.java -text src/main/java/forge/card/cost/CostExile.java -text +src/main/java/forge/card/cost/CostExileAndPay.java -text src/main/java/forge/card/cost/CostGainLife.java -text src/main/java/forge/card/cost/CostMill.java -text src/main/java/forge/card/cost/CostPart.java -text diff --git a/res/cardsfolder/b/back_from_the_brink.txt b/res/cardsfolder/b/back_from_the_brink.txt new file mode 100644 index 00000000000..2c137884b68 --- /dev/null +++ b/res/cardsfolder/b/back_from_the_brink.txt @@ -0,0 +1,7 @@ +Name:Back from the Brink +ManaCost:4 U U +Types:Enchantment +Text:no text +A:AB$ CopyPermanent | Cost$ ExileAndPay | Defined$ Exiled | SorcerySpeed$ True | SpellDescription$ Put a token onto the battlefield that's a copy of that card. Activate this ability only any time you could cast a sorcery. +SetInfo:ISD Rare +Oracle:Exile a creature card from your graveyard and pay its mana cost: Put a token onto the battlefield that's a copy of that card. Activate this ability only any time you could cast a sorcery. diff --git a/src/main/java/forge/card/cost/Cost.java b/src/main/java/forge/card/cost/Cost.java index 606e61d050b..352ebcdae4e 100644 --- a/src/main/java/forge/card/cost/Cost.java +++ b/src/main/java/forge/card/cost/Cost.java @@ -300,6 +300,10 @@ public class Cost { final String description = splitStr.length > 2 ? splitStr[2] : null; return new CostExile(splitStr[0], splitStr[1], description, ZoneType.Graveyard, true); } + + if(parse.equals("ExileAndPay")) { + return new CostExileAndPay(); + } if(parse.startsWith("Return<")) { final String[] splitStr = abCostParse(parse, 3); diff --git a/src/main/java/forge/card/cost/CostExileAndPay.java b/src/main/java/forge/card/cost/CostExileAndPay.java new file mode 100644 index 00000000000..b3120f6e1cd --- /dev/null +++ b/src/main/java/forge/card/cost/CostExileAndPay.java @@ -0,0 +1,160 @@ +package forge.card.cost; + +import java.util.ArrayList; +import java.util.List; + +import forge.Card; +import forge.CardLists; +import forge.card.spellability.SpellAbility; +import forge.card.spellability.SpellAbilityStackInstance; +import forge.card.spellability.SpellPermanent; +import forge.game.GameState; +import forge.game.ai.ComputerUtilCard; +import forge.game.ai.ComputerUtilCost; +import forge.game.player.AIPlayer; +import forge.game.zone.ZoneType; +import forge.gui.GuiChoose; + +/** + * TODO: Write javadoc for this type. + * + */ +public class CostExileAndPay extends CostPartWithList { + + /* (non-Javadoc) + * @see forge.card.cost.CostPartWithList#doPayment(forge.card.spellability.SpellAbility, forge.Card) + */ + @Override + protected void doPayment(SpellAbility ability, Card targetCard) { + ability.getActivatingPlayer().getGame().getAction().exile(targetCard); + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPartWithList#getHashForList() + */ + @Override + public String getHashForList() { + return "Exiled"; + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility) + */ + @Override + public boolean canPay(SpellAbility ability) { + return CardLists.getValidCards(ability.getActivatingPlayer().getZone(ZoneType.Graveyard), "Creature", ability.getActivatingPlayer(), ability.getSourceCard()).size() > 0; + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#decideAIPayment(forge.game.player.AIPlayer, forge.card.spellability.SpellAbility, forge.Card) + */ + @Override + public PaymentDecision decideAIPayment(AIPlayer ai, SpellAbility ability, Card source) { + List validGrave = CardLists.getValidCards(ability.getActivatingPlayer().getZone(ZoneType.Graveyard), "Creature", ability.getActivatingPlayer(), ability.getSourceCard()); + + if(validGrave.size() == 0) + { + return null; + } + + Card bestCard = null; + int bestScore = 0; + + for(Card candidate : validGrave) + { + boolean selectable = false; + for(SpellAbility sa : candidate.getSpellAbilities()) + { + if(sa instanceof SpellPermanent) + { + if(ComputerUtilCost.canPayCost(sa, ai)) + { + selectable = true; + } + } + } + + if(!selectable) + { + continue; + } + + int candidateScore = ComputerUtilCard.evaluateCreature(candidate); + if(candidateScore > bestScore) + { + bestScore = candidateScore; + bestCard = candidate; + } + } + + return bestCard == null ? null : new PaymentDecision(bestCard); + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility, forge.game.GameState) + */ + @Override + public boolean payHuman(SpellAbility ability, GameState game) { + List validGrave = CardLists.getValidCards(ability.getActivatingPlayer().getZone(ZoneType.Graveyard), "Creature", ability.getActivatingPlayer(), ability.getSourceCard()); + + Card selectedCard = GuiChoose.oneOrNone("Choose a creature card to exile.", validGrave); + if(selectedCard == null) + { + return false; + } + + List options = new ArrayList(); + for(SpellAbility sa : selectedCard.getSpellAbilities()) + { + if(sa instanceof SpellPermanent) + { + options.add(sa.getPayCosts()); + } + } + + Cost selectedCost = GuiChoose.oneOrNone("Choose a cost", options); + if(selectedCost == null) + { + return false; + } + + final CostPayment pay = new CostPayment(selectedCost, ability); + pay.payCost(game); + if(!pay.isFullyPaid()) + { + return false; + } + + executePayment(ability,selectedCard); + + return true; + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#payAI(forge.card.cost.PaymentDecision, forge.game.player.AIPlayer, forge.card.spellability.SpellAbility, forge.Card) + */ + @Override + public void payAI(PaymentDecision decision, AIPlayer ai, SpellAbility ability, Card source) { + for (final Card c : decision.cards) { + executePayment(ability, c); + for(SpellAbility sa : c.getSpellAbilities()) + { + if(sa instanceof SpellPermanent && ComputerUtilCost.canPayCost(sa, ai)) + { + final CostPayment pay = new CostPayment(sa.getPayCosts(), sa); + pay.payComputerCosts(ai, ai.getGame()); + } + } + } + this.reportPaidCardsTo(ability); + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#toString() + */ + @Override + public String toString() { + return "Exile a creature card from your graveyard and pay it's mana cost"; + } + +}