Merge branch 'master' of github.com:TrinityCore/TrinityCore

This commit is contained in:
Nay
2013-08-27 23:56:34 +01:00
11 changed files with 1183 additions and 1274 deletions

View File

@@ -0,0 +1 @@
UPDATE `instance_template` SET `script`='instance_vault_of_archavon' WHERE `map`=624;

View File

@@ -372,23 +372,36 @@ void AddSC_thunder_bluff();
void AddSC_ungoro_crater();
void AddSC_winterspring();
//northrend
// Northrend
void AddSC_boss_slad_ran();
void AddSC_boss_moorabi();
void AddSC_boss_drakkari_colossus();
void AddSC_boss_gal_darah();
void AddSC_boss_eck();
void AddSC_instance_gundrak();
void AddSC_boss_krik_thir(); //Azjol-Nerub
// Azjol-Nerub - Azjol-Nerub
void AddSC_boss_krik_thir();
void AddSC_boss_hadronox();
void AddSC_boss_anub_arak();
void AddSC_instance_azjol_nerub();
void AddSC_instance_ahnkahet(); //Azjol-Nerub Ahn'kahet
void AddSC_boss_amanitar();
void AddSC_boss_taldaram();
void AddSC_boss_jedoga_shadowseeker();
// Azjol-Nerub - Ahn'kahet
void AddSC_boss_elder_nadox();
void AddSC_boss_taldaram();
void AddSC_boss_amanitar();
void AddSC_boss_jedoga_shadowseeker();
void AddSC_boss_volazj();
void AddSC_instance_ahnkahet();
// Drak'Tharon Keep
void AddSC_boss_trollgore();
void AddSC_boss_novos();
void AddSC_boss_king_dred();
void AddSC_boss_tharon_ja();
void AddSC_instance_drak_tharon_keep();
void AddSC_boss_argent_challenge(); //Trial of the Champion
void AddSC_boss_black_knight();
void AddSC_boss_grand_champions();
@@ -457,26 +470,28 @@ void AddSC_boss_freya();
void AddSC_boss_yogg_saron();
void AddSC_boss_algalon_the_observer();
void AddSC_instance_ulduar();
void AddSC_boss_keleseth(); //Utgarde Keep
// Utgarde Keep - Utgarde Keep
void AddSC_boss_keleseth();
void AddSC_boss_skarvald_dalronn();
void AddSC_boss_ingvar_the_plunderer();
void AddSC_instance_utgarde_keep();
void AddSC_boss_svala(); //Utgarde pinnacle
void AddSC_utgarde_keep();
// Utgarde Keep - Utgarde Pinnacle
void AddSC_boss_svala();
void AddSC_boss_palehoof();
void AddSC_boss_skadi();
void AddSC_boss_ymiron();
void AddSC_instance_utgarde_pinnacle();
void AddSC_utgarde_keep();
void AddSC_boss_archavon(); //Vault of Archavon
// Vault of Archavon
void AddSC_boss_archavon();
void AddSC_boss_emalon();
void AddSC_boss_koralon();
void AddSC_boss_toravon();
void AddSC_instance_archavon();
void AddSC_boss_trollgore(); //Drak'Tharon Keep
void AddSC_boss_novos();
void AddSC_boss_king_dred();
void AddSC_boss_tharon_ja();
void AddSC_instance_drak_tharon_keep();
void AddSC_instance_vault_of_archavon();
void AddSC_boss_cyanigosa(); //Violet Hold
void AddSC_boss_erekem();
void AddSC_boss_ichoron();
@@ -1163,12 +1178,28 @@ void AddNorthrendScripts()
AddSC_boss_gal_darah();
AddSC_boss_eck();
AddSC_instance_gundrak();
AddSC_boss_amanitar();
AddSC_boss_taldaram(); //Azjol-Nerub Ahn'kahet
// Azjol-Nerub - Ahn'kahet
AddSC_boss_elder_nadox();
AddSC_boss_taldaram();
AddSC_boss_amanitar();
AddSC_boss_jedoga_shadowseeker();
AddSC_boss_volazj();
AddSC_instance_ahnkahet();
// Azjol-Nerub - Azjol-Nerub
AddSC_boss_krik_thir();
AddSC_boss_hadronox();
AddSC_boss_anub_arak();
AddSC_instance_azjol_nerub();
// Drak'Tharon Keep
AddSC_boss_trollgore();
AddSC_boss_novos();
AddSC_boss_king_dred();
AddSC_boss_tharon_ja();
AddSC_instance_drak_tharon_keep();
AddSC_boss_argent_challenge(); //Trial of the Champion
AddSC_boss_black_knight();
AddSC_boss_grand_champions();
@@ -1181,10 +1212,6 @@ void AddNorthrendScripts()
AddSC_boss_twin_valkyr();
AddSC_boss_northrend_beasts();
AddSC_instance_trial_of_the_crusader();
AddSC_boss_krik_thir(); //Azjol-Nerub Azjol-Nerub
AddSC_boss_hadronox();
AddSC_boss_anub_arak();
AddSC_instance_azjol_nerub();
AddSC_boss_anubrekhan(); //Naxxramas
AddSC_boss_maexxna();
AddSC_boss_patchwerk();
@@ -1241,26 +1268,28 @@ void AddNorthrendScripts()
AddSC_boss_yogg_saron();
AddSC_boss_algalon_the_observer();
AddSC_instance_ulduar();
AddSC_boss_keleseth(); //Utgarde Keep
// Utgarde Keep - Utgarde Keep
AddSC_boss_keleseth();
AddSC_boss_skarvald_dalronn();
AddSC_boss_ingvar_the_plunderer();
AddSC_instance_utgarde_keep();
AddSC_boss_svala(); //Utgarde pinnacle
AddSC_utgarde_keep();
// Utgarde Keep - Utgarde Pinnacle
AddSC_boss_svala();
AddSC_boss_palehoof();
AddSC_boss_skadi();
AddSC_boss_ymiron();
AddSC_instance_utgarde_pinnacle();
AddSC_utgarde_keep();
AddSC_boss_archavon(); //Vault of Archavon
// Vault of Archavon
AddSC_boss_archavon();
AddSC_boss_emalon();
AddSC_boss_koralon();
AddSC_boss_toravon();
AddSC_instance_archavon();
AddSC_boss_trollgore(); //Drak'Tharon Keep
AddSC_boss_novos();
AddSC_boss_king_dred();
AddSC_boss_tharon_ja();
AddSC_instance_drak_tharon_keep();
AddSC_instance_vault_of_archavon();
AddSC_boss_cyanigosa(); //Violet Hold
AddSC_boss_erekem();
AddSC_boss_ichoron();

View File

