Antharas.java 28 KB

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