Package com.l2jfrozen.gameserver.datatables.sql

Source Code of com.l2jfrozen.gameserver.datatables.sql.SkillTreeTable

/*
* 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, 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., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package com.l2jfrozen.gameserver.datatables.sql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javolution.util.FastList;
import javolution.util.FastMap;

import com.l2jfrozen.Config;
import com.l2jfrozen.gameserver.datatables.SkillTable;
import com.l2jfrozen.gameserver.model.L2EnchantSkillLearn;
import com.l2jfrozen.gameserver.model.L2PledgeSkillLearn;
import com.l2jfrozen.gameserver.model.L2Skill;
import com.l2jfrozen.gameserver.model.L2SkillLearn;
import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
import com.l2jfrozen.gameserver.model.base.ClassId;
import com.l2jfrozen.gameserver.skills.holders.ISkillsHolder;
import com.l2jfrozen.gameserver.skills.holders.PlayerSkillHolder;
import com.l2jfrozen.util.CloseUtil;
import com.l2jfrozen.util.database.L2DatabaseFactory;

/**
* This class ...
*
* @version $Revision: 1.13.2.2.2.8 $ $Date: 2005/04/06 16:13:25 $
*/
public class SkillTreeTable
{
  private final static Logger _log = Logger.getLogger(SkillTreeTable.class.getName());
  private static SkillTreeTable _instance;

  private Map<ClassId, Map<Integer, L2SkillLearn>> _skillTrees;
  private List<L2SkillLearn> _fishingSkillTrees; //all common skills (teached by Fisherman)
  private List<L2SkillLearn> _expandDwarfCraftSkillTrees; //list of special skill for dwarf (expand dwarf craft) learned by class teacher
  private List<L2PledgeSkillLearn> _pledgeSkillTrees; //pledge skill list
  private List<L2EnchantSkillLearn> _enchantSkillTrees; //enchant skill list

  public static SkillTreeTable getInstance()
  {
    if(_instance == null)
    {
      _instance = new SkillTreeTable();
    }

    return _instance;
  }

  /**
   * Return the minimum level needed to have this Expertise.<BR>
   * <BR>
   *
   * @param grade The grade level searched
   * @return
   */
  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<Integer, L2SkillLearn> learnMap = getSkillTrees().get(ClassId.paladin);

    int skillHashCode = SkillTable.getSkillHashCode(239, grade);

    if(learnMap.containsKey(skillHashCode))
      return learnMap.get(skillHashCode).getMinLevel();
   