@@ -125,11 +125,11 @@ set(scripts_STAT_SRCS
Northrend/VaultOfArchavon/boss_emalon.cpp
Northrend/VaultOfArchavon/boss_toravon.cpp
Northrend/zone_sholazar_basin.cpp
Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
Northrend/UtgardeKeep/UtgardePinnacle/instance_pinnacle.cpp
Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp

View File

@@ -57,7 +57,10 @@ enum Events
EVENT_WOE_STRIKE,
EVENT_SHADOW_AXE,
EVENT_JUST_TRANSFORMED,
EVENT_SUMMON_BANSHEE
EVENT_SUMMON_BANSHEE,
EVENT_RESURRECT_1,
EVENT_RESURRECT_2
};
enum Phases
@@ -95,295 +98,277 @@ enum Spells
class boss_ingvar_the_plunderer : public CreatureScript
{
public:
boss_ingvar_the_plunderer() : CreatureScript("boss_ingvar_the_plunderer") { }
public:
boss_ingvar_the_plunderer() : CreatureScript("boss_ingvar_the_plunderer") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new boss_ingvar_the_plundererAI(creature);
}
struct boss_ingvar_the_plundererAI : public ScriptedAI
{
boss_ingvar_the_plundererAI(Creature* creature) : ScriptedAI(creature)
struct boss_ingvar_the_plundererAI : public BossAI
{
instance = creature->GetInstanceScript();
bIsUndead = false;
}
InstanceScript* instance;
bool bIsUndead;
void Reset() OVERRIDE
{
if (bIsUndead)
me->UpdateEntry(NPC_INGVAR_HUMAN);
bIsUndead = false;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
me->SetStandState(UNIT_STAND_STATE_STAND);
events.Reset();
events.SetPhase(PHASE_HUMAN);
events.ScheduleEvent(EVENT_CLEAVE, urand(6, 12)*IN_MILLISECONDS, 0, PHASE_HUMAN);
events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18, 21)*IN_MILLISECONDS, 0, PHASE_HUMAN);
events.ScheduleEvent(EVENT_ENRAGE, urand(7, 14)*IN_MILLISECONDS, 0, PHASE_HUMAN);
events.ScheduleEvent(EVENT_SMASH, urand(12, 17)*IN_MILLISECONDS, 0, PHASE_HUMAN);
if (instance)
instance->SetData(DATA_INGVAR_EVENT, NOT_STARTED);
}
void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE
{
if (damage >= me->GetHealth() && !bIsUndead)
boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR)
{
//DoCast(me, SPELL_INGVAR_FEIGN_DEATH, true); // Dont work ???
// visuel hack
me->SetHealth(0);
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->GetMotionMaster()->MovementExpired(false);
me->GetMotionMaster()->MoveIdle();
me->SetStandState(UNIT_STAND_STATE_DEAD);
// visuel hack end
events.SetPhase(PHASE_EVENT);
events.ScheduleEvent(EVENT_SUMMON_BANSHEE, 3 * IN_MILLISECONDS, 0, PHASE_EVENT);
Talk(YELL_DEAD_1);
_isUndead = false;
}
if (events.IsInPhase(PHASE_EVENT))
damage = 0;
}
void StartZombiePhase()
{
bIsUndead = true;
me->UpdateEntry(NPC_INGVAR_UNDEAD);
events.ScheduleEvent(EVENT_JUST_TRANSFORMED, 2 * IN_MILLISECONDS, 0, PHASE_EVENT);
Talk(YELL_AGGRO_2);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
if (!bIsUndead)
Talk(YELL_AGGRO_1);
if (instance)
instance->SetData(DATA_INGVAR_EVENT, IN_PROGRESS);
me->SetInCombatWithZone();
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
Talk(YELL_DEAD_2);
if (instance)
void Reset() OVERRIDE
{
if (_isUndead)
me->UpdateEntry(NPC_INGVAR_HUMAN);
_isUndead = false;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
me->SetStandState(UNIT_STAND_STATE_STAND);
_Reset();
events.SetPhase(PHASE_HUMAN);
events.ScheduleEvent(EVENT_CLEAVE, urand(6, 12)*IN_MILLISECONDS, 0, PHASE_HUMAN);
events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18, 21)*IN_MILLISECONDS, 0, PHASE_HUMAN);
events.ScheduleEvent(EVENT_ENRAGE, urand(7, 14)*IN_MILLISECONDS, 0, PHASE_HUMAN);
events.ScheduleEvent(EVENT_SMASH, urand(12, 17)*IN_MILLISECONDS, 0, PHASE_HUMAN);
}
void DamageTaken(Unit* /*doneBy*/, uint32& damage) OVERRIDE
{
if (damage >= me->GetHealth() && !_isUndead)
{
//DoCast(me, SPELL_INGVAR_FEIGN_DEATH, true); // Dont work ???
// visuel hack
me->SetHealth(0);
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->GetMotionMaster()->MovementExpired(false);
me->GetMotionMaster()->MoveIdle();
me->SetStandState(UNIT_STAND_STATE_DEAD);
// visuel hack end
events.SetPhase(PHASE_EVENT);
events.ScheduleEvent(EVENT_SUMMON_BANSHEE, 3 * IN_MILLISECONDS, 0, PHASE_EVENT);
Talk(YELL_DEAD_1);
}
if (events.IsInPhase(PHASE_EVENT))
damage = 0;
}
void StartZombiePhase()
{
_isUndead = true;
me->UpdateEntry(NPC_INGVAR_UNDEAD);
events.ScheduleEvent(EVENT_JUST_TRANSFORMED, 2 * IN_MILLISECONDS, 0, PHASE_EVENT);
Talk(YELL_AGGRO_2);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
if (!_isUndead)
Talk(YELL_AGGRO_1);
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
Talk(YELL_DEAD_2);
// Ingvar has NPC_INGVAR_UNDEAD id in this moment, so we have to update encounter state for his original id
instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, NPC_INGVAR_HUMAN, me);
instance->SetData(DATA_INGVAR_EVENT, DONE);
}
}
void ScheduleSecondPhase()
{
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);
}
void KilledUnit(Unit* /*victim*/) OVERRIDE
{
Talk(bIsUndead ? YELL_KILL_1 : YELL_KILL_2);
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim() && !events.IsInPhase(PHASE_EVENT))
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
void ScheduleSecondPhase()
{
switch (eventId)
{
// PHASE ONE
case EVENT_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, urand(6, 12)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_STAGGERING_ROAR:
DoCast(me, SPELL_STAGGERING_ROAR);
events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18, 22)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_ENRAGE:
DoCast(me, SPELL_ENRAGE);
events.ScheduleEvent(EVENT_ENRAGE, urand(7, 14)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_SMASH:
DoCastAOE(SPELL_SMASH);
events.ScheduleEvent(EVENT_SMASH, urand(12, 16)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_JUST_TRANSFORMED:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetInCombatWithZone();
me->GetMotionMaster()->MoveChase(me->GetVictim());
ScheduleSecondPhase();
return;
case EVENT_SUMMON_BANSHEE:
DoCast(me, SPELL_SUMMON_BANSHEE);
return;
// PHASE TWO
case EVENT_DARK_SMASH:
DoCastVictim(SPELL_DARK_SMASH);
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, 22)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
case EVENT_WOE_STRIKE:
DoCastVictim(SPELL_WOE_STRIKE);
events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10, 14)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
case EVENT_SHADOW_AXE:
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
{
DoCast(target, SPELL_SHADOW_AXE_SUMMON);
}
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
}
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);
}
DoMeleeAttackIfReady();
void KilledUnit(Unit* /*victim*/) OVERRIDE
{
Talk(_isUndead ? YELL_KILL_1 : YELL_KILL_2);
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim() && !events.IsInPhase(PHASE_EVENT))
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
// PHASE ONE
case EVENT_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, urand(6, 12)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_STAGGERING_ROAR:
DoCast(me, SPELL_STAGGERING_ROAR);
events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18, 22)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_ENRAGE:
DoCast(me, SPELL_ENRAGE);
events.ScheduleEvent(EVENT_ENRAGE, urand(7, 14)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_SMASH:
DoCastAOE(SPELL_SMASH);
events.ScheduleEvent(EVENT_SMASH, urand(12, 16)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_JUST_TRANSFORMED:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetInCombatWithZone();
me->GetMotionMaster()->MoveChase(me->GetVictim());
ScheduleSecondPhase();
return;
case EVENT_SUMMON_BANSHEE:
DoCast(me, SPELL_SUMMON_BANSHEE);
return;
// PHASE TWO
case EVENT_DARK_SMASH:
DoCastVictim(SPELL_DARK_SMASH);
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, 22)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
case EVENT_WOE_STRIKE:
DoCastVictim(SPELL_WOE_STRIKE);
events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10, 14)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
case EVENT_SHADOW_AXE:
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
DoCast(target, SPELL_SHADOW_AXE_SUMMON);
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
}
}
DoMeleeAttackIfReady();
}
private:
bool _isUndead;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return GetUtgardeKeepAI<boss_ingvar_the_plundererAI>(creature);
}
private:
EventMap events;
};
};
class npc_annhylde_the_caller : public CreatureScript
{
public:
npc_annhylde_the_caller() : CreatureScript("npc_annhylde_the_caller") { }
public:
npc_annhylde_the_caller() : CreatureScript("npc_annhylde_the_caller") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_annhylde_the_callerAI(creature);
}
struct npc_annhylde_the_callerAI : public ScriptedAI
{
npc_annhylde_the_callerAI(Creature* creature) : ScriptedAI(creature)
struct npc_annhylde_the_callerAI : public ScriptedAI
{
instance = creature->GetInstanceScript();
}
float x, y, z;
InstanceScript* instance;
uint32 uiResurectTimer;
uint32 uiResurectPhase;
void Reset() OVERRIDE
{
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
me->SetHover(true);
me->GetPosition(x, y, z);
DoTeleportTo(x+1, y, z+30);
Unit* ingvar = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_INGVAR) : 0);
if (ingvar)
npc_annhylde_the_callerAI(Creature* creature) : ScriptedAI(creature)
{
me->GetMotionMaster()->MovePoint(1, x, y, z+15);
// Talk(YELL_RESSURECT);
_instance = creature->GetInstanceScript();
}
}
void MovementInform(uint32 type, uint32 id) OVERRIDE
{
if (type != POINT_MOTION_TYPE)
return;
Unit* ingvar = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_INGVAR) : 0);
if (ingvar)
void Reset() OVERRIDE
{
switch (id)
_events.Reset();
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
me->SetHover(true);
me->GetPosition(x, y, z);
DoTeleportTo(x+1, y, z+30);
if (Creature* ingvar = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_INGVAR)))
{
case 1:
ingvar->RemoveAura(SPELL_SUMMON_BANSHEE);
ingvar->CastSpell(ingvar, SPELL_SCOURG_RESURRECTION_DUMMY, true);
DoCast(ingvar, SPELL_SCOURG_RESURRECTION_BEAM);
uiResurectTimer = 8000;
uiResurectPhase = 1;
break;
case 2:
me->SetVisible(false);
me->DealDamage(me, me->GetHealth());
me->RemoveCorpse();
break;
me->GetMotionMaster()->MovePoint(1, x, y, z+15);
// Talk(YELL_RESSURECT);
}
}
}
void AttackStart(Unit* /*who*/) OVERRIDE {}
void MoveInLineOfSight(Unit* /*who*/) OVERRIDE {}
void EnterCombat(Unit* /*who*/) OVERRIDE {}
void UpdateAI(uint32 diff) OVERRIDE
{
if (uiResurectTimer)
void MovementInform(uint32 type, uint32 id) OVERRIDE
{
if (uiResurectTimer <= diff)
if (type != POINT_MOTION_TYPE)
return;
if (Creature* ingvar = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_INGVAR)))
{
if (uiResurectPhase == 1)
switch (id)
{
Unit* ingvar = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_INGVAR) : 0);
if (ingvar)
{
ingvar->SetStandState(UNIT_STAND_STATE_STAND);
ingvar->CastSpell(ingvar, SPELL_SCOURG_RESURRECTION_HEAL, false);
}
uiResurectTimer = 3000;
uiResurectPhase = 2;
case 1:
ingvar->RemoveAura(SPELL_SUMMON_BANSHEE);
ingvar->CastSpell(ingvar, SPELL_SCOURG_RESURRECTION_DUMMY, true);
DoCast(ingvar, SPELL_SCOURG_RESURRECTION_BEAM);
_events.ScheduleEvent(EVENT_RESURRECT_1, 8000);
break;
case 2:
me->DespawnOrUnsummon();
break;
default:
break;
}
else if (uiResurectPhase == 2)
{
if (Creature* ingvar = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_INGVAR) : 0))
{
ingvar->RemoveAurasDueToSpell(SPELL_SCOURG_RESURRECTION_DUMMY);
if (ingvar->GetVictim())
if (boss_ingvar_the_plunderer::boss_ingvar_the_plundererAI* ai = CAST_AI(boss_ingvar_the_plunderer::boss_ingvar_the_plundererAI, ingvar->AI()))
ai->StartZombiePhase();
me->GetMotionMaster()->MovePoint(2, x+1, y, z+30);
++uiResurectPhase;
uiResurectTimer = 0;
}
}
} else uiResurectTimer -= diff;
}
}
void AttackStart(Unit* /*who*/) OVERRIDE { }
void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
void EnterCombat(Unit* /*who*/) OVERRIDE { }
void UpdateAI(uint32 diff) OVERRIDE
{
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_RESURRECT_1:
if (Creature* ingvar = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_INGVAR)))
{
ingvar->SetStandState(UNIT_STAND_STATE_STAND);
ingvar->CastSpell(ingvar, SPELL_SCOURG_RESURRECTION_HEAL, false);
}
_events.ScheduleEvent(EVENT_RESURRECT_2, 3000);
break;
case EVENT_RESURRECT_2:
if (Creature* ingvar = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_INGVAR)))
{
ingvar->RemoveAurasDueToSpell(SPELL_SCOURG_RESURRECTION_DUMMY);
if (ingvar->GetVictim())
if (boss_ingvar_the_plunderer::boss_ingvar_the_plundererAI* ai = CAST_AI(boss_ingvar_the_plunderer::boss_ingvar_the_plundererAI, ingvar->AI()))
ai->StartZombiePhase();
me->GetMotionMaster()->MovePoint(2, x+1, y, z+30);
}
break;
default:
break;
}
}
}
private:
InstanceScript* _instance;
EventMap _events;
float x, y, z;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return GetUtgardeKeepAI<npc_annhylde_the_callerAI>(creature);
}
};
};
enum ShadowAxe
@@ -428,12 +413,7 @@ public:
{
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();
me->DespawnOrUnsummon(10000);
}
}
};

