Bladeren bron

Reworking Beleth

Fully rewritten the script, no more Runnables at all.
Fixed the untargetable Beleth.
Includes retail like fix - only real Beleth cast horn of rising.
Includes retail like fix - all Beleth dissapear for 60 seconds only if
the chosen one gets killed, and not the opposite like it was.
Npcs are properly spawned / deleted whenever needed.

Notes:
Cameras are probably a bit wrong, they are too low on floor and
sometimes you see sky because of that.
Removed that part with broadcasting of Missing Text, at least until
someone would get the real text they should broadcast with proper
conditions... (if any at all).

Patch by: sahar
Reviewed by: @Zoey76
Zoey76 10 jaren geleden
bovenliggende
commit
b8dc5050cc
1 gewijzigde bestanden met toevoegingen van 539 en 507 verwijderingen
  1. 539 507
      L2J_DataPack/dist/game/data/scripts/ai/individual/Beleth.java

+ 539 - 507
L2J_DataPack/dist/game/data/scripts/ai/individual/Beleth.java

@@ -20,12 +20,10 @@ package ai.individual;
 
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ScheduledFuture;
 
 import ai.npc.AbstractNpcAI;
 
 import com.l2jserver.Config;
-import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.cache.HtmCache;
 import com.l2jserver.gameserver.data.xml.impl.DoorData;
@@ -40,10 +38,10 @@ import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.effects.L2EffectType;
+import com.l2jserver.gameserver.model.holders.ItemHolder;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
 import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.model.zone.L2ZoneType;
-import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
 import com.l2jserver.gameserver.network.serverpackets.DoorStatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
 import com.l2jserver.gameserver.network.serverpackets.PlaySound;
