mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 08:28:32 +01:00
Scripts/Nexus: Update Keristrasza to new model (#26438)
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user