From 22b14d0b70ce97797fe0ca35ffcc6262b0330c3d Mon Sep 17 00:00:00 2001 From: ArsenalNut Date: Fri, 30 Dec 2011 20:36:21 +0000 Subject: [PATCH] Creating branch for changes for supporting "Produced$ Any" in mana abilities --- res/cardsfolder/c/city_of_brass.txt | 13 +- res/cardsfolder/g/glimmervoid.txt | 1 + src/main/java/forge/Card.java | 5 +- src/main/java/forge/ComputerUtil.java | 255 +++++++++++++++++- .../abilityfactory/AbilityFactoryMana.java | 53 +++- src/main/java/forge/card/mana/Mana.java | 11 + src/main/java/forge/card/mana/ManaPool.java | 165 +++++++----- .../forge/card/spellability/AbilityMana.java | 78 ++++++ .../forge/gui/input/InputPayManaCostUtil.java | 9 +- 9 files changed, 505 insertions(+), 85 deletions(-) diff --git a/res/cardsfolder/c/city_of_brass.txt b/res/cardsfolder/c/city_of_brass.txt index d20a3e2dd35..4dbfe52a056 100644 --- a/res/cardsfolder/c/city_of_brass.txt +++ b/res/cardsfolder/c/city_of_brass.txt @@ -2,11 +2,12 @@ Name:City of Brass ManaCost:no cost Types:Land Text:no text -A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add W to your mana pool. -A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add B to your mana pool. -A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add U to your mana pool. -A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add R to your mana pool. -A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add G to your mana pool. +A:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 1 | SpellDescription$ Add one mana of any color to your mana pool. +#A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add W to your mana pool. +#A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add B to your mana pool. +#A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add U to your mana pool. +#A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add R to your mana pool. +#A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add G to your mana pool. T:Mode$ Taps | ValidCard$ Card.Self | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME becomes tapped, it deals 1 damage to you. SVar:TrigDamage:AB$DealDamage | Cost$ 0 | Defined$ You | NumDmg$ 1 SVar:Rarity:Rare @@ -18,4 +19,4 @@ SetInfo:5ED|Rare|http://magiccards.info/scans/en/5e/413.jpg SetInfo:6ED|Rare|http://magiccards.info/scans/en/6e/321.jpg SetInfo:CHR|Rare|http://magiccards.info/scans/en/ch/92.jpg SetInfo:ARN|Uncommon|http://magiccards.info/scans/en/an/85.jpg -End \ No newline at end of file +End diff --git a/res/cardsfolder/g/glimmervoid.txt b/res/cardsfolder/g/glimmervoid.txt index 32cbdaae78e..bbd5a00569c 100644 --- a/res/cardsfolder/g/glimmervoid.txt +++ b/res/cardsfolder/g/glimmervoid.txt @@ -2,6 +2,7 @@ Name:Glimmervoid ManaCost:no cost Types:Land Text:no text +#A:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 1 | SpellDescription$ Add one mana of any color to your mana pool. A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add W to your mana pool. A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add B to your mana pool. A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add U to your mana pool. diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 870b0f55d6a..165d66a60eb 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -2790,11 +2790,10 @@ public class Card extends GameEntity implements Comparable { continue; } - if (am.isBasic() && !res.contains(am)) { - res.add(am); - } else if (am.isReflectedMana() && !res.contains(am)) { + if ((am.isBasic() || am.isReflectedMana() || am.isAnyMana()) && !res.contains(am)) { res.add(am); } + } return res; diff --git a/src/main/java/forge/ComputerUtil.java b/src/main/java/forge/ComputerUtil.java index aa3db3879ad..34e49a491de 100644 --- a/src/main/java/forge/ComputerUtil.java +++ b/src/main/java/forge/ComputerUtil.java @@ -36,6 +36,7 @@ import forge.card.spellability.AbilityMana; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; import forge.error.ErrorViewer; +import forge.gui.input.InputPayManaCostUtil; /** *

