/*
 * Copyright (C) 2004-2013 L2J DataPack
 * 
 * This file is part of L2J DataPack.
 * 
 * L2J DataPack is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * L2J DataPack is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package ai.group_template;

import static com.l2jserver.gameserver.datatables.SkillTable.*;
import jp.sf.l2j.arrayMaps.SortedIntIntArrayMap;
import jp.sf.l2j.arrayMaps.SortedIntObjectArrayMap;
import jp.sf.l2j.troja.FastIntObjectMap;
import quests.Q00020_BringUpWithLove.Q00020_BringUpWithLove;
import ai.npc.AbstractNpcAI;

import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.datatables.NpcTable;
import com.l2jserver.gameserver.datatables.SkillTable;
import com.l2jserver.gameserver.enums.QuestEventType;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jserver.gameserver.model.skills.L2Skill;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.serverpackets.AbstractNpcInfo;
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
import com.l2jserver.gameserver.util.Util;

/**
 * Growth-capable mobs: Polymorphing upon successful feeding.<br>
 * Updated to Freya.
 * @author Fulminus, Gigiikun
 */
public class BeastFarm extends AbstractNpcAI
{
	private static final int GOLDEN_SPICE = 15474;	//【アイテム】ゴールデン スパイス
	private static final int CRYSTAL_SPICE = 15475;	//【アイテム】クリスタル スパイス
	private static final int SKILL_GOLDEN_SPICE = 9049;	//【スキル】飼料：ゴールデン スパイス
	private static final int SKILL_CRYSTAL_SPICE = 9050;	//【スキル】飼料：クリスタル スパイス
	private static final int SKILL_BLESSED_GOLDEN_SPICE = 9051;	//【スキル】飼料：祝福されたゴールデン スパイス
	private static final int SKILL_BLESSED_CRYSTAL_SPICE = 9052;	//【スキル】飼料：祝福されたクリスタル スパイス
	private static final int SKILL_SGRADE_GOLDEN_SPICE = 9053;	//【スキル】飼料：Sグレード ゴールデン スパイス
	private static final int SKILL_SGRADE_CRYSTAL_SPICE = 9054;	//【スキル】飼料：Sグレード クリスタル スパイス
	private static final int[] TAMED_BEASTS =
	{
		18869,	// 手なずけられた アルパイン クッカブロ
		18870,	// 手なずけられた アルパイン クーガー
		18871,	// 手なずけられた アルパイン バッファロー
		18872,	// 手なずけられた アルパイン グレンデル
	};
	private static final SortedIntObjectArrayMap<String> TAMED_BEAST_NAMES = new SortedIntObjectArrayMap<String>()
		.append(18869, "#1801106")	// "アルパイン クッカブロ"
		.append(18870, "#1801107")	// "アルパイン クーガー"
		.append(18871, "#1801108")	// "アルパイン バッファロー"
		.append(18872, "#1801109")	// "アルパイン グレンデル"
	;
	private static final int TAME_CHANCE = 20;
	protected static final int[] SPECIAL_SPICE_CHANCES =
	{
		33,
		75
	};
	
	// all mobs that can eat...
	private static final int[] FEEDABLE_BEASTS =
	{
		// Kookaburras アルパイン クッカブロ
		18873,
		18874,
		18875,
		18876,
		18877,
		18878,
		18879,
		// Cougars アルパイン クーガー
		18880,
		18881,
		18882,
		18883,
		18884,
		18885,
		18886,
		// Buffalos アルパイン バッファロー
		18887,
		18888,
		18889,
		18890,
		18891,
		18892,
		18893,
		// Grendels アルパイン グレンデル
		18894,
		18895,
		18896,
		18897,
		18898,
		18899,
		18900
	};
	
	private static FastIntObjectMap<Integer> _FeedInfo = new FastIntObjectMap<>();
	private static FastIntObjectMap<GrowthCapableMob> GROWTH_CAPABLE_MOBS = new FastIntObjectMap<>();
	private static TamedBeast[] TAMED_BEAST_DATA;
	
