refactor(Scripts/UtgardeKeep): Upgrade scripts to new register method (#20795)

This commit is contained in:
Andrew
2024-11-30 20:25:27 -03:00
committed by GitHub
parent 5e4f6ac576
commit a4a278a0e7
5 changed files with 711 additions and 797 deletions

View File

@@ -99,299 +99,288 @@ enum eEvents
EVENT_AXE_PICKUP,
};
class boss_ingvar_the_plunderer : public CreatureScript
struct boss_ingvar_the_plunderer : public ScriptedAI
{
public:
boss_ingvar_the_plunderer() : CreatureScript("boss_ingvar_the_plunderer") { }
CreatureAI* GetAI(Creature* pCreature) const override
boss_ingvar_the_plunderer(Creature* c) : ScriptedAI(c), summons(me)
{
return GetUtgardeKeepAI<boss_ingvar_the_plundererAI>(pCreature);
pInstance = c->GetInstanceScript();
}
struct boss_ingvar_the_plundererAI : public ScriptedAI
InstanceScript* pInstance;
EventMap events;
SummonList summons;
ObjectGuid ValkyrGUID;
ObjectGuid ThrowGUID;
void Reset() override
{
boss_ingvar_the_plundererAI(Creature* c) : ScriptedAI(c), summons(me)
{
pInstance = c->GetInstanceScript();
}
ValkyrGUID.Clear();
ThrowGUID.Clear();
events.Reset();
summons.DespawnAll();
me->SetDisplayId(DISPLAYID_DEFAULT);
me->LoadEquipment(1);
FeignDeath(false);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
InstanceScript* pInstance;
EventMap events;
SummonList summons;
ObjectGuid ValkyrGUID;
ObjectGuid ThrowGUID;
if (pInstance)
pInstance->SetData(DATA_INGVAR, NOT_STARTED);
}
void Reset() override
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (me->GetDisplayId() == DISPLAYID_DEFAULT && damage >= me->GetHealth())
{
ValkyrGUID.Clear();
ThrowGUID.Clear();
events.Reset();
summons.DespawnAll();
me->SetDisplayId(DISPLAYID_DEFAULT);
me->LoadEquipment(1);
FeignDeath(false);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
damage = 0;
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
if (pInstance)
pInstance->SetData(DATA_INGVAR, NOT_STARTED);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (me->GetDisplayId() == DISPLAYID_DEFAULT && damage >= me->GetHealth())
{
damage = 0;
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
FeignDeath(true);
events.Reset();
events.RescheduleEvent(EVENT_START_RESURRECTION, 1s);
events.RescheduleEvent(EVENT_YELL_DEAD_1, 0ms);
}
}
void JustEngagedWith(Unit* /*who*/) override
{
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
FeignDeath(true);
events.Reset();
// schedule Phase 1 abilities
events.RescheduleEvent(EVENT_START_RESURRECTION, 1s);
events.RescheduleEvent(EVENT_YELL_DEAD_1, 0ms);
}
}
void JustEngagedWith(Unit* /*who*/) override
{
events.Reset();
// schedule Phase 1 abilities
events.RescheduleEvent(EVENT_SPELL_ROAR, 15s);
events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s);
events.RescheduleEvent(EVENT_SPELL_SMASH, 5s);
events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s);
Talk(YELL_AGGRO_1);
me->LowerPlayerDamageReq(me->GetMaxHealth());
if (pInstance)
pInstance->SetData(DATA_INGVAR, IN_PROGRESS);
}
void JustSummoned(Creature* s) override
{
summons.Summon(s);
if (s->GetEntry() == NPC_ANNHYLDE)
{
ValkyrGUID = s->GetGUID();
s->SetCanFly(true);
s->SetDisableGravity(true);
s->SetPosition(s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() + 35.0f, s->GetOrientation());
s->SetFacingTo(s->GetOrientation());
}
else if (s->GetEntry() == NPC_THROW)
{
ThrowGUID = s->GetGUID();
if (Unit* t = SelectTarget(SelectTargetMethod::Random, 0, 70.0f, true))
s->GetMotionMaster()->MovePoint(0, t->GetPositionX(), t->GetPositionY(), t->GetPositionZ());
}
}
void KilledUnit(Unit* /*who*/) override
{
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
Talk(YELL_KILL_2);
else
Talk(YELL_KILL_1);
}
void FeignDeath(bool apply)
{
if (apply)
{
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
}
else
{
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
}
}
void JustDied(Unit* /*killer*/) override
{
events.Reset();
summons.DespawnAll();
Talk(YELL_DEAD_2);
if (pInstance)
{
pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_INGVAR_UNDEAD, 1); // undead entry needed for achievements
pInstance->SetData(DATA_INGVAR, DONE);
}
}
void EnterEvadeMode(EvadeReason why) override
{
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
ScriptedAI::EnterEvadeMode(why);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case 0:
break;
case EVENT_YELL_DEAD_1:
Talk(YELL_DEAD_1);
break;
case EVENT_START_RESURRECTION:
me->CastSpell(me, SPELL_SUMMON_VALKYR, true);
events.RescheduleEvent(EVENT_VALKYR_BEAM, 7s);
events.RescheduleEvent(EVENT_VALKYR_MOVE, 1ms);
events.RescheduleEvent(EVENT_ANNHYLDE_YELL, 3s);
break;
case EVENT_VALKYR_MOVE:
if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID))
s->GetMotionMaster()->MovePoint(1, s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() - 15.0f);
break;
case EVENT_ANNHYLDE_YELL:
if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID))
s->AI()->Talk(YELL_ANHYLDE_2);
break;
case EVENT_VALKYR_BEAM:
me->RemoveAura(SPELL_SUMMON_VALKYR);
if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID))
c->CastSpell(me, SPELL_RESURRECTION_BEAM, false);
events.RescheduleEvent(EVENT_RESURRECTION_BALL, 4s);
break;
case EVENT_RESURRECTION_BALL:
me->CastSpell(me, SPELL_RESURRECTION_BALL, true);
events.RescheduleEvent(EVENT_RESURRECTION_HEAL, 4s);
break;
case EVENT_RESURRECTION_HEAL:
me->RemoveAura(SPELL_RESURRECTION_BALL);
me->CastSpell(me, SPELL_RESURRECTION_HEAL, true);
FeignDeath(false);
events.RescheduleEvent(EVENT_MORPH_TO_UNDEAD, 3s);
break;
case EVENT_MORPH_TO_UNDEAD:
me->CastSpell(me, SPELL_INGVAR_TRANSFORM, true);
events.RescheduleEvent(EVENT_START_PHASE_2, 1s);
break;
case EVENT_START_PHASE_2:
if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID))
{
c->DespawnOrUnsummon();
summons.DespawnAll();
}
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
AttackStart(me->GetVictim());
me->GetMotionMaster()->MoveChase(me->GetVictim());
Talk(YELL_AGGRO_2);
// schedule Phase 2 abilities
events.RescheduleEvent(EVENT_SPELL_ROAR, 15s);
events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s);
events.RescheduleEvent(EVENT_SPELL_SMASH, 5s);
events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s);
Talk(YELL_AGGRO_1);
me->LowerPlayerDamageReq(me->GetMaxHealth());
break;
if (pInstance)
pInstance->SetData(DATA_INGVAR, IN_PROGRESS);
}
void JustSummoned(Creature* s) override
{
summons.Summon(s);
if (s->GetEntry() == NPC_ANNHYLDE)
{
ValkyrGUID = s->GetGUID();
s->SetCanFly(true);
s->SetDisableGravity(true);
s->SetPosition(s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() + 35.0f, s->GetOrientation());
s->SetFacingTo(s->GetOrientation());
}
else if (s->GetEntry() == NPC_THROW)
{
ThrowGUID = s->GetGUID();
if (Unit* t = SelectTarget(SelectTargetMethod::Random, 0, 70.0f, true))
s->GetMotionMaster()->MovePoint(0, t->GetPositionX(), t->GetPositionY(), t->GetPositionZ());
}
}
void KilledUnit(Unit* /*who*/) override
{
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
Talk(YELL_KILL_2);
else
Talk(YELL_KILL_1);
}
void FeignDeath(bool apply)
{
if (apply)
{
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
}
else
{
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
}
}
void JustDied(Unit* /*killer*/) override
{
events.Reset();
summons.DespawnAll();
Talk(YELL_DEAD_2);
if (pInstance)
{
pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_INGVAR_UNDEAD, 1); // undead entry needed for achievements
pInstance->SetData(DATA_INGVAR, DONE);
}
}
void EnterEvadeMode(EvadeReason why) override
{
// ABILITIES HERE:
case EVENT_UNROOT:
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
ScriptedAI::EnterEvadeMode(why);
}
break;
case EVENT_SPELL_ROAR:
Talk(EMOTE_ROAR);
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
me->_AddCreatureSpellCooldown(SPELL_STAGGERING_ROAR, 0, 0);
me->_AddCreatureSpellCooldown(SPELL_DREADFUL_ROAR, 0, 0);
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell((Unit*)nullptr, SPELL_STAGGERING_ROAR, false);
else
me->CastSpell((Unit*)nullptr, SPELL_DREADFUL_ROAR, false);
events.Repeat(15s, 20s);
break;
case EVENT_SPELL_CLEAVE_OR_WOE_STRIKE:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0)
{
case 0:
break;
case EVENT_YELL_DEAD_1:
Talk(YELL_DEAD_1);
break;
case EVENT_START_RESURRECTION:
me->CastSpell(me, SPELL_SUMMON_VALKYR, true);
events.RescheduleEvent(EVENT_VALKYR_BEAM, 7s);
events.RescheduleEvent(EVENT_VALKYR_MOVE, 1ms);
events.RescheduleEvent(EVENT_ANNHYLDE_YELL, 3s);
break;
case EVENT_VALKYR_MOVE:
if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID))
s->GetMotionMaster()->MovePoint(1, s->GetPositionX(), s->GetPositionY(), s->GetPositionZ() - 15.0f);
break;
case EVENT_ANNHYLDE_YELL:
if (Creature* s = ObjectAccessor::GetCreature(*me, ValkyrGUID))
s->AI()->Talk(YELL_ANHYLDE_2);
break;
case EVENT_VALKYR_BEAM:
me->RemoveAura(SPELL_SUMMON_VALKYR);
if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID))
c->CastSpell(me, SPELL_RESURRECTION_BEAM, false);
events.RescheduleEvent(EVENT_RESURRECTION_BALL, 4s);
break;
case EVENT_RESURRECTION_BALL:
me->CastSpell(me, SPELL_RESURRECTION_BALL, true);
events.RescheduleEvent(EVENT_RESURRECTION_HEAL, 4s);
break;
case EVENT_RESURRECTION_HEAL:
me->RemoveAura(SPELL_RESURRECTION_BALL);
me->CastSpell(me, SPELL_RESURRECTION_HEAL, true);
FeignDeath(false);
events.RescheduleEvent(EVENT_MORPH_TO_UNDEAD, 3s);
break;
case EVENT_MORPH_TO_UNDEAD:
me->CastSpell(me, SPELL_INGVAR_TRANSFORM, true);
events.RescheduleEvent(EVENT_START_PHASE_2, 1s);
break;
case EVENT_START_PHASE_2:
if (Creature* c = ObjectAccessor::GetCreature(*me, ValkyrGUID))
{
c->DespawnOrUnsummon();
summons.DespawnAll();
}
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
AttackStart(me->GetVictim());
me->GetMotionMaster()->MoveChase(me->GetVictim());
Talk(YELL_AGGRO_2);
// schedule Phase 2 abilities
events.RescheduleEvent(EVENT_SPELL_ROAR, 15s);
events.RescheduleEvent(EVENT_SPELL_CLEAVE_OR_WOE_STRIKE, 2s);
events.RescheduleEvent(EVENT_SPELL_SMASH, 5s);
events.RescheduleEvent(EVENT_SPELL_ENRAGE_OR_SHADOW_AXE, 10s);
break;
// ABILITIES HERE:
case EVENT_UNROOT:
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
break;
case EVENT_SPELL_ROAR:
Talk(EMOTE_ROAR);
me->_AddCreatureSpellCooldown(SPELL_STAGGERING_ROAR, 0, 0);
me->_AddCreatureSpellCooldown(SPELL_DREADFUL_ROAR, 0, 0);
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell((Unit*)nullptr, SPELL_STAGGERING_ROAR, false);
else
me->CastSpell((Unit*)nullptr, SPELL_DREADFUL_ROAR, false);
events.Repeat(15s, 20s);
break;
case EVENT_SPELL_CLEAVE_OR_WOE_STRIKE:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0 )
{
events.Repeat(3s);
break;
}
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
else
me->CastSpell(me->GetVictim(), SPELL_WOE_STRIKE, false);
events.Repeat(3s, 7s);
break;
case EVENT_SPELL_SMASH:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0 )
{
events.Repeat(3s);
break;
}
me->SetControlled(true, UNIT_STATE_ROOT);
me->DisableRotate(true);
me->SendMovementFlagUpdate();
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell((Unit*)nullptr, SPELL_SMASH, false);
else
me->CastSpell((Unit*)nullptr, SPELL_DARK_SMASH, false);
events.Repeat(9s, 11s);
events.RescheduleEvent(EVENT_UNROOT, 3750ms);
break;
case EVENT_SPELL_ENRAGE_OR_SHADOW_AXE:
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
{
me->CastSpell(me, SPELL_ENRAGE, false);
events.Repeat(10s);
}
else
{
me->CastSpell((Unit*)nullptr, SPELL_SHADOW_AXE, true);
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
events.Repeat(35s);
events.RescheduleEvent(EVENT_AXE_RETURN, 10s);
}
break;
case EVENT_AXE_RETURN:
if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
c->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
events.RescheduleEvent(EVENT_AXE_PICKUP, 1500ms);
break;
case EVENT_AXE_PICKUP:
if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
{
c->DestroyForNearbyPlayers();
c->DespawnOrUnsummon();
summons.DespawnAll();
}
ThrowGUID.Clear();
SetEquipmentSlots(true);
break;
events.Repeat(3s);
break;
}
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
DoMeleeAttackIfReady();
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
else
me->CastSpell(me->GetVictim(), SPELL_WOE_STRIKE, false);
events.Repeat(3s, 7s);
break;
case EVENT_SPELL_SMASH:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == 0)
{
events.Repeat(3s);
break;
}
me->SetControlled(true, UNIT_STATE_ROOT);
me->DisableRotate(true);
me->SendMovementFlagUpdate();
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
me->CastSpell((Unit*)nullptr, SPELL_SMASH, false);
else
me->CastSpell((Unit*)nullptr, SPELL_DARK_SMASH, false);
events.Repeat(9s, 11s);
events.RescheduleEvent(EVENT_UNROOT, 3750ms);
break;
case EVENT_SPELL_ENRAGE_OR_SHADOW_AXE:
if (me->GetDisplayId() == DISPLAYID_DEFAULT)
{
me->CastSpell(me, SPELL_ENRAGE, false);
events.Repeat(10s);
}
else
{
me->CastSpell((Unit*)nullptr, SPELL_SHADOW_AXE, true);
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
events.Repeat(35s);
events.RescheduleEvent(EVENT_AXE_RETURN, 10s);
}
break;
case EVENT_AXE_RETURN:
if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
c->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
events.RescheduleEvent(EVENT_AXE_PICKUP, 1500ms);
break;
case EVENT_AXE_PICKUP:
if (Creature* c = ObjectAccessor::GetCreature(*me, ThrowGUID))
{
c->DestroyForNearbyPlayers();
c->DespawnOrUnsummon();
summons.DespawnAll();
}
ThrowGUID.Clear();
SetEquipmentSlots(true);
break;
}
};
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
DoMeleeAttackIfReady();
}
};
void AddSC_boss_ingvar_the_plunderer()
{
new boss_ingvar_the_plunderer();
RegisterUtgardeKeepCreatureAI(boss_ingvar_the_plunderer);
}

