Kamaloka.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728
  1. /*
  2. * Copyright (C) 2004-2014 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 instances.Kamaloka;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.Calendar;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.function.Function;
  26. import java.util.logging.Level;
  27. import com.l2jserver.gameserver.datatables.SkillData;
  28. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  29. import com.l2jserver.gameserver.model.L2Party;
  30. import com.l2jserver.gameserver.model.L2Spawn;
  31. import com.l2jserver.gameserver.model.L2World;
  32. import com.l2jserver.gameserver.model.Location;
  33. import com.l2jserver.gameserver.model.actor.L2Character;
  34. import com.l2jserver.gameserver.model.actor.L2Npc;
  35. import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
  36. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  37. import com.l2jserver.gameserver.model.entity.Instance;
  38. import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
  39. import com.l2jserver.gameserver.model.quest.Quest;
  40. import com.l2jserver.gameserver.model.skills.BuffInfo;
  41. import com.l2jserver.gameserver.model.skills.Skill;
  42. import com.l2jserver.gameserver.network.SystemMessageId;
  43. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  44. public final class Kamaloka extends Quest
  45. {
  46. /*
  47. * Reset time for all kamaloka Default: 6:30AM on server time
  48. */
  49. private static final int RESET_HOUR = 6;
  50. private static final int RESET_MIN = 30;
  51. /*
  52. * Time after which instance without players will be destroyed Default: 5 minutes
  53. */
  54. private static final int EMPTY_DESTROY_TIME = 5;
  55. /*
  56. * Time to destroy instance (and eject players away) after boss defeat Default: 5 minutes
  57. */
  58. private static final int EXIT_TIME = 5;
  59. /*
  60. * Maximum level difference between players level and kamaloka level Default: 5
  61. */
  62. private static final int MAX_LEVEL_DIFFERENCE = 5;
  63. /*
  64. * If true shaman in the first room will have same npcId as other mobs, making radar useless Default: true (but not retail like)
  65. */
  66. private static final boolean STEALTH_SHAMAN = true;
  67. // Template IDs for Kamaloka
  68. // @formatter:off
  69. private static final int[] TEMPLATE_IDS =
  70. {
  71. 57, 58, 73, 60, 61, 74, 63, 64, 75, 66, 67, 76, 69, 70, 77, 72, 78, 79, 134
  72. };
  73. // Level of the Kamaloka
  74. private static final int[] LEVEL =
  75. {
  76. 23, 26, 29, 33, 36, 39, 43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 78, 81, 83
  77. };
  78. // Duration of the instance, minutes
  79. private static final int[] DURATION =
  80. {
  81. 30, 30, 45, 30, 30, 45, 30, 30, 45, 30, 30, 45, 30, 30, 45, 30, 45, 45, 45
  82. };
  83. // Maximum party size for the instance
  84. private static final int[] MAX_PARTY_SIZE =
  85. {
  86. 6, 6, 9, 6, 6, 9, 6, 6, 9, 6, 6, 9, 6, 6, 9, 6, 9, 9, 9
  87. };
  88. /**
  89. * List of buffs NOT removed on enter from player and pet<br>
  90. * On retail only newbie guide buffs not removed<br>
  91. * CAUTION: array must be sorted in ascension order!
  92. */
  93. protected static final int[] BUFFS_WHITELIST =
  94. {
  95. 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, 5632, 5637, 5950
  96. };
  97. // @formatter:on
  98. // Teleport points into instances x, y, z
  99. private static final Location[] TELEPORTS =
  100. {
  101. new Location(-88429, -220629, -7903),
  102. new Location(-82464, -219532, -7899),
  103. new Location(-10700, -174882, -10936), // -76280, -185540, -10936
  104. new Location(-89683, -213573, -8106),
  105. new Location(-81413, -213568, -8104),
  106. new Location(-10700, -174882, -10936), // -76280, -174905, -10936
  107. new Location(-89759, -206143, -8120),
  108. new Location(-81415, -206078, -8107),
  109. new Location(-10700, -174882, -10936),
  110. new Location(-56999, -219856, -8117),
  111. new Location(-48794, -220261, -8075),
  112. new Location(-10700, -174882, -10936),
  113. new Location(-56940, -212939, -8072),
  114. new Location(-55566, -206139, -8120),
  115. new Location(-10700, -174882, -10936),
  116. new Location(-49805, -206139, -8117),
  117. new Location(-10700, -174882, -10936),
  118. new Location(-10700, -174882, -10936),
  119. new Location(22003, -174886, -10900),
  120. };
  121. // Respawn delay for the mobs in the first room, seconds Default: 25
  122. private static final int FIRST_ROOM_RESPAWN_DELAY = 25;
  123. /**
  124. * First room information, null if room not spawned.<br>
  125. * Skill is casted on the boss when shaman is defeated and mobs respawn stopped<br>
  126. * Default: 5699 (decrease pdef)<br>
  127. * shaman npcId, minions npcId, skillId, skillLvl
  128. */
  129. private static final int[][] FIRST_ROOM =
  130. {
  131. null,
  132. null,
  133. {
  134. 22485,
  135. 22486,
  136. 5699,
  137. 1
  138. },
  139. null,
  140. null,
  141. {
  142. 22488,
  143. 22489,
  144. 5699,
  145. 2
  146. },
  147. null,
  148. null,
  149. {
  150. 22491,
  151. 22492,
  152. 5699,
  153. 3
  154. },
  155. null,
  156. null,
  157. {
  158. 22494,
  159. 22495,
  160. 5699,
  161. 4
  162. },
  163. null,
  164. null,
  165. {
  166. 22497,
  167. 22498,
  168. 5699,
  169. 5
  170. },
  171. null,
  172. {
  173. 22500,
  174. 22501,
  175. 5699,
  176. 6
  177. },
  178. {
  179. 22503,
  180. 22504,
  181. 5699,
  182. 7
  183. },
  184. {
  185. 25706,
  186. 25707,
  187. 5699,
  188. 7
  189. }
  190. };
  191. /*
  192. * First room spawns, null if room not spawned x, y, z
  193. */
  194. private static final int[][][] FIRST_ROOM_SPAWNS =
  195. {
  196. null,
  197. null,
  198. {
  199. {
  200. -12381,
  201. -174973,
  202. -10955
  203. },
  204. {
  205. -12413,
  206. -174905,
  207. -10955
  208. },
  209. {
  210. -12377,
  211. -174838,
  212. -10953
  213. },
  214. {
  215. -12316,
  216. -174903,
  217. -10953
  218. },
  219. {
  220. -12326,
  221. -174786,
  222. -10953
  223. },
  224. {
  225. -12330,
  226. -175024,
  227. -10953
  228. },
  229. {
  230. -12211,
  231. -174900,
  232. -10955
  233. },
  234. {
  235. -12238,
  236. -174849,
  237. -10953
  238. },
  239. {
  240. -12233,
  241. -174954,
  242. -10953
  243. }
  244. },
  245. null,
  246. null,
  247. {
  248. {
  249. -12381,
  250. -174973,
  251. -10955
  252. },
  253. {
  254. -12413,
  255. -174905,
  256. -10955
  257. },
  258. {
  259. -12377,
  260. -174838,
  261. -10953
  262. },
  263. {
  264. -12316,
  265. -174903,
  266. -10953
  267. },
  268. {
  269. -12326,
  270. -174786,
  271. -10953
  272. },
  273. {
  274. -12330,
  275. -175024,
  276. -10953
  277. },
  278. {
  279. -12211,
  280. -174900,
  281. -10955
  282. },
  283. {
  284. -12238,
  285. -174849,
  286. -10953
  287. },
  288. {
  289. -12233,
  290. -174954,
  291. -10953
  292. }
  293. },
  294. null,
  295. null,
  296. {
  297. {
  298. -12381,
  299. -174973,
  300. -10955
  301. },
  302. {
  303. -12413,
  304. -174905,
  305. -10955
  306. },
  307. {
  308. -12377,
  309. -174838,
  310. -10953
  311. },
  312. {
  313. -12316,
  314. -174903,
  315. -10953
  316. },
  317. {
  318. -12326,
  319. -174786,
  320. -10953
  321. },
  322. {
  323. -12330,
  324. -175024,
  325. -10953
  326. },
  327. {
  328. -12211,
  329. -174900,
  330. -10955
  331. },
  332. {
  333. -12238,
  334. -174849,
  335. -10953
  336. },
  337. {
  338. -12233,
  339. -174954,
  340. -10953
  341. }
  342. },
  343. null,
  344. null,
  345. {
  346. {
  347. -12381,
  348. -174973,
  349. -10955
  350. },
  351. {
  352. -12413,
  353. -174905,
  354. -10955
  355. },
  356. {
  357. -12377,
  358. -174838,
  359. -10953
  360. },
  361. {
  362. -12316,
  363. -174903,
  364. -10953
  365. },
  366. {
  367. -12326,
  368. -174786,
  369. -10953
  370. },
  371. {
  372. -12330,
  373. -175024,
  374. -10953
  375. },
  376. {
  377. -12211,
  378. -174900,
  379. -10955
  380. },
  381. {
  382. -12238,
  383. -174849,
  384. -10953
  385. },
  386. {
  387. -12233,
  388. -174954,
  389. -10953
  390. }
  391. },
  392. null,
  393. null,
  394. {
  395. {
  396. -12381,
  397. -174973,
  398. -10955
  399. },
  400. {
  401. -12413,
  402. -174905,
  403. -10955
  404. },
  405. {
  406. -12377,
  407. -174838,
  408. -10953
  409. },
  410. {
  411. -12316,
  412. -174903,
  413. -10953
  414. },
  415. {
  416. -12326,
  417. -174786,
  418. -10953
  419. },
  420. {
  421. -12330,
  422. -175024,
  423. -10953
  424. },
  425. {
  426. -12211,
  427. -174900,
  428. -10955
  429. },
  430. {
  431. -12238,
  432. -174849,
  433. -10953
  434. },
  435. {
  436. -12233,
  437. -174954,
  438. -10953
  439. }
  440. },
  441. null,
  442. {
  443. {
  444. -12381,
  445. -174973,
  446. -10955
  447. },
  448. {
  449. -12413,
  450. -174905,
  451. -10955
  452. },
  453. {
  454. -12377,
  455. -174838,
  456. -10953
  457. },
  458. {
  459. -12316,
  460. -174903,
  461. -10953
  462. },
  463. {
  464. -12326,
  465. -174786,
  466. -10953
  467. },
  468. {
  469. -12330,
  470. -175024,
  471. -10953
  472. },
  473. {
  474. -12211,
  475. -174900,
  476. -10955
  477. },
  478. {
  479. -12238,
  480. -174849,
  481. -10953
  482. },
  483. {
  484. -12233,
  485. -174954,
  486. -10953
  487. }
  488. },
  489. {
  490. {
  491. -12381,
  492. -174973,
  493. -10955
  494. },
  495. {
  496. -12413,
  497. -174905,
  498. -10955
  499. },
  500. {
  501. -12377,
  502. -174838,
  503. -10953
  504. },
  505. {
  506. -12316,
  507. -174903,
  508. -10953
  509. },
  510. {
  511. -12326,
  512. -174786,
  513. -10953
  514. },
  515. {
  516. -12330,
  517. -175024,
  518. -10953
  519. },
  520. {
  521. -12211,
  522. -174900,
  523. -10955
  524. },
  525. {
  526. -12238,
  527. -174849,
  528. -10953
  529. },
  530. {
  531. -12233,
  532. -174954,
  533. -10953
  534. }
  535. },
  536. {
  537. {
  538. 20409,
  539. -174827,
  540. -10912
  541. },
  542. {
  543. 20409,
  544. -174947,
  545. -10912
  546. },
  547. {
  548. 20494,
  549. -174887,
  550. -10912
  551. },
  552. {
  553. 20494,
  554. -174767,
  555. -10912
  556. },
  557. {
  558. 20614,
  559. -174887,
  560. -10912
  561. },
  562. {
  563. 20579,
  564. -174827,
  565. -10912
  566. },
  567. {
  568. 20579,
  569. -174947,
  570. -10912
  571. },
  572. {
  573. 20494,
  574. -175007,
  575. -10912
  576. },
  577. {
  578. 20374,
  579. -174887,
  580. -10912
  581. }
  582. }
  583. };
  584. /*
  585. * Second room information, null if room not spawned Skill is casted on the boss when all mobs are defeated Default: 5700 (decrease mdef) npcId, skillId, skillLvl
  586. */
  587. private static final int[][] SECOND_ROOM =
  588. {
  589. null,
  590. null,
  591. {
  592. 22487,
  593. 5700,
  594. 1
  595. },
  596. null,
  597. null,
  598. {
  599. 22490,
  600. 5700,
  601. 2
  602. },
  603. null,
  604. null,
  605. {
  606. 22493,
  607. 5700,
  608. 3
  609. },
  610. null,
  611. null,
  612. {
  613. 22496,
  614. 5700,
  615. 4
  616. },
  617. null,
  618. null,
  619. {
  620. 22499,
  621. 5700,
  622. 5
  623. },
  624. null,
  625. {
  626. 22502,
  627. 5700,
  628. 6
  629. },
  630. {
  631. 22505,
  632. 5700,
  633. 7
  634. },
  635. {
  636. 25708,
  637. 5700,
  638. 7
  639. }
  640. };
  641. /*
  642. * Spawns for second room, null if room not spawned x, y, z
  643. */
  644. private static final int[][][] SECOND_ROOM_SPAWNS =
  645. {
  646. null,
  647. null,
  648. {
  649. {
  650. -14547,
  651. -174901,
  652. -10690
  653. },
  654. {
  655. -14543,
  656. -175030,
  657. -10690
  658. },
  659. {
  660. -14668,
  661. -174900,
  662. -10690
  663. },
  664. {
  665. -14538,
  666. -174774,
  667. -10690
  668. },
  669. {
  670. -14410,
  671. -174904,
  672. -10690
  673. }
  674. },
  675. null,
  676. null,
  677. {
  678. {
  679. -14547,
  680. -174901,
  681. -10690
  682. },
  683. {
  684. -14543,
  685. -175030,
  686. -10690
  687. },
  688. {
  689. -14668,
  690. -174900,
  691. -10690
  692. },
  693. {
  694. -14538,
  695. -174774,
  696. -10690
  697. },
  698. {
  699. -14410,
  700. -174904,
  701. -10690
  702. }
  703. },
  704. null,
  705. null,
  706. {
  707. {
  708. -14547,
  709. -174901,
  710. -10690
  711. },
  712. {
  713. -14543,
  714. -175030,
  715. -10690
  716. },
  717. {
  718. -14668,
  719. -174900,
  720. -10690
  721. },
  722. {
  723. -14538,
  724. -174774,
  725. -10690
  726. },
  727. {
  728. -14410,
  729. -174904,
  730. -10690
  731. }
  732. },
  733. null,
  734. null,
  735. {
  736. {
  737. -14547,
  738. -174901,
  739. -10690
  740. },
  741. {
  742. -14543,
  743. -175030,
  744. -10690
  745. },
  746. {
  747. -14668,
  748. -174900,
  749. -10690
  750. },
  751. {
  752. -14538,
  753. -174774,
  754. -10690
  755. },
  756. {
  757. -14410,
  758. -174904,
  759. -10690
  760. }
  761. },
  762. null,
  763. null,
  764. {
  765. {
  766. -14547,
  767. -174901,
  768. -10690
  769. },
  770. {
  771. -14543,
  772. -175030,
  773. -10690
  774. },
  775. {
  776. -14668,
  777. -174900,
  778. -10690
  779. },
  780. {
  781. -14538,
  782. -174774,
  783. -10690
  784. },
  785. {
  786. -14410,
  787. -174904,
  788. -10690
  789. }
  790. },
  791. null,
  792. {
  793. {
  794. -14547,
  795. -174901,
  796. -10690
  797. },
  798. {
  799. -14543,
  800. -175030,
  801. -10690
  802. },
  803. {
  804. -14668,
  805. -174900,
  806. -10690
  807. },
  808. {
  809. -14538,
  810. -174774,
  811. -10690
  812. },
  813. {
  814. -14410,
  815. -174904,
  816. -10690
  817. }
  818. },
  819. {
  820. {
  821. -14547,
  822. -174901,
  823. -10690
  824. },
  825. {
  826. -14543,
  827. -175030,
  828. -10690
  829. },
  830. {
  831. -14668,
  832. -174900,
  833. -10690
  834. },
  835. {
  836. -14538,
  837. -174774,
  838. -10690
  839. },
  840. {
  841. -14410,
  842. -174904,
  843. -10690
  844. }
  845. },
  846. {
  847. {
  848. 18175,
  849. -174991,
  850. -10653
  851. },
  852. {
  853. 18070,
  854. -174890,
  855. -10655
  856. },
  857. {
  858. 18157,
  859. -174886,
  860. -10655
  861. },
  862. {
  863. 18249,
  864. -174885,
  865. -10653
  866. },
  867. {
  868. 18144,
  869. -174821,
  870. -10648
  871. }
  872. }
  873. };
  874. // miniboss info
  875. // skill is casted on the boss when miniboss is defeated
  876. // npcId, x, y, z, skill id, skill level
  877. /*
  878. * Miniboss information, null if miniboss not spawned Skill is casted on the boss when miniboss is defeated Default: 5701 (decrease patk) npcId, x, y, z, skillId, skillLvl
  879. */
  880. private static final int[][] MINIBOSS =
  881. {
  882. null,
  883. null,
  884. {
  885. 25616,
  886. -16874,
  887. -174900,
  888. -10427,
  889. 5701,
  890. 1
  891. },
  892. null,
  893. null,
  894. {
  895. 25617,
  896. -16874,
  897. -174900,
  898. -10427,
  899. 5701,
  900. 2
  901. },
  902. null,
  903. null,
  904. {
  905. 25618,
  906. -16874,
  907. -174900,
  908. -10427,
  909. 5701,
  910. 3
  911. },
  912. null,
  913. null,
  914. {
  915. 25619,
  916. -16874,
  917. -174900,
  918. -10427,
  919. 5701,
  920. 4
  921. },
  922. null,
  923. null,
  924. {
  925. 25620,
  926. -16874,
  927. -174900,
  928. -10427,
  929. 5701,
  930. 5
  931. },
  932. null,
  933. {
  934. 25621,
  935. -16874,
  936. -174900,
  937. -10427,
  938. 5701,
  939. 6
  940. },
  941. {
  942. 25622,
  943. -16874,
  944. -174900,
  945. -10427,
  946. 5701,
  947. 7
  948. },
  949. {
  950. 25709,
  951. 15828,
  952. -174885,
  953. -10384,
  954. 5701,
  955. 7
  956. }
  957. };
  958. /*
  959. * Bosses of the kamaloka Instance ends when boss is defeated npcId, x, y, z
  960. */
  961. private static final int[][] BOSS =
  962. {
  963. {
  964. 18554,
  965. -88998,
  966. -220077,
  967. -7892
  968. },
  969. {
  970. 18555,
  971. -81891,
  972. -220078,
  973. -7893
  974. },
  975. {
  976. 29129,
  977. -20659,
  978. -174903,
  979. -9983
  980. },
  981. {
  982. 18558,
  983. -89183,
  984. -213564,
  985. -8100
  986. },
  987. {
  988. 18559,
  989. -81937,
  990. -213566,
  991. -8100
  992. },
  993. {
  994. 29132,
  995. -20659,
  996. -174903,
  997. -9983
  998. },
  999. {
  1000. 18562,
  1001. -89054,
  1002. -206144,
  1003. -8115
  1004. },
  1005. {
  1006. 18564,
  1007. -81937,
  1008. -206077,
  1009. -8100
  1010. },
  1011. {
  1012. 29135,
  1013. -20659,
  1014. -174903,
  1015. -9983
  1016. },
  1017. {
  1018. 18566,
  1019. -56281,
  1020. -219859,
  1021. -8115
  1022. },
  1023. {
  1024. 18568,
  1025. -49336,
  1026. -220260,
  1027. -8068
  1028. },
  1029. {
  1030. 29138,
  1031. -20659,
  1032. -174903,
  1033. -9983
  1034. },
  1035. {
  1036. 18571,
  1037. -56415,
  1038. -212939,
  1039. -8068
  1040. },
  1041. {
  1042. 18573,
  1043. -56281,
  1044. -206140,
  1045. -8115
  1046. },
  1047. {
  1048. 29141,
  1049. -20659,
  1050. -174903,
  1051. -9983
  1052. },
  1053. {
  1054. 18577,
  1055. -49084,
  1056. -206140,
  1057. -8115
  1058. },
  1059. {
  1060. 29144,
  1061. -20659,
  1062. -174903,
  1063. -9983
  1064. },
  1065. {
  1066. 29147,
  1067. -20659,
  1068. -174903,
  1069. -9983
  1070. },
  1071. {
  1072. 25710,
  1073. 12047,
  1074. -174887,
  1075. -9944
  1076. }
  1077. };
  1078. /*
  1079. * Escape telepoters spawns, null if not spawned x, y, z
  1080. */
  1081. private static final int[][] TELEPORTERS =
  1082. {
  1083. null,
  1084. null,
  1085. {
  1086. -10865,
  1087. -174905,
  1088. -10944
  1089. },
  1090. null,
  1091. null,
  1092. {
  1093. -10865,
  1094. -174905,
  1095. -10944
  1096. },
  1097. null,
  1098. null,
  1099. {
  1100. -10865,
  1101. -174905,
  1102. -10944
  1103. },
  1104. null,
  1105. null,
  1106. {
  1107. -10865,
  1108. -174905,
  1109. -10944
  1110. },
  1111. null,
  1112. null,
  1113. {
  1114. -10865,
  1115. -174905,
  1116. -10944
  1117. },
  1118. null,
  1119. {
  1120. -10865,
  1121. -174905,
  1122. -10944
  1123. },
  1124. {
  1125. -10865,
  1126. -174905,
  1127. -10944
  1128. },
  1129. {
  1130. 21837,
  1131. -174885,
  1132. -10904
  1133. }
  1134. };
  1135. /*
  1136. * Escape teleporter npcId
  1137. */
  1138. private static final int TELEPORTER = 32496;
  1139. /** Kamaloka captains (start npc's) npcIds. */
  1140. private static final int[] CAPTAINS =
  1141. {
  1142. 30332,
  1143. 30071,
  1144. 30916,
  1145. 30196,
  1146. 31981,
  1147. 31340
  1148. };
  1149. protected class KamaWorld extends InstanceWorld
  1150. {
  1151. public int index; // 0-18 index of the kama type in arrays
  1152. public int shaman = 0; // objectId of the shaman
  1153. public List<L2Spawn> firstRoom; // list of the spawns in the first room (excluding shaman)
  1154. public List<Integer> secondRoom;// list of objectIds mobs in the second room
  1155. public int miniBoss = 0; // objectId of the miniboss
  1156. public L2Npc boss = null; // boss
  1157. }
  1158. private Kamaloka()
  1159. {
  1160. super(-1, Kamaloka.class.getSimpleName(), "instances");
  1161. addFirstTalkId(TELEPORTER);
  1162. addTalkId(TELEPORTER);
  1163. for (int cap : CAPTAINS)
  1164. {
  1165. addStartNpc(cap);
  1166. addTalkId(cap);
  1167. }
  1168. for (int[] mob : FIRST_ROOM)
  1169. {
  1170. if (mob != null)
  1171. {
  1172. if (STEALTH_SHAMAN)
  1173. {
  1174. addKillId(mob[1]);
  1175. }
  1176. else
  1177. {
  1178. addKillId(mob[0]);
  1179. }
  1180. }
  1181. }
  1182. for (int[] mob : SECOND_ROOM)
  1183. {
  1184. if (mob != null)
  1185. {
  1186. addKillId(mob[0]);
  1187. }
  1188. }
  1189. for (int[] mob : MINIBOSS)
  1190. {
  1191. if (mob != null)
  1192. {
  1193. addKillId(mob[0]);
  1194. }
  1195. }
  1196. for (int[] mob : BOSS)
  1197. {
  1198. addKillId(mob[0]);
  1199. }
  1200. }
  1201. /**
  1202. * Check if party with player as leader allowed to enter
  1203. * @param player party leader
  1204. * @param index (0-18) index of the kamaloka in arrays
  1205. * @return true if party allowed to enter
  1206. */
  1207. private static final boolean checkConditions(L2PcInstance player, int index)
  1208. {
  1209. final L2Party party = player.getParty();
  1210. // player must be in party
  1211. if (party == null)
  1212. {
  1213. player.sendPacket(SystemMessageId.NOT_IN_PARTY_CANT_ENTER);
  1214. return false;
  1215. }
  1216. // ...and be party leader
  1217. if (party.getLeader() != player)
  1218. {
  1219. player.sendPacket(SystemMessageId.ONLY_PARTY_LEADER_CAN_ENTER);
  1220. return false;
  1221. }
  1222. // party must not exceed max size for selected instance
  1223. if (party.getMemberCount() > MAX_PARTY_SIZE[index])
  1224. {
  1225. player.sendPacket(SystemMessageId.PARTY_EXCEEDED_THE_LIMIT_CANT_ENTER);
  1226. return false;
  1227. }
  1228. // get level of the instance
  1229. final int level = LEVEL[index];
  1230. // and client name
  1231. final String instanceName = InstanceManager.getInstance().getInstanceIdName(TEMPLATE_IDS[index]);
  1232. Map<Integer, Long> instanceTimes;
  1233. // for each party member
  1234. for (L2PcInstance partyMember : party.getMembers())
  1235. {
  1236. // player level must be in range
  1237. if (Math.abs(partyMember.getLevel() - level) > MAX_LEVEL_DIFFERENCE)
  1238. {
  1239. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_LEVEL_REQUIREMENT_NOT_SUFFICIENT);
  1240. sm.addPcName(partyMember);
  1241. player.sendPacket(sm);
  1242. return false;
  1243. }
  1244. // player must be near party leader
  1245. if (!partyMember.isInsideRadius(player, 1000, true, true))
  1246. {
  1247. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_LOCATION_THAT_CANNOT_BE_ENTERED);
  1248. sm.addPcName(partyMember);
  1249. player.sendPacket(sm);
  1250. return false;
  1251. }
  1252. // get instances reenter times for player
  1253. instanceTimes = InstanceManager.getInstance().getAllInstanceTimes(partyMember.getObjectId());
  1254. if (instanceTimes != null)
  1255. {
  1256. for (int id : instanceTimes.keySet())
  1257. {
  1258. // find instance with same name (kamaloka or labyrinth)
  1259. // TODO: Zoey76: Don't use instance name, use other system.
  1260. if (!instanceName.equals(InstanceManager.getInstance().getInstanceIdName(id)))
  1261. {
  1262. continue;
  1263. }
  1264. // if found instance still can't be reentered - exit
  1265. if (System.currentTimeMillis() < instanceTimes.get(id))
  1266. {
  1267. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_REENTER_YET);
  1268. sm.addPcName(partyMember);
  1269. player.sendPacket(sm);
  1270. return false;
  1271. }
  1272. }
  1273. }
  1274. }
  1275. return true;
  1276. }
  1277. /**
  1278. * Removing all buffs from player and pet except BUFFS_WHITELIST
  1279. * @param ch player
  1280. */
  1281. private static final void removeBuffs(L2Character ch)
  1282. {
  1283. Function<BuffInfo, Boolean> removeBuffs = info ->
  1284. {
  1285. if ((info != null) && !info.getSkill().isStayAfterDeath() && (Arrays.binarySearch(BUFFS_WHITELIST, info.getSkill().getId()) < 0))
  1286. {
  1287. info.getEffected().getEffectList().stopSkillEffects(true, info.getSkill());
  1288. }
  1289. return true;
  1290. };
  1291. ch.getEffectList().forEach(removeBuffs, false);
  1292. if (ch.hasSummon())
  1293. {
  1294. ch.getSummon().getEffectList().forEach(removeBuffs, false);
  1295. }
  1296. }
  1297. /**
  1298. * Handling enter of the players into kamaloka
  1299. * @param player party leader
  1300. * @param index (0-18) kamaloka index in arrays
  1301. */
  1302. private final synchronized void enterInstance(L2PcInstance player, int index)
  1303. {
  1304. int templateId;
  1305. try
  1306. {
  1307. templateId = TEMPLATE_IDS[index];
  1308. }
  1309. catch (ArrayIndexOutOfBoundsException e)
  1310. {
  1311. throw e;
  1312. }
  1313. // check for existing instances for this player
  1314. InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
  1315. // player already in the instance
  1316. if (world != null)
  1317. {
  1318. // but not in kamaloka
  1319. if (!(world instanceof KamaWorld) || (world.getTemplateId() != templateId))
  1320. {
  1321. player.sendPacket(SystemMessageId.ALREADY_ENTERED_ANOTHER_INSTANCE_CANT_ENTER);
  1322. return;
  1323. }
  1324. // check for level difference again on reenter
  1325. if (Math.abs(player.getLevel() - LEVEL[((KamaWorld) world).index]) > MAX_LEVEL_DIFFERENCE)
  1326. {
  1327. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_LEVEL_REQUIREMENT_NOT_SUFFICIENT);
  1328. sm.addPcName(player);
  1329. player.sendPacket(sm);
  1330. return;
  1331. }
  1332. // check what instance still exist
  1333. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1334. if (inst != null)
  1335. {
  1336. removeBuffs(player);
  1337. teleportPlayer(player, TELEPORTS[index], world.getInstanceId());
  1338. }
  1339. return;
  1340. }
  1341. // Creating new kamaloka instance
  1342. if (!checkConditions(player, index))
  1343. {
  1344. return;
  1345. }
  1346. // Creating dynamic instance without template
  1347. final int instanceId = InstanceManager.getInstance().createDynamicInstance(null);
  1348. final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
  1349. // set name for the kamaloka
  1350. inst.setName(InstanceManager.getInstance().getInstanceIdName(templateId));
  1351. // set return location
  1352. inst.setSpawnLoc(new Location(player));
  1353. // disable summon friend into instance
  1354. inst.setAllowSummon(false);
  1355. // set duration and empty destroy time
  1356. inst.setDuration(DURATION[index] * 60000);
  1357. inst.setEmptyDestroyTime(EMPTY_DESTROY_TIME * 60000);
  1358. // Creating new instanceWorld, using our instanceId and templateId
  1359. world = new KamaWorld();
  1360. world.setInstanceId(instanceId);
  1361. world.setTemplateId(templateId);
  1362. // set index for easy access to the arrays
  1363. ((KamaWorld) world).index = index;
  1364. InstanceManager.getInstance().addWorld(world);
  1365. world.setStatus(0);
  1366. // spawn npcs
  1367. spawnKama((KamaWorld) world);
  1368. // and finally teleport party into instance
  1369. final L2Party party = player.getParty();
  1370. for (L2PcInstance partyMember : party.getMembers())
  1371. {
  1372. world.addAllowed(partyMember.getObjectId());
  1373. removeBuffs(partyMember);
  1374. teleportPlayer(partyMember, TELEPORTS[index], instanceId);
  1375. }
  1376. return;
  1377. }
  1378. /**
  1379. * Called on instance finish and handles reenter time for instance
  1380. * @param world instanceWorld
  1381. */
  1382. private static final void finishInstance(InstanceWorld world)
  1383. {
  1384. if (world instanceof KamaWorld)
  1385. {
  1386. Calendar reenter = Calendar.getInstance();
  1387. reenter.set(Calendar.MINUTE, RESET_MIN);
  1388. // if time is >= RESET_HOUR - roll to the next day
  1389. if (reenter.get(Calendar.HOUR_OF_DAY) >= RESET_HOUR)
  1390. {
  1391. reenter.add(Calendar.DATE, 1);
  1392. }
  1393. reenter.set(Calendar.HOUR_OF_DAY, RESET_HOUR);
  1394. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_S1_RESTRICTED);
  1395. sm.addInstanceName(world.getTemplateId());
  1396. // set instance reenter time for all allowed players
  1397. for (int objectId : world.getAllowed())
  1398. {
  1399. L2PcInstance obj = L2World.getInstance().getPlayer(objectId);
  1400. if ((obj != null) && obj.isOnline())
  1401. {
  1402. InstanceManager.getInstance().setInstanceTime(objectId, world.getTemplateId(), reenter.getTimeInMillis());
  1403. obj.sendPacket(sm);
  1404. }
  1405. }
  1406. // destroy instance after EXIT_TIME
  1407. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1408. inst.setDuration(EXIT_TIME * 60000);
  1409. inst.setEmptyDestroyTime(0);
  1410. }
  1411. }
  1412. /**
  1413. * Spawn all NPCs in kamaloka
  1414. * @param world instanceWorld
  1415. */
  1416. @SuppressWarnings("all")
  1417. private final void spawnKama(KamaWorld world)
  1418. {
  1419. int[] npcs;
  1420. int[][] spawns;
  1421. L2Npc npc;
  1422. final int index = world.index;
  1423. // first room
  1424. npcs = FIRST_ROOM[index];
  1425. spawns = FIRST_ROOM_SPAWNS[index];
  1426. if (npcs != null)
  1427. {
  1428. world.firstRoom = new ArrayList<L2Spawn>(spawns.length - 1);
  1429. int shaman = getRandom(spawns.length); // random position for shaman
  1430. for (int i = 0; i < spawns.length; i++)
  1431. {
  1432. if (i == shaman)
  1433. {
  1434. // stealth shaman use same npcId as other mobs
  1435. npc = addSpawn(STEALTH_SHAMAN ? npcs[1] : npcs[0], spawns[i][0], spawns[i][1], spawns[i][2], 0, false, 0, false, world.getInstanceId());
  1436. world.shaman = npc.getObjectId();
  1437. }
  1438. else
  1439. {
  1440. npc = addSpawn(npcs[1], spawns[i][0], spawns[i][1], spawns[i][2], 0, false, 0, false, world.getInstanceId());
  1441. L2Spawn spawn = npc.getSpawn();
  1442. spawn.setRespawnDelay(FIRST_ROOM_RESPAWN_DELAY);
  1443. spawn.setAmount(1);
  1444. spawn.startRespawn();
  1445. world.firstRoom.add(spawn); // store mobs spawns
  1446. }
  1447. npc.setIsNoRndWalk(true);
  1448. }
  1449. }
  1450. // second room
  1451. npcs = SECOND_ROOM[index];
  1452. spawns = SECOND_ROOM_SPAWNS[index];
  1453. if (npcs != null)
  1454. {
  1455. world.secondRoom = new ArrayList<Integer>(spawns.length);
  1456. for (int[] spawn : spawns)
  1457. {
  1458. npc = addSpawn(npcs[0], spawn[0], spawn[1], spawn[2], 0, false, 0, false, world.getInstanceId());
  1459. npc.setIsNoRndWalk(true);
  1460. world.secondRoom.add(npc.getObjectId());
  1461. }
  1462. }
  1463. // miniboss
  1464. if (MINIBOSS[index] != null)
  1465. {
  1466. npc = addSpawn(MINIBOSS[index][0], MINIBOSS[index][1], MINIBOSS[index][2], MINIBOSS[index][3], 0, false, 0, false, world.getInstanceId());
  1467. npc.setIsNoRndWalk(true);
  1468. world.miniBoss = npc.getObjectId();
  1469. }
  1470. // escape teleporter
  1471. if (TELEPORTERS[index] != null)
  1472. {
  1473. addSpawn(TELEPORTER, TELEPORTERS[index][0], TELEPORTERS[index][1], TELEPORTERS[index][2], 0, false, 0, false, world.getInstanceId());
  1474. }
  1475. // boss
  1476. npc = addSpawn(BOSS[index][0], BOSS[index][1], BOSS[index][2], BOSS[index][3], 0, false, 0, false, world.getInstanceId());
  1477. ((L2MonsterInstance) npc).setOnKillDelay(100);
  1478. world.boss = npc;
  1479. }
  1480. /**
  1481. * Handles only player's enter, single parameter - integer kamaloka index
  1482. */
  1483. @Override
  1484. public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  1485. {
  1486. if (npc == null)
  1487. {
  1488. return "";
  1489. }
  1490. try
  1491. {
  1492. enterInstance(player, Integer.parseInt(event));
  1493. }
  1494. catch (Exception e)
  1495. {
  1496. _log.log(Level.WARNING, "", e);
  1497. }
  1498. return "";
  1499. }
  1500. /**
  1501. * Talk with captains and using of the escape teleporter
  1502. */
  1503. @Override
  1504. public final String onTalk(L2Npc npc, L2PcInstance player)
  1505. {
  1506. final int npcId = npc.getId();
  1507. if (npcId == TELEPORTER)
  1508. {
  1509. final L2Party party = player.getParty();
  1510. // only party leader can talk with escape teleporter
  1511. if ((party != null) && party.isLeader(player))
  1512. {
  1513. final InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
  1514. if (world instanceof KamaWorld)
  1515. {
  1516. // party members must be in the instance
  1517. if (world.isAllowed(player.getObjectId()))
  1518. {
  1519. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1520. // teleports entire party away
  1521. for (L2PcInstance partyMember : party.getMembers())
  1522. {
  1523. if ((partyMember != null) && (partyMember.getInstanceId() == world.getInstanceId()))
  1524. {
  1525. teleportPlayer(partyMember, inst.getSpawnLoc(), 0);
  1526. }
  1527. }
  1528. }
  1529. }
  1530. }
  1531. }
  1532. else
  1533. {
  1534. return npcId + ".htm";
  1535. }
  1536. return "";
  1537. }
  1538. /**
  1539. * Only escape teleporters first talk handled
  1540. */
  1541. @Override
  1542. public final String onFirstTalk(L2Npc npc, L2PcInstance player)
  1543. {
  1544. if (npc.getId() == TELEPORTER)
  1545. {
  1546. if (player.isInParty() && player.getParty().isLeader(player))
  1547. {
  1548. return "32496.htm";
  1549. }
  1550. return "32496-no.htm";
  1551. }
  1552. return "";
  1553. }
  1554. @Override
  1555. public final String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
  1556. {
  1557. final InstanceWorld tmpWorld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
  1558. if (tmpWorld instanceof KamaWorld)
  1559. {
  1560. final KamaWorld world = (KamaWorld) tmpWorld;
  1561. final int objectId = npc.getObjectId();
  1562. // first room was spawned ?
  1563. if (world.firstRoom != null)
  1564. {
  1565. // is shaman killed ?
  1566. if ((world.shaman != 0) && (world.shaman == objectId))
  1567. {
  1568. world.shaman = 0;
  1569. // stop respawn of the minions
  1570. for (L2Spawn spawn : world.firstRoom)
  1571. {
  1572. if (spawn != null)
  1573. {
  1574. spawn.stopRespawn();
  1575. }
  1576. }
  1577. world.firstRoom.clear();
  1578. world.firstRoom = null;
  1579. if (world.boss != null)
  1580. {
  1581. final int skillId = FIRST_ROOM[world.index][2];
  1582. final int skillLvl = FIRST_ROOM[world.index][3];
  1583. if ((skillId != 0) && (skillLvl != 0))
  1584. {
  1585. final Skill skill = SkillData.getInstance().getSkill(skillId, skillLvl);
  1586. if (skill != null)
  1587. {
  1588. skill.applyEffects(world.boss, world.boss);
  1589. }
  1590. }
  1591. }
  1592. return super.onKill(npc, player, isSummon);
  1593. }
  1594. }
  1595. // second room was spawned ?
  1596. if (world.secondRoom != null)
  1597. {
  1598. boolean all = true;
  1599. // check for all mobs in the second room
  1600. for (int i = 0; i < world.secondRoom.size(); i++)
  1601. {
  1602. // found killed now mob
  1603. if (world.secondRoom.get(i) == objectId)
  1604. {
  1605. world.secondRoom.set(i, 0);
  1606. }
  1607. else if (world.secondRoom.get(i) != 0)
  1608. {
  1609. all = false;
  1610. }
  1611. }
  1612. // all mobs killed ?
  1613. if (all)
  1614. {
  1615. world.secondRoom.clear();
  1616. world.secondRoom = null;
  1617. if (world.boss != null)
  1618. {
  1619. final int skillId = SECOND_ROOM[world.index][1];
  1620. final int skillLvl = SECOND_ROOM[world.index][2];
  1621. if ((skillId != 0) && (skillLvl != 0))
  1622. {
  1623. final Skill skill = SkillData.getInstance().getSkill(skillId, skillLvl);
  1624. if (skill != null)
  1625. {
  1626. skill.applyEffects(world.boss, world.boss);
  1627. }
  1628. }
  1629. }
  1630. return super.onKill(npc, player, isSummon);
  1631. }
  1632. }
  1633. // miniboss spawned ?
  1634. if ((world.miniBoss != 0) && (world.miniBoss == objectId))
  1635. {
  1636. world.miniBoss = 0;
  1637. if (world.boss != null)
  1638. {
  1639. final int skillId = MINIBOSS[world.index][4];
  1640. final int skillLvl = MINIBOSS[world.index][5];
  1641. if ((skillId != 0) && (skillLvl != 0))
  1642. {
  1643. final Skill skill = SkillData.getInstance().getSkill(skillId, skillLvl);
  1644. if (skill != null)
  1645. {
  1646. skill.applyEffects(world.boss, world.boss);
  1647. }
  1648. }
  1649. }
  1650. return super.onKill(npc, player, isSummon);
  1651. }
  1652. // boss was killed, finish instance
  1653. if ((world.boss != null) && (world.boss == npc))
  1654. {
  1655. world.boss = null;
  1656. finishInstance(world);
  1657. }
  1658. }
  1659. return super.onKill(npc, player, isSummon);
  1660. }
  1661. public static void main(String[] args)
  1662. {
  1663. new Kamaloka();
  1664. }
  1665. }