diff --git a/src/main/java/forge/card/cost/Cost.java b/src/main/java/forge/card/cost/Cost.java index 016ea4e9982..66ce7a4caa9 100644 --- a/src/main/java/forge/card/cost/Cost.java +++ b/src/main/java/forge/card/cost/Cost.java @@ -140,8 +140,7 @@ public class Cost { this.name = card != null ? card.getName() : ""; boolean xCantBe0 = false; - int amountX = 0; - + StringBuilder manaParts = new StringBuilder(); String[] parts = TextUtil.splitWithParenthesis(parse, ' ', '<', '>'); @@ -156,8 +155,6 @@ public class Cost { for(String part : parts) { if( "XCantBe0".equals(part) ) xCantBe0 = true; - else if ( "X".equals(part) ) - amountX++; else { CostPart cp = parseCostPart(part, tapCost, untapCost); if ( null != cp ) @@ -168,11 +165,10 @@ public class Cost { } - if ((amountX > 0) || manaParts.length() > 0) { - this.costParts.add(0, new CostPartMana(manaParts.toString(), amountX, xCantBe0)); + if (manaParts.length() > 0) { + this.costParts.add(0, new CostPartMana(new ManaCost(new ManaCostParser(manaParts.toString())), xCantBe0)); } - - + // inspect parts to set Sac, {T} and {Q} flags for (int iCp = 0; iCp < costParts.size(); iCp++) { CostPart cp = costParts.get(iCp); @@ -368,7 +364,7 @@ public class Cost { final ManaCostBeingPaid changedCost = new ManaCostBeingPaid(mana); changedCost.applySpellCostChange(sa); - ((CostPartMana)part).setAdjustedMana(changedCost.toString(false)); + ((CostPartMana)part).setAdjustedMana(changedCost.toManaCost()); costChanged = true; } } @@ -376,7 +372,7 @@ public class Cost { // Spells with a cost of 0 should be affected too final ManaCostBeingPaid changedCost = new ManaCostBeingPaid("0"); changedCost.applySpellCostChange(sa); - this.costParts.add(new CostPartMana(changedCost.toString(), 0, false)); + this.costParts.add(new CostPartMana(changedCost.toManaCost(), false)); } } diff --git a/src/main/java/forge/card/cost/CostPartMana.java b/src/main/java/forge/card/cost/CostPartMana.java index d962268e0fe..63bde67ed62 100644 --- a/src/main/java/forge/card/cost/CostPartMana.java +++ b/src/main/java/forge/card/cost/CostPartMana.java @@ -17,11 +17,11 @@ */ package forge.card.cost; -import com.google.common.base.Strings; - import forge.Card; import forge.FThreads; import forge.card.ability.AbilityUtils; +import forge.card.mana.ManaCost; +import forge.card.mana.ManaCostShard; import forge.card.spellability.SpellAbility; import forge.control.input.InputPayManaOfCostPayment; import forge.control.input.InputPayManaX; @@ -35,9 +35,8 @@ import forge.game.player.AIPlayer; */ public class CostPartMana extends CostPart { // "Leftover" - private String mana = ""; - private int amountX = 0; - private String adjustedMana = ""; + private final ManaCost cost; + private ManaCost adjustedCost; private boolean xCantBe0 = false; /** @@ -45,19 +44,9 @@ public class CostPartMana extends CostPart { * * @return the mana */ - public final String getMana() { + public final ManaCost getMana() { // Only used for Human to pay for non-X cost first - return this.mana; - } - - /** - * Sets the mana. - * - * @param sCost - * the new mana - */ - public final void setMana(final String sCost) { - this.mana = sCost; + return this.cost; } /** @@ -66,7 +55,7 @@ public class CostPartMana extends CostPart { * @return true, if successful */ public final boolean hasNoXManaCost() { - return this.amountX == 0; + return getAmountOfX() == 0; } /** @@ -75,36 +64,7 @@ public class CostPartMana extends CostPart { * @return the x mana */ public final int getAmountOfX() { - return this.amountX; - } - - /** - * Sets the x mana. - * - * @param xCost - * the new x mana - */ - public final void setAmountOfX(final int xCost) { - this.amountX = xCost; - } - - /** - * Gets the adjusted mana. - * - * @return the adjusted mana - */ - public final String getAdjustedMana() { - return this.adjustedMana; - } - - /** - * Sets the adjusted mana. - * - * @param adjustedMana - * the new adjusted mana - */ - public final void setAdjustedMana(final String adjustedMana) { - this.adjustedMana = adjustedMana; + return this.cost.getShardCount(ManaCostShard.X); } /** @@ -126,13 +86,13 @@ public class CostPartMana extends CostPart { * * @return the mana to pay */ - public final String getManaToPay() { + public final ManaCost getManaToPay() { // Only used for Human to pay for non-X cost first - if (!this.adjustedMana.equals("")) { - return this.adjustedMana; + if (this.adjustedCost != null ) { + return this.adjustedCost; } - return this.mana; + return this.cost; } @Override @@ -150,9 +110,8 @@ public class CostPartMana extends CostPart { * the amount * @param xCantBe0 TODO */ - public CostPartMana(final String mana, final int amount, boolean xCantBe0) { - this.mana = mana.trim(); - this.amountX = amount; + public CostPartMana(final ManaCost cost, boolean xCantBe0) { + this.cost = cost; this.setxCantBe0(xCantBe0); } @@ -163,13 +122,7 @@ public class CostPartMana extends CostPart { */ @Override public final String toString() { - final StringBuilder sb = new StringBuilder(); - - sb.append(Strings.repeat("X ", this.amountX)); - if ( sb.length() == 0 || mana != "0" ) - sb.append(this.mana); - - return sb.toString().trim(); + return cost.toString(); } /* @@ -228,7 +181,7 @@ public class CostPartMana extends CostPart { if(!inpPayment.isPaid()) return false; } else { - int x = AbilityUtils.calculateAmount(source, ability.getSVar("X"), ability); + int x = AbilityUtils.calculateAmount(source, "X", ability); source.setXManaCostPaid(x); } } @@ -244,6 +197,12 @@ public class CostPartMana extends CostPart { return new PaymentDecision(0); } - // Inputs - + /** + * TODO: Write javadoc for this method. + * @param manaCost + */ + public void setAdjustedMana(ManaCost manaCost) { + // this is set when static effects of LodeStone Golems or Thalias are applied + adjustedCost = manaCost; + } } diff --git a/src/main/java/forge/card/cost/CostPayment.java b/src/main/java/forge/card/cost/CostPayment.java index d48047ff435..706440f03e4 100644 --- a/src/main/java/forge/card/cost/CostPayment.java +++ b/src/main/java/forge/card/cost/CostPayment.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import forge.Card; +import forge.card.mana.ManaCost; import forge.card.spellability.SpellAbility; import forge.game.GameState; import forge.game.player.AIPlayer; @@ -179,7 +180,7 @@ public class CostPayment { final List parts = this.cost.getCostParts(); if (this.getCost().getCostMana() == null) { - parts.add(new CostPartMana("0", 0, false)); + parts.add(new CostPartMana(ManaCost.ZERO, false)); } Map, PaymentDecision> decisions = new HashMap, PaymentDecision>(); diff --git a/src/main/java/forge/card/cost/CostUtil.java b/src/main/java/forge/card/cost/CostUtil.java index e71ed8799ac..ae8ee6f676e 100644 --- a/src/main/java/forge/card/cost/CostUtil.java +++ b/src/main/java/forge/card/cost/CostUtil.java @@ -126,31 +126,19 @@ public class CostUtil { } public static Cost combineCosts(Cost cost1, Cost cost2) { - if (cost1 == null) { - if (cost2 == null) { - return null; - } else { - return cost2; - } - } - - if (cost2 == null) { - return cost1; - } + if (cost1 == null) return cost2; + if (cost2 == null) return cost1; + CostPartMana costPart2 = cost2.getCostMana(); for (final CostPart part : cost1.getCostParts()) { - if (!(part instanceof CostPartMana)) { + if (part instanceof CostPartMana && costPart2 != null) { + ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana()); + boolean xCanBe0 = ((CostPartMana) part).canXbe0() && costPart2.canXbe0(); + oldManaCost.combineManaCost(costPart2.getMana()); + + cost2.getCostParts().add(0, new CostPartMana(oldManaCost.toManaCost(), !xCanBe0)); + } else { cost2.getCostParts().add(part); - } else { - CostPartMana newCostMana = cost2.getCostMana(); - if (newCostMana != null) { - ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(part.toString()); - newCostMana.setAmountOfX(oldManaCost.getXcounter() + newCostMana.getAmountOfX()); - oldManaCost.combineManaCost(newCostMana.toString()); - newCostMana.setMana(oldManaCost.toString(false)); - } else { - cost2.getCostParts().add(0, part); - } } } return cost2; diff --git a/src/main/java/forge/card/mana/ManaCostBeingPaid.java b/src/main/java/forge/card/mana/ManaCostBeingPaid.java index dd4ebeb4803..839d1eadc4a 100644 --- a/src/main/java/forge/card/mana/ManaCostBeingPaid.java +++ b/src/main/java/forge/card/mana/ManaCostBeingPaid.java @@ -19,6 +19,7 @@ package forge.card.mana; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map.Entry; @@ -47,6 +48,47 @@ import forge.util.MyRandom; * @version $Id$ */ public class ManaCostBeingPaid { + private class ManaCostBeingPaidIterator implements IParserManaCost { + private Iterator mch; + private ManaCostShard nextShard; + private int remainingShards = 0; + + public ManaCostBeingPaidIterator() { + mch = unpaidShards.keySet().iterator(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public ManaCostShard next() { + if (remainingShards == 0) + throw new UnsupportedOperationException("All shards were depleted, call hasNext()"); + remainingShards--; + return nextShard; + } + + @Override + public boolean hasNext() { + if ( remainingShards > 0 ) return true; + if ( !mch.hasNext() ) return false; + + nextShard = mch.next(); + if ( nextShard == ManaCostShard.COLORLESS ) + return this.hasNext(); // skip colorless + remainingShards = unpaidShards.get(nextShard); + + return true; + } + + @Override + public int getTotalColorlessCost() { + return unpaidShards.get(ManaCostShard.COLORLESS); + } + } + // holds Mana_Part objects // ManaPartColor is stored before ManaPartColorless private final HashMap unpaidShards = new HashMap(); @@ -528,24 +570,19 @@ public class ManaCostBeingPaid { return true; } - /** - *

- * combineManaCost. - *

- * - * @param extra - * a {@link java.lang.String} object. - */ - public final void combineManaCost(final String extra) { - final ManaCost manaCost = new ManaCost(new ManaCostParser(extra)); - for (ManaCostShard shard : manaCost.getShards()) { + public final void combineManaCost(final ManaCost extra) { + for (ManaCostShard shard : extra.getShards()) { if (shard == ManaCostShard.X) { cntX++; } else { increaseShard(shard, 1); } } - increaseColorlessMana(manaCost.getGenericCost()); + increaseColorlessMana(extra.getGenericCost()); + } + + public final void combineManaCost(final String extra) { + combineManaCost(new ManaCost(new ManaCostParser(extra))); } /** @@ -609,6 +646,10 @@ public class ManaCostBeingPaid { } return cmc; } + + public ManaCost toManaCost() { + return new ManaCost(new ManaCostBeingPaidIterator()); + } /** *