package plugin.exporttokens; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import pcgen.cdom.base.Constants; import pcgen.cdom.util.CControl; import pcgen.core.Equipment; import pcgen.core.PlayerCharacter; import pcgen.core.analysis.BonusCalc; import pcgen.core.analysis.OutputNameFormatting; import pcgen.core.display.CharacterDisplay; import pcgen.io.ExportHandler; import pcgen.io.exporttoken.EqToken; import pcgen.io.exporttoken.Token; import pcgen.util.BigDecimalHelper; import pcgen.util.Delta; import pcgen.util.Logging; /** * Class deals with ARMOR Token */ public class ArmorToken extends Token { /** Name of the Token */ public static final String TOKENNAME = "ARMOR"; /** * Get the token name * @return token name */ @Override public String getTokenName() { return TOKENNAME; } /** * @see pcgen.io.exporttoken.Token#getToken(java.lang.String, pcgen.core.PlayerCharacter, pcgen.io.ExportHandler) */ @Override public String getToken(String tokenSource, PlayerCharacter pc, ExportHandler eh) { if (tokenSource.startsWith("ARMOR") && ((tokenSource.charAt(5) == '.') || Character.isDigit(tokenSource .charAt(5)))) { return getArmorToken(tokenSource, pc, eh); } return ""; } /** * @param tokenSource * @param pc * @param eh The ExportHandler to advise if there are no more items. * @return token * */ public static String getArmorToken(String tokenSource, PlayerCharacter pc, ExportHandler eh) { return replaceTokenArmor(tokenSource, pc, eh); } /** * See the PCGen Docs on Token Syntax * * @param aString * @param aPC * @param eh The ExportHandler to advise if there are no more items. * @return int */ private static String replaceTokenArmor(String aString, PlayerCharacter aPC, ExportHandler eh) { final StringTokenizer aTok = new StringTokenizer(aString, "."); final String[] tokens = new String[aTok.countTokens()]; for (int i = 0; aTok.hasMoreTokens(); ++i) { tokens[i] = aTok.nextToken(); } String property = ""; // When removing old syntax, this if should be removed if (tokens.length > 0) { property = tokens[tokens.length - 1]; } int equipped = 3; int index = 0; String type = ""; String subtype = ""; int merge = Constants.MERGE_ALL; for (int i = 0; i < tokens.length; ++i) { if ("ARMOR".equals(tokens[i])) { continue; } // When removing old syntax, delete this if else if (tokens[i].startsWith("ARMOR")) { try { index = Integer.parseInt(tokens[i].substring(5)); } catch (NumberFormatException nfe) { index = 0; } Logging .errorPrint("Old syntax ARMORx will be replaced for ARMOR.x"); } else if ("ALL".equals(tokens[i])) { equipped = 3; } // When removing old syntax, delete this if else if (tokens[i].startsWith("ALL")) { Logging .errorPrint("Old syntax ALLx will be replaced for ALL.x"); index = Integer.parseInt(tokens[i].substring(3)); equipped = 3; } else if ("EQUIPPED".equals(tokens[i])) { equipped = 1; } // When removing old syntax, delete this if else if (tokens[i].startsWith("EQUIPPED")) { Logging .errorPrint("Old syntax EQUIPPEDx will be replaced for EQUIPPED.x"); index = Integer.parseInt(tokens[i].substring(8)); equipped = 1; } else if ("NOT_EQUIPPED".equals(tokens[i])) { equipped = 2; } // When removing old syntax, delete this if else if (tokens[i].startsWith("NOT_EQUIPPED")) { Logging .errorPrint("Old syntax NOT_EQUIPPEDx will be replaced for NOT_EQUIPPED.x"); index = Integer.parseInt(tokens[i].substring(12)); equipped = 2; } else if (tokens[i].equals("MERGENONE")) { merge = Constants.MERGE_NONE; } else if (tokens[i].equals("MERGELOC")) { merge = Constants.MERGE_LOCATION; } else if (tokens[i].equals("MERGEALL")) { merge = Constants.MERGE_ALL; } else if (tokens[i].equals("ISTYPE")) { property = tokens[i] + "." + tokens[i + 1]; break; } else if (tokens[i].equals("NAME")) { property = tokens[i]; if (i < (tokens.length - 1)) { property += "." + tokens[i + 1]; } break; } else if (i < (tokens.length - 1)) { try { index = Integer.parseInt(tokens[i]); } catch (NumberFormatException exc) { if ("".equals(type)) { type = tokens[i]; } else { subtype = tokens[i]; } } } else { property = tokens[i]; } } if ("".equals(type)) { return _replaceTokenArmor(index, property, equipped, merge, aPC, eh); } else if ("SUIT".equals(type)) { return _replaceTokenArmorSuit(index, subtype, property, equipped, merge, aPC, eh); } else if ("SHIRT".equals(type)) { return _replaceTokenArmorShirt(index, subtype, property, equipped, merge, aPC, eh); } else if ("SHIELD".equals(type)) { return _replaceTokenArmorShield(index, subtype, property, equipped, merge, aPC, eh); } else if ("ITEM".equals(type) || "ACITEM".equals(type)) { return _replaceTokenArmorItem(index, subtype, property, equipped, merge, aPC, eh); } else { return _replaceTokenArmorVarious(index, type, subtype, property, equipped, merge, aPC, eh); } } /** * select suits - shields * @param armor * @param property * @param equipped * @param merge * @param aPC * @param eh The ExportHandler to advise if there are no more items. * @return int */ private static String _replaceTokenArmor(int armor, String property, int equipped, int merge, PlayerCharacter aPC, ExportHandler eh) { final List<Equipment> aArrayList = aPC.getEquipmentOfTypeInOutputOrder("Armor", equipped, merge); final List<Equipment> bArrayList = aPC.getEquipmentOfTypeInOutputOrder("Shield", equipped, merge); for (Equipment eq : bArrayList) { aArrayList.remove(eq); } if (armor < aArrayList.size()) { final Equipment eq = aArrayList.get(armor); return _writeArmorProperty(eq, property, aPC); } eh.setNoMoreItems(true); return ""; } /** * select items, which improve AC but are not type ARMOR * @param item * @param subtype * @param property * @param equipped * @param merge * @param aPC * @param eh The ExportHandler to advise if there are no more items. * @return int */ private static String _replaceTokenArmorItem(int item, String subtype, String property, int equipped, int merge, PlayerCharacter aPC, ExportHandler eh) { // select all pieces of equipment of status==equipped // filter all AC relevant stuff final List<Equipment> aArrayList = new ArrayList<>(); for (Equipment eq : aPC.getEquipmentListInOutputOrder(merge)) { if (("".equals(subtype) || eq.isType(subtype)) && ((equipped == 3) || ((equipped == 2) && !eq.isEquipped()) || ((equipped == 1) && eq .isEquipped()))) { if (eq.altersAC(aPC) && !eq.isArmor() && !eq.isShield()) { aArrayList.add(eq); } } } if (item < aArrayList.size()) { final Equipment eq = aArrayList.get(item); return _writeArmorProperty(eq, property, aPC); } eh.setNoMoreItems(true); return ""; } /** * select shields * @param shield * @param subtype * @param property * @param equipped * @param merge * @param aPC * @param eh The ExportHandler to advise if there are no more items. * @return int */ private static String _replaceTokenArmorShield(int shield, String subtype, String property, int equipped, int merge, PlayerCharacter aPC, ExportHandler eh) { final List<Equipment> aArrayList = aPC.getEquipmentOfTypeInOutputOrder("Shield", subtype, equipped, merge); if (shield < aArrayList.size()) { final Equipment eq = aArrayList.get(shield); return _writeArmorProperty(eq, property, aPC); } eh.setNoMoreItems(true); return ""; } /** * select shirts * @param shirt * @param subtype * @param property * @param equipped * @param merge * @param aPC * @param eh The ExportHandler to advise if there are no more items. * @return int */ private static String _replaceTokenArmorShirt(int shirt, String subtype, String property, int equipped, int merge, PlayerCharacter aPC, ExportHandler eh) { final List<Equipment> aArrayList = aPC.getEquipmentOfTypeInOutputOrder("Shirt", subtype, equipped, merge); if (shirt < aArrayList.size()) { final Equipment eq = aArrayList.get(shirt); return _writeArmorProperty(eq, property, aPC); } eh.setNoMoreItems(true); return ""; } /** * select suits * @param suit * @param subtype * @param property * @param equipped * @param merge * @param aPC * @param eh The ExportHandler to advise if there are no more items. * @return int */ private static String _replaceTokenArmorSuit(int suit, String subtype, String property, int equipped, int merge, PlayerCharacter aPC, ExportHandler eh) { final List<Equipment> aArrayList = aPC.getEquipmentOfTypeInOutputOrder("Suit", subtype, equipped, merge); // // Temporary hack until someone gets around to fixing it properly // //aArrayList.addAll(aPC.getEquipmentOfTypeInOutputOrder("Shirt", subtype, equipped)); if (suit < aArrayList.size()) { final Equipment eq = aArrayList.get(suit); return _writeArmorProperty(eq, property, aPC); } eh.setNoMoreItems(true); return ""; } /** * select various stuff, that improves AC * @param index * @param type * @param subtype * @param property * @param equipped * @param merge * @param aPC * @param eh The ExportHandler to advise if there are no more items. * @return int */ private static String _replaceTokenArmorVarious(int index, String type, String subtype, String property, int equipped, int merge, PlayerCharacter aPC, ExportHandler eh) { final List<Equipment> aArrayList = new ArrayList<>(); for (Equipment eq : aPC.getEquipmentOfTypeInOutputOrder(type, subtype, equipped, merge)) { if (eq.getACMod(aPC).intValue() > 0) { aArrayList.add(eq); } else if (eq.altersAC(aPC)) { aArrayList.add(eq); } } if (index < aArrayList.size()) { final Equipment eq = aArrayList.get(index); return _writeArmorProperty(eq, property, aPC); } eh.setNoMoreItems(true); return ""; } private static String _writeArmorProperty(Equipment eq, String property, PlayerCharacter aPC) { CharacterDisplay display = aPC.getDisplay(); StringBuilder ret = new StringBuilder(); if (property.startsWith("NAME")) { if (eq.isEquipped() && !property.equals("NAMENOSTAR")) { ret.append("*"); } ret.append(OutputNameFormatting.parseOutputName(eq, aPC)); ret.append(eq.getAppliedName()); } else if (property.startsWith("OUTPUTNAME")) { // TODO this appears to be the same as above. Should be refactored if (eq.isEquipped()) { ret.append("*"); } ret.append(OutputNameFormatting.parseOutputName(eq, aPC)); ret.append(eq.getAppliedName()); } else if (property.startsWith("TOTALAC") || property.startsWith("ACBONUS")) { // adjustments for new equipment modifier // EQMARMOR|AC|x|TYPE=ENHANCEMENT changed to COMBAT|AC|x|TYPE=Armor.ENHANCEMENT //FileAccess.write(output, Delta.toString(eq.getACMod())); String acMod = aPC.getControl(CControl.EQACMOD); if (acMod != null) { Object o = aPC.getLocal(eq, acMod); int intValue = ((Number) o).intValue(); ret.append(Delta.toString(intValue)); } else { ret.append(Delta.toString((int) eq.bonusTo(aPC, "COMBAT", "AC", true))); } } else if (property.startsWith("BASEAC")) { // adjustments for new equipment modifier // EQMARMOR|AC|x|TYPE=ENHANCEMENT changed to COMBAT|AC|x|TYPE=Armor.ENHANCEMENT //FileAccess.write(output, Delta.toString(eq.getACMod())); String baseMod = aPC.getControl(CControl.EQBASEACMOD); if (baseMod != null) { Object o = aPC.getLocal(eq, baseMod); int intValue = ((Number) o).intValue(); ret.append(Delta.toString(intValue)); } else { ret.append(Delta.toString((int) BonusCalc.charBonusTo(eq, "COMBAT", "AC", aPC))); } } else if (property.startsWith("MAXDEX")) { final int iMax = EqToken.getMaxDexTokenInt(aPC, eq); if (iMax != Constants.MAX_MAXDEX) { ret.append(Delta.toString(iMax)); } } else if (property.startsWith("ACCHECK")) { ret.append(Delta.toString(EqToken.getAcCheckTokenInt(aPC, eq))); } else if (property.startsWith("EDR")) { ret.append(Delta.toString(EqToken.getEdrTokenInt(aPC, eq))); } else if (property.startsWith("ISTYPE")) { if (eq.isType(property.substring(property.indexOf(".") + 1))) { ret.append("TRUE"); } else { ret.append("FALSE"); } } else if (property.startsWith("SPELLFAIL")) { ret.append(EqToken.getSpellFailureTokenInt(aPC, eq)); } else if (property.startsWith("MOVE")) { final StringTokenizer aTok = new StringTokenizer(eq.moveString(), ",", false); String tempString = ""; if (("M".equals(display.getSize()) || "S".equals(display.getSize())) && (aTok.countTokens() > 0)) { tempString = aTok.nextToken(); if ("S".equals(display.getSize()) && (aTok.countTokens() > 1)) { tempString = aTok.nextToken(); } } ret.append(tempString); } else if (property.startsWith("SPROP")) { ret.append(eq.getSpecialProperties(aPC)); } else if (property.startsWith("TYPE")) { String typeString = ""; if (eq.isLight()) { typeString = "Light"; } else if (eq.isMedium()) { typeString = "Medium"; } else if (eq.isHeavy()) { typeString = "Heavy"; } else if (eq.isShield()) { typeString = "Shield"; } else if (eq.isExtra()) { typeString = "Extra"; } ret.append(typeString); } else if (property.startsWith("WT")) { ret .append(BigDecimalHelper .trimZeros(eq.getWeight(aPC).toString())); } return ret.toString(); } }