/*
 * This program 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.
 * 
 * This program 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.individual;

import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;

import javolution.util.FastList;
import net.sf.l2j.Config;
import net.sf.l2j.gameserver.ThreadPoolManager;
import net.sf.l2j.gameserver.ai.CtrlIntention;
import net.sf.l2j.gameserver.datatables.SkillTable;
import net.sf.l2j.gameserver.instancemanager.GrandBossManager;
import net.sf.l2j.gameserver.model.L2CharPosition;
import net.sf.l2j.gameserver.model.L2Character;
import net.sf.l2j.gameserver.model.L2Effect;
import net.sf.l2j.gameserver.model.L2Object;
import net.sf.l2j.gameserver.model.L2Skill;
import net.sf.l2j.gameserver.model.L2Summon;
import net.sf.l2j.gameserver.model.actor.instance.L2DecoyInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2GrandBossInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PlayableInstance;
import net.sf.l2j.gameserver.model.quest.QuestTimer;
import net.sf.l2j.gameserver.model.zone.type.L2BossZone;
import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
import net.sf.l2j.gameserver.network.serverpackets.Earthquake;
import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
import net.sf.l2j.gameserver.network.serverpackets.SpecialCamera;
import net.sf.l2j.gameserver.templates.StatsSet;
import net.sf.l2j.gameserver.util.Broadcast;
import net.sf.l2j.gameserver.util.Util;
import net.sf.l2j.util.Rnd;
import ai.group_template.L2AttackableAIScript;

/**
 * Valakas AI
 * @author Kerberos
 */
public class Valakas extends L2AttackableAIScript
{
	private int i_ai0 = 0;
	private int i_ai1 = 0;
	private int i_ai2 = 0;
	private int i_ai3 = 0;
	private int i_ai4 = 0;
	private int i_quest0 = 0;
	private long i_quest1 = 0; // time to tracking valakas when was last time attacked
	private int i_quest2 = 0; // hate value for 1st player
	private int i_quest3 = 0; // hate value for 2nd player
	private int i_quest4 = 0; // hate value for 3rd player
	private L2Character c_quest2 = null; // 1st most hated target
	private L2Character c_quest3 = null; // 2nd most hated target
	private L2Character c_quest4 = null; // 3rd most hated target

	private static final int VALAKAS = 29028;

	//Valakas Status Tracking :
	private static final byte DORMANT = 0;     	//Valakas is spawned and no one has entered yet. Entry is unlocked
	private static final byte WAITING = 1;     	//Valakas is spawend and someone has entered, triggering a 30 minute window for additional people to enter
	                							//before he unleashes his attack. Entry is unlocked
	private static final byte FIGHTING = 2;    	//Valakas is engaged in battle, annihilating his foes. Entry is locked
	private static final byte DEAD = 3;        	//Valakas has been killed. Entry is locked
	
	private static L2BossZone _Zone;
	
