package forge.gui.input; import forge.AllZone; import forge.Card; import forge.Constant; import forge.card.mana.ManaCost; import forge.card.mana.ManaPool; import forge.card.spellability.Ability_Mana; import forge.card.spellability.SpellAbility; import forge.gui.GuiUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * <p>Input_PayManaCostUtil class.</p> * * @author Forge * @version $Id: $ */ public class Input_PayManaCostUtil { //all mana abilities start with this and typical look like "tap: add G" //mana abilities are Strings and are retrieved by calling card.getKeyword() //taps any card that has mana ability, not just land /** * <p>activateManaAbility.</p> * * @param sa a {@link forge.card.spellability.SpellAbility} object. * @param card a {@link forge.Card} object. * @param manaCost a {@link forge.card.mana.ManaCost} object. * @return a {@link forge.card.mana.ManaCost} object. */ public static ManaCost activateManaAbility(SpellAbility sa, Card card, ManaCost manaCost) { //make sure computer's lands aren't selected if (card.getController().isComputer()) return manaCost; if (card instanceof ManaPool) return ((ManaPool) card).subtractMana(sa, manaCost); ArrayList<Ability_Mana> 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<Ability_Mana> it = abilities.iterator();//you can't remove unneeded abilities inside a for(am:abilities) loop :( while (it.hasNext()) { Ability_Mana ma = it.next(); ma.setActivatingPlayer(AllZone.getHumanPlayer()); if (!ma.canPlay()) it.remove(); else if (!canMake(ma, cneeded.toString())) it.remove(); if (!skipExpress) { // skip express mana if the ability is not undoable if (!ma.isUndoable()) { skipExpress = true; continue; } } } if (abilities.isEmpty()) return manaCost; // 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<Ability_Mana> colorMatches = new ArrayList<Ability_Mana>(); 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() && choice) { HashMap<String, Ability_Mana> ability = new HashMap<String, Ability_Mana>(); for (Ability_Mana am : abilities) ability.put(am.toString(), am); chosen = (Ability_Mana) GuiUtils.getChoice("Choose mana ability", abilities.toArray()); } AllZone.getGameAction().playSpellAbility(chosen); manaCost = AllZone.getManaPool().subtractMana(sa, manaCost, chosen); AllZone.getHumanBattlefield().updateObservers();//DO NOT REMOVE THIS, otherwise the cards don't always tap (copied) return manaCost; } /** * <p>getManaAbilities.</p> * * @param card a {@link forge.Card} object. * @return a {@link java.util.ArrayList} object. */ public static ArrayList<Ability_Mana> getManaAbilities(Card card) { return card.getManaAbility(); } //color is like "G", returns "Green" /** * <p>canMake.</p> * * @param am a {@link forge.card.spellability.Ability_Mana} object. * @param mana a {@link java.lang.String} object. * @return a boolean. */ public static boolean canMake(Ability_Mana am, String mana) { if (mana.contains("1")) return true; if (mana.contains("S") && am.isSnow()) return true; for (String color : ManaPool.formatMana(am)) if (mana.contains(color)) return true; return false; } /** * <p>getLongColorString.</p> * * @param color a {@link java.lang.String} object. * @return a {@link java.lang.String} object. */ public static String getLongColorString(String color) { Map<String, String> m = new HashMap<String, String>(); m.put("G", Constant.Color.Green); m.put("R", Constant.Color.Red); m.put("U", Constant.Color.Blue); m.put("B", Constant.Color.Black); m.put("W", Constant.Color.White); m.put("S", Constant.Color.Snow); Object o = m.get(color); if (o == null) o = Constant.Color.Colorless; return o.toString(); } /** * <p>getShortColorString.</p> * * @param color a {@link java.lang.String} object. * @return a {@link java.lang.String} object. */ public static String getShortColorString(String color) { Map<String, String> m = new HashMap<String, String>(); m.put(Constant.Color.Green, "G"); m.put(Constant.Color.Red, "R"); m.put(Constant.Color.Blue, "U"); m.put(Constant.Color.Black, "B"); m.put(Constant.Color.White, "W"); m.put(Constant.Color.Colorless, "1"); m.put(Constant.Color.Snow, "S"); Object o = m.get(color); return o.toString(); } }