Merge pull request #12992 from Nyeriah/patch-uk

Scripts/UtgardeKeep: Update Skarvald & Dalronn scripts to EventMaps
This commit is contained in:
joschiwald
2014-08-31 20:09:56 +02:00

View File

@@ -18,7 +18,7 @@
/* ScriptData
SDName: Boss_Skarvald_Dalronn
SD%Complete: 95
SDComment: Needs adjustments to blizzlike timers, Yell Text + Sound to DB
SDComment: Needs adjustments to blizzlike timers
SDCategory: Utgarde Keep
EndScriptData */
@@ -26,21 +26,15 @@ EndScriptData */
#include "ScriptedCreature.h"
#include "utgarde_keep.h"
enum Yells
enum Texts
{
// signed for 24200, but used by 24200, 27390
YELL_SKARVALD_AGGRO = 0,
YELL_SKARVALD_DAL_DIED = 1,
YELL_SKARVALD_SKA_DIEDFIRST = 2,
YELL_SKARVALD_KILL = 3,
YELL_SKARVALD_DAL_DIEDFIRST = 4,
// Texts are common for both bosses and their ghosts.
SAY_AGGRO = 0,
SAY_DEATH = 1, // Said once both bosses are dead.
SAY_DIED_FIRST = 2, // Said by the first boss that dies.
SAY_KILL = 3,
SAY_DEATH_RESPONSE = 4 // Said by the boss alive after the first one dies.
// signed for 24201, but used by 24201, 27389
YELL_DALRONN_AGGRO = 0,
YELL_DALRONN_SKA_DIED = 1,
YELL_DALRONN_DAL_DIEDFIRST = 2,
YELL_DALRONN_KILL = 3,
YELL_DALRONN_SKA_DIEDFIRST = 4
};
enum Spells
@@ -48,16 +42,38 @@ enum Spells
// Spells of Skarvald and his Ghost
SPELL_CHARGE = 43651,
SPELL_STONE_STRIKE = 48583,
SPELL_SUMMON_SKARVALD_GHOST = 48613,
SPELL_ENRAGE = 48193,
SPELL_SUMMON_SKARVALD_GHOST = 48613,
// Spells of Dalronn and his Ghost
SPELL_SHADOW_BOLT = 43649,
H_SPELL_SHADOW_BOLT = 59575,
H_SPELL_SUMMON_SKELETONS = 52611,
SPELL_SUMMON_SKELETONS = 52611,
SPELL_DEBILITATE = 43650,
SPELL_SUMMON_DALRONN_GHOST = 48612,
};
enum Events
{
// Skarvald the Constructor
EVENT_SKARVALD_CHARGE = 1,
EVENT_STONE_STRIKE,
// Dalronn the Controller
EVENT_SHADOW_BOLT,
EVENT_DEBILITATE,
EVENT_SUMMON_SKELETONS,
EVENT_DELAYED_AGGRO_SAY, // Dalronn's SAY_AGGRO is delayed so it doesn't overlap Skarvald's one.
// Common event to both bosses.
// Delays SAY_DEATH_RESPONSE so it doesn't overlap with the SAY_DIED_FIRST from the boss that has just died.
EVENT_DEATH_RESPONSE
};
enum Actions
{
ACTION_OTHER_JUST_DIED = 1,
ACTION_DESPAWN_SUMMONS = 2 // Only needed to clear off the ghosts when the second boss dies.
};
class SkarvaldChargePredicate
{
public:
@@ -72,151 +88,142 @@ class SkarvaldChargePredicate
Unit* me;
};
struct generic_boss_controllerAI : public BossAI
{
generic_boss_controllerAI(Creature* creature) : BossAI(creature, DATA_SKARVALD_DALRONN)
{
OtherBossData = 0;
IsInGhostForm = false;
}
void Reset() override
{
if (me->GetEntry() == NPC_SKARVALD_GHOST || me->GetEntry() == NPC_DALRONN_GHOST)
{
IsInGhostForm = true;
// Call this here since ghosts aren't set in combat as they spawn.
DoZoneInCombat(me, 50.0f);
}
else
_Reset();
}
void EnterCombat(Unit* /*who*/) override
{
if (!IsInGhostForm)
_EnterCombat();
}
void JustDied(Unit* /*killer*/) override
{
if (Creature* otherBoss = ObjectAccessor::GetCreature(*me, instance->GetData64(OtherBossData)))
{
if (otherBoss->IsAlive())
{
Talk(SAY_DIED_FIRST);
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
otherBoss->AI()->DoAction(ACTION_OTHER_JUST_DIED);
DoCast(me, OtherBossData == DATA_DALRONN ? SPELL_SUMMON_SKARVALD_GHOST : SPELL_SUMMON_DALRONN_GHOST, true);
}
else
{
Talk(SAY_DEATH);
otherBoss->AI()->DoAction(ACTION_DESPAWN_SUMMONS);
_JustDied();
}
}
}
void DoAction(int32 actionId) override
{
switch (actionId)
{
case ACTION_OTHER_JUST_DIED:
events.ScheduleEvent(EVENT_DEATH_RESPONSE, 2000);
break;
case ACTION_DESPAWN_SUMMONS:
summons.DespawnAll();
break;
default:
break;
}
}
void ExecuteEvent(uint32 eventId) override
{
if (eventId == EVENT_DEATH_RESPONSE)
Talk(SAY_DEATH_RESPONSE);
}
void KilledUnit(Unit* who) override
{
if (!IsInGhostForm && who->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_KILL);
}
protected:
uint32 OtherBossData;
bool IsInGhostForm;
};
class boss_skarvald_the_constructor : public CreatureScript
{
public:
boss_skarvald_the_constructor() : CreatureScript("boss_skarvald_the_constructor") { }
struct boss_skarvald_the_constructorAI : public BossAI
struct boss_skarvald_the_constructorAI : public generic_boss_controllerAI
{
boss_skarvald_the_constructorAI(Creature* creature) : BossAI(creature, DATA_SKARVALD_DALRONN) { }
bool ghost;
uint32 Charge_Timer;
uint32 StoneStrike_Timer;
uint32 Response_Timer;
uint32 Check_Timer;
bool Dalronn_isDead;
bool Enraged;
boss_skarvald_the_constructorAI(Creature* creature) : generic_boss_controllerAI(creature)
{
Enraged = false;
}
void Reset() override
{
Charge_Timer = 5000;
StoneStrike_Timer = 10000;
Dalronn_isDead = false;
Response_Timer = 0;
Check_Timer = 5000;
OtherBossData = DATA_DALRONN;
Enraged = false;
ghost = me->GetEntry() == NPC_SKARVALD_GHOST;
if (!ghost)
_Reset();
generic_boss_controllerAI::Reset();
}
void EnterCombat(Unit* /*who*/) override
void EnterCombat(Unit* who) override
{
if (!ghost)
if (!IsInGhostForm)
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SKARVALD_CHARGE, 5000);
events.ScheduleEvent(EVENT_STONE_STRIKE, 10000);
generic_boss_controllerAI::EnterCombat(who);
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
_EnterCombat();
Talk(YELL_SKARVALD_AGGRO);
case EVENT_SKARVALD_CHARGE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, SkarvaldChargePredicate(me)))
DoCast(target, SPELL_CHARGE);
events.ScheduleEvent(EVENT_CHARGE, urand(5000, 10000));
break;
case EVENT_STONE_STRIKE:
DoCastVictim(SPELL_STONE_STRIKE);
events.ScheduleEvent(EVENT_STONE_STRIKE, urand(5000, 10000));
break;
default:
generic_boss_controllerAI::ExecuteEvent(eventId);
break;
}
}
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
if (!Enraged && !ghost && me->HealthBelowPctDamaged(15, damage))
if (!Enraged && !IsInGhostForm && me->HealthBelowPctDamaged(15, damage))
{
Enraged = true;
DoCast(me, SPELL_ENRAGE);
}
}
void DoAction(int32 /*actionId*/)
{
summons.DespawnAll();
}
void JustDied(Unit* killer) override
{
if (!ghost)
{
if (Creature* dalronn = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_DALRONN)))
{
if (dalronn->IsAlive())
{
Talk(YELL_SKARVALD_SKA_DIEDFIRST);
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
//DoCast(me, SPELL_SUMMON_SKARVALD_GHOST, true);
if (Creature* temp = me->SummonCreature(NPC_SKARVALD_GHOST, *me, TEMPSUMMON_CORPSE_DESPAWN, 5000))
{
temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
temp->AI()->AttackStart(killer);
}
}
else
{
dalronn->AI()->DoAction(0);
_JustDied();
Talk(YELL_SKARVALD_DAL_DIED);
}
}
}
}
void KilledUnit(Unit* who) override
{
if (!ghost && who->GetTypeId() == TYPEID_PLAYER)
Talk(YELL_SKARVALD_KILL);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
if (!ghost)
{
if (Check_Timer)
{
if (Check_Timer <= diff)
{
Check_Timer = 5000;
Creature* dalronn = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_DALRONN));
if (dalronn && dalronn->isDead())
{
Dalronn_isDead = true;
Response_Timer = 2000;
Check_Timer = 0;
}
}
else
Check_Timer -= diff;
}
if (Response_Timer && Dalronn_isDead)
{
if (Response_Timer <= diff)
{
Talk(YELL_SKARVALD_DAL_DIEDFIRST);
Response_Timer = 0;
}
else
Response_Timer -= diff;
}
}
if (Charge_Timer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, SkarvaldChargePredicate(me)))
DoCast(target, SPELL_CHARGE);
Charge_Timer = 5000 + rand32() % 5000;
}
else
Charge_Timer -= diff;
if (StoneStrike_Timer <= diff)
{
DoCastVictim(SPELL_STONE_STRIKE);
StoneStrike_Timer = 5000 + rand32() % 5000;
}
else
StoneStrike_Timer -= diff;
if (!me->HasUnitState(UNIT_STATE_CASTING))
DoMeleeAttackIfReady();
}
private:
bool Enraged;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -230,171 +237,60 @@ class boss_dalronn_the_controller : public CreatureScript
public:
boss_dalronn_the_controller() : CreatureScript("boss_dalronn_the_controller") { }
struct boss_dalronn_the_controllerAI : public BossAI
struct boss_dalronn_the_controllerAI : public generic_boss_controllerAI
{
boss_dalronn_the_controllerAI(Creature* creature) : BossAI(creature, DATA_SKARVALD_DALRONN) { }
bool ghost;
uint32 ShadowBolt_Timer;
uint32 Debilitate_Timer;
uint32 Summon_Timer;
uint32 Response_Timer;
uint32 Check_Timer;
uint32 AggroYell_Timer;
bool Skarvald_isDead;
boss_dalronn_the_controllerAI(Creature* creature) : generic_boss_controllerAI(creature) { }
void Reset() override
{
ShadowBolt_Timer = 1000;
Debilitate_Timer = 5000;
Summon_Timer = 10000;
Check_Timer = 5000;
Skarvald_isDead = false;
Response_Timer = 0;
AggroYell_Timer = 0;
ghost = me->GetEntry() == NPC_DALRONN_GHOST;
if (!ghost)
_Reset();
OtherBossData = DATA_SKARVALD;
generic_boss_controllerAI::Reset();
}
void EnterCombat(Unit* /*who*/) override
void EnterCombat(Unit* who) override
{
if (!ghost)
{
_EnterCombat();
AggroYell_Timer = 5000;
}
events.ScheduleEvent(EVENT_SHADOW_BOLT, 1000);
events.ScheduleEvent(EVENT_DEBILITATE, 5000);
if (!IsInGhostForm)
events.ScheduleEvent(EVENT_DELAYED_AGGRO_SAY, 5000);
if (IsHeroic())
events.ScheduleEvent(EVENT_SUMMON_SKELETONS, 10000);
generic_boss_controllerAI::EnterCombat(who);
}
void DoAction(int32 /*actionId*/)
void ExecuteEvent(uint32 eventId) override
{
summons.DespawnAll();
}
void JustDied(Unit* killer) override
{
if (!ghost)
switch (eventId)
{
if (Creature* skarvald = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SKARVALD)))
{
if (skarvald->IsAlive())
{
Talk(YELL_DALRONN_DAL_DIEDFIRST);
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
//DoCast(me, SPELL_SUMMON_DALRONN_GHOST, true);
if (Creature* temp = me->SummonCreature(NPC_DALRONN_GHOST, *me, TEMPSUMMON_CORPSE_DESPAWN, 5000))
{
temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
temp->AI()->AttackStart(killer);
}
}
else
{
skarvald->AI()->DoAction(0);
_JustDied();
Talk(YELL_DALRONN_SKA_DIED);
}
}
}
}
void KilledUnit(Unit* who) override
{
if (!ghost && who->GetTypeId() == TYPEID_PLAYER)
Talk(YELL_DALRONN_KILL);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
if (AggroYell_Timer)
{
if (AggroYell_Timer <= diff)
{
Talk(YELL_DALRONN_AGGRO);
AggroYell_Timer = 0;
}
else
AggroYell_Timer -= diff;
}
if (!ghost)
{
if (Check_Timer)
{
if (Check_Timer <= diff)
{
Check_Timer = 5000;
Creature* skarvald = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SKARVALD));
if (skarvald && skarvald->isDead())
{
Skarvald_isDead = true;
Response_Timer = 2000;
Check_Timer = 0;
}
}
else
Check_Timer -= diff;
}
if (Response_Timer && Skarvald_isDead)
{
if (Response_Timer <= diff)
{
Talk(YELL_DALRONN_SKA_DIEDFIRST);
Response_Timer = 0;
}
else
Response_Timer -= diff;
}
}
if (ShadowBolt_Timer <= diff)
{
if (!me->IsNonMeleeSpellCast(false))
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
DoCast(target, SPELL_SHADOW_BOLT);
ShadowBolt_Timer = 2100;//give a 100ms pause to try cast other spells
}
}
else
ShadowBolt_Timer -= diff;
if (Debilitate_Timer <= diff)
{
if (!me->IsNonMeleeSpellCast(false))
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
DoCast(target, SPELL_DEBILITATE);
Debilitate_Timer = 5000 + rand32() % 5000;
}
}
else
Debilitate_Timer -= diff;
if (IsHeroic())
{
if (Summon_Timer <= diff)
{
case EVENT_SHADOW_BOLT:
if (!me->IsNonMeleeSpellCast(false))
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
DoCast(target, SPELL_SHADOW_BOLT);
events.ScheduleEvent(EVENT_SHADOW_BOLT, 2100); //give a 100ms pause to try cast other spells
break;
case EVENT_DEBILITATE:
if (!me->IsNonMeleeSpellCast(false))
{
DoCast(me, H_SPELL_SUMMON_SKELETONS);
Summon_Timer = (rand32() % 10000) + 20000;
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
DoCast(target, SPELL_DEBILITATE);
}
}
else
Summon_Timer -= diff;
events.ScheduleEvent(EVENT_DEBILITATE, urand(5000, 10000));
break;
case EVENT_SUMMON_SKELETONS:
if (!me->IsNonMeleeSpellCast(false))
DoCast(SPELL_SUMMON_SKELETONS);
events.ScheduleEvent(EVENT_SUMMON_SKELETONS, urand(10000, 30000));
break;
case EVENT_DELAYED_AGGRO_SAY:
Talk(SAY_AGGRO);
break;
default:
generic_boss_controllerAI::ExecuteEvent(eventId);
break;
}
DoMeleeAttackIfReady();
}
};