@@ -54,292 +52,76 @@ import com.l2jserver.gameserver.util.Util;
 
 /**
  * Beleth's AI.
- * @author Treat
+ * @author Treat, Sahar
  */
 public final class Beleth extends AbstractNpcAI
 {
+	// Status
+	private static final int ALIVE = 0;
+	private static final int INIT = 1;
+	private static final int FIGHT = 2;
+	private static final int DEAD = 3;
 	// NPCs
-	private static final int BELETH_ID_1 = 29118;
-	private static final int BELETH_ID_2 = 29119; // Fake Beleth
-	protected static L2Npc CAMERA;
-	protected static L2Npc CAMERA2;
-	protected static L2Npc CAMERA3;
-	protected static L2Npc CAMERA4;
-	protected static L2Npc BELETH;
-	protected static L2Npc PRIEST;
-	protected static L2ZoneType ZONE = null;
-	private static L2PcInstance BELETH_KILLER;
-	private static boolean DEBUG = false;
-	protected static boolean MOVIE = false;
-	private static boolean ATTACKED = false;
-	private static int ALLOW_OBJECT_ID = 0;
-	private static int KILLED = 0;
-	protected static ScheduledFuture<?> SPAWN_TIMER = null;
-	protected static final List<L2Npc> MINIONS = new CopyOnWriteArrayList<>();
+	private static final int REAL_BELETH = 29118;
+	private static final int FAKE_BELETH = 29119;
+	private static final int STONE_COFFIN = 32470;
+	private static final int ELF = 29128;
+	private static final int WHIRPOOL = 29125;
+	// Zones
+	private static final L2ZoneType ZONE = ZoneManager.getInstance().getZoneById(12018);
+	private static final Location BELETH_SPAWN = new Location(16323, 213059, -9357, 49152);
+	// Skills
 	private static final SkillHolder BLEED = new SkillHolder(5495, 1);
 	private static final SkillHolder FIREBALL = new SkillHolder(5496, 1);
 	private static final SkillHolder HORN_OF_RISING = new SkillHolder(5497, 1);
 	private static final SkillHolder LIGHTENING = new SkillHolder(5499, 1);
-	
-	protected static final Location BELETH_SPAWN = new Location(16323, 213059, -9357, 49152);
+	// Doors
+	private static final int DOOR1 = 20240001;
+	private static final int DOOR2 = 20240002;
+	private static final int DOOR3 = 20240003;
+	// Items
+	private static final ItemHolder RING = new ItemHolder(10314, 1);
+	// Variables
+	private L2Npc _camera1;
+	private L2Npc _camera2;
+	private L2Npc _camera3;
+	private L2Npc _camera4;
+	private L2Npc _whirpool;
+	private L2Npc _beleth;
+	private L2Npc _priest;
+	private L2Npc _stone;
+	private L2PcInstance _killer;
+	private int _allowedObjId;
+	private int _killedCount;
+	private final List<L2Npc> _minions = new CopyOnWriteArrayList<>();
 	
 	private Beleth()
 	{
 		super(Beleth.class.getSimpleName(), "ai/individual");
-		ZONE = ZoneManager.getInstance().getZoneById(12018);
-		addEnterZoneId(12018);
-		registerMobs(BELETH_ID_1, BELETH_ID_2);
-		addStartNpc(32470);
-		addTalkId(32470);
-		addFirstTalkId(29128);
-		StatsSet info = GrandBossManager.getInstance().getStatsSet(BELETH_ID_1);
-		int status = GrandBossManager.getInstance().getBossStatus(BELETH_ID_1);
-		if (status == 3)
+		addEnterZoneId(ZONE.getId());
+		registerMobs(REAL_BELETH, FAKE_BELETH);
+		addStartNpc(STONE_COFFIN);
+		addTalkId(STONE_COFFIN);
+		addFirstTalkId(ELF);
+		StatsSet info = GrandBossManager.getInstance().getStatsSet(REAL_BELETH);
+		int status = GrandBossManager.getInstance().getBossStatus(REAL_BELETH);
+		if (status == DEAD)
 		{
 			final long time = (info.getLong("respawn_time") - System.currentTimeMillis());
 			if (time > 0)
 			{
-				startQuestTimer("UNLOCK", time, null, null);
+				startQuestTimer("BELETH_UNLOCK", time, null, null);
 			}
 			else
 			{
-				GrandBossManager.getInstance().setBossStatus(BELETH_ID_1, 0);
+				GrandBossManager.getInstance().setBossStatus(REAL_BELETH, ALIVE);
 			}
 		}
-		else if (status != 0)
+		else if (status != ALIVE)
 		{
-			GrandBossManager.getInstance().setBossStatus(BELETH_ID_1, 0);
-		}
-		DoorData.getInstance().getDoor(20240001).openMe();
-	}
-	
-	public static void startSpawnTask()
-	{
-		ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(1), DEBUG ? 10000 : 300000);
-	}
-	
-	private static class Spawn implements Runnable
-	{
-		private int _taskId = 0;
-		
-		public Spawn(int taskId)
-		{
-			_taskId = taskId;
-		}
-		
-		@Override
-		public void run()
-		{
-			try
-			{
-				int instanceId = 0;
-				switch (_taskId)
-				{
-					case 1:
-						MOVIE = true;
-						for (L2Character npc : ZONE.getCharactersInside())
-						{
-							if (npc.isNpc())
-							{
-								npc.deleteMe();
-							}
-						}
-						CAMERA = addSpawn(29120, new Location(16323, 213142, -9357, 0, instanceId));
-						CAMERA2 = addSpawn(29121, new Location(16323, 210741, -9357, 0, instanceId));
-						CAMERA3 = addSpawn(29122, new Location(16323, 213170, -9357, 0, instanceId));
-						CAMERA4 = addSpawn(29123, new Location(16323, 214917, -9356, 0, instanceId));
-						ZONE.broadcastPacket(new PlaySound(1, "BS07_A", 1, CAMERA.getObjectId(), CAMERA.getX(), CAMERA.getY(), CAMERA.getZ()));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 75, -25, 0, 2500, 0, 0, 1, 0, 0));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 75, -25, 0, 2500, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(2), 300);
-						break;
-					case 2:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 1800, -45, -45, 5000, 5000, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(3), 4900);
-						break;
-					case 3:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 2500, -120, -45, 5000, 5000, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(4), 4900);
-						break;
-					case 4:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 2200, 130, 0, 0, 1500, -20, 15, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(5), 1400);
-						break;
-					case 5:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 2300, 100, 0, 2000, 4500, 0, 10, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(6), 2500);
-						break;
-					case 6:
-						L2DoorInstance door = DoorData.getInstance().getDoor(20240001);
-						door.closeMe();
-						ZONE.broadcastPacket(new StaticObject(door, false));
-						ZONE.broadcastPacket(new DoorStatusUpdate(door));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(7), 1700);
-						break;
-					case 7:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 1500, 210, 0, 0, 1500, 0, 0, 1, 0, 0));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 900, 255, 0, 5000, 6500, 0, 10, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(8), 6000);
-						break;
-					case 8:
-						addSpawn(29125, new Location(16323, 214917, -9356, 0, instanceId));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 900, 255, 0, 0, 1500, 0, 10, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(9), 1000);
-						break;
-					case 9:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 1000, 255, 0, 7000, 17000, 0, 25, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(10), 3000);
-						break;
-					case 10:
-						BELETH = addSpawn(BELETH_ID_1, new Location(16321, 214211, -9352, 49369, instanceId));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(11), 200);
-						break;
-					case 11:
-						ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 1));
-						for (int i = 0; i < 6; i++)
-						{
-							int x = (int) ((150 * Math.cos(i * 1.046666667)) + 16323);
-							int y = (int) ((150 * Math.sin(i * 1.046666667)) + 213059);
-							L2Npc minion = addSpawn(BELETH_ID_2, new Location(x, y, -9357, 49152, BELETH.getInstanceId()));
-							minion.setShowSummonAnimation(true);
-							minion.deleteMe();
-							MINIONS.add(minion);
-						}
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(12), 6800);
-						break;
-					case 12:
-						ZONE.broadcastPacket(new SpecialCamera(BELETH, 0, 270, -5, 0, 4000, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(13), 3500);
-						break;
-					case 13:
-						ZONE.broadcastPacket(new SpecialCamera(BELETH, 800, 270, 10, 3000, 6000, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(14), 5000);
-						break;
-					case 14:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 0, 5000, 0, 0, 1, 0, 0));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 0, 5000, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(15), 100);
-						break;
-					case 15:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 3000, 6000, 0, 5, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(16), 1400);
-						break;
-					case 16:
-						BELETH.teleToLocation(BELETH_SPAWN);
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(17), 200);
-						break;
-					case 17:
-						ZONE.broadcastPacket(new MagicSkillUse(BELETH, BELETH, 5532, 1, 2000, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(18), 2000);
-						break;
-					case 18:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 700, 270, 20, 1500, 8000, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(19), 6900);
-						break;
-					case 19:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 40, 260, 0, 0, 4000, 0, 0, 1, 0, 0));
-						for (L2Npc fakeBeleth : MINIONS)
-						{
-							fakeBeleth.spawnMe();
-						}
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(20), 3000);
-						break;
-					case 20:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 40, 280, 0, 0, 4000, 5, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(21), 3000);
-						break;
-					case 21:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 5, 250, 5, 0, 13000, 20, 15, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(22), 1000);
-						break;
-					case 22:
-						ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 3));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(23), 4000);
-						break;
-					case 23:
-						ZONE.broadcastPacket(new MagicSkillUse(BELETH, BELETH, 5533, 1, 2000, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(24), 6800);
-						break;
-					case 24:
-						BELETH.deleteMe();
-						for (L2Npc fakeBeleth : MINIONS)
-						{
-							fakeBeleth.deleteMe();
-						}
-						MINIONS.clear();
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(25), 1000);
-						break;
-					case 25:
-						CAMERA.deleteMe();
-						CAMERA2.deleteMe();
-						CAMERA3.deleteMe();
-						CAMERA4.deleteMe();
-						MOVIE = false;
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(26), 60000);
-						break;
-					case 26:
-						if (SPAWN_TIMER != null)
-						{
-							SPAWN_TIMER.cancel(false);
-							setSpawnTimer(0);
-						}
-						SpawnBeleths();
-						break;
-					case 27:
-						BELETH.doDie(null);
-						CAMERA = addSpawn(29122, new Location(16323, 213170, -9357, 0, instanceId));
-						CAMERA.broadcastPacket(new PlaySound(1, "BS07_D", 1, CAMERA.getObjectId(), CAMERA.getX(), CAMERA.getY(), CAMERA.getZ()));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 290, 25, 0, 10000, 0, 0, 1, 0, 0));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 290, 25, 0, 10000, 0, 0, 1, 0, 0));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 110, 25, 4000, 10000, 0, 0, 1, 0, 0));
-						ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 5));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(28), 4000);
-						break;
-					case 28:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 295, 25, 4000, 5000, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(29), 4500);
-						break;
-					case 29:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 295, 10, 4000, 11000, 0, 25, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(30), 9000);
-						break;
-					case 30:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 250, 90, 25, 0, 1000, 0, 0, 1, 0, 0));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA, 250, 90, 25, 0, 10000, 0, 0, 1, 0, 0));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(31), 2000);
-						break;
-					case 31:
-						PRIEST.spawnMe();
-						BELETH.deleteMe();
-						CAMERA2 = addSpawn(29121, new Location(14056, 213170, -9357, 0, instanceId));
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(32), 3500);
-						break;
-					case 32:
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 800, 180, 0, 0, 4000, 0, 10, 1, 0, 0));
-						ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 800, 180, 0, 0, 4000, 0, 10, 1, 0, 0));
-						L2DoorInstance door2 = DoorData.getInstance().getDoor(20240002);
-						door2.openMe();
-						ZONE.broadcastPacket(new StaticObject(door2, false));
-						ZONE.broadcastPacket(new DoorStatusUpdate(door2));
-						DoorData.getInstance().getDoor(20240003).openMe();
-						ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(33), 4000);
-						break;
-					case 33:
-						CAMERA.deleteMe();
-						CAMERA2.deleteMe();
-						MOVIE = false;
-						break;
-					case 333:
-						BELETH = addSpawn(BELETH_ID_1, new Location(16323, 213170, -9357, 49152));
-						break;
-				
-				}
-			}
-			catch (Exception e)
-			{
-				e.printStackTrace();
-			}
+			GrandBossManager.getInstance().setBossStatus(REAL_BELETH, ALIVE);
 		}
