/* * Copyright 2008 (C) Tom Parker <thpr@users.sourceforge.net> * Derived from EquipmentModifier.java * Copyright 2001 (C) Bryan McRoberts <merton_monk@yahoo.com> * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package pcgen.core.analysis; import java.math.BigDecimal; import java.util.HashSet; import java.util.Set; import java.util.StringTokenizer; import pcgen.cdom.enumeration.FormulaKey; import pcgen.cdom.enumeration.IntegerKey; import pcgen.cdom.enumeration.ObjectKey; import pcgen.cdom.enumeration.StringKey; import pcgen.core.Equipment; import pcgen.core.EquipmentModifier; import pcgen.core.Globals; import pcgen.core.PCClass; import pcgen.core.PlayerCharacter; import pcgen.core.bonus.BonusObj; import pcgen.core.prereq.Prerequisite; import pcgen.core.spell.Spell; import pcgen.util.Delta; public class EqModCost { private static final String s_CHARGES = "CHARGES"; public static BigDecimal addItemCosts(EquipmentModifier eqMod, final PlayerCharacter aPC, final String bonusType, final int qty, final Equipment parent) { double val = 0; Set<String> typesToGetBonusesFor = new HashSet<>(); for (BonusObj bonus : eqMod.getBonusList(parent)) { boolean meetsAll = true; if (bonus.getBonusName().equals(bonusType)) { StringTokenizer aTok = new StringTokenizer(bonus.toString() .substring(bonusType.length()), "|", false); final String bType = aTok.nextToken(); aTok = new StringTokenizer(bType.substring(5), ".", false); String typeString = "TYPE"; while (aTok.hasMoreTokens()) { final String sub_type = aTok.nextToken(); meetsAll = parent.isType(sub_type); if (!meetsAll) { break; } typeString += "." + sub_type; } if (meetsAll) { typesToGetBonusesFor.add(typeString); } } } for (String typeString : typesToGetBonusesFor) { val += eqMod.bonusTo(aPC, bonusType, typeString, parent); } return new BigDecimal(val * qty); } public static boolean getCostDouble(EquipmentModifier eqMod) { // // Uninitialized? // Boolean costdouble = eqMod.get(ObjectKey.COST_DOUBLE); if (costdouble == null) { if (eqMod.isType("MagicalEnhancement") || eqMod.isType("BaseMaterial")) { return false; } if (eqMod.isIType("MAGIC")) { return true; } for (Prerequisite preReq : eqMod.getPrerequisiteList()) { if ("TYPE".equalsIgnoreCase(preReq.getKind()) && ((preReq.getKey() .equalsIgnoreCase("EQMODTYPE=MagicalEnhancement")) || (preReq .getKey() .equalsIgnoreCase("EQMODTYPE.MagicalEnhancement")))) { return true; } } return false; } return costdouble; } public static String getCost(EquipmentModifier eqMod, final String listEntry) { String costFormula = eqMod.getSafe(FormulaKey.COST).toString(); String modChoice = ""; while (costFormula.indexOf("%SPELLLEVEL") >= 0) { final int idx = costFormula.indexOf("%SPELLLEVEL"); if (modChoice.isEmpty()) { final int iLevel = EqModSpellInfo.getSpellInfo(listEntry, "SPELLLEVEL"); if (iLevel == 0) { modChoice = "0.5"; } else { modChoice = Integer.toString(iLevel); } } costFormula = costFormula.substring(0, idx) + modChoice + costFormula.substring(idx + 11); } costFormula = replaceCostSpellCost(costFormula, listEntry); costFormula = replaceCostSpellXPCost(costFormula, listEntry); costFormula = replaceCostCasterLevel(costFormula, listEntry); costFormula = replaceCostCharges(costFormula, listEntry); costFormula = replaceCostChoice(costFormula, listEntry); return costFormula; } private static String replaceCostCasterLevel(String costFormula, final String listEntry) { String modChoice = ""; while (costFormula.indexOf("%CASTERLEVEL") >= 0) { final int idx = costFormula.indexOf("%CASTERLEVEL"); if (modChoice.isEmpty()) { final int iCasterLevel = EqModSpellInfo.getSpellInfo( listEntry, "CASTERLEVEL"); modChoice = Integer.toString(iCasterLevel); // // Tack on the item creation multiplier, if there is one // final String castClassKey = EqModSpellInfo .getSpellInfoString(listEntry, "CASTER"); if (!castClassKey.isEmpty()) { final PCClass castClass = Globals.getContext().getReferenceContext() .silentlyGetConstructedCDOMObject(PCClass.class, castClassKey); if (castClass != null) { final StringBuilder multiple = new StringBuilder(200); String aString = castClass.get(StringKey.ITEMCREATE); if (aString != null && !aString.isEmpty()) { final StringTokenizer aTok = new StringTokenizer( aString, "+-*/()", true); // // This is to support older versions of the // ITEMCREATE tag // that allowed 0.5, because it used to be just a // multiple // if (aTok.countTokens() == 1) { multiple.append(iCasterLevel).append('*') .append(aString); } else { while (aTok.hasMoreTokens()) { aString = aTok.nextToken(); if (aString.equals("CL")) { multiple.append(iCasterLevel); } else { multiple.append(aString); } } } modChoice = multiple.toString(); } } } } costFormula = costFormula.substring(0, idx) + "(" + modChoice + ")" + costFormula.substring(idx + 12); } return costFormula; } private static String replaceCostCharges(String costFormula, final String listEntry) { String modChoice = ""; while (costFormula.indexOf("%" + s_CHARGES) >= 0) { final int idx = costFormula.indexOf("%" + s_CHARGES); if (modChoice.isEmpty()) { modChoice = Integer.toString(EqModSpellInfo.getSpellInfo( listEntry, s_CHARGES)); } costFormula = costFormula.substring(0, idx) + modChoice + costFormula.substring(idx + 8); } return costFormula; } private static String replaceCostSpellCost(String costFormula, final String listEntry) { String modChoice = ""; while (costFormula.indexOf("%SPELLCOST") >= 0) { final int idx = costFormula.indexOf("%SPELLCOST"); if (modChoice.isEmpty()) { final String spellName = EqModSpellInfo.getSpellInfoString( listEntry, "SPELLNAME"); final Spell aSpell = Globals.getContext().getReferenceContext() .silentlyGetConstructedCDOMObject(Spell.class, spellName); if (aSpell != null) { modChoice = aSpell.getSafe(ObjectKey.COST).toString(); } } costFormula = costFormula.substring(0, idx) + modChoice + costFormula.substring(idx + 10); } return costFormula; } private static String replaceCostChoice(String costFormula, final String listEntry) { String modChoice = ""; while (costFormula.indexOf("%CHOICE") >= 0) { final int idx = costFormula.indexOf("%CHOICE"); if (modChoice.isEmpty()) { final int offs = listEntry.lastIndexOf('|'); int modValue = 0; try { modValue = Delta.parseInt(listEntry.substring(offs + 1)); } catch (NumberFormatException exc) { // TODO: Should this really be ignored? } modChoice = Integer.toString(modValue); } costFormula = costFormula.substring(0, idx) + modChoice + costFormula.substring(idx + 7); } return costFormula; } private static String replaceCostSpellXPCost(String costFormula, final String listEntry) { String modChoice = ""; while (costFormula.indexOf("%SPELLXPCOST") >= 0) { final int idx = costFormula.indexOf("%SPELLXPCOST"); if (modChoice.isEmpty()) { final String spellName = EqModSpellInfo.getSpellInfoString( listEntry, "SPELLNAME"); final Spell aSpell = Globals.getContext().getReferenceContext() .silentlyGetConstructedCDOMObject(Spell.class, spellName); if (aSpell != null) { modChoice = Integer.toString(aSpell .getSafe(IntegerKey.XP_COST)); } } costFormula = costFormula.substring(0, idx) + modChoice + costFormula.substring(idx + 12); } return costFormula; } }