From c8620ef411a22081bd410f8f4530f421d4a122b2 Mon Sep 17 00:00:00 2001
From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com>
Date: Sun, 19 Mar 2017 19:13:23 +0000
Subject: [PATCH] Harnak Underground Ruins zone rework. Contributed by
gigilo1968.
---
.../HarnakUndergroundRuinsZone.java | 294 +++++++
.../TalkingIsland/HarnakUndergroundRuins.xml | 763 ++++++++++++------
.../dist/game/data/zones/custom_script.xml | 72 ++
.../network/serverpackets/ExSendUIEvent.java | 33 +
.../HarnakUndergroundRuinsZone.java | 294 +++++++
.../TalkingIsland/HarnakUndergroundRuins.xml | 763 ++++++++++++------
.../dist/game/data/zones/custom_script.xml | 72 ++
.../network/serverpackets/ExSendUIEvent.java | 33 +
8 files changed, 1854 insertions(+), 470 deletions(-)
create mode 100644 L2J_Mobius_Helios/dist/game/data/scripts/ai/areas/TalkingIsland/HarnakUndergroundRuinsZone/HarnakUndergroundRuinsZone.java
create mode 100644 L2J_Mobius_Underground/dist/game/data/scripts/ai/areas/TalkingIsland/HarnakUndergroundRuinsZone/HarnakUndergroundRuinsZone.java
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/ai/areas/TalkingIsland/HarnakUndergroundRuinsZone/HarnakUndergroundRuinsZone.java b/L2J_Mobius_Helios/dist/game/data/scripts/ai/areas/TalkingIsland/HarnakUndergroundRuinsZone/HarnakUndergroundRuinsZone.java
new file mode 100644
index 0000000000..1078ee92a6
--- /dev/null
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/ai/areas/TalkingIsland/HarnakUndergroundRuinsZone/HarnakUndergroundRuinsZone.java
@@ -0,0 +1,294 @@
+/*
+ * 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.TalkingIsland.HarnakUndergroundRuinsZone;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.l2jmobius.gameserver.ThreadPoolManager;
+import com.l2jmobius.gameserver.ai.CtrlIntention;
+import com.l2jmobius.gameserver.instancemanager.ZoneManager;
+import com.l2jmobius.gameserver.model.actor.L2Npc;
+import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.spawns.SpawnTemplate;
+import com.l2jmobius.gameserver.model.zone.L2ZoneType;
+import com.l2jmobius.gameserver.network.NpcStringId;
+import com.l2jmobius.gameserver.network.serverpackets.ExSendUIEvent;
+import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Harnak Underground Ruins
+ * @video https://www.youtube.com/watch?v=0IdcAB3aYO0
+ * @author LasTravel, Gigi
+ * @date 2017-03-10 - [13:09:05]
+ */
+public class HarnakUndergroundRuinsZone extends AbstractNpcAI
+{
+ //@formatter:off
+ private static final int[] NORMAL_MOBS = {22931, 22932, 22933, 22934, 22935, 22936, 22937, 22938, 23349};
+ //@formatter:on
+ static Map _roomInfo = new HashMap<>(24);
+ final static Set _templates = ConcurrentHashMap.newKeySet();
+
+ public HarnakUndergroundRuinsZone()
+ {
+ addKillId(NORMAL_MOBS);
+ addSpawnId(NORMAL_MOBS);
+ startQuestTimer("HARNAK_SPAWN", 15000, null, null, false);
+ }
+
+ @Override
+ public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
+ {
+ if (event.equals("HARNAK_SPAWN"))
+ {
+ for (int zoneId = 60142; zoneId <= 60165; zoneId++)
+ {
+ L2ZoneType zone = ZoneManager.getInstance().getZoneById(zoneId);
+ _roomInfo.put(zone, new zoneInfo());
+ String zoneName = zone.getName().toLowerCase().replace(" ", "_");
+ _templates.stream().forEach(t -> t.spawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName), null));
+ }
+ }
+ return super.onAdvEvent(event, npc, player);
+ }
+
+ public static final class zoneInfo
+ {
+ private int currentPoints = 0;
+ private int currentMonitorizedDamage = 0;
+ private int zoneStage = 0;
+
+ void setZoneStage(int a)
+ {
+ zoneStage = a;
+ }
+
+ void setCurrentPoint(int a)
+ {
+ currentPoints = a;
+ }
+
+ void setMonitorizedDamage(int a)
+ {
+ currentMonitorizedDamage = a;
+ }
+
+ int getZoneStage()
+ {
+ return zoneStage;
+ }
+
+ int getCurrentPoints()
+ {
+ return currentPoints;
+ }
+
+ int getCurrentMonitorizedDamage()
+ {
+ return currentMonitorizedDamage;
+ }
+
+ void reset()
+ {
+ currentPoints = 0;
+ currentMonitorizedDamage = 0;
+ zoneStage = 0;
+ }
+ }
+
+ private static final class changeZoneStage implements Runnable
+ {
+ private final L2ZoneType zone;
+
+ public changeZoneStage(L2ZoneType a)
+ {
+ zone = a;
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ zoneInfo currentInfo = _roomInfo.get(zone);
+ switch (currentInfo.getZoneStage())
+ {
+ case 0:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MONITOR_THE_DAMAGE_FOR_30_SEC, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 1:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 2:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT2, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 3:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT3, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 4:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT4, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 5:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT5, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 6:
+ {
+ if (currentInfo.getCurrentMonitorizedDamage() >= 10)
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.DEMONIC_SYSTEM_WILL_ACTIVATE, ExShowScreenMessage.TOP_CENTER, 3000));
+ String zoneName = zone.getName().toLowerCase().replace(" ", "_");
+ _templates.stream().forEach(t -> t.despawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName)));
+ _templates.stream().forEach(t -> t.spawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName.concat("_demonic")), null));
+ zone.getPlayersInside().forEach(temp -> temp.sendPacket(new ExSendUIEvent(temp, false, false, 600, 0, NpcStringId.DEMONIC_SYSTEM_ACTIVATED)));
+ currentInfo.setZoneStage(7);
+ ThreadPoolManager.getInstance().scheduleGeneral(new changeZoneStage(zone), 600000); // 10min
+ }
+ else
+ {
+ currentInfo.reset();
+ return;
+ }
+ break;
+ }
+ case 7:
+ {
+ currentInfo.reset();
+ for (L2PcInstance player : zone.getPlayersInside())
+ {
+ if (player != null)
+ {
+ player.sendPacket(new ExSendUIEvent(player));
+ }
+ }
+ String zoneName = zone.getName().toLowerCase().replace(" ", "_");
+ _templates.stream().forEach(t -> t.despawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName.concat("_demonic"))));
+ _templates.stream().forEach(t -> t.spawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName), null));
+ return;
+ }
+ }
+ if (currentInfo.getZoneStage() < 6)
+ {
+ currentInfo.setZoneStage(currentInfo.getZoneStage() + 1);
+ ThreadPoolManager.getInstance().scheduleGeneral(new changeZoneStage(zone), 5000);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
+ {
+ for (Entry currentZone : _roomInfo.entrySet())
+ {
+ if (currentZone.getKey().isInsideZone(npc))
+ {
+ zoneInfo currentInfo = currentZone.getValue();
+ int currentPoints = currentInfo.getCurrentPoints();
+ if (currentPoints == 300)
+ {
+ if (currentInfo.getZoneStage() < 1)
+ {
+ return super.onKill(npc, killer, isSummon);
+ }
+ int currentDamage = currentInfo.getCurrentMonitorizedDamage();
+ int calcDamage = currentDamage + 1;
+ if (calcDamage >= 10)
+ {
+ calcDamage = 10;
+ }
+ currentInfo.setMonitorizedDamage(calcDamage);
+ for (L2PcInstance player : currentZone.getKey().getPlayersInside())
+ {
+ if (player != null)
+ {
+ player.sendPacket(new ExSendUIEvent(player, ExSendUIEvent.TYPE_NORNIL, calcDamage, 10, NpcStringId.MONITOR_THE_DAMAGE));
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ int calcPoints = currentPoints + 1;
+ if (calcPoints >= 300)
+ {
+ calcPoints = 300;
+ ThreadPoolManager.getInstance().scheduleGeneral(new changeZoneStage(currentZone.getKey()), 1000);
+ }
+ currentInfo.setCurrentPoint(calcPoints);
+ for (L2PcInstance player : currentZone.getKey().getPlayersInside())
+ {
+ if (player != null)
+ {
+ player.sendPacket(new ExSendUIEvent(player, ExSendUIEvent.TYPE_NORNIL, calcPoints, 300, NpcStringId.DANGER_INCREASING_DANGER_INCREASING));
+ }
+ }
+ }
+ }
+
+ if (npc.getDisplayEffect() > 0)
+ {
+ L2MonsterInstance copy = (L2MonsterInstance) addSpawn(npc.getId(), npc.getX(), npc.getY(), npc.getZ(), 0, true, 0, false);
+ copy.setTarget(killer);
+ copy.addDamageHate(killer, 500, 99999);
+ copy.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, killer);
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public final String onSpawn(L2Npc npc)
+ {
+ if (getRandom(20) > 18)
+ {
+ npc.setDisplayEffect(1);
+ }
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public void onSpawnActivate(SpawnTemplate template)
+ {
+ _templates.add(template);
+ }
+
+ public static void main(String[] args)
+ {
+ new HarnakUndergroundRuinsZone();
+ }
+}
diff --git a/L2J_Mobius_Helios/dist/game/data/spawns/TalkingIsland/HarnakUndergroundRuins.xml b/L2J_Mobius_Helios/dist/game/data/spawns/TalkingIsland/HarnakUndergroundRuins.xml
index 60c414c76b..643e3bfdf9 100644
--- a/L2J_Mobius_Helios/dist/game/data/spawns/TalkingIsland/HarnakUndergroundRuins.xml
+++ b/L2J_Mobius_Helios/dist/game/data/spawns/TalkingIsland/HarnakUndergroundRuins.xml
@@ -1,254 +1,547 @@
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Helios/dist/game/data/zones/custom_script.xml b/L2J_Mobius_Helios/dist/game/data/zones/custom_script.xml
index 92b043acb8..a4369aa412 100644
--- a/L2J_Mobius_Helios/dist/game/data/zones/custom_script.xml
+++ b/L2J_Mobius_Helios/dist/game/data/zones/custom_script.xml
@@ -801,4 +801,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExSendUIEvent.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExSendUIEvent.java
index 91b8d28cb2..b37cfb34e2 100644
--- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExSendUIEvent.java
+++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExSendUIEvent.java
@@ -26,6 +26,17 @@ import com.l2jmobius.gameserver.network.OutgoingPackets;
public class ExSendUIEvent implements IClientOutgoingPacket
{
+ // UI Types
+ public static int TYPE_COUNT_DOWN = 0;
+ public static int TYPE_REMOVE = 1;
+ public static int TYPE_ISTINA = 2;
+ public static int TYPE_COUNTER = 3;
+ public static int TYPE_GP_TIMER = 4;
+ public static int TYPE_NORNIL = 5;
+ public static int TYPE_DRACO_INCUBATION_1 = 6;
+ public static int TYPE_DRACO_INCUBATION_2 = 7;
+ public static int TYPE_CLAN_PROGRESS_BAR = 8;
+
private final int _objectId;
private final int _type;
private final int _countUp;
@@ -36,6 +47,28 @@ public class ExSendUIEvent implements IClientOutgoingPacket
private final int _npcstringId;
private List _params = null;
+ /**
+ * Remove UI
+ * @param player
+ */
+ public ExSendUIEvent(L2PcInstance player)
+ {
+ this(player, TYPE_REMOVE, 0, 0, 0, 0, 0, -1);
+ }
+
+ /**
+ * @param player
+ * @param uiType
+ * @param currentPoints
+ * @param maxPoints
+ * @param npcString
+ * @param params
+ */
+ public ExSendUIEvent(L2PcInstance player, int uiType, int currentPoints, int maxPoints, NpcStringId npcString, String... params)
+ {
+ this(player, uiType, -1, currentPoints, maxPoints, -1, -1, npcString.getId(), params);
+ }
+
/**
* @param player
* @param hide
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/ai/areas/TalkingIsland/HarnakUndergroundRuinsZone/HarnakUndergroundRuinsZone.java b/L2J_Mobius_Underground/dist/game/data/scripts/ai/areas/TalkingIsland/HarnakUndergroundRuinsZone/HarnakUndergroundRuinsZone.java
new file mode 100644
index 0000000000..1078ee92a6
--- /dev/null
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/ai/areas/TalkingIsland/HarnakUndergroundRuinsZone/HarnakUndergroundRuinsZone.java
@@ -0,0 +1,294 @@
+/*
+ * 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.TalkingIsland.HarnakUndergroundRuinsZone;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.l2jmobius.gameserver.ThreadPoolManager;
+import com.l2jmobius.gameserver.ai.CtrlIntention;
+import com.l2jmobius.gameserver.instancemanager.ZoneManager;
+import com.l2jmobius.gameserver.model.actor.L2Npc;
+import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.spawns.SpawnTemplate;
+import com.l2jmobius.gameserver.model.zone.L2ZoneType;
+import com.l2jmobius.gameserver.network.NpcStringId;
+import com.l2jmobius.gameserver.network.serverpackets.ExSendUIEvent;
+import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * Harnak Underground Ruins
+ * @video https://www.youtube.com/watch?v=0IdcAB3aYO0
+ * @author LasTravel, Gigi
+ * @date 2017-03-10 - [13:09:05]
+ */
+public class HarnakUndergroundRuinsZone extends AbstractNpcAI
+{
+ //@formatter:off
+ private static final int[] NORMAL_MOBS = {22931, 22932, 22933, 22934, 22935, 22936, 22937, 22938, 23349};
+ //@formatter:on
+ static Map _roomInfo = new HashMap<>(24);
+ final static Set _templates = ConcurrentHashMap.newKeySet();
+
+ public HarnakUndergroundRuinsZone()
+ {
+ addKillId(NORMAL_MOBS);
+ addSpawnId(NORMAL_MOBS);
+ startQuestTimer("HARNAK_SPAWN", 15000, null, null, false);
+ }
+
+ @Override
+ public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
+ {
+ if (event.equals("HARNAK_SPAWN"))
+ {
+ for (int zoneId = 60142; zoneId <= 60165; zoneId++)
+ {
+ L2ZoneType zone = ZoneManager.getInstance().getZoneById(zoneId);
+ _roomInfo.put(zone, new zoneInfo());
+ String zoneName = zone.getName().toLowerCase().replace(" ", "_");
+ _templates.stream().forEach(t -> t.spawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName), null));
+ }
+ }
+ return super.onAdvEvent(event, npc, player);
+ }
+
+ public static final class zoneInfo
+ {
+ private int currentPoints = 0;
+ private int currentMonitorizedDamage = 0;
+ private int zoneStage = 0;
+
+ void setZoneStage(int a)
+ {
+ zoneStage = a;
+ }
+
+ void setCurrentPoint(int a)
+ {
+ currentPoints = a;
+ }
+
+ void setMonitorizedDamage(int a)
+ {
+ currentMonitorizedDamage = a;
+ }
+
+ int getZoneStage()
+ {
+ return zoneStage;
+ }
+
+ int getCurrentPoints()
+ {
+ return currentPoints;
+ }
+
+ int getCurrentMonitorizedDamage()
+ {
+ return currentMonitorizedDamage;
+ }
+
+ void reset()
+ {
+ currentPoints = 0;
+ currentMonitorizedDamage = 0;
+ zoneStage = 0;
+ }
+ }
+
+ private static final class changeZoneStage implements Runnable
+ {
+ private final L2ZoneType zone;
+
+ public changeZoneStage(L2ZoneType a)
+ {
+ zone = a;
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ zoneInfo currentInfo = _roomInfo.get(zone);
+ switch (currentInfo.getZoneStage())
+ {
+ case 0:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.MONITOR_THE_DAMAGE_FOR_30_SEC, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 1:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 2:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT2, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 3:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT3, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 4:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT4, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 5:
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.SECONDS_LEFT5, ExShowScreenMessage.TOP_CENTER, 3000));
+ break;
+ }
+ case 6:
+ {
+ if (currentInfo.getCurrentMonitorizedDamage() >= 10)
+ {
+ zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.DEMONIC_SYSTEM_WILL_ACTIVATE, ExShowScreenMessage.TOP_CENTER, 3000));
+ String zoneName = zone.getName().toLowerCase().replace(" ", "_");
+ _templates.stream().forEach(t -> t.despawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName)));
+ _templates.stream().forEach(t -> t.spawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName.concat("_demonic")), null));
+ zone.getPlayersInside().forEach(temp -> temp.sendPacket(new ExSendUIEvent(temp, false, false, 600, 0, NpcStringId.DEMONIC_SYSTEM_ACTIVATED)));
+ currentInfo.setZoneStage(7);
+ ThreadPoolManager.getInstance().scheduleGeneral(new changeZoneStage(zone), 600000); // 10min
+ }
+ else
+ {
+ currentInfo.reset();
+ return;
+ }
+ break;
+ }
+ case 7:
+ {
+ currentInfo.reset();
+ for (L2PcInstance player : zone.getPlayersInside())
+ {
+ if (player != null)
+ {
+ player.sendPacket(new ExSendUIEvent(player));
+ }
+ }
+ String zoneName = zone.getName().toLowerCase().replace(" ", "_");
+ _templates.stream().forEach(t -> t.despawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName.concat("_demonic"))));
+ _templates.stream().forEach(t -> t.spawn(g -> String.valueOf(g.getName()).equalsIgnoreCase(zoneName), null));
+ return;
+ }
+ }
+ if (currentInfo.getZoneStage() < 6)
+ {
+ currentInfo.setZoneStage(currentInfo.getZoneStage() + 1);
+ ThreadPoolManager.getInstance().scheduleGeneral(new changeZoneStage(zone), 5000);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
+ {
+ for (Entry currentZone : _roomInfo.entrySet())
+ {
+ if (currentZone.getKey().isInsideZone(npc))
+ {
+ zoneInfo currentInfo = currentZone.getValue();
+ int currentPoints = currentInfo.getCurrentPoints();
+ if (currentPoints == 300)
+ {
+ if (currentInfo.getZoneStage() < 1)
+ {
+ return super.onKill(npc, killer, isSummon);
+ }
+ int currentDamage = currentInfo.getCurrentMonitorizedDamage();
+ int calcDamage = currentDamage + 1;
+ if (calcDamage >= 10)
+ {
+ calcDamage = 10;
+ }
+ currentInfo.setMonitorizedDamage(calcDamage);
+ for (L2PcInstance player : currentZone.getKey().getPlayersInside())
+ {
+ if (player != null)
+ {
+ player.sendPacket(new ExSendUIEvent(player, ExSendUIEvent.TYPE_NORNIL, calcDamage, 10, NpcStringId.MONITOR_THE_DAMAGE));
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ int calcPoints = currentPoints + 1;
+ if (calcPoints >= 300)
+ {
+ calcPoints = 300;
+ ThreadPoolManager.getInstance().scheduleGeneral(new changeZoneStage(currentZone.getKey()), 1000);
+ }
+ currentInfo.setCurrentPoint(calcPoints);
+ for (L2PcInstance player : currentZone.getKey().getPlayersInside())
+ {
+ if (player != null)
+ {
+ player.sendPacket(new ExSendUIEvent(player, ExSendUIEvent.TYPE_NORNIL, calcPoints, 300, NpcStringId.DANGER_INCREASING_DANGER_INCREASING));
+ }
+ }
+ }
+ }
+
+ if (npc.getDisplayEffect() > 0)
+ {
+ L2MonsterInstance copy = (L2MonsterInstance) addSpawn(npc.getId(), npc.getX(), npc.getY(), npc.getZ(), 0, true, 0, false);
+ copy.setTarget(killer);
+ copy.addDamageHate(killer, 500, 99999);
+ copy.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, killer);
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public final String onSpawn(L2Npc npc)
+ {
+ if (getRandom(20) > 18)
+ {
+ npc.setDisplayEffect(1);
+ }
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public void onSpawnActivate(SpawnTemplate template)
+ {
+ _templates.add(template);
+ }
+
+ public static void main(String[] args)
+ {
+ new HarnakUndergroundRuinsZone();
+ }
+}
diff --git a/L2J_Mobius_Underground/dist/game/data/spawns/TalkingIsland/HarnakUndergroundRuins.xml b/L2J_Mobius_Underground/dist/game/data/spawns/TalkingIsland/HarnakUndergroundRuins.xml
index 60c414c76b..643e3bfdf9 100644
--- a/L2J_Mobius_Underground/dist/game/data/spawns/TalkingIsland/HarnakUndergroundRuins.xml
+++ b/L2J_Mobius_Underground/dist/game/data/spawns/TalkingIsland/HarnakUndergroundRuins.xml
@@ -1,254 +1,547 @@
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Underground/dist/game/data/zones/custom_script.xml b/L2J_Mobius_Underground/dist/game/data/zones/custom_script.xml
index 92b043acb8..a4369aa412 100644
--- a/L2J_Mobius_Underground/dist/game/data/zones/custom_script.xml
+++ b/L2J_Mobius_Underground/dist/game/data/zones/custom_script.xml
@@ -801,4 +801,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExSendUIEvent.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExSendUIEvent.java
index 91b8d28cb2..b37cfb34e2 100644
--- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExSendUIEvent.java
+++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExSendUIEvent.java
@@ -26,6 +26,17 @@ import com.l2jmobius.gameserver.network.OutgoingPackets;
public class ExSendUIEvent implements IClientOutgoingPacket
{
+ // UI Types
+ public static int TYPE_COUNT_DOWN = 0;
+ public static int TYPE_REMOVE = 1;
+ public static int TYPE_ISTINA = 2;
+ public static int TYPE_COUNTER = 3;
+ public static int TYPE_GP_TIMER = 4;
+ public static int TYPE_NORNIL = 5;
+ public static int TYPE_DRACO_INCUBATION_1 = 6;
+ public static int TYPE_DRACO_INCUBATION_2 = 7;
+ public static int TYPE_CLAN_PROGRESS_BAR = 8;
+
private final int _objectId;
private final int _type;
private final int _countUp;
@@ -36,6 +47,28 @@ public class ExSendUIEvent implements IClientOutgoingPacket
private final int _npcstringId;
private List _params = null;
+ /**
+ * Remove UI
+ * @param player
+ */
+ public ExSendUIEvent(L2PcInstance player)
+ {
+ this(player, TYPE_REMOVE, 0, 0, 0, 0, 0, -1);
+ }
+
+ /**
+ * @param player
+ * @param uiType
+ * @param currentPoints
+ * @param maxPoints
+ * @param npcString
+ * @param params
+ */
+ public ExSendUIEvent(L2PcInstance player, int uiType, int currentPoints, int maxPoints, NpcStringId npcString, String... params)
+ {
+ this(player, uiType, -1, currentPoints, maxPoints, -1, -1, npcString.getId(), params);
+ }
+
/**
* @param player
* @param hide