AvantGarde.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. * Copyright (C) 2004-2015 L2J DataPack
  3. *
  4. * This file is part of L2J DataPack.
  5. *
  6. * L2J DataPack is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J DataPack is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package ai.npc.AvantGarde;
  20. import java.util.List;
  21. import ai.npc.AbstractNpcAI;
  22. import com.l2jserver.Config;
  23. import com.l2jserver.gameserver.data.xml.impl.MultisellData;
  24. import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
  25. import com.l2jserver.gameserver.datatables.SkillData;
  26. import com.l2jserver.gameserver.instancemanager.QuestManager;
  27. import com.l2jserver.gameserver.model.L2SkillLearn;
  28. import com.l2jserver.gameserver.model.actor.L2Npc;
  29. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  30. import com.l2jserver.gameserver.model.base.AcquireSkillType;
  31. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  32. import com.l2jserver.gameserver.model.quest.QuestState;
  33. import com.l2jserver.gameserver.model.skills.Skill;
  34. import com.l2jserver.gameserver.network.SystemMessageId;
  35. import com.l2jserver.gameserver.network.clientpackets.RequestAcquireSkill;
  36. import com.l2jserver.gameserver.network.serverpackets.AcquireSkillList;
  37. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  38. import com.l2jserver.gameserver.util.Util;
  39. import custom.Validators.SubClassSkills;
  40. /**
  41. * Avant-Garde AI.<br>
  42. * Sub-Class Certification system, skill learning and certification canceling.<br>
  43. * Transformation skill learning and transformation scroll sell.
  44. * @author Zoey76
  45. */
  46. public class AvantGarde extends AbstractNpcAI
  47. {
  48. // NPC
  49. private static final int AVANT_GARDE = 32323;
  50. // Items
  51. // @formatter:off
  52. private static final int[] ITEMS =
  53. {
  54. 10280, 10281, 10282, 10283, 10284, 10285, 10286, 10287, 10288, 10289, 10290, 10291, 10292, 10293, 10294, 10612
  55. };
  56. // @formatter:on
  57. // Misc
  58. private static final String[] QUEST_VAR_NAMES =
  59. {
  60. "EmergentAbility65-",
  61. "EmergentAbility70-",
  62. "ClassAbility75-",
  63. "ClassAbility80-"
  64. };
  65. public AvantGarde()
  66. {
  67. super(AvantGarde.class.getSimpleName(), "ai/npc");
  68. addStartNpc(AVANT_GARDE);
  69. addTalkId(AVANT_GARDE);
  70. addFirstTalkId(AVANT_GARDE);
  71. addAcquireSkillId(AVANT_GARDE);
  72. }
  73. @Override
  74. public String onAcquireSkill(L2Npc npc, L2PcInstance player, Skill skill, AcquireSkillType type)
  75. {
  76. switch (type)
  77. {
  78. case TRANSFORM:
  79. {
  80. showTransformSkillList(player);
  81. break;
  82. }
  83. case SUBCLASS:
  84. {
  85. showSubClassSkillList(player);
  86. break;
  87. }
  88. }
  89. return null;
  90. }
  91. @Override
  92. public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  93. {
  94. String htmltext = null;
  95. switch (event)
  96. {
  97. case "32323-02.html":
  98. case "32323-02a.html":
  99. case "32323-02b.html":
  100. case "32323-02c.html":
  101. case "32323-05.html":
  102. case "32323-05a.html":
  103. case "32323-05no.html":
  104. case "32323-06.html":
  105. case "32323-06no.html":
  106. {
  107. htmltext = event;
  108. break;
  109. }
  110. case "LearnTransformationSkill":
  111. {
  112. if (RequestAcquireSkill.canTransform(player))
  113. {
  114. showTransformSkillList(player);
  115. }
  116. else
  117. {
  118. htmltext = "32323-03.html";
  119. }
  120. break;
  121. }
  122. case "BuyTransformationItems":
  123. {
  124. if (RequestAcquireSkill.canTransform(player))
  125. {
  126. MultisellData.getInstance().separateAndSend(32323001, player, npc, false);
  127. }
  128. else
  129. {
  130. htmltext = "32323-04.html";
  131. }
  132. break;
  133. }
  134. case "LearnSubClassSkill":
  135. {
  136. if (!RequestAcquireSkill.canTransform(player))
  137. {
  138. htmltext = "32323-04.html";
  139. }
  140. if (player.isSubClassActive())
  141. {
  142. htmltext = "32323-08.html";
  143. }
  144. else
  145. {
  146. boolean hasItems = false;
  147. for (int id : ITEMS)
  148. {
  149. if (player.getInventory().getItemByItemId(id) != null)
  150. {
  151. hasItems = true;
  152. break;
  153. }
  154. }
  155. if (hasItems)
  156. {
  157. showSubClassSkillList(player);
  158. }
  159. else
  160. {
  161. htmltext = "32323-08.html";
  162. }
  163. }
  164. break;
  165. }
  166. case "CancelCertification":
  167. {
  168. if (player.getSubClasses().size() == 0)
  169. {
  170. htmltext = "32323-07.html";
  171. }
  172. else if (player.isSubClassActive())
  173. {
  174. htmltext = "32323-08.html";
  175. }
  176. else if (player.getAdena() < Config.FEE_DELETE_SUBCLASS_SKILLS)
  177. {
  178. htmltext = "32323-08no.html";
  179. }
  180. else
  181. {
  182. QuestState st = player.getQuestState(SubClassSkills.class.getSimpleName());
  183. if (st == null)
  184. {
  185. st = QuestManager.getInstance().getQuest(SubClassSkills.class.getSimpleName()).newQuestState(player);
  186. }
  187. int activeCertifications = 0;
  188. for (String varName : QUEST_VAR_NAMES)
  189. {
  190. for (int i = 1; i <= Config.MAX_SUBCLASS; i++)
  191. {
  192. String qvar = st.getGlobalQuestVar(varName + i);
  193. if (!qvar.isEmpty() && (qvar.endsWith(";") || !qvar.equals("0")))
  194. {
  195. activeCertifications++;
  196. }
  197. }
  198. }
  199. if (activeCertifications == 0)
  200. {
  201. htmltext = "32323-10no.html";
  202. }
  203. else
  204. {
  205. for (String varName : QUEST_VAR_NAMES)
  206. {
  207. for (int i = 1; i <= Config.MAX_SUBCLASS; i++)
  208. {
  209. final String qvarName = varName + i;
  210. final String qvar = st.getGlobalQuestVar(qvarName);
  211. if (qvar.endsWith(";"))
  212. {
  213. final String skillIdVar = qvar.replace(";", "");
  214. if (Util.isDigit(skillIdVar))
  215. {
  216. int skillId = Integer.parseInt(skillIdVar);
  217. final Skill sk = SkillData.getInstance().getSkill(skillId, 1);
  218. if (sk != null)
  219. {
  220. player.removeSkill(sk);
  221. st.saveGlobalQuestVar(qvarName, "0");
  222. }
  223. }
  224. else
  225. {
  226. _log.warning("Invalid Sub-Class Skill Id: " + skillIdVar + " for player " + player.getName() + "!");
  227. }
  228. }
  229. else if (!qvar.isEmpty() && !qvar.equals("0"))
  230. {
  231. if (Util.isDigit(qvar))
  232. {
  233. final int itemObjId = Integer.parseInt(qvar);
  234. L2ItemInstance itemInstance = player.getInventory().getItemByObjectId(itemObjId);
  235. if (itemInstance != null)
  236. {
  237. player.destroyItem("CancelCertification", itemObjId, 1, player, false);
  238. }
  239. else
  240. {
  241. itemInstance = player.getWarehouse().getItemByObjectId(itemObjId);
  242. if (itemInstance != null)
  243. {
  244. _log.warning("Somehow " + player.getName() + " put a certification book into warehouse!");
  245. player.getWarehouse().destroyItem("CancelCertification", itemInstance, 1, player, false);
  246. }
  247. else
  248. {
  249. _log.warning("Somehow " + player.getName() + " deleted a certification book!");
  250. }
  251. }
  252. st.saveGlobalQuestVar(qvarName, "0");
  253. }
  254. else
  255. {
  256. _log.warning("Invalid item object Id: " + qvar + " for player " + player.getName() + "!");
  257. }
  258. }
  259. }
  260. }
  261. player.reduceAdena("Cleanse", Config.FEE_DELETE_SUBCLASS_SKILLS, npc, true);
  262. htmltext = "32323-09no.html";
  263. player.sendSkillList();
  264. }
  265. // Let's consume all certification books, even those not present in database.
  266. for (int itemId : ITEMS)
  267. {
  268. L2ItemInstance item = player.getInventory().getItemByItemId(itemId);
  269. if (item != null)
  270. {
  271. _log.warning(getClass().getName() + ": player " + player + " had 'extra' certification skill books while cancelling sub-class certifications!");
  272. player.destroyItem("CancelCertificationExtraBooks", item, npc, false);
  273. }
  274. }
  275. }
  276. break;
  277. }
  278. }
  279. return htmltext;
  280. }
  281. @Override
  282. public String onFirstTalk(L2Npc npc, L2PcInstance player)
  283. {
  284. return "32323-01.html";
  285. }
  286. @Override
  287. public String onTalk(L2Npc npc, L2PcInstance talker)
  288. {
  289. return "32323-01.html";
  290. }
  291. /**
  292. * Display the Sub-Class Skill list to the player.
  293. * @param player the player
  294. */
  295. public static void showSubClassSkillList(L2PcInstance player)
  296. {
  297. final List<L2SkillLearn> subClassSkills = SkillTreesData.getInstance().getAvailableSubClassSkills(player);
  298. final AcquireSkillList asl = new AcquireSkillList(AcquireSkillType.SUBCLASS);
  299. int count = 0;
  300. for (L2SkillLearn s : subClassSkills)
  301. {
  302. if (SkillData.getInstance().getSkill(s.getSkillId(), s.getSkillLevel()) != null)
  303. {
  304. count++;
  305. asl.addSkill(s.getSkillId(), s.getSkillLevel(), s.getSkillLevel(), 0, 0);
  306. }
  307. }
  308. if (count > 0)
  309. {
  310. player.sendPacket(asl);
  311. }
  312. else
  313. {
  314. player.sendPacket(SystemMessageId.NO_MORE_SKILLS_TO_LEARN);
  315. }
  316. }
  317. /**
  318. * This displays Transformation Skill List to the player.
  319. * @param player the active character.
  320. */
  321. public static void showTransformSkillList(L2PcInstance player)
  322. {
  323. final List<L2SkillLearn> skills = SkillTreesData.getInstance().getAvailableTransformSkills(player);
  324. final AcquireSkillList asl = new AcquireSkillList(AcquireSkillType.TRANSFORM);
  325. int counts = 0;
  326. for (L2SkillLearn s : skills)
  327. {
  328. if (SkillData.getInstance().getSkill(s.getSkillId(), s.getSkillLevel()) != null)
  329. {
  330. counts++;
  331. asl.addSkill(s.getSkillId(), s.getSkillLevel(), s.getSkillLevel(), s.getLevelUpSp(), 0);
  332. }
  333. }
  334. if (counts == 0)
  335. {
  336. final int minlevel = SkillTreesData.getInstance().getMinLevelForNewSkill(player, SkillTreesData.getInstance().getTransformSkillTree());
  337. if (minlevel > 0)
  338. {
  339. // No more skills to learn, come back when you level.
  340. final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.DO_NOT_HAVE_FURTHER_SKILLS_TO_LEARN_S1);
  341. sm.addInt(minlevel);
  342. player.sendPacket(sm);
  343. }
  344. else
  345. {
  346. player.sendPacket(SystemMessageId.NO_MORE_SKILLS_TO_LEARN);
  347. }
  348. }
  349. else
  350. {
  351. player.sendPacket(asl);
  352. }
  353. }
  354. public static void main(String[] args)
  355. {
  356. new AvantGarde();
  357. }
  358. }