From 3d2ccb84a29f6972abed872ea2c9bef7f0e6b03e Mon Sep 17 00:00:00 2001
From: Adry85 <adrya85@hotmail.it>
Date: Sun, 24 Sep 2017 17:55:45 +0200
Subject: [PATCH] Retail like Necromancer of the Valley AI.

---
 dist/game/data/scripts.cfg                    |  1 +
 .../ai/group_template/DragonValley.java       | 93 ++-----------------
 .../ai/individual/NecromancerOfTheValley.java | 88 ++++++++++++++++++
 3 files changed, 98 insertions(+), 84 deletions(-)
 create mode 100644 dist/game/data/scripts/ai/individual/NecromancerOfTheValley.java

diff --git a/dist/game/data/scripts.cfg b/dist/game/data/scripts.cfg
index bffb18782c..66f3823abe 100644
--- a/dist/game/data/scripts.cfg
+++ b/dist/game/data/scripts.cfg
@@ -165,6 +165,7 @@ ai/individual/QueenShyeed.java
 ai/individual/RagnaOrcCommander.java
 ai/individual/RagnaOrcHero.java
 ai/individual/RagnaOrcSeer.java
+ai/individual/NecromancerOfTheValley.java
 ai/individual/ShadowSummoner.java
 ai/individual/SinEater.java
 ai/individual/SinWardens.java
diff --git a/dist/game/data/scripts/ai/group_template/DragonValley.java b/dist/game/data/scripts/ai/group_template/DragonValley.java
index c0272c9638..70d39b2274 100644
--- a/dist/game/data/scripts/ai/group_template/DragonValley.java
+++ b/dist/game/data/scripts/ai/group_template/DragonValley.java
@@ -26,7 +26,6 @@ import com.l2jserver.gameserver.model.actor.L2Playable;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.base.ClassId;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
-import com.l2jserver.gameserver.model.skills.Skill;
 import com.l2jserver.gameserver.util.Util;
 
 import ai.npc.AbstractNpcAI;
