diff --git a/.gitattributes b/.gitattributes index b4cba7c7992..e969f02de01 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9704,6 +9704,7 @@ src/main/java/forge/card/cost/Cost.java svneol=native#text/plain src/main/java/forge/card/cost/CostDiscard.java -text src/main/java/forge/card/cost/CostExile.java -text src/main/java/forge/card/cost/CostMana.java -text +src/main/java/forge/card/cost/CostMill.java -text src/main/java/forge/card/cost/CostPart.java -text src/main/java/forge/card/cost/CostPartWithList.java -text src/main/java/forge/card/cost/CostPayLife.java -text diff --git a/res/cardsfolder/m/millikin.txt b/res/cardsfolder/m/millikin.txt index a17fbb332d4..0b055b7f20c 100644 --- a/res/cardsfolder/m/millikin.txt +++ b/res/cardsfolder/m/millikin.txt @@ -3,8 +3,7 @@ ManaCost:2 Types:Artifact Creature Construct Text:no text PT:0/1 -A:AB$ Mill | Cost$ T | NumCards$ 1 | Defined$ You | SubAbility$ SVar=DBMana | CostDesc$ Tap, | SpellDescription$ Put the top card of your library into your graveyard: -SVar:DBMana:DB$Mana | Produced$ 1 | SpellDescription$ Add 1 to your mana pool. +A:AB$ Mana | Cost$ T Mill<1> | Produced$ 1 | SpellDescription$ Add 1 to your mana pool. SVar:RemAIDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/millikin.jpg diff --git a/src/main/java/forge/card/cost/Cost.java b/src/main/java/forge/card/cost/Cost.java index 26eefe69cdb..4f0c1c319c8 100644 --- a/src/main/java/forge/card/cost/Cost.java +++ b/src/main/java/forge/card/cost/Cost.java @@ -91,6 +91,7 @@ public class Cost { private final static String subStr = "SubCounter<"; private final static String addStr = "AddCounter<"; private final static String lifeStr = "PayLife<"; + private final static String millStr = "Mill<"; private final static String discStr = "Discard<"; private final static String sacStr = "Sac<"; private final static String exileStr = "Exile<"; @@ -149,6 +150,13 @@ public class Cost { costParts.add(new CostPayLife(splitStr[0])); } + while (parse.contains(millStr)) { + // PayLife + String[] splitStr = abCostParse(parse, millStr, 1); + parse = abUpdateParse(parse, millStr); + + costParts.add(new CostMill(splitStr[0])); + } while (parse.contains(discStr)) { // Discard diff --git a/src/main/java/forge/card/cost/CostMill.java b/src/main/java/forge/card/cost/CostMill.java new file mode 100644 index 00000000000..a4f94de1413 --- /dev/null +++ b/src/main/java/forge/card/cost/CostMill.java @@ -0,0 +1,162 @@ +package forge.card.cost; + +import java.util.Iterator; + +import forge.AllZone; +import forge.AllZoneUtil; +import forge.Card; +import forge.CardList; +import forge.Constant; +import forge.GameActionUtil; +import forge.Player; +import forge.PlayerZone; +import forge.card.abilityFactory.AbilityFactory; +import forge.card.spellability.SpellAbility; + +/** + * This is for the "Mill" Cost. Putting cards from the top of your library into your graveyard as a cost. + * This Cost doesn't appear on very many cards, but might appear in more in the future. + * This will show up in the form of Mill<1> + */ +public class CostMill extends CostPartWithList { + + public CostMill(String amount){ + this.amount = amount; + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility, forge.Card, forge.Player, forge.card.cost.Cost) + */ + @Override + public boolean canPay(SpellAbility ability, Card source, Player activator, Cost cost) { + PlayerZone zone = AllZone.getZone(Constant.Zone.Library, activator); + + Integer i = convertAmount(); + + if (i == null){ + String sVar = source.getSVar(amount); + if (sVar.equals("XChoice")){ + return true; + } + + i = AbilityFactory.calculateAmount(source, amount, ability); + } + + return i < zone.size(); + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#decideAIPayment(forge.card.spellability.SpellAbility, forge.Card, forge.card.cost.Cost_Payment) + */ + @Override + public boolean decideAIPayment(SpellAbility ability, Card source, Cost_Payment payment) { + resetList(); + + Integer c = convertAmount(); + if (c == null){ + String sVar = source.getSVar(amount); + // Generalize this + if (sVar.equals("XChoice")){ + return false; + } + + c = AbilityFactory.calculateAmount(source, amount, ability); + } + + list = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getComputerPlayer(), c); + + if (list == null || list.size() < c) + return false; + + return true; + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#payAI(forge.card.spellability.SpellAbility, forge.Card, forge.card.cost.Cost_Payment) + */ + @Override + public void payAI(SpellAbility ability, Card source, Cost_Payment payment) { + for (Card c : list) + AllZone.getGameAction().moveToGraveyard(c); + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility, forge.Card, forge.card.cost.Cost_Payment) + */ + @Override + public boolean payHuman(SpellAbility ability, Card source, Cost_Payment payment) { + String amount = getAmount(); + Integer c = convertAmount(); + Player activator = ability.getActivatingPlayer(); + + if (c == null){ + String sVar = source.getSVar(amount); + // Generalize this + if (sVar.equals("XChoice")){ + c = CostUtil.chooseXValue(source, list.size()); + } + else{ + c = AbilityFactory.calculateAmount(source, amount, ability); + } + } + CardList list = AllZoneUtil.getPlayerCardsInLibrary(activator, c); + + if (list == null || list.size() > c){ + // I don't believe this is possible + payment.cancelCost(); + return false; + } + + StringBuilder sb = new StringBuilder(); + sb.append("Mill ").append(c).append(" cards from your library?"); + + boolean doMill = GameActionUtil.showYesNoDialog(source, sb.toString()); + if (doMill){ + resetList(); + Iterator itr = list.iterator(); + while(itr.hasNext()){ + Card card = (Card)itr.next(); + addToList(card); + AllZone.getGameAction().moveToGraveyard(card); + } + addListToHash(ability, "Milled"); + payment.paidCost(this); + return false; + } + else{ + payment.cancelCost(); + return false; + } + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + Integer i = convertAmount(); + sb.append("Put the top "); + + if (i != null) { + sb.append(i); + } else { + sb.append(amount); + } + + sb.append(" card"); + if(i == null || i > 1) { + sb.append("s"); + } + sb.append(" from the top of your library into your graveyard"); + + return sb.toString(); + } + + /* (non-Javadoc) + * @see forge.card.cost.CostPart#refund(forge.Card) + */ + @Override + public void refund(Card source) { + } +}