fix(Core/Scripts): Rewrite Warbringer O'mrogg (#16346)

* fix(Core/Scripts): Rewrite Warbringer O'mrogg

* typo
This commit is contained in:
Angelo Venturini
2023-05-21 18:24:07 -03:00
committed by GitHub
parent 93c42a4f09
commit 67be37def6
4 changed files with 248 additions and 198 deletions

View File

@@ -17,6 +17,8 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "TaskScheduler.h"
#include "shattered_halls.h"
enum Spells
@@ -34,32 +36,23 @@ enum Equip
EQUIP_BURNING_MAUL = 2
};
enum Creatures
enum HeadYells
{
NPC_LEFT_HEAD = 19523,
NPC_RIGHT_HEAD = 19524
SAY_ON_AGGRO = 0,
SAY_ON_AGGRO_2,
SAY_ON_AGGRO_3,
SAY_ON_BEATDOWN,
SAY_ON_BEATDOWN_2,
SAY_ON_BEATDOWN_3,
SAY_ON_KILL,
SAY_ON_KILL_2,
SAY_ON_DEATH
};
enum Misc
{
EMOTE_ENRAGE = 0,
SETDATA_DATA = 1,
SETDATA_YELL = 1
};
enum Events
{
EVENT_AGGRO_YELL_1 = 1,
EVENT_AGGRO_YELL_2 = 2,
EVENT_AGGRO_YELL_3 = 3,
EVENT_THREAT_YELL_L_1 = 4,
EVENT_THREAT_YELL_L_2 = 5,
EVENT_THREAT_YELL_L_3 = 6,
EVENT_THREAT_YELL_R_1 = 7,
EVENT_KILL_YELL_LEFT = 8,
EVENT_KILL_YELL_RIGHT = 9,
EVENT_DEATH_YELL = 10
EMOTE_BURNING_MAUL = 0,
DATA_BURNING_MAUL_END = 1
};
enum Phase
@@ -79,217 +72,218 @@ struct boss_warbringer_omrogg : public BossAI
});
}
EventMap events2;
Creature* GetLeftHead()
void HandleHeadTalk(HeadYells yell)
{
return summons.GetCreatureWithEntry(NPC_LEFT_HEAD);
}
Creature* GetRightHead()
{
return summons.GetCreatureWithEntry(NPC_RIGHT_HEAD);
}
void JustEngagedWith(Unit* /*who*/) override
{
me->SummonCreature(NPC_LEFT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0);
me->SummonCreature(NPC_RIGHT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0);
if (Creature* LeftHead = GetLeftHead())
switch (yell)
{
uint8 aggroYell = urand(EVENT_AGGRO_YELL_1, EVENT_AGGRO_YELL_3);
LeftHead->AI()->Talk(aggroYell - 1);
events2.ScheduleEvent(aggroYell, 3000);
}
_JustEngagedWith();
scheduler.Schedule(500ms, GROUP_FULL_PHASE, [this](TaskContext context)
{
scheduler.Schedule(12100ms, 17300ms, GROUP_NON_BURNING_PHASE, [this](TaskContext context)
case SAY_ON_AGGRO:
{
DoCastAOE(SPELL_THUNDERCLAP);
context.Repeat(17200ms, 24200ms);
}).Schedule(20s, 30s, GROUP_NON_BURNING_PHASE, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_BEATDOWN);
me->SetUnitFlag(UNIT_FLAG_PACIFIED);
me->SetReactState(REACT_PASSIVE);
scheduler.Schedule(200ms, GROUP_NON_BURNING_PHASE, [this](TaskContext /*context*/)
uint8 group = urand(SAY_ON_AGGRO, SAY_ON_AGGRO_3);
if (Creature* leftHead = instance->GetCreature(DATA_OMROGG_LEFT_HEAD))
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
uint8 threatYell = urand(EVENT_THREAT_YELL_L_1, EVENT_THREAT_YELL_R_1);
if (Creature* head = threatYell == EVENT_THREAT_YELL_R_1 ? GetRightHead() : GetLeftHead())
leftHead->AI()->Talk(group);
_headTalk.Schedule(3600ms, [this, group](TaskContext /*context*/)
{
head->AI()->Talk(threatYell - 1);
}
events.ScheduleEvent(threatYell, 3000);
DoResetThreatList();
me->AddThreat(target, 2250.0f);
scheduler.Schedule(1200ms, GROUP_BURNING_PHASE, [this](TaskContext /*context*/)
{
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveUnitFlag(UNIT_FLAG_PACIFIED);
if (Creature* rightHead = instance->GetCreature(DATA_OMROGG_RIGHT_HEAD))
rightHead->AI()->Talk(group);
});
}
}).Schedule(40s, 60s, GROUP_NON_BURNING_PHASE, [this](TaskContext /*context*/)
}
break;
}
case SAY_ON_BEATDOWN:
{
if (Creature* leftHead = instance->GetCreature(DATA_OMROGG_LEFT_HEAD))
{
me->SetUnitFlag(UNIT_FLAG_PACIFIED);
me->SetReactState(REACT_PASSIVE);
scheduler.Schedule(1200ms, GROUP_NON_BURNING_PHASE, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_FEAR);
DoCastSelf(SPELL_BURNING_MAUL);
me->LoadEquipment(EQUIP_BURNING_MAUL);
scheduler.CancelGroup(GROUP_NON_BURNING_PHASE);
scheduler.Schedule(200ms, GROUP_BURNING_PHASE, [this](TaskContext /*context*/)
leftHead->AI()->Talk(SAY_ON_BEATDOWN);
_headTalk.Schedule(3600ms, [this](TaskContext context)
{
me->Yell("%s roars!", LANG_UNIVERSAL);
scheduler.Schedule(2200ms, GROUP_BURNING_PHASE, [this](TaskContext /*context*/)
if (Creature* rightHead = instance->GetCreature(DATA_OMROGG_RIGHT_HEAD))
rightHead->AI()->Talk(SAY_ON_BEATDOWN);
context.Schedule(3600ms, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
uint8 group = urand(SAY_ON_BEATDOWN_2, SAY_ON_BEATDOWN_3);
if (Creature* leftHead = instance->GetCreature(DATA_OMROGG_LEFT_HEAD))
leftHead->AI()->Talk(group);
context.Schedule(3600ms, [this, group](TaskContext /*context*/)
{
uint8 threatYell = urand(EVENT_THREAT_YELL_L_1, EVENT_THREAT_YELL_R_1);
if (Creature* head = threatYell == EVENT_THREAT_YELL_R_1 ? GetRightHead() : GetLeftHead())
{
head->AI()->Talk(threatYell - 1);
}
events.ScheduleEvent(threatYell, 3000);
DoResetThreatList();
me->AddThreat(target, 2250.0f);
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveUnitFlag(UNIT_FLAG_PACIFIED);
}
if (Creature* rightHead = instance->GetCreature(DATA_OMROGG_RIGHT_HEAD))
rightHead->AI()->Talk(group);
});
});
});
scheduler.Schedule(4850ms, 8500ms, GROUP_BURNING_PHASE, [this](TaskContext context)
{
DoCastAOE(SPELL_BLAST_WAVE, false);
context.Repeat(4850ms, 8500ms);
}).Schedule(45s, 60s, GROUP_BURNING_PHASE, [this](TaskContext context)
{
me->LoadEquipment(EQUIP_STANDARD);
context.CancelGroup(GROUP_BURNING_PHASE);
scheduler.RescheduleGroup(GROUP_NON_BURNING_PHASE, 5ms);
context.RescheduleGroup(GROUP_NON_BURNING_PHASE, 5ms);
context.RescheduleGroup(GROUP_FULL_PHASE, 1050ms);
});
}
break;
}
case SAY_ON_KILL:
{
uint8 group = urand(SAY_ON_KILL, SAY_ON_KILL_2);
if (Creature* leftHead = instance->GetCreature(DATA_OMROGG_LEFT_HEAD))
leftHead->AI()->Talk(group);
_headTalk.Schedule(3600ms, [this, group](TaskContext /*context*/)
{
if (Creature* rightHead = instance->GetCreature(DATA_OMROGG_RIGHT_HEAD))
rightHead->AI()->Talk(group);
});
});
});
context.Repeat(130s, 150s);
});
break;
}
case SAY_ON_DEATH:
{
if (Creature* leftHead = instance->GetCreature(DATA_OMROGG_LEFT_HEAD))
leftHead->AI()->Talk(SAY_ON_DEATH);
_headTalk.Schedule(3600ms, [this](TaskContext /*context*/)
{
if (Creature* rightHead = instance->GetCreature(DATA_OMROGG_RIGHT_HEAD))
rightHead->AI()->Talk(SAY_ON_DEATH);
});
break;
}
default:
break;
}
}
void JustSummoned(Creature* summoned) override
void SetData(uint32 data, uint32) override
{
summons.Summon(summoned);
}
void KilledUnit(Unit* /*victim*/) override
{
Creature* head = nullptr;
uint32 eventId = EVENT_KILL_YELL_LEFT;
if (urand(0, 1))
{
head = GetLeftHead();
eventId = EVENT_KILL_YELL_LEFT;
}
else
{
head = GetRightHead();
eventId = EVENT_KILL_YELL_RIGHT;
}
if (head)
{
head->AI()->Talk(eventId - 1);
}
events2.ScheduleEvent(eventId, 3000);
}
void JustDied(Unit* /*killer*/) override
{
Creature* LeftHead = GetLeftHead();
Creature* RightHead = GetRightHead();
if (!LeftHead || !RightHead)
if (data != DATA_BURNING_MAUL_END)
return;
LeftHead->DespawnOrUnsummon(5000);
RightHead->DespawnOrUnsummon(5000);
LeftHead->AI()->Talk(EVENT_DEATH_YELL - 1);
RightHead->AI()->SetData(SETDATA_DATA, SETDATA_YELL);
instance->SetBossState(DATA_OMROGG, DONE);
scheduler.CancelGroup(GROUP_BURNING_PHASE);
ScheduleNonBurningPhase();
ScheduleBurningPhase();
}
void ScheduleNonBurningPhase()
{
scheduler.
Schedule(12100ms, 17300ms, GROUP_NON_BURNING_PHASE, [this](TaskContext context)
{
DoCastAOE(SPELL_THUNDERCLAP);
context.Repeat(17200ms, 24200ms);
})
.Schedule(20s, 30s, GROUP_NON_BURNING_PHASE, [this](TaskContext context)
{
DoCastSelf(SPELL_BEATDOWN);
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
context.Schedule(200ms, GROUP_NON_BURNING_PHASE, [this](TaskContext context)
{
DoResetThreatList();
if (Unit* newTarget = SelectTarget(SelectTargetMethod::Random, 1))
me->AddThreat(newTarget, 2250.f);
HandleHeadTalk(SAY_ON_BEATDOWN);
context.Schedule(1200ms, GROUP_NON_BURNING_PHASE, [this](TaskContext /*context*/)
{
me->SetReactState(REACT_AGGRESSIVE);
});
});
context.Repeat();
});
}
void ScheduleBurningPhase()
{
scheduler.
Schedule(45s, 60s, GROUP_BURNING_PHASE, [this](TaskContext context)
{
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
context.CancelGroup(GROUP_NON_BURNING_PHASE);
context.Schedule(1200ms, [this](TaskContext context)
{
DoCastAOE(SPELL_FEAR);
DoCast(SPELL_BURNING_MAUL);
context.Schedule(200ms, [this](TaskContext context)
{
Talk(EMOTE_BURNING_MAUL);
context.Schedule(2200ms, [this](TaskContext context)
{
DoResetThreatList();
if (Unit* newTarget = SelectTarget(SelectTargetMethod::Random, 1))
me->AddThreat(newTarget, 2250.f);
me->SetReactState(REACT_AGGRESSIVE);
context.Schedule(4850ms, 8500ms, GROUP_BURNING_PHASE, [this](TaskContext context)
{
DoCastAOE(SPELL_BLAST_WAVE);
context.Repeat();
});
});
});
});
});
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
_headTalk.CancelAll();
HandleHeadTalk(SAY_ON_AGGRO);
ScheduleNonBurningPhase();
ScheduleBurningPhase();
}
void KilledUnit(Unit* victim) override
{
if (victim && victim->GetTypeId() == TYPEID_PLAYER)
HandleHeadTalk(SAY_ON_KILL);
}
void JustDied(Unit* killer) override
{
HandleHeadTalk(SAY_ON_DEATH);
BossAI::JustDied(killer);
}
void UpdateAI(uint32 diff) override
{
events2.Update(diff);
scheduler.Update(diff);
switch (uint32 eventId = events2.ExecuteEvent())
{
case EVENT_AGGRO_YELL_1:
case EVENT_AGGRO_YELL_2:
case EVENT_AGGRO_YELL_3:
case EVENT_KILL_YELL_LEFT:
case EVENT_THREAT_YELL_L_1:
case EVENT_THREAT_YELL_L_2:
case EVENT_THREAT_YELL_L_3:
if (Creature* RightHead = GetRightHead())
{
RightHead->AI()->Talk(eventId - 1);
}
break;
case EVENT_KILL_YELL_RIGHT:
case EVENT_THREAT_YELL_R_1:
if (Creature* LeftHead = GetLeftHead())
{
LeftHead->AI()->Talk(eventId - 1);
}
break;
}
_headTalk.Update(diff);
if (!UpdateVictim())
return;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
scheduler.Update(diff, [this]
{
DoMeleeAttackIfReady();
});
}
protected:
TaskScheduler _headTalk;
};
struct npc_omrogg_heads : public NullCreatureAI
class spell_burning_maul : public AuraScript
{
npc_omrogg_heads(Creature* creature) : NullCreatureAI(creature)
{
timer = 0;
}
PrepareAuraScript(spell_burning_maul);
void SetData(uint32 data, uint32 value) override
void HandleOnRemove(AuraEffect const* /* aurEff */, AuraEffectHandleModes /* mode */)
{
if (Unit* caster = GetCaster())
{
if (data == SETDATA_DATA && value == SETDATA_YELL)
timer = 1;
}
void UpdateAI(uint32 diff) override
{
if (timer)
if (Creature* omrogg = caster->ToCreature())
{
timer += diff;
if (timer >= 3000)
{
timer = 0;
Talk(EVENT_DEATH_YELL - 1);
}
omrogg->LoadEquipment(EQUIP_STANDARD);
omrogg->AI()->SetData(DATA_BURNING_MAUL_END, 0);
}
}
uint32 timer;
}
void HandleOnApply(AuraEffect const* /* aurEff */, AuraEffectHandleModes /* mode */)
{
if (Unit* caster = GetCaster())
if (Creature* omrogg = caster->ToCreature())
omrogg->LoadEquipment(EQUIP_BURNING_MAUL);
}
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_burning_maul::HandleOnRemove, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
OnEffectApply += AuraEffectApplyFn(spell_burning_maul::HandleOnApply, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
void AddSC_boss_warbringer_omrogg()
{
RegisterShatteredHallsCreatureAI(boss_warbringer_omrogg);
RegisterShatteredHallsCreatureAI(npc_omrogg_heads);
RegisterSpellScript(spell_burning_maul);
}

View File

@@ -22,9 +22,11 @@
ObjectData const creatureData[] =
{
{ NPC_GRAND_WARLOCK_NETHEKURSE, DATA_NETHEKURSE },
{ NPC_WARCHIEF_KARGATH, DATA_KARGATH },
{ 0, 0 }
{ NPC_GRAND_WARLOCK_NETHEKURSE , DATA_NETHEKURSE },
{ NPC_WARCHIEF_KARGATH , DATA_KARGATH },
{ NPC_OMROGG_LEFT_HEAD , DATA_OMROGG_LEFT_HEAD },
{ NPC_OMROGG_RIGHT_HEAD , DATA_OMROGG_RIGHT_HEAD },
{ 0 , 0 }
};
DoorData const doorData[] =

View File

@@ -35,7 +35,9 @@ enum DataTypes
DATA_PRISONER_1 = 11,
DATA_PRISONER_2 = 12,
DATA_PRISONER_3 = 13,
DATA_EXECUTIONER = 14
DATA_EXECUTIONER = 14,
DATA_OMROGG_LEFT_HEAD = 15,
DATA_OMROGG_RIGHT_HEAD = 16
};
enum CreatureIds
@@ -44,6 +46,10 @@ enum CreatureIds
NPC_WARCHIEF_KARGATH = 16808,
NPC_FEL_ORC_CONVERT = 17083,
// O'MROGG
NPC_OMROGG_LEFT_HEAD = 19523,
NPC_OMROGG_RIGHT_HEAD = 19524,
// Trial of the Naaru: Mercy
NPC_SHATTERED_EXECUTIONER = 17301,
NPC_RIFLEMAN_BROWNBEARD = 17289,