Scripts/Nexus: Update Keristrasza to new model (#26438)

This commit is contained in:
offl
2021-04-20 17:38:27 +03:00
committed by GitHub
parent 158f877a4e
commit 08fc6314d0
2 changed files with 176 additions and 208 deletions

View File

@@ -63,228 +63,195 @@ enum Misc
DATA_CONTAINMENT_SPHERES = 3
};
class boss_keristrasza : public CreatureScript
struct boss_keristrasza : public BossAI
{
public:
boss_keristrasza() : CreatureScript("boss_keristrasza") { }
boss_keristrasza(Creature* creature) : BossAI(creature, DATA_KERISTRASZA)
{
Initialize();
}
struct boss_keristraszaAI : public BossAI
void Initialize()
{
_enrage = false;
_intenseCold = true;
}
void Reset() override
{
Initialize();
_intenseColdList.clear();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
RemovePrison(CheckContainmentSpheres());
_Reset();
}
void JustEngagedWith(Unit* who) override
{
Talk(SAY_AGGRO);
DoCastAOE(SPELL_INTENSE_COLD);
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_CRYSTAL_FIRE_BREATH, 14s);
events.ScheduleEvent(EVENT_CRYSTAL_CHAINS_CRYSTALLIZE, DUNGEON_MODE(30s, 11s));
events.ScheduleEvent(EVENT_TAIL_SWEEP, 5s);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
}
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
bool CheckContainmentSpheres(bool remove_prison = false)
{
ContainmentSphereGUIDs[0] = instance->GetGuidData(ANOMALUS_CONTAINMENT_SPHERE);
ContainmentSphereGUIDs[1] = instance->GetGuidData(ORMOROKS_CONTAINMENT_SPHERE);
ContainmentSphereGUIDs[2] = instance->GetGuidData(TELESTRAS_CONTAINMENT_SPHERE);
for (uint8 i = 0; i < DATA_CONTAINMENT_SPHERES; ++i)
{
boss_keristraszaAI(Creature* creature) : BossAI(creature, DATA_KERISTRASZA)
{
Initialize();
}
void Initialize()
{
_enrage = false;
_intenseCold = true;
}
void Reset() override
{
Initialize();
_intenseColdList.clear();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
RemovePrison(CheckContainmentSpheres());
_Reset();
}
void JustEngagedWith(Unit* who) override
{
Talk(SAY_AGGRO);
DoCastAOE(SPELL_INTENSE_COLD);
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_CRYSTAL_FIRE_BREATH, 14s);
events.ScheduleEvent(EVENT_CRYSTAL_CHAINS_CRYSTALLIZE, DUNGEON_MODE(30s, 11s));
events.ScheduleEvent(EVENT_TAIL_SWEEP, 5s);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
}
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
bool CheckContainmentSpheres(bool remove_prison = false)
{
ContainmentSphereGUIDs[0] = instance->GetGuidData(ANOMALUS_CONTAINMENT_SPHERE);
ContainmentSphereGUIDs[1] = instance->GetGuidData(ORMOROKS_CONTAINMENT_SPHERE);
ContainmentSphereGUIDs[2] = instance->GetGuidData(TELESTRAS_CONTAINMENT_SPHERE);
for (uint8 i = 0; i < DATA_CONTAINMENT_SPHERES; ++i)
{
GameObject* ContainmentSphere = ObjectAccessor::GetGameObject(*me, ContainmentSphereGUIDs[i]);
if (!ContainmentSphere)
return false;
if (ContainmentSphere->GetGoState() != GO_STATE_ACTIVE)
return false;
}
if (remove_prison)
RemovePrison(true);
return true;
}
void RemovePrison(bool remove)
{
if (remove)
{
me->SetImmuneToPC(false);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if (me->HasAura(SPELL_FROZEN_PRISON))
me->RemoveAurasDueToSpell(SPELL_FROZEN_PRISON);
}
else
{
me->SetImmuneToPC(true);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
DoCast(me, SPELL_FROZEN_PRISON, false);
}
}
void SetGUID(ObjectGuid const& guid, int32 id) override
{
if (id == DATA_INTENSE_COLD)
_intenseColdList.push_back(guid);
}
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
if (!_enrage && me->HealthBelowPctDamaged(25, damage))
{
Talk(SAY_ENRAGE);
Talk(SAY_FRENZY);
DoCast(me, SPELL_ENRAGE);
_enrage = true;
}
}
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_CRYSTAL_FIRE_BREATH:
DoCastVictim(SPELL_CRYSTALFIRE_BREATH);
events.ScheduleEvent(EVENT_CRYSTAL_FIRE_BREATH, 14s);
break;
case EVENT_CRYSTAL_CHAINS_CRYSTALLIZE:
DoCast(me, SPELL_TAIL_SWEEP);
events.ScheduleEvent(EVENT_CRYSTAL_CHAINS_CRYSTALLIZE, 5s);
break;
case EVENT_TAIL_SWEEP:
Talk(SAY_CRYSTAL_NOVA);
if (IsHeroic())
DoCast(me, SPELL_CRYSTALLIZE);
else if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
DoCast(target, SPELL_CRYSTAL_CHAINS);
events.ScheduleEvent(EVENT_TAIL_SWEEP, DUNGEON_MODE(30s, 11s));
break;
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
DoMeleeAttackIfReady();
}
private:
bool _intenseCold;
bool _enrage;
ObjectGuid ContainmentSphereGUIDs[DATA_CONTAINMENT_SPHERES];
public:
GuidList _intenseColdList;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetNexusAI<boss_keristraszaAI>(creature);
GameObject* ContainmentSphere = ObjectAccessor::GetGameObject(*me, ContainmentSphereGUIDs[i]);
if (!ContainmentSphere)
return false;
if (ContainmentSphere->GetGoState() != GO_STATE_ACTIVE)
return false;
}
if (remove_prison)
RemovePrison(true);
return true;
}
void RemovePrison(bool remove)
{
if (remove)
{
me->SetImmuneToPC(false);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if (me->HasAura(SPELL_FROZEN_PRISON))
me->RemoveAurasDueToSpell(SPELL_FROZEN_PRISON);
}
else
{
me->SetImmuneToPC(true);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
DoCast(me, SPELL_FROZEN_PRISON, false);
}
}
void SetGUID(ObjectGuid const& guid, int32 id) override
{
if (id == DATA_INTENSE_COLD)
_intenseColdList.push_back(guid);
}
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
if (!_enrage && me->HealthBelowPctDamaged(25, damage))
{
Talk(SAY_ENRAGE);
Talk(SAY_FRENZY);
DoCast(me, SPELL_ENRAGE);
_enrage = true;
}
}
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_CRYSTAL_FIRE_BREATH:
DoCastVictim(SPELL_CRYSTALFIRE_BREATH);
events.ScheduleEvent(EVENT_CRYSTAL_FIRE_BREATH, 14s);
break;
case EVENT_CRYSTAL_CHAINS_CRYSTALLIZE:
DoCast(me, SPELL_TAIL_SWEEP);
events.ScheduleEvent(EVENT_CRYSTAL_CHAINS_CRYSTALLIZE, 5s);
break;
case EVENT_TAIL_SWEEP:
Talk(SAY_CRYSTAL_NOVA);
if (IsHeroic())
DoCast(me, SPELL_CRYSTALLIZE);
else if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
DoCast(target, SPELL_CRYSTAL_CHAINS);
events.ScheduleEvent(EVENT_TAIL_SWEEP, DUNGEON_MODE(30s, 11s));
break;
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
DoMeleeAttackIfReady();
}
private:
bool _intenseCold;
bool _enrage;
ObjectGuid ContainmentSphereGUIDs[DATA_CONTAINMENT_SPHERES];
public:
GuidList _intenseColdList;
};
class containment_sphere : public GameObjectScript
struct containment_sphere : public GameObjectAI
{
public:
containment_sphere() : GameObjectScript("containment_sphere") { }
containment_sphere(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
struct containment_sphereAI : public GameObjectAI
InstanceScript* instance;
bool OnGossipHello(Player* /*player*/) override
{
containment_sphereAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
InstanceScript* instance;
bool OnGossipHello(Player* /*player*/) override
Creature* keristrasza = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KERISTRASZA));
if (keristrasza && keristrasza->IsAlive())
{
Creature* keristrasza = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_KERISTRASZA));
if (keristrasza && keristrasza->IsAlive())
{
// maybe these are hacks :(
me->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
me->SetGoState(GO_STATE_ACTIVE);
// maybe these are hacks :(
me->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
me->SetGoState(GO_STATE_ACTIVE);
ENSURE_AI(boss_keristrasza::boss_keristraszaAI, keristrasza->AI())->CheckContainmentSpheres(true);
}
return true;
ENSURE_AI(boss_keristrasza, keristrasza->AI())->CheckContainmentSpheres(true);
}
};
GameObjectAI* GetAI(GameObject* go) const override
{
return GetNexusAI<containment_sphereAI>(go);
return true;
}
};
class spell_intense_cold : public SpellScriptLoader
class spell_intense_cold : public AuraScript
{
public:
spell_intense_cold() : SpellScriptLoader("spell_intense_cold") { }
PrepareAuraScript(spell_intense_cold);
class spell_intense_cold_AuraScript : public AuraScript
{
PrepareAuraScript(spell_intense_cold_AuraScript);
void HandlePeriodicTick(AuraEffect const* aurEff)
{
if (aurEff->GetBase()->GetStackAmount() < 2)
return;
Unit* caster = GetCaster();
/// @todo the caster should be boss but not the player
if (!caster || !caster->GetAI())
return;
caster->GetAI()->SetGUID(GetTarget()->GetGUID(), DATA_INTENSE_COLD);
}
void HandlePeriodicTick(AuraEffect const* aurEff)
{
if (aurEff->GetBase()->GetStackAmount() < 2)
return;
Unit* caster = GetCaster();
/// @todo the caster should be boss but not the player
if (!caster || !caster->GetAI())
return;
caster->GetAI()->SetGUID(GetTarget()->GetGUID(), DATA_INTENSE_COLD);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_intense_cold_AuraScript::HandlePeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_intense_cold_AuraScript();
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_intense_cold::HandlePeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
}
};
class achievement_intense_cold : public AchievementCriteriaScript
@@ -299,7 +266,7 @@ class achievement_intense_cold : public AchievementCriteriaScript
if (!target)
return false;
GuidList _intenseColdList = ENSURE_AI(boss_keristrasza::boss_keristraszaAI, target->ToCreature()->AI())->_intenseColdList;
GuidList _intenseColdList = ENSURE_AI(boss_keristrasza, target->ToCreature()->AI())->_intenseColdList;
if (!_intenseColdList.empty())
for (GuidList::iterator itr = _intenseColdList.begin(); itr != _intenseColdList.end(); ++itr)
if (player->GetGUID() == *itr)
@@ -311,8 +278,8 @@ class achievement_intense_cold : public AchievementCriteriaScript
void AddSC_boss_keristrasza()
{
new boss_keristrasza();
new containment_sphere();
RegisterNexusCreatureAI(boss_keristrasza);
RegisterNexusGameObjectAI(containment_sphere);
RegisterSpellScript(spell_intense_cold);
new achievement_intense_cold();
new spell_intense_cold();
}

View File

@@ -72,5 +72,6 @@ inline AI* GetNexusAI(T* obj)
}
#define RegisterNexusCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetNexusAI)
#define RegisterNexusGameObjectAI(ai_name) RegisterGameObjectAIWithFactory(ai_name, GetNexusAI)
#endif