	private static final NpcStringId[] HATE_TEXT =
	{
		NpcStringId.WHAT_DID_YOU_JUST_DO_TO_ME,
		NpcStringId.ARE_YOU_TRYING_TO_TAME_ME_DONT_DO_THAT,
		NpcStringId.DONT_GIVE_SUCH_A_THING_YOU_CAN_ENDANGER_YOURSELF,
		NpcStringId.YUCK_WHAT_IS_THIS_IT_TASTES_TERRIBLE,
		NpcStringId.IM_HUNGRY_GIVE_ME_A_LITTLE_MORE_PLEASE,
	};
	private static final NpcStringId[][] GROW_TEXT =
	{
		{
			NpcStringId.WHAT_IS_THIS_IS_THIS_EDIBLE,
			NpcStringId.DONT_WORRY_ABOUT_ME,
			NpcStringId.THANK_YOU_THAT_WAS_DELICIOUS,
			NpcStringId.I_THINK_I_AM_STARTING_TO_LIKE_YOU,
			NpcStringId.EEEEEK_EEEEEK,
		},
		{
			NpcStringId.DONT_KEEP_TRYING_TO_TAME_ME_I_DONT_WANT_TO_BE_TAMED,
			NpcStringId.IT_IS_JUST_FOOD_TO_ME_ALTHOUGH_IT_MAY_ALSO_BE_YOUR_HAND,
			NpcStringId.IF_I_KEEP_EATING_LIKE_THIS_WONT_I_BECOME_FAT_CHOMP_CHOMP,
			NpcStringId.WHY_DO_YOU_KEEP_FEEDING_ME,
			NpcStringId.DONT_TRUST_ME_IM_AFRAID_I_MAY_BETRAY_YOU_LATER,
		},
		{
			NpcStringId.GRRRRR,
			NpcStringId.YOU_BROUGHT_THIS_UPON_YOURSELF,
			NpcStringId.I_FEEL_STRANGE_I_KEEP_HAVING_THESE_EVIL_THOUGHTS,
			NpcStringId.ALAS_SO_THIS_IS_HOW_IT_ALL_ENDS,
			NpcStringId.I_DONT_FEEL_SO_GOOD_OH_MY_MIND_IS_VERY_TROUBLED,
		},
	};
	
	private static final NpcStringId[] TAMED_TEXT =
	{
		NpcStringId.S1_SO_WHAT_DO_YOU_THINK_IT_IS_LIKE_TO_BE_TAMED,
		NpcStringId.S1_WHENEVER_I_SEE_SPICE_I_THINK_I_WILL_MISS_YOUR_HAND_THAT_USED_TO_FEED_IT_TO_ME,
		NpcStringId.S1_DONT_GO_TO_THE_VILLAGE_I_DONT_HAVE_THE_STRENGTH_TO_FOLLOW_YOU,
		NpcStringId.THANK_YOU_FOR_TRUSTING_ME_S1_I_HOPE_I_WILL_BE_HELPFUL_TO_YOU,
		NpcStringId.S1_WILL_I_BE_ABLE_TO_HELP_YOU,
	};
	