+		DoorData.getInstance().getDoor(DOOR1).openMe();
 	}
 	
 	@Override
@@ -347,10 +129,10 @@ public final class Beleth extends AbstractNpcAI
 	{
 		switch (event)
 		{
-			case "UNLOCK":
+			case "BELETH_UNLOCK":
 			{
-				GrandBossManager.getInstance().setBossStatus(BELETH_ID_1, 0);
-				DoorData.getInstance().getDoor(20240001).openMe();
+				GrandBossManager.getInstance().setBossStatus(REAL_BELETH, ALIVE);
+				DoorData.getInstance().getDoor(DOOR1).openMe();
 				break;
 			}
 			case "CAST":
@@ -362,6 +144,364 @@ public final class Beleth extends AbstractNpcAI
 				}
 				break;
 			}
+			case "SPAWN1":
+			{
+				ZONE.getCharactersInside().forEach(c ->
+				{
+					c.disableAllSkills();
+					c.setIsInvul(true);
+					c.setIsImmobilized(true);
+				});
+				
+				_camera1 = addSpawn(29120, new Location(16323, 213142, -9357));
+				_camera2 = addSpawn(29121, new Location(16323, 210741, -9357));
+				_camera3 = addSpawn(29122, new Location(16323, 213170, -9357));
+				_camera4 = addSpawn(29123, new Location(16323, 214917, -9356));
+				
+				ZONE.broadcastPacket(new PlaySound(1, "BS07_A", 1, _camera1.getObjectId(), _camera1.getX(), _camera1.getY(), _camera1.getZ()));
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 400, 75, -25, 0, 2500, 0, 0, 1, 0, 0));
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 400, 75, -25, 0, 2500, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN2", 300, null, null);
+			}
+			case "SPAWN2":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 1800, -45, -45, 5000, 5000, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN3", 4900, null, null);
+			}
+			case "SPAWN3":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 2500, -120, -45, 5000, 5000, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN4", 4900, null, null);
+			}
+			case "SPAWN4":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera2, 2200, 130, 0, 0, 1500, -20, 15, 1, 0, 0));
+				
+				startQuestTimer("SPAWN5", 1400, null, null);
+			}
+			case "SPAWN5":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera2, 2300, 100, 0, 2000, 4500, 0, 10, 1, 0, 0));
+				
+				startQuestTimer("SPAWN6", 2500, null, null);
+			}
+			case "SPAWN6":
+			{
+				final L2DoorInstance door = DoorData.getInstance().getDoor(DOOR1);
+				door.closeMe();
+				
+				ZONE.broadcastPacket(new StaticObject(door, false));
+				ZONE.broadcastPacket(new DoorStatusUpdate(door));
+				
+				startQuestTimer("SPAWN7", 1700, null, null);
+			}
+			case "SPAWN7":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera4, 1500, 210, 0, 0, 1500, 0, 0, 1, 0, 0));
+				ZONE.broadcastPacket(new SpecialCamera(_camera4, 900, 255, 0, 5000, 6500, 0, 10, 1, 0, 0));
+				
+				startQuestTimer("SPAWN8", 6000, null, null);
+			}
+			case "SPAWN8":
+			{
+				_whirpool = addSpawn(WHIRPOOL, new Location(16323, 214917, -9356));
+				
+				ZONE.broadcastPacket(new SpecialCamera(_camera4, 900, 255, 0, 0, 1500, 0, 10, 1, 0, 0));
+				
+				startQuestTimer("SPAWN9", 1000, null, null);
+			}
+			case "SPAWN9":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera4, 1000, 255, 0, 7000, 17000, 0, 25, 1, 0, 0));
+				
+				startQuestTimer("SPAWN10", 3000, null, null);
+			}
+			case "SPAWN10":
+			{
+				_beleth = addSpawn(REAL_BELETH, new Location(16321, 214211, -9352, 49369));
+				_beleth.disableAllSkills();
+				_beleth.setIsInvul(true);
+				_beleth.setIsImmobilized(true);
+				
+				startQuestTimer("SPAWN11", 200, null, null);
+			}
+			case "SPAWN11":
+			{
+				ZONE.broadcastPacket(new SocialAction(_beleth.getObjectId(), 1));
+				
+				for (int i = 0; i < 6; i++)
+				{
+					int x = (int) ((150 * Math.cos(i * 1.046666667)) + 16323);
+					int y = (int) ((150 * Math.sin(i * 1.046666667)) + 213059);
+					L2Npc minion = addSpawn(FAKE_BELETH, new Location(x, y, -9357, 49152));
+					minion.setShowSummonAnimation(true);
+					minion.decayMe();
+					
+					_minions.add(minion);
+				}
+				
+				startQuestTimer("SPAWN12", 6800, null, null);
+			}
+			case "SPAWN12":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_beleth, 0, 270, -5, 0, 4000, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN13", 3500, null, null);
+			}
+			case "SPAWN13":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_beleth, 800, 270, 10, 3000, 6000, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN14", 5000, null, null);
+			}
+			case "SPAWN14":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera3, 100, 270, 15, 0, 5000, 0, 0, 1, 0, 0));
+				ZONE.broadcastPacket(new SpecialCamera(_camera3, 100, 270, 15, 0, 5000, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN15", 100, null, null);
+			}
+			case "SPAWN15":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera3, 100, 270, 15, 3000, 6000, 0, 5, 1, 0, 0));
+				
+				startQuestTimer("SPAWN16", 1400, null, null);
+			}
+			case "SPAWN16":
+			{
+				_beleth.teleToLocation(BELETH_SPAWN);
+				
+				startQuestTimer("SPAWN17", 200, null, null);
+			}
+			case "SPAWN17":
+			{
+				ZONE.broadcastPacket(new MagicSkillUse(_beleth, _beleth, 5532, 1, 2000, 0));
+				
+				startQuestTimer("SPAWN18", 2000, null, null);
+			}
+			case "SPAWN18":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera3, 700, 270, 20, 1500, 8000, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN19", 6900, null, null);
+			}
+			case "SPAWN19":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera3, 40, 260, 0, 0, 4000, 0, 0, 1, 0, 0));
+				
+				for (L2Npc fakeBeleth : _minions)
+				{
+					fakeBeleth.spawnMe();
+					fakeBeleth.disableAllSkills();
+					fakeBeleth.setIsInvul(true);
+					fakeBeleth.setIsImmobilized(true);
+				}
+				
+				startQuestTimer("SPAWN20", 3000, null, null);
+			}
+			case "SPAWN20":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera3, 40, 280, 0, 0, 4000, 5, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN21", 3000, null, null);
+			}
+			case "SPAWN21":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera3, 5, 250, 5, 0, 13000, 20, 15, 1, 0, 0));
+				
+				startQuestTimer("SPAWN22", 1000, null, null);
+			}
+			case "SPAWN22":
+			{
+				ZONE.broadcastPacket(new SocialAction(_beleth.getObjectId(), 3));
+				
+				startQuestTimer("SPAWN23", 4000, null, null);
+			}
+			case "SPAWN23":
+			{
+				ZONE.broadcastPacket(new MagicSkillUse(_beleth, _beleth, 5533, 1, 2000, 0));
+				
+				startQuestTimer("SPAWN24", 6800, null, null);
+			}
+			case "SPAWN24":
+			{
+				_beleth.deleteMe();
+				_beleth = null;
+				
+				for (L2Npc fakeBeleth : _minions)
+				{
+					fakeBeleth.deleteMe();
+				}
+				_minions.clear();
+				
+				_camera1.deleteMe();
+				_camera2.deleteMe();
+				_camera3.deleteMe();
+				_camera4.deleteMe();
+				
+				for (L2Character c : ZONE.getCharactersInside())
+				{
+					c.enableAllSkills();
+					c.setIsInvul(false);
+					c.setIsImmobilized(false);
+				}
+				
+				startQuestTimer("SPAWN25", 60000, null, null);
+			}
+			case "SPAWN25":
+			{
+				int a = 0;
+				for (int i = 0; i < 16; i++)
+				{
+					a++;
+					
+					int x = (int) ((650 * Math.cos(i * 0.39)) + 16323);
+					int y = (int) ((650 * Math.sin(i * 0.39)) + 213170);
+					
+					npc = addSpawn(FAKE_BELETH, new Location(x, y, -9357, 49152));
+					_minions.add(npc);
+					
+					if (a >= 2)
+					{
+						npc.setIsOverloaded(true);
+						a = 0;
+					}
+				}
+				
+				int[] xm = new int[16];
+				int[] ym = new int[16];
+				for (int i = 0; i < 4; i++)
+				{
+					xm[i] = (int) ((1700 * Math.cos((i * 1.57) + 0.78)) + 16323);
+					ym[i] = (int) ((1700 * Math.sin((i * 1.57) + 0.78)) + 213170);
+					
+					npc = addSpawn(FAKE_BELETH, new Location(xm[i], ym[i], -9357, 49152));
+					npc.setIsImmobilized(true);
+					
+					_minions.add(npc);
+				}
+				
+				xm[4] = (xm[0] + xm[1]) / 2;
+				ym[4] = (ym[0] + ym[1]) / 2;
+				npc = addSpawn(FAKE_BELETH, new Location(xm[4], ym[4], -9357, 49152));
+				npc.setIsImmobilized(true);
+				_minions.add(npc);
+				xm[5] = (xm[1] + xm[2]) / 2;
+				ym[5] = (ym[1] + ym[2]) / 2;
+				npc = addSpawn(FAKE_BELETH, new Location(xm[5], ym[5], -9357, 49152));
+				npc.setIsImmobilized(true);
+				_minions.add(npc);
+				xm[6] = (xm[2] + xm[3]) / 2;
+				ym[6] = (ym[2] + ym[3]) / 2;
+				npc = addSpawn(FAKE_BELETH, new Location(xm[6], ym[6], -9357, 49152));
+				npc.setIsImmobilized(true);
+				_minions.add(npc);
+				xm[7] = (xm[3] + xm[0]) / 2;
+				ym[7] = (ym[3] + ym[0]) / 2;
+				npc = addSpawn(FAKE_BELETH, new Location(xm[7], ym[7], -9357, 49152));
+				npc.setIsImmobilized(true);
+				_minions.add(npc);
+				
+				xm[8] = (xm[0] + xm[4]) / 2;
+				ym[8] = (ym[0] + ym[4]) / 2;
+				_minions.add(addSpawn(FAKE_BELETH, new Location(xm[8], ym[8], -9357, 49152)));
+				xm[9] = (xm[4] + xm[1]) / 2;
+				ym[9] = (ym[4] + ym[1]) / 2;
+				_minions.add(addSpawn(FAKE_BELETH, new Location(xm[9], ym[9], -9357, 49152)));
+				xm[10] = (xm[1] + xm[5]) / 2;
+				ym[10] = (ym[1] + ym[5]) / 2;
+				_minions.add(addSpawn(FAKE_BELETH, new Location(xm[10], ym[10], -9357, 49152)));
+				xm[11] = (xm[5] + xm[2]) / 2;
+				ym[11] = (ym[5] + ym[2]) / 2;
+				_minions.add(addSpawn(FAKE_BELETH, new Location(xm[11], ym[11], -9357, 49152)));
+				xm[12] = (xm[2] + xm[6]) / 2;
+				ym[12] = (ym[2] + ym[6]) / 2;
+				_minions.add(addSpawn(FAKE_BELETH, new Location(xm[12], ym[12], -9357, 49152)));
+				xm[13] = (xm[6] + xm[3]) / 2;
+				ym[13] = (ym[6] + ym[3]) / 2;
+				_minions.add(addSpawn(FAKE_BELETH, new Location(xm[13], ym[13], -9357, 49152)));
+				xm[14] = (xm[3] + xm[7]) / 2;
+				ym[14] = (ym[3] + ym[7]) / 2;
+				_minions.add(addSpawn(FAKE_BELETH, new Location(xm[14], ym[14], -9357, 49152)));
+				xm[15] = (xm[7] + xm[0]) / 2;
+				ym[15] = (ym[7] + ym[0]) / 2;
+				_minions.add(addSpawn(FAKE_BELETH, new Location(xm[15], ym[15], -9357, 49152)));
+				
+				_allowedObjId = _minions.get(getRandom(_minions.size())).getObjectId();
+			}
+			case "SPAWN_REAL":
+			{
+				_beleth = addSpawn(REAL_BELETH, new Location(16323, 213170, -9357, 49152));
+			}
+			case "SPAWN26":
+			{
+				_beleth.doDie(null);
+				
+				_camera1 = addSpawn(29122, new Location(16323, 213170, -9357));
+				_camera1.broadcastPacket(new PlaySound(1, "BS07_D", 1, _camera1.getObjectId(), _camera1.getX(), _camera1.getY(), _camera1.getZ()));
+				
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 400, 290, 25, 0, 10000, 0, 0, 1, 0, 0));
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 400, 290, 25, 0, 10000, 0, 0, 1, 0, 0));
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 400, 110, 25, 4000, 10000, 0, 0, 1, 0, 0));
+				ZONE.broadcastPacket(new SocialAction(_beleth.getObjectId(), 5));
+				
+				startQuestTimer("SPAWN27", 4000, null, null);
+			}
+			case "SPAWN27":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 400, 295, 25, 4000, 5000, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN28", 4500, null, null);
+			}
+			case "SPAWN28":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 400, 295, 10, 4000, 11000, 0, 25, 1, 0, 0));
+				
+				startQuestTimer("SPAWN29", 9000, null, null);
+			}
+			case "SPAWN29":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 250, 90, 25, 0, 1000, 0, 0, 1, 0, 0));
+				ZONE.broadcastPacket(new SpecialCamera(_camera1, 250, 90, 25, 0, 10000, 0, 0, 1, 0, 0));
+				
+				startQuestTimer("SPAWN30", 2000, null, null);
+			}
+			case "SPAWN30":
+			{
+				_priest.spawnMe();
+				_beleth.deleteMe();
+				
+				_camera2 = addSpawn(29121, new Location(14056, 213170, -9357));
+				
+				startQuestTimer("SPAWN31", 3500, null, null);
+			}
+			case "SPAWN31":
+			{
+				ZONE.broadcastPacket(new SpecialCamera(_camera2, 800, 180, 0, 0, 4000, 0, 10, 1, 0, 0));
+				ZONE.broadcastPacket(new SpecialCamera(_camera2, 800, 180, 0, 0, 4000, 0, 10, 1, 0, 0));
+				
+				L2DoorInstance door2 = DoorData.getInstance().getDoor(DOOR2);
+				door2.openMe();
+				
+				ZONE.broadcastPacket(new StaticObject(door2, false));
+				ZONE.broadcastPacket(new DoorStatusUpdate(door2));
+				
+				DoorData.getInstance().getDoor(DOOR3).openMe();
+				
+				_camera1.deleteMe();
+				_camera2.deleteMe();
+				_whirpool.deleteMe();
+				
+				for (L2Character c : ZONE.getCharactersInside())
+				{
+					c.enableAllSkills();
+					c.setIsInvul(false);
+					c.setIsImmobilized(false);
+				}
+			}
 		}
 		return super.onAdvEvent(event, npc, player);
 	}
