Arushinai:
+Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
+Baium's anger was so great that the Heavenly Rift itself began yo change under his influence.
+I'll give you a little clue... So that you can imagine what can happen in the fault.
+Or you will be attacked by 40 Divine Angels (kill them as soon as you notice),
+or the will be 20 Bombs (their explosions will summon the Divine Angels, who will also have to be killed).
+And be careful: from an exploding bomb can drop anything valuable! Either you need to protect the Tower from 20 Divine Angels who will try to destroy it.
+If you do this, you will receive a reward. Be extremely attentive!
+Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
+Gather with strength - and go!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
new file mode 100644
index 0000000000..5d50e993eb
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
@@ -0,0 +1,4 @@
+Arushinai:
+It's not easy to get into the Heavenly Rift. When are you ready, I will send you back to Dimensional Vortex.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
new file mode 100644
index 0000000000..98be98fc90
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
@@ -0,0 +1,6 @@
+Arushinai:
+Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
+Inside the fault, you can stay not longer than 30 minutes. In such a dangerous place, mutual assistance and teamwork are especially important.
+And remember: if you leave the rift prematurely, you will not be able to return here!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
new file mode 100644
index 0000000000..c6db1d0803
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
@@ -0,0 +1,155 @@
+/*
+ * 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.TowerOfInsolence.Arushinai;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Arushinai extends AbstractNpcAI
+{
+ // NPC
+ private static final int ARUSHINAI = 30401;
+
+ private Arushinai()
+ {
+ addStartNpc(ARUSHINAI);
+ addTalkId(ARUSHINAI);
+ addFirstTalkId(ARUSHINAI);
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("proceed"))
+ {
+ if (!player.isGM())
+ {
+ Party party = player.getParty();
+ if (party == null)
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ }
+
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
+ {
+ return null; // TODO: Find html?
+ }
+
+ final int riftLevel = Rnd.get(1, 3);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
+ switch (riftLevel)
+ {
+ case 1:
+ {
+ HeavenlyRiftManager.startEvent20Bomb(player);
+ return null;
+ }
+ case 2:
+ {
+ HeavenlyRiftManager.startEventTower(player);
+ return null;
+ }
+ case 3:
+ {
+ HeavenlyRiftManager.startEvent40Angels(player);
+ break;
+ }
+ }
+ return null;
+ }
+
+ if (!event.equals("finish"))
+ {
+ return null;
+ }
+
+ if (player.isInParty())
+ {
+ Party party = player.getParty();
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(114264, 13352, -5104);
+ }
+ return null;
+ }
+
+ if (player.isGM())
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
+ return null;
+ }
+
+ public static void main(String[] args)
+ {
+ new Arushinai();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
new file mode 100644
index 0000000000..ec1f8a6799
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
@@ -0,0 +1,6 @@
+
+Dimensional Vortex:
+The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a Celestial Shard. You can extract it from the Unidentified Stone after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
new file mode 100644
index 0000000000..be5290b1f5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
@@ -0,0 +1,5 @@
+Dimensional Vortex:
+Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the Unidentified Stone to extract Broken Celestial Shards from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
new file mode 100644
index 0000000000..ddba0bd4f0
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
@@ -0,0 +1,4 @@
+Dimensional Vortex:
+You need an Airborne Fragment from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
new file mode 100644
index 0000000000..7b63cb1b68
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
@@ -0,0 +1,6 @@
+Dimensional Vortex:
+Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
new file mode 100644
index 0000000000..e676849ad1
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
@@ -0,0 +1,135 @@
+/*
+ * 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.TowerOfInsolence.DimensionalVortex;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DimensionalVortex extends AbstractNpcAI
+{
+ // NPC
+ private static final int DIMENTIONAL_VORTEX = 30952;
+ // Items
+ private static final int CELESTIAL_SHARD = 49759;
+ private static final int BROKEN_CELESTIAL_SHARD = 49767;
+
+ private DimensionalVortex()
+ {
+ addStartNpc(DIMENTIONAL_VORTEX);
+ addTalkId(DIMENTIONAL_VORTEX);
+ addFirstTalkId(DIMENTIONAL_VORTEX);
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("tryenter"))
+ {
+ if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
+ {
+ if (player.isGM())
+ {
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ player.teleToLocation(112685, 13362, 10966);
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
+ return null;
+ }
+ if (!player.isInParty())
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ return null;
+ }
+ final Party party = player.getParty();
+ if ((party == null) || !party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(112685, 13362, 10966);
+ }
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
+ }
+ else
+ {
+ return "30952-3.htm";
+ }
+ }
+ else if (event.equals("exchange"))
+ {
+ long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
+ if (count < 10)
+ {
+ return "30952-2.htm";
+ }
+ if ((count % 10) != 0)
+ {
+ count -= count % 10;
+ }
+ final long reward = count / 10;
+ player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
+ player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
+ }
+ return null;
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ public static void main(String[] args)
+ {
+ new DimensionalVortex();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
new file mode 100644
index 0000000000..1768844cde
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
@@ -0,0 +1,233 @@
+/*
+ * 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.TowerOfInsolence;
+
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.model.ChanceLocation;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
+import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class EnergyOfInsolence extends AbstractNpcAI
+{
+ private static final int LEVEL_MAX_DIFF = 9;
+ private static final int TIME_UNTIL_MOVE = 1800000;
+ private static final int ELMOREDEN_LADY = 20977;
+ private static final int POWER_ANGEL_AMON = 21081;
+ private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
+ private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
+ private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
+ private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
+ private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
+ private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
+ {
+ ELMOREDEN_LADY,
+ POWER_ANGEL_AMON
+ };
+ private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
+ {
+ 20978,
+ 20979,
+ 21073,
+ 21082,
+ 21083
+ };
+ private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
+ {
+ 20980,
+ 20981,
+ 20982,
+ 20983,
+ 20984,
+ 20985,
+ 21074,
+ 21075,
+ 21076,
+ 21077,
+ 21080
+ };
+ private static ScheduledFuture> _scheduleTaskElmoreden;
+ private static ScheduledFuture> _scheduleTaskAmon;
+
+ private EnergyOfInsolence()
+ {
+ addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(UNIDENTIFIED_STONE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_MINIONS);
+ }
+
+ private void makeInvul(Npc npc)
+ {
+ npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(true);
+ }
+
+ private void makeMortal(Npc npc)
+ {
+ npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(false);
+ }
+
+ private void makeTalk(Npc npc, boolean spawning)
+ {
+ NpcStringId npcStringId = null;
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
+ }
+ }
+ npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, true);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ makeInvul(npc);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ }
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
+ {
+ npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, false);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ _scheduleTaskElmoreden.cancel(true);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon.cancel(true);
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
+ {
+ npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
+ {
+ final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
+ if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
+ {
+ makeMortal(leader);
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static AbstractNpcAI provider()
+ {
+ return new EnergyOfInsolence();
+ }
+
+ public class ScheduleAITask implements Runnable
+ {
+ private final Npc _npc;
+ private final int _npcId;
+
+ public ScheduleAITask(Npc npc, int npcId)
+ {
+ _npc = npc;
+ _npcId = npcId;
+ }
+
+ @Override
+ public void run()
+ {
+ if (_npc != null)
+ {
+ _npc.deleteMe();
+ }
+
+ try
+ {
+ final Spawn spawn = new Spawn(_npcId);
+ final List spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
+ final List locations = spawns.get(0).getLocation();
+ final Location location = locations.get(Rnd.get(locations.size()));
+ spawn.setLocation(location);
+ spawn.doSpawn();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new EnergyOfInsolence();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
new file mode 100644
index 0000000000..758820626f
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
@@ -0,0 +1,106 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.Playable;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.events.AbstractScript;
+import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Bomb extends AbstractNpcAI
+{
+ // NPCs
+ private static final int BOMB = 18003;
+ private static final int DIVINE_ANGEL = 20139;
+ // Items
+ private static final int[] ITEM_DROP_1 = new int[]
+ {
+ 49756,
+ 49762,
+ 49763
+ };
+ private static final int[] ITEM_DROP_2 = new int[]
+ {
+ 49760,
+ 49761
+ };
+
+ public Bomb()
+ {
+ addKillId(BOMB);
+ addSpawnId(BOMB);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (Rnd.get(100) < 33)
+ {
+ AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
+ }
+ else
+ {
+ World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
+ {
+ if ((creature != null) && !creature.isDead())
+ {
+ creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
+ }
+ });
+ if (Rnd.get(100) < 50)
+ {
+ if (Rnd.get(100) < 90)
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
+ }
+ else
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
+ }
+ }
+ }
+ if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Bomb();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
new file mode 100644
index 0000000000..5635daa582
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
@@ -0,0 +1,79 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.ai.AttackableAI;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DivineAngel extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public DivineAngel()
+ {
+ addSpawnId(DIVINE_ANGEL);
+ addKillId(DIVINE_ANGEL);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
+
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
+ {
+ ((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
+ }
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
+ {
+ ((AttackableAI) npc.getAI()).setGlobalAggro(0);
+ }
+ return super.onSpawn(npc);
+ }
+
+ public static void main(String[] args)
+ {
+ new DivineAngel();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
new file mode 100644
index 0000000000..667f598286
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
@@ -0,0 +1,64 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Tower extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public Tower()
+ {
+ addKillId(TOWER);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
+ {
+ creature.decayMe();
+ }
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Tower();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/spawns/Aden/Aden.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/spawns/Aden/Aden.xml
index 31d58570e1..13442fff0a 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/spawns/Aden/Aden.xml
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/spawns/Aden/Aden.xml
@@ -3,8 +3,6 @@
-
-
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/spawns/Aden/TowerOfInsolence.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/spawns/Aden/TowerOfInsolence.xml
index 3e2afbce77..4d41300ca7 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/spawns/Aden/TowerOfInsolence.xml
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/spawns/Aden/TowerOfInsolence.xml
@@ -1609,10 +1609,9 @@
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/18000-18099.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/18000-18099.xml
index 363d59a8ec..41b83a94fc 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/18000-18099.xml
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/18000-18099.xml
@@ -141,7 +141,7 @@
MALE
-
+
@@ -175,7 +175,7 @@
MALE
-
+
@@ -185,7 +185,7 @@
520
-
+
@@ -305,6 +305,7 @@
DEMONICFEMALE
+
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/20100-20199.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/20100-20199.xml
index db7d45536e..dc9c208de9 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/20100-20199.xml
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/npcs/20100-20199.xml
@@ -1778,6 +1778,7 @@
DIVINEMALE
+
@@ -1803,7 +1804,11 @@
false
-
+
+
+ ALL
+
+
diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/zones/no_restart.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/zones/no_restart.xml
index 5efbfe3bd9..9049d695d1 100644
--- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/zones/no_restart.xml
+++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/zones/no_restart.xml
@@ -322,6 +322,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
new file mode 100644
index 0000000000..29800c3dd8
--- /dev/null
+++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
@@ -0,0 +1,142 @@
+/*
+ * 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 org.l2jmobius.gameserver.instancemanager;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.zone.ZoneType;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+/**
+ * @author Brutallis
+ */
+public class HeavenlyRiftManager
+{
+ private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
+
+ public static ZoneType getZone()
+ {
+ return ZONE;
+ }
+
+ public static int getAliveNpcCount(int npcId)
+ {
+ int result = 0;
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
+ {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ public static void startEvent20Bomb(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
+ spawnMonster(18003, 113352, 12936, 10976, 1800000);
+ spawnMonster(18003, 113592, 13272, 10976, 1800000);
+ spawnMonster(18003, 113816, 13592, 10976, 1800000);
+ spawnMonster(18003, 113080, 13192, 10976, 1800000);
+ spawnMonster(18003, 113336, 13528, 10976, 1800000);
+ spawnMonster(18003, 113560, 13832, 10976, 1800000);
+ spawnMonster(18003, 112776, 13512, 10976, 1800000);
+ spawnMonster(18003, 113064, 13784, 10976, 1800000);
+ spawnMonster(18003, 112440, 13848, 10976, 1800000);
+ spawnMonster(18003, 112728, 14104, 10976, 1800000);
+ spawnMonster(18003, 112760, 14600, 10976, 1800000);
+ spawnMonster(18003, 112392, 14456, 10976, 1800000);
+ spawnMonster(18003, 112104, 14184, 10976, 1800000);
+ spawnMonster(18003, 111816, 14488, 10976, 1800000);
+ spawnMonster(18003, 112104, 14760, 10976, 1800000);
+ spawnMonster(18003, 112392, 15032, 10976, 1800000);
+ spawnMonster(18003, 112120, 15288, 10976, 1800000);
+ spawnMonster(18003, 111784, 15064, 10976, 1800000);
+ spawnMonster(18003, 111480, 14824, 10976, 1800000);
+ spawnMonster(18003, 113144, 14216, 10976, 1800000);
+ }
+
+ public static void startEventTower(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
+ spawnMonster(18004, 112648, 14072, 10976, 1800000);
+ ThreadPool.schedule(() ->
+ {
+ for (int i = 0; i < 20; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }, 10000);
+ }
+
+ public static void startEvent40Angels(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
+ for (int i = 0; i < 40; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }
+
+ private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
+ {
+ try
+ {
+ Spawn spawn = new Spawn(npcId);
+ Location location = new Location(x, y, z);
+ spawn.setLocation(location);
+ Npc npc = spawn.doSpawn();
+ npc.scheduleDespawn(despawnTime);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ public static class ClearZoneTask implements Runnable
+ {
+ private final Npc _npc;
+
+ public ClearZoneTask(Npc npc)
+ {
+ _npc = npc;
+ }
+
+ @Override
+ public void run()
+ {
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isPlayer())
+ {
+ creature.teleToLocation(114264, 13352, -5104);
+ }
+ else if (creature.isNpc() && (creature.getId() != 30401))
+ {
+ creature.decayMe();
+ }
+ }
+ _npc.setBusy(false);
+ }
+ }
+}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/multisell/30952.xml b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/multisell/30952.xml
new file mode 100644
index 0000000000..6eb9971522
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/multisell/30952.xml
@@ -0,0 +1,12 @@
+
+
+
+ 30952
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
new file mode 100644
index 0000000000..e3f0d71258
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
@@ -0,0 +1,12 @@
+Arushinai:
+Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
+Baium's anger was so great that the Heavenly Rift itself began yo change under his influence.
+I'll give you a little clue... So that you can imagine what can happen in the fault.
+Or you will be attacked by 40 Divine Angels (kill them as soon as you notice),
+or the will be 20 Bombs (their explosions will summon the Divine Angels, who will also have to be killed).
+And be careful: from an exploding bomb can drop anything valuable! Either you need to protect the Tower from 20 Divine Angels who will try to destroy it.
+If you do this, you will receive a reward. Be extremely attentive!
+Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
+Gather with strength - and go!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
new file mode 100644
index 0000000000..5d50e993eb
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
@@ -0,0 +1,4 @@
+Arushinai:
+It's not easy to get into the Heavenly Rift. When are you ready, I will send you back to Dimensional Vortex.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
new file mode 100644
index 0000000000..98be98fc90
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
@@ -0,0 +1,6 @@
+Arushinai:
+Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
+Inside the fault, you can stay not longer than 30 minutes. In such a dangerous place, mutual assistance and teamwork are especially important.
+And remember: if you leave the rift prematurely, you will not be able to return here!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
new file mode 100644
index 0000000000..c6db1d0803
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
@@ -0,0 +1,155 @@
+/*
+ * 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.TowerOfInsolence.Arushinai;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Arushinai extends AbstractNpcAI
+{
+ // NPC
+ private static final int ARUSHINAI = 30401;
+
+ private Arushinai()
+ {
+ addStartNpc(ARUSHINAI);
+ addTalkId(ARUSHINAI);
+ addFirstTalkId(ARUSHINAI);
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("proceed"))
+ {
+ if (!player.isGM())
+ {
+ Party party = player.getParty();
+ if (party == null)
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ }
+
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
+ {
+ return null; // TODO: Find html?
+ }
+
+ final int riftLevel = Rnd.get(1, 3);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
+ switch (riftLevel)
+ {
+ case 1:
+ {
+ HeavenlyRiftManager.startEvent20Bomb(player);
+ return null;
+ }
+ case 2:
+ {
+ HeavenlyRiftManager.startEventTower(player);
+ return null;
+ }
+ case 3:
+ {
+ HeavenlyRiftManager.startEvent40Angels(player);
+ break;
+ }
+ }
+ return null;
+ }
+
+ if (!event.equals("finish"))
+ {
+ return null;
+ }
+
+ if (player.isInParty())
+ {
+ Party party = player.getParty();
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(114264, 13352, -5104);
+ }
+ return null;
+ }
+
+ if (player.isGM())
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
+ return null;
+ }
+
+ public static void main(String[] args)
+ {
+ new Arushinai();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
new file mode 100644
index 0000000000..ec1f8a6799
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
@@ -0,0 +1,6 @@
+
+Dimensional Vortex:
+The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a Celestial Shard. You can extract it from the Unidentified Stone after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
new file mode 100644
index 0000000000..be5290b1f5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
@@ -0,0 +1,5 @@
+Dimensional Vortex:
+Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the Unidentified Stone to extract Broken Celestial Shards from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
new file mode 100644
index 0000000000..ddba0bd4f0
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
@@ -0,0 +1,4 @@
+Dimensional Vortex:
+You need an Airborne Fragment from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
new file mode 100644
index 0000000000..7b63cb1b68
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
@@ -0,0 +1,6 @@
+Dimensional Vortex:
+Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
new file mode 100644
index 0000000000..e676849ad1
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
@@ -0,0 +1,135 @@
+/*
+ * 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.TowerOfInsolence.DimensionalVortex;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DimensionalVortex extends AbstractNpcAI
+{
+ // NPC
+ private static final int DIMENTIONAL_VORTEX = 30952;
+ // Items
+ private static final int CELESTIAL_SHARD = 49759;
+ private static final int BROKEN_CELESTIAL_SHARD = 49767;
+
+ private DimensionalVortex()
+ {
+ addStartNpc(DIMENTIONAL_VORTEX);
+ addTalkId(DIMENTIONAL_VORTEX);
+ addFirstTalkId(DIMENTIONAL_VORTEX);
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("tryenter"))
+ {
+ if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
+ {
+ if (player.isGM())
+ {
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ player.teleToLocation(112685, 13362, 10966);
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
+ return null;
+ }
+ if (!player.isInParty())
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ return null;
+ }
+ final Party party = player.getParty();
+ if ((party == null) || !party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(112685, 13362, 10966);
+ }
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
+ }
+ else
+ {
+ return "30952-3.htm";
+ }
+ }
+ else if (event.equals("exchange"))
+ {
+ long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
+ if (count < 10)
+ {
+ return "30952-2.htm";
+ }
+ if ((count % 10) != 0)
+ {
+ count -= count % 10;
+ }
+ final long reward = count / 10;
+ player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
+ player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
+ }
+ return null;
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ public static void main(String[] args)
+ {
+ new DimensionalVortex();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
new file mode 100644
index 0000000000..1768844cde
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
@@ -0,0 +1,233 @@
+/*
+ * 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.TowerOfInsolence;
+
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.model.ChanceLocation;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
+import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class EnergyOfInsolence extends AbstractNpcAI
+{
+ private static final int LEVEL_MAX_DIFF = 9;
+ private static final int TIME_UNTIL_MOVE = 1800000;
+ private static final int ELMOREDEN_LADY = 20977;
+ private static final int POWER_ANGEL_AMON = 21081;
+ private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
+ private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
+ private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
+ private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
+ private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
+ private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
+ {
+ ELMOREDEN_LADY,
+ POWER_ANGEL_AMON
+ };
+ private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
+ {
+ 20978,
+ 20979,
+ 21073,
+ 21082,
+ 21083
+ };
+ private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
+ {
+ 20980,
+ 20981,
+ 20982,
+ 20983,
+ 20984,
+ 20985,
+ 21074,
+ 21075,
+ 21076,
+ 21077,
+ 21080
+ };
+ private static ScheduledFuture> _scheduleTaskElmoreden;
+ private static ScheduledFuture> _scheduleTaskAmon;
+
+ private EnergyOfInsolence()
+ {
+ addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(UNIDENTIFIED_STONE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_MINIONS);
+ }
+
+ private void makeInvul(Npc npc)
+ {
+ npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(true);
+ }
+
+ private void makeMortal(Npc npc)
+ {
+ npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(false);
+ }
+
+ private void makeTalk(Npc npc, boolean spawning)
+ {
+ NpcStringId npcStringId = null;
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
+ }
+ }
+ npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, true);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ makeInvul(npc);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ }
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
+ {
+ npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, false);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ _scheduleTaskElmoreden.cancel(true);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon.cancel(true);
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
+ {
+ npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
+ {
+ final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
+ if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
+ {
+ makeMortal(leader);
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static AbstractNpcAI provider()
+ {
+ return new EnergyOfInsolence();
+ }
+
+ public class ScheduleAITask implements Runnable
+ {
+ private final Npc _npc;
+ private final int _npcId;
+
+ public ScheduleAITask(Npc npc, int npcId)
+ {
+ _npc = npc;
+ _npcId = npcId;
+ }
+
+ @Override
+ public void run()
+ {
+ if (_npc != null)
+ {
+ _npc.deleteMe();
+ }
+
+ try
+ {
+ final Spawn spawn = new Spawn(_npcId);
+ final List spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
+ final List locations = spawns.get(0).getLocation();
+ final Location location = locations.get(Rnd.get(locations.size()));
+ spawn.setLocation(location);
+ spawn.doSpawn();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new EnergyOfInsolence();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
new file mode 100644
index 0000000000..758820626f
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
@@ -0,0 +1,106 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.Playable;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.events.AbstractScript;
+import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Bomb extends AbstractNpcAI
+{
+ // NPCs
+ private static final int BOMB = 18003;
+ private static final int DIVINE_ANGEL = 20139;
+ // Items
+ private static final int[] ITEM_DROP_1 = new int[]
+ {
+ 49756,
+ 49762,
+ 49763
+ };
+ private static final int[] ITEM_DROP_2 = new int[]
+ {
+ 49760,
+ 49761
+ };
+
+ public Bomb()
+ {
+ addKillId(BOMB);
+ addSpawnId(BOMB);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (Rnd.get(100) < 33)
+ {
+ AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
+ }
+ else
+ {
+ World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
+ {
+ if ((creature != null) && !creature.isDead())
+ {
+ creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
+ }
+ });
+ if (Rnd.get(100) < 50)
+ {
+ if (Rnd.get(100) < 90)
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
+ }
+ else
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
+ }
+ }
+ }
+ if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Bomb();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
new file mode 100644
index 0000000000..5635daa582
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
@@ -0,0 +1,79 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.ai.AttackableAI;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DivineAngel extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public DivineAngel()
+ {
+ addSpawnId(DIVINE_ANGEL);
+ addKillId(DIVINE_ANGEL);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
+
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
+ {
+ ((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
+ }
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
+ {
+ ((AttackableAI) npc.getAI()).setGlobalAggro(0);
+ }
+ return super.onSpawn(npc);
+ }
+
+ public static void main(String[] args)
+ {
+ new DivineAngel();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
new file mode 100644
index 0000000000..667f598286
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
@@ -0,0 +1,64 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Tower extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public Tower()
+ {
+ addKillId(TOWER);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
+ {
+ creature.decayMe();
+ }
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Tower();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/spawns/Aden/Aden.xml b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/spawns/Aden/Aden.xml
index 31d58570e1..13442fff0a 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/spawns/Aden/Aden.xml
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/spawns/Aden/Aden.xml
@@ -3,8 +3,6 @@
-
-
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/spawns/Aden/TowerOfInsolence.xml b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/spawns/Aden/TowerOfInsolence.xml
index 3e2afbce77..4d41300ca7 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/spawns/Aden/TowerOfInsolence.xml
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/spawns/Aden/TowerOfInsolence.xml
@@ -1609,10 +1609,9 @@
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/npcs/18000-18099.xml b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/npcs/18000-18099.xml
index 363d59a8ec..41b83a94fc 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/npcs/18000-18099.xml
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/npcs/18000-18099.xml
@@ -141,7 +141,7 @@
MALE
-
+
@@ -175,7 +175,7 @@
MALE
-
+
@@ -185,7 +185,7 @@
520
-
+
@@ -305,6 +305,7 @@
DEMONICFEMALE
+
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/npcs/20100-20199.xml b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/npcs/20100-20199.xml
index 8cdc376eed..9f46783245 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/npcs/20100-20199.xml
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/npcs/20100-20199.xml
@@ -1778,6 +1778,7 @@
DIVINEMALE
+
@@ -1803,7 +1804,11 @@
false
-
+
+
+ ALL
+
+
diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/zones/no_restart.xml b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/zones/no_restart.xml
index 5efbfe3bd9..9049d695d1 100644
--- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/zones/no_restart.xml
+++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/zones/no_restart.xml
@@ -322,6 +322,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
new file mode 100644
index 0000000000..29800c3dd8
--- /dev/null
+++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
@@ -0,0 +1,142 @@
+/*
+ * 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 org.l2jmobius.gameserver.instancemanager;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.zone.ZoneType;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+/**
+ * @author Brutallis
+ */
+public class HeavenlyRiftManager
+{
+ private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
+
+ public static ZoneType getZone()
+ {
+ return ZONE;
+ }
+
+ public static int getAliveNpcCount(int npcId)
+ {
+ int result = 0;
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
+ {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ public static void startEvent20Bomb(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
+ spawnMonster(18003, 113352, 12936, 10976, 1800000);
+ spawnMonster(18003, 113592, 13272, 10976, 1800000);
+ spawnMonster(18003, 113816, 13592, 10976, 1800000);
+ spawnMonster(18003, 113080, 13192, 10976, 1800000);
+ spawnMonster(18003, 113336, 13528, 10976, 1800000);
+ spawnMonster(18003, 113560, 13832, 10976, 1800000);
+ spawnMonster(18003, 112776, 13512, 10976, 1800000);
+ spawnMonster(18003, 113064, 13784, 10976, 1800000);
+ spawnMonster(18003, 112440, 13848, 10976, 1800000);
+ spawnMonster(18003, 112728, 14104, 10976, 1800000);
+ spawnMonster(18003, 112760, 14600, 10976, 1800000);
+ spawnMonster(18003, 112392, 14456, 10976, 1800000);
+ spawnMonster(18003, 112104, 14184, 10976, 1800000);
+ spawnMonster(18003, 111816, 14488, 10976, 1800000);
+ spawnMonster(18003, 112104, 14760, 10976, 1800000);
+ spawnMonster(18003, 112392, 15032, 10976, 1800000);
+ spawnMonster(18003, 112120, 15288, 10976, 1800000);
+ spawnMonster(18003, 111784, 15064, 10976, 1800000);
+ spawnMonster(18003, 111480, 14824, 10976, 1800000);
+ spawnMonster(18003, 113144, 14216, 10976, 1800000);
+ }
+
+ public static void startEventTower(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
+ spawnMonster(18004, 112648, 14072, 10976, 1800000);
+ ThreadPool.schedule(() ->
+ {
+ for (int i = 0; i < 20; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }, 10000);
+ }
+
+ public static void startEvent40Angels(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
+ for (int i = 0; i < 40; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }
+
+ private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
+ {
+ try
+ {
+ Spawn spawn = new Spawn(npcId);
+ Location location = new Location(x, y, z);
+ spawn.setLocation(location);
+ Npc npc = spawn.doSpawn();
+ npc.scheduleDespawn(despawnTime);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ public static class ClearZoneTask implements Runnable
+ {
+ private final Npc _npc;
+
+ public ClearZoneTask(Npc npc)
+ {
+ _npc = npc;
+ }
+
+ @Override
+ public void run()
+ {
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isPlayer())
+ {
+ creature.teleToLocation(114264, 13352, -5104);
+ }
+ else if (creature.isNpc() && (creature.getId() != 30401))
+ {
+ creature.decayMe();
+ }
+ }
+ _npc.setBusy(false);
+ }
+ }
+}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/multisell/30952.xml b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/multisell/30952.xml
new file mode 100644
index 0000000000..6eb9971522
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/multisell/30952.xml
@@ -0,0 +1,12 @@
+
+
+
+ 30952
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
new file mode 100644
index 0000000000..e3f0d71258
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
@@ -0,0 +1,12 @@
+Arushinai:
+Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
+Baium's anger was so great that the Heavenly Rift itself began yo change under his influence.
+I'll give you a little clue... So that you can imagine what can happen in the fault.
+Or you will be attacked by 40 Divine Angels (kill them as soon as you notice),
+or the will be 20 Bombs (their explosions will summon the Divine Angels, who will also have to be killed).
+And be careful: from an exploding bomb can drop anything valuable! Either you need to protect the Tower from 20 Divine Angels who will try to destroy it.
+If you do this, you will receive a reward. Be extremely attentive!
+Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
+Gather with strength - and go!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
new file mode 100644
index 0000000000..5d50e993eb
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
@@ -0,0 +1,4 @@
+Arushinai:
+It's not easy to get into the Heavenly Rift. When are you ready, I will send you back to Dimensional Vortex.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
new file mode 100644
index 0000000000..98be98fc90
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
@@ -0,0 +1,6 @@
+Arushinai:
+Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
+Inside the fault, you can stay not longer than 30 minutes. In such a dangerous place, mutual assistance and teamwork are especially important.
+And remember: if you leave the rift prematurely, you will not be able to return here!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
new file mode 100644
index 0000000000..c6db1d0803
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
@@ -0,0 +1,155 @@
+/*
+ * 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.TowerOfInsolence.Arushinai;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Arushinai extends AbstractNpcAI
+{
+ // NPC
+ private static final int ARUSHINAI = 30401;
+
+ private Arushinai()
+ {
+ addStartNpc(ARUSHINAI);
+ addTalkId(ARUSHINAI);
+ addFirstTalkId(ARUSHINAI);
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("proceed"))
+ {
+ if (!player.isGM())
+ {
+ Party party = player.getParty();
+ if (party == null)
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ }
+
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
+ {
+ return null; // TODO: Find html?
+ }
+
+ final int riftLevel = Rnd.get(1, 3);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
+ switch (riftLevel)
+ {
+ case 1:
+ {
+ HeavenlyRiftManager.startEvent20Bomb(player);
+ return null;
+ }
+ case 2:
+ {
+ HeavenlyRiftManager.startEventTower(player);
+ return null;
+ }
+ case 3:
+ {
+ HeavenlyRiftManager.startEvent40Angels(player);
+ break;
+ }
+ }
+ return null;
+ }
+
+ if (!event.equals("finish"))
+ {
+ return null;
+ }
+
+ if (player.isInParty())
+ {
+ Party party = player.getParty();
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(114264, 13352, -5104);
+ }
+ return null;
+ }
+
+ if (player.isGM())
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
+ return null;
+ }
+
+ public static void main(String[] args)
+ {
+ new Arushinai();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
new file mode 100644
index 0000000000..ec1f8a6799
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
@@ -0,0 +1,6 @@
+
+Dimensional Vortex:
+The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a Celestial Shard. You can extract it from the Unidentified Stone after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
new file mode 100644
index 0000000000..be5290b1f5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
@@ -0,0 +1,5 @@
+Dimensional Vortex:
+Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the Unidentified Stone to extract Broken Celestial Shards from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
new file mode 100644
index 0000000000..ddba0bd4f0
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
@@ -0,0 +1,4 @@
+Dimensional Vortex:
+You need an Airborne Fragment from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
new file mode 100644
index 0000000000..7b63cb1b68
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
@@ -0,0 +1,6 @@
+Dimensional Vortex:
+Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
new file mode 100644
index 0000000000..e676849ad1
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
@@ -0,0 +1,135 @@
+/*
+ * 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.TowerOfInsolence.DimensionalVortex;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DimensionalVortex extends AbstractNpcAI
+{
+ // NPC
+ private static final int DIMENTIONAL_VORTEX = 30952;
+ // Items
+ private static final int CELESTIAL_SHARD = 49759;
+ private static final int BROKEN_CELESTIAL_SHARD = 49767;
+
+ private DimensionalVortex()
+ {
+ addStartNpc(DIMENTIONAL_VORTEX);
+ addTalkId(DIMENTIONAL_VORTEX);
+ addFirstTalkId(DIMENTIONAL_VORTEX);
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("tryenter"))
+ {
+ if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
+ {
+ if (player.isGM())
+ {
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ player.teleToLocation(112685, 13362, 10966);
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
+ return null;
+ }
+ if (!player.isInParty())
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ return null;
+ }
+ final Party party = player.getParty();
+ if ((party == null) || !party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(112685, 13362, 10966);
+ }
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
+ }
+ else
+ {
+ return "30952-3.htm";
+ }
+ }
+ else if (event.equals("exchange"))
+ {
+ long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
+ if (count < 10)
+ {
+ return "30952-2.htm";
+ }
+ if ((count % 10) != 0)
+ {
+ count -= count % 10;
+ }
+ final long reward = count / 10;
+ player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
+ player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
+ }
+ return null;
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ public static void main(String[] args)
+ {
+ new DimensionalVortex();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
new file mode 100644
index 0000000000..1768844cde
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
@@ -0,0 +1,233 @@
+/*
+ * 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.TowerOfInsolence;
+
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.model.ChanceLocation;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
+import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class EnergyOfInsolence extends AbstractNpcAI
+{
+ private static final int LEVEL_MAX_DIFF = 9;
+ private static final int TIME_UNTIL_MOVE = 1800000;
+ private static final int ELMOREDEN_LADY = 20977;
+ private static final int POWER_ANGEL_AMON = 21081;
+ private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
+ private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
+ private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
+ private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
+ private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
+ private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
+ {
+ ELMOREDEN_LADY,
+ POWER_ANGEL_AMON
+ };
+ private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
+ {
+ 20978,
+ 20979,
+ 21073,
+ 21082,
+ 21083
+ };
+ private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
+ {
+ 20980,
+ 20981,
+ 20982,
+ 20983,
+ 20984,
+ 20985,
+ 21074,
+ 21075,
+ 21076,
+ 21077,
+ 21080
+ };
+ private static ScheduledFuture> _scheduleTaskElmoreden;
+ private static ScheduledFuture> _scheduleTaskAmon;
+
+ private EnergyOfInsolence()
+ {
+ addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(UNIDENTIFIED_STONE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_MINIONS);
+ }
+
+ private void makeInvul(Npc npc)
+ {
+ npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(true);
+ }
+
+ private void makeMortal(Npc npc)
+ {
+ npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(false);
+ }
+
+ private void makeTalk(Npc npc, boolean spawning)
+ {
+ NpcStringId npcStringId = null;
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
+ }
+ }
+ npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, true);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ makeInvul(npc);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ }
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
+ {
+ npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, false);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ _scheduleTaskElmoreden.cancel(true);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon.cancel(true);
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
+ {
+ npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
+ {
+ final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
+ if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
+ {
+ makeMortal(leader);
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static AbstractNpcAI provider()
+ {
+ return new EnergyOfInsolence();
+ }
+
+ public class ScheduleAITask implements Runnable
+ {
+ private final Npc _npc;
+ private final int _npcId;
+
+ public ScheduleAITask(Npc npc, int npcId)
+ {
+ _npc = npc;
+ _npcId = npcId;
+ }
+
+ @Override
+ public void run()
+ {
+ if (_npc != null)
+ {
+ _npc.deleteMe();
+ }
+
+ try
+ {
+ final Spawn spawn = new Spawn(_npcId);
+ final List spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
+ final List locations = spawns.get(0).getLocation();
+ final Location location = locations.get(Rnd.get(locations.size()));
+ spawn.setLocation(location);
+ spawn.doSpawn();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new EnergyOfInsolence();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
new file mode 100644
index 0000000000..758820626f
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
@@ -0,0 +1,106 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.Playable;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.events.AbstractScript;
+import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Bomb extends AbstractNpcAI
+{
+ // NPCs
+ private static final int BOMB = 18003;
+ private static final int DIVINE_ANGEL = 20139;
+ // Items
+ private static final int[] ITEM_DROP_1 = new int[]
+ {
+ 49756,
+ 49762,
+ 49763
+ };
+ private static final int[] ITEM_DROP_2 = new int[]
+ {
+ 49760,
+ 49761
+ };
+
+ public Bomb()
+ {
+ addKillId(BOMB);
+ addSpawnId(BOMB);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (Rnd.get(100) < 33)
+ {
+ AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
+ }
+ else
+ {
+ World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
+ {
+ if ((creature != null) && !creature.isDead())
+ {
+ creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
+ }
+ });
+ if (Rnd.get(100) < 50)
+ {
+ if (Rnd.get(100) < 90)
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
+ }
+ else
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
+ }
+ }
+ }
+ if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Bomb();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
new file mode 100644
index 0000000000..5635daa582
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
@@ -0,0 +1,79 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.ai.AttackableAI;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DivineAngel extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public DivineAngel()
+ {
+ addSpawnId(DIVINE_ANGEL);
+ addKillId(DIVINE_ANGEL);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
+
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
+ {
+ ((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
+ }
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
+ {
+ ((AttackableAI) npc.getAI()).setGlobalAggro(0);
+ }
+ return super.onSpawn(npc);
+ }
+
+ public static void main(String[] args)
+ {
+ new DivineAngel();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
new file mode 100644
index 0000000000..667f598286
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
@@ -0,0 +1,64 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Tower extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public Tower()
+ {
+ addKillId(TOWER);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
+ {
+ creature.decayMe();
+ }
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Tower();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/spawns/Aden/Aden.xml b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/spawns/Aden/Aden.xml
index 31d58570e1..13442fff0a 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/spawns/Aden/Aden.xml
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/spawns/Aden/Aden.xml
@@ -3,8 +3,6 @@
-
-
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/spawns/Aden/TowerOfInsolence.xml b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/spawns/Aden/TowerOfInsolence.xml
index ab5c823f8c..a4a4d20a99 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/spawns/Aden/TowerOfInsolence.xml
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/spawns/Aden/TowerOfInsolence.xml
@@ -1638,6 +1638,7 @@
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/npcs/18000-18099.xml b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/npcs/18000-18099.xml
index 7b286a2037..f0a13de6b5 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/npcs/18000-18099.xml
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/npcs/18000-18099.xml
@@ -141,12 +141,12 @@
MALE
-
+
-
-
+
+ 370
@@ -175,7 +175,7 @@
MALE
-
+
@@ -185,7 +185,7 @@
520
-
+
@@ -305,6 +305,7 @@
DEMONICFEMALE
+
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/npcs/20100-20199.xml b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/npcs/20100-20199.xml
index 39fe355a4c..04c4a7adab 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/npcs/20100-20199.xml
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/npcs/20100-20199.xml
@@ -1718,6 +1718,7 @@
DIVINEMALE
+
@@ -1743,7 +1744,11 @@
false
-
+
+
+ ALL
+
+
diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/zones/no_restart.xml b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/zones/no_restart.xml
index 5efbfe3bd9..9049d695d1 100644
--- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/zones/no_restart.xml
+++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/zones/no_restart.xml
@@ -322,6 +322,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
new file mode 100644
index 0000000000..29800c3dd8
--- /dev/null
+++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
@@ -0,0 +1,142 @@
+/*
+ * 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 org.l2jmobius.gameserver.instancemanager;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.zone.ZoneType;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+/**
+ * @author Brutallis
+ */
+public class HeavenlyRiftManager
+{
+ private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
+
+ public static ZoneType getZone()
+ {
+ return ZONE;
+ }
+
+ public static int getAliveNpcCount(int npcId)
+ {
+ int result = 0;
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
+ {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ public static void startEvent20Bomb(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
+ spawnMonster(18003, 113352, 12936, 10976, 1800000);
+ spawnMonster(18003, 113592, 13272, 10976, 1800000);
+ spawnMonster(18003, 113816, 13592, 10976, 1800000);
+ spawnMonster(18003, 113080, 13192, 10976, 1800000);
+ spawnMonster(18003, 113336, 13528, 10976, 1800000);
+ spawnMonster(18003, 113560, 13832, 10976, 1800000);
+ spawnMonster(18003, 112776, 13512, 10976, 1800000);
+ spawnMonster(18003, 113064, 13784, 10976, 1800000);
+ spawnMonster(18003, 112440, 13848, 10976, 1800000);
+ spawnMonster(18003, 112728, 14104, 10976, 1800000);
+ spawnMonster(18003, 112760, 14600, 10976, 1800000);
+ spawnMonster(18003, 112392, 14456, 10976, 1800000);
+ spawnMonster(18003, 112104, 14184, 10976, 1800000);
+ spawnMonster(18003, 111816, 14488, 10976, 1800000);
+ spawnMonster(18003, 112104, 14760, 10976, 1800000);
+ spawnMonster(18003, 112392, 15032, 10976, 1800000);
+ spawnMonster(18003, 112120, 15288, 10976, 1800000);
+ spawnMonster(18003, 111784, 15064, 10976, 1800000);
+ spawnMonster(18003, 111480, 14824, 10976, 1800000);
+ spawnMonster(18003, 113144, 14216, 10976, 1800000);
+ }
+
+ public static void startEventTower(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
+ spawnMonster(18004, 112648, 14072, 10976, 1800000);
+ ThreadPool.schedule(() ->
+ {
+ for (int i = 0; i < 20; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }, 10000);
+ }
+
+ public static void startEvent40Angels(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
+ for (int i = 0; i < 40; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }
+
+ private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
+ {
+ try
+ {
+ Spawn spawn = new Spawn(npcId);
+ Location location = new Location(x, y, z);
+ spawn.setLocation(location);
+ Npc npc = spawn.doSpawn();
+ npc.scheduleDespawn(despawnTime);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ public static class ClearZoneTask implements Runnable
+ {
+ private final Npc _npc;
+
+ public ClearZoneTask(Npc npc)
+ {
+ _npc = npc;
+ }
+
+ @Override
+ public void run()
+ {
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isPlayer())
+ {
+ creature.teleToLocation(114264, 13352, -5104);
+ }
+ else if (creature.isNpc() && (creature.getId() != 30401))
+ {
+ creature.decayMe();
+ }
+ }
+ _npc.setBusy(false);
+ }
+ }
+}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/multisell/30952.xml b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/multisell/30952.xml
new file mode 100644
index 0000000000..6eb9971522
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/multisell/30952.xml
@@ -0,0 +1,12 @@
+
+
+
+ 30952
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
new file mode 100644
index 0000000000..e3f0d71258
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
@@ -0,0 +1,12 @@
+Arushinai:
+Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
+Baium's anger was so great that the Heavenly Rift itself began yo change under his influence.
+I'll give you a little clue... So that you can imagine what can happen in the fault.
+Or you will be attacked by 40 Divine Angels (kill them as soon as you notice),
+or the will be 20 Bombs (their explosions will summon the Divine Angels, who will also have to be killed).
+And be careful: from an exploding bomb can drop anything valuable! Either you need to protect the Tower from 20 Divine Angels who will try to destroy it.
+If you do this, you will receive a reward. Be extremely attentive!
+Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
+Gather with strength - and go!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
new file mode 100644
index 0000000000..5d50e993eb
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
@@ -0,0 +1,4 @@
+Arushinai:
+It's not easy to get into the Heavenly Rift. When are you ready, I will send you back to Dimensional Vortex.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
new file mode 100644
index 0000000000..98be98fc90
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
@@ -0,0 +1,6 @@
+Arushinai:
+Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
+Inside the fault, you can stay not longer than 30 minutes. In such a dangerous place, mutual assistance and teamwork are especially important.
+And remember: if you leave the rift prematurely, you will not be able to return here!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
new file mode 100644
index 0000000000..c6db1d0803
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
@@ -0,0 +1,155 @@
+/*
+ * 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.TowerOfInsolence.Arushinai;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Arushinai extends AbstractNpcAI
+{
+ // NPC
+ private static final int ARUSHINAI = 30401;
+
+ private Arushinai()
+ {
+ addStartNpc(ARUSHINAI);
+ addTalkId(ARUSHINAI);
+ addFirstTalkId(ARUSHINAI);
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("proceed"))
+ {
+ if (!player.isGM())
+ {
+ Party party = player.getParty();
+ if (party == null)
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ }
+
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
+ {
+ return null; // TODO: Find html?
+ }
+
+ final int riftLevel = Rnd.get(1, 3);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
+ switch (riftLevel)
+ {
+ case 1:
+ {
+ HeavenlyRiftManager.startEvent20Bomb(player);
+ return null;
+ }
+ case 2:
+ {
+ HeavenlyRiftManager.startEventTower(player);
+ return null;
+ }
+ case 3:
+ {
+ HeavenlyRiftManager.startEvent40Angels(player);
+ break;
+ }
+ }
+ return null;
+ }
+
+ if (!event.equals("finish"))
+ {
+ return null;
+ }
+
+ if (player.isInParty())
+ {
+ Party party = player.getParty();
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(114264, 13352, -5104);
+ }
+ return null;
+ }
+
+ if (player.isGM())
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
+ return null;
+ }
+
+ public static void main(String[] args)
+ {
+ new Arushinai();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
new file mode 100644
index 0000000000..ec1f8a6799
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
@@ -0,0 +1,6 @@
+
+Dimensional Vortex:
+The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a Celestial Shard. You can extract it from the Unidentified Stone after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
new file mode 100644
index 0000000000..be5290b1f5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
@@ -0,0 +1,5 @@
+Dimensional Vortex:
+Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the Unidentified Stone to extract Broken Celestial Shards from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
new file mode 100644
index 0000000000..ddba0bd4f0
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
@@ -0,0 +1,4 @@
+Dimensional Vortex:
+You need an Airborne Fragment from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
new file mode 100644
index 0000000000..7b63cb1b68
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
@@ -0,0 +1,6 @@
+Dimensional Vortex:
+Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
new file mode 100644
index 0000000000..e676849ad1
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
@@ -0,0 +1,135 @@
+/*
+ * 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.TowerOfInsolence.DimensionalVortex;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DimensionalVortex extends AbstractNpcAI
+{
+ // NPC
+ private static final int DIMENTIONAL_VORTEX = 30952;
+ // Items
+ private static final int CELESTIAL_SHARD = 49759;
+ private static final int BROKEN_CELESTIAL_SHARD = 49767;
+
+ private DimensionalVortex()
+ {
+ addStartNpc(DIMENTIONAL_VORTEX);
+ addTalkId(DIMENTIONAL_VORTEX);
+ addFirstTalkId(DIMENTIONAL_VORTEX);
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("tryenter"))
+ {
+ if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
+ {
+ if (player.isGM())
+ {
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ player.teleToLocation(112685, 13362, 10966);
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
+ return null;
+ }
+ if (!player.isInParty())
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ return null;
+ }
+ final Party party = player.getParty();
+ if ((party == null) || !party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(112685, 13362, 10966);
+ }
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
+ }
+ else
+ {
+ return "30952-3.htm";
+ }
+ }
+ else if (event.equals("exchange"))
+ {
+ long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
+ if (count < 10)
+ {
+ return "30952-2.htm";
+ }
+ if ((count % 10) != 0)
+ {
+ count -= count % 10;
+ }
+ final long reward = count / 10;
+ player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
+ player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
+ }
+ return null;
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ public static void main(String[] args)
+ {
+ new DimensionalVortex();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
new file mode 100644
index 0000000000..1768844cde
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
@@ -0,0 +1,233 @@
+/*
+ * 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.TowerOfInsolence;
+
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.model.ChanceLocation;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
+import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class EnergyOfInsolence extends AbstractNpcAI
+{
+ private static final int LEVEL_MAX_DIFF = 9;
+ private static final int TIME_UNTIL_MOVE = 1800000;
+ private static final int ELMOREDEN_LADY = 20977;
+ private static final int POWER_ANGEL_AMON = 21081;
+ private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
+ private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
+ private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
+ private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
+ private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
+ private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
+ {
+ ELMOREDEN_LADY,
+ POWER_ANGEL_AMON
+ };
+ private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
+ {
+ 20978,
+ 20979,
+ 21073,
+ 21082,
+ 21083
+ };
+ private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
+ {
+ 20980,
+ 20981,
+ 20982,
+ 20983,
+ 20984,
+ 20985,
+ 21074,
+ 21075,
+ 21076,
+ 21077,
+ 21080
+ };
+ private static ScheduledFuture> _scheduleTaskElmoreden;
+ private static ScheduledFuture> _scheduleTaskAmon;
+
+ private EnergyOfInsolence()
+ {
+ addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(UNIDENTIFIED_STONE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_MINIONS);
+ }
+
+ private void makeInvul(Npc npc)
+ {
+ npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(true);
+ }
+
+ private void makeMortal(Npc npc)
+ {
+ npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(false);
+ }
+
+ private void makeTalk(Npc npc, boolean spawning)
+ {
+ NpcStringId npcStringId = null;
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
+ }
+ }
+ npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, true);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ makeInvul(npc);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ }
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
+ {
+ npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, false);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ _scheduleTaskElmoreden.cancel(true);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon.cancel(true);
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
+ {
+ npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
+ {
+ final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
+ if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
+ {
+ makeMortal(leader);
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static AbstractNpcAI provider()
+ {
+ return new EnergyOfInsolence();
+ }
+
+ public class ScheduleAITask implements Runnable
+ {
+ private final Npc _npc;
+ private final int _npcId;
+
+ public ScheduleAITask(Npc npc, int npcId)
+ {
+ _npc = npc;
+ _npcId = npcId;
+ }
+
+ @Override
+ public void run()
+ {
+ if (_npc != null)
+ {
+ _npc.deleteMe();
+ }
+
+ try
+ {
+ final Spawn spawn = new Spawn(_npcId);
+ final List spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
+ final List locations = spawns.get(0).getLocation();
+ final Location location = locations.get(Rnd.get(locations.size()));
+ spawn.setLocation(location);
+ spawn.doSpawn();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new EnergyOfInsolence();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
new file mode 100644
index 0000000000..758820626f
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
@@ -0,0 +1,106 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.Playable;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.events.AbstractScript;
+import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Bomb extends AbstractNpcAI
+{
+ // NPCs
+ private static final int BOMB = 18003;
+ private static final int DIVINE_ANGEL = 20139;
+ // Items
+ private static final int[] ITEM_DROP_1 = new int[]
+ {
+ 49756,
+ 49762,
+ 49763
+ };
+ private static final int[] ITEM_DROP_2 = new int[]
+ {
+ 49760,
+ 49761
+ };
+
+ public Bomb()
+ {
+ addKillId(BOMB);
+ addSpawnId(BOMB);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (Rnd.get(100) < 33)
+ {
+ AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
+ }
+ else
+ {
+ World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
+ {
+ if ((creature != null) && !creature.isDead())
+ {
+ creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
+ }
+ });
+ if (Rnd.get(100) < 50)
+ {
+ if (Rnd.get(100) < 90)
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
+ }
+ else
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
+ }
+ }
+ }
+ if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Bomb();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
new file mode 100644
index 0000000000..5635daa582
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
@@ -0,0 +1,79 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.ai.AttackableAI;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DivineAngel extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public DivineAngel()
+ {
+ addSpawnId(DIVINE_ANGEL);
+ addKillId(DIVINE_ANGEL);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
+
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
+ {
+ ((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
+ }
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
+ {
+ ((AttackableAI) npc.getAI()).setGlobalAggro(0);
+ }
+ return super.onSpawn(npc);
+ }
+
+ public static void main(String[] args)
+ {
+ new DivineAngel();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
new file mode 100644
index 0000000000..667f598286
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
@@ -0,0 +1,64 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Tower extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public Tower()
+ {
+ addKillId(TOWER);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
+ {
+ creature.decayMe();
+ }
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Tower();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/spawns/Aden/Aden.xml b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/spawns/Aden/Aden.xml
index 929fa7b588..62adc335ba 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/spawns/Aden/Aden.xml
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/spawns/Aden/Aden.xml
@@ -3,8 +3,6 @@
-
-
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/spawns/Aden/TowerOfInsolence.xml b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/spawns/Aden/TowerOfInsolence.xml
index ab5c823f8c..a4a4d20a99 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/spawns/Aden/TowerOfInsolence.xml
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/spawns/Aden/TowerOfInsolence.xml
@@ -1638,6 +1638,7 @@
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/npcs/18000-18099.xml b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/npcs/18000-18099.xml
index ad25915a56..81d0a24a30 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/npcs/18000-18099.xml
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/npcs/18000-18099.xml
@@ -185,7 +185,7 @@
520
-
+
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/npcs/20100-20199.xml b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/npcs/20100-20199.xml
index 4ee4cd69de..0dafd561fe 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/npcs/20100-20199.xml
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/npcs/20100-20199.xml
@@ -1745,7 +1745,11 @@
false
-
+
+
+ ALL
+
+
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/zones/no_restart.xml b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/zones/no_restart.xml
index a7be76e3c1..7516849450 100644
--- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/zones/no_restart.xml
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/zones/no_restart.xml
@@ -322,6 +322,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
new file mode 100644
index 0000000000..29800c3dd8
--- /dev/null
+++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
@@ -0,0 +1,142 @@
+/*
+ * 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 org.l2jmobius.gameserver.instancemanager;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.zone.ZoneType;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+/**
+ * @author Brutallis
+ */
+public class HeavenlyRiftManager
+{
+ private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
+
+ public static ZoneType getZone()
+ {
+ return ZONE;
+ }
+
+ public static int getAliveNpcCount(int npcId)
+ {
+ int result = 0;
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
+ {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ public static void startEvent20Bomb(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
+ spawnMonster(18003, 113352, 12936, 10976, 1800000);
+ spawnMonster(18003, 113592, 13272, 10976, 1800000);
+ spawnMonster(18003, 113816, 13592, 10976, 1800000);
+ spawnMonster(18003, 113080, 13192, 10976, 1800000);
+ spawnMonster(18003, 113336, 13528, 10976, 1800000);
+ spawnMonster(18003, 113560, 13832, 10976, 1800000);
+ spawnMonster(18003, 112776, 13512, 10976, 1800000);
+ spawnMonster(18003, 113064, 13784, 10976, 1800000);
+ spawnMonster(18003, 112440, 13848, 10976, 1800000);
+ spawnMonster(18003, 112728, 14104, 10976, 1800000);
+ spawnMonster(18003, 112760, 14600, 10976, 1800000);
+ spawnMonster(18003, 112392, 14456, 10976, 1800000);
+ spawnMonster(18003, 112104, 14184, 10976, 1800000);
+ spawnMonster(18003, 111816, 14488, 10976, 1800000);
+ spawnMonster(18003, 112104, 14760, 10976, 1800000);
+ spawnMonster(18003, 112392, 15032, 10976, 1800000);
+ spawnMonster(18003, 112120, 15288, 10976, 1800000);
+ spawnMonster(18003, 111784, 15064, 10976, 1800000);
+ spawnMonster(18003, 111480, 14824, 10976, 1800000);
+ spawnMonster(18003, 113144, 14216, 10976, 1800000);
+ }
+
+ public static void startEventTower(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
+ spawnMonster(18004, 112648, 14072, 10976, 1800000);
+ ThreadPool.schedule(() ->
+ {
+ for (int i = 0; i < 20; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }, 10000);
+ }
+
+ public static void startEvent40Angels(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
+ for (int i = 0; i < 40; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }
+
+ private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
+ {
+ try
+ {
+ Spawn spawn = new Spawn(npcId);
+ Location location = new Location(x, y, z);
+ spawn.setLocation(location);
+ Npc npc = spawn.doSpawn();
+ npc.scheduleDespawn(despawnTime);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ public static class ClearZoneTask implements Runnable
+ {
+ private final Npc _npc;
+
+ public ClearZoneTask(Npc npc)
+ {
+ _npc = npc;
+ }
+
+ @Override
+ public void run()
+ {
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isPlayer())
+ {
+ creature.teleToLocation(114264, 13352, -5104);
+ }
+ else if (creature.isNpc() && (creature.getId() != 30401))
+ {
+ creature.decayMe();
+ }
+ }
+ _npc.setBusy(false);
+ }
+ }
+}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/multisell/30952.xml b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/multisell/30952.xml
new file mode 100644
index 0000000000..6eb9971522
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/multisell/30952.xml
@@ -0,0 +1,12 @@
+
+
+
+ 30952
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
new file mode 100644
index 0000000000..e3f0d71258
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
@@ -0,0 +1,12 @@
+Arushinai:
+Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
+Baium's anger was so great that the Heavenly Rift itself began yo change under his influence.
+I'll give you a little clue... So that you can imagine what can happen in the fault.
+Or you will be attacked by 40 Divine Angels (kill them as soon as you notice),
+or the will be 20 Bombs (their explosions will summon the Divine Angels, who will also have to be killed).
+And be careful: from an exploding bomb can drop anything valuable! Either you need to protect the Tower from 20 Divine Angels who will try to destroy it.
+If you do this, you will receive a reward. Be extremely attentive!
+Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
+Gather with strength - and go!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
new file mode 100644
index 0000000000..5d50e993eb
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
@@ -0,0 +1,4 @@
+Arushinai:
+It's not easy to get into the Heavenly Rift. When are you ready, I will send you back to Dimensional Vortex.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
new file mode 100644
index 0000000000..98be98fc90
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
@@ -0,0 +1,6 @@
+Arushinai:
+Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
+Inside the fault, you can stay not longer than 30 minutes. In such a dangerous place, mutual assistance and teamwork are especially important.
+And remember: if you leave the rift prematurely, you will not be able to return here!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
new file mode 100644
index 0000000000..c6db1d0803
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
@@ -0,0 +1,155 @@
+/*
+ * 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.TowerOfInsolence.Arushinai;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Arushinai extends AbstractNpcAI
+{
+ // NPC
+ private static final int ARUSHINAI = 30401;
+
+ private Arushinai()
+ {
+ addStartNpc(ARUSHINAI);
+ addTalkId(ARUSHINAI);
+ addFirstTalkId(ARUSHINAI);
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("proceed"))
+ {
+ if (!player.isGM())
+ {
+ Party party = player.getParty();
+ if (party == null)
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ }
+
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
+ {
+ return null; // TODO: Find html?
+ }
+
+ final int riftLevel = Rnd.get(1, 3);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
+ switch (riftLevel)
+ {
+ case 1:
+ {
+ HeavenlyRiftManager.startEvent20Bomb(player);
+ return null;
+ }
+ case 2:
+ {
+ HeavenlyRiftManager.startEventTower(player);
+ return null;
+ }
+ case 3:
+ {
+ HeavenlyRiftManager.startEvent40Angels(player);
+ break;
+ }
+ }
+ return null;
+ }
+
+ if (!event.equals("finish"))
+ {
+ return null;
+ }
+
+ if (player.isInParty())
+ {
+ Party party = player.getParty();
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(114264, 13352, -5104);
+ }
+ return null;
+ }
+
+ if (player.isGM())
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
+ return null;
+ }
+
+ public static void main(String[] args)
+ {
+ new Arushinai();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
new file mode 100644
index 0000000000..ec1f8a6799
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
@@ -0,0 +1,6 @@
+
+Dimensional Vortex:
+The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a Celestial Shard. You can extract it from the Unidentified Stone after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
new file mode 100644
index 0000000000..be5290b1f5
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
@@ -0,0 +1,5 @@
+Dimensional Vortex:
+Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the Unidentified Stone to extract Broken Celestial Shards from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
new file mode 100644
index 0000000000..ddba0bd4f0
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
@@ -0,0 +1,4 @@
+Dimensional Vortex:
+You need an Airborne Fragment from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
new file mode 100644
index 0000000000..7b63cb1b68
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
@@ -0,0 +1,6 @@
+Dimensional Vortex:
+Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
new file mode 100644
index 0000000000..e676849ad1
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
@@ -0,0 +1,135 @@
+/*
+ * 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.TowerOfInsolence.DimensionalVortex;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DimensionalVortex extends AbstractNpcAI
+{
+ // NPC
+ private static final int DIMENTIONAL_VORTEX = 30952;
+ // Items
+ private static final int CELESTIAL_SHARD = 49759;
+ private static final int BROKEN_CELESTIAL_SHARD = 49767;
+
+ private DimensionalVortex()
+ {
+ addStartNpc(DIMENTIONAL_VORTEX);
+ addTalkId(DIMENTIONAL_VORTEX);
+ addFirstTalkId(DIMENTIONAL_VORTEX);
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("tryenter"))
+ {
+ if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
+ {
+ if (player.isGM())
+ {
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ player.teleToLocation(112685, 13362, 10966);
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
+ return null;
+ }
+ if (!player.isInParty())
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ return null;
+ }
+ final Party party = player.getParty();
+ if ((party == null) || !party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(112685, 13362, 10966);
+ }
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
+ }
+ else
+ {
+ return "30952-3.htm";
+ }
+ }
+ else if (event.equals("exchange"))
+ {
+ long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
+ if (count < 10)
+ {
+ return "30952-2.htm";
+ }
+ if ((count % 10) != 0)
+ {
+ count -= count % 10;
+ }
+ final long reward = count / 10;
+ player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
+ player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
+ }
+ return null;
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ public static void main(String[] args)
+ {
+ new DimensionalVortex();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
new file mode 100644
index 0000000000..1768844cde
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
@@ -0,0 +1,233 @@
+/*
+ * 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.TowerOfInsolence;
+
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.model.ChanceLocation;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
+import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class EnergyOfInsolence extends AbstractNpcAI
+{
+ private static final int LEVEL_MAX_DIFF = 9;
+ private static final int TIME_UNTIL_MOVE = 1800000;
+ private static final int ELMOREDEN_LADY = 20977;
+ private static final int POWER_ANGEL_AMON = 21081;
+ private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
+ private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
+ private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
+ private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
+ private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
+ private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
+ {
+ ELMOREDEN_LADY,
+ POWER_ANGEL_AMON
+ };
+ private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
+ {
+ 20978,
+ 20979,
+ 21073,
+ 21082,
+ 21083
+ };
+ private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
+ {
+ 20980,
+ 20981,
+ 20982,
+ 20983,
+ 20984,
+ 20985,
+ 21074,
+ 21075,
+ 21076,
+ 21077,
+ 21080
+ };
+ private static ScheduledFuture> _scheduleTaskElmoreden;
+ private static ScheduledFuture> _scheduleTaskAmon;
+
+ private EnergyOfInsolence()
+ {
+ addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(UNIDENTIFIED_STONE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_MINIONS);
+ }
+
+ private void makeInvul(Npc npc)
+ {
+ npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(true);
+ }
+
+ private void makeMortal(Npc npc)
+ {
+ npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(false);
+ }
+
+ private void makeTalk(Npc npc, boolean spawning)
+ {
+ NpcStringId npcStringId = null;
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
+ }
+ }
+ npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, true);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ makeInvul(npc);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ }
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
+ {
+ npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, false);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ _scheduleTaskElmoreden.cancel(true);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon.cancel(true);
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
+ {
+ npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
+ {
+ final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
+ if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
+ {
+ makeMortal(leader);
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static AbstractNpcAI provider()
+ {
+ return new EnergyOfInsolence();
+ }
+
+ public class ScheduleAITask implements Runnable
+ {
+ private final Npc _npc;
+ private final int _npcId;
+
+ public ScheduleAITask(Npc npc, int npcId)
+ {
+ _npc = npc;
+ _npcId = npcId;
+ }
+
+ @Override
+ public void run()
+ {
+ if (_npc != null)
+ {
+ _npc.deleteMe();
+ }
+
+ try
+ {
+ final Spawn spawn = new Spawn(_npcId);
+ final List spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
+ final List locations = spawns.get(0).getLocation();
+ final Location location = locations.get(Rnd.get(locations.size()));
+ spawn.setLocation(location);
+ spawn.doSpawn();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new EnergyOfInsolence();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
new file mode 100644
index 0000000000..758820626f
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
@@ -0,0 +1,106 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.Playable;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.events.AbstractScript;
+import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Bomb extends AbstractNpcAI
+{
+ // NPCs
+ private static final int BOMB = 18003;
+ private static final int DIVINE_ANGEL = 20139;
+ // Items
+ private static final int[] ITEM_DROP_1 = new int[]
+ {
+ 49756,
+ 49762,
+ 49763
+ };
+ private static final int[] ITEM_DROP_2 = new int[]
+ {
+ 49760,
+ 49761
+ };
+
+ public Bomb()
+ {
+ addKillId(BOMB);
+ addSpawnId(BOMB);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (Rnd.get(100) < 33)
+ {
+ AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
+ }
+ else
+ {
+ World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
+ {
+ if ((creature != null) && !creature.isDead())
+ {
+ creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
+ }
+ });
+ if (Rnd.get(100) < 50)
+ {
+ if (Rnd.get(100) < 90)
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
+ }
+ else
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
+ }
+ }
+ }
+ if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Bomb();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
new file mode 100644
index 0000000000..5635daa582
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
@@ -0,0 +1,79 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.ai.AttackableAI;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DivineAngel extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public DivineAngel()
+ {
+ addSpawnId(DIVINE_ANGEL);
+ addKillId(DIVINE_ANGEL);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
+
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
+ {
+ ((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
+ }
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
+ {
+ ((AttackableAI) npc.getAI()).setGlobalAggro(0);
+ }
+ return super.onSpawn(npc);
+ }
+
+ public static void main(String[] args)
+ {
+ new DivineAngel();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
new file mode 100644
index 0000000000..667f598286
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
@@ -0,0 +1,64 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Tower extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public Tower()
+ {
+ addKillId(TOWER);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
+ {
+ creature.decayMe();
+ }
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Tower();
+ }
+}
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/spawns/Aden/Aden.xml b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/spawns/Aden/Aden.xml
index 929fa7b588..62adc335ba 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/spawns/Aden/Aden.xml
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/spawns/Aden/Aden.xml
@@ -3,8 +3,6 @@
-
-
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/spawns/Aden/TowerOfInsolence.xml b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/spawns/Aden/TowerOfInsolence.xml
index ab5c823f8c..a4a4d20a99 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/spawns/Aden/TowerOfInsolence.xml
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/spawns/Aden/TowerOfInsolence.xml
@@ -1638,6 +1638,7 @@
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/stats/npcs/18000-18099.xml b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/stats/npcs/18000-18099.xml
index ad25915a56..81d0a24a30 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/stats/npcs/18000-18099.xml
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/stats/npcs/18000-18099.xml
@@ -185,7 +185,7 @@
520
-
+
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/stats/npcs/20100-20199.xml b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/stats/npcs/20100-20199.xml
index 4ee4cd69de..0dafd561fe 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/stats/npcs/20100-20199.xml
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/stats/npcs/20100-20199.xml
@@ -1745,7 +1745,11 @@
false
-
+
+
+ ALL
+
+
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/zones/no_restart.xml b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/zones/no_restart.xml
index a7be76e3c1..7516849450 100644
--- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/zones/no_restart.xml
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/game/data/zones/no_restart.xml
@@ -322,6 +322,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
new file mode 100644
index 0000000000..29800c3dd8
--- /dev/null
+++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
@@ -0,0 +1,142 @@
+/*
+ * 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 org.l2jmobius.gameserver.instancemanager;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.zone.ZoneType;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+/**
+ * @author Brutallis
+ */
+public class HeavenlyRiftManager
+{
+ private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
+
+ public static ZoneType getZone()
+ {
+ return ZONE;
+ }
+
+ public static int getAliveNpcCount(int npcId)
+ {
+ int result = 0;
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
+ {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ public static void startEvent20Bomb(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
+ spawnMonster(18003, 113352, 12936, 10976, 1800000);
+ spawnMonster(18003, 113592, 13272, 10976, 1800000);
+ spawnMonster(18003, 113816, 13592, 10976, 1800000);
+ spawnMonster(18003, 113080, 13192, 10976, 1800000);
+ spawnMonster(18003, 113336, 13528, 10976, 1800000);
+ spawnMonster(18003, 113560, 13832, 10976, 1800000);
+ spawnMonster(18003, 112776, 13512, 10976, 1800000);
+ spawnMonster(18003, 113064, 13784, 10976, 1800000);
+ spawnMonster(18003, 112440, 13848, 10976, 1800000);
+ spawnMonster(18003, 112728, 14104, 10976, 1800000);
+ spawnMonster(18003, 112760, 14600, 10976, 1800000);
+ spawnMonster(18003, 112392, 14456, 10976, 1800000);
+ spawnMonster(18003, 112104, 14184, 10976, 1800000);
+ spawnMonster(18003, 111816, 14488, 10976, 1800000);
+ spawnMonster(18003, 112104, 14760, 10976, 1800000);
+ spawnMonster(18003, 112392, 15032, 10976, 1800000);
+ spawnMonster(18003, 112120, 15288, 10976, 1800000);
+ spawnMonster(18003, 111784, 15064, 10976, 1800000);
+ spawnMonster(18003, 111480, 14824, 10976, 1800000);
+ spawnMonster(18003, 113144, 14216, 10976, 1800000);
+ }
+
+ public static void startEventTower(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
+ spawnMonster(18004, 112648, 14072, 10976, 1800000);
+ ThreadPool.schedule(() ->
+ {
+ for (int i = 0; i < 20; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }, 10000);
+ }
+
+ public static void startEvent40Angels(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
+ for (int i = 0; i < 40; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }
+
+ private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
+ {
+ try
+ {
+ Spawn spawn = new Spawn(npcId);
+ Location location = new Location(x, y, z);
+ spawn.setLocation(location);
+ Npc npc = spawn.doSpawn();
+ npc.scheduleDespawn(despawnTime);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ public static class ClearZoneTask implements Runnable
+ {
+ private final Npc _npc;
+
+ public ClearZoneTask(Npc npc)
+ {
+ _npc = npc;
+ }
+
+ @Override
+ public void run()
+ {
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isPlayer())
+ {
+ creature.teleToLocation(114264, 13352, -5104);
+ }
+ else if (creature.isNpc() && (creature.getId() != 30401))
+ {
+ creature.decayMe();
+ }
+ }
+ _npc.setBusy(false);
+ }
+ }
+}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/multisell/30952.xml b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/multisell/30952.xml
new file mode 100644
index 0000000000..6eb9971522
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/multisell/30952.xml
@@ -0,0 +1,12 @@
+
+
+
+ 30952
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
new file mode 100644
index 0000000000..e3f0d71258
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-1.htm
@@ -0,0 +1,12 @@
+Arushinai:
+Baium spent hundreds of years imprisoned. He was forced to watch how slowly his empire died...
+Baium's anger was so great that the Heavenly Rift itself began yo change under his influence.
+I'll give you a little clue... So that you can imagine what can happen in the fault.
+Or you will be attacked by 40 Divine Angels (kill them as soon as you notice),
+or the will be 20 Bombs (their explosions will summon the Divine Angels, who will also have to be killed).
+And be careful: from an exploding bomb can drop anything valuable! Either you need to protect the Tower from 20 Divine Angels who will try to destroy it.
+If you do this, you will receive a reward. Be extremely attentive!
+Fight shoulder to shoulder with you members. And remember: if you leave the Heavenly Rift before the due time, you can not return here.
+Gather with strength - and go!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
new file mode 100644
index 0000000000..5d50e993eb
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401-2.htm
@@ -0,0 +1,4 @@
+Arushinai:
+It's not easy to get into the Heavenly Rift. When are you ready, I will send you back to Dimensional Vortex.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
new file mode 100644
index 0000000000..98be98fc90
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/30401.htm
@@ -0,0 +1,6 @@
+Arushinai:
+Do you know how the Heavenly Rift came about? The ego of the emperor Baium split the heaven.
+Inside the fault, you can stay not longer than 30 minutes. In such a dangerous place, mutual assistance and teamwork are especially important.
+And remember: if you leave the rift prematurely, you will not be able to return here!
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
new file mode 100644
index 0000000000..c6db1d0803
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/Arushinai/Arushinai.java
@@ -0,0 +1,155 @@
+/*
+ * 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.TowerOfInsolence.Arushinai;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Arushinai extends AbstractNpcAI
+{
+ // NPC
+ private static final int ARUSHINAI = 30401;
+
+ private Arushinai()
+ {
+ addStartNpc(ARUSHINAI);
+ addTalkId(ARUSHINAI);
+ addFirstTalkId(ARUSHINAI);
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30401-1.htm") || event.equals("30401-2.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("proceed"))
+ {
+ if (!player.isGM())
+ {
+ Party party = player.getParty();
+ if (party == null)
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ }
+
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_complete", 0) != 0)
+ {
+ return null; // TODO: Find html?
+ }
+
+ final int riftLevel = Rnd.get(1, 3);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", riftLevel);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 4);
+ switch (riftLevel)
+ {
+ case 1:
+ {
+ HeavenlyRiftManager.startEvent20Bomb(player);
+ return null;
+ }
+ case 2:
+ {
+ HeavenlyRiftManager.startEventTower(player);
+ return null;
+ }
+ case 3:
+ {
+ HeavenlyRiftManager.startEvent40Angels(player);
+ break;
+ }
+ }
+ return null;
+ }
+
+ if (!event.equals("finish"))
+ {
+ return null;
+ }
+
+ if (player.isInParty())
+ {
+ Party party = player.getParty();
+ if (!party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.YOU_CANNOT_PROCEED_AS_YOU_ARE_NOT_A_PARTY_LEADER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(114264, 13352, -5104);
+ }
+ return null;
+ }
+
+ if (player.isGM())
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ player.teleToLocation(114264, 13352, -5104);
+ return null;
+ }
+
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_IN_A_PARTY);
+ return null;
+ }
+
+ public static void main(String[] args)
+ {
+ new Arushinai();
+ }
+}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
new file mode 100644
index 0000000000..ec1f8a6799
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-1.htm
@@ -0,0 +1,6 @@
+
+Dimensional Vortex:
+The energy of Emperor Baium's Rage caused by his imprisoning cracked the skies forming a rift. This rift leads to a new dimension. In order to get there, you will need a Celestial Shard. You can extract it from the Unidentified Stone after you kill all the monsters at the 6th floor or at higher floors of the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
new file mode 100644
index 0000000000..be5290b1f5
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-2.htm
@@ -0,0 +1,5 @@
+Dimensional Vortex:
+Eliminate all the monsters at the 6th floor or higher floors of the Tower of Insolence and use the Unidentified Stone to extract Broken Celestial Shards from it. You can exchange them for a special scroll, which might be useful during your hunt in the Tower of Insolence.
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
new file mode 100644
index 0000000000..ddba0bd4f0
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952-3.htm
@@ -0,0 +1,4 @@
+Dimensional Vortex:
+You need an Airborne Fragment from defeating the monsters on the sixth floor of the Tower of Insolence to enter the Airborne Rift.
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
new file mode 100644
index 0000000000..7b63cb1b68
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/30952.htm
@@ -0,0 +1,6 @@
+Dimensional Vortex:
+Baium was the emperor of Elmoreden, but angered the Gods and was put into solitude for years. He resented Einhasad for cursing him. A small rift appeared in the skies because of the ominous energy surrounding Baium.
+
+
+
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
new file mode 100644
index 0000000000..e676849ad1
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/DimensionalVortex/DimensionalVortex.java
@@ -0,0 +1,135 @@
+/*
+ * 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.TowerOfInsolence.DimensionalVortex;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.Party;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.SystemMessageId;
+import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DimensionalVortex extends AbstractNpcAI
+{
+ // NPC
+ private static final int DIMENTIONAL_VORTEX = 30952;
+ // Items
+ private static final int CELESTIAL_SHARD = 49759;
+ private static final int BROKEN_CELESTIAL_SHARD = 49767;
+
+ private DimensionalVortex()
+ {
+ addStartNpc(DIMENTIONAL_VORTEX);
+ addTalkId(DIMENTIONAL_VORTEX);
+ addFirstTalkId(DIMENTIONAL_VORTEX);
+ }
+
+ @Override
+ public String onAdvEvent(String event, Npc npc, PlayerInstance player)
+ {
+ if (event.equals("30952-1.htm") || event.equals("30952-2.htm") || event.equals("30952-3.htm"))
+ {
+ return event;
+ }
+
+ if (event.equals("tryenter"))
+ {
+ if (getQuestItemsCount(player, CELESTIAL_SHARD) >= 1)
+ {
+ if (player.isGM())
+ {
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ player.teleToLocation(112685, 13362, 10966);
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 180000);
+ return null;
+ }
+ if (!player.isInParty())
+ {
+ player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
+ return null;
+ }
+ final Party party = player.getParty();
+ if ((party == null) || !party.isLeader(player))
+ {
+ player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
+ return null;
+ }
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ if (player.calculateDistance2D(partyMember) > Config.ALT_PARTY_RANGE)
+ {
+ continue;
+ }
+ final SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
+ sm.addPcName(partyMember);
+ player.sendPacket(sm);
+ party.broadcastToPartyMembers(player, sm);
+ return null;
+ }
+ player.destroyItemByItemId("Rift", CELESTIAL_SHARD, 1, npc, true);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ for (PlayerInstance partyMember : party.getMembers())
+ {
+ partyMember.teleToLocation(112685, 13362, 10966);
+ }
+ ThreadPool.schedule(new HeavenlyRiftManager.ClearZoneTask(npc), 1200000);
+ }
+ else
+ {
+ return "30952-3.htm";
+ }
+ }
+ else if (event.equals("exchange"))
+ {
+ long count = getQuestItemsCount(player, BROKEN_CELESTIAL_SHARD);
+ if (count < 10)
+ {
+ return "30952-2.htm";
+ }
+ if ((count % 10) != 0)
+ {
+ count -= count % 10;
+ }
+ final long reward = count / 10;
+ player.destroyItemByItemId("Rift", BROKEN_CELESTIAL_SHARD, count, npc, true);
+ player.addItem("Rift", CELESTIAL_SHARD, reward, npc, true);
+ }
+ return null;
+ }
+
+ @Override
+ public String onFirstTalk(Npc npc, PlayerInstance player)
+ {
+ return npc.getId() + ".htm";
+ }
+
+ public static void main(String[] args)
+ {
+ new DimensionalVortex();
+ }
+}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
new file mode 100644
index 0000000000..c186f5b28d
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/EnergyOfInsolence.java
@@ -0,0 +1,235 @@
+/*
+ * 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.TowerOfInsolence;
+
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.commons.util.CommonUtil;
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.data.xml.impl.SpawnData;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.model.ChanceLocation;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
+import org.l2jmobius.gameserver.model.spawns.NpcSpawnTemplate;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class EnergyOfInsolence extends AbstractNpcAI
+{
+ private static final int LEVEL_MAX_DIFF = 9;
+ private static final int TIME_UNTIL_MOVE = 1800000;
+ private static final int ELMOREDEN_LADY = 20977;
+ private static final int POWER_ANGEL_AMON = 21081;
+ private static final int ENERGY_OF_INSOLENCE_DROP_RATE = 70;
+ private static final int ENERGY_OF_INSOLENCE_ITEM_ID = 49685;
+ private static final int ENERGY_OF_INSOLENCE_DROP_COUNT = 1;
+ private static final int UNIDENTIFIED_STONE_DROP_RATE = 4;
+ private static final int UNIDENTIFIED_STONE_ITEM_ID = 49766;
+ private static final int[] ENERGY_OF_INSOLENCE_NPC_IDS = new int[]
+ {
+ ELMOREDEN_LADY,
+ POWER_ANGEL_AMON
+ };
+ private static final int[] ENERGY_OF_INSOLENCE_MINIONS = new int[]
+ {
+ 20978,
+ 20979,
+ 21073,
+ 21082,
+ 21083
+ };
+ private static final int[] UNIDENTIFIED_STONE_NPC_IDS = new int[]
+ {
+ 20980,
+ 20981,
+ 20982,
+ 20983,
+ 20984,
+ 20985,
+ 21074,
+ 21075,
+ 21076,
+ 21077,
+ 21080,
+ 21980,
+ 21981
+ };
+ private static ScheduledFuture> _scheduleTaskElmoreden;
+ private static ScheduledFuture> _scheduleTaskAmon;
+
+ private EnergyOfInsolence()
+ {
+ addSpawnId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_NPC_IDS);
+ addKillId(UNIDENTIFIED_STONE_NPC_IDS);
+ addKillId(ENERGY_OF_INSOLENCE_MINIONS);
+ }
+
+ private void makeInvul(Npc npc)
+ {
+ npc.getEffectList().startAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(true);
+ }
+
+ private void makeMortal(Npc npc)
+ {
+ npc.getEffectList().stopAbnormalVisualEffect(new AbnormalVisualEffect[]
+ {
+ AbnormalVisualEffect.INVINCIBILITY
+ });
+ npc.setInvul(false);
+ }
+
+ private void makeTalk(Npc npc, boolean spawning)
+ {
+ NpcStringId npcStringId = null;
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ npcStringId = spawning ? NpcStringId.MY_SERVANTS_CAN_KEEP_ME_SAFE_I_HAVE_NOTHING_TO_FEAR : NpcStringId.CAN_T_DIE_IN_A_PLACE_LIKE_THIS;
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ npcStringId = spawning ? NpcStringId.I_WONDER_WHO_IT_IS_THAT_IS_LURKING_ABOUT : NpcStringId.WHY_WOULD_YOU_BUILD_A_TOWER_IN_OUR_TERRITORY;
+ }
+ }
+ npc.broadcastSay(ChatType.NPC_SHOUT, npcStringId);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, true);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ makeInvul(npc);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(npc, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(npc, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ }
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (CommonUtil.contains(UNIDENTIFIED_STONE_NPC_IDS, npc.getId()) && ((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= UNIDENTIFIED_STONE_DROP_RATE))
+ {
+ npc.dropItem(killer, UNIDENTIFIED_STONE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_NPC_IDS, npc.getId()))
+ {
+ makeTalk(npc, false);
+ switch (npc.getId())
+ {
+ case ELMOREDEN_LADY:
+ {
+ _scheduleTaskElmoreden.cancel(true);
+ _scheduleTaskElmoreden = ThreadPool.schedule(new ScheduleAITask(null, ELMOREDEN_LADY), TIME_UNTIL_MOVE);
+ break;
+ }
+ case POWER_ANGEL_AMON:
+ {
+ _scheduleTaskAmon.cancel(true);
+ _scheduleTaskAmon = ThreadPool.schedule(new ScheduleAITask(null, POWER_ANGEL_AMON), TIME_UNTIL_MOVE);
+ }
+ }
+ if (((killer.getLevel() - npc.getLevel()) <= LEVEL_MAX_DIFF) && (Rnd.get(100) <= ENERGY_OF_INSOLENCE_DROP_RATE))
+ {
+ npc.dropItem(killer, ENERGY_OF_INSOLENCE_ITEM_ID, ENERGY_OF_INSOLENCE_DROP_COUNT);
+ }
+ }
+ if (CommonUtil.contains(ENERGY_OF_INSOLENCE_MINIONS, npc.getId()))
+ {
+ final MonsterInstance leader = ((MonsterInstance) npc).getLeader();
+ if ((leader != null) && (leader.getMinionList().getSpawnedMinions().size() == 0) && !leader.isDead())
+ {
+ makeMortal(leader);
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static AbstractNpcAI provider()
+ {
+ return new EnergyOfInsolence();
+ }
+
+ public class ScheduleAITask implements Runnable
+ {
+ private final Npc _npc;
+ private final int _npcId;
+
+ public ScheduleAITask(Npc npc, int npcId)
+ {
+ _npc = npc;
+ _npcId = npcId;
+ }
+
+ @Override
+ public void run()
+ {
+ if (_npc != null)
+ {
+ _npc.deleteMe();
+ }
+
+ try
+ {
+ final Spawn spawn = new Spawn(_npcId);
+ final List spawns = SpawnData.getInstance().getNpcSpawns(npcSpawnTemplate -> npcSpawnTemplate.getId() == _npcId);
+ final List locations = spawns.get(0).getLocation();
+ final Location location = locations.get(Rnd.get(locations.size()));
+ spawn.setLocation(location);
+ spawn.doSpawn();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new EnergyOfInsolence();
+ }
+}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
new file mode 100644
index 0000000000..758820626f
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Bomb.java
@@ -0,0 +1,106 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.commons.util.Rnd;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.WorldObject;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.Playable;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.events.AbstractScript;
+import org.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Bomb extends AbstractNpcAI
+{
+ // NPCs
+ private static final int BOMB = 18003;
+ private static final int DIVINE_ANGEL = 20139;
+ // Items
+ private static final int[] ITEM_DROP_1 = new int[]
+ {
+ 49756,
+ 49762,
+ 49763
+ };
+ private static final int[] ITEM_DROP_2 = new int[]
+ {
+ 49760,
+ 49761
+ };
+
+ public Bomb()
+ {
+ addKillId(BOMB);
+ addSpawnId(BOMB);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ npc.broadcastPacket(new ExChangeNpcState(npc.getObjectId(), 1));
+ return super.onSpawn(npc);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if (Rnd.get(100) < 33)
+ {
+ AbstractScript.addSpawn(DIVINE_ANGEL, npc, false, 1800000);
+ }
+ else
+ {
+ World.getInstance().forEachVisibleObjectInRange((WorldObject) npc, Playable.class, 200, creature ->
+ {
+ if ((creature != null) && !creature.isDead())
+ {
+ creature.reduceCurrentHp(Rnd.get(300, 400), npc, null);
+ }
+ });
+ if (Rnd.get(100) < 50)
+ {
+ if (Rnd.get(100) < 90)
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_1[Rnd.get(ITEM_DROP_1.length)], 1);
+ }
+ else
+ {
+ npc.dropItem(killer.getActingPlayer(), ITEM_DROP_2[Rnd.get(ITEM_DROP_2.length)], 1);
+ }
+ }
+ }
+ if (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0)
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Bomb();
+ }
+}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
new file mode 100644
index 0000000000..5635daa582
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/DivineAngel.java
@@ -0,0 +1,79 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.ai.AttackableAI;
+import org.l2jmobius.gameserver.enums.ChatType;
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class DivineAngel extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public DivineAngel()
+ {
+ addSpawnId(DIVINE_ANGEL);
+ addKillId(DIVINE_ANGEL);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ if ((GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) > 1) && (HeavenlyRiftManager.getAliveNpcCount(npc.getId()) == 0))
+ {
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 1);
+
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && (creature.getId() == TOWER) && !creature.isDead())
+ {
+ ((Npc) creature).broadcastSay(ChatType.NPC_SHOUT, NpcStringId.DIVINE_ANGELS_ARE_NOWHERE_TO_BE_SEEN_I_WANT_TO_TALK_TO_THE_PARTY_LEADER);
+ }
+ }
+ }
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ if (GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0) == 2)
+ {
+ ((AttackableAI) npc.getAI()).setGlobalAggro(0);
+ }
+ return super.onSpawn(npc);
+ }
+
+ public static void main(String[] args)
+ {
+ new DivineAngel();
+ }
+}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
new file mode 100644
index 0000000000..667f598286
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/scripts/ai/areas/TowerOfInsolence/HeavenlyRift/Tower.java
@@ -0,0 +1,64 @@
+/*
+ * 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.TowerOfInsolence.HeavenlyRift;
+
+import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
+import org.l2jmobius.gameserver.instancemanager.HeavenlyRiftManager;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+import ai.AbstractNpcAI;
+
+/**
+ * @author Brutallis
+ */
+public class Tower extends AbstractNpcAI
+{
+ // NPCs
+ private static final int TOWER = 18004;
+ private static final int DIVINE_ANGEL = 20139;
+
+ public Tower()
+ {
+ addKillId(TOWER);
+ }
+
+ @Override
+ public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
+ {
+ HeavenlyRiftManager.getZone().broadcastPacket(new ExShowScreenMessage(NpcStringId.YOU_HAVE_FAILED, 2, 5000));
+ for (Creature creature : HeavenlyRiftManager.getZone().getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == DIVINE_ANGEL))
+ {
+ creature.decayMe();
+ }
+ }
+ GlobalVariablesManager.getInstance().set("heavenly_rift_complete", GlobalVariablesManager.getInstance().getInt("heavenly_rift_level", 0));
+ GlobalVariablesManager.getInstance().set("heavenly_rift_level", 0);
+ GlobalVariablesManager.getInstance().set("heavenly_rift_reward", 0);
+ return super.onKill(npc, killer, isSummon);
+ }
+
+ public static void main(String[] args)
+ {
+ new Tower();
+ }
+}
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/spawns/Aden/Aden.xml b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/spawns/Aden/Aden.xml
index 929fa7b588..62adc335ba 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/spawns/Aden/Aden.xml
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/spawns/Aden/Aden.xml
@@ -3,8 +3,6 @@
-
-
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/spawns/Aden/TowerOfInsolence.xml b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/spawns/Aden/TowerOfInsolence.xml
index ab5c823f8c..a4a4d20a99 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/spawns/Aden/TowerOfInsolence.xml
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/spawns/Aden/TowerOfInsolence.xml
@@ -1638,6 +1638,7 @@
+
\ No newline at end of file
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/stats/npcs/18000-18099.xml b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/stats/npcs/18000-18099.xml
index ad25915a56..81d0a24a30 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/stats/npcs/18000-18099.xml
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/stats/npcs/18000-18099.xml
@@ -185,7 +185,7 @@
520
-
+
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/stats/npcs/20100-20199.xml b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/stats/npcs/20100-20199.xml
index 96e520cf58..38d813f2b9 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/stats/npcs/20100-20199.xml
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/stats/npcs/20100-20199.xml
@@ -1743,7 +1743,11 @@
false
-
+
+
+ ALL
+
+
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/zones/no_restart.xml b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/zones/no_restart.xml
index a7be76e3c1..7516849450 100644
--- a/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/zones/no_restart.xml
+++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/game/data/zones/no_restart.xml
@@ -322,6 +322,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
new file mode 100644
index 0000000000..29800c3dd8
--- /dev/null
+++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/HeavenlyRiftManager.java
@@ -0,0 +1,142 @@
+/*
+ * 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 org.l2jmobius.gameserver.instancemanager;
+
+import org.l2jmobius.commons.concurrent.ThreadPool;
+import org.l2jmobius.gameserver.model.Location;
+import org.l2jmobius.gameserver.model.Spawn;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Npc;
+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
+import org.l2jmobius.gameserver.model.zone.ZoneType;
+import org.l2jmobius.gameserver.network.NpcStringId;
+import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
+
+/**
+ * @author Brutallis
+ */
+public class HeavenlyRiftManager
+{
+ private static final ZoneType ZONE = ZoneManager.getInstance().getZoneByName("heavenly_rift");
+
+ public static ZoneType getZone()
+ {
+ return ZONE;
+ }
+
+ public static int getAliveNpcCount(int npcId)
+ {
+ int result = 0;
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isMonster() && !creature.isDead() && (creature.getId() == npcId))
+ {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ public static void startEvent20Bomb(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.SET_OFF_BOMBS_AND_GET_TREASURES, 2, 5000));
+ spawnMonster(18003, 113352, 12936, 10976, 1800000);
+ spawnMonster(18003, 113592, 13272, 10976, 1800000);
+ spawnMonster(18003, 113816, 13592, 10976, 1800000);
+ spawnMonster(18003, 113080, 13192, 10976, 1800000);
+ spawnMonster(18003, 113336, 13528, 10976, 1800000);
+ spawnMonster(18003, 113560, 13832, 10976, 1800000);
+ spawnMonster(18003, 112776, 13512, 10976, 1800000);
+ spawnMonster(18003, 113064, 13784, 10976, 1800000);
+ spawnMonster(18003, 112440, 13848, 10976, 1800000);
+ spawnMonster(18003, 112728, 14104, 10976, 1800000);
+ spawnMonster(18003, 112760, 14600, 10976, 1800000);
+ spawnMonster(18003, 112392, 14456, 10976, 1800000);
+ spawnMonster(18003, 112104, 14184, 10976, 1800000);
+ spawnMonster(18003, 111816, 14488, 10976, 1800000);
+ spawnMonster(18003, 112104, 14760, 10976, 1800000);
+ spawnMonster(18003, 112392, 15032, 10976, 1800000);
+ spawnMonster(18003, 112120, 15288, 10976, 1800000);
+ spawnMonster(18003, 111784, 15064, 10976, 1800000);
+ spawnMonster(18003, 111480, 14824, 10976, 1800000);
+ spawnMonster(18003, 113144, 14216, 10976, 1800000);
+ }
+
+ public static void startEventTower(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.PROTECT_THE_CENTRAL_TOWER_FROM_DIVINE_ANGELS, 2, 5000));
+ spawnMonster(18004, 112648, 14072, 10976, 1800000);
+ ThreadPool.schedule(() ->
+ {
+ for (int i = 0; i < 20; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }, 10000);
+ }
+
+ public static void startEvent40Angels(PlayerInstance player)
+ {
+ ZONE.broadcastPacket(new ExShowScreenMessage(NpcStringId.DESTROY_WEAKENED_DIVINE_ANGELS, 2, 5000));
+ for (int i = 0; i < 40; ++i)
+ {
+ spawnMonster(20139, 112696, 13960, 10958, 1800000);
+ }
+ }
+
+ private static void spawnMonster(int npcId, int x, int y, int z, long despawnTime)
+ {
+ try
+ {
+ Spawn spawn = new Spawn(npcId);
+ Location location = new Location(x, y, z);
+ spawn.setLocation(location);
+ Npc npc = spawn.doSpawn();
+ npc.scheduleDespawn(despawnTime);
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ public static class ClearZoneTask implements Runnable
+ {
+ private final Npc _npc;
+
+ public ClearZoneTask(Npc npc)
+ {
+ _npc = npc;
+ }
+
+ @Override
+ public void run()
+ {
+ for (Creature creature : ZONE.getCharactersInside())
+ {
+ if (creature.isPlayer())
+ {
+ creature.teleToLocation(114264, 13352, -5104);
+ }
+ else if (creature.isNpc() && (creature.getId() != 30401))
+ {
+ creature.decayMe();
+ }
+ }
+ _npc.setBusy(false);
+ }
+ }
+}