diff --git a/L2J_Mobius_Helios/dist/game/data/DoorData.xml b/L2J_Mobius_Helios/dist/game/data/DoorData.xml
index d6f7219773..be38ed909c 100644
--- a/L2J_Mobius_Helios/dist/game/data/DoorData.xml
+++ b/L2J_Mobius_Helios/dist/game/data/DoorData.xml
@@ -17139,7 +17139,7 @@
-
+
diff --git a/L2J_Mobius_Helios/dist/game/data/instances/NornilsGarden.xml b/L2J_Mobius_Helios/dist/game/data/instances/NornilsGarden.xml
new file mode 100644
index 0000000000..7035cb3502
--- /dev/null
+++ b/L2J_Mobius_Helios/dist/game/data/instances/NornilsGarden.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/33781-01.html b/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/33781-01.html
new file mode 100644
index 0000000000..3af6e21760
--- /dev/null
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/33781-01.html
@@ -0,0 +1,3 @@
+Boz Core:
+This is the Nornil's Garden, in which hosts the Spicula Zero
+
\ No newline at end of file
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/33781.html b/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/33781.html
new file mode 100644
index 0000000000..2ac1ac6e98
--- /dev/null
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/33781.html
@@ -0,0 +1,5 @@
+Boz Core:
+This is the central device that manages the Spicula Clone Generator. It seems connected to Nornil's Garden, home to Spicula Zero is.
+
+(It is recommended to go to Nornil's Garden as a group of 7.)
+
\ No newline at end of file
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/NornilsGarden.java b/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/NornilsGarden.java
new file mode 100644
index 0000000000..cb81130801
--- /dev/null
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/NornilsGarden.java
@@ -0,0 +1,314 @@
+/*
+ * 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 instances.NornilsGarden;
+
+import com.l2jmobius.commons.util.CommonUtil;
+import com.l2jmobius.gameserver.ai.CtrlIntention;
+import com.l2jmobius.gameserver.model.L2World;
+import com.l2jmobius.gameserver.model.actor.L2Attackable;
+import com.l2jmobius.gameserver.model.actor.L2Character;
+import com.l2jmobius.gameserver.model.actor.L2Npc;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.holders.SkillHolder;
+import com.l2jmobius.gameserver.model.instancezone.Instance;
+import com.l2jmobius.gameserver.network.SystemMessageId;
+import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import instances.AbstractInstance;
+
+/**
+ * Nornils Garden Instance
+ * @URL https://l2wiki.com/Nornils_Garden
+ * @Video https://www.youtube.com/watch?v=6QKzzmJ5GUs
+ * @author Gigi
+ * @date 2017-02-22 - [15:22:27]
+ */
+public class NornilsGarden extends AbstractInstance
+{
+ // NPCs
+ private static final int BOZ_CORE = 33781;
+ private static final int SPICULA_ZERO = 25901;
+ // Monsters
+ private final static int BOZ_STAGE1 = 19298;
+ private final static int BOZ_STAGE2 = 19305;
+ private final static int BOZ_STAGE3 = 19403;
+ private final static int BOZ_STAGE4 = BOZ_STAGE2;
+ private final static int SPICULA_ELITE_CAPTAIN = 19299;
+ private final static int SPICULA_ELITE_LIEUTNANT = 19300;
+ private final static int ELITE_SOLDIER_CLONE_1 = 19301;
+ private final static int SPICULA_ELITE_GUARD_1 = 19302;
+ private final static int ELITE_SOLDIER_CLONE_2 = 19303;
+ private final static int SPICULA_ELITE_GUARD_2 = 19304;
+ private static final int[] ATTACABLE_MONSTERS =
+ {
+ SPICULA_ELITE_CAPTAIN,
+ SPICULA_ELITE_CAPTAIN,
+ SPICULA_ELITE_LIEUTNANT,
+ ELITE_SOLDIER_CLONE_1,
+ SPICULA_ELITE_GUARD_1,
+ ELITE_SOLDIER_CLONE_2,
+ SPICULA_ELITE_GUARD_2
+ };
+ // Skills
+ private static final SkillHolder DARK_SPHERES = new SkillHolder(15234, 1);
+ private static final SkillHolder DARK_WIND = new SkillHolder(15235, 1);
+ private static final SkillHolder DARK_THRUST = new SkillHolder(15236, 1);
+ private static final SkillHolder DARK_BUSTER = new SkillHolder(15237, 1);
+ private static final SkillHolder DARK_BREATH = new SkillHolder(15238, 1);
+ // Chance
+ private final static int CHANCE_DARK_SPHERES = 15;
+ private final static int CHANCE_DARK_WIND = 30;
+ private final static int CHANCE_DARK_THRUST = 15;
+ private final static int CHANCE_DARK_BUSTER = 15;
+ private final static int CHANCE_DARK_BREATH = 30;
+ // Misc
+ private static final int TEMPLATE_ID = 231;
+
+ public NornilsGarden()
+ {
+ super(TEMPLATE_ID);
+ addStartNpc(BOZ_CORE);
+ addTalkId(BOZ_CORE);
+ addFirstTalkId(BOZ_CORE);
+ addAttackId(SPICULA_ZERO);
+ addKillId(ATTACABLE_MONSTERS);
+ addKillId(SPICULA_ZERO);
+ addKillId(BOZ_STAGE1, BOZ_STAGE2, BOZ_STAGE3, BOZ_STAGE4);
+ addSeeCreatureId(BOZ_STAGE1);
+ addSpawnId(ATTACABLE_MONSTERS);
+ }
+
+ @Override
+ public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
+ {
+ final Instance world = npc.getInstanceWorld();
+ if (isInInstance(world))
+ {
+ switch (event)
+ {
+ case "stage1":
+ {
+ world.spawnGroup("wave_1");
+ startQuestTimer("stage1_1", 20000, npc, null, true);
+ break;
+ }
+ case "stage1_1":
+ {
+ if (!npc.isDead() && world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
+ {
+ world.spawnGroup("wave_1");
+ npc.setTargetable(true);
+ }
+ break;
+ }
+ case "stage2":
+ {
+ if (world.isStatus(5) && world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
+ {
+ world.openCloseDoor(16200016, true);
+ cancelQuestTimers("stage2");
+ world.spawnGroup("wave_3");
+ }
+ break;
+ }
+ case "stage3":
+ {
+ if (world.isStatus(6) && world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
+ {
+ world.openCloseDoor(16200201, true);
+ cancelQuestTimers("stage3");
+ cancelQuestTimers("check_agrro");
+ }
+ break;
+ }
+ case "check_agrro":
+ {
+ if ((world != null) && !npc.isDead() && !npc.isInCombat())
+ {
+ L2World.getInstance().forEachVisibleObjectInRange(npc, L2PcInstance.class, 1500, knownChar ->
+ {
+ if (CommonUtil.contains(ATTACABLE_MONSTERS, npc.getId()) && !npc.isInCombat())
+ {
+ npc.setRunning();
+ ((L2Attackable) npc).addDamageHate(knownChar, 0, 99999);
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, knownChar);
+ }
+ });
+ }
+ break;
+ }
+ }
+ }
+ else if (event.equals("enterInstance"))
+ {
+ enterInstance(player, npc, TEMPLATE_ID);
+ }
+ return super.onAdvEvent(event, npc, player);
+ }
+
+ @Override
+ public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
+ {
+ final Instance world = npc.getInstanceWorld();
+ if (isInInstance(world))
+ {
+ world.openCloseDoor(16200201, false);
+ }
+ if ((attacker != null) && !attacker.isDead() && !npc.isCastingNow())
+ {
+ if ((getRandom(100) < CHANCE_DARK_SPHERES) && (npc.getCurrentHpPercent() <= 95))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_SPHERES.getSkill());
+ }
+ else if ((getRandom(100) < CHANCE_DARK_WIND) && (npc.getCurrentHpPercent() <= 75))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_WIND.getSkill());
+ }
+ else if ((getRandom(100) < CHANCE_DARK_THRUST) && (npc.getCurrentHpPercent() <= 50))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_THRUST.getSkill());
+ }
+ else if ((getRandom(100) < CHANCE_DARK_BUSTER) && (npc.getCurrentHpPercent() <= 25))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_BUSTER.getSkill());
+ }
+ else if ((getRandom(100) < CHANCE_DARK_BREATH) && (npc.getCurrentHpPercent() <= 10))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_BREATH.getSkill());
+ }
+ }
+ return super.onAttack(npc, attacker, damage, isSummon);
+ }
+
+ @Override
+ public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
+ {
+ final Instance world = npc.getInstanceWorld();
+ switch (world.getStatus())
+ {
+ case 0:
+ {
+ if (npc.getId() == BOZ_STAGE1)
+ {
+ cancelQuestTimers("stage1_1");
+ world.openCloseDoor(16200015, true);
+ world.setStatus(1);
+ }
+ break;
+ }
+ case 1:
+ {
+ if ((npc.getId() == BOZ_STAGE2) && (world.getAliveNpcs(BOZ_STAGE2).size() < 6))
+ {
+ world.spawnGroup("wave_2_1");
+ world.setStatus(2);
+ }
+ break;
+ }
+ case 2:
+ {
+ if ((npc.getId() == BOZ_STAGE2) && (world.getAliveNpcs(BOZ_STAGE2).size() < 5))
+ {
+ world.spawnGroup("wave_2_2");
+ world.setStatus(3);
+ }
+ break;
+ }
+ case 3:
+ {
+ if ((npc.getId() == BOZ_STAGE2) && (world.getAliveNpcs(BOZ_STAGE2).size() < 4))
+ {
+ world.spawnGroup("wave_2_3");
+ world.setStatus(4);
+ }
+ break;
+ }
+ case 4:
+ {
+ if ((npc.getId() == BOZ_STAGE2) && (world.getAliveNpcs(BOZ_STAGE2).size() < 3))
+ {
+ world.spawnGroup("wave_2_4");
+ startQuestTimer("stage2", 15000, npc, null, true);
+ world.setStatus(5);
+ }
+ break;
+ }
+ case 5:
+ {
+ if (npc.getId() == BOZ_STAGE3)
+ {
+ startQuestTimer("stage3", 10000, npc, null, true);
+ world.setStatus(6);
+ }
+ break;
+ }
+ case 6:
+ {
+ if (npc.getId() == SPICULA_ZERO)
+ {
+ world.getAliveNpcs(BOZ_STAGE4).forEach(boz -> boz.doDie(null));
+ world.spawnGroup("wave_4");
+ world.finishInstance();
+ world.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.THIS_DUNGEON_WILL_EXPIRE_IN_S1_MINUTE_S_YOU_WILL_BE_FORCED_OUT_OF_THE_DUNGEON_WHEN_THE_TIME_EXPIRES).addInt((int) 5.0D));
+ }
+ break;
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public String onFirstTalk(L2Npc npc, L2PcInstance player)
+ {
+ return "33781.html";
+ }
+
+ @Override
+ public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
+ {
+ if ((npc.getId() == BOZ_STAGE1) && creature.isPlayable() && npc.isScriptValue(0))
+ {
+ startQuestTimer("stage1", 3000, npc, null);
+ npc.setTargetable(false);
+ npc.setScriptValue(1);
+ }
+ return super.onSeeCreature(npc, creature, isSummon);
+ }
+
+ @Override
+ public String onSpawn(L2Npc npc)
+ {
+ final Instance world = npc.getInstanceWorld();
+ if (isInInstance(world) && (CommonUtil.contains(ATTACABLE_MONSTERS, npc.getId())))
+ {
+ ((L2Attackable) npc).setCanStopAttackByTime(false);
+ ((L2Attackable) npc).setCanReturnToSpawnPoint(false);
+ startQuestTimer("check_agrro", 1000, npc, null, true);
+ }
+ return super.onSpawn(npc);
+ }
+
+ public static void main(String[] args)
+ {
+ new NornilsGarden();
+ }
+}
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/condNoPartyLeader.html b/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/condNoPartyLeader.html
new file mode 100644
index 0000000000..1dcd1e4560
--- /dev/null
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/instances/NornilsGarden/condNoPartyLeader.html
@@ -0,0 +1,4 @@
+Boz Core:
+Aren't you in a party? But you are not the party leader.
+(Only the party leader can request to enter.)
+
\ No newline at end of file
diff --git a/L2J_Mobius_Helios/dist/game/data/stats/npcs/19200-19299.xml b/L2J_Mobius_Helios/dist/game/data/stats/npcs/19200-19299.xml
index eba197573d..b5d1709aa2 100644
--- a/L2J_Mobius_Helios/dist/game/data/stats/npcs/19200-19299.xml
+++ b/L2J_Mobius_Helios/dist/game/data/stats/npcs/19200-19299.xml
@@ -3583,7 +3583,7 @@
-
+
NORNIL_METUCELLAR
diff --git a/L2J_Mobius_Helios/dist/game/data/stats/npcs/19300-19399.xml b/L2J_Mobius_Helios/dist/game/data/stats/npcs/19300-19399.xml
index 652edcd393..a1a9c4e0e7 100644
--- a/L2J_Mobius_Helios/dist/game/data/stats/npcs/19300-19399.xml
+++ b/L2J_Mobius_Helios/dist/game/data/stats/npcs/19300-19399.xml
@@ -245,7 +245,7 @@
-
+
diff --git a/L2J_Mobius_Helios/dist/game/data/stats/npcs/19400-19499.xml b/L2J_Mobius_Helios/dist/game/data/stats/npcs/19400-19499.xml
index 521d9722df..63ebe960c5 100644
--- a/L2J_Mobius_Helios/dist/game/data/stats/npcs/19400-19499.xml
+++ b/L2J_Mobius_Helios/dist/game/data/stats/npcs/19400-19499.xml
@@ -147,7 +147,7 @@
-
+
diff --git a/L2J_Mobius_Helios/dist/game/data/stats/npcs/25900-25999.xml b/L2J_Mobius_Helios/dist/game/data/stats/npcs/25900-25999.xml
index a23557fcf5..cf27ec04b3 100644
--- a/L2J_Mobius_Helios/dist/game/data/stats/npcs/25900-25999.xml
+++ b/L2J_Mobius_Helios/dist/game/data/stats/npcs/25900-25999.xml
@@ -32,13 +32,6 @@
-
-
-
-
-
-
-
HUMANOID
MALE
@@ -74,46 +67,64 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/L2J_Mobius_Underground/dist/game/data/DoorData.xml b/L2J_Mobius_Underground/dist/game/data/DoorData.xml
index d6f7219773..be38ed909c 100644
--- a/L2J_Mobius_Underground/dist/game/data/DoorData.xml
+++ b/L2J_Mobius_Underground/dist/game/data/DoorData.xml
@@ -17139,7 +17139,7 @@
-
+
diff --git a/L2J_Mobius_Underground/dist/game/data/instances/NornilsGarden.xml b/L2J_Mobius_Underground/dist/game/data/instances/NornilsGarden.xml
new file mode 100644
index 0000000000..7035cb3502
--- /dev/null
+++ b/L2J_Mobius_Underground/dist/game/data/instances/NornilsGarden.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/33781-01.html b/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/33781-01.html
new file mode 100644
index 0000000000..3af6e21760
--- /dev/null
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/33781-01.html
@@ -0,0 +1,3 @@
+Boz Core:
+This is the Nornil's Garden, in which hosts the Spicula Zero
+
\ No newline at end of file
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/33781.html b/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/33781.html
new file mode 100644
index 0000000000..2ac1ac6e98
--- /dev/null
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/33781.html
@@ -0,0 +1,5 @@
+Boz Core:
+This is the central device that manages the Spicula Clone Generator. It seems connected to Nornil's Garden, home to Spicula Zero is.
+
+(It is recommended to go to Nornil's Garden as a group of 7.)
+
\ No newline at end of file
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/NornilsGarden.java b/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/NornilsGarden.java
new file mode 100644
index 0000000000..cb81130801
--- /dev/null
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/NornilsGarden.java
@@ -0,0 +1,314 @@
+/*
+ * 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 instances.NornilsGarden;
+
+import com.l2jmobius.commons.util.CommonUtil;
+import com.l2jmobius.gameserver.ai.CtrlIntention;
+import com.l2jmobius.gameserver.model.L2World;
+import com.l2jmobius.gameserver.model.actor.L2Attackable;
+import com.l2jmobius.gameserver.model.actor.L2Character;
+import com.l2jmobius.gameserver.model.actor.L2Npc;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.holders.SkillHolder;
+import com.l2jmobius.gameserver.model.instancezone.Instance;
+import com.l2jmobius.gameserver.network.SystemMessageId;
+import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import instances.AbstractInstance;
+
+/**
+ * Nornils Garden Instance
+ * @URL https://l2wiki.com/Nornils_Garden
+ * @Video https://www.youtube.com/watch?v=6QKzzmJ5GUs
+ * @author Gigi
+ * @date 2017-02-22 - [15:22:27]
+ */
+public class NornilsGarden extends AbstractInstance
+{
+ // NPCs
+ private static final int BOZ_CORE = 33781;
+ private static final int SPICULA_ZERO = 25901;
+ // Monsters
+ private final static int BOZ_STAGE1 = 19298;
+ private final static int BOZ_STAGE2 = 19305;
+ private final static int BOZ_STAGE3 = 19403;
+ private final static int BOZ_STAGE4 = BOZ_STAGE2;
+ private final static int SPICULA_ELITE_CAPTAIN = 19299;
+ private final static int SPICULA_ELITE_LIEUTNANT = 19300;
+ private final static int ELITE_SOLDIER_CLONE_1 = 19301;
+ private final static int SPICULA_ELITE_GUARD_1 = 19302;
+ private final static int ELITE_SOLDIER_CLONE_2 = 19303;
+ private final static int SPICULA_ELITE_GUARD_2 = 19304;
+ private static final int[] ATTACABLE_MONSTERS =
+ {
+ SPICULA_ELITE_CAPTAIN,
+ SPICULA_ELITE_CAPTAIN,
+ SPICULA_ELITE_LIEUTNANT,
+ ELITE_SOLDIER_CLONE_1,
+ SPICULA_ELITE_GUARD_1,
+ ELITE_SOLDIER_CLONE_2,
+ SPICULA_ELITE_GUARD_2
+ };
+ // Skills
+ private static final SkillHolder DARK_SPHERES = new SkillHolder(15234, 1);
+ private static final SkillHolder DARK_WIND = new SkillHolder(15235, 1);
+ private static final SkillHolder DARK_THRUST = new SkillHolder(15236, 1);
+ private static final SkillHolder DARK_BUSTER = new SkillHolder(15237, 1);
+ private static final SkillHolder DARK_BREATH = new SkillHolder(15238, 1);
+ // Chance
+ private final static int CHANCE_DARK_SPHERES = 15;
+ private final static int CHANCE_DARK_WIND = 30;
+ private final static int CHANCE_DARK_THRUST = 15;
+ private final static int CHANCE_DARK_BUSTER = 15;
+ private final static int CHANCE_DARK_BREATH = 30;
+ // Misc
+ private static final int TEMPLATE_ID = 231;
+
+ public NornilsGarden()
+ {
+ super(TEMPLATE_ID);
+ addStartNpc(BOZ_CORE);
+ addTalkId(BOZ_CORE);
+ addFirstTalkId(BOZ_CORE);
+ addAttackId(SPICULA_ZERO);
+ addKillId(ATTACABLE_MONSTERS);
+ addKillId(SPICULA_ZERO);
+ addKillId(BOZ_STAGE1, BOZ_STAGE2, BOZ_STAGE3, BOZ_STAGE4);
+ addSeeCreatureId(BOZ_STAGE1);
+ addSpawnId(ATTACABLE_MONSTERS);
+ }
+
+ @Override
+ public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
+ {
+ final Instance world = npc.getInstanceWorld();
+ if (isInInstance(world))
+ {
+ switch (event)
+ {
+ case "stage1":
+ {
+ world.spawnGroup("wave_1");
+ startQuestTimer("stage1_1", 20000, npc, null, true);
+ break;
+ }
+ case "stage1_1":
+ {
+ if (!npc.isDead() && world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
+ {
+ world.spawnGroup("wave_1");
+ npc.setTargetable(true);
+ }
+ break;
+ }
+ case "stage2":
+ {
+ if (world.isStatus(5) && world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
+ {
+ world.openCloseDoor(16200016, true);
+ cancelQuestTimers("stage2");
+ world.spawnGroup("wave_3");
+ }
+ break;
+ }
+ case "stage3":
+ {
+ if (world.isStatus(6) && world.getAliveNpcs(ATTACABLE_MONSTERS).isEmpty())
+ {
+ world.openCloseDoor(16200201, true);
+ cancelQuestTimers("stage3");
+ cancelQuestTimers("check_agrro");
+ }
+ break;
+ }
+ case "check_agrro":
+ {
+ if ((world != null) && !npc.isDead() && !npc.isInCombat())
+ {
+ L2World.getInstance().forEachVisibleObjectInRange(npc, L2PcInstance.class, 1500, knownChar ->
+ {
+ if (CommonUtil.contains(ATTACABLE_MONSTERS, npc.getId()) && !npc.isInCombat())
+ {
+ npc.setRunning();
+ ((L2Attackable) npc).addDamageHate(knownChar, 0, 99999);
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, knownChar);
+ }
+ });
+ }
+ break;
+ }
+ }
+ }
+ else if (event.equals("enterInstance"))
+ {
+ enterInstance(player, npc, TEMPLATE_ID);
+ }
+ return super.onAdvEvent(event, npc, player);
+ }
+
+ @Override
+ public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
+ {
+ final Instance world = npc.getInstanceWorld();
+ if (isInInstance(world))
+ {
+ world.openCloseDoor(16200201, false);
+ }
+ if ((attacker != null) && !attacker.isDead() && !npc.isCastingNow())
+ {
+ if ((getRandom(100) < CHANCE_DARK_SPHERES) && (npc.getCurrentHpPercent() <= 95))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_SPHERES.getSkill());
+ }
+ else if ((getRandom(100) < CHANCE_DARK_WIND) && (npc.getCurrentHpPercent() <= 75))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_WIND.getSkill());
+ }
+ else if ((getRandom(100) < CHANCE_DARK_THRUST) && (npc.getCurrentHpPercent() <= 50))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_THRUST.getSkill());
+ }
+ else if ((getRandom(100) < CHANCE_DARK_BUSTER) && (npc.getCurrentHpPercent() <= 25))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_BUSTER.getSkill());
+ }
+ else if ((getRandom(100) < CHANCE_DARK_BREATH) && (npc.getCurrentHpPercent() <= 10))
+ {
+ npc.setTarget(attacker);
+ npc.doCast(DARK_BREATH.getSkill());
+ }
+ }
+ return super.onAttack(npc, attacker, damage, isSummon);
+ }
+
+ @Override
+ public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
+ {
+ final Instance world = npc.getInstanceWorld();
+ switch (world.getStatus())
+ {
+ case 0:
+ {
+ if (npc.getId() == BOZ_STAGE1)
+ {
+ cancelQuestTimers("stage1_1");
+ world.openCloseDoor(16200015, true);
+ world.setStatus(1);
+ }
+ break;
+ }
+ case 1:
+ {
+ if ((npc.getId() == BOZ_STAGE2) && (world.getAliveNpcs(BOZ_STAGE2).size() < 6))
+ {
+ world.spawnGroup("wave_2_1");
+ world.setStatus(2);
+ }
+ break;
+ }
+ case 2:
+ {
+ if ((npc.getId() == BOZ_STAGE2) && (world.getAliveNpcs(BOZ_STAGE2).size() < 5))
+ {
+ world.spawnGroup("wave_2_2");
+ world.setStatus(3);
+ }
+ break;
+ }
+ case 3:
+ {
+ if ((npc.getId() == BOZ_STAGE2) && (world.getAliveNpcs(BOZ_STAGE2).size() < 4))
+ {
+ world.spawnGroup("wave_2_3");
+ world.setStatus(4);
+ }
+ break;
+ }
+ case 4:
+ {
+ if ((npc.getId() == BOZ_STAGE2) && (world.getAliveNpcs(BOZ_STAGE2).size() < 3))
+ {
+ world.spawnGroup("wave_2_4");
+ startQuestTimer("stage2", 15000, npc, null, true);
+ world.setStatus(5);
+ }
+ break;
+ }
+ case 5:
+ {
+ if (npc.getId() == BOZ_STAGE3)
+ {
+ startQuestTimer("stage3", 10000, npc, null, true);
+ world.setStatus(6);
+ }
+ break;
+ }
+ case 6:
+ {
+ if (npc.getId() == SPICULA_ZERO)
+ {
+ world.getAliveNpcs(BOZ_STAGE4).forEach(boz -> boz.doDie(null));
+ world.spawnGroup("wave_4");
+ world.finishInstance();
+ world.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.THIS_DUNGEON_WILL_EXPIRE_IN_S1_MINUTE_S_YOU_WILL_BE_FORCED_OUT_OF_THE_DUNGEON_WHEN_THE_TIME_EXPIRES).addInt((int) 5.0D));
+ }
+ break;
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public String onFirstTalk(L2Npc npc, L2PcInstance player)
+ {
+ return "33781.html";
+ }
+
+ @Override
+ public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
+ {
+ if ((npc.getId() == BOZ_STAGE1) && creature.isPlayable() && npc.isScriptValue(0))
+ {
+ startQuestTimer("stage1", 3000, npc, null);
+ npc.setTargetable(false);
+ npc.setScriptValue(1);
+ }
+ return super.onSeeCreature(npc, creature, isSummon);
+ }
+
+ @Override
+ public String onSpawn(L2Npc npc)
+ {
+ final Instance world = npc.getInstanceWorld();
+ if (isInInstance(world) && (CommonUtil.contains(ATTACABLE_MONSTERS, npc.getId())))
+ {
+ ((L2Attackable) npc).setCanStopAttackByTime(false);
+ ((L2Attackable) npc).setCanReturnToSpawnPoint(false);
+ startQuestTimer("check_agrro", 1000, npc, null, true);
+ }
+ return super.onSpawn(npc);
+ }
+
+ public static void main(String[] args)
+ {
+ new NornilsGarden();
+ }
+}
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/condNoPartyLeader.html b/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/condNoPartyLeader.html
new file mode 100644
index 0000000000..1dcd1e4560
--- /dev/null
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/instances/NornilsGarden/condNoPartyLeader.html
@@ -0,0 +1,4 @@
+Boz Core:
+Aren't you in a party? But you are not the party leader.
+(Only the party leader can request to enter.)
+
\ No newline at end of file
diff --git a/L2J_Mobius_Underground/dist/game/data/stats/npcs/19200-19299.xml b/L2J_Mobius_Underground/dist/game/data/stats/npcs/19200-19299.xml
index eba197573d..b5d1709aa2 100644
--- a/L2J_Mobius_Underground/dist/game/data/stats/npcs/19200-19299.xml
+++ b/L2J_Mobius_Underground/dist/game/data/stats/npcs/19200-19299.xml
@@ -3583,7 +3583,7 @@
-
+
NORNIL_METUCELLAR
diff --git a/L2J_Mobius_Underground/dist/game/data/stats/npcs/19300-19399.xml b/L2J_Mobius_Underground/dist/game/data/stats/npcs/19300-19399.xml
index ec62d738e0..9fe8972b20 100644
--- a/L2J_Mobius_Underground/dist/game/data/stats/npcs/19300-19399.xml
+++ b/L2J_Mobius_Underground/dist/game/data/stats/npcs/19300-19399.xml
@@ -245,7 +245,7 @@
-
+
diff --git a/L2J_Mobius_Underground/dist/game/data/stats/npcs/19400-19499.xml b/L2J_Mobius_Underground/dist/game/data/stats/npcs/19400-19499.xml
index 1d918a24b9..6338323d1d 100644
--- a/L2J_Mobius_Underground/dist/game/data/stats/npcs/19400-19499.xml
+++ b/L2J_Mobius_Underground/dist/game/data/stats/npcs/19400-19499.xml
@@ -147,7 +147,7 @@
-
+
diff --git a/L2J_Mobius_Underground/dist/game/data/stats/npcs/25900-25999.xml b/L2J_Mobius_Underground/dist/game/data/stats/npcs/25900-25999.xml
index a23557fcf5..cf27ec04b3 100644
--- a/L2J_Mobius_Underground/dist/game/data/stats/npcs/25900-25999.xml
+++ b/L2J_Mobius_Underground/dist/game/data/stats/npcs/25900-25999.xml
@@ -32,13 +32,6 @@
-
-
-
-
-
-
-
HUMANOID
MALE
@@ -74,46 +67,64 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+