@@ -369,142 +509,62 @@ public final class Beleth extends AbstractNpcAI
 	@Override
 	public String onEnterZone(L2Character character, L2ZoneType zone)
 	{
-		if (((character.isPlayer()) && (GrandBossManager.getInstance().getBossStatus(BELETH_ID_1) == 1)) || (DEBUG && (GrandBossManager.getInstance().getBossStatus(BELETH_ID_1) != 2) && (character.isPlayer())))
+		if (character.isPlayer() && (GrandBossManager.getInstance().getBossStatus(REAL_BELETH) == INIT))
 		{
-			startSpawnTask();
-			GrandBossManager.getInstance().setBossStatus(BELETH_ID_1, 2);
-		}
-		
-		return super.onEnterZone(character, zone);
-	}
-	
-	@Override
-	public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
-	{
-		if ((npc.getId() == BELETH_ID_1) && (killer != null))
-		{
-			setBelethKiller(killer);
-			GrandBossManager.getInstance().setBossStatus(BELETH_ID_1, 3);
-			// Calculate Min and Max respawn times randomly.
-			final long respawnTime = (Config.BELETH_SPAWN_INTERVAL + getRandom(-Config.BELETH_SPAWN_RANDOM, Config.BELETH_SPAWN_RANDOM)) * 3600000;
-			StatsSet info = GrandBossManager.getInstance().getStatsSet(BELETH_ID_1);
-			info.set("respawn_time", System.currentTimeMillis() + respawnTime);
-			GrandBossManager.getInstance().setStatsSet(BELETH_ID_1, info);
-			startQuestTimer("UNLOCK", respawnTime, null, null);
-			deleteAll();
-			npc.deleteMe();
-			MOVIE = true;
-			BELETH = addSpawn(BELETH_ID_1, new Location(16323, 213170, -9357, 49152));
-			BELETH.setIsInvul(true);
-			BELETH.setIsImmobilized(true);
-			BELETH.disableAllSkills();
-			PRIEST = addSpawn(29128, new Location(BELETH));
-			PRIEST.setShowSummonAnimation(true);
-			PRIEST.decayMe();
-			addSpawn(32470, new Location(12470, 215607, -9381, 49152));
-			ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(27), 1000);
-		}
-		else if (npc.getId() == BELETH_ID_2)
-		{
-			if (npc.getObjectId() == ALLOW_OBJECT_ID)
+			if (_priest != null)
 			{
-				MINIONS.remove(npc);
-				KILLED++;
-				if (KILLED >= 5)
-				{
-					deleteAll();
-					setSpawnTimer(1);
-				}
-				else
-				{
-					ALLOW_OBJECT_ID = MINIONS.get(getRandom(MINIONS.size())).getObjectId();
-					ATTACKED = false;
-				}
+				_priest.deleteMe();
 			}
-			else if (SPAWN_TIMER == null)
+			if (_stone != null)
 			{
-				deleteAll();
-				setSpawnTimer(2);
-				KILLED = 0;
+				_stone.deleteMe();
 			}
-			npc.abortCast();
-			npc.setTarget(null);
-			npc.deleteMe();
+			
+			GrandBossManager.getInstance().setBossStatus(REAL_BELETH, FIGHT);
+			startQuestTimer("SPAWN1", 300000, null, null);
 		}
-		return null;
+		
+		return super.onEnterZone(character, zone);
 	}
 	
 	@Override
 	public String onSkillSee(L2Npc npc, L2PcInstance player, Skill skill, L2Object[] targets, boolean isSummon)
 	{
-		if ((npc != null) && !npc.isDead() && ((npc.getId() == BELETH_ID_1) || (npc.getId() == BELETH_ID_2)) && !npc.isCastingNow() && skill.hasEffectType(L2EffectType.HEAL) && (getRandom(100) < 80))
+		if (!npc.isDead() && (npc.getId() == REAL_BELETH) && !npc.isCastingNow() && skill.hasEffectType(L2EffectType.HEAL) && (getRandom(100) < 80))
 		{
 			npc.setTarget(player);
 			npc.doCast(HORN_OF_RISING.getSkill());
 		}
+		
 		return null;
 	}
 	
 	@Override
-	public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
+	public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
 	{
-		if (npc == null)
+		if (!npc.isDead() && !npc.isCastingNow())
 		{
-			return super.onAttack(npc, attacker, damage, isSummon);
-		}
-		
-		if ((npc.getId() == BELETH_ID_1) || (npc.getId() == BELETH_ID_2))
-		{
-			if ((npc.getObjectId() == ALLOW_OBJECT_ID) && !ATTACKED)
-			{
-				ATTACKED = true;
-				L2Npc fakeBeleth = MINIONS.get(getRandom(MINIONS.size()));
-				while (fakeBeleth.getObjectId() == ALLOW_OBJECT_ID)
-				{
-					fakeBeleth = MINIONS.get(getRandom(MINIONS.size()));
-				}
-				ZONE.broadcastPacket(new CreatureSay(fakeBeleth.getObjectId(), 0, fakeBeleth.getName(), "Miss text.")); // TODO: Find retail text.
-			}
 			if (getRandom(100) < 40)
-			{
-				return null;
-			}
-			final double distance = npc.calculateDistance(attacker, false, false);
-			if ((distance > 500) || (getRandom(100) < 80))
-			{
-				for (L2Npc beleth : MINIONS)
-				{
-					if ((beleth != null) && !beleth.isDead() && Util.checkIfInRange(900, beleth, attacker, false) && !beleth.isCastingNow())
-					{
-						beleth.setTarget(attacker);
-						beleth.doCast(FIREBALL.getSkill());
-					}
-				}
-				if ((BELETH != null) && !BELETH.isDead() && Util.checkIfInRange(900, BELETH, attacker, false) && !BELETH.isCastingNow())
-				{
-					BELETH.setTarget(attacker);
-					BELETH.doCast(FIREBALL.getSkill());
-				}
-			}
-			else if (!npc.isDead() && !npc.isCastingNow())
 			{
 				if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
 				{
-					npc.doCast(LIGHTENING.getSkill());
+					npc.doCast(BLEED.getSkill());
 					return null;
 				}
-				((L2Attackable) npc).clearAggroList();
 			}
+			npc.setTarget(player);
+			npc.doCast(FIREBALL.getSkill());
 		}
+		
 		return null;
 	}
 	
 	@Override
 	public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
 	{
-		if ((npc != null) && !npc.isDead() && ((npc.getId() == BELETH_ID_1) || (npc.getId() == BELETH_ID_2)) && !npc.isCastingNow())
+		if (!npc.isDead() && !npc.isCastingNow())
 		{
-			if ((player != null) && !player.isDead())
+			if (!player.isDead())
 			{
 				final double distance2 = npc.calculateDistance(player, false, false);
 				if ((distance2 > 890) && !npc.isMovementDisabled())
@@ -542,200 +602,172 @@ public final class Beleth extends AbstractNpcAI
 	}
 	
 	@Override
-	public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
+	public String onSpawn(L2Npc npc)
 	{
-		if ((npc != null) && !npc.isDead() && ((npc.getId() == BELETH_ID_1) || (npc.getId() == BELETH_ID_2)) && !npc.isCastingNow() && !MOVIE)
+		npc.setRunning();
+		if (!npc.getKnownList().getKnownPlayersInRadius(300).isEmpty() && (getRandom(100) < 60))
 		{
-			if (getRandom(100) < 40)
-			{
-				if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
-				{
-					npc.doCast(BLEED.getSkill());
-					return null;
-				}
-			}
-			npc.setTarget(player);
-			npc.doCast(FIREBALL.getSkill());
+			npc.doCast(BLEED.getSkill());
 		}
-		return null;
-	}
-	
-	@Override
-	public String onSpawn(L2Npc npc)
-	{
-		if ((npc.getId() == BELETH_ID_1) || (npc.getId() == BELETH_ID_2))
+		if (npc.getId() == REAL_BELETH)
 		{
-			npc.setRunning();
-			if (!MOVIE && !npc.getKnownList().getKnownPlayersInRadius(300).isEmpty() && (getRandom(100) < 60))
-			{
-				npc.doCast(BLEED.getSkill());
-			}
-			if (npc.getId() == BELETH_ID_1)
-			{
-				npc.getSpawn().setRespawnDelay(0);// setOnKillDelay
-			}
+			npc.getSpawn().setRespawnDelay(0);
 		}
+		
 		return null;
 	}
 	
 	@Override
 	public String onTalk(L2Npc npc, L2PcInstance player)
 	{
-		final String html;
-		if ((BELETH_KILLER != null) && (player.getObjectId() == BELETH_KILLER.getObjectId()))
+		String html;
+		if ((_killer != null) && (player.getObjectId() == _killer.getObjectId()))
 		{
-			player.addItem("Kill Beleth", 10314, 1, null, true);// giveItems(10314, 1, 0)
-			BELETH_KILLER = null;
+			_killer = null;
+			
+			giveItems(player, RING);
+			
 			html = "32470a.htm";
 		}
 		else
 		{
 			html = "32470b.htm";
 		}
+		
 		return HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "data/html/default/" + html);
 	}
 	
 	@Override
 	public String onFirstTalk(L2Npc npc, L2PcInstance player)
 	{
-		return null;
+		return onTalk(npc, player);
 	}
 	
-	private static void setBelethKiller(L2PcInstance killer)
+	@Override
+	public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
 	{
-		if (killer.getParty() != null)
+		if (getRandom(100) < 40)
 		{
-			if (killer.getParty().getCommandChannel() != null)
+			return null;
+		}
+		
+		final double distance = npc.calculateDistance(attacker, false, false);
+		if ((distance > 500) || (getRandom(100) < 80))
+		{
+			for (L2Npc beleth : _minions)
 			{
-				BELETH_KILLER = killer.getParty().getCommandChannel().getLeader();
+				if ((beleth != null) && !beleth.isDead() && Util.checkIfInRange(900, beleth, attacker, false) && !beleth.isCastingNow())
+				{
+					beleth.setTarget(attacker);
+					beleth.doCast(FIREBALL.getSkill());
+				}
 			}
-			else
+			if ((_beleth != null) && !_beleth.isDead() && Util.checkIfInRange(900, _beleth, attacker, false) && !_beleth.isCastingNow())
 			{
-				BELETH_KILLER = killer.getParty().getLeader();
+				_beleth.setTarget(attacker);
+				_beleth.doCast(FIREBALL.getSkill());
 			}
 		}
-		else
+		else if (!npc.isDead() && !npc.isCastingNow())
 		{
-			BELETH_KILLER = killer;
+			if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
+			{
+				npc.doCast(LIGHTENING.getSkill());
+				return null;
+			}
+			((L2Attackable) npc).clearAggroList();
 		}
+		
+		return null;
 	}
 	
-	protected static void setSpawnTimer(int event)
+	@Override
+	public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
 	{
-		switch (event)
+		if (npc.getId() == REAL_BELETH)
 		{
-			case 0:
-				SPAWN_TIMER = null;
-				break;
-			case 1:
-				SPAWN_TIMER = ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(333), 60000);
-				break;
-			case 2:
-				SPAWN_TIMER = ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(26), 60000);
-				break;
-			default:
-				break;
+			setBelethKiller(killer);
+			GrandBossManager.getInstance().setBossStatus(REAL_BELETH, DEAD);
+			final long respawnTime = (Config.BELETH_SPAWN_INTERVAL + getRandom(-Config.BELETH_SPAWN_RANDOM, Config.BELETH_SPAWN_RANDOM)) * 3600000;
+			StatsSet info = GrandBossManager.getInstance().getStatsSet(REAL_BELETH);
+			info.set("respawn_time", System.currentTimeMillis() + respawnTime);
+			GrandBossManager.getInstance().setStatsSet(REAL_BELETH, info);
+			startQuestTimer("BELETH_UNLOCK", respawnTime, null, null);
+			
+			deleteAll();
+			npc.deleteMe();
+			
+			for (L2Character c : ZONE.getCharactersInside())
+			{
+				c.disableAllSkills();
+				c.setIsInvul(true);
+				c.setIsImmobilized(true);
+			}
+			
+			_beleth = addSpawn(REAL_BELETH, new Location(16323, 213170, -9357, 49152));
+			_beleth.disableAllSkills();
+			_beleth.setIsInvul(true);
+			_beleth.setIsImmobilized(true);
+			
+			_priest = addSpawn(ELF, new Location(_beleth));
+			_priest.setShowSummonAnimation(true);
+			_priest.decayMe();
+			
+			_stone = addSpawn(STONE_COFFIN, new Location(12470, 215607, -9381, 49152));
+			
+			startQuestTimer("SPAWN26", 1000, null, null);
 		}
-	}
-	
-	private static void deleteAll()
-	{
-		if ((MINIONS != null) && !MINIONS.isEmpty())
+		else if ((npc.getId() == FAKE_BELETH) && (npc.getObjectId() == _allowedObjId))
 		{
-			for (L2Npc npc : MINIONS)
+			deleteAll();
+			
+			_killedCount++;
+			if (_killedCount >= 5)
 			{
-				if (npc.isDead())
-				{
-					continue;
-				}
-				npc.abortCast();
-				npc.setTarget(null);
-				npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
-				npc.deleteMe();
+				startQuestTimer("SPAWN_REAL", 60000, null, null);
+			}
+			else
+			{
+				startQuestTimer("SPAWN25", 60000, null, null);
 			}
-			MINIONS.clear();
 		}
-		ALLOW_OBJECT_ID = 0;
-		ATTACKED = false;
+		
+		return null;
 	}
 	
-	protected static void SpawnBeleths()
+	private void setBelethKiller(L2PcInstance killer)
 	{
-		int a = 0;
-		L2Npc npc;
-		for (int i = 0; i < 16; i++)
+		if (killer.getParty() != null)
 		{
-			a++;
-			int x = (int) ((650 * Math.cos(i * 0.39)) + 16323);
-			int y = (int) ((650 * Math.sin(i * 0.39)) + 213170);
-			npc = addSpawn(BELETH_ID_2, new Location(x, y, -9357, 49152));
-			MINIONS.add(npc);
-			if (a >= 2)
+			if (killer.getParty().getCommandChannel() != null)
 			{
-				npc.setIsOverloaded(true);
-				a = 0;
+				_killer = killer.getParty().getCommandChannel().getLeader();
+			}
+			else
+			{
+				_killer = killer.getParty().getLeader();
 			}
 		}
-		int[] xm = new int[16];
-		int[] ym = new int[16];
-		for (int i = 0; i < 4; i++)
+		else
 		{
-			xm[i] = (int) ((1700 * Math.cos((i * 1.57) + 0.78)) + 16323);
-			ym[i] = (int) ((1700 * Math.sin((i * 1.57) + 0.78)) + 213170);
-			npc = addSpawn(BELETH_ID_2, new Location(xm[i], ym[i], -9357, 49152));
-			npc.setIsImmobilized(true);
-			MINIONS.add(npc);
+			_killer = killer;
 		}
-		xm[4] = (xm[0] + xm[1]) / 2;
-		ym[4] = (ym[0] + ym[1]) / 2;
-		npc = addSpawn(BELETH_ID_2, new Location(xm[4], ym[4], -9357, 49152));
-		npc.setIsImmobilized(true);
-		MINIONS.add(npc);
-		xm[5] = (xm[1] + xm[2]) / 2;
-		ym[5] = (ym[1] + ym[2]) / 2;
-		npc = addSpawn(BELETH_ID_2, new Location(xm[5], ym[5], -9357, 49152));
-		npc.setIsImmobilized(true);
-		MINIONS.add(npc);
-		xm[6] = (xm[2] + xm[3]) / 2;
-		ym[6] = (ym[2] + ym[3]) / 2;
-		npc = addSpawn(BELETH_ID_2, new Location(xm[6], ym[6], -9357, 49152));
-		npc.setIsImmobilized(true);
-		MINIONS.add(npc);
-		xm[7] = (xm[3] + xm[0]) / 2;
-		ym[7] = (ym[3] + ym[0]) / 2;
-		npc = addSpawn(BELETH_ID_2, new Location(xm[7], ym[7], -9357, 49152));
-		npc.setIsImmobilized(true);
-		MINIONS.add(npc);
-		xm[8] = (xm[0] + xm[4]) / 2;
-		ym[8] = (ym[0] + ym[4]) / 2;
-		MINIONS.add(addSpawn(BELETH_ID_2, new Location(xm[8], ym[8], -9357, 49152)));
-		xm[9] = (xm[4] + xm[1]) / 2;
-		ym[9] = (ym[4] + ym[1]) / 2;
-		MINIONS.add(addSpawn(BELETH_ID_2, new Location(xm[9], ym[9], -9357, 49152)));
-		xm[10] = (xm[1] + xm[5]) / 2;
-		ym[10] = (ym[1] + ym[5]) / 2;
-		MINIONS.add(addSpawn(BELETH_ID_2, new Location(xm[10], ym[10], -9357, 49152)));
-		xm[11] = (xm[5] + xm[2]) / 2;
-		ym[11] = (ym[5] + ym[2]) / 2;
-		MINIONS.add(addSpawn(BELETH_ID_2, new Location(xm[11], ym[11], -9357, 49152)));
-		xm[12] = (xm[2] + xm[6]) / 2;
-		ym[12] = (ym[2] + ym[6]) / 2;
-		MINIONS.add(addSpawn(BELETH_ID_2, new Location(xm[12], ym[12], -9357, 49152)));
-		xm[13] = (xm[6] + xm[3]) / 2;
-		ym[13] = (ym[6] + ym[3]) / 2;
-		MINIONS.add(addSpawn(BELETH_ID_2, new Location(xm[13], ym[13], -9357, 49152)));
-		xm[14] = (xm[3] + xm[7]) / 2;
-		ym[14] = (ym[3] + ym[7]) / 2;
-		MINIONS.add(addSpawn(BELETH_ID_2, new Location(xm[14], ym[14], -9357, 49152)));
-		xm[15] = (xm[7] + xm[0]) / 2;
-		ym[15] = (ym[7] + ym[0]) / 2;
-		MINIONS.add(addSpawn(BELETH_ID_2, new Location(xm[15], ym[15], -9357, 49152)));
-		ALLOW_OBJECT_ID = MINIONS.get(getRandom(MINIONS.size())).getObjectId();
-		ATTACKED = false;
+	}
+	
+	private void deleteAll()
+	{
+		_minions.stream().filter(n -> !n.isDead()).forEach(n ->
+		{
+			n.abortCast();
+			n.setTarget(null);
+			n.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+			n.deleteMe();
+		});
+		_allowedObjId = 0;
 	}
 	
 	public static void main(String[] args)
 	{
 		new Beleth();
 	}
-}
+}