From b959d5cc87e262efdebf1fc079a3637b41af3df2 Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Thu, 4 Jul 2024 20:13:41 +0200 Subject: [PATCH] refactor(Scripts/ZulAman): Nalorakk refactored (#19010) * init * update movement * updates and debug * stuck :/ scheduler doesn't seem to update when at the end of wp movement??? * fix wps and implement fight * finalise * unused * Update boss_nalorakk.cpp * keep oprientation * ran_intro --- .../updates/pending_db_world/waypoints.sql | 14 + .../EasternKingdoms/ZulAman/boss_nalorakk.cpp | 642 ++++++++---------- .../ZulAman/instance_zulaman.cpp | 4 +- .../scripts/EasternKingdoms/ZulAman/zulaman.h | 6 +- 4 files changed, 286 insertions(+), 380 deletions(-) create mode 100644 data/sql/updates/pending_db_world/waypoints.sql diff --git a/data/sql/updates/pending_db_world/waypoints.sql b/data/sql/updates/pending_db_world/waypoints.sql new file mode 100644 index 000000000..f36912184 --- /dev/null +++ b/data/sql/updates/pending_db_world/waypoints.sql @@ -0,0 +1,14 @@ +-- +DELETE FROM `waypoint_data` WHERE `id` IN (2357601, 2357602, 2357603); +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(2357601, 1, -52.642, 1419.357, 27.31, NULL, 0, 1, 0, 100, 0), +(2357602, 1, -69.908, 1419.721, 27.31, NULL, 0, 1, 0, 100, 0), +(2357602, 2, -79.929, 1395.958, 27.31, NULL, 0, 1, 0, 100, 0), +(2357602, 3, -80.072, 1374.555, 40.87, NULL, 0, 1, 0, 100, 0), +(2357603, 1, -80.072, 1314.398, 40.87, NULL, 0, 1, 0, 100, 0), +(2357603, 2, -80.072, 1295.775, 48.60, NULL, 0, 1, 0, 100, 0); + +DELETE FROM `creature_text` WHERE `CreatureID` = 23576 AND `GroupID` IN (14, 15); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23576, 14, 0, 'Mua-ha-ha!', 14, 0, 100, 0, 0, 0, 22145, 1, 'Nalorakk - RUN AWAY'), +(23576, 15, 0, '%s transforms into a bear!', 16, 0, 100, 0, 0, 0, 24263, 1, 'Nalorakk - EMOTE BEAR'); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp index 5631b5edc..af0e1e19d 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp @@ -46,19 +46,6 @@ enum Spells SPELL_DEAFENINGROAR = 42398 }; -// Trash Waves -float NalorakkWay[8][3] = -{ - { 18.569f, 1414.512f, 11.42f}, // waypoint 1 - {-17.264f, 1419.551f, 12.62f}, - {-52.642f, 1419.357f, 27.31f}, // waypoint 2 - {-69.908f, 1419.721f, 27.31f}, - {-79.929f, 1395.958f, 27.31f}, - {-80.072f, 1374.555f, 40.87f}, // waypoint 3 - {-80.072f, 1314.398f, 40.87f}, - {-80.072f, 1295.775f, 48.60f} // waypoint 4 -}; - enum Talks { SAY_WAVE1 = 0, @@ -74,399 +61,300 @@ enum Talks SAY_KILL_TWO, SAY_DEATH, SAY_NALORAKK_EVENT1, // Not implemented - SAY_NALORAKK_EVENT2 // Not implemented + SAY_NALORAKK_EVENT2, // Not implemented + SAY_RUN_AWAY, + EMOTE_BEAR }; -class boss_nalorakk : public CreatureScript +enum Phases { -public: - boss_nalorakk() - : CreatureScript("boss_nalorakk") + PHASE_SEND_GUARDS_1 = 0, + PHASE_SEND_GUARDS_2 = 1, + PHASE_SEND_GUARDS_3 = 2, + PHASE_SEND_GUARDS_4 = 3, + PHASE_SEND_GUARDS_5 = 4, + PHASE_START_COMBAT = 5 +}; + +enum NalorakkGroups +{ + GROUP_CHECK_DEAD = 1, + GROUP_MOVE = 2, + GROUP_BERSERK = 3, + GROUP_HUMAN = 4, + GROUP_BEAR = 5 +}; + +struct boss_nalorakk : public BossAI +{ + boss_nalorakk(Creature* creature) : BossAI(creature, DATA_NALORAKKEVENT) { + _ranIntro = false; + _active = true; + creature->SetReactState(REACT_PASSIVE); + me->SetImmuneToAll(true); } - struct boss_nalorakkAI : public ScriptedAI + void Reset() override { - boss_nalorakkAI(Creature* creature) : ScriptedAI(creature) + BossAI::Reset(); + _waveList.clear(); + _introScheduler.CancelAll(); + if (_bearForm) { - MoveEvent = true; - MovePhase = 0; - instance = creature->GetInstanceScript(); + me->RemoveAurasDueToSpell(SPELL_BEARFORM); + _bearForm = false; } - - InstanceScript* instance; - - uint32 BrutalSwipe_Timer; - uint32 Mangle_Timer; - uint32 Surge_Timer; - - uint32 LaceratingSlash_Timer; - uint32 RendFlesh_Timer; - uint32 DeafeningRoar_Timer; - - uint32 ShapeShift_Timer; - uint32 Berserk_Timer; - - bool inBearForm; - bool MoveEvent; - bool inMove; - uint32 MovePhase; - uint32 waitTimer; - - void Reset() override + if (_ranIntro) { - if (MoveEvent) - { - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - inMove = false; - waitTimer = 0; - me->SetSpeed(MOVE_RUN, 2); - me->SetWalk(false); - ResetMobs(); - } - else - { - (*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]); - } + _phase = PHASE_START_COMBAT; + me->SetReactState(REACT_AGGRESSIVE); + _active = false; - if (instance) - { - instance->SetData(DATA_NALORAKKEVENT, NOT_STARTED); - } - - Surge_Timer = urand(15000, 20000); - BrutalSwipe_Timer = urand(7000, 12000); - Mangle_Timer = urand(10000, 15000); - ShapeShift_Timer = urand(45000, 50000); - Berserk_Timer = 600000; - - inBearForm = false; - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id } + } - void ResetMobs() + void MoveInLineOfSight(Unit* who) override + { + if (who->IsPlayer() && _phase < PHASE_START_COMBAT && _active) { - std::list templist; - float x, y, z; - me->GetPosition(x, y, z); - + _active = false; + switch (_phase) { - CellCoord pair(Acore::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Acore::AllFriendlyCreaturesInGrid check(me); - Acore::CreatureListSearcher searcher(me, templist, check); - - TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange()); - } - - if (templist.empty()) - return; - - for (std::list::const_iterator i = templist.begin(); i != templist.end(); ++i) - if ((*i) && me->GetGUID() != (*i)->GetGUID() && me->IsWithinDistInMap((*i), 25)) - (*i)->AI()->Reset(); - } - - void SendAttacker(Unit* target) - { - std::list templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Acore::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Acore::AllFriendlyCreaturesInGrid check(me); - Acore::CreatureListSearcher searcher(me, templist, check); - - TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange()); - } - - if (templist.empty()) - return; - - for (std::list::const_iterator i = templist.begin(); i != templist.end(); ++i) - { - if ((*i) && me->IsWithinDistInMap((*i), 25)) - { - (*i)->SetNoCallAssistance(true); - (*i)->AI()->AttackStart(target); - } - } - } - - void AttackStart(Unit* who) override - { - if (!MoveEvent) - ScriptedAI::AttackStart(who); - } - - void MoveInLineOfSight(Unit* who) override - - { - if (!MoveEvent) - { - ScriptedAI::MoveInLineOfSight(who); - } - else - { - if (me->IsHostileTo(who)) - { - if (!inMove) + case PHASE_SEND_GUARDS_1: + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_AXE_THROWER); + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_TRIBESMAN); + GroupedAttack(_waveList); + Talk(SAY_WAVE1); + _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context) { - switch (MovePhase) + if (CheckFullyDeadGroup(_waveList)) { - case 0: - if (me->IsWithinDistInMap(who, 50)) + if (_phase == PHASE_SEND_GUARDS_1) + { + _introScheduler.CancelGroup(GROUP_CHECK_DEAD); + _waveList.clear(); + me->GetMotionMaster()->MovePath(me->GetEntry()*100+1, false); + Talk(SAY_RUN_AWAY); + _introScheduler.Schedule(5s, [this](TaskContext) { - Talk(SAY_WAVE1); - - (*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 2: - if (me->IsWithinDistInMap(who, 40)) - { - Talk(SAY_WAVE2); - - (*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 5: - if (me->IsWithinDistInMap(who, 40)) - { - Talk(SAY_WAVE3); - - (*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 7: - if (me->IsWithinDistInMap(who, 50)) - { - SendAttacker(who); - - Talk(SAY_WAVE4); - - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - - MoveEvent = false; - } - break; + me->SetFacingTo(6.25f); + _active = true; + }); + _phase = PHASE_SEND_GUARDS_2; + } } - } - } - } - } - - void JustEngagedWith(Unit* /*who*/) override - { - if (instance) - instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS); - - Talk(SAY_AGGRO); - DoZoneInCombat(); - } - - void JustDied(Unit* /*killer*/) override - { - ResetMobs(); - - if (instance) - instance->SetData(DATA_NALORAKKEVENT, DONE); - - Talk(SAY_DEATH); - } - - void KilledUnit(Unit* /*victim*/) override - { - switch (urand(0, 1)) - { - case 0: - Talk(SAY_KILL_ONE); + context.Repeat(5s); + }); break; - case 1: - Talk(SAY_KILL_TWO); - break; - } - } - - void MovementInform(uint32 type, uint32 id) override - { - if (MoveEvent) - { - if (type != POINT_MOTION_TYPE) - return; - - if (!inMove) - return; - - if (MovePhase != id) - return; - - switch (MovePhase) - { - case 2: - me->SetOrientation(3.1415f * 2); - inMove = false; - return; - case 1: - case 3: - case 4: - case 6: - MovePhase ++; - waitTimer = 1; - inMove = true; - return; - case 5: - me->SetOrientation(3.1415f * 0.5f); - inMove = false; - return; - case 7: - me->SetOrientation(3.1415f * 0.5f); - inMove = false; - return; - } - } - } - - void UpdateAI(uint32 diff) override - { - if (waitTimer && inMove) - { - if (waitTimer <= diff) - { - (*me).GetMotionMaster()->MovementExpired(); - (*me).GetMotionMaster()->MovePoint(MovePhase, NalorakkWay[MovePhase][0], NalorakkWay[MovePhase][1], NalorakkWay[MovePhase][2]); - waitTimer = 0; - } - else waitTimer -= diff; - } - - if (!UpdateVictim()) - return; - - if (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - Talk(SAY_BERSERK); - Berserk_Timer = 600000; - } - else Berserk_Timer -= diff; - - if (ShapeShift_Timer <= diff) - { - if (inBearForm) - { - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); - Talk(SAY_SHIFTEDTOTROLL); - me->RemoveAurasDueToSpell(SPELL_BEARFORM); - Surge_Timer = urand(15000, 20000); - BrutalSwipe_Timer = urand(7000, 12000); - Mangle_Timer = urand(10000, 15000); - ShapeShift_Timer = urand(45000, 50000); - inBearForm = false; - } - else - { - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0); - Talk(SAY_SHIFTEDTOBEAR); - DoCast(me, SPELL_BEARFORM, true); - LaceratingSlash_Timer = 2000; // dur 18s - RendFlesh_Timer = 3000; // dur 5s - DeafeningRoar_Timer = urand(5000, 10000); // dur 2s - ShapeShift_Timer = urand(20000, 25000); // dur 30s - inBearForm = true; - } - } - else ShapeShift_Timer -= diff; - - if (!inBearForm) - { - if (BrutalSwipe_Timer <= diff) - { - DoCastVictim(SPELL_BRUTALSWIPE); - BrutalSwipe_Timer = urand(7000, 12000); - } - else BrutalSwipe_Timer -= diff; - - if (Mangle_Timer <= diff) - { - if (me->GetVictim() && !me->GetVictim()->HasAura(SPELL_MANGLEEFFECT)) + case PHASE_SEND_GUARDS_2: + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_AXE_THROWER); + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_TRIBESMAN); + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_MEDICINE_MAN); + GroupedAttack(_waveList); + Talk(SAY_WAVE2); + _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context) { - DoCastVictim(SPELL_MANGLE); - Mangle_Timer = 1000; - } - else Mangle_Timer = urand(10000, 15000); - } - else Mangle_Timer -= diff; + if (CheckFullyDeadGroup(_waveList)) + { + if (_phase == PHASE_SEND_GUARDS_2) + { + _introScheduler.CancelGroup(GROUP_CHECK_DEAD); + _waveList.clear(); + Talk(SAY_RUN_AWAY); + me->GetMotionMaster()->MovePath(me->GetEntry()*100+2, false); + _introScheduler.Schedule(6s, [this](TaskContext) + { + me->SetFacingTo(1.54f); + _active = true; + }); + _phase = PHASE_SEND_GUARDS_3; + } - if (Surge_Timer <= diff) - { - Talk(SAY_SURGE); - Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 45, true); - if (target) - DoCast(target, SPELL_SURGE); - Surge_Timer = urand(15000, 20000); - } - else Surge_Timer -= diff; + } + context.Repeat(5s); + }); + break; + case PHASE_SEND_GUARDS_3: + me->GetCreaturesWithEntryInRange(_waveList, 10.0f, NPC_AMANISHI_WARBRINGER); + GroupedAttack(_waveList); + Talk(SAY_WAVE3); + _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context) + { + if (CheckFullyDeadGroup(_waveList)) + { + if (_phase == PHASE_SEND_GUARDS_3) + { + _introScheduler.CancelGroup(GROUP_CHECK_DEAD); + _waveList.clear(); + Talk(SAY_RUN_AWAY); + me->GetMotionMaster()->MovePath(me->GetEntry()*100+3, false); + _introScheduler.Schedule(6s, [this](TaskContext) + { + me->SetFacingTo(1.54f); + _active = true; + }); + _phase = PHASE_SEND_GUARDS_4; + } + } + context.Repeat(5s); + }); + break; + case PHASE_SEND_GUARDS_4: + me->GetCreaturesWithEntryInRange(_waveList, 25.0f, NPC_AMANISHI_WARBRINGER); + me->GetCreaturesWithEntryInRange(_waveList, 25.0f, NPC_AMANISHI_MEDICINE_MAN); + GroupedAttack(_waveList); + Talk(SAY_WAVE4); + _introScheduler.Schedule(5s, GROUP_CHECK_DEAD, [this](TaskContext context) + { + if (CheckFullyDeadGroup(_waveList)) + { + if (_phase == PHASE_SEND_GUARDS_4) + { + _introScheduler.CancelGroup(GROUP_CHECK_DEAD); + me->SetHomePosition(me->GetPosition()); + me->SetImmuneToAll(false); + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + _waveList.clear(); + _phase = PHASE_START_COMBAT; + _ranIntro = true; + } + } + context.Repeat(5s); + }); + break; + } + } + BossAI::MoveInLineOfSight(who); + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + scheduler.Schedule(15s, 20s, GROUP_HUMAN, [this](TaskContext context) + { + Talk(SAY_SURGE); + DoCastRandomTarget(SPELL_SURGE, 0, 45.0f, false, false, false); + context.Repeat(); + }).Schedule(7s, 12s, GROUP_HUMAN, [this](TaskContext context) + { + DoCastVictim(SPELL_BRUTALSWIPE); + context.Repeat(); + }).Schedule(10s, 15s, GROUP_HUMAN, [this](TaskContext context) + { + if (!me->GetVictim()->HasAura(SPELL_MANGLEEFFECT)) + { + DoCastVictim(SPELL_MANGLE); + context.Repeat(1s); } else { - if (LaceratingSlash_Timer <= diff) - { - DoCastVictim(SPELL_LACERATINGSLASH); - LaceratingSlash_Timer = urand(18000, 23000); - } - else LaceratingSlash_Timer -= diff; - - if (RendFlesh_Timer <= diff) - { - DoCastVictim(SPELL_RENDFLESH); - RendFlesh_Timer = urand(5000, 10000); - } - else RendFlesh_Timer -= diff; - - if (DeafeningRoar_Timer <= diff) - { - DoCastVictim(SPELL_DEAFENINGROAR); - DeafeningRoar_Timer = urand(15000, 20000); - } - else DeafeningRoar_Timer -= diff; + context.Repeat(); } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulAmanAI(creature); + }).Schedule(10min, GROUP_BERSERK, [this](TaskContext) + { + Talk(SAY_BERSERK); + DoCastSelf(SPELL_BERSERK, true); + }).Schedule(45s, 50s, GROUP_HUMAN, [this](TaskContext) + { + ShapeShift(_bearForm); + }); } + + void ShapeShift(bool currentlyInBearForm) + { + if (currentlyInBearForm) + { + Talk(SAY_SHIFTEDTOTROLL); + me->RemoveAurasDueToSpell(SPELL_BEARFORM); + scheduler.CancelGroup(GROUP_BEAR); + _bearForm = false; + scheduler.Schedule(15s, 20s, GROUP_HUMAN, [this](TaskContext context) + { + Talk(SAY_SURGE); + DoCastRandomTarget(SPELL_SURGE, 0, 45.0f, false, false, false); + context.Repeat(); + }).Schedule(7s, 12s, GROUP_HUMAN, [this](TaskContext context) + { + DoCastVictim(SPELL_BRUTALSWIPE); + context.Repeat(); + }).Schedule(10s, 15s, GROUP_HUMAN, [this](TaskContext context) + { + DoCastVictim(SPELL_MANGLE); + context.Repeat(); + }).Schedule(10min, GROUP_BERSERK, [this](TaskContext) + { + Talk(SAY_BERSERK); + DoCastSelf(SPELL_BERSERK, true); + }).Schedule(45s, 50s, GROUP_HUMAN, [this](TaskContext) + { + ShapeShift(_bearForm); + }); + } + else + { + Talk(SAY_SHIFTEDTOBEAR); + Talk(EMOTE_BEAR); + DoCastSelf(SPELL_BEARFORM, true); + scheduler.CancelGroup(GROUP_HUMAN); + _bearForm = true; + scheduler.Schedule(2s, GROUP_BEAR, [this](TaskContext context) + { + DoCastVictim(SPELL_LACERATINGSLASH); + context.Repeat(18s, 23s); + }).Schedule(3s, GROUP_BEAR, [this](TaskContext context) + { + DoCastVictim(SPELL_RENDFLESH); + context.Repeat(5s, 10s); + }).Schedule(5s, 10s, GROUP_BEAR, [this](TaskContext context) + { + DoCastSelf(SPELL_DEAFENINGROAR); + context.Repeat(15s, 20s); + }).Schedule(25s, 30s, GROUP_BEAR, [this](TaskContext context) + { + ShapeShift(_bearForm); + context.Repeat(); + }); + } + } + + void GroupedAttack(std::list attackerList) + { + for (Creature* attacker : attackerList) + { + attacker->SetInCombatWithZone(); + } + } + + void UpdateAI(uint32 diff) override + { + _introScheduler.Update(diff); + BossAI::UpdateAI(diff); + } + + bool CheckFullyDeadGroup(std::list groupToCheck) + { + for (Creature* member : groupToCheck) + { + if (member->IsAlive()) + { + return false; + } + } + return true; + } +private: + uint8 _phase; + bool _ranIntro; + bool _active; + bool _bearForm; + TaskScheduler _introScheduler; + std::list _waveList; }; void AddSC_boss_nalorakk() { - new boss_nalorakk(); + RegisterZulAmanCreatureAI(boss_nalorakk); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index baa83f557..ffb1b771b 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -57,8 +57,8 @@ Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f}; ObjectData const creatureData[] = { - { NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX }, - { 0, 0 } + { NPC_SPIRIT_LYNX, DATA_SPIRIT_LYNX }, + { 0, 0 } }; ObjectData const gameObjectData[] = diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index 4ca81145b..caf94bfc2 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -46,7 +46,11 @@ enum CreatureIds NPC_HEXLORD = 24239, NPC_HALAZZI = 23577, NPC_NALORAKK = 23576, - NPC_SPIRIT_LYNX = 24143 + NPC_SPIRIT_LYNX = 24143, + NPC_AMANISHI_WARBRINGER = 23580, + NPC_AMANISHI_TRIBESMAN = 23582, + NPC_AMANISHI_MEDICINE_MAN = 23581, + NPC_AMANISHI_AXE_THROWER = 23542 }; enum GameobjectIds