	// Boss: Valakas
	public Valakas(int id,String name,String descr)
	{
        super(id,name,descr);
        int[] mob = {VALAKAS};
        this.registerMobs(mob);
        i_ai0 = 0;
        i_ai1 = 0;
        i_ai2 = 0;
        i_ai3 = 0;
        i_ai4 = 0;
        i_quest0 = 0;
        i_quest1 = System.currentTimeMillis();
        _Zone = GrandBossManager.getInstance().getZone(212852,-114842,-1632);
        StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
        int status = GrandBossManager.getInstance().getBossStatus(VALAKAS);
        if (info.getInteger("loc_x") == 0 && info.getInteger("loc_y") == 0) status = DEAD;	//[JOJO]
        if (status == DEAD)
        {
            // load the unlock date and time for valakas from DB
            long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
            // if valakas is locked until a certain time, mark it so and start the unlock timer
            // the unlock time has not yet expired.  Mark valakas as currently locked.  Setup a timer
            // to fire at the correct time (calculate the time between now and the unlock time,
            // setup a timer to fire after that many msec)
            if (temp > 0)
            {
                this.startQuestTimer("valakas_unlock", temp, null, null);
                _log.info("AI script : Next spawn date of Valakas is " + new SimpleDateFormat("yyyy/MM/dd HH:mm").format(new Date(info.getLong("respawn_time"))) + ".");
            }
            else
            {
                // the time has already expired while the server was offline. Immediately spawn valakas in his cave.
                // also, the status needs to be changed to DORMANT
                L2GrandBossInstance valakas = (L2GrandBossInstance) addSpawn(VALAKAS,-105200,-253104,-15264,0,false,0);
                GrandBossManager.getInstance().setBossStatus(VALAKAS,DORMANT);
                GrandBossManager.getInstance().addBoss(valakas);
                final L2NpcInstance _valakas = valakas;
                ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
    				public void run()
    				{
    					try
    		            {
    						_valakas.setIsInvul(true);
    		                _valakas.setRunning();
    		            }
    		            catch (Throwable e)
    		            {
    		            }
    				}
    			},100L);
                startQuestTimer("1003", 60000, valakas, null, true);
            }
        }
        else
        {
            int loc_x = info.getInteger("loc_x");
            int loc_y = info.getInteger("loc_y");
            int loc_z = info.getInteger("loc_z") - 20;
            int heading = info.getInteger("heading");
            final int hp = info.getInteger("currentHP");
            final int mp = info.getInteger("currentMP");
            L2GrandBossInstance valakas = (L2GrandBossInstance) addSpawn(VALAKAS,loc_x,loc_y,loc_z,heading,false,0);
            GrandBossManager.getInstance().addBoss(valakas);
            final L2NpcInstance _valakas = valakas;
            ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
				public void run()
				{
					try
		            {
			            _valakas.setCurrentHpMp(hp,mp);
						_valakas.setIsInvul(true);
		                _valakas.setRunning();
		            }
		            catch (Throwable e)
		            {
		            }
				}
			},100L);

            startQuestTimer("1003", 60000, valakas, null, true);
            if (status == WAITING)
            {
                // Start timer to lock entry after 30 minutes
                startQuestTimer("1001_3",Config.FWV_APPTIMEOFVALAKAS, valakas, null);	//[JOJO]
            }
            else if (status == FIGHTING)
            {
                // Start repeating timer to check for inactivity
                startQuestTimer("1002"/*"valakas_despawn"*/,60000, valakas, null, true);	//[JOJO]
                valakas.setIsInvul(false);
            }
        }
	}

	public String onAdvEvent (String event, L2NpcInstance npc, L2PcInstance player)
	{
        if (npc != null)
        {
			if (event.equals("1001_3")) // <- scripts/teleports/6000_GrandBossTeleporters/__init__.py
			{
				this.startQuestTimer("1001_2",60000, npc, null);
				this.screenMessage("3分前");
				this.announce("ヴァラカスは噴火口の中央から登場します。");
/////////////////////////////////////////////////////////////////
//DEBUG:ヴァラカス散歩範囲マーカー
//addSpawn(31112, 211080,-112822,-1662, 0,false,300000);
//addSpawn(31112, 212037,-112822,-1662, 0,false,300000);
//addSpawn(31112, 212994,-112822,-1662, 0,false,300000);
//addSpawn(31112, 213952,-112822,-1662, 0,false,300000);
//addSpawn(31112, 214909,-112822,-1662, 0,false,300000);
//addSpawn(31112, 214909,-113577,-1662, 0,false,300000);
//addSpawn(31112, 214909,-114331,-1662, 0,false,300000);
//addSpawn(31112, 214909,-115086,-1662, 0,false,300000);
//addSpawn(31112, 214909,-115841,-1662, 0,false,300000);
//addSpawn(31112, 213952,-115841,-1662, 0,false,300000);
//addSpawn(31112, 212994,-115841,-1662, 0,false,300000);
//addSpawn(31112, 212037,-115841,-1662, 0,false,300000);
//addSpawn(31112, 211080,-115841,-1662, 0,false,300000);
//addSpawn(31112, 211080,-115086,-1662, 0,false,300000);
//addSpawn(31112, 211080,-114331,-1662, 0,false,300000);
//addSpawn(31112, 211080,-113577,-1662, 0,false,300000);
/////////////////////////////////////////////////////////////////
//DEBUG:立入禁止区域マーカー
//addSpawn(13006, 212852, -114842, -1632, 0, false, 300000);
//for (int i = 0; i < 20; i++) {
//	int x = (int)(1500.0 * Math.cos(i * 0.3141592654));
//	int y = (int)(1500.0 * Math.sin(i * 0.3141592654));
//	addSpawn(13006, 212852+x, -114842+y, -1632, 0, false, 300000);
//}
/////////////////////////////////////////////////////////////////
			}
			else if (event == "1001_2")
			{
				this.startQuestTimer("1001_1",60000, npc, null);
				this.screenMessage("2分前");
			}
			else if (event == "1001_1")
			{
				this.startQuestTimer("1001_1:15",45000, npc, null);
				this.screenMessage("1分前");
			}
			else if (event == "1001_1:15")
			{
				this.startQuestTimer("1001_1:8",7000, npc, null);
				_Zone.broadcastPacket(new Earthquake(212852,-114842,-1632,40,15));
			}
			else if (event == "1001_1:8")
			{
				this.startQuestTimer("1001",8000, npc, null);
				for (L2Character cha : _Zone.getCharactersInside().values())
				{
					if (! (cha instanceof L2PlayableInstance)) continue;
					int dx = cha.getX() -  212852;
					int dy = cha.getY() - -114842;
					//UPDATE npc SET aggro = 800
					//assert(npc.getAggroRange()  <= 800);
					double aa = 1500.0 / Math.sqrt(dx * dx + dy * dy);
					if (aa > 1.0) cha.teleToLocation(212852 + (int)(dx * aa), -114842 + (int)(dy * aa), cha.getZ());
				}
			}
            else if (event == "1001")
            {
                _Zone.updateKnownList(npc);
                npc.setIsInvul(true);
                ((L2GrandBossInstance)npc).setIsInSocialAction(true);
                npc.teleToLocation(212852,-114842,-1632);
            	// delete me once animations available
            	GrandBossManager.getInstance().setBossStatus(VALAKAS,FIGHTING);
            	//
                i_quest1 = System.currentTimeMillis();
//                final L2NpcInstance _valakas = npc;
//                ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() {
//    				public void run()
//    				{
//    					try
//    		            {
//    						broadcastSpawn(_valakas);
//    		            }
//    		            catch (Throwable e)
//    		            {
//    		            }
//    				}
//    			},1L);
//                startQuestTimer("1004",2000, npc, null);
                startQuestTimer("1004", 500, npc, null);
                this.screenMessage("覚醒");
            }
            else if (event == "1002") { if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) {	//+[JOJO]
//            	int lvl = 0;
//    			int sk_4691 = 0;
//    			L2Effect[] effects = npc.getAllEffects();
//    			if (effects != null && effects.length != 0)	//+[JOJO]
//    			{
//    				for (L2Effect e : effects)
//    				{
//    					if (e.getSkill().getId() == 4629)
//    					{
//    						sk_4691 = 1;
//    						lvl = e.getSkill().getLevel();
//    						break;
//    					}
//    				}
//    	        }
            	long temp = System.currentTimeMillis() - i_quest1;
            	if (temp > 900000)
            	{
            			cancelQuestTimer("1002", npc, null);
            			npc.getAI().setIntention(AI_INTENTION_IDLE);
            			npc.teleToLocation(-105200,-253104,-15264);
            			GrandBossManager.getInstance().setBossStatus(VALAKAS,DORMANT);
            			npc.setCurrentHpMp(npc.getMaxHp(),npc.getMaxMp());
            			_Zone.updateKnownList(npc);
            			_Zone.oustAllPlayers();
            			i_quest2 = 0;
            			i_quest3 = 0;
            			i_quest4 = 0;
                }
//            	else if (npc.getCurrentHp() > ( ( npc.getMaxHp() * 1 ) / 4 ) )
//            	{
//            		if (sk_4691 == 0 ||(sk_4691 == 1 && lvl != 4))
//            		{
//            			npc.setTarget(npc);
//            			npc.doCast(SkillTable.getInstance().getInfo(4691,4));
//            		}
//            	}
//            	else if (npc.getCurrentHp() > ( ( npc.getMaxHp() * 2 ) / 4 ) )
//            	{
//            		if (sk_4691 == 0 ||(sk_4691 == 1 && lvl != 3))
//            		{
//            			npc.setTarget(npc);
//            			npc.doCast(SkillTable.getInstance().getInfo(4691,3));
//            		}
//            	}
//            	else if (npc.getCurrentHp() > ( ( npc.getMaxHp() * 3 ) / 4 ) )
//            	{
//            		if (sk_4691 == 0 ||(sk_4691 == 1 && lvl != 2))
//            		{
//            			npc.setTarget(npc);
//            			npc.doCast(SkillTable.getInstance().getInfo(4691,2));
//            		}
//            	}
//            	else if (sk_4691 == 0 ||(sk_4691 == 1 && lvl != 1))
//            	{
//            		npc.setTarget(npc);
//            		npc.doCast(SkillTable.getInstance().getInfo(4691,1));
//            	}
				else if (Config.FWV_MOVEATRANDOM && temp >= 60000 && ! npc.isAttackingNow())	//[JOJO] move at random.
				{
					if (Rnd.get(5) == 0) {
						_Zone.broadcastPacket(new SocialAction(npc.getObjectId(), Rnd.get(1,4)));
					} else {
						_Zone.updateKnownList(npc);
						L2CharPosition pos = new L2CharPosition(Rnd.get(211080,214909), Rnd.get(-115841,-112822), -1662, 0);
						npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, pos);
					}
				}
            }}
            else if (event == "1003" && npc != null)
            {
            	if (!npc.isInvul())
            		getRandomSkill(npc);
            	else
            		npc.getAI().setIntention(AI_INTENTION_IDLE);
            }
            else if (event == "1004")
            {
                startQuestTimer("1102",/*TODO:fine-tuning*/1000, npc, null);//1
                _Zone.broadcastPacket(new PlaySound(1, "BS03_A", 1, npc.getObjectId(), 212852,-114842,-1632));
            }
            else if (event == "1102")
            {
                startQuestTimer("1103",1500, npc, null);//2
                _Zone.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 1800, 180, -1, 1500, 15000));//2
            }
            else if (event == "1103")
            {
                startQuestTimer("1104",3300, npc, null);//3
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 1300, 180, -5, 3000, 15000));//3
            }
            else if (event == "1104")
            {
                startQuestTimer("1105",1300, npc, null);//4
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 500, 180, -8, 600, 15000));//4
            }
            else if (event == "1105")
            {
            	startQuestTimer("1106",1600, npc, null);//5
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 1200, 180, -5, 300, 15000));//5
            }
            else if (event == "1106")
            {
                startQuestTimer("1107",200, npc, null);//6
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 2800, 250, 70, 0, 15000));//6
            }
            else if (event == "1107")
            {
                startQuestTimer("1108",5700, npc, null);//7
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 2600, 30, 60, 3400, 15000));//7
            }
            else if (event == "1108")
            {
                startQuestTimer("1109",1400, npc, null);//8
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 700, 150, -65, 0, 15000));//8
            }
            else if (event == "1109")
            {
                startQuestTimer("110A",6700, npc, null);//9
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 1200, 150, -55, 2900, 15000));//9
            }
            else if (event == "110A")
            {
                startQuestTimer("110B",3700, npc, null);//10
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 750, 170, -10, 1700, 5700));//10
            }
            else if (event == "110B")
            {
                startQuestTimer("1110",2000, npc, null);//11
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(), 840, 170, -5, 1200, 2000));//11
            }
            else if (event == "1110")
            {
            	// uncoment me once animations available
            	//GrandBossManager.getInstance().setBossStatus(VALAKAS,FIGHTING);	//TODO:要確認
            	startQuestTimer("1002",60000, npc, null, true);
            	npc.setIsInvul(false);
            	((L2GrandBossInstance)npc).setIsInSocialAction(false);
            	getRandomSkill(npc);
            	Broadcast.announceToOnlinePlayers("火竜ヴァラカスが登場しました。");
            	this.announce("ヴァラカスを15分間攻撃しないでいると、巣に戻ってしまいます。");
            }
            else if (event == "1111")
            {
                startQuestTimer("1112",3500, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),210,-5,3000,15000,10000));
            }
            else if (event == "1112")
            {
                startQuestTimer("1113",4500, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),200,-8,3000,15000,10000));
            }
            else if (event == "1113")
            {
                startQuestTimer("1114",500, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),190,0,500,15000,10000));
            }
            else if (event == "1114")
            {
                startQuestTimer("1115",4600, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),120,0,2500,15000,10000));
            }
            else if (event == "1115")
            {
                startQuestTimer("1116",750, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),20,0,700,15000,10000));
            }
            else if (event == "1116")
            {
                startQuestTimer("1117",2500, npc, null);
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),10,0,1000,15000,10000));
            }
            else if (event == "1117")
            {
                _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),10,0,300,15000,250));
                addSpawn(31759,212852,-114842,-1632,0,false,900000);
                int radius = 1500;
                for (int i=0; i < /*JOJO*/19; i++)
                {
                    int x = (int) (radius*Math.cos(i*.331)); //.331~2pi/19
                    int y = (int) (radius*Math.sin(i*.331));
                    addSpawn(31759,212852+x,-114842+y,-1632,0,false,900000);
                }
