Baium.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /*
  2. * Copyright (C) 2004-2013 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;
  20. import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
  21. import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
  22. import java.util.ArrayList;
  23. import java.util.Collection;
  24. import java.util.List;
  25. import java.util.logging.Level;
  26. import javolution.util.FastList;
  27. import ai.npc.AbstractNpcAI;
  28. import com.l2jserver.Config;
  29. import com.l2jserver.gameserver.GeoData;
  30. import com.l2jserver.gameserver.ThreadPoolManager;
  31. import com.l2jserver.gameserver.enums.MountType;
  32. import com.l2jserver.gameserver.instancemanager.GrandBossManager;
  33. import com.l2jserver.gameserver.model.L2Object;
  34. import com.l2jserver.gameserver.model.Location;
  35. import com.l2jserver.gameserver.model.StatsSet;
  36. import com.l2jserver.gameserver.model.actor.L2Character;
  37. import com.l2jserver.gameserver.model.actor.L2Npc;
  38. import com.l2jserver.gameserver.model.actor.instance.L2DecoyInstance;
  39. import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
  40. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  41. import com.l2jserver.gameserver.model.holders.SkillHolder;
  42. import com.l2jserver.gameserver.model.quest.QuestTimer;
  43. import com.l2jserver.gameserver.model.skills.L2Skill;
  44. import com.l2jserver.gameserver.model.zone.type.L2BossZone;
  45. import com.l2jserver.gameserver.network.serverpackets.Earthquake;
  46. import com.l2jserver.gameserver.network.serverpackets.MoveToPawn;
  47. import com.l2jserver.gameserver.network.serverpackets.PlaySound;
  48. import com.l2jserver.gameserver.util.Util;
  49. /**
  50. * Baium's AI.
  51. * @author Fulminus
  52. */
  53. public class Baium extends AbstractNpcAI
  54. {
  55. // NPCs
  56. private static final int STONE_BAIUM = 29025;
  57. private static final int ANGELIC_VORTEX = 31862;
  58. private static final int LIVE_BAIUM = 29020;
  59. private static final int ARCHANGEL = 29021;
  60. private static final int TELEPORT_CUBIC = 31842;
  61. // Item
  62. private static final int BLOODED_FABRIC = 4295;
  63. // Baium status tracking
  64. private static final byte ASLEEP = 0; // baium is in the stone version, waiting to be woken up. Entry is unlocked
  65. private static final byte AWAKE = 1; // baium is awake and fighting. Entry is locked.
  66. private static final byte DEAD = 2; // baium has been killed and has not yet spawned. Entry is locked
  67. // Fixed archangel spawn location
  68. private static final Location[] ANGEL_LOCATION =
  69. {
  70. new Location(114239, 17168, 10080, 63544),
  71. new Location(115780, 15564, 10080, 13620),
  72. new Location(114880, 16236, 10080, 5400),
  73. new Location(115168, 17200, 10080, 0),
  74. new Location(115792, 16608, 10080, 0)
  75. };
  76. private static final Location[] TELEPORT_CUBIC_LOCATION = new Location[]
  77. {
  78. new Location(108784, 16000, -4928),
  79. new Location(113824, 10448, -5164),
  80. new Location(115488, 22096, -5168),
  81. };
  82. private static final Location BAIUM_DESPAWN = new Location(116033, 17447, 10104);
  83. private static final Location BAIUM_ENTER = new Location(113100, 14500, 10077);
  84. // Skills
  85. private static final SkillHolder GENERAL_ATTACK = new SkillHolder(4127, 1);
  86. private static final SkillHolder WIND_OF_FORCE = new SkillHolder(4128, 1);
  87. private static final SkillHolder EARTHQUAKE = new SkillHolder(4129, 1);
  88. private static final SkillHolder STRIKING_OF_THUNDERBOLT = new SkillHolder(4130, 1);
  89. private static final SkillHolder STUN = new SkillHolder(4131, 1);
  90. private static final SkillHolder BAIUM_HEAL = new SkillHolder(4135, 1);
  91. private static final SkillHolder HINDER_STRIDER = new SkillHolder(4258, 1);
  92. // private static final SkillHolder PRESENT_FROM_BAIUM = new SkillHolder(4136, 1);
  93. private long _LastAttackVsBaiumTime = 0;
  94. protected final List<L2Npc> _Minions = new ArrayList<>(5);
  95. private L2BossZone _Zone;
  96. private L2Character _target;
  97. private SkillHolder _skill;
  98. private Baium(String name, String descr)
  99. {
  100. super(name, descr);
  101. registerMobs(LIVE_BAIUM);
  102. // Quest NPC starter initialization
  103. addStartNpc(STONE_BAIUM, ANGELIC_VORTEX, TELEPORT_CUBIC);
  104. addTalkId(STONE_BAIUM, ANGELIC_VORTEX, TELEPORT_CUBIC);
  105. _Zone = GrandBossManager.getInstance().getZone(113100, 14500, 10077);
  106. StatsSet info = GrandBossManager.getInstance().getStatsSet(LIVE_BAIUM);
  107. int status = GrandBossManager.getInstance().getBossStatus(LIVE_BAIUM);
  108. if (status == DEAD)
  109. {
  110. // load the unlock date and time for baium from DB
  111. long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
  112. if (temp > 0)
  113. {
  114. // the unlock time has not yet expired. Mark Baium as currently locked (dead). Setup a timer
  115. // to fire at the correct time (calculate the time between now and the unlock time,
  116. // setup a timer to fire after that many msec)
  117. startQuestTimer("baium_unlock", temp, null, null);
  118. }
  119. else
  120. {
  121. // the time has already expired while the server was offline. Delete the saved time and
  122. // immediately spawn the stone-baium. Also the state need not be changed from ASLEEP
  123. addSpawn(STONE_BAIUM, 116033, 17447, 10107, -25348, false, 0);
  124. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM, ASLEEP);
  125. }
  126. }
  127. else if (status == AWAKE)
  128. {
  129. int loc_x = info.getInt("loc_x");
  130. int loc_y = info.getInt("loc_y");
  131. int loc_z = info.getInt("loc_z");
  132. int heading = info.getInt("heading");
  133. final int hp = info.getInt("currentHP");
  134. final int mp = info.getInt("currentMP");
  135. L2GrandBossInstance baium = (L2GrandBossInstance) addSpawn(LIVE_BAIUM, loc_x, loc_y, loc_z, heading, false, 0);
  136. GrandBossManager.getInstance().addBoss(baium);
  137. final L2Npc _baium = baium;
  138. ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
  139. {
  140. @Override
  141. public void run()
  142. {
  143. try
  144. {
  145. _baium.setCurrentHpMp(hp, mp);
  146. _baium.setIsInvul(true);
  147. _baium.setIsImmobilized(true);
  148. _baium.setRunning();
  149. _baium.broadcastSocialAction(2);
  150. startQuestTimer("baium_wakeup", 15000, _baium, null);
  151. }
  152. catch (Exception e)
  153. {
  154. e.printStackTrace();
  155. }
  156. }
  157. }, 100L);
  158. }
  159. else
  160. {
  161. addSpawn(STONE_BAIUM, 116033, 17447, 10107, -25348, false, 0);
  162. }
  163. }
  164. @Override
  165. public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  166. {
  167. switch (event)
  168. {
  169. case "baium_unlock":
  170. {
  171. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM, ASLEEP);
  172. addSpawn(STONE_BAIUM, 116033, 17447, 10107, -25348, false, 0);
  173. break;
  174. }
  175. case "skill_range":
  176. {
  177. if (npc != null)
  178. {
  179. callSkillAI(npc);
  180. }
  181. break;
  182. }
  183. case "clean_player":
  184. {
  185. _target = getRandomTarget(npc);
  186. break;
  187. }
  188. case "baium_wakeup":
  189. {
  190. if ((npc != null) && (npc.getId() == LIVE_BAIUM))
  191. {
  192. npc.broadcastSocialAction(1);
  193. npc.broadcastPacket(new Earthquake(npc.getX(), npc.getY(), npc.getZ(), 40, 5));
  194. npc.broadcastPacket(new PlaySound(1, "BS02_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
  195. // start monitoring baium's inactivity
  196. _LastAttackVsBaiumTime = System.currentTimeMillis();
  197. startQuestTimer("baium_despawn", 60000, npc, null, true);
  198. startQuestTimer("skill_range", 500, npc, null, true);
  199. final L2Npc baium = npc;
  200. ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
  201. {
  202. @Override
  203. public void run()
  204. {
  205. try
  206. {
  207. baium.setIsInvul(false);
  208. baium.setIsImmobilized(false);
  209. for (L2Npc minion : _Minions)
  210. {
  211. minion.setShowSummonAnimation(false);
  212. }
  213. }
  214. catch (Exception e)
  215. {
  216. _log.log(Level.WARNING, "", e);
  217. }
  218. }
  219. }, 11100L);
  220. // TODO: Player that wake up Baium take damage.
  221. for (Location loc : ANGEL_LOCATION)
  222. {
  223. L2Npc angel = addSpawn(ARCHANGEL, loc, false, 0, true);
  224. angel.setIsInvul(true);
  225. _Minions.add(angel);
  226. }
  227. }
  228. // despawn the live baium after 30 minutes of inactivity
  229. // also check if the players are cheating, having pulled Baium outside his zone...
  230. break;
  231. }
  232. case "baium_despawn":
  233. {
  234. if ((npc != null) && (npc.getId() == LIVE_BAIUM))
  235. {
  236. // just in case the zone reference has been lost (somehow...), restore the reference
  237. if (_Zone == null)
  238. {
  239. _Zone = GrandBossManager.getInstance().getZone(113100, 14500, 10077);
  240. }
  241. if ((_LastAttackVsBaiumTime + 1800000) < System.currentTimeMillis())
  242. {
  243. npc.deleteMe(); // despawn the live-baium
  244. for (L2Npc minion : _Minions)
  245. {
  246. if (minion != null)
  247. {
  248. minion.getSpawn().stopRespawn();
  249. minion.deleteMe();
  250. }
  251. }
  252. _Minions.clear();
  253. addSpawn(STONE_BAIUM, 116033, 17447, 10107, -25348, false, 0); // spawn stone-baium
  254. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM, ASLEEP); // mark that Baium is not awake any more
  255. _Zone.oustAllPlayers();
  256. cancelQuestTimer("baium_despawn", npc, null);
  257. }
  258. else if (((_LastAttackVsBaiumTime + 300000) < System.currentTimeMillis()) && (npc.getCurrentHp() < ((npc.getMaxHp() * 3) / 4.0)))
  259. {
  260. npc.setIsCastingNow(false); // just in case
  261. npc.setTarget(npc);
  262. if (npc.isPhysicalMuted())
  263. {
  264. return super.onAdvEvent(event, npc, player);
  265. }
  266. npc.doCast(BAIUM_HEAL.getSkill());
  267. npc.setIsCastingNow(true);
  268. }
  269. else if (!_Zone.isInsideZone(npc))
  270. {
  271. npc.teleToLocation(BAIUM_DESPAWN);
  272. }
  273. }
  274. break;
  275. }
  276. }
  277. return super.onAdvEvent(event, npc, player);
  278. }
  279. @Override
  280. public String onTalk(L2Npc npc, L2PcInstance player)
  281. {
  282. String htmltext = "";
  283. if (_Zone == null)
  284. {
  285. _Zone = GrandBossManager.getInstance().getZone(113100, 14500, 10077);
  286. }
  287. if (_Zone == null)
  288. {
  289. return "<html><body>Angelic Vortex:<br>You may not enter while admin disabled this zone</body></html>";
  290. }
  291. switch (npc.getId())
  292. {
  293. case STONE_BAIUM:
  294. {
  295. if (GrandBossManager.getInstance().getBossStatus(LIVE_BAIUM) == ASLEEP)
  296. {
  297. if (_Zone.isPlayerAllowed(player))
  298. {
  299. // once Baium is awaken, no more people may enter until he dies, the server reboots, or
  300. // 30 minutes pass with no attacks made against Baium.
  301. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM, AWAKE);
  302. npc.deleteMe();
  303. L2GrandBossInstance baium = (L2GrandBossInstance) addSpawn(LIVE_BAIUM, npc, true);
  304. GrandBossManager.getInstance().addBoss(baium);
  305. final L2Npc _baium = baium;
  306. ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
  307. {
  308. @Override
  309. public void run()
  310. {
  311. try
  312. {
  313. _baium.setIsInvul(true);
  314. _baium.setRunning();
  315. _baium.broadcastSocialAction(2);
  316. startQuestTimer("baium_wakeup", 15000, _baium, null);
  317. _baium.setShowSummonAnimation(false);
  318. }
  319. catch (Throwable e)
  320. {
  321. _log.log(Level.WARNING, "", e);
  322. }
  323. }
  324. }, 100L);
  325. }
  326. else
  327. {
  328. htmltext = "Conditions are not right to wake up Baium";
  329. }
  330. }
  331. break;
  332. }
  333. case ANGELIC_VORTEX:
  334. {
  335. if (player.isFlying())
  336. {
  337. // print "Player "+player.getName()+" attempted to enter Baium's lair while flying!";
  338. return "<html><body>Angelic Vortex:<br>You may not enter while flying a wyvern</body></html>";
  339. }
  340. if ((GrandBossManager.getInstance().getBossStatus(LIVE_BAIUM) == ASLEEP) && hasQuestItems(player, BLOODED_FABRIC))
  341. {
  342. takeItems(player, BLOODED_FABRIC, 1);
  343. // allow entry for the player for the next 30 secs (more than enough time for the TP to happen)
  344. // Note: this just means 30secs to get in, no limits on how long it takes before we get out.
  345. _Zone.allowPlayerEntry(player, 30);
  346. player.teleToLocation(BAIUM_ENTER);
  347. }
  348. else
  349. {
  350. npc.showChatWindow(player, 1);
  351. }
  352. break;
  353. }
  354. case TELEPORT_CUBIC:
  355. {
  356. final Location loc = TELEPORT_CUBIC_LOCATION[getRandom(TELEPORT_CUBIC_LOCATION.length)];
  357. player.teleToLocation(loc.getX() + getRandom(100), loc.getY() + getRandom(100), loc.getZ());
  358. break;
  359. }
  360. }
  361. return htmltext;
  362. }
  363. @Override
  364. public String onSpellFinished(L2Npc npc, L2PcInstance player, L2Skill skill)
  365. {
  366. if (npc.isInvul())
  367. {
  368. npc.getAI().setIntention(AI_INTENTION_IDLE);
  369. return null;
  370. }
  371. callSkillAI(npc);
  372. return super.onSpellFinished(npc, player, skill);
  373. }
  374. @Override
  375. public String onSpawn(L2Npc npc)
  376. {
  377. npc.disableCoreAI(true);
  378. return super.onSpawn(npc);
  379. }
  380. @Override
  381. public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
  382. {
  383. if (!_Zone.isInsideZone(attacker))
  384. {
  385. attacker.reduceCurrentHp(attacker.getCurrentHp(), attacker, false, false, null);
  386. return super.onAttack(npc, attacker, damage, isSummon);
  387. }
  388. if (npc.isInvul())
  389. {
  390. npc.getAI().setIntention(AI_INTENTION_IDLE);
  391. return super.onAttack(npc, attacker, damage, isSummon);
  392. }
  393. if (attacker.getMountType() == MountType.STRIDER)
  394. {
  395. if (!attacker.isAffectedBySkill(HINDER_STRIDER.getSkillId()))
  396. {
  397. npc.setTarget(attacker);
  398. if (npc.isMuted())
  399. {
  400. return super.onAttack(npc, attacker, damage, isSummon);
  401. }
  402. npc.doCast(HINDER_STRIDER.getSkill());
  403. }
  404. }
  405. // update a variable with the last action against baium
  406. _LastAttackVsBaiumTime = System.currentTimeMillis();
  407. callSkillAI(npc);
  408. return super.onAttack(npc, attacker, damage, isSummon);
  409. }
  410. @Override
  411. public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
  412. {
  413. cancelQuestTimer("baium_despawn", npc, null);
  414. npc.broadcastPacket(new PlaySound(1, "BS01_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
  415. // spawn the "Teleportation Cubic" for 15 minutes (to allow players to exit the lair)
  416. addSpawn(TELEPORT_CUBIC, 115017, 15549, 10090, 0, false, 900000);
  417. // Calculate Min and Max respawn times randomly.
  418. long respawnTime = Config.BAIUM_SPAWN_INTERVAL + getRandom(-Config.BAIUM_SPAWN_RANDOM, Config.BAIUM_SPAWN_RANDOM);
  419. respawnTime *= 3600000;
  420. GrandBossManager.getInstance().setBossStatus(LIVE_BAIUM, DEAD);
  421. startQuestTimer("baium_unlock", respawnTime, null, null);
  422. // also save the respawn time so that the info is maintained past reboots
  423. StatsSet info = GrandBossManager.getInstance().getStatsSet(LIVE_BAIUM);
  424. info.set("respawn_time", (System.currentTimeMillis()) + respawnTime);
  425. GrandBossManager.getInstance().setStatsSet(LIVE_BAIUM, info);
  426. for (L2Npc minion : _Minions)
  427. {
  428. if (minion != null)
  429. {
  430. minion.getSpawn().stopRespawn();
  431. minion.deleteMe();
  432. }
  433. }
  434. _Minions.clear();
  435. final QuestTimer timer = getQuestTimer("skill_range", npc, null);
  436. if (timer != null)
  437. {
  438. timer.cancelAndRemove();
  439. }
  440. return super.onKill(npc, killer, isSummon);
  441. }
  442. public L2Character getRandomTarget(L2Npc npc)
  443. {
  444. FastList<L2Character> result = FastList.newInstance();
  445. Collection<L2Object> objs = npc.getKnownList().getKnownObjects().values();
  446. {
  447. for (L2Object obj : objs)
  448. {
  449. if (obj.isPlayable() || (obj instanceof L2DecoyInstance))
  450. {
  451. if (obj.isPlayer())
  452. {
  453. if (obj.getActingPlayer().getAppearance().getInvisible())
  454. {
  455. continue;
  456. }
  457. }
  458. if (((((L2Character) obj).getZ() < (npc.getZ() - 100)) && (((L2Character) obj).getZ() > (npc.getZ() + 100))) || !(GeoData.getInstance().canSeeTarget(((L2Character) obj).getX(), ((L2Character) obj).getY(), ((L2Character) obj).getZ(), npc.getX(), npc.getY(), npc.getZ())))
  459. {
  460. continue;
  461. }
  462. }
  463. if (obj.isPlayable() || (obj instanceof L2DecoyInstance))
  464. {
  465. if (Util.checkIfInRange(9000, npc, obj, true) && !((L2Character) obj).isDead())
  466. {
  467. result.add((L2Character) obj);
  468. }
  469. }
  470. }
  471. }
  472. if (result.isEmpty())
  473. {
  474. for (L2Npc minion : _Minions)
  475. {
  476. if (minion != null)
  477. {
  478. result.add(minion);
  479. }
  480. }
  481. }
  482. if (result.isEmpty())
  483. {
  484. FastList.recycle(result);
  485. return null;
  486. }
  487. Object[] characters = result.toArray();
  488. QuestTimer timer = getQuestTimer("clean_player", npc, null);
  489. if (timer != null)
  490. {
  491. timer.cancelAndRemove();
  492. }
  493. startQuestTimer("clean_player", 20000, npc, null);
  494. L2Character target = (L2Character) characters[getRandom(characters.length)];
  495. FastList.recycle(result);
  496. return target;
  497. }
  498. public synchronized void callSkillAI(L2Npc npc)
  499. {
  500. if (npc.isInvul() || npc.isCastingNow())
  501. {
  502. return;
  503. }
  504. if ((_target == null) || _target.isDead() || !(_Zone.isInsideZone(_target)))
  505. {
  506. _target = getRandomTarget(npc);
  507. if (_target != null)
  508. {
  509. _skill = getRandomSkill(npc);
  510. }
  511. }
  512. L2Character target = _target;
  513. SkillHolder skill = _skill;
  514. if (skill == null)
  515. {
  516. skill = (getRandomSkill(npc));
  517. }
  518. if (npc.isPhysicalMuted())
  519. {
  520. return;
  521. }
  522. if ((target == null) || target.isDead() || !(_Zone.isInsideZone(target)))
  523. {
  524. npc.setIsCastingNow(false);
  525. return;
  526. }
  527. if (Util.checkIfInRange(skill.getSkill().getCastRange(), npc, target, true))
  528. {
  529. npc.getAI().setIntention(AI_INTENTION_IDLE);
  530. npc.setTarget(target);
  531. npc.setIsCastingNow(true);
  532. _target = null;
  533. _skill = null;
  534. if (getDist(skill.getSkill().getCastRange()) > 0)
  535. {
  536. npc.broadcastPacket(new MoveToPawn(npc, target, getDist(skill.getSkill().getCastRange())));
  537. }
  538. try
  539. {
  540. Thread.sleep(1000);
  541. npc.stopMove(null);
  542. npc.doCast(skill.getSkill());
  543. }
  544. catch (Exception e)
  545. {
  546. e.printStackTrace();
  547. }
  548. }
  549. else
  550. {
  551. npc.getAI().setIntention(AI_INTENTION_FOLLOW, target, null);
  552. npc.setIsCastingNow(false);
  553. }
  554. }
  555. public SkillHolder getRandomSkill(L2Npc npc)
  556. {
  557. SkillHolder skill;
  558. if (npc.getCurrentHp() > ((npc.getMaxHp() * 3) / 4.0))
  559. {
  560. if (getRandom(100) < 10)
  561. {
  562. skill = WIND_OF_FORCE;
  563. }
  564. else if (getRandom(100) < 10)
  565. {
  566. skill = EARTHQUAKE;
  567. }
  568. else
  569. {
  570. skill = GENERAL_ATTACK;
  571. }
  572. }
  573. else if (npc.getCurrentHp() > ((npc.getMaxHp() * 2) / 4.0))
  574. {
  575. if (getRandom(100) < 10)
  576. {
  577. skill = STUN;
  578. }
  579. else if (getRandom(100) < 10)
  580. {
  581. skill = WIND_OF_FORCE;
  582. }
  583. else if (getRandom(100) < 10)
  584. {
  585. skill = EARTHQUAKE;
  586. }
  587. else
  588. {
  589. skill = GENERAL_ATTACK;
  590. }
  591. }
  592. else if (npc.getCurrentHp() > (npc.getMaxHp() / 4.0))
  593. {
  594. if (getRandom(100) < 10)
  595. {
  596. skill = STRIKING_OF_THUNDERBOLT;
  597. }
  598. else if (getRandom(100) < 10)
  599. {
  600. skill = STUN;
  601. }
  602. else if (getRandom(100) < 10)
  603. {
  604. skill = WIND_OF_FORCE;
  605. }
  606. else if (getRandom(100) < 10)
  607. {
  608. skill = EARTHQUAKE;
  609. }
  610. else
  611. {
  612. skill = GENERAL_ATTACK;
  613. }
  614. }
  615. else if (getRandom(100) < 10)
  616. {
  617. skill = STRIKING_OF_THUNDERBOLT;
  618. }
  619. else if (getRandom(100) < 10)
  620. {
  621. skill = STUN;
  622. }
  623. else if (getRandom(100) < 10)
  624. {
  625. skill = WIND_OF_FORCE;
  626. }
  627. else if (getRandom(100) < 10)
  628. {
  629. skill = EARTHQUAKE;
  630. }
  631. else
  632. {
  633. skill = GENERAL_ATTACK;
  634. }
  635. return skill;
  636. }
  637. @Override
  638. public String onSkillSee(L2Npc npc, L2PcInstance caster, L2Skill skill, L2Object[] targets, boolean isSummon)
  639. {
  640. if (npc.isInvul())
  641. {
  642. npc.getAI().setIntention(AI_INTENTION_IDLE);
  643. return null;
  644. }
  645. npc.setTarget(caster);
  646. return super.onSkillSee(npc, caster, skill, targets, isSummon);
  647. }
  648. public int getDist(int range)
  649. {
  650. int dist = 0;
  651. switch (range)
  652. {
  653. case -1:
  654. break;
  655. case 100:
  656. dist = 85;
  657. break;
  658. default:
  659. dist = range - 85;
  660. break;
  661. }
  662. return dist;
  663. }
  664. public static void main(String[] args)
  665. {
  666. new Baium(Baium.class.getSimpleName(), "ai");
  667. }
  668. }