diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7dfe6de007a..56ea65e5d7a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -81,4 +81,4 @@ include(cmake/showoptions.cmake)
add_subdirectory(dep)
# add core sources
-add_subdirectory(src)
\ No newline at end of file
+add_subdirectory(src)
diff --git a/PreLoad.cmake b/PreLoad.cmake
index e624104dab9..f7cf5a1ebe6 100644
--- a/PreLoad.cmake
+++ b/PreLoad.cmake
@@ -20,4 +20,4 @@
# set(CMAKE_INSTALL_PREFIX
# "" CACHE PATH "Default install path")
# endif()
-#endif()
\ No newline at end of file
+#endif()
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 62e2c6220ac..9c2fa9861d0 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2015 TrinityCore
+* Copyright (C) 2008-2015 TrinityCore
* Copyright (C) 2005-2009 MaNGOS
*
* This program is free software; you can redistribute it and/or modify it
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 166afec6b39..e36196c742a 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (C) 2008-2015 TrinityCore
+ * Copyright (C) 2008-2015 TrinityCore
*
* 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
@@ -47,17 +47,17 @@ public:
static ChatCommand mmapCommandTable[] =
{
{ "loadedtiles", rbac::RBAC_PERM_COMMAND_MMAP_LOADEDTILES, false, &HandleMmapLoadedTilesCommand, "", NULL },
- { "loc", rbac::RBAC_PERM_COMMAND_MMAP_LOC, false, &HandleMmapLocCommand, "", NULL },
- { "path", rbac::RBAC_PERM_COMMAND_MMAP_PATH, false, &HandleMmapPathCommand, "", NULL },
- { "stats", rbac::RBAC_PERM_COMMAND_MMAP_STATS, false, &HandleMmapStatsCommand, "", NULL },
- { "testarea", rbac::RBAC_PERM_COMMAND_MMAP_TESTAREA, false, &HandleMmapTestArea, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "loc", rbac::RBAC_PERM_COMMAND_MMAP_LOC, false, &HandleMmapLocCommand, "", NULL },
+ { "path", rbac::RBAC_PERM_COMMAND_MMAP_PATH, false, &HandleMmapPathCommand, "", NULL },
+ { "stats", rbac::RBAC_PERM_COMMAND_MMAP_STATS, false, &HandleMmapStatsCommand, "", NULL },
+ { "testarea", rbac::RBAC_PERM_COMMAND_MMAP_TESTAREA, false, &HandleMmapTestArea, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
- { "mmap", rbac::RBAC_PERM_COMMAND_MMAP, true, NULL, "", mmapCommandTable },
- { NULL, 0, false, NULL, "", NULL }
+ { "mmap", rbac::RBAC_PERM_COMMAND_MMAP, true, NULL, "", mmapCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
index b4ef9f34c64..4dcb41f533b 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
@@ -15,19 +15,67 @@
* with this program. If not, see .
*/
+/* ScriptData
+SDName: boss_Akilzon
+SD%Complete: 75%
+SDComment: Missing timer for Call Lightning and Sound ID's
+SQLUpdate:
+#Temporary fix for Soaring Eagles
+
+EndScriptData */
+
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "Cell.h"
+#include "CellImpl.h"
#include "zulaman.h"
+#include "Weather.h"
+
+enum Spells
+{
+ SPELL_STATIC_DISRUPTION = 43622,
+ SPELL_STATIC_VISUAL = 45265,
+ SPELL_CALL_LIGHTNING = 43661, // Missing timer
+ SPELL_GUST_OF_WIND = 43621,
+ SPELL_ELECTRICAL_STORM = 43648,
+ SPELL_BERSERK = 45078,
+ SPELL_ELECTRICAL_OVERLOAD = 43658,
+ SPELL_EAGLE_SWOOP = 44732,
+ SPELL_ZAP = 43137,
+ SPELL_SAND_STORM = 25160
+};
enum Says
{
- SAY_AGGRO = 0,
- SAY_PLAYER_KILL = 1,
- EMOTE_ELECTRICAL_STORM = 2,
- SAY_SUMMON_EAGLE = 3,
- SAY_SUMMON_BIRDS = 4,
- SAY_BERSERK = 5,
- SAY_DEATH = 6
+ SAY_AGGRO = 0,
+ SAY_SUMMON = 1,
+ SAY_INTRO = 2, // Not used in script
+ SAY_ENRAGE = 3,
+ SAY_KILL = 4,
+ SAY_DEATH = 5
+};
+
+enum Misc
+{
+ NPC_SOARING_EAGLE = 24858,
+ SE_LOC_X_MAX = 400,
+ SE_LOC_X_MIN = 335,
+ SE_LOC_Y_MAX = 1435,
+ SE_LOC_Y_MIN = 1370
+};
+
+enum Events
+{
+ EVENT_STATIC_DISRUPTION = 1,
+ EVENT_GUST_OF_WIND = 2,
+ EVENT_CALL_LIGHTNING = 3,
+ EVENT_ELECTRICAL_STORM = 4,
+ EVENT_RAIN = 5,
+ EVENT_SUMMON_EAGLES = 6,
+ EVENT_STORM_SEQUENCE = 7,
+ EVENT_ENRAGE = 8
};
class boss_akilzon : public CreatureScript
@@ -37,17 +85,45 @@ class boss_akilzon : public CreatureScript
struct boss_akilzonAI : public BossAI
{
- boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON) { }
+ boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZONEVENT)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ TargetGUID.Clear();
+ CloudGUID.Clear();
+ CycloneGUID.Clear();
+ for (ObjectGuid& guid : BirdGUIDs)
+ guid.Clear();
+
+ StormCount = 0;
+ isRaining = false;
+ }
void Reset() override
{
_Reset();
+
+ Initialize();
+
+ SetWeather(WEATHER_STATE_FINE, 0.0f);
}
void EnterCombat(Unit* /*who*/) override
{
+ events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 20000)); // 10 to 20 seconds (bosskillers)
+ events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000)); // 20 to 30 seconds(bosskillers)
+ events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(10000, 20000)); // totaly random timer. can't find any info on this
+ events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers)
+ events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000));
+ events.ScheduleEvent(EVENT_ENRAGE, 10*MINUTE*IN_MILLISECONDS); // 10 minutes till enrage(bosskillers)
+
Talk(SAY_AGGRO);
_EnterCombat();
+ //DoZoneInCombat();
+ instance->SetData(DATA_AKILZONEVENT, IN_PROGRESS);
}
void JustDied(Unit* /*killer*/) override
@@ -60,6 +136,91 @@ class boss_akilzon : public CreatureScript
{
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_PLAYER_KILL);
+ Talk(SAY_KILL);
+ }
+
+ void SetWeather(uint32 weather, float grade)
+ {
+ Map* map = me->GetMap();
+ if (!map->IsDungeon())
+ return;
+
+ WorldPacket data(SMSG_WEATHER, (4+4+4));
+ data << uint32(weather) << float(grade) << uint8(0);
+
+ map->SendToPlayers(&data);
+ }
+
+ void HandleStormSequence(Unit* Cloud) // 1: begin, 2-9: tick, 10: end
+ {
+ if (StormCount < 10 && StormCount > 1)
+ {
+ // deal damage
+ int32 bp0 = 800;
+ for (uint8 i = 2; i < StormCount; ++i)
+ bp0 *= 2;
+
+ CellCoord p(Trinity::ComputeCellCoord(me->GetPositionX(), me->GetPositionY()));
+ Cell cell(p);
+ cell.SetNoCreate();
+
+ std::list tempUnitMap;
+
+ {
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(me, me, SIZE_OF_GRIDS);
+ Trinity::UnitListSearcher searcher(me, tempUnitMap, u_check);
+
+ TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher);
+ TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher);
+
+ cell.Visit(p, world_unit_searcher, *me->GetMap(), *me, SIZE_OF_GRIDS);
+ cell.Visit(p, grid_unit_searcher, *me->GetMap(), *me, SIZE_OF_GRIDS);
+ }
+
+ // deal damage
+ for (std::list::const_iterator i = tempUnitMap.begin(); i != tempUnitMap.end(); ++i)
+ {
+ if (Unit* target = (*i))
+ {
+ if (Cloud && !Cloud->IsWithinDist(target, 6, false))
+ Cloud->CastCustomSpell(target, SPELL_ZAP, &bp0, NULL, NULL, true, 0, 0, me->GetGUID());
+ }
+ }
+
+ // visual
+ float x, y, z;
+ z = me->GetPositionZ();
+ uint8 maxCount = 5 + rand32() % 5;
+ for (uint8 i = 0; i < maxCount; ++i)
+ {
+ x = 343.0f + rand32() % 60;
+ y = 1380.0f + rand32() % 60;
+ if (Unit* trigger = me->SummonTrigger(x, y, z, 0, 2000))
+ {
+ trigger->setFaction(35);
+ trigger->SetMaxHealth(100000);
+ trigger->SetHealth(100000);
+ trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ if (Cloud)
+ Cloud->CastCustomSpell(trigger, /*43661*/SPELL_ZAP, &bp0, NULL, NULL, true, 0, 0, Cloud->GetGUID());
+ }
+ }
+ }
+
+ ++StormCount;
+
+ if (StormCount > 10)
+ {
+ StormCount = 0; // finish
+ events.ScheduleEvent(EVENT_SUMMON_EAGLES, 5000);
+ me->InterruptNonMeleeSpells(false);
+ CloudGUID.Clear();
+ if (Cloud)
+ Cloud->DealDamage(Cloud, Cloud->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ SetWeather(WEATHER_STATE_FINE, 0.0f);
+ isRaining = false;
+ }
+ events.ScheduleEvent(EVENT_STORM_SEQUENCE, 1000);
}
void UpdateAI(uint32 diff) override
@@ -69,21 +230,149 @@ class boss_akilzon : public CreatureScript
events.Update(diff);
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- /*
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
+ case EVENT_STATIC_DISRUPTION:
+ {
+ Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
+ if (!target)
+ target = me->GetVictim();
+ if (target)
+ {
+ TargetGUID = target->GetGUID();
+ DoCast(target, SPELL_STATIC_DISRUPTION, false);
+ me->SetInFront(me->GetVictim());
+ }
+ /*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f;
+ SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f);*/
+ events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 18000));
+ break;
+ }
+ case EVENT_GUST_OF_WIND:
+ {
+ Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
+ if (!target)
+ target = me->GetVictim();
+ if (target)
+ DoCast(target, SPELL_GUST_OF_WIND);
+ events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000));
+ break;
+ }
+ case EVENT_CALL_LIGHTNING:
+ DoCastVictim(SPELL_CALL_LIGHTNING);
+ events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(12000, 17000)); // totaly random timer. can't find any info on this
+ break;
+ case EVENT_ELECTRICAL_STORM:
+ {
+ Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true);
+ if (!target)
+ {
+ EnterEvadeMode();
+ return;
+ }
+ target->CastSpell(target, 44007, true); // cloud visual
+ DoCast(target, SPELL_ELECTRICAL_STORM, false); // storm cyclon + visual
+ float x, y, z;
+ target->GetPosition(x, y, z);
+ /// @todo: fix it in correct way, that causes player to can fly until logout
+ /*
+ if (target)
+ {
+ target->SetDisableGravity(true);
+ target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0);
+ }
+ */
+
+ Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000);
+ if (Cloud)
+ {
+ CloudGUID = Cloud->GetGUID();
+ Cloud->SetDisableGravity(true);
+ Cloud->StopMoving();
+ Cloud->SetObjectScale(1.0f);
+ Cloud->setFaction(35);
+ Cloud->SetMaxHealth(9999999);
+ Cloud->SetHealth(9999999);
+ Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+ StormCount = 1;
+ events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers)
+ events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000));
+ break;
+ }
+ case EVENT_RAIN:
+ if (!isRaining)
+ {
+ SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f);
+ isRaining = true;
+ }
+ else
+ events.ScheduleEvent(EVENT_RAIN, 1000);
+ break;
+ case EVENT_STORM_SEQUENCE:
+ {
+ Unit* target = ObjectAccessor::GetUnit(*me, CloudGUID);
+ if (!target || !target->IsAlive())
+ {
+ EnterEvadeMode();
+ return;
+ }
+ else if (Unit* Cyclone = ObjectAccessor::GetUnit(*me, CycloneGUID))
+ Cyclone->CastSpell(target, SPELL_SAND_STORM, true); // keep casting or...
+ HandleStormSequence(target);
+ break;
+ }
+ case EVENT_SUMMON_EAGLES:
+ Talk(SAY_SUMMON);
+
+ float x, y, z;
+ me->GetPosition(x, y, z);
+
+ for (uint8 i = 0; i < 8; ++i)
+ {
+ Unit* bird = ObjectAccessor::GetUnit(*me, BirdGUIDs[i]);
+ if (!bird) //they despawned on die
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ {
+ x = target->GetPositionX() + irand(-10, 10);
+ y = target->GetPositionY() + irand(-10, 10);
+ z = target->GetPositionZ() + urand(16, 20);
+ if (z > 95)
+ z = 95.0f - urand(0, 5);
+ }
+ Creature* creature = me->SummonCreature(NPC_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ if (creature)
+ {
+ creature->AddThreat(me->GetVictim(), 1.0f);
+ creature->AI()->AttackStart(me->GetVictim());
+ BirdGUIDs[i] = creature->GetGUID();
+ }
+ }
+ }
+ break;
+ case EVENT_ENRAGE:
+ Talk(SAY_ENRAGE);
+ DoCast(me, SPELL_BERSERK, true);
+ events.ScheduleEvent(EVENT_ENRAGE, 600000);
+ break;
default:
break;
}
}
- */
DoMeleeAttackIfReady();
}
+
+ private:
+ ObjectGuid BirdGUIDs[8];
+ ObjectGuid TargetGUID;
+ ObjectGuid CycloneGUID;
+ ObjectGuid CloudGUID;
+ uint8 StormCount;
+ bool isRaining;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -92,7 +381,99 @@ class boss_akilzon : public CreatureScript
}
};
+class npc_akilzon_eagle : public CreatureScript
+{
+ public:
+ npc_akilzon_eagle() : CreatureScript("npc_akilzon_eagle") { }
+
+ struct npc_akilzon_eagleAI : public ScriptedAI
+ {
+ npc_akilzon_eagleAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ EagleSwoop_Timer = urand(5000, 10000);
+ arrived = true;
+ TargetGUID.Clear();
+ }
+
+ uint32 EagleSwoop_Timer;
+ bool arrived;
+ ObjectGuid TargetGUID;
+
+ void Reset() override
+ {
+ Initialize();
+ me->SetDisableGravity(true);
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ DoZoneInCombat();
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) override { }
+
+
+ void MovementInform(uint32, uint32) override
+ {
+ arrived = true;
+ if (TargetGUID)
+ {
+ if (Unit* target = ObjectAccessor::GetUnit(*me, TargetGUID))
+ DoCast(target, SPELL_EAGLE_SWOOP, true);
+ TargetGUID.Clear();
+ me->SetSpeed(MOVE_RUN, 1.2f);
+ EagleSwoop_Timer = urand(5000, 10000);
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (EagleSwoop_Timer <= diff)
+ EagleSwoop_Timer = 0;
+ else
+ EagleSwoop_Timer -= diff;
+
+ if (arrived)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ {
+ float x, y, z;
+ if (EagleSwoop_Timer)
+ {
+ x = target->GetPositionX() + irand(-10, 10);
+ y = target->GetPositionY() + irand(-10, 10);
+ z = target->GetPositionZ() + urand(10, 15);
+ if (z > 95)
+ z = 95.0f - urand(0, 5);
+ }
+ else
+ {
+ target->GetContactPoint(me, x, y, z);
+ z += 2;
+ me->SetSpeed(MOVE_RUN, 5.0f);
+ TargetGUID = target->GetGUID();
+ }
+ me->GetMotionMaster()->MovePoint(0, x, y, z);
+ arrived = false;
+ }
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_akilzon_eagleAI(creature);
+ }
+};
+
void AddSC_boss_akilzon()
{
new boss_akilzon();
+ new npc_akilzon_eagle();
}
+
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp
index dcef6dc6166..2317582af99 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008-2015 TrinityCore
+ * Copyright (C) 2006-2009 ScriptDev2
*
* 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
@@ -18,56 +19,187 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulaman.h"
-
-enum Says
-{
- SAY_AGGRO = 0,
- SAY_PLAYER_KILL = 1,
- SAY_MELEE = 2,
- SAY_SPLIT = 3,
- SAY_COMBINE = 4,
- SAY_DEATH = 5
-};
+#include "SpellInfo.h"
enum Spells
{
+ SPELL_DUAL_WIELD = 29651,
+ SPELL_SABER_LASH = 43267,
+ SPELL_FRENZY = 43139,
+ SPELL_FLAMESHOCK = 43303,
+ SPELL_EARTHSHOCK = 43305,
+ SPELL_TRANSFORM_SPLIT = 43142,
+ SPELL_TRANSFORM_SPLIT2 = 43573,
+ SPELL_TRANSFORM_MERGE = 43271,
+ SPELL_SUMMON_LYNX = 43143,
+ SPELL_SUMMON_TOTEM = 43302,
+ SPELL_BERSERK = 45078,
+ SPELL_LYNX_FRENZY = 43290, // Used by Spirit Lynx
+ SPELL_SHRED_ARMOR = 43243 // Used by Spirit Lynx
};
-enum Events
+enum Hal_CreatureIds
{
+ NPC_SPIRIT_LYNX = 24143,
+ NPC_TOTEM = 24224
+};
+
+enum PhaseHalazzi
+{
+ PHASE_NONE = 0,
+ PHASE_LYNX = 1,
+ PHASE_SPLIT = 2,
+ PHASE_HUMAN = 3,
+ PHASE_MERGE = 4,
+ PHASE_ENRAGE = 5
+};
+
+enum Yells
+{
+ SAY_AGGRO = 0,
+ SAY_SABER = 1,
+ SAY_SPLIT = 2,
+ SAY_MERGE = 3,
+ SAY_KILL = 4,
+ SAY_DEATH = 5,
+ SAY_BERSERK = 6
};
class boss_halazzi : public CreatureScript
{
public:
-
boss_halazzi() : CreatureScript("boss_halazzi") { }
- struct boss_halazziAI : public BossAI
+ struct boss_halazziAI : public ScriptedAI
{
- boss_halazziAI(Creature* creature) : BossAI(creature, DATA_HALAZZI) { }
+ boss_halazziAI(Creature* creature) : ScriptedAI(creature), summons(me)
+ {
+ Initialize();
+ instance = creature->GetInstanceScript();
+ Phase = PHASE_NONE;
+ FrenzyTimer = 0;
+ SaberlashTimer = 0;
+ ShockTimer = 0;
+ TotemTimer = 0;
+ }
+
+ void Initialize()
+ {
+ LynxGUID.Clear();
+ TransformCount = 0;
+ BerserkTimer = 600000;
+ CheckTimer = 1000;
+ }
+
+ InstanceScript* instance;
+ SummonList summons;
+ PhaseHalazzi Phase;
+
+ uint32 FrenzyTimer;
+ uint32 SaberlashTimer;
+ uint32 ShockTimer;
+ uint32 TotemTimer;
+ uint32 CheckTimer;
+ uint32 BerserkTimer;
+ uint32 TransformCount;
+
+ ObjectGuid LynxGUID;
void Reset() override
{
- _Reset();
+ instance->SetData(DATA_HALAZZIEVENT, NOT_STARTED);
+ summons.DespawnAll();
+
+ Initialize();
+
+ DoCast(me, SPELL_DUAL_WIELD, true);
+
+ Phase = PHASE_NONE;
+ EnterPhase(PHASE_LYNX);
}
void EnterCombat(Unit* /*who*/) override
{
+ instance->SetData(DATA_HALAZZIEVENT, IN_PROGRESS);
Talk(SAY_AGGRO);
- _EnterCombat();
+ EnterPhase(PHASE_LYNX);
}
- void JustDied(Unit* /*killer*/) override
+ void JustSummoned(Creature* summon) override
{
- Talk(SAY_DEATH);
- _JustDied();
+ summon->AI()->AttackStart(me->GetVictim());
+ if (summon->GetEntry() == NPC_SPIRIT_LYNX)
+ LynxGUID = summon->GetGUID();
+ summons.Summon(summon);
}
- void KilledUnit(Unit* victim) override
+ void DamageTaken(Unit* /*done_by*/, uint32 &damage) override
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_PLAYER_KILL);
+ if (damage >= me->GetHealth() && Phase != PHASE_ENRAGE)
+ damage = 0;
+ }
+
+ void SpellHit(Unit*, const SpellInfo* spell) override
+ {
+ if (spell->Id == SPELL_TRANSFORM_SPLIT2)
+ EnterPhase(PHASE_HUMAN);
+ }
+
+ void AttackStart(Unit* who) override
+ {
+ if (Phase != PHASE_MERGE)
+ ScriptedAI::AttackStart(who);
+ }
+
+ void EnterPhase(PhaseHalazzi NextPhase)
+ {
+ switch (NextPhase)
+ {
+ case PHASE_LYNX:
+ case PHASE_ENRAGE:
+ if (Phase == PHASE_MERGE)
+ {
+ DoCast(me, SPELL_TRANSFORM_MERGE, true);
+ me->Attack(me->GetVictim(), true);
+ me->GetMotionMaster()->MoveChase(me->GetVictim());
+ }
+ if (Creature* Lynx = ObjectAccessor::GetCreature(*me, LynxGUID))
+ Lynx->DisappearAndDie();
+ me->SetMaxHealth(600000);
+ me->SetHealth(600000 - 150000 * TransformCount);
+ FrenzyTimer = 16000;
+ SaberlashTimer = 20000;
+ ShockTimer = 10000;
+ TotemTimer = 12000;
+ break;
+ case PHASE_SPLIT:
+ Talk(SAY_SPLIT);
+ DoCast(me, SPELL_TRANSFORM_SPLIT, true);
+ break;
+ case PHASE_HUMAN:
+ //DoCast(me, SPELL_SUMMON_LYNX, true);
+ DoSpawnCreature(NPC_SPIRIT_LYNX, 5, 5, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ me->SetMaxHealth(400000);
+ me->SetHealth(400000);
+ ShockTimer = 10000;
+ TotemTimer = 12000;
+ break;
+ case PHASE_MERGE:
+ if (Unit* pLynx = ObjectAccessor::GetUnit(*me, LynxGUID))
+ {
+ Talk(SAY_MERGE);
+ pLynx->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pLynx->GetMotionMaster()->Clear();
+ pLynx->GetMotionMaster()->MoveFollow(me, 0, 0);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveFollow(pLynx, 0, 0);
+ ++TransformCount;
+ }
+ break;
+ default:
+ break;
+ }
+ Phase = NextPhase;
}
void UpdateAI(uint32 diff) override
@@ -75,32 +207,194 @@ class boss_halazzi : public CreatureScript
if (!UpdateVictim())
return;
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- /*
- while (uint32 eventId = events.ExecuteEvent())
+ if (BerserkTimer <= diff)
{
- switch (eventId)
+ Talk(SAY_BERSERK);
+ DoCast(me, SPELL_BERSERK, true);
+ BerserkTimer = 60000;
+ } else BerserkTimer -= diff;
+
+ if (Phase == PHASE_LYNX || Phase == PHASE_ENRAGE)
+ {
+ if (SaberlashTimer <= diff)
{
- default:
- break;
+ // A tank with more than 490 defense skills should receive no critical hit
+ //DoCast(me, 41296, true);
+ DoCastVictim(SPELL_SABER_LASH, true);
+ //me->RemoveAurasDueToSpell(41296);
+ SaberlashTimer = 30000;
+ } else SaberlashTimer -= diff;
+
+ if (FrenzyTimer <= diff)
+ {
+ DoCast(me, SPELL_FRENZY);
+ FrenzyTimer = urand(10000, 15000);
+ } else FrenzyTimer -= diff;
+
+ if (Phase == PHASE_LYNX)
+ {
+ if (CheckTimer <= diff)
+ {
+ if (HealthBelowPct(25 * (3 - TransformCount)))
+ EnterPhase(PHASE_SPLIT);
+ CheckTimer = 1000;
+ } else CheckTimer -= diff;
}
}
- */
+
+ if (Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE)
+ {
+ if (TotemTimer <= diff)
+ {
+ DoCast(me, SPELL_SUMMON_TOTEM);
+ TotemTimer = 20000;
+ } else TotemTimer -= diff;
+
+ if (ShockTimer <= diff)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ {
+ if (target->IsNonMeleeSpellCast(false))
+ DoCast(target, SPELL_EARTHSHOCK);
+ else
+ DoCast(target, SPELL_FLAMESHOCK);
+ ShockTimer = urand(10000, 15000);
+ }
+ } else ShockTimer -= diff;
+
+ if (Phase == PHASE_HUMAN)
+ {
+ if (CheckTimer <= diff)
+ {
+ if (!HealthAbovePct(20) /*HealthBelowPct(10)*/)
+ EnterPhase(PHASE_MERGE);
+ else
+ {
+ Unit* Lynx = ObjectAccessor::GetUnit(*me, LynxGUID);
+ if (Lynx && !Lynx->HealthAbovePct(20) /*Lynx->HealthBelowPct(10)*/)
+ EnterPhase(PHASE_MERGE);
+ }
+ CheckTimer = 1000;
+ } else CheckTimer -= diff;
+ }
+ }
+
+ if (Phase == PHASE_MERGE)
+ {
+ if (CheckTimer <= diff)
+ {
+ Unit* Lynx = ObjectAccessor::GetUnit(*me, LynxGUID);
+ if (Lynx)
+ {
+ Lynx->GetMotionMaster()->MoveFollow(me, 0, 0);
+ me->GetMotionMaster()->MoveFollow(Lynx, 0, 0);
+ if (me->IsWithinDistInMap(Lynx, 6.0f))
+ {
+ if (TransformCount < 3)
+ EnterPhase(PHASE_LYNX);
+ else
+ EnterPhase(PHASE_ENRAGE);
+ }
+ }
+ CheckTimer = 1000;
+ } else CheckTimer -= diff;
+ }
DoMeleeAttackIfReady();
}
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Talk(SAY_KILL);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ instance->SetData(DATA_HALAZZIEVENT, DONE);
+ Talk(SAY_DEATH);
+ }
};
CreatureAI* GetAI(Creature* creature) const override
{
- return GetZulAmanAI(creature);
+ return GetInstanceAI(creature);
+ }
+};
+
+// Spirits Lynx AI
+class npc_halazzi_lynx : public CreatureScript
+{
+ public:
+ npc_halazzi_lynx() : CreatureScript("npc_halazzi_lynx") { }
+
+ struct npc_halazzi_lynxAI : public ScriptedAI
+ {
+ npc_halazzi_lynxAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds
+ shredder_timer = 4000;
+ }
+
+ uint32 FrenzyTimer;
+ uint32 shredder_timer;
+
+ void Reset() override
+ {
+ Initialize();
+ }
+
+ void DamageTaken(Unit* /*done_by*/, uint32 &damage) override
+ {
+ if (damage >= me->GetHealth())
+ damage = 0;
+ }
+
+ void AttackStart(Unit* who) override
+ {
+ if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ ScriptedAI::AttackStart(who);
+ }
+
+ void EnterCombat(Unit* /*who*/) override {/*DoZoneInCombat();*/ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (FrenzyTimer <= diff)
+ {
+ DoCast(me, SPELL_LYNX_FRENZY);
+ FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds
+ } else FrenzyTimer -= diff;
+
+ if (shredder_timer <= diff)
+ {
+ DoCastVictim(SPELL_SHRED_ARMOR);
+ shredder_timer = 4000;
+ } else shredder_timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_halazzi_lynxAI(creature);
}
};
void AddSC_boss_halazzi()
{
new boss_halazzi();
+ new npc_halazzi_lynx();
}
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
index 9040edf1e12..01ac3920082 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008-2015 TrinityCore
+ * Copyright (C) 2006-2007 ScriptDev2
*
* 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
@@ -15,63 +16,375 @@
* with this program. If not, see .
*/
+/* ScriptData
+SDName: Boss_Hex_Lord_Malacrass
+SD%Complete:
+SDComment:
+SDCategory: Zul'Aman
+EndScriptData */
+
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "zulaman.h"
-enum Says
+#define YELL_AGGRO "Da shadow gonna fall on you... "
+#define SOUND_YELL_AGGRO 12041
+#define YELL_SPIRIT_BOLTS "Your soul gonna bleed!"
+#define SOUND_YELL_SPIRIT_BOLTS 12047
+#define YELL_DRAIN_POWER "Darkness comin\' for you"
+#define SOUND_YELL_DRAIN_POWER 12046
+#define YELL_KILL_ONE "Dis a nightmare ya don\' wake up from!"
+#define SOUND_YELL_KILL_ONE 12043
+#define YELL_KILL_TWO "Azzaga choogo zinn!"
+#define SOUND_YELL_KILL_TWO 12044
+#define YELL_DEATH "Dis not... da end of me..."
+#define SOUND_YELL_DEATH 12051
+
+
+enum Creatures
{
- SAY_AGGRO = 0,
- SAY_PLAYER_KILL = 1,
- SAY_SPIRIT_BOLTS = 2,
- SAY_SIPHON_SOUL = 3,
- SAY_PET_DEATH = 4,
- SAY_DEATH = 5
+ NPC_TEMP_TRIGGER = 23920
};
enum Spells
{
+ SPELL_SPIRIT_BOLTS = 43383,
+ SPELL_DRAIN_POWER = 44131,
+ SPELL_SIPHON_SOUL = 43501,
+
+ // Druid
+ SPELL_DR_THORNS = 43420,
+ SPELL_DR_LIFEBLOOM = 43421,
+ SPELL_DR_MOONFIRE = 43545,
+
+ // Hunter
+ SPELL_HU_EXPLOSIVE_TRAP = 43444,
+ SPELL_HU_FREEZING_TRAP = 43447,
+ SPELL_HU_SNAKE_TRAP = 43449,
+
+ // Mage
+ SPELL_MG_FIREBALL = 41383,
+ SPELL_MG_FROST_NOVA = 43426,
+ SPELL_MG_ICE_LANCE = 43427,
+ SPELL_MG_FROSTBOLT = 43428,
+
+ // Paladin
+ SPELL_PA_CONSECRATION = 43429,
+ SPELL_PA_AVENGING_WRATH = 43430,
+ SPELL_PA_HOLY_LIGHT = 43451,
+
+ // Priest
+ SPELL_PR_HEAL = 41372,
+ SPELL_PR_MIND_BLAST = 41374,
+ SPELL_PR_SW_DEATH = 41375,
+ SPELL_PR_PSYCHIC_SCREAM = 43432,
+ SPELL_PR_MIND_CONTROL = 43550,
+ SPELL_PR_PAIN_SUPP = 44416,
+
+ // Rogue
+ SPELL_RO_BLIND = 43433,
+ SPELL_RO_SLICE_DICE = 43457,
+ SPELL_RO_WOUND_POISON = 43461,
+
+ // Shaman
+ SPELL_SH_CHAIN_LIGHT = 43435,
+ SPELL_SH_FIRE_NOVA = 43436,
+ SPELL_SH_HEALING_WAVE = 43548,
+
+ // Warlock
+ SPELL_WL_CURSE_OF_DOOM = 43439,
+ SPELL_WL_RAIN_OF_FIRE = 43440,
SPELL_WL_UNSTABLE_AFFL = 43522,
SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523,
+
+ // Warrior
+ SPELL_WR_MORTAL_STRIKE = 43441,
+ SPELL_WR_WHIRLWIND = 43442,
+ SPELL_WR_SPELL_REFLECT = 43443,
+
+ // Thurg
+ SPELL_BLOODLUST = 43578,
+ SPELL_CLEAVE = 15496,
+
+ // Gazakroth
+ SPELL_FIREBOLT = 43584,
+
+ // Alyson Antille
+ SPELL_FLASH_HEAL = 43575,
+ SPELL_DISPEL_MAGIC = 43577,
+
+ // Lord Raadan
+ SPELL_FLAME_BREATH = 43582,
+ SPELL_THUNDERCLAP = 43583,
+
+ // Darkheart
+ SPELL_PSYCHIC_WAIL = 43590,
+
+ // Slither
+ SPELL_VENOM_SPIT = 43579,
+
+ // Fenstalker
+ SPELL_VOLATILE_INFECTION = 43586,
+
+ // Koragg
+ SPELL_COLD_STARE = 43593,
+ SPELL_MIGHTY_BLOW = 43592
+
};
-enum Events
+#define ORIENT 1.5696f
+#define POS_Y 921.2795f
+#define POS_Z 33.8883f
+
+static float Pos_X[4] = {112.8827f, 107.8827f, 122.8827f, 127.8827f};
+
+static uint32 AddEntryList[8]=
{
+ 24240, //Alyson Antille
+ 24241, //Thurg
+ 24242, //Slither
+ 24243, //Lord Raadan
+ 24244, //Gazakroth
+ 24245, //Fenstalker
+ 24246, //Darkheart
+ 24247 //Koragg
+};
+
+enum AbilityTarget
+{
+ ABILITY_TARGET_SELF = 0,
+ ABILITY_TARGET_VICTIM = 1,
+ ABILITY_TARGET_ENEMY = 2,
+ ABILITY_TARGET_HEAL = 3,
+ ABILITY_TARGET_BUFF = 4,
+ ABILITY_TARGET_SPECIAL = 5
+};
+
+struct PlayerAbilityStruct
+{
+ uint32 spell;
+ AbilityTarget target;
+ uint32 cooldown; //FIXME - it's never used
+};
+
+static PlayerAbilityStruct PlayerAbility[][3] =
+{
+ // 1 warrior
+ {{SPELL_WR_SPELL_REFLECT, ABILITY_TARGET_SELF, 10000},
+ {SPELL_WR_WHIRLWIND, ABILITY_TARGET_SELF, 10000},
+ {SPELL_WR_MORTAL_STRIKE, ABILITY_TARGET_VICTIM, 6000}},
+ // 2 paladin
+ {{SPELL_PA_CONSECRATION, ABILITY_TARGET_SELF, 10000},
+ {SPELL_PA_HOLY_LIGHT, ABILITY_TARGET_HEAL, 10000},
+ {SPELL_PA_AVENGING_WRATH, ABILITY_TARGET_SELF, 10000}},
+ // 3 hunter
+ {{SPELL_HU_EXPLOSIVE_TRAP, ABILITY_TARGET_SELF, 10000},
+ {SPELL_HU_FREEZING_TRAP, ABILITY_TARGET_SELF, 10000},
+ {SPELL_HU_SNAKE_TRAP, ABILITY_TARGET_SELF, 10000}},
+ // 4 rogue
+ {{SPELL_RO_WOUND_POISON, ABILITY_TARGET_VICTIM, 3000},
+ {SPELL_RO_SLICE_DICE, ABILITY_TARGET_SELF, 10000},
+ {SPELL_RO_BLIND, ABILITY_TARGET_ENEMY, 10000}},
+ // 5 priest
+ {{SPELL_PR_PAIN_SUPP, ABILITY_TARGET_HEAL, 10000},
+ {SPELL_PR_HEAL, ABILITY_TARGET_HEAL, 10000},
+ {SPELL_PR_PSYCHIC_SCREAM, ABILITY_TARGET_SELF, 10000}},
+ // 5* shadow priest
+ {{SPELL_PR_MIND_CONTROL, ABILITY_TARGET_ENEMY, 15000},
+ {SPELL_PR_MIND_BLAST, ABILITY_TARGET_ENEMY, 5000},
+ {SPELL_PR_SW_DEATH, ABILITY_TARGET_ENEMY, 10000}},
+ // 7 shaman
+ {{SPELL_SH_FIRE_NOVA, ABILITY_TARGET_SELF, 10000},
+ {SPELL_SH_HEALING_WAVE, ABILITY_TARGET_HEAL, 10000},
+ {SPELL_SH_CHAIN_LIGHT, ABILITY_TARGET_ENEMY, 8000}},
+ // 8 mage
+ {{SPELL_MG_FIREBALL, ABILITY_TARGET_ENEMY, 5000},
+ {SPELL_MG_FROSTBOLT, ABILITY_TARGET_ENEMY, 5000},
+ {SPELL_MG_ICE_LANCE, ABILITY_TARGET_SPECIAL, 2000}},
+ // 9 warlock
+ {{SPELL_WL_CURSE_OF_DOOM, ABILITY_TARGET_ENEMY, 10000},
+ {SPELL_WL_RAIN_OF_FIRE, ABILITY_TARGET_ENEMY, 10000},
+ {SPELL_WL_UNSTABLE_AFFL, ABILITY_TARGET_ENEMY, 10000}},
+ // 11 druid
+ {{SPELL_DR_LIFEBLOOM, ABILITY_TARGET_HEAL, 10000},
+ {SPELL_DR_THORNS, ABILITY_TARGET_SELF, 10000},
+ {SPELL_DR_MOONFIRE, ABILITY_TARGET_ENEMY, 8000}}
+};
+
+struct boss_hexlord_addAI : public ScriptedAI
+{
+ InstanceScript* instance;
+
+ boss_hexlord_addAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
+
+ void Reset() override { }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ DoZoneInCombat();
+ }
+
+ void UpdateAI(uint32 /*diff*/) override
+ {
+ if (instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS)
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ DoMeleeAttackIfReady();
+ }
};
class boss_hexlord_malacrass : public CreatureScript
{
public:
- boss_hexlord_malacrass() : CreatureScript("boss_hexlord_malacrass") { }
-
- struct boss_hex_lord_malacrassAI : public BossAI
+ boss_hexlord_malacrass()
+ : CreatureScript("boss_hexlord_malacrass")
{
- boss_hex_lord_malacrassAI(Creature* creature) : BossAI(creature, DATA_HEXLORD) { }
+ }
+
+ struct boss_hex_lord_malacrassAI : public ScriptedAI
+ {
+ boss_hex_lord_malacrassAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ instance = creature->GetInstanceScript();
+ SelectAddEntry();
+ for (uint8 i = 0; i < 4; ++i)
+ AddGUID[i].Clear();
+ PlayerGUID.Clear();
+ PlayerClass = CLASS_NONE;
+ }
+
+ void Initialize()
+ {
+ SpiritBolts_Timer = 20000;
+ DrainPower_Timer = 60000;
+ SiphonSoul_Timer = 100000;
+ PlayerAbility_Timer = 99999;
+ CheckAddState_Timer = 5000;
+ ResetTimer = 5000;
+ }
+
+ InstanceScript* instance;
+
+ ObjectGuid AddGUID[4];
+ uint32 AddEntry[4];
+
+ ObjectGuid PlayerGUID;
+
+ uint32 SpiritBolts_Timer;
+ uint32 DrainPower_Timer;
+ uint32 SiphonSoul_Timer;
+ uint32 PlayerAbility_Timer;
+ uint32 CheckAddState_Timer;
+ uint32 ResetTimer;
+
+ uint32 PlayerClass;
void Reset() override
{
- _Reset();
+ instance->SetData(DATA_HEXLORDEVENT, NOT_STARTED);
+
+ Initialize();
+
+ SpawnAdds();
+
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916);
+ me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
}
void EnterCombat(Unit* /*who*/) override
{
- Talk(SAY_AGGRO);
- _EnterCombat();
+ instance->SetData(DATA_HEXLORDEVENT, IN_PROGRESS);
+
+ DoZoneInCombat();
+ me->Yell(YELL_AGGRO, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_AGGRO);
+
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ Creature* creature = ObjectAccessor::GetCreature(*me, AddGUID[i]);
+ if (creature && creature->IsAlive())
+ creature->AI()->AttackStart(me->GetVictim());
+ else
+ {
+ EnterEvadeMode();
+ break;
+ }
+ }
+ }
+
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ switch (urand(0, 1))
+ {
+ case 0:
+ me->Yell(YELL_KILL_ONE, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE);
+ break;
+ case 1:
+ me->Yell(YELL_KILL_TWO, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO);
+ break;
+ }
}
void JustDied(Unit* /*killer*/) override
{
- Talk(SAY_DEATH);
- _JustDied();
+ instance->SetData(DATA_HEXLORDEVENT, DONE);
+
+ me->Yell(YELL_DEATH, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_DEATH);
+
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ Unit* Temp = ObjectAccessor::GetUnit(*me, AddGUID[i]);
+ if (Temp && Temp->IsAlive())
+ Temp->DealDamage(Temp, Temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
}
- void KilledUnit(Unit* victim) override
+ void SelectAddEntry()
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_PLAYER_KILL);
+ std::vector AddList;
+
+ for (uint8 i = 0; i < 8; ++i)
+ AddList.push_back(AddEntryList[i]);
+
+ while (AddList.size() > 4)
+ AddList.erase(AddList.begin() + rand32() % AddList.size());
+
+ uint8 i = 0;
+ for (std::vector::const_iterator itr = AddList.begin(); itr != AddList.end(); ++itr, ++i)
+ AddEntry[i] = *itr;
+ }
+
+ void SpawnAdds()
+ {
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ Creature* creature = (ObjectAccessor::GetCreature((*me), AddGUID[i]));
+ if (!creature || !creature->IsAlive())
+ {
+ if (creature) creature->setDeathState(DEAD);
+ creature = me->SummonCreature(AddEntry[i], Pos_X[i], POS_Y, POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0);
+ if (creature) AddGUID[i] = creature->GetGUID();
+ }
+ else
+ {
+ creature->AI()->EnterEvadeMode();
+ creature->SetPosition(Pos_X[i], POS_Y, POS_Z, ORIENT);
+ creature->StopMoving();
+ }
+ }
}
void UpdateAI(uint32 diff) override
@@ -79,23 +392,125 @@ class boss_hexlord_malacrass : public CreatureScript
if (!UpdateVictim())
return;
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- /*
- while (uint32 eventId = events.ExecuteEvent())
+ if (ResetTimer <= diff)
{
- switch (eventId)
+ if (me->IsWithinDist3d(119.223f, 1035.45f, 29.4481f, 10))
{
- default:
- break;
+ EnterEvadeMode();
+ return;
}
- }
- */
+ ResetTimer = 5000;
+ } else ResetTimer -= diff;
+
+ if (CheckAddState_Timer <= diff)
+ {
+ for (uint8 i = 0; i < 4; ++i)
+ if (Creature* temp = ObjectAccessor::GetCreature(*me, AddGUID[i]))
+ if (temp->IsAlive() && !temp->GetVictim())
+ temp->AI()->AttackStart(me->GetVictim());
+
+ CheckAddState_Timer = 5000;
+ } else CheckAddState_Timer -= diff;
+
+ if (DrainPower_Timer <= diff)
+ {
+ DoCast(me, SPELL_DRAIN_POWER, true);
+ me->Yell(YELL_DRAIN_POWER, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER);
+ DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear
+ } else DrainPower_Timer -= diff;
+
+ if (SpiritBolts_Timer <= diff)
+ {
+ if (DrainPower_Timer < 12000) // channel 10 sec
+ SpiritBolts_Timer = 13000; // cast drain power first
+ else
+ {
+ DoCast(me, SPELL_SPIRIT_BOLTS, false);
+ me->Yell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS);
+ SpiritBolts_Timer = 40000;
+ SiphonSoul_Timer = 10000; // ready to drain
+ PlayerAbility_Timer = 99999;
+ }
+ } else SpiritBolts_Timer -= diff;
+
+ if (SiphonSoul_Timer <= diff)
+ {
+ Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true);
+ Unit* trigger = DoSpawnCreature(NPC_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000);
+ if (!target || !trigger)
+ {
+ EnterEvadeMode();
+ return;
+ }
+ else
+ {
+ trigger->SetDisplayId(11686);
+ trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ trigger->CastSpell(target, SPELL_SIPHON_SOUL, true);
+ trigger->GetMotionMaster()->MoveChase(me);
+
+ //DoCast(target, SPELL_SIPHON_SOUL, true);
+ //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, target->GetGUID());
+ //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL);
+
+ PlayerGUID = target->GetGUID();
+ PlayerAbility_Timer = urand(8000, 10000);
+ PlayerClass = target->getClass() - 1;
+
+ if (PlayerClass == CLASS_DRUID-1)
+ PlayerClass = CLASS_DRUID;
+ else if (PlayerClass == CLASS_PRIEST-1 && target->HasSpell(15473))
+ PlayerClass = CLASS_PRIEST; // shadow priest
+
+ SiphonSoul_Timer = 99999; // buff lasts 30 sec
+ }
+ } else SiphonSoul_Timer -= diff;
+
+ if (PlayerAbility_Timer <= diff)
+ {
+ //Unit* target = ObjectAccessor::GetUnit(*me, PlayerGUID);
+ //if (target && target->IsAlive())
+ //{
+ UseAbility();
+ PlayerAbility_Timer = urand(8000, 10000);
+ //}
+ } else PlayerAbility_Timer -= diff;
DoMeleeAttackIfReady();
}
+
+ void UseAbility()
+ {
+ uint8 random = urand(0, 2);
+ Unit* target = NULL;
+ switch (PlayerAbility[PlayerClass][random].target)
+ {
+ case ABILITY_TARGET_SELF:
+ target = me;
+ break;
+ case ABILITY_TARGET_VICTIM:
+ target = me->GetVictim();
+ break;
+ case ABILITY_TARGET_ENEMY:
+ default:
+ target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
+ break;
+ case ABILITY_TARGET_HEAL:
+ target = DoSelectLowestHpFriendly(50, 0);
+ break;
+ case ABILITY_TARGET_BUFF:
+ {
+ std::list templist = DoFindFriendlyMissingBuff(50, PlayerAbility[PlayerClass][random].spell);
+ if (!templist.empty())
+ target = *(templist.begin());
+ }
+ break;
+ }
+ if (target)
+ DoCast(target, PlayerAbility[PlayerClass][random].spell, false);
+ }
};
CreatureAI* GetAI(Creature* creature) const override
@@ -104,6 +519,511 @@ class boss_hexlord_malacrass : public CreatureScript
}
};
+class boss_thurg : public CreatureScript
+{
+ public:
+
+ boss_thurg()
+ : CreatureScript("boss_thurg")
+ {
+ }
+
+ struct boss_thurgAI : public boss_hexlord_addAI
+ {
+
+ boss_thurgAI(Creature* creature) : boss_hexlord_addAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ bloodlust_timer = 15000;
+ cleave_timer = 10000;
+ }
+
+ uint32 bloodlust_timer;
+ uint32 cleave_timer;
+
+ void Reset() override
+ {
+ Initialize();
+
+ boss_hexlord_addAI::Reset();
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (bloodlust_timer <= diff)
+ {
+ std::list templist = DoFindFriendlyMissingBuff(50, SPELL_BLOODLUST);
+ if (!templist.empty())
+ {
+ if (Unit* target = *(templist.begin()))
+ DoCast(target, SPELL_BLOODLUST, false);
+ }
+ bloodlust_timer = 12000;
+ } else bloodlust_timer -= diff;
+
+ if (cleave_timer <= diff)
+ {
+ DoCastVictim(SPELL_CLEAVE, false);
+ cleave_timer = 12000; //3 sec cast
+ } else cleave_timer -= diff;
+
+ boss_hexlord_addAI::UpdateAI(diff);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+class boss_alyson_antille : public CreatureScript
+{
+ public:
+
+ boss_alyson_antille()
+ : CreatureScript("boss_alyson_antille")
+ {
+ }
+
+ struct boss_alyson_antilleAI : public boss_hexlord_addAI
+ {
+ //Holy Priest
+ boss_alyson_antilleAI(Creature* creature) : boss_hexlord_addAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ flashheal_timer = 2500;
+ dispelmagic_timer = 10000;
+ }
+
+ uint32 flashheal_timer;
+ uint32 dispelmagic_timer;
+
+ void Reset() override
+ {
+ Initialize();
+
+ //AcquireGUID();
+
+ boss_hexlord_addAI::Reset();
+ }
+
+ void AttackStart(Unit* who) override
+ {
+ if (!who)
+ return;
+
+ if (who->isTargetableForAttack())
+ {
+ if (me->Attack(who, false))
+ {
+ me->GetMotionMaster()->MoveChase(who, 20);
+ me->AddThreat(who, 0.0f);
+ }
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (flashheal_timer <= diff)
+ {
+ Unit* target = DoSelectLowestHpFriendly(99, 30000);
+ if (target)
+ {
+ if (target->IsWithinDistInMap(me, 50))
+ DoCast(target, SPELL_FLASH_HEAL, false);
+ else
+ {
+ // bugged
+ //me->GetMotionMaster()->Clear();
+ //me->GetMotionMaster()->MoveChase(target, 20);
+ }
+ }
+ else
+ {
+ if (urand(0, 1))
+ target = DoSelectLowestHpFriendly(50, 0);
+ else
+ target = SelectTarget(SELECT_TARGET_RANDOM, 0);
+ if (target)
+ DoCast(target, SPELL_DISPEL_MAGIC, false);
+ }
+ flashheal_timer = 2500;
+ } else flashheal_timer -= diff;
+
+ /*if (dispelmagic_timer <= diff)
+ {
+ if (urand(0, 1))
+ {
+ Unit* target = SelectTarget();
+
+ DoCast(target, SPELL_DISPEL_MAGIC, false);
+ }
+ else
+ me->CastSpell(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DISPEL_MAGIC, false);
+
+ dispelmagic_timer = 12000;
+ } else dispelmagic_timer -= diff;*/
+
+ boss_hexlord_addAI::UpdateAI(diff);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+struct boss_gazakrothAI : public boss_hexlord_addAI
+{
+ boss_gazakrothAI(Creature* creature) : boss_hexlord_addAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ firebolt_timer = 2000;
+ }
+
+ uint32 firebolt_timer;
+
+ void Reset() override
+ {
+ Initialize();
+ boss_hexlord_addAI::Reset();
+ }
+
+ void AttackStart(Unit* who) override
+ {
+ if (!who)
+ return;
+
+ if (who->isTargetableForAttack())
+ {
+ if (me->Attack(who, false))
+ {
+ me->GetMotionMaster()->MoveChase(who, 20);
+ me->AddThreat(who, 0.0f);
+ }
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (firebolt_timer <= diff)
+ {
+ DoCastVictim(SPELL_FIREBOLT, false);
+ firebolt_timer = 700;
+ } else firebolt_timer -= diff;
+
+ boss_hexlord_addAI::UpdateAI(diff);
+ }
+};
+
+class boss_lord_raadan : public CreatureScript
+{
+ public:
+
+ boss_lord_raadan()
+ : CreatureScript("boss_lord_raadan")
+ {
+ }
+
+ struct boss_lord_raadanAI : public boss_hexlord_addAI
+ {
+ boss_lord_raadanAI(Creature* creature) : boss_hexlord_addAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ flamebreath_timer = 8000;
+ thunderclap_timer = 13000;
+ }
+
+ uint32 flamebreath_timer;
+ uint32 thunderclap_timer;
+
+ void Reset() override
+ {
+ Initialize();
+
+ boss_hexlord_addAI::Reset();
+
+ }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (thunderclap_timer <= diff)
+ {
+ DoCastVictim(SPELL_THUNDERCLAP, false);
+ thunderclap_timer = 12000;
+ } else thunderclap_timer -= diff;
+
+ if (flamebreath_timer <= diff)
+ {
+ DoCastVictim(SPELL_FLAME_BREATH, false);
+ flamebreath_timer = 12000;
+ } else flamebreath_timer -= diff;
+
+ boss_hexlord_addAI::UpdateAI(diff);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+class boss_darkheart : public CreatureScript
+{
+ public:
+
+ boss_darkheart()
+ : CreatureScript("boss_darkheart")
+ {
+ }
+
+ struct boss_darkheartAI : public boss_hexlord_addAI
+ {
+ boss_darkheartAI(Creature* creature) : boss_hexlord_addAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ psychicwail_timer = 8000;
+ }
+
+ uint32 psychicwail_timer;
+
+ void Reset() override
+ {
+ Initialize();
+ boss_hexlord_addAI::Reset();
+ }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (psychicwail_timer <= diff)
+ {
+ DoCastVictim(SPELL_PSYCHIC_WAIL, false);
+ psychicwail_timer = 12000;
+ } else psychicwail_timer -= diff;
+
+ boss_hexlord_addAI::UpdateAI(diff);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+
+class boss_slither : public CreatureScript
+{
+ public:
+
+ boss_slither()
+ : CreatureScript("boss_slither")
+ {
+ }
+
+ struct boss_slitherAI : public boss_hexlord_addAI
+ {
+ boss_slitherAI(Creature* creature) : boss_hexlord_addAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ venomspit_timer = 5000;
+ }
+
+ uint32 venomspit_timer;
+
+ void Reset() override
+ {
+ Initialize();
+ boss_hexlord_addAI::Reset();
+ }
+
+ void AttackStart(Unit* who) override
+ {
+ if (!who)
+ return;
+
+ if (who->isTargetableForAttack())
+ {
+ if (me->Attack(who, false))
+ {
+ me->GetMotionMaster()->MoveChase(who, 20);
+ me->AddThreat(who, 0.0f);
+ }
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (venomspit_timer <= diff)
+ {
+ if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(victim, SPELL_VENOM_SPIT, false);
+ venomspit_timer = 2500;
+ } else venomspit_timer -= diff;
+
+ boss_hexlord_addAI::UpdateAI(diff);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+class boss_fenstalker : public CreatureScript
+{
+ public:
+
+ boss_fenstalker()
+ : CreatureScript("boss_fenstalker")
+ {
+ }
+
+ struct boss_fenstalkerAI : public boss_hexlord_addAI
+ {
+ boss_fenstalkerAI(Creature* creature) : boss_hexlord_addAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ volatileinf_timer = 15000;
+ }
+
+ uint32 volatileinf_timer;
+
+ void Reset() override
+ {
+ Initialize();
+ boss_hexlord_addAI::Reset();
+
+ }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (volatileinf_timer <= diff)
+ {
+ // core bug
+ if (me->GetVictim())
+ me->EnsureVictim()->CastSpell(me->GetVictim(), SPELL_VOLATILE_INFECTION, false);
+ volatileinf_timer = 12000;
+ } else volatileinf_timer -= diff;
+
+ boss_hexlord_addAI::UpdateAI(diff);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+class boss_koragg : public CreatureScript
+{
+ public:
+
+ boss_koragg()
+ : CreatureScript("boss_koragg")
+ {
+ }
+
+ struct boss_koraggAI : public boss_hexlord_addAI
+ {
+ boss_koraggAI(Creature* creature) : boss_hexlord_addAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ coldstare_timer = 15000;
+ mightyblow_timer = 10000;
+ }
+
+ uint32 coldstare_timer;
+ uint32 mightyblow_timer;
+
+ void Reset() override
+ {
+ Initialize();
+ boss_hexlord_addAI::Reset();
+
+ }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (mightyblow_timer <= diff)
+ {
+ DoCastVictim(SPELL_MIGHTY_BLOW, false);
+ mightyblow_timer = 12000;
+ }
+ if (coldstare_timer <= diff)
+ {
+ if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(victim, SPELL_COLD_STARE, false);
+ coldstare_timer = 12000;
+ }
+
+ boss_hexlord_addAI::UpdateAI(diff);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
class spell_hexlord_unstable_affliction : public SpellScriptLoader
{
public:
@@ -141,5 +1061,14 @@ class spell_hexlord_unstable_affliction : public SpellScriptLoader
void AddSC_boss_hex_lord_malacrass()
{
new boss_hexlord_malacrass();
+ new boss_thurg();
+ // new boss_gazakroth();
+ new boss_lord_raadan();
+ new boss_darkheart();
+ new boss_slither();
+ new boss_fenstalker();
+ new boss_koragg();
+ new boss_alyson_antille();
new spell_hexlord_unstable_affliction();
}
+
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
index b4e20641a85..3228fbfde1b 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008-2015 TrinityCore
+ * Copyright (C) 2006-2009 ScriptDev2
*
* 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
@@ -15,83 +16,430 @@
* with this program. If not, see .
*/
+/* ScriptData
+SDName: Boss_Janalai
+SD%Complete: 100
+SDComment:
+SDCategory: Zul'Aman
+EndScriptData */
+
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulaman.h"
+#include "GridNotifiers.h"
+#include "CellImpl.h"
-enum Says
+enum Yells
{
- SAY_AGGRO = 0,
- SAY_PLAYER_KILL = 1,
- SAY_SUMMON_HATCHER = 2,
- SAY_FIRE_BOMB = 3,
- SAY_HATCH_ALL_EGGS = 4,
- EMOTE_FRENZY = 5,
- SAY_DEATH = 6
+ SAY_AGGRO = 0,
+ SAY_FIRE_BOMBS = 1,
+ SAY_SUMMON_HATCHER = 2,
+ SAY_ALL_EGGS = 3,
+ SAY_BERSERK = 4,
+ SAY_SLAY = 5,
+ SAY_DEATH = 6,
+ SAY_EVENT_STRANGERS = 7,
+ SAY_EVENT_FRIENDS = 8
};
enum Spells
{
+ // Jan'alai
+ SPELL_FLAME_BREATH = 43140,
+ SPELL_FIRE_WALL = 43113,
+ SPELL_ENRAGE = 44779,
+ SPELL_SUMMON_PLAYERS = 43097,
+ SPELL_TELE_TO_CENTER = 43098, // coord
+ SPELL_HATCH_ALL = 43144,
+ SPELL_BERSERK = 45078,
+
+ // Fire Bob Spells
+ SPELL_FIRE_BOMB_CHANNEL = 42621, // last forever
+ SPELL_FIRE_BOMB_THROW = 42628, // throw visual
+ SPELL_FIRE_BOMB_DUMMY = 42629, // bomb visual
+ SPELL_FIRE_BOMB_DAMAGE = 42630,
+
+ // Hatcher Spells
+ SPELL_HATCH_EGG = 42471, // 43734
+ SPELL_SUMMON_HATCHLING = 42493,
+
+ // Hatchling Spells
+ SPELL_FLAMEBUFFET = 43299
};
-enum Events
+enum Creatures
{
+ NPC_AMANI_HATCHER = 23818,
+ NPC_HATCHLING = 23598, // 42493
+ NPC_EGG = 23817,
+ NPC_FIRE_BOMB = 23920
};
+const int area_dx = 44;
+const int area_dy = 51;
+
+float JanalainPos[1][3] =
+{
+ {-33.93f, 1149.27f, 19}
+};
+
+float FireWallCoords[4][4] =
+{
+ {-10.13f, 1149.27f, 19, 3.1415f},
+ {-33.93f, 1123.90f, 19, 0.5f*3.1415f},
+ {-54.80f, 1150.08f, 19, 0},
+ {-33.93f, 1175.68f, 19, 1.5f*3.1415f}
+};
+
+float hatcherway[2][5][3] =
+{
+ {
+ {-87.46f, 1170.09f, 6},
+ {-74.41f, 1154.75f, 6},
+ {-52.74f, 1153.32f, 19},
+ {-33.37f, 1172.46f, 19},
+ {-33.09f, 1203.87f, 19}
+ },
+ {
+ {-86.57f, 1132.85f, 6},
+ {-73.94f, 1146.00f, 6},
+ {-52.29f, 1146.51f, 19},
+ {-33.57f, 1125.72f, 19},
+ {-34.29f, 1095.22f, 19}
+ }
+};
class boss_janalai : public CreatureScript
{
public:
- boss_janalai() : CreatureScript("boss_janalai") { }
-
- struct boss_janalaiAI : public BossAI
+ boss_janalai()
+ : CreatureScript("boss_janalai")
{
- boss_janalaiAI(Creature* creature) : BossAI(creature, DATA_JANALAI) { }
+ }
+
+ struct boss_janalaiAI : public ScriptedAI
+ {
+ boss_janalaiAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ instance = creature->GetInstanceScript();
+ }
+
+ void Initialize()
+ {
+ FireBreathTimer = 8000;
+ BombTimer = 30000;
+ BombSequenceTimer = 1000;
+ BombCount = 0;
+ HatcherTimer = 10000;
+ EnrageTimer = MINUTE * 5 * IN_MILLISECONDS;
+
+ noeggs = false;
+ isBombing = false;
+ enraged = false;
+
+ isFlameBreathing = false;
+
+ for (uint8 i = 0; i < 40; ++i)
+ FireBombGUIDs[i].Clear();
+ }
+
+ InstanceScript* instance;
+
+ uint32 FireBreathTimer;
+ uint32 BombTimer;
+ uint32 BombSequenceTimer;
+ uint32 BombCount;
+ uint32 HatcherTimer;
+ uint32 EnrageTimer;
+
+ bool noeggs;
+ bool enraged;
+ bool isBombing;
+
+ bool isFlameBreathing;
+
+ ObjectGuid FireBombGUIDs[40];
void Reset() override
{
- _Reset();
- }
+ instance->SetData(DATA_JANALAIEVENT, NOT_STARTED);
- void EnterCombat(Unit* /*who*/) override
- {
- Talk(SAY_AGGRO);
- _EnterCombat();
+ Initialize();
+
+ HatchAllEggs(1);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
- _JustDied();
+
+ instance->SetData(DATA_JANALAIEVENT, DONE);
}
- void KilledUnit(Unit* victim) override
+ void KilledUnit(Unit* /*victim*/) override
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_PLAYER_KILL);
+ Talk(SAY_SLAY);
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ instance->SetData(DATA_JANALAIEVENT, IN_PROGRESS);
+
+ Talk(SAY_AGGRO);
+ // DoZoneInCombat();
+ }
+
+ void DamageDealt(Unit* target, uint32 &damage, DamageEffectType /*damagetype*/) override
+ {
+ if (isFlameBreathing)
+ {
+ if (!me->HasInArc(float(M_PI) / 6, target))
+ damage = 0;
+ }
+ }
+
+ void FireWall()
+ {
+ uint8 WallNum;
+ Creature* wall = NULL;
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ if (i == 0 || i == 2)
+ WallNum = 3;
+ else
+ WallNum = 2;
+
+ for (uint8 j = 0; j < WallNum; j++)
+ {
+ if (WallNum == 3)
+ wall = me->SummonCreature(NPC_FIRE_BOMB, FireWallCoords[i][0], FireWallCoords[i][1]+5*(j-1), FireWallCoords[i][2], FireWallCoords[i][3], TEMPSUMMON_TIMED_DESPAWN, 15000);
+ else
+ wall = me->SummonCreature(NPC_FIRE_BOMB, FireWallCoords[i][0]-2+4*j, FireWallCoords[i][1], FireWallCoords[i][2], FireWallCoords[i][3], TEMPSUMMON_TIMED_DESPAWN, 15000);
+ if (wall) wall->CastSpell(wall, SPELL_FIRE_WALL, true);
+ }
+ }
+ }
+
+ void SpawnBombs()
+ {
+ float dx, dy;
+ for (int i(0); i < 40; ++i)
+ {
+ dx = float(irand(-area_dx/2, area_dx/2));
+ dy = float(irand(-area_dy/2, area_dy/2));
+
+ Creature* bomb = DoSpawnCreature(NPC_FIRE_BOMB, dx, dy, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 15000);
+ if (bomb)
+ FireBombGUIDs[i] = bomb->GetGUID();
+ }
+ BombCount = 0;
+ }
+
+ bool HatchAllEggs(uint32 action) //1: reset, 2: isHatching all
+ {
+ std::list templist;
+ float x, y, z;
+ me->GetPosition(x, y, z);
+
+ {
+ CellCoord pair(Trinity::ComputeCellCoord(x, y));
+ Cell cell(pair);
+ cell.SetNoCreate();
+
+ Trinity::AllCreaturesOfEntryInRange check(me, NPC_EGG, 100);
+ Trinity::CreatureListSearcher searcher(me, templist, check);
+
+ TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher);
+
+ cell.Visit(pair, cSearcher, *me->GetMap(), *me, me->GetGridActivationRange());
+ }
+
+ //TC_LOG_ERROR("scripts", "Eggs %d at middle", templist.size());
+ if (templist.empty())
+ return false;
+
+ for (std::list::const_iterator i = templist.begin(); i != templist.end(); ++i)
+ {
+ if (action == 1)
+ (*i)->SetDisplayId(10056);
+ else if (action == 2 &&(*i)->GetDisplayId() != 11686)
+ (*i)->CastSpell(*i, SPELL_HATCH_EGG, false);
+ }
+ return true;
+ }
+
+ void Boom()
+ {
+ std::list templist;
+ float x, y, z;
+ me->GetPosition(x, y, z);
+
+ {
+ CellCoord pair(Trinity::ComputeCellCoord(x, y));
+ Cell cell(pair);
+ cell.SetNoCreate();
+
+ Trinity::AllCreaturesOfEntryInRange check(me, NPC_FIRE_BOMB, 100);
+ Trinity::CreatureListSearcher searcher(me, templist, check);
+
+ TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher);
+
+ cell.Visit(pair, cSearcher, *me->GetMap(), *me, me->GetGridActivationRange());
+ }
+ for (std::list::const_iterator i = templist.begin(); i != templist.end(); ++i)
+ {
+ (*i)->CastSpell(*i, SPELL_FIRE_BOMB_DAMAGE, true);
+ (*i)->RemoveAllAuras();
+ }
+ }
+
+ void HandleBombSequence()
+ {
+ if (BombCount < 40)
+ {
+ if (Unit* FireBomb = ObjectAccessor::GetUnit(*me, FireBombGUIDs[BombCount]))
+ {
+ FireBomb->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(FireBomb, SPELL_FIRE_BOMB_THROW, true);
+ FireBomb->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+ ++BombCount;
+ if (BombCount == 40)
+ {
+ BombSequenceTimer = 5000;
+ } else BombSequenceTimer = 100;
+ }
+ else
+ {
+ Boom();
+ isBombing = false;
+ BombTimer = urand(20000, 40000);
+ me->RemoveAurasDueToSpell(SPELL_FIRE_BOMB_CHANNEL);
+ if (EnrageTimer <= 10000)
+ EnrageTimer = 0;
+ else
+ EnrageTimer -= 10000;
+ }
}
void UpdateAI(uint32 diff) override
{
+ if (isFlameBreathing)
+ {
+ if (!me->IsNonMeleeSpellCast(false))
+ isFlameBreathing = false;
+ else
+ return;
+ }
+
+ if (isBombing)
+ {
+ if (BombSequenceTimer <= diff)
+ HandleBombSequence();
+ else
+ BombSequenceTimer -= diff;
+ return;
+ }
+
if (!UpdateVictim())
return;
- events.Update(diff);
+ //enrage if under 25% hp before 5 min.
+ if (!enraged && HealthBelowPct(25))
+ EnrageTimer = 0;
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- /*
- while (uint32 eventId = events.ExecuteEvent())
+ if (EnrageTimer <= diff)
{
- switch (eventId)
+ if (!enraged)
{
- default:
- break;
+ DoCast(me, SPELL_ENRAGE, true);
+ enraged = true;
+ EnrageTimer = 300000;
}
+ else
+ {
+ Talk(SAY_BERSERK);
+ DoCast(me, SPELL_BERSERK, true);
+ EnrageTimer = 300000;
+ }
+ } else EnrageTimer -= diff;
+
+ if (BombTimer <= diff)
+ {
+ Talk(SAY_FIRE_BOMBS);
+
+ me->AttackStop();
+ me->GetMotionMaster()->Clear();
+ DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]);
+ me->StopMoving();
+ DoCast(me, SPELL_FIRE_BOMB_CHANNEL, false);
+ //DoTeleportPlayer(me, JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2], 0);
+ //DoCast(me, SPELL_TELE_TO_CENTER, true);
+
+ FireWall();
+ SpawnBombs();
+ isBombing = true;
+ BombSequenceTimer = 100;
+
+ //Teleport every Player into the middle
+ Map* map = me->GetMap();
+ if (!map->IsDungeon())
+ return;
+
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (Player* i_pl = i->GetSource())
+ if (i_pl->IsAlive())
+ DoTeleportPlayer(i_pl, JanalainPos[0][0] - 5 + rand32() % 10, JanalainPos[0][1] - 5 + rand32() % 10, JanalainPos[0][2], 0);
+ //DoCast(Temp, SPELL_SUMMON_PLAYERS, true) // core bug, spell does not work if too far
+ return;
+ } else BombTimer -= diff;
+
+ if (!noeggs)
+ {
+ if (HealthBelowPct(35))
+ {
+ Talk(SAY_ALL_EGGS);
+
+ me->AttackStop();
+ me->GetMotionMaster()->Clear();
+ DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]);
+ me->StopMoving();
+ DoCast(me, SPELL_HATCH_ALL, false);
+ HatchAllEggs(2);
+ noeggs = true;
+ }
+ else if (HatcherTimer <= diff)
+ {
+ if (HatchAllEggs(0))
+ {
+ Talk(SAY_SUMMON_HATCHER);
+ me->SummonCreature(NPC_AMANI_HATCHER, hatcherway[0][0][0], hatcherway[0][0][1], hatcherway[0][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
+ me->SummonCreature(NPC_AMANI_HATCHER, hatcherway[1][0][0], hatcherway[1][0][1], hatcherway[1][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
+ HatcherTimer = 90000;
+ }
+ else
+ noeggs = true;
+ } else HatcherTimer -= diff;
}
- */
+
+ EnterEvadeIfOutOfCombatArea(diff);
DoMeleeAttackIfReady();
+
+ if (FireBreathTimer <= diff)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ {
+ me->AttackStop();
+ me->GetMotionMaster()->Clear();
+ DoCast(target, SPELL_FLAME_BREATH, false);
+ me->StopMoving();
+ isFlameBreathing = true;
+ }
+ FireBreathTimer = 8000;
+ } else FireBreathTimer -= diff;
}
};
@@ -101,7 +449,283 @@ class boss_janalai : public CreatureScript
}
};
+class npc_janalai_firebomb : public CreatureScript
+{
+ public:
+
+ npc_janalai_firebomb()
+ : CreatureScript("npc_janalai_firebomb")
+ {
+ }
+
+ struct npc_janalai_firebombAI : public ScriptedAI
+ {
+ npc_janalai_firebombAI(Creature* creature) : ScriptedAI(creature){ }
+
+ void Reset() override { }
+
+ void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
+ {
+ if (spell->Id == SPELL_FIRE_BOMB_THROW)
+ DoCast(me, SPELL_FIRE_BOMB_DUMMY, true);
+ }
+
+ void EnterCombat(Unit* /*who*/) override { }
+
+ void AttackStart(Unit* /*who*/) override { }
+
+ void MoveInLineOfSight(Unit* /*who*/) override { }
+
+
+ void UpdateAI(uint32 /*diff*/) override { }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_janalai_firebombAI(creature);
+ }
+};
+
+class npc_janalai_hatcher : public CreatureScript
+{
+ public:
+
+ npc_janalai_hatcher()
+ : CreatureScript("npc_janalai_hatcher")
+ {
+ }
+
+ struct npc_janalai_hatcherAI : public ScriptedAI
+ {
+ npc_janalai_hatcherAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ instance = creature->GetInstanceScript();
+ }
+
+ void Initialize()
+ {
+ waypoint = 0;
+ isHatching = false;
+ hasChangedSide = false;
+ WaitTimer = 1;
+ HatchNum = 0;
+ side = false;
+ }
+
+ InstanceScript* instance;
+
+ uint32 waypoint;
+ uint32 HatchNum;
+ uint32 WaitTimer;
+
+ bool side;
+ bool hasChangedSide;
+ bool isHatching;
+
+ void Reset() override
+ {
+ me->SetWalk(true);
+ Initialize();
+ side =(me->GetPositionY() < 1150);
+ }
+
+ bool HatchEggs(uint32 num)
+ {
+ std::list templist;
+ float x, y, z;
+ me->GetPosition(x, y, z);
+
+ {
+ CellCoord pair(Trinity::ComputeCellCoord(x, y));
+ Cell cell(pair);
+ cell.SetNoCreate();
+
+ Trinity::AllCreaturesOfEntryInRange check(me, 23817, 50);
+ Trinity::CreatureListSearcher searcher(me, templist, check);
+
+ TypeContainerVisitor, GridTypeMapContainer> cSearcher(searcher);
+
+ cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange());
+ }
+
+ //TC_LOG_ERROR("scripts", "Eggs %d at %d", templist.size(), side);
+
+ for (std::list::const_iterator i = templist.begin(); i != templist.end() && num > 0; ++i)
+ if ((*i)->GetDisplayId() != 11686)
+ {
+ (*i)->CastSpell(*i, SPELL_HATCH_EGG, false);
+ num--;
+ }
+
+ return num == 0; // if num == 0, no more templist
+ }
+
+ void EnterCombat(Unit* /*who*/) override { }
+ void AttackStart(Unit* /*who*/) override { }
+ void MoveInLineOfSight(Unit* /*who*/) override { }
+
+ void MovementInform(uint32, uint32) override
+ {
+ if (waypoint == 5)
+ {
+ isHatching = true;
+ HatchNum = 1;
+ WaitTimer = 5000;
+ }
+ else
+ WaitTimer = 1;
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!instance || !(instance->GetData(DATA_JANALAIEVENT) == IN_PROGRESS))
+ {
+ me->DisappearAndDie();
+ return;
+ }
+
+ if (!isHatching)
+ {
+ if (WaitTimer)
+ {
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePoint(0, hatcherway[side][waypoint][0], hatcherway[side][waypoint][1], hatcherway[side][waypoint][2]);
+ ++waypoint;
+ WaitTimer = 0;
+ }
+ }
+ else
+ {
+ if (WaitTimer <= diff)
+ {
+ if (HatchEggs(HatchNum))
+ {
+ ++HatchNum;
+ WaitTimer = 10000;
+ }
+ else if (!hasChangedSide)
+ {
+ side = side ? 0 : 1;
+ isHatching = false;
+ waypoint = 3;
+ WaitTimer = 1;
+ hasChangedSide = true;
+ }
+ else
+ me->DisappearAndDie();
+
+ } else WaitTimer -= diff;
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+class npc_janalai_hatchling : public CreatureScript
+{
+ public:
+
+ npc_janalai_hatchling()
+ : CreatureScript("npc_janalai_hatchling")
+ {
+ }
+
+ struct npc_janalai_hatchlingAI : public ScriptedAI
+ {
+ npc_janalai_hatchlingAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ instance = creature->GetInstanceScript();
+ }
+
+ void Initialize()
+ {
+ BuffetTimer = 7000;
+ }
+
+ InstanceScript* instance;
+ uint32 BuffetTimer;
+
+ void Reset() override
+ {
+ Initialize();
+ if (me->GetPositionY() > 1150)
+ me->GetMotionMaster()->MovePoint(0, hatcherway[0][3][0] + rand32() % 4 - 2, 1150.0f + rand32() % 4 - 2, hatcherway[0][3][2]);
+ else
+ me->GetMotionMaster()->MovePoint(0, hatcherway[1][3][0] + rand32() % 4 - 2, 1150.0f + rand32() % 4 - 2, hatcherway[1][3][2]);
+
+ me->SetDisableGravity(true);
+ }
+
+ void EnterCombat(Unit* /*who*/) override {/*DoZoneInCombat();*/ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!instance || !(instance->GetData(DATA_JANALAIEVENT) == IN_PROGRESS))
+ {
+ me->DisappearAndDie();
+ return;
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ if (BuffetTimer <= diff)
+ {
+ DoCastVictim(SPELL_FLAMEBUFFET, false);
+ BuffetTimer = 10000;
+ } else BuffetTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+class npc_janalai_egg : public CreatureScript
+{
+public:
+ npc_janalai_egg(): CreatureScript("npc_janalai_egg") { }
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_janalai_eggAI(creature);
+ }
+
+ struct npc_janalai_eggAI : public ScriptedAI
+ {
+ npc_janalai_eggAI(Creature* creature) : ScriptedAI(creature){ }
+
+ void Reset() override { }
+
+ void UpdateAI(uint32 /*diff*/) override { }
+
+ void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
+ {
+ if (spell->Id == SPELL_HATCH_EGG)
+ {
+ DoCast(SPELL_SUMMON_HATCHLING);
+ }
+ }
+ };
+
+};
+
void AddSC_boss_janalai()
{
new boss_janalai();
+ new npc_janalai_firebomb();
+ new npc_janalai_hatcher();
+ new npc_janalai_hatchling();
+ new npc_janalai_egg();
}
+
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
index dcc6f02473e..a0e4d037f8a 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008-2015 TrinityCore
+ * Copyright (C) 2006-2009 ScriptDev2
*
* 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
@@ -15,86 +16,444 @@
* with this program. If not, see .
*/
+/* ScriptData
+SDName: Boss_Nalorakk
+SD%Complete: 100
+SDComment:
+SDCategory: Zul'Aman
+EndScriptData */
+
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulaman.h"
-
-enum Says
-{
- SAY_WAVE_1 = 0,
- SAY_WAVE_2 = 1,
- SAY_WAVE_3 = 2,
- SAY_WAVE_4 = 3,
- SAY_AGGRO = 4,
- SAY_PLAYER_KILL = 5,
- SAY_SURGE = 6,
- EMOTE_SURGE = 7,
- EMOTE_BEAR = 8,
- SAY_BEAR = 9,
- SAY_TROLL = 10,
- SAY_DEATH = 11
-};
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "CellImpl.h"
enum Spells
{
+ SPELL_BERSERK = 45078,
+
+ // Troll form
+ SPELL_BRUTALSWIPE = 42384,
+ SPELL_MANGLE = 42389,
+ SPELL_MANGLEEFFECT = 44955,
+ SPELL_SURGE = 42402,
+ SPELL_BEARFORM = 42377,
+
+ // Bear form
+ SPELL_LACERATINGSLASH = 42395,
+ SPELL_RENDFLESH = 42397,
+ SPELL_DEAFENINGROAR = 42398
};
-enum Events
+// 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
};
+#define YELL_NALORAKK_WAVE1 "Get da move on, guards! It be killin' time!"
+#define SOUND_NALORAKK_WAVE1 12066
+#define YELL_NALORAKK_WAVE2 "Guards, go already! Who you more afraid of, dem... or me?"
+#define SOUND_NALORAKK_WAVE2 12067
+#define YELL_NALORAKK_WAVE3 "Ride now! Ride out dere and bring me back some heads!"
+#define SOUND_NALORAKK_WAVE3 12068
+#define YELL_NALORAKK_WAVE4 "I be losin' me patience! Go on: make dem wish dey was never born!"
+#define SOUND_NALORAKK_WAVE4 12069
+
+//Unimplemented SoundIDs
+/*
+#define SOUND_NALORAKK_EVENT1 12078
+#define SOUND_NALORAKK_EVENT2 12079
+*/
+
+//General defines
+#define YELL_AGGRO "You be dead soon enough!"
+#define SOUND_YELL_AGGRO 12070
+#define YELL_KILL_ONE "Mua-ha-ha! Now whatchoo got to say?"
+#define SOUND_YELL_KILL_ONE 12075
+#define YELL_KILL_TWO "Da Amani gonna rule again!"
+#define SOUND_YELL_KILL_TWO 12076
+#define YELL_DEATH "I... be waitin' on da udda side...."
+#define SOUND_YELL_DEATH 12077
+#define YELL_BERSERK "You had your chance, now it be too late!" //Never seen this being used, so just guessing from what I hear.
+#define SOUND_YELL_BERSERK 12074
+#define YELL_SURGE "I bring da pain!"
+#define SOUND_YELL_SURGE 12071
+
+#define YELL_SHIFTEDTOTROLL "Make way for Nalorakk!"
+#define SOUND_YELL_TOTROLL 12073
+
+
+#define YELL_SHIFTEDTOBEAR "You call on da beast, you gonna get more dan you bargain for!"
+#define SOUND_YELL_TOBEAR 12072
+
class boss_nalorakk : public CreatureScript
{
public:
- boss_nalorakk() : CreatureScript("boss_nalorakk") { }
-
- struct boss_nalorakkAI : public BossAI
+ boss_nalorakk()
+ : CreatureScript("boss_nalorakk")
{
- boss_nalorakkAI(Creature* creature) : BossAI(creature, DATA_NALORAKK) { }
+ }
+
+ struct boss_nalorakkAI : public ScriptedAI
+ {
+ boss_nalorakkAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ inMove = false;
+ MoveEvent = true;
+ MovePhase = 0;
+ waitTimer = 0;
+ LaceratingSlash_Timer = 0;
+ RendFlesh_Timer = 0;
+ DeafeningRoar_Timer = 0;
+ instance = creature->GetInstanceScript();
+ }
+
+ void Initialize()
+ {
+ 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;
+ }
+
+ 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
{
- _Reset();
+ if (MoveEvent)
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ inMove = false;
+ waitTimer = 0;
+ me->SetSpeed(MOVE_RUN, 2);
+ me->SetWalk(false);
+ }else
+ {
+ (*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]);
+ }
+
+ instance->SetData(DATA_NALORAKKEVENT, NOT_STARTED);
+
+ Initialize();
+ // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id
+ }
+
+ void SendAttacker(Unit* target)
+ {
+ std::list templist;
+ float x, y, z;
+ me->GetPosition(x, y, z);
+
+ {
+ CellCoord pair(Trinity::ComputeCellCoord(x, y));
+ Cell cell(pair);
+ cell.SetNoCreate();
+
+ Trinity::AllFriendlyCreaturesInGrid check(me);
+ Trinity::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)
+ {
+ switch (MovePhase)
+ {
+ case 0:
+ if (me->IsWithinDistInMap(who, 50))
+ {
+ me->Yell(YELL_NALORAKK_WAVE1, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_NALORAKK_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))
+ {
+ me->Yell(YELL_NALORAKK_WAVE2, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_NALORAKK_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))
+ {
+ me->Yell(YELL_NALORAKK_WAVE3, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_NALORAKK_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);
+
+ me->Yell(YELL_NALORAKK_WAVE4, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE4);
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ MoveEvent = false;
+ }
+ break;
+ }
+ }
+ }
+ }
}
void EnterCombat(Unit* /*who*/) override
{
- Talk(SAY_AGGRO);
- _EnterCombat();
+ instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS);
+
+ me->Yell(YELL_AGGRO, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_AGGRO);
+ DoZoneInCombat();
}
void JustDied(Unit* /*killer*/) override
{
- Talk(SAY_DEATH);
- _JustDied();
+ instance->SetData(DATA_NALORAKKEVENT, DONE);
+
+ me->Yell(YELL_DEATH, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_DEATH);
}
- void KilledUnit(Unit* victim) override
+ void KilledUnit(Unit* /*victim*/) override
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_PLAYER_KILL);
+ switch (urand(0, 1))
+ {
+ case 0:
+ me->Yell(YELL_KILL_ONE, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE);
+ break;
+ case 1:
+ me->Yell(YELL_KILL_TWO, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_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;
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
- /*
- while (uint32 eventId = events.ExecuteEvent())
+ if (Berserk_Timer <= diff)
{
- switch (eventId)
+ DoCast(me, SPELL_BERSERK, true);
+ me->Yell(YELL_BERSERK, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_BERSERK);
+ Berserk_Timer = 600000;
+ } else Berserk_Timer -= diff;
+
+ if (ShapeShift_Timer <= diff)
+ {
+ if (inBearForm)
{
- default:
- break;
+ // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
+ me->Yell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_TOTROLL);
+ 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);
+ me->Yell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_TOBEAR);
+ 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->EnsureVictim()->HasAura(SPELL_MANGLEEFFECT))
+ {
+ DoCastVictim(SPELL_MANGLE);
+ Mangle_Timer = 1000;
+ }
+ else Mangle_Timer = urand(10000, 15000);
+ } else Mangle_Timer -= diff;
+
+ if (Surge_Timer <= diff)
+ {
+ me->Yell(YELL_SURGE, LANG_UNIVERSAL);
+ DoPlaySoundToSet(me, SOUND_YELL_SURGE);
+ Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 45, true);
+ if (target)
+ DoCast(target, SPELL_SURGE);
+ Surge_Timer = urand(15000, 20000);
+ } else Surge_Timer -= diff;
+ }
+ 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;
}
- */
DoMeleeAttackIfReady();
}
@@ -110,3 +469,4 @@ void AddSC_boss_nalorakk()
{
new boss_nalorakk();
}
+
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
index 153040fdcfe..3b52e6775b2 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008-2015 TrinityCore
+ * Copyright (C) 2006-2009 ScriptDev2
*
* 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
@@ -15,209 +16,421 @@
* with this program. If not, see .
*/
+/* ScriptData
+SDName: Zulaman
+SD%Complete: 90
+SDComment: Forest Frog will turn into different NPC's. Workaround to prevent new entry from running this script
+SDCategory: Zul'Aman
+EndScriptData */
+
+/* ContentData
+npc_forest_frog
+EndContentData */
+
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
-#include "Player.h"
-#include "CreatureTextMgr.h"
-#include "SpellScript.h"
#include "zulaman.h"
+#include "Player.h"
+#include "SpellInfo.h"
+#include "SpellScript.h"
+
+/*######
+## npc_forest_frog
+######*/
+
+enum ForestFrog
+{
+ // Spells
+ SPELL_REMOVE_AMANI_CURSE = 43732,
+ SPELL_PUSH_MOJO = 43923,
+
+ // Creatures
+ NPC_FOREST_FROG = 24396
+
+};
+
+class npc_forest_frog : public CreatureScript
+{
+ public:
+
+ npc_forest_frog()
+ : CreatureScript("npc_forest_frog")
+ {
+ }
+
+ struct npc_forest_frogAI : public ScriptedAI
+ {
+ npc_forest_frogAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
+
+ InstanceScript* instance;
+
+ void Reset() override { }
+
+ void EnterCombat(Unit* /*who*/) override { }
+
+ void DoSpawnRandom()
+ {
+ uint32 cEntry = 0;
+ switch (rand32() % 10)
+ {
+ case 0: cEntry = 24397; break; //Mannuth
+ case 1: cEntry = 24403; break; //Deez
+ case 2: cEntry = 24404; break; //Galathryn
+ case 3: cEntry = 24405; break; //Adarrah
+ case 4: cEntry = 24406; break; //Fudgerick
+ case 5: cEntry = 24407; break; //Darwen
+ case 6: cEntry = 24445; break; //Mitzi
+ case 7: cEntry = 24448; break; //Christian
+ case 8: cEntry = 24453; break; //Brennan
+ case 9: cEntry = 24455; break; //Hollee
+ }
+
+ if (!instance->GetData(TYPE_RAND_VENDOR_1))
+ if (rand32() % 10 == 1) cEntry = 24408; //Gunter
+ if (!instance->GetData(TYPE_RAND_VENDOR_2))
+ if (rand32() % 10 == 1) cEntry = 24409; //Kyren
+
+ if (cEntry) me->UpdateEntry(cEntry);
+
+ if (cEntry == 24408) instance->SetData(TYPE_RAND_VENDOR_1, DONE);
+ if (cEntry == 24409) instance->SetData(TYPE_RAND_VENDOR_2, DONE);
+ }
+
+ void SpellHit(Unit* caster, const SpellInfo* spell) override
+ {
+ if (spell->Id == SPELL_REMOVE_AMANI_CURSE && caster->GetTypeId() == TYPEID_PLAYER && me->GetEntry() == NPC_FOREST_FROG)
+ {
+ //increase or decrease chance of mojo?
+ if (rand32() % 99 == 50) DoCast(caster, SPELL_PUSH_MOJO, true);
+ else DoSpawnRandom();
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI(creature);
+ }
+};
+
+/*######
+## npc_zulaman_hostage
+######*/
+
+#define GOSSIP_HOSTAGE1 "I am glad to help you."
+
+static uint32 HostageEntry[] = {23790, 23999, 24024, 24001};
+static uint32 ChestEntry[] = {186648, 187021, 186672, 186667};
+
+class npc_zulaman_hostage : public CreatureScript
+{
+ public:
+ npc_zulaman_hostage() : CreatureScript("npc_zulaman_hostage") { }
+
+ bool OnGossipHello(Player* player, Creature* creature) override
+ {
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HOSTAGE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
+ return true;
+ }
+
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
+ {
+ player->PlayerTalkClass->ClearMenus();
+
+ if (action == GOSSIP_ACTION_INFO_DEF + 1)
+ player->CLOSE_GOSSIP_MENU();
+
+ if (!creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
+ return true;
+
+ creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+
+ InstanceScript* instance = creature->GetInstanceScript();
+ if (instance)
+ {
+ //uint8 progress = instance->GetData(DATA_CHESTLOOTED);
+ instance->SetData(DATA_CHESTLOOTED, 0);
+ float x, y, z;
+ creature->GetPosition(x, y, z);
+ uint32 entry = creature->GetEntry();
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ if (HostageEntry[i] == entry)
+ {
+ creature->SummonGameObject(ChestEntry[i], x-2, y, z, 0, 0, 0, 0, 0, 0);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+};
+
+/*######
+## npc_harrison_jones
+######*/
enum Says
{
- // Vol'jin
- SAY_INTRO_1 = 0,
- SAY_INTRO_2 = 1,
- SAY_INTRO_3 = 2,
- SAY_INTRO_4 = 3,
- SAY_INTRO_FAIL = 4,
-
- // Hex Lord Malacrass
- SAY_HEXLOR_INTRO = 0
+ SAY_HARRISON_0 = 0,
+ SAY_HARRISON_1 = 1,
+ SAY_HARRISON_2 = 0,
+ SAY_HARRISON_3 = 1
};
enum Spells
{
- // Vol'jin
- SPELL_BANGING_THE_GONG = 45225
+ SPELL_BANGING_THE_GONG = 45225,
+ SPELL_STEALTH = 34189,
+ SPELL_COSMETIC_SPEAR_THROW = 43647
};
enum Events
{
- EVENT_INTRO_MOVEPOINT_1 = 1,
- EVENT_INTRO_MOVEPOINT_2 = 2,
- EVENT_INTRO_MOVEPOINT_3 = 3,
- EVENT_BANGING_THE_GONG = 4,
- EVENT_START_DOOR_OPENING_1 = 5,
- EVENT_START_DOOR_OPENING_2 = 6,
- EVENT_START_DOOR_OPENING_3 = 7,
- EVENT_START_DOOR_OPENING_4 = 8,
- EVENT_START_DOOR_OPENING_5 = 9,
- EVENT_START_DOOR_OPENING_6 = 10,
- EVENT_START_DOOR_OPENING_7 = 11
+ GONG_EVENT_1 = 1,
+ GONG_EVENT_2 = 2,
+ GONG_EVENT_3 = 3,
+ GONG_EVENT_4 = 4,
+ GONG_EVENT_5 = 5,
+ GONG_EVENT_6 = 6,
+ GONG_EVENT_7 = 7,
+ GONG_EVENT_8 = 8,
+ GONG_EVENT_9 = 9,
+ GONG_EVENT_10 = 10,
+ GONG_EVENT_11 = 11
};
-enum Points
+enum Waypoints
{
- POINT_INTRO = 1,
- POINT_STRANGE_GONG = 2,
- POINT_START_DOOR_OPENING_1 = 3,
- POINT_START_DOOR_OPENING_2 = 4
+ HARRISON_MOVE_1 = 860440,
+ HARRISON_MOVE_2 = 860441,
+ HARRISON_MOVE_3 = 860442
};
-enum Misc
+enum DisplayIds
{
- ITEM_VIRTUAL_ITEM = 5301
+ MODEL_HARRISON_JONES_0 = 22340,
+ MODEL_HARRISON_JONES_1 = 22354,
+ MODEL_HARRISON_JONES_2 = 22347
};
-Position const VoljinIntroWaypoint[4] =
+enum EntryIds
{
- { 117.7349f, 1662.77f, 42.02156f, 0.0f },
- { 132.14f, 1645.143f, 42.02158f, 0.0f },
- { 121.8901f, 1639.118f, 42.23253f, 0.0f },
- { 122.618f, 1639.546f, 42.11659f, 0.0f },
+ NPC_HARRISON_JONES_1 = 24375,
+ NPC_HARRISON_JONES_2 = 24365,
+ NPC_AMANISHI_GUARDIAN = 23597,
};
-class npc_voljin_zulaman : public CreatureScript
+enum Weapons
+{
+ WEAPON_MACE = 5301,
+ WEAPON_SPEAR = 13631
+};
+
+class npc_harrison_jones : public CreatureScript
{
public:
- npc_voljin_zulaman() : CreatureScript("npc_voljin_zulaman") { }
- struct npc_voljin_zulamanAI : public ScriptedAI
+ npc_harrison_jones() : CreatureScript("npc_harrison_jones")
{
- npc_voljin_zulamanAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
+ }
+
+ struct npc_harrison_jonesAI : public ScriptedAI
+ {
+ npc_harrison_jonesAI(Creature* creature) : ScriptedAI(creature)
{
- me->SetDisplayId(me->GetCreatureTemplate()->Modelid1);
- if (_instance->GetData(DATA_ZULAMAN_STATE) == NOT_STARTED)
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ Initialize();
+ instance = creature->GetInstanceScript();
}
+ void Initialize()
+ {
+ _gongEvent = 0;
+ _gongTimer = 0;
+ uiTargetGUID = 0;
+ }
+
+ InstanceScript* instance;
+
+ uint8 _gongEvent;
+ uint32 _gongTimer;
+ uint64 uiTargetGUID;
+
void Reset() override
{
- _gongCount = 0;
+ Initialize();
}
+ void EnterCombat(Unit* /*who*/) override { }
+
void sGossipSelect(Player* player, uint32 sender, uint32 action) override
{
- if (_instance->GetData(DATA_ZULAMAN_STATE) != NOT_STARTED)
- return;
-
- if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
- {
- _events.Reset();
- me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
+ if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ me->SetFacingToObject(player);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
- _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_1, 1000);
- Talk(SAY_INTRO_1, player);
- me->SetWalk(true);
- }
+ Talk(SAY_HARRISON_0);
+ _gongEvent = GONG_EVENT_1;
+ _gongTimer = 4000;
+ }
}
- void DoAction(int32 action) override
+ void SpellHit(Unit*, const SpellInfo* spell) override
{
- if (action == ACTION_START_ZULAMAN)
+ if (spell->Id == SPELL_COSMETIC_SPEAR_THROW)
{
- if (++_gongCount == 10)
- _events.ScheduleEvent(EVENT_START_DOOR_OPENING_1, 500);
+ me->RemoveAllAuras();
+ me->SetEntry(NPC_HARRISON_JONES_2);
+ me->SetDisplayId(MODEL_HARRISON_JONES_2);
+ me->SetTarget(ObjectGuid::Empty);
+ me->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_DEAD);
+ me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+ instance->SetData(DATA_GONGEVENT, DONE);
}
}
void UpdateAI(uint32 diff) override
{
- _events.Update(diff);
- while (uint32 eventId = _events.ExecuteEvent())
+ if (_gongEvent)
{
- switch (eventId)
+ if (_gongTimer <= diff)
{
- case EVENT_INTRO_MOVEPOINT_1:
- me->GetMotionMaster()->MovePoint(POINT_INTRO, VoljinIntroWaypoint[0]);
- _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_2, 1000);
- break;
- case EVENT_INTRO_MOVEPOINT_2:
- me->GetMotionMaster()->MovePoint(POINT_STRANGE_GONG, VoljinIntroWaypoint[1]);
- _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_3, 4000);
- break;
- case EVENT_INTRO_MOVEPOINT_3:
- Talk(SAY_INTRO_2);
- _events.ScheduleEvent(EVENT_BANGING_THE_GONG, 3000);
- case EVENT_BANGING_THE_GONG:
- DoCast(me, SPELL_BANGING_THE_GONG);
- if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(DATA_STRANGE_GONG)))
- strangeGong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, uint32(ITEM_VIRTUAL_ITEM));
- break;
- case EVENT_START_DOOR_OPENING_1:
- me->RemoveAura(SPELL_BANGING_THE_GONG);
- _events.ScheduleEvent(EVENT_START_DOOR_OPENING_2, 500);
- break;
- case EVENT_START_DOOR_OPENING_2:
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, uint32(0));
- if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(DATA_STRANGE_GONG)))
- strangeGong->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- _events.ScheduleEvent(EVENT_START_DOOR_OPENING_3, 500);
- break;
- case EVENT_START_DOOR_OPENING_3:
- me->GetMotionMaster()->MovePoint(POINT_START_DOOR_OPENING_1, VoljinIntroWaypoint[2]);
- break;
- case EVENT_START_DOOR_OPENING_4:
- _instance->SetData(DATA_ZULAMAN_STATE, IN_PROGRESS);
- if (GameObject* masiveGate = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(DATA_MASSIVE_GATE)))
- masiveGate->SetGoState(GO_STATE_ACTIVE);
- _events.ScheduleEvent(EVENT_START_DOOR_OPENING_5, 3000);
- break;
- case EVENT_START_DOOR_OPENING_5:
- Talk(SAY_INTRO_4);
- _events.ScheduleEvent(EVENT_START_DOOR_OPENING_6, 6000);
- break;
- case EVENT_START_DOOR_OPENING_6:
- _events.ScheduleEvent(EVENT_START_DOOR_OPENING_7, 6000);
- break;
- case EVENT_START_DOOR_OPENING_7:
- if (Creature* hexLordTrigger = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HEXLORD_TRIGGER)))
- sCreatureTextMgr->SendChat(hexLordTrigger, SAY_HEXLOR_INTRO, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP);
- break;
- default:
- break;
+ switch (_gongEvent)
+ {
+ case GONG_EVENT_1:
+ me->GetMotionMaster()->MovePath(HARRISON_MOVE_1, false);
+ _gongEvent = GONG_EVENT_2;
+ _gongTimer = 12000;
+ break;
+ case GONG_EVENT_2:
+ me->SetFacingTo(6.235659f);
+ Talk(SAY_HARRISON_1);
+ DoCast(me, SPELL_BANGING_THE_GONG);
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_MACE));
+ me->SetSheath(SHEATH_STATE_MELEE);
+ _gongEvent = GONG_EVENT_3;
+ _gongTimer = 4000;
+ break;
+ case GONG_EVENT_3:
+ if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetGuidData(GO_STRANGE_GONG)))
+ gong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ _gongEvent = GONG_EVENT_4;
+ _gongTimer = 105000;
+ break;
+ case GONG_EVENT_4:
+ me->RemoveAura(SPELL_BANGING_THE_GONG);
+ if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetGuidData(GO_STRANGE_GONG)))
+ gong->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+
+ // trigger or gong will need to be scripted to set IN_PROGRESS after enough hits.
+ // This is temp workaround.
+ instance->SetData(DATA_GONGEVENT, IN_PROGRESS); // to be removed.
+
+ if (instance->GetData(DATA_GONGEVENT) == IN_PROGRESS)
+ {
+ // Players are Now Saved to instance at SPECIAL (Player should be notified?)
+ me->GetMotionMaster()->MovePath(HARRISON_MOVE_2, false);
+ _gongEvent = GONG_EVENT_5;
+ _gongTimer = 5000;
+ }
+ else
+ {
+ _gongTimer = 1000;
+ _gongEvent = GONG_EVENT_9;
+ }
+ break;
+ case GONG_EVENT_5:
+ me->SetEntry(NPC_HARRISON_JONES_1);
+ me->SetDisplayId(MODEL_HARRISON_JONES_1);
+ Talk(SAY_HARRISON_2);
+ _gongTimer = 12000;
+ _gongEvent = GONG_EVENT_6;
+ break;
+ case GONG_EVENT_6:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
+ Talk(SAY_HARRISON_3);
+ _gongTimer = 7000;
+ _gongEvent = GONG_EVENT_7;
+ break;
+ case GONG_EVENT_7:
+ if (!uiTargetGUID)
+ {
+ std::list targetList;
+ GetCreatureListWithEntryInGrid(targetList, me, NPC_AMANISHI_GUARDIAN, 26.0f);
+ if (!targetList.empty())
+ {
+ for (std::list::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
+ {
+ if (Creature* ptarget = *itr)
+ {
+ if (ptarget->GetPositionX() > 120)
+ {
+ ptarget->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_SPEAR));
+ ptarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ ptarget->SetReactState(REACT_PASSIVE);
+ ptarget->AI()->SetData(0, 1);
+ }
+ else
+ {
+ ptarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ ptarget->SetReactState(REACT_PASSIVE);
+ ptarget->AI()->SetData(0, 2);
+ }
+ }
+ }
+ }
+ }
+
+ if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetGuidData(GO_MASSIVE_GATE)))
+ gate->SetGoState(GO_STATE_ACTIVE);
+ _gongTimer = 2000;
+ _gongEvent = GONG_EVENT_8;
+ break;
+ case GONG_EVENT_8:
+ DoCast(me, SPELL_STEALTH);
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(0));
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ me->GetMotionMaster()->MovePath(HARRISON_MOVE_3, false);
+ _gongTimer = 1000;
+ _gongEvent = 0;
+ break;
+ case GONG_EVENT_9:
+ me->GetMotionMaster()->MovePoint(0, 120.687f, 1674.0f, 42.0217f);
+ _gongTimer = 12000;
+ _gongEvent = GONG_EVENT_10;
+ break;
+ case GONG_EVENT_10:
+ me->SetFacingTo(1.59044f);
+ _gongEvent = 11;
+ _gongTimer = 6000;
+ break;
+ case GONG_EVENT_11:
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+
+ instance->SetData(DATA_GONGEVENT, NOT_STARTED);
+ _gongEvent = 0;
+ _gongTimer = 1000;
+ break;
+ }
}
+ else
+ _gongTimer -= diff;
}
}
-
- void MovementInform(uint32 movementType, uint32 pointId) override
- {
- if (movementType != POINT_MOTION_TYPE)
- return;
-
- switch (pointId)
- {
- case POINT_STRANGE_GONG:
- if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(DATA_STRANGE_GONG)))
- me->SetFacingToObject(strangeGong); // setInFront
- break;
- case POINT_START_DOOR_OPENING_1:
- me->SetFacingTo(4.747295f);
- me->GetMotionMaster()->MovePoint(POINT_START_DOOR_OPENING_2, VoljinIntroWaypoint[3]);
- Talk(SAY_INTRO_3);
- _events.ScheduleEvent(EVENT_START_DOOR_OPENING_4, 4500);
- break;
- default:
- break;
- }
- }
-
- private:
- InstanceScript* _instance;
- EventMap _events;
- uint8 _gongCount;
};
CreatureAI* GetAI(Creature* creature) const override
{
- return GetInstanceAI(creature);
+ return GetInstanceAI(creature);
}
};
-// 45226 - Banging the Gong
class spell_banging_the_gong : public SpellScriptLoader
{
public:
@@ -245,8 +458,11 @@ class spell_banging_the_gong : public SpellScriptLoader
}
};
+
void AddSC_zulaman()
{
- new npc_voljin_zulaman();
+ new npc_forest_frog();
+ new npc_zulaman_hostage();
+ new npc_harrison_jones();
new spell_banging_the_gong();
}
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
index 42b23016fde..74162f0859d 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008-2015 TrinityCore
+ * Copyright (C) 2006-2009 ScriptDev2
*
* 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
@@ -18,74 +19,45 @@
#ifndef DEF_ZULAMAN_H
#define DEF_ZULAMAN_H
-uint32 const EncounterCount = 6;
-#define ZulAmanScriptName "instance_zulaman"
#define DataHeader "ZA"
enum DataTypes
{
- // BossState
- DATA_AKILZON = 0,
- DATA_NALORAKK = 1,
- DATA_JANALAI = 2,
- DATA_HALAZZI = 3,
- DATA_HEXLORD = 4,
- DATA_DAAKARA = 5,
-
- // Data64
- DATA_HEXLORD_TRIGGER,
-
- DATA_STRANGE_GONG,
- DATA_MASSIVE_GATE,
-
- // SetData
- DATA_ZULAMAN_STATE
+ DATA_GONGEVENT = 0,
+ DATA_NALORAKKEVENT = 1,
+ DATA_AKILZONEVENT = 2,
+ DATA_JANALAIEVENT = 3,
+ DATA_HALAZZIEVENT = 4,
+ DATA_HEXLORDEVENT = 5,
+ DATA_ZULJINEVENT = 6,
+ DATA_CHESTLOOTED = 7,
+ TYPE_RAND_VENDOR_1 = 8,
+ TYPE_RAND_VENDOR_2 = 9
};
enum CreatureIds
{
- NPC_AKILZON = 23574,
- NPC_NALORAKK = 23576,
- NPC_JANALAI = 23578,
- NPC_HALAZZI = 23577,
- NPC_HEXLORD = 24239,
- NPC_DAAKARA = 23863,
-
- NPC_VOLJIN = 52924,
- NPC_HEXLORD_TRIGGER = 24363
+ NPC_HARRISON_JONES = 24358,
+ NPC_JANALAI = 23578,
+ NPC_ZULJIN = 23863,
+ NPC_HEXLORD = 24239,
+ NPC_HALAZZI = 23577,
+ NPC_NALORAKK = 23576
};
-enum GameObjectIds
+enum GameobjectIds
{
- GO_STRANGE_GONG = 187359,
- GO_MASSIVE_GATE = 186728,
+ GO_DOOR_HALAZZI = 186303,
+ GO_GATE_ZULJIN = 186304,
+ GO_GATE_HEXLORD = 186305,
+ GO_MASSIVE_GATE = 186728,
+ GO_DOOR_AKILZON = 186858,
+ GO_DOOR_ZULJIN = 186859,
+ GO_HARKORS_SATCHEL = 187021,
+ GO_TANZARS_TRUNK = 186648,
+ GO_ASHLIS_BAG = 186672,
+ GO_KRAZS_PACKAGE = 186667,
+ GO_STRANGE_GONG = 187359
};
-enum ZulAmanEvents
-{
- EVENT_START_ZULAMAN = 15897,
- EVENT_UPDATE_ZULAMAN_TIMER = 1,
-};
-
-enum ZulAmanAction
-{
- ACTION_START_ZULAMAN = 1
-};
-
-enum ZulAmanWorldStates
-{
- WORLD_STATE_ZULAMAN_TIMER_ENABLED = 3104,
- WORLD_STATE_ZULAMAN_TIMER = 3106,
-};
-
-template
-CreatureAI* GetZulAmanAI(Creature* creature)
-{
- if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
- if (instance->GetInstanceScript())
- if (instance->GetScriptId() == sObjectMgr->GetScriptId(ZulAmanScriptName))
- return new AI(creature);
- return NULL;
-}
-
#endif
diff --git a/src/server/scripts/Kalimdor/zone_felwood.cpp b/src/server/scripts/Kalimdor/zone_felwood.cpp
index 97891e0338f..f0d172db7fa 100644
--- a/src/server/scripts/Kalimdor/zone_felwood.cpp
+++ b/src/server/scripts/Kalimdor/zone_felwood.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (C) 2008-2015 TrinityCore
+ * Copyright (C) 2008-2015 TrinityCore
*
* 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
diff --git a/src/tools/map_extractor/wdt.h b/src/tools/map_extractor/wdt.h
index fbec55353a3..8eed0bc6093 100644
--- a/src/tools/map_extractor/wdt.h
+++ b/src/tools/map_extractor/wdt.h
@@ -87,4 +87,4 @@ public:
#pragma pack(pop)
-#endif
\ No newline at end of file
+#endif