Antharas.java 28 KB

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