NPC related changes.

This commit is contained in:
MobiusDev
2017-08-16 23:36:38 +00:00
parent 1402651b38
commit e4f3e8364c
661 changed files with 660023 additions and 668713 deletions

View File

@@ -1,74 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package ai.areas.EnchantedValley;
import java.util.ArrayList;
import java.util.List;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import ai.AbstractNpcAI;
/**
* AI from Flower Bud in Enchanted Valley, after kill random spawn<br>
* [Nymph Rose (Elegant), Nymph Lily (Elegant), Nymph Tulip (Elegant), Nymph Cosmos (Elegant)]
* @author Gigi
*/
public final class FlowerBud extends AbstractNpcAI
{
// NPCs
private static final int FLOWER_BUD = 19600;
private static final List<Integer> FLOWER_SPAWNS = new ArrayList<>();
static
{
FLOWER_SPAWNS.add(23582);
FLOWER_SPAWNS.add(23583);
FLOWER_SPAWNS.add(23584);
FLOWER_SPAWNS.add(23585);
}
private FlowerBud()
{
addKillId(FLOWER_BUD);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("spawn") && npc.isDead())
{
final L2Npc elegant = addSpawn(FLOWER_SPAWNS.get(Rnd.get(FLOWER_SPAWNS.size())), npc, false, 120000, false);
addAttackPlayerDesire(elegant, player);
}
return event;
}
@Override
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
{
startQuestTimer("spawn", 3000, npc, killer);
return super.onKill(npc, killer, isSummon);
}
public static void main(String[] args)
{
new FlowerBud();
}
}

View File

@@ -1,5 +0,0 @@
<html><body>Merlot:<br>
Currently, dimensional teleportation is not available. We can't just send you whenever we want.<br>
We can only send you <font color="LEVEL">on weeks when there are no Dimensional Sieges</font>.<br>
Also, you must be above <font color="LEVEL">Lv. 99</font>, since the other dimension is very dangerous.
</body></html>

View File

@@ -1,5 +0,0 @@
<html><body>Merlot:<br>
If you have an Atelia Crystal that you received from defeating the Embryo in this dimension, I'll give you 1 Dimensional Coin and 14 million SP.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Merlot give_coin">"I have an Atelia Crystal."</Button>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h npc_%objectId%_Chat 0">Back</Button>
</body></html>

View File

@@ -1,6 +0,0 @@
<html><body>Merlot:<br>
I'm exchanging rewards for Dimensional Coins.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 3401800">"I want to exchange a Dimensional Coin for a reward."</button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_multisell 3401801">"I want to exchange a Enhancement Stone Coupon."</button>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h npc_%objectId%_Chat 0">Back</Button>
</body></html>

View File

@@ -1,3 +0,0 @@
<html><body>Merlot:<br>
You don't have an Atelia Energy Crystal. Please check again.<br>
</body></html>

View File

@@ -1,10 +0,0 @@
<html><body>Merlot:<br>
Hello! I'm Merlot.<br>
Did you know that the Embryo have started appearing in the other dimension? I've been told by Master Mermoden to defeat those Embryo, and I've been searching for people to help me.<br>
And... I came here... and met Aria... and I kind of, uh... fell in love.<br>
Well, I'm just here to look for someone who will help me defeat the enemy.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Merlot dimensional_raid">"I want to go into the Dimensional Raid."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Merlot 34018-2.htm">"I want to exchange an Atelia Crystal for a Dimensional Coin."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Merlot 34018-3.htm">"I want to exchange rewards."</Button>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -1,101 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package ai.areas.HuntersVillage.Merlot;
import com.l2jmobius.gameserver.enums.QuestSound;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import ai.AbstractNpcAI;
/**
* Merlot AI.
* @author crystalgarden
*/
public final class Merlot extends AbstractNpcAI
{
// NPC
private static final int MERLOT = 34018;
// Item
private static final int ATELIA_CRYSTAL = 45610;
private static final int DIMENSIONAL_COIN = 45941;
// Misc
private static final int MIN_LEVEL = 99;
// Location
private static final Location DIMENSIONAL_RAID = new Location(116503, 75392, -2712); // Merlot Position
private Merlot()
{
addStartNpc(MERLOT);
addTalkId(MERLOT);
addFirstTalkId(MERLOT);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = null;
switch (event)
{
case "34018-2.htm":
case "34018-3.htm":
{
htmltext = event;
break;
}
case "give_coin":
{
if (hasQuestItems(player, ATELIA_CRYSTAL))
{
giveItems(player, DIMENSIONAL_COIN, 1);
addExpAndSp(player, 0, 14000000);
playSound(player, QuestSound.ITEMSOUND_QUEST_ITEMGET);
}
else
{
htmltext = "34018-5.htm";
}
break;
}
case "dimensional_raid": // Need TODO Dimensional Raid
{
if (player.getLevel() < MIN_LEVEL)
{
htmltext = "34018-1.htm";
}
else
{
player.teleToLocation(DIMENSIONAL_RAID);
}
break;
}
}
return htmltext;
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
return "34018.htm";
}
public static void main(String[] args)
{
new Merlot();
}
}

