/* Noeppel, Noeppel...NOOOOOOOH */ package net.sf.l2j.gameserver.datatables; import java.io.File; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javolution.util.FastList; import javolution.util.FastMap; import net.sf.l2j.L2DatabaseFactory; import net.sf.l2j.gameserver.model.L2EnchantSkillLearn; import net.sf.l2j.gameserver.model.L2PledgeSkillLearn; import net.sf.l2j.gameserver.model.L2Skill; import net.sf.l2j.gameserver.model.L2SkillLearn; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; import net.sf.l2j.gameserver.model.base.ClassId; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; /** * This class ... * * @version $Revision: 1.13.2.2.2.8 $ $Date: 2005/04/06 16:13:25 $ */ public class SkillTreeTable { private static Logger _log = Logger.getLogger(SkillTreeTable.class.getName()); private static SkillTreeTable _instance; private Map> _skillTrees; private List _fishingSkillTrees; //all common skills (teached by Fisherman) private List _expandDwarfCraftSkillTrees; //list of special skill for dwarf (expand dwarf craft) learned by class teacher private List _pledgeSkillTrees; //pledge skill list private List _enchantSkillTrees; //enchant skill list private Map> _skillsById; private Map _nohSkillLevel; private Map> _nohSkills; private Map _indexToId; private Map _idToIndex; private int _iD=140; private int getId(){ _iD++; return _iD; } public int parseNohSkill(Node n){ if ("skill".equalsIgnoreCase(n.getNodeName())){ NamedNodeMap attrs = n.getAttributes(); int id = Integer.parseInt(attrs.getNamedItem("id").getNodeValue()); int lvl= Integer.parseInt(attrs.getNamedItem("level").getNodeValue()); int mih=0; // if(attrs.getNamedItem("xId")!=null)mih=Integer.parseInt(attrs.getNamedItem("xId").getNodeValue()); int xId; if(mih!=0)xId=mih; else xId=getId(); _indexToId.put(xId,id); _idToIndex.put(id,xId); _nohSkillLevel.put(xId,lvl); //if(id==1177)_log.warning("1177:"+xId); //if(id==142)_log.warning("142:"+xId); _log.warning("skill id: "+id+" lvl: "+lvl+" xId: "+xId); List noh=new FastList(); //_log.warning("Skill id="+xId+" id="+id); for (Node d=n.getFirstChild(); d != null; d = d.getNextSibling()){ int i=parseNohSkill(d); _log.warning("child id="+i); if(i!=0)noh.add(i); } _nohSkills.put(xId,noh); return xId; } return 0; } public static SkillTreeTable getInstance() { if (_instance == null) _instance = new SkillTreeTable(); return _instance; } /** * Return the minimum level needed to have this Expertise.

* * @param grade The grade level searched */ public int indexToId(int x){ return _indexToId.get(x); } public int idToIndex(int x){ return _idToIndex.get(x); } public int getExpertiseLevel(int grade) { if (grade <= 0) return 0; // since expertise comes at same level for all classes we use paladin for now Map learnMap = getSkillTrees().get(ClassId.paladin); int skillHashCode = SkillTable.getSkillHashCode(239,grade); if (learnMap.containsKey(skillHashCode)) { return learnMap.get(skillHashCode).getMinLevel(); } _log.severe("Expertise not found for grade "+grade); return 0; } /** * Each class receives new skill on certain levels, this methods allow the retrieval of the minimun character level * of given class required to learn a given skill * @param skillId The iD of the skill * @param classID The classId of the character * @param skillLvl The SkillLvl * @return The min level */ public int getMinSkillLevel(int skillId, ClassId classId, int skillLvl) { Map map = getSkillTrees().get(classId); int skillHashCode = SkillTable.getSkillHashCode(skillId,skillLvl); if (map.containsKey(skillHashCode)) { return map.get(skillHashCode).getMinLevel(); } return 0; } public int getMinSkillLevel(int skillId, int skillLvl) { int skillHashCode = SkillTable.getSkillHashCode(skillId, skillLvl); // Look on all classes for this skill (takes the first one found) for (Map map : getSkillTrees().values()) { // checks if the current class has this skill if (map.containsKey(skillHashCode)) { return map.get(skillHashCode).getMinLevel(); } } return 0; } private SkillTreeTable() { int classId = 0; int count = 0; _idToIndex=new FastMap(); _indexToId=new FastMap(); _nohSkills=new FastMap>(); _nohSkillLevel=new FastMap(); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); factory.setIgnoringComments(true); File file = new File("data/noh/Skills.xml"); _log.warning("start parse"); if (!file.exists()) { _log.warning("NO FILE"); } DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse( file ); Node rootNode = document.getDocumentElement(); Document doc = factory.newDocumentBuilder().parse(file); Node n=doc.getFirstChild(); parseNohSkill(n); } catch (Exception e) {System.out.println(e); } java.sql.Connection con = null; _skillsById=new FastMap>(); try { con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement statement = con.prepareStatement("SELECT * FROM class_list ORDER BY id"); ResultSet classlist = statement.executeQuery(); Map map; int parentClassId; L2SkillLearn skillLearn; while (classlist.next()) { map = new FastMap(); parentClassId = classlist.getInt("parent_id"); classId = classlist.getInt("id"); PreparedStatement statement2 = con.prepareStatement("SELECT class_id, skill_id, level, name, sp, min_level FROM skill_trees where class_id=? ORDER BY skill_id, level"); statement2.setInt(1, classId); ResultSet skilltree = statement2.executeQuery(); if (parentClassId != -1) { Map parentMap = getSkillTrees().get(ClassId.values()[parentClassId]); map.putAll(parentMap); } int prevSkillId = -1; while (skilltree.next()) { int id = skilltree.getInt("skill_id"); int lvl = skilltree.getInt("level"); String name = skilltree.getString("name"); int minLvl = skilltree.getInt("min_level"); int cost = skilltree.getInt("sp"); if (prevSkillId != id) prevSkillId = id; skillLearn = new L2SkillLearn(id, lvl, minLvl, name, cost, 0, 0); map.put(SkillTable.getSkillHashCode(id,lvl), skillLearn); if(_skillsById.get(id)==null){ _skillsById.put(id,new FastMap()); } Map temp=_skillsById.get(id); temp.put(SkillTable.getSkillHashCode(id,lvl), skillLearn); _skillsById.put(id,temp); } getSkillTrees().put(ClassId.values()[classId], map); skilltree.close(); statement2.close(); count += map.size(); _log.fine("SkillTreeTable: skill tree for class " + classId + " has " + map.size() + " skills"); } classlist.close(); statement.close(); } catch (Exception e) { _log.severe("Error while creating skill tree (Class ID " + classId + "):" + e); } _log.config("SkillTreeTable: Loaded " + count + " skills."); //Skill tree for fishing skill (from Fisherman) int count2 = 0; int count3 = 0; try { _fishingSkillTrees = new FastList(); _expandDwarfCraftSkillTrees = new FastList(); PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, name, sp, min_level, costid, cost, isfordwarf FROM fishing_skill_trees ORDER BY skill_id, level"); ResultSet skilltree2 = statement.executeQuery(); int prevSkillId = -1; while (skilltree2.next()) { int id = skilltree2.getInt("skill_id"); int lvl = skilltree2.getInt("level"); String name = skilltree2.getString("name"); int minLvl = skilltree2.getInt("min_level"); int cost = skilltree2.getInt("sp"); int costId = skilltree2.getInt("costid"); int costCount = skilltree2.getInt("cost"); int isDwarven = skilltree2.getInt("isfordwarf"); if (prevSkillId != id) prevSkillId = id; L2SkillLearn skill = new L2SkillLearn(id, lvl, minLvl, name, cost, costId, costCount); if (isDwarven == 0) _fishingSkillTrees.add(skill); else _expandDwarfCraftSkillTrees.add(skill); } skilltree2.close(); statement.close(); count2 = _fishingSkillTrees.size(); count3 = _expandDwarfCraftSkillTrees.size(); } catch (Exception e) { _log.severe("Error while creating fishing skill table: " + e); } int count4 = 0; try { _enchantSkillTrees = new FastList(); PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, name, base_lvl, sp, min_skill_lvl, exp, success_rate76, success_rate77, success_rate78 FROM enchant_skill_trees ORDER BY skill_id, level"); ResultSet skilltree3 = statement.executeQuery(); int prevSkillId = -1; while (skilltree3.next()) { int id = skilltree3.getInt("skill_id"); int lvl = skilltree3.getInt("level"); String name = skilltree3.getString("name"); int baseLvl = skilltree3.getInt("base_lvl"); int minSkillLvl = skilltree3.getInt("min_skill_lvl"); int sp = skilltree3.getInt("sp"); int exp = skilltree3.getInt("exp"); byte rate76 = skilltree3.getByte("success_rate76"); byte rate77 = skilltree3.getByte("success_rate77"); byte rate78 = skilltree3.getByte("success_rate78"); if (prevSkillId != id) prevSkillId = id; L2EnchantSkillLearn skill = new L2EnchantSkillLearn(id, lvl, minSkillLvl, baseLvl, name, sp, exp, rate76 , rate77, rate78); _enchantSkillTrees.add(skill); } skilltree3.close(); statement.close(); count4 = _enchantSkillTrees.size(); } catch (Exception e) { _log.severe("Error while creating enchant skill table: " + e); } int count5 = 0; try { _pledgeSkillTrees = new FastList(); PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, name, clan_lvl, repCost, itemId FROM pledge_skill_trees ORDER BY skill_id, level"); ResultSet skilltree4 = statement.executeQuery(); int prevSkillId = -1; while (skilltree4.next()) { int id = skilltree4.getInt("skill_id"); int lvl = skilltree4.getInt("level"); String name = skilltree4.getString("name"); int baseLvl = skilltree4.getInt("clan_lvl"); int sp = skilltree4.getInt("repCost"); int itemId = skilltree4.getInt("itemId"); if (prevSkillId != id) prevSkillId = id; L2PledgeSkillLearn skill = new L2PledgeSkillLearn(id, lvl, baseLvl, name, sp, itemId); _pledgeSkillTrees.add(skill); } skilltree4.close(); statement.close(); count5 = _pledgeSkillTrees.size(); } catch (Exception e) { _log.severe("Error while creating fishing skill table: " + e); } finally { try { con.close(); } catch (Exception e) {} } _log.config("FishingSkillTreeTable: Loaded " + count2 + " general skills."); _log.config("FishingSkillTreeTable: Loaded " + count3 + " dwarven skills."); _log.config("EnchantSkillTreeTable: Loaded " + count4 + " enchant skills."); _log.config("PledgeSkillTreeTable: Loaded " + count5 + " pledge skills"); } private Map> getSkillTrees() { if (_skillTrees == null) _skillTrees = new FastMap>(); return _skillTrees; } public L2SkillLearn[] getAvailableSkills(L2PcInstance cha, ClassId classId2) { List result = new FastList(); Map test= new FastMap(); Collection skills = new FastList(); for(int i : cha.getNohSkill().getSkills()){ Map temp=_skillsById.get(i); for(L2SkillLearn x : temp.values()){ skills.add(x); } } /*for(Map temp : _skillsById.values()){ skills.addAll(temp.values()); }*/ if(skills!=null){ L2Skill[] oldSkills = cha.getAllSkills(); for (L2SkillLearn temp : skills) { if (temp.getMinLevel() <= cha.getLevel()) { boolean knownSkill = false; for (int j = 0; j < oldSkills.length && !knownSkill; j++) { if (oldSkills[j].getId() == temp.getId() ) { knownSkill = true; if ( oldSkills[j].getLevel() == temp.getLevel()-1) { // this is the next level of a skill that we know for(int x : cha.getNohSkill().getSkills()){ if(temp.getId()==x){ if(test.get(x)==null){ result.add(temp); test.put(x,true); } } } } } } if (!knownSkill && temp.getLevel() == 1) { // this is a new skill for(int x : cha.getNohSkill().getSkills()){ if(temp.getId()==x){ if(test.get(x)==null){ result.add(temp); test.put(x,true); } } } } } }} if (result == null) { // the skilltree for this class is undefined, so we give an empty list _log.warning("Skilltree for class is not defined !"); return new L2SkillLearn[0]; } return result.toArray(new L2SkillLearn[result.size()]); } public L2SkillLearn[] getAvailableSkills(L2PcInstance cha) { List result = new FastList(); List skills = new FastList(); skills.addAll(_fishingSkillTrees); if (skills == null) { // the skilltree for this class is undefined, so we give an empty list _log.warning("Skilltree for fishing is not defined !"); return new L2SkillLearn[0]; } if (cha.hasDwarvenCraft() && _expandDwarfCraftSkillTrees != null) { skills.addAll(_expandDwarfCraftSkillTrees); } L2Skill[] oldSkills = cha.getAllSkills(); for (L2SkillLearn temp : skills) { if (temp.getMinLevel() <= cha.getLevel()) { boolean knownSkill = false; for (int j = 0; j < oldSkills.length && !knownSkill; j++) { if (oldSkills[j].getId() == temp.getId() ) { knownSkill = true; if ( oldSkills[j].getLevel() == temp.getLevel()-1) { // this is the next level of a skill that we know result.add(temp); } } } if (!knownSkill && temp.getLevel() == 1) { // this is a new skill result.add(temp); } } } return result.toArray(new L2SkillLearn[result.size()]); } public L2EnchantSkillLearn[] getAvailableEnchantSkills(L2PcInstance cha) { List result = new FastList(); List skills = new FastList(); skills.addAll(_enchantSkillTrees); if (skills == null) { // the skilltree for this class is undefined, so we give an empty list _log.warning("Skilltree for enchanting is not defined !"); return new L2EnchantSkillLearn[0]; } L2Skill[] oldSkills = cha.getAllSkills(); for (L2EnchantSkillLearn temp : skills) { if (76 <= cha.getLevel()) { boolean knownSkill = false; for (int j = 0; j < oldSkills.length && !knownSkill; j++) { if (oldSkills[j].getId() == temp.getId() ) { knownSkill = true; if ( oldSkills[j].getLevel() == temp.getMinSkillLevel()) { // this is the next level of a skill that we know result.add(temp); } } } } } //cha.sendMessage("loaded "+ result.size()+" enchant skills for this char(You)"); return result.toArray(new L2EnchantSkillLearn[result.size()]); } public L2PledgeSkillLearn[] getAvailablePledgeSkills(L2PcInstance cha) { List result = new FastList(); List skills = _pledgeSkillTrees; if (skills == null) { // the skilltree for this class is undefined, so we give an empty list _log.warning("No clan skills defined!"); return new L2PledgeSkillLearn[0]; } L2Skill[] oldSkills = cha.getClan().getAllSkills(); for (L2PledgeSkillLearn temp : skills) { if (temp.getBaseLevel() <= cha.getClan().getLevel()) { boolean knownSkill = false; for (int j = 0; j < oldSkills.length && !knownSkill; j++) { if (oldSkills[j].getId() == temp.getId() ) { knownSkill = true; if ( oldSkills[j].getLevel() == temp.getLevel()-1) { // this is the next level of a skill that we know result.add(temp); } } } if (!knownSkill && temp.getLevel() == 1) { // this is a new skill result.add(temp); } } } return result.toArray(new L2PledgeSkillLearn[result.size()]); } /** * Returns all allowed skills for a given class. * @param classId * @return all allowed skills for a given class. */ public Collection getAllowedSkills(ClassId classId) { return getSkillTrees().get(classId).values(); } public int getMinLevelForNewSkill(L2PcInstance cha, ClassId classId) { int minLevel = 0; Collection skills = getSkillTrees().get(classId).values(); if (skills == null) { // the skilltree for this class is undefined, so we give an empty list _log.warning("Skilltree for class " + classId + " is not defined !"); return minLevel; } for (L2SkillLearn temp: skills) { if (temp.getMinLevel() > cha.getLevel() && temp.getSpCost() != 0) if (minLevel==0 || temp.getMinLevel() skills = new FastList(); skills.addAll(_fishingSkillTrees); if (skills == null) { // the skilltree for this class is undefined, so we give an empty list _log.warning("SkillTree for fishing is not defined !"); return minLevel; } if (cha.hasDwarvenCraft() && _expandDwarfCraftSkillTrees != null) { skills.addAll(_expandDwarfCraftSkillTrees); } for (L2SkillLearn s : skills) { if (s.getMinLevel() > cha.getLevel()) if (minLevel == 0 || s.getMinLevel() < minLevel) minLevel = s.getMinLevel(); } return minLevel; } public int getSkillCost(L2PcInstance player, L2Skill skill) { int skillCost = 100000000; int skillHashCode = SkillTable.getSkillHashCode(skill); int skillId=skill.getId(); if (_skillsById.get(skillId).containsKey(skillHashCode)) { L2SkillLearn skillLearn = _skillsById.get(skillId).get(skillHashCode); if (skillLearn.getMinLevel() <= player.getLevel()) { return skillLearn.getSpCost(); } } return skillCost; } public List getNohSkills(int index, int level){ List nohs =_nohSkills.get(index); List result=new FastList(); if(nohs==null){ _log.warning("Scheisse-.-"); return null; } if(nohs.isEmpty()){ _log.warning("Scheisse-.-"); return null; } for(int x : nohs){ if(level>=_nohSkillLevel.get(x))result.add(x); } return result; } public String getSkillName(int id){ Map ski=_skillsById.get(id); String name="leer"; for( L2SkillLearn skil : ski.values()){ name=skil.getName(); } return name; } public int getSkillSpCost(L2PcInstance player, L2Skill skill) { int skillCost = 100000000; L2EnchantSkillLearn[] enchantSkillLearnList = getAvailableEnchantSkills(player); for (L2EnchantSkillLearn enchantSkillLearn : enchantSkillLearnList) { if (enchantSkillLearn.getId() != skill.getId()) continue; if (enchantSkillLearn.getLevel() != skill.getLevel()) continue; if (76 > player.getLevel()) continue; skillCost = enchantSkillLearn.getSpCost(); } return skillCost; } public int getSkillExpCost(L2PcInstance player, L2Skill skill) { int skillCost = 100000000; L2EnchantSkillLearn[] enchantSkillLearnList = getAvailableEnchantSkills(player); for (L2EnchantSkillLearn enchantSkillLearn : enchantSkillLearnList) { if (enchantSkillLearn.getId() != skill.getId()) continue; if (enchantSkillLearn.getLevel() != skill.getLevel()) continue; if (76 > player.getLevel()) continue; skillCost = enchantSkillLearn.getExp(); } return skillCost; } public byte getSkillRate(L2PcInstance player, L2Skill skill) { L2EnchantSkillLearn[] enchantSkillLearnList = getAvailableEnchantSkills(player); for (L2EnchantSkillLearn enchantSkillLearn : enchantSkillLearnList) { if (enchantSkillLearn.getId() != skill.getId()) continue; if (enchantSkillLearn.getLevel() != skill.getLevel()) continue; return enchantSkillLearn.getRate(player); } return 0; } }