	private void autoChat(L2Npc npc, NpcStringId[] text, long delay)
	{
		autoChat(npc, text, null, delay);
	}
	private void autoChat(L2Npc npc, NpcStringId[] text, L2PcInstance player, long delay)
	{
		autoChat(npc, player, text[getRandom(text.length)], delay);
	}
	private void autoChat(final L2Npc npc, final L2PcInstance player, final NpcStringId text, long delay)
	{
		ThreadPoolManager.getInstance().scheduleGeneral(new Runnable(){
			@Override
			public void run()
			{
				if (!npc.isVisible()) return;
				NpcSay npcSay = new NpcSay(npc.getObjectId(), 0, npc.getId(), text);
				if (player != null) npcSay.addPcName(player);
				npc.broadcastPacket(npcSay);
			}
		}, delay);
	}
	
	
	private BeastFarm()
	{
		super(BeastFarm.class.getSimpleName(), "ai/group_template");
		registerMobs(FEEDABLE_BEASTS, QuestEventType.ON_KILL, QuestEventType.ON_SKILL_SEE);
		
		GrowthCapableMob temp;
		
		// Kookabura
		temp = new GrowthCapableMob(100, 0, 18869);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18874);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18875);
		temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18869);
		temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18869);
		temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18878);
		temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18879);
		GROWTH_CAPABLE_MOBS.put(18873, temp);
		
		temp = new GrowthCapableMob(40, 1, 18869);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18876);
		GROWTH_CAPABLE_MOBS.put(18874, temp);
		
		temp = new GrowthCapableMob(40, 1, 18869);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18877);
		GROWTH_CAPABLE_MOBS.put(18875, temp);
		
		temp = new GrowthCapableMob(25, 2, 18869);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18878);
		GROWTH_CAPABLE_MOBS.put(18876, temp);
		
		temp = new GrowthCapableMob(25, 2, 18869);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18879);
		GROWTH_CAPABLE_MOBS.put(18877, temp);
		
		// Cougar
		temp = new GrowthCapableMob(100, 0, 18870);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18881);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18882);
		temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18870);
		temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18870);
		temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18885);
		temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18886);
		GROWTH_CAPABLE_MOBS.put(18880, temp);
		
		temp = new GrowthCapableMob(40, 1, 18870);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18883);
		GROWTH_CAPABLE_MOBS.put(18881, temp);
		
		temp = new GrowthCapableMob(40, 1, 18870);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18884);
		GROWTH_CAPABLE_MOBS.put(18882, temp);
		
		temp = new GrowthCapableMob(25, 2, 18870);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18885);
		GROWTH_CAPABLE_MOBS.put(18883, temp);
		
		temp = new GrowthCapableMob(25, 2, 18870);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18886);
		GROWTH_CAPABLE_MOBS.put(18884, temp);
		
		// Buffalo
		temp = new GrowthCapableMob(100, 0, 18871);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18888);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18889);
		temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18871);
		temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18871);
		temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18892);
		temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18893);
		GROWTH_CAPABLE_MOBS.put(18887, temp);
		
		temp = new GrowthCapableMob(40, 1, 18871);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18890);
		GROWTH_CAPABLE_MOBS.put(18888, temp);
		
		temp = new GrowthCapableMob(40, 1, 18871);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18891);
		GROWTH_CAPABLE_MOBS.put(18889, temp);
		
		temp = new GrowthCapableMob(25, 2, 18871);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18892);
		GROWTH_CAPABLE_MOBS.put(18890, temp);
		
		temp = new GrowthCapableMob(25, 2, 18871);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18893);
		GROWTH_CAPABLE_MOBS.put(18891, temp);
		
		// Grendel
		temp = new GrowthCapableMob(100, 0, 18872);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18895);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18896);
		temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18872);
		temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18872);
		temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18899);
		temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18900);
		GROWTH_CAPABLE_MOBS.put(18894, temp);
		
		temp = new GrowthCapableMob(40, 1, 18872);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18897);
		GROWTH_CAPABLE_MOBS.put(18895, temp);
		
		temp = new GrowthCapableMob(40, 1, 18872);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18898);
		GROWTH_CAPABLE_MOBS.put(18896, temp);
		
		temp = new GrowthCapableMob(25, 2, 18872);
		temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18899);
		GROWTH_CAPABLE_MOBS.put(18897, temp);
		
		temp = new GrowthCapableMob(25, 2, 18872);
		temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18900);
		GROWTH_CAPABLE_MOBS.put(18898, temp);
		
		// Tamed beasts data
		TAMED_BEAST_DATA = new TamedBeast[]{
			// 1801103 鋭い$s1
			// 6432-1 ロアー フォーカス - 5分間、クリティカル攻撃の確率が35%向上します。
			// 6668-1 ロアー デス ウィスパー - 5分間、クリティカル攻撃の威力が35%向上します。
			new TamedBeast(1801103, getSkillHashCode(6432, 1), getSkillHashCode(6668, 1)),
			// 1801104 有能な$s1
			// 6433-1 ロアー ガイダンス - 5分間、命中率が7向上します。
			// 6670-1 ロアー ヴァンパイアリック レイジ - 5分間、敵に与えた一般近接物理ダメージの9%をHPとして回復します。
			new TamedBeast(1801104, getSkillHashCode(6433, 1), getSkillHashCode(6670, 1)),
			// 1801101 敏捷な$s1
			// 6434-1 ロアー ヘイスト - 5分間、攻撃速度が38%向上します。
			// 6667-1 ロアー ウィンド ウォーク - 5分間、移動速度が33向上します。
			new TamedBeast(1801101, getSkillHashCode(6434, 1), getSkillHashCode(6667, 1)),
			// 1801105 乱暴な$s1
			// 6671-1 ロアー バーサーカー スピリッツ - 5分間、防御力が8%、魔法抵抗力が16%、回避率4が低下して、攻撃力が8%、魔力が16%、攻撃速度が8%、魔法詠唱速度が8%、移動速度が8向上します。
			new TamedBeast(1801105, getSkillHashCode(6671, 1)),
			// 1801102 祝福の$s1
			// 6669-1 ロアー ブレス ザ ボディ - 5分間、最大HPが35%増加します。
			// 6672-1 ロアー ブレス シールド - 5分間、シールド防御率が30%向上します。
			new TamedBeast(1801102, getSkillHashCode(6669, 1), getSkillHashCode(6672, 1)),
			// 1801100 バランスの$s1
			// 6431-1 ロアー マイト - 5分間、攻撃力が19%向上します。
			// 6666-1 ロアー シールド - 5分間、防御力が18%向上します。
			new TamedBeast(1801100, getSkillHashCode(6431, 1), getSkillHashCode(6666, 1)),
		};
	}
	
	private void spawnNext(L2Npc npc, L2PcInstance player, int nextNpcId, int food)
	{
		// remove the feedinfo of the mob that got despawned, if any
	//	if (_FeedInfo.containsKey(npc.getObjectId()))
	//	{
	//		if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
	//		{
				_FeedInfo.remove(npc.getObjectId());
	//		}
	//	}
		// despawn the old mob
		// TODO: same code? FIXED?
		/*
		 * if (_GrowthCapableMobs.get(npc.getId()).getGrowthLevel() == 0) { npc.deleteMe(); } else {
		 */
		if (npc.isMoving()) npc.stopMove(null);	//[JOJO]
		npc.deleteMe();
		// }
		
		// if this is finally a trained mob, then despawn any other trained mobs that the
		// player might have and initialize the Tamed Beast.
		if (Util.contains(TAMED_BEASTS, nextNpcId))
		{
			L2NpcTemplate template = NpcTable.getInstance().getTemplate(nextNpcId);
			L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(IdFactory.getInstance().getNextId(), template, player, food, npc.getX(), npc.getY(), npc.getZ(), true);
			
			TamedBeast beast = TAMED_BEAST_DATA[getRandom(TAMED_BEAST_DATA.length)];
			nextNpc.nameId = beast.getNameId();
			nextNpc.nameParam = TAMED_BEAST_NAMES.get(nextNpcId, nextNpc.getName());
			nextNpc.broadcastPacket(new AbstractNpcInfo.NpcInfo(nextNpc, player));
			nextNpc.setRunning();
			
			nextNpc.removeBuffSkills();
			for (int sh : beast.getSkills())
			{
				nextNpc.addSkill(getSkill(sh));
			}
			nextNpc.startOwnerBuffs();
			
			Q00020_BringUpWithLove.checkJewelOfInnocence(player);
			autoChat(nextNpc, TAMED_TEXT, player, 1000);	//+[JOJO]
		}
		else
		{
			// if not trained, the newly spawned mob will automatically be agro against its feeder
			// (what happened to "never bite the hand that feeds you" anyway?!)
			L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
			
			// register the player in the feedinfo for the mob that just spawned
			_FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
			nextNpc.setRunning();
			nextNpc.addDamageHate(player, 0, 99999);
			nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
			
			player.setTarget(nextNpc);
			
			GrowthCapableMob growthCapableMob;
			if ((growthCapableMob = GROWTH_CAPABLE_MOBS.get(npc.getId())) != null)
				autoChat(nextNpc, GROW_TEXT[growthCapableMob.getGrowthLevel()], 1000);	//+[JOJO]
		}
	}
	
	@Override
	public String onSkillSee(L2Npc npc, L2PcInstance caster, L2Skill skill, L2Object[] targets, boolean isSummon)
	{
		// this behavior is only run when the target of skill is the passed npc (chest)
		// i.e. when the player is attempting to open the chest using a skill
		if (!Util.contains(targets, npc))
		{
			return super.onSkillSee(npc, caster, skill, targets, isSummon);
		}
		// gather some values on local variables
		int npcId = npc.getId();
		int skillId = skill.getId();
		// check if the npc and skills used are valid for this script. Exit if invalid.
		if (!Util.contains(FEEDABLE_BEASTS, npcId) || ((skillId != SKILL_GOLDEN_SPICE) && (skillId != SKILL_CRYSTAL_SPICE) && (skillId != SKILL_BLESSED_GOLDEN_SPICE) && (skillId != SKILL_BLESSED_CRYSTAL_SPICE) && (skillId != SKILL_SGRADE_GOLDEN_SPICE) && (skillId != SKILL_SGRADE_CRYSTAL_SPICE)))
		{
			return super.onSkillSee(npc, caster, skill, targets, isSummon);
		}
		
		// first gather some values on local variables
		int objectId = npc.getObjectId();
		int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
		if (GROWTH_CAPABLE_MOBS.containsKey(npcId))
		{
			growthLevel = GROWTH_CAPABLE_MOBS.get(npcId).getGrowthLevel();
		}
		
		// prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
		// If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
		if ((growthLevel == 0) && _FeedInfo.containsKey(objectId))
		{
			return super.onSkillSee(npc, caster, skill, targets, isSummon);
		}
		
		_FeedInfo.put(objectId, caster.getObjectId());
		
		// display the social action of the beast eating the food.
		npc.broadcastSocialAction(2);
		
		int food = 0;
		if ((skillId == SKILL_GOLDEN_SPICE) || (skillId == SKILL_BLESSED_GOLDEN_SPICE))
		{
			food = GOLDEN_SPICE;
		}
		else if ((skillId == SKILL_CRYSTAL_SPICE) || (skillId == SKILL_BLESSED_CRYSTAL_SPICE))
		{
			food = CRYSTAL_SPICE;
		}
		
		// if this pet can't grow, it's all done.
		if (GROWTH_CAPABLE_MOBS.containsKey(npcId))
		{
			// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
			int newNpcId = GROWTH_CAPABLE_MOBS.get(npcId).getLeveledNpcId(skillId);
			if (newNpcId == -1)
			{
				if (growthLevel == 0)
				{
					_FeedInfo.remove(objectId);
					npc.setRunning();
					((L2Attackable) npc).addDamageHate(caster, 0, 1);
					npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, caster);
				}
				autoChat(npc, HATE_TEXT, skill.getHitTime());	//+[JOJO]
				return super.onSkillSee(npc, caster, skill, targets, isSummon);
			}
			else if ((growthLevel > 0) && (_FeedInfo.get(objectId) != caster.getObjectId()))
			{
				// check if this is the same player as the one who raised it from growth 0.
				// if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
				autoChat(npc, HATE_TEXT, skill.getHitTime());	//+[JOJO]
				return super.onSkillSee(npc, caster, skill, targets, isSummon);
			}
			spawnNext(npc, caster, newNpcId, food);
		}
		else
		{
			caster.sendMessage("The beast spit out the feed instead of eating it.");
			((L2Attackable) npc).dropItem(caster, food, 1);
		}
		return super.onSkillSee(npc, caster, skill, targets, isSummon);
	}
	
	@Override
	public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
	{
		// remove the feedinfo of the mob that got killed, if any
	//	if (_FeedInfo.containsKey(npc.getObjectId()))
	//	{
			_FeedInfo.remove(npc.getObjectId());
	//	}
		return super.onKill(npc, killer, isSummon);
	}
	
	// all mobs that grow by eating
	private static class GrowthCapableMob
	{
		private final int _chance;
		private final int _growthLevel;
		private final int _tameNpcId;
		private final SortedIntIntArrayMap _skillSuccessNpcIdList = new SortedIntIntArrayMap();
		
		public GrowthCapableMob(int chance, int growthLevel, int tameNpcId)
		{
			_chance = chance;
			_growthLevel = growthLevel;
			_tameNpcId = tameNpcId;
		}
		
		public void addNpcIdForSkillId(int skillId, int npcId)
		{
			_skillSuccessNpcIdList.put(skillId, npcId);
		}
		
		public int getGrowthLevel()
		{
			return _growthLevel;
		}
		
		public int getLeveledNpcId(int skillId)
		{
			if (!_skillSuccessNpcIdList.containsKey(skillId))
			{
				return -1;
			}
			else if ((skillId == SKILL_BLESSED_GOLDEN_SPICE) || (skillId == SKILL_BLESSED_CRYSTAL_SPICE) || (skillId == SKILL_SGRADE_GOLDEN_SPICE) || (skillId == SKILL_SGRADE_CRYSTAL_SPICE))
			{
				if (getRandom(100) < SPECIAL_SPICE_CHANCES[0])
				{
					if (getRandom(100) < SPECIAL_SPICE_CHANCES[1])
					{
						return _skillSuccessNpcIdList.get(skillId);
					}
					else if ((skillId == SKILL_BLESSED_GOLDEN_SPICE) || (skillId == SKILL_SGRADE_GOLDEN_SPICE))
					{
						return _skillSuccessNpcIdList.get(SKILL_GOLDEN_SPICE);
					}
					else
					{
						return _skillSuccessNpcIdList.get(SKILL_CRYSTAL_SPICE);
					}
				}
				return -1;
			}
			else if ((_growthLevel == 2) && (getRandom(100) < TAME_CHANCE))
			{
				return _tameNpcId;
			}
			else if (getRandom(100) < _chance)
			{
				return _skillSuccessNpcIdList.get(skillId);
			}
			else
			{
				return -1;
			}
		}
	}
	
	private static class TamedBeast
	{
		private final int nameNpcStringId;
		private final int[] sh;
		
		public TamedBeast(int nameNpcStringId, int... skillHashCode)
		{
			this.nameNpcStringId = nameNpcStringId;
			this.sh = skillHashCode;
		}
		
		public int getNameId()
		{
			return nameNpcStringId;
		}
		
		public int[] getSkills()
		{
			return sh;
		}
	}
	
	public static void main(String[] args)
	{
		new BeastFarm();
	}
}
