Kamaloka.java 31 KB

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