Antharas.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package ai.individual;
  16. import java.util.Collection;
  17. import java.util.List;
  18. import java.util.Map;
  19. import java.util.concurrent.ScheduledFuture;
  20. import javolution.util.FastList;
  21. import javolution.util.FastMap;
  22. import ai.npc.AbstractNpcAI;
  23. import com.l2jserver.Config;
  24. import com.l2jserver.gameserver.GeoData;
  25. import com.l2jserver.gameserver.ThreadPoolManager;
  26. import com.l2jserver.gameserver.ai.CtrlIntention;
  27. import com.l2jserver.gameserver.datatables.NpcTable;
  28. import com.l2jserver.gameserver.datatables.SkillTable;
  29. import com.l2jserver.gameserver.datatables.SpawnTable;
  30. import com.l2jserver.gameserver.instancemanager.GrandBossManager;
  31. import com.l2jserver.gameserver.model.L2CharPosition;
  32. import com.l2jserver.gameserver.model.L2Spawn;
  33. import com.l2jserver.gameserver.model.L2World;
  34. import com.l2jserver.gameserver.model.StatsSet;
  35. import com.l2jserver.gameserver.model.actor.L2Character;
  36. import com.l2jserver.gameserver.model.actor.L2Npc;
  37. import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
  38. import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
  39. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  40. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  41. import com.l2jserver.gameserver.model.skills.L2Skill;
  42. import com.l2jserver.gameserver.model.zone.type.L2BossZone;
  43. import com.l2jserver.gameserver.network.serverpackets.Earthquake;
  44. import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
  45. import com.l2jserver.gameserver.network.serverpackets.PlaySound;
  46. import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
  47. /**
  48. * This class ... control for sequence of fight against Antharas.
  49. * @author L2J_JP SANDMAN
  50. */
  51. public class Antharas extends AbstractNpcAI
  52. {
  53. // config
  54. private static final int FWA_ACTIVITYTIMEOFANTHARAS = 120;
  55. // private static final int FWA_APPTIMEOFANTHARAS = 1800000;
  56. private static final int FWA_INACTIVITYTIME = 900000;
  57. private static final boolean FWA_OLDANTHARAS = false;
  58. private static final boolean FWA_MOVEATRANDOM = true;
  59. private static final boolean FWA_DOSERVEREARTHQUAKE = true;
  60. private static final int FWA_LIMITOFWEAK = 45;
  61. private static final int FWA_LIMITOFNORMAL = 63;
  62. private static final int FWA_MAXMOBS = 10; // this includes Antharas itself
  63. private static final int FWA_INTERVALOFMOBSWEAK = 180000;
  64. private static final int FWA_INTERVALOFMOBSNORMAL = 150000;
  65. private static final int FWA_INTERVALOFMOBSSTRONG = 120000;
  66. private static final int FWA_PERCENTOFBEHEMOTH = 60;
  67. private static final int FWA_SELFDESTRUCTTIME = 15000;
  68. // Location of teleport cube.
  69. private final int _teleportCubeId = 31859;
  70. private final int _teleportCubeLocation[][] =
  71. {
  72. {
  73. 177615,
  74. 114941,
  75. -7709,
  76. 0
  77. }
  78. };
  79. protected List<L2Spawn> _teleportCubeSpawn = new FastList<>();
  80. protected List<L2Npc> _teleportCube = new FastList<>();
  81. // Spawn data of monsters.
  82. protected Map<Integer, L2Spawn> _monsterSpawn = new FastMap<>();
  83. // Instance of monsters.
  84. protected List<L2Npc> _monsters = new FastList<>();
  85. protected L2GrandBossInstance _antharas = null;
  86. // monstersId
  87. private static final int ANTHARASOLDID = 29019;
  88. private static final int ANTHARASWEAKID = 29066;
  89. private static final int ANTHARASNORMALID = 29067;
  90. private static final int ANTHARASSTRONGID = 29068;
  91. // Tasks.
  92. protected ScheduledFuture<?> _cubeSpawnTask = null;
  93. protected ScheduledFuture<?> _monsterSpawnTask = null;
  94. protected ScheduledFuture<?> _activityCheckTask = null;
  95. protected ScheduledFuture<?> _socialTask = null;
  96. protected ScheduledFuture<?> _mobiliseTask = null;
  97. protected ScheduledFuture<?> _mobsSpawnTask = null;
  98. protected ScheduledFuture<?> _selfDestructionTask = null;
  99. protected ScheduledFuture<?> _moveAtRandomTask = null;
  100. protected ScheduledFuture<?> _movieTask = null;
  101. // Antharas Status Tracking :
  102. private static final byte DORMANT = 0; // Antharas is spawned and no one has entered yet. Entry is unlocked
  103. private static final byte WAITING = 1; // Antharas is spawend and someone has entered, triggering a 30 minute window for additional people to enter
  104. // before he unleashes his attack. Entry is unlocked
  105. private static final byte FIGHTING = 2; // Antharas is engaged in battle, annihilating his foes. Entry is locked
  106. private static final byte DEAD = 3; // Antharas has been killed. Entry is locked
  107. protected static long _LastAction = 0;
  108. protected static L2BossZone _Zone;
  109. // Boss: Antharas
  110. private Antharas(String name, String descr)
  111. {
  112. super(name, descr);
  113. int[] mob =
  114. {
  115. ANTHARASOLDID,
  116. ANTHARASWEAKID,
  117. ANTHARASNORMALID,
  118. ANTHARASSTRONGID,
  119. 29069,
  120. 29070,
  121. 29071,
  122. 29072,
  123. 29073,
  124. 29074,
  125. 29075,
  126. 29076
  127. };
  128. registerMobs(mob);
  129. init();
  130. }
  131. // Initialize
  132. private void init()
  133. {
  134. // Setting spawn data of monsters.
  135. try
  136. {
  137. _Zone = GrandBossManager.getInstance().getZone(179700, 113800, -7709);
  138. L2NpcTemplate template1;
  139. L2Spawn tempSpawn;
  140. // Old Antharas
  141. template1 = NpcTable.getInstance().getTemplate(ANTHARASOLDID);
  142. tempSpawn = new L2Spawn(template1);
  143. tempSpawn.setLocx(181323);
  144. tempSpawn.setLocy(114850);
  145. tempSpawn.setLocz(-7623);
  146. tempSpawn.setHeading(32542);
  147. tempSpawn.setAmount(1);
  148. tempSpawn.setRespawnDelay(FWA_ACTIVITYTIMEOFANTHARAS * 2);
  149. SpawnTable.getInstance().addNewSpawn(tempSpawn, false);
  150. _monsterSpawn.put(29019, tempSpawn);
  151. // Weak Antharas
  152. template1 = NpcTable.getInstance().getTemplate(ANTHARASWEAKID);
  153. tempSpawn = new L2Spawn(template1);
  154. tempSpawn.setLocx(181323);
  155. tempSpawn.setLocy(114850);
  156. tempSpawn.setLocz(-7623);
  157. tempSpawn.setHeading(32542);
  158. tempSpawn.setAmount(1);
  159. tempSpawn.setRespawnDelay(FWA_ACTIVITYTIMEOFANTHARAS * 2);
  160. SpawnTable.getInstance().addNewSpawn(tempSpawn, false);
  161. _monsterSpawn.put(29066, tempSpawn);
  162. // Normal Antharas
  163. template1 = NpcTable.getInstance().getTemplate(ANTHARASNORMALID);
  164. tempSpawn = new L2Spawn(template1);
  165. tempSpawn.setLocx(181323);
  166. tempSpawn.setLocy(114850);
  167. tempSpawn.setLocz(-7623);
  168. tempSpawn.setHeading(32542);
  169. tempSpawn.setAmount(1);
  170. tempSpawn.setRespawnDelay(FWA_ACTIVITYTIMEOFANTHARAS * 2);
  171. SpawnTable.getInstance().addNewSpawn(tempSpawn, false);
  172. _monsterSpawn.put(29067, tempSpawn);
  173. // Strong Antharas
  174. template1 = NpcTable.getInstance().getTemplate(ANTHARASSTRONGID);
  175. tempSpawn = new L2Spawn(template1);
  176. tempSpawn.setLocx(181323);
  177. tempSpawn.setLocy(114850);
  178. tempSpawn.setLocz(-7623);
  179. tempSpawn.setHeading(32542);
  180. tempSpawn.setAmount(1);
  181. tempSpawn.setRespawnDelay(FWA_ACTIVITYTIMEOFANTHARAS * 2);
  182. SpawnTable.getInstance().addNewSpawn(tempSpawn, false);
  183. _monsterSpawn.put(29068, tempSpawn);
  184. }
  185. catch (Exception e)
  186. {
  187. _log.warning(e.getMessage());
  188. }
  189. // Setting spawn data of teleport cube.
  190. try
  191. {
  192. L2NpcTemplate Cube = NpcTable.getInstance().getTemplate(_teleportCubeId);
  193. L2Spawn spawnDat;
  194. for (int[] element : _teleportCubeLocation)
  195. {
  196. spawnDat = new L2Spawn(Cube);
  197. spawnDat.setAmount(1);
  198. spawnDat.setLocx(element[0]);
  199. spawnDat.setLocy(element[1]);
  200. spawnDat.setLocz(element[2]);
  201. spawnDat.setHeading(element[3]);
  202. spawnDat.setRespawnDelay(60);
  203. spawnDat.setLocation(0);
  204. SpawnTable.getInstance().addNewSpawn(spawnDat, false);
  205. _teleportCubeSpawn.add(spawnDat);
  206. }
  207. }
  208. catch (Exception e)
  209. {
  210. _log.warning(e.getMessage());
  211. }
  212. int status = GrandBossManager.getInstance().getBossStatus(ANTHARASOLDID);
  213. if (FWA_OLDANTHARAS || (status == WAITING))
  214. {
  215. StatsSet info = GrandBossManager.getInstance().getStatsSet(ANTHARASOLDID);
  216. Long respawnTime = info.getLong("respawn_time");
  217. if ((status == DEAD) && (respawnTime <= System.currentTimeMillis()))
  218. {
  219. // the time has already expired while the server was offline. Immediately spawn antharas in his cave.
  220. // also, the status needs to be changed to DORMANT
  221. GrandBossManager.getInstance().setBossStatus(ANTHARASOLDID, DORMANT);
  222. status = DORMANT;
  223. }
  224. else if (status == FIGHTING)
  225. {
  226. int loc_x = info.getInteger("loc_x");
  227. int loc_y = info.getInteger("loc_y");
  228. int loc_z = info.getInteger("loc_z");
  229. int heading = info.getInteger("heading");
  230. int hp = info.getInteger("currentHP");
  231. int mp = info.getInteger("currentMP");
  232. _antharas = (L2GrandBossInstance) addSpawn(ANTHARASOLDID, loc_x, loc_y, loc_z, heading, false, 0);
  233. GrandBossManager.getInstance().addBoss(_antharas);
  234. _antharas.setCurrentHpMp(hp, mp);
  235. _LastAction = System.currentTimeMillis();
  236. // Start repeating timer to check for inactivity
  237. _activityCheckTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new CheckActivity(), 60000, 60000);
  238. }
  239. else if (status == DEAD)
  240. {
  241. ThreadPoolManager.getInstance().scheduleGeneral(new UnlockAntharas(ANTHARASOLDID), respawnTime - System.currentTimeMillis());
  242. }
  243. else
  244. {
  245. setAntharasSpawnTask();
  246. }
  247. }
  248. else
  249. {
  250. int statusWeak = GrandBossManager.getInstance().getBossStatus(ANTHARASWEAKID);
  251. int statusNormal = GrandBossManager.getInstance().getBossStatus(ANTHARASNORMALID);
  252. int statusStrong = GrandBossManager.getInstance().getBossStatus(ANTHARASSTRONGID);
  253. int antharasId = 0;
  254. if ((statusWeak == FIGHTING) || (statusWeak == DEAD))
  255. {
  256. antharasId = ANTHARASWEAKID;
  257. status = statusWeak;
  258. }
  259. else if ((statusNormal == FIGHTING) || (statusNormal == DEAD))
  260. {
  261. antharasId = ANTHARASNORMALID;
  262. status = statusNormal;
  263. }
  264. else if ((statusStrong == FIGHTING) || (statusStrong == DEAD))
  265. {
  266. antharasId = ANTHARASSTRONGID;
  267. status = statusStrong;
  268. }
  269. if ((antharasId != 0) && (status == FIGHTING))
  270. {
  271. StatsSet info = GrandBossManager.getInstance().getStatsSet(antharasId);
  272. int loc_x = info.getInteger("loc_x");
  273. int loc_y = info.getInteger("loc_y");
  274. int loc_z = info.getInteger("loc_z");
  275. int heading = info.getInteger("heading");
  276. int hp = info.getInteger("currentHP");
  277. int mp = info.getInteger("currentMP");
  278. _antharas = (L2GrandBossInstance) addSpawn(antharasId, loc_x, loc_y, loc_z, heading, false, 0);
  279. GrandBossManager.getInstance().addBoss(_antharas);
  280. _antharas.setCurrentHpMp(hp, mp);
  281. _LastAction = System.currentTimeMillis();
  282. // Start repeating timer to check for inactivity
  283. _activityCheckTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new CheckActivity(), 60000, 60000);
  284. }
  285. else if ((antharasId != 0) && (status == DEAD))
  286. {
  287. StatsSet info = GrandBossManager.getInstance().getStatsSet(antharasId);
  288. Long respawnTime = info.getLong("respawn_time");
  289. if (respawnTime <= System.currentTimeMillis())
  290. {
  291. // the time has already expired while the server was offline. Immediately spawn antharas in his cave.
  292. // also, the status needs to be changed to DORMANT
  293. GrandBossManager.getInstance().setBossStatus(antharasId, DORMANT);
  294. status = DORMANT;
  295. }
  296. else
  297. {
  298. ThreadPoolManager.getInstance().scheduleGeneral(new UnlockAntharas(antharasId), respawnTime - System.currentTimeMillis());
  299. }
  300. }
  301. }
  302. }
  303. // Do spawn teleport cube.
  304. public void spawnCube()
  305. {
  306. if (_mobsSpawnTask != null)
  307. {
  308. _mobsSpawnTask.cancel(true);
  309. _mobsSpawnTask = null;
  310. }
  311. if (_selfDestructionTask != null)
  312. {
  313. _selfDestructionTask.cancel(true);
  314. _selfDestructionTask = null;
  315. }
  316. if (_activityCheckTask != null)
  317. {
  318. _activityCheckTask.cancel(false);
  319. _activityCheckTask = null;
  320. }
  321. for (L2Spawn spawnDat : _teleportCubeSpawn)
  322. {
  323. _teleportCube.add(spawnDat.doSpawn());
  324. }
  325. }
  326. // Setting Antharas spawn task.
  327. public void setAntharasSpawnTask()
  328. {
  329. if (_monsterSpawnTask == null)
  330. {
  331. synchronized (this)
  332. {
  333. if (_monsterSpawnTask == null)
  334. {
  335. GrandBossManager.getInstance().setBossStatus(ANTHARASOLDID, WAITING);
  336. _monsterSpawnTask = ThreadPoolManager.getInstance().scheduleGeneral(new AntharasSpawn(1), Config.Antharas_Wait_Time);
  337. }
  338. }
  339. }
  340. }
  341. @Override
  342. public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  343. {
  344. if (event.equalsIgnoreCase("waiting"))
  345. {
  346. setAntharasSpawnTask();
  347. }
  348. return super.onAdvEvent(event, npc, player);
  349. }
  350. protected void startMinionSpawns(int antharasId)
  351. {
  352. int intervalOfMobs;
  353. // Interval of minions is decided by the type of Antharas
  354. // that invaded the lair.
  355. switch (antharasId)
  356. {
  357. case ANTHARASWEAKID:
  358. intervalOfMobs = FWA_INTERVALOFMOBSWEAK;
  359. break;
  360. case ANTHARASNORMALID:
  361. intervalOfMobs = FWA_INTERVALOFMOBSNORMAL;
  362. break;
  363. default:
  364. intervalOfMobs = FWA_INTERVALOFMOBSSTRONG;
  365. break;
  366. }
  367. // Spawn mobs.
  368. _mobsSpawnTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new MobsSpawn(), intervalOfMobs, intervalOfMobs);
  369. }
  370. // Do spawn Antharas.
  371. private class AntharasSpawn implements Runnable
  372. {
  373. private int _taskId = 0;
  374. private final Collection<L2Character> _players = _Zone.getCharactersInside();
  375. public AntharasSpawn(int taskId)
  376. {
  377. _taskId = taskId;
  378. }
  379. @Override
  380. public void run()
  381. {
  382. int npcId;
  383. L2Spawn antharasSpawn = null;
  384. switch (_taskId)
  385. {
  386. case 1: // Spawn.
  387. // Strength of Antharas is decided by the number of players that
  388. // invaded the lair.
  389. _monsterSpawnTask.cancel(false);
  390. _monsterSpawnTask = null;
  391. if (FWA_OLDANTHARAS)
  392. {
  393. npcId = 29019; // old
  394. }
  395. else if (_players.size() <= FWA_LIMITOFWEAK)
  396. {
  397. npcId = 29066; // weak
  398. }
  399. else if (_players.size() > FWA_LIMITOFNORMAL)
  400. {
  401. npcId = 29068; // strong
  402. }
  403. else
  404. {
  405. npcId = 29067; // normal
  406. }
  407. // Do spawn.
  408. antharasSpawn = _monsterSpawn.get(npcId);
  409. _antharas = (L2GrandBossInstance) antharasSpawn.doSpawn();
  410. GrandBossManager.getInstance().addBoss(_antharas);
  411. _monsters.add(_antharas);
  412. _antharas.setIsImmobilized(true);
  413. GrandBossManager.getInstance().setBossStatus(ANTHARASOLDID, DORMANT);
  414. GrandBossManager.getInstance().setBossStatus(npcId, FIGHTING);
  415. _LastAction = System.currentTimeMillis();
  416. // Start repeating timer to check for inactivity
  417. _activityCheckTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new CheckActivity(), 60000, 60000);
  418. // Setting 1st time of minions spawn task.
  419. if (!FWA_OLDANTHARAS)
  420. {
  421. startMinionSpawns(npcId);
  422. }
  423. // Set next task.
  424. if (_socialTask != null)
  425. {
  426. _socialTask.cancel(true);
  427. _socialTask = null;
  428. }
  429. _socialTask = ThreadPoolManager.getInstance().scheduleGeneral(new AntharasSpawn(2), 16);
  430. break;
  431. case 2:
  432. // Set camera.
  433. broadcastPacket(new SpecialCamera(_antharas.getObjectId(), 700, 13, -19, 0, 20000, 0, 0, 1, 0));
  434. // Set next task.
  435. if (_socialTask != null)
  436. {
  437. _socialTask.cancel(true);
  438. _socialTask = null;
  439. }
  440. _socialTask = ThreadPoolManager.getInstance().scheduleGeneral(new AntharasSpawn(3), 3000);
  441. break;
  442. case 3:
  443. // Do social.
  444. broadcastPacket(new SpecialCamera(_antharas.getObjectId(), 700, 13, 0, 6000, 20000, 0, 0, 1, 0));
  445. // Set next task.
  446. if (_socialTask != null)
  447. {
  448. _socialTask.cancel(true);
  449. _socialTask = null;
  450. }
  451. _socialTask = ThreadPoolManager.getInstance().scheduleGeneral(new AntharasSpawn(4), 10000);
  452. break;
  453. case 4:
  454. broadcastPacket(new SpecialCamera(_antharas.getObjectId(), 3700, 0, -3, 0, 10000, 0, 0, 1, 0));
  455. // Set next task.
  456. if (_socialTask != null)
  457. {
  458. _socialTask.cancel(true);
  459. _socialTask = null;
  460. }
  461. _socialTask = ThreadPoolManager.getInstance().scheduleGeneral(new AntharasSpawn(5), 200);
  462. break;
  463. case 5:
  464. // Do social.
  465. broadcastPacket(new SpecialCamera(_antharas.getObjectId(), 1100, 0, -3, 22000, 30000, 0, 0, 1, 0));
  466. // Set next task.
  467. if (_socialTask != null)
  468. {
  469. _socialTask.cancel(true);
  470. _socialTask = null;
  471. }
  472. _socialTask = ThreadPoolManager.getInstance().scheduleGeneral(new AntharasSpawn(6), 10800);
  473. break;
  474. case 6:
  475. // Set camera.
  476. broadcastPacket(new SpecialCamera(_antharas.getObjectId(), 1100, 0, -3, 300, 7000, 0, 0, 1, 0));
  477. // Set next task.
  478. if (_socialTask != null)
  479. {
  480. _socialTask.cancel(true);
  481. _socialTask = null;
  482. }
  483. _socialTask = ThreadPoolManager.getInstance().scheduleGeneral(new AntharasSpawn(7), 1900);
  484. break;
  485. case 7:
  486. _antharas.abortCast();
  487. _mobiliseTask = ThreadPoolManager.getInstance().scheduleGeneral(new SetMobilised(_antharas), 16);
  488. // Move at random.
  489. if (FWA_MOVEATRANDOM)
  490. {
  491. L2CharPosition pos = new L2CharPosition(getRandom(175000, 178500), getRandom(112400, 116000), -7707, 0);
  492. _moveAtRandomTask = ThreadPoolManager.getInstance().scheduleGeneral(new MoveAtRandom(_antharas, pos), 500);
  493. }
  494. if (_socialTask != null)
  495. {
  496. _socialTask.cancel(true);
  497. _socialTask = null;
  498. }
  499. break;
  500. }
  501. }
  502. }
  503. protected void broadcastPacket(L2GameServerPacket mov)
  504. {
  505. if (_Zone != null)
  506. {
  507. for (L2Character characters : _Zone.getCharactersInside())
  508. {
  509. if (characters.isPlayer())
  510. {
  511. characters.sendPacket(mov);
  512. }
  513. }
  514. }
  515. }
  516. // Do spawn Behemoth or Bomber.
  517. private class MobsSpawn implements Runnable
  518. {
  519. public MobsSpawn()
  520. {
  521. }
  522. @Override
  523. public void run()
  524. {
  525. L2NpcTemplate template1;
  526. L2Spawn tempSpawn;
  527. boolean isBehemoth = getRandom(100) < FWA_PERCENTOFBEHEMOTH;
  528. try
  529. {
  530. int mobNumber = (isBehemoth ? 2 : 3);
  531. // Set spawn.
  532. for (int i = 0; i < mobNumber; i++)
  533. {
  534. if (_monsters.size() >= FWA_MAXMOBS)
  535. {
  536. break;
  537. }
  538. int npcId;
  539. if (isBehemoth)
  540. {
  541. npcId = 29069;
  542. }
  543. else
  544. {
  545. npcId = getRandom(29070, 29076);
  546. }
  547. template1 = NpcTable.getInstance().getTemplate(npcId);
  548. tempSpawn = new L2Spawn(template1);
  549. // allocates it at random in the lair of Antharas.
  550. int tried = 0;
  551. boolean notFound = true;
  552. int x = 175000;
  553. int y = 112400;
  554. int dt = ((_antharas.getX() - x) * (_antharas.getX() - x)) + ((_antharas.getY() - y) * (_antharas.getY() - y));
  555. while ((tried++ < 25) && notFound)
  556. {
  557. int rx = getRandom(175000, 179900);
  558. int ry = getRandom(112400, 116000);
  559. int rdt = ((_antharas.getX() - rx) * (_antharas.getX() - rx)) + ((_antharas.getY() - ry) * (_antharas.getY() - ry));
  560. if (GeoData.getInstance().canSeeTarget(_antharas.getX(), _antharas.getY(), -7704, rx, ry, -7704))
  561. {
  562. if (rdt < dt)
  563. {
  564. x = rx;
  565. y = ry;
  566. dt = rdt;
  567. if (rdt <= 900000)
  568. {
  569. notFound = false;
  570. }
  571. }
  572. }
  573. }
  574. tempSpawn.setLocx(x);
  575. tempSpawn.setLocy(y);
  576. tempSpawn.setLocz(-7704);
  577. tempSpawn.setHeading(0);
  578. tempSpawn.setAmount(1);
  579. tempSpawn.setRespawnDelay(FWA_ACTIVITYTIMEOFANTHARAS * 2);
  580. SpawnTable.getInstance().addNewSpawn(tempSpawn, false);
  581. // Do spawn.
  582. _monsters.add(tempSpawn.doSpawn());
  583. }
  584. }
  585. catch (Exception e)
  586. {
  587. _log.warning(e.getMessage());
  588. }
  589. }
  590. }
  591. @Override
  592. public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isPet)
  593. {
  594. switch (npc.getNpcId())
  595. {
  596. case 29070:
  597. case 29071:
  598. case 29072:
  599. case 29073:
  600. case 29074:
  601. case 29075:
  602. case 29076:
  603. if ((_selfDestructionTask == null) && !npc.isDead())
  604. {
  605. _selfDestructionTask = ThreadPoolManager.getInstance().scheduleGeneral(new SelfDestructionOfBomber(npc), FWA_SELFDESTRUCTTIME);
  606. }
  607. break;
  608. }
  609. return super.onAggroRangeEnter(npc, player, isPet);
  610. }
  611. // Do self destruction.
  612. private class SelfDestructionOfBomber implements Runnable
  613. {
  614. private final L2Npc _bomber;
  615. public SelfDestructionOfBomber(L2Npc bomber)
  616. {
  617. _bomber = bomber;
  618. }
  619. @Override
  620. public void run()
  621. {
  622. L2Skill skill = null;
  623. switch (_bomber.getNpcId())
  624. {
  625. case 29070:
  626. case 29071:
  627. case 29072:
  628. case 29073:
  629. case 29074:
  630. case 29075:
  631. skill = SkillTable.getInstance().getInfo(5097, 1);
  632. break;
  633. case 29076:
  634. skill = SkillTable.getInstance().getInfo(5094, 1);
  635. break;
  636. }
  637. _bomber.doCast(skill);
  638. if (_selfDestructionTask != null)
  639. {
  640. _selfDestructionTask.cancel(false);
  641. _selfDestructionTask = null;
  642. }
  643. }
  644. }
  645. @Override
  646. public String onSpellFinished(L2Npc npc, L2PcInstance player, L2Skill skill)
  647. {
  648. if (npc.isInvul())
  649. {
  650. return null;
  651. }
  652. else if ((skill != null) && ((skill.getId() == 5097) || (skill.getId() == 5094)))
  653. {
  654. switch (npc.getNpcId())
  655. {
  656. case 29070:
  657. case 29071:
  658. case 29072:
  659. case 29073:
  660. case 29074:
  661. case 29075:
  662. case 29076:
  663. npc.doDie(npc);
  664. break;
  665. }
  666. }
  667. return super.onSpellFinished(npc, player, skill);
  668. }
  669. // At end of activity time.
  670. protected class CheckActivity implements Runnable
  671. {
  672. @Override
  673. public void run()
  674. {
  675. Long temp = (System.currentTimeMillis() - _LastAction);
  676. if (temp > FWA_INACTIVITYTIME)
  677. {
  678. GrandBossManager.getInstance().setBossStatus(_antharas.getNpcId(), DORMANT);
  679. setUnspawn();
  680. }
  681. }
  682. }
  683. // Clean Antharas's lair.
  684. public void setUnspawn()
  685. {
  686. // Eliminate players.
  687. _Zone.oustAllPlayers();
  688. // Not executed tasks is canceled.
  689. if (_cubeSpawnTask != null)
  690. {
  691. _cubeSpawnTask.cancel(true);
  692. _cubeSpawnTask = null;
  693. }
  694. if (_monsterSpawnTask != null)
  695. {
  696. _monsterSpawnTask.cancel(true);
  697. _monsterSpawnTask = null;
  698. }
  699. if (_activityCheckTask != null)
  700. {
  701. _activityCheckTask.cancel(false);
  702. _activityCheckTask = null;
  703. }
  704. if (_socialTask != null)
  705. {
  706. _socialTask.cancel(true);
  707. _socialTask = null;
  708. }
  709. if (_mobiliseTask != null)
  710. {
  711. _mobiliseTask.cancel(true);
  712. _mobiliseTask = null;
  713. }
  714. if (_mobsSpawnTask != null)
  715. {
  716. _mobsSpawnTask.cancel(true);
  717. _mobsSpawnTask = null;
  718. }
  719. if (_selfDestructionTask != null)
  720. {
  721. _selfDestructionTask.cancel(true);
  722. _selfDestructionTask = null;
  723. }
  724. if (_moveAtRandomTask != null)
  725. {
  726. _moveAtRandomTask.cancel(true);
  727. _moveAtRandomTask = null;
  728. }
  729. // Delete monsters.
  730. for (L2Npc mob : _monsters)
  731. {
  732. mob.getSpawn().stopRespawn();
  733. mob.deleteMe();
  734. }
  735. _monsters.clear();
  736. // Delete teleport cube.
  737. for (L2Npc cube : _teleportCube)
  738. {
  739. cube.getSpawn().stopRespawn();
  740. cube.deleteMe();
  741. }
  742. _teleportCube.clear();
  743. }
  744. // Do spawn teleport cube.
  745. private class CubeSpawn implements Runnable
  746. {
  747. private final int _type;
  748. public CubeSpawn(int type)
  749. {
  750. _type = type;
  751. }
  752. @Override
  753. public void run()
  754. {
  755. if (_type == 0)
  756. {
  757. spawnCube();
  758. _cubeSpawnTask = ThreadPoolManager.getInstance().scheduleGeneral(new CubeSpawn(1), 1800000);
  759. }
  760. else
  761. {
  762. setUnspawn();
  763. }
  764. }
  765. }
  766. // UnLock Antharas.
  767. private static class UnlockAntharas implements Runnable
  768. {
  769. private final int _bossId;
  770. public UnlockAntharas(int bossId)
  771. {
  772. _bossId = bossId;
  773. }
  774. @Override
  775. public void run()
  776. {
  777. GrandBossManager.getInstance().setBossStatus(_bossId, DORMANT);
  778. if (FWA_DOSERVEREARTHQUAKE)
  779. {
  780. for (L2PcInstance p : L2World.getInstance().getAllPlayersArray())
  781. {
  782. p.broadcastPacket(new Earthquake(185708, 114298, -8221, 20, 10));
  783. }
  784. }
  785. }
  786. }
  787. // Action is enabled the boss.
  788. private class SetMobilised implements Runnable
  789. {
  790. private final L2GrandBossInstance _boss;
  791. public SetMobilised(L2GrandBossInstance boss)
  792. {
  793. _boss = boss;
  794. }
  795. @Override
  796. public void run()
  797. {
  798. _boss.setIsImmobilized(false);
  799. // When it is possible to act, a social action is canceled.
  800. if (_socialTask != null)
  801. {
  802. _socialTask.cancel(true);
  803. _socialTask = null;
  804. }
  805. }
  806. }
  807. // Move at random on after Antharas appears.
  808. private static class MoveAtRandom implements Runnable
  809. {
  810. private final L2Npc _npc;
  811. private final L2CharPosition _pos;
  812. public MoveAtRandom(L2Npc npc, L2CharPosition pos)
  813. {
  814. _npc = npc;
  815. _pos = pos;
  816. }
  817. @Override
  818. public void run()
  819. {
  820. _npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, _pos);
  821. }
  822. }
  823. @Override
  824. public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isPet)
  825. {
  826. if ((npc.getNpcId() == 29019) || (npc.getNpcId() == 29066) || (npc.getNpcId() == 29067) || (npc.getNpcId() == 29068))
  827. {
  828. _LastAction = System.currentTimeMillis();
  829. if (GrandBossManager.getInstance().getBossStatus(_antharas.getNpcId()) != FIGHTING)
  830. {
  831. _Zone.oustAllPlayers();
  832. }
  833. else if (!FWA_OLDANTHARAS && (_mobsSpawnTask == null))
  834. {
  835. startMinionSpawns(npc.getNpcId());
  836. }
  837. }
  838. else if ((npc.getNpcId() > 29069) && (npc.getNpcId() < 29077) && (npc.getCurrentHp() <= damage))
  839. {
  840. L2Skill skill = null;
  841. switch (npc.getNpcId())
  842. {
  843. case 29070:
  844. case 29071:
  845. case 29072:
  846. case 29073:
  847. case 29074:
  848. case 29075:
  849. skill = SkillTable.getInstance().getInfo(5097, 1);
  850. break;
  851. case 29076:
  852. skill = SkillTable.getInstance().getInfo(5094, 1);
  853. break;
  854. }
  855. npc.doCast(skill);
  856. }
  857. return super.onAttack(npc, attacker, damage, isPet);
  858. }
  859. @Override
  860. public String onKill(L2Npc npc, L2PcInstance killer, boolean isPet)
  861. {
  862. if ((npc.getNpcId() == 29019) || (npc.getNpcId() == 29066) || (npc.getNpcId() == 29067) || (npc.getNpcId() == 29068))
  863. {
  864. npc.broadcastPacket(new PlaySound(1, "BS01_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
  865. _cubeSpawnTask = ThreadPoolManager.getInstance().scheduleGeneral(new CubeSpawn(0), 10000);
  866. GrandBossManager.getInstance().setBossStatus(npc.getNpcId(), DEAD);
  867. // Respawn time is 264 Hours - 72 Random Hours
  868. long respawnTime = (long) Config.Interval_Of_Antharas_Spawn - getRandom(Config.Random_Of_Antharas_Spawn);
  869. ThreadPoolManager.getInstance().scheduleGeneral(new UnlockAntharas(npc.getNpcId()), respawnTime);
  870. // also save the respawn time so that the info is maintained past reboots
  871. StatsSet info = GrandBossManager.getInstance().getStatsSet(npc.getNpcId());
  872. info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
  873. GrandBossManager.getInstance().setStatsSet(npc.getNpcId(), info);
  874. }
  875. else if (npc.getNpcId() == 29069)
  876. {
  877. int countHPHerb = getRandom(6, 18);
  878. int countMPHerb = getRandom(6, 18);
  879. for (int i = 0; i < countHPHerb; i++)
  880. {
  881. ((L2MonsterInstance) npc).dropItem(killer, 8602, 1);
  882. }
  883. for (int i = 0; i < countMPHerb; i++)
  884. {
  885. ((L2MonsterInstance) npc).dropItem(killer, 8605, 1);
  886. }
  887. }
  888. if (_monsters.contains(npc))
  889. {
  890. _monsters.remove(npc);
  891. }
  892. return super.onKill(npc, killer, isPet);
  893. }
  894. public static void main(String[] args)
  895. {
  896. new Antharas(Antharas.class.getSimpleName(), "ai");
  897. }
  898. }