fix(Scripts/AQ): Rewrite bug trio fight (#11565)

* fix(Core/AQ): Rewrite bug trio fight

* update sql to newest

* with a comment

* fix build

* finish?

* build

* add evade boundary
This commit is contained in:
Nefertumm
2022-05-08 05:49:23 -03:00
committed by GitHub
parent e09327163c
commit 6ca5938d75
4 changed files with 399 additions and 264 deletions

View File

@@ -0,0 +1,18 @@
--
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_vem_knockback', 'spell_vem_vengeance');
DELETE FROM `spell_script_names` WHERE `spell_id` = 18670; -- Delete the current script to prevent stacking.
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(18670, 'spell_vem_knockback'),
(25790, 'spell_vem_vengeance');
UPDATE `creature_template` SET `unit_flags` = `unit_flags`|33554432, `flags_extra` = `flags_extra`|128 WHERE `entry` = 15933;
DELETE FROM `creature_template_addon` WHERE `entry` = 15933;
INSERT INTO `creature_template_addon` (`entry`,`auras`) VALUES
(15933, '25786 26575');
DELETE FROM `creature_text` WHERE `CreatureID` IN (15511, 15543, 15544);
INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
(15511, 0, 0, '%s is devoured!', 16, 0, 100, 0, 0, 0, 11115, 0, 'Lord Kri - EMOTE_DEVOURED'),
(15543, 0, 0, '%s is devoured!', 16, 0, 100, 0, 0, 0, 11115, 0, 'Princess Yauj - EMOTE_DEVOURED'),
(15544, 0, 0, '%s is devoured!', 16, 0, 100, 0, 0, 0, 11115, 0, 'Vem - EMOTE_DEVOURED');

View File

@@ -15,330 +15,446 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: boss_kri, boss_yauj, boss_vem : The Bug Trio
SD%Complete: 100
SDComment:
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "temple_of_ahnqiraj.h"
#include "TaskScheduler.h"
enum Spells
{
SPELL_CLEAVE = 26350,
SPELL_TOXIC_VOLLEY = 25812,
SPELL_POISON_CLOUD = 38718, //Only Spell with right dmg.
SPELL_ENRAGE = 34624, //Changed cause 25790 is cast on gamers too. Same prob with old explosion of twin emperors.
SPELL_BLOODY_DEATH = 25770,
SPELL_FULL_HEAL = 17683,
SPELL_CHARGE = 26561,
SPELL_KNOCKBACK = 26027,
// Kri
SPELL_CLEAVE = 26350,
SPELL_THRASH = 3391,
SPELL_TOXIC_VOLLEY = 25812,
SPELL_POISON_CLOUD = 26590,
SPELL_HEAL = 25807,
SPELL_FEAR = 19408
// Vem
SPELL_CHARGE = 26561,
SPELL_KNOCKBACK = 18670,
SPELL_KNOCKDOWN = 19128,
SPELL_VENGEANCE = 25790,
// Yauj
SPELL_HEAL = 25807,
SPELL_FEAR = 26580,
SPELL_RAVAGE = 3242,
SPELL_DISPEL = 25808,
NPC_YAUJ_BROOD = 15621
};
class boss_kri : public CreatureScript
enum Misc
{
public:
boss_kri() : CreatureScript("boss_kri") { }
ACTION_CONSUME = 0,
CreatureAI* GetAI(Creature* creature) const override
{
return GetTempleOfAhnQirajAI<boss_kriAI>(creature);
}
EMOTE_DEVOURED = 0,
struct boss_kriAI : public ScriptedAI
{
boss_kriAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
POINT_CONSUME = 0,
InstanceScript* instance;
uint32 Cleave_Timer;
uint32 ToxicVolley_Timer;
uint32 Check_Timer;
bool VemDead;
bool Death;
void Reset() override
{
Cleave_Timer = urand(4000, 8000);
ToxicVolley_Timer = urand(6000, 12000);
Check_Timer = 2000;
VemDead = false;
Death = false;
}
void EnterCombat(Unit* /*who*/) override
{
}
void JustDied(Unit* /*killer*/) override
{
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
//Cleave_Timer
if (Cleave_Timer <= diff)
{
DoCastVictim(SPELL_CLEAVE);
Cleave_Timer = urand(5000, 12000);
}
else Cleave_Timer -= diff;
//ToxicVolley_Timer
if (ToxicVolley_Timer <= diff)
{
DoCastVictim(SPELL_TOXIC_VOLLEY);
ToxicVolley_Timer = urand(10000, 15000);
}
else ToxicVolley_Timer -= diff;
if (!HealthAbovePct(5) && !Death)
{
DoCastVictim(SPELL_POISON_CLOUD);
Death = true;
}
if (!VemDead)
{
//Checking if Vem is dead. If yes we will enrage.
if (Check_Timer <= diff)
{
if (instance->GetData(DATA_VEMISDEAD))
{
DoCast(me, SPELL_ENRAGE);
VemDead = true;
}
Check_Timer = 2000;
}
else Check_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
VEM_WAYPOINT_PATH = 876030
};
class boss_vem : public CreatureScript
const Position resetPoint = { -8582.0f, 2047.0f, -1.62f }; // Taken from CMangos
struct boss_bug_trio : public BossAI
{
public:
boss_vem() : CreatureScript("boss_vem") { }
boss_bug_trio(Creature* creature) : BossAI(creature, DATA_BUG_TRIO) { Reset(); }
CreatureAI* GetAI(Creature* creature) const override
bool CheckInRoom() override
{
return GetTempleOfAhnQirajAI<boss_vemAI>(creature);
if (me->GetExactDist2d(resetPoint) <= 10.f)
{
EnterEvadeMode(EVADE_REASON_BOUNDARY);
return false;
}
return true;
}
struct boss_vemAI : public ScriptedAI
void EnterCombatWithTrio(Unit* who)
{
boss_vemAI(Creature* creature) : ScriptedAI(creature)
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM)))
if (vem->GetGUID() != me->GetGUID())
vem->GetAI()->AttackStart(who);
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
if (kri->GetGUID() != me->GetGUID())
kri->GetAI()->AttackStart(who);
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ)))
if (yauj->GetGUID() != me->GetGUID())
yauj->GetAI()->AttackStart(who);
}
void EvadeAllBosses(EvadeReason why)
{
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM)))
{
instance = creature->GetInstanceScript();
if (vem->GetGUID() != me->GetGUID())
{
if (vem->IsAlive() && !vem->IsInEvadeMode())
vem->AI()->EnterEvadeMode(why);
else
vem->Respawn();
}
}
InstanceScript* instance;
uint32 Charge_Timer;
uint32 KnockBack_Timer;
uint32 Enrage_Timer;
bool Enraged;
void Reset() override
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
{
Charge_Timer = urand(15000, 27000);
KnockBack_Timer = urand(8000, 20000);
Enrage_Timer = 120000;
Enraged = false;
if (kri->GetGUID() != me->GetGUID())
{
if (kri->IsAlive() && !kri->IsInEvadeMode())
kri->AI()->EnterEvadeMode(why);
else
kri->Respawn();
}
}
void JustDied(Unit* /*killer*/) override
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ)))
{
instance->SetData(DATA_VEM_DEATH, 0);
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
if (yauj->GetGUID() != me->GetGUID())
{
if (yauj->IsAlive() && !yauj->IsInEvadeMode())
yauj->AI()->EnterEvadeMode(why);
else
yauj->Respawn();
}
}
}
void DoAction(int32 action) override
{
if (action != ACTION_CONSUME || dying)
{
return;
}
void EnterCombat(Unit* /*who*/) override
{
}
isEating = true;
me->SetSpeed(MOVE_RUN, 45.f/7.f); // From sniffs
me->SetReactState(REACT_PASSIVE);
}
void UpdateAI(uint32 diff) override
void MovementInform(uint32 type, uint32 /*id*/) override
{
if (type != POINT_MOTION_TYPE)
return;
me->GetMotionMaster()->MoveIdle();
me->SetSpeed(MOVE_RUN, 15.f/7.f); // From sniffs
DoCastSelf(SPELL_FULL_HEAL, true);
DoResetThreat();
isEating = false;
_scheduler.Schedule(4s, [this](TaskContext /*context*/)
{
//Return since we have no target
if (!UpdateVictim())
me->SetReactState(REACT_AGGRESSIVE);
if (Unit* target = me->GetVictim())
{
me->GetMotionMaster()->MoveChase(target);
AttackStart(target);
}
});
}
void EnterEvadeMode(EvadeReason why) override
{
BossAI::EnterEvadeMode(why);
EvadeAllBosses(why);
}
void Reset() override
{
BossAI::Reset();
_scheduler.CancelAll();
dying = false;
isEating = false;
instance->SetData(DATA_BUG_TRIO_DEATH, 0);
me->SetSpeed(MOVE_RUN, 15.f / 7.f); // From sniffs
me->SetStandState(UNIT_STAND_STATE_STAND);
me->SetControlled(false, UNIT_STATE_ROOT);
if (me->GetEntry() == NPC_VEM)
{
me->GetMotionMaster()->MovePath(VEM_WAYPOINT_PATH, true);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim() || isEating || !CheckInRoom())
return;
_scheduler.Update(diff, [this]
{
DoMeleeAttackIfReady();
});
}
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (me->HealthBelowPctDamaged(1, damage) && instance->GetData(DATA_BUG_TRIO_DEATH) < 2 && who->GetGUID() != me->GetGUID())
{
damage = 0;
if (isEating)
return;
//Charge_Timer
if (Charge_Timer <= diff)
_scheduler.CancelAll();
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetReactState(REACT_PASSIVE);
me->SetControlled(true, UNIT_STATE_ROOT);
DoFinalSpell();
// Move the other bugs to this bug position
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM)))
{
Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
if (target)
if (vem->GetGUID() != me->GetGUID())
{
DoCast(target, SPELL_CHARGE);
//me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1);
AttackStart(target);
vem->AI()->DoAction(ACTION_CONSUME);
vem->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
}
Charge_Timer = urand(8000, 16000);
}
else Charge_Timer -= diff;
//KnockBack_Timer
if (KnockBack_Timer <= diff)
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
{
DoCastVictim(SPELL_KNOCKBACK);
if (DoGetThreat(me->GetVictim()))
DoModifyThreatPercent(me->GetVictim(), -80);
KnockBack_Timer = urand(15000, 25000);
if (kri->GetGUID() != me->GetGUID())
{
kri->AI()->DoAction(ACTION_CONSUME);
kri->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
}
}
else KnockBack_Timer -= diff;
//Enrage_Timer
if (!Enraged && Enrage_Timer <= diff)
if (Creature* yauj = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_YAUJ)))
{
DoCast(me, SPELL_ENRAGE);
Enraged = true;
if (yauj->GetGUID() != me->GetGUID())
{
yauj->AI()->DoAction(ACTION_CONSUME);
yauj->GetMotionMaster()->MovePoint(POINT_CONSUME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
}
}
else Charge_Timer -= diff;
DoMeleeAttackIfReady();
_scheduler.Schedule(4s, [this](TaskContext /*context*/)
{
if (!me->IsInEvadeMode())
{
DoCastSelf(SPELL_BLOODY_DEATH, true);
Talk(EMOTE_DEVOURED);
me->DespawnOrUnsummon(1000);
}
});
}
};
}
void DoFinalSpell()
{
switch (me->GetEntry())
{
case NPC_KRI:
DoCastSelf(SPELL_POISON_CLOUD, true);
break;
case NPC_VEM:
DoCastSelf(SPELL_VENGEANCE, true);
break;
case NPC_YAUJ:
for (uint8 i = 0; i < 10; ++i)
{
Position randomPos;
me->GetRandomContactPoint(me, randomPos.m_positionX, randomPos.m_positionY, randomPos.m_positionZ);
if (Creature* summon = me->SummonCreature(NPC_YAUJ_BROOD, randomPos))
DoZoneInCombat(summon);
}
break;
default:
break;
}
}
void JustDied(Unit* killer) override
{
if (killer->GetGUID() == me->GetGUID())
{
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
return;
}
BossAI::JustDied(killer);
}
TaskScheduler _scheduler;
bool dying;
bool isEating;
};
class boss_yauj : public CreatureScript
struct boss_kri : public boss_bug_trio
{
public:
boss_yauj() : CreatureScript("boss_yauj") { }
CreatureAI* GetAI(Creature* creature) const override
boss_kri(Creature* creature) : boss_bug_trio(creature)
{
return GetTempleOfAhnQirajAI<boss_yaujAI>(creature);
}
struct boss_yaujAI : public ScriptedAI
void EnterCombat(Unit* who) override
{
boss_yaujAI(Creature* creature) : ScriptedAI(creature)
EnterCombatWithTrio(who);
_scheduler.Schedule(4s, 8s, [this](TaskContext context)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint32 Heal_Timer;
uint32 Fear_Timer;
uint32 Check_Timer;
bool VemDead;
void Reset() override
DoCastVictim(SPELL_CLEAVE);
context.Repeat(5s, 12s);
})
.Schedule(6s, 30s, [this](TaskContext context)
{
Heal_Timer = urand(25000, 40000);
Fear_Timer = urand(12000, 24000);
Check_Timer = 2000;
VemDead = false;
}
void JustDied(Unit* /*killer*/) override
DoCastVictim(SPELL_TOXIC_VOLLEY);
context.Repeat(10s, 25s);
})
.Schedule(6s, [this](TaskContext context)
{
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
DoCastVictim(SPELL_THRASH);
context.Repeat(2s, 6s);
});
}
};
for (uint8 i = 0; i < 10; ++i)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
struct boss_vem : public boss_bug_trio
{
boss_vem(Creature* creature) : boss_bug_trio(creature)
{
}
void EnterCombat(Unit* who) override
{
EnterCombatWithTrio(who);
_scheduler.Schedule(15s, 27s, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, [this](Unit* target) -> bool
{
if (Creature* Summoned = me->SummonCreature(15621, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000))
Summoned->AI()->AttackStart(target);
}
}
}
if (target->GetTypeId() != TYPEID_PLAYER)
return false;
if (me->IsWithinMeleeRange(target) || target == me->GetVictim())
return false;
if (!me->IsWithinLOS(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()))
return false;
void EnterCombat(Unit* /*who*/) override
return true;
}))
{
DoCast(target, SPELL_CHARGE);
}
context.Repeat(8s, 16s);
})
.Schedule(10s, 20s, [this](TaskContext context)
{
}
void UpdateAI(uint32 diff) override
DoCastVictim(SPELL_KNOCKBACK);
context.Repeat(10s, 20s);
})
.Schedule(5s, 8s, [this](TaskContext context)
{
//Return since we have no target
if (!UpdateVictim())
return;
//Fear_Timer
if (Fear_Timer <= diff)
DoCastVictim(SPELL_KNOCKDOWN);
context.Repeat(15s, 20s);
})
.Schedule(1s, [this](TaskContext context)
{
if (instance->GetData(DATA_BUG_TRIO_DEATH) == 2 && !me->HasAura(SPELL_VENGEANCE)) // Vem is the only one left.
{
DoCastVictim(SPELL_FEAR);
DoResetThreat();
Fear_Timer = 20000;
DoCastSelf(SPELL_VENGEANCE, true);
}
else Fear_Timer -= diff;
context.Repeat(1s);
});
}
};
//Casting Heal to other twins or herself.
if (Heal_Timer <= diff)
struct boss_yauj : public boss_bug_trio
{
boss_yauj(Creature* creature) : boss_bug_trio(creature)
{
}
void EnterCombat(Unit* who) override
{
EnterCombatWithTrio(who);
_scheduler.Schedule(20s, 30s, [this](TaskContext context)
{
if (me->GetHealthPct() <= 93.f)
{
switch (urand(0, 2))
{
case 0:
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KRI)))
DoCast(kri, SPELL_HEAL);
break;
case 1:
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VEM)))
DoCast(vem, SPELL_HEAL);
break;
case 2:
DoCast(me, SPELL_HEAL);
break;
}
Heal_Timer = 15000 + rand() % 15000;
DoCastSelf(SPELL_HEAL);
}
else Heal_Timer -= diff;
//Checking if Vem is dead. If yes we will enrage.
if (Check_Timer <= diff)
else if (Unit* friendly = DoSelectLowestHpFriendly(100.f))
{
if (!VemDead)
{
if (instance->GetData(DATA_VEMISDEAD))
{
DoCast(me, SPELL_ENRAGE);
VemDead = true;
}
}
Check_Timer = 2000;
DoCast(friendly, SPELL_HEAL);
}
else Check_Timer -= diff;
context.Repeat(10s, 30s);
})
.Schedule(12s, 24s, [this](TaskContext context)
{
DoCastAOE(SPELL_FEAR);
DoResetThreat();
context.Repeat(20s);
})
.Schedule(12s, [this](TaskContext context)
{
DoCastVictim(SPELL_RAVAGE);
context.Repeat(10s, 15s);
})
.Schedule(10s, 30s, [this](TaskContext context)
{
std::list<Creature*> targets = DoFindFriendlyCC(50.f);
if (!targets.empty())
{
if (Creature* target = *(targets.begin()))
me->CastSpell(target, SPELL_DISPEL);
}
context.Repeat(10s, 15s);
});
}
};
DoMeleeAttackIfReady();
class spell_vem_knockback : public SpellScript
{
PrepareSpellScript(spell_vem_knockback);
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Unit* target = GetHitUnit())
{
if (Creature* cCaster = GetCaster()->ToCreature())
{
cCaster->getThreatMgr().modifyThreatPercent(target, -80);
}
}
};
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_vem_knockback::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_vem_vengeance : public SpellScript
{
PrepareSpellScript(spell_vem_vengeance);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if([&](WorldObject const* target) -> bool
{
return target->GetEntry() != NPC_YAUJ && target->GetEntry() != NPC_VEM && target->GetEntry() != NPC_KRI;
});
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_vem_vengeance::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
void AddSC_bug_trio()
{
new boss_kri();
new boss_vem();
new boss_yauj();
RegisterCreatureAI(boss_kri);
RegisterCreatureAI(boss_vem);
RegisterCreatureAI(boss_yauj);
RegisterSpellScript(spell_vem_knockback);
RegisterSpellScript(spell_vem_vengeance);
}

View File

@@ -56,6 +56,7 @@ public:
ObjectGuid SkeramGUID;
ObjectGuid VemGUID;
ObjectGuid KriGUID;
ObjectGuid YaujGUID;
ObjectGuid VeklorGUID;
ObjectGuid VeknilashGUID;
ObjectGuid ViscidusGUID;
@@ -88,6 +89,9 @@ public:
case NPC_KRI:
KriGUID = creature->GetGUID();
break;
case NPC_YAUJ:
YaujGUID = creature->GetGUID();
break;
case NPC_VEKLOR:
VeklorGUID = creature->GetGUID();
break;
@@ -106,11 +110,6 @@ public:
{
switch (type)
{
case DATA_VEMISDEAD:
if (IsBossDied[0])
return 1;
break;
case DATA_VEKLORISDEAD:
if (IsBossDied[1])
return 1;
@@ -140,6 +139,8 @@ public:
return VemGUID;
case DATA_KRI:
return KriGUID;
case DATA_YAUJ:
return YaujGUID;
case DATA_VEKLOR:
return VeklorGUID;
case DATA_VEKNILASH:
@@ -155,12 +156,11 @@ public:
{
switch (type)
{
case DATA_VEM_DEATH:
IsBossDied[0] = true;
break;
case DATA_BUG_TRIO_DEATH:
++BugTrioDeathCount;
if (data != 0)
++BugTrioDeathCount;
else
BugTrioDeathCount = 0;
break;
case DATA_VEKLOR_DEATH:

View File

@@ -27,8 +27,8 @@ enum DataTypes
DATA_SKERAM = 1,
DATA_KRI = 2,
DATA_VEM = 3,
DATA_VEMISDEAD = 4,
DATA_VEM_DEATH = 5,
DATA_YAUJ = 4,
DATA_BUG_TRIO = 5,
DATA_VEKLOR = 6,
DATA_VEKLORISDEAD = 7,
DATA_VEKLOR_DEATH = 8,
@@ -60,6 +60,7 @@ enum Creatures
NPC_SKERAM = 15263,
NPC_VEM = 15544,
NPC_KRI = 15511,
NPC_YAUJ = 15543,
NPC_VEKLOR = 15276,
NPC_VEKNILASH = 15275,
NPC_OURO = 15517,