Sailren.java 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * Copyright (C) 2004-2014 L2J DataPack
  3. *
  4. * This file is part of L2J DataPack.
  5. *
  6. * L2J DataPack is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J DataPack is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package ai.individual.Sailren;
  20. import ai.npc.AbstractNpcAI;
  21. import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
  22. import com.l2jserver.gameserver.instancemanager.ZoneManager;
  23. import com.l2jserver.gameserver.model.TeleportWhereType;
  24. import com.l2jserver.gameserver.model.actor.L2Attackable;
  25. import com.l2jserver.gameserver.model.actor.L2Character;
  26. import com.l2jserver.gameserver.model.actor.L2Npc;
  27. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  28. import com.l2jserver.gameserver.model.actor.instance.L2RaidBossInstance;
  29. import com.l2jserver.gameserver.model.holders.SkillHolder;
  30. import com.l2jserver.gameserver.model.zone.type.L2NoRestartZone;
  31. import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
  32. /**
  33. * Sailren AI.
  34. * @author St3eT
  35. */
  36. public final class Sailren extends AbstractNpcAI
  37. {
  38. // NPCs
  39. private static final int STATUE = 32109; // Shilen's Stone Statue
  40. private static final int MOVIE_NPC = 32110; // Invisible NPC for movie
  41. private static final int SAILREN = 29065; // Sailren
  42. private static final int VELOCIRAPTOR = 22218; // Velociraptor
  43. private static final int PTEROSAUR = 22199; // Pterosaur
  44. private static final int TREX = 22217; // Tyrannosaurus
  45. private static final int CUBIC = 32107; // Teleportation Cubic
  46. // Item
  47. private static final int GAZKH = 8784; // Gazkh
  48. // Skill
  49. private static final SkillHolder ANIMATION = new SkillHolder(5090, 1);
  50. // Zone
  51. private static final L2NoRestartZone zone = ZoneManager.getInstance().getZoneById(70049, L2NoRestartZone.class);
  52. // Misc
  53. private static final int RESPAWN = 1; // Respawn time (in hours)
  54. private static final int MAX_TIME = 3200; // Max time for Sailren fight (in minutes)
  55. private static Status STATUS = Status.ALIVE;
  56. private static int _killCount = 0;
  57. private static long _lastAttack = 0;
  58. private static enum Status
  59. {
  60. ALIVE,
  61. IN_FIGHT,
  62. DEAD
  63. }
  64. private Sailren()
  65. {
  66. super(Sailren.class.getSimpleName(), "ai/individual");
  67. addStartNpc(STATUE, CUBIC);
  68. addTalkId(STATUE, CUBIC);
  69. addFirstTalkId(STATUE);
  70. addKillId(VELOCIRAPTOR, PTEROSAUR, TREX, SAILREN);
  71. addAttackId(VELOCIRAPTOR, PTEROSAUR, TREX, SAILREN);
  72. final long remain = GlobalVariablesManager.getInstance().getLong("SailrenRespawn", 0) - System.currentTimeMillis();
  73. if (remain > 0)
  74. {
  75. STATUS = Status.DEAD;
  76. startQuestTimer("CLEAR_STATUS", remain, null, null);
  77. }
  78. }
  79. @Override
  80. public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  81. {
  82. switch (event)
  83. {
  84. case "32109-01.html":
  85. case "32109-01a.html":
  86. case "32109-02a.html":
  87. case "32109-03a.html":
  88. {
  89. return event;
  90. }
  91. case "enter":
  92. {
  93. String htmltext = null;
  94. if (!player.isInParty())
  95. {
  96. htmltext = "32109-01.html";
  97. }
  98. else if (STATUS == Status.DEAD)
  99. {
  100. htmltext = "32109-04.html";
  101. }
  102. else if (STATUS == Status.IN_FIGHT)
  103. {
  104. htmltext = "32109-05.html";
  105. }
  106. else if (!player.getParty().isLeader(player))
  107. {
  108. htmltext = "32109-03.html";
  109. }
  110. else if (!hasQuestItems(player, GAZKH))
  111. {
  112. htmltext = "32109-02.html";
  113. }
  114. else
  115. {
  116. takeItems(player, GAZKH, 1);
  117. STATUS = Status.IN_FIGHT;
  118. _lastAttack = System.currentTimeMillis();
  119. for (L2PcInstance member : player.getParty().getMembers())
  120. {
  121. if (member.isInsideRadius(npc, 1000, true, false))
  122. {
  123. member.teleToLocation(27549, -6638, -2008);
  124. }
  125. }
  126. startQuestTimer("SPAWN_VELOCIRAPTOR", 60000, null, null);
  127. startQuestTimer("TIME_OUT", MAX_TIME * 1000, null, null);
  128. startQuestTimer("CHECK_ATTACK", 120000, null, null);
  129. }
  130. return htmltext;
  131. }
  132. case "teleportOut":
  133. {
  134. player.teleToLocation(TeleportWhereType.TOWN);
  135. break;
  136. }
  137. case "SPAWN_VELOCIRAPTOR":
  138. {
  139. for (int i = 0; i < 3; i++)
  140. {
  141. addSpawn(VELOCIRAPTOR, 27313 + getRandom(150), -6766 + getRandom(150), -1975, 0, false, 0);
  142. }
  143. break;
  144. }
  145. case "SPAWN_SAILREN":
  146. {
  147. final L2RaidBossInstance sailren = (L2RaidBossInstance) addSpawn(SAILREN, 27549, -6638, -2008, 0, false, 0);
  148. final L2Npc movieNpc = addSpawn(MOVIE_NPC, sailren.getX(), sailren.getY(), sailren.getZ() + 30, 0, false, 26000);
  149. sailren.setIsInvul(true);
  150. sailren.setIsImmobilized(true);
  151. zone.broadcastPacket(new SpecialCamera(movieNpc, 60, 110, 30, 4000, 1500, 20000, 0, 65, 1, 0, 0));
  152. startQuestTimer("ATTACK", 24600, sailren, null);
  153. startQuestTimer("ANIMATION", 2000, movieNpc, null);
  154. startQuestTimer("CAMERA_1", 4100, movieNpc, null);
  155. break;
  156. }
  157. case "ANIMATION":
  158. {
  159. if (npc != null)
  160. {
  161. npc.setTarget(npc);
  162. npc.doCast(ANIMATION.getSkill());
  163. startQuestTimer("ANIMATION", 2000, npc, null);
  164. }
  165. break;
  166. }
  167. case "CAMERA_1":
  168. {
  169. zone.broadcastPacket(new SpecialCamera(npc, 100, 180, 30, 3000, 1500, 20000, 0, 50, 1, 0, 0));
  170. startQuestTimer("CAMERA_2", 3000, npc, null);
  171. break;
  172. }
  173. case "CAMERA_2":
  174. {
  175. zone.broadcastPacket(new SpecialCamera(npc, 150, 270, 25, 3000, 1500, 20000, 0, 30, 1, 0, 0));
  176. startQuestTimer("CAMERA_3", 3000, npc, null);
  177. break;
  178. }
  179. case "CAMERA_3":
  180. {
  181. zone.broadcastPacket(new SpecialCamera(npc, 160, 360, 20, 3000, 1500, 20000, 10, 15, 1, 0, 0));
  182. startQuestTimer("CAMERA_4", 3000, npc, null);
  183. break;
  184. }
  185. case "CAMERA_4":
  186. {
  187. zone.broadcastPacket(new SpecialCamera(npc, 160, 450, 10, 3000, 1500, 20000, 0, 10, 1, 0, 0));
  188. startQuestTimer("CAMERA_5", 3000, npc, null);
  189. break;
  190. }
  191. case "CAMERA_5":
  192. {
  193. zone.broadcastPacket(new SpecialCamera(npc, 160, 560, 0, 3000, 1500, 20000, 0, 10, 1, 0, 0));
  194. startQuestTimer("CAMERA_6", 7000, npc, null);
  195. break;
  196. }
  197. case "CAMERA_6":
  198. {
  199. zone.broadcastPacket(new SpecialCamera(npc, 70, 560, 0, 500, 1500, 7000, -15, 20, 1, 0, 0));
  200. break;
  201. }
  202. case "ATTACK":
  203. {
  204. npc.setIsInvul(false);
  205. npc.setIsImmobilized(false);
  206. break;
  207. }
  208. case "CLEAR_STATUS":
  209. {
  210. STATUS = Status.ALIVE;
  211. break;
  212. }
  213. case "TIME_OUT":
  214. {
  215. if (STATUS == Status.IN_FIGHT)
  216. {
  217. STATUS = Status.ALIVE;
  218. }
  219. for (L2Character charInside : zone.getCharactersInside())
  220. {
  221. if (charInside != null)
  222. {
  223. if (charInside.isPlayer())
  224. {
  225. charInside.teleToLocation(TeleportWhereType.TOWN);
  226. }
  227. else if (charInside.isNpc())
  228. {
  229. charInside.deleteMe();
  230. }
  231. }
  232. }
  233. break;
  234. }
  235. case "CHECK_ATTACK":
  236. {
  237. if (!zone.getPlayersInside().isEmpty() && ((_lastAttack + 600000) < System.currentTimeMillis()))
  238. {
  239. cancelQuestTimer("TIME_OUT", null, null);
  240. notifyEvent("TIME_OUT", null, null);
  241. }
  242. else
  243. {
  244. startQuestTimer("CHECK_ATTACK", 120000, null, null);
  245. }
  246. break;
  247. }
  248. }
  249. return super.onAdvEvent(event, npc, player);
  250. }
  251. @Override
  252. public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
  253. {
  254. if (zone.isCharacterInZone(attacker))
  255. {
  256. _lastAttack = System.currentTimeMillis();
  257. }
  258. return super.onAttack(npc, attacker, damage, isSummon);
  259. }
  260. @Override
  261. public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
  262. {
  263. if (zone.isCharacterInZone(killer))
  264. {
  265. switch (npc.getId())
  266. {
  267. case SAILREN:
  268. {
  269. STATUS = Status.DEAD;
  270. addSpawn(CUBIC, 27644, -6638, -2008, 0, false, 300000);
  271. final long respawnTime = RESPAWN * 3600000;
  272. GlobalVariablesManager.getInstance().set("SailrenRespawn", System.currentTimeMillis() + respawnTime);
  273. cancelQuestTimer("CHECK_ATTACK", null, null);
  274. cancelQuestTimer("TIME_OUT", null, null);
  275. startQuestTimer("CLEAR_STATUS", respawnTime, null, null);
  276. startQuestTimer("TIME_OUT", 300000, null, null);
  277. break;
  278. }
  279. case VELOCIRAPTOR:
  280. {
  281. _killCount++;
  282. if (_killCount == 3)
  283. {
  284. final L2Attackable pterosaur = (L2Attackable) addSpawn(PTEROSAUR, 27313, -6766, -1975, 0, false, 0);
  285. attackPlayer(pterosaur, killer);
  286. _killCount = 0;
  287. }
  288. break;
  289. }
  290. case PTEROSAUR:
  291. {
  292. final L2Attackable trex = (L2Attackable) addSpawn(TREX, 27313, -6766, -1975, 0, false, 0);
  293. attackPlayer(trex, killer);
  294. break;
  295. }
  296. case TREX:
  297. {
  298. startQuestTimer("SPAWN_SAILREN", 180000, null, null);
  299. break;
  300. }
  301. }
  302. }
  303. return super.onKill(npc, killer, isSummon);
  304. }
  305. @Override
  306. public boolean unload(boolean removeFromList)
  307. {
  308. if (STATUS == Status.IN_FIGHT)
  309. {
  310. _log.info(getClass().getSimpleName() + ": Script is being unloaded while Sailren is active, clearing zone.");
  311. notifyEvent("TIME_OUT", null, null);
  312. }
  313. return super.unload(removeFromList);
  314. }
  315. public static void main(String[] args)
  316. {
  317. new Sailren();
  318. }
  319. }