From dd73e512e64ec4a711e4a04350d80dcdd5ece2f6 Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 09:01:47 +0000 Subject: [PATCH] add Exile to Ability_Cost code (e.g. |Cost$Exile<1/Creature>|) --- src/forge/Ability_Cost.java | 53 ++++++++++++++ src/forge/ComputerUtil.java | 22 ++++++ src/forge/Cost_Payment.java | 137 +++++++++++++++++++++++++++++++++++- 3 files changed, 211 insertions(+), 1 deletion(-) diff --git a/src/forge/Ability_Cost.java b/src/forge/Ability_Cost.java index 7c2bb1ddc2e..a0a64670b30 100644 --- a/src/forge/Ability_Cost.java +++ b/src/forge/Ability_Cost.java @@ -11,6 +11,15 @@ public class Ability_Cost { public boolean getSacThis() { return sacThis; } private int sacAmount = 0; public int getSacAmount() { return sacAmount; } + + private boolean exileCost = false; + public boolean getExileCost() { return exileCost; } + private String exileType = ""; // or CARDNAME + public String getExileType() { return exileType; } + private boolean exileThis = false; + public boolean getExileThis() { return exileThis; } + private int exileAmount = 0; + public int getExileAmount() { return exileAmount; } private boolean tapCost = false; public boolean getTap() { return tapCost; } @@ -125,6 +134,17 @@ public class Ability_Cost { sacThis = (sacType.equals("CARDNAME")); } + String exileStr = "Exile<"; + if(parse.contains(exileStr)) { + exileCost = true; + String[] splitStr = abCostParse(parse, exileStr, 2); + parse = abUpdateParse(parse, exileStr); + + exileAmount = Integer.parseInt(splitStr[0]); + exileType = splitStr[1]; + exileThis = (exileType.equals("CARDNAME")); + } + String returnStr = "Return<"; if(parse.contains(returnStr)) { returnCost = true; @@ -244,6 +264,11 @@ public class Ability_Cost { first = false; } + if (exileCost){ + cost.append(exileString(first)); + first = false; + } + if (returnCost){ cost.append(returnString(first)); first = false; @@ -348,6 +373,11 @@ public class Ability_Cost { first = false; } + if (exileCost){ + cost.append(exileString(first)); + first = false; + } + if (returnCost){ cost.append(returnString(first)); first = false; @@ -380,6 +410,29 @@ public class Ability_Cost { } return cost.toString(); } + + public String exileString(boolean first) { + StringBuilder cost = new StringBuilder(); + if(first) { + if(isAbility) + cost.append("Exile "); + else + cost.append("exile "); + } + else { + cost.append(", exile "); + } + + if(exileType.equals("CARDNAME")) + cost.append(name); + else { + cost.append(exileAmount).append(" "); + cost.append(exileType); + if(exileAmount > 1) + cost.append("s"); + } + return cost.toString(); + } public String returnString(boolean first) { diff --git a/src/forge/ComputerUtil.java b/src/forge/ComputerUtil.java index f3834dc0baa..177ffdf3639 100644 --- a/src/forge/ComputerUtil.java +++ b/src/forge/ComputerUtil.java @@ -299,6 +299,23 @@ public class ComputerUtil return false; } + if (cost.getExileCost()){ + // if there's an exile in the cost, just because we can Pay it doesn't mean we want to. + if (!cost.getExileThis()){ + PlayerZone play = AllZone.getZone(Constant.Zone.Play, Constant.Player.Computer); + CardList typeList = new CardList(play.getCards()); + typeList = typeList.getValidCards(cost.getExileType().split(",")); + Card target = sa.getTargetCard(); + if (target != null && target.getController().equals(Constant.Player.Computer)) // don't exile the card we're pumping + typeList.remove(target); + + if (cost.getExileAmount() > typeList.size()) + return false; + } + else if (cost.getExileThis() && !AllZone.GameAction.isCardInPlay(card)) + return false; + } + if (cost.getReturnCost()){ // if there's a return in the cost, just because we can Pay it doesn't mean we want to. if (!cost.getReturnThis()){ @@ -556,6 +573,11 @@ public class ComputerUtil return typeList.get(0); } + static public Card chooseExileType(String type, Card activate, Card target){ + //logic is the same as sacrifice... + return chooseSacrificeType(type, activate, target); + } + static public Card chooseTapType(String type, Card activate, boolean tap, int index){ PlayerZone play = AllZone.getZone(Constant.Zone.Play, Constant.Player.Computer); CardList typeList = new CardList(play.getCards()); diff --git a/src/forge/Cost_Payment.java b/src/forge/Cost_Payment.java index 46d423164c3..ff578bd023e 100644 --- a/src/forge/Cost_Payment.java +++ b/src/forge/Cost_Payment.java @@ -23,6 +23,7 @@ public class Cost_Payment { private boolean payMana; private boolean paySubCounter; private boolean paySac; + private boolean payExile; private boolean payLife; private boolean payDiscard; private boolean payTapXType; @@ -39,6 +40,7 @@ public class Cost_Payment { public void setPayMana(boolean bPay){ payMana = bPay; } public void setPayDiscard(boolean bSac){ payDiscard = bSac; } public void setPaySac(boolean bSac){ paySac = bSac; } + public void setPayExile(boolean bExile) { payExile = bExile; } public void setPayTapXType(boolean bTapX) { payTapXType = bTapX; } public void setPayReturn(boolean bReturn){ payReturn = bReturn; } @@ -54,6 +56,7 @@ public class Cost_Payment { payMana = cost.hasNoManaCost(); paySubCounter = !cost.getSubCounter(); paySac = !cost.getSacCost(); + payExile = !cost.getExileCost(); payLife = !cost.getLifeCost(); payDiscard = !cost.getDiscardCost(); payTapXType = !cost.getTapXTypeCost(); @@ -138,6 +141,18 @@ public class Cost_Payment { return false; } + if (cost.getExileCost()){ + if (!cost.getExileThis()){ + CardList typeList = AllZoneUtil.getPlayerCardsInPlay(card.getController()); + + typeList = typeList.getValidCards(cost.getExileType().split(",")); + if (typeList.size() < cost.getExileAmount()) + return false; + } + else if (!AllZone.GameAction.isCardInPlay(card)) + return false; + } + if (cost.getReturnCost()){ if (!cost.getReturnThis()){ PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController()); @@ -259,6 +274,14 @@ public class Cost_Payment { return false; } + if (!payExile && cost.getExileCost()){ // exile stuff here + if (cost.getExileThis()) + changeInput.stopSetNext(exileThis(ability, this)); + else + changeInput.stopSetNext(exileType(ability, cost.getExileType(), this)); + return false; + } + if (!payReturn && cost.getReturnCost()){ // return stuff here if (cost.getReturnThis()) changeInput.stopSetNext(returnThis(ability, this)); @@ -313,12 +336,15 @@ public class Cost_Payment { // can't really unsacrifice things + //can't really unexile things + // can't really unreturn things } public void payComputerCosts(){ // make sure ComputerUtil.canPayAdditionalCosts() is updated when updating new Costs ArrayList sacCard = new ArrayList(); + ArrayList exileCard = new ArrayList(); ArrayList tapXCard = new ArrayList(); ArrayList returnCard = new ArrayList(); ability.setActivatingPlayer(Constant.Player.Computer); @@ -338,6 +364,21 @@ public class Cost_Payment { } } + // double check if something can be exiled here. Real check is in ComputerUtil.canPayAdditionalCosts() + if (cost.getExileCost()){ + if (cost.getExileThis()) + exileCard.add(card); + else{ + for(int i = 0; i < cost.getExileAmount(); i++) + exileCard.add(ComputerUtil.chooseExileType(cost.getExileType(), card, ability.getTargetCard())); + } + + if (exileCard.size() != cost.getExileAmount()){ + System.out.println("Couldn't find a valid card to exile for: "+card.getName()); + return; + } + } + if (cost.getReturnCost()){ if (cost.getReturnThis()) returnCard.add(card); @@ -417,6 +458,11 @@ public class Cost_Payment { AllZone.GameAction.sacrifice(c); } + if (cost.getExileCost()){ + for(Card c : sacCard) + AllZone.GameAction.exile(c); + } + if (cost.getReturnCost()){ for(Card c : returnCard) AllZone.GameAction.moveToHand(c); @@ -577,6 +623,95 @@ public class Cost_Payment { return target; }//sacrificeType() + public static Input exileThis(final SpellAbility spell, final Cost_Payment payment) { + Input target = new Input() { + @Override + public void showMessage() { + Card card = spell.getSourceCard(); + if(card.getController().equals(Constant.Player.Human) && AllZone.GameAction.isCardInPlay(card)) { + StringBuilder sb = new StringBuilder(); + sb.append(card.getName()); + sb.append(" - Exile?"); + Object[] possibleValues = {"Yes", "No"}; + Object choice = JOptionPane.showOptionDialog(null, sb.toString(), card.getName() + " - Cost", + JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, + null, possibleValues, possibleValues[0]); + if(choice.equals(0)) { + payment.setPayExile(true); + AllZone.GameAction.exile(card); + stop(); + payment.payCost(); + } + else{ + payment.setCancel(true); + stop(); + payment.payCost(); + } + } + } + }; + return target; + }//input_exile() + + public static Input exileType(final SpellAbility spell, final String type, final Cost_Payment payment){ + Input target = new Input() { + private CardList typeList; + private int nExiles = 0; + private int nNeeded = payment.getCost().getExileAmount(); + + @Override + public void showMessage() { + StringBuilder msg = new StringBuilder("Exile "); + int nLeft = nNeeded - nExiles; + msg.append(nLeft).append(" "); + msg.append(type); + if (nLeft > 1){ + msg.append("s"); + } + + PlayerZone play = AllZone.getZone(Constant.Zone.Play, spell.getSourceCard().getController()); + typeList = new CardList(play.getCards()); + typeList = typeList.getValidCards(type.split(",")); + AllZone.Display.showMessage(msg.toString()); + ButtonUtil.enableOnlyCancel(); + } + + @Override + public void selectButtonCancel() { + cancel(); + } + + @Override + public void selectCard(Card card, PlayerZone zone) { + if(typeList.contains(card)) { + nExiles++; + AllZone.GameAction.exile(card); + typeList.remove(card); + //in case nothing else to exile + if(nExiles == nNeeded) + done(); + else if (typeList.size() == 0) // this really shouldn't happen + cancel(); + else + showMessage(); + } + } + + public void done(){ + payment.setPayExile(true); + stop(); + payment.payCost(); + } + + public void cancel(){ + payment.setCancel(true); + stop(); + payment.payCost(); + } + }; + return target; + }//exileType() + public static Input input_tapXCost(final int nCards, final String cardType, final CardList cardList, SpellAbility sa, final Cost_Payment payment) { //final SpellAbility sp = sa; Input target = new Input() { @@ -721,5 +856,5 @@ public class Cost_Payment { } }; return target; - }//sacrificeType() + }//returnType() }