PailakaSongOfIceAndFire.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  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 instances.Pailaka;
  16. import com.l2jserver.gameserver.ThreadPoolManager;
  17. import com.l2jserver.gameserver.ai.CtrlIntention;
  18. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  19. import com.l2jserver.gameserver.instancemanager.InstanceManager.InstanceWorld;
  20. import com.l2jserver.gameserver.model.actor.L2Character;
  21. import com.l2jserver.gameserver.model.actor.L2Npc;
  22. import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
  23. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  24. import com.l2jserver.gameserver.model.entity.Instance;
  25. import com.l2jserver.gameserver.model.quest.Quest;
  26. import com.l2jserver.gameserver.model.quest.QuestState;
  27. import com.l2jserver.gameserver.model.quest.State;
  28. import com.l2jserver.gameserver.model.zone.L2ZoneType;
  29. import com.l2jserver.gameserver.network.SystemMessageId;
  30. public class PailakaSongOfIceAndFire extends Quest
  31. {
  32. private static final String qn = "128_PailakaSongOfIceAndFire";
  33. private static final int MIN_LEVEL = 36;
  34. private static final int MAX_LEVEL = 42;
  35. private static final int EXIT_TIME = 5;
  36. private static final int INSTANCE_ID = 43;
  37. protected static final int[] TELEPORT =
  38. {
  39. -52875,
  40. 188232,
  41. -4696
  42. };
  43. private static final int ZONE = 20108;
  44. private static final int ADLER1 = 32497;
  45. private static final int ADLER2 = 32510;
  46. private static final int SINAI = 32500;
  47. private static final int INSPECTOR = 32507;
  48. private static final int[] NPCS =
  49. {
  50. ADLER1,
  51. ADLER2,
  52. SINAI,
  53. INSPECTOR
  54. };
  55. private static final int HILLAS = 18610;
  56. private static final int PAPION = 18609;
  57. private static final int KINSUS = 18608;
  58. private static final int GARGOS = 18607;
  59. private static final int ADIANTUM = 18620;
  60. private static final int BLOOM = 18616;
  61. private static final int BOTTLE = 32492;
  62. private static final int BRAZIER = 32493;
  63. private static final int[] MONSTERS =
  64. {
  65. HILLAS,
  66. PAPION,
  67. KINSUS,
  68. GARGOS,
  69. ADIANTUM,
  70. BLOOM,
  71. BOTTLE,
  72. BRAZIER,
  73. 18611,
  74. 18612,
  75. 18613,
  76. 18614,
  77. 18615
  78. };
  79. private static final int SWORD = 13034;
  80. private static final int ENH_SWORD1 = 13035;
  81. private static final int ENH_SWORD2 = 13036;
  82. private static final int BOOK1 = 13130;
  83. private static final int BOOK2 = 13131;
  84. private static final int BOOK3 = 13132;
  85. private static final int BOOK4 = 13133;
  86. private static final int BOOK5 = 13134;
  87. private static final int BOOK6 = 13135;
  88. private static final int BOOK7 = 13136;
  89. private static final int WATER_ESSENCE = 13038;
  90. private static final int FIRE_ESSENCE = 13039;
  91. private static final int SHIELD_POTION = 13032;
  92. private static final int HEAL_POTION = 13033;
  93. private static final int FIRE_ENHANCER = 13040;
  94. private static final int WATER_ENHANCER = 13041;
  95. private static final int[] ITEMS =
  96. {
  97. SWORD,
  98. ENH_SWORD1,
  99. ENH_SWORD2,
  100. BOOK1,
  101. BOOK2,
  102. BOOK3,
  103. BOOK4,
  104. BOOK5,
  105. BOOK6,
  106. BOOK7,
  107. WATER_ESSENCE,
  108. FIRE_ESSENCE,
  109. SHIELD_POTION,
  110. HEAL_POTION,
  111. FIRE_ENHANCER,
  112. WATER_ENHANCER
  113. };
  114. // @formatter:off
  115. private static final int[][] DROPLIST =
  116. {
  117. // must be sorted by npcId !
  118. // npcId, itemId, chance
  119. {
  120. BLOOM, SHIELD_POTION, 30
  121. },
  122. {
  123. BLOOM, HEAL_POTION, 80
  124. },
  125. {
  126. BOTTLE, SHIELD_POTION, 10
  127. },
  128. {
  129. BOTTLE, WATER_ENHANCER, 40
  130. },
  131. {
  132. BOTTLE, HEAL_POTION, 80
  133. },
  134. {
  135. BRAZIER, SHIELD_POTION, 10
  136. },
  137. {
  138. BRAZIER, FIRE_ENHANCER, 40
  139. },
  140. {
  141. BRAZIER, HEAL_POTION, 80
  142. }
  143. };
  144. /**
  145. * itemId, count, chance
  146. */
  147. private static final int[][] HP_HERBS_DROPLIST =
  148. {
  149. {
  150. 8602, 1, 10
  151. },
  152. {
  153. 8601, 1, 40
  154. },
  155. {
  156. 8600, 1, 70
  157. }
  158. };
  159. /**
  160. * itemId, count, chance
  161. */
  162. private static final int[][] MP_HERBS_DROPLIST =
  163. {
  164. {
  165. 8605, 1, 10
  166. },
  167. {
  168. 8604, 1, 40
  169. },
  170. {
  171. 8603, 1, 70
  172. }
  173. };
  174. // @formatter:on
  175. private static final int[] REWARDS =
  176. {
  177. 13294,
  178. 13293,
  179. 13129
  180. };
  181. private static final void dropHerb(L2Npc mob, L2PcInstance player, int[][] drop)
  182. {
  183. final int chance = getRandom(100);
  184. for (int[] element : drop)
  185. {
  186. if (chance < element[2])
  187. {
  188. ((L2MonsterInstance) mob).dropItem(player, element[0], element[1]);
  189. return;
  190. }
  191. }
  192. }
  193. private static final void dropItem(L2Npc mob, L2PcInstance player)
  194. {
  195. final int npcId = mob.getNpcId();
  196. final int chance = getRandom(100);
  197. for (int[] drop : DROPLIST)
  198. {
  199. if (npcId == drop[0])
  200. {
  201. if (chance < drop[2])
  202. {
  203. ((L2MonsterInstance) mob).dropItem(player, drop[1], getRandom(1, 6));
  204. return;
  205. }
  206. }
  207. if (npcId < drop[0])
  208. {
  209. return; // not found
  210. }
  211. }
  212. }
  213. protected static final void teleportPlayer(L2PcInstance player, int[] coords, int instanceId)
  214. {
  215. player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  216. player.setInstanceId(instanceId);
  217. player.teleToLocation(coords[0], coords[1], coords[2], true);
  218. }
  219. private final synchronized void enterInstance(L2PcInstance player)
  220. {
  221. // check for existing instances for this player
  222. InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
  223. if (world != null)
  224. {
  225. if (world.templateId != INSTANCE_ID)
  226. {
  227. player.sendPacket(SystemMessageId.ALREADY_ENTERED_ANOTHER_INSTANCE_CANT_ENTER);
  228. return;
  229. }
  230. Instance inst = InstanceManager.getInstance().getInstance(world.instanceId);
  231. if (inst != null)
  232. {
  233. teleportPlayer(player, TELEPORT, world.instanceId);
  234. }
  235. return;
  236. }
  237. // New instance
  238. final int instanceId = InstanceManager.getInstance().createDynamicInstance("PailakaSongOfIceAndFire.xml");
  239. world = new InstanceWorld();
  240. world.instanceId = instanceId;
  241. world.templateId = INSTANCE_ID;
  242. InstanceManager.getInstance().addWorld(world);
  243. world.allowed.add(player.getObjectId());
  244. teleportPlayer(player, TELEPORT, instanceId);
  245. }
  246. @Override
  247. public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  248. {
  249. final QuestState st = player.getQuestState(qn);
  250. if (st == null)
  251. {
  252. return getNoQuestMsg(player);
  253. }
  254. final int cond = st.getInt("cond");
  255. if (event.equalsIgnoreCase("enter"))
  256. {
  257. enterInstance(player);
  258. return null;
  259. }
  260. else if (event.equalsIgnoreCase("32497-03.htm"))
  261. {
  262. if (cond == 0)
  263. {
  264. st.set("cond", "1");
  265. st.setState(State.STARTED);
  266. st.playSound("ItemSound.quest_accept");
  267. }
  268. }
  269. else if (event.equalsIgnoreCase("32500-06.htm"))
  270. {
  271. if (cond == 1)
  272. {
  273. st.set("cond", "2");
  274. st.playSound("ItemSound.quest_itemget");
  275. st.giveItems(SWORD, 1);
  276. st.giveItems(BOOK1, 1);
  277. }
  278. }
  279. else if (event.equalsIgnoreCase("32507-04.htm"))
  280. {
  281. if (cond == 3)
  282. {
  283. st.set("cond", "4");
  284. st.playSound("ItemSound.quest_middle");
  285. st.takeItems(SWORD, -1);
  286. st.takeItems(WATER_ESSENCE, -1);
  287. st.takeItems(BOOK2, -1);
  288. st.giveItems(BOOK3, 1);
  289. st.giveItems(ENH_SWORD1, 1);
  290. }
  291. }
  292. else if (event.equalsIgnoreCase("32507-08.htm"))
  293. {
  294. if (cond == 6)
  295. {
  296. st.set("cond", "7");
  297. st.playSound("ItemSound.quest_itemget");
  298. st.takeItems(ENH_SWORD1, -1);
  299. st.takeItems(BOOK5, -1);
  300. st.takeItems(FIRE_ESSENCE, -1);
  301. st.giveItems(ENH_SWORD2, 1);
  302. st.giveItems(BOOK6, 1);
  303. }
  304. }
  305. else if (event.equalsIgnoreCase("32510-02.htm"))
  306. {
  307. st.unset("cond");
  308. st.playSound("ItemSound.quest_finish");
  309. st.exitQuest(false);
  310. Instance inst = InstanceManager.getInstance().getInstance(npc.getInstanceId());
  311. inst.setDuration(EXIT_TIME * 60000);
  312. inst.setEmptyDestroyTime(0);
  313. if (inst.containsPlayer(player.getObjectId()))
  314. {
  315. player.setVitalityPoints(20000, true);
  316. st.addExpAndSp(810000, 50000);
  317. for (int id : REWARDS)
  318. {
  319. st.giveItems(id, 1);
  320. }
  321. }
  322. }
  323. return event;
  324. }
  325. @Override
  326. public final String onFirstTalk(L2Npc npc, L2PcInstance player)
  327. {
  328. return npc.getNpcId() + ".htm";
  329. }
  330. @Override
  331. public final String onTalk(L2Npc npc, L2PcInstance player)
  332. {
  333. final QuestState st = player.getQuestState(qn);
  334. if (st == null)
  335. {
  336. return getNoQuestMsg(player);
  337. }
  338. final int cond = st.getInt("cond");
  339. switch (npc.getNpcId())
  340. {
  341. case ADLER1:
  342. switch (st.getState())
  343. {
  344. case State.CREATED:
  345. if (player.getLevel() < MIN_LEVEL)
  346. {
  347. return "32497-05.htm";
  348. }
  349. if (player.getLevel() > MAX_LEVEL)
  350. {
  351. return "32497-06.htm";
  352. }
  353. return "32497-01.htm";
  354. case State.STARTED:
  355. if (cond > 1)
  356. {
  357. return "32497-00.htm";
  358. }
  359. return "32497-03.htm";
  360. case State.COMPLETED:
  361. return "32497-07.htm";
  362. default:
  363. return "32497-01.htm";
  364. }
  365. case SINAI:
  366. if (cond > 1)
  367. {
  368. return "32500-00.htm";
  369. }
  370. return "32500-01.htm";
  371. case INSPECTOR:
  372. switch (st.getInt("cond"))
  373. {
  374. case 1:
  375. return "32507-01.htm";
  376. case 2:
  377. return "32507-02.htm";
  378. case 3:
  379. return "32507-03.htm";
  380. case 4:
  381. case 5:
  382. return "32507-05.htm";
  383. case 6:
  384. return "32507-06.htm";
  385. default:
  386. return "32507-09.htm";
  387. }
  388. case ADLER2:
  389. if (st.getState() == State.COMPLETED)
  390. {
  391. return "32510-00.htm";
  392. }
  393. else if (cond == 9)
  394. {
  395. return "32510-01.htm";
  396. }
  397. }
  398. return getNoQuestMsg(player);
  399. }
  400. @Override
  401. public final String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isPet)
  402. {
  403. if (!npc.isDead())
  404. {
  405. npc.doDie(attacker);
  406. }
  407. return super.onAttack(npc, attacker, damage, isPet);
  408. }
  409. @Override
  410. public final String onKill(L2Npc npc, L2PcInstance player, boolean isPet)
  411. {
  412. QuestState st = player.getQuestState(qn);
  413. if ((st == null) || (st.getState() != State.STARTED))
  414. {
  415. return null;
  416. }
  417. final int cond = st.getInt("cond");
  418. switch (npc.getNpcId())
  419. {
  420. case HILLAS:
  421. if (cond == 2)
  422. {
  423. st.set("cond", "3");
  424. st.playSound("ItemSound.quest_itemget");
  425. st.takeItems(BOOK1, -1);
  426. st.giveItems(BOOK2, 1);
  427. st.giveItems(WATER_ESSENCE, 1);
  428. }
  429. addSpawn(PAPION, -53903, 181484, -4555, 30456, false, 0, false, npc.getInstanceId());
  430. break;
  431. case PAPION:
  432. if (cond == 4)
  433. {
  434. st.takeItems(BOOK3, -1);
  435. st.giveItems(BOOK4, 1);
  436. st.set("cond", "5");
  437. st.playSound("ItemSound.quest_itemget");
  438. }
  439. addSpawn(KINSUS, -61415, 181418, -4818, 63852, false, 0, false, npc.getInstanceId());
  440. break;
  441. case KINSUS:
  442. if (cond == 5)
  443. {
  444. st.set("cond", "6");
  445. st.playSound("ItemSound.quest_itemget");
  446. st.takeItems(BOOK4, -1);
  447. st.giveItems(BOOK5, 1);
  448. st.giveItems(FIRE_ESSENCE, 1);
  449. }
  450. addSpawn(GARGOS, -61354, 183624, -4821, 63613, false, 0, false, npc.getInstanceId());
  451. break;
  452. case GARGOS:
  453. if (cond == 7)
  454. {
  455. st.set("cond", "8");
  456. st.playSound("ItemSound.quest_itemget");
  457. st.takeItems(BOOK6, -1);
  458. st.giveItems(BOOK7, 1);
  459. }
  460. addSpawn(ADIANTUM, -53297, 185027, -4617, 1512, false, 0, false, npc.getInstanceId());
  461. break;
  462. case ADIANTUM:
  463. if (cond == 8)
  464. {
  465. st.set("cond", "9");
  466. st.playSound("ItemSound.quest_middle");
  467. st.takeItems(BOOK7, -1);
  468. addSpawn(ADLER2, -53297, 185027, -4617, 33486, false, 0, false, npc.getInstanceId());
  469. }
  470. break;
  471. case BOTTLE:
  472. case BRAZIER:
  473. case BLOOM:
  474. dropItem(npc, player);
  475. break;
  476. default:
  477. // hardcoded herb drops
  478. dropHerb(npc, player, HP_HERBS_DROPLIST);
  479. dropHerb(npc, player, MP_HERBS_DROPLIST);
  480. break;
  481. }
  482. return super.onKill(npc, player, isPet);
  483. }
  484. @Override
  485. public String onExitZone(L2Character character, L2ZoneType zone)
  486. {
  487. if ((character instanceof L2PcInstance) && !character.isDead() && !character.isTeleporting() && ((L2PcInstance) character).isOnline())
  488. {
  489. InstanceWorld world = InstanceManager.getInstance().getWorld(character.getInstanceId());
  490. if ((world != null) && (world.templateId == INSTANCE_ID))
  491. {
  492. ThreadPoolManager.getInstance().scheduleGeneral(new Teleport(character, world.instanceId), 1000);
  493. }
  494. }
  495. return super.onExitZone(character, zone);
  496. }
  497. static final class Teleport implements Runnable
  498. {
  499. private final L2Character _char;
  500. private final int _instanceId;
  501. public Teleport(L2Character c, int id)
  502. {
  503. _char = c;
  504. _instanceId = id;
  505. }
  506. @Override
  507. public void run()
  508. {
  509. try
  510. {
  511. teleportPlayer((L2PcInstance) _char, TELEPORT, _instanceId);
  512. }
  513. catch (Exception e)
  514. {
  515. e.printStackTrace();
  516. }
  517. }
  518. }
  519. public PailakaSongOfIceAndFire(int questId, String name, String descr)
  520. {
  521. super(questId, name, descr);
  522. addStartNpc(ADLER1);
  523. for (int npcId : NPCS)
  524. {
  525. addFirstTalkId(npcId);
  526. addTalkId(npcId);
  527. }
  528. addAttackId(BOTTLE);
  529. addAttackId(BRAZIER);
  530. for (int mobId : MONSTERS)
  531. {
  532. addKillId(mobId);
  533. }
  534. addExitZoneId(ZONE);
  535. questItemIds = ITEMS;
  536. }
  537. public static void main(String[] args)
  538. {
  539. new PailakaSongOfIceAndFire(128, qn, "Pailaka - Song of Ice and Fire");
  540. }
  541. }