aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp127
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h9
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp6
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp62
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp106
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp148
-rw-r--r--src/server/scripts/Northrend/Naxxramas/naxxramas.h50
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp166
-rw-r--r--src/server/worldserver/worldserver.conf.dist63
-rw-r--r--src/tools/connection_patcher/Program.cpp5
12 files changed, 446 insertions, 300 deletions
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 55f19d1612e..8b2365079c7 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -456,7 +456,7 @@ void AccountMgr::LoadRBAC()
while (result->NextRow());
TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading default permissions");
- result = LoginDatabase.Query("SELECT secId, permissionId FROM rbac_default_permissions ORDER BY secId ASC");
+ result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realmHandle.Index);
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
index a0ff40c8a3c..e0416b56397 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
@@ -25,10 +25,9 @@ EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
-#include "hyjal.h"
-#include "SpellAuras.h"
-#include "hyjal_trash.h"
+#include "SpellScript.h"
#include "Player.h"
+#include "hyjal.h"
enum Texts
{
@@ -39,44 +38,44 @@ enum Texts
SAY_ENRAGE = 5,
SAY_DEATH = 6,
SAY_SOUL_CHARGE = 7,
+ // YELL_ARCHIMONDE_INTRO = 8
};
enum Spells
{
- SPELL_DENOUEMENT_WISP = 32124,
- SPELL_ANCIENT_SPARK = 39349,
- SPELL_PROTECTION_OF_ELUNE = 38528,
-
- SPELL_DRAIN_WORLD_TREE = 39140,
- SPELL_DRAIN_WORLD_TREE_2 = 39141,
-
- SPELL_FINGER_OF_DEATH = 31984,
- SPELL_HAND_OF_DEATH = 35354,
- SPELL_AIR_BURST = 32014,
- SPELL_GRIP_OF_THE_LEGION = 31972,
- SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
- SPELL_DOOMFIRE_SPAWN = 32074,
- SPELL_DOOMFIRE = 31945,
- SPELL_SOUL_CHARGE_YELLOW = 32045,
- SPELL_SOUL_CHARGE_GREEN = 32051,
- SPELL_SOUL_CHARGE_RED = 32052,
- SPELL_UNLEASH_SOUL_YELLOW = 32054,
- SPELL_UNLEASH_SOUL_GREEN = 32057,
- SPELL_UNLEASH_SOUL_RED = 32053,
- SPELL_FEAR = 31970,
+ SPELL_DENOUEMENT_WISP = 32124,
+ SPELL_ANCIENT_SPARK = 39349,
+ SPELL_PROTECTION_OF_ELUNE = 38528,
+
+ SPELL_DRAIN_WORLD_TREE = 39140,
+ SPELL_DRAIN_WORLD_TREE_TRIGGERED = 39141,
+
+ SPELL_FINGER_OF_DEATH = 31984,
+ SPELL_HAND_OF_DEATH = 35354,
+ SPELL_AIR_BURST = 32014,
+ SPELL_GRIP_OF_THE_LEGION = 31972,
+ SPELL_DOOMFIRE_STRIKE = 31903, // summons two creatures
+ SPELL_DOOMFIRE_SPAWN = 32074,
+ SPELL_DOOMFIRE = 31945,
+ SPELL_SOUL_CHARGE_YELLOW = 32045,
+ SPELL_SOUL_CHARGE_GREEN = 32051,
+ SPELL_SOUL_CHARGE_RED = 32052,
+ SPELL_UNLEASH_SOUL_YELLOW = 32054,
+ SPELL_UNLEASH_SOUL_GREEN = 32057,
+ SPELL_UNLEASH_SOUL_RED = 32053,
+ SPELL_FEAR = 31970
};
enum Events
{
- EVENT_DRAIN_NORDRASSIL = 1,
- EVENT_HAND_OF_DEATH, // Raid wiper
+ EVENT_HAND_OF_DEATH = 1, // Raid wiper
EVENT_UNLEASH_SOUL_CHARGE,
EVENT_FINGER_OF_DEATH,
EVENT_GRIP_OF_THE_LEGION,
EVENT_FEAR,
EVENT_AIR_BURST,
EVENT_DOOMFIRE,
- EVENT_DISTANCE_CHECK, // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
+ EVENT_DISTANCE_CHECK, // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
EVENT_SUMMON_WHISP
};
@@ -84,8 +83,7 @@ enum Summons
{
NPC_DOOMFIRE = 18095,
NPC_DOOMFIRE_SPIRIT = 18104,
- NPC_ANCIENT_WISP = 17946,
- NPC_CHANNEL_TARGET = 22418
+ NPC_ANCIENT_WISP = 17946
};
enum Actions
@@ -94,8 +92,6 @@ enum Actions
ACTION_CHANNEL_WORLD_TREE
};
-Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f};
-
class npc_ancient_wisp : public CreatureScript
{
public:
@@ -220,7 +216,6 @@ public:
}
void MoveInLineOfSight(Unit* who) override
-
{
//will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0
//when UpdateAI needs it, it will be forced to select randomPoint
@@ -279,10 +274,9 @@ public:
void Initialize()
{
DoomfireSpiritGUID.Clear();
- WorldTreeGUID.Clear();
SoulChargeCount = 0;
- WispCount = 0; // When ~30 wisps are summoned, Archimonde dies
+ WispCount = 0; // When ~30 wisps are summoned, Archimonde dies
_unleashSpell = 0;
_chargeSpell = 0;
@@ -290,13 +284,17 @@ public:
HasProtected = false;
}
+ void InitializeAI() override
+ {
+ BossAI::InitializeAI();
+ DoAction(ACTION_CHANNEL_WORLD_TREE);
+ }
+
void Reset() override
{
Initialize();
_Reset();
me->RemoveAllAuras(); // Reset Soul Charge auras.
- if (!me->isMoving())
- DoAction(ACTION_CHANNEL_WORLD_TREE);
}
void EnterCombat(Unit* /*who*/) override
@@ -317,11 +315,6 @@ public:
{
switch (eventId)
{
- case EVENT_DRAIN_NORDRASSIL:
- if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
- Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true);
- events.ScheduleEvent(EVENT_DRAIN_NORDRASSIL, 1000);
- break;
case EVENT_HAND_OF_DEATH:
DoCastAOE(SPELL_HAND_OF_DEATH);
events.ScheduleEvent(EVENT_HAND_OF_DEATH, 2000);
@@ -387,7 +380,7 @@ public:
events.ScheduleEvent(EVENT_DOOMFIRE, 20000);
break;
case EVENT_DISTANCE_CHECK:
- if (Creature* channelTrigger = ObjectAccessor::GetCreature(*me, WorldTreeGUID))
+ if (Creature* channelTrigger = instance->GetCreature(DATA_CHANNEL_TARGET))
if (me->IsWithinDistInMap(channelTrigger, 75.0f))
DoAction(ACTION_ENRAGE);
events.ScheduleEvent(EVENT_DISTANCE_CHECK, 5000);
@@ -503,18 +496,7 @@ public:
Talk(SAY_ENRAGE);
break;
case ACTION_CHANNEL_WORLD_TREE:
- if (Creature* temp = me->SummonCreature(NPC_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000))
- {
- WorldTreeGUID = temp->GetGUID();
-
- if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
- {
- Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Nordrassil->SetDisplayId(11686);
- DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE);
- }
- events.ScheduleEvent(EVENT_DRAIN_NORDRASSIL, 1000);
- }
+ DoCastAOE(SPELL_DRAIN_WORLD_TREE, true);
break;
default:
break;
@@ -538,7 +520,6 @@ public:
private:
ObjectGuid DoomfireSpiritGUID;
- ObjectGuid WorldTreeGUID;
uint8 SoulChargeCount;
uint8 WispCount;
uint32 _chargeSpell;
@@ -553,10 +534,46 @@ public:
}
};
+// 39142 - Drain World Tree Dummy
+class spell_archimonde_drain_world_tree_dummy : public SpellScriptLoader
+{
+ public:
+ spell_archimonde_drain_world_tree_dummy() : SpellScriptLoader("spell_archimonde_drain_world_tree_dummy") { }
+
+ class spell_archimonde_drain_world_tree_dummy_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_archimonde_drain_world_tree_dummy_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DRAIN_WORLD_TREE_TRIGGERED))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ target->CastSpell(GetCaster(), SPELL_DRAIN_WORLD_TREE_TRIGGERED, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_archimonde_drain_world_tree_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_archimonde_drain_world_tree_dummy_SpellScript();
+ }
+};
+
void AddSC_boss_archimonde()
{
new boss_archimonde();
new npc_doomfire();
new npc_doomfire_targetting();
new npc_ancient_wisp();
+ new spell_archimonde_drain_world_tree_dummy();
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
index c5f4d4ae679..54a763573ed 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
@@ -44,7 +44,8 @@ enum DataTypes
DATA_HORDE_RETREAT = 17,
DATA_RAIDDAMAGE = 18,
DATA_RESET_RAIDDAMAGE = 19,
- TYPE_RETREAT = 20
+ TYPE_RETREAT = 20,
+ DATA_CHANNEL_TARGET = 21
};
enum WorldStateIds
@@ -77,7 +78,8 @@ enum CreaturesIds
KAZROGAL = 17888,
AZGALOR = 17842,
ARCHIMONDE = 17968,
- NPC_WORLD_TRIGGER_TINY = 21987
+ NPC_WORLD_TRIGGER_TINY = 21987,
+ NPC_CHANNEL_TARGET = 22418
};
enum GameobjectIds
@@ -89,5 +91,6 @@ enum GameobjectIds
GO_ROARING_FLAME = 182592
};
-#endif
+#define MINRAIDDAMAGE 700000 // minimal damage before trash can drop loot and reputation, resets if faction leader dies
+#endif
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
index 56b79b6b3e1..0394b8535e5 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
@@ -26,7 +26,6 @@ enum Spells
SPELL_METEOR = 33814, //infernal visual
SPELL_IMMOLATION = 37059,
SPELL_FLAME_BUFFET = 31724,
- NPC_TRIGGER = 21987, //World Trigger (Tiny)
MODEL_INVIS = 11686, //invisible model
SPELL_DISEASE_CLOUD = 31607,
SPELL_KNOCKDOWN = 31610,
@@ -465,10 +464,7 @@ public:
}
if (!meteor)
{
- float x, y, z;
- me->GetPosition(x, y, z);
- Creature* trigger = me->SummonCreature(NPC_TRIGGER, x + 8, y + 8, z + 25 + rand32() % 10, me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 1000);
- if (trigger)
+ if (Creature* trigger = me->SummonCreature(NPC_WORLD_TRIGGER_TINY, me->GetPositionWithOffset({ 8.0f, 8.0f, frand(25.0f, 35.0f), 0.0f }), TEMPSUMMON_TIMED_DESPAWN, 1000))
{
trigger->SetVisible(false);
trigger->setFaction(me->getFaction());
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
index 18122ba2b0c..62f82ebcee1 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
@@ -21,8 +21,6 @@
#include "hyjal.h"
#include "ScriptedEscortAI.h"
-#define MINRAIDDAMAGE 700000//minimal damage before trash can drop loot and reputation, resets if faction leader dies
-
struct hyjal_trashAI : public npc_escortAI
{
hyjal_trashAI(Creature* creature);
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
index bd3f4fc62cc..99b8515c6e8 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
@@ -26,12 +26,7 @@ EndScriptData */
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
-#include "hyjal_trash.h"
-#include "Player.h"
-#include "WorldPacket.h"
-#include "Chat.h"
-#include "WorldSession.h"
-#include "Packets/ChatPackets.h"
+#include "hyjal.h"
/* Battle of Mount Hyjal encounters:
0 - Rage Winterchill event
@@ -41,8 +36,16 @@ EndScriptData */
4 - Archimonde event
*/
-#define YELL_EFFORTS "All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more."
-#define YELL_EFFORTS_NAME "Archimonde"
+enum Yells
+{
+ YELL_ARCHIMONDE_INTRO = 8
+};
+
+ObjectData const creatureData[] =
+{
+ { NPC_CHANNEL_TARGET, DATA_CHANNEL_TARGET },
+ { 0, 0 } // END
+};
class instance_hyjal : public InstanceMapScript
{
@@ -59,6 +62,7 @@ public:
instance_mount_hyjal_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
+ LoadObjectData(creatureData, nullptr);
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
RaidDamage = 0;
@@ -133,6 +137,8 @@ public:
TyrandeWhisperwind = creature->GetGUID();
break;
}
+
+ InstanceScript::OnCreatureCreate(creature);
}
ObjectGuid GetGuidData(uint32 identifier) const override
@@ -166,42 +172,18 @@ public:
m_auiEncounter[2] = data;
break;
case DATA_AZGALOREVENT:
+ m_auiEncounter[3] = data;
+ if (data == DONE)
{
- m_auiEncounter[3] = data;
- if (data == DONE)
+ instance->LoadGrid(5581.49f, -3445.63f);
+ if (Creature* archimonde = instance->GetCreature(Archimonde))
{
- if (Creature* archimonde = instance->GetCreature(Archimonde))
- archimonde->SetVisible(true);
-
- if (ArchiYell)
- break;
-
- ArchiYell = true;
+ archimonde->SetVisible(true);
- Creature* creature = instance->GetCreature(Azgalor);
- if (creature)
+ if (!ArchiYell)
{
- Creature* unit = creature->SummonCreature(NPC_WORLD_TRIGGER_TINY, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
-
- Map* map = creature->GetMap();
- if (map->IsDungeon() && unit)
- {
- unit->SetVisible(false);
- Map::PlayerList const &PlayerList = map->GetPlayers();
- if (PlayerList.isEmpty())
- return;
-
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (Player* player = i->GetSource())
- {
- WorldPackets::Chat::Chat packet;
- ChatHandler::BuildChatPacket(&packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, player, YELL_EFFORTS);
- player->SendDirectMessage(packet.Write());
- player->PlayDirectSound(10986, player);
- }
- }
- }
+ ArchiYell = true;
+ archimonde->AI()->Talk(YELL_ARCHIMONDE_INTRO);
}
}
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 102d1f0fb5b..8c927dcb0ac 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -30,26 +30,23 @@ EndScriptData */
#include "naxxramas.h"
#include "Player.h"
-enum Yells
+enum Texts
{
- //when shappiron dies. dialog between kel and lich king (in this order)
- SAY_SAPP_DIALOG1 = 0, //not used
- SAY_SAPP_DIALOG2_LICH = 1, //not used
- SAY_SAPP_DIALOG3 = 2, //not used
- SAY_SAPP_DIALOG4_LICH = 3, //not used
- SAY_SAPP_DIALOG5 = 4, //not used
- SAY_CAT_DIED = 5, //when cat dies, not used
- //when each of the 4 wing bosses dies
- SAY_TAUNT = 6,
SAY_AGGRO = 7,
SAY_SLAY = 8,
SAY_DEATH = 9,
SAY_CHAIN = 10,
SAY_FROST_BLAST = 11,
SAY_REQUEST_AID = 12, //start of phase 3
- SAY_ANSWER_REQUEST = 13, //lich king answer
+ EMOTE_PHASE_TWO = 13,
SAY_SUMMON_MINIONS = 14, //start of phase 1
- SAY_SPECIAL = 15
+ SAY_SPECIAL = 15,
+
+ // The Lich King
+ SAY_ANSWER_REQUEST = 3,
+
+ // Old World Trigger
+ SAY_GUARDIAN_SPAWNED = 0
};
enum Events
@@ -70,7 +67,10 @@ enum Events
EVENT_TRIGGER,
EVENT_PHASE,
- EVENT_MORTAL_WOUND
+ EVENT_MORTAL_WOUND,
+
+ EVENT_ANSWER_REQUEST,
+ EVENT_SUMMON_GUARDIANS
};
enum Spells
@@ -123,6 +123,13 @@ enum Spells
SPELL_MORTAL_WOUND = 28467
};
+enum Phases
+{
+ PHASE_ONE = 1, // Players move in the circle and Kel'Thuzad spawns his minions.
+ PHASE_TWO = 2, // Starts on a timer.
+ PHASE_THREE = 3 // At 45% health.
+};
+
enum Creatures
{
NPC_WASTE = 16427, // Soldiers of the Frozen Wastes
@@ -270,15 +277,11 @@ public:
void Initialize()
{
nGuardiansOfIcecrownCount = 0;
- uiGuardiansOfIcecrownTimer = 5000; // 5 seconds for summoning each Guardian of Icecrown in phase 3
- Phase = 0;
nAbomination = 0;
nWeaver = 0;
}
- uint32 Phase;
- uint32 uiGuardiansOfIcecrownTimer;
uint32 uiFaction;
uint8 nGuardiansOfIcecrownCount;
@@ -345,7 +348,6 @@ public:
void EnterCombat(Unit* /*who*/) override
{
me->setFaction(uiFaction);
-
_EnterCombat();
for (uint8 i = 0; i <= 3; ++i)
{
@@ -354,10 +356,10 @@ public:
}
DoCast(me, SPELL_KELTHUZAD_CHANNEL, false);
Talk(SAY_SUMMON_MINIONS);
- Phase = 1;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
me->SetFloatValue(UNIT_FIELD_COMBATREACH, 4);
me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 4);
+ events.SetPhase(PHASE_ONE);
events.ScheduleEvent(EVENT_TRIGGER, 5000);
events.ScheduleEvent(EVENT_WASTE, 15000);
events.ScheduleEvent(EVENT_ABOMIN, 30000);
@@ -365,6 +367,23 @@ public:
events.ScheduleEvent(EVENT_PHASE, 228000);
}
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (events.IsInPhase(PHASE_TWO) && me->HealthBelowPctDamaged(45, damage))
+ {
+ Talk(SAY_REQUEST_AID);
+ events.SetPhase(PHASE_THREE);
+ events.ScheduleEvent(EVENT_ANSWER_REQUEST, 4000);
+
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_KELTHUZAD_PORTAL01 + i)))
+ if (portal->getLootState() == GO_READY)
+ portal->UseDoorOrButton();
+ }
+ }
+ }
+
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -372,7 +391,7 @@ public:
events.Update(diff);
- if (Phase == 1)
+ if (events.IsInPhase(PHASE_ONE))
{
while (uint32 eventId = events.ExecuteEvent())
{
@@ -405,6 +424,7 @@ public:
case EVENT_PHASE:
events.Reset();
Talk(SAY_AGGRO);
+ Talk(EMOTE_PHASE_TWO);
spawns.DespawnAll();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
me->CastStop();
@@ -417,7 +437,7 @@ public:
events.ScheduleEvent(EVENT_BLAST, urand(60000, 120000));
if (GetDifficulty() == DIFFICULTY_25_N)
events.ScheduleEvent(EVENT_CHAIN, urand(30000, 60000));
- Phase = 2;
+ events.SetPhase(PHASE_TWO);
break;
default:
break;
@@ -426,38 +446,6 @@ public:
}
else
{
- //start phase 3 when we are 45% health
- if (Phase != 3)
- {
- if (HealthBelowPct(45))
- {
- Phase = 3;
- Talk(SAY_REQUEST_AID);
- //here Lich King should respond to KelThuzad but I don't know which Creature to make talk
- //so for now just make Kelthuzad says it.
- Talk(SAY_ANSWER_REQUEST);
-
- for (uint8 i = 0; i <= 3; ++i)
- {
- if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_KELTHUZAD_PORTAL01 + i)))
- if (portal->getLootState() == GO_READY)
- portal->UseDoorOrButton();
- }
- }
- }
- else if (nGuardiansOfIcecrownCount < RAID_MODE(2, 4))
- {
- if (uiGuardiansOfIcecrownTimer <= diff)
- {
- /// @todo Add missing text
- if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
- guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
- ++nGuardiansOfIcecrownCount;
- uiGuardiansOfIcecrownTimer = 5000;
- }
- else uiGuardiansOfIcecrownTimer -= diff;
- }
-
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
@@ -609,6 +597,18 @@ public:
Talk(SAY_FROST_BLAST);
events.Repeat(30000, 90000);
break;
+ case EVENT_ANSWER_REQUEST:
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_LICH_KING)))
+ lichKing->AI()->Talk(SAY_ANSWER_REQUEST);
+ events.ScheduleEvent(EVENT_SUMMON_GUARDIANS, 5000);
+ break;
+ case EVENT_SUMMON_GUARDIANS:
+ if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
+ guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
+ ++nGuardiansOfIcecrownCount;
+ if (nGuardiansOfIcecrownCount < RAID_MODE(2, 4))
+ events.ScheduleEvent(EVENT_SUMMON_GUARDIANS, 5000);
+ break;
default:
break;
}
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index bada44b20a0..ce478cd0664 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -115,6 +115,7 @@ class instance_naxxramas : public InstanceMapScript
minHorsemenDiedTime = 0;
maxHorsemenDiedTime = 0;
AbominationCount = 0;
+ CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT;
playerDied = 0;
}
@@ -156,6 +157,9 @@ class instance_naxxramas : public InstanceMapScript
case NPC_KEL_THUZAD:
KelthuzadGUID = creature->GetGUID();
break;
+ case NPC_LICH_KING:
+ LichKingGUID = creature->GetGUID();
+ break;
default:
break;
}
@@ -201,6 +205,9 @@ class instance_naxxramas : public InstanceMapScript
case GO_KELTHUZAD_TRIGGER:
KelthuzadTriggerGUID = go->GetGUID();
break;
+ case GO_ROOM_KELTHUZAD:
+ KelthuzadDoorGUID = go->GetGUID();
+ break;
default:
break;
}
@@ -242,6 +249,15 @@ class instance_naxxramas : public InstanceMapScript
playerDied = 1;
SaveToDB();
}
+
+ if (Creature* creature = unit->ToCreature())
+ if (creature->GetEntry() == NPC_BIGGLESWORTH)
+ {
+ // Loads Kel'Thuzad's grid. We need this as he must be active in order for his texts to work.
+ instance->LoadGrid(3749.67f, -5114.06f);
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_KELTHUZAD_CAT_DIED);
+ }
}
void SetData(uint32 id, uint32 value) override
@@ -327,6 +343,8 @@ class instance_naxxramas : public InstanceMapScript
return PortalsGUID[3];
case DATA_KELTHUZAD_TRIGGER:
return KelthuzadTriggerGUID;
+ case DATA_LICH_KING:
+ return LichKingGUID;
}
return ObjectGuid::Empty;
@@ -337,18 +355,131 @@ class instance_naxxramas : public InstanceMapScript
if (!InstanceScript::SetBossState(id, state))
return false;
- if (id == BOSS_HORSEMEN && state == DONE)
+ switch (id)
{
- if (GameObject* horsemenChest = instance->GetGameObject(HorsemenChestGUID))
- {
- horsemenChest->SetRespawnTime(horsemenChest->GetRespawnDelay());
- horsemenChest->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- }
+ case BOSS_MAEXXNA:
+ case BOSS_LOATHEB:
+ case BOSS_THADDIUS:
+ if (state == DONE)
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ break;
+ case BOSS_GOTHIK:
+ if (state == DONE)
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ, 10000);
+ break;
+ case BOSS_HORSEMEN:
+ if (state == DONE)
+ {
+ if (GameObject* horsemenChest = instance->GetGameObject(HorsemenChestGUID))
+ {
+ horsemenChest->SetRespawnTime(horsemenChest->GetRespawnDelay());
+ horsemenChest->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ }
+ break;
+ case BOSS_SAPPHIRON:
+ if (state == DONE)
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD, 6000);
+ break;
+ default:
+ break;
}
return true;
}
+ void Update(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DIALOGUE_GOTHIK_KORTHAZZ:
+ if (Creature* korthazz = instance->GetCreature(ThaneGUID))
+ korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK, 5000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_ZELIEK:
+ if (Creature* zeliek = instance->GetCreature(SirGUID))
+ zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_BLAUMEUX:
+ if (Creature* blaumeux = instance->GetCreature(LadyGUID))
+ blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_RIVENDARE:
+ if (Creature* rivendare = instance->GetCreature(BaronGUID))
+ rivendare->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_BLAUMEUX2:
+ if (Creature* blaumeux = instance->GetCreature(LadyGUID))
+ blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_ZELIEK2:
+ if (Creature* zeliek = instance->GetCreature(SirGUID))
+ zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_KORTHAZZ2:
+ if (Creature* korthazz = instance->GetCreature(ThaneGUID))
+ korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_RIVENDARE2:
+ if (Creature* rivendare = instance->GetCreature(BaronGUID))
+ rivendare->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ break;
+ case EVENT_KELTHUZAD_WING_TAUNT:
+ // Loads Kel'Thuzad's grid. We need this as he must be active in order for his texts to work.
+ instance->LoadGrid(3749.67f, -5114.06f);
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(CurrentWingTaunt);
+ ++CurrentWingTaunt;
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD);
+ HandleGameObject(KelthuzadDoorGUID, false);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING, 6000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_LICHKING:
+ if (Creature* lichKing = instance->GetCreature(LichKingGUID))
+ lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2, 16000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD2);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING2, 9000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_LICHKING2:
+ if (Creature* lichKing = instance->GetCreature(LichKingGUID))
+ lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING2);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3, 12000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD3);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4, 6000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4);
+ HandleGameObject(KelthuzadDoorGUID, true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
void HeiganErupt(uint32 section)
{
for (uint32 i = 0; i < 4; ++i)
@@ -450,10 +581,15 @@ class instance_naxxramas : public InstanceMapScript
ObjectGuid KelthuzadGUID;
ObjectGuid KelthuzadTriggerGUID;
ObjectGuid PortalsGUID[4];
+ ObjectGuid KelthuzadDoorGUID;
+ ObjectGuid LichKingGUID;
uint8 AbominationCount;
+ uint8 CurrentWingTaunt;
/* The Immortal / The Undying */
uint32 playerDied;
+
+ EventMap events;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
index 8325271a403..eb77980f3ba 100644
--- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h
+++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
@@ -71,6 +71,7 @@ enum Data64
DATA_KELTHUZAD_PORTAL03,
DATA_KELTHUZAD_PORTAL04,
DATA_KELTHUZAD_TRIGGER,
+ DATA_LICH_KING
};
enum CreaturesIds
@@ -89,7 +90,10 @@ enum CreaturesIds
NPC_CRYPT_GUARD = 16573,
NPC_NAXXRAMAS_FOLLOWER = 16505,
NPC_FOLLOWER_WORSHIPPER = 16506,
- NPC_DK_UNDERSTUDY = 16803
+ NPC_DK_UNDERSTUDY = 16803,
+ NPC_BIGGLESWORTH = 16998,
+ NPC_LICH_KING = 16980,
+ NPC_OLD_WORLD_TRIGGER = 15384
};
enum GameObjectsIds
@@ -142,6 +146,50 @@ enum SpellIds
SPELL_SLIME = 28801
};
+enum InstanceEvents
+{
+ // Dialogue that happens after Gothik's death.
+ EVENT_DIALOGUE_GOTHIK_KORTHAZZ = 1,
+ EVENT_DIALOGUE_GOTHIK_ZELIEK,
+ EVENT_DIALOGUE_GOTHIK_BLAUMEUX,
+ EVENT_DIALOGUE_GOTHIK_RIVENDARE,
+ EVENT_DIALOGUE_GOTHIK_BLAUMEUX2,
+ EVENT_DIALOGUE_GOTHIK_ZELIEK2,
+ EVENT_DIALOGUE_GOTHIK_KORTHAZZ2,
+ EVENT_DIALOGUE_GOTHIK_RIVENDARE2,
+
+ // Dialogue that happens after each wing.
+ EVENT_KELTHUZAD_WING_TAUNT,
+
+ // Dialogue that happens after Sapphiron's death.
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD,
+ EVENT_DIALOGUE_SAPPHIRON_LICHKING,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2,
+ EVENT_DIALOGUE_SAPPHIRON_LICHKING2,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4
+};
+
+enum InstanceTexts
+{
+ // The Four Horsemen
+ SAY_DIALOGUE_GOTHIK_HORSEMAN = 5,
+ SAY_DIALOGUE_GOTHIK_HORSEMAN2 = 6,
+
+ // Kel'Thuzad
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD = 0,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD2 = 2,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD3 = 4,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4 = 20,
+
+ SAY_KELTHUZAD_CAT_DIED = 5,
+ SAY_KELTHUZAD_FIRST_WING_TAUNT = 16,
+
+ // Lich King
+ SAY_DIALOGUE_SAPPHIRON_LICH_KING = 1,
+ SAY_DIALOGUE_SAPPHIRON_LICH_KING2 = 2
+};
+
/*
template<class AI>
CreatureAI* GetNaxxramasAI(Creature* creature)
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
index c0760afec23..8c7d0c2797f 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
@@ -28,7 +28,7 @@ EndScriptData */
#include "SpellScript.h"
#include "halls_of_lightning.h"
-enum Yells
+enum Texts
{
SAY_INTRO_1 = 0,
SAY_INTRO_2 = 1,
@@ -51,6 +51,21 @@ enum Spells
SPELL_PULSING_SHOCKWAVE_AURA = 59414
};
+enum Events
+{
+ EVENT_ARC_LIGHTNING = 1,
+ EVENT_LIGHTNING_NOVA,
+ EVENT_RESUME_PULSING_SHOCKWAVE,
+ EVENT_INTRO_DIALOGUE
+};
+
+enum Phases
+{
+ // Phases are used to allow executing the intro event while UpdateVictim() returns false and convenience.
+ PHASE_INTRO = 1,
+ PHASE_NORMAL
+};
+
enum Misc
{
ACHIEV_TIMELY_DEATH_START_EVENT = 20384
@@ -65,57 +80,41 @@ class boss_loken : public CreatureScript
public:
boss_loken() : CreatureScript("boss_loken") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_lokenAI>(creature);
- }
-
- struct boss_lokenAI : public ScriptedAI
+ struct boss_lokenAI : public BossAI
{
- boss_lokenAI(Creature* creature) : ScriptedAI(creature)
+ boss_lokenAI(Creature* creature) : BossAI(creature, DATA_LOKEN)
{
Initialize();
- instance = creature->GetInstanceScript();
+ _isIntroDone = false;
}
void Initialize()
{
- m_uiArcLightning_Timer = 15000;
- m_uiLightningNova_Timer = 20000;
- m_uiResumePulsingShockwave_Timer = 1000;
-
- m_uiHealthAmountModifier = 1;
+ _healthAmountModifier = 1;
}
- InstanceScript* instance;
-
- uint32 m_uiArcLightning_Timer;
- uint32 m_uiLightningNova_Timer;
- uint32 m_uiResumePulsingShockwave_Timer;
-
- uint32 m_uiHealthAmountModifier;
-
void Reset() override
{
Initialize();
-
- instance->SetBossState(DATA_LOKEN, NOT_STARTED);
+ _Reset();
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT);
}
void EnterCombat(Unit* /*who*/) override
{
+ _EnterCombat();
Talk(SAY_AGGRO);
-
- instance->SetBossState(DATA_LOKEN, IN_PROGRESS);
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_ARC_LIGHTNING, 15000);
+ events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 20000);
+ events.ScheduleEvent(EVENT_RESUME_PULSING_SHOCKWAVE, 1000);
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
-
- instance->SetBossState(DATA_LOKEN, DONE);
+ _JustDied();
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PULSING_SHOCKWAVE_AURA);
}
@@ -125,66 +124,89 @@ public:
Talk(SAY_SLAY);
}
- void UpdateAI(uint32 uiDiff) override
+ void MoveInLineOfSight(Unit* who) override
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- if (m_uiResumePulsingShockwave_Timer)
+ if (!_isIntroDone && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 40.0f))
{
- if (m_uiResumePulsingShockwave_Timer <= uiDiff)
- {
- DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
- me->ClearUnitState(UNIT_STATE_CASTING); // this flag breaks movement
-
- DoCast(me, SPELL_PULSING_SHOCKWAVE, true);
- m_uiResumePulsingShockwave_Timer = 0;
- }
- else
- m_uiResumePulsingShockwave_Timer -= uiDiff;
+ _isIntroDone = true;
+ Talk(SAY_INTRO_1);
+ events.ScheduleEvent(EVENT_INTRO_DIALOGUE, 20000, 0, PHASE_INTRO);
}
+ BossAI::MoveInLineOfSight(who);
+ }
- if (m_uiArcLightning_Timer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_ARC_LIGHTNING);
+ void UpdateAI(uint32 diff) override
+ {
+ if (events.IsInPhase(PHASE_NORMAL) && !UpdateVictim())
+ return;
- m_uiArcLightning_Timer = urand(15000, 16000);
- }
- else
- m_uiArcLightning_Timer -= uiDiff;
+ events.Update(diff);
- if (m_uiLightningNova_Timer <= uiDiff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- Talk(SAY_NOVA);
- Talk(EMOTE_NOVA);
- DoCast(me, SPELL_LIGHTNING_NOVA);
-
- me->RemoveAurasDueToSpell(SPELL_PULSING_SHOCKWAVE);
- m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura
- m_uiLightningNova_Timer = urand(20000, 21000);
+ switch (eventId)
+ {
+ case EVENT_ARC_LIGHTNING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_ARC_LIGHTNING);
+ events.ScheduleEvent(EVENT_ARC_LIGHTNING, urand(15000, 16000));
+ break;
+ case EVENT_LIGHTNING_NOVA:
+ Talk(SAY_NOVA);
+ Talk(EMOTE_NOVA);
+ DoCastAOE(SPELL_LIGHTNING_NOVA);
+ me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_PULSING_SHOCKWAVE, me));
+ events.ScheduleEvent(EVENT_RESUME_PULSING_SHOCKWAVE, DUNGEON_MODE(5000, 4000)); // Pause Pulsing Shockwave aura
+ events.ScheduleEvent(EVENT_LIGHTNING_NOVA, urand(20000, 21000));
+ break;
+ case EVENT_RESUME_PULSING_SHOCKWAVE:
+ DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
+ me->ClearUnitState(UNIT_STATE_CASTING); // This flag breaks movement.
+ DoCast(me, SPELL_PULSING_SHOCKWAVE, true);
+ break;
+ case EVENT_INTRO_DIALOGUE:
+ Talk(SAY_INTRO_2);
+ events.SetPhase(PHASE_NORMAL);
+ break;
+ default:
+ break;
+ }
}
- else
- m_uiLightningNova_Timer -= uiDiff;
- // Health check
- if (HealthBelowPct(100 - 25 * m_uiHealthAmountModifier))
+ DoMeleeAttackIfReady();
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (me->HealthBelowPctDamaged(100 - 25 * _healthAmountModifier, damage))
{
- switch (m_uiHealthAmountModifier)
+ switch (_healthAmountModifier)
{
- case 1: Talk(SAY_75HEALTH); break;
- case 2: Talk(SAY_50HEALTH); break;
- case 3: Talk(SAY_25HEALTH); break;
+ case 1:
+ Talk(SAY_75HEALTH);
+ break;
+ case 2:
+ Talk(SAY_50HEALTH);
+ break;
+ case 3:
+ Talk(SAY_25HEALTH);
+ break;
+ default:
+ break;
}
-
- ++m_uiHealthAmountModifier;
+ ++_healthAmountModifier;
}
-
- DoMeleeAttackIfReady();
}
+
+ private:
+ uint32 _healthAmountModifier;
+ bool _isIntroDone;
};
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_lokenAI>(creature);
+ }
};
class spell_loken_pulsing_shockwave : public SpellScriptLoader
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 36395d4d06e..1aefbfa13de 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -3034,7 +3034,7 @@ AuctionHouseBot.Buyer.Neutral.Chance.Ratio = 3
###################################################################################################
###################################################################################################
-# LOGGING SYSTEM SETTINGS
+# LOGGING SYSTEM SETTINGS
#
# Appender config values: Given a appender "name"
# Appender.name
@@ -3192,67 +3192,6 @@ Allow.IP.Based.Action.Logging = 0
###################################################################################################
###################################################################################################
-# GUILD LEVELING SETTINGS
-#
-# Guild.LevelingEnabled
-# Description: Controls whether guild can gain levels
-# Default: 1
-#
-
-Guild.LevelingEnabled = 1
-
-#
-# Guild.SaveInterval
-# Description: Time (in minutes) between guild experience saves
-# Default: 15
-#
-
-Guild.SaveInterval = 15
-
-#
-# Guild.MaxLevel
-# Description: Defines max level a guild can reach
-# Default: 25
-#
-
-Guild.MaxLevel = 25
-
-#
-# Guild.UndeletableLevel
-# Description: Guild reaching this level (and higher) cannot be disbanded anymore
-# Default: 4
-#
-
-Guild.UndeletableLevel = 4
-
-#
-# Guild.XPModifier
-# Description: Multiplier for guild experience gained from quests
-# Default: 0.25
-#
-
-Guild.XPModifier = 0.25
-
-#
-# Guild.DailyXPCap
-# Description: Maximum experience points a guild can earn each day
-# Default: 7807500
-#
-
-Guild.DailyXPCap = 7807500
-
-#
-# Guild.WeeklyReputationCap
-# Description: Maximum guild reputation a player can earn every week
-# Default: 4375
-#
-
-Guild.WeeklyReputationCap = 4375
-
-#
-###################################################################################################
-
-###################################################################################################
# CURRENCIES SETTINGS
#
# Currency.ResetInterval
diff --git a/src/tools/connection_patcher/Program.cpp b/src/tools/connection_patcher/Program.cpp
index 56007232d20..fe86936a95e 100644
--- a/src/tools/connection_patcher/Program.cpp
+++ b/src/tools/connection_patcher/Program.cpp
@@ -194,6 +194,11 @@ int main(int argc, char** argv)
do_patches<Patches::Mac::x64, Patterns::Mac::x64>
(&patcher, renamed_binary_path);
+ {
+ namespace fs = boost::filesystem;
+ fs::permissions(renamed_binary_path, fs::add_perms | fs::others_exe | fs::group_exe | fs::owner_exe);
+ }
+
do_module<Patches::Mac::x64, Patterns::Mac::x64>
( "97eeb2e28e9e56ed6a22d09f44e2ff43c93315e006bbad43bafc0defaa6f50ae.auth"
, "/Users/Shared/Blizzard/Battle.net/Cache/"