diff --git a/Mage/src/mage/abilities/costs/CompositeCost.java b/Mage/src/mage/abilities/costs/CompositeCost.java index dd04d8a4a5..6c243ccc5e 100644 --- a/Mage/src/mage/abilities/costs/CompositeCost.java +++ b/Mage/src/mage/abilities/costs/CompositeCost.java @@ -23,6 +23,11 @@ public class CompositeCost implements Cost { this.description = cost.description; } + @Override + public UUID getId() { + throw new RuntimeException("Not supported method"); + } + @Override public String getText() { return description; diff --git a/Mage/src/mage/abilities/costs/Cost.java b/Mage/src/mage/abilities/costs/Cost.java index 5303b570ed..53eb10c8d8 100644 --- a/Mage/src/mage/abilities/costs/Cost.java +++ b/Mage/src/mage/abilities/costs/Cost.java @@ -37,6 +37,7 @@ import mage.target.Targets; public interface Cost extends Serializable { + public UUID getId(); public String getText(); public boolean canPay(UUID sourceId, UUID controllerId, Game game); public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana); diff --git a/Mage/src/mage/abilities/costs/CostImpl.java b/Mage/src/mage/abilities/costs/CostImpl.java index 7aed4b6841..c18d0328d4 100644 --- a/Mage/src/mage/abilities/costs/CostImpl.java +++ b/Mage/src/mage/abilities/costs/CostImpl.java @@ -31,8 +31,11 @@ package mage.abilities.costs; import mage.target.Target; import mage.target.Targets; +import java.util.UUID; + public abstract class CostImpl> implements Cost { + protected UUID id; protected String text; protected boolean paid; protected Targets targets; @@ -41,11 +44,13 @@ public abstract class CostImpl> implements Cost { public abstract T copy(); public CostImpl() { + id = UUID.randomUUID(); paid = false; targets = new Targets(); } public CostImpl(final CostImpl cost) { + this.id = cost.id; this.text = cost.text; this.paid = cost.paid; this.targets = cost.targets.copy(); @@ -82,4 +87,9 @@ public abstract class CostImpl> implements Cost { paid = true; } + @Override + public UUID getId() { + return this.id; + } + } diff --git a/Mage/src/mage/abilities/costs/CostsImpl.java b/Mage/src/mage/abilities/costs/CostsImpl.java index d5614b596b..77866656b9 100644 --- a/Mage/src/mage/abilities/costs/CostsImpl.java +++ b/Mage/src/mage/abilities/costs/CostsImpl.java @@ -51,7 +51,12 @@ public class CostsImpl extends ArrayList implements Costs } } - @Override + @Override + public UUID getId() { + throw new RuntimeException("Not supported method"); + } + + @Override public String getText() { if (this.size() == 0) return ""; diff --git a/Mage/src/mage/abilities/costs/mana/ManaCostImpl.java b/Mage/src/mage/abilities/costs/mana/ManaCostImpl.java index b15b68982e..71e002caf4 100644 --- a/Mage/src/mage/abilities/costs/mana/ManaCostImpl.java +++ b/Mage/src/mage/abilities/costs/mana/ManaCostImpl.java @@ -29,6 +29,7 @@ package mage.abilities.costs.mana; import java.util.UUID; + import mage.Constants.ColoredManaSymbol; import mage.Mana; import mage.abilities.Ability; @@ -40,269 +41,269 @@ import mage.players.Player; public abstract class ManaCostImpl> extends CostImpl implements ManaCost { - protected Mana payment; - protected Mana cost; - protected ManaOptions options; + protected Mana payment; + protected Mana cost; + protected ManaOptions options; - @Override - public abstract T copy(); + @Override + public abstract T copy(); - public ManaCostImpl() { - payment = new Mana(); - options = new ManaOptions(); - } + public ManaCostImpl() { + payment = new Mana(); + options = new ManaOptions(); + } - public ManaCostImpl(final ManaCostImpl manaCost) { - super(manaCost); - this.payment = manaCost.payment.copy(); - this.cost = manaCost.cost.copy(); - this.options = manaCost.options.copy(); - } + public ManaCostImpl(final ManaCostImpl manaCost) { + super(manaCost); + this.payment = manaCost.payment.copy(); + this.cost = manaCost.cost.copy(); + this.options = manaCost.options.copy(); + } - @Override - public Mana getPayment() { - return payment; - } + @Override + public Mana getPayment() { + return payment; + } - @Override - public Mana getMana() { - return cost; - } + @Override + public Mana getMana() { + return cost; + } - @Override - public ManaOptions getOptions() { - return options; - } + @Override + public ManaOptions getOptions() { + return options; + } - @Override - public void clearPaid() { - payment.clear(); - super.clearPaid(); - } + @Override + public void clearPaid() { + payment.clear(); + super.clearPaid(); + } - protected boolean assignColored(Ability ability, Game game, ManaPool pool, ColoredManaSymbol mana) { - // first check special mana - switch (mana) { - case B: - if (payConditionalBlack(ability, game, pool)) return true; - if (pool.getBlack() > 0) { - this.payment.addBlack(); - pool.removeBlack(); - return true; - } - break; - case U: - if (payConditionalBlue(ability, game, pool)) return true; - if (pool.getBlue() > 0) { - this.payment.addBlue(); - pool.removeBlue(); - return true; - } - break; - case W: - if (payConditionalWhite(ability, game, pool)) return true; - if (pool.getWhite() > 0) { - this.payment.addWhite(); - pool.removeWhite(); - return true; - } - break; - case G: - if (payConditionalGreen(ability, game, pool)) return true; - if (pool.getGreen() > 0) { - this.payment.addGreen(); - pool.removeGreen(); - return true; - } - break; - case R: - if (payConditionalRed(ability, game, pool)) return true; - if (pool.getRed() > 0) { - this.payment.addRed(); - pool.removeRed(); - return true; - } - break; - } - return false; - } + protected boolean assignColored(Ability ability, Game game, ManaPool pool, ColoredManaSymbol mana) { + // first check special mana + switch (mana) { + case B: + if (payConditionalBlack(ability, game, pool)) return true; + if (pool.getBlack() > 0) { + this.payment.addBlack(); + pool.removeBlack(); + return true; + } + break; + case U: + if (payConditionalBlue(ability, game, pool)) return true; + if (pool.getBlue() > 0) { + this.payment.addBlue(); + pool.removeBlue(); + return true; + } + break; + case W: + if (payConditionalWhite(ability, game, pool)) return true; + if (pool.getWhite() > 0) { + this.payment.addWhite(); + pool.removeWhite(); + return true; + } + break; + case G: + if (payConditionalGreen(ability, game, pool)) return true; + if (pool.getGreen() > 0) { + this.payment.addGreen(); + pool.removeGreen(); + return true; + } + break; + case R: + if (payConditionalRed(ability, game, pool)) return true; + if (pool.getRed() > 0) { + this.payment.addRed(); + pool.removeRed(); + return true; + } + break; + } + return false; + } - private boolean payConditionalRed(Ability ability, Game game, ManaPool pool) { - if (pool.getConditionalRed(ability, game) > 0) { - this.payment.addRed(); - pool.removeConditionalRed(ability, game); - return true; - } - return false; - } + private boolean payConditionalRed(Ability ability, Game game, ManaPool pool) { + if (pool.getConditionalRed(ability, game) > 0) { + this.payment.addRed(); + pool.removeConditionalRed(ability, game); + return true; + } + return false; + } - private boolean payConditionalGreen(Ability ability, Game game, ManaPool pool) { - if (pool.getConditionalGreen(ability, game) > 0) { - this.payment.addGreen(); - pool.removeConditionalGreen(ability, game); - return true; - } - return false; - } + private boolean payConditionalGreen(Ability ability, Game game, ManaPool pool) { + if (pool.getConditionalGreen(ability, game) > 0) { + this.payment.addGreen(); + pool.removeConditionalGreen(ability, game); + return true; + } + return false; + } - private boolean payConditionalWhite(Ability ability, Game game, ManaPool pool) { - if (pool.getConditionalWhite(ability, game) > 0) { - this.payment.addWhite(); - pool.removeConditionalWhite(ability, game); - return true; - } - return false; - } + private boolean payConditionalWhite(Ability ability, Game game, ManaPool pool) { + if (pool.getConditionalWhite(ability, game) > 0) { + this.payment.addWhite(); + pool.removeConditionalWhite(ability, game); + return true; + } + return false; + } - private boolean payConditionalBlue(Ability ability, Game game, ManaPool pool) { - if (pool.getConditionalBlue(ability, game) > 0) { - this.payment.addBlue(); - pool.removeConditionalBlue(ability, game); - return true; - } - return false; - } + private boolean payConditionalBlue(Ability ability, Game game, ManaPool pool) { + if (pool.getConditionalBlue(ability, game) > 0) { + this.payment.addBlue(); + pool.removeConditionalBlue(ability, game); + return true; + } + return false; + } - private boolean payConditionalBlack(Ability ability, Game game, ManaPool pool) { - if (pool.getConditionalBlack(ability, game) > 0) { - this.payment.addBlack(); - pool.removeConditionalBlack(ability, game); - return true; - } - return false; - } + private boolean payConditionalBlack(Ability ability, Game game, ManaPool pool) { + if (pool.getConditionalBlack(ability, game) > 0) { + this.payment.addBlack(); + pool.removeConditionalBlack(ability, game); + return true; + } + return false; + } - private boolean payConditionalColorless(Ability ability, Game game, ManaPool pool) { - if (pool.getConditionalColorless(ability, game) > 0) { - this.payment.addColorless(); - pool.removeConditionalColorless(ability, game); - return true; - } - return false; - } + private boolean payConditionalColorless(Ability ability, Game game, ManaPool pool) { + if (pool.getConditionalColorless(ability, game) > 0) { + this.payment.addColorless(); + pool.removeConditionalColorless(ability, game); + return true; + } + return false; + } - protected boolean assignColorless(Ability ability, Game game, ManaPool pool, int mana) { - int conditionalCount = pool.getConditionalCount(ability, game, null); - while (mana > payment.count() && (pool.count() > 0 || conditionalCount > 0)) { - if (payConditionalColorless(ability, game, pool)) continue; - if (payConditionalBlack(ability, game, pool)) continue; - if (payConditionalBlue(ability, game, pool)) continue; - if (payConditionalWhite(ability, game, pool)) continue; - if (payConditionalGreen(ability, game, pool)) continue; - if (payConditionalRed(ability, game, pool)) continue; + protected boolean assignColorless(Ability ability, Game game, ManaPool pool, int mana) { + int conditionalCount = pool.getConditionalCount(ability, game, null); + while (mana > payment.count() && (pool.count() > 0 || conditionalCount > 0)) { + if (payConditionalColorless(ability, game, pool)) continue; + if (payConditionalBlack(ability, game, pool)) continue; + if (payConditionalBlue(ability, game, pool)) continue; + if (payConditionalWhite(ability, game, pool)) continue; + if (payConditionalGreen(ability, game, pool)) continue; + if (payConditionalRed(ability, game, pool)) continue; - if (pool.getColorless() > 0) { - this.payment.addColorless(); - pool.removeColorless(); - continue; - } - if (pool.getBlack() > 0) { - this.payment.addBlack(); - pool.removeBlack(); - continue; - } - if (pool.getBlue() > 0) { - this.payment.addBlue(); - pool.removeBlue(); - continue; - } - if (pool.getWhite() > 0) { - this.payment.addWhite(); - pool.removeWhite(); - continue; - } - if (pool.getGreen() > 0) { - this.payment.addGreen(); - pool.removeGreen(); - continue; - } - if (pool.getRed() > 0) { - this.payment.addRed(); - pool.removeRed(); - continue; - } - break; - } - return mana > payment.count(); - } + if (pool.getColorless() > 0) { + this.payment.addColorless(); + pool.removeColorless(); + continue; + } + if (pool.getBlack() > 0) { + this.payment.addBlack(); + pool.removeBlack(); + continue; + } + if (pool.getBlue() > 0) { + this.payment.addBlue(); + pool.removeBlue(); + continue; + } + if (pool.getWhite() > 0) { + this.payment.addWhite(); + pool.removeWhite(); + continue; + } + if (pool.getGreen() > 0) { + this.payment.addGreen(); + pool.removeGreen(); + continue; + } + if (pool.getRed() > 0) { + this.payment.addRed(); + pool.removeRed(); + continue; + } + break; + } + return mana > payment.count(); + } - protected boolean isColoredPaid(ColoredManaSymbol mana) { - switch (mana) { - case B: - if (this.payment.getBlack() > 0) - return true; - case U: - if (this.payment.getBlue() > 0) - return true; - case W: - if (this.payment.getWhite() > 0) - return true; - case G: - if (this.payment.getGreen() > 0) - return true; - case R: - if (this.payment.getRed() > 0) - return true; - } - return false; - } + protected boolean isColoredPaid(ColoredManaSymbol mana) { + switch (mana) { + case B: + if (this.payment.getBlack() > 0) + return true; + case U: + if (this.payment.getBlue() > 0) + return true; + case W: + if (this.payment.getWhite() > 0) + return true; + case G: + if (this.payment.getGreen() > 0) + return true; + case R: + if (this.payment.getRed() > 0) + return true; + } + return false; + } - protected boolean isColorlessPaid(int mana) { - if (this.payment.count() >= mana) - return true; - return false; - } + protected boolean isColorlessPaid(int mana) { + if (this.payment.count() >= mana) + return true; + return false; + } - @Override - public boolean canPay(UUID sourceId, UUID controllerId, Game game) { - return true; - } + @Override + public boolean canPay(UUID sourceId, UUID controllerId, Game game) { + return true; + } - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { - if (noMana) { - setPaid(); - return true; - } - Player player = game.getPlayer(controllerId); - assignPayment(game, ability, player.getManaPool()); - while (!isPaid()) { - if (player.playMana(this, game)) - assignPayment(game, ability, player.getManaPool()); - else - return false; - } - return true; - } + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + if (noMana) { + setPaid(); + return true; + } + Player player = game.getPlayer(controllerId); + assignPayment(game, ability, player.getManaPool()); + while (!isPaid()) { + if (player.playMana(this, game)) + assignPayment(game, ability, player.getManaPool()); + else + return false; + } + return true; + } - @Override - public void setPaid() { - this.paid = true; - } + @Override + public void setPaid() { + this.paid = true; + } - @Override - public void setPayment(Mana mana) { - this.payment.add(mana); - } + @Override + public void setPayment(Mana mana) { + this.payment.add(mana); + } - protected void addColoredOption(ColoredManaSymbol symbol) { - switch (symbol) { - case B: - this.options.add(Mana.BlackMana); - break; - case U: - this.options.add(Mana.BlueMana); - break; - case W: - this.options.add(Mana.WhiteMana); - break; - case R: - this.options.add(Mana.RedMana); - break; - case G: - this.options.add(Mana.GreenMana); - break; - } - } + protected void addColoredOption(ColoredManaSymbol symbol) { + switch (symbol) { + case B: + this.options.add(Mana.BlackMana); + break; + case U: + this.options.add(Mana.BlueMana); + break; + case W: + this.options.add(Mana.WhiteMana); + break; + case R: + this.options.add(Mana.RedMana); + break; + case G: + this.options.add(Mana.GreenMana); + break; + } + } } diff --git a/Mage/src/mage/abilities/costs/mana/ManaCostsImpl.java b/Mage/src/mage/abilities/costs/mana/ManaCostsImpl.java index a8a091d89c..d2edd98b11 100644 --- a/Mage/src/mage/abilities/costs/mana/ManaCostsImpl.java +++ b/Mage/src/mage/abilities/costs/mana/ManaCostsImpl.java @@ -45,122 +45,126 @@ import java.util.*; */ public class ManaCostsImpl extends ArrayList implements ManaCosts { - private static Map costs = new HashMap(); + protected UUID id; - public ManaCostsImpl() { - } + private static Map costs = new HashMap(); - public ManaCostsImpl(String mana) { - load(mana); - } + public ManaCostsImpl() { + this.id = UUID.randomUUID(); + } - public ManaCostsImpl(final ManaCostsImpl costs) { - for (T cost : costs) { - this.add((T) cost.copy()); - } - } + public ManaCostsImpl(String mana) { + this.id = UUID.randomUUID(); + load(mana); + } - @Override - public boolean add(ManaCost cost) { - if (cost instanceof ManaCosts) { - for (ManaCost manaCost : (ManaCosts) cost) { - super.add((T) manaCost); - } - return true; - } else { - return super.add((T) cost); - } - } + public ManaCostsImpl(final ManaCostsImpl costs) { + this.id = costs.id; + for (T cost : costs) { + this.add((T) cost.copy()); + } + } - @Override - public int convertedManaCost() { - int total = 0; - for (ManaCost cost : this) { - total += cost.convertedManaCost(); - } - return total; - } + @Override + public boolean add(ManaCost cost) { + if (cost instanceof ManaCosts) { + for (ManaCost manaCost : (ManaCosts) cost) { + super.add((T) manaCost); + } + return true; + } else { + return super.add((T) cost); + } + } - @Override - public Mana getMana() { - Mana mana = new Mana(); - for (ManaCost cost : this) { - mana.add(cost.getMana()); - } - return mana; - } + @Override + public int convertedManaCost() { + int total = 0; + for (ManaCost cost : this) { + total += cost.convertedManaCost(); + } + return total; + } - @Override - public Mana getPayment() { - Mana manaTotal = new Mana(); - for (ManaCost cost : this) { - manaTotal.add(cost.getPayment()); - } - return manaTotal; - } + @Override + public Mana getMana() { + Mana mana = new Mana(); + for (ManaCost cost : this) { + mana.add(cost.getMana()); + } + return mana; + } - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { - if (this.size() == 0 || noMana) { - setPaid(); - return true; - } + @Override + public Mana getPayment() { + Mana manaTotal = new Mana(); + for (ManaCost cost : this) { + manaTotal.add(cost.getPayment()); + } + return manaTotal; + } - Player player = game.getPlayer(controllerId); - assignPayment(game, ability, player.getManaPool()); - while (!isPaid()) { - if (player.playMana(this.getUnpaid(), game)) - assignPayment(game, ability, player.getManaPool()); - else - return false; - } - for (ManaCost cost : this.getUnpaidVariableCosts()) { - VariableManaCost vCost = (VariableManaCost) cost; - while (!vCost.isPaid()) { - if (player.playXMana(vCost, (ManaCosts) this, game)) - vCost.assignPayment(game, ability, player.getManaPool()); - else - return false; - } - } - return true; - } + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + if (this.size() == 0 || noMana) { + setPaid(); + return true; + } - @Override - public ManaCosts getUnpaid() { - ManaCosts unpaid = new ManaCostsImpl(); - for (T cost : this) { - if (!(cost instanceof VariableManaCost) && !cost.isPaid()) - unpaid.add((T) cost.getUnpaid()); - } - return unpaid; - } + Player player = game.getPlayer(controllerId); + assignPayment(game, ability, player.getManaPool()); + while (!isPaid()) { + if (player.playMana(this.getUnpaid(), game)) + assignPayment(game, ability, player.getManaPool()); + else + return false; + } + for (ManaCost cost : this.getUnpaidVariableCosts()) { + VariableManaCost vCost = (VariableManaCost) cost; + while (!vCost.isPaid()) { + if (player.playXMana(vCost, (ManaCosts) this, game)) + vCost.assignPayment(game, ability, player.getManaPool()); + else + return false; + } + } + return true; + } - @Override - public ManaCosts getUnpaidVariableCosts() { - ManaCosts unpaid = new ManaCostsImpl(); - for (ManaCost cost : this) { - if (cost instanceof VariableManaCost && !cost.isPaid()) - unpaid.add((T) cost.getUnpaid()); - } - return unpaid; - } + @Override + public ManaCosts getUnpaid() { + ManaCosts unpaid = new ManaCostsImpl(); + for (T cost : this) { + if (!(cost instanceof VariableManaCost) && !cost.isPaid()) + unpaid.add((T) cost.getUnpaid()); + } + return unpaid; + } - - - @Override - public List getVariableCosts() { - List variableCosts = new ArrayList(); - for (ManaCost cost : this) { - if (cost instanceof VariableCost) - variableCosts.add((VariableCost) cost); - } + @Override + public ManaCosts getUnpaidVariableCosts() { + ManaCosts unpaid = new ManaCostsImpl(); + for (ManaCost cost : this) { + if (cost instanceof VariableManaCost && !cost.isPaid()) + unpaid.add((T) cost.getUnpaid()); + } + return unpaid; + } + + + @Override + public List getVariableCosts() { + List variableCosts = new ArrayList(); + for (ManaCost cost : this) { + if (cost instanceof VariableCost) + variableCosts.add((VariableCost) cost); + } // if (variableCosts.size() == 0) { // // add empty cost (#Issue 210) // variableCosts.add(new VariableManaCost()); // } - return variableCosts; - } + return variableCosts; + } @Override public int getX() { @@ -170,177 +174,182 @@ public class ManaCostsImpl extends ArrayList implements M amount = variableCosts.get(0).getAmount(); return amount; } - - @Override - public void setPayment(Mana mana) { - } - @Override - public void assignPayment(Game game, Ability ability, ManaPool pool) { - //attempt to pay colored costs first + @Override + public void setPayment(Mana mana) { + } - for (ManaCost cost : this) { - if (!cost.isPaid() && cost instanceof ColoredManaCost) { - cost.assignPayment(game, ability, pool); - } - } + @Override + public void assignPayment(Game game, Ability ability, ManaPool pool) { + //attempt to pay colored costs first - for (ManaCost cost : this) { - if (!cost.isPaid() && cost instanceof HybridManaCost) { - cost.assignPayment(game, ability, pool); - } - } + for (ManaCost cost : this) { + if (!cost.isPaid() && cost instanceof ColoredManaCost) { + cost.assignPayment(game, ability, pool); + } + } - for (ManaCost cost : this) { - if (!cost.isPaid() && cost instanceof MonoHybridManaCost) { - cost.assignPayment(game, ability, pool); - } - } + for (ManaCost cost : this) { + if (!cost.isPaid() && cost instanceof HybridManaCost) { + cost.assignPayment(game, ability, pool); + } + } - for (ManaCost cost : this) { - if (!cost.isPaid() && cost instanceof GenericManaCost) { - cost.assignPayment(game, ability, pool); - } - } + for (ManaCost cost : this) { + if (!cost.isPaid() && cost instanceof MonoHybridManaCost) { + cost.assignPayment(game, ability, pool); + } + } - for (ManaCost cost : this) { - if (!cost.isPaid() && cost instanceof VariableManaCost) { - cost.assignPayment(game, ability, pool); - } - } - } + for (ManaCost cost : this) { + if (!cost.isPaid() && cost instanceof GenericManaCost) { + cost.assignPayment(game, ability, pool); + } + } - @Override - public void load(String mana) { - this.clear(); - if (costs.containsKey(mana)) { - ManaCosts savedCosts = costs.get(mana); - for (ManaCost cost : savedCosts) { - this.add((T) cost.copy()); - } - } else { - if (mana == null || mana.length() == 0) - return; - String[] symbols = mana.split("^\\{|\\}\\{|\\}$"); - for (String symbol : symbols) { - if (symbol.length() > 0) { - if (symbol.length() == 1 || isNumeric(symbol)) { - if (Character.isDigit(symbol.charAt(0))) { - this.add((T) new GenericManaCost(Integer.valueOf(symbol))); - } else { - if (!symbol.equals("X")) - this.add((T) new ColoredManaCost(ColoredManaSymbol.lookup(symbol.charAt(0)))); - else - this.add((T) new VariableManaCost()); - //TODO: handle multiple {X} and/or {Y} symbols - } - } else { - if (Character.isDigit(symbol.charAt(0))) { - this.add((T) new MonoHybridManaCost(ColoredManaSymbol.lookup(symbol.charAt(2)))); - } else if (symbol.contains("P")) { - this.add((T) new PhyrexianManaCost(ColoredManaSymbol.lookup(symbol.charAt(0)))); - } else { - this.add((T) new HybridManaCost(ColoredManaSymbol.lookup(symbol.charAt(0)), ColoredManaSymbol.lookup(symbol.charAt(2)))); - } - } - } - } - costs.put(mana, this.copy()); - } - } + for (ManaCost cost : this) { + if (!cost.isPaid() && cost instanceof VariableManaCost) { + cost.assignPayment(game, ability, pool); + } + } + } - private boolean isNumeric(String symbol) { - try { - Integer.parseInt(symbol); - return true; - } catch (NumberFormatException e) { - return false; - } - } + @Override + public void load(String mana) { + this.clear(); + if (costs.containsKey(mana)) { + ManaCosts savedCosts = costs.get(mana); + for (ManaCost cost : savedCosts) { + this.add((T) cost.copy()); + } + } else { + if (mana == null || mana.length() == 0) + return; + String[] symbols = mana.split("^\\{|\\}\\{|\\}$"); + for (String symbol : symbols) { + if (symbol.length() > 0) { + if (symbol.length() == 1 || isNumeric(symbol)) { + if (Character.isDigit(symbol.charAt(0))) { + this.add((T) new GenericManaCost(Integer.valueOf(symbol))); + } else { + if (!symbol.equals("X")) + this.add((T) new ColoredManaCost(ColoredManaSymbol.lookup(symbol.charAt(0)))); + else + this.add((T) new VariableManaCost()); + //TODO: handle multiple {X} and/or {Y} symbols + } + } else { + if (Character.isDigit(symbol.charAt(0))) { + this.add((T) new MonoHybridManaCost(ColoredManaSymbol.lookup(symbol.charAt(2)))); + } else if (symbol.contains("P")) { + this.add((T) new PhyrexianManaCost(ColoredManaSymbol.lookup(symbol.charAt(0)))); + } else { + this.add((T) new HybridManaCost(ColoredManaSymbol.lookup(symbol.charAt(0)), ColoredManaSymbol.lookup(symbol.charAt(2)))); + } + } + } + } + costs.put(mana, this.copy()); + } + } - @Override - public List getSymbols() { - List symbols = new ArrayList(); - for (ManaCost cost : this) { - symbols.add(cost.getText()); - } - return symbols; - } + private boolean isNumeric(String symbol) { + try { + Integer.parseInt(symbol); + return true; + } catch (NumberFormatException e) { + return false; + } + } - @Override - public String getText() { - if (this.size() == 0) - return ""; + @Override + public List getSymbols() { + List symbols = new ArrayList(); + for (ManaCost cost : this) { + symbols.add(cost.getText()); + } + return symbols; + } - StringBuilder sbText = new StringBuilder(); - for (ManaCost cost : this) { - sbText.append(cost.getText()); - } - return sbText.toString(); - } + @Override + public UUID getId() { + return this.id; + } - @Override - public ManaOptions getOptions() { - ManaOptions options = new ManaOptions(); - for (ManaCost cost : this) { - options.addMana(cost.getOptions()); - } - return options; - } + @Override + public String getText() { + if (this.size() == 0) + return ""; - @Override - public boolean testPay(Mana testMana) { - for (ManaCost cost : this) { - if (cost.testPay(testMana)) - return true; - } - return false; - } + StringBuilder sbText = new StringBuilder(); + for (ManaCost cost : this) { + sbText.append(cost.getText()); + } + return sbText.toString(); + } - @Override - public boolean canPay(UUID sourceId, UUID controllerId, Game game) { - for (T cost : this) { - if (!cost.canPay(sourceId, controllerId, game)) - return false; - } - return true; - } + @Override + public ManaOptions getOptions() { + ManaOptions options = new ManaOptions(); + for (ManaCost cost : this) { + options.addMana(cost.getOptions()); + } + return options; + } - @Override - public boolean isPaid() { - for (T cost : this) { - if (!((T) cost instanceof VariableManaCost) && !cost.isPaid()) - return false; - } - return true; - } + @Override + public boolean testPay(Mana testMana) { + for (ManaCost cost : this) { + if (cost.testPay(testMana)) + return true; + } + return false; + } - @Override - public void clearPaid() { - for (T cost : this) { - cost.clearPaid(); - } - } + @Override + public boolean canPay(UUID sourceId, UUID controllerId, Game game) { + for (T cost : this) { + if (!cost.canPay(sourceId, controllerId, game)) + return false; + } + return true; + } - @Override - public void setPaid() { - for (T cost : this) { - cost.setPaid(); - } - } + @Override + public boolean isPaid() { + for (T cost : this) { + if (!((T) cost instanceof VariableManaCost) && !cost.isPaid()) + return false; + } + return true; + } - @Override - public Targets getTargets() { - Targets targets = new Targets(); - for (T cost : this) { - targets.addAll(cost.getTargets()); - } - return targets; - } + @Override + public void clearPaid() { + for (T cost : this) { + cost.clearPaid(); + } + } - @Override - public ManaCosts copy() { - return new ManaCostsImpl(this); - } + @Override + public void setPaid() { + for (T cost : this) { + cost.setPaid(); + } + } + + @Override + public Targets getTargets() { + Targets targets = new Targets(); + for (T cost : this) { + targets.addAll(cost.getTargets()); + } + return targets; + } + + @Override + public ManaCosts copy() { + return new ManaCostsImpl(this); + } }