Advertisement
tedlol

selm

Aug 28th, 2012
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.25 KB | None | 0 0
  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.group_template;
  16.  
  17. import ai.group_template.L2AttackableAIScript;
  18. import ai.npc.AbstractNpcAI;
  19.  
  20. import com.l2jserver.gameserver.GameTimeController;
  21. import com.l2jserver.gameserver.ThreadPoolManager;
  22. import com.l2jserver.gameserver.ai.CtrlIntention;
  23. import com.l2jserver.gameserver.datatables.SkillTable;
  24. import com.l2jserver.gameserver.datatables.SpawnTable;
  25. import com.l2jserver.gameserver.instancemanager.WalkingManager;
  26. import com.l2jserver.gameserver.instancemanager.ZoneManager;
  27. import com.l2jserver.gameserver.model.L2CharPosition;
  28. import com.l2jserver.gameserver.model.L2Object;
  29. import com.l2jserver.gameserver.model.L2Spawn;
  30. import com.l2jserver.gameserver.model.actor.L2Character;
  31. import com.l2jserver.gameserver.model.actor.L2Npc;
  32. import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
  33. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  34. import com.l2jserver.gameserver.model.skills.L2Skill;
  35. import com.l2jserver.gameserver.model.zone.L2ZoneType;
  36. import com.l2jserver.gameserver.network.NpcStringId;
  37. import com.l2jserver.gameserver.network.clientpackets.Say2;
  38. import com.l2jserver.gameserver.network.serverpackets.NpcSay;
  39. import com.l2jserver.gameserver.network.serverpackets.SocialAction;
  40. import com.l2jserver.gameserver.util.Util;
  41. import com.l2jserver.util.Rnd;
  42.  
  43. import java.util.HashMap;
  44. import java.util.HashSet;
  45. import java.util.List;
  46. import java.util.Map;
  47. import java.util.Set;
  48.  
  49. import javolution.util.FastList;
  50.  
  51. /**
  52. * Sel Mahum Training Ground AI.
  53. * @author GKR
  54. */
  55.  
  56. /** Some assumes
  57. * Fire Mahums (aka Private Warriors)
  58. * i_ai0 - 0 means walking around, 1 - means moving / moved to fire. For this approach i_ai0 == 0 means !isNoRndWalk(), i_ai1 == 1 means isNoRndWalk().
  59. * i_ai3 - 0 means walking around, 1 - means moving / moved to eat. For this approach i_ai3 == 0 means !isBusy(), i_ai1 == 1 isBusy().
  60. */
  61.  
  62. public class SelMahums extends AbstractNpcAI
  63. {
  64.  
  65. //Sel Mahum Drill Sergeant, Sel Mahum Training Officer, Sel Mahum Drill Sergeant respectively
  66. private static final int[] MAHUM_CHIEFS = { 22775, 22776, 22778 };
  67.  
  68. //Sel Mahum Recruit, Sel Mahum Recruit, Sel Mahum Soldier, Sel Mahum Recruit, Sel Mahum Soldier respectively
  69. private static final int[] MAHUM_SOLDIERS = { 22780, 22782, 22783, 22784, 22785 };
  70.  
  71. // Sel Mahum Squad Leaders
  72. private static final int[] FIRE_MAHUMS = { 22786, 22787, 22788 };
  73.  
  74. private static final int CHEF = 18908;
  75. private static final int FIRE = 18927;
  76. private static final int STOVE = 18933;
  77.  
  78. private static final int[] CHIEF_SOCIAL_ACTIONS = { 1, 4, 5, 7 };
  79. private static final int[] SOLDIER_SOCIAL_ACTIONS = { 1, 5, 6, 7 };
  80.  
  81. //private static final int OHS_Weapon = 15280;
  82. //private static final int THS_Weapon = 15281;
  83.  
  84. /**
  85. * 1801112 - Who is mucking with my recruits!?!
  86. * 1801113 - You are entering a world of hurt!
  87. */
  88. //I get crash of client, if use "int" constructor, so I use "String" constructor here
  89. //private static final int[] CHIEF_FSTRINGS = { 1801112, 1801113 };
  90. //private static final String[] CHIEF_FSTRINGS = { "Who is mucking with my recruits!?!", "You are entering a world of hurt!" };
  91. private static final NpcStringId[] CHIEF_FSTRINGS =
  92. {
  93. NpcStringId.HOW_DARE_YOU_ATTACK_MY_RECRUITS,
  94. NpcStringId.WHO_IS_DISRUPTING_THE_ORDER
  95. };
  96.  
  97. /**
  98. * 1801114 - They done killed da Sarge... Run!!
  99. * 1801115 - Don't Panic... Okay, Panic!
  100. */
  101. //I get crash of client, if use "int" constructor, so I use "String" constructor here
  102. //private static final int[] SOLDIER_FSTRINGS = { 1801114, 1801115 };
  103. //private static final String[] SOLDIER_FSTRINGS = { "They done killed da Sarge... Run!!", "Don't Panic... Okay, Panic!" };
  104. private static final NpcStringId[] SOLDIER_FSTRINGS =
  105. {
  106. NpcStringId.THE_DRILLMASTER_IS_DEAD,
  107. NpcStringId.LINE_UP_THE_RANKS
  108. };
  109.  
  110. private static final NpcStringId[] CHEF_FSTRINGS =
  111. {
  112. NpcStringId.I_BROUGHT_THE_FOOD,
  113. NpcStringId.COME_AND_EAT
  114. };
  115.  
  116. private static List<L2Spawn> _spawns = new FastList<L2Spawn>(); //all Mahum's spawns are stored here
  117. private static Set<Integer> _scheduledReturnTasks = new HashSet<>(); //Used to track scheduled Return Tasks
  118.  
  119. // Holder for Chef's info
  120. private Map<Integer, Long> _firstAttackTime = new HashMap<>();
  121.  
  122. public SelMahums (String name, String descr)
  123. {
  124. super(name, descr);
  125.  
  126. for (int i : MAHUM_CHIEFS)
  127. {
  128. addAttackId(i);
  129. addKillId(i);
  130. addSpawnId(i);
  131. }
  132.  
  133. for (int i : MAHUM_SOLDIERS)
  134. addSpawnId(i);
  135.  
  136. for (int i : FIRE_MAHUMS)
  137. {
  138. addMoveFinishedId(i);
  139. addSpawnId(i);
  140. }
  141.  
  142. addSpawnId(CHEF);
  143. addAttackId(CHEF);
  144. addKillId(CHEF);
  145. addNodeArrivedId(CHEF);
  146. addSpellFinishedId(CHEF);
  147. addSpawnId(FIRE);
  148. addSkillSeeId(STOVE);
  149. addSpawnId(STOVE);
  150.  
  151. //Send event to monsters, that was spawned through SpawnTable at server start (it is impossible to track first spawn)
  152. for (L2Spawn npcSpawn : SpawnTable.getInstance().getSpawnTable())
  153. {
  154. if (Util.contains(MAHUM_CHIEFS, npcSpawn.getNpcid()) || Util.contains(MAHUM_SOLDIERS, npcSpawn.getNpcid()))
  155. {
  156. onSpawn(npcSpawn.getLastSpawn());
  157. _spawns.add(npcSpawn);
  158. }
  159. else if (npcSpawn.getNpcid() == CHEF || npcSpawn.getNpcid() == FIRE || npcSpawn.getNpcid() == STOVE)
  160. {
  161. onSpawn(npcSpawn.getLastSpawn());
  162. }
  163. }
  164. }
  165.  
  166. @Override
  167. public String onAdvEvent (String event, L2Npc npc, L2PcInstance player)
  168. {
  169. if (event.equalsIgnoreCase("do_social_action"))
  170. {
  171. if (npc != null && !npc.isDead())
  172. {
  173. if (!npc.isBusy() && npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE &&
  174. npc.getX() == npc.getSpawn().getLocx() && npc.getY() == npc.getSpawn().getLocy())
  175. {
  176. int idx = Rnd.get(6);
  177. if (idx <= CHIEF_SOCIAL_ACTIONS.length - 1)
  178. {
  179. npc.broadcastPacket(new SocialAction(npc.getObjectId(), CHIEF_SOCIAL_ACTIONS[idx]));
  180.  
  181. L2ZoneType zone = getZone(npc, "sel_mahum_training_grounds", false);
  182.  
  183. if (zone != null )
  184. {
  185. for (L2Character ch : zone.getCharactersInside())
  186. {
  187. if (ch != null && !ch.isDead() && ch instanceof L2MonsterInstance && !((L2MonsterInstance) ch).isBusy() &&
  188. Util.contains(MAHUM_SOLDIERS, ((L2MonsterInstance) ch).getNpcId()) && ch.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE &&
  189. ch.getX() == ((L2MonsterInstance) ch).getSpawn().getLocx() && ch.getY() == ((L2MonsterInstance) ch).getSpawn().getLocy())
  190. ch.broadcastPacket(new SocialAction(ch.getObjectId(), SOLDIER_SOCIAL_ACTIONS[idx]));
  191. }
  192. }
  193. }
  194. }
  195.  
  196. startQuestTimer("do_social_action", 15000, npc, null);
  197. }
  198. }
  199.  
  200. else if (event.equalsIgnoreCase("reset_busy_state"))
  201. {
  202. if (npc != null)
  203. {
  204. npc.setBusy(false);
  205. npc.disableCoreAI(false);
  206. }
  207. }
  208.  
  209. else if (event.equalsIgnoreCase("fire"))
  210. {
  211. startQuestTimer("fire", 30000 + Rnd.get(5000), npc, null);
  212. npc.setDisplayEffect(2);
  213. boolean fireBurns;
  214.  
  215. if (Rnd.get(GameTimeController.getInstance().isNowNight() ? 2 : 4) < 1)
  216. {
  217. fireBurns = true;
  218. npc.setBusyMessage("burn");
  219. npc.setDisplayEffect(1);
  220. }
  221. else
  222. {
  223. fireBurns = false;
  224. npc.setBusyMessage("");
  225. npc.setDisplayEffect(2);
  226. }
  227.  
  228. L2ZoneType zone = getZone(npc, "sel_mahum_fire", false);
  229.  
  230. if (zone != null)
  231. {
  232. for (L2Character ch : zone.getCharactersInside())
  233. {
  234. if (ch instanceof L2MonsterInstance)
  235. {
  236. L2MonsterInstance monster = (L2MonsterInstance) ch;
  237. if (Util.contains(FIRE_MAHUMS, monster.getNpcId()) && monster.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK)
  238. {
  239. if (fireBurns) // Fire burns (@SCE_CAMPFIRE_START)
  240. {
  241. if (!monster.isNoRndWalk())
  242. {
  243. monster.setIsNoRndWalk(true); // i_ai0 = 1
  244. monster.setIsRunning(false);
  245. moveToRandomPoint(zone, monster, npc, 100, 200);
  246.  
  247. }
  248. }
  249. else // Fire goes out (@SCE_CAMPFIRE_END)
  250. {
  251. monster.setIsNoRndWalk(false);
  252. monster.setBusy(false);
  253. //monster.setRHandId(THS_Weapon);
  254. startQuestTimer("return_from_fire", 3000, monster, null);
  255. }
  256. }
  257. }
  258. else if (ch instanceof L2Npc && ((L2Npc) ch).getNpcId() == STOVE) // Fire goes out (@SCE_CAMPFIRE_DUMMY)
  259. {
  260. if (!fireBurns)
  261. {
  262. ch.deleteMe();
  263. }
  264. }
  265. }
  266. }
  267. }
  268.  
  269. else if (event.equalsIgnoreCase("return_from_fire"))
  270. {
  271. if (npc != null && npc instanceof L2MonsterInstance)
  272. ((L2MonsterInstance)npc).returnHome();
  273. }
  274.  
  275. else if (event.equalsIgnoreCase("fire_arrived"))
  276. {
  277. // myself.i_quest0 = 1;
  278. npc.setIsRunning(false);
  279. npc.setTarget(npc);
  280.  
  281. if (npc.isBusy()) // Eating - i_ai3 = 1
  282. {
  283. npc.doCast(SkillTable.getInstance().getInfo(6332, 1));
  284. npc.setDisplayEffect(1);
  285. }
  286. else // Sleeping
  287. {
  288. npc.doCast(SkillTable.getInstance().getInfo(6331, 1));
  289. //SkillTable.getInstance().getInfo(6331, 1).getEffectsSelf(npc);
  290. npc.setDisplayEffect(2);
  291. }
  292.  
  293. startQuestTimer("remove_effects", 300000, npc, null);
  294. }
  295.  
  296. // @SCE_DINNER_EAT
  297. else if (event.equalsIgnoreCase("notify_dinner"))
  298. {
  299. L2ZoneType zone = getZone(npc, "sel_mahum_fire", false);
  300.  
  301. if (zone != null)
  302. {
  303. for (L2Character ch : zone.getCharactersInside())
  304. {
  305. if (ch instanceof L2MonsterInstance)
  306. {
  307. L2MonsterInstance monster = (L2MonsterInstance) ch;
  308. if (Util.contains(FIRE_MAHUMS, monster.getNpcId()) && npc.isInsideRadius(monster, 600, true, true) &&
  309. !monster.isBusy() && monster.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK)
  310. {
  311. if (monster.isNoRndWalk()) // i_ai0 == 1
  312. {
  313. //monster.setRHandId(THS_Weapon);
  314. }
  315. monster.setIsNoRndWalk(true); // Moving to fire - i_ai0 = 1
  316. monster.setBusy(true); // Eating - i_ai3 = 1
  317. monster.setIsRunning(true);
  318.  
  319. NpcSay ns;
  320. if (Rnd.get(3) < 1)
  321. ns = new NpcSay(monster.getObjectId(), Say2.ALL, monster.getNpcId(), NpcStringId.LOOKS_DELICIOUS);
  322. else
  323. ns = new NpcSay(monster.getObjectId(), Say2.ALL, monster.getNpcId(), NpcStringId.LETS_GO_EAT);
  324.  
  325. monster.broadcastPacket(ns);
  326. moveToRandomPoint(zone, monster, npc, 100, 110);
  327. }
  328. }
  329. }
  330. }
  331. }
  332.  
  333. else if (event.equalsIgnoreCase("remove_effects"))
  334. {
  335. if (npc != null)
  336. {
  337. // myself.i_quest0 = 0;
  338. npc.setIsRunning(true);
  339. npc.setDisplayEffect(3);
  340. }
  341. }
  342.  
  343. else if (event.equalsIgnoreCase("reset_full_bottle_prize"))
  344. {
  345. if (npc != null && !npc.isDead())
  346. npc.setBusyMessage("");
  347. }
  348.  
  349. else if (event.equalsIgnoreCase("chef_heal_player"))
  350. {
  351. if (player != null && !player.isDead() && !npc.getBusyMessage().isEmpty() &&
  352. (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ATTACK || npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST))
  353. {
  354. npc.setTarget(player);
  355. npc.doCast(SkillTable.getInstance().getInfo(6330, 1));
  356. }
  357. else
  358. {
  359. cancelQuestTimer("chef_set_invul", npc, null);
  360. npc.setBusy(false); // i_ai2 = 0
  361. npc.setIsRunning(false);
  362. }
  363. }
  364.  
  365. else if (event.equalsIgnoreCase("chef_set_invul"))
  366. {
  367. if (npc != null && !npc.isDead())
  368. npc.setIsInvul(true);
  369. }
  370.  
  371. else if (event.equalsIgnoreCase("chef_remove_invul"))
  372. {
  373. if (npc != null && !npc.isDead() && npc instanceof L2MonsterInstance)
  374. {
  375. npc.setIsInvul(false);
  376. npc.setBusyMessage(""); // i_ai5 = 0
  377.  
  378. if (player != null && !player.isDead() && npc.getKnownList().knowsThePlayer(player))
  379. {
  380. ((L2MonsterInstance) npc).addDamageHate(player, 0, 999);
  381. ((L2MonsterInstance) npc).getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player, null);
  382. }
  383. }
  384. }
  385.  
  386. return null;
  387. }
  388.  
  389. @Override
  390. public String onAttack (L2Npc npc, L2PcInstance attacker, int damage, boolean isPet, L2Skill skill)
  391. {
  392. if (Util.contains(MAHUM_CHIEFS, npc.getNpcId()))
  393. {
  394. if (!npc.isDead() && !npc.isBusy())
  395. {
  396. if (Rnd.get(10) < 1)
  397. npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.ALL, npc.getNpcId(), CHIEF_FSTRINGS[Rnd.get(2)]));
  398.  
  399. npc.setBusy(true);
  400. startQuestTimer("reset_busy_state", 60000, npc, null);
  401. }
  402. }
  403.  
  404. else if (npc.getNpcId() == CHEF)
  405. {
  406. if (!npc.isBusy()) // i_ai2 == 0
  407. {
  408. if (npc.getBusyMessage().isEmpty()) // i_ai5 == 0
  409. {
  410. if (getQuestTimer("chef_remove_invul", npc, null) != null)
  411. cancelQuestTimer("chef_remove_invul", npc, null);
  412.  
  413. startQuestTimer("chef_remove_invul", 180000, npc, attacker);
  414.  
  415. _firstAttackTime.putIfAbsent(npc.getObjectId(), System.currentTimeMillis()); //i_ai6
  416. npc.setBusyMessage("!"); // i_ai5 == 1
  417. }
  418. startQuestTimer("chef_heal_player", 1000, npc, attacker);
  419. startQuestTimer("chef_set_invul", 60000, npc, null);
  420. npc.setBusy(true); // i_ai2 = 1
  421. }
  422. }
  423. return super.onAttack(npc, attacker, damage, isPet, skill);
  424. }
  425.  
  426. @Override
  427. // @SCE_SOUP_FAILURE
  428. public String onSkillSee(L2Npc npc, L2PcInstance caster, L2Skill skill, L2Object[] targets, boolean isPet)
  429. {
  430. if (npc.getNpcId() == STOVE && skill.getId() == 9075 && Util.contains(targets, npc))
  431. {
  432. npc.doCast(SkillTable.getInstance().getInfo(6688, 1));
  433.  
  434. L2ZoneType zone = getZone(npc, "sel_mahum_fire", false);
  435.  
  436. if (zone != null)
  437. {
  438. for (L2Character ch : zone.getCharactersInside())
  439. {
  440. if (ch instanceof L2MonsterInstance)
  441. {
  442. L2MonsterInstance monster = (L2MonsterInstance) ch;
  443. if (Util.contains(FIRE_MAHUMS, monster.getNpcId()))
  444. {
  445. monster.setBusyMessage(caster.getName()); // REMEMBER: Use it in 289 quest
  446. startQuestTimer("reset_full_bottle_prize", 180000, monster, null);
  447. }
  448. }
  449. }
  450. }
  451.  
  452. }
  453. return null;
  454. }
  455.  
  456. @Override
  457. public String onSpellFinished(L2Npc npc, L2PcInstance player, L2Skill skill)
  458. {
  459. if (npc.getNpcId() == CHEF && skill != null && skill.getId() == 6330)
  460. {
  461. if (player != null && !player.isDead() && !npc.getBusyMessage().isEmpty() &&
  462. (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ATTACK || npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST))
  463. {
  464. npc.setTarget(player);
  465. npc.doCast(SkillTable.getInstance().getInfo(6330, 1));
  466. }
  467. else
  468. {
  469. cancelQuestTimer("chef_set_invul", npc, null);
  470. npc.setBusy(false); // i_ai2 = 0
  471. npc.setBusyMessage(""); // i_ai5 = 0
  472. }
  473. }
  474. return super.onSpellFinished(npc, player, skill);
  475. }
  476.  
  477. @Override
  478. public String onKill (L2Npc npc, L2PcInstance killer, boolean isPet)
  479. {
  480. if (Util.contains(MAHUM_CHIEFS, npc.getNpcId()))
  481. {
  482. L2ZoneType leaderZone = getZone(npc, "sel_mahum_training_grounds", false);
  483.  
  484. if (leaderZone != null)
  485. {
  486. for (L2Spawn sp : _spawns)
  487. {
  488. if (sp == null)
  489. continue;
  490.  
  491. L2MonsterInstance soldier = (L2MonsterInstance) sp.getLastSpawn();
  492. if (soldier != null && !soldier.isDead())
  493. {
  494. L2ZoneType soldierZone = getZone(soldier, "sel_mahum_training_grounds", false);
  495. if (soldierZone != null && leaderZone.getId() == soldierZone.getId())
  496. {
  497. if (Rnd.get(4) < 1)
  498. soldier.broadcastPacket(new NpcSay(soldier.getObjectId(), Say2.ALL, soldier.getNpcId(), SOLDIER_FSTRINGS[Rnd.get(2)]));
  499.  
  500. soldier.setBusy(true);
  501. soldier.setIsRunning(true);
  502. soldier.clearAggroList();
  503. soldier.disableCoreAI(true);
  504. soldier.getAI().setIntention( CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition((soldier.getX() + Rnd.get(-800, 800)), (soldier.getY()+ Rnd.get(-800, 800)), soldier.getZ(), soldier.getHeading()));
  505. startQuestTimer("reset_busy_state", 5000, soldier, null);
  506. }
  507. }
  508. }
  509. //Soldiers should return into spawn location, if they have "NO_DESIRE" state. It looks like AI_INTENTION_ACTIVE in L2J terms,
  510. //but we have no possibility to track AI intention change, so timer is used here. Time can be ajusted, if needed.
  511. if (!_scheduledReturnTasks.contains(leaderZone.getId())) //Check for shceduled task presence for this zone
  512. {
  513. _scheduledReturnTasks.add(leaderZone.getId()); //register scheduled task for zone
  514. ThreadPoolManager.getInstance().scheduleGeneral(new ReturnTask(leaderZone.getId()), 120000); //schedule task
  515. }
  516. }
  517. }
  518.  
  519. else if (npc.getNpcId() == CHEF && npc instanceof L2MonsterInstance)
  520. {
  521. if (_firstAttackTime.containsKey(npc.getObjectId()))
  522. {
  523. if (System.currentTimeMillis() - _firstAttackTime.get(npc.getObjectId()) <= 60000)
  524. {
  525. if (Rnd.get(10) < 2)
  526. ((L2MonsterInstance) npc).dropItem(killer, 15492, 1);
  527. }
  528.  
  529. _firstAttackTime.remove(npc.getObjectId());
  530. }
  531. }
  532.  
  533. return super.onKill(npc,killer,isPet);
  534. }
  535.  
  536. @Override
  537. public String onSpawn(L2Npc npc)
  538. {
  539. if (!npc.isTeleporting())
  540. {
  541. if (Util.contains(MAHUM_CHIEFS, npc.getNpcId()) || Util.contains(MAHUM_SOLDIERS, npc.getNpcId()))
  542. {
  543. if (Util.contains(MAHUM_CHIEFS, npc.getNpcId()))
  544. startQuestTimer("do_social_action", 15000, npc, null);
  545.  
  546. npc.disableCoreAI(false);
  547. npc.setBusy(false);
  548. npc.setIsNoRndWalk(true);
  549. npc.setRandomAnimationEnabled(false);
  550. }
  551.  
  552. else if (npc.getNpcId() == CHEF && getRoute(npc) > 0)
  553. {
  554. WalkingManager.getInstance().startMoving(npc, getRoute(npc));
  555. npc.setBusyMessage("");
  556. npc.setBusy(false);
  557. npc.setIsInvul(false);
  558. }
  559.  
  560. else if (npc.getNpcId() == FIRE)
  561. {
  562. startQuestTimer("fire", 1000, npc, null);
  563. }
  564.  
  565. else if (Util.contains(FIRE_MAHUMS, npc.getNpcId()))
  566. {
  567. npc.setBusy(false);
  568. npc.setBusyMessage("");
  569. npc.setDisplayEffect(3);
  570. }
  571. }
  572.  
  573. return super.onSpawn(npc);
  574. }
  575.  
  576. @Override
  577. public String onNodeArrived(L2Npc npc)
  578. {
  579. L2ZoneType zone = getZone(npc, "sel_mahum_fire", true);
  580.  
  581. if (zone != null)
  582. {
  583. for (L2Character ch : zone.getCharactersInside())
  584. {
  585. if (ch instanceof L2Npc)
  586. {
  587. L2Npc monster = (L2Npc) ch;
  588. if (monster.getNpcId() == FIRE && npc.isInsideRadius(monster, 300, true, true))
  589. {
  590. monster.setDisplayEffect(1);
  591. addSpawn(STOVE, monster.getX(), monster.getY(), monster.getZ() + 100, 0, false, 0);
  592. startQuestTimer("notify_dinner", 2000, monster, null); // @SCE_DINNER_EAT
  593. npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.ALL, npc.getNpcId(), CHEF_FSTRINGS[Rnd.get(2)]));
  594. }
  595. }
  596. }
  597. }
  598. return super.onNodeArrived(npc);
  599. }
  600.  
  601. @Override
  602. public String onMoveFinished(L2Npc npc)
  603. {
  604. // Npc moved to fire
  605. if (npc.isNoRndWalk())
  606. {
  607. //npc.setRHandId(OHS_Weapon);
  608. startQuestTimer("fire_arrived", 3000, npc, null);
  609. }
  610.  
  611. return super.onMoveFinished(npc);
  612. }
  613.  
  614. private L2ZoneType getZone(L2Npc npc, String nameTemplate, boolean currentLoc)
  615. {
  616. try
  617. {
  618. int x;
  619. int y;
  620. int z;
  621.  
  622. if (currentLoc)
  623. {
  624. x = npc.getX();
  625. y = npc.getY();
  626. z = npc.getZ();
  627. }
  628. else
  629. {
  630. x = npc.getSpawn().getLocx();
  631. y = npc.getSpawn().getLocy();
  632. z = npc.getSpawn().getLocz();
  633. }
  634.  
  635. for (L2ZoneType zone : ZoneManager.getInstance().getZones(x, y, z))
  636. {
  637. if (zone.getName().startsWith(nameTemplate))
  638. return zone;
  639. }
  640. }
  641.  
  642. catch(NullPointerException e)
  643. {
  644. }
  645.  
  646. catch(IndexOutOfBoundsException e)
  647. {
  648. }
  649.  
  650. return null;
  651. }
  652.  
  653. /**
  654. * Returns monsters in their spawn location
  655. */
  656. private class ReturnTask implements Runnable
  657. {
  658. private final int _zoneId;
  659. private boolean _runAgain;
  660.  
  661. public ReturnTask(int zoneId)
  662. {
  663. _zoneId = zoneId;
  664. _runAgain = false;
  665. }
  666.  
  667. @Override
  668. public void run()
  669. {
  670. for (L2Spawn sp: _spawns)
  671. {
  672. L2MonsterInstance monster = (L2MonsterInstance) sp.getLastSpawn();
  673.  
  674. if (monster != null && !monster.isDead())
  675. {
  676. L2ZoneType zone = getZone(monster, "sel_mahum_training_grounds", false);
  677. if (zone != null && zone.getId() == _zoneId)
  678. {
  679. if (monster.getX() != sp.getLocx() && monster.getY() != sp.getLocy()) //Check if there is monster not in spawn location
  680. {
  681. //Teleport him if not engaged in battle / not flee
  682. if (monster.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE || monster.getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
  683. {
  684. monster.setHeading(sp.getHeading());
  685. monster.teleToLocation(sp.getLocx(), sp.getLocy(), sp.getLocz());
  686. }
  687. else //There is monster('s) not in spawn location, but engaged in battle / flee. Set flag to repeat Return Task for this zone
  688. _runAgain = true;
  689. }
  690. }
  691. }
  692. }
  693. if (_runAgain) //repeat task
  694. ThreadPoolManager.getInstance().scheduleGeneral(new ReturnTask(_zoneId), 120000);
  695. else // Task is not sheduled ahain for this zone, unregister it
  696. _scheduledReturnTasks.remove(_zoneId);
  697. }
  698. }
  699.  
  700. private static int getRoute(L2Npc npc)
  701. {
  702. int ret = -1;
  703.  
  704. if (npc.getNpcId() != CHEF)
  705. return ret;
  706.  
  707. switch (npc.getSpawn().getLocx())
  708. {
  709. case 85852: // 85852;53212;-3624 Cooker_01
  710. case 82814: // 82814;69481;-3192 Cooker_09
  711. ret = 11;
  712. break;
  713. case 93964: // 93964;55692;-3352 Cooker_02
  714. ret = 12;
  715. break;
  716. case 87612: // 87612;59356;-3552 Cooker_03
  717. case 88532: // 88532;60352;-3642 Cooker_05
  718. ret = 13;
  719. break;
  720. case 83724: // 83724;62668;-3472 Cooker_04
  721. ret = 14;
  722. break;
  723. case 92981: // 92981;60834;-3288 Cooker_06
  724. ret = 15;
  725. break;
  726. case 78332: // 78332;63440;-3640 Cooker_07
  727. ret = 16;
  728. break;
  729. case 77836: // 77836;68796;-3312 Cooker_08
  730. ret = 17;
  731. break;
  732. case 83404: // 83404;65772;-3032 Cooker_10
  733. ret = 18;
  734. break;
  735. case 96487: // 96487;69432;-3408 Cooker_11
  736. ret = 19;
  737. break;
  738. case 91238: // 91238;67728;-3631 Cooker_12
  739. ret = 20;
  740. break;
  741. }
  742.  
  743. return ret;
  744. }
  745.  
  746. private void moveToRandomPoint(L2ZoneType zone, L2MonsterInstance monster, L2Npc npc, int minRange, int maxRange)
  747. {
  748. int[] coord = null;
  749. for (int i = 0; i < 1000; i++)
  750. {
  751. coord = zone.getZone().getRandomPoint();
  752. if (Util.calculateDistance(npc.getX(), npc.getY(), coord[0], coord[1]) >= minRange && Util.calculateDistance(npc.getX(), npc.getY(), coord[0], coord[1]) <= maxRange)
  753. {
  754. break;
  755. }
  756. }
  757. if (coord != null)
  758. {
  759. monster.stopMove(null);
  760. monster.getAI().setIntention( CtrlIntention.AI_INTENTION_MOVE_TO, new L2CharPosition(coord[0], coord[1], npc.getZ(), npc.getHeading()));
  761. }
  762.  
  763. }
  764.  
  765. public static void main(String[] args)
  766. {
  767. // now call the constructor (starts up the ai)
  768. new SelMahums(SelMahums.class.getSimpleName(),"ai");
  769. }
  770. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement