diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java
new file mode 100644
index 0000000000..f76b4463cb
--- /dev/null
+++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java
@@ -0,0 +1,141 @@
+/*
+ * This file is part of the L2J Mobius project.
+ * 
+ * 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 .
+ */
+package ai.areas.SeaOfSpores;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.SkillHolder;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author NviX
+ */
+public class SeaOfSpores extends AbstractNpcAI
+{
+	// Mobs
+	private static final int[] GROUP_MOBS =
+	{
+		24227, // Keros
+		24228, // Falena
+		24229, // Atrofa
+		24230, // Nuba
+		24231 // Torfedo
+	};
+	private static final int[] SOLO_MOBS =
+	{
+		24234, // Lesatanas
+		24235, // Arbor
+		24236, // Tergus
+		24237, // Skeletus
+		24238, // Atrofine
+	};
+	// Special Mobs
+	private static final int ARANEA = 24226;
+	private static final int ARIMA = 24232;
+	private static final int HARANE = 24233;
+	private static final int ARIMUS = 24239;
+	// Skills
+	private static final SkillHolder ABSORB_ENERGY1 = new SkillHolder(32483, 1);
+	private static final SkillHolder ABSORB_ENERGY2 = new SkillHolder(32481, 1);
+	private static final SkillHolder REFINED_ENERGY = new SkillHolder(32485, 1);
+	
+	private SeaOfSpores()
+	{
+		addAttackId(ARIMA, ARIMUS);
+		addKillId(SOLO_MOBS);
+		addKillId(GROUP_MOBS);
+		addKillId(ARIMA, ARIMUS);
+	}
+	
+	@Override
+	public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
+	{
+		if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.7)) && !npc.isCastingNow())
+		{
+			if (npc.getId() == ARIMA)
+			{
+				npc.doCast(ABSORB_ENERGY2.getSkill());
+			}
+			else if (npc.getId() == ARIMUS)
+			{
+				npc.doCast(ABSORB_ENERGY1.getSkill());
+			}
+		}
+		return super.onAttack(npc, attacker, damage, isSummon);
+	}
+	
+	@Override
+	public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+	{
+		if (CommonUtil.contains(SOLO_MOBS, npc.getId()) && (getRandom(1000) < 2))
+		{
+			addSpawn(ARIMUS, npc, false, 300000);
+		}
+		else if (CommonUtil.contains(GROUP_MOBS, npc.getId()) && (getRandom(1000) < 2))
+		{
+			addSpawn(ARIMA, npc, false, 300000);
+		}
+		else if (npc.getId() == ARIMA)
+		{
+			List members = new ArrayList<>();
+			if (killer.getParty() != null)
+			{
+				members = killer.getParty().getMembers();
+			}
+			else
+			{
+				members.add(killer);
+			}
+			for (PlayerInstance member : members)
+			{
+				member.doCast(REFINED_ENERGY.getSkill());
+			}
+			if (getRandom(1000) < 2)
+			{
+				addSpawn(ARANEA, npc, false, 300000);
+				addSpawn(HARANE, npc, false, 300000);
+			}
+		}
+		else if (npc.getId() == ARIMUS)
+		{
+			List members = new ArrayList<>();
+			if (killer.getParty() != null)
+			{
+				members = killer.getParty().getMembers();
+			}
+			else
+			{
+				members.add(killer);
+			}
+			for (PlayerInstance member : members)
+			{
+				member.doCast(REFINED_ENERGY.getSkill());
+			}
+		}
+		return super.onKill(npc, killer, isSummon);
+	}
+	
+	public static void main(String[] args)
+	{
+		new SeaOfSpores();
+	}
+}
diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
index ba7b1b9681..8f5d996e6c 100644
--- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
+++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
@@ -23,20 +23,14 @@ import org.l2jmobius.Config;
 import org.l2jmobius.gameserver.ai.CtrlIntention;
 import org.l2jmobius.gameserver.enums.ChatType;
 import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
-import org.l2jmobius.gameserver.instancemanager.ZoneManager;
 import org.l2jmobius.gameserver.model.Location;
-import org.l2jmobius.gameserver.model.Spawn;
 import org.l2jmobius.gameserver.model.StatSet;
-import org.l2jmobius.gameserver.model.WorldObject;
 import org.l2jmobius.gameserver.model.actor.Attackable;
-import org.l2jmobius.gameserver.model.actor.Creature;
 import org.l2jmobius.gameserver.model.actor.Npc;
 import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
 import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
 import org.l2jmobius.gameserver.model.holders.SkillHolder;
-import org.l2jmobius.gameserver.model.skills.Skill;
 import org.l2jmobius.gameserver.model.skills.SkillCaster;
-import org.l2jmobius.gameserver.model.zone.ZoneType;
 import org.l2jmobius.gameserver.network.NpcStringId;
 import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
 
@@ -48,13 +42,7 @@ import ai.AbstractNpcAI;
  */
 public class Orfen extends AbstractNpcAI
 {
-	private static final Location[] POS =
-	{
-		new Location(43200, 16304, -4395),
-		new Location(43300, 16404, -4395),
-		new Location(43400, 16504, -4395),
-		new Location(43500, 16604, -4395)
-	};
+	private static final Location POS = new Location(43728, 17220, -4342);
 	
 	private static final NpcStringId[] TEXT =
 	{
@@ -65,21 +53,26 @@ public class Orfen extends AbstractNpcAI
 	};
 	
 	private static final int ORFEN = 29325;
-	// private static final int RAIKEL = 29015;
 	private static final int ARIMA = 29326;
-	// private static final int RIBA = 29017;
 	private static final int ARIMUS = 29327;
 	
-	private static boolean _IsTeleported;
 	private static Set _minions = ConcurrentHashMap.newKeySet();
-	private static ZoneType ZONE;
 	
 	private static final byte ALIVE = 0;
 	private static final byte DEAD = 1;
 	
-	private static final SkillHolder PARALYSIS = new SkillHolder(4064, 1);
 	private static final SkillHolder BLOW = new SkillHolder(4067, 4);
 	private static final SkillHolder ORFEN_HEAL = new SkillHolder(4516, 1);
+	private static final SkillHolder ORFEN_SLASHER = new SkillHolder(32486, 1);
+	private static final SkillHolder ORFEN_FATAL_SLASHER = new SkillHolder(32487, 1);
+	private static final SkillHolder ORFEN_ENERGY_SCATTER = new SkillHolder(32488, 1);
+	private static final SkillHolder ORFEN_FURY_ENERGY_WAVE = new SkillHolder(32489, 1);
+	private static final SkillHolder YOKE_OF_ORFEN = new SkillHolder(32490, 1);
+	private static final SkillHolder ORFEN_BLOW_UP = new SkillHolder(32491, 1);
+	private static final SkillHolder ORFEN_FATAL_STAMP = new SkillHolder(32492, 1);
+	private static final SkillHolder ORFEN_RAISE_SPORE = new SkillHolder(32493, 1);
+	private static final SkillHolder HALLUCINATING_DUST = new SkillHolder(32494, 1);
+	private static final SkillHolder ORFEN_RAGE = new SkillHolder(32495, 1);
 	
 	private Orfen()
 	{
@@ -90,8 +83,6 @@ public class Orfen extends AbstractNpcAI
 			ARIMUS
 		};
 		registerMobs(mobs);
-		_IsTeleported = false;
-		ZONE = ZoneManager.getInstance().getZoneById(12013);
 		final StatSet info = GrandBossManager.getInstance().getStatSet(ORFEN);
 		final int status = GrandBossManager.getInstance().getBossStatus(ORFEN);
 		if (status == DEAD)
@@ -107,21 +98,7 @@ public class Orfen extends AbstractNpcAI
 			else
 			{
 				// the time has already expired while the server was offline. Immediately spawn Orfen.
-				final int i = getRandom(10);
-				Location loc;
-				if (i < 4)
-				{
-					loc = POS[1];
-				}
-				else if (i < 7)
-				{
-					loc = POS[2];
-				}
-				else
-				{
-					loc = POS[3];
-				}
-				final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
+				final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0);
 				GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
 				spawnBoss(orfen);
 			}
@@ -140,20 +117,10 @@ public class Orfen extends AbstractNpcAI
 		}
 	}
 	
-	public void setSpawnPoint(Npc npc, int index)
-	{
-		((Attackable) npc).clearAggroList();
-		npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
-		final Spawn spawn = npc.getSpawn();
-		spawn.setLocation(POS[index]);
-		npc.teleToLocation(POS[index], false);
-	}
-	
 	public void spawnBoss(GrandBossInstance npc)
 	{
 		GrandBossManager.getInstance().addBoss(npc);
 		npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
-		startQuestTimer("check_orfen_pos", 10000, npc, null, true);
 		// Spawn minions
 		final int x = npc.getX();
 		final int y = npc.getY();
@@ -178,36 +145,10 @@ public class Orfen extends AbstractNpcAI
 	{
 		if (event.equalsIgnoreCase("orfen_unlock"))
 		{
-			final int i = getRandom(10);
-			Location loc;
-			if (i < 4)
-			{
-				loc = POS[1];
-			}
-			else if (i < 7)
-			{
-				loc = POS[2];
-			}
-			else
-			{
-				loc = POS[3];
-			}
-			final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
+			final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0);
 			GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
 			spawnBoss(orfen);
 		}
-		else if (event.equalsIgnoreCase("check_orfen_pos"))
-		{
-			if ((_IsTeleported && (npc.getCurrentHp() > (npc.getMaxHp() * 0.95))) || (!ZONE.isInsideZone(npc) && !_IsTeleported))
-			{
-				setSpawnPoint(npc, getRandom(3) + 1);
-				_IsTeleported = false;
-			}
-			else if (_IsTeleported && !ZONE.isInsideZone(npc))
-			{
-				setSpawnPoint(npc, 0);
-			}
-		}
 		else if (event.equalsIgnoreCase("check_minion_loc"))
 		{
 			for (Attackable mob : _minions)
@@ -237,23 +178,6 @@ public class Orfen extends AbstractNpcAI
 		return super.onAdvEvent(event, npc, player);
 	}
 	
-	@Override
-	public String onSkillSee(Npc npc, PlayerInstance caster, Skill skill, WorldObject[] targets, boolean isSummon)
-	{
-		if (npc.getId() == ORFEN)
-		{
-			final Creature originalCaster = isSummon ? caster.getServitors().values().stream().findFirst().orElse(caster.getPet()) : caster;
-			if ((skill.getEffectPoint() > 0) && (getRandom(5) == 0) && npc.isInsideRadius2D(originalCaster, 1000))
-			{
-				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(4)], caster.getName());
-				originalCaster.teleToLocation(npc.getLocation());
-				npc.setTarget(originalCaster);
-				npc.doCast(PARALYSIS.getSkill());
-			}
-		}
-		return super.onSkillSee(npc, caster, skill, targets, isSummon);
-	}
-	
 	@Override
 	public String onFactionCall(Npc npc, Npc caller, PlayerInstance attacker, boolean isSummon)
 	{
@@ -291,17 +215,65 @@ public class Orfen extends AbstractNpcAI
 		final int npcId = npc.getId();
 		if (npcId == ORFEN)
 		{
-			if (!_IsTeleported && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2)))
-			{
-				_IsTeleported = true;
-				setSpawnPoint(npc, 0);
-			}
-			else if (npc.isInsideRadius2D(attacker, 1000) && !npc.isInsideRadius2D(attacker, 300) && (getRandom(10) == 0))
+			if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
 			{
 				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
-				attacker.teleToLocation(npc.getLocation());
 				npc.setTarget(attacker);
-				npc.doCast(PARALYSIS.getSkill());
+				npc.doCast(ORFEN_FATAL_SLASHER.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_ENERGY_SCATTER.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_FURY_ENERGY_WAVE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(YOKE_OF_ORFEN.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_BLOW_UP.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_FATAL_STAMP.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_RAISE_SPORE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(HALLUCINATING_DUST.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0) && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5)))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_RAGE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_SLASHER.getSkill());
 			}
 		}
 		else if (npcId == ARIMUS)
@@ -315,6 +287,15 @@ public class Orfen extends AbstractNpcAI
 		return super.onAttack(npc, attacker, damage, isSummon);
 	}
 	
+	private boolean manageSkills(Npc npc)
+	{
+		if (npc.isCastingNow())
+		{
+			return false;
+		}
+		return true;
+	}
+	
 	@Override
 	public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
 	{
@@ -331,7 +312,6 @@ public class Orfen extends AbstractNpcAI
 			info.set("respawn_time", System.currentTimeMillis() + respawnTime);
 			GrandBossManager.getInstance().setStatSet(ORFEN, info);
 			cancelQuestTimer("check_minion_loc", npc, null);
-			cancelQuestTimer("check_orfen_pos", npc, null);
 			startQuestTimer("despawn_minions", 20000, null, null);
 			cancelQuestTimers("spawn_minion");
 		}
diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java
new file mode 100644
index 0000000000..f76b4463cb
--- /dev/null
+++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java
@@ -0,0 +1,141 @@
+/*
+ * This file is part of the L2J Mobius project.
+ * 
+ * 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 .
+ */
+package ai.areas.SeaOfSpores;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.SkillHolder;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author NviX
+ */
+public class SeaOfSpores extends AbstractNpcAI
+{
+	// Mobs
+	private static final int[] GROUP_MOBS =
+	{
+		24227, // Keros
+		24228, // Falena
+		24229, // Atrofa
+		24230, // Nuba
+		24231 // Torfedo
+	};
+	private static final int[] SOLO_MOBS =
+	{
+		24234, // Lesatanas
+		24235, // Arbor
+		24236, // Tergus
+		24237, // Skeletus
+		24238, // Atrofine
+	};
+	// Special Mobs
+	private static final int ARANEA = 24226;
+	private static final int ARIMA = 24232;
+	private static final int HARANE = 24233;
+	private static final int ARIMUS = 24239;
+	// Skills
+	private static final SkillHolder ABSORB_ENERGY1 = new SkillHolder(32483, 1);
+	private static final SkillHolder ABSORB_ENERGY2 = new SkillHolder(32481, 1);
+	private static final SkillHolder REFINED_ENERGY = new SkillHolder(32485, 1);
+	
+	private SeaOfSpores()
+	{
+		addAttackId(ARIMA, ARIMUS);
+		addKillId(SOLO_MOBS);
+		addKillId(GROUP_MOBS);
+		addKillId(ARIMA, ARIMUS);
+	}
+	
+	@Override
+	public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
+	{
+		if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.7)) && !npc.isCastingNow())
+		{
+			if (npc.getId() == ARIMA)
+			{
+				npc.doCast(ABSORB_ENERGY2.getSkill());
+			}
+			else if (npc.getId() == ARIMUS)
+			{
+				npc.doCast(ABSORB_ENERGY1.getSkill());
+			}
+		}
+		return super.onAttack(npc, attacker, damage, isSummon);
+	}
+	
+	@Override
+	public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+	{
+		if (CommonUtil.contains(SOLO_MOBS, npc.getId()) && (getRandom(1000) < 2))
+		{
+			addSpawn(ARIMUS, npc, false, 300000);
+		}
+		else if (CommonUtil.contains(GROUP_MOBS, npc.getId()) && (getRandom(1000) < 2))
+		{
+			addSpawn(ARIMA, npc, false, 300000);
+		}
+		else if (npc.getId() == ARIMA)
+		{
+			List members = new ArrayList<>();
+			if (killer.getParty() != null)
+			{
+				members = killer.getParty().getMembers();
+			}
+			else
+			{
+				members.add(killer);
+			}
+			for (PlayerInstance member : members)
+			{
+				member.doCast(REFINED_ENERGY.getSkill());
+			}
+			if (getRandom(1000) < 2)
+			{
+				addSpawn(ARANEA, npc, false, 300000);
+				addSpawn(HARANE, npc, false, 300000);
+			}
+		}
+		else if (npc.getId() == ARIMUS)
+		{
+			List members = new ArrayList<>();
+			if (killer.getParty() != null)
+			{
+				members = killer.getParty().getMembers();
+			}
+			else
+			{
+				members.add(killer);
+			}
+			for (PlayerInstance member : members)
+			{
+				member.doCast(REFINED_ENERGY.getSkill());
+			}
+		}
+		return super.onKill(npc, killer, isSummon);
+	}
+	
+	public static void main(String[] args)
+	{
+		new SeaOfSpores();
+	}
+}
diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
index 29da6a5a6b..8f5d996e6c 100644
--- a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
+++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
@@ -23,20 +23,14 @@ import org.l2jmobius.Config;
 import org.l2jmobius.gameserver.ai.CtrlIntention;
 import org.l2jmobius.gameserver.enums.ChatType;
 import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
-import org.l2jmobius.gameserver.instancemanager.ZoneManager;
 import org.l2jmobius.gameserver.model.Location;
-import org.l2jmobius.gameserver.model.Spawn;
 import org.l2jmobius.gameserver.model.StatSet;
-import org.l2jmobius.gameserver.model.WorldObject;
 import org.l2jmobius.gameserver.model.actor.Attackable;
-import org.l2jmobius.gameserver.model.actor.Creature;
 import org.l2jmobius.gameserver.model.actor.Npc;
 import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
 import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
 import org.l2jmobius.gameserver.model.holders.SkillHolder;
-import org.l2jmobius.gameserver.model.skills.Skill;
 import org.l2jmobius.gameserver.model.skills.SkillCaster;
-import org.l2jmobius.gameserver.model.zone.ZoneType;
 import org.l2jmobius.gameserver.network.NpcStringId;
 import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
 
@@ -48,13 +42,7 @@ import ai.AbstractNpcAI;
  */
 public class Orfen extends AbstractNpcAI
 {
-	private static final Location[] POS =
-	{
-		new Location(43200, 16304, -4395),
-		new Location(43300, 16404, -4395),
-		new Location(43400, 16504, -4395),
-		new Location(43500, 16604, -4395)
-	};
+	private static final Location POS = new Location(43728, 17220, -4342);
 	
 	private static final NpcStringId[] TEXT =
 	{
@@ -68,16 +56,23 @@ public class Orfen extends AbstractNpcAI
 	private static final int ARIMA = 29326;
 	private static final int ARIMUS = 29327;
 	
-	private static boolean _IsTeleported;
 	private static Set _minions = ConcurrentHashMap.newKeySet();
-	private static ZoneType ZONE;
 	
 	private static final byte ALIVE = 0;
 	private static final byte DEAD = 1;
 	
-	private static final SkillHolder PARALYSIS = new SkillHolder(4064, 1);
 	private static final SkillHolder BLOW = new SkillHolder(4067, 4);
 	private static final SkillHolder ORFEN_HEAL = new SkillHolder(4516, 1);
+	private static final SkillHolder ORFEN_SLASHER = new SkillHolder(32486, 1);
+	private static final SkillHolder ORFEN_FATAL_SLASHER = new SkillHolder(32487, 1);
+	private static final SkillHolder ORFEN_ENERGY_SCATTER = new SkillHolder(32488, 1);
+	private static final SkillHolder ORFEN_FURY_ENERGY_WAVE = new SkillHolder(32489, 1);
+	private static final SkillHolder YOKE_OF_ORFEN = new SkillHolder(32490, 1);
+	private static final SkillHolder ORFEN_BLOW_UP = new SkillHolder(32491, 1);
+	private static final SkillHolder ORFEN_FATAL_STAMP = new SkillHolder(32492, 1);
+	private static final SkillHolder ORFEN_RAISE_SPORE = new SkillHolder(32493, 1);
+	private static final SkillHolder HALLUCINATING_DUST = new SkillHolder(32494, 1);
+	private static final SkillHolder ORFEN_RAGE = new SkillHolder(32495, 1);
 	
 	private Orfen()
 	{
@@ -88,8 +83,6 @@ public class Orfen extends AbstractNpcAI
 			ARIMUS
 		};
 		registerMobs(mobs);
-		_IsTeleported = false;
-		ZONE = ZoneManager.getInstance().getZoneById(12013);
 		final StatSet info = GrandBossManager.getInstance().getStatSet(ORFEN);
 		final int status = GrandBossManager.getInstance().getBossStatus(ORFEN);
 		if (status == DEAD)
@@ -105,21 +98,7 @@ public class Orfen extends AbstractNpcAI
 			else
 			{
 				// the time has already expired while the server was offline. Immediately spawn Orfen.
-				final int i = getRandom(10);
-				Location loc;
-				if (i < 4)
-				{
-					loc = POS[1];
-				}
-				else if (i < 7)
-				{
-					loc = POS[2];
-				}
-				else
-				{
-					loc = POS[3];
-				}
-				final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
+				final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0);
 				GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
 				spawnBoss(orfen);
 			}
@@ -138,20 +117,10 @@ public class Orfen extends AbstractNpcAI
 		}
 	}
 	
-	public void setSpawnPoint(Npc npc, int index)
-	{
-		((Attackable) npc).clearAggroList();
-		npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
-		final Spawn spawn = npc.getSpawn();
-		spawn.setLocation(POS[index]);
-		npc.teleToLocation(POS[index], false);
-	}
-	
 	public void spawnBoss(GrandBossInstance npc)
 	{
 		GrandBossManager.getInstance().addBoss(npc);
 		npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
-		startQuestTimer("check_orfen_pos", 10000, npc, null, true);
 		// Spawn minions
 		final int x = npc.getX();
 		final int y = npc.getY();
@@ -176,36 +145,10 @@ public class Orfen extends AbstractNpcAI
 	{
 		if (event.equalsIgnoreCase("orfen_unlock"))
 		{
-			final int i = getRandom(10);
-			Location loc;
-			if (i < 4)
-			{
-				loc = POS[1];
-			}
-			else if (i < 7)
-			{
-				loc = POS[2];
-			}
-			else
-			{
-				loc = POS[3];
-			}
-			final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
+			final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0);
 			GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
 			spawnBoss(orfen);
 		}
-		else if (event.equalsIgnoreCase("check_orfen_pos"))
-		{
-			if ((_IsTeleported && (npc.getCurrentHp() > (npc.getMaxHp() * 0.95))) || (!ZONE.isInsideZone(npc) && !_IsTeleported))
-			{
-				setSpawnPoint(npc, getRandom(3) + 1);
-				_IsTeleported = false;
-			}
-			else if (_IsTeleported && !ZONE.isInsideZone(npc))
-			{
-				setSpawnPoint(npc, 0);
-			}
-		}
 		else if (event.equalsIgnoreCase("check_minion_loc"))
 		{
 			for (Attackable mob : _minions)
@@ -235,23 +178,6 @@ public class Orfen extends AbstractNpcAI
 		return super.onAdvEvent(event, npc, player);
 	}
 	
-	@Override
-	public String onSkillSee(Npc npc, PlayerInstance caster, Skill skill, WorldObject[] targets, boolean isSummon)
-	{
-		if (npc.getId() == ORFEN)
-		{
-			final Creature originalCaster = isSummon ? caster.getServitors().values().stream().findFirst().orElse(caster.getPet()) : caster;
-			if ((skill.getEffectPoint() > 0) && (getRandom(5) == 0) && npc.isInsideRadius2D(originalCaster, 1000))
-			{
-				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(4)], caster.getName());
-				originalCaster.teleToLocation(npc.getLocation());
-				npc.setTarget(originalCaster);
-				npc.doCast(PARALYSIS.getSkill());
-			}
-		}
-		return super.onSkillSee(npc, caster, skill, targets, isSummon);
-	}
-	
 	@Override
 	public String onFactionCall(Npc npc, Npc caller, PlayerInstance attacker, boolean isSummon)
 	{
@@ -289,17 +215,65 @@ public class Orfen extends AbstractNpcAI
 		final int npcId = npc.getId();
 		if (npcId == ORFEN)
 		{
-			if (!_IsTeleported && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2)))
-			{
-				_IsTeleported = true;
-				setSpawnPoint(npc, 0);
-			}
-			else if (npc.isInsideRadius2D(attacker, 1000) && !npc.isInsideRadius2D(attacker, 300) && (getRandom(10) == 0))
+			if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
 			{
 				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
-				attacker.teleToLocation(npc.getLocation());
 				npc.setTarget(attacker);
-				npc.doCast(PARALYSIS.getSkill());
+				npc.doCast(ORFEN_FATAL_SLASHER.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_ENERGY_SCATTER.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_FURY_ENERGY_WAVE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(YOKE_OF_ORFEN.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_BLOW_UP.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_FATAL_STAMP.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_RAISE_SPORE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(HALLUCINATING_DUST.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0) && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5)))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_RAGE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_SLASHER.getSkill());
 			}
 		}
 		else if (npcId == ARIMUS)
@@ -313,6 +287,15 @@ public class Orfen extends AbstractNpcAI
 		return super.onAttack(npc, attacker, damage, isSummon);
 	}
 	
+	private boolean manageSkills(Npc npc)
+	{
+		if (npc.isCastingNow())
+		{
+			return false;
+		}
+		return true;
+	}
+	
 	@Override
 	public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
 	{
@@ -329,7 +312,6 @@ public class Orfen extends AbstractNpcAI
 			info.set("respawn_time", System.currentTimeMillis() + respawnTime);
 			GrandBossManager.getInstance().setStatSet(ORFEN, info);
 			cancelQuestTimer("check_minion_loc", npc, null);
-			cancelQuestTimer("check_orfen_pos", npc, null);
 			startQuestTimer("despawn_minions", 20000, null, null);
 			cancelQuestTimers("spawn_minion");
 		}
diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java
new file mode 100644
index 0000000000..f76b4463cb
--- /dev/null
+++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/areas/SeaOfSpores/SeaOfSpores.java
@@ -0,0 +1,141 @@
+/*
+ * This file is part of the L2J Mobius project.
+ * 
+ * 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 .
+ */
+package ai.areas.SeaOfSpores;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.holders.SkillHolder;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author NviX
+ */
+public class SeaOfSpores extends AbstractNpcAI
+{
+	// Mobs
+	private static final int[] GROUP_MOBS =
+	{
+		24227, // Keros
+		24228, // Falena
+		24229, // Atrofa
+		24230, // Nuba
+		24231 // Torfedo
+	};
+	private static final int[] SOLO_MOBS =
+	{
+		24234, // Lesatanas
+		24235, // Arbor
+		24236, // Tergus
+		24237, // Skeletus
+		24238, // Atrofine
+	};
+	// Special Mobs
+	private static final int ARANEA = 24226;
+	private static final int ARIMA = 24232;
+	private static final int HARANE = 24233;
+	private static final int ARIMUS = 24239;
+	// Skills
+	private static final SkillHolder ABSORB_ENERGY1 = new SkillHolder(32483, 1);
+	private static final SkillHolder ABSORB_ENERGY2 = new SkillHolder(32481, 1);
+	private static final SkillHolder REFINED_ENERGY = new SkillHolder(32485, 1);
+	
+	private SeaOfSpores()
+	{
+		addAttackId(ARIMA, ARIMUS);
+		addKillId(SOLO_MOBS);
+		addKillId(GROUP_MOBS);
+		addKillId(ARIMA, ARIMUS);
+	}
+	
+	@Override
+	public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
+	{
+		if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.7)) && !npc.isCastingNow())
+		{
+			if (npc.getId() == ARIMA)
+			{
+				npc.doCast(ABSORB_ENERGY2.getSkill());
+			}
+			else if (npc.getId() == ARIMUS)
+			{
+				npc.doCast(ABSORB_ENERGY1.getSkill());
+			}
+		}
+		return super.onAttack(npc, attacker, damage, isSummon);
+	}
+	
+	@Override
+	public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+	{
+		if (CommonUtil.contains(SOLO_MOBS, npc.getId()) && (getRandom(1000) < 2))
+		{
+			addSpawn(ARIMUS, npc, false, 300000);
+		}
+		else if (CommonUtil.contains(GROUP_MOBS, npc.getId()) && (getRandom(1000) < 2))
+		{
+			addSpawn(ARIMA, npc, false, 300000);
+		}
+		else if (npc.getId() == ARIMA)
+		{
+			List members = new ArrayList<>();
+			if (killer.getParty() != null)
+			{
+				members = killer.getParty().getMembers();
+			}
+			else
+			{
+				members.add(killer);
+			}
+			for (PlayerInstance member : members)
+			{
+				member.doCast(REFINED_ENERGY.getSkill());
+			}
+			if (getRandom(1000) < 2)
+			{
+				addSpawn(ARANEA, npc, false, 300000);
+				addSpawn(HARANE, npc, false, 300000);
+			}
+		}
+		else if (npc.getId() == ARIMUS)
+		{
+			List members = new ArrayList<>();
+			if (killer.getParty() != null)
+			{
+				members = killer.getParty().getMembers();
+			}
+			else
+			{
+				members.add(killer);
+			}
+			for (PlayerInstance member : members)
+			{
+				member.doCast(REFINED_ENERGY.getSkill());
+			}
+		}
+		return super.onKill(npc, killer, isSummon);
+	}
+	
+	public static void main(String[] args)
+	{
+		new SeaOfSpores();
+	}
+}
diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
index 29da6a5a6b..8f5d996e6c 100644
--- a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
+++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Orfen/Orfen.java
@@ -23,20 +23,14 @@ import org.l2jmobius.Config;
 import org.l2jmobius.gameserver.ai.CtrlIntention;
 import org.l2jmobius.gameserver.enums.ChatType;
 import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
-import org.l2jmobius.gameserver.instancemanager.ZoneManager;
 import org.l2jmobius.gameserver.model.Location;
-import org.l2jmobius.gameserver.model.Spawn;
 import org.l2jmobius.gameserver.model.StatSet;
-import org.l2jmobius.gameserver.model.WorldObject;
 import org.l2jmobius.gameserver.model.actor.Attackable;
-import org.l2jmobius.gameserver.model.actor.Creature;
 import org.l2jmobius.gameserver.model.actor.Npc;
 import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
 import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
 import org.l2jmobius.gameserver.model.holders.SkillHolder;
-import org.l2jmobius.gameserver.model.skills.Skill;
 import org.l2jmobius.gameserver.model.skills.SkillCaster;
-import org.l2jmobius.gameserver.model.zone.ZoneType;
 import org.l2jmobius.gameserver.network.NpcStringId;
 import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
 
@@ -48,13 +42,7 @@ import ai.AbstractNpcAI;
  */
 public class Orfen extends AbstractNpcAI
 {
-	private static final Location[] POS =
-	{
-		new Location(43200, 16304, -4395),
-		new Location(43300, 16404, -4395),
-		new Location(43400, 16504, -4395),
-		new Location(43500, 16604, -4395)
-	};
+	private static final Location POS = new Location(43728, 17220, -4342);
 	
 	private static final NpcStringId[] TEXT =
 	{
@@ -68,16 +56,23 @@ public class Orfen extends AbstractNpcAI
 	private static final int ARIMA = 29326;
 	private static final int ARIMUS = 29327;
 	
-	private static boolean _IsTeleported;
 	private static Set _minions = ConcurrentHashMap.newKeySet();
-	private static ZoneType ZONE;
 	
 	private static final byte ALIVE = 0;
 	private static final byte DEAD = 1;
 	
-	private static final SkillHolder PARALYSIS = new SkillHolder(4064, 1);
 	private static final SkillHolder BLOW = new SkillHolder(4067, 4);
 	private static final SkillHolder ORFEN_HEAL = new SkillHolder(4516, 1);
+	private static final SkillHolder ORFEN_SLASHER = new SkillHolder(32486, 1);
+	private static final SkillHolder ORFEN_FATAL_SLASHER = new SkillHolder(32487, 1);
+	private static final SkillHolder ORFEN_ENERGY_SCATTER = new SkillHolder(32488, 1);
+	private static final SkillHolder ORFEN_FURY_ENERGY_WAVE = new SkillHolder(32489, 1);
+	private static final SkillHolder YOKE_OF_ORFEN = new SkillHolder(32490, 1);
+	private static final SkillHolder ORFEN_BLOW_UP = new SkillHolder(32491, 1);
+	private static final SkillHolder ORFEN_FATAL_STAMP = new SkillHolder(32492, 1);
+	private static final SkillHolder ORFEN_RAISE_SPORE = new SkillHolder(32493, 1);
+	private static final SkillHolder HALLUCINATING_DUST = new SkillHolder(32494, 1);
+	private static final SkillHolder ORFEN_RAGE = new SkillHolder(32495, 1);
 	
 	private Orfen()
 	{
@@ -88,8 +83,6 @@ public class Orfen extends AbstractNpcAI
 			ARIMUS
 		};
 		registerMobs(mobs);
-		_IsTeleported = false;
-		ZONE = ZoneManager.getInstance().getZoneById(12013);
 		final StatSet info = GrandBossManager.getInstance().getStatSet(ORFEN);
 		final int status = GrandBossManager.getInstance().getBossStatus(ORFEN);
 		if (status == DEAD)
@@ -105,21 +98,7 @@ public class Orfen extends AbstractNpcAI
 			else
 			{
 				// the time has already expired while the server was offline. Immediately spawn Orfen.
-				final int i = getRandom(10);
-				Location loc;
-				if (i < 4)
-				{
-					loc = POS[1];
-				}
-				else if (i < 7)
-				{
-					loc = POS[2];
-				}
-				else
-				{
-					loc = POS[3];
-				}
-				final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
+				final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0);
 				GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
 				spawnBoss(orfen);
 			}
@@ -138,20 +117,10 @@ public class Orfen extends AbstractNpcAI
 		}
 	}
 	
-	public void setSpawnPoint(Npc npc, int index)
-	{
-		((Attackable) npc).clearAggroList();
-		npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
-		final Spawn spawn = npc.getSpawn();
-		spawn.setLocation(POS[index]);
-		npc.teleToLocation(POS[index], false);
-	}
-	
 	public void spawnBoss(GrandBossInstance npc)
 	{
 		GrandBossManager.getInstance().addBoss(npc);
 		npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
-		startQuestTimer("check_orfen_pos", 10000, npc, null, true);
 		// Spawn minions
 		final int x = npc.getX();
 		final int y = npc.getY();
@@ -176,36 +145,10 @@ public class Orfen extends AbstractNpcAI
 	{
 		if (event.equalsIgnoreCase("orfen_unlock"))
 		{
-			final int i = getRandom(10);
-			Location loc;
-			if (i < 4)
-			{
-				loc = POS[1];
-			}
-			else if (i < 7)
-			{
-				loc = POS[2];
-			}
-			else
-			{
-				loc = POS[3];
-			}
-			final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
+			final GrandBossInstance orfen = (GrandBossInstance) addSpawn(ORFEN, POS, false, 0);
 			GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
 			spawnBoss(orfen);
 		}
-		else if (event.equalsIgnoreCase("check_orfen_pos"))
-		{
-			if ((_IsTeleported && (npc.getCurrentHp() > (npc.getMaxHp() * 0.95))) || (!ZONE.isInsideZone(npc) && !_IsTeleported))
-			{
-				setSpawnPoint(npc, getRandom(3) + 1);
-				_IsTeleported = false;
-			}
-			else if (_IsTeleported && !ZONE.isInsideZone(npc))
-			{
-				setSpawnPoint(npc, 0);
-			}
-		}
 		else if (event.equalsIgnoreCase("check_minion_loc"))
 		{
 			for (Attackable mob : _minions)
@@ -235,23 +178,6 @@ public class Orfen extends AbstractNpcAI
 		return super.onAdvEvent(event, npc, player);
 	}
 	
-	@Override
-	public String onSkillSee(Npc npc, PlayerInstance caster, Skill skill, WorldObject[] targets, boolean isSummon)
-	{
-		if (npc.getId() == ORFEN)
-		{
-			final Creature originalCaster = isSummon ? caster.getServitors().values().stream().findFirst().orElse(caster.getPet()) : caster;
-			if ((skill.getEffectPoint() > 0) && (getRandom(5) == 0) && npc.isInsideRadius2D(originalCaster, 1000))
-			{
-				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(4)], caster.getName());
-				originalCaster.teleToLocation(npc.getLocation());
-				npc.setTarget(originalCaster);
-				npc.doCast(PARALYSIS.getSkill());
-			}
-		}
-		return super.onSkillSee(npc, caster, skill, targets, isSummon);
-	}
-	
 	@Override
 	public String onFactionCall(Npc npc, Npc caller, PlayerInstance attacker, boolean isSummon)
 	{
@@ -289,17 +215,65 @@ public class Orfen extends AbstractNpcAI
 		final int npcId = npc.getId();
 		if (npcId == ORFEN)
 		{
-			if (!_IsTeleported && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2)))
-			{
-				_IsTeleported = true;
-				setSpawnPoint(npc, 0);
-			}
-			else if (npc.isInsideRadius2D(attacker, 1000) && !npc.isInsideRadius2D(attacker, 300) && (getRandom(10) == 0))
+			if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
 			{
 				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
-				attacker.teleToLocation(npc.getLocation());
 				npc.setTarget(attacker);
-				npc.doCast(PARALYSIS.getSkill());
+				npc.doCast(ORFEN_FATAL_SLASHER.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_ENERGY_SCATTER.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_FURY_ENERGY_WAVE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(YOKE_OF_ORFEN.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_BLOW_UP.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_FATAL_STAMP.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_RAISE_SPORE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(HALLUCINATING_DUST.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000) && (getRandom(10) == 0) && (npc.getCurrentHp() <= (npc.getMaxHp() * 0.5)))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_RAGE.getSkill());
+			}
+			else if (manageSkills(npc) && npc.isInsideRadius2D(attacker, 1000))
+			{
+				npc.broadcastSay(ChatType.NPC_GENERAL, TEXT[getRandom(3)], attacker.getName());
+				npc.setTarget(attacker);
+				npc.doCast(ORFEN_SLASHER.getSkill());
 			}
 		}
 		else if (npcId == ARIMUS)
@@ -313,6 +287,15 @@ public class Orfen extends AbstractNpcAI
 		return super.onAttack(npc, attacker, damage, isSummon);
 	}
 	
+	private boolean manageSkills(Npc npc)
+	{
+		if (npc.isCastingNow())
+		{
+			return false;
+		}
+		return true;
+	}
+	
 	@Override
 	public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
 	{
@@ -329,7 +312,6 @@ public class Orfen extends AbstractNpcAI
 			info.set("respawn_time", System.currentTimeMillis() + respawnTime);
 			GrandBossManager.getInstance().setStatSet(ORFEN, info);
 			cancelQuestTimer("check_minion_loc", npc, null);
-			cancelQuestTimer("check_orfen_pos", npc, null);
 			startQuestTimer("despawn_minions", 20000, null, null);
 			cancelQuestTimers("spawn_minion");
 		}