View File

@@ -1,4 +0,0 @@
<html><body>Teleport Device:<br>
Cannot enter the Atelia Castle.<br>
(Kelbim has not appeared in the Atelia Fortress so you cannot enter.)
</body></html>

View File

@@ -1,3 +0,0 @@
<html><body>Teleport Device:<br>
(A command channel needs at least %min% members to challenge Kelbim.)
</body></html>

View File

@@ -1,4 +0,0 @@
<html><body>Teleport Device:<br>
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
(The players who belong to an association can only enter through the Association Leader.)
</body></html>

View File

@@ -1,5 +0,0 @@
<html><body>Teleport Device:<br>
I'll help you enter the Atelia Castle.<br1>
Would you like to enter?<br>
<Button ALIGN=LEFT ICON="TELEPORT" action="bypass -h Quest Kelbim">"Yes, please."</Button>
</body></html>

View File

@@ -1,435 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package ai.bosses.Kelbim;
import java.util.ArrayList;
import java.util.List;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.enums.Movie;
import com.l2jmobius.gameserver.instancemanager.GrandBossManager;
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
import com.l2jmobius.gameserver.model.L2Party;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.TeleportWhereType;
import com.l2jmobius.gameserver.model.actor.L2Attackable;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.quest.QuestTimer;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
import com.l2jmobius.gameserver.network.serverpackets.Earthquake;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.util.Broadcast;
import ai.AbstractNpcAI;
/**
* Kelbim AI<br>
* @author LasTravel<br>
* @video https://www.youtube.com/watch?v=qVkk2BJoGoU
*/
public class Kelbim extends AbstractNpcAI
{
// Status
private static final int ALIVE = 0;
private static final int WAITING = 1;
private static final int FIGHTING = 2;
private static final int DEAD = 3;
// NPCs
private static final int ENTER_DEVICE = 34052;
private static final int TELEPORT_DEVICE = 34053;
private static final int KELBIM_SHOUT = 19597;
private static final int KELBIM = 26124;
private static final int GUARDIAN_SINISTRA = 26126;
private static final int GUARDIAN_DESTRA = 26127;
private static final int[] KELBIM_GUARDIANS =
{
GUARDIAN_SINISTRA,
GUARDIAN_DESTRA
};
private static final int KELBIM_GUARD = 26129;
private static final int KELBIM_ALTAR = 26130;
private static final int[] KELBIM_MINIONS =
{
GUARDIAN_SINISTRA,
GUARDIAN_DESTRA,
KELBIM_GUARD
};
private static final int[] ALL_MONSTERS =
{
KELBIM,
KELBIM_MINIONS[0],
KELBIM_MINIONS[1],
KELBIM_MINIONS[2],
KELBIM_ALTAR
};
// Doors
private static final int DOOR1 = 18190002;
private static final int DOOR2 = 18190004;
// Skills
private static final Skill METEOR_CRASH = SkillData.getInstance().getSkill(23692, 1);
private static final Skill WATER_DROP = SkillData.getInstance().getSkill(23693, 1);
private static final Skill TORNADO_SACKLE = SkillData.getInstance().getSkill(23694, 1);
private static final Skill FLAME_THROWER = SkillData.getInstance().getSkill(23699, 1);
private static final Skill[] AREA_SKILLS =
{
METEOR_CRASH,
WATER_DROP,
TORNADO_SACKLE,
FLAME_THROWER
};
// Misc
private static final L2ZoneType ZONE = ZoneManager.getInstance().getZoneById(60023);
private static final Location KELBIM_LOCATION = new Location(-55386, 58939, -274);
// Vars
private static L2Npc _kelbimBoss;
private static long _lastAction;
private static int _bossStage;
private static ArrayList<L2Npc> _minions = new ArrayList<>();
public Kelbim()
{
addTalkId(ENTER_DEVICE, TELEPORT_DEVICE);
addStartNpc(ENTER_DEVICE, TELEPORT_DEVICE);
addFirstTalkId(ENTER_DEVICE, TELEPORT_DEVICE);
addAttackId(ALL_MONSTERS);
addKillId(KELBIM);
// Unlock
final StatsSet info = GrandBossManager.getInstance().getStatsSet(KELBIM);
final long time = info.getLong("respawn_time") - System.currentTimeMillis();
if (time > 0)
{
startQuestTimer("unlock_kelbim", time, null, null);
}
else
{
openDoor(DOOR1, 0);
openDoor(DOOR2, 0);
}
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
switch (event)
{
case "unlock_kelbim":
{
GrandBossManager.getInstance().setBossStatus(KELBIM, ALIVE);
Broadcast.toAllOnlinePlayers(new Earthquake(-55754, 59903, -269, 20, 10));
openDoor(DOOR1, 0);
openDoor(DOOR2, 0);
break;
}
case "check_activity_task":
{
if ((_lastAction + 900000) < System.currentTimeMillis())
{
GrandBossManager.getInstance().setBossStatus(KELBIM, ALIVE);
for (L2Character charInside : ZONE.getCharactersInside())
{
if (charInside != null)
{
if (charInside.isNpc())
{
charInside.deleteMe();
}
else if (charInside.isPlayer())
{
charInside.teleToLocation(MapRegionManager.getInstance().getTeleToLocation(charInside, TeleportWhereType.TOWN));
}
}
}
startQuestTimer("end_kelbim", 2000, null, null);
}
else
{
startQuestTimer("check_activity_task", 60000, null, null);
}
break;
}
case "stage_1_start":
{
_bossStage = 1;
GrandBossManager.getInstance().setBossStatus(KELBIM, FIGHTING);
playMovie(ZONE.getPlayersInside(), Movie.SC_KELBIM_OPENING);
startQuestTimer("stage_1_kelbim_spawn", 25000, null, null);
break;
}
case "stage_1_kelbim_spawn":
{
_kelbimBoss = addSpawn(KELBIM, -56340, 60801, -269, 54262, false, 0);
_lastAction = System.currentTimeMillis();
startQuestTimer("check_activity_task", 60000, null, null, true);
startQuestTimer("stage_all_random_area_attack", Rnd.get(2, 3) * 60000, null, null);
break;
}
case "stage_all_spawn_minions":
{
for (int i = 0; i < Rnd.get((_bossStage * 5) / 2, _bossStage * 5); i++)
{
L2Npc minion = addSpawn(KELBIM_GUARD, _kelbimBoss.getX(), _kelbimBoss.getY(), _kelbimBoss.getZ(), 0, true, 0, true, 0);
minion.setIsRunning(true);
((L2Attackable) minion).setIsRaidMinion(true);
_minions.add(minion);
}
for (int i = 0; i < Rnd.get((_bossStage * 2) / 2, _bossStage * 2); i++)
{
L2Npc minion = addSpawn(KELBIM_GUARDIANS[Rnd.get(KELBIM_GUARDIANS.length)], _kelbimBoss.getX(), _kelbimBoss.getY(), _kelbimBoss.getZ(), 0, true, 0, true, 0);
minion.setIsRunning(true);
((L2Attackable) minion).setIsRaidMinion(true);
_minions.add(minion);
}
break;
}
case "stage_all_random_area_attack":
{
if ((_bossStage > 0) && (_bossStage < 7))
{
if (_kelbimBoss.isInCombat())
{
Skill randomAttackSkill = AREA_SKILLS[Rnd.get(AREA_SKILLS.length)];
ArrayList<L2Npc> _skillNpcs = new ArrayList<>();
for (L2PcInstance pl : ZONE.getPlayersInside())
{
if (pl == null)
{
continue;
}
if (Rnd.get(100) > 40)
{
L2Npc skillMob = addSpawn(KELBIM_SHOUT, pl.getX(), pl.getY(), pl.getZ() + 10, 0, true, 60000, false, 0);
_skillNpcs.add(skillMob);
_minions.add(skillMob);
}
}
for (L2Npc skillNpc : _skillNpcs)
{
if (skillNpc == null)
{
continue;
}
skillNpc.doCast(randomAttackSkill);
}
}
startQuestTimer("stage_all_random_area_attack", Rnd.get(1, 2) * 60000, null, null);
}
break;
}
case "cancel_timers":
{
QuestTimer activityTimer = getQuestTimer("check_activity_task", null, null);
if (activityTimer != null)
{
activityTimer.cancel();
}
break;
}
case "end_kelbim":
{
_bossStage = 0;
ZONE.oustAllPlayers();
if (_kelbimBoss != null)
{
_kelbimBoss.deleteMe();
}
if (!_minions.isEmpty())
{
for (L2Npc minion : _minions)
{
if (minion == null)
{
continue;
}
minion.deleteMe();
}
}
_minions.clear();
break;
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
switch (npc.getId())
{
case TELEPORT_DEVICE:
{
player.teleToLocation(-55730, 55643, -1954);
break;
}
case ENTER_DEVICE:
{
return "34052.html";
}
}
return super.onFirstTalk(npc, player);
}
@Override
public String onTalk(L2Npc npc, L2PcInstance player)
{
if (npc.getId() == ENTER_DEVICE)
{
int status = GrandBossManager.getInstance().getBossStatus(KELBIM);
if (status > ALIVE)
{
return "34052-1.html";
}
if (!player.isInParty())
{
final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
packet.setHtml(getHtm(player.getHtmlPrefix(), "34052-2.html"));
packet.replace("%min%", Integer.toString(Config.KELBIM_MIN_PLAYERS));
player.sendPacket(packet);
return null;
}
final L2Party party = player.getParty();
final boolean isInCC = party.isInCommandChannel();
final List<L2PcInstance> members = (isInCC) ? party.getCommandChannel().getMembers() : party.getMembers();
final boolean isPartyLeader = (isInCC) ? party.getCommandChannel().isLeader(player) : party.isLeader(player);
if (!isPartyLeader)
{
return "34052-3.html";
}
else if ((members.size() < Config.KELBIM_MIN_PLAYERS) || (members.size() > Config.KELBIM_MAX_PLAYERS))
{
final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
packet.setHtml(getHtm(player.getHtmlPrefix(), "34052-2.html"));
packet.replace("%min%", Integer.toString(Config.KELBIM_MIN_PLAYERS));
player.sendPacket(packet);
}
else
{
for (L2PcInstance member : members)
{
if (member.isInsideRadius(npc, 1000, true, false))
{
member.teleToLocation(KELBIM_LOCATION, true);
}
}
}
if (status == ALIVE)
{
GrandBossManager.getInstance().setBossStatus(KELBIM, WAITING);
startQuestTimer("stage_1_start", Config.KELBIM_WAIT_TIME * 60 * 1000, null, null);
}
}
return super.onTalk(npc, player);
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isPet)
{
if (npc.getId() == KELBIM)
{
_lastAction = System.currentTimeMillis();
switch (_bossStage)
{
case 1:
{
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.80))
{
_bossStage = 2;
notifyEvent("stage_all_spawn_minions", null, null);
}
break;
}
case 2:
{
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.60))
{
_bossStage = 3;
notifyEvent("stage_all_spawn_minions", null, null);
}
break;
}
case 3:
{
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.40))
{
_bossStage = 4;
notifyEvent("stage_all_spawn_minions", null, null);
}
break;
}
case 4:
{
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.20))
{
_bossStage = 5;
notifyEvent("stage_all_spawn_minions", null, null);
}
break;
}
case 5:
{
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.05))
{
_bossStage = 6;
notifyEvent("stage_all_spawn_minions", null, null);
}
break;
}
}
}
return super.onAttack(npc, attacker, damage, isPet);
}
@Override
public String onKill(L2Npc npc, L2PcInstance killer, boolean isPet)
{
_bossStage = 7;
addSpawn(TELEPORT_DEVICE, -54331, 58331, -264, 16292, false, 1800000);
notifyEvent("cancel_timers", null, null);
closeDoor(DOOR1, 0);
closeDoor(DOOR2, 0);
GrandBossManager.getInstance().setBossStatus(KELBIM, DEAD);
final long respawnTime = (Config.KELBIM_SPAWN_INTERVAL + getRandom(-Config.KELBIM_SPAWN_RANDOM, Config.KELBIM_SPAWN_RANDOM)) * 3600000;
final StatsSet info = GrandBossManager.getInstance().getStatsSet(KELBIM);
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(KELBIM, info);
startQuestTimer("unlock_kelbim", respawnTime, null, null);
startQuestTimer("end_kelbim", 1800000, null, null);
return super.onKill(npc, killer, isPet);
}
public static void main(String[] args)
{
new Kelbim();
}
}