View File

@@ -75,268 +75,247 @@ float AttackLoc[3]= {197.636f, 194.046f, 40.8164f};
class npc_frost_tomb : public CreatureScript
{
public:
npc_frost_tomb() : CreatureScript("npc_frost_tomb") {}
public:
npc_frost_tomb() : CreatureScript("npc_frost_tomb") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_frost_tombAI(creature);
}
struct npc_frost_tombAI : public ScriptedAI
{
npc_frost_tombAI(Creature* creature) : ScriptedAI(creature)
struct npc_frost_tombAI : public ScriptedAI
{
if (me->IsSummon())
if (Unit* summon = me->ToTempSummon()->GetSummoner())
DoCast(summon, SPELL_FROST_TOMB, true);
npc_frost_tombAI(Creature* creature) : ScriptedAI(creature)
{
_instance = creature->GetInstanceScript();
}
instance = creature->GetInstanceScript();
}
void IsSummonedBy(Unit* summoner) OVERRIDE
{
DoCast(summoner, SPELL_FROST_TOMB, true);
}
void UpdateAI(uint32 /*diff*/) OVERRIDE {}
void UpdateAI(uint32 /*diff*/) OVERRIDE { }
void JustDied(Unit* /*killer*/) OVERRIDE
void JustDied(Unit* /*killer*/) OVERRIDE
{
if (Creature* keleseth = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_PRINCE_KELESETH)))
keleseth->AI()->SetData(DATA_ON_THE_ROCKS, false);
}
private:
InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
if (instance)
if (Unit* boss = me->GetUnit(*me, instance->GetData64(DATA_PRINCEKELESETH)))
if (boss->ToCreature() && boss->ToCreature()->AI())
boss->ToCreature()->AI()->SetData(DATA_ON_THE_ROCKS, false);
return GetUtgardeKeepAI<npc_frost_tombAI>(creature);
}
private:
InstanceScript* instance;
};
};
class boss_keleseth : public CreatureScript
{
public:
boss_keleseth() : CreatureScript("boss_keleseth") {}
public:
boss_keleseth() : CreatureScript("boss_keleseth") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new boss_kelesethAI(creature);
}
struct boss_kelesethAI : public BossAI
{
boss_kelesethAI(Creature* creature) : BossAI(creature, DATA_PRINCEKELESETH_EVENT){}
void Reset() OVERRIDE
struct boss_kelesethAI : public BossAI
{
if (instance)
instance->SetData(DATA_PRINCEKELESETH_EVENT, NOT_STARTED);
boss_kelesethAI(Creature* creature) : BossAI(creature, DATA_PRINCE_KELESETH) { }
events.Reset();
events.ScheduleEvent(EVENT_SHADOWBOLT, urand(2, 3)*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_FROST_TOMB, urand(14, 19)*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SUMMON_SKELETONS, 6*IN_MILLISECONDS);
summons.DespawnAll();
onTheRocks = true;
}
void EnterCombat(Unit* who) OVERRIDE
{
me->SetInCombatWithZone();
if (instance)
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())
void Reset() OVERRIDE
{
for (std::list<Creature*>::iterator itr = runemages.begin(); itr != runemages.end(); ++itr)
{
if ((*itr)->IsAlive() && (*itr)->IsWithinLOSInMap(me))
(*itr)->AI()->AttackStart(who);
}
_Reset();
events.ScheduleEvent(EVENT_SHADOWBOLT, urand(2, 3)*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_FROST_TOMB, urand(14, 19)*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SUMMON_SKELETONS, 6*IN_MILLISECONDS);
onTheRocks = true;
}
std::list<Creature*> strategists;
me->GetCreatureListWithEntryInGrid(strategists, NPC_STRATEGIST, 60.0f);
if (!strategists.empty())
void EnterCombat(Unit* who) OVERRIDE
{
for (std::list<Creature*>::iterator itr = strategists.begin(); itr != strategists.end(); ++itr)
_EnterCombat();
Talk(SAY_START_COMBAT);
if (!who)
return;
std::list<Creature*> guards;
me->GetCreatureListWithEntryInGrid(guards, NPC_RUNEMAGE, 60.0f);
me->GetCreatureListWithEntryInGrid(guards, NPC_STRATEGIST, 60.0f);
if (!guards.empty())
{
if ((*itr)->IsAlive() && (*itr)->IsWithinLOSInMap(me))
(*itr)->AI()->AttackStart(who);
}
}
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
if (instance)
instance->SetData(DATA_PRINCEKELESETH_EVENT, DONE);
summons.DespawnAll();
Talk(SAY_DEATH);
}
void SetData(uint32 data, uint32 value) OVERRIDE
{
if (data == DATA_ON_THE_ROCKS)
onTheRocks = value;
}
uint32 GetData(uint32 data) const OVERRIDE
{
if (data == DATA_ON_THE_ROCKS)
return onTheRocks;
return 0;
}
void UpdateAI(uint32 diff) OVERRIDE
{
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();
break;
case EVENT_SHADOWBOLT:
DoCastVictim(SPELL_SHADOWBOLT);
events.ScheduleEvent(EVENT_SHADOWBOLT, urand(2, 3)*IN_MILLISECONDS);
break;
case EVENT_FROST_TOMB:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true, -SPELL_FROST_TOMB))
for (std::list<Creature*>::iterator itr = guards.begin(); itr != guards.end(); ++itr)
{
Talk(SAY_FROST_TOMB);
Talk(SAY_FROST_TOMB_EMOTE, target->GetGUID());
DoCast(target, SPELL_FROST_TOMB_STUN, true);
// checked from sniffs - the player casts the spell
target->CastSpell(target, SPELL_FROST_TOMB_SUMMON, true);
if ((*itr)->IsAlive() && (*itr)->IsWithinLOSInMap(me))
(*itr)->AI()->AttackStart(who);
}
events.ScheduleEvent(EVENT_FROST_TOMB, urand(14, 19)*IN_MILLISECONDS);
break;
}
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
Talk(SAY_DEATH);
}
void SummonSkeletons()
void SetData(uint32 data, uint32 value) OVERRIDE
{
if (data == DATA_ON_THE_ROCKS)
onTheRocks = value;
}
uint32 GetData(uint32 data) const OVERRIDE
{
if (data == DATA_ON_THE_ROCKS)
return onTheRocks;
return 0;
}
void UpdateAI(uint32 diff) OVERRIDE
{
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();
break;
case EVENT_SHADOWBOLT:
DoCastVictim(SPELL_SHADOWBOLT);
events.ScheduleEvent(EVENT_SHADOWBOLT, urand(2, 3) * IN_MILLISECONDS);
break;
case EVENT_FROST_TOMB:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true, -SPELL_FROST_TOMB))
{
Talk(SAY_FROST_TOMB);
Talk(SAY_FROST_TOMB_EMOTE, target->GetGUID());
DoCast(target, SPELL_FROST_TOMB_STUN, true);
// checked from sniffs - the player casts the spell
target->CastSpell(target, SPELL_FROST_TOMB_SUMMON, true);
}
events.ScheduleEvent(EVENT_FROST_TOMB, urand(14, 19) * IN_MILLISECONDS);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void SummonSkeletons()
{
// I could not found any spell casted for this
for (uint8 i = 0; i < 4; ++i)
me->SummonCreature(NPC_SKELETON, SkeletonSpawnPoint[0][0], SkeletonSpawnPoint[0][1], SKELETONSPAWN_Z, 0);
}
private:
bool onTheRocks;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
// I could not found any spell casted for this
for (uint8 i = 0; i < 4; ++i)
me->SummonCreature(NPC_SKELETON, SkeletonSpawnPoint[0][0], SkeletonSpawnPoint[0][1], SKELETONSPAWN_Z, 0);
return GetUtgardeKeepAI<boss_kelesethAI>(creature);
}
private:
bool onTheRocks;
};
};
class npc_vrykul_skeleton : public CreatureScript
{
public:
npc_vrykul_skeleton() : CreatureScript("npc_vrykul_skeleton") {}
public:
npc_vrykul_skeleton() : CreatureScript("npc_vrykul_skeleton") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_vrykul_skeletonAI(creature);
}
struct npc_vrykul_skeletonAI : public ScriptedAI
{
npc_vrykul_skeletonAI(Creature* creature) : ScriptedAI(creature) {}
void Reset() OVERRIDE
struct npc_vrykul_skeletonAI : public ScriptedAI
{
events.Reset();
events.ScheduleEvent(EVENT_DECREPIFY, urand(4, 6)*IN_MILLISECONDS);
npc_vrykul_skeletonAI(Creature* creature) : ScriptedAI(creature) { }
}
void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE
{
if (damage >= me->GetHealth())
void Reset() OVERRIDE
{
damage = 0;
events.Reset();
events.ScheduleEvent(EVENT_DECREPIFY, urand(4, 6) * IN_MILLISECONDS);
}
void DamageTaken(Unit* /*doneBy*/, uint32& damage) OVERRIDE
{
if (damage >= me->GetHealth())
{
damage = 0;
// There are some issues with pets
// they will still attack. I would say it is a PetAI bug
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
{
// from sniffs
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
events.Reset();
events.ScheduleEvent(EVENT_RESURRECT, urand(18, 22) * IN_MILLISECONDS);
me->GetMotionMaster()->MovementExpired(false);
me->GetMotionMaster()->MoveIdle();
}
}
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_DECREPIFY:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_DECREPIFY))
DoCast(target, SPELL_DECREPIFY);
events.ScheduleEvent(EVENT_DECREPIFY, urand(1, 5)*IN_MILLISECONDS);
break;
case EVENT_RESURRECT:
events.ScheduleEvent(EVENT_FULL_HEAL, 1 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SHADOW_FISSURE, 1 * IN_MILLISECONDS);
break;
case EVENT_FULL_HEAL:
DoCast(me, SPELL_FULL_HEAL, true);
break;
case EVENT_SHADOW_FISSURE:
DoCast(me, SPELL_SHADOW_FISSURE, true);
DoCastAOE(SPELL_BONE_ARMOR, true);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->RemoveFlag(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
me->GetMotionMaster()->MoveChase(me->GetVictim());
events.ScheduleEvent(EVENT_DECREPIFY, urand(4, 6) * IN_MILLISECONDS);
break;
default:
break;
}
}
// There are some issues with pets
// they will still attack. I would say it is a PetAI bug
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
{
// from sniffs
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
events.Reset();
events.ScheduleEvent(EVENT_RESURRECT, urand(18, 22)*IN_MILLISECONDS);
me->GetMotionMaster()->MovementExpired(false);
me->GetMotionMaster()->MoveIdle();
}
DoMeleeAttackIfReady();
}
}
void UpdateAI(uint32 diff) OVERRIDE
private:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_DECREPIFY:
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_DECREPIFY), SPELL_DECREPIFY);
events.ScheduleEvent(EVENT_DECREPIFY, urand(1, 5)*IN_MILLISECONDS);
break;
case EVENT_RESURRECT:
events.ScheduleEvent(EVENT_FULL_HEAL, 1*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SHADOW_FISSURE, 1*IN_MILLISECONDS);
break;
case EVENT_FULL_HEAL:
DoCast(me, SPELL_FULL_HEAL, true);
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());
events.ScheduleEvent(EVENT_DECREPIFY, urand(4, 6)*IN_MILLISECONDS);
break;
}
}
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
DoMeleeAttackIfReady();
return GetUtgardeKeepAI<npc_vrykul_skeletonAI>(creature);
}
private:
EventMap events;
};
};
class spell_frost_tomb : public SpellScriptLoader
@@ -347,12 +326,14 @@ class spell_frost_tomb : public SpellScriptLoader
class spell_frost_tomb_AuraScript : public AuraScript
{
PrepareAuraScript(spell_frost_tomb_AuraScript);
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
if (Unit* caster = GetCaster())
if (caster->ToCreature() && caster->IsAlive())
caster->ToCreature()->DespawnOrUnsummon(1000);
if (caster->IsAlive())
if (Creature* creature = caster->ToCreature())
creature->DespawnOrUnsummon(1000);
}
void Register() OVERRIDE

