Advertisement
Guest User

Battle_With_Keber_v03.patch

a guest
Oct 24th, 2022
790
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.51 KB | None | 0 0
  1. Index: dist/game/data/stats/npcs/18500-18599.xml
  2. IDEA additional info:
  3. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  4. <+>UTF-8
  5. ===================================================================
  6. diff --git a/dist/game/data/stats/npcs/18500-18599.xml b/dist/game/data/stats/npcs/18500-18599.xml
  7. --- a/dist/game/data/stats/npcs/18500-18599.xml
  8. +++ b/dist/game/data/stats/npcs/18500-18599.xml (date 1660042100604)
  9. @@ -1137,6 +1137,10 @@
  10. <item id="57" min="439" max="485" chance="100" /> <!-- Adena -->
  11. </drop>
  12. </dropLists>
  13. + <skillList>
  14. + <skill id="4416" level="6" /> <!-- Humanoids -->
  15. + <skill id="4408" level="10" /> <!-- HP Increase 2x -->
  16. + </skillList>
  17. </npc>
  18. <npc id="18540" level="63" type="Monster" name="Kishan's Minion" title="Elite">
  19. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  20. @@ -1164,6 +1168,10 @@
  21. <item id="57" min="1171" max="1295" chance="100" /> <!-- Adena -->
  22. </drop>
  23. </dropLists>
  24. + <skillList>
  25. + <skill id="4416" level="6" /> <!-- Humanoids -->
  26. + <skill id="4408" level="10" /> <!-- HP Increase 2x -->
  27. + </skillList>
  28. </npc>
  29. <npc id="18541" level="63" type="Monster" name="Kishan's Minion" title="Brainwashed">
  30. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  31. @@ -1186,6 +1194,9 @@
  32. <radius normal="9" />
  33. <height normal="41.5" />
  34. </collision>
  35. + <skillList>
  36. + <skill id="4416" level="6" /> <!-- Humanoids -->
  37. + </skillList>
  38. </npc>
  39. <npc id="18542" level="69" type="RaidBoss" name="Noma" title="Keber's Henchman">
  40. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  41. @@ -1207,6 +1218,10 @@
  42. <radius normal="35" />
  43. <height normal="48.1" />
  44. </collision>
  45. + <skillList>
  46. + <skill id="4416" level="6" /> <!-- Humanoids -->
  47. + <skill id="4408" level="12" /> <!-- HP Increase 4x -->
  48. + </skillList>
  49. </npc>
  50. <npc id="18543" level="69" type="Monster" name="Noma's Minion">
  51. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  52. @@ -1234,6 +1249,10 @@
  53. <item id="57" min="836" max="924" chance="100" /> <!-- Adena -->
  54. </drop>
  55. </dropLists>
  56. + <skillList>
  57. + <skill id="4416" level="11" /> <!-- Giants -->
  58. + <skill id="4408" level="10" /> <!-- HP Increase 2x -->
  59. + </skillList>
  60. </npc>
  61. <npc id="18544" level="69" type="Monster" name="Noma's Minion" title="Elite">
  62. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  63. @@ -1260,6 +1279,10 @@
  64. <item id="57" min="2233" max="2468" chance="100" /> <!-- Adena -->
  65. </drop>
  66. </dropLists>
  67. + <skillList>
  68. + <skill id="4416" level="11" /> <!-- Giants -->
  69. + <skill id="4408" level="10" /> <!-- HP Increase 2x -->
  70. + </skillList>
  71. </npc>
  72. <npc id="18545" level="69" type="Monster" name="Noma's Minion" title="Brainwashed">
  73. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  74. @@ -1282,6 +1305,9 @@
  75. <radius normal="15" />
  76. <height normal="40" />
  77. </collision>
  78. + <skillList>
  79. + <skill id="4416" level="11" /> <!-- Giants -->
  80. + </skillList>
  81. </npc>
  82. <npc id="18546" level="75" type="RaidBoss" name="Spall" title="Keber's Henchman">
  83. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  84. @@ -1303,6 +1329,10 @@
  85. <radius normal="36.3" />
  86. <height normal="65.2" />
  87. </collision>
  88. + <skillList>
  89. + <skill id="4416" level="11" /> <!-- Giants -->
  90. + <skill id="4408" level="12" /> <!-- HP Increase 4x -->
  91. + </skillList>
  92. </npc>
  93. <npc id="18547" level="75" type="Monster" name="Spall's Minion">
  94. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  95. @@ -1329,6 +1359,10 @@
  96. <item id="57" min="1188" max="1313" chance="100" /> <!-- Adena -->
  97. </drop>
  98. </dropLists>
  99. + <skillList>
  100. + <skill id="4416" level="6" /> <!-- Humanoids -->
  101. + <skill id="4408" level="10" /> <!-- HP Increase 2x -->
  102. + </skillList>
  103. </npc>
  104. <npc id="18548" level="75" type="Monster" name="Spall's Minion" title="Elite">
  105. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  106. @@ -1355,6 +1389,10 @@
  107. <item id="57" min="3135" max="3465" chance="100" /> <!-- Adena -->
  108. </drop>
  109. </dropLists>
  110. + <skillList>
  111. + <skill id="4416" level="6" /> <!-- Humanoids -->
  112. + <skill id="4408" level="10" /> <!-- HP Increase 2x -->
  113. + </skillList>
  114. </npc>
  115. <npc id="18549" level="75" type="Monster" name="Spall's Minion" title="Brainwashed">
  116. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  117. @@ -1376,6 +1414,9 @@
  118. <radius normal="30.8" />
  119. <height normal="51.065" />
  120. </collision>
  121. + <skillList>
  122. + <skill id="4416" level="6" /> <!-- Humanoids -->
  123. + </skillList>
  124. </npc>
  125. <npc id="18550" level="85" type="Folk" name="">
  126. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  127. @@ -1396,8 +1437,7 @@
  128. <height normal="0.1" />
  129. </collision>
  130. </npc>
  131. - <npc id="18551" level="80" type="Monster" name="Keber's Seal Stone">
  132. - <!-- AUTO GENERATED NPC TODO: FIX IT -->
  133. + <npc id="18551" level="80" type="Folk" name="Keber's Seal Stone">
  134. <race>ETC</race>
  135. <sex>MALE</sex>
  136. <acquire exp="5786" />
  137. @@ -1411,11 +1451,14 @@
  138. </speed>
  139. <hitTime>600</hitTime>
  140. </stats>
  141. - <status attackable="true" />
  142. + <status attackable="false" randomWalk="false" targetable="false" talkable="false" undying="true" showName="false" />
  143. <collision>
  144. <radius normal="25" />
  145. <height normal="62.5" />
  146. </collision>
  147. + <skillList>
  148. + <skill id="4416" level="2" /> <!-- Magical Creatures -->
  149. + </skillList>
  150. </npc>
  151. <npc id="18552" level="69" type="RaidBoss" name="Keber" title="Maddened">
  152. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  153. @@ -1437,6 +1480,10 @@
  154. <radius normal="60" />
  155. <height normal="99.5" />
  156. </collision>
  157. + <skillList>
  158. + <skill id="4416" level="7" /> <!-- Spirits -->
  159. + <skill id="4408" level="12" /> <!-- HP Increase 4x -->
  160. + </skillList>
  161. </npc>
  162. <npc id="18553" level="75" type="RaidBoss" name="Keber" title="Maddened">
  163. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  164. @@ -1458,6 +1505,10 @@
  165. <radius normal="60" />
  166. <height normal="99.5" />
  167. </collision>
  168. + <skillList>
  169. + <skill id="4416" level="7" /> <!-- Spirits -->
  170. + <skill id="4408" level="12" /> <!-- HP Increase 4x -->
  171. + </skillList>
  172. </npc>
  173. <npc id="18554" level="85" type="Monster" name="Otherworldly Shard" title="Full of Energy">
  174. <!-- AUTO GENERATED NPC TODO: FIX IT -->
  175. Index: dist/game/data/stats/npcs/34200-34299.xml
  176. IDEA additional info:
  177. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  178. <+>UTF-8
  179. ===================================================================
  180. diff --git a/dist/game/data/stats/npcs/34200-34299.xml b/dist/game/data/stats/npcs/34200-34299.xml
  181. --- a/dist/game/data/stats/npcs/34200-34299.xml
  182. +++ b/dist/game/data/stats/npcs/34200-34299.xml (date 1660042163538)
  183. @@ -431,13 +431,13 @@
  184. </attribute>
  185. <abnormalResist physical="0" magical="0" />
  186. </stats>
  187. - <status attackable="false" undying="true" canMove="false" targetable="false" showName="false" />
  188. + <status attackable="false" undying="true" canMove="false" targetable="true" showName="true" />
  189. <collision>
  190. <radius normal="11" />
  191. <height normal="17" />
  192. </collision>
  193. <skillList>
  194. - <skill id="4416" level="2" /> <!-- Magical Creatures -->
  195. + <skill id="4416" level="18" /> <!-- Dwarves -->
  196. <skill id="4408" level="1" /> <!-- HP Increase (1x) -->
  197. <skill id="4409" level="1" /> <!-- MP Increase (1x) -->
  198. <skill id="4410" level="11" /> <!-- Average Damage Dealer -->
  199. Index: dist/game/data/spawns/Event/BattleWithKeber.xml
  200. IDEA additional info:
  201. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  202. <+>UTF-8
  203. ===================================================================
  204. diff --git a/dist/game/data/spawns/Event/BattleWithKeber.xml b/dist/game/data/spawns/Event/BattleWithKeber.xml
  205. new file mode 100644
  206. --- /dev/null (date 1660037887187)
  207. +++ b/dist/game/data/spawns/Event/BattleWithKeber.xml (date 1660037887187)
  208. @@ -0,0 +1,42 @@
  209. +<?xml version="1.0" encoding="UTF-8"?>
  210. +<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/spawns.xsd">
  211. + <spawn name="KEBER_MINIONS" spawnByDefault="false" >
  212. + <group name="KISHAN" spawnByDefault="false" >
  213. + <territories>
  214. + <territory shape="NPoly" rad="1" minZ="-4200" maxZ="-3900">
  215. + <node x="132014" y="8285"/>
  216. + <node x="131835" y="7488"/>
  217. + <node x="133928" y="6075"/>
  218. + <node x="134502" y="6557"/>
  219. + <node x="134451" y="7720"/>
  220. + <node x="133914" y="8721"/>
  221. + </territory>
  222. + </territories>
  223. + <npc id="18539" count="100" respawnTime="10sec" respawnRandom="0sec" /> <!-- Kishan's Minion -->
  224. + </group>
  225. + <group name="NOMA" spawnByDefault="false" >
  226. + <territories>
  227. + <territory shape="NPoly" rad="1" minZ="-3740" maxZ="-3700">
  228. + <node x="160635" y="21541"/>
  229. + <node x="161147" y="20888"/>
  230. + <node x="162234" y="20084"/>
  231. + <node x="161978" y="23005"/>
  232. + <node x="162910" y="23084"/>
  233. + <node x="163398" y="22379"/>
  234. + <node x="163727" y="23411"/>
  235. + <node x="162218" y="23713"/>
  236. + <node x="161268" y="23180"/>
  237. + </territory>
  238. + </territories>
  239. + <npc id="18543" count="120" respawnTime="10sec" respawnRandom="0sec" /> <!-- Noma's Minion -->
  240. + </group>
  241. + <group name="SPALL" spawnByDefault="false" >
  242. + <territories>
  243. + <territory shape="Cylinder" rad="700" minZ="-6100" maxZ="-6000">
  244. + <node x="180942" y="52673"/>
  245. + </territory>
  246. + </territories>
  247. + <npc id="18547" count="80" respawnTime="10sec" respawnRandom="0sec" /> <!-- Spall's Minion -->
  248. + </group>
  249. + </spawn>
  250. +</list>
  251. Index: dist/game/data/scripts/events/BattleWithKeber/config.xml
  252. IDEA additional info:
  253. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  254. <+>UTF-8
  255. ===================================================================
  256. diff --git a/dist/game/data/scripts/events/BattleWithKeber/config.xml b/dist/game/data/scripts/events/BattleWithKeber/config.xml
  257. new file mode 100644
  258. --- /dev/null (date 1660035394386)
  259. +++ b/dist/game/data/scripts/events/BattleWithKeber/config.xml (date 1660035394386)
  260. @@ -0,0 +1,11 @@
  261. +<?xml version="1.0" encoding="UTF-8"?>
  262. +<event name="Battle With Keber" active="19 08 2020-16 10 2029" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../xsd/eventConfig.xsd">
  263. + <spawnlist>
  264. + <add npc="34216" x="146966" y="25726" z="-2020" heading="6133" /> <!-- Bonnie -->
  265. + <add npc="34216" x="83673" y="148857" z="-3413" heading="29500" /> <!-- Bonnie -->
  266. + <!-- ETC -->
  267. + <add npc="18551" x="133474" y="7730" z="-4320" heading="0" /> <!-- Keber's Seal Stone / Plains of Glory -->
  268. + <add npc="18551" x="161481" y="22041" z="-3696" heading="0" /> <!-- Keber's Seal Stone / War-Torn Plains -->
  269. + <add npc="18551" x="180942" y="52673" z="-6100" heading="0" /> <!-- Keber's Seal Stone / Silent Valley -->
  270. + </spawnlist>
  271. +</event>
  272. \ No newline at end of file
  273. Index: dist/game/data/scripts/events/BattleWithKeber/34216-01.html
  274. IDEA additional info:
  275. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  276. <+>UTF-8
  277. ===================================================================
  278. diff --git a/dist/game/data/scripts/events/BattleWithKeber/34216-01.html b/dist/game/data/scripts/events/BattleWithKeber/34216-01.html
  279. new file mode 100644
  280. --- /dev/null (date 1659911243198)
  281. +++ b/dist/game/data/scripts/events/BattleWithKeber/34216-01.html (date 1659911243198)
  282. @@ -0,0 +1,14 @@
  283. +<html><body>Event Manager Bonnie:
  284. +<br>
  285. +Hey, you! You're right, I'm talking you!
  286. +<br>
  287. +Do you know we have a new problem? It's <font color="LEVEL">Keber</font>!
  288. +&nbsp;He threatens to Aden.
  289. +&nbsp;They say Keber and his lackeys appear
  290. +&nbsp;<font color="LEVEL">every hour</font> on the <font color="LEVEL">Plains of Glory, War-Torn Plains and in the Silent Valley</font>.
  291. +<br>
  292. +If you defeat Keber and his servants, you can get <font color="LEVEL">Talisman of Aden</font>.
  293. +&nbsp;I can teleport you to the villain. Do to want to go?
  294. +<br>
  295. +<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest BattleWithKeber 34216-02.html">"I'll go right now"</Button>
  296. +</body></html>
  297. \ No newline at end of file
  298. Index: dist/game/data/scripts/events/BattleWithKeber/34216-02.html
  299. IDEA additional info:
  300. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  301. <+>UTF-8
  302. ===================================================================
  303. diff --git a/dist/game/data/scripts/events/BattleWithKeber/34216-02.html b/dist/game/data/scripts/events/BattleWithKeber/34216-02.html
  304. new file mode 100644
  305. --- /dev/null (date 1659911213566)
  306. +++ b/dist/game/data/scripts/events/BattleWithKeber/34216-02.html (date 1659911213566)
  307. @@ -0,0 +1,8 @@
  308. +<html><body>Event Manager Bonnie:
  309. +<br>
  310. +If you don't have time to get to the destination by yourself, I can teleport you. Of course, it's not for free. Where do to want to go?
  311. +<br>
  312. +<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest BattleWithKeber TELEPORT_01">Plains of Glory (%n1% adena)</Button>
  313. +<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest BattleWithKeber TELEPORT_02">War-Torn Plains (%n2% adena)</Button>
  314. +<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest BattleWithKeber TELEPORT_03">Silent Valley (%n3% adena)</Button>
  315. +</body></html>
  316. \ No newline at end of file
  317. Index: dist/game/data/scripts/events/BattleWithKeber/34216-03.html
  318. IDEA additional info:
  319. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  320. <+>UTF-8
  321. ===================================================================
  322. diff --git a/dist/game/data/scripts/events/BattleWithKeber/34216-03.html b/dist/game/data/scripts/events/BattleWithKeber/34216-03.html
  323. new file mode 100644
  324. --- /dev/null (date 1659911243213)
  325. +++ b/dist/game/data/scripts/events/BattleWithKeber/34216-03.html (date 1659911243213)
  326. @@ -0,0 +1,4 @@
  327. +<html><body>Event Manager Bonnie:
  328. +<br>
  329. +Good luck! I hope you will defeat Keber.
  330. +</body></html>
  331. \ No newline at end of file
  332. Index: dist/game/data/scripts/events/BattleWithKeber/34216-04.html
  333. IDEA additional info:
  334. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  335. <+>UTF-8
  336. ===================================================================
  337. diff --git a/dist/game/data/scripts/events/BattleWithKeber/34216-04.html b/dist/game/data/scripts/events/BattleWithKeber/34216-04.html
  338. new file mode 100644
  339. --- /dev/null (date 1659911243206)
  340. +++ b/dist/game/data/scripts/events/BattleWithKeber/34216-04.html (date 1659911243206)
  341. @@ -0,0 +1,4 @@
  342. +<html><body>Event Manager Bonnie:
  343. +<br>
  344. +You don't have enough adena. Check your pockets once again!
  345. +</body></html>
  346. \ No newline at end of file
  347. Index: dist/game/data/scripts/events/BattleWithKeber/BattleWithKeber.java
  348. IDEA additional info:
  349. Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  350. <+>UTF-8
  351. ===================================================================
  352. diff --git a/dist/game/data/scripts/events/BattleWithKeber/BattleWithKeber.java b/dist/game/data/scripts/events/BattleWithKeber/BattleWithKeber.java
  353. new file mode 100644
  354. --- /dev/null (date 1660045003127)
  355. +++ b/dist/game/data/scripts/events/BattleWithKeber/BattleWithKeber.java (date 1660045003127)
  356. @@ -0,0 +1,472 @@
  357. +/*
  358. + * This file is part of the L2J Mobius project.
  359. + *
  360. + * This program is free software: you can redistribute it and/or modify
  361. + * it under the terms of the GNU General Public License as published by
  362. + * the Free Software Foundation, either version 3 of the License, or
  363. + * (at your option) any later version.
  364. + *
  365. + * This program is distributed in the hope that it will be useful,
  366. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  367. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  368. + * General Public License for more details.
  369. + *
  370. + * You should have received a copy of the GNU General Public License
  371. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  372. + */
  373. +package events.BattleWithKeber;
  374. +
  375. +import org.l2jmobius.commons.util.Rnd;
  376. +import org.l2jmobius.gameserver.data.xml.SpawnData;
  377. +import org.l2jmobius.gameserver.model.Location;
  378. +import org.l2jmobius.gameserver.model.World;
  379. +import org.l2jmobius.gameserver.model.WorldObject;
  380. +import org.l2jmobius.gameserver.model.actor.Npc;
  381. +import org.l2jmobius.gameserver.model.actor.Player;
  382. +import org.l2jmobius.gameserver.model.holders.ItemChanceHolder;
  383. +import org.l2jmobius.gameserver.model.quest.LongTimeEvent;
  384. +import org.l2jmobius.gameserver.model.spawns.SpawnGroup;
  385. +import org.l2jmobius.gameserver.model.spawns.SpawnTemplate;
  386. +import org.l2jmobius.gameserver.network.NpcStringId;
  387. +import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
  388. +import org.l2jmobius.gameserver.util.Broadcast;
  389. +
  390. +import java.util.ArrayList;
  391. +import java.util.Calendar;
  392. +import java.util.HashSet;
  393. +import java.util.LinkedList;
  394. +import java.util.List;
  395. +import java.util.Map;
  396. +import java.util.Set;
  397. +import java.util.concurrent.atomic.AtomicIntegerArray;
  398. +import java.util.concurrent.atomic.AtomicReference;
  399. +
  400. +/**
  401. + * @author Index
  402. + */
  403. +public class BattleWithKeber extends LongTimeEvent
  404. +{
  405. + // NPCs
  406. + private static final int BONNIE = 34216;
  407. + private final static int KEBER_SEAL_STONE = 18551;
  408. + // Locations from Bonnie teleport
  409. + private final static Location PLAINS_OF_GLORY_TP = new Location(133994, 7136, -4352);
  410. + private final static Location WAR_TORN_PLAINS_TP = new Location(161658, 21299, -3672);
  411. + private final static Location SILENT_VALLEY_TP = new Location(181645, 52823, -6112);
  412. + // Spawn locations for monsters
  413. + // private final static Location PLAINS_OF_GLORY_BOSS = new Location(133423, 7354, -4400);
  414. + private final static Location PLAINS_OF_GLORY_BOSS = new Location(132573, 7865, -4300);
  415. + private final static Location WAR_TORN_PLAINS_BOSS = new Location(161205, 21680, -3680);
  416. + private final static Location SILENT_VALLEY_BOSS = new Location(180640, 52824, -6096);
  417. + // Monsters
  418. + private final static int KEBER_LOW = 18537; // 63
  419. + private final static int KEBER_MIDDLE = 18552; // 69
  420. + private final static int KEBER_HIGH = 18553; // 75
  421. + private final static int KISHAN = 18538; // 63
  422. + private final static int NOMA = 18542; // 69
  423. + private final static int SPALL = 18546; // 75
  424. + private final static Set<Integer> BOSS_SET_FOR_CHECK = Set.of(KEBER_LOW, KEBER_MIDDLE, KEBER_HIGH, KISHAN, NOMA, SPALL);
  425. + private final static List<Integer> NORMAL_MINIONS = new LinkedList<>(List.of(18539, 18543, 18547));
  426. + private final static List<Integer> ELITE_MINIONS = new LinkedList<>(List.of(18540, 18544, 18548));
  427. + private final static List<Integer> BRAINWASHED_MINIONS = new LinkedList<>(List.of(18541, 18545, 18549));
  428. + // Drop
  429. + private final static Set<ItemChanceHolder> KEBER_LOW_DROP = Set.of(
  430. + new ItemChanceHolder(57, 100, 525_000), // Adeba x525 000
  431. + new ItemChanceHolder(91767, 100, 1), // Enchant Kit: Talisman of Aden x2
  432. + new ItemChanceHolder(94481, 100, 150) // Clan XP x150
  433. + );
  434. + private final static Set<ItemChanceHolder> KEBER_MIDDLE_DROP = Set.of(
  435. + new ItemChanceHolder(57, 100, 725_000), // Adeba 725 000
  436. + new ItemChanceHolder(91767, 100, 1), // Enchant Kit: Talisman of Aden x2
  437. + new ItemChanceHolder(94481, 100, 150) // Clan XP x150
  438. + );
  439. + private final static Set<ItemChanceHolder> KEBER_HIGH_DROP = Set.of(
  440. + new ItemChanceHolder(57, 100, 925_000), // Adeba x925 000
  441. + new ItemChanceHolder(91767, 100, 1), // Enchant Kit: Talisman of Aden x2
  442. + new ItemChanceHolder(94481, 100, 150) // Clan XP x150
  443. + );
  444. + private final static Set<ItemChanceHolder> KISHAN_DROP = Set.of(
  445. + new ItemChanceHolder(57, 100, 45_000), // Adeba x45 000
  446. + new ItemChanceHolder(91767, 100, 1), // Enchant Kit: Talisman of Aden x1
  447. + new ItemChanceHolder(94481, 100, 50) // Clan XP x50
  448. + );
  449. + private final static Set<ItemChanceHolder> NOMA_DROP = Set.of(
  450. + new ItemChanceHolder(57, 100, 55_000), // Adeba x55 000
  451. + new ItemChanceHolder(91767, 100, 1), // Enchant Kit: Talisman of Aden x1
  452. + new ItemChanceHolder(94481, 100, 50) // Clan XP x50
  453. + );
  454. + private final static Set<ItemChanceHolder> SPALL_DROP = Set.of(
  455. + new ItemChanceHolder(57, 100, 65_000), // Adeba x55 000
  456. + new ItemChanceHolder(91767, 100, 1), // Enchant Kit: Talisman of Aden x1
  457. + new ItemChanceHolder(94481, 100, 50) // Clan XP x50
  458. + );
  459. + private final static Set<ItemChanceHolder> MINION_DROP = Set.of(
  460. + new ItemChanceHolder(91767, 10, 1) // Enchant Kit: Talisman of Aden x1
  461. + );
  462. + Map<Integer, Set<ItemChanceHolder>> NPC_DROP = Map.of(
  463. + KEBER_LOW, KEBER_LOW_DROP,
  464. + KEBER_MIDDLE, KEBER_MIDDLE_DROP,
  465. + KEBER_HIGH, KEBER_HIGH_DROP,
  466. + KISHAN, KISHAN_DROP,
  467. + NOMA, NOMA_DROP,
  468. + SPALL, SPALL_DROP
  469. + );
  470. + // Misc
  471. + Map<Integer, NpcStringId> BROADCAST_MESSAGES = Map.of(
  472. + KEBER_LOW, NpcStringId.AHEM_YOU_DARE_TO_BOTHER_KEBER_YOU_WILL_SEE_NO_MERCY,
  473. + KEBER_MIDDLE, NpcStringId.AHEM_YOU_DARE_TO_BOTHER_KEBER_YOU_WILL_SEE_NO_MERCY,
  474. + KEBER_HIGH, NpcStringId.AHEM_YOU_DARE_TO_BOTHER_KEBER_YOU_WILL_SEE_NO_MERCY,
  475. + KISHAN, NpcStringId.KISHAN_MY_SERVANT_ATTACK,
  476. + NOMA, NpcStringId.NOMA_MY_SERVANT_ATTACK,
  477. + SPALL, NpcStringId.SPALL_MY_SERVANT_ATTACK,
  478. + EVENT_MESSAGE_START, NpcStringId.MAKE_THE_SACRED_BLOOD_SACRIFICE_TO_KEBER_ATTACK,
  479. + EVENT_MESSAGE_KILL, NpcStringId.AH_YOU_ARE_INDEED_STRONG_S1_I_HAVE_TO_RETREAT_THIS_TIME,
  480. + EVENT_MESSAGE_TO_KILLER, NpcStringId.YOU_WILL_NOT_BE_FORGIVEN_I_WILL_BE_BACK_AND_YOU_LL_REGRET_IT,
  481. + EVENT_MESSAGE_WEAK, NpcStringId.LOOKS_LIKE_YOU_RE_WAY_TOO_WEAK_TO_BEAT_ME
  482. + );
  483. + private final static int EVENT_MESSAGE_START = -1;
  484. + private final static int EVENT_MESSAGE_KILL = -2;
  485. + private final static int EVENT_MESSAGE_TO_KILLER = -3;
  486. + private final static int EVENT_MESSAGE_WEAK = -4;
  487. + private final static int ELITE_MONSTER_COUNT = 200;
  488. + private final static int BRAINWASHED_MONSTER_COUNT = 100;
  489. + private final static int PLAINS_OF_GLORY_TP_COST = 2000;
  490. + private final static int WAR_TORN_PLAINS_TP_COST = 2500;
  491. + private final static int SILENT_VALLEY_TP_COST = 3000;
  492. + private final static AtomicIntegerArray MINION_KILL_COUNTER = new AtomicIntegerArray(3);
  493. + private final static AtomicReference<SpawnTemplate> SPAWN_TEMPLATE = new AtomicReference<>();
  494. + private final static AtomicIntegerArray MINION_MAX_COUNT = new AtomicIntegerArray(3);
  495. +
  496. + private BattleWithKeber()
  497. + {
  498. + if (isEventPeriod())
  499. + {
  500. + addFirstTalkId(BONNIE);
  501. + addTalkId(BONNIE);
  502. + addKillId(KEBER_LOW, KEBER_MIDDLE, KEBER_HIGH, KISHAN, NOMA, SPALL);
  503. + addKillId(NORMAL_MINIONS);
  504. + addKillId(ELITE_MINIONS);
  505. + addKillId(BRAINWASHED_MINIONS);
  506. + addSpawnId(KEBER_LOW, KEBER_MIDDLE, KEBER_HIGH, KISHAN, NOMA, SPALL);
  507. + addSpawnId(NORMAL_MINIONS);
  508. + addSpawnId(ELITE_MINIONS);
  509. + startQuestTimer("KEBER_EVENT_START", getMSTimeForEventStage(1), null, null);
  510. + SPAWN_TEMPLATE.set(SpawnData.getInstance().getSpawns().stream().filter(t -> t.getName() != null).filter(t -> t.getName().contains("KEBER_MINIONS")).findAny().orElse(null));
  511. + if (SPAWN_TEMPLATE.get() != null)
  512. + {
  513. + final String SPAWN_GROUP_KISHAN = "KISHAN";
  514. + final String SPAWN_GROUP_NOMA = "NOMA";
  515. + final String SPAWN_GROUP_SPALL = "SPALL";
  516. + MINION_MAX_COUNT.set(0, SPAWN_TEMPLATE.get().getGroups().stream().filter(g -> (g.getName() != null && g.getName().equalsIgnoreCase(SPAWN_GROUP_KISHAN))).findFirst().get().getSpawns().stream().findFirst().get().getCount());
  517. + MINION_MAX_COUNT.set(1, SPAWN_TEMPLATE.get().getGroups().stream().filter(g -> (g.getName() != null && g.getName().equalsIgnoreCase(SPAWN_GROUP_NOMA))).findFirst().get().getSpawns().stream().findFirst().get().getCount());
  518. + MINION_MAX_COUNT.set(2, SPAWN_TEMPLATE.get().getGroups().stream().filter(g -> (g.getName() != null && g.getName().equalsIgnoreCase(SPAWN_GROUP_SPALL))).findFirst().get().getSpawns().stream().findFirst().get().getCount());
  519. + }
  520. + }
  521. + }
  522. +
  523. + private long getMSTimeForEventStage(int type)
  524. + {
  525. + Calendar returnTime = Calendar.getInstance();
  526. + returnTime.set(Calendar.MILLISECOND, 0);
  527. + // returnTime.set(Calendar.SECOND, 0);
  528. + if (type == 1)
  529. + {
  530. + returnTime.set(Calendar.MINUTE, 0);
  531. + returnTime.add(Calendar.HOUR_OF_DAY, 1);
  532. + }
  533. + else if (type == 2)
  534. + {
  535. + returnTime.add(Calendar.MINUTE, 10);
  536. + }
  537. + else if (type == 3)
  538. + {
  539. + returnTime.add(Calendar.MINUTE, 5);
  540. + }
  541. + if (returnTime.getTimeInMillis() < System.currentTimeMillis())
  542. + {
  543. + returnTime.add(Calendar.DAY_OF_YEAR, 1);
  544. + }
  545. + return returnTime.getTimeInMillis() - System.currentTimeMillis();
  546. + }
  547. +
  548. + @Override
  549. + public String onKill(Npc npc, Player killer, boolean isSummon)
  550. + {
  551. + if (NORMAL_MINIONS.contains(npc.getId()) || ELITE_MINIONS.contains(npc.getId()))
  552. + {
  553. + final int type = getFieldType(npc.getId());
  554. + int count = MINION_KILL_COUNTER.get(type);
  555. + if (count >= ELITE_MONSTER_COUNT && ELITE_MINIONS.contains(npc.getId()))
  556. + {
  557. + MINION_KILL_COUNTER.addAndGet(type, 1);
  558. + }
  559. + else if (count < ELITE_MONSTER_COUNT)
  560. + {
  561. + MINION_KILL_COUNTER.addAndGet(type, 1);
  562. + }
  563. + }
  564. + else
  565. + {
  566. + Set<ItemChanceHolder> monsterDrop = (npc.getTemplate().getLevel() > killer.getLevel() - 15 && npc.getTemplate().getLevel() < killer.getLevel() + 15) ? NPC_DROP.getOrDefault(npc.getId(), MINION_DROP) : new HashSet<>();
  567. + for (ItemChanceHolder drop : monsterDrop)
  568. + {
  569. + if (Rnd.get(0, 100) <= drop.getChance())
  570. + {
  571. + if (drop.getId() == 94481 && killer.getClan() != null) // AVOID TO GET CLAN POINTS AS ITEM
  572. + {
  573. + killer.getClan().addExp(killer.getObjectId(), (int) drop.getCount());
  574. + }
  575. + else
  576. + {
  577. + killer.addItem(_eventName, drop.getId(), drop.getCount(), null, true);
  578. + }
  579. + }
  580. + }
  581. + if (BOSS_SET_FOR_CHECK.contains(npc.getId()))
  582. + {
  583. + final int type = getFieldType(npc.getId());
  584. + changeNPCSpawn(type, true, false);
  585. + Broadcast.toKnownPlayers(killer, new ExShowScreenMessage(BROADCAST_MESSAGES.get(EVENT_MESSAGE_KILL), ExShowScreenMessage.TOP_CENTER, 10000, killer.getName()));
  586. + killer.sendPacket(new ExShowScreenMessage(BROADCAST_MESSAGES.get(EVENT_MESSAGE_TO_KILLER), ExShowScreenMessage.TOP_CENTER, 5000));
  587. + for (Npc crystal : World.getInstance().getVisibleObjects(npc, Npc.class))
  588. + {
  589. + if (crystal.getId() == KEBER_SEAL_STONE)
  590. + {
  591. + crystal.setDisplayEffect(2); // remove effect
  592. + break;
  593. + }
  594. + }
  595. + }
  596. + }
  597. + return super.onKill(npc, killer, isSummon);
  598. + }
  599. +
  600. + @Override
  601. + public String onAdvEvent(String event, Npc npc, Player player)
  602. + {
  603. + switch (event)
  604. + {
  605. + case "34216-02.html":
  606. + {
  607. + String html = getHtm(player, "34216-02.html");
  608. + html = html.replace("%n1%", String.valueOf(PLAINS_OF_GLORY_TP_COST));
  609. + html = html.replace("%n2%", String.valueOf(WAR_TORN_PLAINS_TP_COST));
  610. + html = html.replace("%n3%", String.valueOf(SILENT_VALLEY_TP_COST));
  611. + return html;
  612. + }
  613. + case "TELEPORT_01":
  614. + case "TELEPORT_02":
  615. + case "TELEPORT_03":
  616. + {
  617. + long adena = player.getAdena();
  618. + byte requestLocation = Byte.parseByte(event.replace("TELEPORT_0", ""));
  619. + if (adena < (requestLocation == 1 ? PLAINS_OF_GLORY_TP_COST : requestLocation == 2 ? WAR_TORN_PLAINS_TP_COST : SILENT_VALLEY_TP_COST))
  620. + {
  621. + return "34216-04.html";
  622. + }
  623. + else
  624. + {
  625. + player.teleToLocation((requestLocation == 1 ? PLAINS_OF_GLORY_TP : requestLocation == 2 ? WAR_TORN_PLAINS_TP : SILENT_VALLEY_TP));
  626. + return "34216-03.html";
  627. + }
  628. + }
  629. + case "KEBER_EVENT_START":
  630. + {
  631. + List<WorldObject> objects = World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == KEBER_SEAL_STONE).toList();
  632. + for (Object crystal : objects)
  633. + {
  634. + ((Npc)crystal).setDisplayEffect(1); // add effect
  635. + Broadcast.toKnownPlayers(((Npc)crystal), new ExShowScreenMessage(BROADCAST_MESSAGES.get(EVENT_MESSAGE_START), ExShowScreenMessage.TOP_CENTER, 5000));
  636. + }
  637. + MINION_KILL_COUNTER.set(0, 0);
  638. + MINION_KILL_COUNTER.set(1, 0);
  639. + MINION_KILL_COUNTER.set(2, 0);
  640. + SPAWN_TEMPLATE.get().getGroups().forEach(SpawnGroup::spawnAll);
  641. + cancelQuestTimer("KEBER_EVENT_START", null, null);
  642. + startQuestTimer("KEBER_EVENT_BOSS_STAGE", getMSTimeForEventStage(2), null, null);
  643. + break;
  644. + }
  645. + case "KEBER_EVENT_BOSS_STAGE":
  646. + {
  647. + changeNPCSpawn(3, false, false);
  648. + for (int fieldType = 0; fieldType < 3; fieldType++)
  649. + {
  650. + final int summonedBossID = ((Rnd.get(0, 100) <= 50) ?
  651. + (fieldType == 0 ? KEBER_LOW : fieldType == 1 ? KEBER_MIDDLE : KEBER_HIGH) :
  652. + (fieldType == 0 ? KISHAN : fieldType == 1 ? NOMA : SPALL));
  653. + final Location spawnLoc = (fieldType == 0 ? PLAINS_OF_GLORY_BOSS : fieldType == 1 ? WAR_TORN_PLAINS_BOSS : SILENT_VALLEY_BOSS);
  654. + final long despawnTime = 5 * 60 * 1000; // 5 minute
  655. + addSpawn(summonedBossID, spawnLoc, false, despawnTime);
  656. + }
  657. + cancelQuestTimer("KEBER_EVENT_BOSS_STAGE", null, null);
  658. + startQuestTimer("KEBER_EVENT_END", getMSTimeForEventStage(3), null, null);
  659. + break;
  660. + }
  661. + case "KEBER_EVENT_END":
  662. + {
  663. + List<WorldObject> objects = World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == KEBER_SEAL_STONE).toList();
  664. + for (Object crystal : objects)
  665. + {
  666. + ((Npc)crystal).setDisplayEffect(2); // remove effect
  667. + for (Npc boss : World.getInstance().getVisibleObjects(((Npc) crystal), Npc.class))
  668. + {
  669. + if (BOSS_SET_FOR_CHECK.contains(boss.getId()) && !boss.isAlikeDead())
  670. + {
  671. + Broadcast.toKnownPlayers(((Npc)crystal), new ExShowScreenMessage(BROADCAST_MESSAGES.get(EVENT_MESSAGE_WEAK), ExShowScreenMessage.TOP_CENTER, 5000));
  672. + break;
  673. + }
  674. + }
  675. + }
  676. + cancelQuestTimer("KEBER_EVENT_END", null, null);
  677. + startQuestTimer("KEBER_EVENT_START", getMSTimeForEventStage(1), null, null);
  678. + changeNPCSpawn(3, true, true);
  679. + break;
  680. + }
  681. + }
  682. + return null;
  683. + }
  684. +
  685. + /**
  686. + * Because value hardcoded and I know all IDs, can use it for get fast access to any field monster
  687. + * @param npcID
  688. + * @return 0 - Plains; 1 - War-Torn; 2 - Silent Valley;
  689. + */
  690. + private int getFieldType(int npcID)
  691. + {
  692. + if (npcID == KEBER_LOW || npcID == KISHAN || npcID == NORMAL_MINIONS.get(0) || npcID == ELITE_MINIONS.get(0) || npcID == BRAINWASHED_MINIONS.get(0))
  693. + {
  694. + return 0;
  695. + }
  696. + else if (npcID == KEBER_MIDDLE || npcID == NOMA || npcID == NORMAL_MINIONS.get(1) || npcID == ELITE_MINIONS.get(1) || npcID == BRAINWASHED_MINIONS.get(1))
  697. + {
  698. + return 1;
  699. + }
  700. + else if (npcID == KEBER_HIGH || npcID == SPALL || npcID == NORMAL_MINIONS.get(2) || npcID == ELITE_MINIONS.get(2) || npcID == BRAINWASHED_MINIONS.get(2))
  701. + {
  702. + return 2;
  703. + }
  704. + return -1;
  705. + }
  706. + private void changeNPCSpawn(int type, boolean deleteNPCs, boolean removeAll)
  707. + {
  708. + List<WorldObject> objects = new ArrayList<>();
  709. + if (type == 0 || type >= 3)
  710. + {
  711. + if (!removeAll)
  712. + {
  713. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == NORMAL_MINIONS.get(0)).toList());
  714. + }
  715. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == ELITE_MINIONS.get(0)).toList());
  716. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == BRAINWASHED_MINIONS.get(0)).toList());
  717. + if (removeAll)
  718. + {
  719. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == KISHAN).toList());
  720. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == KEBER_LOW).toList());
  721. + }
  722. + }
  723. + if (type == 1 || type >= 3)
  724. + {
  725. + if (!removeAll)
  726. + {
  727. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == NORMAL_MINIONS.get(1)).toList());
  728. + }
  729. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == ELITE_MINIONS.get(1)).toList());
  730. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == BRAINWASHED_MINIONS.get(1)).toList());
  731. + if (removeAll)
  732. + {
  733. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == NOMA).toList());
  734. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == KEBER_MIDDLE).toList());
  735. + }
  736. + }
  737. + if (type == 2 || type >= 3)
  738. + {
  739. + if (!removeAll)
  740. + {
  741. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == NORMAL_MINIONS.get(2)).toList());
  742. + }
  743. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == ELITE_MINIONS.get(2)).toList());
  744. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == BRAINWASHED_MINIONS.get(2)).toList());
  745. + if (removeAll)
  746. + {
  747. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == SPALL).toList());
  748. + objects.addAll(World.getInstance().getVisibleObjects().stream().filter(WorldObject::isNpc).filter(wo -> wo.getId() == KEBER_HIGH).toList());
  749. + }
  750. + }
  751. + if (removeAll)
  752. + {
  753. + SPAWN_TEMPLATE.get().getGroups().forEach(SpawnGroup::despawnAll);
  754. + }
  755. + for (Object SelectedNPC : objects)
  756. + {
  757. + Npc monster = ((Npc) SelectedNPC);
  758. + monster.getSpawn().stopRespawn();
  759. + if (deleteNPCs)
  760. + {
  761. + if (BOSS_SET_FOR_CHECK.contains(monster.getTemplate().getId()) && monster.isAlikeDead())
  762. + {
  763. + continue;
  764. + }
  765. + monster.deleteMe();
  766. + }
  767. + }
  768. + }
  769. +
  770. + @Override
  771. + public String onSpawn(Npc npc)
  772. + {
  773. + final int type = getFieldType(npc.getId());
  774. + final boolean eventIsPending = getQuestTimer("KEBER_EVENT_START", null, null) != null && getQuestTimer("KEBER_EVENT_START", null, null).isActive();
  775. + final boolean eventOnBossStage = getQuestTimer("KEBER_EVENT_END", null, null) != null && getQuestTimer("KEBER_EVENT_END", null, null).isActive();
  776. + if (type != -1 && npc.getId() == NORMAL_MINIONS.get(type))
  777. + {
  778. + if (eventIsPending || eventOnBossStage)
  779. + {
  780. + npc.getSpawn().stopRespawn();
  781. + npc.deleteMe();
  782. + return super.onSpawn(npc);
  783. + }
  784. +
  785. + final int eliteMonsterID = ELITE_MINIONS.get(type);
  786. + final int brainWashedMonsterID = BRAINWASHED_MINIONS.get(type);
  787. + final int nearbyMonstersCount =
  788. + World.getInstance().getVisibleObjects(npc, Npc.class).stream().filter(nearby ->
  789. + (nearby.getId() == NORMAL_MINIONS.get(type) || nearby.getId() == eliteMonsterID || nearby.getId() == brainWashedMonsterID)
  790. + ).toList().size();
  791. + final int maxSpawnMonsters = MINION_MAX_COUNT.length() == 0 ? 0 : MINION_MAX_COUNT.get(type);
  792. + if (nearbyMonstersCount >= maxSpawnMonsters)
  793. + {
  794. + npc.deleteMe();
  795. + return super.onSpawn(npc);
  796. + }
  797. + final int killedCount = MINION_KILL_COUNTER.get(type);
  798. + if (killedCount >= ELITE_MONSTER_COUNT + BRAINWASHED_MONSTER_COUNT)
  799. + {
  800. + addSpawn(brainWashedMonsterID, npc.getLocation());
  801. + npc.deleteMe();
  802. + }
  803. + else if (killedCount >= ELITE_MONSTER_COUNT)
  804. + {
  805. + addSpawn(eliteMonsterID, npc.getLocation());
  806. + npc.deleteMe();
  807. + }
  808. + }
  809. + else if (BOSS_SET_FOR_CHECK.contains(npc.getId()))
  810. + {
  811. + // Broadcast to nearby players string which says "monster respawn"
  812. + Broadcast.toKnownPlayers(npc, new ExShowScreenMessage(BROADCAST_MESSAGES.get(npc.getId()), ExShowScreenMessage.TOP_CENTER, 5000));
  813. + World.getInstance().getVisibleObjects(npc, Player.class).stream().findAny().ifPresent(player -> addAttackPlayerDesire(npc, player));
  814. + }
  815. + return super.onSpawn(npc);
  816. + }
  817. +
  818. + @Override
  819. + public String onFirstTalk(Npc npc, Player player)
  820. + {
  821. + return "34216-01.html";
  822. + }
  823. +
  824. + public static void main(String[] args)
  825. + {
  826. + new BattleWithKeber();
  827. + }
  828. +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement