Baium.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  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 static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
  17. import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
  18. import java.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.List;
  21. import java.util.logging.Level;
  22. import javolution.util.FastList;
  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.datatables.SkillTable;
  28. import com.l2jserver.gameserver.instancemanager.GrandBossManager;
  29. import com.l2jserver.gameserver.model.L2Effect;
  30. import com.l2jserver.gameserver.model.L2Object;
  31. import com.l2jserver.gameserver.model.L2Skill;
  32. import com.l2jserver.gameserver.model.actor.L2Character;
  33. import com.l2jserver.gameserver.model.actor.L2Npc;
  34. import com.l2jserver.gameserver.model.actor.L2Playable;
  35. import com.l2jserver.gameserver.model.actor.instance.L2DecoyInstance;
  36. import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
  37. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  38. import com.l2jserver.gameserver.model.quest.QuestTimer;
  39. import com.l2jserver.gameserver.model.zone.type.L2BossZone;
  40. import com.l2jserver.gameserver.network.serverpackets.Earthquake;
  41. import com.l2jserver.gameserver.network.serverpackets.MoveToPawn;
  42. import com.l2jserver.gameserver.network.serverpackets.PlaySound;
  43. import com.l2jserver.gameserver.network.serverpackets.SocialAction;
  44. import com.l2jserver.gameserver.templates.StatsSet;
  45. import com.l2jserver.gameserver.util.Util;
  46. import com.l2jserver.util.Rnd;
  47. /**
  48. * Baium AI
  49. *
  50. * Note1: if the server gets rebooted while players are still fighting Baium, there is no lock, but
  51. * players also lose their ability to wake baium up. However, should another person
  52. * enter the room and wake him up, the players who had stayed inside may join the raid.
  53. * This can be helpful for players who became victims of a reboot (they only need 1 new player to
  54. * enter and wake up baium) and is not too exploitable since any player wishing to exploit it
  55. * would have to suffer 5 days of being parked in an empty room.
  56. * Note2: Neither version of Baium should be a permanent spawn. This script is fully capable of
  57. * spawning the statue-version when the lock expires and switching it to the mob version promptly.
  58. *
  59. * Additional notes ( source http://aleenaresron.blogspot.com/2006_08_01_archive.html ):
  60. * * Baium only first respawns five days after his last death. And from those five days he will
  61. * respawn within 1-8 hours of his last death. So, you have to know his last time of death.
  62. * * If by some freak chance you are the only one in Baium's chamber and NO ONE comes in
  63. * [ha, ha] you or someone else will have to wake Baium. There is a good chance that Baium
  64. * will automatically kill whoever wakes him. There are some people that have been able to
  65. * wake him and not die, however if you've already gone through the trouble of getting the
  66. * bloody fabric and camped him out and researched his spawn time, are you willing to take that
  67. * chance that you'll wake him and not be able to finish your quest? Doubtful.
  68. * [ this powerful attack vs the player who wakes him up is NOT yet implemented here]
  69. * * once someone starts attacking Baium no one else can port into the chamber where he is.
  70. * Unlike with the other raid bosses, you can just show up at any time as long as you are there
  71. * when they die. Not true with Baium. Once he gets attacked, the port to Baium closes. byebye,
  72. * see you in 5 days. If nobody attacks baium for 30 minutes, he auto-despawns and unlocks the
  73. * vortex
  74. *
  75. * @author Fulminus version 0.1
  76. */
  77. public class Baium extends L2AttackableAIScript
  78. {
  79. private L2Character _target;
  80. private L2Skill _skill;
  81. private static final int STONE_BAIUM = 29025;
  82. private static final int ANGELIC_VORTEX = 31862;
  83. private static final int LIVE_BAIUM = 29020;
  84. private static final int ARCHANGEL = 29021;
  85. //Baium status tracking
  86. private static final byte ASLEEP = 0; // baium is in the stone version, waiting to be woken up. Entry is unlocked
  87. private static final byte AWAKE = 1; // baium is awake and fighting. Entry is locked.
  88. private static final byte DEAD = 2; // baium has been killed and has not yet spawned. Entry is locked
  89. // fixed archangel spawnloc
  90. private final static int ANGEL_LOCATION[][] =
  91. {
  92. { 114239, 17168, 10080, 63544 },
  93. { 115780, 15564, 10080, 13620 },
  94. { 114880, 16236, 10080, 5400 },
  95. { 115168, 17200, 10080, 0 },
  96. { 115792, 16608, 10080, 0 },
  97. };
  98. private long _LastAttackVsBaiumTime = 0;
  99. private final List<L2Npc> _Minions = new ArrayList<L2Npc>(5);
  100. private L2BossZone _Zone;
  101. public Baium (int questId, String name, String descr)
  102. {
  103. super(questId, name, descr);
  104. int[] mob = {LIVE_BAIUM};
  105. this.registerMobs(mob);
  106. // Quest NPC starter initialization
  107. addStartNpc(STONE_BAIUM);
  108. addStartNpc(ANGELIC_VORTEX);
  109. addTalkId(STONE_BAIUM);
  110. addTalkId(ANGELIC_VORTEX);
  111. _Zone = GrandBossManager.getInstance().getZone(113100,14500,10077);
  112. StatsSet info = GrandBossManager.getInstance().getStatsSet(LIVE_BAIUM);
  113. int status = GrandBossManager.getInstance().getBossStatus(LIVE_BAIUM);
  114. if (status == DEAD)
  115. {
  116. // load the unlock date and time for baium from DB
  117. long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
  118. if (temp > 0)
  119. {
  120. // the unlock time has not yet expired. Mark Baium as currently locked (dead). Setup a timer
  121. // to fire at the correct time (calculate the time between now and the unlock time,
  122. // setup a timer to fire after that many msec)
  123. startQuestTimer("baium_unlock", temp, null, null);
  124. }
  125. else
  126. {
  127. // the time has already expired while the server was offline. Delete the saved time and
  128. // immediately spawn the stone-baium. Also the state need not be changed from ASLEEP
  129. addSpawn(STONE_BAIUM,116033,17447,10104,40188,false,0);
  130. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM,ASLEEP);
  131. }
  132. }
  133. else if (status == AWAKE)
  134. {
  135. int loc_x = info.getInteger("loc_x");
  136. int loc_y = info.getInteger("loc_y");
  137. int loc_z = info.getInteger("loc_z");
  138. int heading = info.getInteger("heading");
  139. final int hp = info.getInteger("currentHP");
  140. final int mp = info.getInteger("currentMP");
  141. L2GrandBossInstance baium = (L2GrandBossInstance) addSpawn(LIVE_BAIUM,loc_x,loc_y,loc_z,heading,false,0);
  142. GrandBossManager.getInstance().addBoss(baium);
  143. final L2Npc _baium = baium;
  144. ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
  145. @Override
  146. public void run()
  147. {
  148. try
  149. {
  150. _baium.setCurrentHpMp(hp,mp);
  151. _baium.setIsInvul(true);
  152. _baium.setIsImmobilized(true);
  153. _baium.setRunning();
  154. _baium.broadcastPacket(new SocialAction(_baium,2));
  155. startQuestTimer("baium_wakeup",15000, _baium, null);
  156. }
  157. catch (Exception e)
  158. {
  159. e.printStackTrace();
  160. }
  161. }
  162. },100L);
  163. }
  164. else
  165. addSpawn(STONE_BAIUM,116033,17447,10104,40188,false,0);
  166. }
  167. @Override
  168. public String onAdvEvent (String event, L2Npc npc, L2PcInstance player)
  169. {
  170. if (event.equalsIgnoreCase("baium_unlock"))
  171. {
  172. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM,ASLEEP);
  173. addSpawn(STONE_BAIUM,116033,17447,10104,40188,false,0);
  174. }
  175. else if (event.equalsIgnoreCase("skill_range") && npc != null)
  176. {
  177. callSkillAI(npc);
  178. }
  179. else if (event.equalsIgnoreCase("clean_player"))
  180. {
  181. _target = getRandomTarget(npc);
  182. }
  183. else if (event.equalsIgnoreCase("baium_wakeup") && npc != null)
  184. {
  185. if (npc.getNpcId() == LIVE_BAIUM)
  186. {
  187. npc.broadcastPacket(new SocialAction(npc,1));
  188. npc.broadcastPacket(new Earthquake(npc.getX(), npc.getY(), npc.getZ(),40,5));
  189. // start monitoring baium's inactivity
  190. _LastAttackVsBaiumTime = System.currentTimeMillis();
  191. startQuestTimer("baium_despawn", 60000, npc, null, true);
  192. startQuestTimer("skill_range", 500, npc, null, true);
  193. final L2Npc baium = npc;
  194. ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
  195. @Override
  196. public void run()
  197. {
  198. try
  199. {
  200. baium.setIsInvul(false);
  201. baium.setIsImmobilized(false);
  202. for (L2Npc minion : _Minions)
  203. minion.setShowSummonAnimation(false);
  204. }
  205. catch (Exception e)
  206. {
  207. _log.log(Level.WARNING, "", e);
  208. }
  209. }
  210. },11100L);
  211. // TODO: the person who woke baium up should be knocked across the room, onto a wall, and
  212. // lose massive amounts of HP.
  213. for (int i = 0; i < ANGEL_LOCATION.length; i++)
  214. {
  215. L2Npc angel = addSpawn(ARCHANGEL, ANGEL_LOCATION[i][0], ANGEL_LOCATION[i][1], ANGEL_LOCATION[i][2], ANGEL_LOCATION[i][3], false, 0, true);
  216. angel.setIsInvul(true);
  217. _Minions.add(angel);
  218. }
  219. }
  220. // despawn the live baium after 30 minutes of inactivity
  221. // also check if the players are cheating, having pulled Baium outside his zone...
  222. }
  223. else if (event.equalsIgnoreCase("baium_despawn") && npc != null)
  224. {
  225. if (npc.getNpcId() == LIVE_BAIUM)
  226. {
  227. // just in case the zone reference has been lost (somehow...), restore the reference
  228. if (_Zone == null)
  229. _Zone = GrandBossManager.getInstance().getZone(113100,14500,10077);
  230. if (_LastAttackVsBaiumTime + 1800000 < System.currentTimeMillis())
  231. {
  232. npc.deleteMe(); // despawn the live-baium
  233. for (L2Npc minion : _Minions)
  234. if (minion != null)
  235. {
  236. minion.getSpawn().stopRespawn();
  237. minion.deleteMe();
  238. }
  239. _Minions.clear();
  240. addSpawn(STONE_BAIUM,116033,17447,10104,40188,false,0); // spawn stone-baium
  241. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM,ASLEEP); // mark that Baium is not awake any more
  242. _Zone.oustAllPlayers();
  243. cancelQuestTimer("baium_despawn", npc, null);
  244. }
  245. else if ((_LastAttackVsBaiumTime + 300000 < System.currentTimeMillis()) && npc.getCurrentHp() < ( ( npc.getMaxHp() * 3 ) / 4.0 ))
  246. {
  247. npc.setIsCastingNow(false); //just in case
  248. npc.setTarget(npc);
  249. L2Skill skill = SkillTable.getInstance().getInfo(4135, 1);
  250. if (skill.isMagic())
  251. {
  252. if (npc.isMuted())
  253. return super.onAdvEvent(event, npc, player);
  254. }
  255. else
  256. {
  257. if (npc.isPhysicalMuted())
  258. return super.onAdvEvent(event, npc, player);
  259. }
  260. npc.doCast(skill);
  261. npc.setIsCastingNow(true);
  262. }
  263. else if (!_Zone.isInsideZone(npc))
  264. npc.teleToLocation(116033,17447,10104);
  265. }
  266. }
  267. return super.onAdvEvent(event, npc, player);
  268. }
  269. @Override
  270. public String onTalk(L2Npc npc,L2PcInstance player)
  271. {
  272. int npcId = npc.getNpcId();
  273. String htmltext = "";
  274. if (_Zone == null)
  275. _Zone = GrandBossManager.getInstance().getZone(113100,14500,10077);
  276. if (_Zone == null)
  277. return "<html><body>Angelic Vortex:<br>You may not enter while admin disabled this zone</body></html>";
  278. if (npcId == STONE_BAIUM && GrandBossManager.getInstance().getBossStatus(LIVE_BAIUM) == ASLEEP)
  279. {
  280. if (_Zone.isPlayerAllowed(player))
  281. {
  282. // once Baium is awaken, no more people may enter until he dies, the server reboots, or
  283. // 30 minutes pass with no attacks made against Baium.
  284. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM,AWAKE);
  285. npc.deleteMe();
  286. L2GrandBossInstance baium = (L2GrandBossInstance) addSpawn(LIVE_BAIUM, npc, true);
  287. GrandBossManager.getInstance().addBoss(baium);
  288. final L2Npc _baium = baium;
  289. ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
  290. @Override
  291. public void run()
  292. {
  293. try
  294. {
  295. _baium.setIsInvul(true);
  296. _baium.setRunning();
  297. _baium.broadcastPacket(new SocialAction(_baium,2));
  298. startQuestTimer("baium_wakeup",15000, _baium, null);
  299. _baium.setShowSummonAnimation(false);
  300. }
  301. catch (Throwable e)
  302. {
  303. _log.log(Level.WARNING, "", e);
  304. }
  305. }
  306. },100L);
  307. }
  308. else
  309. htmltext = "Conditions are not right to wake up Baium";
  310. }
  311. else if (npcId == ANGELIC_VORTEX)
  312. {
  313. if (player.isFlying())
  314. {
  315. //print "Player "+player.getName()+" attempted to enter Baium's lair while flying!";
  316. return "<html><body>Angelic Vortex:<br>You may not enter while flying a wyvern</body></html>";
  317. }
  318. if (GrandBossManager.getInstance().getBossStatus(LIVE_BAIUM) == ASLEEP
  319. && player.getQuestState("baium").getQuestItemsCount(4295) > 0) // bloody fabric
  320. {
  321. player.getQuestState("baium").takeItems(4295,1);
  322. // allow entry for the player for the next 30 secs (more than enough time for the TP to happen)
  323. // Note: this just means 30secs to get in, no limits on how long it takes before we get out.
  324. _Zone.allowPlayerEntry(player,30);
  325. player.teleToLocation(113100,14500,10077);
  326. }
  327. else
  328. npc.showChatWindow(player, 1);
  329. }
  330. return htmltext;
  331. }
  332. @Override
  333. public String onSpellFinished(L2Npc npc, L2PcInstance player, L2Skill skill)
  334. {
  335. if (npc.isInvul())
  336. {
  337. npc.getAI().setIntention(AI_INTENTION_IDLE);
  338. return null;
  339. }
  340. else if (npc.getNpcId() == LIVE_BAIUM && !npc.isInvul())
  341. {
  342. callSkillAI(npc);
  343. }
  344. return super.onSpellFinished(npc, player, skill);
  345. }
  346. @Override
  347. public String onSpawn(L2Npc npc)
  348. {
  349. npc.disableCoreAI(true);
  350. return super.onSpawn(npc);
  351. }
  352. @Override
  353. public String onAttack (L2Npc npc, L2PcInstance attacker, int damage, boolean isPet)
  354. {
  355. if (!_Zone.isInsideZone(attacker))
  356. {
  357. attacker.reduceCurrentHp(attacker.getCurrentHp(),attacker,false,false, null);
  358. return super.onAttack(npc, attacker, damage, isPet);
  359. }
  360. if (npc.isInvul())
  361. {
  362. npc.getAI().setIntention(AI_INTENTION_IDLE);
  363. return super.onAttack(npc, attacker, damage, isPet);
  364. }
  365. else if (npc.getNpcId() == LIVE_BAIUM && !npc.isInvul())
  366. {
  367. if (attacker.getMountType() == 1)
  368. {
  369. int sk_4258 = 0;
  370. L2Effect[] effects = attacker.getAllEffects();
  371. if (effects != null && effects.length != 0)
  372. {
  373. for (L2Effect e : effects)
  374. {
  375. if (e.getSkill().getId() == 4258)
  376. sk_4258 = 1;
  377. }
  378. }
  379. if (sk_4258 == 0)
  380. {
  381. npc.setTarget(attacker);
  382. L2Skill skill = SkillTable.getInstance().getInfo(4258,1);
  383. if (skill.isMagic())
  384. {
  385. if (npc.isMuted())
  386. return super.onAttack(npc, attacker, damage, isPet);
  387. }
  388. else
  389. {
  390. if (npc.isPhysicalMuted())
  391. return super.onAttack(npc, attacker, damage, isPet);
  392. }
  393. npc.doCast(skill);
  394. }
  395. }
  396. // update a variable with the last action against baium
  397. _LastAttackVsBaiumTime = System.currentTimeMillis();
  398. callSkillAI(npc);
  399. }
  400. return super.onAttack(npc, attacker, damage, isPet);
  401. }
  402. @Override
  403. public String onKill (L2Npc npc, L2PcInstance killer, boolean isPet)
  404. {
  405. cancelQuestTimer("baium_despawn", npc, null);
  406. npc.broadcastPacket(new PlaySound(1, "BS01_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
  407. // spawn the "Teleportation Cubic" for 15 minutes (to allow players to exit the lair)
  408. addSpawn(29055,115203,16620,10078,0,false,900000); ////should we teleport everyone out if the cubic despawns??
  409. // "lock" baium for 5 days and 1 to 8 hours [i.e. 432,000,000 + 1*3,600,000 + random-less-than(8*3,600,000) millisecs]
  410. long respawnTime = (long)Config.Interval_Of_Baium_Spawn + Rnd.get(Config.Random_Of_Baium_Spawn);
  411. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM,DEAD);
  412. startQuestTimer("baium_unlock", respawnTime, null, null);
  413. // also save the respawn time so that the info is maintained past reboots
  414. StatsSet info = GrandBossManager.getInstance().getStatsSet(LIVE_BAIUM);
  415. info.set("respawn_time",(System.currentTimeMillis()) + respawnTime);
  416. GrandBossManager.getInstance().setStatsSet(LIVE_BAIUM,info);
  417. for (L2Npc minion : _Minions)
  418. if (minion != null)
  419. {
  420. minion.getSpawn().stopRespawn();
  421. minion.deleteMe();
  422. }
  423. _Minions.clear();
  424. if (getQuestTimer("skill_range", npc, null) != null)
  425. getQuestTimer("skill_range", npc, null).cancel();
  426. return super.onKill(npc,killer,isPet);
  427. }
  428. public L2Character getRandomTarget(L2Npc npc)
  429. {
  430. FastList<L2Character> result = FastList.newInstance();
  431. Collection<L2Object> objs = npc.getKnownList().getKnownObjects().values();
  432. {
  433. for (L2Object obj : objs)
  434. {
  435. if (obj instanceof L2Playable || obj instanceof L2DecoyInstance)
  436. {
  437. if (obj instanceof L2PcInstance)
  438. {
  439. if (((L2PcInstance) obj).getAppearance().getInvisible())
  440. continue;
  441. }
  442. if (((L2Character) obj).getZ() < ( npc.getZ() - 100 ) && ((L2Character) obj).getZ() > ( npc.getZ() + 100 )
  443. || !(GeoData.getInstance().canSeeTarget(((L2Character) obj).getX(), ((L2Character) obj).getY(), ((L2Character) obj).getZ(), npc.getX(), npc.getY(), npc.getZ())))
  444. continue;
  445. }
  446. if (obj instanceof L2Playable || obj instanceof L2DecoyInstance)
  447. {
  448. if (Util.checkIfInRange(9000, npc, obj, true) && !((L2Character) obj).isDead())
  449. result.add((L2Character) obj);
  450. }
  451. }
  452. }
  453. if (result.isEmpty())
  454. {
  455. for (L2Npc minion : _Minions)
  456. if (minion != null)
  457. result.add(minion);
  458. }
  459. if (result.isEmpty())
  460. {
  461. FastList.recycle(result);
  462. return null;
  463. }
  464. Object[] characters = result.toArray();
  465. QuestTimer timer = getQuestTimer("clean_player", npc, null);
  466. if (timer != null)
  467. timer.cancel();
  468. startQuestTimer("clean_player", 20000, npc, null);
  469. L2Character target = (L2Character) characters[Rnd.get(characters.length)];
  470. FastList.recycle(result);
  471. return target;
  472. }
  473. public synchronized void callSkillAI(L2Npc npc)
  474. {
  475. if (npc.isInvul() || npc.isCastingNow())
  476. return;
  477. if (_target == null || _target.isDead() || !(_Zone.isInsideZone(_target)))
  478. {
  479. _target = getRandomTarget(npc);
  480. if (_target != null)
  481. _skill = SkillTable.getInstance().getInfo(getRandomSkill(npc),1);
  482. }
  483. L2Character target = _target;
  484. L2Skill skill = _skill;
  485. if (skill == null)
  486. skill = SkillTable.getInstance().getInfo(getRandomSkill(npc),1);
  487. if (skill.isMagic())
  488. {
  489. if (npc.isMuted())
  490. return;
  491. }
  492. else
  493. {
  494. if (npc.isPhysicalMuted())
  495. return;
  496. }
  497. if (target == null || target.isDead() || !(_Zone.isInsideZone(target)))
  498. {
  499. npc.setIsCastingNow(false);
  500. return;
  501. }
  502. if (Util.checkIfInRange(skill.getCastRange(), npc, target, true))
  503. {
  504. npc.getAI().setIntention(AI_INTENTION_IDLE);
  505. npc.setTarget(target);
  506. npc.setIsCastingNow(true);
  507. _target = null;
  508. _skill = null;
  509. if (getDist(skill.getCastRange()) > 0)
  510. npc.broadcastPacket(new MoveToPawn(npc,target,getDist(skill.getCastRange())));
  511. try
  512. {
  513. Thread.sleep(1000);
  514. npc.stopMove(null);
  515. npc.doCast(skill);
  516. }
  517. catch (Exception e)
  518. {e.printStackTrace();}
  519. }
  520. else
  521. {
  522. npc.getAI().setIntention(AI_INTENTION_FOLLOW, target, null);
  523. npc.setIsCastingNow(false);
  524. }
  525. }
  526. public int getRandomSkill(L2Npc npc)
  527. {
  528. int skill;
  529. if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 3 ) / 4.0 ) )
  530. {
  531. if( Rnd.get(100) < 10 )
  532. skill = 4128;
  533. else if( Rnd.get(100) < 10 )
  534. skill = 4129;
  535. else
  536. skill = 4127;
  537. }
  538. else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 2 ) / 4.0) )
  539. {
  540. if( Rnd.get(100) < 10 )
  541. skill = 4131;
  542. else if( Rnd.get(100) < 10 )
  543. skill = 4128;
  544. else if( Rnd.get(100) < 10 )
  545. skill = 4129;
  546. else
  547. skill = 4127;
  548. }
  549. else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 1 ) / 4.0 ) )
  550. {
  551. if( Rnd.get(100) < 10 )
  552. skill = 4130;
  553. else if( Rnd.get(100) < 10 )
  554. skill = 4131;
  555. else if( Rnd.get(100) < 10 )
  556. skill = 4128;
  557. else if( Rnd.get(100) < 10 )
  558. skill = 4129;
  559. else
  560. skill = 4127;
  561. }
  562. else if( Rnd.get(100) < 10 )
  563. skill = 4130;
  564. else if( Rnd.get(100) < 10 )
  565. skill = 4131;
  566. else if( Rnd.get(100) < 10 )
  567. skill = 4128;
  568. else if( Rnd.get(100) < 10 )
  569. skill = 4129;
  570. else
  571. skill = 4127;
  572. return skill;
  573. }
  574. @Override
  575. public String onSkillSee (L2Npc npc, L2PcInstance caster, L2Skill skill, L2Object[] targets, boolean isPet)
  576. {
  577. if (npc.isInvul())
  578. {
  579. npc.getAI().setIntention(AI_INTENTION_IDLE);
  580. return null;
  581. }
  582. npc.setTarget(caster);
  583. return super.onSkillSee(npc, caster, skill, targets, isPet);
  584. }
  585. public int getDist(int range)
  586. {
  587. int dist = 0;
  588. switch(range)
  589. {
  590. case -1:
  591. break;
  592. case 100:
  593. dist = 85;
  594. break;
  595. default:
  596. dist = range-85;
  597. break;
  598. }
  599. return dist;
  600. }
  601. public static void main(String[] args)
  602. {
  603. // Quest class and state definition
  604. new Baium(-1, "baium", "ai");
  605. }
  606. }