Java tutorial
package de.earthdawn; /******************************************************************************\ Copyright (C) 2010-2011 Holger von Rhein <lortas@freenet.de> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. \******************************************************************************/ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Random; import javax.swing.JOptionPane; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.SAXException; import com.itextpdf.text.pdf.codec.Base64; import de.earthdawn.config.ApplicationProperties; import de.earthdawn.config.ECECharacteristics; import de.earthdawn.data.*; import de.earthdawn.event.CharChangeRefresh; import de.earthdawn.namegenerator.NameGenerator; public class CharacterContainer extends CharChangeRefresh { private EDCHARACTER character = null; private static Random rand = new Random(); public static final ApplicationProperties PROPERTIES = ApplicationProperties.create(); public static final ECECharacteristics PROPERTIES_Characteristics = PROPERTIES.getCharacteristics(); public static MOVEMENTATTRIBUTENameType OptionalRule_AttributeBasedMovement = PROPERTIES.getOptionalRules() .getATTRIBUTEBASEDMOVEMENT().getAttribute(); public static final String threadWeavingName = PROPERTIES.getThreadWeavingName(); public static final String durabilityName = PROPERTIES.getDurabilityName(); public static final List<String> speakSkillName = PROPERTIES.getLanguageSkillSpeakName(); public static final List<String> readwriteSkillName = PROPERTIES.getLanguageSkillReadWriteName(); public static String DATEFORMAT = PROPERTIES.getOptionalRules().getDATEFORMAT(); public static final List<String> languageSkillSpeakNames = PROPERTIES.getLanguageSkillSpeakName(); public static final List<String> languageSkillReadWriteNames = PROPERTIES.getLanguageSkillReadWriteName(); public static String getCurrentDateTime() { DateFormat dateFormat = new SimpleDateFormat(DATEFORMAT); Date date = new Date(); return dateFormat.format(date); } public CharacterContainer() { character = new EDCHARACTER(); } public CharacterContainer(EDCHARACTER c) { character = c; } public CharacterContainer(File xmlfile) throws IOException, JAXBException, ParserConfigurationException, SAXException, TransformerException { // XML-Daten einlesen byte[] xmldata = new byte[(int) xmlfile.length()]; FileInputStream xmlInputStream = new FileInputStream(xmlfile); xmlInputStream.read(xmldata); xmlInputStream.close(); // XML-Daten unge'typ't parsen DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document doc = docBuilder.parse(new ByteArrayInputStream(xmldata)); // XML Root Element ermitteln Node rootnode = doc.getLastChild(); if (rootnode == null) { throw new RuntimeException("XML has no root element"); } String[] rootnames = rootnode.getNodeName().split(":"); String rootname; if (rootnames.length > 1) { rootname = rootnames[1]; } else { rootname = rootnames[0]; } if (!rootname.equals("EDCHARACTER")) { throw new RuntimeException("XML root element '" + rootname + "' is not 'EDCHARACTER'"); } Node version = rootnode.getAttributes().getNamedItem("xsd-version"); String value = (version == null) ? "" : version.getNodeValue(); if (value.isEmpty()) { JOptionPane.showMessageDialog(null, "No xsd-version set. Try to read it as like xsd-version 1.0. Procced at your own risk"); value = "1.0"; } if (value.equals("1.0")) { // XSLT Transformation System.out.println("XML mit xsd-version 1.0, transformiere nach aktuellem Schema"); TransformerFactory tFactory = TransformerFactory.newInstance(); try { Transformer transformer = tFactory.newTransformer( new javax.xml.transform.stream.StreamSource("config/convertcharacter_1.0.xsl")); ByteArrayOutputStream xmldataNew = new ByteArrayOutputStream(); transformer.transform( new javax.xml.transform.stream.StreamSource(new ByteArrayInputStream(xmldata)), new javax.xml.transform.stream.StreamResult(xmldataNew)); xmldata = xmldataNew.toByteArray(); } catch (TransformerException e) { System.err.print("Transformation alter (1.0) XML-character Version fehlgeschlagen : "); System.err.println(e.getLocalizedMessage()); } } else if (value.equals("1.1")) { // Nothing ToDo. This is most current xsd version. } else { JOptionPane.showMessageDialog(null, "Unknown xsd-version '" + value + "'. But try to read anyway. Procced at your own risk"); } JAXBContext jc = JAXBContext.newInstance("de.earthdawn.data"); Unmarshaller u = jc.createUnmarshaller(); character = (EDCHARACTER) u.unmarshal(new ByteArrayInputStream(xmldata)); } public void setEDCHARACTER(EDCHARACTER c) { character = c; } public void writeXml(OutputStream out, String encoding) throws JAXBException, UnsupportedEncodingException { PrintStream fileio = new PrintStream(out, false, encoding); fileio.println("<?xml version=\"1.0\" encoding=\"" + encoding + "\" standalone=\"no\"?>"); fileio.println("<?xml-stylesheet type=\"text/xsl\" href=\"earthdawncharacter.xsl\"?>"); // Lsche XSD-Version character.setXsdVersion(null); // Sieht kopmisch aus, setzt aber die Default/Fixed XSD-Version character.setXsdVersion(character.getXsdVersion()); toXml(encoding).marshal(character, fileio); fileio.close(); } public void writeHtml(OutputStream out, String encoding) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { writeXml(baos, encoding); } catch (UnsupportedEncodingException | JAXBException e) { System.err.println(e.getLocalizedMessage()); return; } String htmlstring = ""; // Transformiere das Character XML mit Hilfe des XSLT nach HTML TransformerFactory tFactory = TransformerFactory.newInstance(); try { Transformer transformer = tFactory .newTransformer(new javax.xml.transform.stream.StreamSource("config/earthdawncharacter.xsl")); ByteArrayOutputStream html = new ByteArrayOutputStream(); transformer.transform( new javax.xml.transform.stream.StreamSource(new ByteArrayInputStream(baos.toByteArray())), new javax.xml.transform.stream.StreamResult(html)); htmlstring = html.toString(encoding); } catch (TransformerException | UnsupportedEncodingException e) { System.err.println(e.getLocalizedMessage()); return; } try { // Lese CSS ein um die referenz im HTML durch inline zu ersetzen File cssfile = new File("config/earthdawncharacter.css"); byte[] cssdata = new byte[(int) cssfile.length()]; FileInputStream cssio = new FileInputStream(cssfile); cssio.read(cssdata); cssio.close(); // Ersetzte CSS link durch CSS inline htmlstring = htmlstring.replaceAll( "<link *rel=\"stylesheet\" *type=\"text/css\" *href=\"earthdawncharacter\\.css\" */?>", "<style type=\"text/css\">" + new String(cssdata) + "</style>"); } catch (IOException e) { System.err.println(e.getLocalizedMessage()); } // Entferne XSLT Fehler htmlstring = htmlstring.replaceAll("(%0A|%09)*;base64,(%0A|%09)*", ";base64,"); // Ersetze alle Icon Links durch inline Bilder for (File iconfile : (new File("icons")).listFiles()) { if (iconfile.getName().endsWith(".png")) { try { htmlstring = htmlstring.replace(iconfile.toURI().getRawPath(), "data:image/png;base64," + Base64 .encodeFromFile(iconfile.getCanonicalPath()).replace("\r", "").replace("\n", "")); } catch (IOException e) { System.err.println(e.getMessage()); } } } //Schreibe Ergebnis weg try { PrintStream fileio = new PrintStream(out, false, encoding); fileio.print(htmlstring); fileio.close(); } catch (UnsupportedEncodingException e) { System.err.println(e.getMessage()); } } public Marshaller toXml(String encoding) throws JAXBException { character.setEditorpath((new File("")).toURI().getRawPath()); JAXBContext jc = JAXBContext.newInstance("de.earthdawn.data"); Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_ENCODING, encoding); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://earthdawn.com/character earthdawncharacter.xsd"); m.setProperty(Marshaller.JAXB_FRAGMENT, true); return m; } public EDCHARACTER getEDCHARACTER() { return character; } public String getName() { return character.getName(); } public String setRandomName() { final APPEARANCEType appearance = getAppearance(); final String race = appearance.getRace(); final GenderType gender = appearance.getGender(); NameGenerator namegenerator = new NameGenerator(PROPERTIES.getRandomNamesByRaces()); String name = namegenerator.generateName(race, gender); //String name = namegenerator.generateName2(race,gender); //String name = namegenerator.generateName3(race,gender); character.setName(name); return name; } public String getPlayer() { String player = character.getPlayer(); if (player == null) return ""; return player; } public APPEARANCEType getAppearance() { APPEARANCEType appearance = character.getAPPEARANCE(); if (appearance != null) return appearance; // If not found: create appearance = new APPEARANCEType(); appearance.setRace("Human"); appearance.setOrigin("Barsaive"); appearance.setGender(GenderType.MALE); appearance.setEyes("brown"); appearance.setAge(20); appearance.setHair("black"); appearance.setHeight(5.5f); appearance.setSkin("caucasian"); appearance.setWeight(176); character.setAPPEARANCE(appearance); return appearance; } public HashMap<String, ATTRIBUTEType> getAttributes() { List<ATTRIBUTEType> attributelist = character.getATTRIBUTE(); HashMap<String, ATTRIBUTEType> attributes = new HashMap<String, ATTRIBUTEType>(); for (ATTRIBUTEType attribute : attributelist) { attributes.put(attribute.getName().value(), attribute); } for (ATTRIBUTENameType name : ATTRIBUTENameType.values()) { // Wenn das Attribut bereits exisitert, kein neues Setzen if (attributes.containsKey(name.value())) continue; // Das "Attribut" na soll nicht angefgt werden if (name.equals(ATTRIBUTENameType.NA)) continue; ATTRIBUTEType attribute = new ATTRIBUTEType(); attribute.setName(name); attributelist.add(attribute); attributes.put(attribute.getName().value(), attribute); } return attributes; } public int getAttributesCost() { int result = 0; for (ATTRIBUTEType attribute : character.getATTRIBUTE()) { // Das "Attribut" na soll nicht beachtet werden if (attribute.equals(ATTRIBUTENameType.NA)) continue; result += attribute.getCost(); } return result; } public DEFENSEType getDefence() { DEFENSEType defense = character.getDEFENSE(); if (defense == null) { defense = new DEFENSEType(); character.setDEFENSE(defense); } return defense; } public CALCULATEDLEGENDPOINTSType getCalculatedLegendpoints() { CALCULATEDLEGENDPOINTSType calculatedLegendpoints = character.getCALCULATEDLEGENDPOINTS(); if (calculatedLegendpoints == null) { calculatedLegendpoints = new CALCULATEDLEGENDPOINTSType(); character.setCALCULATEDLEGENDPOINTS(calculatedLegendpoints); } return calculatedLegendpoints; } public void addLegendPointsSpent(CALCULATEDLEGENDPOINTSType oldLP) { CALCULATEDLEGENDPOINTSType calculatedLP = getCalculatedLegendpoints(); List<ACCOUNTINGType> legendpoints = getLegendPoints().getLEGENDPOINTS(); String currentDateTime = getCurrentDateTime(); String comment = "-LP spent (automaticly added by ECE)"; int diff = 0; diff = calculatedLP.getAttributes() - oldLP.getAttributes(); if (diff > 0) { ACCOUNTINGType entry = new ACCOUNTINGType(); entry.setComment("Attribute" + comment); entry.setType(PlusminusType.MINUS); entry.setValue(diff); entry.setWhen(currentDateTime); legendpoints.add(entry); } diff = calculatedLP.getDisciplinetalents() - oldLP.getDisciplinetalents(); if (diff > 0) { ACCOUNTINGType entry = new ACCOUNTINGType(); entry.setComment("Disciplinetalents" + comment); entry.setType(PlusminusType.MINUS); entry.setValue(diff); entry.setWhen(currentDateTime); legendpoints.add(entry); } diff = calculatedLP.getKarma() - oldLP.getKarma(); if (diff > 0) { ACCOUNTINGType entry = new ACCOUNTINGType(); entry.setComment("Karma" + comment); entry.setType(PlusminusType.MINUS); entry.setValue(diff); entry.setWhen(currentDateTime); legendpoints.add(entry); } diff = calculatedLP.getKnacks() - oldLP.getKnacks(); if (diff > 0) { ACCOUNTINGType entry = new ACCOUNTINGType(); entry.setComment("Knacks" + comment); entry.setType(PlusminusType.MINUS); entry.setValue(diff); entry.setWhen(currentDateTime); legendpoints.add(entry); } diff = calculatedLP.getMagicitems() - oldLP.getMagicitems(); if (diff > 0) { ACCOUNTINGType entry = new ACCOUNTINGType(); entry.setComment("Magicitems" + comment); entry.setType(PlusminusType.MINUS); entry.setValue(diff); entry.setWhen(currentDateTime); legendpoints.add(entry); } diff = calculatedLP.getOptionaltalents() - oldLP.getOptionaltalents(); if (diff > 0) { ACCOUNTINGType entry = new ACCOUNTINGType(); entry.setComment("Optionaltalents" + comment); entry.setType(PlusminusType.MINUS); entry.setValue(diff); entry.setWhen(currentDateTime); legendpoints.add(entry); } diff = calculatedLP.getSkills() - oldLP.getSkills(); if (diff > 0) { ACCOUNTINGType entry = new ACCOUNTINGType(); entry.setComment("Skills" + comment); entry.setType(PlusminusType.MINUS); entry.setValue(diff); entry.setWhen(currentDateTime); legendpoints.add(entry); } diff = calculatedLP.getSpells() - oldLP.getSpells(); if (diff > 0) { ACCOUNTINGType entry = new ACCOUNTINGType(); entry.setComment("Spells" + comment); entry.setType(PlusminusType.MINUS); entry.setValue(diff); entry.setWhen(currentDateTime); legendpoints.add(entry); } } public void calculateLegendPointsAndStatus() { EXPERIENCEType legendpoints = getLegendPoints(); List<Integer> lp = CharacterContainer.calculateAccounting(legendpoints.getLEGENDPOINTS()); legendpoints.setCurrentlegendpoints(lp.get(0) - lp.get(1)); legendpoints.setTotallegendpoints(lp.get(0)); CHARACTERISTICSLEGENDARYSTATUS legendstatus = ApplicationProperties.create().getCharacteristics() .getLegendaystatus(getDisciplineMaxCircle().getCircle()); legendpoints.setRenown(legendstatus.getReown()); legendpoints.setReputation(legendstatus.getReputation()); } public void resetInitiative(STEPDICEType value) { INITIATIVEType initiative = new INITIATIVEType(); initiative.setArmorpenalty(0); initiative.setModification(0); initiative.setBase(value.getStep()); initiative.setStep(value.getStep()); initiative.setDice(value.getDice()); character.setINITIATIVE(initiative); } public INITIATIVEType getInitiative() { INITIATIVEType initiative = character.getINITIATIVE(); if (initiative == null) { initiative = new INITIATIVEType(); character.setINITIATIVE(initiative); } return initiative; } public HEALTHType getHealth() { HEALTHType health = character.getHEALTH(); if (health == null) { health = new HEALTHType(); character.setHEALTH(health); } return health; } public DEATHType getDeath() { HEALTHType health = getHealth(); DEATHType death = health.getDEATH(); if (death == null) { death = new DEATHType(); health.setDEATH(death); } return death; } public DEATHType getUnconsciousness() { HEALTHType health = getHealth(); DEATHType unconsciousness = health.getUNCONSCIOUSNESS(); if (unconsciousness == null) { unconsciousness = new DEATHType(); health.setUNCONSCIOUSNESS(unconsciousness); } return unconsciousness; } public WOUNDType getWound() { HEALTHType health = getHealth(); WOUNDType wound = health.getWOUNDS(); if (wound == null) { wound = new WOUNDType(); health.setWOUNDS(wound); } return wound; } public RECOVERYType getRecovery() { HEALTHType health = getHealth(); RECOVERYType recovery = health.getRECOVERY(); if (recovery == null) { recovery = new RECOVERYType(); health.setRECOVERY(recovery); } return recovery; } public KARMAType getKarma() { KARMAType karma = character.getKARMA(); if (karma == null) { karma = new KARMAType(); character.setKARMA(karma); } return karma; } public MOVEMENTType getMovement() { MOVEMENTType movement = character.getMOVEMENT(); if (movement == null) { movement = new MOVEMENTType(); character.setMOVEMENT(movement); } return movement; } public CARRYINGType getCarrying() { CARRYINGType carrying = character.getCARRYING(); if (carrying == null) { carrying = new CARRYINGType(); character.setCARRYING(carrying); } return carrying; } public PROTECTIONType getProtection() { PROTECTIONType protection = character.getPROTECTION(); if (protection == null) { protection = new PROTECTIONType(); character.setPROTECTION(protection); } return protection; } public String getAbilities() { String abilities = character.getRACEABILITES(); if (abilities == null) { abilities = ""; character.setRACEABILITES(abilities); } return abilities; } public void setAbilities(String newValue) { character.setRACEABILITES(newValue); } public List<DISCIPLINEType> getDisciplines() { List<DISCIPLINEType> disciplines = character.getDISCIPLINE(); CALCULATEDLEGENDPOINTSType calculatedlegendpoints = character.getCALCULATEDLEGENDPOINTS(); // Solange die letzte Disziplin keinen Kreis hat, wird diese entfernt. while ((!disciplines.isEmpty()) && (disciplines.get(disciplines.size() - 1).getCircle() < 1)) { int disciplineNumber = disciplines.size(); disciplines.remove(disciplineNumber - 1); // Wenn es keine Berechneten Legendenpunkte gibt, dann ist hier auch nichts zu tun. if (calculatedlegendpoints == null) continue; // Anpasssungen der berechneten Legendenpunkt fr Talente einer Disziplin die gelscht wird, knnen auch weg List<NEWDISCIPLINETALENTADJUSTMENTType> remove = new ArrayList<NEWDISCIPLINETALENTADJUSTMENTType>(); List<NEWDISCIPLINETALENTADJUSTMENTType> newdisciplinetalentadjustments = calculatedlegendpoints .getNEWDISCIPLINETALENTADJUSTMENT(); for (NEWDISCIPLINETALENTADJUSTMENTType e : newdisciplinetalentadjustments) { if (e.getDisciplinenumber() == disciplineNumber) remove.add(e); } newdisciplinetalentadjustments.removeAll(remove); } // Bei allen anderen Disziplinen die keinen Kreis haben wird dort der Kreis auf 1 hoch gesetzt. for (DISCIPLINEType discipline : disciplines) { if (discipline.getCircle() < 1) discipline.setCircle(1); } return disciplines; } public List<String> getDisciplineNames() { List<String> result = new ArrayList<String>(); for (DISCIPLINEType discipline : getDisciplines()) { result.add(discipline.getName()); } return result; } public List<String> getAllKarmaritual() { List<String> result = new ArrayList<String>(); for (DISCIPLINEType discipline : getDisciplines()) { String karmaritual = discipline.getKARMARITUAL(); if (karmaritual == null) { result.add(discipline.getName() + ": NA"); } else { result.add(discipline.getName() + ": " + karmaritual); } } return result; } public String getAllHalfMagic() { StringBuilder result = new StringBuilder(); for (DISCIPLINEType discipline : getDisciplines()) { String halfmagic = discipline.getHALFMAGIC(); result.append("["); result.append(discipline.getName()); result.append("]: "); if (halfmagic == null) { result.append("NA"); } else { result.append(halfmagic); } result.append("; "); } return result.toString(); } public List<Integer> getDisciplineCircles() { List<Integer> result = new ArrayList<Integer>(); for (DISCIPLINEType discipline : getDisciplines()) { result.add(discipline.getCircle()); } return result; } public int getDisciplineOrder(String disciplinename) { int order = 1; for (DISCIPLINEType discipline : getDisciplines()) { if (disciplinename.equals(discipline.getName())) return order; order++; } // Not found return 0; } public HashMap<String, DISCIPLINEType> getAllDisciplinesByName() { HashMap<String, DISCIPLINEType> result = new HashMap<String, DISCIPLINEType>(); for (DISCIPLINEType discipline : getDisciplines()) { result.put(discipline.getName(), discipline); } return result; } public int getCircleOf(String discipline) { DISCIPLINEType usedDiscipline = getAllDisciplinesByName().get(discipline); if (usedDiscipline == null) { System.err.println("No discipline '" + discipline + "' is in use."); return 0; } else { return usedDiscipline.getCircle(); } } public int getCircleOf(int disciplineNumber) { if (disciplineNumber < 1) { System.err.println("Discipline numer " + disciplineNumber + " is to low!"); return 0; } List<DISCIPLINEType> disciplines = getDisciplines(); if (disciplineNumber > disciplines.size()) { System.err.println("Discipline numer " + disciplineNumber + " is to high!"); return 0; } return disciplines.get(disciplineNumber - 1).getCircle(); } public DISCIPLINEType getDisciplineMaxCircle() { DISCIPLINEType discipline = new DISCIPLINEType(); discipline.setCircle(0); discipline.setName("na"); for (DISCIPLINEType d : getDisciplines()) if (d.getCircle() > discipline.getCircle()) discipline = d; return discipline; } public DISCIPLINEType getDisciplineMinCircle() { return getDisciplineMinCircle(0); } // Bestimme den Kleinsten Kreis einer Diszipline aber ohen die Disziplin mit der Nummer "notDiscipline" public DISCIPLINEType getDisciplineMinCircle(int notDiscipline) { DISCIPLINEType discipline = new DISCIPLINEType(); discipline.setCircle(20); discipline.setName("na"); int disciplinenumber = 0; for (DISCIPLINEType d : getDisciplines()) { disciplinenumber++; if (disciplinenumber == notDiscipline) continue; if (d.getCircle() < discipline.getCircle()) discipline = d; } return discipline; } public List<TalentsContainer> getAllTalents() { List<TalentsContainer> result = new ArrayList<TalentsContainer>(); for (DISCIPLINEType discipline : getDisciplines()) { result.add(new TalentsContainer(discipline)); } return result; } public HashMap<String, TalentsContainer> getAllTalentsByDisziplinName() { HashMap<String, TalentsContainer> alltalents = new HashMap<String, TalentsContainer>(); for (DISCIPLINEType discipline : getDisciplines()) { alltalents.put(discipline.getName(), new TalentsContainer(discipline)); } return alltalents; } public List<TALENTType> getTalentByName(String searchTalent) { List<TALENTType> result = new ArrayList<TALENTType>(); for (TalentsContainer talents : getAllTalents()) { for (TALENTType talent : talents.getDisciplineAndOptionaltalents()) { if (talent.getName().equals(searchTalent)) { result.add(talent); } } } return result; } public TALENTType getTalentByDisciplinAndName(String disciplin, String searchTalent) { for (DISCIPLINEType discipline : getDisciplines()) { if (!discipline.getName().equals(disciplin)) continue; TalentsContainer alltalents = new TalentsContainer(discipline); for (TALENTType talent : alltalents.getDisciplinetalents()) { if (talent.getName().equals(searchTalent)) return talent; } List<TALENTType> optionaltalents = alltalents.getOptionaltalents(); List<TALENTType> remove = new ArrayList<TALENTType>(); TALENTType result = null; for (TALENTType talent : optionaltalents) { RANKType rank = talent.getRANK(); if ((rank == null) || (rank.getRank() < 1)) { remove.add(talent); continue; } if (talent.getName().equals(searchTalent)) result = talent; } optionaltalents.removeAll(remove); if (result != null) return result; } // Not found return null; } public HashMap<String, List<TALENTType>> getThreadWeavingTalents() { HashMap<String, List<TALENTType>> result = new HashMap<String, List<TALENTType>>(); for (DISCIPLINEType discipline : getDisciplines()) { List<TALENTType> threadweaving = new ArrayList<TALENTType>(); for (TALENTType talent : (new TalentsContainer(discipline)).getDisciplineAndOptionaltalents()) if (threadWeavingName.equals(talent.getName())) threadweaving.add(talent); result.put(discipline.getName(), threadweaving); } return result; } public List<SKILLType> getSkills() { List<SKILLType> skills = new ArrayList<SKILLType>(); skills.addAll(character.getSKILL()); int discount = 1; for (DISCIPLINEType discipline : getDisciplines()) { for (TALENTType talent : (new TalentsContainer(discipline)).getDisciplineAndOptionaltalents()) { SKILLType skill = talent.getALIGNEDSKILL(); if (skill != null) { if (skill.getRealigned() == 0) skill.setRealigned(discount); skills.add(skill); } } discount++; } // Normiere Limitation fr die Skills for (SKILLType skill : skills) { List<String> limitations = skill.getLIMITATION(); Collections.sort(limitations); String limitation = join(limitations); limitations.clear(); if (!limitation.isEmpty()) limitations.add(limitation); } Collections.sort(skills, new SkillComparator()); return skills; } static public String join(List<?> list) { return join(", ", list); } static public String join(String seperator, List<?> list) { Iterator<?> iterator = list.iterator(); if (!iterator.hasNext()) return ""; StringBuffer result = new StringBuffer(); while (true) { result.append(iterator.next().toString().replaceAll("\\s\\s*", " ").replaceFirst("^\\s*", "") .replaceFirst("\\s*$", "")); if (iterator.hasNext()) result.append(seperator); else return result.toString(); } } public void addSkill(SKILLType skill) { character.getSKILL().add(skill); } public void removeSkill(SKILLType skill) { character.getSKILL().remove(skill); } public void removeSkill(List<SKILLType> skills) { character.getSKILL().removeAll(skills); } public List<SKILLType> getSpeakSkills() { List<SKILLType> result = new ArrayList<SKILLType>(); for (SKILLType skill : getSkills()) { if (speakSkillName.contains(skill.getName())) result.add(skill); } return result; } public List<SKILLType> getReadWriteSkills() { List<SKILLType> result = new ArrayList<SKILLType>(); for (SKILLType skill : getSkills()) { if (readwriteSkillName.contains(skill.getName())) result.add(skill); } return result; } public List<SKILLType> getNonLanguageSkills() { List<SKILLType> result = new ArrayList<SKILLType>(); for (SKILLType skill : getSkills()) { if (languageSkillSpeakNames.contains(skill.getName())) continue; if (languageSkillReadWriteNames.contains(skill.getName())) continue; result.add(skill); } return result; } public List<SKILLType> getOnlyLanguageSkills() { List<SKILLType> result = new ArrayList<SKILLType>(); for (SKILLType skill : getSkills()) { if (languageSkillSpeakNames.contains(skill.getName()) || languageSkillReadWriteNames.contains(skill.getName())) result.add(skill); } return result; } public void updateAlignedSkills() { List<SKILLType> alignedskills = new ArrayList<SKILLType>(); for (SKILLType skill : character.getSKILL()) { // Skills die keinen Rang haben knnen bersprungen werden. if ((skill.getRANK() == null) || (skill.getRANK().getRank() < 1)) continue; String skillname = skill.getName(); String skilllimitation = join(skill.getLIMITATION()); int discount = 0; for (DISCIPLINEType discipline : getDisciplines()) { if (skill == null) break; discount++; for (TALENTType talent : (new TalentsContainer(discipline)).getDisciplineAndOptionaltalents()) { // Talente die keine Rang haben knnen bersprungen werden if ((talent.getRANK() == null) || (talent.getRANK().getRank() < 1)) continue; String limitation = join(talent.getLIMITATION()); if (talent.getName().equals(skillname) && limitation.equals(skilllimitation)) { skill.setRealigned(discount); alignedskills.add(skill); talent.setALIGNEDSKILL(skill); skill = null; break; } } } } character.getSKILL().removeAll(alignedskills); } public EXPERIENCEType getLegendPoints() { EXPERIENCEType experience = character.getEXPERIENCE(); if (experience == null) { experience = new EXPERIENCEType(); experience.setCurrentlegendpoints(0); experience.setTotallegendpoints(0); character.setEXPERIENCE(experience); } return experience; } public void clearSpentLegendPoints() { EXPERIENCEType experience = getLegendPoints(); List<ACCOUNTINGType> legendpoints = experience.getLEGENDPOINTS(); List<ACCOUNTINGType> remove = new ArrayList<ACCOUNTINGType>(); for (ACCOUNTINGType a : legendpoints) { if (a.getType().equals(PlusminusType.MINUS)) remove.add(a); } legendpoints.removeAll(remove); experience.setCurrentlegendpoints(experience.getTotallegendpoints()); } public List<WEAPONType> getWeapons() { return character.getWEAPON(); } public List<DISCIPLINEBONUSType> getDisciplineBonuses() { List<DISCIPLINEBONUSType> bonuses = new ArrayList<DISCIPLINEBONUSType>(); for (DISCIPLINEType discipline : character.getDISCIPLINE()) { bonuses.addAll(discipline.getDISCIPLINEBONUS()); } return bonuses; } public List<ElementkindType> getDisciplinePrimElements() { List<ElementkindType> elements = new ArrayList<ElementkindType>(); for (DISCIPLINEType discipline : character.getDISCIPLINE()) { elements.add(discipline.getPrimelement()); } return elements; } public void clearDisciplineBonuses() { for (DISCIPLINEType discipline : character.getDISCIPLINE()) { discipline.getDISCIPLINEBONUS().clear(); } } public List<COINSType> getAllCoins() { List<COINSType> allCoins = character.getCOINS(); if (allCoins.isEmpty()) { COINSType coins = new COINSType(); coins.setSilver(100); // Startguthaben coins.setLocation("self"); coins.setUsed(YesnoType.YES); coins.setName("Starting Purse"); coins.setKind(ItemkindType.COINS); allCoins.add(coins); } return allCoins; } public List<SPELLType> getAllSpells() { List<SPELLType> result = new ArrayList<SPELLType>(); for (DISCIPLINEType discipline : getDisciplines()) { List<SPELLType> spells = discipline.getSPELL(); if (spells != null) result.addAll(spells); } return result; } public void clearOpenSpellList() { character.getOPENSPELL().clear(); } public void addOpenSpell(SPELLType spell) { character.getOPENSPELL().add(spell); } public List<SPELLType> getOpenSpellList() { return character.getOPENSPELL(); } /* * Liefert fr jede Diszipline des Charakters pro Kreis eine Auflistung der verwendeten Optionalen Talente * Die uere HashMap beinhaltet als Key, den Disziplinnamen. Die Values ist eine Liste, * wobei nicht der erste Eintrag fr den ersten Kreis steht sondern der Eintrag mit dem Index=1, * das selbe gilt fr die anderen Kreise analog * Die Werte der Liste ist wieder rum eine Liste von Talenten. * */ public HashMap<String, List<List<TALENTType>>> getUsedOptionalTalents() { HashMap<String, List<List<TALENTType>>> result = new HashMap<String, List<List<TALENTType>>>(); // Schleife ber alle Disziplinen des Charakters for (DISCIPLINEType discipline : getDisciplines()) { // Erstelle schon mal eine Ausreichende Liste von Leeren Listen um die Talente aufzunehmen. List<List<TALENTType>> list = new ArrayList<List<TALENTType>>(); // !!! ACHTUNG: Kreis 1 hat Index 1 und nicht Index 0 !!! for (int i = 0; i <= 15; i++) list.add(new ArrayList<TALENTType>()); // Schleife ber alle Optionalen Talente for (TALENTType talent : discipline.getOPTIONALTALENT()) { // Sollte kein Realignment statt gefunden haben, dann handelt es sich um ein "benutzes" Optionales Talent if (talent.getRealigned() < 1) list.get(talent.getCircle()).add(talent); } result.put(discipline.getName(), list); } return result; } public static String getFullTalentname(TALENTType talent) { String name = talent.getName(); // Falls es das DurabilityTalent ist, dann ignoriere die Limitationsangabe if (name.equals(durabilityName)) return durabilityName; if (talent.getLIMITATION().size() < 1) return name; return name + " : " + talent.getLIMITATION().get(0); } public static String getFullTalentname(TALENTABILITYType talent) { String name = talent.getName(); // Falls es das DurabilityTalent ist, dann ignoriere die Limitationsangabe if (name.equals(durabilityName)) return durabilityName; String limitation = talent.getLimitation(); if (limitation.isEmpty()) return name; return name + " : " + limitation; } public static String getFullTalentname(KNACKBASEType knack) { String name = knack.getName(); // Falls es das DurabilityTalent ist, dann ignoriere die Limitationsangabe if (name.equals(durabilityName)) return durabilityName; String limitation = knack.getLimitation(); if (limitation == null) return name; if (limitation.isEmpty()) return name; return name + " : " + limitation; } public List<TALENTABILITYType> getUnusedOptionalTalents(DISCIPLINE disciplineDefinition, int talentCircleNr) { List<TALENTABILITYType> result = new ArrayList<TALENTABILITYType>(); List<TALENTType> usedTalents = new ArrayList<TALENTType>(); // multiUseTalents sind Talente die mehr als einmal gelernt werden knnen HashMap<String, Integer> multiUseTalents = PROPERTIES.getMultiUseTalents(); // Schleife ber alle gelernten Disziplinen for (DISCIPLINEType discipline : getDisciplines()) { for (TALENTType talent : (new TalentsContainer(discipline)).getDisciplineAndOptionaltalents()) { String name = getFullTalentname(talent); Integer multiUseCount = multiUseTalents.get(name); if (multiUseCount == null) { // Wenn es kein MultiUseTalent ist, dann behandele es ganz normal // und fge es in die Liste der Benutzen Talent hinzu usedTalents.add(talent); } else { // Wenn es sich aber um ein MultiUseTalent handelt, Zhle den MultiUse-Zhler hinunter, // es sei denn er ist bereits auf Eins, dann fge das Talent in die Liste der Benutzen Talent hinzu if (multiUseCount > 1) multiUseCount--; else usedTalents.add(talent); // Aktuallisiere den MultiUse-Zhler bzw lsche das Talent aus der MultiUse Liste if (multiUseCount > 0) multiUseTalents.put(name, multiUseCount); else multiUseTalents.remove(name); } } } int mincircle = 1; int maxcircle = 0; // Durchlaufe die Kreisdefinition des gesuchten Disziplin rckwrts und ermittele alle mglichen Optionaltalente for (int circlenr = talentCircleNr; circlenr > 0; circlenr--) { DISCIPLINECIRCLEType disciplineCircle = disciplineDefinition.getCIRCLE().get(circlenr - 1); for (TALENTABILITYType talent : disciplineCircle.getOPTIONALTALENT()) { TALENTType found = null; String talentname = getFullTalentname(talent); for (TALENTType ut : usedTalents) if ((ut.getCircle() >= circlenr) && getFullTalentname(ut).equals(talentname)) found = ut; // Wenn das Talent nicht gefunden wurde, steht es dem Charakter als weiteres Optionales Talent zur Verfgung if (found == null) result.add(talent); // Wenn das Talent gefunden wurde, steht es dem Charakter NICHT ein weiteres mal als Optionales Talent zur Verfgung. // Wird aber aus der Liste entfernt falls nochmal danach gesucht werden sollte, damit es dann nicht gefunden wird. else usedTalents.remove(found); } FOREIGNTALENTSType foreignTalents = disciplineCircle.getFOREIGNTALENTS(); if (foreignTalents != null) { if (foreignTalents.getMincircle() < mincircle) mincircle = foreignTalents.getMincircle(); if (foreignTalents.getMaxcircle() > maxcircle) maxcircle = foreignTalents.getMaxcircle(); } } if (mincircle <= maxcircle) { // Wenn min und max ein glltiges Intervall ergeben, dann sind FOREIGNTALENTS definiert und mssen eingefgt werden. // Um doppelte Auflistung zu vermeiden Erzeuge ein Liste von allen benutzten Talente sowie den Talenten, die bereits // als Optionale Talente identifiziert wurden. HashMap<String, TALENTABILITYType> talents = PROPERTIES.getTalentsByCircle(mincircle, maxcircle); List<String> potentialTalents = new ArrayList<String>(); for (TALENTType talent : usedTalents) potentialTalents.add(getFullTalentname(talent)); for (TALENTABILITYType talent : result) potentialTalents.add(getFullTalentname(talent)); // Erweitere die Ergebnisliste um FOREIGNTALENTS nur wenn diese noch nicht enthalten waren. for (TALENTABILITYType talent : talents.values()) { String name = getFullTalentname(talent); if (potentialTalents.contains(name)) potentialTalents.remove(name); else result.add(talent); } } return result; } public HashMap<String, List<Integer>> getCircleOfMissingOptionalTalents() { HashMap<String, List<Integer>> result = new HashMap<String, List<Integer>>(); HashMap<String, List<List<TALENTType>>> talentsMap = getUsedOptionalTalents(); // Eine Schleife ber alle Disciplinenamen des Charakters for (String discipline : talentsMap.keySet()) { List<Integer> list = new ArrayList<Integer>(); // Hole alle benutzen Optionalen Talente der aktuellen Disziplin List<List<TALENTType>> talentsList = talentsMap.get(discipline); if (talentsList == null) { System.err.println("A talent list for the discipline '" + discipline + "' could not be found."); talentsList = new ArrayList<List<TALENTType>>(); for (int i = 0; i <= 15; i++) talentsList.add(new ArrayList<TALENTType>()); } int disciplineNumber = getDisciplineOrder(discipline); // Falls in den Optionalen Regel Default Talente festgelegt seine sollte, hole diese HashMap<String, Integer> defaultOptionalTalents = PROPERTIES .getDefaultOptionalTalents(disciplineNumber); int disciplineCircle = getCircleOf(disciplineNumber); int circlenr = 0; for (int numberOfOptionalTalents : PROPERTIES .getNumberOfOptionalTalentsPerCircleByDiscipline(discipline)) { circlenr++; if (circlenr > disciplineCircle) break; List<TALENTType> talents = new ArrayList<TALENTType>(); for (TALENTType talent : talentsList.get(circlenr)) { // Ermittele den Kreis fr ein Default Optional Talent Integer c = defaultOptionalTalents.get(talent.getName()); // Wenn der Kreis undefinert ist, dann war es kein Default Optionales Talent, sondern ein normales Optionales Talent // Nur wenn der Kreis bei einem Default Optionalen Talent nicht ber dem aktuellen Kreis liegt darf es eingefgt werden if ((c != null) && (c <= circlenr)) continue; talents.add(talent); } // Jetzt zhlen wir noch wieviele der Optionalen Talente nicht ber Vielseitigkeit gelernt wurden // und ziehen diese von der Anzahl der mglichen Optionalen Talente ab int freeOptionalTalents = numberOfOptionalTalents - isNotLearnedByVersatility(talents); // Fge der Anzahl ensprechend viel den aktuellen Kreis in die Ergebnisliste hinzu. for (int i = 0; i < freeOptionalTalents; i++) list.add(circlenr); } result.put(discipline, list); } return result; } public static boolean isLearnedByVersatility(TALENTType talent) { TALENTTEACHERType teacher = talent.getTEACHER(); if (teacher == null) return false; if (teacher.getByversatility().equals(YesnoType.YES)) return true; return false; } public static int isLearnedByVersatility(List<TALENTType> talents) { if (talents == null) return 0; int result = 0; for (TALENTType talent : talents) { if (isLearnedByVersatility(talent)) result++; } return result; } public static int isNotLearnedByVersatility(List<TALENTType> talents) { if (talents == null) return 0; int result = 0; for (TALENTType talent : talents) { if (!isLearnedByVersatility(talent)) result++; } return result; } public void addDiciplin(String name) { // Wenn die Disziplin bereits vorhanden, dann tue nichts if (getAllDisciplinesByName().get(name) != null) return; DISCIPLINEType discipline = new DISCIPLINEType(); discipline.setName(name); discipline.setCircle(1); character.getDISCIPLINE().add(discipline); ensureDisciplinTalentsExits(); realignOptionalTalents(); } public void removeLastDiciplin() { List<DISCIPLINEType> disciplines = character.getDISCIPLINE(); int size = disciplines.size(); if (size < 1) return; // Falls zu Talenten der zu lschenden Disziplin zugeordnete Skill enthalten sind, // mssen die Skills zu Skillliste verschoben werden. TalentsContainer talents = new TalentsContainer(disciplines.get(size - 1)); for (TALENTType talent : talents.getDisciplineAndOptionaltalents()) { SKILLType skill = talent.getALIGNEDSKILL(); if (skill != null) { talent.setALIGNEDSKILL(null); addSkill(skill); } } disciplines.remove(size - 1); } public void ensureDisciplinTalentsExits() { List<String> totalListOfDisciplineTalents = new ArrayList<String>(); for (TalentsContainer talents : getAllTalents()) { for (TALENTType talent : talents.getDisciplinetalents()) { totalListOfDisciplineTalents.add(getFullTalentname(talent)); } } for (DISCIPLINEType discipline : getDisciplines()) { DISCIPLINE disciplineDefinition = PROPERTIES.getDisziplin(discipline.getName()); // Wenn es zu der Disziplin der Talentliste keine Disziplindefinition gibt, dann ber springe diese Talentliste if (disciplineDefinition == null) continue; int disciplineCircleNr = discipline.getCircle(); int circlenr = 0; for (DISCIPLINECIRCLEType disciplineCircleDefinition : disciplineDefinition.getCIRCLE()) { circlenr++; if (circlenr > disciplineCircleNr) break; for (TALENTABILITYType disciplineTalent : disciplineCircleDefinition.getDISCIPLINETALENT()) { TALENTType newTalent = new TALENTType(); newTalent.setName(disciplineTalent.getName()); String limitation = disciplineTalent.getLimitation(); if (!limitation.isEmpty()) newTalent.getLIMITATION().add(limitation); newTalent.setCircle(circlenr); String newFullTalentName = getFullTalentname(newTalent); if (!totalListOfDisciplineTalents.contains(newFullTalentName)) { discipline.getDISZIPLINETALENT().add(newTalent); totalListOfDisciplineTalents.add(newFullTalentName); } } } } } public void realignOptionalTalents() { // Talentname von Unempfindlichkeit ermitteln final String durabilityName = PROPERTIES.getDurabilityName(); // Talente ermitteln die mehrfach verwendet werden drfen. HashMap<String, Integer> multiUseTalents = PROPERTIES.getMultiUseTalents(); // Liste alle vom Charakter gelernter Disziplinen List<DISCIPLINEType> disciplines = character.getDISCIPLINE(); // Wenn man bei Eins anfngt zu nummerieren, dann ist die Anzahl der Disziplinen auch gleichzeitig die Nummer der letzten Disziplin. int maxDisciplineOrder = disciplines.size(); int disciplineOrder = 0; for (DISCIPLINEType discipline : disciplines) { // Die Nummerierung der Disziplinen fngt bei Eins an, daher zlen wir hier schon hoch disciplineOrder++; for (TALENTType disTalent : discipline.getDISZIPLINETALENT()) { // Ermittle fr sptere Vergleiche den vollstndigen Diszipline namen (mit Limitation Bezeichnung) String disTalentName = getFullTalentname(disTalent); for (DISCIPLINEType compareDiscipline : disciplines) { // Talentlisten nicht mit sich selbst vergleichen, daher Schleife berspringen, wenn es die selbe Disziplin ist. if (discipline == compareDiscipline) continue; // Disziplinetalente knnen nicht realigned werden, daher ist auch keine gesonderte Prfung // ob dieses Talent bereits ge-realigned ist nicht notwendig und wre unsinnig for (TALENTType optTalent : compareDiscipline.getOPTIONALTALENT()) { String optTalentName = getFullTalentname(optTalent); if (multiUseTalents.containsKey(optTalentName)) { // MultiUseTalents knnen nicht realigned werden. // Prfe, ob es eventuell doch gemacht wurde, wenn ja korigieren wir es hier if (optTalent.getRealigned() > 0) optTalent.setRealigned(0); // Springe zum nchsten Talent, fhr diesen Schleifen durchlauf nicht fort. continue; } // Sollte das Optinaltalent auf ein Talent einer nicht mehr exisiterenden Disziplin realgined sind, // kann dieses Realgined entfernt werden if (optTalent.getRealigned() > maxDisciplineOrder) optTalent.setRealigned(0); // Unterscheide, ob das Disziplintalent das Unempfindlichkeit-Talent ist if (durabilityName.equals(disTalent.getName())) { // Wenn ja, dann ist die Limitation nicht wichtig und wir prfen nur ob das vergleichende Talent eben falls das Unempfindlichkeit-Talent ist. if (durabilityName.equals(optTalent.getName())) optTalent.setRealigned(disciplineOrder); } else { // Wenn nein, dann ist die Limitation wichtig und muss identisch sein. Daher werden die "vollstdnige" Talentnamen verglichen if (disTalentName.equals(optTalentName)) optTalent.setRealigned(disciplineOrder); } } } } } } public TALENTType addOptionalTalent(String disciplineName, int circle, TALENTABILITYType talenttype, boolean byVersatility) { if (talenttype == null) return null; TALENTType talent = new TALENTType(); talent.setName(talenttype.getName()); if (!talenttype.getLimitation().isEmpty()) talent.getLIMITATION().add(talenttype.getLimitation()); talent.setCircle(circle); RANKType rank = new RANKType(); rank.setRank(1); talent.setRANK(rank); TALENTTEACHERType teacher = new TALENTTEACHERType(); if (byVersatility) teacher.setByversatility(YesnoType.YES); talent.setTEACHER(teacher); int disciplineOrder = getDisciplineOrder(disciplineName); if (disciplineOrder < 1) { System.err.println("Discipline '" + disciplineName + "' cound not be found. So, the optional talent '" + talenttype.getName() + "' cound not be inserted."); return null; } // Wenn es sich bei dem neuen OptionalTalent um das Unempfindlichkeitstalent handelt, // dann muss geprft werden, ob dieses bereits in einder anderen Disziplin vorhanden ist. //TODO: nicht nur Unempfindlichkeitstalent if (durabilityName.equals(talent.getName())) { for (DISCIPLINEType discipline : getDisciplines()) { // Wenn die Disziplinnamen ber einstimmen, dann handelt es sich um die selbe Disziplin // und es brauch nichts geprft werden. if (disciplineName.equals(discipline.getName())) continue; for (TALENTType optTalent : discipline.getOPTIONALTALENT()) { if (!durabilityName.equals(optTalent.getName())) continue; optTalent.setRealigned(disciplineOrder); } } } getAllTalents().get(disciplineOrder - 1).getOptionaltalents().add(talent); return talent; } public void addSpell(String discipline, SPELLType spell) { for (DISCIPLINEType dis : getDisciplines()) { if (dis.getName().equals(discipline)) { dis.getSPELL().add(spell); return; } } System.err.println("Discipline '" + discipline + "' not found, could not add a spells."); } public void removeSpell(String disciplinename, SPELLType spell) { if (spell == null) return; removeSpell(disciplinename, spell.getName()); } public void removeSpell(String disciplinename, String spellname) { for (DISCIPLINEType dis : getDisciplines()) { if (dis.getName().equals(disciplinename)) { List<SPELLType> spells = dis.getSPELL(); List<SPELLType> spelltoremove = new ArrayList<SPELLType>(); for (SPELLType currentspell : spells) { if (spellname.equals(currentspell.getName())) { spelltoremove.add(currentspell); } } spells.removeAll(spelltoremove); return; } } } public boolean hasSpellLearned(String disciplinename, SPELLType spelltype) { return hasSpellLearned(disciplinename, spelltype.getName()); } public boolean hasSpellLearned(String disciplinename, String spellname) { for (DISCIPLINEType discipline : getDisciplines()) { if (disciplinename.equals(discipline.getName())) { for (SPELLType spell : discipline.getSPELL()) { if (spellname.equals(spell.getName())) return true; } return false; } } return false; } public boolean hasSpellLearnedBySpellability(String disciplinename, SPELLType spelltype) { return hasSpellLearnedBySpellability(disciplinename, spelltype.getName()); } public boolean hasSpellLearnedBySpellability(String disciplinename, String spellname) { for (DISCIPLINEType discipline : getDisciplines()) { if (disciplinename.equals(discipline.getName())) { for (SPELLType spell : discipline.getSPELL()) { if (spellname.equals(spell.getName())) return spell.getByspellability().equals(YesnoType.YES); } return false; } } return false; } public void toggleSpellLearnedBySpellability(String disciplinename, SPELLType spelltype) { toggleSpellLearnedBySpellability(disciplinename, spelltype.getName()); } public void toggleSpellLearnedBySpellability(String disciplinename, String spellname) { for (DISCIPLINEType discipline : getDisciplines()) { if (disciplinename.equals(discipline.getName())) { for (SPELLType spell : discipline.getSPELL()) { if (spellname.equals(spell.getName())) { if (spell.getByspellability().equals(YesnoType.YES)) spell.setByspellability(YesnoType.NO); else spell.setByspellability(YesnoType.YES); return; } } return; } } } public boolean hasKnackLearned(KNACKBASEType knack) { String knackName = knack.getName(); String knackLimitation = knack.getLimitation(); boolean noKnackLimitation = knackLimitation.isEmpty(); for (TalentsContainer talents : getAllTalents()) { for (TALENTType talent : talents.getDisciplineAndOptionaltalents()) { boolean matchLimitation = false; if (noKnackLimitation) matchLimitation = true; else if (talent.getLIMITATION().size() > 0) matchLimitation = talent.getLIMITATION().get(0).equals(knackLimitation); if (matchLimitation) for (KNACKType k : talent.getKNACK()) { if (k.getName().equals(knackName)) return true; } } } return false; } public void removeKnack(KNACKBASEType knack) { String knackName = knack.getName(); String knackLimitation = knack.getLimitation(); boolean noKnackLimitation = knackLimitation.isEmpty(); for (TalentsContainer talents : getAllTalents()) { for (TALENTType talent : talents.getDisciplineAndOptionaltalents()) { boolean matchLimitation = false; if (noKnackLimitation) matchLimitation = true; else if (talent.getLIMITATION().size() > 0) matchLimitation = talent.getLIMITATION().get(0).equals(knackLimitation); if (matchLimitation) { List<KNACKType> talentknacks = talent.getKNACK(); List<KNACKType> remove = new ArrayList<KNACKType>(); for (KNACKType k : talentknacks) if (k.getName().equals(knackName)) remove.add(k); talentknacks.removeAll(remove); } } } } public List<ITEMType> getItems() { return character.getITEM(); } public String getDESCRIPTION() { String result = character.getDESCRIPTION(); if (result == null) return ""; return result; } public void setDESCRIPTION(String description) { character.setDESCRIPTION(description); } public String getCOMMENT() { String result = character.getCOMMENT(); if (result == null) return ""; return result; } public void setCOMMENT(String comment) { character.setCOMMENT(comment); } public List<MAGICITEMType> getMagicItem() { return character.getMAGICITEM(); } public List<THREADITEMType> getThreadItem() { return character.getTHREADITEM(); } public List<MAGICITEMType> getBloodCharmItem() { return character.getBLOODCHARMITEM(); } public List<PATTERNITEMType> getPatternItem() { return character.getPATTERNITEM(); } public List<ARMORType> getMagicArmor() { List<ARMORType> magicarmor = new ArrayList<ARMORType>(); for (THREADITEMType magicitem : getThreadItem()) { String name = magicitem.getName(); float weight = magicitem.getWeight(); YesnoType used = magicitem.getUsed(); ItemkindType kind = magicitem.getKind(); int weaven = magicitem.getWeaventhreadrank(); String location = magicitem.getLocation(); int edn = magicitem.getEnchantingdifficultynumber(); int blooddamage = magicitem.getBlooddamage(); int dr = magicitem.getDepatterningrate(); String bookref = magicitem.getBookref(); int size = magicitem.getSize(); int rank = 0; ARMORType newmagicarmor = null; SHIELDType newmagicshield = null; List<CHARACTERISTICSCOST> LpCosts = PROPERTIES_Characteristics.getTalentRankLPIncreaseTable(1, magicitem.getLpcostgrowth()); for (THREADRANKType threadrank : magicitem.getTHREADRANK()) { threadrank.setLpcost(LpCosts.get(rank).getCost()); rank++; ARMORType armor = threadrank.getARMOR(); if (armor != null) { armor.setName(name); armor.setWeight(weight); armor.setUsed(used); armor.setKind(kind); armor.setLocation(location); armor.setEdn(edn); armor.setBlooddamage(blooddamage); armor.setDepatterningrate(dr); armor.setBookref(bookref); armor.setSize(size); if (weaven == rank) newmagicarmor = armor; } SHIELDType shield = threadrank.getSHIELD(); if (shield != null) { shield.setName(name); shield.setWeight(weight); shield.setUsed(used); shield.setKind(kind); shield.setLocation(location); shield.setEdn(edn); shield.setBlooddamage(blooddamage); shield.setDepatterningrate(dr); shield.setBookref(bookref); shield.setSize(size); if (weaven == rank) newmagicshield = shield; } } if (newmagicarmor != null) magicarmor.add(copyArmor(newmagicarmor, true)); if (newmagicshield != null) magicarmor.add(copyArmor(newmagicshield, true)); } return magicarmor; } public static ARMORType copyArmor(ARMORType armor, boolean setvirtual) { if (armor == null) return null; ARMORType newarmor; if (armor instanceof SHIELDType) newarmor = new SHIELDType(); else newarmor = new ARMORType(); copyItem(armor, newarmor, setvirtual); newarmor.setDateforged(armor.getDateforged()); newarmor.setEdn(armor.getEdn()); newarmor.setEdnElement(armor.getEdnElement()); newarmor.setMysticarmor(armor.getMysticarmor()); newarmor.setPenalty(armor.getPenalty()); newarmor.setPhysicalarmor(armor.getPhysicalarmor()); newarmor.setTimesforgedMystic(armor.getTimesforgedMystic()); newarmor.setTimesforgedPhysical(armor.getPhysicalarmor()); if (newarmor instanceof SHIELDType) { ((SHIELDType) newarmor).setMysticdeflectionbonus(((SHIELDType) armor).getMysticdeflectionbonus()); ((SHIELDType) newarmor).setPhysicaldeflectionbonus(((SHIELDType) armor).getPhysicaldeflectionbonus()); ((SHIELDType) newarmor).setShatterthreshold(((SHIELDType) armor).getShatterthreshold()); } return newarmor; } public List<ARMORType> removeVirtualArmorFromNormalArmorList() { List<ARMORType> armors = getProtection().getARMOROrSHIELD(); List<ARMORType> delete = new ArrayList<ARMORType>(); for (ARMORType armor : armors) if (armor.getVirtual().equals(YesnoType.YES)) delete.add(armor); armors.removeAll(delete); return armors; } public List<WEAPONType> getMagicWeapon() { List<WEAPONType> magicweapon = new ArrayList<WEAPONType>(); for (THREADITEMType magicitem : getThreadItem()) { String name = magicitem.getName(); float weight = magicitem.getWeight(); YesnoType used = magicitem.getUsed(); int weaven = magicitem.getWeaventhreadrank(); int blooddamage = magicitem.getBlooddamage(); int dr = magicitem.getDepatterningrate(); String bookref = magicitem.getBookref(); int size = magicitem.getSize(); int rank = 0; WEAPONType newmagicweapon = null; List<CHARACTERISTICSCOST> LpCosts = PROPERTIES_Characteristics.getTalentRankLPIncreaseTable(1, magicitem.getLpcostgrowth()); for (THREADRANKType threadrank : magicitem.getTHREADRANK()) { threadrank.setLpcost(LpCosts.get(rank).getCost()); rank++; WEAPONType weapon = threadrank.getWEAPON(); if (weapon != null) { weapon.setName(name); weapon.setWeight(weight); weapon.setUsed(used); weapon.setKind(magicitem.getKind()); weapon.setBlooddamage(blooddamage); weapon.setDepatterningrate(dr); weapon.setBookref(bookref); weapon.setSize(size); if (weaven > 0) newmagicweapon = weapon; } weaven--; } if (newmagicweapon != null) magicweapon.add(copyWeapon(newmagicweapon, true)); } return magicweapon; } public static WEAPONType copyWeapon(WEAPONType weapon, boolean setvirtual) { if (weapon == null) return null; WEAPONType newweapon = new WEAPONType(); copyItem(weapon, newweapon, setvirtual); newweapon.setDateforged(weapon.getDateforged()); newweapon.setDepatterningrate(weapon.getDepatterningrate()); newweapon.setDamagestep(weapon.getDamagestep()); newweapon.setDexteritymin(weapon.getDexteritymin()); newweapon.setLongrange(weapon.getLongrange()); newweapon.setShortrange(weapon.getShortrange()); newweapon.setStrengthmin(weapon.getStrengthmin()); newweapon.setTimesforged(weapon.getTimesforged()); return newweapon; } public static WOUNDType copyWound(WOUNDType wound) { if (wound == null) return null; WOUNDType newwound = new WOUNDType(); newwound.setBlood(wound.getBlood()); newwound.setNormal(wound.getNormal()); newwound.setPenalties(wound.getPenalties()); newwound.setThreshold(wound.getThreshold()); return newwound; } public static DISZIPINABILITYType copyDisciplineAbility(DISZIPINABILITYType disciplineability) { if (disciplineability == null) return null; DISZIPINABILITYType newdisciplineability = new DISZIPINABILITYType(); newdisciplineability.setCount(disciplineability.getCount()); return newdisciplineability; } public static DEFENSEABILITYType copyDefenseAbility(DEFENSEABILITYType defenseability) { if (defenseability == null) return null; DEFENSEABILITYType newdefenseability = new DEFENSEABILITYType(); newdefenseability.setBonus(defenseability.getBonus()); newdefenseability.setKind(defenseability.getKind()); return newdefenseability; } public static TALENTABILITYType copyTalentAbility(TALENTABILITYType talentability) { if (talentability == null) return null; TALENTABILITYType newtalentability = new TALENTABILITYType(); newtalentability.setBonus(talentability.getBonus()); newtalentability.setLimitation(talentability.getLimitation()); newtalentability.setName(talentability.getName()); newtalentability.setPool(talentability.getPool()); return newtalentability; } public static THREADRANKType copyThreadRank(THREADRANKType rank) { if (rank == null) return null; THREADRANKType newrank = new THREADRANKType(); newrank.setEffect(rank.getEffect()); newrank.setLpcost(rank.getLpcost()); newrank.setKeyknowledge(rank.getKeyknowledge()); newrank.setDeed(rank.getDeed()); newrank.setARMOR(copyArmor(rank.getARMOR(), false)); newrank.setSHIELD((SHIELDType) copyArmor(rank.getSHIELD(), false)); newrank.setWEAPON(copyWeapon(rank.getWEAPON(), false)); newrank.setWOUND(copyWound(rank.getWOUND())); for (String i : rank.getABILITY()) newrank.getABILITY().add(i); for (String i : rank.getSPELL()) newrank.getSPELL().add(i); for (DISZIPINABILITYType i : rank.getINITIATIVE()) newrank.getINITIATIVE().add(copyDisciplineAbility(i)); for (DISZIPINABILITYType i : rank.getKARMASTEP()) newrank.getKARMASTEP().add(copyDisciplineAbility(i)); for (DISZIPINABILITYType i : rank.getMAXKARMA()) newrank.getINITIATIVE().add(copyDisciplineAbility(i)); for (DISZIPINABILITYType i : rank.getRECOVERYTEST()) newrank.getMAXKARMA().add(copyDisciplineAbility(i)); for (DISZIPINABILITYType i : rank.getSPELLABILITY()) newrank.getSPELLABILITY().add(copyDisciplineAbility(i)); for (DEFENSEABILITYType i : rank.getDEFENSE()) newrank.getDEFENSE().add(copyDefenseAbility(i)); for (TALENTABILITYType i : rank.getTALENT()) newrank.getTALENT().add(copyTalentAbility(i)); return newrank; } public List<WEAPONType> cutMagicWeaponFromNormalWeaponList() { List<WEAPONType> magicWeapon = getMagicWeapon(); List<WEAPONType> normalWeaponList = character.getWEAPON(); List<WEAPONType> delete = new ArrayList<WEAPONType>(); for (WEAPONType weapon : normalWeaponList) { String weaponName = weapon.getName(); for (WEAPONType w : magicWeapon) { w.setVirtual(YesnoType.YES); if (weaponName.equals(w.getName())) delete.add(weapon); } } normalWeaponList.removeAll(delete); return magicWeapon; } public static List<Integer> calculateAccounting(List<ACCOUNTINGType> accountings) { int plus = 0; int minus = 0; for (ACCOUNTINGType lp : accountings) { switch (lp.getType()) { case PLUS: plus += lp.getValue(); break; case MINUS: minus += lp.getValue(); break; } } List<Integer> account = new ArrayList<Integer>(); account.add(plus); // 0 account.add(minus); // 1 return account; } public DEVOTIONType getDevotionPoints() { return character.getDEVOTION(); } public String getPassion() { DEVOTIONType devotion = getDevotionPoints(); if (devotion == null) return ""; String passion = devotion.getPassion(); if (passion == null) return ""; return passion; } public int calculateDevotionPoints() { DEVOTIONType devotionpoints = getDevotionPoints(); if (devotionpoints == null) return 0; List<Integer> dp = calculateAccounting(devotionpoints.getDEVOTIONPOINTS()); int result = dp.get(0) - dp.get(1); devotionpoints.setValue(result); return result; } public int getNumberOfTalentsLearnedByVersatility() { List<TalentsContainer> allTalents = getAllTalents(); if (allTalents == null) return 0; int result = 0; for (TalentsContainer talents : allTalents) { result += isLearnedByVersatility(talents.getDisciplineAndOptionaltalents()); } return result; } public int getUnusedVersatilityRanks() { int result = -getNumberOfTalentsLearnedByVersatility(); List<TALENTType> versatilityList = getTalentByName(PROPERTIES.getVersatilityName()); if (versatilityList == null) return result; if (versatilityList.isEmpty()) return result; for (TALENTType versatility : versatilityList) { RANKType rank = versatility.getRANK(); if (rank != null) { result += rank.getRank(); } } return result; } public void removeEmptySkills() { List<SKILLType> skills = getSkills(); List<SKILLType> remove = new ArrayList<SKILLType>(); for (SKILLType skill : skills) { RANKType rank = skill.getRANK(); if ((rank != null) && (rank.getRank() > 0)) { // Lsche alle leeren Limitaions, falls welche vorhanden sind while (skill.getLIMITATION().remove("")) ; continue; } remove.add(skill); } removeSkill(remove); } // Finde zu allen Talenten, ob es Realigned Talente dazu gibt und aktuallisiere deren Realigned Rank public void updateRealignedTalents() { HashMap<String, List<TALENTType>> realignedTalentHash = new HashMap<String, List<TALENTType>>(); // Finde alle Talente die als Realigned makiert sind for (TalentsContainer talents : getAllTalents()) { insertIfRealigned(realignedTalentHash, talents.getDisciplineAndOptionaltalents()); } for (String talentName : realignedTalentHash.keySet()) { // Wurde ein Talent Realigned, dann gibt es das Talent unter gleichen Namen mehrfach. List<TALENTType> talentsByName = getTalentByName(talentName); List<TALENTType> realignedTalentList = realignedTalentHash.get(talentName); // Entferne unter der gleichnamigen Talenten alle die realgined wurden talentsByName.removeAll(realignedTalentList); // Theoretisch sollte in talentsByName nun genau ein Element brig bleiben. // Bestimme fr dieses nun den Realigned-Rang int maxRealignedRank = 0; for (TALENTType talent : realignedTalentList) { int currentRealignedRank = talent.getRANK().getRank(); if (maxRealignedRank < currentRealignedRank) maxRealignedRank = currentRealignedRank; } // Auch wenn nur genau ein Talent betroffen sein drfte, nutzen wir eine Schleife. for (TALENTType talent : talentsByName) { RANKType rank = talent.getRANK(); // An dieser Stelle sollte der rank nicht 'null' sein knnen, aber eine Prfung schadet nicht. if (rank == null) { rank = new RANKType(); talent.setRANK(rank); } rank.setRealignedrank(maxRealignedRank); } } } private void insertIfRealigned(HashMap<String, List<TALENTType>> realignedTalents, List<TALENTType> talents) { for (TALENTType talent : talents) { if (talent.getRealigned() > 0) { String talentName = talent.getName(); List<TALENTType> list = realignedTalents.get(talentName); if (list == null) { list = new ArrayList<TALENTType>(); realignedTalents.put(talentName, list); } list.add(talent); } } } public void removeZeroRankOptionalTalents() { for (TalentsContainer talents : getAllTalents()) { List<TALENTType> rankZeroTalents = new ArrayList<TALENTType>(); List<TALENTType> optionalTalents = talents.getOptionaltalents(); for (TALENTType talent : optionalTalents) { RANKType rank = talent.getRANK(); if ((rank == null) || (rank.getRank() < 1)) { rankZeroTalents.add(talent); // Sollte ein Skill zu diesem Tallent Realigned sein, dann lse diese Verbindung bei Rank 0 SKILLType skill = talent.getALIGNEDSKILL(); if (skill != null) { talent.setALIGNEDSKILL(null); addSkill(skill); } } } optionalTalents.removeAll(rankZeroTalents); } } public void removeIllegalTalents() { for (DISCIPLINEType discipline : getDisciplines()) { int disciplineCircleNr = discipline.getCircle(); List<TALENTType> remove = new ArrayList<TALENTType>(); List<TALENTType> disciplineTalents = discipline.getDISZIPLINETALENT(); for (TALENTType talent : disciplineTalents) { if (talent.getCircle() > disciplineCircleNr) remove.add(talent); } disciplineTalents.removeAll(remove); remove.clear(); List<TALENTType> optionalTalents = discipline.getDISZIPLINETALENT(); for (TALENTType talent : optionalTalents) { if (talent.getCircle() > disciplineCircleNr) { remove.add(talent); continue; } // Talente bei denen die Limitation auf "(#)" endet kommen von ThreadItems und fliegen erstmal raus // Diese werden wieder vom ThreadItem ergnzt, wenn es noch da ist. if (join(talent.getLIMITATION()).endsWith("(#)")) { remove.add(talent); continue; } } optionalTalents.removeAll(remove); } for (DISCIPLINEType discipline1 : getDisciplines()) { for (TALENTType talent1 : discipline1.getDISZIPLINETALENT()) { String talentname1 = getFullTalentname(talent1); for (DISCIPLINEType discipline2 : getDisciplines()) { if (discipline1 == discipline2) continue; // in anderen Diszipinen (2) darf es kein Disziplintalent geben, // dass bereits in dieser Disziplin (1) ein Disziplintalent ist. List<TALENTType> remove = new ArrayList<TALENTType>(); List<TALENTType> talents2 = discipline2.getDISZIPLINETALENT(); for (TALENTType talent2 : talents2) { String talentname2 = getFullTalentname(talent2); if (talentname1.equals(talentname2)) remove.add(talent2); } talents2.removeAll(remove); } } } } public NAMEGIVERABILITYType getRace() { APPEARANCEType appearance = getAppearance(); String race = appearance.getRace(); String origin = appearance.getOrigin(); NAMEGIVERABILITYType fallback = null; for (NAMEGIVERABILITYType n : PROPERTIES.getNamegivers()) { if (n.getName().equals(race)) { // wenn der Rassenname bereinstimmt, dann knnte es schon mal passen // und da wir "first-match" und nicht "last-match" haben wollen, setzen wir den fallback nur wenn er noch nicht gesetzt wurde if (fallback == null) fallback = n; // aber erst wenn auch das Ursprungsgebiet zusammen passt haben wir unsere Rassendefinition if (n.getORIGIN().contains(origin)) return n; } } return fallback; } public void calculateMovement() { int movementFlight = 0; int movementGround = 0; NAMEGIVERABILITYType namegiver = getRace(); if (namegiver != null) { movementFlight = namegiver.getMovementFlight(); movementGround = namegiver.getMovementGround(); } HashMap<String, ATTRIBUTEType> attributes = getAttributes(); ATTRIBUTEType strength = attributes.get("STR"); ATTRIBUTEType dexterity = attributes.get("DEX"); int modStr = Math.round((float) (strength.getCurrentvalue() - strength.getRacevalue()) / 3f); int modDex = Math.round((float) (dexterity.getCurrentvalue() - dexterity.getRacevalue()) / 3f); switch (OptionalRule_AttributeBasedMovement) { case DEX: movementGround += modDex; if (movementFlight > 0) movementFlight += modDex; break; case STR: movementGround += modStr; if (movementFlight > 0) movementFlight += modStr; break; case STR_DEX: int av = Math.round((modDex + modStr) / 2f); movementGround += av; if (movementFlight > 0) movementFlight += av; break; case MAX: int max = (modDex > modStr) ? modDex : modStr; movementGround += max; if (movementFlight > 0) movementFlight += max; break; case NA: break; } MOVEMENTType movement = getMovement(); movement.setFlight(movementFlight); movement.setGround(movementGround); } public void calculateCarrying() { CARRYINGType carrying = getCarrying(); List<Integer> encumbrance = PROPERTIES_Characteristics.getENCUMBRANCE(); int strength = getAttributes().get("STR").getCurrentvalue(); if (strength < 1) { // wenn Wert kleiner 1, dann keine Fehlermedung sondern einfach nur den Wert korrigieren strength = 1; } if (strength > encumbrance.size()) { strength = encumbrance.size(); System.err.println( "The strength attribute was out of range. The carrying value will now base on: " + strength); } Integer carryingValue = encumbrance.get(strength); carrying.setCarrying(carryingValue); carrying.setLifting(carryingValue * 2); } public HashMap<String, ITEMType> getHashOfAllItems() { HashMap<String, ITEMType> result = new HashMap<String, ITEMType>(); for (ITEMType item : character.getITEM()) result.put(item.getName(), item); int pursecounter = 0; for (COINSType coins : character.getCOINS()) { String name = coins.getName(); if (name == null) { name = "Purse #" + String.valueOf(++pursecounter); } else { if (name.isEmpty()) name = "Purse #" + String.valueOf(++pursecounter); else name = "Purse " + name; } name += " (c:" + coins.getCopper() + " s:" + coins.getSilver() + " g:" + coins.getGold(); if (coins.getEarth() > 0) name += " e:" + coins.getEarth(); if (coins.getWater() > 0) name += " w:" + coins.getWater(); if (coins.getAir() > 0) name += " a:" + coins.getAir(); if (coins.getFire() > 0) name += " f:" + coins.getFire(); if (coins.getOrichalcum() > 0) name += " o:" + coins.getOrichalcum(); name += ")"; result.put(name, coins); } for (ITEMType item : character.getWEAPON()) result.put(item.getName(), item); PROTECTIONType protection = character.getPROTECTION(); if (protection != null) { boolean naturalArmor = true; // Der erste Eintrag ist immer die natrliche Rstung for (ITEMType item : protection.getARMOROrSHIELD()) { if (naturalArmor) { // Die natrliche Rstng nicht als Gegenstand auflisten naturalArmor = false; continue; } result.put(item.getName(), item); } } for (ITEMType item : character.getMAGICITEM()) result.put(item.getName(), item); for (ITEMType item : character.getBLOODCHARMITEM()) result.put(item.getName(), item); for (ITEMType item : character.getPATTERNITEM()) result.put(item.getName(), item); for (ITEMType item : character.getTHREADITEM()) result.put(item.getName(), item); return result; } public List<ITEMType> getAllNonVirtualItems() { List<ITEMType> result = new ArrayList<ITEMType>(); for (ITEMType item : character.getITEM()) if (item.getVirtual().equals(YesnoType.NO)) result.add(item); for (ITEMType item : character.getCOINS()) if (item.getVirtual().equals(YesnoType.NO)) result.add(item); for (ITEMType item : character.getWEAPON()) if (item.getVirtual().equals(YesnoType.NO)) result.add(item); PROTECTIONType protection = character.getPROTECTION(); if (protection != null) { for (ITEMType item : protection.getARMOROrSHIELD()) if (item.getVirtual().equals(YesnoType.NO)) result.add(item); } for (ITEMType item : character.getMAGICITEM()) if (item.getVirtual().equals(YesnoType.NO)) result.add(item); for (ITEMType item : character.getBLOODCHARMITEM()) if (item.getVirtual().equals(YesnoType.NO)) result.add(item); for (ITEMType item : character.getPATTERNITEM()) if (item.getVirtual().equals(YesnoType.NO)) result.add(item); for (ITEMType item : character.getTHREADITEM()) if (item.getVirtual().equals(YesnoType.NO)) result.add(item); return result; } public List<Base64BinaryType> getPortrait() { List<Base64BinaryType> result = character.getPORTRAIT(); if (result.isEmpty()) { APPEARANCEType appearance = getAppearance(); File[] files = new File("images/character").listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { if (name == null) return false; name = name.toLowerCase(); if (!name.startsWith("portrait_")) return false; if (name.endsWith(".jpg")) return true; if (name.endsWith(".png")) return true; if (name.endsWith(".gif")) return true; return false; } }); List<List<File>> filescore = new ArrayList<List<File>>(); filescore.add(new ArrayList<File>()); // 0 filescore.add(new ArrayList<File>()); // 1 filescore.add(new ArrayList<File>()); // 2 filescore.add(new ArrayList<File>()); // 3 filescore.get(0).add(new File("images/character/portrait.jpg")); String race = "_" + appearance.getRace().toLowerCase() + "_"; String gender = "_" + appearance.getGender().value().toLowerCase() + "_"; String origin = "_" + appearance.getOrigin().toLowerCase() + "_"; for (File f : files) { String name = f.getName().toLowerCase().replace(".", "_"); if (name.contains(race)) { int score = 1; if (name.contains(gender)) score++; if (name.contains(origin)) score++; filescore.get(score).add(f); } } File file = null; for (int score = 3; score >= 0; score--) { if (file != null) break; List<File> fileset = filescore.get(score); if (!fileset.isEmpty()) file = fileset.get(rand.nextInt(fileset.size())); } if (file != null) try { FileInputStream fileInputStream = new FileInputStream(file); byte[] data = new byte[(int) file.length()]; fileInputStream.read(data); fileInputStream.close(); Base64BinaryType base64bin = new Base64BinaryType(); base64bin.setValue(data); final String[] filename = file.getName().split("\\."); base64bin.setContenttype("image/" + filename[filename.length - 1]); result.add(base64bin); } catch (FileNotFoundException e) { // Wenn Datei nicht gefunden, dann Pech. System.err.println("can not insert default portrait : " + e.getLocalizedMessage()); } catch (IOException e) { System.err.println("can not insert default portrait : " + e.getLocalizedMessage()); } } return result; } public void readjustInitiativeModifikator(int adjustment, boolean armor) { INITIATIVEType initiative = getInitiative(); if (armor) { int currentarmorpenalty = initiative.getArmorpenalty(); if (adjustment > currentarmorpenalty) { initiative.setArmorpenalty(0); System.err.println("Armor penalty can not be negativ. Reduce initiative adjustment from " + adjustment + " to " + currentarmorpenalty); adjustment = currentarmorpenalty; } else { initiative.setArmorpenalty(currentarmorpenalty - adjustment); } } initiative.setModification(initiative.getModification() + adjustment); initiative.setStep(initiative.getBase() + initiative.getModification()); initiative.setDice(PROPERTIES.step2Dice(initiative.getStep())); for (TalentsContainer talents : getAllTalents()) { for (TALENTType talent : talents.getDisciplineAndOptionaltalents()) readjustSkillInitiativeModifikator(talent, adjustment); } for (SKILLType skill : getSkills()) readjustSkillInitiativeModifikator(skill, adjustment); } private static void readjustSkillInitiativeModifikator(SKILLType skill, int adjustment) { // Wenn der Skill gar keine Initiative-Skill ist, tut nichts if (!skill.getIsinitiative().equals(YesnoType.YES)) return; skill.setBonus(skill.getBonus() + adjustment); RANKType rank = skill.getRANK(); if (rank == null) { rank = new RANKType(); skill.setRANK(rank); } rank.setBonus(rank.getBonus() + adjustment); rank.setStep(rank.getStep() + adjustment); rank.setDice(PROPERTIES.step2Dice(rank.getStep())); } public void clearLanguages() { character.getLANGUAGE().clear(); } public LanguageContainer getDefaultLanguages() { String origin = getAppearance().getOrigin(); String race = getAppearance().getRace(); LanguageContainer defaultlanguages = new LanguageContainer(PROPERTIES.getDefaultLanguage(origin)); for (NAMEGIVERABILITYType namegiver : PROPERTIES.getNamegivers()) { if (namegiver.getName().equals(race)) { defaultlanguages.insertLanguages(namegiver.getDEFAULTLANGUAGE()); } } return defaultlanguages; } public LanguageContainer getLanguages() { LanguageContainer defaultlanguages = getDefaultLanguages().copy(); int[] defaultCountOfSpeakReadWrite = defaultlanguages.getCountOfSpeakReadWrite(null); LanguageContainer languages = new LanguageContainer(character.getLANGUAGE()); for (CHARACTERLANGUAGEType l : defaultlanguages.getLanguages()) { int[] currentCountOfSpeakReadWrite = languages.getCountOfSpeakReadWrite(null); if ((currentCountOfSpeakReadWrite[0] >= defaultCountOfSpeakReadWrite[0]) && (currentCountOfSpeakReadWrite[1] >= defaultCountOfSpeakReadWrite[1])) break; languages.insertLanguage(l); } return languages; } public void fillOptionalTalentsRandom(String disciplinename) { int circleNr = getCircleOf(disciplinename); while (true) { List<Integer> l = getCircleOfMissingOptionalTalents().get(disciplinename); if (l.isEmpty()) break; int circle = l.get(0); DISCIPLINE discipline = PROPERTIES.getDisziplin(disciplinename); List<TALENTABILITYType> talentlist = getUnusedOptionalTalents(discipline, circle); // Suche nach dem Talent Unempfindlichkeit TALENTABILITYType talent = null; for (TALENTABILITYType t : talentlist) { if (t.getName().equals(durabilityName)) { talent = t; TALENTType newtalent = addOptionalTalent(disciplinename, circle, talent, false); newtalent.getRANK().setRank(circleNr); break; } } if (talent == null) { talent = talentlist.get(spaeterzufall(talentlist.size())); TALENTType newtalent = addOptionalTalent(disciplinename, circle, talent, false); newtalent.getRANK().setRank(circleNr - spaeterzufall(circle)); } } } public static int spaeterzufall(int bereich) { int g = 1; for (int i = 0; i < bereich; i++) g += i; int r = rand.nextInt(g); g = 0; for (int i = 0; i < bereich; i++) { if (r <= g) return i; g += i; } return bereich - 1; } public void clearBloodDamage() { HEALTHType health = getHealth(); // Ermittle aktuellen Blutschaden um die Anpassung der Todes und Bewustlosigkeitsschwelle zu korrigieren int blooddamge = health.getBlooddamage(); DEATHType death = getDeath(); death.setValue(death.getValue() + blooddamge); death.setAdjustment(death.getAdjustment() + blooddamge); DEATHType unconsciousness = getUnconsciousness(); unconsciousness.setValue(unconsciousness.getValue() + blooddamge); unconsciousness.setAdjustment(unconsciousness.getAdjustment() + blooddamge); // Jetzt setze den Blutschaden auf 0 health.setBlooddamage(0); // Ohne Blutschaden gibts auch keine "Zerfallsrate" health.setDepatterningrate(0); } public void addBloodDamgeFrom(ITEMType item) { HEALTHType health = getHealth(); int itemBloodDamge = item.getBlooddamage(); health.setBlooddamage(health.getBlooddamage() + itemBloodDamge); health.setDepatterningrate(health.getDepatterningrate() + item.getDepatterningrate()); DEATHType death = health.getDEATH(); death.setAdjustment(death.getAdjustment() - itemBloodDamge); DEATHType unconsciousness = health.getUNCONSCIOUSNESS(); unconsciousness.setAdjustment(unconsciousness.getAdjustment() - itemBloodDamge); } public void insertKnack(KNACKBASEType knack) { String limitation = knack.getLimitation(); String knackname = knack.getName(); boolean noLimitation = limitation.isEmpty(); for (TALENTType talent : getTalentByName(knack.getBasename())) { boolean matchLimitation = false; if (noLimitation) matchLimitation = true; else if (talent.getLIMITATION().size() > 0) matchLimitation = talent.getLIMITATION().get(0).equals(limitation); if (matchLimitation) { List<KNACKType> talentknacks = talent.getKNACK(); for (KNACKType k : talentknacks) { if (k.getName().equals(knackname)) return; } KNACKType k = new KNACKType(); k.setName(knackname); k.setMinrank(knack.getMinrank()); k.setStrain(knack.getStrain()); k.setBookref(knack.getBookref()); talentknacks.add(k); return; } } } public static void makeMaxForge(ARMORType armor) { if (armor == null) return; int physicalarmor = armor.getPhysicalarmor(); Double p = Math.ceil(Double.valueOf(physicalarmor) / 2.0d); armor.setPhysicalarmor(physicalarmor + p.intValue()); int mysticarmor = armor.getMysticarmor(); Double m = Math.ceil(Double.valueOf(mysticarmor) / 2.0d); armor.setMysticarmor(mysticarmor + m.intValue()); } public static void makeMaxForge(WEAPONType weapon) { if (weapon == null) return; weapon.setDamagestep(weapon.getDamagestep() + weapon.getSize()); } public static void copyItem(ITEMType src, ITEMType dst) { copyItem(src, dst, false); } public static void copyItem(ITEMType src, ITEMType dst, boolean setvirtual) { dst.setBlooddamage(src.getBlooddamage()); dst.setBookref(src.getBookref()); dst.setDepatterningrate(src.getDepatterningrate()); dst.setDESCRIPTION(src.getDESCRIPTION()); dst.setKind(src.getKind()); dst.setLocation(src.getLocation()); dst.setName(src.getName()); dst.setPrice(src.getPrice()); dst.setSize(src.getSize()); dst.setUsed(src.getUsed()); dst.setWeight(src.getWeight()); if (setvirtual) dst.setVirtual(YesnoType.YES); else dst.setVirtual(src.getVirtual()); List<Base64BinaryType> images = dst.getIMAGE(); for (Base64BinaryType image : src.getIMAGE()) images.add(copyImage(image)); } public static void copyItem(MAGICITEMType src, MAGICITEMType dst) { copyItem(src, dst, false); } public static void copyItem(MAGICITEMType src, MAGICITEMType dst, boolean setvirtual) { copyItem((ITEMType) src, (ITEMType) dst, setvirtual); dst.setEnchantingdifficultynumber(src.getEnchantingdifficultynumber()); dst.setEffect(src.getEffect()); dst.setSpelldefense(src.getSpelldefense()); } public static void copyItem(PATTERNITEMType src, PATTERNITEMType dst) { copyItem(src, dst, false); } public static void copyItem(PATTERNITEMType src, PATTERNITEMType dst, boolean setvirtual) { copyItem((MAGICITEMType) src, (MAGICITEMType) dst, setvirtual); dst.setPatternkind(src.getPatternkind()); dst.setTruepattern(src.getTruepattern()); dst.setKeyknowledge(src.getKeyknowledge()); dst.setWeaventhreadrank(src.getWeaventhreadrank()); } public static void copyItem(THREADITEMType src, THREADITEMType dst) { copyItem(src, dst, false); } public static void copyItem(THREADITEMType src, THREADITEMType dst, boolean setvirtual) { copyItem((MAGICITEMType) src, (MAGICITEMType) dst, setvirtual); dst.setLpcostgrowth(src.getLpcostgrowth()); dst.setMaxthreads(src.getMaxthreads()); dst.setWeaventhreadrank(src.getWeaventhreadrank()); dst.setARMOR(copyArmor(src.getARMOR(), setvirtual)); dst.setSHIELD((SHIELDType) copyArmor(src.getSHIELD(), setvirtual)); dst.setWEAPON(copyWeapon(src.getWEAPON(), setvirtual)); List<THREADRANKType> ranks = dst.getTHREADRANK(); for (THREADRANKType rank : src.getTHREADRANK()) { ranks.add(copyThreadRank(rank)); } } public static Base64BinaryType copyImage(Base64BinaryType image) { if (image == null) return null; Base64BinaryType result = new Base64BinaryType(); result.setContenttype(image.getContenttype()); result.setValue(image.getValue()); return result; } }