@@ -177,6 +178,8 @@ public class ComputerUtil { final CostPayment pay = new CostPayment(cost, sa); if (pay.payComputerCosts()) { AllZone.getStack().addAndUnfreeze(sa); + //TODO: solve problems with TapsForMana triggers by adding + // sources tapped here if possible (ArsenalNut) } } } @@ -615,6 +618,168 @@ public class ComputerUtil { cost.setManaNeededToAvoidNegativeEffect(card.getSVar("ManaNeededToAvoidNegativeEffect").split(",")); } + + // get map of mana abilities + HashMap> manaAbilityMap = mapManaSources(player); + // initialize ArrayList list for mana needed + ArrayList> partSources = + new ArrayList>(); + ArrayList partPriority = new ArrayList(); + String[] costParts = cost.toString().split(" "); + Boolean foundAllSources = true; + if (manaAbilityMap.isEmpty()) { + foundAllSources = false; + } + else { + String[] shortColors = {"W", "U", "B" , "R", "G"}; + // loop over cost parts + for (int nPart = 0; nPart < costParts.length; nPart++) { + ManaCost costPart = new ManaCost(costParts[nPart]); + ArrayList srcFound = new ArrayList(); + // get colored mana required + ManaCost onlyColored = costPart; + onlyColored.removeColorlessMana(); + for (String color : shortColors) { + if (onlyColored.isColor(color)) { + // Is source available? + if (manaAbilityMap.containsKey(color)) { + srcFound.addAll(manaAbilityMap.get(color)); + } + } + } + // Test for Colorless + if (costPart.isColor("1")) { + srcFound.addAll(manaAbilityMap.get("1")); + } + // Test for Snow + if (costPart.isColor("S")) { + if (manaAbilityMap.containsKey("S")) { + srcFound.addAll(manaAbilityMap.get("S")); + } + } + + // add sources to array lists + partSources.add(nPart, srcFound); + // add to sorted priority list + if (srcFound.size() > 0) { + int i; + for (i = 0; i < partPriority.size(); i++) { + if (srcFound.size() < partSources.get(i).size()) { + break; + } + } + partPriority.add(i, nPart); + } + else { + foundAllSources = false; + break; + } + } + } + /* + if (!foundAllSources) { + if (!test) { + // real payment should not arrive here + throw new RuntimeException("ComputerUtil : payManaCost() cost was not paid for " + sa.getSourceCard().getName()); + } + return false; + } + */ + + ManaCost testCost = new ManaCost(cost.toString()); + // Create array to keep track of sources used + ArrayList usedSources = new ArrayList(); + //this is to prevent errors for mana sources that have abilities that cost mana. + usedSources.add(sa.getSourceCard()); + // Loop over mana needed + int nPriority = 0; + while (nPriority < partPriority.size()) { + int nPart = partPriority.get(nPriority); + ArrayList manaAbilities = partSources.get(nPart); + ManaCost costPart = new ManaCost(costParts[nPart]); + // Loop over mana abilities that can be used to current mana cost part + for (AbilityMana m : manaAbilities) { + Card sourceCard = m.getSourceCard(); + + // Check if source has already been used + if (usedSources.contains(sourceCard)) { + continue; + } + + // Check if AI can still play this mana ability + m.setActivatingPlayer(player); + //if the AI can't pay the additional costs skip the mana ability + if (m.getPayCosts() != null) { + if (!canPayAdditionalCosts(m, player)) { + continue; + } + } else if (sourceCard.isTapped()) { + continue; + } + + // add source card to used list + usedSources.add(sourceCard); + +// // add source card to used list +// if (!test) { +// //Pay additional costs +// if (m.getPayCosts() != null) { +// Cost_Payment pay = new Cost_Payment(m.getPayCosts(), m); +// if (!pay.payComputerCosts()) { +// continue; +// } +// } +// else { +// sourceCard.tap(); +// } +// // resolve mana ability +// m.resolve(); +// // subtract mana from mana pool +// cost = manapool.subtractMana(sa, cost, m); +// } +// else { + String manaProduced; + // Check if paying snow mana + if ("S".equals(costParts[nPart])) { + manaProduced = "S"; + } + else { + // check if ability produces any color + //TODO: This won't work with Hybrid mana or colorless costs (111230 - ArsenalNut) + if (m.isAnyMana()) { + m.setAnyChoice(costParts[nPart]); + } + // get produced mana + manaProduced = m.getManaProduced(); + } + // pay cost + String color = InputPayManaCostUtil.getLongColorString(manaProduced); + testCost.payMana(color); + costPart.payMana(color); +// } + // check if color is still needed + if (costPart.isPaid()) { + break; + } + } // end of mana ability loop + if (!costPart.isPaid()) { + break; + } + else { + nPriority++; + } + + } // end of cost parts loop + + // // check if paid +// if (cost.isPaid()) { +// //if (sa instanceof Spell_Permanent) // should probably add this +// sa.getSourceCard().setColorsPaid(cost.getColorsPaid()); +// sa.getSourceCard().setSunburstValue(cost.getSunburst()); +// manapool.clearPay(sa, test); +// return true; +// } + final CardList manaSources = ComputerUtil.getAvailableMana(); // this is to prevent errors for mana sources that have abilities that @@ -861,7 +1026,7 @@ public class ComputerUtil { sortedManaSources.add(card); } } - + //TODO: Check for cards that produce "Any" as base mana (ArsenalNut) // 2. Search for mana sources that have a certain number of mana // abilities (start with 1 and go up to 5) and no drawback/costs for (int number = 1; number < 6; number++) { @@ -983,7 +1148,93 @@ public class ComputerUtil { return res; } - // plays a land if one is available + /** + *

mapManaSources.

+ * + * @param player a {@link forge.Player} object. + * @return HashMap + */ + public static HashMap> mapManaSources(final Player player) { + HashMap> manaMap = new HashMap>(); + + ArrayList whiteSources = new ArrayList(); + ArrayList blueSources = new ArrayList(); + ArrayList blackSources = new ArrayList(); + ArrayList redSources = new ArrayList(); + ArrayList greenSources = new ArrayList(); + ArrayList colorlessSources = new ArrayList(); + ArrayList snowSources = new ArrayList(); + + // Get list of current available mana sources + final CardList manaSources = ComputerUtil.getAvailableMana(); + + // Loop over all mana sources + for (int i = 0; i < manaSources.size(); i++) { + Card sourceCard = manaSources.get(i); + ArrayList manaAbilities = sourceCard.getAIPlayableMana(); + + // Loop over all mana abilities for a source + for (AbilityMana m : manaAbilities) { + + //don't use abilities with dangerous drawbacks + if (m.getSubAbility() != null) { + if (!m.getSubAbility().chkAIDrawback()) { + continue; + } + } + + // add to colorless source list + colorlessSources.add(m); + + // find possible colors + if (m.canProduce("W") || m.isAnyMana()) { + whiteSources.add(m); + } + if (m.canProduce("U") || m.isAnyMana()) { + blueSources.add(m); + } + if (m.canProduce("B") || m.isAnyMana()) { + blackSources.add(m); + } + if (m.canProduce("R") || m.isAnyMana()) { + redSources.add(m); + } + if (m.canProduce("G") || m.isAnyMana()) { + greenSources.add(m); + } + if (m.isSnow()) { + snowSources.add(m); + } + } // end of mana abilities loop + } // end of mana sources loop + + // Add sources + if (!whiteSources.isEmpty()) { + manaMap.put("W", whiteSources); + } + if (!blueSources.isEmpty()) { + manaMap.put("U", blueSources); + } + if (!blackSources.isEmpty()) { + manaMap.put("B", blackSources); + } + if (!redSources.isEmpty()) { + manaMap.put("R", redSources); + } + if (!greenSources.isEmpty()) { + manaMap.put("G", greenSources); + } + if (!colorlessSources.isEmpty()) { + manaMap.put("1", colorlessSources); + } + if (!snowSources.isEmpty()) { + manaMap.put("S", snowSources); + } + + return manaMap; + } + + //plays a land if one is available /** *

* chooseLandsToPlay. diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java index 3cb0cacc17e..13e803f6877 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryMana.java @@ -18,6 +18,7 @@ package forge.card.abilityfactory; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.Random; @@ -85,6 +86,11 @@ public class AbilityFactoryMana { return false; } + @Override + public String getManaProduced() { + // TODO Auto-generated method stub + return manaGenerated(this, this.af, this); + } }; return abMana; } @@ -117,6 +123,10 @@ public class AbilityFactoryMana { return false; } + @Override + public String getManaProduced() { + return manaGenerated(this.tmpMana, this.af, this); + } }; @Override @@ -168,6 +178,10 @@ public class AbilityFactoryMana { return false; } + @Override + public String getManaProduced() { + return manaGenerated(this.tmpMana, this.af, this); + } }; @Override @@ -241,6 +255,18 @@ public class AbilityFactoryMana { return sb.toString(); } + + /** + *

manaGenerated.

+ * + * @param abMana a {@link forge.card.spellability.Ability_Mana} object. + * @param af a {@link forge.card.abilityFactory.AbilityFactory} object. + * @param sa a {@link forge.card.spellability.SpellAbility} object. + * @return a {@link java.lang.String} object. + */ + public static String manaGenerated(final AbilityMana abMana, final AbilityFactory af, final SpellAbility sa) { + return generatedMana(abMana, af, sa); + } /** *

@@ -277,6 +303,22 @@ public class AbilityFactoryMana { tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Defined"), sa); } + if (abMana.isAnyMana()) { + for (Player p : tgtPlayers) { + if (tgt == null || p.canBeTargetedBy(sa)) { + // AI color choice is set in ComputerUtils so only human players need to make a choice + if (sa.getActivatingPlayer().isHuman()) { + Object o = GuiUtils.getChoice("Choose a color", Constant.Color.ONLY_COLORS); + if (null == o) { + return; + } + String choice = (String) o; + abMana.setAnyChoice(choice.substring(0, 1).toUpperCase()); + } + } + } + } + for (final Player player : tgtPlayers) { abMana.produceMana(AbilityFactoryMana.generatedMana(abMana, af, sa), player); } @@ -319,7 +361,16 @@ public class AbilityFactoryMana { int amount = params.containsKey("Amount") ? AbilityFactory.calculateAmount(af.getHostCard(), params.get("Amount"), sa) : 1; - String baseMana = abMana.mana(); + String baseMana; + if (abMana.isAnyMana()) { + baseMana = abMana.getAnyChoice(); + if (baseMana.isEmpty()) { + baseMana = "Any"; + } + } else { + baseMana = abMana.mana(); + } + if (baseMana.equals("Chosen")) { // this will only support 1 chosen color for now. baseMana = InputPayManaCostUtil.getShortColorString(card.getChosenColor().get(0)); diff --git a/src/main/java/forge/card/mana/Mana.java b/src/main/java/forge/card/mana/Mana.java index 90fd88aec55..ba028aa8480 100644 --- a/src/main/java/forge/card/mana/Mana.java +++ b/src/main/java/forge/card/mana/Mana.java @@ -246,4 +246,15 @@ public class Mana { public final void decrementAmount() { this.amount--; } + + /** + *

+ * decrementAmount. + *

+ * + * @param amountDecrement a int. + */ + public void decrementAmount(final int amountDecrement) { + this.amount -= amountDecrement; + } } diff --git a/src/main/java/forge/card/mana/ManaPool.java b/src/main/java/forge/card/mana/ManaPool.java index ffdb93bb732..9b57120118e 100644 --- a/src/main/java/forge/card/mana/ManaPool.java +++ b/src/main/java/forge/card/mana/ManaPool.java @@ -498,7 +498,7 @@ public class ManaPool { break; } } - this.removeManaFrom(pool, set); + this.removeManaFrom(pool, set, mana.getAmount()); } /** @@ -510,21 +510,23 @@ public class ManaPool { * a {@link java.util.ArrayList} object. * @param choice * a {@link forge.card.mana.Mana} object. + * @param amount + * an int . */ - public final void removeManaFrom(final ArrayList pool, final Mana choice) { + public final void removeManaFrom(final ArrayList pool, final Mana choice, final int amount) { if (choice != null) { - if (choice.getAmount() == 1) { + if (choice.getAmount() == amount) { pool.remove(choice); } else { - choice.decrementAmount(); + choice.decrementAmount(amount); } if (pool.equals(this.floatingMana)) { int i = ManaPool.MAP.get(choice.getColor()); if (choice.isSnow()) { - this.floatingSnowTotals[i] -= choice.getAmount(); + this.floatingSnowTotals[i] -= amount; } else { - this.floatingTotals[i] -= choice.getAmount(); + this.floatingTotals[i] -= amount; } } owner.updateObservers(); @@ -685,7 +687,7 @@ public class ManaPool { * @return a {@link forge.card.mana.ManaCost} object. */ public final ManaCost subtractMana(final SpellAbility sa, ManaCost m, final AbilityMana... mAbilities) { - final ArrayList paidAbs = sa.getPayingManaAbilities(); + final ArrayList paidAbs = sa.getPayingManaAbilities(); // why??? if (mAbilities.length == 0) { // paying from Mana Pool @@ -699,8 +701,17 @@ public class ManaPool { // paying via Mana Abilities for (final AbilityMana mability : mAbilities) { - paidAbs.add(mability); - final String[] cost = ManaPool.formatMana(mability); + paidAbs.add(mability); // why??? + //TODO: Look at using new getManaProduced() method of Ability_Mana (ArsenalNut) + //String[] cost = formatMana(mability); + String[] cost = null; + if (mability.isAnyMana()) { + cost = new String[1]; + cost[0] = mability.getAnyChoice(); + } + else { + cost = formatMana(mability); + } m = this.subtractMultiple(sa, cost, m); } @@ -738,7 +749,7 @@ public class ManaPool { for (final Mana m : manaArray) { if (manaCost.isNeeded(m)) { manaCost.payMana(m); - payMana.add(m); + payMana.add(m); // what is this used for? anything this.findAndRemoveFrom(this.floatingMana, m); } else { break; @@ -806,78 +817,81 @@ public class ManaPool { // TODO account for unpaying mana in payMana and floatingPool final ArrayList payMana = sa.getPayingMana(); + if ((payMana.size() == 0) && (this.floatingMana.size() == 0)) { + return false; + } + final ArrayList removePaying = new ArrayList(); final ArrayList removeFloating = new ArrayList(); - int i = 0, j = 0; - boolean usePay = payMana.size() > 0; - final boolean flag = false; - - String manaStr = mana[i]; - String color = InputPayManaCostUtil.getLongColorString(manaStr); - - if (!usePay && (this.floatingMana.size() == 0)) { + int manaAccounted = 0; + // loop over mana paid + for (Mana manaPaid : payMana) { + if (manaPaid.fromSourceCard(c)) { + for (int i = 0;i < mana.length;i++ ) { + if (manaPaid.getColor().equals(InputPayManaCostUtil.getLongColorString(mana[i]))) { + final int amt = manaPaid.getColorlessAmount(); + if (amt > 0) { + final int difference = Integer.parseInt(mana[i]) - amt; + if (difference > 0) { + mana[i] = Integer.toString(difference); + } else { + manaAccounted += amt; + } + } else { + manaAccounted += manaPaid.getAmount(); + } + removePaying.add(manaPaid); + break; + } + } + } + if (manaAccounted == mana.length) { + break; + } + } + // loop over mana pool if not all of the generated mana is accounted for + if (manaAccounted < mana.length) { + for (Mana manaFloat : this.floatingMana) { + if (manaFloat.fromSourceCard(c)) { + for (int i = 0;i < mana.length;i++ ) { + if (manaFloat.getColor().equals(InputPayManaCostUtil.getLongColorString(mana[i]))) { + final int amt = manaFloat.getColorlessAmount(); + if (amt > 0) { + final int difference = Integer.parseInt(mana[i]) - amt; + if (difference > 0) { + mana[i] = Integer.toString(difference); + } else { + manaAccounted += amt; + } + } else { + manaAccounted += manaFloat.getAmount(); + } + removeFloating.add(manaFloat); + break; + } + } + } + if (manaAccounted == mana.length) { + break; + } + } + } + // When is it legitimate for all the mana not to be accountable? + // Does this condition really indicate an bug in Forge? + if (manaAccounted < mana.length) { return false; } - while (i < mana.length) { - - final Mana m = usePay ? payMana.get(j) : this.floatingMana.get(j); - - if (m.fromSourceCard(c) && m.getColor().equals(color)) { - final int amt = m.getColorlessAmount(); - if (amt > 0) { - final int difference = Integer.parseInt(manaStr) - amt; - if (difference > 0) { - manaStr = Integer.toString(difference); - } else { - i += amt; - if (i < mana.length) { - manaStr = mana[i]; - } - } - } else { - i += m.getAmount(); - if (i < mana.length) { - manaStr = mana[i]; - } - } - color = InputPayManaCostUtil.getLongColorString(manaStr); - if (usePay) { - removePaying.add(m); - } else { - removeFloating.add(m); - } - - // If mana has been depleted, break from loop. All Accounted - // for! - if (i == mana.length) { - break; - } - } - - j++; // increase j until we reach the end of paying, then reset and - // use floating. - if (usePay) { - if (payMana.size() == j) { - j = 0; - usePay = false; - } - } - if (!usePay && (this.floatingMana.size() == j) && !flag) { - return false; - } - } - for (int k = 0; k < removePaying.size(); k++) { - this.removeManaFrom(payMana, removePaying.get(k)); + this.removeManaFrom(payMana, removePaying.get(k), removePaying.get(k).getAmount()); } for (int k = 0; k < removeFloating.size(); k++) { - this.removeManaFrom(this.floatingMana, removeFloating.get(k)); + this.removeManaFrom(this.floatingMana, removeFloating.get(k), removeFloating.get(k).getAmount()); } return true; } - + /** *

* unpaid. @@ -896,7 +910,16 @@ public class ManaPool { // go through paidAbilities if they are undoable for (final AbilityMana am : payAbs) { if (am.isUndoable()) { - final String[] formattedMana = ManaPool.formatMana(am); + //final String[] formattedMana = ManaPool.formatMana(am); + /*String[] formattedMana = null; + if (am.isAnyMana()) { + formattedMana = new String[1]; + formattedMana[0] = am.getAnyChoice(); + } + else { + formattedMana = formatMana(am); + }*/ + final String[] formattedMana = am.getLastProduced().split(" "); if (this.accountFor(sa, formattedMana, am.getSourceCard())) { am.undo(); } diff --git a/src/main/java/forge/card/spellability/AbilityMana.java b/src/main/java/forge/card/spellability/AbilityMana.java index 8bf108b0e3c..4174c9d4d5e 100644 --- a/src/main/java/forge/card/spellability/AbilityMana.java +++ b/src/main/java/forge/card/spellability/AbilityMana.java @@ -39,6 +39,8 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se private static final long serialVersionUID = -6816356991224950520L; private String origProduced; + private String lastAnyChoice = ""; + private String lastProduced = ""; private int amount = 1; /** The reflected. */ @@ -177,6 +179,8 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se // this.getActivatingPlayer().ManaPool.addManaToFloating(origProduced, // getSourceCard()); manaPool.addManaToFloating(produced, source); + //store produced to last produced + this.lastProduced = produced; // TODO all of the following would be better as trigger events // "tapped for mana" @@ -202,6 +206,35 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se } // end produceMana(String) + /** + *

+ * getProducedMana. + *

+ * + * @return a {@link java.lang.String} object. + */ + public String getManaProduced() { + StringBuilder sb = new StringBuilder(); + if (this.amount == 0) { + sb.append("0"); + } + else { + try { + // if baseMana is an integer(colorless), just multiply amount and baseMana + int base = Integer.parseInt(this.origProduced); + sb.append(base * this.amount); + } catch (NumberFormatException e) { + for (int i = 0; i < this.amount; i++) { + if (i != 0) { + sb.append(" "); + } + sb.append(this.origProduced); + } + } + } + return sb.toString(); + } + /** *

* mana. @@ -237,6 +270,39 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se this.reflected = bReflect; } + /** + *

+ * setAnyChoice. + *

+ * + * @param s a {@link java.lang.String} object. + */ + public void setAnyChoice(String s) { + this.lastAnyChoice = s; + } + + /** + *

+ * Getter for the field lastAnyChoice. + *

+ * + * @return a {@link java.lang.String} object. + */ + public String getAnyChoice() { + return this.lastAnyChoice; + } + + /** + *

+ * Getter for the field lastProduced. + *

+ * + * @return a {@link java.lang.String} object. + */ + public String getLastProduced() { + return this.lastProduced; + } + /** *

* isSnow. @@ -270,6 +336,17 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se return this.reflected; } + /** + *

+ * isAnyMana. + *

+ * + * @return a boolean. + */ + public boolean isAnyMana() { + return this.origProduced.contains("Any"); + } + /** *

* canProduce. @@ -280,6 +357,7 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se * @return a boolean. */ public final boolean canProduce(final String s) { + //TODO: look at where this called from and take "Any" into account return this.origProduced.contains(s); } diff --git a/src/main/java/forge/gui/input/InputPayManaCostUtil.java b/src/main/java/forge/gui/input/InputPayManaCostUtil.java index 17abae25f8f..3417e63e5df 100644 --- a/src/main/java/forge/gui/input/InputPayManaCostUtil.java +++ b/src/main/java/forge/gui/input/InputPayManaCostUtil.java @@ -119,6 +119,8 @@ public class InputPayManaCostUtil { colorMatches.add(am); } } + } else if (am.isAnyMana()) { + colorMatches.add(am); } else { final String[] m = ManaPool.formatMana(am); for (final String color : m) { @@ -130,7 +132,8 @@ public class InputPayManaCostUtil { } } - if ((colorMatches.size() == 0) || (colorMatches.size() == abilities.size())) { + // Why is choice made "false" if colorMatches and abilities have same size + if ((colorMatches.size() == 0)) { // can only match colorless just grab the first and move on. choice = false; } else if (colorMatches.size() < abilities.size()) { @@ -211,7 +214,9 @@ public class InputPayManaCostUtil { if (mana.contains("S") && am.isSnow()) { return true; } - + if (am.isAnyMana()) { + return true; + } if (am.isReflectedMana()) { final ArrayList reflectableColors = AbilityFactoryMana.reflectableMana(am, am.getAbilityFactory(), new ArrayList(), new ArrayList());