SkillTreeTable.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package com.l2jserver.gameserver.datatables;
  16. import java.sql.Connection;
  17. import java.sql.PreparedStatement;
  18. import java.sql.ResultSet;
  19. import java.util.Collection;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.logging.Level;
  23. import java.util.logging.Logger;
  24. import com.l2jserver.L2DatabaseFactory;
  25. import com.l2jserver.gameserver.model.L2EnchantSkillLearn;
  26. import com.l2jserver.gameserver.model.L2PledgeSkillLearn;
  27. import com.l2jserver.gameserver.model.L2Skill;
  28. import com.l2jserver.gameserver.model.L2SkillLearn;
  29. import com.l2jserver.gameserver.model.L2TransformSkillLearn;
  30. import com.l2jserver.gameserver.model.L2EnchantSkillLearn.EnchantSkillDetail;
  31. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  32. import com.l2jserver.gameserver.model.base.ClassId;
  33. import javolution.util.FastList;
  34. import javolution.util.FastMap;
  35. /**
  36. * This class ...
  37. *
  38. * @version $Revision: 1.13.2.2.2.8 $ $Date: 2005/04/06 16:13:25 $
  39. */
  40. public class SkillTreeTable
  41. {
  42. public static final int NORMAL_ENCHANT_COST_MULTIPLIER = 1;
  43. public static final int SAFE_ENCHANT_COST_MULTIPLIER = 5;
  44. public static final int ADENA_XP_DIV = 3; //TODO magic number
  45. public static final int NORMAL_ENCHANT_BOOK = 6622;
  46. public static final int SAFE_ENCHANT_BOOK = 9627;
  47. public static final int CHANGE_ENCHANT_BOOK = 9626;
  48. public static final int UNTRAIN_ENCHANT_BOOK = 9625;
  49. private static Logger _log = Logger.getLogger(SkillTreeTable.class.getName());
  50. private Map<ClassId, Map<Integer, L2SkillLearn>> _skillTrees;
  51. private List<L2SkillLearn> _fishingSkillTrees; //all common skills (teached by Fisherman)
  52. private List<L2SkillLearn> _expandDwarfCraftSkillTrees; //list of special skill for dwarf (expand dwarf craft) learned by class teacher
  53. private List<L2PledgeSkillLearn> _pledgeSkillTrees; //pledge skill list
  54. private Map<Integer, L2EnchantSkillLearn> _enchantSkillTrees; //enchant skill list
  55. private List<L2TransformSkillLearn> _TransformSkillTrees; // Transform Skills (Test)
  56. private FastList<L2SkillLearn> _specialSkillTrees;
  57. public static SkillTreeTable getInstance()
  58. {
  59. return SingletonHolder._instance;
  60. }
  61. /**
  62. * Return the minimum level needed to have this Expertise.<BR><BR>
  63. *
  64. * @param grade The grade level searched
  65. */
  66. public int getExpertiseLevel(int grade)
  67. {
  68. if (grade <= 0)
  69. return 0;
  70. // since expertise comes at same level for all classes we use paladin for now
  71. Map<Integer, L2SkillLearn> learnMap = getSkillTrees().get(ClassId.paladin);
  72. int skillHashCode = SkillTable.getSkillHashCode(239, grade);
  73. if (learnMap.containsKey(skillHashCode))
  74. {
  75. return learnMap.get(skillHashCode).getMinLevel();
  76. }
  77. _log.severe("Expertise not found for grade " + grade);
  78. return 0;
  79. }
  80. /**
  81. * Each class receives new skill on certain levels, this methods allow the retrieval of the minimun character level
  82. * of given class required to learn a given skill
  83. * @param skillId The iD of the skill
  84. * @param classID The classId of the character
  85. * @param skillLvl The SkillLvl
  86. * @return The min level
  87. */
  88. public int getMinSkillLevel(int skillId, ClassId classId, int skillLvl)
  89. {
  90. Map<Integer, L2SkillLearn> map = getSkillTrees().get(classId);
  91. int skillHashCode = SkillTable.getSkillHashCode(skillId, skillLvl);
  92. if (map.containsKey(skillHashCode))
  93. {
  94. return map.get(skillHashCode).getMinLevel();
  95. }
  96. return 0;
  97. }
  98. public int getMinSkillLevel(int skillId, int skillLvl)
  99. {
  100. int skillHashCode = SkillTable.getSkillHashCode(skillId, skillLvl);
  101. // Look on all classes for this skill (takes the first one found)
  102. for (Map<Integer, L2SkillLearn> map : getSkillTrees().values())
  103. {
  104. // checks if the current class has this skill
  105. if (map.containsKey(skillHashCode))
  106. {
  107. return map.get(skillHashCode).getMinLevel();
  108. }
  109. }
  110. return 0;
  111. }
  112. private SkillTreeTable()
  113. {
  114. int classId = 0;
  115. int count = 0;
  116. int count2 = 0;
  117. int count3 = 0;
  118. int count4 = 0;
  119. int count5 = 0;
  120. int count6 = 0;
  121. int count7 = 0;
  122. Connection con = null;
  123. try
  124. {
  125. con = L2DatabaseFactory.getInstance().getConnection();
  126. try
  127. {
  128. PreparedStatement statement = con.prepareStatement("SELECT * FROM class_list ORDER BY id");
  129. ResultSet classlist = statement.executeQuery();
  130. Map<Integer, L2SkillLearn> map;
  131. int parentClassId;
  132. L2SkillLearn skillLearn;
  133. while (classlist.next())
  134. {
  135. map = new FastMap<Integer, L2SkillLearn>();
  136. parentClassId = classlist.getInt("parent_id");
  137. classId = classlist.getInt("id");
  138. 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");
  139. statement2.setInt(1, classId);
  140. ResultSet skilltree = statement2.executeQuery();
  141. if (parentClassId != -1)
  142. {
  143. Map<Integer, L2SkillLearn> parentMap = getSkillTrees().get(ClassId.values()[parentClassId]);
  144. map.putAll(parentMap);
  145. }
  146. int prevSkillId = -1;
  147. while (skilltree.next())
  148. {
  149. int id = skilltree.getInt("skill_id");
  150. int lvl = skilltree.getInt("level");
  151. String name = skilltree.getString("name");
  152. int minLvl = skilltree.getInt("min_level");
  153. int cost = skilltree.getInt("sp");
  154. if (prevSkillId != id)
  155. prevSkillId = id;
  156. skillLearn = new L2SkillLearn(id, lvl, minLvl, name, cost, 0, 0);
  157. map.put(SkillTable.getSkillHashCode(id, lvl), skillLearn);
  158. }
  159. getSkillTrees().put(ClassId.values()[classId], map);
  160. skilltree.close();
  161. statement2.close();
  162. count += map.size();
  163. _log.fine("SkillTreeTable: skill tree for class " + classId + " has " + map.size() + " skills");
  164. }
  165. classlist.close();
  166. statement.close();
  167. }
  168. catch (Exception e)
  169. {
  170. _log.severe("Error while creating skill tree (Class ID " + classId + "):" + e);
  171. }
  172. _log.config("SkillTreeTable: Loaded " + count + " skills.");
  173. //Skill tree for fishing skill (from Fisherman)
  174. try
  175. {
  176. _fishingSkillTrees = new FastList<L2SkillLearn>();
  177. _expandDwarfCraftSkillTrees = new FastList<L2SkillLearn>();
  178. PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, name, sp, min_level, costid, cost, isfordwarf FROM fishing_skill_trees ORDER BY skill_id, level");
  179. ResultSet skilltree2 = statement.executeQuery();
  180. int prevSkillId = -1;
  181. while (skilltree2.next())
  182. {
  183. int id = skilltree2.getInt("skill_id");
  184. int lvl = skilltree2.getInt("level");
  185. String name = skilltree2.getString("name");
  186. int minLvl = skilltree2.getInt("min_level");
  187. int cost = skilltree2.getInt("sp");
  188. int costId = skilltree2.getInt("costid");
  189. int costCount = skilltree2.getInt("cost");
  190. int isDwarven = skilltree2.getInt("isfordwarf");
  191. if (prevSkillId != id)
  192. prevSkillId = id;
  193. L2SkillLearn skill = new L2SkillLearn(id, lvl, minLvl, name, cost, costId, costCount);
  194. if (isDwarven == 0)
  195. _fishingSkillTrees.add(skill);
  196. else
  197. _expandDwarfCraftSkillTrees.add(skill);
  198. }
  199. skilltree2.close();
  200. statement.close();
  201. count2 = _fishingSkillTrees.size();
  202. count3 = _expandDwarfCraftSkillTrees.size();
  203. }
  204. catch (Exception e)
  205. {
  206. _log.severe("Error while creating fishing skill table: " + e);
  207. }
  208. try
  209. {
  210. _enchantSkillTrees = new FastMap<Integer, L2EnchantSkillLearn>();
  211. PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, base_lvl, sp, min_skill_lvl, exp, success_rate76, success_rate77, success_rate78, success_rate79, success_rate80, success_rate81, success_rate82, success_rate83, success_rate84, success_rate85 FROM enchant_skill_trees ORDER BY skill_id, level");
  212. ResultSet skilltree3 = statement.executeQuery();
  213. int prevSkillId = -1;
  214. while (skilltree3.next())
  215. {
  216. int id = skilltree3.getInt("skill_id");
  217. int lvl = skilltree3.getInt("level");
  218. int baseLvl = skilltree3.getInt("base_lvl");
  219. int minSkillLvl = skilltree3.getInt("min_skill_lvl");
  220. int sp = skilltree3.getInt("sp");
  221. int exp = skilltree3.getInt("exp");
  222. byte rate76 = skilltree3.getByte("success_rate76");
  223. byte rate77 = skilltree3.getByte("success_rate77");
  224. byte rate78 = skilltree3.getByte("success_rate78");
  225. byte rate79 = skilltree3.getByte("success_rate79");
  226. byte rate80 = skilltree3.getByte("success_rate80");
  227. byte rate81 = skilltree3.getByte("success_rate81");
  228. byte rate82 = skilltree3.getByte("success_rate82");
  229. byte rate83 = skilltree3.getByte("success_rate83");
  230. byte rate84 = skilltree3.getByte("success_rate84");
  231. byte rate85 = skilltree3.getByte("success_rate85");
  232. if (prevSkillId != id)
  233. prevSkillId = id;
  234. L2EnchantSkillLearn skill = _enchantSkillTrees.get(id);
  235. if (skill == null)
  236. {
  237. skill = new L2EnchantSkillLearn(id, baseLvl);
  238. _enchantSkillTrees.put(id, skill);
  239. }
  240. EnchantSkillDetail esd = new EnchantSkillDetail(lvl, minSkillLvl, sp, exp, rate76, rate77, rate78, rate79, rate80, rate81, rate82, rate83, rate84, rate85);
  241. skill.addEnchantDetail(esd);
  242. }
  243. skilltree3.close();
  244. statement.close();
  245. count4 = _enchantSkillTrees.size();
  246. }
  247. catch (Exception e)
  248. {
  249. _log.log(Level.SEVERE, "Error while creating enchant skill table ", e);
  250. }
  251. try
  252. {
  253. _pledgeSkillTrees = new FastList<L2PledgeSkillLearn>();
  254. PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, name, clan_lvl, repCost, itemId, itemCount FROM pledge_skill_trees ORDER BY skill_id, level");
  255. ResultSet skilltree4 = statement.executeQuery();
  256. int prevSkillId = -1;
  257. while (skilltree4.next())
  258. {
  259. int id = skilltree4.getInt("skill_id");
  260. int lvl = skilltree4.getInt("level");
  261. String name = skilltree4.getString("name");
  262. int baseLvl = skilltree4.getInt("clan_lvl");
  263. int sp = skilltree4.getInt("repCost");
  264. int itemId = skilltree4.getInt("itemId");
  265. int itemCount = skilltree4.getInt("itemCount");
  266. if (prevSkillId != id)
  267. prevSkillId = id;
  268. L2PledgeSkillLearn skill = new L2PledgeSkillLearn(id, lvl, baseLvl, name, sp, itemId, itemCount);
  269. _pledgeSkillTrees.add(skill);
  270. }
  271. skilltree4.close();
  272. statement.close();
  273. count5 = _pledgeSkillTrees.size();
  274. }
  275. catch (Exception e)
  276. {
  277. _log.severe("Error while creating pledge skill table: " + e);
  278. }
  279. try
  280. {
  281. _TransformSkillTrees = new FastList<L2TransformSkillLearn>();
  282. PreparedStatement statement = con.prepareStatement("SELECT race_id, skill_id, item_id, level, name, sp, min_level FROM transform_skill_trees ORDER BY race_id, skill_id, level");
  283. ResultSet skilltree5 = statement.executeQuery();
  284. int prevSkillId = -1;
  285. while (skilltree5.next())
  286. {
  287. int race_id = skilltree5.getInt("race_id");
  288. int skill_id = skilltree5.getInt("skill_id");
  289. int item_id = skilltree5.getInt("item_id");
  290. int level = skilltree5.getInt("level");
  291. String name = skilltree5.getString("name");
  292. int sp = skilltree5.getInt("sp");
  293. int min_level = skilltree5.getInt("min_level");
  294. if (prevSkillId != skill_id)
  295. prevSkillId = skill_id;
  296. L2TransformSkillLearn skill = new L2TransformSkillLearn(race_id, skill_id, item_id, level, name, sp, min_level);
  297. _TransformSkillTrees.add(skill);
  298. }
  299. skilltree5.close();
  300. statement.close();
  301. count6 = _TransformSkillTrees.size();
  302. }
  303. catch (Exception e)
  304. {
  305. _log.log(Level.SEVERE, "Error while creating Transformation skill table ", e);
  306. }
  307. try
  308. {
  309. _specialSkillTrees = new FastList<L2SkillLearn>();
  310. PreparedStatement statement = con.prepareStatement("SELECT skill_id, level, name, costid, cost FROM special_skill_trees ORDER BY skill_id, level");
  311. ResultSet skilltree6 = statement.executeQuery();
  312. int prevSkillId = -1;
  313. while (skilltree6.next())
  314. {
  315. int id = skilltree6.getInt("skill_id");
  316. int lvl = skilltree6.getInt("level");
  317. String name = skilltree6.getString("name");
  318. int costId = skilltree6.getInt("costid");
  319. int costCount = skilltree6.getInt("cost");
  320. if (prevSkillId != id)
  321. prevSkillId = id;
  322. L2SkillLearn skill = new L2SkillLearn(id, lvl, 0, name, 0, costId, costCount);
  323. _specialSkillTrees.add(skill);
  324. }
  325. skilltree6.close();
  326. statement.close();
  327. count7 = _specialSkillTrees.size();
  328. }
  329. catch (Exception e)
  330. {
  331. _log.severe("Error while creating special skill table: " + e);
  332. }
  333. }
  334. catch (Exception e)
  335. {
  336. _log.log(Level.SEVERE, "Error while skill tables ", e);
  337. }
  338. finally
  339. {
  340. try
  341. {
  342. con.close();
  343. }
  344. catch (Exception e)
  345. {
  346. }
  347. }
  348. _log.config("FishingSkillTreeTable: Loaded " + count2 + " general skills.");
  349. _log.config("DwarvenCraftSkillTreeTable: Loaded " + count3 + " dwarven skills.");
  350. _log.config("EnchantSkillTreeTable: Loaded " + count4 + " enchant skills.");
  351. _log.config("PledgeSkillTreeTable: Loaded " + count5 + " pledge skills");
  352. _log.config("TransformSkillTreeTable: Loaded " + count6 + " transform skills");
  353. _log.config("SpecialSkillTreeTable: Loaded " + count7 + " special skills");
  354. }
  355. private Map<ClassId, Map<Integer, L2SkillLearn>> getSkillTrees()
  356. {
  357. if (_skillTrees == null)
  358. _skillTrees = new FastMap<ClassId, Map<Integer, L2SkillLearn>>();
  359. return _skillTrees;
  360. }
  361. public L2SkillLearn[] getAvailableSkills(L2PcInstance cha, ClassId classId)
  362. {
  363. List<L2SkillLearn> result = new FastList<L2SkillLearn>();
  364. Collection<L2SkillLearn> skills = getSkillTrees().get(classId).values();
  365. if (skills == null)
  366. {
  367. // the skilltree for this class is undefined, so we give an empty list
  368. _log.warning("Skilltree for class " + classId + " is not defined !");
  369. return new L2SkillLearn[0];
  370. }
  371. L2Skill[] oldSkills = cha.getAllSkills();
  372. for (L2SkillLearn temp : skills)
  373. {
  374. if (temp.getMinLevel() <= cha.getLevel())
  375. {
  376. boolean knownSkill = false;
  377. for (int j = 0; j < oldSkills.length && !knownSkill; j++)
  378. {
  379. if (oldSkills[j].getId() == temp.getId())
  380. {
  381. knownSkill = true;
  382. if (oldSkills[j].getLevel() == temp.getLevel() - 1)
  383. {
  384. // this is the next level of a skill that we know
  385. result.add(temp);
  386. }
  387. }
  388. }
  389. if (!knownSkill && temp.getLevel() == 1)
  390. {
  391. // this is a new skill
  392. result.add(temp);
  393. }
  394. }
  395. }
  396. return result.toArray(new L2SkillLearn[result.size()]);
  397. }
  398. public L2SkillLearn[] getAvailableSkills(L2PcInstance cha)
  399. {
  400. List<L2SkillLearn> result = new FastList<L2SkillLearn>();
  401. List<L2SkillLearn> skills = new FastList<L2SkillLearn>();
  402. skills.addAll(_fishingSkillTrees);
  403. if (skills == null)
  404. {
  405. // the skilltree for this class is undefined, so we give an empty list
  406. _log.warning("Skilltree for fishing is not defined !");
  407. return new L2SkillLearn[0];
  408. }
  409. if (cha.hasDwarvenCraft() && _expandDwarfCraftSkillTrees != null)
  410. {
  411. skills.addAll(_expandDwarfCraftSkillTrees);
  412. }
  413. L2Skill[] oldSkills = cha.getAllSkills();
  414. for (L2SkillLearn temp : skills)
  415. {
  416. if (temp.getMinLevel() <= cha.getLevel())
  417. {
  418. boolean knownSkill = false;
  419. for (int j = 0; j < oldSkills.length && !knownSkill; j++)
  420. {
  421. if (oldSkills[j].getId() == temp.getId())
  422. {
  423. knownSkill = true;
  424. if (oldSkills[j].getLevel() == temp.getLevel() - 1)
  425. {
  426. // this is the next level of a skill that we know
  427. result.add(temp);
  428. }
  429. }
  430. }
  431. if (!knownSkill && temp.getLevel() == 1)
  432. {
  433. // this is a new skill
  434. result.add(temp);
  435. }
  436. }
  437. }
  438. return result.toArray(new L2SkillLearn[result.size()]);
  439. }
  440. public L2SkillLearn[] getAvailableSpecialSkills(L2PcInstance cha)
  441. {
  442. List<L2SkillLearn> result = new FastList<L2SkillLearn>();
  443. List<L2SkillLearn> skills = new FastList<L2SkillLearn>();
  444. skills.addAll(_specialSkillTrees);
  445. if (skills == null)
  446. {
  447. // the skilltree for this class is undefined, so we give an empty list
  448. _log.warning("Skilltree for special is not defined !");
  449. return new L2SkillLearn[0];
  450. }
  451. L2Skill[] oldSkills = cha.getAllSkills();
  452. for (L2SkillLearn temp : skills)
  453. {
  454. boolean knownSkill = false;
  455. for (int j = 0; j < oldSkills.length && !knownSkill; j++)
  456. {
  457. if (oldSkills[j].getId() == temp.getId())
  458. {
  459. knownSkill = true;
  460. if (oldSkills[j].getLevel() == temp.getLevel() - 1)
  461. {
  462. // this is the next level of a skill that we know
  463. result.add(temp);
  464. }
  465. }
  466. }
  467. if (!knownSkill && temp.getLevel() == 1)
  468. {
  469. // this is a new skill
  470. result.add(temp);
  471. }
  472. }
  473. return result.toArray(new L2SkillLearn[result.size()]);
  474. }
  475. public L2EnchantSkillLearn getSkillEnchantmentForSkill(L2Skill skill)
  476. {
  477. L2EnchantSkillLearn esl = this.getSkillEnchantmentBySkillId(skill.getId());
  478. // there is enchantment for this skill and we have the required level of it
  479. if (esl != null && skill.getLevel() >= esl.getBaseLevel())
  480. {
  481. return esl;
  482. }
  483. return null;
  484. }
  485. public L2EnchantSkillLearn getSkillEnchantmentBySkillId(int skillId)
  486. {
  487. return _enchantSkillTrees.get(skillId);
  488. }
  489. public L2TransformSkillLearn[] getAvailableTransformSkills(L2PcInstance cha)
  490. {
  491. List<L2TransformSkillLearn> result = new FastList<L2TransformSkillLearn>();
  492. List<L2TransformSkillLearn> skills = _TransformSkillTrees;
  493. if (skills == null)
  494. {
  495. // the skilltree for this class is undefined, so we give an empty list
  496. _log.warning("No Transform skills defined!");
  497. return new L2TransformSkillLearn[0];
  498. }
  499. L2Skill[] oldSkills = cha.getAllSkills();
  500. for (L2TransformSkillLearn temp : skills)
  501. {
  502. if (temp.getMinLevel() <= cha.getLevel() && (temp.getRace() == cha.getRace().ordinal() || temp.getRace() == -1))
  503. {
  504. boolean knownSkill = false;
  505. for (int j = 0; j < oldSkills.length && !knownSkill; j++)
  506. {
  507. if (oldSkills[j].getId() == temp.getId())
  508. {
  509. knownSkill = true;
  510. if (oldSkills[j].getLevel() == temp.getLevel() - 1)
  511. {
  512. // this is the next level of a skill that we know
  513. result.add(temp);
  514. }
  515. }
  516. }
  517. if (!knownSkill && temp.getLevel() == 1)
  518. {
  519. // this is a new skill
  520. result.add(temp);
  521. }
  522. }
  523. }
  524. return result.toArray(new L2TransformSkillLearn[result.size()]);
  525. }
  526. public L2PledgeSkillLearn[] getAvailablePledgeSkills(L2PcInstance cha)
  527. {
  528. List<L2PledgeSkillLearn> result = new FastList<L2PledgeSkillLearn>();
  529. List<L2PledgeSkillLearn> skills = _pledgeSkillTrees;
  530. if (skills == null)
  531. {
  532. // the skilltree for this class is undefined, so we give an empty list
  533. _log.warning("No clan skills defined!");
  534. return new L2PledgeSkillLearn[0];
  535. }
  536. L2Skill[] oldSkills = cha.getClan().getAllSkills();
  537. for (L2PledgeSkillLearn temp : skills)
  538. {
  539. if (temp.getBaseLevel() <= cha.getClan().getLevel())
  540. {
  541. boolean knownSkill = false;
  542. for (int j = 0; j < oldSkills.length && !knownSkill; j++)
  543. {
  544. if (oldSkills[j].getId() == temp.getId())
  545. {
  546. knownSkill = true;
  547. if (oldSkills[j].getLevel() == temp.getLevel() - 1)
  548. {
  549. // this is the next level of a skill that we know
  550. result.add(temp);
  551. }
  552. }
  553. }
  554. if (!knownSkill && temp.getLevel() == 1)
  555. {
  556. // this is a new skill
  557. result.add(temp);
  558. }
  559. }
  560. }
  561. return result.toArray(new L2PledgeSkillLearn[result.size()]);
  562. }
  563. /**
  564. * Returns all allowed skills for a given class.
  565. * @param classId
  566. * @return all allowed skills for a given class.
  567. */
  568. public Collection<L2SkillLearn> getAllowedSkills(ClassId classId)
  569. {
  570. return getSkillTrees().get(classId).values();
  571. }
  572. public int getMinLevelForNewSkill(L2PcInstance cha, ClassId classId)
  573. {
  574. int minLevel = 0;
  575. Collection<L2SkillLearn> skills = getSkillTrees().get(classId).values();
  576. if (skills == null)
  577. {
  578. // the skilltree for this class is undefined, so we give an empty list
  579. _log.warning("Skilltree for class " + classId + " is not defined !");
  580. return minLevel;
  581. }
  582. for (L2SkillLearn temp : skills)
  583. {
  584. if (temp.getMinLevel() > cha.getLevel() && temp.getSpCost() != 0)
  585. if (minLevel == 0 || temp.getMinLevel() < minLevel)
  586. minLevel = temp.getMinLevel();
  587. }
  588. return minLevel;
  589. }
  590. public int getMinLevelForNewSkill(L2PcInstance cha)
  591. {
  592. int minLevel = 0;
  593. List<L2SkillLearn> skills = new FastList<L2SkillLearn>();
  594. skills.addAll(_fishingSkillTrees);
  595. if (skills == null)
  596. {
  597. // the skilltree for this class is undefined, so we give an empty list
  598. _log.warning("SkillTree for fishing is not defined !");
  599. return minLevel;
  600. }
  601. if (cha.hasDwarvenCraft() && _expandDwarfCraftSkillTrees != null)
  602. {
  603. skills.addAll(_expandDwarfCraftSkillTrees);
  604. }
  605. for (L2SkillLearn s : skills)
  606. {
  607. if (s.getMinLevel() > cha.getLevel())
  608. if (minLevel == 0 || s.getMinLevel() < minLevel)
  609. minLevel = s.getMinLevel();
  610. }
  611. return minLevel;
  612. }
  613. public int getMinLevelForNewTransformSkill(L2PcInstance cha)
  614. {
  615. int minLevel = 0;
  616. List<L2TransformSkillLearn> skills = new FastList<L2TransformSkillLearn>();
  617. skills.addAll(_TransformSkillTrees);
  618. if (skills == null)
  619. {
  620. // the skilltree for this class is undefined, so we give an empty list
  621. _log.warning("SkillTree for fishing is not defined !");
  622. return minLevel;
  623. }
  624. for (L2TransformSkillLearn s : skills)
  625. {
  626. if ((s.getMinLevel() > cha.getLevel()) && (s.getRace() == cha.getRace().ordinal()))
  627. if (minLevel == 0 || s.getMinLevel() < minLevel)
  628. minLevel = s.getMinLevel();
  629. }
  630. return minLevel;
  631. }
  632. public int getSkillCost(L2PcInstance player, L2Skill skill)
  633. {
  634. int skillCost = 100000000;
  635. ClassId classId = player.getSkillLearningClassId();
  636. int skillHashCode = SkillTable.getSkillHashCode(skill);
  637. if (getSkillTrees().get(classId).containsKey(skillHashCode))
  638. {
  639. L2SkillLearn skillLearn = getSkillTrees().get(classId).get(skillHashCode);
  640. if (skillLearn.getMinLevel() <= player.getLevel())
  641. {
  642. skillCost = skillLearn.getSpCost();
  643. if (!player.getClassId().equalsOrChildOf(classId))
  644. return skillCost;
  645. }
  646. }
  647. return skillCost;
  648. }
  649. public int getEnchantSkillSpCost(L2Skill skill)
  650. {
  651. L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
  652. if (enchantSkillLearn != null)
  653. {
  654. EnchantSkillDetail esd = enchantSkillLearn.getEnchantSkillDetail(skill.getLevel());
  655. if (esd != null)
  656. {
  657. return esd.getSpCost();
  658. }
  659. }
  660. return Integer.MAX_VALUE;
  661. }
  662. public int getEnchantSkillAdenaCost(L2Skill skill)
  663. {
  664. L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
  665. if (enchantSkillLearn != null)
  666. {
  667. EnchantSkillDetail esd = enchantSkillLearn.getEnchantSkillDetail(skill.getLevel());
  668. if (esd != null)
  669. {
  670. return esd.getAdena();
  671. }
  672. }
  673. return Integer.MAX_VALUE;
  674. }
  675. public byte getEnchantSkillRate(L2PcInstance player, L2Skill skill)
  676. {
  677. L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
  678. if (enchantSkillLearn != null)
  679. {
  680. EnchantSkillDetail esd = enchantSkillLearn.getEnchantSkillDetail(skill.getLevel());
  681. if (esd != null)
  682. {
  683. return esd.getRate(player);
  684. }
  685. }
  686. return 0;
  687. }
  688. @SuppressWarnings("synthetic-access")
  689. private static class SingletonHolder
  690. {
  691. protected static final SkillTreeTable _instance = new SkillTreeTable();
  692. }
  693. }