mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 01:37:37 +01:00
Core/DB: Utgarde Keep
This commit is contained in:
@@ -83,7 +83,7 @@ enum Spells
|
||||
SPELL_WOE_STRIKE = 42730,
|
||||
|
||||
ENTRY_THROW_TARGET = 23996,
|
||||
SPELL_SHADOW_AXE_SUMMON = 42749
|
||||
SPELL_SHADOW_AXE_SUMMON = 42748
|
||||
};
|
||||
|
||||
class boss_ingvar_the_plunderer : public CreatureScript
|
||||
@@ -108,8 +108,10 @@ public:
|
||||
|
||||
bool bIsUndead;
|
||||
bool bEventInProgress;
|
||||
bool justTransformed;
|
||||
|
||||
uint32 uiSpawnResTimer;
|
||||
uint32 afterTransformTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
@@ -130,12 +132,9 @@ public:
|
||||
events.ScheduleEvent(EVENT_ENRAGE, urand(7,14)*IN_MILLISECONDS, 0, PHASE_HUMAN);
|
||||
events.ScheduleEvent(EVENT_SMASH, urand(12,17)*IN_MILLISECONDS, 0, PHASE_HUMAN);
|
||||
|
||||
events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10,14)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
|
||||
uiSpawnResTimer = 3000;
|
||||
afterTransformTimer = 2000;
|
||||
justTransformed = false;
|
||||
|
||||
if (instance)
|
||||
instance->SetData(DATA_INGVAR_EVENT, NOT_STARTED);
|
||||
@@ -158,7 +157,12 @@ public:
|
||||
|
||||
bEventInProgress = true;
|
||||
bIsUndead = true;
|
||||
|
||||
events.SetPhase(PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,18)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10,14)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
|
||||
DoScriptText(YELL_DEAD_1, me);
|
||||
}
|
||||
@@ -173,20 +177,21 @@ public:
|
||||
{
|
||||
bIsUndead = true;
|
||||
bEventInProgress = false;
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->UpdateEntry(MOB_INGVAR_UNDEAD);
|
||||
me->SetInCombatWith(me->getVictim());
|
||||
me->GetMotionMaster()->MoveChase(me->getVictim());
|
||||
justTransformed = true;
|
||||
|
||||
DoScriptText(YELL_AGGRO_2, me);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
DoScriptText(YELL_AGGRO_1, me);
|
||||
if (!bIsUndead)
|
||||
DoScriptText(YELL_AGGRO_1, me);
|
||||
|
||||
if (instance)
|
||||
instance->SetData(DATA_INGVAR_EVENT, IN_PROGRESS);
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
@@ -211,7 +216,7 @@ public:
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
if (!UpdateVictim() && !justTransformed)
|
||||
return;
|
||||
|
||||
if (bEventInProgress)
|
||||
@@ -229,6 +234,21 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (justTransformed)
|
||||
{
|
||||
if (afterTransformTimer <= diff)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetInCombatWithZone();
|
||||
me->GetMotionMaster()->MoveChase(me->getVictim());
|
||||
justTransformed = false;
|
||||
afterTransformTimer = 2000;
|
||||
} else
|
||||
afterTransformTimer -= diff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
@@ -245,7 +265,7 @@ public:
|
||||
break;
|
||||
case EVENT_STAGGERING_ROAR:
|
||||
DoCast(me, SPELL_STAGGERING_ROAR);
|
||||
events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_HUMAN);
|
||||
events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18,22)*IN_MILLISECONDS, 0, PHASE_HUMAN);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
@@ -253,16 +273,16 @@ public:
|
||||
break;
|
||||
case EVENT_SMASH:
|
||||
DoCastVictim(SPELL_SMASH);
|
||||
events.ScheduleEvent(EVENT_SMASH, urand(12,17)*IN_MILLISECONDS, 0, PHASE_HUMAN);
|
||||
events.ScheduleEvent(EVENT_SMASH, urand(12,16)*IN_MILLISECONDS, 0, PHASE_HUMAN);
|
||||
break;
|
||||
// PHASE TWO
|
||||
case EVENT_DARK_SMASH:
|
||||
DoCastVictim(SPELL_DARK_SMASH);
|
||||
events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_DARK_SMASH, urand(12,16)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
break;
|
||||
case EVENT_DREADFUL_ROAR:
|
||||
DoCast(me, SPELL_DREADFUL_ROAR);
|
||||
events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
break;
|
||||
case EVENT_WOE_STRIKE:
|
||||
DoCastVictim(SPELL_WOE_STRIKE);
|
||||
@@ -271,8 +291,7 @@ public:
|
||||
case EVENT_SHADOW_AXE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
|
||||
{
|
||||
me->SummonCreature(ENTRY_THROW_TARGET, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2000);
|
||||
DoCast(me, SPELL_SHADOW_AXE_SUMMON);
|
||||
DoCast(target, SPELL_SHADOW_AXE_SUMMON);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
|
||||
break;
|
||||
@@ -430,32 +449,34 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
uint32 uiDespawnTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Unit* target = me->FindNearestCreature(ENTRY_THROW_TARGET, 50);
|
||||
if (target)
|
||||
if (Creature* target = me->FindNearestCreature(ENTRY_THROW_TARGET, 50.0f))
|
||||
{
|
||||
DoCast(me, SPELL_SHADOW_AXE_DAMAGE);
|
||||
float x, y, z;
|
||||
target->GetPosition(x, y, z);
|
||||
me->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
me->GetMotionMaster()->MoveCharge(x, y, z, 42.0f, 28);
|
||||
target->DisappearAndDie();
|
||||
}
|
||||
uiDespawnTimer = 7000;
|
||||
}
|
||||
void AttackStart(Unit* /*who*/) {}
|
||||
void MoveInLineOfSight(Unit* /*who*/) {}
|
||||
void EnterCombat(Unit* /*who*/) {}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (uiDespawnTimer <= diff)
|
||||
else
|
||||
{
|
||||
me->DealDamage(me, me->GetHealth());
|
||||
me->RemoveCorpse();
|
||||
uiDespawnTimer = 0;
|
||||
} else uiDespawnTimer -= diff;
|
||||
me->DisappearAndDie();
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == 28)
|
||||
{
|
||||
DoCast(me, SPELL_SHADOW_AXE_DAMAGE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
if (TempSummon* summon = me->ToTempSummon())
|
||||
{
|
||||
summon->UnSummon(10000);
|
||||
}
|
||||
else
|
||||
me->DisappearAndDie();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -43,6 +43,9 @@ enum KelsethEncounter
|
||||
NPC_FROSTTOMB = 23965,
|
||||
NPC_SKELETON = 23970,
|
||||
|
||||
NPC_RUNEMAGE = 23960,
|
||||
NPC_STRATEGIST = 23956,
|
||||
|
||||
SAY_START_COMBAT = 1,
|
||||
SAY_SUMMON_SKELETONS,
|
||||
SAY_FROST_TOMB,
|
||||
@@ -118,10 +121,7 @@ public:
|
||||
|
||||
struct boss_kelesethAI : public BossAI
|
||||
{
|
||||
boss_kelesethAI(Creature* creature) : BossAI(creature, DATA_PRINCEKELESETH_EVENT)
|
||||
{
|
||||
creature->SetReactState(REACT_DEFENSIVE);
|
||||
}
|
||||
boss_kelesethAI(Creature* creature) : BossAI(creature, DATA_PRINCEKELESETH_EVENT){}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
@@ -137,11 +137,36 @@ public:
|
||||
onTheRocks = true;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
instance->SetData(DATA_PRINCEKELESETH_EVENT, IN_PROGRESS);
|
||||
Talk(SAY_START_COMBAT);
|
||||
|
||||
if (!who)
|
||||
return;
|
||||
|
||||
std::list<Creature*> runemages;
|
||||
me->GetCreatureListWithEntryInGrid(runemages, NPC_RUNEMAGE, 60.0f);
|
||||
if (!runemages.empty())
|
||||
{
|
||||
for (std::list<Creature*>::iterator itr = runemages.begin(); itr != runemages.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->isAlive() && (*itr)->IsWithinLOSInMap(me))
|
||||
(*itr)->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
|
||||
std::list<Creature*> strategists;
|
||||
me->GetCreatureListWithEntryInGrid(strategists, NPC_STRATEGIST, 60.0f);
|
||||
if (!strategists.empty())
|
||||
{
|
||||
for (std::list<Creature*>::iterator itr = strategists.begin(); itr != strategists.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->isAlive() && (*itr)->IsWithinLOSInMap(me))
|
||||
(*itr)->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
@@ -165,10 +190,20 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 const eventId)
|
||||
void UpdateAI(uint32 const diff)
|
||||
{
|
||||
switch (eventId)
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SUMMON_SKELETONS:
|
||||
Talk(SAY_SUMMON_SKELETONS);
|
||||
SummonSkeletons();
|
||||
@@ -189,7 +224,10 @@ public:
|
||||
}
|
||||
events.ScheduleEvent(EVENT_FROST_TOMB, urand(14,19)*IN_MILLISECONDS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void SummonSkeletons()
|
||||
@@ -222,7 +260,6 @@ public:
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_DECREPIFY, urand(4,6)*IN_MILLISECONDS);
|
||||
|
||||
DoCast(SPELL_BONE_ARMOR);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*done_by*/, uint32 &damage)
|
||||
@@ -275,6 +312,13 @@ public:
|
||||
break;
|
||||
case EVENT_SHADOW_FISSURE:
|
||||
DoCast(me, SPELL_SHADOW_FISSURE, true);
|
||||
if (TempSummon* temp = me->ToTempSummon())
|
||||
{
|
||||
if (Unit* summoner = temp->GetSummoner())
|
||||
{
|
||||
DoCast(summoner, SPELL_BONE_ARMOR);
|
||||
}
|
||||
}
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
|
||||
me->GetMotionMaster()->MoveChase(me->getVictim());
|
||||
|
||||
@@ -47,6 +47,7 @@ enum eEnums
|
||||
SPELL_CHARGE = 43651,
|
||||
SPELL_STONE_STRIKE = 48583,
|
||||
SPELL_SUMMON_SKARVALD_GHOST = 48613,
|
||||
SPELL_ENRAGE = 48193,
|
||||
MOB_SKARVALD_GHOST = 27390,
|
||||
//Spells of Dalronn and his Ghost
|
||||
MOB_DALRONN_THE_CONTROLLER = 24201,
|
||||
@@ -58,6 +59,20 @@ enum eEnums
|
||||
MOB_DALRONN_GHOST = 27389
|
||||
};
|
||||
|
||||
class SkarvaldChargePredicate
|
||||
{
|
||||
public:
|
||||
SkarvaldChargePredicate(Unit* unit) : me(unit) {}
|
||||
|
||||
bool operator() (WorldObject* object) const
|
||||
{
|
||||
return object->GetDistance2d(me) >= 5.0f && object->GetDistance2d(me) <= 30.0f;
|
||||
}
|
||||
|
||||
private:
|
||||
Unit* me;
|
||||
};
|
||||
|
||||
class boss_skarvald_the_constructor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -83,6 +98,7 @@ public:
|
||||
uint32 Response_Timer;
|
||||
uint32 Check_Timer;
|
||||
bool Dalronn_isDead;
|
||||
bool Enraged;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
@@ -90,6 +106,7 @@ public:
|
||||
StoneStrike_Timer = 10000;
|
||||
Dalronn_isDead = false;
|
||||
Check_Timer = 5000;
|
||||
Enraged = false;
|
||||
|
||||
ghost = (me->GetEntry() == MOB_SKARVALD_GHOST);
|
||||
if (!ghost && instance)
|
||||
@@ -116,6 +133,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage)
|
||||
{
|
||||
if (!Enraged && !ghost && me->HealthBelowPctDamaged(15, damage))
|
||||
{
|
||||
Enraged = true;
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
if (!ghost && instance)
|
||||
@@ -194,7 +220,7 @@ public:
|
||||
|
||||
if (Charge_Timer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_CHARGE);
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, SkarvaldChargePredicate(me)), SPELL_CHARGE);
|
||||
Charge_Timer = 5000+rand()%5000;
|
||||
} else Charge_Timer -= diff;
|
||||
|
||||
@@ -204,7 +230,8 @@ public:
|
||||
StoneStrike_Timer = 5000+rand()%5000;
|
||||
} else StoneStrike_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "utgarde_keep.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
uint32 entry_search[3] =
|
||||
{
|
||||
@@ -164,7 +166,82 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
enum TickingTimeBomb
|
||||
{
|
||||
SPELL_TICKING_TIME_BOMB_EXPLODE = 59687
|
||||
};
|
||||
class spell_ticking_time_bomb : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ticking_time_bomb() : SpellScriptLoader("spell_ticking_time_bomb") { }
|
||||
|
||||
class spell_ticking_time_bomb_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ticking_time_bomb_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellEntry*/)
|
||||
{
|
||||
return (bool) sSpellMgr->GetSpellInfo(SPELL_TICKING_TIME_BOMB_EXPLODE);
|
||||
}
|
||||
|
||||
void HandleOnEffectRemove(AuraEffect const* /* aurEff */, AuraEffectHandleModes /* mode */)
|
||||
{
|
||||
if (GetCaster() == GetTarget())
|
||||
{
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_TICKING_TIME_BOMB_EXPLODE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_ticking_time_bomb_AuraScript::HandleOnEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_ticking_time_bomb_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
enum Fixate
|
||||
{
|
||||
SPELL_FIXATE_TRIGGER = 40415
|
||||
};
|
||||
class spell_fixate : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_fixate() : SpellScriptLoader("spell_fixate") { }
|
||||
|
||||
class spell_fixate_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_fixate_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellEntry*/)
|
||||
{
|
||||
return (bool) sSpellMgr->GetSpellInfo(SPELL_FIXATE_TRIGGER);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
// The unit has to cast the taunt on hisself, but we need the original caster for SPELL_AURA_MOD_TAUNT
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_FIXATE_TRIGGER, true, 0, 0, GetHitUnit()->GetGUID());
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_fixate_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_fixate_SpellScript();
|
||||
}
|
||||
};
|
||||
void AddSC_utgarde_keep()
|
||||
{
|
||||
new npc_dragonflayer_forge_master();
|
||||
new spell_ticking_time_bomb();
|
||||
new spell_fixate();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user