From 7771f74aa18bc14d41285e4ba70f037e9dc5d8c3 Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 05:42:15 +0000 Subject: [PATCH] - Improved "Express" Mana choosing for paying costs with mana sources that produce more than one mana. - Fixed bug with Invasion sac-lands where the wrong mana is removed from the ManaPool. (Note: If there's any weird issues with Express Mana choosing, it can be disabled by setting skipExpress to false in tapCard() of Input_PayManaCostUtil) --- src/forge/Input_PayManaCostUtil.java | 43 ++++++++++++++-- src/forge/ManaCost.java | 4 +- src/forge/ManaPool.java | 76 ++++++++++------------------ 3 files changed, 68 insertions(+), 55 deletions(-) diff --git a/src/forge/Input_PayManaCostUtil.java b/src/forge/Input_PayManaCostUtil.java index e40bb716a9c..3ee2ba9a769 100644 --- a/src/forge/Input_PayManaCostUtil.java +++ b/src/forge/Input_PayManaCostUtil.java @@ -14,25 +14,60 @@ public class Input_PayManaCostUtil if(card instanceof ManaPool) return ((ManaPool)card).subtractMana(manaCost); - ArrayList abilities = getManaAbilities(card); + ArrayList abilities = getManaAbilities(card); StringBuilder cneeded = new StringBuilder(); + boolean choice = true; + boolean skipExpress = false; + for(String color : Constant.Color.ManaColors) if(manaCost.isNeeded(color)) cneeded.append(getShortColorString(color)); + Iterator it = abilities.iterator();//you can't remove unneeded abilities inside a for(am:abilities) loop :( while(it.hasNext()) { Ability_Mana ma = it.next(); if (!ma.canPlay()) it.remove(); else if (!canMake(ma, cneeded.toString())) it.remove(); + + if (!skipExpress){ + // skip express mana if there's a a sacrifice or the ability is not undoable + if (ma.isSacrifice() || !ma.undoable()){ + skipExpress = true; + continue; + } + } } if(abilities.isEmpty()) return manaCost; - //String color; + // todo when implementing sunburst + // If the card has sunburst or any other ability that tracks mana spent, skip express Mana choice + // if (card.getTrackManaPaid()) skipExpress = true; + + if (!skipExpress){ + // express Mana Choice + ArrayList colorMatches = new ArrayList(); + + for(Ability_Mana am : abilities){ + String[] m = ManaPool.formatMana(am); + for(String color : m) + if(manaCost.isColor(color)) // convert to long before checking if color + colorMatches.add(am); + } + + if (colorMatches.size() == 0 || colorMatches.size() == abilities.size()) + // can only match colorless just grab the first and move on. + choice = false; + else if (colorMatches.size() < abilities.size()){ + // leave behind only color matches + abilities = colorMatches; + } + } + Ability_Mana chosen = abilities.get(0); - if(1 < abilities.size()) + if(1 < abilities.size() && choice) { HashMap ability = new HashMap(); for(Ability_Mana am : abilities) @@ -167,7 +202,7 @@ public class Input_PayManaCostUtil if(am.isReflectedMana()) { for( String color:((Ability_Reflected_Mana)am).getPossibleColors()) { if (mana.contains(getShortColorString(color))) { - return true; + return true; } } return false; diff --git a/src/forge/ManaCost.java b/src/forge/ManaCost.java index e76b47fe592..db793aea3d7 100644 --- a/src/forge/ManaCost.java +++ b/src/forge/ManaCost.java @@ -24,12 +24,12 @@ public class ManaCost { manaPart = split(manaCost); } + // takes a Short Color and returns true if it exists in the mana cost. Easier for split costs public boolean isColor(String color){ for(Object s : manaPart){ - if (Input_PayManaCostUtil.getLongColorString(s.toString()).equals(color)) + if (s.toString().contains(color)) return true; } - return false; } diff --git a/src/forge/ManaPool.java b/src/forge/ManaPool.java index 9b3383d1874..c4187465c51 100644 --- a/src/forge/ManaPool.java +++ b/src/forge/ManaPool.java @@ -115,50 +115,9 @@ public class ManaPool extends Card { } public void addManaToFloating(String manaStr, Card card) { - manaStr = manaStr.trim(); - String[] manaArr = manaStr.split(" "); - - String color = ""; - int currentTotal = 0; - int genericTotal = 0; - int snowTotal = 0; - - for(String c : manaArr){ - String longStr = Input_PayManaCostUtil.getLongColorString(c); - if (longStr.equals(Constant.Color.Colorless)){ - genericTotal += Integer.parseInt(c); - if (card.isSnow()) - snowTotal += Integer.parseInt(c); - } - else if (color.equals("")){ - color = longStr; - currentTotal = 1; - } - else if (color.equals(longStr)){ - currentTotal++; - } - else{ // color != longstr - // add aggregate color - floatingMana.add(new Mana(color, currentTotal, card)); - floatingTotals[map.get(color)] += currentTotal; - if (card.isSnow()) - floatingTotals[map.get(Constant.Color.Snow)] += currentTotal; - - color = longStr; - currentTotal = 1; - } - } - if (!color.equals("")){ // some colored mana was produced - floatingMana.add(new Mana(color, currentTotal, card)); - floatingTotals[map.get(color)] += currentTotal; - if (card.isSnow()) - floatingTotals[map.get(Constant.Color.Snow)] += currentTotal; - } - - if (genericTotal > 0){ - floatingMana.add(new Mana(Constant.Color.Colorless, genericTotal, card)); - floatingTotals[map.get(Constant.Color.Colorless)] += genericTotal; - floatingTotals[map.get(Constant.Color.Snow)] += snowTotal; + ArrayList manaList = convertStringToMana(manaStr, card); + for(Mana m : manaList){ + addManaToPool(floatingMana, m); } //Omnath, Locus of Mana Pump Trigger @@ -172,6 +131,13 @@ public class ManaPool extends Card { } public void addManaToPaying(String manaStr, Card card) { + ArrayList manaList = convertStringToMana(manaStr, card); + for(Mana m : manaList) + addManaToPool(payingMana, m); + } + + public static ArrayList convertStringToMana(String manaStr, Card card){ + ArrayList manaList = new ArrayList(); manaStr = manaStr.trim(); String[] manaArr = manaStr.split(" "); @@ -192,16 +158,18 @@ public class ManaPool extends Card { } else{ // more than one color generated // add aggregate color - payingMana.add(new Mana(color, total, card)); + manaList.add(new Mana(color, total, card)); color = longStr; total = 1; } } if (total > 0) - payingMana.add(new Mana(color, total, card)); + manaList.add(new Mana(color, total, card)); if (genericTotal > 0) - payingMana.add(new Mana(Constant.Color.Colorless, genericTotal, card)); + manaList.add(new Mana(Constant.Color.Colorless, genericTotal, card)); + + return manaList; } public void clearPool() @@ -317,6 +285,17 @@ public class ManaPool extends Card { removeManaFrom(pool, choice); } + public void findAndRemoveFrom(ArrayList pool, Mana mana){ + Mana set = null; + for (Mana m : pool){ + if (m.getSourceCard().equals(mana.getSourceCard()) && m.getColor().equals(mana.getColor())){ + set = m; + break; + } + } + removeManaFrom(pool, set); + } + public void removeManaFrom(ArrayList pool, Mana choice){ if (choice != null){ if (choice.getAmount() == 1) @@ -438,7 +417,6 @@ public class ManaPool extends Card { // get a mana of this type from floating, bail if none available Mana mana = getManaFrom(floatingMana, manaStr); if (mana == null) return manaCost; // no matching mana in the pool - Card c = mana.getSourceCard(); Mana[] manaArray = mana.toSingleArray(); @@ -447,7 +425,7 @@ public class ManaPool extends Card { if (manaCost.isNeeded(m)){ manaCost.payMana(m); payingMana.add(m); - removeManaFromFloating(manaCost, c); + findAndRemoveFrom(floatingMana, m); } else break;