Kamaloka.java 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732
  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 instances.Kamaloka;
  20. import instances.AbstractInstance;
  21. import java.util.ArrayList;
  22. import java.util.Arrays;
  23. import java.util.Calendar;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.function.Function;
  27. import java.util.logging.Level;
  28. import com.l2jserver.gameserver.datatables.SkillData;
  29. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  30. import com.l2jserver.gameserver.model.L2Party;
  31. import com.l2jserver.gameserver.model.L2Spawn;
  32. import com.l2jserver.gameserver.model.L2World;
  33. import com.l2jserver.gameserver.model.Location;
  34. import com.l2jserver.gameserver.model.actor.L2Character;
  35. import com.l2jserver.gameserver.model.actor.L2Npc;
  36. import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
  37. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  38. import com.l2jserver.gameserver.model.entity.Instance;
  39. import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
  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 AbstractInstance
  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. public Kamaloka()
  1159. {
  1160. super(Kamaloka.class.getSimpleName());
  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_S_LEVEL_REQUIREMENT_IS_NOT_SUFFICIENT_AND_CANNOT_BE_ENTERED);
  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_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
  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_RE_ENTER_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. final 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. return true;
  1289. }
  1290. return false;
  1291. };
  1292. ch.getEffectList().forEach(removeBuffs, false);
  1293. if (ch.hasSummon())
  1294. {
  1295. ch.getSummon().getEffectList().forEach(removeBuffs, false);
  1296. }
  1297. }
  1298. /**
  1299. * Handling enter of the players into kamaloka
  1300. * @param player party leader
  1301. * @param index (0-18) kamaloka index in arrays
  1302. */
  1303. private final synchronized void enterInstance(L2PcInstance player, int index)
  1304. {
  1305. int templateId;
  1306. try
  1307. {
  1308. templateId = TEMPLATE_IDS[index];
  1309. }
  1310. catch (ArrayIndexOutOfBoundsException e)
  1311. {
  1312. throw e;
  1313. }
  1314. // check for existing instances for this player
  1315. InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
  1316. // player already in the instance
  1317. if (world != null)
  1318. {
  1319. // but not in kamaloka
  1320. if (!(world instanceof KamaWorld) || (world.getTemplateId() != templateId))
  1321. {
  1322. player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
  1323. return;
  1324. }
  1325. // check for level difference again on reenter
  1326. if (Math.abs(player.getLevel() - LEVEL[((KamaWorld) world).index]) > MAX_LEVEL_DIFFERENCE)
  1327. {
  1328. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_REQUIREMENT_IS_NOT_SUFFICIENT_AND_CANNOT_BE_ENTERED);
  1329. sm.addPcName(player);
  1330. player.sendPacket(sm);
  1331. return;
  1332. }
  1333. // check what instance still exist
  1334. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1335. if (inst != null)
  1336. {
  1337. removeBuffs(player);
  1338. teleportPlayer(player, TELEPORTS[index], world.getInstanceId());
  1339. }
  1340. return;
  1341. }
  1342. // Creating new kamaloka instance
  1343. if (!checkConditions(player, index))
  1344. {
  1345. return;
  1346. }
  1347. // Creating dynamic instance without template
  1348. final int instanceId = InstanceManager.getInstance().createDynamicInstance(null);
  1349. final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
  1350. // set name for the kamaloka
  1351. inst.setName(InstanceManager.getInstance().getInstanceIdName(templateId));
  1352. // set return location
  1353. inst.setSpawnLoc(new Location(player));
  1354. // disable summon friend into instance
  1355. inst.setAllowSummon(false);
  1356. // set duration and empty destroy time
  1357. inst.setDuration(DURATION[index] * 60000);
  1358. inst.setEmptyDestroyTime(EMPTY_DESTROY_TIME * 60000);
  1359. // Creating new instanceWorld, using our instanceId and templateId
  1360. world = new KamaWorld();
  1361. world.setInstanceId(instanceId);
  1362. world.setTemplateId(templateId);
  1363. // set index for easy access to the arrays
  1364. ((KamaWorld) world).index = index;
  1365. InstanceManager.getInstance().addWorld(world);
  1366. world.setStatus(0);
  1367. // spawn npcs
  1368. spawnKama((KamaWorld) world);
  1369. // and finally teleport party into instance
  1370. final L2Party party = player.getParty();
  1371. for (L2PcInstance partyMember : party.getMembers())
  1372. {
  1373. world.addAllowed(partyMember.getObjectId());
  1374. removeBuffs(partyMember);
  1375. teleportPlayer(partyMember, TELEPORTS[index], instanceId);
  1376. }
  1377. return;
  1378. }
  1379. /**
  1380. * Called on instance finish and handles reenter time for instance
  1381. * @param world instanceWorld
  1382. */
  1383. @Override
  1384. protected final void finishInstance(InstanceWorld world)
  1385. {
  1386. if (world instanceof KamaWorld)
  1387. {
  1388. Calendar reenter = Calendar.getInstance();
  1389. reenter.set(Calendar.MINUTE, RESET_MIN);
  1390. // if time is >= RESET_HOUR - roll to the next day
  1391. if (reenter.get(Calendar.HOUR_OF_DAY) >= RESET_HOUR)
  1392. {
  1393. reenter.add(Calendar.DATE, 1);
  1394. }
  1395. reenter.set(Calendar.HOUR_OF_DAY, RESET_HOUR);
  1396. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_FROM_HERE_S1_S_ENTRY_HAS_BEEN_RESTRICTED);
  1397. sm.addInstanceName(world.getTemplateId());
  1398. // set instance reenter time for all allowed players
  1399. for (int objectId : world.getAllowed())
  1400. {
  1401. L2PcInstance obj = L2World.getInstance().getPlayer(objectId);
  1402. if ((obj != null) && obj.isOnline())
  1403. {
  1404. InstanceManager.getInstance().setInstanceTime(objectId, world.getTemplateId(), reenter.getTimeInMillis());
  1405. obj.sendPacket(sm);
  1406. }
  1407. }
  1408. // destroy instance after EXIT_TIME
  1409. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1410. inst.setDuration(EXIT_TIME * 60000);
  1411. inst.setEmptyDestroyTime(0);
  1412. }
  1413. }
  1414. /**
  1415. * Spawn all NPCs in kamaloka
  1416. * @param world instanceWorld
  1417. */
  1418. @SuppressWarnings("all")
  1419. private final void spawnKama(KamaWorld world)
  1420. {
  1421. int[] npcs;
  1422. int[][] spawns;
  1423. L2Npc npc;
  1424. final int index = world.index;
  1425. // first room
  1426. npcs = FIRST_ROOM[index];
  1427. spawns = FIRST_ROOM_SPAWNS[index];
  1428. if (npcs != null)
  1429. {
  1430. world.firstRoom = new ArrayList<L2Spawn>(spawns.length - 1);
  1431. int shaman = getRandom(spawns.length); // random position for shaman
  1432. for (int i = 0; i < spawns.length; i++)
  1433. {
  1434. if (i == shaman)
  1435. {
  1436. // stealth shaman use same npcId as other mobs
  1437. npc = addSpawn(STEALTH_SHAMAN ? npcs[1] : npcs[0], spawns[i][0], spawns[i][1], spawns[i][2], 0, false, 0, false, world.getInstanceId());
  1438. world.shaman = npc.getObjectId();
  1439. }
  1440. else
  1441. {
  1442. npc = addSpawn(npcs[1], spawns[i][0], spawns[i][1], spawns[i][2], 0, false, 0, false, world.getInstanceId());
  1443. L2Spawn spawn = npc.getSpawn();
  1444. spawn.setRespawnDelay(FIRST_ROOM_RESPAWN_DELAY);
  1445. spawn.setAmount(1);
  1446. spawn.startRespawn();
  1447. world.firstRoom.add(spawn); // store mobs spawns
  1448. }
  1449. npc.setIsNoRndWalk(true);
  1450. }
  1451. }
  1452. // second room
  1453. npcs = SECOND_ROOM[index];
  1454. spawns = SECOND_ROOM_SPAWNS[index];
  1455. if (npcs != null)
  1456. {
  1457. world.secondRoom = new ArrayList<Integer>(spawns.length);
  1458. for (int[] spawn : spawns)
  1459. {
  1460. npc = addSpawn(npcs[0], spawn[0], spawn[1], spawn[2], 0, false, 0, false, world.getInstanceId());
  1461. npc.setIsNoRndWalk(true);
  1462. world.secondRoom.add(npc.getObjectId());
  1463. }
  1464. }
  1465. // miniboss
  1466. if (MINIBOSS[index] != null)
  1467. {
  1468. npc = addSpawn(MINIBOSS[index][0], MINIBOSS[index][1], MINIBOSS[index][2], MINIBOSS[index][3], 0, false, 0, false, world.getInstanceId());
  1469. npc.setIsNoRndWalk(true);
  1470. world.miniBoss = npc.getObjectId();
  1471. }
  1472. // escape teleporter
  1473. if (TELEPORTERS[index] != null)
  1474. {
  1475. addSpawn(TELEPORTER, TELEPORTERS[index][0], TELEPORTERS[index][1], TELEPORTERS[index][2], 0, false, 0, false, world.getInstanceId());
  1476. }
  1477. // boss
  1478. npc = addSpawn(BOSS[index][0], BOSS[index][1], BOSS[index][2], BOSS[index][3], 0, false, 0, false, world.getInstanceId());
  1479. ((L2MonsterInstance) npc).setOnKillDelay(100);
  1480. world.boss = npc;
  1481. }
  1482. /**
  1483. * Handles only player's enter, single parameter - integer kamaloka index
  1484. */
  1485. @Override
  1486. public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  1487. {
  1488. if (npc == null)
  1489. {
  1490. return "";
  1491. }
  1492. try
  1493. {
  1494. enterInstance(player, Integer.parseInt(event));
  1495. }
  1496. catch (Exception e)
  1497. {
  1498. _log.log(Level.WARNING, "", e);
  1499. }
  1500. return "";
  1501. }
  1502. /**
  1503. * Talk with captains and using of the escape teleporter
  1504. */
  1505. @Override
  1506. public final String onTalk(L2Npc npc, L2PcInstance player)
  1507. {
  1508. final int npcId = npc.getId();
  1509. if (npcId == TELEPORTER)
  1510. {
  1511. final L2Party party = player.getParty();
  1512. // only party leader can talk with escape teleporter
  1513. if ((party != null) && party.isLeader(player))
  1514. {
  1515. final InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
  1516. if (world instanceof KamaWorld)
  1517. {
  1518. // party members must be in the instance
  1519. if (world.isAllowed(player.getObjectId()))
  1520. {
  1521. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1522. // teleports entire party away
  1523. for (L2PcInstance partyMember : party.getMembers())
  1524. {
  1525. if ((partyMember != null) && (partyMember.getInstanceId() == world.getInstanceId()))
  1526. {
  1527. teleportPlayer(partyMember, inst.getSpawnLoc(), 0);
  1528. }
  1529. }
  1530. }
  1531. }
  1532. }
  1533. }
  1534. else
  1535. {
  1536. return npcId + ".htm";
  1537. }
  1538. return "";
  1539. }
  1540. /**
  1541. * Only escape teleporters first talk handled
  1542. */
  1543. @Override
  1544. public final String onFirstTalk(L2Npc npc, L2PcInstance player)
  1545. {
  1546. if (npc.getId() == TELEPORTER)
  1547. {
  1548. if (player.isInParty() && player.getParty().isLeader(player))
  1549. {
  1550. return "32496.htm";
  1551. }
  1552. return "32496-no.htm";
  1553. }
  1554. return "";
  1555. }
  1556. @Override
  1557. public final String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
  1558. {
  1559. final InstanceWorld tmpWorld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
  1560. if (tmpWorld instanceof KamaWorld)
  1561. {
  1562. final KamaWorld world = (KamaWorld) tmpWorld;
  1563. final int objectId = npc.getObjectId();
  1564. // first room was spawned ?
  1565. if (world.firstRoom != null)
  1566. {
  1567. // is shaman killed ?
  1568. if ((world.shaman != 0) && (world.shaman == objectId))
  1569. {
  1570. world.shaman = 0;
  1571. // stop respawn of the minions
  1572. for (L2Spawn spawn : world.firstRoom)
  1573. {
  1574. if (spawn != null)
  1575. {
  1576. spawn.stopRespawn();
  1577. }
  1578. }
  1579. world.firstRoom.clear();
  1580. world.firstRoom = null;
  1581. if (world.boss != null)
  1582. {
  1583. final int skillId = FIRST_ROOM[world.index][2];
  1584. final int skillLvl = FIRST_ROOM[world.index][3];
  1585. if ((skillId != 0) && (skillLvl != 0))
  1586. {
  1587. final Skill skill = SkillData.getInstance().getSkill(skillId, skillLvl);
  1588. if (skill != null)
  1589. {
  1590. skill.applyEffects(world.boss, world.boss);
  1591. }
  1592. }
  1593. }
  1594. return super.onKill(npc, player, isSummon);
  1595. }
  1596. }
  1597. // second room was spawned ?
  1598. if (world.secondRoom != null)
  1599. {
  1600. boolean all = true;
  1601. // check for all mobs in the second room
  1602. for (int i = 0; i < world.secondRoom.size(); i++)
  1603. {
  1604. // found killed now mob
  1605. if (world.secondRoom.get(i) == objectId)
  1606. {
  1607. world.secondRoom.set(i, 0);
  1608. }
  1609. else if (world.secondRoom.get(i) != 0)
  1610. {
  1611. all = false;
  1612. }
  1613. }
  1614. // all mobs killed ?
  1615. if (all)
  1616. {
  1617. world.secondRoom.clear();
  1618. world.secondRoom = null;
  1619. if (world.boss != null)
  1620. {
  1621. final int skillId = SECOND_ROOM[world.index][1];
  1622. final int skillLvl = SECOND_ROOM[world.index][2];
  1623. if ((skillId != 0) && (skillLvl != 0))
  1624. {
  1625. final Skill skill = SkillData.getInstance().getSkill(skillId, skillLvl);
  1626. if (skill != null)
  1627. {
  1628. skill.applyEffects(world.boss, world.boss);
  1629. }
  1630. }
  1631. }
  1632. return super.onKill(npc, player, isSummon);
  1633. }
  1634. }
  1635. // miniboss spawned ?
  1636. if ((world.miniBoss != 0) && (world.miniBoss == objectId))
  1637. {
  1638. world.miniBoss = 0;
  1639. if (world.boss != null)
  1640. {
  1641. final int skillId = MINIBOSS[world.index][4];
  1642. final int skillLvl = MINIBOSS[world.index][5];
  1643. if ((skillId != 0) && (skillLvl != 0))
  1644. {
  1645. final Skill skill = SkillData.getInstance().getSkill(skillId, skillLvl);
  1646. if (skill != null)
  1647. {
  1648. skill.applyEffects(world.boss, world.boss);
  1649. }
  1650. }
  1651. }
  1652. return super.onKill(npc, player, isSummon);
  1653. }
  1654. // boss was killed, finish instance
  1655. if ((world.boss != null) && (world.boss == npc))
  1656. {
  1657. world.boss = null;
  1658. finishInstance(world);
  1659. }
  1660. }
  1661. return super.onKill(npc, player, isSummon);
  1662. }
  1663. @Override
  1664. public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
  1665. {
  1666. }
  1667. }