Guest User

Untitled

a guest
Jun 8th, 2021
34
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package instances;
  2.  
  3. import l2ro.commons.threading.RunnableImpl;
  4. import l2ro.commons.util.Rnd;
  5. import l2ro.gameserver.ThreadPoolManager;
  6. import l2ro.gameserver.ai.CtrlEvent;
  7. import l2ro.gameserver.listener.actor.OnCurrentHpDamageListener;
  8. import l2ro.gameserver.listener.actor.OnDeathListener;
  9. import l2ro.gameserver.listener.zone.OnZoneEnterLeaveListener;
  10. import l2ro.gameserver.model.Creature;
  11. import l2ro.gameserver.model.Player;
  12. import l2ro.gameserver.model.Skill;
  13. import l2ro.gameserver.model.Zone;
  14. import l2ro.gameserver.model.entity.Reflection;
  15. import l2ro.gameserver.model.instances.NpcInstance;
  16. import l2ro.gameserver.network.serverpackets.*;
  17. import l2ro.gameserver.network.serverpackets.ExShowScreenMessage.ScreenMessageAlign;
  18. import l2ro.gameserver.network.serverpackets.components.NpcString;
  19. import l2ro.gameserver.tables.SkillTable;
  20. import l2ro.gameserver.utils.Location;
  21. import org.apache.commons.lang3.ArrayUtils;
  22. import org.slf4j.Logger;
  23. import org.slf4j.LoggerFactory;
  24.  
  25. import java.util.ArrayList;
  26. import java.util.List;
  27. import java.util.concurrent.ScheduledFuture;
  28.  
  29. /**
  30. * @author pchayka
  31. * <p/>
  32. * Данж Frintezza для Freya Throne
  33. */
  34.  
  35. public class Frintezza extends Reflection
  36. {
  37. private static final Logger LOG = LoggerFactory.getLogger(Frintezza.class);
  38.  
  39. private static final int HallAlarmDevice = 18328;
  40. private static final int DarkChoirPlayer = 18339;
  41. private static final int _weakScarletId = 29046;
  42. private static final int _strongScarletId = 29047;
  43. private static final int TeleportCube = 29061;
  44. private static final int _frintezzasSwordId = 7903;
  45. private static final int DewdropItem = 8556;
  46.  
  47. private static final int[] hallADoors = {17130051, 17130052, 17130053, 17130054, 17130055, 17130056, 17130057, 17130058};
  48. private static final int[] corridorADoors = {17130042, 17130043};
  49. private static final int[] hallBDoors = {17130061, 17130062, 17130063, 17130064, 17130065, 17130066, 17130067, 17130068, 17130069, 17130070};
  50. private static final int[] corridorBDoors = {17130045, 17130046};
  51. private static final int[] blockANpcs = {18329, 18330, 18331, 18333};
  52. private static final int[] blockBNpcs = {18334, 18335, 18336, 18337, 18338};
  53.  
  54. private static int _intervalOfFrintezzaSongs = 30000;
  55.  
  56. @SuppressWarnings("serial")
  57. public static class NpcLocation extends Location
  58. {
  59. public int npcId;
  60.  
  61. public NpcLocation()
  62. {
  63. }
  64.  
  65. public NpcLocation(int x, int y, int z, int heading, int npcId)
  66. {
  67. super(x, y, z, heading);
  68. this.npcId = npcId;
  69. }
  70. }
  71.  
  72. //The Boss
  73. private static NpcLocation frintezzaSpawn = new NpcLocation(-87784, -155090, -9080, 16048, 29045);
  74.  
  75. // Weak Scarlet Van Halisha.
  76. private static NpcLocation scarletSpawnWeak = new NpcLocation(-87784, -153288, -9176, 16384, 29046);
  77.  
  78. // Portrait spawns - 4 portraits = 4 spawns
  79. private static NpcLocation[] portraitSpawns = {new NpcLocation(-86136, -153960, -9168, 35048, 29048),
  80. new NpcLocation(-86184, -152456, -9168, 28205, 29049),
  81. new NpcLocation(-89368, -152456, -9168, 64817, 29048),
  82. new NpcLocation(-89416, -153976, -9168, 57730, 29049)};
  83.  
  84. // Demon spawns - 4 portraits = 4 demons
  85. private static NpcLocation[] demonSpawns = {new NpcLocation(-86136, -153960, -9168, 35048, 29050),
  86. new NpcLocation(-86184, -152456, -9168, 28205, 29051),
  87. new NpcLocation(-89368, -152456, -9168, 64817, 29051),
  88. new NpcLocation(-89416, -153976, -9168, 57730, 29050)};
  89.  
  90. private NpcInstance _frintezzaDummy, frintezza, weakScarlet, strongScarlet;
  91. private NpcInstance[] portraits = new NpcInstance[4];
  92. private NpcInstance[] demons = new NpcInstance[4];
  93. private int _scarletMorph = 0;
  94.  
  95. private static final long battleStartDelay = 5 * 60000L; // 5min
  96.  
  97. private DeathListener _deathListener = new DeathListener();
  98. private CurrentHpListener _currentHpListener = new CurrentHpListener();
  99. private ZoneListener _zoneListener = new ZoneListener();
  100.  
  101. private ScheduledFuture<?> musicTask;
  102.  
  103. @Override
  104. protected void onCreate()
  105. {
  106. super.onCreate();
  107.  
  108. getZone("[Frintezza]").addListener(_zoneListener);
  109.  
  110. for (NpcInstance n : getNpcs())
  111. n.addListener(_deathListener);
  112.  
  113. blockUnblockNpcs(true, blockANpcs);
  114. }
  115.  
  116. private class FrintezzaStart extends RunnableImpl
  117. {
  118. @Override
  119. public void runImpl() throws Exception
  120. {
  121. ThreadPoolManager.getInstance().schedule(new Spawn(1), 1000);
  122. }
  123. }
  124.  
  125. private class Spawn extends RunnableImpl
  126. {
  127. private int _taskId = 0;
  128.  
  129. public Spawn(int taskId)
  130. {
  131. _taskId = taskId;
  132. }
  133.  
  134. @Override
  135. public void runImpl() throws Exception
  136. {
  137. try
  138. {
  139. switch (_taskId)
  140. {
  141. case 1: // spawn.
  142. _frintezzaDummy = spawn(new NpcLocation(-87784, -155096, -9080, 16048, 29059));
  143. ThreadPoolManager.getInstance().schedule(new Spawn(2), 1000);
  144. break;
  145. case 2:
  146. closeDoor(corridorBDoors[1]);
  147. frintezza = spawn(frintezzaSpawn);
  148. showSocialActionMovie(frintezza, 500, 90, 0, 6500, 8000, 0);
  149. for (int i = 0; i < 4; i++)
  150. {
  151. portraits[i] = spawn(portraitSpawns[i]);
  152. portraits[i].startImmobilized();
  153. demons[i] = spawn(demonSpawns[i]);
  154. }
  155. blockAll(true);
  156. ThreadPoolManager.getInstance().schedule(new Spawn(3), 6500);
  157. break;
  158. case 3:
  159. showSocialActionMovie(_frintezzaDummy, 1800, 90, 8, 6500, 7000, 0);
  160. ThreadPoolManager.getInstance().schedule(new Spawn(4), 900);
  161. break;
  162. case 4:
  163. showSocialActionMovie(_frintezzaDummy, 140, 90, 10, 2500, 4500, 0);
  164. ThreadPoolManager.getInstance().schedule(new Spawn(5), 4000);
  165. break;
  166. case 5:
  167. showSocialActionMovie(frintezza, 40, 75, -10, 0, 1000, 0);
  168. showSocialActionMovie(frintezza, 40, 75, -10, 0, 12000, 0);
  169. ThreadPoolManager.getInstance().schedule(new Spawn(6), 1350);
  170. break;
  171. case 6:
  172. frintezza.broadcastPacket(new SocialAction(frintezza.getObjectId(), 2));
  173. ThreadPoolManager.getInstance().schedule(new Spawn(7), 7000);
  174. break;
  175. case 7:
  176. _frintezzaDummy.deleteMe();
  177. _frintezzaDummy = null;
  178. ThreadPoolManager.getInstance().schedule(new Spawn(8), 1000);
  179. break;
  180. case 8:
  181. showSocialActionMovie(demons[0], 140, 0, 3, 22000, 3000, 1);
  182. ThreadPoolManager.getInstance().schedule(new Spawn(9), 2800);
  183. break;
  184. case 9:
  185. showSocialActionMovie(demons[1], 140, 0, 3, 22000, 3000, 1);
  186. ThreadPoolManager.getInstance().schedule(new Spawn(10), 2800);
  187. break;
  188. case 10:
  189. showSocialActionMovie(demons[2], 140, 180, 3, 22000, 3000, 1);
  190. ThreadPoolManager.getInstance().schedule(new Spawn(11), 2800);
  191. break;
  192. case 11:
  193. showSocialActionMovie(demons[3], 140, 180, 3, 22000, 3000, 1);
  194. ThreadPoolManager.getInstance().schedule(new Spawn(12), 3000);
  195. break;
  196. case 12:
  197. showSocialActionMovie(frintezza, 240, 90, 0, 0, 1000, 0);
  198. showSocialActionMovie(frintezza, 240, 90, 25, 5500, 10000, 3);
  199. ThreadPoolManager.getInstance().schedule(new Spawn(13), 3000);
  200. break;
  201. case 13:
  202. showSocialActionMovie(frintezza, 100, 195, 35, 0, 10000, 0);
  203. ThreadPoolManager.getInstance().schedule(new Spawn(14), 700);
  204. break;
  205. case 14:
  206. showSocialActionMovie(frintezza, 100, 195, 35, 0, 10000, 0);
  207. ThreadPoolManager.getInstance().schedule(new Spawn(15), 1300);
  208. break;
  209. case 15:
  210. showSocialActionMovie(frintezza, 120, 180, 45, 1500, 10000, 0);
  211. frintezza.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5006, 1, 34000, 0));
  212. ThreadPoolManager.getInstance().schedule(new Spawn(16), 1500);
  213. break;
  214. case 16:
  215. showSocialActionMovie(frintezza, 520, 135, 45, 8000, 10000, 0);
  216. ThreadPoolManager.getInstance().schedule(new Spawn(17), 7500);
  217. break;
  218. case 17:
  219. showSocialActionMovie(frintezza, 1500, 110, 25, 10000, 13000, 0);
  220. ThreadPoolManager.getInstance().schedule(new Spawn(18), 9500);
  221. break;
  222. case 18:
  223. weakScarlet = spawn(scarletSpawnWeak);
  224. block(weakScarlet, true);
  225. weakScarlet.addListener(_currentHpListener);
  226. weakScarlet.broadcastPacket(new MagicSkillUse(weakScarlet, weakScarlet, 5016, 1, 3000, 0));
  227. Earthquake eq = new Earthquake(weakScarlet.getLoc(), 50, 6);
  228. for (Player pc : getPlayers())
  229. pc.broadcastPacket(eq);
  230. showSocialActionMovie(weakScarlet, 1000, 160, 20, 6000, 6000, 0);
  231. ThreadPoolManager.getInstance().schedule(new Spawn(19), 5500);
  232. break;
  233. case 19:
  234. showSocialActionMovie(weakScarlet, 800, 160, 5, 1000, 10000, 2);
  235. ThreadPoolManager.getInstance().schedule(new Spawn(20), 2100);
  236. break;
  237. case 20:
  238. showSocialActionMovie(weakScarlet, 300, 60, 8, 0, 10000, 0);
  239. ThreadPoolManager.getInstance().schedule(new Spawn(21), 2000);
  240. break;
  241. case 21:
  242. showSocialActionMovie(weakScarlet, 1000, 90, 10, 3000, 5000, 0);
  243. ThreadPoolManager.getInstance().schedule(new Spawn(22), 3000);
  244. break;
  245. case 22:
  246. for (Player pc : getPlayers())
  247. pc.leaveMovieMode();
  248. ThreadPoolManager.getInstance().schedule(new Spawn(23), 2000);
  249. break;
  250. case 23:
  251. blockAll(false);
  252. spawn(new NpcLocation(-87904, -141296, -9168, 0, TeleportCube));
  253. _scarletMorph = 1;
  254. musicTask = ThreadPoolManager.getInstance().schedule(new Music(), 5000);
  255. break;
  256. }
  257. }
  258. catch (RuntimeException e)
  259. {
  260. LOG.error("Error on Frintezza Spawn", e);
  261. }
  262. }
  263. }
  264.  
  265. private class Music extends RunnableImpl
  266. {
  267. @Override
  268. public void runImpl() throws Exception
  269. {
  270. if (frintezza == null)
  271. return;
  272. int song = Math.max(1, Math.min(4, getSong()));
  273. NpcString song_name;
  274. switch (song)
  275. {
  276. case 1:
  277. song_name = NpcString.REQUIEM_OF_HATRED;
  278. break;
  279. case 2:
  280. song_name = NpcString.FRENETIC_TOCCATA;
  281. break;
  282. case 3:
  283. song_name = NpcString.FUGUE_OF_JUBILATION;
  284. break;
  285. case 4:
  286. song_name = NpcString.MOURNFUL_CHORALE_PRELUDE;
  287. break;
  288. default:
  289. return;
  290. }
  291. if (!frintezza.isBlocked())
  292. {
  293. frintezza.broadcastPacket(new ExShowScreenMessage(song_name, 3000, ScreenMessageAlign.TOP_CENTER, true, 1, -1, true));
  294. frintezza.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5007, song, _intervalOfFrintezzaSongs, 0));
  295. // Launch the song's effects (they start about 10 seconds after he starts to play)
  296. ThreadPoolManager.getInstance().schedule(new SongEffectLaunched(getSongTargets(song), song, 10000), 10000);
  297. }
  298. // Schedule a new song to be played in 30-40 seconds...
  299. musicTask = ThreadPoolManager.getInstance().schedule(new Music(), _intervalOfFrintezzaSongs + Rnd.get(10000));
  300. }
  301.  
  302. /**
  303. * Depending on the song, returns the song's targets (either mobs or players)
  304. */
  305. private List<Creature> getSongTargets(int songId)
  306. {
  307. List<Creature> targets = new ArrayList<Creature>();
  308. if (songId < 4) // Target is the minions
  309. {
  310. if (weakScarlet != null && !weakScarlet.isDead())
  311. targets.add(weakScarlet);
  312. if (strongScarlet != null && !strongScarlet.isDead())
  313. targets.add(strongScarlet);
  314. for (int i = 0; i < 4; i++)
  315. {
  316. if (portraits[i] != null && !portraits[i].isDead())
  317. targets.add(portraits[i]);
  318. if (demons[i] != null && !demons[i].isDead())
  319. targets.add(demons[i]);
  320. }
  321. }
  322. else
  323. // Target is the players
  324. for (Player pc : getPlayers())
  325. if (!pc.isDead())
  326. targets.add(pc);
  327. return targets;
  328. }
  329.  
  330. /**
  331. * returns the chosen symphony for Frintezza to play
  332. * If the minions are injured he has 40% to play a healing song
  333. * If they are all dead, he will only play harmful player symphonies
  334. */
  335. private int getSong()
  336. {
  337. if (minionsNeedHeal())
  338. return 1;
  339. return Rnd.get(2, 4);
  340. }
  341.  
  342. /**
  343. * Checks if Frintezza's minions need heal (only major minions are checked) Return a "need heal" = true only 40% of the time
  344. */
  345. private boolean minionsNeedHeal()
  346. {
  347. if (!Rnd.chance(40))
  348. return false;
  349. if (weakScarlet != null && !weakScarlet.isAlikeDead() && weakScarlet.getCurrentHp() < weakScarlet.getMaxHp() * 2 / 3)
  350. return true;
  351. if (strongScarlet != null && !strongScarlet.isAlikeDead() && strongScarlet.getCurrentHp() < strongScarlet.getMaxHp() * 2 / 3)
  352. return true;
  353. for (int i = 0; i < 4; i++)
  354. {
  355. if (portraits[i] != null && !portraits[i].isDead() && portraits[i].getCurrentHp() < portraits[i].getMaxHp() / 3)
  356. return true;
  357. if (demons[i] != null && !demons[i].isDead() && demons[i].getCurrentHp() < demons[i].getMaxHp() / 3)
  358. return true;
  359. }
  360. return false;
  361. }
  362. }
  363.  
  364. /**
  365. * The song was played, this class checks it's affects (if any)
  366. */
  367. private class SongEffectLaunched extends RunnableImpl
  368. {
  369. private final List<Creature> _targets;
  370. private final int _song, _currentTime;
  371.  
  372. /**
  373. * @param targets - song's targets
  374. * @param song - song id 1-5
  375. * @param currentTimeOfSong - skills during music play are consecutive, repeating
  376. */
  377. public SongEffectLaunched(List<Creature> targets, int song, int currentTimeOfSong)
  378. {
  379. _targets = targets;
  380. _song = song;
  381. _currentTime = currentTimeOfSong;
  382. }
  383.  
  384. @Override
  385. public void runImpl() throws Exception
  386. {
  387. if (frintezza == null)
  388. return;
  389. // If the song time is over stop this loop
  390. if (_currentTime > _intervalOfFrintezzaSongs)
  391. return;
  392. // Skills are consecutive, so call them again
  393. SongEffectLaunched songLaunched = new SongEffectLaunched(_targets, _song, _currentTime + _intervalOfFrintezzaSongs / 10);
  394. ThreadPoolManager.getInstance().schedule(songLaunched, _intervalOfFrintezzaSongs / 10);
  395. frintezza.callSkill(SkillTable.getInstance().getInfo(5008, _song), _targets, false);
  396. }
  397. }
  398.  
  399. private NpcInstance spawn(NpcLocation loc)
  400. {
  401. return addSpawnWithoutRespawn(loc.npcId, loc, 0);
  402. }
  403.  
  404. /**
  405. * Shows a movie to the players in the lair.
  406. *
  407. * @param target - L2NpcInstance target is the center of this movie
  408. * @param dist - int distance from target
  409. * @param yaw - angle of movie (north = 90, south = 270, east = 0 , west = 180)
  410. * @param pitch - pitch > 0 looks up / pitch < 0 looks down
  411. * @param time - fast ++ or slow -- depends on the value
  412. * @param duration - How long to watch the movie
  413. * @param socialAction - 1,2,3,4 social actions / other values do nothing
  414. */
  415. private void showSocialActionMovie(NpcInstance target, int dist, int yaw, int pitch, int time, int duration, int socialAction)
  416. {
  417. if (target == null)
  418. return;
  419. for (Player pc : getPlayers())
  420. if (pc.getDistance(target) <= 2550)
  421. {
  422. pc.enterMovieMode();
  423. pc.specialCamera(target, dist, yaw, pitch, time, duration);
  424. }
  425. else
  426. pc.leaveMovieMode();
  427. if (socialAction > 0 && socialAction < 5)
  428. target.broadcastPacket(new SocialAction(target.getObjectId(), socialAction));
  429. }
  430.  
  431. private void blockAll(boolean flag)
  432. {
  433. block(frintezza, flag);
  434. block(weakScarlet, flag);
  435. block(strongScarlet, flag);
  436. for (int i = 0; i < 4; i++)
  437. {
  438. block(portraits[i], flag);
  439. block(demons[i], flag);
  440. }
  441. }
  442.  
  443. private void block(NpcInstance npc, boolean flag)
  444. {
  445. if (npc == null || npc.isDead())
  446. return;
  447. if (flag)
  448. {
  449. npc.abortAttack(true, false);
  450. npc.abortCast(true, true);
  451. npc.setTarget(null);
  452. if (npc.isMoving)
  453. npc.stopMove();
  454. npc.block();
  455. }
  456. else
  457. npc.unblock();
  458. npc.setIsInvul(flag);
  459. }
  460.  
  461. private class SecondMorph extends RunnableImpl
  462. {
  463. private int _taskId = 0;
  464.  
  465. public SecondMorph(int taskId)
  466. {
  467. _taskId = taskId;
  468. }
  469.  
  470. @Override
  471. public void runImpl() throws Exception
  472. {
  473. try
  474. {
  475. switch (_taskId)
  476. {
  477. case 1:
  478. int angle = Math.abs((weakScarlet.getHeading() < 32768 ? 180 : 540) - (int) (weakScarlet.getHeading() / 182.044444444));
  479. for (Player pc : getPlayers())
  480. pc.enterMovieMode();
  481. blockAll(true);
  482. showSocialActionMovie(weakScarlet, 500, angle, 5, 500, 15000, 0);
  483. ThreadPoolManager.getInstance().schedule(new SecondMorph(2), 2000);
  484. break;
  485. case 2:
  486. weakScarlet.broadcastPacket(new SocialAction(weakScarlet.getObjectId(), 1));
  487. weakScarlet.setCurrentHp(weakScarlet.getMaxHp() * 3 / 4, false);
  488. weakScarlet.setRHandId(_frintezzasSwordId);
  489. weakScarlet.broadcastCharInfo();
  490. ThreadPoolManager.getInstance().schedule(new SecondMorph(3), 5500);
  491. break;
  492. case 3:
  493. weakScarlet.broadcastPacket(new SocialAction(weakScarlet.getObjectId(), 4));
  494. blockAll(false);
  495. Skill skill = SkillTable.getInstance().getInfo(5017, 1);
  496. skill.getEffects(weakScarlet, weakScarlet, false, false);
  497. for (Player pc : getPlayers())
  498. pc.leaveMovieMode();
  499. break;
  500. }
  501. }
  502. catch (RuntimeException e)
  503. {
  504. LOG.error("Error on Frintezza Second Morph", e);
  505. }
  506. }
  507. }
  508.  
  509. private class ThirdMorph extends RunnableImpl
  510. {
  511. private int _taskId = 0;
  512. private int _angle = 0;
  513.  
  514. public ThirdMorph(int taskId)
  515. {
  516. _taskId = taskId;
  517. }
  518.  
  519. @Override
  520. public void runImpl() throws Exception
  521. {
  522. try
  523. {
  524. switch (_taskId)
  525. {
  526. case 1:
  527. _angle = Math.abs((weakScarlet.getHeading() < 32768 ? 180 : 540) - (int) (weakScarlet.getHeading() / 182.044444444));
  528. for (Player pc : getPlayers())
  529. pc.enterMovieMode();
  530. blockAll(true);
  531. frintezza.broadcastPacket(new MagicSkillCanceled(frintezza.getObjectId()));
  532. frintezza.broadcastPacket(new SocialAction(frintezza.getObjectId(), 4));
  533. ThreadPoolManager.getInstance().schedule(new ThirdMorph(2), 100);
  534. break;
  535. case 2:
  536. showSocialActionMovie(frintezza, 250, 120, 15, 0, 1000, 0);
  537. showSocialActionMovie(frintezza, 250, 120, 15, 0, 10000, 0);
  538. ThreadPoolManager.getInstance().schedule(new ThirdMorph(3), 6500);
  539. break;
  540. case 3:
  541. frintezza.broadcastPacket(new MagicSkillUse(frintezza, frintezza, 5006, 1, 34000, 0));
  542. showSocialActionMovie(frintezza, 500, 70, 15, 3000, 10000, 0);
  543. ThreadPoolManager.getInstance().schedule(new ThirdMorph(4), 3000);
  544. break;
  545. case 4:
  546. showSocialActionMovie(frintezza, 2500, 90, 12, 6000, 10000, 0);
  547. ThreadPoolManager.getInstance().schedule(new ThirdMorph(5), 3000);
  548. break;
  549. case 5:
  550. showSocialActionMovie(weakScarlet, 250, _angle, 12, 0, 1000, 0);
  551. showSocialActionMovie(weakScarlet, 250, _angle, 12, 0, 10000, 0);
  552. ThreadPoolManager.getInstance().schedule(new ThirdMorph(6), 500);
  553. break;
  554. case 6:
  555. weakScarlet.doDie(weakScarlet);
  556. showSocialActionMovie(weakScarlet, 450, _angle, 14, 8000, 8000, 0);
  557. ThreadPoolManager.getInstance().schedule(new ThirdMorph(7), 6250);
  558. break;
  559. case 7:
  560. NpcLocation loc = new NpcLocation();
  561. loc.set(weakScarlet.getLoc());
  562. loc.npcId = _strongScarletId;
  563. weakScarlet.deleteMe();
  564. weakScarlet = null;
  565. strongScarlet = spawn(loc);
  566. strongScarlet.addListener(_deathListener);
  567. block(strongScarlet, true);
  568. showSocialActionMovie(strongScarlet, 450, _angle, 12, 500, 14000, 2);
  569. ThreadPoolManager.getInstance().schedule(new ThirdMorph(9), 5000);
  570. break;
  571. case 9:
  572. blockAll(false);
  573. for (Player pc : getPlayers())
  574. pc.leaveMovieMode();
  575. Skill skill = SkillTable.getInstance().getInfo(5017, 1);
  576. skill.getEffects(strongScarlet, strongScarlet, false, false);
  577. break;
  578. }
  579. }
  580. catch (Exception e)
  581. {
  582. e.printStackTrace();
  583. }
  584. }
  585. }
  586.  
  587. private class Die extends RunnableImpl
  588. {
  589. private int _taskId = 0;
  590.  
  591. public Die(int taskId)
  592. {
  593. _taskId = taskId;
  594. }
  595.  
  596. @Override
  597. public void runImpl() throws Exception
  598. {
  599. try
  600. {
  601. switch (_taskId)
  602. {
  603. case 1:
  604. blockAll(true);
  605. int _angle = Math.abs((strongScarlet.getHeading() < 32768 ? 180 : 540) - (int) (strongScarlet.getHeading() / 182.044444444));
  606. showSocialActionMovie(strongScarlet, 300, _angle - 180, 5, 0, 7000, 0);
  607. showSocialActionMovie(strongScarlet, 200, _angle, 85, 4000, 10000, 0);
  608. ThreadPoolManager.getInstance().schedule(new Die(2), 7500);
  609. break;
  610. case 2:
  611. showSocialActionMovie(frintezza, 100, 120, 5, 0, 7000, 0);
  612. showSocialActionMovie(frintezza, 100, 90, 5, 5000, 15000, 0);
  613. ThreadPoolManager.getInstance().schedule(new Die(3), 6000);
  614. break;
  615. case 3:
  616. showSocialActionMovie(frintezza, 900, 90, 25, 7000, 10000, 0);
  617. frintezza.doDie(frintezza);
  618. frintezza = null;
  619. ThreadPoolManager.getInstance().schedule(new Die(4), 7000);
  620. break;
  621. case 4:
  622. for (Player pc : getPlayers())
  623. pc.leaveMovieMode();
  624. cleanUp();
  625. break;
  626. }
  627. }
  628. catch (RuntimeException e)
  629. {
  630. LOG.error("Error On Frintezza Death", e);
  631. }
  632. }
  633. }
  634.  
  635. private void cleanUp()
  636. {
  637. startCollapseTimer(15 * 60 * 1000L);
  638. for (Player p : getPlayers())
  639. p.sendPacket(new SystemMessage(SystemMessage.THIS_DUNGEON_WILL_EXPIRE_IN_S1_MINUTES).addNumber(15));
  640. for (NpcInstance n : getNpcs())
  641. n.deleteMe();
  642. }
  643.  
  644. // Hack: ToRemove when doors will operate normally in reflections
  645. private void blockUnblockNpcs(boolean block, int[] npcArray)
  646. {
  647. for (NpcInstance n : getNpcs())
  648. if (ArrayUtils.contains(npcArray, n.getNpcId()))
  649. {
  650. if (block)
  651. {
  652. n.block();
  653. n.setIsInvul(true);
  654. }
  655. else
  656. {
  657. n.unblock();
  658. n.setIsInvul(false);
  659. }
  660. }
  661. }
  662.  
  663. public class CurrentHpListener implements OnCurrentHpDamageListener
  664. {
  665. @Override
  666. public void onCurrentHpDamage(Creature actor, double damage, Creature attacker, Skill skill)
  667. {
  668. if (actor.isDead() || actor != weakScarlet)
  669. return;
  670. double newHp = actor.getCurrentHp() - damage;
  671. double maxHp = actor.getMaxHp();
  672. switch (_scarletMorph)
  673. {
  674. case 1:
  675. if (newHp < 0.75 * maxHp)
  676. {
  677. _scarletMorph = 2;
  678. ThreadPoolManager.getInstance().schedule(new SecondMorph(1), 1100);
  679. }
  680. break;
  681. case 2:
  682. if (newHp < 0.1 * maxHp)
  683. {
  684. _scarletMorph = 3;
  685. ThreadPoolManager.getInstance().schedule(new ThirdMorph(1), 2000);
  686. }
  687. break;
  688. }
  689. }
  690. }
  691.  
  692. private class DeathListener implements OnDeathListener
  693. {
  694. @Override
  695. public void onDeath(Creature self, Creature killer)
  696. {
  697. if (self.isNpc())
  698. {
  699. if (self.getNpcId() == HallAlarmDevice)
  700. {
  701. for (int i = 0; i < hallADoors.length; i++)
  702. openDoor(hallADoors[i]);
  703. blockUnblockNpcs(false, blockANpcs);
  704. for (NpcInstance n : getNpcs())
  705. if (ArrayUtils.contains(blockANpcs, n.getNpcId()))
  706. n.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, getPlayers().get(Rnd.get(getPlayers().size())), 200);
  707. }
  708. else if (ArrayUtils.contains(blockANpcs, self.getNpcId()))
  709. {
  710. //ToCheck: find easier way
  711. for (NpcInstance n : getNpcs())
  712. if (ArrayUtils.contains(blockANpcs, n.getNpcId()) && !n.isDead())
  713. return;
  714. for (int i = 0; i < corridorADoors.length; i++)
  715. openDoor(corridorADoors[i]);
  716. blockUnblockNpcs(true, blockBNpcs);
  717. }
  718. else if (self.getNpcId() == DarkChoirPlayer)
  719. {
  720. for (NpcInstance n : getNpcs())
  721. if (n.getNpcId() == DarkChoirPlayer && !n.isDead())
  722. return;
  723. for (int i = 0; i < hallBDoors.length; i++)
  724. openDoor(hallBDoors[i]);
  725. blockUnblockNpcs(false, blockBNpcs);
  726. }
  727. else if (ArrayUtils.contains(blockBNpcs, self.getNpcId()))
  728. {
  729. if (Rnd.chance(10))
  730. ((NpcInstance) self).dropItem(killer.getPlayer(), DewdropItem, 1);
  731. //ToCheck: find easier way
  732. for (NpcInstance n : getNpcs())
  733. if ((ArrayUtils.contains(blockBNpcs, n.getNpcId()) || ArrayUtils.contains(blockANpcs, n.getNpcId())) && !n.isDead())
  734. return;
  735. for (int i = 0; i < corridorBDoors.length; i++)
  736. openDoor(corridorBDoors[i]);
  737. ThreadPoolManager.getInstance().schedule(new FrintezzaStart(), battleStartDelay);
  738. }
  739. else if (self.getNpcId() == _weakScarletId)
  740. {
  741. self.decayMe();
  742. return;
  743. }
  744. else if (self.getNpcId() == _strongScarletId)
  745. {
  746. ThreadPoolManager.getInstance().schedule(new Die(1), 10);
  747. setReenterTime(System.currentTimeMillis());
  748. }
  749. }
  750. }
  751. }
  752.  
  753. public class ZoneListener implements OnZoneEnterLeaveListener
  754. {
  755. @Override
  756. public void onZoneEnter(Zone zone, Creature cha)
  757. {
  758. }
  759.  
  760. @Override
  761. public void onZoneLeave(Zone zone, Creature cha)
  762. {
  763. if (cha.isNpc() && (cha.getNpcId() == _weakScarletId || cha.getNpcId() == _strongScarletId))
  764. {
  765. cha.teleToLocation(new Location(-87784, -153304, -9176));
  766. ((NpcInstance) cha).getAggroList().clear(true);
  767. cha.setCurrentHpMp(cha.getMaxHp(), cha.getMaxMp());
  768. cha.broadcastCharInfo();
  769. }
  770. }
  771. }
  772.  
  773. @Override
  774. protected void onCollapse()
  775. {
  776. super.onCollapse();
  777.  
  778. if (musicTask != null)
  779. musicTask.cancel(true);
  780. }
  781. }
RAW Paste Data