View File

@@ -1,9 +0,0 @@
<html><body>Adventure Guildsman:<br>
Welcome to Underground Gainak, a place with endless adventures.<br>
I've been dispatched here from the Adventurer's Guild.<br>
We know anything and everything that can help you in your adventures. We are also <font color="LEVEL">exchanging Adventurer's Marks and Seals</font>. How can I help you?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventureGuildsman questList">"Tell me about quests."</Button>
<Button ALIGN="LEFT" ICON="NORMAL" action="bypass -h npc_%objectId%_Quest">"I want to exchange Adventurer's Marks and Seals."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest AdventureGuildsman AdventureGuildsman-Gludin.html">"I'd like to use a Life Crystal."</Button>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -47,9 +47,9 @@ public final class AdventureGuildsman extends AbstractNpcAI
31835, 31837, 31838,
31840, 31841, 31991,
31992, 31993, 31995,
33946, 34187, 31812,
31813, 31811, 31801,
31802, 31803
33946, 31812, 31813,
31811, 31801, 31802,
31803
};
// @formatter:on
// Skills

View File

@@ -46,18 +46,12 @@ public final class AreaSkillNpc extends AbstractNpcAI
13323, // Whisper of Fear
13324, // Whisper of Fear
13325, // Whisper of Fear
13458, // Whisper of Fear
13459, // Whisper of Fear
13460, // Whisper of Fear
13310, // Solo Dance
13377, // Solo Dance
13378, // Solo Dance
13379, // Solo Dance
13380, // Solo Dance
13381, // Solo Dance
13452, // Solo Dance
13453, // Solo Dance
13454, // Solo Dance
};
private static final int[] TOTEMS = // ai_totem_of_body
{

View File

@@ -36,15 +36,10 @@ public final class GateOfUnlimitedSummoning extends AbstractNpcAI
{
// NPCs
private static final Map<Integer, Integer> DEATH_GATE = new HashMap<>();
static
{
DEATH_GATE.put(14927, 1); // Death Gate
DEATH_GATE.put(15200, 2); // Death Gate
DEATH_GATE.put(15201, 3); // Death Gate
DEATH_GATE.put(15202, 4); // Death Gate
}
// Skills
private static final int GATE_ROOT = 11289;
private static final int GATE_VORTEX = 11291;