View File

@@ -58,176 +58,154 @@ enum eEvents
EVENT_SUMMON_SKELETONS,
};
class npc_frost_tomb : public CreatureScript
struct npc_frost_tomb : public NullCreatureAI
{
public:
npc_frost_tomb() : CreatureScript("npc_frost_tomb") { }
CreatureAI* GetAI(Creature* pCreature) const override
npc_frost_tomb(Creature* c) : NullCreatureAI(c)
{
return GetUtgardeKeepAI<npc_frost_tombAI>(pCreature);
}
struct npc_frost_tombAI : public NullCreatureAI
{
npc_frost_tombAI(Creature* c) : NullCreatureAI(c)
{
if (TempSummon* t = c->ToTempSummon())
if (Unit* s = t->GetSummonerUnit())
{
PrisonerGUID = s->GetGUID();
if (me->GetInstanceScript() && me->GetInstanceScript()->instance->IsHeroic())
{
const int32 dmg = 2000;
c->CastCustomSpell(s, SPELL_FROST_TOMB_AURA, nullptr, &dmg, nullptr, true);
}
else
c->CastSpell(s, SPELL_FROST_TOMB_AURA, true);
}
}
ObjectGuid PrisonerGUID;
void JustDied(Unit* killer) override
{
if (killer && killer->GetGUID() != me->GetGUID())
if (InstanceScript* pInstance = me->GetInstanceScript())
pInstance->SetData(DATA_ON_THE_ROCKS_ACHIEV, 0);
if (PrisonerGUID)
if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID))
p->RemoveAurasDueToSpell(SPELL_FROST_TOMB_AURA);
me->DespawnOrUnsummon(5000);
}
void UpdateAI(uint32 /*diff*/) override
{
if (PrisonerGUID)
if (TempSummon* t = c->ToTempSummon())
if (Unit* s = t->GetSummonerUnit())
{
if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID))
PrisonerGUID = s->GetGUID();
if (me->GetInstanceScript() && me->GetInstanceScript()->instance->IsHeroic())
{
if (!p->HasAura(SPELL_FROST_TOMB_AURA))
me->KillSelf();
const int32 dmg = 2000;
c->CastCustomSpell(s, SPELL_FROST_TOMB_AURA, nullptr, &dmg, nullptr, true);
}
else
me->KillSelf();
c->CastSpell(s, SPELL_FROST_TOMB_AURA, true);
}
}
};
};
}
ObjectGuid PrisonerGUID;
class boss_keleseth : public CreatureScript
{
public:
boss_keleseth() : CreatureScript("boss_keleseth") { }
CreatureAI* GetAI(Creature* pCreature) const override
void JustDied(Unit* killer) override
{
return GetUtgardeKeepAI<boss_kelesethAI>(pCreature);
if (killer && killer->GetGUID() != me->GetGUID())
if (InstanceScript* pInstance = me->GetInstanceScript())
pInstance->SetData(DATA_ON_THE_ROCKS_ACHIEV, 0);
if (PrisonerGUID)
if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID))
p->RemoveAurasDueToSpell(SPELL_FROST_TOMB_AURA);
me->DespawnOrUnsummon(5000);
}
struct boss_kelesethAI : public ScriptedAI
void UpdateAI(uint32 /*diff*/) override
{
boss_kelesethAI(Creature* c) : ScriptedAI(c)
if (PrisonerGUID)
{
pInstance = c->GetInstanceScript();
}
InstanceScript* pInstance;
EventMap events;
void Reset() override
{
events.Reset();
if (pInstance)
pInstance->SetData(DATA_KELESETH, NOT_STARTED);
}
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
if (Unit* p = ObjectAccessor::GetUnit(*me, PrisonerGUID))
{
Talk(SAY_KILL);
if (!p->HasAura(SPELL_FROST_TOMB_AURA))
me->KillSelf();
}
else
me->KillSelf();
}
}
};
void JustDied(Unit* /*killer*/) override
struct boss_keleseth : public ScriptedAI
{
boss_keleseth(Creature* c) : ScriptedAI(c)
{
pInstance = c->GetInstanceScript();
}
InstanceScript* pInstance;
EventMap events;
void Reset() override
{
events.Reset();
if (pInstance)
pInstance->SetData(DATA_KELESETH, NOT_STARTED);
}
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
{
Talk(SAY_DEATH);
if (pInstance)
pInstance->SetData(DATA_KELESETH, DONE);
Talk(SAY_KILL);
}
}
void JustEngagedWith(Unit* /*who*/) override
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
if (pInstance)
pInstance->SetData(DATA_KELESETH, DONE);
}
void JustEngagedWith(Unit* /*who*/) override
{
events.Reset();
events.RescheduleEvent(EVENT_SPELL_SHADOWBOLT, 0ms);
events.RescheduleEvent(EVENT_FROST_TOMB, 28s);
events.RescheduleEvent(EVENT_SUMMON_SKELETONS, 4s);
Talk(SAY_START_COMBAT);
DoZoneInCombat();
if (pInstance)
pInstance->SetData(DATA_KELESETH, IN_PROGRESS);
}
void AttackStart(Unit* who) override
{
if (!who)
return;
UnitAI::AttackStartCaster(who, 12.0f);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
events.Reset();
events.RescheduleEvent(EVENT_SPELL_SHADOWBOLT, 0ms);
events.RescheduleEvent(EVENT_FROST_TOMB, 28s);
events.RescheduleEvent(EVENT_SUMMON_SKELETONS, 4s);
Talk(SAY_START_COMBAT);
DoZoneInCombat();
if (pInstance)
pInstance->SetData(DATA_KELESETH, IN_PROGRESS);
}
void AttackStart(Unit* who) override
{
if (!who)
return;
UnitAI::AttackStartCaster(who, 12.0f);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
case 0:
break;
case EVENT_SPELL_SHADOWBOLT:
me->CastSpell(me->GetVictim(), SPELL_SHADOWBOLT, false);
events.Repeat(4s, 5s);
break;
case EVENT_FROST_TOMB:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true))
if (!target->HasAura(SPELL_FROST_TOMB_AURA))
{
Talk(SAY_FROST_TOMB_EMOTE, target);
Talk(SAY_FROST_TOMB);
me->CastSpell(target, SPELL_FROST_TOMB, false);
events.Repeat(15s);
break;
}
events.Repeat(1s);
break;
case EVENT_SUMMON_SKELETONS:
Talk(SAY_SUMMON_SKELETONS);
for (uint8 i = 0; i < 5; ++i)
{
case 0:
break;
case EVENT_SPELL_SHADOWBOLT:
me->CastSpell(me->GetVictim(), SPELL_SHADOWBOLT, false);
events.Repeat(4s, 5s);
break;
case EVENT_FROST_TOMB:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true))
if (!target->HasAura(SPELL_FROST_TOMB_AURA))
{
Talk(SAY_FROST_TOMB_EMOTE, target);
Talk(SAY_FROST_TOMB);
me->CastSpell(target, SPELL_FROST_TOMB, false);
events.Repeat(15s);
break;
}
events.Repeat(1s);
break;
case EVENT_SUMMON_SKELETONS:
Talk(SAY_SUMMON_SKELETONS);
for (uint8 i = 0; i < 5; ++i)
float dist = rand_norm() * 4 + 3.0f;
float angle = rand_norm() * 2 * M_PI;
if (Creature* c = me->SummonCreature(NPC_SKELETON, 156.2f + cos(angle) * dist, 259.1f + std::sin(angle) * dist, 42.9f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
if (Unit* target = c->SelectNearestTarget(250.0f))
{
float dist = rand_norm() * 4 + 3.0f;
float angle = rand_norm() * 2 * M_PI;
if (Creature* c = me->SummonCreature(NPC_SKELETON, 156.2f + cos(angle) * dist, 259.1f + std::sin(angle) * dist, 42.9f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
if (Unit* target = c->SelectNearestTarget(250.0f))
{
c->AddThreat(target, 5.0f);
DoZoneInCombat(c);
}
c->AddThreat(target, 5.0f);
DoZoneInCombat(c);
}
break;
}
DoMeleeAttackIfReady();
break;
}
};
DoMeleeAttackIfReady();
}
};
enum eSkeletonEnum
@@ -242,105 +220,94 @@ enum eSkeletonEnum
EVENT_RESURRECT_2,
};
class npc_vrykul_skeleton : public CreatureScript
struct npc_vrykul_skeleton : public ScriptedAI
{
public:
npc_vrykul_skeleton() : CreatureScript("npc_vrykul_skeleton") { }
CreatureAI* GetAI(Creature* pCreature) const override
npc_vrykul_skeleton(Creature* c) : ScriptedAI(c)
{
return GetUtgardeKeepAI<npc_vrykul_skeletonAI>(pCreature);
pInstance = c->GetInstanceScript();
}
struct npc_vrykul_skeletonAI : public ScriptedAI
InstanceScript* pInstance;
EventMap events;
void Reset() override
{
npc_vrykul_skeletonAI(Creature* c) : ScriptedAI(c)
events.Reset();
events.RescheduleEvent(EVENT_SPELL_DECREPIFY, 10s, 20s);
if (IsHeroic())
events.RescheduleEvent(EVENT_SPELL_BONE_ARMOR, 25s, 120s);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (damage >= me->GetHealth())
{
pInstance = c->GetInstanceScript();
damage = 0;
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(true, UNIT_STATE_ROOT);
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
events.RescheduleEvent(EVENT_RESURRECT, 12s);
}
}
void UpdateAI(uint32 diff) override
{
if (pInstance && pInstance->GetData(DATA_KELESETH) != IN_PROGRESS)
{
if (me->IsAlive())
me->KillSelf();
return;
}
InstanceScript* pInstance;
EventMap events;
if (!UpdateVictim())
return;
void Reset() override
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
events.Reset();
events.RescheduleEvent(EVENT_SPELL_DECREPIFY, 10s, 20s);
if (IsHeroic())
events.RescheduleEvent(EVENT_SPELL_BONE_ARMOR, 25s, 120s);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (damage >= me->GetHealth())
{
damage = 0;
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(true, UNIT_STATE_ROOT);
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
me->SetStandState(UNIT_STAND_STATE_DEAD);
me->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
events.RescheduleEvent(EVENT_RESURRECT, 12s);
}
}
void UpdateAI(uint32 diff) override
{
if (pInstance && pInstance->GetData(DATA_KELESETH) != IN_PROGRESS )
{
if (me->IsAlive())
me->KillSelf();
return;
}
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case 0:
break;
case EVENT_SPELL_DECREPIFY:
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
me->CastSpell(me->GetVictim(), SPELL_DECREPIFY, false);
events.Repeat(15s, 25s);
break;
case EVENT_SPELL_BONE_ARMOR:
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
me->CastSpell((Unit*)nullptr, SPELL_BONE_ARMOR, false);
events.Repeat(40s, 120s);
break;
case EVENT_RESURRECT:
events.DelayEvents(3500ms);
DoCast(me, SPELL_SCOURGE_RESURRECTION, true);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
events.RescheduleEvent(EVENT_RESURRECT_2, 3s);
break;
case EVENT_RESURRECT_2:
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->GetMotionMaster()->MoveChase(me->GetVictim());
break;
}
case 0:
break;
case EVENT_SPELL_DECREPIFY:
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
DoMeleeAttackIfReady();
me->CastSpell(me->GetVictim(), SPELL_DECREPIFY, false);
events.Repeat(15s, 25s);
break;
case EVENT_SPELL_BONE_ARMOR:
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
me->CastSpell((Unit*)nullptr, SPELL_BONE_ARMOR, false);
events.Repeat(40s, 120s);
break;
case EVENT_RESURRECT:
events.DelayEvents(3500ms);
DoCast(me, SPELL_SCOURGE_RESURRECTION, true);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
events.RescheduleEvent(EVENT_RESURRECT_2, 3s);
break;
case EVENT_RESURRECT_2:
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
me->GetMotionMaster()->MoveChase(me->GetVictim());
break;
}
};
if (!me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
DoMeleeAttackIfReady();
}
};
class spell_frost_tomb_aura : public AuraScript
@@ -368,8 +335,8 @@ class spell_frost_tomb_aura : public AuraScript
void AddSC_boss_keleseth()
{
new boss_keleseth();
new npc_frost_tomb();
new npc_vrykul_skeleton();
RegisterUtgardeKeepCreatureAI(boss_keleseth);
RegisterUtgardeKeepCreatureAI(npc_frost_tomb);
RegisterUtgardeKeepCreatureAI(npc_vrykul_skeleton);
RegisterSpellScript(spell_frost_tomb_aura);
}