View File

@@ -58,14 +58,6 @@ enum Spells
SPELL_SUMMON_DALRONN_GHOST = 48612,
};
enum Creatures
{
NPC_SKARVALD_THE_CONSTRUCTOR = 24200,
NPC_SKARVALD_GHOST = 27390,
NPC_DALRONN_THE_CONTROLLER = 24201,
NPC_DALRONN_GHOST = 27389
};
class SkarvaldChargePredicate
{
public:
@@ -82,355 +74,334 @@ class SkarvaldChargePredicate
class boss_skarvald_the_constructor : public CreatureScript
{
public:
boss_skarvald_the_constructor() : CreatureScript("boss_skarvald_the_constructor") { }
public:
boss_skarvald_the_constructor() : CreatureScript("boss_skarvald_the_constructor") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new boss_skarvald_the_constructorAI(creature);
}
struct boss_skarvald_the_constructorAI : public ScriptedAI
{
boss_skarvald_the_constructorAI(Creature* creature) : ScriptedAI(creature)
struct boss_skarvald_the_constructorAI : public BossAI
{
instance = creature->GetInstanceScript();
}
boss_skarvald_the_constructorAI(Creature* creature) : BossAI(creature, DATA_SKARVALD_DALRONN) { }
InstanceScript* instance;
bool ghost;
uint32 Charge_Timer;
uint32 StoneStrike_Timer;
uint32 Response_Timer;
uint32 Check_Timer;
bool Dalronn_isDead;
bool Enraged;
bool ghost;
uint32 Charge_Timer;
uint32 StoneStrike_Timer;
uint32 Response_Timer;
uint32 Check_Timer;
bool Dalronn_isDead;
bool Enraged;
void Reset() OVERRIDE
{
Charge_Timer = 5000;
StoneStrike_Timer = 10000;
Dalronn_isDead = false;
Response_Timer = 0;
Check_Timer = 5000;
Enraged = false;
ghost = (me->GetEntry() == NPC_SKARVALD_GHOST);
if (!ghost && instance)
void Reset() OVERRIDE
{
Unit* dalronn = Unit::GetUnit(*me, instance->GetData64(DATA_DALRONN));
if (dalronn && dalronn->isDead())
dalronn->ToCreature()->Respawn();
Charge_Timer = 5000;
StoneStrike_Timer = 10000;
Dalronn_isDead = false;
Response_Timer = 0;
Check_Timer = 5000;
Enraged = false;
instance->SetData(DATA_SKARVALD_DALRONN_EVENT, NOT_STARTED);
ghost = me->GetEntry() == NPC_SKARVALD_GHOST;
if (!ghost)
_Reset();
}
}
void EnterCombat(Unit* who) OVERRIDE
{
if (!ghost && instance)
void EnterCombat(Unit* /*who*/) OVERRIDE
{
Talk(YELL_SKARVALD_AGGRO);
Unit* dalronn = Unit::GetUnit(*me, instance->GetData64(DATA_DALRONN));
if (dalronn && dalronn->IsAlive() && !dalronn->GetVictim())
dalronn->getThreatManager().addThreat(who, 0.0f);
instance->SetData(DATA_SKARVALD_DALRONN_EVENT, IN_PROGRESS);
}
}
void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
{
if (!Enraged && !ghost && me->HealthBelowPctDamaged(15, damage))
{
Enraged = true;
DoCast(me, SPELL_ENRAGE);
}
}
void JustDied(Unit* killer) OVERRIDE
{
if (!ghost && instance)
{
Unit* dalronn = Unit::GetUnit(*me, instance->GetData64(DATA_DALRONN));
if (dalronn)
if (!ghost)
{
if (dalronn->isDead())
{
Talk(YELL_SKARVALD_DAL_DIED);
_EnterCombat();
Talk(YELL_SKARVALD_AGGRO);
}
}
instance->SetData(DATA_SKARVALD_DALRONN_EVENT, DONE);
}
else
{
Talk(YELL_SKARVALD_SKA_DIEDFIRST);
void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
{
if (!Enraged && !ghost && me->HealthBelowPctDamaged(15, damage))
{
Enraged = true;
DoCast(me, SPELL_ENRAGE);
}
}
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
//DoCast(me, SPELL_SUMMON_SKARVALD_GHOST, true);
Creature* temp = me->SummonCreature(NPC_SKARVALD_GHOST, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 5000);
if (temp)
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())
{
temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
temp->AI()->AttackStart(killer);
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* /*victim*/) OVERRIDE
{
if (!ghost)
void KilledUnit(Unit* who) OVERRIDE
{
Talk(YELL_SKARVALD_KILL);
}
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (ghost)
{
if (instance && instance->GetData(DATA_SKARVALD_DALRONN_EVENT) != IN_PROGRESS)
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
if (!ghost && who->GetTypeId() == TYPEID_PLAYER)
Talk(YELL_SKARVALD_KILL);
}
if (!UpdateVictim())
return;
if (!ghost)
void UpdateAI(uint32 diff) OVERRIDE
{
if (Check_Timer)
if (!UpdateVictim())
return;
if (!ghost)
{
if (Check_Timer <= diff)
if (Check_Timer)
{
Check_Timer = 5000;
Unit* dalronn = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_DALRONN) : 0);
if (dalronn && dalronn->isDead())
if (Check_Timer <= diff)
{
Dalronn_isDead = true;
Response_Timer = 2000;
Check_Timer = 0;
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)
else
Check_Timer -= diff;
}
if (Response_Timer && Dalronn_isDead)
{
Talk(YELL_SKARVALD_DAL_DIEDFIRST);
if (Response_Timer <= diff)
{
Talk(YELL_SKARVALD_DAL_DIEDFIRST);
Response_Timer = 0;
} else Response_Timer -= diff;
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+rand()%5000;
}
else
Charge_Timer -= diff;
if (StoneStrike_Timer <= diff)
{
DoCastVictim(SPELL_STONE_STRIKE);
StoneStrike_Timer = 5000+rand()%5000;
}
else
StoneStrike_Timer -= diff;
if (!me->HasUnitState(UNIT_STATE_CASTING))
DoMeleeAttackIfReady();
}
};
if (Charge_Timer <= diff)
{
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, SkarvaldChargePredicate(me)), SPELL_CHARGE);
Charge_Timer = 5000+rand()%5000;
} else Charge_Timer -= diff;
if (StoneStrike_Timer <= diff)
{
DoCastVictim(SPELL_STONE_STRIKE);
StoneStrike_Timer = 5000+rand()%5000;
} else StoneStrike_Timer -= diff;
if (!me->HasUnitState(UNIT_STATE_CASTING))
DoMeleeAttackIfReady();
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return GetUtgardeKeepAI<boss_skarvald_the_constructorAI>(creature);
}
};
};
class boss_dalronn_the_controller : public CreatureScript
{
public:
boss_dalronn_the_controller() : CreatureScript("boss_dalronn_the_controller") { }
public:
boss_dalronn_the_controller() : CreatureScript("boss_dalronn_the_controller") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new boss_dalronn_the_controllerAI(creature);
}
struct boss_dalronn_the_controllerAI : public ScriptedAI
{
boss_dalronn_the_controllerAI(Creature* creature) : ScriptedAI(creature)
struct boss_dalronn_the_controllerAI : public BossAI
{
instance = creature->GetInstanceScript();
}
boss_dalronn_the_controllerAI(Creature* creature) : BossAI(creature, DATA_SKARVALD_DALRONN) { }
InstanceScript* instance;
bool ghost;
uint32 ShadowBolt_Timer;
uint32 Debilitate_Timer;
uint32 Summon_Timer;
bool ghost;
uint32 ShadowBolt_Timer;
uint32 Debilitate_Timer;
uint32 Summon_Timer;
uint32 Response_Timer;
uint32 Check_Timer;
uint32 AggroYell_Timer;
bool Skarvald_isDead;
uint32 Response_Timer;
uint32 Check_Timer;
uint32 AggroYell_Timer;
bool Skarvald_isDead;
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 && instance)
void Reset() OVERRIDE
{
Unit* skarvald = Unit::GetUnit(*me, instance->GetData64(DATA_SKARVALD));
if (skarvald && skarvald->isDead())
skarvald->ToCreature()->Respawn();
ShadowBolt_Timer = 1000;
Debilitate_Timer = 5000;
Summon_Timer = 10000;
Check_Timer = 5000;
Skarvald_isDead = false;
Response_Timer = 0;
AggroYell_Timer = 0;
instance->SetData(DATA_SKARVALD_DALRONN_EVENT, NOT_STARTED);
ghost = me->GetEntry() == NPC_DALRONN_GHOST;
if (!ghost)
_Reset();
}
}
void EnterCombat(Unit* who) OVERRIDE
{
if (!ghost && instance)
void EnterCombat(Unit* /*who*/) OVERRIDE
{
Unit* skarvald = Unit::GetUnit(*me, instance->GetData64(DATA_SKARVALD));
if (skarvald && skarvald->IsAlive() && !skarvald->GetVictim())
skarvald->getThreatManager().addThreat(who, 0.0f);
AggroYell_Timer = 5000;
if (instance)
instance->SetData(DATA_SKARVALD_DALRONN_EVENT, IN_PROGRESS);
}
}
void JustDied(Unit* killer) OVERRIDE
{
if (!ghost && instance)
{
Unit* skarvald = Unit::GetUnit(*me, instance->GetData64(DATA_SKARVALD));
if (skarvald)
if (!ghost)
{
if (skarvald->isDead())
{
Talk(YELL_DALRONN_SKA_DIED);
_EnterCombat();
AggroYell_Timer = 5000;
}
}
if (instance)
instance->SetData(DATA_SKARVALD_DALRONN_EVENT, DONE);
void DoAction(int32 /*actionId*/)
{
summons.DespawnAll();
}
void JustDied(Unit* killer) OVERRIDE
{
if (!ghost)
{
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
{
Talk(YELL_DALRONN_DAL_DIEDFIRST);
AggroYell_Timer -= diff;
}
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
//DoCast(me, SPELL_SUMMON_DALRONN_GHOST, true);
Creature* temp = me->SummonCreature(NPC_DALRONN_GHOST, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 5000);
if (temp)
if (!ghost)
{
if (Check_Timer)
{
if (Check_Timer <= diff)
{
temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
temp->AI()->AttackStart(killer);
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;
}
}
}
}
void KilledUnit(Unit* /*victim*/) OVERRIDE
{
if (!ghost)
{
Talk(YELL_DALRONN_KILL);
}
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (ghost)
{
if (instance && instance->GetData(DATA_SKARVALD_DALRONN_EVENT) != IN_PROGRESS)
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
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;
Unit* skarvald = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_SKARVALD) : 0);
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->IsNonMeleeSpellCasted(false))
{
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), 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->IsNonMeleeSpellCasted(false))
{
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_DEBILITATE);
Debilitate_Timer = 5000+rand()%5000;
}
} else Debilitate_Timer -= diff;
if (IsHeroic())
{
if (Summon_Timer <= diff)
if (ShadowBolt_Timer <= diff)
{
if (!me->IsNonMeleeSpellCasted(false))
{
DoCast(me, H_SPELL_SUMMON_SKELETONS);
Summon_Timer = (rand()%10000) + 20000;
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 Summon_Timer -= diff;
}
else
ShadowBolt_Timer -= diff;
if (Debilitate_Timer <= diff)
{
if (!me->IsNonMeleeSpellCasted(false))
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
DoCast(target, SPELL_DEBILITATE);
Debilitate_Timer = 5000+rand()%5000;
}
}
else
Debilitate_Timer -= diff;
if (IsHeroic())
{
if (Summon_Timer <= diff)
{
if (!me->IsNonMeleeSpellCasted(false))
{
DoCast(me, H_SPELL_SUMMON_SKELETONS);
Summon_Timer = (rand()%10000) + 20000;
}
}
else
Summon_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
DoMeleeAttackIfReady();
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return GetUtgardeKeepAI<boss_dalronn_the_controllerAI>(creature);
}
};
};
void AddSC_boss_skarvald_dalronn()