    return 0;
  }

  /**
   * Each class receives new skill on certain levels, this methods allow the retrieval of the minimum 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<Integer, L2SkillLearn> 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<Integer, L2SkillLearn> 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;

    Connection con = null;

    try
    {
      con = L2DatabaseFactory.getInstance().getConnection(false);
      final PreparedStatement statement = con.prepareStatement("SELECT * FROM class_list ORDER BY id");
      final ResultSet classlist = statement.executeQuery();

      Map<Integer, L2SkillLearn> map;
      int parentClassId;
      L2SkillLearn skillLearn;

      while(classlist.next())
      {
        map = new FastMap<Integer, L2SkillLearn>();
        parentClassId = classlist.getInt("parent_id");
        classId = classlist.getInt("id");
        final 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);
        final ResultSet skilltree = statement2.executeQuery();

        if(parentClassId != -1)
        {
          Map<Integer, L2SkillLearn> 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);
        }

        getSkillTrees().put(ClassId.values()[classId], map);
        skilltree.close();
        statement2.close();

        count += map.size();
        _log.finest("SkillTreeTable: skill tree for class {} has {} skills "+ classId+" "+ map.size());
      }

      classlist.close();
      statement.close();
    }
    catch(Exception e)
    {
      _log.severe("Error while creating skill tree (Class ID {}): "+ classId+" "+ e);
    }
   

    _log.finest("SkillTreeTable: Loaded {} skills."+" "+ count);

    //Skill tree for fishing skill (from Fisherman)
    int count2 = 0;
    int count3 = 0;

    try
    {
      _fishingSkillTrees = new FastList<L2SkillLearn>();
      _expandDwarfCraftSkillTrees = new FastList<L2SkillLearn>();
      if (con == null)
      {
        con = L2DatabaseFactory.getInstance().getConnection(false);
      }
      final PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, name, sp, min_level, costid, cost, isfordwarf FROM fishing_skill_trees ORDER BY skill_id, level");
      final 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<L2EnchantSkillLearn>();
      if (con == null)
      {
        con = L2DatabaseFactory.getInstance().getConnection(false);
      }
      final 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");
      final 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;
        }

        _enchantSkillTrees.add(new L2EnchantSkillLearn(id, lvl, minSkillLvl, baseLvl, name, sp, exp, rate76, rate77, rate78));
      }

      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<L2PledgeSkillLearn>();
      if (con == null)
      {
        con = L2DatabaseFactory.getInstance().getConnection(false);
      }
      final PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, name, clan_lvl, repCost, itemId FROM pledge_skill_trees ORDER BY skill_id, level");
      final 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;
        }

        _pledgeSkillTrees.add(new L2PledgeSkillLearn(id, lvl, baseLvl, name, sp, itemId));
      }

      skilltree4.close();
      statement.close();

      count5 = _pledgeSkillTrees.size();
    }
    catch(Exception e)
    {
      _log.severe("Error while creating fishing skill table"+" "+ e);
    }
    finally
    {
      CloseUtil.close(con);
    }

    _log.finest("FishingSkillTreeTable: Loaded {} general skills."+" "+ count2);
    _log.finest("FishingSkillTreeTable: Loaded {} dwarven skills."+" "+ count3);
    _log.finest("EnchantSkillTreeTable: Loaded {} enchant skills."+" "+ count4);
    _log.finest("PledgeSkillTreeTable: Loaded {} pledge skills"+" "+ count5);
  }

  private Map<ClassId, Map<Integer, L2SkillLearn>> getSkillTrees()
  {
    if(_skillTrees == null)
    {
      _skillTrees = new FastMap<ClassId, Map<Integer, L2SkillLearn>>();
    }

    return _skillTrees;
  }

  public L2SkillLearn[] getAvailableSkills(L2PcInstance player, ClassId classId)
  {
    List<L2SkillLearn> result = getAvailableSkills(player, classId, player);
    return result.toArray(new L2SkillLearn[result.size()]);
  }
 
  /**
   * Gets the available skills.
   * @param player the learning skill player.
   * @param classId the learning skill class ID.
   * @param includeByFs if {@code true} skills from Forgotten Scroll will be included.
   * @param includeAutoGet if {@code true} Auto-Get skills will be included.
   * @param holder
   * @return all available skills for a given {@code player}, {@code classId}, {@code includeByFs} and {@code includeAutoGet}.
   */
  /*
  private List<L2SkillLearn> getAvailableSkills(L2PcInstance cha, ClassId classId, ISkillsHolder holder)
  {
   
    List<L2SkillLearn> result = new FastList<L2SkillLearn>();
    Collection<L2SkillLearn> skills = getSkillTrees().get(classId).values();

    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;
  }
  */
  /**
   * Gets the available skills.
   * @param player the learning skill player.
   * @param classId the learning skill class ID.
   * @param holder
   * @return all available skills for a given {@code player}, {@code classId}, {@code includeByFs} and {@code includeAutoGet}.
   */
  private List<L2SkillLearn> getAvailableSkills(L2PcInstance player, ClassId classId, ISkillsHolder holder)
  {
    final List<L2SkillLearn> result = new ArrayList<L2SkillLearn>();
    Collection<L2SkillLearn> skills = getSkillTrees().get(classId).values();

    if (skills.isEmpty())
    {
      // The Skill Tree for this class is undefined.
      _log.warning(getClass().getSimpleName() + ": Skilltree for class " + classId + " is not defined!");
      return result;
    }
   
    for (L2SkillLearn skill : skills)
    {
      if (skill.getMinLevel() <= player.getLevel())
      {
        final L2Skill oldSkill = holder.getKnownSkill(skill.getId());
        if (oldSkill != null)
        {
          if (oldSkill.getLevel() == (skill.getLevel() - 1))
          {
            result.add(skill);
          }
        }
        else if (skill.getLevel() == 1)
        {
          result.add(skill);
        }
      }
    }
    return result;
  }

  public L2SkillLearn[] getAvailableSkills(L2PcInstance cha)
  {
    List<L2SkillLearn> result = new FastList<L2SkillLearn>();
    List<L2SkillLearn> skills = new FastList<L2SkillLearn>();

    skills.addAll(_fishingSkillTrees);

    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<L2EnchantSkillLearn> result = new FastList<L2EnchantSkillLearn>();
    List<L2EnchantSkillLearn> skills = new FastList<L2EnchantSkillLearn>();

    skills.addAll(_enchantSkillTrees);

    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<L2PledgeSkillLearn> result = new FastList<L2PledgeSkillLearn>();
    List<L2PledgeSkillLearn> 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<L2SkillLearn> getAllowedSkills(ClassId classId)
  {
    return getSkillTrees().get(classId).values();
  }

  public int getMinLevelForNewSkill(L2PcInstance cha, ClassId classId)
  {
    int minLevel = 0;
    Collection<L2SkillLearn> 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 {} is not defined !"+" "+ classId);
      return minLevel;
    }

    for(L2SkillLearn temp : skills)
    {
      if(temp.getMinLevel() > cha.getLevel() && temp.getSpCost() != 0)
        if(minLevel == 0 || temp.getMinLevel() < minLevel)
        {
          minLevel = temp.getMinLevel();
        }
    }

    return minLevel;
  }

  public int getMinLevelForNewSkill(L2PcInstance cha)
  {
    int minLevel = 0;
    List<L2SkillLearn> skills = new FastList<L2SkillLearn>();

    skills.addAll(_fishingSkillTrees);

    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;
    ClassId classId = player.getSkillLearningClassId();
    int skillHashCode = SkillTable.getSkillHashCode(skill);

    if(getSkillTrees().get(classId).containsKey(skillHashCode))
    {
      L2SkillLearn skillLearn = getSkillTrees().get(classId).get(skillHashCode);
      if(skillLearn.getMinLevel() <= player.getLevel())
      {
        skillCost = skillLearn.getSpCost();
        if(!player.getClassId().equalsOrChildOf(classId))
        {
          if(skill.getCrossLearnAdd() < 0)
            return skillCost;

          skillCost += skill.getCrossLearnAdd();
          skillCost *= skill.getCrossLearnMul();
        }

        if(classId.getRace() != player.getRace() && !player.isSubClassActive())
        {
          skillCost *= skill.getCrossLearnRace();
        }

        if(classId.isMage() != player.getClassId().isMage())
        {
          skillCost *= skill.getCrossLearnProf();
        }
      }
    }

    return skillCost;
  }

  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;
  }

  /**
   * @param player
   * @param classId
   * @return
   */
  public Collection<L2Skill> getAllAvailableSkills(L2PcInstance player, ClassId classId)
  {
    // Get available skills
    int unLearnable = 0;
    PlayerSkillHolder holder = new PlayerSkillHolder(player.getSkills());
    List<L2SkillLearn> learnable = getAvailableSkills(player, classId, holder);
    while (learnable.size() > unLearnable)
    {
      for (L2SkillLearn s : learnable)
      {
        L2Skill sk = SkillTable.getInstance().getInfo(s.getId(), s.getLevel());
        if ((sk == null) || ((sk.getId() == L2Skill.SKILL_DIVINE_INSPIRATION) && !Config.AUTO_LEARN_DIVINE_INSPIRATION && !player.isGM()))
        {
          unLearnable++;
          continue;
        }
       
        holder.addSkill(sk);
      }
     
      // Get new available skills, some skills depend of previous skills to be available.
      learnable = getAvailableSkills(player, classId, holder);
    }
    return holder.getSkills().values();
  }
}
TOP

Related Classes of com.l2jfrozen.gameserver.datatables.sql.SkillTreeTable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.