Antharas.java 27 KB

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