aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRushor <PBienati@web.de>2015-02-11 18:12:54 +0100
committerMitchesD <majklprofik@seznam.cz>2015-02-18 20:18:39 +0100
commit809c125881f96487149b78407da0580a1f48f994 (patch)
tree4c4fa586d67dfb6c89eda00bb95d670ad1b323e9
parent93236fdda4d2901796af4dadd833e15bc5212f73 (diff)
Scripts/HallsOfLightning: Boss Volkhan - Add OOC Forgecast
closes #14066 (cherry picked from commit dc87cc69a1a61bfed5a5eca70e418a015d09e25d)
-rw-r--r--sql/updates/world/2015_02_18_00_world.sql4
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp243
2 files changed, 133 insertions, 114 deletions
diff --git a/sql/updates/world/2015_02_18_00_world.sql b/sql/updates/world/2015_02_18_00_world.sql
new file mode 100644
index 00000000000..6a4c12347a3
--- /dev/null
+++ b/sql/updates/world/2015_02_18_00_world.sql
@@ -0,0 +1,4 @@
+--
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1 AND `SourceEntry`=52654;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 52654, 0, 0, 31, 0, 3, 28823, 0, 0, 0, 0, '', 'Temper only target Volkhan\'s Anvil');
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
index d653ec9e57d..e967f4aa8c5 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
@@ -29,7 +29,7 @@ EndScriptData */
#include "Player.h"
#include "SpellInfo.h"
-enum Enums
+enum Texts
{
SAY_AGGRO = 0,
SAY_FORGE = 1,
@@ -38,29 +38,50 @@ enum Enums
SAY_DEATH = 4,
EMOTE_TO_ANVIL = 5,
EMOTE_SHATTER = 6,
+};
+enum Spells
+{
SPELL_HEAT = 52387,
SPELL_SHATTERING_STOMP = 52237,
-
SPELL_TEMPER = 52238,
SPELL_TEMPER_DUMMY = 52654,
-
SPELL_SUMMON_MOLTEN_GOLEM = 52405,
+ SPELL_FORGE_VISUAL = 52654,
// Molten Golem
SPELL_BLAST_WAVE = 23113,
SPELL_IMMOLATION_STRIKE = 52433,
SPELL_SHATTER = 52429,
+};
+enum Events
+{
+ EVENT_PAUSE = 1,
+ EVENT_SHATTERING_STOMP = 2,
+ EVENT_SHATTER = 3,
+ EVENT_FORGE_CAST = 4,
+
+ // Molten Golem
+ EVENT_BLAST = 5,
+ EVENT_IMMOLATION = 6
+};
+
+enum Npcs
+{
NPC_VOLKHAN_ANVIL = 28823,
NPC_MOLTEN_GOLEM = 28695,
NPC_BRITTLE_GOLEM = 28681,
-
MAX_GOLEM = 2,
-
DATA_SHATTER_RESISTANT = 2042
};
+enum Phases
+{
+ PHASE_INTRO = 1,
+ PHASE_NORMAL
+};
+
/*######
## Boss Volkhan
######*/
@@ -68,68 +89,44 @@ class boss_volkhan : public CreatureScript
{
public:
boss_volkhan() : CreatureScript("boss_volkhan") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_volkhanAI>(creature);
- }
-
- struct boss_volkhanAI : public ScriptedAI
+
+ struct boss_volkhanAI : public BossAI
{
- boss_volkhanAI(Creature* creature) : ScriptedAI(creature)
+ boss_volkhanAI(Creature* creature) : BossAI(creature, DATA_VOLKHAN)
{
Initialize();
- instance = creature->GetInstanceScript();
}
void Initialize()
{
- m_bIsStriking = false;
- m_bHasTemper = false;
+ m_bIsStriking = false;
+ m_bHasTemper = false;
m_bCanShatterGolem = false;
-
- m_uiPause_Timer = 3500;
- m_uiShatteringStomp_Timer = 0;
- m_uiShatter_Timer = 5000;
- m_uiDelay_Timer = 1000;
- m_uiSummonPhase = 0;
- GolemsShattered = 0;
+ m_uiDelay_Timer = 1000;
+ m_uiSummonPhase = 0;
+ GolemsShattered = 0;
m_uiHealthAmountModifier = 1;
}
- InstanceScript* instance;
-
- GuidList m_lGolemGUIDList;
-
- bool m_bHasTemper;
- bool m_bIsStriking;
- bool m_bCanShatterGolem;
-
- uint8 GolemsShattered;
- uint32 m_uiPause_Timer;
- uint32 m_uiShatteringStomp_Timer;
- uint32 m_uiShatter_Timer;
- uint32 m_uiDelay_Timer;
- uint32 m_uiSummonPhase;
-
- uint32 m_uiHealthAmountModifier;
-
void Reset() override
{
Initialize();
-
+ _Reset();
DespawnGolem();
m_lGolemGUIDList.clear();
-
- instance->SetBossState(DATA_VOLKHAN, NOT_STARTED);
+ events.SetPhase(PHASE_INTRO);
+ events.ScheduleEvent(EVENT_FORGE_CAST, 2 * IN_MILLISECONDS, 0, PHASE_INTRO);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
-
- instance->SetBossState(DATA_VOLKHAN, IN_PROGRESS);
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_PAUSE, 3.5 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SHATTERING_STOMP, 0 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SHATTER, 5 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ _EnterCombat();
}
void AttackStart(Unit* who) override
@@ -150,7 +147,7 @@ public:
Talk(SAY_DEATH);
DespawnGolem();
- instance->SetBossState(DATA_VOLKHAN, DONE);
+ _JustDied();
}
void KilledUnit(Unit* who) override
@@ -224,59 +221,61 @@ public:
return 0;
}
- void UpdateAI(uint32 uiDiff) override
+ void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim())
+ // Return since we have no target and are in CombatPhase
+ if (events.IsInPhase(PHASE_NORMAL) && !UpdateVictim())
return;
- if (m_bIsStriking)
- {
- if (m_uiPause_Timer <= uiDiff)
- {
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
- if (me->GetVictim())
- me->GetMotionMaster()->MoveChase(me->GetVictim());
-
- m_bHasTemper = false;
- m_bIsStriking = false;
- m_uiPause_Timer = 3500;
- }
- else
- m_uiPause_Timer -= uiDiff;
+ events.Update(diff);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- }
- // When to start shatter? After 60, 40 or 20% hp?
- if (!m_bHasTemper && m_uiHealthAmountModifier >= 3)
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (m_uiShatteringStomp_Timer <= uiDiff)
+ switch (eventId)
{
- // Should he stomp even if he has no brittle golem to shatter?
- Talk(SAY_STOMP);
-
- DoCast(me, SPELL_SHATTERING_STOMP);
+ case EVENT_PAUSE:
+ if (m_bIsStriking)
+ {
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
+ if (me->GetVictim())
+ me->GetMotionMaster()->MoveChase(me->GetVictim());
- Talk(EMOTE_SHATTER);
+ m_bHasTemper = false;
+ m_bIsStriking = false;
+ events.ScheduleEvent(EVENT_PAUSE, 3.5 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ }
+ break;
+ case EVENT_SHATTERING_STOMP:
+ if (!m_bHasTemper && m_uiHealthAmountModifier >= 3)
+ {
+ // Should he stomp even if he has no brittle golem to shatter?
+ Talk(SAY_STOMP);
- m_uiShatteringStomp_Timer = 30000;
- m_bCanShatterGolem = true;
- }
- else
- m_uiShatteringStomp_Timer -= uiDiff;
- }
+ DoCast(me, SPELL_SHATTERING_STOMP);
- // Shatter Golems 3 seconds after Shattering Stomp
- if (m_bCanShatterGolem)
- {
- if (m_uiShatter_Timer <= uiDiff)
- {
- ShatterGolem();
- m_uiShatter_Timer = 3000;
- m_bCanShatterGolem = false;
+ Talk(EMOTE_SHATTER);
+ events.ScheduleEvent(EVENT_SHATTERING_STOMP, 30 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ m_bCanShatterGolem = true;
+ }
+ break;
+ case EVENT_SHATTER:
+ if (m_bCanShatterGolem)
+ {
+ ShatterGolem();
+ events.ScheduleEvent(EVENT_SHATTER, 3 * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ m_bCanShatterGolem = false;
+ }
+ break;
+ case EVENT_FORGE_CAST:
+ DoCast(me, SPELL_FORGE_VISUAL);
+ events.ScheduleEvent(EVENT_FORGE_CAST, 15 * IN_MILLISECONDS, 0, PHASE_INTRO);
+ break;
+ default:
+ break;
}
- else
- m_uiShatter_Timer -= uiDiff;
}
// Health check
@@ -302,12 +301,10 @@ public:
me->GetMotionMaster()->MoveTargetedHome();
m_uiSummonPhase = 2; // Set Next Phase
break;
-
case 2:
// 2 - Check if reached Anvil
// This is handled in: void JustReachedHome() override
break;
-
case 3:
// 3 - Cast Temper on the Anvil
if (Unit* target = GetClosestCreatureWithEntry(me, NPC_VOLKHAN_ANVIL, 1000.0f, true))
@@ -319,10 +316,9 @@ public:
m_uiDelay_Timer = 1000; // Delay 2 seconds before next phase can begin
m_uiSummonPhase = 4; // Set Next Phase
break;
-
case 4:
// 4 - Wait for delay to expire
- if (m_uiDelay_Timer <= uiDiff)
+ if (m_uiDelay_Timer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0))
{
@@ -333,9 +329,8 @@ public:
m_uiSummonPhase = 5;
}
else
- m_uiDelay_Timer -= uiDiff;
+ m_uiDelay_Timer -= diff;
break;
-
case 5:
// 5 - Spawn the Golems
if (Creature* creatureTarget = GetClosestCreatureWithEntry(me, NPC_VOLKHAN_ANVIL, 1000.0f, true))
@@ -349,13 +344,30 @@ public:
DoMeleeAttackIfReady();
}
+
+ private:
+ GuidList m_lGolemGUIDList;
+ uint32 m_uiHealthAmountModifier;
+ uint8 GolemsShattered;
+ uint32 m_uiDelay_Timer;
+ uint32 m_uiSummonPhase;
+
+ bool m_bHasTemper;
+ bool m_bIsStriking;
+ bool m_bCanShatterGolem;
};
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_volkhanAI>(creature);
+ }
+
};
/*######
## npc_molten_golem
######*/
+
class npc_molten_golem : public CreatureScript
{
public:
@@ -376,18 +388,12 @@ public:
void Initialize()
{
m_bIsFrozen = false;
-
- m_uiBlast_Timer = 20000;
- m_uiDeathDelay_Timer = 0;
- m_uiImmolation_Timer = 5000;
+ events.ScheduleEvent(EVENT_BLAST, 20 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_IMMOLATION, 5 * IN_MILLISECONDS);
}
bool m_bIsFrozen;
- uint32 m_uiBlast_Timer;
- uint32 m_uiDeathDelay_Timer;
- uint32 m_uiImmolation_Timer;
-
void Reset() override
{
Initialize();
@@ -433,30 +439,39 @@ public:
me->DespawnOrUnsummon();
}
- void UpdateAI(uint32 uiDiff) override
+ void UpdateAI(uint32 diff) override
{
// Return since we have no target or if we are frozen
if (!UpdateVictim() || m_bIsFrozen)
return;
- if (m_uiBlast_Timer <= uiDiff)
- {
- DoCast(me, SPELL_BLAST_WAVE);
- m_uiBlast_Timer = 20000;
- }
- else
- m_uiBlast_Timer -= uiDiff;
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiImmolation_Timer <= uiDiff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- DoCastVictim(SPELL_IMMOLATION_STRIKE);
- m_uiImmolation_Timer = 5000;
+ switch (eventId)
+ {
+ case EVENT_BLAST:
+ DoCast(me, SPELL_BLAST_WAVE);
+ events.ScheduleEvent(EVENT_BLAST, 20 * IN_MILLISECONDS);
+ break;
+ case EVENT_IMMOLATION:
+ DoCastVictim(SPELL_IMMOLATION_STRIKE);
+ events.ScheduleEvent(EVENT_BLAST, 5 * IN_MILLISECONDS);
+ break;
+ default:
+ break;
+ }
}
- else
- m_uiImmolation_Timer -= uiDiff;
DoMeleeAttackIfReady();
}
+
+ private:
+ EventMap events;
};
};