View File

@@ -15,300 +15,244 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Instance_Utgarde_Keep
SD%Complete: 90
SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Utgarde Keep Scripts
SDCategory: Utgarde Keep
EndScriptData */
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "utgarde_keep.h"
#include "Player.h"
#define MAX_ENCOUNTER 3
DoorData const doorData[] =
{
{ GO_GIANT_PORTCULLIS_1, DATA_INGVAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{ GO_GIANT_PORTCULLIS_2, DATA_INGVAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
};
#define ENTRY_BELLOW_1 186688
#define ENTRY_BELLOW_2 186689
#define ENTRY_BELLOW_3 186690
#define ENTRY_FORGEFIRE_1 186692
#define ENTRY_FORGEFIRE_2 186693
#define ENTRY_FORGEFIRE_3 186691
#define ENTRY_GLOWING_ANVIL_1 186609
#define ENTRY_GLOWING_ANVIL_2 186610
#define ENTRY_GLOWING_ANVIL_3 186611
#define ENTRY_GIANT_PORTCULLIS_1 186756
#define ENTRY_GIANT_PORTCULLIS_2 186694
/* Utgarde Keep encounters:
0 - Prince Keleseth
1 - Skarvald Dalronn
2 - Ingvar the Plunderer
*/
MinionData const minionData[] =
{
{ NPC_SKARVALD, DATA_SKARVALD_DALRONN },
{ NPC_DALRONN, DATA_SKARVALD_DALRONN }
};
class instance_utgarde_keep : public InstanceMapScript
{
public:
instance_utgarde_keep() : InstanceMapScript("instance_utgarde_keep", 574) { }
public:
instance_utgarde_keep() : InstanceMapScript(UKScriptName, 574) { }
InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
{
return new instance_utgarde_keep_InstanceMapScript(map);
}
struct instance_utgarde_keep_InstanceMapScript : public InstanceScript
{
instance_utgarde_keep_InstanceMapScript(Map* map) : InstanceScript(map) {}
uint64 Keleseth;
uint64 Skarvald;
uint64 Dalronn;
uint64 Ingvar;
uint64 forge_bellow[3];
uint64 forge_fire[3];
uint64 forge_anvil[3];
uint64 portcullis[2];
uint32 m_auiEncounter[MAX_ENCOUNTER];
uint32 forge_event[3];
std::string str_data;
void Initialize() OVERRIDE
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
Keleseth = 0;
Skarvald = 0;
Dalronn = 0;
Ingvar = 0;
for (uint8 i = 0; i < 3; ++i)
struct instance_utgarde_keep_InstanceMapScript : public InstanceScript
{
instance_utgarde_keep_InstanceMapScript(Map* map) : InstanceScript(map)
{
forge_bellow[i] = 0;
forge_fire[i] = 0;
forge_anvil[i] = 0;
forge_event[i] = NOT_STARTED;
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
LoadMinionData(minionData);
PrinceKelesethGUID = 0;
SkarvaldGUID = 0;
DalronnGUID = 0;
IngvarGUID = 0;
}
portcullis[0] = 0;
portcullis[1] = 0;
}
bool IsEncounterInProgress() const OVERRIDE
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
return true;
return false;
}
Player* GetPlayerInMap()
{
Map::PlayerList const& players = instance->GetPlayers();
if (!players.isEmpty())
void OnCreatureCreate(Creature* creature) OVERRIDE
{
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
switch (creature->GetEntry())
{
if (Player* player = itr->GetSource())
return player;
case NPC_PRINCE_KELESETH:
PrinceKelesethGUID = creature->GetGUID();
break;
case NPC_SKARVALD:
SkarvaldGUID = creature->GetGUID();
AddMinion(creature, true);
break;
case NPC_DALRONN:
DalronnGUID = creature->GetGUID();
AddMinion(creature, true);
break;
case NPC_INGVAR:
IngvarGUID = creature->GetGUID();
break;
default:
break;
}
}
TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance Utgarde Keep: GetPlayerInMap, but PlayerList is empty!");
return NULL;
}
void OnCreatureCreate(Creature* creature) OVERRIDE
{
switch (creature->GetEntry())
void OnCreatureRemove(Creature* creature) OVERRIDE
{
case 23953: Keleseth = creature->GetGUID(); break;
case 24201: Dalronn = creature->GetGUID(); break;
case 24200: Skarvald = creature->GetGUID(); break;
case 23954: Ingvar = creature->GetGUID(); break;
}
}
void OnGameObjectCreate(GameObject* go) OVERRIDE
{
switch (go->GetEntry())
{
//door and object id
case ENTRY_BELLOW_1: forge_bellow[0] = go->GetGUID();
if (forge_event[0] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_BELLOW_2: forge_bellow[1] = go->GetGUID();
if (forge_event[1] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_BELLOW_3: forge_bellow[2] = go->GetGUID();
if (forge_event[2] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_FORGEFIRE_1: forge_fire[0] = go->GetGUID();
if (forge_event[0] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_FORGEFIRE_2: forge_fire[1] = go->GetGUID();
if (forge_event[1] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_FORGEFIRE_3: forge_fire[2] = go->GetGUID();
if (forge_event[2] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_GLOWING_ANVIL_1: forge_anvil[0] = go->GetGUID();
if (forge_event[0] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_GLOWING_ANVIL_2: forge_anvil[1] = go->GetGUID();
if (forge_event[1] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_GLOWING_ANVIL_3: forge_anvil[2] = go->GetGUID();
if (forge_event[2] != NOT_STARTED)HandleGameObject(0, true, go);break;
case ENTRY_GIANT_PORTCULLIS_1: portcullis[0] = go->GetGUID();
if (m_auiEncounter[2] == DONE)HandleGameObject(0, true, go);break;
case ENTRY_GIANT_PORTCULLIS_2: portcullis[1] = go->GetGUID();
if (m_auiEncounter[2] == DONE)HandleGameObject(0, true, go);break;
}
}
uint64 GetData64(uint32 identifier) const OVERRIDE
{
switch (identifier)
{
case DATA_PRINCEKELESETH: return Keleseth;
case DATA_DALRONN: return Dalronn;
case DATA_SKARVALD: return Skarvald;
case DATA_INGVAR: return Ingvar;
}
return 0;
}
void SetData(uint32 type, uint32 data) OVERRIDE
{
switch (type)
{
case DATA_PRINCEKELESETH_EVENT:
m_auiEncounter[0] = data;
break;
case DATA_SKARVALD_DALRONN_EVENT:
m_auiEncounter[1] = data;
break;
case DATA_INGVAR_EVENT:
if (data == DONE)
switch (creature->GetEntry())
{
HandleGameObject(portcullis[0], true);
HandleGameObject(portcullis[1], true);
case NPC_SKARVALD:
case NPC_DALRONN:
AddMinion(creature, false);
break;
default:
break;
}
m_auiEncounter[2] = data;
break;
case EVENT_FORGE_1:
if (data == NOT_STARTED)
}
void OnGameObjectCreate(GameObject* go) OVERRIDE
{
switch (go->GetEntry())
{
HandleGameObject(forge_bellow[0], false);
HandleGameObject(forge_fire[0], false);
HandleGameObject(forge_anvil[0], false);
}else
{
HandleGameObject(forge_bellow[0], true);
HandleGameObject(forge_fire[0], true);
HandleGameObject(forge_anvil[0], true);
case GO_BELLOW_1:
Forges[0].BellowGUID = go->GetGUID();
HandleGameObject(0, Forges[0].Event != NOT_STARTED, go);
break;
case GO_BELLOW_2:
Forges[1].BellowGUID = go->GetGUID();
HandleGameObject(0, Forges[1].Event != NOT_STARTED, go);
break;
case GO_BELLOW_3:
Forges[2].BellowGUID = go->GetGUID();
HandleGameObject(0, Forges[2].Event != NOT_STARTED, go);
break;
case GO_FORGEFIRE_1:
Forges[0].FireGUID = go->GetGUID();
HandleGameObject(0, Forges[0].Event != NOT_STARTED, go);
break;
case GO_FORGEFIRE_2:
Forges[1].FireGUID = go->GetGUID();
HandleGameObject(0, Forges[1].Event != NOT_STARTED, go);
break;
case GO_FORGEFIRE_3:
Forges[2].FireGUID = go->GetGUID();
HandleGameObject(0, Forges[2].Event != NOT_STARTED, go);
break;
case GO_GLOWING_ANVIL_1:
Forges[0].AnvilGUID = go->GetGUID();
HandleGameObject(0, Forges[0].Event != NOT_STARTED, go);
break;
case GO_GLOWING_ANVIL_2:
Forges[1].AnvilGUID = go->GetGUID();
HandleGameObject(0, Forges[1].Event != NOT_STARTED, go);
break;
case GO_GLOWING_ANVIL_3:
Forges[2].AnvilGUID = go->GetGUID();
HandleGameObject(0, Forges[2].Event != NOT_STARTED, go);
break;
case GO_GIANT_PORTCULLIS_1:
case GO_GIANT_PORTCULLIS_2:
AddDoor(go, true);
break;
default:
break;
}
forge_event[0] = data;
break;
case EVENT_FORGE_2:
if (data == NOT_STARTED)
}
void OnGameObjectRemove(GameObject* go) OVERRIDE
{
switch (go->GetEntry())
{
HandleGameObject(forge_bellow[1], false);
HandleGameObject(forge_fire[1], false);
HandleGameObject(forge_anvil[1], false);
}else
{
HandleGameObject(forge_bellow[1], true);
HandleGameObject(forge_fire[1], true);
HandleGameObject(forge_anvil[1], true);
case GO_GIANT_PORTCULLIS_1:
case GO_GIANT_PORTCULLIS_2:
AddDoor(go, false);
break;
default:
break;
}
forge_event[1] = data;
break;
case EVENT_FORGE_3:
if (data == NOT_STARTED)
}
uint64 GetData64(uint32 type) const OVERRIDE
{
switch (type)
{
HandleGameObject(forge_bellow[2], false);
HandleGameObject(forge_fire[2], false);
HandleGameObject(forge_anvil[2], false);
}else
{
HandleGameObject(forge_bellow[2], true);
HandleGameObject(forge_fire[2], true);
HandleGameObject(forge_anvil[2], true);
case DATA_PRINCE_KELESETH:
return PrinceKelesethGUID;
case DATA_SKARVALD:
return SkarvaldGUID;
case DATA_DALRONN:
return DalronnGUID;
case DATA_INGVAR:
return IngvarGUID;
default:
break;
}
forge_event[2] = data;
break;
return 0;
}
if (data == DONE)
void SetData(uint32 type, uint32 data) OVERRIDE
{
SaveToDB();
}
}
switch (type)
{
case DATA_FORGE_1:
case DATA_FORGE_2:
case DATA_FORGE_3:
{
uint8 i = type - DATA_FORGE_1;
HandleGameObject(Forges[i].AnvilGUID, data != NOT_STARTED);
HandleGameObject(Forges[i].BellowGUID, data != NOT_STARTED);
HandleGameObject(Forges[i].FireGUID, data != NOT_STARTED);
Forges[i].Event = data;
uint32 GetData(uint32 type) const OVERRIDE
if (data == DONE)
SaveToDB();
break;
}
default:
break;
}
}
std::string GetSaveData() OVERRIDE
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "U K " << GetBossSaveData();
for (uint8 i = 0; i < 3; ++i)
saveStream << Forges[i].Event << ' ';
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
}
void Load(char const* str) OVERRIDE
{
if (!str)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(str);
char dataHead1, dataHead2;
std::istringstream loadStream(str);
loadStream >> dataHead1 >> dataHead2;
if (dataHead1 == 'U' && dataHead2 == 'K')
{
for (uint32 i = 0; i < EncounterCount; ++i)
{
uint32 tmpState;
loadStream >> tmpState;
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
tmpState = NOT_STARTED;
SetBossState(i, EncounterState(tmpState));
}
for (uint8 i = 0; i < 3; ++i)
loadStream >> Forges[i].Event;
}
else
OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
protected:
ForgeInfo Forges[3];
uint64 PrinceKelesethGUID;
uint64 SkarvaldGUID;
uint64 DalronnGUID;
uint64 IngvarGUID;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
{
switch (type)
{
case DATA_PRINCEKELESETH_EVENT: return m_auiEncounter[0];
case DATA_SKARVALD_DALRONN_EVENT: return m_auiEncounter[1];
case DATA_INGVAR_EVENT: return m_auiEncounter[2];
}
return 0;
return new instance_utgarde_keep_InstanceMapScript(map);
}
std::string GetSaveData() OVERRIDE
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "U K " << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' '
<< m_auiEncounter[2] << ' ' << forge_event[0] << ' ' << forge_event[1] << ' ' << forge_event[2];
str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
return str_data;
}
void Load(const char* in) OVERRIDE
{
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0, data1, data2, data3, data4, data5;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5;
if (dataHead1 == 'U' && dataHead2 == 'K')
{
m_auiEncounter[0] = data0;
m_auiEncounter[1] = data1;
m_auiEncounter[2] = data2;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
forge_event[0] = data3;
forge_event[1] = data4;
forge_event[2] = data5;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
};
void AddSC_instance_utgarde_keep()

View File

@@ -21,142 +21,97 @@
#include "SpellScript.h"
#include "SpellAuraEffects.h"
uint32 entry_search[3] =
uint32 ForgeSearch[3] =
{
186609,
186610,
186611
GO_GLOWING_ANVIL_1,
GO_GLOWING_ANVIL_2,
GO_GLOWING_ANVIL_3
};
class npc_dragonflayer_forge_master : public CreatureScript
{
public:
npc_dragonflayer_forge_master() : CreatureScript("npc_dragonflayer_forge_master") { }
public:
npc_dragonflayer_forge_master() : CreatureScript("npc_dragonflayer_forge_master") { }
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_dragonflayer_forge_masterAI(creature);
}
struct npc_dragonflayer_forge_masterAI : public ScriptedAI
{
npc_dragonflayer_forge_masterAI(Creature* creature) : ScriptedAI(creature)
struct npc_dragonflayer_forge_masterAI : public ScriptedAI
{
instance = creature->GetInstanceScript();
fm_Type = 0;
}
InstanceScript* instance;
uint8 fm_Type;
void Reset() OVERRIDE
{
if (fm_Type == 0)
fm_Type = GetForgeMasterType();
CheckForge();
}
void CheckForge()
{
if (instance)
npc_dragonflayer_forge_masterAI(Creature* creature) : ScriptedAI(creature)
{
switch (fm_Type)
{
case 1:
instance->SetData(EVENT_FORGE_1, me->IsAlive() ? NOT_STARTED : DONE);
break;
case 2:
instance->SetData(EVENT_FORGE_2, me->IsAlive() ? NOT_STARTED : DONE);
break;
case 3:
instance->SetData(EVENT_FORGE_3, me->IsAlive() ? NOT_STARTED : DONE);
break;
}
_instance = creature->GetInstanceScript();
_forgeId = 0;
}
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
if (fm_Type == 0)
fm_Type = GetForgeMasterType();
if (instance)
void Reset() OVERRIDE
{
switch (fm_Type)
{
case 1:
instance->SetData(EVENT_FORGE_1, DONE);
break;
if (!_forgeId)
_forgeId = GetForgeMasterType();
case 2:
instance->SetData(EVENT_FORGE_2, DONE);
break;
if (!me->IsAlive())
return;
case 3:
instance->SetData(EVENT_FORGE_3, DONE);
break;
}
if (_forgeId)
_instance->SetData(DATA_FORGE_1 + _forgeId - 1, NOT_STARTED);
}
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
if (fm_Type == 0)
fm_Type = GetForgeMasterType();
if (instance)
void JustDied(Unit* /*killer*/) OVERRIDE
{
switch (fm_Type)
{
case 1:
instance->SetData(EVENT_FORGE_1, IN_PROGRESS);
break;
if (!_forgeId)
_forgeId = GetForgeMasterType();
case 2:
instance->SetData(EVENT_FORGE_2, IN_PROGRESS);
break;
case 3:
instance->SetData(EVENT_FORGE_3, IN_PROGRESS);
break;
}
if (_forgeId)
_instance->SetData(DATA_FORGE_1 + _forgeId - 1, DONE);
}
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
}
uint8 GetForgeMasterType()
{
float diff = 30.0f;
uint8 near_f = 0;
for (uint8 i = 0; i < 3; ++i)
void EnterCombat(Unit* /*who*/) OVERRIDE
{
if (GameObject* go = me->FindNearestGameObject(entry_search[i], 30))
if (!_forgeId)
_forgeId = GetForgeMasterType();
if (_forgeId)
_instance->SetData(DATA_FORGE_1 + _forgeId - 1, IN_PROGRESS);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
}
void UpdateAI(uint32 /*diff*/) OVERRIDE
{
if (!_forgeId)
_forgeId = GetForgeMasterType();
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
private:
uint8 GetForgeMasterType()
{
float diff = 30.0f;
uint8 id = 0;
for (uint8 i = 0; i < 3; ++i)
{
if (me->IsWithinDist(go, diff, false))
if (GameObject* go = me->FindNearestGameObject(ForgeSearch[i], 30))
{
near_f = i + 1;
diff = me->GetDistance2d(go);
if (me->IsWithinDist(go, diff, false))
{
id = i + 1;
diff = me->GetDistance2d(go);
}
}
}
return id > 0 && id < 4 ? id : 0;
}
return near_f > 0 && near_f < 4 ? near_f : 0;
}
void UpdateAI(uint32 /* diff */) OVERRIDE
InstanceScript* _instance;
uint8 _forgeId;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
if (fm_Type == 0)
fm_Type = GetForgeMasterType();
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
return GetUtgardeKeepAI<npc_dragonflayer_forge_masterAI>(creature);
}
};
};
enum TickingTimeBomb
@@ -183,9 +138,7 @@ class spell_ticking_time_bomb : public SpellScriptLoader
void HandleOnEffectRemove(AuraEffect const* /* aurEff */, AuraEffectHandleModes /* mode */)
{
if (GetCaster() == GetTarget())
{
GetTarget()->CastSpell(GetTarget(), SPELL_TICKING_TIME_BOMB_EXPLODE, true);
}
}
void Register() OVERRIDE
@@ -204,6 +157,7 @@ enum Fixate
{
SPELL_FIXATE_TRIGGER = 40415
};
class spell_fixate : public SpellScriptLoader
{
public:
@@ -222,8 +176,7 @@ class spell_fixate : public SpellScriptLoader
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());
GetHitUnit()->CastSpell(GetCaster(), SPELL_FIXATE_TRIGGER, true);
}
void Register() OVERRIDE
@@ -260,86 +213,86 @@ const Position protodrakeCheckPos = {206.24f, -190.28f, 200.11f, 0.f};
class npc_enslaved_proto_drake : public CreatureScript
{
public:
npc_enslaved_proto_drake() : CreatureScript("npc_enslaved_proto_drake") { }
public:
npc_enslaved_proto_drake() : CreatureScript("npc_enslaved_proto_drake") { }
struct npc_enslaved_proto_drakeAI : public ScriptedAI
{
npc_enslaved_proto_drakeAI(Creature* creature) : ScriptedAI(creature)
struct npc_enslaved_proto_drakeAI : public ScriptedAI
{
_setData = false;
}
void Reset() OVERRIDE
{
_events.Reset();
_events.ScheduleEvent(EVENT_REND, urand(2000, 3000));
_events.ScheduleEvent(EVENT_FLAME_BREATH, urand(5500, 7000));
_events.ScheduleEvent(EVENT_KNOCKAWAY, urand(3500, 6000));
}
void MovementInform(uint32 type, uint32 id) OVERRIDE
{
if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST)
npc_enslaved_proto_drakeAI(Creature* creature) : ScriptedAI(creature)
{
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
_setData = false;
}
}
void SetData(uint32 type, uint32 data) OVERRIDE
{
if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->GetDistance(protodrakeCheckPos) < 5.0f)
void Reset() OVERRIDE
{
_setData = true;
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
me->GetMotionMaster()->MovePath(PATH_PROTODRAKE, false);
_events.Reset();
_events.ScheduleEvent(EVENT_REND, urand(2000, 3000));
_events.ScheduleEvent(EVENT_FLAME_BREATH, urand(5500, 7000));
_events.ScheduleEvent(EVENT_KNOCKAWAY, urand(3500, 6000));
}
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventid = _events.ExecuteEvent())
void MovementInform(uint32 type, uint32 id) OVERRIDE
{
switch (eventid)
if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST)
{
case EVENT_REND:
DoCast(SPELL_REND);
_events.ScheduleEvent(EVENT_REND, urand(15000, 20000));
break;
case EVENT_FLAME_BREATH:
DoCast(SPELL_FLAME_BREATH);
_events.ScheduleEvent(EVENT_FLAME_BREATH, urand(11000, 12000));
break;
case EVENT_KNOCKAWAY:
DoCast(SPELL_KNOCK_AWAY);
_events.ScheduleEvent(EVENT_KNOCKAWAY, urand(7000, 8500));
break;
default:
break;
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
}
}
DoMeleeAttackIfReady();
void SetData(uint32 type, uint32 data) OVERRIDE
{
if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->GetDistance(protodrakeCheckPos) < 5.0f)
{
_setData = true;
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
me->GetMotionMaster()->MovePath(PATH_PROTODRAKE, false);
}
}
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventid = _events.ExecuteEvent())
{
switch (eventid)
{
case EVENT_REND:
DoCast(SPELL_REND);
_events.ScheduleEvent(EVENT_REND, urand(15000, 20000));
break;
case EVENT_FLAME_BREATH:
DoCast(SPELL_FLAME_BREATH);
_events.ScheduleEvent(EVENT_FLAME_BREATH, urand(11000, 12000));
break;
case EVENT_KNOCKAWAY:
DoCast(SPELL_KNOCK_AWAY);
_events.ScheduleEvent(EVENT_KNOCKAWAY, urand(7000, 8500));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
bool _setData;
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_enslaved_proto_drakeAI(creature);
}
private:
bool _setData;
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_enslaved_proto_drakeAI(creature);
}
};
void AddSC_utgarde_keep()

View File

@@ -15,23 +15,73 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEF_UTGARDE_KEEP_H
#define DEF_UTGARDE_KEEP_H
#ifndef UTGARDE_KEEP_H_
#define UTGARDE_KEEP_H_
#define UKScriptName "instance_utgarde_keep"
uint32 const EncounterCount = 3;
enum DataTypes
{
DATA_PRINCEKELESETH = 1,
DATA_SKARVALD = 3,
DATA_DALRONN = 4,
DATA_INGVAR = 6,
// Encounter States/Boss GUIDs
DATA_PRINCE_KELESETH = 0,
DATA_SKARVALD_DALRONN = 1,
DATA_INGVAR = 2,
DATA_PRINCEKELESETH_EVENT = 2,
DATA_SKARVALD_DALRONN_EVENT = 5,
DATA_INGVAR_EVENT = 7,
// Additional Data
DATA_SKARVALD = 3,
DATA_DALRONN = 4,
EVENT_FORGE_1 = 8,
EVENT_FORGE_2 = 9,
EVENT_FORGE_3 = 10
DATA_FORGE_1 = 5,
DATA_FORGE_2 = 6,
DATA_FORGE_3 = 7
};
#endif
enum CreatureIds
{
NPC_PRINCE_KELESETH = 23953,
NPC_SKARVALD = 24200,
NPC_DALRONN = 24201,
NPC_INGVAR = 23954,
NPC_DALRONN_GHOST = 27389,
NPC_SKARVALD_GHOST = 27390
};
enum GameObjectIds
{
GO_BELLOW_1 = 186688,
GO_BELLOW_2 = 186689,
GO_BELLOW_3 = 186690,
GO_FORGEFIRE_1 = 186692,
GO_FORGEFIRE_2 = 186693,
GO_FORGEFIRE_3 = 186691,
GO_GLOWING_ANVIL_1 = 186609,
GO_GLOWING_ANVIL_2 = 186610,
GO_GLOWING_ANVIL_3 = 186611,
GO_GIANT_PORTCULLIS_1 = 186756,
GO_GIANT_PORTCULLIS_2 = 186694
};
struct ForgeInfo
{
ForgeInfo() : AnvilGUID(0), BellowGUID(0), FireGUID(0), Event(NOT_STARTED) { };
uint64 AnvilGUID;
uint64 BellowGUID;
uint64 FireGUID;
uint32 Event;
};
template<class AI>
AI* GetUtgardeKeepAI(Creature* creature)
{
return GetInstanceAI<AI>(creature, UKScriptName);
}
#endif // UTGARDE_KEEP_H_

View File

@@ -26,14 +26,14 @@
4 - Toravon the Ice Watcher event
*/
class instance_archavon : public InstanceMapScript
class instance_vault_of_archavon : public InstanceMapScript
{
public:
instance_archavon() : InstanceMapScript("instance_archavon", 624) { }
instance_vault_of_archavon() : InstanceMapScript("instance_vault_of_archavon", 624) { }
struct instance_archavon_InstanceMapScript : public InstanceScript
struct instance_vault_of_archavon_InstanceMapScript : public InstanceScript
{
instance_archavon_InstanceMapScript(Map* map) : InstanceScript(map)
instance_vault_of_archavon_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetBossNumber(EncounterCount);
@@ -135,11 +135,11 @@ class instance_archavon : public InstanceMapScript
InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
{
return new instance_archavon_InstanceMapScript(map);
return new instance_vault_of_archavon_InstanceMapScript(map);
}
};
void AddSC_instance_archavon()
void AddSC_instance_vault_of_archavon()
{
new instance_archavon();
new instance_vault_of_archavon();
}