fix(Scripts/Gundrak): Update Galdarah script (#23206)

This commit is contained in:
Andrew
2025-10-24 03:53:40 -03:00
committed by GitHub
parent 6208acd5e5
commit f3931c0a33
3 changed files with 105 additions and 154 deletions

View File

@@ -0,0 +1,2 @@
--
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|2147483648 WHERE `entry` IN (29306, 31368);

View File

@@ -49,175 +49,124 @@ enum Yells
enum Events enum Events
{ {
EVENT_STAMPEDE = 1, EVENT_KILL_TALK = 1
EVENT_WHIRLING_SLASH = 2,
EVENT_PUNCTURE = 3,
EVENT_ENRAGE = 4,
EVENT_IMPALING_CHARGE = 5,
EVENT_UNSUMMON_RHINO = 6,
EVENT_STOMP = 7,
EVENT_KILL_TALK = 8
}; };
class boss_gal_darah : public CreatureScript struct boss_gal_darah : public BossAI
{ {
public: boss_gal_darah(Creature* creature) : BossAI(creature, DATA_GAL_DARAH) { }
boss_gal_darah() : CreatureScript("boss_gal_darah") { }
CreatureAI* GetAI(Creature* creature) const override void Reset() override
{ {
return GetGundrakAI<boss_gal_darahAI>(creature); BossAI::Reset();
DoCastSelf(SPELL_START_VISUAL);
impaledList.clear();
_stampedeVictim.Clear();
} }
struct boss_gal_darahAI : public BossAI void JustReachedHome() override
{ {
boss_gal_darahAI(Creature* creature) : BossAI(creature, DATA_GAL_DARAH) BossAI::JustReachedHome();
DoCastSelf(SPELL_START_VISUAL);
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TRANSFORM_TO_RHINO)
{ {
ScheduleTimedEvent(8s, 11s, [&] {
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
{
DoCast(target, SPELL_IMPALING_CHARGE);
impaledList.insert(target->GetGUID());
}
}, 16s, 17s);
ScheduleTimedEvent(6s, 8s, [&] {
DoCastSelf(SPELL_ENRAGE);
}, 16s, 17s);
ScheduleTimedEvent(7s, 10s, [&] {
DoCastAOE(SPELL_STOMP);
}, 10s, 12s);
me->m_Events.AddEventAtOffset([&] {
scheduler.CancelAll();
DoCastSelf(SPELL_TRANSFORM_TO_TROLL);
}, 32s);
} }
else if (spellInfo->Id == SPELL_TRANSFORM_TO_TROLL)
uint8 phaseCounter;
GuidSet impaledList;
void Reset() override
{ {
BossAI::Reset(); ScheduleEvents();
impaledList.clear();
phaseCounter = 0;
} }
}
void InitializeAI() override void ScheduleEvents()
{ {
BossAI::InitializeAI(); ScheduleTimedEvent(10s, [&] {
me->CastSpell(me, SPELL_START_VISUAL, false); Talk(SAY_SUMMON_RHINO);
} if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f))
void JustReachedHome() override
{
BossAI::JustReachedHome();
me->CastSpell(me, SPELL_START_VISUAL, false);
}
void ScheduleEvents(bool troll)
{
events.Reset();
if (troll)
{ {
events.RescheduleEvent(EVENT_STAMPEDE, 10s); _stampedeVictim = target->GetGUID();
events.RescheduleEvent(EVENT_WHIRLING_SLASH, 21s); DoCast(target, SPELL_STAMPEDE);
} }
else }, 15s);
{
events.RescheduleEvent(EVENT_PUNCTURE, 10s);
events.RescheduleEvent(EVENT_ENRAGE, 15s);
events.RescheduleEvent(EVENT_IMPALING_CHARGE, 21s);
events.RescheduleEvent(EVENT_STOMP, 5s);
}
}
void JustEngagedWith(Unit* who) override ScheduleTimedEvent(10s, 16s, [&] {
DoCastVictim(SPELL_PUNCTURE);
}, 15s, 18s);
ScheduleTimedEvent(11s, 19s, [&] {
DoCastAOE(SPELL_WHIRLING_SLASH);
}, 17s, 19s);
me->m_Events.AddEventAtOffset([&] {
scheduler.CancelAll();
DoCastSelf(SPELL_TRANSFORM_TO_RHINO);
}, 32s);
}
void JustEngagedWith(Unit* who) override
{
Talk(SAY_AGGRO);
BossAI::JustEngagedWith(who);
ScheduleEvents();
me->RemoveAurasDueToSpell(SPELL_START_VISUAL);
me->InterruptNonMeleeSpells(true);
}
void JustSummoned(Creature* summon) override
{
if (Unit* target = ObjectAccessor::GetUnit(*me, _stampedeVictim))
summon->CastSpell(target, SPELL_STAMPEDE_DMG, true);
summons.Summon(summon);
}
uint32 GetData(uint32 /*type*/) const override
{
return impaledList.size();
}
void JustDied(Unit* killer) override
{
Talk(SAY_DEATH);
BossAI::JustDied(killer);
}
void KilledUnit(Unit*) override
{
if (!events.HasTimeUntilEvent(EVENT_KILL_TALK))
{ {
Talk(SAY_AGGRO); Talk(SAY_SLAY);
BossAI::JustEngagedWith(who); events.ScheduleEvent(EVENT_KILL_TALK, 6s);
ScheduleEvents(true);
me->RemoveAurasDueToSpell(SPELL_START_VISUAL);
me->InterruptNonMeleeSpells(true);
} }
}
void JustSummoned(Creature* summon) override private:
{ GuidSet impaledList;
uint32 despawnTime = 0; ObjectGuid _stampedeVictim;
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true))
{
summon->CastSpell(target, SPELL_STAMPEDE_DMG, true);
despawnTime = (summon->GetDistance(target) / 40.0f * 1000) + 500;
}
summon->DespawnOrUnsummon(Milliseconds(despawnTime));
}
uint32 GetData(uint32 /*type*/) const override
{
return impaledList.size();
}
void JustDied(Unit* killer) override
{
Talk(SAY_DEATH);
BossAI::JustDied(killer);
}
void KilledUnit(Unit*) override
{
if (!events.HasTimeUntilEvent(EVENT_KILL_TALK))
{
Talk(SAY_SLAY);
events.ScheduleEvent(EVENT_KILL_TALK, 6s);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_CHARGING))
return;
switch (events.ExecuteEvent())
{
case EVENT_STAMPEDE:
Talk(SAY_SUMMON_RHINO);
me->CastSpell(me->GetVictim(), SPELL_STAMPEDE, false);
events.ScheduleEvent(EVENT_STAMPEDE, 15s);
break;
case EVENT_WHIRLING_SLASH:
if (++phaseCounter >= 3)
{
ScheduleEvents(false);
me->CastSpell(me, SPELL_TRANSFORM_TO_RHINO, false);
Talk(SAY_TRANSFORM_1);
phaseCounter = 0;
return;
}
events.ScheduleEvent(EVENT_WHIRLING_SLASH, 21s);
me->CastSpell(me, SPELL_WHIRLING_SLASH, false);
break;
case EVENT_PUNCTURE:
me->CastSpell(me->GetVictim(), SPELL_PUNCTURE, false);
events.ScheduleEvent(EVENT_PUNCTURE, 8s);
break;
case EVENT_ENRAGE:
me->CastSpell(me, SPELL_ENRAGE, false);
events.ScheduleEvent(EVENT_ENRAGE, 20s);
break;
case EVENT_STOMP:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
me->CastSpell(target, SPELL_STOMP, false);
events.ScheduleEvent(EVENT_STOMP, 20s);
break;
case EVENT_IMPALING_CHARGE:
if (++phaseCounter >= 3)
{
ScheduleEvents(true);
me->CastSpell(me, SPELL_TRANSFORM_TO_TROLL, false);
Talk(SAY_TRANSFORM_2);
phaseCounter = 0;
return;
}
events.ScheduleEvent(EVENT_IMPALING_CHARGE, 21s);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, false))
{
me->CastSpell(target, SPELL_IMPALING_CHARGE, false);
impaledList.insert(target->GetGUID());
}
break;
}
DoMeleeAttackIfReady();
}
};
}; };
class spell_galdarah_impaling_charge : public SpellScript class spell_galdarah_impaling_charge : public SpellScript
@@ -265,9 +214,7 @@ class spell_galdarah_transform : public SpellScript
class achievement_share_the_love : public AchievementCriteriaScript class achievement_share_the_love : public AchievementCriteriaScript
{ {
public: public:
achievement_share_the_love() : AchievementCriteriaScript("achievement_share_the_love") achievement_share_the_love() : AchievementCriteriaScript("achievement_share_the_love") { }
{
}
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
{ {
@@ -280,7 +227,7 @@ public:
void AddSC_boss_gal_darah() void AddSC_boss_gal_darah()
{ {
new boss_gal_darah(); RegisterGundrakCreatureAI(boss_gal_darah);
RegisterSpellScript(spell_galdarah_impaling_charge); RegisterSpellScript(spell_galdarah_impaling_charge);
RegisterSpellScript(spell_galdarah_transform); RegisterSpellScript(spell_galdarah_transform);
new achievement_share_the_love(); new achievement_share_the_love();

View File

@@ -71,4 +71,6 @@ inline AI* GetGundrakAI(T* obj)
return GetInstanceAI<AI>(obj, GundrakScriptName); return GetInstanceAI<AI>(obj, GundrakScriptName);
} }
#define RegisterGundrakCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetGundrakAI)
#endif #endif