Kamaloka.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749
  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.logging.Level;
  26. import com.l2jserver.gameserver.datatables.SkillTable;
  27. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  28. import com.l2jserver.gameserver.model.L2Party;
  29. import com.l2jserver.gameserver.model.L2Spawn;
  30. import com.l2jserver.gameserver.model.L2World;
  31. import com.l2jserver.gameserver.model.Location;
  32. import com.l2jserver.gameserver.model.actor.L2Character;
  33. import com.l2jserver.gameserver.model.actor.L2Npc;
  34. import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
  35. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  36. import com.l2jserver.gameserver.model.entity.Instance;
  37. import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
  38. import com.l2jserver.gameserver.model.interfaces.IProcedure;
  39. import com.l2jserver.gameserver.model.quest.Quest;
  40. import com.l2jserver.gameserver.model.skills.BuffInfo;
  41. import com.l2jserver.gameserver.model.skills.L2Skill;
  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. private static final IProcedure<BuffInfo, Boolean> REMOVE_BUFFS = new IProcedure<BuffInfo, Boolean>()
  1163. {
  1164. @Override
  1165. public Boolean execute(BuffInfo info)
  1166. {
  1167. if ((info != null) && !info.getSkill().isStayAfterDeath() && (Arrays.binarySearch(BUFFS_WHITELIST, info.getSkill().getId()) < 0))
  1168. {
  1169. info.getEffected().getEffectList().stopSkillEffects(true, info.getSkill());
  1170. }
  1171. return true;
  1172. }
  1173. };
  1174. protected class KamaWorld extends InstanceWorld
  1175. {
  1176. public int index; // 0-18 index of the kama type in arrays
  1177. public int shaman = 0; // objectId of the shaman
  1178. public List<L2Spawn> firstRoom; // list of the spawns in the first room (excluding shaman)
  1179. public List<Integer> secondRoom;// list of objectIds mobs in the second room
  1180. public int miniBoss = 0; // objectId of the miniboss
  1181. public L2Npc boss = null; // boss
  1182. }
  1183. private Kamaloka()
  1184. {
  1185. super(-1, Kamaloka.class.getSimpleName(), "instances");
  1186. addFirstTalkId(TELEPORTER);
  1187. addTalkId(TELEPORTER);
  1188. for (int cap : CAPTAINS)
  1189. {
  1190. addStartNpc(cap);
  1191. addTalkId(cap);
  1192. }
  1193. for (int[] mob : FIRST_ROOM)
  1194. {
  1195. if (mob != null)
  1196. {
  1197. if (STEALTH_SHAMAN)
  1198. {
  1199. addKillId(mob[1]);
  1200. }
  1201. else
  1202. {
  1203. addKillId(mob[0]);
  1204. }
  1205. }
  1206. }
  1207. for (int[] mob : SECOND_ROOM)
  1208. {
  1209. if (mob != null)
  1210. {
  1211. addKillId(mob[0]);
  1212. }
  1213. }
  1214. for (int[] mob : MINIBOSS)
  1215. {
  1216. if (mob != null)
  1217. {
  1218. addKillId(mob[0]);
  1219. }
  1220. }
  1221. for (int[] mob : BOSS)
  1222. {
  1223. addKillId(mob[0]);
  1224. }
  1225. }
  1226. /**
  1227. * Check if party with player as leader allowed to enter
  1228. * @param player party leader
  1229. * @param index (0-18) index of the kamaloka in arrays
  1230. * @return true if party allowed to enter
  1231. */
  1232. private static final boolean checkConditions(L2PcInstance player, int index)
  1233. {
  1234. final L2Party party = player.getParty();
  1235. // player must be in party
  1236. if (party == null)
  1237. {
  1238. player.sendPacket(SystemMessageId.NOT_IN_PARTY_CANT_ENTER);
  1239. return false;
  1240. }
  1241. // ...and be party leader
  1242. if (party.getLeader() != player)
  1243. {
  1244. player.sendPacket(SystemMessageId.ONLY_PARTY_LEADER_CAN_ENTER);
  1245. return false;
  1246. }
  1247. // party must not exceed max size for selected instance
  1248. if (party.getMemberCount() > MAX_PARTY_SIZE[index])
  1249. {
  1250. player.sendPacket(SystemMessageId.PARTY_EXCEEDED_THE_LIMIT_CANT_ENTER);
  1251. return false;
  1252. }
  1253. // get level of the instance
  1254. final int level = LEVEL[index];
  1255. // and client name
  1256. final String instanceName = InstanceManager.getInstance().getInstanceIdName(INSTANCE_IDS[index]);
  1257. Map<Integer, Long> instanceTimes;
  1258. // for each party member
  1259. for (L2PcInstance partyMember : party.getMembers())
  1260. {
  1261. // player level must be in range
  1262. if (Math.abs(partyMember.getLevel() - level) > MAX_LEVEL_DIFFERENCE)
  1263. {
  1264. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_LEVEL_REQUIREMENT_NOT_SUFFICIENT);
  1265. sm.addPcName(partyMember);
  1266. player.sendPacket(sm);
  1267. return false;
  1268. }
  1269. // player must be near party leader
  1270. if (!partyMember.isInsideRadius(player, 1000, true, true))
  1271. {
  1272. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_LOCATION_THAT_CANNOT_BE_ENTERED);
  1273. sm.addPcName(partyMember);
  1274. player.sendPacket(sm);
  1275. return false;
  1276. }
  1277. // get instances reenter times for player
  1278. instanceTimes = InstanceManager.getInstance().getAllInstanceTimes(partyMember.getObjectId());
  1279. if (instanceTimes != null)
  1280. {
  1281. for (int id : instanceTimes.keySet())
  1282. {
  1283. // find instance with same name (kamaloka or labyrinth)
  1284. // TODO: Zoey76: Don't use instance name, use other system.
  1285. if (!instanceName.equals(InstanceManager.getInstance().getInstanceIdName(id)))
  1286. {
  1287. continue;
  1288. }
  1289. // if found instance still can't be reentered - exit
  1290. if (System.currentTimeMillis() < instanceTimes.get(id))
  1291. {
  1292. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_REENTER_YET);
  1293. sm.addPcName(partyMember);
  1294. player.sendPacket(sm);
  1295. return false;
  1296. }
  1297. }
  1298. }
  1299. }
  1300. return true;
  1301. }
  1302. /**
  1303. * Removing all buffs from player and pet except BUFFS_WHITELIST
  1304. * @param ch player
  1305. */
  1306. private static final void removeBuffs(L2Character ch)
  1307. {
  1308. ch.getEffectList().forEach(REMOVE_BUFFS, false);
  1309. if (ch.hasSummon())
  1310. {
  1311. ch.getSummon().getEffectList().forEach(REMOVE_BUFFS, false);
  1312. }
  1313. }
  1314. /**
  1315. * Handling enter of the players into kamaloka
  1316. * @param player party leader
  1317. * @param index (0-18) kamaloka index in arrays
  1318. */
  1319. private final synchronized void enterInstance(L2PcInstance player, int index)
  1320. {
  1321. int templateId;
  1322. try
  1323. {
  1324. templateId = INSTANCE_IDS[index];
  1325. }
  1326. catch (ArrayIndexOutOfBoundsException e)
  1327. {
  1328. throw e;
  1329. }
  1330. // check for existing instances for this player
  1331. InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
  1332. // player already in the instance
  1333. if (world != null)
  1334. {
  1335. // but not in kamaloka
  1336. if (!(world instanceof KamaWorld) || (world.getTemplateId() != templateId))
  1337. {
  1338. player.sendPacket(SystemMessageId.ALREADY_ENTERED_ANOTHER_INSTANCE_CANT_ENTER);
  1339. return;
  1340. }
  1341. // check for level difference again on reenter
  1342. if (Math.abs(player.getLevel() - LEVEL[((KamaWorld) world).index]) > MAX_LEVEL_DIFFERENCE)
  1343. {
  1344. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_LEVEL_REQUIREMENT_NOT_SUFFICIENT);
  1345. sm.addPcName(player);
  1346. player.sendPacket(sm);
  1347. return;
  1348. }
  1349. // check what instance still exist
  1350. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1351. if (inst != null)
  1352. {
  1353. removeBuffs(player);
  1354. teleportPlayer(player, TELEPORTS[index], world.getInstanceId());
  1355. }
  1356. return;
  1357. }
  1358. // Creating new kamaloka instance
  1359. if (!checkConditions(player, index))
  1360. {
  1361. return;
  1362. }
  1363. // Creating dynamic instance without template
  1364. final int instanceId = InstanceManager.getInstance().createDynamicInstance(null);
  1365. final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
  1366. // set name for the kamaloka
  1367. inst.setName(InstanceManager.getInstance().getInstanceIdName(templateId));
  1368. // set return location
  1369. inst.setSpawnLoc(new Location(player));
  1370. // disable summon friend into instance
  1371. inst.setAllowSummon(false);
  1372. // set duration and empty destroy time
  1373. inst.setDuration(DURATION[index] * 60000);
  1374. inst.setEmptyDestroyTime(EMPTY_DESTROY_TIME * 60000);
  1375. // Creating new instanceWorld, using our instanceId and templateId
  1376. world = new KamaWorld();
  1377. world.setInstanceId(instanceId);
  1378. world.setTemplateId(templateId);
  1379. // set index for easy access to the arrays
  1380. ((KamaWorld) world).index = index;
  1381. InstanceManager.getInstance().addWorld(world);
  1382. world.setStatus(0);
  1383. // spawn npcs
  1384. spawnKama((KamaWorld) world);
  1385. // and finally teleport party into instance
  1386. final L2Party party = player.getParty();
  1387. for (L2PcInstance partyMember : party.getMembers())
  1388. {
  1389. world.addAllowed(partyMember.getObjectId());
  1390. removeBuffs(partyMember);
  1391. teleportPlayer(partyMember, TELEPORTS[index], instanceId);
  1392. }
  1393. return;
  1394. }
  1395. /**
  1396. * Called on instance finish and handles reenter time for instance
  1397. * @param world instanceWorld
  1398. */
  1399. private static final void finishInstance(InstanceWorld world)
  1400. {
  1401. if (world instanceof KamaWorld)
  1402. {
  1403. Calendar reenter = Calendar.getInstance();
  1404. reenter.set(Calendar.MINUTE, RESET_MIN);
  1405. // if time is >= RESET_HOUR - roll to the next day
  1406. if (reenter.get(Calendar.HOUR_OF_DAY) >= RESET_HOUR)
  1407. {
  1408. reenter.add(Calendar.DATE, 1);
  1409. }
  1410. reenter.set(Calendar.HOUR_OF_DAY, RESET_HOUR);
  1411. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_S1_RESTRICTED);
  1412. sm.addInstanceName(world.getTemplateId());
  1413. // set instance reenter time for all allowed players
  1414. for (int objectId : world.getAllowed())
  1415. {
  1416. L2PcInstance obj = L2World.getInstance().getPlayer(objectId);
  1417. if ((obj != null) && obj.isOnline())
  1418. {
  1419. InstanceManager.getInstance().setInstanceTime(objectId, world.getTemplateId(), reenter.getTimeInMillis());
  1420. obj.sendPacket(sm);
  1421. }
  1422. }
  1423. // destroy instance after EXIT_TIME
  1424. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1425. inst.setDuration(EXIT_TIME * 60000);
  1426. inst.setEmptyDestroyTime(0);
  1427. }
  1428. }
  1429. /**
  1430. * Spawn all NPCs in kamaloka
  1431. * @param world instanceWorld
  1432. */
  1433. @SuppressWarnings("all")
  1434. private final void spawnKama(KamaWorld world)
  1435. {
  1436. int[] npcs;
  1437. int[][] spawns;
  1438. L2Npc npc;
  1439. final int index = world.index;
  1440. // first room
  1441. npcs = FIRST_ROOM[index];
  1442. spawns = FIRST_ROOM_SPAWNS[index];
  1443. if (npcs != null)
  1444. {
  1445. world.firstRoom = new ArrayList<L2Spawn>(spawns.length - 1);
  1446. int shaman = getRandom(spawns.length); // random position for shaman
  1447. for (int i = 0; i < spawns.length; i++)
  1448. {
  1449. if (i == shaman)
  1450. {
  1451. // stealth shaman use same npcId as other mobs
  1452. npc = addSpawn(STEALTH_SHAMAN ? npcs[1] : npcs[0], spawns[i][0], spawns[i][1], spawns[i][2], 0, false, 0, false, world.getInstanceId());
  1453. world.shaman = npc.getObjectId();
  1454. }
  1455. else
  1456. {
  1457. npc = addSpawn(npcs[1], spawns[i][0], spawns[i][1], spawns[i][2], 0, false, 0, false, world.getInstanceId());
  1458. L2Spawn spawn = npc.getSpawn();
  1459. spawn.setRespawnDelay(FIRST_ROOM_RESPAWN_DELAY);
  1460. spawn.setAmount(1);
  1461. spawn.startRespawn();
  1462. world.firstRoom.add(spawn); // store mobs spawns
  1463. }
  1464. npc.setIsNoRndWalk(true);
  1465. }
  1466. }
  1467. // second room
  1468. npcs = SECOND_ROOM[index];
  1469. spawns = SECOND_ROOM_SPAWNS[index];
  1470. if (npcs != null)
  1471. {
  1472. world.secondRoom = new ArrayList<Integer>(spawns.length);
  1473. for (int[] spawn : spawns)
  1474. {
  1475. npc = addSpawn(npcs[0], spawn[0], spawn[1], spawn[2], 0, false, 0, false, world.getInstanceId());
  1476. npc.setIsNoRndWalk(true);
  1477. world.secondRoom.add(npc.getObjectId());
  1478. }
  1479. }
  1480. // miniboss
  1481. if (MINIBOSS[index] != null)
  1482. {
  1483. npc = addSpawn(MINIBOSS[index][0], MINIBOSS[index][1], MINIBOSS[index][2], MINIBOSS[index][3], 0, false, 0, false, world.getInstanceId());
  1484. npc.setIsNoRndWalk(true);
  1485. world.miniBoss = npc.getObjectId();
  1486. }
  1487. // escape teleporter
  1488. if (TELEPORTERS[index] != null)
  1489. {
  1490. addSpawn(TELEPORTER, TELEPORTERS[index][0], TELEPORTERS[index][1], TELEPORTERS[index][2], 0, false, 0, false, world.getInstanceId());
  1491. }
  1492. // boss
  1493. npc = addSpawn(BOSS[index][0], BOSS[index][1], BOSS[index][2], BOSS[index][3], 0, false, 0, false, world.getInstanceId());
  1494. ((L2MonsterInstance) npc).setOnKillDelay(100);
  1495. world.boss = npc;
  1496. }
  1497. /**
  1498. * Handles only player's enter, single parameter - integer kamaloka index
  1499. */
  1500. @Override
  1501. public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  1502. {
  1503. if (npc == null)
  1504. {
  1505. return "";
  1506. }
  1507. try
  1508. {
  1509. enterInstance(player, Integer.parseInt(event));
  1510. }
  1511. catch (Exception e)
  1512. {
  1513. _log.log(Level.WARNING, "", e);
  1514. }
  1515. return "";
  1516. }
  1517. /**
  1518. * Talk with captains and using of the escape teleporter
  1519. */
  1520. @Override
  1521. public final String onTalk(L2Npc npc, L2PcInstance player)
  1522. {
  1523. final int npcId = npc.getId();
  1524. if (npcId == TELEPORTER)
  1525. {
  1526. final L2Party party = player.getParty();
  1527. // only party leader can talk with escape teleporter
  1528. if ((party != null) && party.isLeader(player))
  1529. {
  1530. final InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
  1531. if (world instanceof KamaWorld)
  1532. {
  1533. // party members must be in the instance
  1534. if (world.isAllowed(player.getObjectId()))
  1535. {
  1536. Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
  1537. // teleports entire party away
  1538. for (L2PcInstance partyMember : party.getMembers())
  1539. {
  1540. if ((partyMember != null) && (partyMember.getInstanceId() == world.getInstanceId()))
  1541. {
  1542. teleportPlayer(partyMember, inst.getSpawnLoc(), 0);
  1543. }
  1544. }
  1545. }
  1546. }
  1547. }
  1548. }
  1549. else
  1550. {
  1551. return npcId + ".htm";
  1552. }
  1553. return "";
  1554. }
  1555. /**
  1556. * Only escape teleporters first talk handled
  1557. */
  1558. @Override
  1559. public final String onFirstTalk(L2Npc npc, L2PcInstance player)
  1560. {
  1561. if (npc.getId() == TELEPORTER)
  1562. {
  1563. if (player.isInParty() && player.getParty().isLeader(player))
  1564. {
  1565. return "32496.htm";
  1566. }
  1567. return "32496-no.htm";
  1568. }
  1569. return "";
  1570. }
  1571. @Override
  1572. public final String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
  1573. {
  1574. final InstanceWorld tmpWorld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
  1575. if (tmpWorld instanceof KamaWorld)
  1576. {
  1577. final KamaWorld world = (KamaWorld) tmpWorld;
  1578. final int objectId = npc.getObjectId();
  1579. // first room was spawned ?
  1580. if (world.firstRoom != null)
  1581. {
  1582. // is shaman killed ?
  1583. if ((world.shaman != 0) && (world.shaman == objectId))
  1584. {
  1585. world.shaman = 0;
  1586. // stop respawn of the minions
  1587. for (L2Spawn spawn : world.firstRoom)
  1588. {
  1589. if (spawn != null)
  1590. {
  1591. spawn.stopRespawn();
  1592. }
  1593. }
  1594. world.firstRoom.clear();
  1595. world.firstRoom = null;
  1596. if (world.boss != null)
  1597. {
  1598. final int skillId = FIRST_ROOM[world.index][2];
  1599. final int skillLvl = FIRST_ROOM[world.index][3];
  1600. if ((skillId != 0) && (skillLvl != 0))
  1601. {
  1602. final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
  1603. if (skill != null)
  1604. {
  1605. skill.applyEffects(world.boss, world.boss);
  1606. }
  1607. }
  1608. }
  1609. return super.onKill(npc, player, isSummon);
  1610. }
  1611. }
  1612. // second room was spawned ?
  1613. if (world.secondRoom != null)
  1614. {
  1615. boolean all = true;
  1616. // check for all mobs in the second room
  1617. for (int i = 0; i < world.secondRoom.size(); i++)
  1618. {
  1619. // found killed now mob
  1620. if (world.secondRoom.get(i) == objectId)
  1621. {
  1622. world.secondRoom.set(i, 0);
  1623. }
  1624. else if (world.secondRoom.get(i) != 0)
  1625. {
  1626. all = false;
  1627. }
  1628. }
  1629. // all mobs killed ?
  1630. if (all)
  1631. {
  1632. world.secondRoom.clear();
  1633. world.secondRoom = null;
  1634. if (world.boss != null)
  1635. {
  1636. final int skillId = SECOND_ROOM[world.index][1];
  1637. final int skillLvl = SECOND_ROOM[world.index][2];
  1638. if ((skillId != 0) && (skillLvl != 0))
  1639. {
  1640. final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
  1641. if (skill != null)
  1642. {
  1643. skill.applyEffects(world.boss, world.boss);
  1644. }
  1645. }
  1646. }
  1647. return super.onKill(npc, player, isSummon);
  1648. }
  1649. }
  1650. // miniboss spawned ?
  1651. if ((world.miniBoss != 0) && (world.miniBoss == objectId))
  1652. {
  1653. world.miniBoss = 0;
  1654. if (world.boss != null)
  1655. {
  1656. final int skillId = MINIBOSS[world.index][4];
  1657. final int skillLvl = MINIBOSS[world.index][5];
  1658. if ((skillId != 0) && (skillLvl != 0))
  1659. {
  1660. final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
  1661. if (skill != null)
  1662. {
  1663. skill.applyEffects(world.boss, world.boss);
  1664. }
  1665. }
  1666. }
  1667. return super.onKill(npc, player, isSummon);
  1668. }
  1669. // boss was killed, finish instance
  1670. if ((world.boss != null) && (world.boss == npc))
  1671. {
  1672. world.boss = null;
  1673. finishInstance(world);
  1674. }
  1675. }
  1676. return super.onKill(npc, player, isSummon);
  1677. }
  1678. public static void main(String[] args)
  1679. {
  1680. new Kamaloka();
  1681. }
  1682. }