//              cancelQuestTimer("1002", npc, null);
                startQuestTimer("remove_players",900000, null, null);
                // delete me once animations available
                GrandBossManager.getInstance().setBossStatus(VALAKAS,DEAD);
                //
                this.screenMessage("討伐成功");
                this.announce("15分以内にヴァラカスの棲処から退去してください。");
            }
        }
        else
        {
            if (event == "valakas_unlock")
            {
                L2GrandBossInstance valakas = (L2GrandBossInstance) addSpawn(VALAKAS,-105200,-253104,-15264,32768,false,0);
                GrandBossManager.getInstance().addBoss(valakas);
                GrandBossManager.getInstance().setBossStatus(VALAKAS,DORMANT);
            }
            else if (event == "remove_players")
            {
                _Zone.oustAllPlayers();
            }
        }
        return super.onAdvEvent(event, npc, player);
	}

	public String onAttack (L2NpcInstance npc, L2PcInstance attacker, int damage, boolean isPet)
	{
		if (npc.isInvul())
		{
			return null;
		}
		i_quest1 = System.currentTimeMillis();
//[JOJO] Note: ↓ヴァラカスが死ぬとＰＣはゴダード城の村に強制送還される。
//      if (GrandBossManager.getInstance().getBossStatus(VALAKAS) != FIGHTING)
//      {
//      	attacker.teleToLocation(150037,-57255,-2976);	//-[JOJO]
//      }
    	if (attacker.getMountType() == 1)
    	{
			int sk_4258 = 0;
			L2Effect[] effects = attacker.getAllEffects();
			if (effects.length != 0 || effects != null)
			{
				for (L2Effect e : effects)
				{
					if (e.getSkill().getId() == 4258)
					{
						sk_4258 = 1;
					}
				}
	        }
			if (sk_4258 == 0)
			{
				npc.setTarget(attacker);
				npc.doCast(SkillTable.getInstance().getInfo(4258,1));
			}
    	}
		if( attacker.getZ() < ( npc.getZ() + 200 ) )
		{
			if( i_ai2 == 0 )
			{
				i_ai1 = ( i_ai1 + damage );
			}
			if( i_quest0 == 0 )
			{
				i_ai4 = ( i_ai4 + damage );
			}
			if( i_quest0 == 0 )
			{
				i_ai3 = ( i_ai3 + damage );
			}
			else if(i_ai2 == 0 )
			{
				i_ai0 = ( i_ai0 + damage );
			}
			if( i_quest0 == 0 )
			{
				if((((i_ai4 / npc.getMaxHp()) * 100)) > 1)
				{
					if( i_ai3 > ( i_ai4 - i_ai3 ) )
					{
						i_ai3 = 0;
						i_ai4 = 0;
						npc.setTarget(npc);
						npc.doCast(SkillTable.getInstance().getInfo(4687,1));
						i_quest0 = 1;
					}
				}
			}

		}
		L2Skill skill = null; // TODO: attack handler require skill
		int i1 = 0;
		if (skill == null)
		{
			if (attacker == c_quest2)
			{
				if (((damage * 1000) + 1000) > i_quest2)
				{
					i_quest2 = ((damage * 1000) + Rnd.get(3000));
				}
			}
			else if (attacker == c_quest3)
			{
				if ((( damage * 1000) + 1000) > i_quest3)
				{
					i_quest3 = ((damage * 1000) + Rnd.get(3000));
				}
			}
			else if (attacker == c_quest4)
			{
				if ((( damage * 1000) + 1000) > i_quest4)
				{
					i_quest4 = ((damage * 1000) + Rnd.get(3000));
				}
			}
			else if( i_quest2 > i_quest3 )
			{
				i1 = 3;
			}
			else if( i_quest2 == i_quest3 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 2;
				}
				else
				{
					i1 = 3;
				}
			}
			else if( i_quest2 < i_quest3 )
			{
				i1 = 2;
			}
			if( i1 == 2 )
			{
				if( i_quest2 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest2 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 2;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest2 < i_quest4 )
				{
					i1 = 2;
				}
			}
			else if( i1 == 3 )
			{
				if( i_quest3 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest3 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 3;
					}
					else
					{
						i1 = 4;
					}
				}
				else if(i_quest3 < i_quest4 )
				{
					i1 = 3;
				}
			}
			if (i1 == 2)
			{
				i_quest2 = (damage * 1000) + Rnd.get(3000);
				c_quest2 = attacker;
			}
			else if (i1 == 3)
			{
				i_quest3 = (damage * 1000) + Rnd.get(3000);
				c_quest3 = attacker;
			}
			else if (i1 == 4)
			{
				i_quest4 = (damage * 1000) + Rnd.get(3000);
				c_quest4 = attacker;
			}
		}
		else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 1 ) / 4 ))
		{
			if( attacker == c_quest2 )
			{
				if( ( ( ( damage / 30 ) * 1000 ) + 1000 ) > i_quest2 )
				{
					i_quest2 = ( ( ( damage / 30 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( attacker == c_quest3 )
			{
				if( ( ( ( damage / 30 ) * 1000 ) + 1000 ) > i_quest3 )
				{
					i_quest3 = ( ( ( damage / 30 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( attacker == c_quest4 )
			{
				if( ( ( ( damage / 30 ) * 1000 ) + 1000 ) > i_quest4 )
				{
					i_quest4 = ( ( ( damage / 30 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( i_quest2 > i_quest3 )
			{
				i1 = 3;
			}
			else if( i_quest2 == i_quest3 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 2;
				}
				else
				{
					i1 = 3;
				}
			}
			else if( i_quest2 < i_quest3 )
			{
				i1 = 2;
			}
			if( i1 == 2 )
			{
				if( i_quest2 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest2 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 2;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest2 < i_quest4 )
				{
					i1 = 2;
				}
			}
			else if( i1 == 3 )
			{
				if( i_quest3 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest3 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 3;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest3 < i_quest4 )
				{
					i1 = 3;
				}
			}
			if (i1 == 2)
			{
					i_quest2 = ( ( ( damage / 30 ) * 1000 ) + Rnd.get(3000) );
					c_quest2 = attacker;
			}
			else if (i1 == 3)
			{
					i_quest3 = ( ( ( damage / 30 ) * 1000 ) + Rnd.get(3000) );
					c_quest3 = attacker;
			}
			else if (i1 == 4)
			{
					i_quest4 = ( ( ( damage / 30 ) * 1000 ) + Rnd.get(3000) );
					c_quest4 = attacker;
			}
		}
		else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 2 ) / 4 ))
		{
			if( attacker == c_quest2 )
			{
				if( ( ( ( damage / 50 ) * 1000 ) + 1000 ) > i_quest2 )
				{
					i_quest2 = ( ( ( damage / 50 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( attacker == c_quest3 )
			{
				if( ( ( ( damage / 50 ) * 1000 ) + 1000 ) > i_quest3 )
				{
					i_quest3 = ( ( ( damage / 50 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( attacker == c_quest4 )
			{
				if( ( ( ( damage / 50 ) * 1000 ) + 1000 ) > i_quest4 )
				{
					i_quest4 = ( ( ( damage / 50 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( i_quest2 > i_quest3 )
			{
				i1 = 3;
			}
			else if( i_quest2 == i_quest3 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 2;
				}
				else
				{
					i1 = 3;
				}
			}
			else if( i_quest2 < i_quest3 )
			{
				i1 = 2;
			}
			if( i1 == 2 )
			{
				if( i_quest2 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest2 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 2;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest2 < i_quest4 )
				{
					i1 = 2;
				}
			}
			else if( i1 == 3 )
			{
				if( i_quest3 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest3 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 3;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest3 < i_quest4 )
				{
					i1 = 3;
				}
			}
			if (i1 == 2)
			{
					i_quest2 = ( ( ( damage / 50 ) * 1000 ) + Rnd.get(3000) );
					c_quest2 = attacker;
			}
			else if (i1 == 3)
			{
					i_quest3 = ( ( ( damage / 50 ) * 1000 ) + Rnd.get(3000) );
					c_quest3 = attacker;
			}
			else if (i1 == 4)
			{
					i_quest4 = ( ( ( damage / 50 ) * 1000 ) + Rnd.get(3000) );
					c_quest4 = attacker;
			}
		}
		else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 3 ) / 4 ))
		{
			if( attacker == c_quest2 )
			{
				if( ( ( ( damage / 100 ) * 1000 ) + 1000 ) > i_quest2 )
				{
					i_quest2 = ( ( ( damage / 100 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( attacker == c_quest3 )
			{
				if( ( ( ( damage / 100 ) * 1000 ) + 1000 ) > i_quest3 )
				{
					i_quest3 = ( ( ( damage / 100 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( attacker == c_quest4 )
			{
				if( ( ( ( damage / 100 ) * 1000 ) + 1000 ) > i_quest4 )
				{
					i_quest4 = ( ( ( damage / 100 ) * 1000 ) + Rnd.get(3000) );
				}
			}
			else if( i_quest2 > i_quest3 )
			{
				i1 = 3;
			}
			else if( i_quest2 == i_quest3 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 2;
				}
				else
				{
					i1 = 3;
				}
			}
			else if( i_quest2 < i_quest3 )
			{
				i1 = 2;
			}
			if( i1 == 2 )
			{
				if( i_quest2 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest2 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 2;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest2 < i_quest4 )
				{
					i1 = 2;
				}
			}
			else if( i1 == 3 )
			{
				if( i_quest3 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest3 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 3;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest3 < i_quest4 )
				{
					i1 = 3;
				}
				if (i1 == 2)
				{
						i_quest2 = ( ( ( damage / 100 ) * 1000 ) + Rnd.get(3000) );
						c_quest2 = attacker;
				}
				else if (i1 == 3)
				{
						i_quest3 = ( ( ( damage / 100 ) * 1000 ) + Rnd.get(3000) );
						c_quest3 = attacker;
				}
				else if (i1 == 4)
				{
						i_quest4 = ( ( ( damage / 100 ) * 1000 ) + Rnd.get(3000) );
						c_quest4 = attacker;
				}
			}
		}
		else if( attacker == c_quest2 )
		{
			if( ( ( ( damage / 150 ) * 1000 ) + 1000 ) > i_quest2 )
			{
				i_quest2 = ( ( ( damage / 150 ) * 1000 ) + Rnd.get(3000) );
			}
		}
		else if( attacker == c_quest3 )
		{
			if( ( ( ( damage / 150 ) * 1000 ) + 1000 ) > i_quest3 )
			{
				i_quest3 = ( ( ( damage / 150 ) * 1000 ) + Rnd.get(3000) );
			}
		}
		else if( attacker == c_quest4 )
		{
			if( ( ( ( damage / 150 ) * 1000 ) + 1000 ) > i_quest4 )
			{
				i_quest4 = ( ( ( damage / 150 ) * 1000 ) + Rnd.get(3000) );
			}
		}
		else if( i_quest2 > i_quest3 )
		{
			i1 = 3;
		}
		else if( i_quest2 == i_quest3 )
		{
			if( Rnd.get(100) < 50 )
			{
				i1 = 2;
			}
			else
			{
				i1 = 3;
			}
		}
		else if( i_quest2 < i_quest3 )
		{
			i1 = 2;
		}
		if( i1 == 2 )
		{
			if( i_quest2 > i_quest4 )
			{
				i1 = 4;
			}
			else if( i_quest2 == i_quest4 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 2;
				}
				else
				{
					i1 = 4;
				}
			}
			else if( i_quest2 < i_quest4 )
			{
				i1 = 2;
			}
		}
		else if( i1 == 3 )
		{
			if( i_quest3 > i_quest4 )
			{
				i1 = 4;
			}
			else if( i_quest3 == i_quest4 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 3;
				}
				else
				{
					i1 = 4;
				}
			}
			else if( i_quest3 < i_quest4 )
			{
				i1 = 3;
			}
		}
		if (i1 == 2)
		{
				i_quest2 = ( ( ( damage / 150 ) * 1000 ) + Rnd.get(3000) );
				c_quest2 = attacker;
		}
		else if (i1 == 3)
		{
				i_quest3 = ( ( ( damage / 150 ) * 1000 ) + Rnd.get(3000) );
				c_quest3 = attacker;
		}
		else if (i1 == 4)
		{
				i_quest4 = ( ( ( damage / 150 ) * 1000 ) + Rnd.get(3000) );
				c_quest4 = attacker;
		}
		getRandomSkill(npc);
		return super.onAttack(npc, attacker, damage, isPet);
	}

    public String onKill (L2NpcInstance npc, L2PcInstance killer, boolean isPet) 
    { 
        cancelQuestTimer("1002", npc, null);
    	startQuestTimer("1111",500, npc, null);
        _Zone.broadcastPacket(new SpecialCamera(npc.getObjectId(),2000,130,-1,0,10000));
        _Zone.broadcastPacket(new PlaySound(1, "B03_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
        // uncoment me once animations available 
        //GrandBossManager.getInstance().setBossStatus(VALAKAS,DEAD);
        long respawnTime = Config.FWV_FIXINTERVALOFVALAKAS + Rnd.get(Config.FWV_RANDOMINTERVALOFVALAKAS);	//[JOJO]
		long respawnDateTime = System.currentTimeMillis() + respawnTime;	//[JOJO]
        this.startQuestTimer("valakas_unlock", respawnTime, null, null);
        // also save the respawn time so that the info is maintained past reboots
        StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
        info.set("respawn_time", respawnDateTime);	//[JOJO]
        GrandBossManager.getInstance().setStatsSet(VALAKAS,info);
		Broadcast.announceToOnlinePlayers("火竜ヴァラカスが死亡しました。次の復活は "+new SimpleDateFormat("yyyy/MM/dd HH:mm").format(new Date(respawnDateTime))+" ごろです。");	//[JOJO]
        return super.onKill(npc,killer,isPet);
    }

	public void getRandomSkill(L2NpcInstance npc)
	{
		if (npc.isInvul() || npc.isCastingNow())
		{
			return;
		}
		L2Skill skill = null;
		int i0 = 0;
		int i1 = 0;
		int i2 = 0;
		L2Character c2 = null;
		if (c_quest2 == null)
			i_quest2 = 0;
		else if (!Util.checkIfInRange(5000, npc, c_quest2, true) || c_quest2.isDead())
			i_quest2 = 0;
		if (c_quest3 == null)
			i_quest3 = 0;
		else if (!Util.checkIfInRange(5000, npc, c_quest3, true) || c_quest3.isDead())
			i_quest3 = 0;	
		if (c_quest4 == null)
			i_quest4 = 0;
		else if (!Util.checkIfInRange(5000, npc, c_quest4, true) || c_quest4.isDead())
			i_quest4 = 0;
		if (i_quest2 > i_quest3)
		{
			i1 = 2;
			i2 = i_quest2;
			c2 = c_quest2;
		}
		else
		{
			i1 = 3;
			i2 = i_quest3;
			c2 = c_quest3;
		}
		if( i_quest4 > i2 )
		{
			i1 = 4;
			i2 = i_quest4;
			c2 = c_quest4;
		}
		if (i2 == 0)
			c2 = getRandomTarget(npc);
		if( i2 > 0 )
		{
			if( Rnd.get(100) < 70)
			{
				if (i1 == 2)
					i_quest2 = 500;
				else if (i1 == 3)
					i_quest3 = 500;
				else if (i1 == 4)
					i_quest4 = 500;
			}
			if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 1 ) / 4 ) )
			{
				i0 = 0;
				i1 = 0;
				if (Util.checkIfInRange(1423, npc, c2, true))
				{
					i0 = 1;
					i1 = 1;
				}
				if (c2.getZ() < (npc.getZ() + 200))
				{
					if( Rnd.get(100) < 20)
					{
						skill = SkillTable.getInstance().getInfo(4690,1);
					}
					else if( Rnd.get(100) < 15)
					{
						skill = SkillTable.getInstance().getInfo(4689,1);
					}
					else if( Rnd.get(100) < 15 && i0 == 1 && i_quest0 == 1 )
					{
						skill = SkillTable.getInstance().getInfo(4685,1);
						i_quest0 = 0;
					}
					else if( Rnd.get(100) < 10 && i1 == 1 )
					{
						skill = SkillTable.getInstance().getInfo(4688,1);
					}
					else if( Rnd.get(100) < 35)
					{
						skill = SkillTable.getInstance().getInfo(4683,1);
					}
					else
					{
						if( Rnd.get(2) == 0) // TODO: replace me with direction, to check if player standing on left or right side of valakas
							skill = SkillTable.getInstance().getInfo(4681,1); // left hand
						else
							skill = SkillTable.getInstance().getInfo(4682,1); // right hand
					}
				}
				else if( Rnd.get(100) < 20)
				{
					skill = SkillTable.getInstance().getInfo(4690,1);
				}
				else if( Rnd.get(100) < 15)
				{
					skill = SkillTable.getInstance().getInfo(4689,1);
				}
				else
				{
					skill = SkillTable.getInstance().getInfo(4684,1);
				}
			}
			else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 2 ) / 4 ) )
			{
				i0 = 0;
				i1 = 0;
				if (Util.checkIfInRange(1423, npc, c2, true))
				{
					i0 = 1;
					i1 = 1;
				}
				if (c2.getZ() < (npc.getZ() + 200))
				{
					if( Rnd.get(100) < 5 )
					{
						skill = SkillTable.getInstance().getInfo(4690,1);
					}
					else if( Rnd.get(100) < 10 )
					{
						skill = SkillTable.getInstance().getInfo(4689,1);
					}
					else if( Rnd.get(100) < 10 && i0 == 1 && i_quest0 == 1 )
					{
						skill = SkillTable.getInstance().getInfo(4685,1);
						i_quest0 = 0;
					}
					else if( Rnd.get(100) < 10 && i1 == 1 )
					{
						skill = SkillTable.getInstance().getInfo(4688,1);
					}
					else if( Rnd.get(100) < 20 )
					{
						skill = SkillTable.getInstance().getInfo(4683,1);
					}
					else
					{
						if( Rnd.get(2) == 0) // TODO: replace me with direction, to check if player standing on left or right side of valakas
							skill = SkillTable.getInstance().getInfo(4681,1); // left hand
						else
							skill = SkillTable.getInstance().getInfo(4682,1); // right hand
					}
				}
				else if( Rnd.get(100) < 5)
				{
					skill = SkillTable.getInstance().getInfo(4690,1);
				}
				else if( Rnd.get(100) < 10)
				{
					skill = SkillTable.getInstance().getInfo(4689,1);
				}
				else
				{
					skill = SkillTable.getInstance().getInfo(4684,1);
				}
			}
			else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 3 ) / 4 ) )
			{
				i0 = 0;
				i1 = 0;
				if (Util.checkIfInRange(1423, npc, c2, true))
				{
					i0 = 1;
					i1 = 1;
				}
				if (c2.getZ() < (npc.getZ() + 200))
				{
					if( Rnd.get(100) < 0 )
					{
						skill = SkillTable.getInstance().getInfo(4690,1);
					}
					else if( Rnd.get(100) < 5 )
					{
						skill = SkillTable.getInstance().getInfo(4689,1);
					}
					else if( Rnd.get(100) < 5 && i0 == 1 && i_quest0 == 1 )
					{
						skill = SkillTable.getInstance().getInfo(4685,1);
						i_quest0 = 0;
					}
					else if( Rnd.get(100) < 10 && i1 == 1 )
					{
						skill = SkillTable.getInstance().getInfo(4688,1);
					}
					else if( Rnd.get(100) < 15 )
					{
						skill = SkillTable.getInstance().getInfo(4683,1);
					}
					else
					{
						if( Rnd.get(2) == 0) // TODO: replace me with direction, to check if player standing on left or right side of valakas
							skill = SkillTable.getInstance().getInfo(4681,1); // left hand
						else
							skill = SkillTable.getInstance().getInfo(4682,1); // right hand
					}
				}
				else if( Rnd.get(100) < 0)
				{
					skill = SkillTable.getInstance().getInfo(4690,1);
				}
				else if( Rnd.get(100) < 5)
				{
					skill = SkillTable.getInstance().getInfo(4689,1);
				}
				else
				{
					skill = SkillTable.getInstance().getInfo(4684,1);
				}
			}
			else
			{
				i0 = 0;
				i1 = 0;
				if (Util.checkIfInRange(1423, npc, c2, true))
				{
					i0 = 1;
					i1 = 1;
				}
				if (c2.getZ() < (npc.getZ() + 200))
				{
					if( Rnd.get(100) < 0 )
					{
						skill = SkillTable.getInstance().getInfo(4690,1);
					}
					else if( Rnd.get(100) < 10 )
					{
						skill = SkillTable.getInstance().getInfo(4689,1);
					}
					else if( Rnd.get(100) < 5 && i0 == 1 && i_quest0 == 1 )
					{
						skill = SkillTable.getInstance().getInfo(4685,1);
						i_quest0 = 0;
					}
					else if( Rnd.get(100) < 10 && i1 == 1 )
					{
						skill = SkillTable.getInstance().getInfo(4688,1);
					}
					else if( Rnd.get(100) < 15 )
					{
						skill = SkillTable.getInstance().getInfo(4683,1);
					}
					else
					{
						if( Rnd.get(2) == 0) // TODO: replace me with direction, to check if player standing on left or right side of valakas
							skill = SkillTable.getInstance().getInfo(4681,1); // left hand
						else
							skill = SkillTable.getInstance().getInfo(4682,1); // right hand
					}
				}
				else if( Rnd.get(100) < 0)
				{
					skill = SkillTable.getInstance().getInfo(4690,1);
				}
				else if( Rnd.get(100) < 10)
				{
					skill = SkillTable.getInstance().getInfo(4689,1);
				}
				else
				{
					skill = SkillTable.getInstance().getInfo(4684,1);
				}
			}
		}
		if (skill != null)
			callSkillAI(npc,c2,skill);
	}

	public void callSkillAI(L2NpcInstance npc, L2Character c2, L2Skill skill)
	{
		if (npc.isInvul())
			return;
		QuestTimer timer = getQuestTimer("1003", npc, null);

		if (npc == null)
		{
			if (timer != null)
				timer.cancel();
			return;
		}

		if (c2 == null || c2.isDead() || timer == null)
		{
			c2 = getRandomTarget(npc); // just in case if hate AI fail
			if (timer == null)
			{
				startQuestTimer("1003", 500, npc, null, true);
				return;
			}
		}
		L2Character target = c2;
		if (target == null || target.isDead())
		{
			if (timer == null)
				startQuestTimer("1003", 500, npc, null, true);
			return;
		}

		if (Util.checkIfInRange(skill.getCastRange(), npc, target, true))
		{
			if (timer != null)
				timer.cancel();
			npc.getAI().setIntention(AI_INTENTION_IDLE);
			npc.setIsCastingNow(true);
			npc.setTarget(target);
			npc.doCast(skill);
			
		}
		else
		{
			if (timer == null)
				startQuestTimer("1003", 500, npc, null, true);
			npc.getAI().setIntention(AI_INTENTION_FOLLOW, target, null);
			npc.setIsCastingNow(false);
		}
	}
//	public void broadcastSpawn(L2NpcInstance npc)
//	{
//		Collection<L2Object> objs = npc.getKnownList().getKnownObjects().values();
//		{
//			for (L2Object obj : objs)
//			{
//				if (obj instanceof L2PcInstance)
//				{
//					if (Util.checkIfInRange(10000, npc, obj, true))
//					{
//						((L2Character) obj).sendPacket(new PlaySound(1, "B03_A", 1, npc.getObjectId(), 212852,-114842,-1632));
//						((L2Character) obj).sendPacket(new SocialAction(npc.getObjectId(),3));
//					}
//				}
//			}
//		}
//		return;
//	}

	public L2Character getRandomTarget(L2NpcInstance npc)
	{
		FastList<L2Character> result = new FastList<L2Character>();
		Collection<L2Object> objs = npc.getKnownList().getKnownObjects().values();
		{
			for (L2Object obj : objs)
			{
				if (obj instanceof L2PcInstance || obj instanceof L2Summon || obj instanceof L2DecoyInstance)
				{
					if (Util.checkIfInRange(5000, npc, obj, true) && !((L2Character) obj).isDead() && !((L2Character) obj).isMG())
						result.add((L2Character) obj);
				}
			}
		}
		if (!result.isEmpty() && result.size() != 0)
		{
			Object[] characters = result.toArray();
			return (L2Character) characters[Rnd.get(characters.length)];
		}
		return null;
	}

    public String onSpellFinished(L2NpcInstance npc, L2PcInstance player, L2Skill skill)
    {
		if (npc.isInvul())
		{
			return null;
		}
		else if (npc.getNpcId() == VALAKAS && !npc.isInvul())
    	{
    		getRandomSkill(npc);
    	}
    	return super.onSpellFinished(npc, player, skill);
    }

    public String onAggroRangeEnter (L2NpcInstance npc, L2PcInstance player, boolean isPet) 
    {
    	int i1 = 0;
        if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
        {
        	if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 1 ) / 4 ))
			{
				if( player == c_quest2 )
				{
					if( ( ( 10 * 1000 ) + 1000 ) > i_quest2 )
					{
						i_quest2 = ((10 * 1000) + Rnd.get(3000));
					}
				}
				else if( player == c_quest3 )
				{
					if( ( ( 10 * 1000 ) + 1000 ) > i_quest3 )
					{
						i_quest3 = ((10 * 1000) + Rnd.get(3000));
					}
				}
				else if( player == c_quest4 )
				{
					if( ( ( 10 * 1000 ) + 1000 ) > i_quest4 )
					{
						i_quest4 = ((10 * 1000) + Rnd.get(3000));
					}
				}
				else if( i_quest2 > i_quest3 )
				{
					i1 = 3;
				}
				else if( i_quest2 == i_quest3 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 2;
					}
					else
					{
						i1 = 3;
					}
				}
				else if( i_quest2 < i_quest3 )
				{
					i1 = 2;
				}
				if( i1 == 2 )
				{
					if( i_quest2 > i_quest4 )
					{
						i1 = 4;
					}
					else if( i_quest2 == i_quest4 )
					{
						if( Rnd.get(100) < 50 )
						{
							i1 = 2;
						}
						else
						{
							i1 = 4;
						}
					}
					else if( i_quest2 < i_quest4 )
					{
						i1 = 2;
					}
				}
				else if( i1 == 3 )
				{
					if( i_quest3 > i_quest4 )
					{
						i1 = 4;
					}
					else if( i_quest3 == i_quest4 )
					{
						if( Rnd.get(100) < 50 )
						{
							i1 = 3;
						}
						else
						{
							i1 = 4;
						}
					}
					else if( i_quest3 < i_quest4 )
					{
						i1 = 3;
					}
				}
				if (i1 == 2)
				{
						i_quest2 = ( ( 10 * 1000 ) + Rnd.get(3000) );
						c_quest2 = player;
				}
				else if (i1 == 3)
				{
						i_quest3 = ( ( 10 * 1000 ) + Rnd.get(3000) );
						c_quest3 = player;
				}
				else if (i1 == 4)
				{
						i_quest4 = ( ( 10 * 1000 ) + Rnd.get(3000) );
						c_quest4 = player;
				}
			}
			else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 2 ) / 4 ))
			{
				if( player == c_quest2 )
				{
					if( ( ( 6 * 1000 ) + 1000 ) > i_quest2 )
					{
						i_quest2 = ( ( 6 * 1000 ) + Rnd.get(3000) );
					}
				}
				else if( player == c_quest3 )
				{
					if( ( ( 6 * 1000 ) + 1000 ) > i_quest3 )
					{
						i_quest3 = ( ( 6 * 1000 ) + Rnd.get(3000) );
					}
				}
				else if( player == c_quest4 )
				{
					if( ( ( 6 * 1000 ) + 1000 ) > i_quest4 )
					{
						i_quest4 = ( ( 6 * 1000 ) + Rnd.get(3000) );
					}
				}
				else if( i_quest2 > i_quest3 )
				{
					i1 = 3;
				}
				else if( i_quest2 == i_quest3 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 2;
					}
					else
					{
						i1 = 3;
					}
				}
				else if( i_quest2 < i_quest3 )
				{
					i1 = 2;
				}
				if( i1 == 2 )
				{
					if( i_quest2 > i_quest4 )
					{
						i1 = 4;
					}
					else if( i_quest2 == i_quest4 )
					{
						if( Rnd.get(100) < 50 )
						{
							i1 = 2;
						}
						else
						{
							i1 = 4;
						}
					}
					else if( i_quest2 < i_quest4 )
					{
						i1 = 2;
					}
				}
				else if( i1 == 3 )
				{
					if( i_quest3 > i_quest4 )
					{
						i1 = 4;
					}
					else if( i_quest3 == i_quest4 )
					{
						if( Rnd.get(100) < 50 )
						{
							i1 = 3;
						}
						else
						{
							i1 = 4;
						}
					}
					else if( i_quest3 < i_quest4 )
					{
						i1 = 3;
					}
				}
				if (i1 == 2)
				{
						i_quest2 = ( ( 6 * 1000 ) + Rnd.get(3000) );
						c_quest2 = player;
				}
				else if (i1 == 3)
				{
						i_quest3 = ( ( 6 * 1000 ) + Rnd.get(3000) );
						c_quest3 = player;
				}
				else if (i1 == 4)
				{
						i_quest4 = ( ( 6 * 1000 ) + Rnd.get(3000) );
						c_quest4 = player;
				}
			}
			else if( npc.getCurrentHp() > ( ( npc.getMaxHp() * 3 ) / 4 ))
			{
				if( player == c_quest2 )
				{
					if( ( ( 3 * 1000 ) + 1000 ) > i_quest2 )
					{
						i_quest2 = ( ( 3 * 1000 ) + Rnd.get(3000) );
					}
				}
				else if( player == c_quest3 )
				{
					if( ( ( 3 * 1000 ) + 1000 ) > i_quest3 )
					{
						i_quest3 = ( ( 3 * 1000 ) + Rnd.get(3000) );
					}
				}
				else if( player == c_quest4 )
				{
					if( ( ( 3 * 1000 ) + 1000 ) > i_quest4 )
					{
						i_quest4 = ( ( 3 * 1000 ) + Rnd.get(3000) );
					}
				}
				else if( i_quest2 > i_quest3 )
				{
					i1 = 3;
				}
				else if( i_quest2 == i_quest3 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 2;
					}
					else
					{
						i1 = 3;
					}
				}
				else if( i_quest2 < i_quest3 )
				{
					i1 = 2;
				}
				if( i1 == 2 )
				{
					if( i_quest2 > i_quest4 )
					{
						i1 = 4;
					}
					else if( i_quest2 == i_quest4 )
					{
						if( Rnd.get(100) < 50 )
						{
							i1 = 2;
						}
						else
						{
							i1 = 4;
						}
					}
					else if( i_quest2 < i_quest4 )
					{
						i1 = 2;
					}
				}
				else if( i1 == 3 )
				{
					if( i_quest3 > i_quest4 )
					{
						i1 = 4;
					}
					else if( i_quest3 == i_quest4 )
					{
						if( Rnd.get(100) < 50 )
						{
							i1 = 3;
						}
						else
						{
							i1 = 4;
						}
					}
					else if( i_quest3 < i_quest4 )
					{
						i1 = 3;
					}
				}
				if (i1 == 2)
				{
						i_quest2 = ( ( 3 * 1000 ) + Rnd.get(3000) );
						c_quest2 = player;
				}
				else if (i1 == 3)
				{
						i_quest3 = ( ( 3 * 1000 ) + Rnd.get(3000) );
						c_quest3 = player;
				}
				else if (i1 == 4)
				{
						i_quest4 = ( ( 3 * 1000 ) + Rnd.get(3000) );
						c_quest4 = player;
				}
			}
			else if( player == c_quest2 )
			{
				if( ( ( 2 * 1000 ) + 1000 ) > i_quest2 )
				{
					i_quest2 = ( ( 2 * 1000 ) + Rnd.get(3000));
				}
			}
			else if( player == c_quest3 )
			{
				if( ( ( 2 * 1000 ) + 1000 ) > i_quest3 )
				{
					i_quest3 = ( ( 2 * 1000 ) + Rnd.get(3000));
				}
			}
			else if( player == c_quest4 )
			{
				if( ( ( 2 * 1000 ) + 1000 ) > i_quest4 )
				{
					i_quest4 = ( ( 2 * 1000 ) + Rnd.get(3000));
				}
			}
			else if( i_quest2 > i_quest3 )
			{
				i1 = 3;
			}
			else if( i_quest2 == i_quest3 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 2;
				}
				else
				{
					i1 = 3;
				}
			}
			else if( i_quest2 < i_quest3 )
			{
				i1 = 2;
			}
			if( i1 == 2 )
			{
				if( i_quest2 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest2 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 2;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest2 < i_quest4 )
				{
					i1 = 2;
				}
			}
			else if( i1 == 3 )
			{
				if( i_quest3 > i_quest4 )
				{
					i1 = 4;
				}
				else if( i_quest3 == i_quest4 )
				{
					if( Rnd.get(100) < 50 )
					{
						i1 = 3;
					}
					else
					{
						i1 = 4;
					}
				}
				else if( i_quest3 < i_quest4 )
				{
					i1 = 3;
				}
			}
			if (i1 == 2)
			{
					i_quest2 = ( ( 2 * 1000 ) + Rnd.get(3000) );
					c_quest2 = player;
			}
			else if (i1 == 3)
			{
					i_quest3 = ( ( 2 * 1000 ) + Rnd.get(3000) );
					c_quest3 = player;
			}
			else if (i1 == 4)
			{
					i_quest4 = ( ( 2 * 1000 ) + Rnd.get(3000) );
					c_quest4 = player;
			}
		}
		else if( player == c_quest2 )
		{
			if( ( ( 1 * 1000 ) + 1000 ) > i_quest2 )
			{
				i_quest2 = ( ( 1 * 1000 ) + Rnd.get(3000) );
			}
		}
		else if( player == c_quest3 )
		{
			if( ( ( 1 * 1000 ) + 1000 ) > i_quest3 )
			{
				i_quest3 = ( ( 1 * 1000 ) + Rnd.get(3000) );
			}
		}
		else if( player == c_quest4 )
		{
			if( ( ( 1 * 1000 ) + 1000 ) > i_quest4 )
			{
				i_quest4 = ( ( 1 * 1000 ) + Rnd.get(3000) );
			}
		}
		else if( i_quest2 > i_quest3 )
		{
			i1 = 3;
		}
		else if( i_quest2 == i_quest3 )
		{
			if( Rnd.get(100) < 50 )
			{
				i1 = 2;
			}
			else
			{
				i1 = 3;
			}
		}
		else if( i_quest2 < i_quest3 )
		{
			i1 = 2;
		}
		if( i1 == 2 )
		{
			if( i_quest2 > i_quest4 )
			{
				i1 = 4;
			}
			else if( i_quest2 == i_quest4 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 2;
				}
				else
				{
					i1 = 4;
				}
			}
			else if( i_quest2 < i_quest4 )
			{
				i1 = 2;
			}
		}
		else if( i1 == 3 )
		{
			if( i_quest3 > i_quest4 )
			{
				i1 = 4;
			}
			else if( i_quest3 == i_quest4 )
			{
				if( Rnd.get(100) < 50 )
				{
					i1 = 3;
				}
				else
				{
					i1 = 4;
				}
			}
			else if( i_quest3 < i_quest4 )
			{
				i1 = 3;
			}
		}
		if (i1 == 2)
		{
				i_quest2 = ( ( 1 * 1000 ) + Rnd.get(3000) );
				c_quest2 = player;
		}
		else if (i1 == 3)
		{
				i_quest3 = ( ( 1 * 1000 ) + Rnd.get(3000) );
				c_quest3 = player;
		}
		else if (i1 == 4)
		{
				i_quest4 = ( ( 1 * 1000 ) + Rnd.get(3000) );
				c_quest4 = player;
		}
        if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING && !npc.isInvul())
        {
        	getRandomSkill(npc);
        }
        else
        	return null;
    	return super.onAggroRangeEnter(npc, player, isPet);
    }

	public String onSkillSee (L2NpcInstance npc, L2PcInstance caster, L2Skill skill, L2Object[] targets, boolean isPet)
	{
		if (npc.isInvul())
		{
			return null;
		}
		npc.setTarget(caster);
		return super.onSkillSee(npc, caster, skill, targets, isPet);
	}

    private void screenMessage(String text) //+[JOJO]
    {
        _Zone.broadcastPacket(new ExShowScreenMessage(text,/*time=>*/10000));
//      _Zone.broadcastPacket(new CreatureSay(0, 15, "ヴァラカス", text));
    }
    private void announce(String text) //+[JOJO]
    {
        _Zone.broadcastPacket(new CreatureSay(0, 10, "", text));
    }
//    private void TRACE(String text) //+[JOJO]
//    {
//        _Zone.broadcastPacket(new CreatureSay(0, 2, "", text));
//    }

   public static void main(String[] args)
    {
    	// now call the constructor (starts up the ai)
    	new Valakas(-1,"valakas","ai");
    }
}
// TODO: datapack_development\data\scripts\teleports\6000_GrandBossTeleporters\__init__.py
//  人数のカウント this.count はクリアされない？