FeedableBeasts.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  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. import java.util.Map;
  17. import javolution.util.FastMap;
  18. import com.l2jserver.gameserver.ai.CtrlIntention;
  19. import com.l2jserver.gameserver.datatables.NpcTable;
  20. import com.l2jserver.gameserver.idfactory.IdFactory;
  21. import com.l2jserver.gameserver.model.L2Object;
  22. import com.l2jserver.gameserver.model.L2Skill;
  23. import com.l2jserver.gameserver.model.actor.L2Attackable;
  24. import com.l2jserver.gameserver.model.actor.L2Npc;
  25. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  26. import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
  27. import com.l2jserver.gameserver.model.quest.QuestState;
  28. import com.l2jserver.gameserver.network.serverpackets.NpcSay;
  29. import com.l2jserver.gameserver.network.serverpackets.SocialAction;
  30. import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
  31. import com.l2jserver.gameserver.util.Util;
  32. import com.l2jserver.util.Rnd;
  33. /**
  34. * Growth-capable mobs: Polymorphing upon successful feeding.
  35. * @author Fulminus
  36. */
  37. public class FeedableBeasts extends L2AttackableAIScript
  38. {
  39. private static final int GOLDEN_SPICE = 6643;
  40. private static final int CRYSTAL_SPICE = 6644;
  41. private static final int SKILL_GOLDEN_SPICE = 2188;
  42. private static final int SKILL_CRYSTAL_SPICE = 2189;
  43. private static final int[] TAMED_BEASTS = {16013, 16014, 16015, 16016, 16017, 16018};
  44. private static final int FOODSKILLDIFF = GOLDEN_SPICE - SKILL_GOLDEN_SPICE;
  45. // all mobs that can eat...
  46. private static final int[] FEEDABLE_BEASTS = {
  47. 21451,21452,21453,21454,21455,21456,21457,21458,21459,21460,21461,21462,21463,
  48. 21464,21465,21466,21467,21468,21469,21470,21471,21472,21473,21474,21475,21476,
  49. 21477,21478,21479,21480,21481,21482,21483,21484,21485,21486,21487,21488,21489,
  50. 21490,21491,21492,21493,21494,21495,21496,21497,21498,21499,21500,21501,21502,
  51. 21503,21504,21505,21506,21507,21824,21825,21826,21827,21828,21829,16013,16014,
  52. 16015,16016,16017,16018
  53. };
  54. private static final Map<Integer,Integer> MAD_COW_POLYMORPH = new FastMap<Integer,Integer>();
  55. static
  56. {
  57. MAD_COW_POLYMORPH.put(21824,21468);
  58. MAD_COW_POLYMORPH.put(21825,21469);
  59. MAD_COW_POLYMORPH.put(21826,21487);
  60. MAD_COW_POLYMORPH.put(21827,21488);
  61. MAD_COW_POLYMORPH.put(21828,21506);
  62. MAD_COW_POLYMORPH.put(21829,21507);
  63. }
  64. //TODO: NpcString
  65. private static final String[][] TEXT =
  66. {
  67. {
  68. "What did you just do to me?","You want to tame me, huh?",
  69. "Do not give me this. Perhaps you will be in danger.",
  70. "Bah bah. What is this unpalatable thing?",
  71. "My belly has been complaining. This hit the spot.",
  72. "What is this? Can I eat it?","You don't need to worry about me.",
  73. "Delicious food, thanks.","I am starting to like you!","Gulp"
  74. },
  75. {
  76. "I do not think you have given up on the idea of taming me.",
  77. "That is just food to me. Perhaps I can eat your hand too.",
  78. "Will eating this make me fat? Ha ha","Why do you always feed me?",
  79. "Do not trust me. I may betray you"
  80. },
  81. {
  82. "Destroy","Look what you have done!",
  83. "Strange feeling...! Evil intentions grow in my heart...!",
  84. "It is happenning!","This is sad...Good is sad...!"
  85. }
  86. };
  87. private static final String[] TAMED_TEXT =
  88. {
  89. "Refills! Yeah!","I am such a gluttonous beast, it is embarrassing! Ha ha",
  90. "Your cooperative feeling has been getting better and better.",
  91. "I will help you!","The weather is really good. Wanna go for a picnic?",
  92. "I really like you! This is tasty...",
  93. "If you do not have to leave this place, then I can help you.",
  94. "What can I help you with?","I am not here only for food!",
  95. "Yam, yam, yam, yam, yam!"
  96. };
  97. private static Map<Integer,Integer> _FeedInfo = new FastMap<Integer,Integer>();
  98. private static Map<Integer,GrowthCapableMob> _GrowthCapableMobs = new FastMap<Integer,GrowthCapableMob>();
  99. // all mobs that grow by eating
  100. private static class GrowthCapableMob
  101. {
  102. private int _growthLevel;
  103. private int _chance;
  104. private Map<Integer, int[][]> _spiceToMob = new FastMap<Integer,int[][]>();
  105. public GrowthCapableMob(int growthLevel, int chance)
  106. {
  107. _growthLevel = growthLevel;
  108. _chance = chance;
  109. }
  110. public void addMobs(int spice, int[][] Mobs)
  111. {
  112. _spiceToMob.put(spice, Mobs);
  113. }
  114. public Integer getMob(int spice,int mobType, int classType)
  115. {
  116. if (_spiceToMob.containsKey(spice))
  117. {
  118. return _spiceToMob.get(spice)[mobType][classType];
  119. }
  120. return null;
  121. }
  122. public Integer getRandomMob(int spice)
  123. {
  124. int[][] temp;
  125. temp = _spiceToMob.get(spice);
  126. int rand = Rnd.get(temp[0].length);
  127. return temp[0][rand];
  128. }
  129. public Integer getChance()
  130. {
  131. return _chance;
  132. }
  133. public Integer getGrowthLevel()
  134. {
  135. return _growthLevel;
  136. }
  137. }
  138. public FeedableBeasts (int questId, String name, String descr)
  139. {
  140. super(questId, name, descr);
  141. this.registerMobs(FEEDABLE_BEASTS, QuestEventType.ON_KILL, QuestEventType.ON_SKILL_SEE);
  142. GrowthCapableMob temp;
  143. final int[][] Kookabura_0_Gold = {{21452,21453, 21454, 21455}};
  144. final int[][] Kookabura_0_Crystal = {{21456,21457, 21458, 21459}};
  145. final int[][] Kookabura_1_Gold_1= {{21460,21462}};
  146. final int[][] Kookabura_1_Gold_2 = {{21461,21463}};
  147. final int[][] Kookabura_1_Crystal_1 = {{21464,21466}};
  148. final int[][] Kookabura_1_Crystal_2 = {{21465,21467}};
  149. final int[][] Kookabura_2_1 = {{21468,21824},{16017,16018}};
  150. final int[][] Kookabura_2_2 = {{21469,21825},{16017,16018}};
  151. final int[][] Buffalo_0_Gold = {{21471,21472, 21473, 21474}};
  152. final int[][] Buffalo_0_Crystal = {{21475,21476, 21477, 21478}};
  153. final int[][] Buffalo_1_Gold_1 = {{21479,21481}};
  154. final int[][] Buffalo_1_Gold_2 = {{21481,21482}};
  155. final int[][] Buffalo_1_Crystal_1 = {{21483,21485}};
  156. final int[][] Buffalo_1_Crystal_2 = {{21484,21486}};
  157. final int[][] Buffalo_2_1 = {{21487,21826},{16013,16014}};
  158. final int[][] Buffalo_2_2 = {{21488,21827},{16013,16014}};
  159. final int[][] Cougar_0_Gold = {{21490,21491, 21492, 21493}};
  160. final int[][] Cougar_0_Crystal = {{21494,21495, 21496, 21497}};
  161. final int[][] Cougar_1_Gold_1 = {{21498,21500}};
  162. final int[][] Cougar_1_Gold_2 = {{21499,21501}};
  163. final int[][] Cougar_1_Crystal_1 = {{21502,21504}};
  164. final int[][] Cougar_1_Crystal_2 = {{21503,21505}};
  165. final int[][] Cougar_2_1 = {{21506,21828},{16015,16016}};
  166. final int[][] Cougar_2_2 = {{21507,21829},{16015,16016}};
  167. // Alpen Kookabura
  168. temp = new GrowthCapableMob(0,100);
  169. temp.addMobs(GOLDEN_SPICE,Kookabura_0_Gold);
  170. temp.addMobs(CRYSTAL_SPICE,Kookabura_0_Crystal);
  171. _GrowthCapableMobs.put(21451, temp);
  172. temp = new GrowthCapableMob(1,40);
  173. temp.addMobs(GOLDEN_SPICE,Kookabura_1_Gold_1);
  174. _GrowthCapableMobs.put(21452, temp);
  175. _GrowthCapableMobs.put(21454, temp);
  176. temp = new GrowthCapableMob(1,40);
  177. temp.addMobs(GOLDEN_SPICE,Kookabura_1_Gold_2);
  178. _GrowthCapableMobs.put(21453, temp);
  179. _GrowthCapableMobs.put(21455, temp);
  180. temp = new GrowthCapableMob(1,40);
  181. temp.addMobs(CRYSTAL_SPICE,Kookabura_1_Crystal_1);
  182. _GrowthCapableMobs.put(21456, temp);
  183. _GrowthCapableMobs.put(21458, temp);
  184. temp = new GrowthCapableMob(1,40);
  185. temp.addMobs(CRYSTAL_SPICE,Kookabura_1_Crystal_2);
  186. _GrowthCapableMobs.put(21457, temp);
  187. _GrowthCapableMobs.put(21459, temp);
  188. temp = new GrowthCapableMob(2,25);
  189. temp.addMobs(GOLDEN_SPICE,Kookabura_2_1);
  190. _GrowthCapableMobs.put(21460, temp);
  191. _GrowthCapableMobs.put(21462, temp);
  192. temp = new GrowthCapableMob(2,25);
  193. temp.addMobs(GOLDEN_SPICE,Kookabura_2_2);
  194. _GrowthCapableMobs.put(21461, temp);
  195. _GrowthCapableMobs.put(21463, temp);
  196. temp = new GrowthCapableMob(2,25);
  197. temp.addMobs(CRYSTAL_SPICE,Kookabura_2_1);
  198. _GrowthCapableMobs.put(21464, temp);
  199. _GrowthCapableMobs.put(21466, temp);
  200. temp = new GrowthCapableMob(2,25);
  201. temp.addMobs(CRYSTAL_SPICE,Kookabura_2_2);
  202. _GrowthCapableMobs.put(21465, temp);
  203. _GrowthCapableMobs.put(21467, temp);
  204. // Alpen Buffalo
  205. temp = new GrowthCapableMob(0,100);
  206. temp.addMobs(GOLDEN_SPICE,Buffalo_0_Gold);
  207. temp.addMobs(CRYSTAL_SPICE,Buffalo_0_Crystal);
  208. _GrowthCapableMobs.put(21470, temp);
  209. temp = new GrowthCapableMob(1,40);
  210. temp.addMobs(GOLDEN_SPICE,Buffalo_1_Gold_1);
  211. _GrowthCapableMobs.put(21471, temp);
  212. _GrowthCapableMobs.put(21473, temp);
  213. temp = new GrowthCapableMob(1,40);
  214. temp.addMobs(GOLDEN_SPICE,Buffalo_1_Gold_2);
  215. _GrowthCapableMobs.put(21472, temp);
  216. _GrowthCapableMobs.put(21474, temp);
  217. temp = new GrowthCapableMob(1,40);
  218. temp.addMobs(CRYSTAL_SPICE,Buffalo_1_Crystal_1);
  219. _GrowthCapableMobs.put(21475, temp);
  220. _GrowthCapableMobs.put(21477, temp);
  221. temp = new GrowthCapableMob(1,40);
  222. temp.addMobs(CRYSTAL_SPICE,Buffalo_1_Crystal_2);
  223. _GrowthCapableMobs.put(21476, temp);
  224. _GrowthCapableMobs.put(21478, temp);
  225. temp = new GrowthCapableMob(2,25);
  226. temp.addMobs(GOLDEN_SPICE,Buffalo_2_1);
  227. _GrowthCapableMobs.put(21479, temp);
  228. _GrowthCapableMobs.put(21481, temp);
  229. temp = new GrowthCapableMob(2,25);
  230. temp.addMobs(GOLDEN_SPICE,Buffalo_2_2);
  231. _GrowthCapableMobs.put(21480, temp);
  232. _GrowthCapableMobs.put(21482, temp);
  233. temp = new GrowthCapableMob(2,25);
  234. temp.addMobs(CRYSTAL_SPICE,Buffalo_2_1);
  235. _GrowthCapableMobs.put(21483, temp);
  236. _GrowthCapableMobs.put(21485, temp);
  237. temp = new GrowthCapableMob(2,25);
  238. temp.addMobs(CRYSTAL_SPICE,Buffalo_2_2);
  239. _GrowthCapableMobs.put(21484, temp);
  240. _GrowthCapableMobs.put(21486, temp);
  241. // Alpen Cougar
  242. temp = new GrowthCapableMob(0,100);
  243. temp.addMobs(GOLDEN_SPICE,Cougar_0_Gold);
  244. temp.addMobs(CRYSTAL_SPICE,Cougar_0_Crystal);
  245. _GrowthCapableMobs.put(21489, temp);
  246. temp = new GrowthCapableMob(1,40);
  247. temp.addMobs(GOLDEN_SPICE,Cougar_1_Gold_1);
  248. _GrowthCapableMobs.put(21490, temp);
  249. _GrowthCapableMobs.put(21492, temp);
  250. temp = new GrowthCapableMob(1,40);
  251. temp.addMobs(GOLDEN_SPICE,Cougar_1_Gold_2);
  252. _GrowthCapableMobs.put(21491, temp);
  253. _GrowthCapableMobs.put(21493, temp);
  254. temp = new GrowthCapableMob(1,40);
  255. temp.addMobs(CRYSTAL_SPICE,Cougar_1_Crystal_1);
  256. _GrowthCapableMobs.put(21494, temp);
  257. _GrowthCapableMobs.put(21496, temp);
  258. temp = new GrowthCapableMob(1,40);
  259. temp.addMobs(CRYSTAL_SPICE,Cougar_1_Crystal_2);
  260. _GrowthCapableMobs.put(21495, temp);
  261. _GrowthCapableMobs.put(21497, temp);
  262. temp = new GrowthCapableMob(2,25);
  263. temp.addMobs(GOLDEN_SPICE,Cougar_2_1);
  264. _GrowthCapableMobs.put(21498, temp);
  265. _GrowthCapableMobs.put(21500, temp);
  266. temp = new GrowthCapableMob(2,25);
  267. temp.addMobs(GOLDEN_SPICE,Cougar_2_2);
  268. _GrowthCapableMobs.put(21499, temp);
  269. _GrowthCapableMobs.put(21501, temp);
  270. temp = new GrowthCapableMob(2,25);
  271. temp.addMobs(CRYSTAL_SPICE,Cougar_2_1);
  272. _GrowthCapableMobs.put(21502, temp);
  273. _GrowthCapableMobs.put(21504, temp);
  274. temp = new GrowthCapableMob(2,25);
  275. temp.addMobs(CRYSTAL_SPICE,Cougar_2_2);
  276. _GrowthCapableMobs.put(21503, temp);
  277. _GrowthCapableMobs.put(21505, temp);
  278. }
  279. public void spawnNext(L2Npc npc, int growthLevel, L2PcInstance player, int food)
  280. {
  281. int npcId = npc.getNpcId();
  282. int nextNpcId = 0;
  283. // find the next mob to spawn, based on the current npcId, growthlevel, and food.
  284. if (growthLevel == 2)
  285. {
  286. // if tamed, the mob that will spawn depends on the class type (fighter/mage) of the player!
  287. if (Rnd.get(2) == 0)
  288. {
  289. if (player.getClassId().isMage())
  290. {
  291. nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 1, 1);
  292. }
  293. else
  294. {
  295. nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 1, 0);
  296. }
  297. }
  298. else
  299. {
  300. // if not tamed, there is a small chance that have "mad cow" disease.
  301. // that is a stronger-than-normal animal that attacks its feeder
  302. if (Rnd.get(5) == 0)
  303. {
  304. nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 0, 1);
  305. }
  306. else
  307. {
  308. nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 0, 0);
  309. }
  310. }
  311. }
  312. else
  313. {
  314. // all other levels of growth are straight-forward
  315. nextNpcId = _GrowthCapableMobs.get(npcId).getRandomMob(food);
  316. }
  317. // remove the feedinfo of the mob that got despawned, if any
  318. if (_FeedInfo.containsKey(npc.getObjectId()))
  319. {
  320. if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
  321. _FeedInfo.remove(npc.getObjectId());
  322. }
  323. // despawn the old mob
  324. //TODO: same code? FIXED?
  325. /*if (_GrowthCapableMobs.get(npcId).getGrowthLevel() == 0)
  326. {
  327. npc.deleteMe();
  328. }
  329. else
  330. {*/
  331. npc.deleteMe();
  332. //}
  333. // if this is finally a trained mob, then despawn any other trained mobs that the
  334. // player might have and initialize the Tamed Beast.
  335. if (Util.contains(TAMED_BEASTS,nextNpcId))
  336. {
  337. if (player.getTrainedBeasts() != null && !player.getTrainedBeasts().isEmpty())
  338. for(L2TamedBeastInstance oldTrained : player.getTrainedBeasts())
  339. oldTrained.deleteMe();
  340. L2NpcTemplate template = NpcTable.getInstance().getTemplate(nextNpcId);
  341. L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(IdFactory.getInstance().getNextId(), template, player, food - FOODSKILLDIFF, npc.getX(), npc.getY(), npc.getZ());
  342. nextNpc.setRunning();
  343. int objectId = nextNpc.getObjectId();
  344. QuestState st = player.getQuestState("20_BringUpWithLove");
  345. if (st != null)
  346. {
  347. if (Rnd.get(100) <= 5 && st.getQuestItemsCount(7185) == 0)
  348. {
  349. //if player has quest 20 going, give quest item
  350. //it's easier to hardcode it in here than to try and repeat this stuff in the quest
  351. st.giveItems(7185,1);
  352. st.set("cond","2");
  353. }
  354. }
  355. // also, perform a rare random chat
  356. int rand = Rnd.get(20);
  357. if (rand == 0)
  358. {
  359. npc.broadcastPacket(new NpcSay(objectId,0,nextNpc.getNpcId(), player.getName()+", will you show me your hideaway?"));
  360. }
  361. else if (rand == 1)
  362. {
  363. npc.broadcastPacket(new NpcSay(objectId,0,nextNpc.getNpcId(), player.getName()+", whenever I look at spice, I think about you."));
  364. }
  365. else if (rand == 2)
  366. {
  367. npc.broadcastPacket(new NpcSay(objectId,0,nextNpc.getNpcId(), player.getName()+", you do not need to return to the village. I will give you strength"));
  368. }
  369. else if (rand == 3)
  370. {
  371. npc.broadcastPacket(new NpcSay(objectId,0,nextNpc.getNpcId(), "Thanks, "+player.getName()+". I hope I can help you"));
  372. }
  373. else if (rand == 4)
  374. {
  375. npc.broadcastPacket(new NpcSay(objectId,0,nextNpc.getNpcId(), player.getName()+", what can I do to help you?"));
  376. }
  377. }
  378. else
  379. {
  380. // if not trained, the newly spawned mob will automatically be agro against its feeder
  381. // (what happened to "never bite the hand that feeds you" anyway?!)
  382. L2Attackable nextNpc = (L2Attackable) this.addSpawn(nextNpcId,npc);
  383. if (MAD_COW_POLYMORPH.containsKey(nextNpcId))
  384. {
  385. this.startQuestTimer("polymorph Mad Cow", 10000, nextNpc, player);
  386. }
  387. // register the player in the feedinfo for the mob that just spawned
  388. _FeedInfo.put(nextNpc.getObjectId(),player.getObjectId());
  389. nextNpc.setRunning();
  390. nextNpc.addDamageHate(player,0,99999);
  391. nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
  392. }
  393. }
  394. @Override
  395. public String onAdvEvent (String event, L2Npc npc, L2PcInstance player)
  396. {
  397. if (event.equalsIgnoreCase("polymorph Mad Cow") && npc != null && player != null)
  398. {
  399. if( MAD_COW_POLYMORPH.containsKey(npc.getNpcId()))
  400. {
  401. // remove the feed info from the previous mob
  402. if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
  403. {
  404. _FeedInfo.remove(npc.getObjectId());
  405. }
  406. // despawn the mad cow
  407. npc.deleteMe();
  408. // spawn the new mob
  409. L2Attackable nextNpc = (L2Attackable) this.addSpawn(MAD_COW_POLYMORPH.get(npc.getNpcId()),npc);
  410. // register the player in the feedinfo for the mob that just spawned
  411. _FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
  412. nextNpc.setRunning();
  413. nextNpc.addDamageHate(player,0,99999);
  414. nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
  415. }
  416. }
  417. return super.onAdvEvent(event,npc,player);
  418. }
  419. @Override
  420. public String onSkillSee (L2Npc npc, L2PcInstance caster, L2Skill skill, L2Object[] targets, boolean isPet)
  421. {
  422. // this behavior is only run when the target of skill is the passed npc (chest)
  423. // i.e. when the player is attempting to open the chest using a skill
  424. if (!Util.contains(targets,npc))
  425. {
  426. return super.onSkillSee(npc,caster,skill,targets,isPet);
  427. }
  428. // gather some values on local variables
  429. int npcId = npc.getNpcId();
  430. int skillId = skill.getId();
  431. // check if the npc and skills used are valid for this script. Exit if invalid.
  432. if (!Util.contains(FEEDABLE_BEASTS,npcId) || (skillId !=SKILL_GOLDEN_SPICE && skillId != SKILL_CRYSTAL_SPICE))
  433. {
  434. return super.onSkillSee(npc,caster,skill,targets,isPet);
  435. }
  436. // first gather some values on local variables
  437. int objectId = npc.getObjectId();
  438. int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
  439. if (_GrowthCapableMobs.containsKey(npcId))
  440. {
  441. growthLevel = _GrowthCapableMobs.get(npcId).getGrowthLevel();
  442. }
  443. // prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
  444. // If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
  445. if (growthLevel==0 && _FeedInfo.containsKey(objectId))
  446. {
  447. return super.onSkillSee(npc,caster,skill,targets,isPet);
  448. }
  449. else
  450. {
  451. _FeedInfo.put(objectId,caster.getObjectId());
  452. }
  453. int food = 0;
  454. if (skillId == SKILL_GOLDEN_SPICE)
  455. {
  456. food = GOLDEN_SPICE;
  457. }
  458. else if (skillId == SKILL_CRYSTAL_SPICE)
  459. {
  460. food = CRYSTAL_SPICE;
  461. }
  462. // display the social action of the beast eating the food.
  463. npc.broadcastPacket(new SocialAction(npc,2));
  464. // if this pet can't grow, it's all done.
  465. if (_GrowthCapableMobs.containsKey(npcId))
  466. {
  467. // do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
  468. if (_GrowthCapableMobs.get(npcId).getMob(food, 0, 0) == null )
  469. {
  470. return super.onSkillSee(npc,caster,skill,targets,isPet);
  471. }
  472. // rare random talk...
  473. if (Rnd.get(20) == 0 )
  474. {
  475. npc.broadcastPacket(new NpcSay(objectId,0,npc.getNpcId(),TEXT[growthLevel][Rnd.get(TEXT[growthLevel].length)]));
  476. }
  477. if (growthLevel > 0 && _FeedInfo.get(objectId) != caster.getObjectId())
  478. {
  479. // check if this is the same player as the one who raised it from growth 0.
  480. // if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
  481. return super.onSkillSee(npc,caster,skill,targets,isPet);
  482. }
  483. // Polymorph the mob, with a certain chance, given its current growth level
  484. if (Rnd.get(100) < _GrowthCapableMobs.get(npcId).getChance())
  485. {
  486. this.spawnNext(npc, growthLevel,caster,food);
  487. }
  488. }
  489. else if (Util.contains(TAMED_BEASTS,npcId) && npc instanceof L2TamedBeastInstance)
  490. {
  491. L2TamedBeastInstance beast = ((L2TamedBeastInstance)npc);
  492. if (skillId == beast.getFoodType())
  493. {
  494. beast.onReceiveFood();
  495. beast.broadcastPacket(new NpcSay(objectId,0,npcId,TAMED_TEXT[Rnd.get(TAMED_TEXT.length)]));
  496. }
  497. }
  498. return super.onSkillSee(npc,caster,skill,targets,isPet);
  499. }
  500. @Override
  501. public String onKill (L2Npc npc, L2PcInstance killer, boolean isPet)
  502. {
  503. // remove the feedinfo of the mob that got killed, if any
  504. if (_FeedInfo.containsKey(npc.getObjectId()))
  505. {
  506. _FeedInfo.remove(npc.getObjectId());
  507. }
  508. return super.onKill(npc,killer,isPet);
  509. }
  510. public static void main(String[] args)
  511. {
  512. // now call the constructor (starts up the ai)
  513. new FeedableBeasts(-1,"feedable_beasts","ai");
  514. }
  515. }