/* * (c) 2000-2009 Carlos G�mez Rodr�guez, todos los derechos reservados / all rights reserved. * Licencia en license/bsd.txt / License in license/bsd.txt */ package eu.irreality.age; import java.io.*; import java.util.*; import eu.irreality.age.debug.Debug; public class Weapon extends Item { private static int USAGE_CORRECTOR = 100; String weapon_type; double minskill_twohand; double minskill_onehand; double maxskill; private String attack_damage_formula; private String defense_damage_formula; //obsolete String damage_type; String[] attack_names_list; //obsolete String wieldableLimbs; List /*of dollar-separated String*/ wieldableLimbs = new Vector(); //modern skill system vars //String wieldableLimbs: already present (namelist) private long attackMinimalUsage; private String[] attackInvolvedSkills; private double[] attackInvolvedSkillRelevance; private double attackProbabilitySteepness; private double attackTimeSteepness; private double attackStartingTime; private double attackRecoverTimeSteepness; private double attackRecoverStartingTime; private long defenseMinimalUsage; private String[] defenseInvolvedSkills; private double[] defenseInvolvedSkillRelevance; private double defenseProbabilitySteepness; private double defenseTimeSteepness; private double defenseStartingTime; private double defenseRecoverTimeSteepness; private double defenseRecoverStartingTime; public void addDamageBonus(int amt) { if ( amt > 0 ) attack_damage_formula = attack_damage_formula + "+" + amt; else if ( amt < 0 ) attack_damage_formula = attack_damage_formula + "-" + amt; } public Weapon ( World mundo , String itemfile ) throws IOException, FileNotFoundException { constructItem ( mundo , itemfile , true , "weapon" ); } public Weapon ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException { constructItem ( mundo , n , true , "weapon" ); } //le pasamos el nodo general de la Entity public void readWeaponSpecifics ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException { if ( ! ( n instanceof org.w3c.dom.Element ) ) throw ( new XMLtoWorldException("Weapon node not Element") ); org.w3c.dom.Element e = (org.w3c.dom.Element) n; //{e is an Element representing this Weapon} //WieldableLimbs: a dollar-separated names list. //XML parsing copy-pasted from parsing of SingularReferenceNames at Item. /* org.w3c.dom.NodeList singRefNamesNodes = e.getElementsByTagName("WieldableLimbs" ); if ( singRefNamesNodes.getLength() > 0 ) { org.w3c.dom.Element singRefNamesNode = (org.w3c.dom.Element)singRefNamesNodes.item(0); org.w3c.dom.NodeList nameNodes = singRefNamesNode.getElementsByTagName("Name"); //init wieldableLimbs wieldableLimbs = ""; for ( int i = 0 ; i < nameNodes.getLength() ; i++ ) { //get this name node org.w3c.dom.Element nameNode = (org.w3c.dom.Element) nameNodes.item(i); //get first text node in this name node -- WE ASSUME THERE IS ONE!! org.w3c.dom.Node hijo = nameNode.getFirstChild(); while ( !( hijo instanceof org.w3c.dom.Text ) ) hijo = hijo.getNextSibling(); //{hijo is an org.w3c.dom.Text} wieldableLimbs += ( hijo.getNodeValue() ); if ( i < nameNodes.getLength()-1 ) //i.e. not last wieldableLimbs += "$"; } } */ //wieldableLimbs is a List of dollar-separated string lists. org.w3c.dom.NodeList singRefNamesNodes = e.getElementsByTagName("WieldableLimbs" ); if ( singRefNamesNodes.getLength() > 0 ) { org.w3c.dom.Element singRefNamesNode = (org.w3c.dom.Element)singRefNamesNodes.item(0); org.w3c.dom.NodeList reqNodes = singRefNamesNode.getElementsByTagName("Requirement"); for ( int k = 0 ; k < reqNodes.getLength() ; k++ ) { //get this req node org.w3c.dom.Element reqNode = (org.w3c.dom.Element)reqNodes.item(k); org.w3c.dom.NodeList nameNodes = reqNode.getElementsByTagName("Name"); //init curLimbNames String curLimbNames = ""; for ( int i = 0 ; i < nameNodes.getLength() ; i++ ) { //get this name node org.w3c.dom.Element nameNode = (org.w3c.dom.Element) nameNodes.item(i); //get first text node in this name node -- WE ASSUME THERE IS ONE!! org.w3c.dom.Node hijo = nameNode.getFirstChild(); while ( !( hijo instanceof org.w3c.dom.Text ) ) hijo = hijo.getNextSibling(); //{hijo is an org.w3c.dom.Text} curLimbNames += ( hijo.getNodeValue() ); if ( i < nameNodes.getLength()-1 ) //i.e. not last curLimbNames += "$"; } wieldableLimbs.add ( curLimbNames ); } } //attack-related info org.w3c.dom.NodeList attackNodes = e.getElementsByTagName("Attack"); if ( attackNodes.getLength() > 0 ) { org.w3c.dom.Element attackNode = (org.w3c.dom.Element)attackNodes.item(0); //OK, we have attack node, now parse different sub-nodes. //attack minimal usage if ( attackNode.hasAttribute("minUsage") ) { try { attackMinimalUsage = Long.valueOf ( attackNode.getAttribute("minUsage") ).longValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at attackMinimalUsage") ); } } else attackMinimalUsage = 0; //default value //attack involved skills org.w3c.dom.NodeList nl1 = attackNode.getElementsByTagName("InvolvedSkills"); if ( nl1.getLength() > 0 ) { org.w3c.dom.Element invsk = (org.w3c.dom.Element) nl1.item(0); org.w3c.dom.NodeList skillnodes = invsk.getElementsByTagName("Skill"); attackInvolvedSkills = new String[skillnodes.getLength()]; attackInvolvedSkillRelevance = new double [skillnodes.getLength()]; for ( int i = 0 ; i < skillnodes.getLength() ; i++ ) { org.w3c.dom.Element skillNode = (org.w3c.dom.Element) skillnodes.item(i); if ( !skillNode.hasAttribute("name") ) throw ( new XMLtoWorldException("Skill node lacking attribute name") ); if ( !skillNode.hasAttribute("relevance") ) //throw ( new XMLtoWorldException("Skill node lacking attribute relevance") ); attackInvolvedSkillRelevance[i] = 1.0; try { if ( skillNode.hasAttribute("relevance") ) attackInvolvedSkillRelevance[i] = Double.valueOf ( skillNode.getAttribute("relevance") ).doubleValue(); attackInvolvedSkills[i] = skillNode.getAttribute("name"); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Wrong number format for relevance attribute at weapon's attack skill node") ); } } } //attack probability org.w3c.dom.NodeList nl = attackNode.getElementsByTagName("Probability"); if ( nl.getLength() > 0 ) { org.w3c.dom.Element atProb = (org.w3c.dom.Element) nl.item(0); if ( atProb.hasAttribute("steepness") ) { try { attackProbabilitySteepness = Double.valueOf ( atProb.getAttribute("steepness") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at attackProbabilitySteepness") ); } } else attackProbabilitySteepness = 0; //default value } //attack time nl = attackNode.getElementsByTagName("Time"); if ( nl.getLength() > 0 ) { org.w3c.dom.Element atProb = (org.w3c.dom.Element) nl.item(0); if ( atProb.hasAttribute("steepness") ) { try { attackTimeSteepness = Double.valueOf ( atProb.getAttribute("steepness") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at attackTimeSteepness") ); } } else attackTimeSteepness = 0; //default value if ( atProb.hasAttribute("starting") ) { try { attackStartingTime = Double.valueOf ( atProb.getAttribute("starting") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at attackStartingTime") ); } } else attackStartingTime = 30; //default value } //attack recover time nl = attackNode.getElementsByTagName("RecoverTime"); if ( nl.getLength() > 0 ) { org.w3c.dom.Element atProb = (org.w3c.dom.Element) nl.item(0); if ( atProb.hasAttribute("steepness") ) { try { attackRecoverTimeSteepness = Double.valueOf ( atProb.getAttribute("steepness") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at attackRecoverTimeSteepness") ); } } else attackRecoverTimeSteepness = 0; //default value if ( atProb.hasAttribute("starting") ) { try { attackRecoverStartingTime = Double.valueOf ( atProb.getAttribute("starting") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at attackRecoverStartingTime") ); } } else attackRecoverStartingTime = 0; //default value } //attack damage (formulae) nl = attackNode.getElementsByTagName("DamageList"); if ( nl.getLength() > 0 ) { org.w3c.dom.Element atDam = (org.w3c.dom.Element) nl.item(0); org.w3c.dom.NodeList damageElements = atDam.getElementsByTagName("Damage"); for ( int i = 0 ; i < damageElements.getLength() ; i++ ) { org.w3c.dom.Element curDamageElement = (org.w3c.dom.Element) damageElements.item(i); if ( !curDamageElement.hasAttribute("type") ) throw ( new XMLtoWorldException("Damage element lacking type attribute") ); if ( !curDamageElement.hasAttribute("formula") ) throw ( new XMLtoWorldException("Damage element lacking formula attribute") ); if ( attack_damage_formula == null ) attack_damage_formula = ""; //append this damtype if ( i > 0 ) attack_damage_formula += "$"; attack_damage_formula += curDamageElement.getAttribute("type"); attack_damage_formula += ":"; attack_damage_formula += curDamageElement.getAttribute("formula"); } } } //defense-related info //copy-pasted from attack-related info replacing attack by defense org.w3c.dom.NodeList defenseNodes = e.getElementsByTagName("Defense"); if ( defenseNodes.getLength() > 0 ) { org.w3c.dom.Element defenseNode = (org.w3c.dom.Element)defenseNodes.item(0); //OK, we have defense node, now parse different sub-nodes. //defense minimal usage if ( defenseNode.hasAttribute("minUsage") ) { try { defenseMinimalUsage = Long.valueOf ( defenseNode.getAttribute("minUsage") ).longValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at defenseMinimalUsage") ); } } else defenseMinimalUsage = 0; //default value //defense involved skills org.w3c.dom.NodeList nl1 = defenseNode.getElementsByTagName("InvolvedSkills"); if ( nl1.getLength() > 0 ) { org.w3c.dom.Element invsk = (org.w3c.dom.Element) nl1.item(0); org.w3c.dom.NodeList skillnodes = invsk.getElementsByTagName("Skill"); defenseInvolvedSkills = new String[skillnodes.getLength()]; defenseInvolvedSkillRelevance = new double [skillnodes.getLength()]; for ( int i = 0 ; i < skillnodes.getLength() ; i++ ) { org.w3c.dom.Element skillNode = (org.w3c.dom.Element) skillnodes.item(i); if ( !skillNode.hasAttribute("name") ) throw ( new XMLtoWorldException("Skill node lacking attribute name") ); if ( !skillNode.hasAttribute("relevance") ) //throw ( new XMLtoWorldException("Skill node lacking attribute relevance") ); defenseInvolvedSkillRelevance[i] = 1.0; try { if ( skillNode.hasAttribute("relevance") ) defenseInvolvedSkillRelevance[i] = Double.valueOf ( skillNode.getAttribute("relevance") ).doubleValue(); defenseInvolvedSkills[i] = skillNode.getAttribute("name"); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Wrong number format for relevance attribute at weapon's defense skill node") ); } } } //defense probability org.w3c.dom.NodeList nl = defenseNode.getElementsByTagName("Probability"); if ( nl.getLength() > 0 ) { org.w3c.dom.Element atProb = (org.w3c.dom.Element) nl.item(0); if ( atProb.hasAttribute("steepness") ) { try { defenseProbabilitySteepness = Double.valueOf ( atProb.getAttribute("steepness") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at defenseProbabilitySteepness") ); } } else defenseProbabilitySteepness = 0; //default value } //defense time nl = defenseNode.getElementsByTagName("Time"); if ( nl.getLength() > 0 ) { org.w3c.dom.Element atProb = (org.w3c.dom.Element) nl.item(0); if ( atProb.hasAttribute("steepness") ) { try { defenseTimeSteepness = Double.valueOf ( atProb.getAttribute("steepness") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at defenseTimeSteepness") ); } } else defenseTimeSteepness = 0; //default value if ( atProb.hasAttribute("starting") ) { try { defenseStartingTime = Double.valueOf ( atProb.getAttribute("starting") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at defenseStartingTime") ); } } else defenseStartingTime = 0; //default value } //defense recover time nl = defenseNode.getElementsByTagName("RecoverTime"); if ( nl.getLength() > 0 ) { org.w3c.dom.Element atProb = (org.w3c.dom.Element) nl.item(0); if ( atProb.hasAttribute("steepness") ) { try { defenseRecoverTimeSteepness = Double.valueOf ( atProb.getAttribute("steepness") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at defenseRecoverTimeSteepness") ); } } else defenseRecoverTimeSteepness = 0; //default value if ( atProb.hasAttribute("starting") ) { try { defenseRecoverStartingTime = Double.valueOf ( atProb.getAttribute("starting") ).doubleValue(); } catch ( NumberFormatException nfe ) { throw ( new XMLtoWorldException("Number format error at defenseRecoverStartingTime") ); } } else defenseRecoverStartingTime = 0; //default value } //defense damage (formulae) nl = defenseNode.getElementsByTagName("DamageList"); if ( nl.getLength() > 0 ) { org.w3c.dom.Element atDam = (org.w3c.dom.Element) nl.item(0); org.w3c.dom.NodeList damageElements = atDam.getElementsByTagName("Damage"); for ( int i = 0 ; i < damageElements.getLength() ; i++ ) { org.w3c.dom.Element curDamageElement = (org.w3c.dom.Element) damageElements.item(i); if ( !curDamageElement.hasAttribute("type") ) throw ( new XMLtoWorldException("Damage element lacking type attribute") ); if ( !curDamageElement.hasAttribute("formula") ) throw ( new XMLtoWorldException("Damage element lacking formula attribute") ); if ( defense_damage_formula == null ) defense_damage_formula = ""; //append this damtype if ( i > 0 ) defense_damage_formula += "$"; defense_damage_formula += curDamageElement.getAttribute("type"); defense_damage_formula += ":"; defense_damage_formula += curDamageElement.getAttribute("formula"); } } } //parsing and initting done. } public org.w3c.dom.Node getXMLRepresentation ( org.w3c.dom.Document doc ) { org.w3c.dom.Node nodoItem = super.getXMLRepresentation(doc); nodoItem.appendChild ( getWeaponSpecificsXMLRepresentation ( doc ) ); return nodoItem; } public org.w3c.dom.Node getWeaponSpecificsXMLRepresentation ( org.w3c.dom.Document doc ) { org.w3c.dom.Element suElemento = doc.createElement("WeaponSpecs"); /* //wieldable limbs if ( wieldableLimbs != null ) { org.w3c.dom.Element elt = doc.createElement("WieldableLimbs"); StringTokenizer st = new StringTokenizer ( wieldableLimbs , "$" ); while ( st.hasMoreTokens() ) { String tok = st.nextToken(); org.w3c.dom.Element esteNombre = doc.createElement("Name"); org.w3c.dom.Text elNombre = doc.createTextNode(tok); esteNombre.appendChild(elNombre); elt.appendChild(esteNombre); } suElemento.appendChild( elt ); } */ //wieldable limbs if ( wieldableLimbs != null ) { org.w3c.dom.Element elt = doc.createElement("WieldableLimbs"); for ( int i = 0 ; i < wieldableLimbs.size() ; i++ ) { String curString = (String) wieldableLimbs.get(i); org.w3c.dom.Element reqNode = doc.createElement("Requirement"); StringTokenizer st = new StringTokenizer ( curString , "$" ); while ( st.hasMoreTokens() ) { String tok = st.nextToken(); org.w3c.dom.Element esteNombre = doc.createElement("Name"); org.w3c.dom.Text elNombre = doc.createTextNode(tok); esteNombre.appendChild(elNombre); reqNode.appendChild(esteNombre); } elt.appendChild( reqNode ); } suElemento.appendChild(elt); } //attack org.w3c.dom.Element attackElement = doc.createElement("Attack"); { attackElement.setAttribute("minUsage" , String.valueOf(attackMinimalUsage)); org.w3c.dom.Element attackSkillsElement = doc.createElement("InvolvedSkills"); { if ( attackInvolvedSkills != null ) { for ( int i = 0 ; i < attackInvolvedSkills.length ; i++ ) { org.w3c.dom.Element thisSkillElement = doc.createElement("Skill"); thisSkillElement.setAttribute("name",attackInvolvedSkills[i]); thisSkillElement.setAttribute("relevance",String.valueOf(attackInvolvedSkillRelevance[i])); attackSkillsElement.appendChild(thisSkillElement); } } attackElement.appendChild(attackSkillsElement); } org.w3c.dom.Element attackProbabilityElement = doc.createElement("Probability"); { attackProbabilityElement.setAttribute("steepness",String.valueOf(attackProbabilitySteepness)); attackElement.appendChild(attackProbabilityElement); } org.w3c.dom.Element attackTimeElement = doc.createElement("Time"); { attackTimeElement.setAttribute("steepness",String.valueOf(attackTimeSteepness)); attackTimeElement.setAttribute("starting",String.valueOf(attackStartingTime)); attackElement.appendChild(attackTimeElement); } org.w3c.dom.Element attackRecoverTimeElement = doc.createElement("RecoverTime"); { attackRecoverTimeElement.setAttribute("steepness",String.valueOf(attackRecoverTimeSteepness)); attackRecoverTimeElement.setAttribute("starting",String.valueOf(attackRecoverStartingTime)); attackElement.appendChild(attackRecoverTimeElement); } org.w3c.dom.Element attackDamageElement = doc.createElement("DamageList"); { if ( attack_damage_formula != null ) { StringTokenizer st = new StringTokenizer(attack_damage_formula,"$"); while ( st.hasMoreTokens() ) { String curToken = st.nextToken(); StringTokenizer st2 = new StringTokenizer ( curToken , ":" ); //separa el tipo de da�o del da�o String damTypeString = st2.nextToken().trim(); String damFormulaString = st2.nextToken().trim(); org.w3c.dom.Element curDamageElement = doc.createElement("Damage"); curDamageElement.setAttribute("type",damTypeString); curDamageElement.setAttribute("formula",damFormulaString); attackDamageElement.appendChild(curDamageElement); } } attackElement.appendChild(attackDamageElement); } suElemento.appendChild(attackElement); } //defense org.w3c.dom.Element defenseElement = doc.createElement("Defense"); { defenseElement.setAttribute("minUsage" , String.valueOf(defenseMinimalUsage)); org.w3c.dom.Element defenseSkillsElement = doc.createElement("InvolvedSkills"); { if ( defenseInvolvedSkills != null ) { for ( int i = 0 ; i < defenseInvolvedSkills.length ; i++ ) { org.w3c.dom.Element thisSkillElement = doc.createElement("Skill"); thisSkillElement.setAttribute("name",defenseInvolvedSkills[i]); thisSkillElement.setAttribute("relevance",String.valueOf(defenseInvolvedSkillRelevance[i])); defenseSkillsElement.appendChild(thisSkillElement); } } defenseElement.appendChild(defenseSkillsElement); } org.w3c.dom.Element defenseProbabilityElement = doc.createElement("Probability"); { defenseProbabilityElement.setAttribute("steepness",String.valueOf(defenseProbabilitySteepness)); defenseElement.appendChild(defenseProbabilityElement); } org.w3c.dom.Element defenseTimeElement = doc.createElement("Time"); { defenseTimeElement.setAttribute("steepness",String.valueOf(defenseTimeSteepness)); defenseTimeElement.setAttribute("starting",String.valueOf(defenseStartingTime)); defenseElement.appendChild(defenseTimeElement); } org.w3c.dom.Element defenseRecoverTimeElement = doc.createElement("RecoverTime"); { defenseRecoverTimeElement.setAttribute("steepness",String.valueOf(defenseRecoverTimeSteepness)); defenseRecoverTimeElement.setAttribute("starting",String.valueOf(defenseRecoverStartingTime)); defenseElement.appendChild(defenseRecoverTimeElement); } org.w3c.dom.Element defenseDamageElement = doc.createElement("DamageList"); { if ( defense_damage_formula != null ) { StringTokenizer st = new StringTokenizer(defense_damage_formula,"$"); while ( st.hasMoreTokens() ) { String curToken = st.nextToken(); StringTokenizer st2 = new StringTokenizer ( curToken , ":" ); //separa el tipo de da�o del da�o String damTypeString = st2.nextToken().trim(); String damFormulaString = st2.nextToken().trim(); org.w3c.dom.Element curDamageElement = doc.createElement("Damage"); curDamageElement.setAttribute("type",damTypeString); curDamageElement.setAttribute("formula",damFormulaString); defenseDamageElement.appendChild(curDamageElement); } } defenseElement.appendChild(defenseDamageElement); } suElemento.appendChild(defenseElement); } return suElemento; } public void readWeaponSpecifics ( World mundo , String itemfile ) throws IOException, FileNotFoundException { String linea; String id_linea; FileInputStream fp = new FileInputStream ( itemfile ); BufferedReader filein = new BufferedReader ( Utility.getBestInputStreamReader ( fp ) ); for ( int line = 1 ; line < 100 ; line++ ) { linea = filein.readLine(); id_linea = StringMethods.getTok( linea , 1 , ' ' ); linea = StringMethods.getToks( linea , 2 , StringMethods.numToks( linea , ' ' ) , ' ' ); if ( id_linea != null ) switch ( Integer.valueOf(id_linea).intValue() ) { case 50: break; case 51: minskill_twohand = Double.valueOf(linea).doubleValue(); break; case 52: minskill_onehand = Double.valueOf(linea).doubleValue(); break; case 53: maxskill = Double.valueOf(linea).doubleValue(); break; case 54: attack_damage_formula = linea; break; case 55: //obsolete damage_type = linea; break; case 60: break; case 61: //wieldable limbs list line wieldableLimbs = new Vector(); wieldableLimbs.add( linea ); break; } } } //el valor de retorno es el da�o hecho public int dealDamage ( Mobile atacante , Mobile defensor , boolean simulated ) { List listaDanos = getDamagesListFromFormula ( attack_damage_formula , atacante ); int danoTotal = 0; for ( int i = 0 ; i < listaDanos.size() ; i++ ) { danoTotal += defensor.tryToDealDamage ( i , ((Integer)listaDanos.get(i)).intValue() , simulated ); } return danoTotal; } public int dealDamageDefended ( Mobile atacante , Mobile defensor , boolean simulated ) { List listaDanosAtaque = getDamagesListFromFormula ( attack_damage_formula , atacante ); List listaDanosDefensa = getDamagesListFromFormula ( defensor.getCurrentWeapon().defense_damage_formula , defensor ); int danoTotal = 0; for ( int i = 0 ; i < listaDanosAtaque.size() ; i++ ) { int danoAHacer; if ( i < listaDanosDefensa.size() ) danoAHacer = ((Integer)listaDanosAtaque.get(i)).intValue() - ((Integer)listaDanosDefensa.get(i)).intValue(); else danoAHacer = ((Integer)listaDanosAtaque.get(i)).intValue(); if ( danoAHacer < 0 ) danoAHacer = 0; danoTotal += defensor.tryToDealDamage ( i , danoAHacer , simulated ); } return danoTotal; } public int dealDamage ( Mobile atacante , Mobile defensor , boolean simulated , /*nullable*/ Item limb ) { Debug.println("Dealing damage with " + this + attack_damage_formula); List listaDanos = getDamagesListFromFormula ( attack_damage_formula , atacante ); Debug.println(""+listaDanos); return defensor.tryToDealDamage ( listaDanos , simulated , limb ); } public int dealDamageDefended ( Mobile atacante , Mobile defensor , boolean simulated , /*nullable*/ Item limb ) { List listaDanosAtaque = getDamagesListFromFormula ( attack_damage_formula , atacante ); List listaDanosDefensa = getDamagesListFromFormula ( defensor.getCurrentWeapon().defense_damage_formula , defensor ); List listaDanosTotal = new ArrayList(); for ( int i = 0 ; i < listaDanosAtaque.size() ; i++ ) { int danoAHacer; if ( i < listaDanosDefensa.size() ) danoAHacer = ((Integer)listaDanosAtaque.get(i)).intValue() - ((Integer)listaDanosDefensa.get(i)).intValue(); else danoAHacer = ((Integer)listaDanosAtaque.get(i)).intValue(); if ( danoAHacer < 0 ) danoAHacer = 0; listaDanosTotal.add(new Integer(danoAHacer)); } return defensor.tryToDealDamage ( listaDanosTotal , simulated , limb ); } //lista de da�os seg�n tipo (f�sico, fuego...) public List getDamagesListFromFormula ( String damage_formula , Mobile atacanteODefensor ) { List listaDanos = new ArrayList(); String ourFormula = getDamageFromFormula ( damage_formula , atacanteODefensor ); StringTokenizer st = new StringTokenizer ( ourFormula , "$" ); while ( st.hasMoreTokens ( ) ) { String curToken = st.nextToken(); StringTokenizer st2 = new StringTokenizer ( curToken , ":" ); //separa el tipo de da�o del da�o int damtype = Integer.valueOf( st2.nextToken().trim() ).intValue(); int damamount = Integer.valueOf( st2.nextToken().trim() ).intValue(); while ( listaDanos.size() <= damtype ) listaDanos.add(null); listaDanos.set(damtype, new Integer(damamount)); } //cambiar nulos por ceros for ( int i = 0 ; i < listaDanos.size() ; i++ ) { if ( listaDanos.get(i) == null ) listaDanos.set( i , new Integer(0) ); } return listaDanos; } public String getDamageFromFormula ( String damage_formula , Mobile atacanteODefensor ) { //Debug.println("Formula is : " + damage_formula); //coge: damage_formula de esta instancia //formula del tipo: // 0: 3D6 - 2 + 3FUE + 0N4 $ 1: 2D6 //devuelve: da�o //formula del tipo: // 0: 24 $ 1: 5 //dependera del bicho atacanteODefensor (parametros como FUE, etc.) String result = ""; if ( damage_formula == null ) return ""; StringTokenizer st = new StringTokenizer ( damage_formula , "$" ); while ( st.hasMoreTokens ( ) ) { String curToken = st.nextToken(); StringTokenizer st2 = new StringTokenizer ( curToken , ":" ); //separa el tipo de da�o del da�o result += st2.nextToken().trim(); //tipo de da�o result += ":"; String laformula = st2.nextToken().trim(); //formula que indica el da�o de ese tipo //calcular el numero que resulta de la formula y concatenarlo StringTokenizer stFormula = new StringTokenizer ( laformula , "+-" , true ); //true para que devuelva tambien los delimitadores boolean sumaOResta = true; //suma int elResultado = 0; //empieza en la suma vacia, formula es suma de cosas. while ( stFormula.hasMoreTokens ( ) ) { String curFormulaToken = stFormula.nextToken().trim(); if ( curFormulaToken.equals("+") ) sumaOResta = true; else if ( curFormulaToken.equals("-") ) sumaOResta = false; else //sumar o restar el resultado de este token al numero { int sumando = processAtomicFormula ( curFormulaToken , atacanteODefensor ); if ( sumaOResta ) elResultado += sumando; else elResultado -= sumando; } } result += String.valueOf(elResultado); result += "$"; } //quitar el d�lar que se a�adi� de m�s, si string no "". if ( result.length() > 0 ) result = result.substring ( 0 , result.length() - 1 ); Debug.println(getUniqueName() + " drawing damage from " + damage_formula + " resulted " + result); return result; } private int processAtomicFormula ( String formula , Mobile atacanteODefensor ) { //auxiliar para getDamageFromFormula //procesa una formula de da�o elemental, ej. 4D6FUE o 4 if ( formula.endsWith("FUE") || formula.endsWith("STR") || formula.endsWith("CON") || formula.endsWith("INT") || formula.endsWith("SAB") || formula.endsWith("WIS") || formula.endsWith("DES") || formula.endsWith("DEX") || formula.endsWith("CHA") || formula.endsWith("CAR") || formula.endsWith("POD") || formula.endsWith("POW") ) { return processAtomicFormula(formula.substring(0,formula.length()-3), atacanteODefensor ) * atacanteODefensor.getStat(formula.substring(formula.length()-3,formula.length())) ; } else if ( formula.equals( "" ) ) { return 0; } else if ( StringMethods.numToks ( formula , 'D' ) > 1 ) { Random rand = getRandom(); int numDados = Integer.valueOf ( StringMethods.getTok ( formula, 1, 'D' ) ) . intValue() ; int cantDado = Integer.valueOf ( StringMethods.getTok ( formula, 2, 'D' ) ) . intValue() ; int tirada = 0; Debug.print("-ndados" + numDados + "-"); for ( int i = 0 ; i < numDados ; i++ ) { //Debug.println("I am " + this + "[IID:"+getID()+"][INAME"+title+"], and my Random is actually " + getRandom()); int temp = rand.nextInt(); tirada += ( Math.abs( temp%cantDado ) + 1 ); Debug.print("<tir" + tirada + ">"); } return tirada; } else { return Integer.valueOf ( formula ) . intValue() ; } } //typical seg�n skill (variar� further seg�n su destreza y el factor aleatorio) public double getTypicalAttackTime ( long usage ) { return getTypicalTime ( usage , attackStartingTime , attackMinimalUsage , attackTimeSteepness ); } public double getTypicalAttackRecoverTime ( long usage ) { return getTypicalTime ( usage , attackRecoverStartingTime , attackMinimalUsage , attackRecoverTimeSteepness ); } public double getTypicalAttackProbability ( long usage ) { return 1 - getTypicalTime ( usage , 1.0 , attackMinimalUsage , attackProbabilitySteepness ); } public double getTypicalDefenseTime ( long usage ) { return getTypicalTime ( usage , defenseStartingTime , defenseMinimalUsage , defenseTimeSteepness ); } public double getTypicalDefenseRecoverTime ( long usage ) { return getTypicalTime ( usage , defenseRecoverStartingTime , defenseMinimalUsage , defenseRecoverTimeSteepness ); } public double getTypicalDefenseProbability ( long usage ) { return 1 - getTypicalTime ( usage , 1.0 , defenseMinimalUsage , defenseProbabilitySteepness ); } public double getTypicalAttackTime ( Mobile m ) { return getTypicalTime ( getAttackUsage(m) , attackStartingTime , attackMinimalUsage , attackTimeSteepness ); } public double getTypicalAttackRecoverTime ( Mobile m ) { return getTypicalTime ( getAttackUsage(m) , attackRecoverStartingTime , attackMinimalUsage , attackRecoverTimeSteepness ); } public double getTypicalAttackProbability ( Mobile m ) { return 1 - getTypicalTime ( getAttackUsage(m) , 1.0 , attackMinimalUsage , attackProbabilitySteepness ); } public double getTypicalDefenseTime ( Mobile m ) { return getTypicalTime ( getDefenseUsage(m) , defenseStartingTime , defenseMinimalUsage , defenseTimeSteepness ); } public double getTypicalDefenseRecoverTime ( Mobile m ) { return getTypicalTime ( getDefenseUsage(m) , defenseRecoverStartingTime , defenseMinimalUsage , defenseRecoverTimeSteepness ); } public double getTypicalDefenseProbability ( Mobile m ) { return 1 - getTypicalTime ( getDefenseUsage(m) , 1.0 , defenseMinimalUsage , defenseProbabilitySteepness ); } //typical seg�n skill (variar� further seg�n su destreza y el factor aleatorio) private double getTypicalTime ( long usage , double starting , long minusage , double steepness ) { if ( usage < minusage ) return 0; else return ( (double)starting / ( Math.pow ( ( (double)usage - (double)minusage ) / (double)USAGE_CORRECTOR + 1 , ( Math.exp(steepness) ) ) ) ); } //uses involved skills and relevance to draw this weapon's specific usage skill. public long getAttackUsage ( Mobile m ) { double theUsage = 0; for ( int i = 0 ; i < attackInvolvedSkills.length ; i++ ) { theUsage += attackInvolvedSkillRelevance[i] * m.getSkill(attackInvolvedSkills[i]); } return (long)theUsage; } //uses involved skills and relevance to draw this weapon's specific usage skill. public long getDefenseUsage ( Mobile m ) { double theUsage = 0; for ( int i = 0 ; i < defenseInvolvedSkills.length ; i++ ) { theUsage += defenseInvolvedSkillRelevance[i] * m.getSkill(defenseInvolvedSkills[i]); } return (long)theUsage; } public void incrementAttackUsage ( Mobile m ) { for ( int i = 0 ; i < attackInvolvedSkills.length ; i++ ) { if ( m.getRandom().nextDouble() < attackInvolvedSkillRelevance[i] ) m.incSkill ( attackInvolvedSkills[i] ); } } public void incrementDefenseUsage ( Mobile m ) { for ( int i = 0 ; i < defenseInvolvedSkills.length ; i++ ) { if ( m.getRandom().nextDouble() < defenseInvolvedSkillRelevance[i] ) m.incSkill ( defenseInvolvedSkills[i] ); } } //de momento, a la espera de generalizar a armas de dos manos y que haya aut�ntica lista de requerimientos //Generalizado. public List getLimbRequirementsList() { /* Vector temp = new Vector(); temp.add ( wieldableLimbs ); return temp; */ return wieldableLimbs; } //notaci�n un poco inconsistente con la de Entity::copyEntityFields; pero bueno public void copyWeaponFieldsTo ( Weapon w ) { copyItemFieldsTo(w); //Entity+Weapon //scalars w.attack_damage_formula = attack_damage_formula; w.attackMinimalUsage = attackMinimalUsage; w.attackProbabilitySteepness = attackProbabilitySteepness; w.attackRecoverStartingTime = attackRecoverStartingTime; w.attackRecoverTimeSteepness = attackRecoverTimeSteepness; w.attackStartingTime = attackStartingTime; w.attackTimeSteepness = attackTimeSteepness; w.defense_damage_formula = defense_damage_formula; w.defenseMinimalUsage = defenseMinimalUsage; w.defenseProbabilitySteepness = defenseProbabilitySteepness; w.defenseRecoverStartingTime = defenseRecoverStartingTime; w.defenseStartingTime = defenseStartingTime; w.defenseTimeSteepness = defenseTimeSteepness; w.maxskill = maxskill; w.minskill_onehand = minskill_onehand; w.minskill_twohand = minskill_twohand; w.weapon_type = weapon_type; if ( attack_names_list != null ) { w.attack_names_list = new String[ attack_names_list.length ]; for ( int i = 0 ; i < w.attack_names_list.length ; i++ ) { w.attack_names_list[i] = attack_names_list[i]; } } if ( attackInvolvedSkillRelevance != null ) { w.attackInvolvedSkillRelevance = new double[ attackInvolvedSkillRelevance.length ]; for ( int i = 0 ; i < w.attackInvolvedSkillRelevance.length ; i++ ) { w.attackInvolvedSkillRelevance[i] = attackInvolvedSkillRelevance[i]; } } if ( attackInvolvedSkills != null ) { w.attackInvolvedSkills = new String[ attackInvolvedSkills.length ]; for ( int i = 0 ; i < w.attackInvolvedSkills.length ; i++ ) { w.attackInvolvedSkills[i] = attackInvolvedSkills[i]; } } if ( defenseInvolvedSkillRelevance != null ) { w.defenseInvolvedSkillRelevance = new double[ defenseInvolvedSkillRelevance.length ]; for ( int i = 0 ; i < w.defenseInvolvedSkillRelevance.length ; i++ ) { w.defenseInvolvedSkillRelevance[i] = defenseInvolvedSkillRelevance[i]; } } if ( defenseInvolvedSkills != null ) { w.defenseInvolvedSkills = new String[ defenseInvolvedSkills.length ]; for ( int i = 0 ; i < w.defenseInvolvedSkills.length ; i++ ) { w.defenseInvolvedSkills[i] = defenseInvolvedSkills[i]; } } if ( wieldableLimbs != null ) { w.wieldableLimbs = new ArrayList(); for ( int i = 0 ; i < wieldableLimbs.size() ; i++ ) { w.wieldableLimbs.add ( wieldableLimbs.get(i) ); } } } public Object clone( ) { //do it! Weapon w = new Weapon(); copyWeaponFieldsTo(w); return w; } //for clones public Weapon() { ; } }