Sailren.java 9.5 KB

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