FeedableBeasts.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  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.group_template;
  20. import java.util.Map;
  21. import javolution.util.FastMap;
  22. import quests.Q00020_BringUpWithLove.Q00020_BringUpWithLove;
  23. import ai.npc.AbstractNpcAI;
  24. import com.l2jserver.gameserver.ai.CtrlIntention;
  25. import com.l2jserver.gameserver.datatables.NpcData;
  26. import com.l2jserver.gameserver.idfactory.IdFactory;
  27. import com.l2jserver.gameserver.model.L2Object;
  28. import com.l2jserver.gameserver.model.actor.L2Attackable;
  29. import com.l2jserver.gameserver.model.actor.L2Npc;
  30. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  31. import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
  32. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  33. import com.l2jserver.gameserver.model.skills.Skill;
  34. import com.l2jserver.gameserver.network.NpcStringId;
  35. import com.l2jserver.gameserver.network.serverpackets.NpcSay;
  36. import com.l2jserver.gameserver.util.Util;
  37. /**
  38. * Growth-capable mobs: Polymorphing upon successful feeding.
  39. * @author Fulminus
  40. */
  41. public class FeedableBeasts extends AbstractNpcAI
  42. {
  43. private static final int GOLDEN_SPICE = 6643;
  44. private static final int CRYSTAL_SPICE = 6644;
  45. private static final int SKILL_GOLDEN_SPICE = 2188;
  46. private static final int SKILL_CRYSTAL_SPICE = 2189;
  47. private static final int FOODSKILLDIFF = GOLDEN_SPICE - SKILL_GOLDEN_SPICE;
  48. // @formatter:off
  49. private static final int[] TAMED_BEASTS =
  50. {
  51. 16013, 16014, 16015, 16016, 16017, 16018
  52. };
  53. // all mobs that can eat...
  54. private static final int[] FEEDABLE_BEASTS =
  55. {
  56. 21451, 21452, 21453, 21454, 21455, 21456, 21457, 21458, 21459, 21460,
  57. 21461, 21462, 21463, 21464, 21465, 21466, 21467, 21468, 21469, 21470,
  58. 21471, 21472, 21473, 21474, 21475, 21476, 21477, 21478, 21479, 21480,
  59. 21481, 21482, 21483, 21484, 21485, 21486, 21487, 21488, 21489, 21490,
  60. 21491, 21492, 21493, 21494, 21495, 21496, 21497, 21498, 21499, 21500,
  61. 21501, 21502, 21503, 21504, 21505, 21506, 21507, 21824, 21825, 21826,
  62. 21827, 21828, 21829, 16013, 16014, 16015, 16016, 16017, 16018
  63. };
  64. // @formatter:on
  65. private static final Map<Integer, Integer> MAD_COW_POLYMORPH = new FastMap<>();
  66. static
  67. {
  68. MAD_COW_POLYMORPH.put(21824, 21468);
  69. MAD_COW_POLYMORPH.put(21825, 21469);
  70. MAD_COW_POLYMORPH.put(21826, 21487);
  71. MAD_COW_POLYMORPH.put(21827, 21488);
  72. MAD_COW_POLYMORPH.put(21828, 21506);
  73. MAD_COW_POLYMORPH.put(21829, 21507);
  74. }
  75. private static final NpcStringId[][] TEXT =
  76. {
  77. {
  78. NpcStringId.WHAT_DID_YOU_JUST_DO_TO_ME,
  79. NpcStringId.ARE_YOU_TRYING_TO_TAME_ME_DONT_DO_THAT,
  80. NpcStringId.DONT_GIVE_SUCH_A_THING_YOU_CAN_ENDANGER_YOURSELF,
  81. NpcStringId.YUCK_WHAT_IS_THIS_IT_TASTES_TERRIBLE,
  82. NpcStringId.IM_HUNGRY_GIVE_ME_A_LITTLE_MORE_PLEASE,
  83. NpcStringId.WHAT_IS_THIS_IS_THIS_EDIBLE,
  84. NpcStringId.DONT_WORRY_ABOUT_ME,
  85. NpcStringId.THANK_YOU_THAT_WAS_DELICIOUS,
  86. NpcStringId.I_THINK_I_AM_STARTING_TO_LIKE_YOU,
  87. NpcStringId.EEEEEK_EEEEEK
  88. },
  89. {
  90. NpcStringId.DONT_KEEP_TRYING_TO_TAME_ME_I_DONT_WANT_TO_BE_TAMED,
  91. NpcStringId.IT_IS_JUST_FOOD_TO_ME_ALTHOUGH_IT_MAY_ALSO_BE_YOUR_HAND,
  92. NpcStringId.IF_I_KEEP_EATING_LIKE_THIS_WONT_I_BECOME_FAT_CHOMP_CHOMP,
  93. NpcStringId.WHY_DO_YOU_KEEP_FEEDING_ME,
  94. NpcStringId.DONT_TRUST_ME_IM_AFRAID_I_MAY_BETRAY_YOU_LATER
  95. },
  96. {
  97. NpcStringId.GRRRRR,
  98. NpcStringId.YOU_BROUGHT_THIS_UPON_YOURSELF,
  99. NpcStringId.I_FEEL_STRANGE_I_KEEP_HAVING_THESE_EVIL_THOUGHTS,
  100. NpcStringId.ALAS_SO_THIS_IS_HOW_IT_ALL_ENDS,
  101. NpcStringId.I_DONT_FEEL_SO_GOOD_OH_MY_MIND_IS_VERY_TROUBLED
  102. }
  103. };
  104. private static final NpcStringId[] TAMED_TEXT =
  105. {
  106. NpcStringId.S1_SO_WHAT_DO_YOU_THINK_IT_IS_LIKE_TO_BE_TAMED,
  107. NpcStringId.S1_WHENEVER_I_SEE_SPICE_I_THINK_I_WILL_MISS_YOUR_HAND_THAT_USED_TO_FEED_IT_TO_ME,
  108. NpcStringId.S1_DONT_GO_TO_THE_VILLAGE_I_DONT_HAVE_THE_STRENGTH_TO_FOLLOW_YOU,
  109. NpcStringId.THANK_YOU_FOR_TRUSTING_ME_S1_I_HOPE_I_WILL_BE_HELPFUL_TO_YOU,
  110. NpcStringId.S1_WILL_I_BE_ABLE_TO_HELP_YOU,
  111. NpcStringId.I_GUESS_ITS_JUST_MY_ANIMAL_MAGNETISM,
  112. NpcStringId.TOO_MUCH_SPICY_FOOD_MAKES_ME_SWEAT_LIKE_A_BEAST,
  113. NpcStringId.ANIMALS_NEED_LOVE_TOO
  114. };
  115. private static Map<Integer, Integer> _FeedInfo = new FastMap<>();
  116. private static Map<Integer, GrowthCapableMob> _GrowthCapableMobs = new FastMap<>();
  117. // all mobs that grow by eating
  118. private static class GrowthCapableMob
  119. {
  120. private final int _growthLevel;
  121. private final int _chance;
  122. private final Map<Integer, int[][]> _spiceToMob = new FastMap<>();
  123. public GrowthCapableMob(int growthLevel, int chance)
  124. {
  125. _growthLevel = growthLevel;
  126. _chance = chance;
  127. }
  128. public void addMobs(int spice, int[][] Mobs)
  129. {
  130. _spiceToMob.put(spice, Mobs);
  131. }
  132. public Integer getMob(int spice, int mobType, int classType)
  133. {
  134. if (_spiceToMob.containsKey(spice))
  135. {
  136. return _spiceToMob.get(spice)[mobType][classType];
  137. }
  138. return null;
  139. }
  140. public Integer getRandomMob(int spice)
  141. {
  142. int[][] temp;
  143. temp = _spiceToMob.get(spice);
  144. int rand = getRandom(temp[0].length);
  145. return temp[0][rand];
  146. }
  147. public Integer getChance()
  148. {
  149. return _chance;
  150. }
  151. public Integer getGrowthLevel()
  152. {
  153. return _growthLevel;
  154. }
  155. }
  156. private FeedableBeasts()
  157. {
  158. super(FeedableBeasts.class.getSimpleName(), "ai/group_template");
  159. addKillId(FEEDABLE_BEASTS);
  160. addSkillSeeId(FEEDABLE_BEASTS);
  161. // TODO: no grendels?
  162. GrowthCapableMob temp;
  163. //@formatter:off
  164. final int[][] Kookabura_0_Gold = {{ 21452, 21453, 21454, 21455 }};
  165. final int[][] Kookabura_0_Crystal = {{ 21456, 21457, 21458, 21459 }};
  166. final int[][] Kookabura_1_Gold_1= {{ 21460, 21462 }};
  167. final int[][] Kookabura_1_Gold_2 = {{ 21461, 21463 }};
  168. final int[][] Kookabura_1_Crystal_1 = {{ 21464, 21466 }};
  169. final int[][] Kookabura_1_Crystal_2 = {{ 21465, 21467 }};
  170. final int[][] Kookabura_2_1 = {{ 21468, 21824}, { 16017, 16018 }};
  171. final int[][] Kookabura_2_2 = {{ 21469, 21825}, { 16017, 16018 }};
  172. final int[][] Buffalo_0_Gold = {{ 21471, 21472, 21473, 21474 }};
  173. final int[][] Buffalo_0_Crystal = {{ 21475, 21476, 21477, 21478 }};
  174. final int[][] Buffalo_1_Gold_1 = {{ 21479, 21481 }};
  175. final int[][] Buffalo_1_Gold_2 = {{ 21481, 21482 }};
  176. final int[][] Buffalo_1_Crystal_1 = {{ 21483, 21485 }};
  177. final int[][] Buffalo_1_Crystal_2 = {{ 21484, 21486 }};
  178. final int[][] Buffalo_2_1 = {{ 21487,21826}, {16013, 16014 }};
  179. final int[][] Buffalo_2_2 = {{ 21488,21827}, {16013, 16014 }};
  180. final int[][] Cougar_0_Gold = {{ 21490, 21491, 21492, 21493 }};
  181. final int[][] Cougar_0_Crystal = {{ 21494,21495, 21496, 21497 }};
  182. final int[][] Cougar_1_Gold_1 = {{ 21498, 21500 }};
  183. final int[][] Cougar_1_Gold_2 = {{ 21499, 21501 }};
  184. final int[][] Cougar_1_Crystal_1 = {{ 21502,21504 }};
  185. final int[][] Cougar_1_Crystal_2 = {{ 21503,21505 }};
  186. final int[][] Cougar_2_1 = {{ 21506, 21828 }, { 16015,16016 }};
  187. final int[][] Cougar_2_2 = {{ 21507, 21829 }, { 16015,16016 }};
  188. //@formatter:on
  189. // Alpen Kookabura
  190. temp = new GrowthCapableMob(0, 100);
  191. temp.addMobs(GOLDEN_SPICE, Kookabura_0_Gold);
  192. temp.addMobs(CRYSTAL_SPICE, Kookabura_0_Crystal);
  193. _GrowthCapableMobs.put(21451, temp);
  194. temp = new GrowthCapableMob(1, 40);
  195. temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_1);
  196. _GrowthCapableMobs.put(21452, temp);
  197. _GrowthCapableMobs.put(21454, temp);
  198. temp = new GrowthCapableMob(1, 40);
  199. temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_2);
  200. _GrowthCapableMobs.put(21453, temp);
  201. _GrowthCapableMobs.put(21455, temp);
  202. temp = new GrowthCapableMob(1, 40);
  203. temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_1);
  204. _GrowthCapableMobs.put(21456, temp);
  205. _GrowthCapableMobs.put(21458, temp);
  206. temp = new GrowthCapableMob(1, 40);
  207. temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_2);
  208. _GrowthCapableMobs.put(21457, temp);
  209. _GrowthCapableMobs.put(21459, temp);
  210. temp = new GrowthCapableMob(2, 25);
  211. temp.addMobs(GOLDEN_SPICE, Kookabura_2_1);
  212. _GrowthCapableMobs.put(21460, temp);
  213. _GrowthCapableMobs.put(21462, temp);
  214. temp = new GrowthCapableMob(2, 25);
  215. temp.addMobs(GOLDEN_SPICE, Kookabura_2_2);
  216. _GrowthCapableMobs.put(21461, temp);
  217. _GrowthCapableMobs.put(21463, temp);
  218. temp = new GrowthCapableMob(2, 25);
  219. temp.addMobs(CRYSTAL_SPICE, Kookabura_2_1);
  220. _GrowthCapableMobs.put(21464, temp);
  221. _GrowthCapableMobs.put(21466, temp);
  222. temp = new GrowthCapableMob(2, 25);
  223. temp.addMobs(CRYSTAL_SPICE, Kookabura_2_2);
  224. _GrowthCapableMobs.put(21465, temp);
  225. _GrowthCapableMobs.put(21467, temp);
  226. // Alpen Buffalo
  227. temp = new GrowthCapableMob(0, 100);
  228. temp.addMobs(GOLDEN_SPICE, Buffalo_0_Gold);
  229. temp.addMobs(CRYSTAL_SPICE, Buffalo_0_Crystal);
  230. _GrowthCapableMobs.put(21470, temp);
  231. temp = new GrowthCapableMob(1, 40);
  232. temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_1);
  233. _GrowthCapableMobs.put(21471, temp);
  234. _GrowthCapableMobs.put(21473, temp);
  235. temp = new GrowthCapableMob(1, 40);
  236. temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_2);
  237. _GrowthCapableMobs.put(21472, temp);
  238. _GrowthCapableMobs.put(21474, temp);
  239. temp = new GrowthCapableMob(1, 40);
  240. temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_1);
  241. _GrowthCapableMobs.put(21475, temp);
  242. _GrowthCapableMobs.put(21477, temp);
  243. temp = new GrowthCapableMob(1, 40);
  244. temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_2);
  245. _GrowthCapableMobs.put(21476, temp);
  246. _GrowthCapableMobs.put(21478, temp);
  247. temp = new GrowthCapableMob(2, 25);
  248. temp.addMobs(GOLDEN_SPICE, Buffalo_2_1);
  249. _GrowthCapableMobs.put(21479, temp);
  250. _GrowthCapableMobs.put(21481, temp);
  251. temp = new GrowthCapableMob(2, 25);
  252. temp.addMobs(GOLDEN_SPICE, Buffalo_2_2);
  253. _GrowthCapableMobs.put(21480, temp);
  254. _GrowthCapableMobs.put(21482, temp);
  255. temp = new GrowthCapableMob(2, 25);
  256. temp.addMobs(CRYSTAL_SPICE, Buffalo_2_1);
  257. _GrowthCapableMobs.put(21483, temp);
  258. _GrowthCapableMobs.put(21485, temp);
  259. temp = new GrowthCapableMob(2, 25);
  260. temp.addMobs(CRYSTAL_SPICE, Buffalo_2_2);
  261. _GrowthCapableMobs.put(21484, temp);
  262. _GrowthCapableMobs.put(21486, temp);
  263. // Alpen Cougar
  264. temp = new GrowthCapableMob(0, 100);
  265. temp.addMobs(GOLDEN_SPICE, Cougar_0_Gold);
  266. temp.addMobs(CRYSTAL_SPICE, Cougar_0_Crystal);
  267. _GrowthCapableMobs.put(21489, temp);
  268. temp = new GrowthCapableMob(1, 40);
  269. temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_1);
  270. _GrowthCapableMobs.put(21490, temp);
  271. _GrowthCapableMobs.put(21492, temp);
  272. temp = new GrowthCapableMob(1, 40);
  273. temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_2);
  274. _GrowthCapableMobs.put(21491, temp);
  275. _GrowthCapableMobs.put(21493, temp);
  276. temp = new GrowthCapableMob(1, 40);
  277. temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_1);
  278. _GrowthCapableMobs.put(21494, temp);
  279. _GrowthCapableMobs.put(21496, temp);
  280. temp = new GrowthCapableMob(1, 40);
  281. temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_2);
  282. _GrowthCapableMobs.put(21495, temp);
  283. _GrowthCapableMobs.put(21497, temp);
  284. temp = new GrowthCapableMob(2, 25);
  285. temp.addMobs(GOLDEN_SPICE, Cougar_2_1);
  286. _GrowthCapableMobs.put(21498, temp);
  287. _GrowthCapableMobs.put(21500, temp);
  288. temp = new GrowthCapableMob(2, 25);
  289. temp.addMobs(GOLDEN_SPICE, Cougar_2_2);
  290. _GrowthCapableMobs.put(21499, temp);
  291. _GrowthCapableMobs.put(21501, temp);
  292. temp = new GrowthCapableMob(2, 25);
  293. temp.addMobs(CRYSTAL_SPICE, Cougar_2_1);
  294. _GrowthCapableMobs.put(21502, temp);
  295. _GrowthCapableMobs.put(21504, temp);
  296. temp = new GrowthCapableMob(2, 25);
  297. temp.addMobs(CRYSTAL_SPICE, Cougar_2_2);
  298. _GrowthCapableMobs.put(21503, temp);
  299. _GrowthCapableMobs.put(21505, temp);
  300. }
  301. private void spawnNext(L2Npc npc, int growthLevel, L2PcInstance player, int food)
  302. {
  303. int npcId = npc.getId();
  304. int nextNpcId = 0;
  305. // find the next mob to spawn, based on the current npcId, growthlevel, and food.
  306. if (growthLevel == 2)
  307. {
  308. // if tamed, the mob that will spawn depends on the class type (fighter/mage) of the player!
  309. if (getRandom(2) == 0)
  310. {
  311. if (player.getClassId().isMage())
  312. {
  313. nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 1, 1);
  314. }
  315. else
  316. {
  317. nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 1, 0);
  318. }
  319. }
  320. else
  321. {
  322. // if not tamed, there is a small chance that have "mad cow" disease.
  323. // that is a stronger-than-normal animal that attacks its feeder
  324. if (getRandom(5) == 0)
  325. {
  326. nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 0, 1);
  327. }
  328. else
  329. {
  330. nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 0, 0);
  331. }
  332. }
  333. }
  334. else
  335. {
  336. // all other levels of growth are straight-forward
  337. nextNpcId = _GrowthCapableMobs.get(npcId).getRandomMob(food);
  338. }
  339. // remove the feedinfo of the mob that got despawned, if any
  340. if (_FeedInfo.containsKey(npc.getObjectId()))
  341. {
  342. if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
  343. {
  344. _FeedInfo.remove(npc.getObjectId());
  345. }
  346. }
  347. // despawn the old mob
  348. // TODO: same code? FIXED?
  349. // @formatter:off
  350. /*
  351. * if (_GrowthCapableMobs.get(npcId).getGrowthLevel() == 0)
  352. {
  353. npc.deleteMe();
  354. }
  355. else
  356. {
  357. */
  358. npc.deleteMe();
  359. // }
  360. // @formatter:on
  361. // if this is finally a trained mob, then despawn any other trained mobs that the
  362. // player might have and initialize the Tamed Beast.
  363. if (Util.contains(TAMED_BEASTS, nextNpcId))
  364. {
  365. if ((player.getTrainedBeasts() != null) && !player.getTrainedBeasts().isEmpty())
  366. {
  367. for (L2TamedBeastInstance oldTrained : player.getTrainedBeasts())
  368. {
  369. oldTrained.deleteMe();
  370. }
  371. }
  372. L2NpcTemplate template = NpcData.getInstance().getTemplate(nextNpcId);
  373. L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(IdFactory.getInstance().getNextId(), template, player, food - FOODSKILLDIFF, npc.getX(), npc.getY(), npc.getZ());
  374. nextNpc.setRunning();
  375. Q00020_BringUpWithLove.checkJewelOfInnocence(player);
  376. // also, perform a rare random chat
  377. if (getRandom(20) == 0)
  378. {
  379. NpcStringId message = NpcStringId.getNpcStringId(getRandom(2024, 2029));
  380. NpcSay packet = new NpcSay(nextNpc, 0, message);
  381. if (message.getParamCount() > 0) // player name, $s1
  382. {
  383. packet.addStringParameter(player.getName());
  384. }
  385. npc.broadcastPacket(packet);
  386. }
  387. // @formatter:off
  388. /*
  389. TODO: The tamed beast consumes one golden/crystal spice
  390. every 60 seconds with an initial delay of 60 seconds
  391. if (tamed beast exists and is alive)
  392. {
  393. if (player has 1+ golden/crystal spice)
  394. {
  395. take one golden/crystal spice;
  396. say random NpcString(getRandom(2029, 2038));
  397. }
  398. }
  399. */
  400. // @formatter:on
  401. }
  402. else
  403. {
  404. // if not trained, the newly spawned mob will automatically be aggro against its feeder
  405. // (what happened to "never bite the hand that feeds you" anyway?!)
  406. L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
  407. if (MAD_COW_POLYMORPH.containsKey(nextNpcId))
  408. {
  409. this.startQuestTimer("polymorph Mad Cow", 10000, nextNpc, player);
  410. }
  411. // register the player in the feedinfo for the mob that just spawned
  412. _FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
  413. nextNpc.setRunning();
  414. nextNpc.addDamageHate(player, 0, 99999);
  415. nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
  416. }
  417. }
  418. @Override
  419. public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
  420. {
  421. if (event.equalsIgnoreCase("polymorph Mad Cow") && (npc != null) && (player != null))
  422. {
  423. if (MAD_COW_POLYMORPH.containsKey(npc.getId()))
  424. {
  425. // remove the feed info from the previous mob
  426. if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
  427. {
  428. _FeedInfo.remove(npc.getObjectId());
  429. }
  430. // despawn the mad cow
  431. npc.deleteMe();
  432. // spawn the new mob
  433. L2Attackable nextNpc = (L2Attackable) addSpawn(MAD_COW_POLYMORPH.get(npc.getId()), npc);
  434. // register the player in the feedinfo for the mob that just spawned
  435. _FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
  436. nextNpc.setRunning();
  437. nextNpc.addDamageHate(player, 0, 99999);
  438. nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
  439. }
  440. }
  441. return super.onAdvEvent(event, npc, player);
  442. }
  443. @Override
  444. public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
  445. {
  446. // this behavior is only run when the target of skill is the passed npc (chest)
  447. // i.e. when the player is attempting to open the chest using a skill
  448. if (!Util.contains(targets, npc))
  449. {
  450. return super.onSkillSee(npc, caster, skill, targets, isSummon);
  451. }
  452. // gather some values on local variables
  453. int npcId = npc.getId();
  454. int skillId = skill.getId();
  455. // check if the npc and skills used are valid for this script. Exit if invalid.
  456. if ((skillId != SKILL_GOLDEN_SPICE) && (skillId != SKILL_CRYSTAL_SPICE))
  457. {
  458. return super.onSkillSee(npc, caster, skill, targets, isSummon);
  459. }
  460. // first gather some values on local variables
  461. int objectId = npc.getObjectId();
  462. int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
  463. if (_GrowthCapableMobs.containsKey(npcId))
  464. {
  465. growthLevel = _GrowthCapableMobs.get(npcId).getGrowthLevel();
  466. }
  467. // prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
  468. // If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
  469. if ((growthLevel == 0) && _FeedInfo.containsKey(objectId))
  470. {
  471. return super.onSkillSee(npc, caster, skill, targets, isSummon);
  472. }
  473. _FeedInfo.put(objectId, caster.getObjectId());
  474. int food = 0;
  475. if (skillId == SKILL_GOLDEN_SPICE)
  476. {
  477. food = GOLDEN_SPICE;
  478. }
  479. else if (skillId == SKILL_CRYSTAL_SPICE)
  480. {
  481. food = CRYSTAL_SPICE;
  482. }
  483. // display the social action of the beast eating the food.
  484. npc.broadcastSocialAction(2);
  485. // if this pet can't grow, it's all done.
  486. if (_GrowthCapableMobs.containsKey(npcId))
  487. {
  488. // do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
  489. if (_GrowthCapableMobs.get(npcId).getMob(food, 0, 0) == null)
  490. {
  491. return super.onSkillSee(npc, caster, skill, targets, isSummon);
  492. }
  493. // rare random talk...
  494. if (getRandom(20) == 0)
  495. {
  496. NpcStringId message = TEXT[growthLevel][getRandom(TEXT[growthLevel].length)];
  497. NpcSay packet = new NpcSay(npc, 0, message);
  498. if (message.getParamCount() > 0) // player name, $s1
  499. {
  500. packet.addStringParameter(caster.getName());
  501. }
  502. npc.broadcastPacket(packet);
  503. }
  504. if ((growthLevel > 0) && (_FeedInfo.get(objectId) != caster.getObjectId()))
  505. {
  506. // check if this is the same player as the one who raised it from growth 0.
  507. // if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
  508. return super.onSkillSee(npc, caster, skill, targets, isSummon);
  509. }
  510. // Polymorph the mob, with a certain chance, given its current growth level
  511. if (getRandom(100) < _GrowthCapableMobs.get(npcId).getChance())
  512. {
  513. spawnNext(npc, growthLevel, caster, food);
  514. }
  515. }
  516. else if (Util.contains(TAMED_BEASTS, npcId) && (npc instanceof L2TamedBeastInstance))
  517. {
  518. L2TamedBeastInstance beast = ((L2TamedBeastInstance) npc);
  519. if (skillId == beast.getFoodType())
  520. {
  521. beast.onReceiveFood();
  522. NpcStringId message = TAMED_TEXT[getRandom(TAMED_TEXT.length)];
  523. NpcSay packet = new NpcSay(npc, 0, message);
  524. if (message.getParamCount() > 0)
  525. {
  526. packet.addStringParameter(caster.getName());
  527. }
  528. beast.broadcastPacket(packet);
  529. }
  530. }
  531. return super.onSkillSee(npc, caster, skill, targets, isSummon);
  532. }
  533. @Override
  534. public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
  535. {
  536. // remove the feedinfo of the mob that got killed, if any
  537. if (_FeedInfo.containsKey(npc.getObjectId()))
  538. {
  539. _FeedInfo.remove(npc.getObjectId());
  540. }
  541. return super.onKill(npc, killer, isSummon);
  542. }
  543. public static void main(String[] args)
  544. {
  545. new FeedableBeasts();
  546. }
  547. }