View File

@@ -66,182 +66,161 @@ enum eEvents
EVENT_MATE_DIED
};
class boss_skarvald_the_constructor : public CreatureScript
struct boss_skarvald_the_constructor : public ScriptedAI
{
public:
boss_skarvald_the_constructor() : CreatureScript("boss_skarvald_the_constructor") { }
CreatureAI* GetAI(Creature* pCreature) const override
boss_skarvald_the_constructor(Creature* c) : ScriptedAI(c)
{
return GetUtgardeKeepAI<boss_skarvald_the_constructorAI>(pCreature);
pInstance = c->GetInstanceScript();
}
struct boss_skarvald_the_constructorAI : public ScriptedAI
InstanceScript* pInstance;
EventMap events;
void Reset() override
{
boss_skarvald_the_constructorAI(Creature* c) : ScriptedAI(c)
me->SetLootMode(0);
events.Reset();
if (me->GetEntry() == NPC_SKARVALD)
{
pInstance = c->GetInstanceScript();
}
InstanceScript* pInstance;
EventMap events;
void Reset() override
{
me->SetLootMode(0);
events.Reset();
if (me->GetEntry() == NPC_SKARVALD)
{
if (pInstance)
{
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, NOT_STARTED);
}
}
else // NPC_SKARVALD_GHOST
{
if (Unit* target = me->SelectNearestTarget(50.0f))
{
me->AddThreat(target, 0.0f);
AttackStart(target);
}
}
}
void DoAction(int32 param) override
{
switch (param)
{
case 1:
events.RescheduleEvent(EVENT_MATE_DIED, 3500ms);
break;
}
}
void JustEngagedWith(Unit* who) override
{
events.Reset();
events.RescheduleEvent(EVENT_SHARVALD_CHARGE, 5s);
events.RescheduleEvent(EVENT_STONE_STRIKE, 10s);
if (me->GetEntry() == NPC_SKARVALD)
{
Talk(YELL_SKARVALD_AGGRO);
if (IsHeroic())
{
events.ScheduleEvent(EVENT_ENRAGE, 1s);
}
}
if (pInstance)
{
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, IN_PROGRESS);
if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN)))
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, NOT_STARTED);
}
}
else // NPC_SKARVALD_GHOST
{
if (Unit* target = me->SelectNearestTarget(50.0f))
{
me->AddThreat(target, 0.0f);
AttackStart(target);
}
}
}
void DoAction(int32 param) override
{
switch (param)
{
case 1:
events.RescheduleEvent(EVENT_MATE_DIED, 3500ms);
break;
}
}
void JustEngagedWith(Unit* who) override
{
events.Reset();
events.RescheduleEvent(EVENT_SHARVALD_CHARGE, 5s);
events.RescheduleEvent(EVENT_STONE_STRIKE, 10s);
if (me->GetEntry() == NPC_SKARVALD)
{
Talk(YELL_SKARVALD_AGGRO);
if (IsHeroic())
{
events.ScheduleEvent(EVENT_ENRAGE, 1s);
}
}
if (pInstance)
{
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, IN_PROGRESS);
if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN)))
{
if (!dalronn->IsInCombat() && who)
{
if (!dalronn->IsInCombat() && who)
{
dalronn->AddThreat(who, 0.0f);
dalronn->AI()->AttackStart(who);
}
dalronn->AddThreat(who, 0.0f);
dalronn->AI()->AttackStart(who);
}
}
}
}
void KilledUnit(Unit* /*victim*/) override
void KilledUnit(Unit* /*victim*/) override
{
if (me->GetEntry() == NPC_SKARVALD)
{
if (me->GetEntry() == NPC_SKARVALD)
{
Talk(YELL_SKARVALD_KILL);
}
Talk(YELL_SKARVALD_KILL);
}
}
void JustDied(Unit* /*Killer*/) override
void JustDied(Unit* /*Killer*/) override
{
if (me->GetEntry() != NPC_SKARVALD)
return;
if (pInstance)
{
if (me->GetEntry() != NPC_SKARVALD)
return;
if (pInstance)
if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN)))
{
if (Creature* dalronn = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_DALRONN)))
if (dalronn->isDead())
{
if (dalronn->isDead())
{
Talk(YELL_SKARVALD_SKA_DIEDFIRST);
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, DONE);
pInstance->SetData(DATA_UNLOCK_SKARVALD_LOOT, 0);
return;
}
else
{
Talk(YELL_SKARVALD_DAL_DIED);
dalronn->AI()->DoAction(1);
}
Talk(YELL_SKARVALD_SKA_DIEDFIRST);
pInstance->SetData(DATA_DALRONN_AND_SKARVALD, DONE);
pInstance->SetData(DATA_UNLOCK_SKARVALD_LOOT, 0);
return;
}
else
{
Talk(YELL_SKARVALD_DAL_DIED);
dalronn->AI()->DoAction(1);
}
}
me->CastSpell((Unit*)nullptr, SPELL_SUMMON_SKARVALD_GHOST, true);
}
me->CastSpell((Unit*)nullptr, SPELL_SUMMON_SKARVALD_GHOST, true);
}
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
case 0:
break;
case EVENT_MATE_DIED:
Talk(YELL_SKARVALD_DAL_DIEDFIRST);
break;
case EVENT_SHARVALD_CHARGE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, (IsHeroic() ? 100.0f : 30.0f), true))
{
case 0:
break;
case EVENT_MATE_DIED:
Talk(YELL_SKARVALD_DAL_DIEDFIRST);
break;
case EVENT_SHARVALD_CHARGE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, (IsHeroic() ? 100.0f : 30.0f), true))
{
DoResetThreatList();
me->AddThreat(target, 10000.0f);
me->CastSpell(target, SPELL_CHARGE, false);
}
events.Repeat(5s, 10s);
break;
case EVENT_STONE_STRIKE:
if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
{
me->CastSpell(me->GetVictim(), SPELL_STONE_STRIKE, false);
events.Repeat(5s, 10s);
}
else
{
events.Repeat(3s);
}
break;
case EVENT_ENRAGE:
if (me->GetHealthPct() <= 60)
{
me->CastSpell(me, SPELL_ENRAGE, true);
break;
}
events.Repeat(1s);
break;
DoResetThreatList();
me->AddThreat(target, 10000.0f);
me->CastSpell(target, SPELL_CHARGE, false);
}
DoMeleeAttackIfReady();
events.Repeat(5s, 10s);
break;
case EVENT_STONE_STRIKE:
if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
{
me->CastSpell(me->GetVictim(), SPELL_STONE_STRIKE, false);
events.Repeat(5s, 10s);
}
else
{
events.Repeat(3s);
}
break;
case EVENT_ENRAGE:
if (me->GetHealthPct() <= 60)
{
me->CastSpell(me, SPELL_ENRAGE, true);
break;
}
events.Repeat(1s);
break;
}
};
DoMeleeAttackIfReady();
}
};
class boss_dalronn_the_controller : public CreatureScript
{
public:
boss_dalronn_the_controller() : CreatureScript("boss_dalronn_the_controller") { }
CreatureAI* GetAI(Creature* pCreature) const override
struct boss_dalronn_the_controller : public ScriptedAI
{
return GetUtgardeKeepAI<boss_dalronn_the_controllerAI>(pCreature);
}
struct boss_dalronn_the_controllerAI : public ScriptedAI
{
boss_dalronn_the_controllerAI(Creature* c) : ScriptedAI(c), summons(me)
boss_dalronn_the_controller(Creature* c) : ScriptedAI(c), summons(me)
{
pInstance = c->GetInstanceScript();
}
@@ -397,10 +376,9 @@ public:
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_skarvald_dalronn()
{
new boss_skarvald_the_constructor();
new boss_dalronn_the_controller();
RegisterUtgardeKeepCreatureAI(boss_skarvald_the_constructor);
RegisterUtgardeKeepCreatureAI(boss_dalronn_the_controller);
}

View File

@@ -23,72 +23,61 @@
#include "SpellScriptLoader.h"
#include "Vehicle.h"
class npc_dragonflayer_forge_master : public CreatureScript
struct npc_dragonflayer_forge_master : public ScriptedAI
{
public:
npc_dragonflayer_forge_master() : CreatureScript("npc_dragonflayer_forge_master") { }
CreatureAI* GetAI(Creature* pCreature) const override
npc_dragonflayer_forge_master(Creature* c) : ScriptedAI(c)
{
return GetUtgardeKeepAI<npc_dragonflayer_forge_masterAI>(pCreature);
pInstance = c->GetInstanceScript();
float x = me->GetHomePosition().GetPositionX();
float y = me->GetHomePosition().GetPositionY();
if (x > 344.0f && x < 357.0f && y < -35.0f && y > -44.0f)
{
dataId = DATA_FORGE_1;
prevDataId = 0;
}
else if (x > 380.0f && x < 389.0f && y < -12.0f && y > -21.0f)
{
dataId = DATA_FORGE_2;
prevDataId = DATA_FORGE_1;
}
else
{
dataId = DATA_FORGE_3;
prevDataId = DATA_FORGE_2;
}
}
struct npc_dragonflayer_forge_masterAI : public ScriptedAI
InstanceScript* pInstance;
uint32 dataId;
uint32 prevDataId;
void Reset() override
{
npc_dragonflayer_forge_masterAI(Creature* c) : ScriptedAI(c)
if (pInstance)
pInstance->SetData(dataId, NOT_STARTED);
}
void JustDied(Unit* /*killer*/) override
{
if (pInstance)
pInstance->SetData(dataId, DONE);
me->SaveRespawnTime();
}
void JustEngagedWith(Unit* /*who*/) override
{
if (pInstance)
{
pInstance = c->GetInstanceScript();
float x = me->GetHomePosition().GetPositionX();
float y = me->GetHomePosition().GetPositionY();
if (x > 344.0f && x < 357.0f && y < -35.0f && y > -44.0f)
if (prevDataId && !pInstance->GetData(prevDataId))
{
dataId = DATA_FORGE_1;
prevDataId = 0;
}
else if (x > 380.0f && x < 389.0f && y < -12.0f && y > -21.0f)
{
dataId = DATA_FORGE_2;
prevDataId = DATA_FORGE_1;
}
else
{
dataId = DATA_FORGE_3;
prevDataId = DATA_FORGE_2;
EnterEvadeMode();
return;
}
pInstance->SetData(dataId, IN_PROGRESS);
}
InstanceScript* pInstance;
uint32 dataId;
uint32 prevDataId;
void Reset() override
{
if (pInstance)
pInstance->SetData(dataId, NOT_STARTED);
}
void JustDied(Unit* /*killer*/) override
{
if (pInstance)
pInstance->SetData(dataId, DONE);
me->SaveRespawnTime();
}
void JustEngagedWith(Unit* /*who*/) override
{
if (pInstance)
{
if (prevDataId && !pInstance->GetData(prevDataId))
{
EnterEvadeMode();
return;
}
pInstance->SetData(dataId, IN_PROGRESS);
}
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
}
};
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
}
};
enum EnslavedProtoDrake
@@ -111,97 +100,86 @@ enum EnslavedProtoDrake
const Position protodrakeCheckPos = {206.24f, -190.28f, 200.11f, 0.f};
class npc_enslaved_proto_drake : public CreatureScript
struct npc_enslaved_proto_drake : public ScriptedAI
{
public:
npc_enslaved_proto_drake() : CreatureScript("npc_enslaved_proto_drake") { }
struct npc_enslaved_proto_drakeAI : public ScriptedAI
npc_enslaved_proto_drake(Creature* creature) : ScriptedAI(creature)
{
npc_enslaved_proto_drakeAI(Creature* creature) : ScriptedAI(creature)
{
_setData = false;
}
void Reset() override
{
_events.Reset();
_events.ScheduleEvent(EVENT_REND, 2s, 3s);
_events.ScheduleEvent(EVENT_FLAME_BREATH, 5500ms, 7000ms);
_events.ScheduleEvent(EVENT_KNOCKAWAY, 3500ms, 6000ms);
}
void MovementInform(uint32 type, uint32 id) override
{
if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST)
{
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f);
if (Vehicle* v = me->GetVehicleKit())
if (Unit* p = v->GetPassenger(0))
if (Creature* rider = p->ToCreature())
rider->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f);
me->SetCanFly(false);
me->SetDisableGravity(false);
me->SetFacingTo(0.25f);
me->SetImmuneToAll(false);
}
}
void SetData(uint32 type, uint32 data) override
{
if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->IsAlive() && me->GetDistance(protodrakeCheckPos) < 10.0f)
{
_setData = true;
me->SetCanFly(true);
me->SetDisableGravity(true);
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, 15s, 20s);
break;
case EVENT_FLAME_BREATH:
DoCast(SPELL_FLAME_BREATH);
_events.ScheduleEvent(EVENT_FLAME_BREATH, 11s, 12s);
break;
case EVENT_KNOCKAWAY:
DoCast(SPELL_KNOCK_AWAY);
_events.ScheduleEvent(EVENT_KNOCKAWAY, 7000ms, 8500ms);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
bool _setData;
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetUtgardeKeepAI<npc_enslaved_proto_drakeAI>(creature);
_setData = false;
}
void Reset() override
{
_events.Reset();
_events.ScheduleEvent(EVENT_REND, 2s, 3s);
_events.ScheduleEvent(EVENT_FLAME_BREATH, 5500ms, 7000ms);
_events.ScheduleEvent(EVENT_KNOCKAWAY, 3500ms, 6000ms);
}
void MovementInform(uint32 type, uint32 id) override
{
if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST)
{
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f);
if (Vehicle* v = me->GetVehicleKit())
if (Unit* p = v->GetPassenger(0))
if (Creature* rider = p->ToCreature())
rider->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.25f);
me->SetCanFly(false);
me->SetDisableGravity(false);
me->SetFacingTo(0.25f);
me->SetImmuneToAll(false);
}
}
void SetData(uint32 type, uint32 data) override
{
if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->IsAlive() && me->GetDistance(protodrakeCheckPos) < 10.0f)
{
_setData = true;
me->SetCanFly(true);
me->SetDisableGravity(true);
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, 15s, 20s);
break;
case EVENT_FLAME_BREATH:
DoCast(SPELL_FLAME_BREATH);
_events.ScheduleEvent(EVENT_FLAME_BREATH, 11s, 12s);
break;
case EVENT_KNOCKAWAY:
DoCast(SPELL_KNOCK_AWAY);
_events.ScheduleEvent(EVENT_KNOCKAWAY, 7000ms, 8500ms);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
bool _setData;
EventMap _events;
};
enum TickingTimeBomb
@@ -234,8 +212,8 @@ class spell_ticking_time_bomb_aura : public AuraScript
void AddSC_utgarde_keep()
{
new npc_dragonflayer_forge_master();
new npc_enslaved_proto_drake();
RegisterUtgardeKeepCreatureAI(npc_dragonflayer_forge_master);
RegisterUtgardeKeepCreatureAI(npc_enslaved_proto_drake);
RegisterSpellScript(spell_ticking_time_bomb_aura);
}

View File

@@ -83,4 +83,6 @@ inline AI* GetUtgardeKeepAI(T* obj)
return GetInstanceAI<AI>(obj, UtgardeKeepScriptName);
}
#define RegisterUtgardeKeepCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetUtgardeKeepAI)
#endif