Scripts/BWL: Update scripts to new register model (3/3) (#26691)

(cherry picked from commit 572b480a2e)
This commit is contained in:
offl
2021-07-14 22:23:17 +03:00
committed by Shauren
parent 62879fec9c
commit 17d3d1087c
2 changed files with 272 additions and 327 deletions

View File

@@ -64,174 +64,141 @@ enum EVENTS
EVENT_CONFLAGRATION = 4
};
class boss_razorgore : public CreatureScript
struct boss_razorgore : public BossAI
{
public:
boss_razorgore() : CreatureScript("boss_razorgore") { }
struct boss_razorgoreAI : public BossAI
boss_razorgore(Creature* creature) : BossAI(creature, DATA_RAZORGORE_THE_UNTAMED)
{
boss_razorgoreAI(Creature* creature) : BossAI(creature, DATA_RAZORGORE_THE_UNTAMED)
Initialize();
}
void Initialize()
{
secondPhase = false;
}
void Reset() override
{
_Reset();
Initialize();
instance->SetData(DATA_EGG_EVENT, NOT_STARTED);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
instance->SetData(DATA_EGG_EVENT, NOT_STARTED);
}
void DoChangePhase()
{
events.ScheduleEvent(EVENT_CLEAVE, 15s);
events.ScheduleEvent(EVENT_STOMP, 35s);
events.ScheduleEvent(EVENT_FIREBALL, 7s);
events.ScheduleEvent(EVENT_CONFLAGRATION, 12s);
secondPhase = true;
me->RemoveAllAuras();
me->SetFullHealth();
}
void DoAction(int32 action) override
{
if (action == ACTION_PHASE_TWO)
DoChangePhase();
}
void DamageTaken(Unit* /*who*/, uint32& damage) override
{
// @todo this is wrong - razorgore should still take damage, he should just nuke the whole room and respawn if he dies during P1
if (!secondPhase)
damage = 0;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
Initialize();
}
void Initialize()
{
secondPhase = false;
}
void Reset() override
{
_Reset();
Initialize();
instance->SetData(DATA_EGG_EVENT, NOT_STARTED);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
instance->SetData(DATA_EGG_EVENT, NOT_STARTED);
}
void DoChangePhase()
{
events.ScheduleEvent(EVENT_CLEAVE, 15s);
events.ScheduleEvent(EVENT_STOMP, 35s);
events.ScheduleEvent(EVENT_FIREBALL, 7s);
events.ScheduleEvent(EVENT_CONFLAGRATION, 12s);
secondPhase = true;
me->RemoveAllAuras();
me->SetFullHealth();
}
void DoAction(int32 action) override
{
if (action == ACTION_PHASE_TWO)
DoChangePhase();
}
void DamageTaken(Unit* /*who*/, uint32& damage) override
{
// @todo this is wrong - razorgore should still take damage, he should just nuke the whole room and respawn if he dies during P1
if (!secondPhase)
damage = 0;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
switch (eventId)
{
case EVENT_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, 7s, 10s);
break;
case EVENT_STOMP:
DoCastVictim(SPELL_WARSTOMP);
events.ScheduleEvent(EVENT_STOMP, 15s, 25s);
break;
case EVENT_FIREBALL:
DoCastVictim(SPELL_FIREBALLVOLLEY);
events.ScheduleEvent(EVENT_FIREBALL, 12s, 15s);
break;
case EVENT_CONFLAGRATION:
DoCastVictim(SPELL_CONFLAGRATION);
events.ScheduleEvent(EVENT_CONFLAGRATION, 30s);
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, 7s, 10s);
break;
case EVENT_STOMP:
DoCastVictim(SPELL_WARSTOMP);
events.ScheduleEvent(EVENT_STOMP, 15s, 25s);
break;
case EVENT_FIREBALL:
DoCastVictim(SPELL_FIREBALLVOLLEY);
events.ScheduleEvent(EVENT_FIREBALL, 12s, 15s);
break;
case EVENT_CONFLAGRATION:
DoCastVictim(SPELL_CONFLAGRATION);
events.ScheduleEvent(EVENT_CONFLAGRATION, 30s);
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
DoMeleeAttackIfReady();
}
DoMeleeAttackIfReady();
}
private:
bool secondPhase;
};
private:
bool secondPhase;
};
CreatureAI* GetAI(Creature* creature) const override
struct go_orb_of_domination : public GameObjectAI
{
go_orb_of_domination(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
InstanceScript* instance;
bool OnGossipHello(Player* player) override
{
return GetBlackwingLairAI<boss_razorgoreAI>(creature);
if (instance->GetData(DATA_EGG_EVENT) != DONE)
{
if (Creature* razorgore = instance->GetCreature(DATA_RAZORGORE_THE_UNTAMED))
{
razorgore->Attack(player, true);
player->CastSpell(razorgore, SPELL_MINDCONTROL);
}
}
return true;
}
};
class go_orb_of_domination : public GameObjectScript
{
public:
go_orb_of_domination() : GameObjectScript("go_orb_of_domination") { }
struct go_orb_of_dominationAI : public GameObjectAI
{
go_orb_of_dominationAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
InstanceScript* instance;
bool OnGossipHello(Player* player) override
{
if (instance->GetData(DATA_EGG_EVENT) != DONE)
{
if (Creature* razorgore = instance->GetCreature(DATA_RAZORGORE_THE_UNTAMED))
{
razorgore->Attack(player, true);
player->CastSpell(razorgore, SPELL_MINDCONTROL);
}
}
return true;
}
};
GameObjectAI* GetAI(GameObject* go) const override
{
return GetBlackwingLairAI<go_orb_of_dominationAI>(go);
}
};
// 19873 - Destroy Egg
class spell_egg_event : public SpellScriptLoader
class spell_egg_event : public SpellScript
{
public:
spell_egg_event() : SpellScriptLoader("spell_egg_event") { }
PrepareSpellScript(spell_egg_event);
class spell_egg_eventSpellScript : public SpellScript
{
PrepareSpellScript(spell_egg_eventSpellScript);
void HandleOnHit()
{
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
instance->SetData(DATA_EGG_EVENT, SPECIAL);
}
void HandleOnHit()
{
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
instance->SetData(DATA_EGG_EVENT, SPECIAL);
}
void Register() override
{
OnHit += SpellHitFn(spell_egg_eventSpellScript::HandleOnHit);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_egg_eventSpellScript();
}
void Register() override
{
OnHit += SpellHitFn(spell_egg_event::HandleOnHit);
}
};
void AddSC_boss_razorgore()
{
new boss_razorgore();
new go_orb_of_domination();
new spell_egg_event();
RegisterBlackwingLairCreatureAI(boss_razorgore);
RegisterBlackwingLairGameObjectAI(go_orb_of_domination);
RegisterSpellScript(spell_egg_event);
}

View File

@@ -64,218 +64,196 @@ enum Events
EVENT_BURNINGADRENALINE_TANK = 11
};
class boss_vaelastrasz : public CreatureScript
struct boss_vaelastrasz : public BossAI
{
public:
boss_vaelastrasz() : CreatureScript("boss_vaelastrasz") { }
struct boss_vaelAI : public BossAI
boss_vaelastrasz(Creature* creature) : BossAI(creature, DATA_VAELASTRAZ_THE_CORRUPT)
{
boss_vaelAI(Creature* creature) : BossAI(creature, DATA_VAELASTRAZ_THE_CORRUPT)
Initialize();
creature->AddNpcFlag(UNIT_NPC_FLAG_GOSSIP);
creature->SetFaction(FACTION_FRIENDLY);
creature->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
void Initialize()
{
PlayerGUID.Clear();
HasYelled = false;
}
void Reset() override
{
_Reset();
me->SetStandState(UNIT_STAND_STATE_DEAD);
Initialize();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
DoCast(me, SPELL_ESSENCEOFTHERED);
me->SetHealth(me->CountPctFromMaxHealth(30));
// now drop damage requirement to be able to take loot
me->ResetPlayerDamageReq();
events.ScheduleEvent(EVENT_CLEAVE, 10s);
events.ScheduleEvent(EVENT_FLAMEBREATH, 15s);
events.ScheduleEvent(EVENT_FIRENOVA, 20s);
events.ScheduleEvent(EVENT_TAILSWIPE, 11s);
events.ScheduleEvent(EVENT_BURNINGADRENALINE_CASTER, 15s);
events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45s);
}
void BeginSpeech(Unit* target)
{
PlayerGUID = target->GetGUID();
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
events.ScheduleEvent(EVENT_SPEECH_1, 1s);
}
void KilledUnit(Unit* victim) override
{
if (rand32() % 5)
return;
Talk(SAY_KILLTARGET, victim);
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
// Speech
if (!UpdateVictim())
{
Initialize();
creature->AddNpcFlag(UNIT_NPC_FLAG_GOSSIP);
creature->SetFaction(FACTION_FRIENDLY);
creature->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
void Initialize()
{
PlayerGUID.Clear();
HasYelled = false;
}
void Reset() override
{
_Reset();
me->SetStandState(UNIT_STAND_STATE_DEAD);
Initialize();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
DoCast(me, SPELL_ESSENCEOFTHERED);
me->SetHealth(me->CountPctFromMaxHealth(30));
// now drop damage requirement to be able to take loot
me->ResetPlayerDamageReq();
events.ScheduleEvent(EVENT_CLEAVE, 10s);
events.ScheduleEvent(EVENT_FLAMEBREATH, 15s);
events.ScheduleEvent(EVENT_FIRENOVA, 20s);
events.ScheduleEvent(EVENT_TAILSWIPE, 11s);
events.ScheduleEvent(EVENT_BURNINGADRENALINE_CASTER, 15s);
events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45s);
}
void BeginSpeech(Unit* target)
{
PlayerGUID = target->GetGUID();
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
events.ScheduleEvent(EVENT_SPEECH_1, 1s);
}
void KilledUnit(Unit* victim) override
{
if (rand32() % 5)
return;
Talk(SAY_KILLTARGET, victim);
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
// Speech
if (!UpdateVictim())
{
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SPEECH_1:
Talk(SAY_LINE1);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
events.ScheduleEvent(EVENT_SPEECH_2, 12s);
break;
case EVENT_SPEECH_2:
Talk(SAY_LINE2);
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
events.ScheduleEvent(EVENT_SPEECH_3, 12s);
break;
case EVENT_SPEECH_3:
Talk(SAY_LINE3);
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
events.ScheduleEvent(EVENT_SPEECH_4, 16s);
break;
case EVENT_SPEECH_4:
me->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
AttackStart(player);
break;
}
}
return;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_CLEAVE:
events.ScheduleEvent(EVENT_CLEAVE, 15s);
DoCastVictim(SPELL_CLEAVE);
case EVENT_SPEECH_1:
Talk(SAY_LINE1);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
events.ScheduleEvent(EVENT_SPEECH_2, 12s);
break;
case EVENT_FLAMEBREATH:
DoCastVictim(SPELL_FLAMEBREATH);
events.ScheduleEvent(EVENT_FLAMEBREATH, 8s, 14s);
case EVENT_SPEECH_2:
Talk(SAY_LINE2);
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
events.ScheduleEvent(EVENT_SPEECH_3, 12s);
break;
case EVENT_FIRENOVA:
DoCastVictim(SPELL_FIRENOVA);
events.ScheduleEvent(EVENT_FIRENOVA, 15s);
case EVENT_SPEECH_3:
Talk(SAY_LINE3);
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
events.ScheduleEvent(EVENT_SPEECH_4, 16s);
break;
case EVENT_TAILSWIPE:
//Only cast if we are behind
/*if (!me->HasInArc(M_PI, me->GetVictim()))
{
DoCast(me->GetVictim(), SPELL_TAILSWIPE);
}*/
events.ScheduleEvent(EVENT_TAILSWIPE, 15s);
break;
case EVENT_BURNINGADRENALINE_CASTER:
{
//selects a random target that isn't the current victim and is a mana user (selects mana users) but not pets
//it also ignores targets who have the aura. We don't want to place the debuff on the same target twice.
if (Unit *target = SelectTarget(SelectTargetMethod::Random, 1, [&](Unit* u) { return u && !u->IsPet() && u->GetPowerType() == POWER_MANA && !u->HasAura(SPELL_BURNINGADRENALINE); }))
{
me->CastSpell(target, SPELL_BURNINGADRENALINE, true);
}
}
//reschedule the event
events.ScheduleEvent(EVENT_BURNINGADRENALINE_CASTER, 15s);
break;
case EVENT_BURNINGADRENALINE_TANK:
//Vael has to cast it himself; contrary to the previous commit's comment. Nothing happens otherwise.
me->CastSpell(me->GetVictim(), SPELL_BURNINGADRENALINE, true);
events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45s);
case EVENT_SPEECH_4:
me->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
AttackStart(player);
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
// Yell if hp lower than 15%
if (HealthBelowPct(15) && !HasYelled)
{
Talk(SAY_HALFLIFE);
HasYelled = true;
}
DoMeleeAttackIfReady();
return;
}
bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
if (menuId == GOSSIP_ID && gossipListId == 0)
switch (eventId)
{
CloseGossipMenuFor(player);
BeginSpeech(player);
case EVENT_CLEAVE:
events.ScheduleEvent(EVENT_CLEAVE, 15s);
DoCastVictim(SPELL_CLEAVE);
break;
case EVENT_FLAMEBREATH:
DoCastVictim(SPELL_FLAMEBREATH);
events.ScheduleEvent(EVENT_FLAMEBREATH, 8s, 14s);
break;
case EVENT_FIRENOVA:
DoCastVictim(SPELL_FIRENOVA);
events.ScheduleEvent(EVENT_FIRENOVA, 15s);
break;
case EVENT_TAILSWIPE:
//Only cast if we are behind
/*if (!me->HasInArc(M_PI, me->GetVictim()))
{
DoCast(me->GetVictim(), SPELL_TAILSWIPE);
}*/
events.ScheduleEvent(EVENT_TAILSWIPE, 15s);
break;
case EVENT_BURNINGADRENALINE_CASTER:
{
//selects a random target that isn't the current victim and is a mana user (selects mana users) but not pets
//it also ignores targets who have the aura. We don't want to place the debuff on the same target twice.
if (Unit *target = SelectTarget(SelectTargetMethod::Random, 1, [&](Unit* u) { return u && !u->IsPet() && u->GetPowerType() == POWER_MANA && !u->HasAura(SPELL_BURNINGADRENALINE); }))
{
me->CastSpell(target, SPELL_BURNINGADRENALINE, true);
}
}
//reschedule the event
events.ScheduleEvent(EVENT_BURNINGADRENALINE_CASTER, 15s);
break;
case EVENT_BURNINGADRENALINE_TANK:
//Vael has to cast it himself; contrary to the previous commit's comment. Nothing happens otherwise.
me->CastSpell(me->GetVictim(), SPELL_BURNINGADRENALINE, true);
events.ScheduleEvent(EVENT_BURNINGADRENALINE_TANK, 45s);
break;
}
return false;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
private:
ObjectGuid PlayerGUID;
bool HasYelled;
};
// Yell if hp lower than 15%
if (HealthBelowPct(15) && !HasYelled)
{
Talk(SAY_HALFLIFE);
HasYelled = true;
}
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackwingLairAI<boss_vaelAI>(creature);
DoMeleeAttackIfReady();
}
bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
{
if (menuId == GOSSIP_ID && gossipListId == 0)
{
CloseGossipMenuFor(player);
BeginSpeech(player);
}
return false;
}
private:
ObjectGuid PlayerGUID;
bool HasYelled;
};
//Need to define an aurascript for EVENT_BURNINGADRENALINE's death effect.
// 18173 - Burning Adrenaline
class spell_vael_burning_adrenaline : public SpellScriptLoader
class spell_vael_burning_adrenaline : public AuraScript
{
public:
spell_vael_burning_adrenaline() : SpellScriptLoader("spell_vael_burning_adrenaline") { }
PrepareAuraScript(spell_vael_burning_adrenaline);
class spell_vael_burning_adrenaline_AuraScript : public AuraScript
void OnAuraRemoveHandler(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
PrepareAuraScript(spell_vael_burning_adrenaline_AuraScript);
//The tooltip says the on death the AoE occurs. According to information: http://qaliaresponse.stage.lithium.com/t5/WoW-Mayhem/Surviving-Burning-Adrenaline-For-tanks/td-p/48609
//Burning Adrenaline can be survived therefore Blizzard's implementation was an AoE bomb that went off if you were still alive and dealt
//damage to the target. You don't have to die for it to go off. It can go off whether you live or die.
GetTarget()->CastSpell(GetTarget(), SPELL_BURNINGADRENALINE_EXPLOSION, true);
}
void OnAuraRemoveHandler(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
//The tooltip says the on death the AoE occurs. According to information: http://qaliaresponse.stage.lithium.com/t5/WoW-Mayhem/Surviving-Burning-Adrenaline-For-tanks/td-p/48609
//Burning Adrenaline can be survived therefore Blizzard's implementation was an AoE bomb that went off if you were still alive and dealt
//damage to the target. You don't have to die for it to go off. It can go off whether you live or die.
GetTarget()->CastSpell(GetTarget(), SPELL_BURNINGADRENALINE_EXPLOSION, true);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_vael_burning_adrenaline_AuraScript::OnAuraRemoveHandler, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_vael_burning_adrenaline_AuraScript();
AfterEffectRemove += AuraEffectRemoveFn(spell_vael_burning_adrenaline::OnAuraRemoveHandler, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
void AddSC_boss_vaelastrasz()
{
new boss_vaelastrasz();
new spell_vael_burning_adrenaline();
RegisterBlackwingLairCreatureAI(boss_vaelastrasz);
RegisterSpellScript(spell_vael_burning_adrenaline);
}