@@ -38,9 +37,6 @@ import ai.npc.AbstractNpcAI;
 public final class DragonValley extends AbstractNpcAI
 {
 	// NPC
-	private static final int NECROMANCER_OF_THE_VALLEY = 22858;
-	private static final int EXPLODING_ORC_GHOST = 22818;
-	private static final int WRATHFUL_ORC_GHOST = 22819;
 	private static final int DRAKOS_ASSASSIN = 22823;
 	private static final int[] SUMMON_NPC =
 	{
@@ -77,7 +73,6 @@ public final class DragonValley extends AbstractNpcAI
 	private static final int GREATER_HERB_OF_MANA = 8604;
 	private static final int SUPERIOR_HERB_OF_MANA = 8605;
 	// Skills
-	private static final SkillHolder SELF_DESTRUCTION = new SkillHolder(6850);
 	private static final SkillHolder MORALE_BOOST1 = new SkillHolder(6885);
 	private static final SkillHolder MORALE_BOOST2 = new SkillHolder(6885, 2);
 	private static final SkillHolder MORALE_BOOST3 = new SkillHolder(6885, 3);
@@ -129,54 +124,23 @@ public final class DragonValley extends AbstractNpcAI
 	private DragonValley()
 	{
 		super(DragonValley.class.getSimpleName(), "ai/group_template");
-		addAttackId(NECROMANCER_OF_THE_VALLEY);
 		addAttackId(SUMMON_NPC);
-		addKillId(NECROMANCER_OF_THE_VALLEY);
 		addKillId(SPOIL_REACT_MONSTER);
-		addSpawnId(EXPLODING_ORC_GHOST, NECROMANCER_OF_THE_VALLEY);
 		addSpawnId(SPOIL_REACT_MONSTER);
-		addSpellFinishedId(EXPLODING_ORC_GHOST);
-	}
-	
-	@Override
-	public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
-	{
-		if (event.equals("SELF_DESTRUCTION") && (npc != null) && !npc.isDead())
-		{
-			final L2Playable playable = npc.getVariables().getObject("playable", L2Playable.class);
-			
-			if ((playable != null) && (npc.calculateDistance(playable, true, false) < 250))
-			{
-				npc.disableCoreAI(true);
-				npc.doCast(SELF_DESTRUCTION);
-			}
-			else if (playable != null)
-			{
-				startQuestTimer("SELF_DESTRUCTION", 3000, npc, null);
-			}
-		}
-		return super.onAdvEvent(event, npc, player);
 	}
 	
 	@Override
 	public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
 	{
-		if (npc.getId() == NECROMANCER_OF_THE_VALLEY)
-		{
-			spawnGhost(npc, attacker, isSummon, 1);
-		}
-		else
+		if ((npc.getCurrentHp() < (npc.getMaxHp() / 2)) && (getRandom(100) < 5) && npc.isScriptValue(0))
 		{
-			if ((npc.getCurrentHp() < (npc.getMaxHp() / 2)) && (getRandom(100) < 5) && npc.isScriptValue(0))
+			npc.setScriptValue(1);
+			final int rnd = getRandom(3, 5);
+			for (int i = 0; i < rnd; i++)
 			{
-				npc.setScriptValue(1);
-				final int rnd = getRandom(3, 5);
-				for (int i = 0; i < rnd; i++)
-				{
-					final L2Playable playable = isSummon ? attacker.getSummon() : attacker;
-					final L2Npc minion = addSpawn(DRAKOS_ASSASSIN, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), true, 0, true);
-					addAttackDesire(minion, playable);
-				}
+				final L2Playable playable = isSummon ? attacker.getSummon() : attacker;
+				final L2Npc minion = addSpawn(DRAKOS_ASSASSIN, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), true, 0, true);
+				addAttackDesire(minion, playable);
 			}
 		}
 		return super.onAttack(npc, attacker, damage, isSummon);
@@ -185,11 +149,7 @@ public final class DragonValley extends AbstractNpcAI
 	@Override
 	public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
 	{
-		if (npc.getId() == NECROMANCER_OF_THE_VALLEY)
-		{
-			spawnGhost(npc, killer, isSummon, 20);
-		}
-		else if (((L2Attackable) npc).isSpoiled())
+		if (((L2Attackable) npc).isSpoiled())
 		{
 			npc.dropItem(killer, getRandom(GREATER_HERB_OF_MANA, SUPERIOR_HERB_OF_MANA), 1);
 			manageMoraleBoost(killer, npc);
@@ -200,28 +160,13 @@ public final class DragonValley extends AbstractNpcAI
 	@Override
 	public String onSpawn(L2Npc npc)
 	{
-		((L2Attackable) npc).setOnKillDelay(0);
-		if (npc.getId() == EXPLODING_ORC_GHOST)
-		{
-			startQuestTimer("SELF_DESTRUCTION", 3000, npc, null);
-		}
-		else if (Util.contains(SPAWN_ANIMATION, npc.getId()))
+		if (Util.contains(SPAWN_ANIMATION, npc.getId()))
 		{
 			npc.setShowSummonAnimation(true);
 		}
 		return super.onSpawn(npc);
 	}
 	
-	@Override
-	public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
-	{
-		if (skill == SELF_DESTRUCTION.getSkill())
-		{
-			npc.doDie(player);
-		}
-		return super.onSpellFinished(npc, player, skill);
-	}
-	
 	private void manageMoraleBoost(L2PcInstance player, L2Npc npc)
 	{
 		double points = 0;
@@ -271,26 +216,6 @@ public final class DragonValley extends AbstractNpcAI
 		}
 	}
 	
-	private void spawnGhost(L2Npc npc, L2PcInstance player, boolean isSummon, int chance)
-	{
-		if ((npc.getScriptValue() < 2) && (getRandom(100) < chance))
-		{
-			int val = npc.getScriptValue();
-			final L2Playable attacker = isSummon ? player.getSummon() : player;
-			final L2Npc ghost1 = addSpawn(EXPLODING_ORC_GHOST, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, true);
-			ghost1.getVariables().set("playable", attacker);
-			addAttackDesire(ghost1, attacker);
-			val++;
-			if ((val < 2) && (getRandomBoolean()))
-			{
-				final L2Npc ghost2 = addSpawn(WRATHFUL_ORC_GHOST, npc.getX(), npc.getY(), npc.getZ() + 20, npc.getHeading(), false, 0, false);
-				addAttackDesire(ghost2, attacker);
-				val++;
-			}
-			npc.setScriptValue(val);
-		}
-	}
-	
 	public static void main(String[] args)
 	{
 		new DragonValley();
diff --git a/dist/game/data/scripts/ai/individual/NecromancerOfTheValley.java b/dist/game/data/scripts/ai/individual/NecromancerOfTheValley.java
new file mode 100644
index 0000000000..90803d0bfd
--- /dev/null
+++ b/dist/game/data/scripts/ai/individual/NecromancerOfTheValley.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2004-2017 L2J DataPack
+ * 
+ * This file is part of L2J DataPack.
+ * 
+ * L2J DataPack is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * L2J DataPack is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package ai.individual;
+
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+import ai.npc.AbstractNpcAI;
+
+/**
+ * Necromancer of the Valley AI.
+ * @author Adry_85
+ * @since 2.6.0.0
+ */
+public class NecromancerOfTheValley extends AbstractNpcAI
+{
+	// NPCs
+	private static final int EXPLODING_ORC_GHOST = 22818;
+	private static final int WRATHFUL_ORC_GHOST = 22819;
+	private static final int NECROMANCER_OF_THE_VALLEY = 22858;
+	// Skill
+	private static final SkillHolder SELF_DESTRUCTION = new SkillHolder(6850);
+	// Misc
+	private static final double HP_PERCENTAGE = 0.60;
+	
+	public NecromancerOfTheValley()
+	{
+		super(NecromancerOfTheValley.class.getSimpleName(), "ai/individual");
+		addAttackId(NECROMANCER_OF_THE_VALLEY);
+		addSpellFinishedId(EXPLODING_ORC_GHOST);
+	}
+	
+	@Override
+	public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
+	{
+		if ((npc.getCurrentHp() < (npc.getMaxHp() * HP_PERCENTAGE)))
+		{
+			if (getRandom(10) < 1)
+			{
+				if (getRandomBoolean())
+				{
+					final L2Npc explodingOrcGhost = addSpawn(EXPLODING_ORC_GHOST, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false);
+					addAttackDesire(explodingOrcGhost, attacker, 10000);
+					addSkillCastDesire(npc, attacker, SELF_DESTRUCTION, 999999999L);
+				}
+				else
+				{
+					final L2Npc wrathfulOrcGhost = addSpawn(WRATHFUL_ORC_GHOST, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false);
+					addAttackDesire(wrathfulOrcGhost, attacker, 10000);
+				}
+			}
+		}
+		return super.onAttack(npc, attacker, damage, isSummon);
+	}
+	
+	@Override
+	public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
+	{
+		if ((skill == SELF_DESTRUCTION.getSkill()) && (npc != null) && !npc.isDead())
+		{
+			npc.doDie(player);
+		}
+		return super.onSpellFinished(npc, player, skill);
+	}
+	
+	public static void main(String[] args)
+	{
+		new NecromancerOfTheValley();
+	}
+}
-- 
GitLab