Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
bash
2025-09-23 14:43:56 +02:00
committed by GitHub
11 changed files with 270 additions and 141 deletions
@@ -56,21 +56,24 @@ enum Misc
{
ACHIEV_TIMED_START_EVENT = 20381,
EVENT_CHECK_HEALTH_25 = 1,
EVENT_CHECK_HEALTH_50 = 2,
EVENT_CHECK_HEALTH_75 = 3,
EVENT_CARRION_BEETELS = 4,
EVENT_LEECHING_SWARM = 5,
EVENT_IMPALE = 6,
EVENT_POUND = 7,
EVENT_CLOSE_DOORS = 8,
EVENT_EMERGE = 9,
EVENT_SUMMON_VENOMANCER = 10,
EVENT_SUMMON_DARTER = 11,
EVENT_SUMMON_GUARDIAN = 12,
EVENT_SUMMON_ASSASSINS = 13,
EVENT_ENABLE_ROTATE = 14,
EVENT_KILL_TALK = 15
EVENT_CARRION_BEETELS = 1,
EVENT_LEECHING_SWARM = 2,
EVENT_IMPALE = 3,
EVENT_POUND = 4,
EVENT_CLOSE_DOORS = 5,
EVENT_EMERGE = 6,
EVENT_SUMMON_VENOMANCER = 7,
EVENT_SUMMON_DARTER = 8,
EVENT_SUMMON_GUARDIAN = 9,
EVENT_SUMMON_ASSASSINS = 10,
EVENT_ENABLE_ROTATE = 11,
EVENT_KILL_TALK = 12
};
enum ANAnubarakNpcs
{
NPC_ANUBAR_GUARDIAN = 29216,
NPC_ANUBAR_VENOMANCER = 29217
};
class boss_anub_arak : public CreatureScript
@@ -83,11 +86,10 @@ class boss_anub_arak : public CreatureScript
boss_anub_arakAI(Creature* creature) : BossAI(creature, DATA_ANUBARAK_EVENT)
{
me->m_SightDistance = 120.0f;
intro = false;
_intro = false;
_summonedMinions = false;
}
bool intro;
void EnterEvadeMode(EvadeReason why) override
{
me->DisableRotate(false);
@@ -96,9 +98,9 @@ class boss_anub_arak : public CreatureScript
void MoveInLineOfSight(Unit* who) override
{
if (!intro && who->IsPlayer())
if (!_intro && who->IsPlayer())
{
intro = true;
_intro = true;
Talk(SAY_INTRO);
}
BossAI::MoveInLineOfSight(who);
@@ -129,8 +131,42 @@ class boss_anub_arak : public CreatureScript
void Reset() override
{
BossAI::Reset();
_summonedMinions = false;
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
ScheduleHealthCheckEvent({ 75, 50, 25 }, [&]{
Talk(SAY_SUBMERGE);
_summonedMinions = false;
DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true);
DoCastSelf(SPELL_SUBMERGE, false);
me->m_Events.AddEventAtOffset([this] {
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
DoCastSelf(SPELL_IMPALE_PERIODIC, true);
}, 2s);
events.Reset();
events.ScheduleEvent(EVENT_EMERGE, 60s);
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 2s);
events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4s);
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 15s);
events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 20s);
events.ScheduleEvent(EVENT_SUMMON_DARTER, 30s);
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 35s);
}, false);
}
void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override
{
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
return;
if (_summonedMinions && !summons.IsAnyCreatureWithEntryAlive(NPC_ANUBAR_GUARDIAN) && !summons.IsAnyCreatureWithEntryAlive(NPC_ANUBAR_VENOMANCER))
{
events.Reset();
events.ScheduleEvent(EVENT_EMERGE, 5s);
}
}
void JustEngagedWith(Unit* ) override
@@ -141,16 +177,13 @@ class boss_anub_arak : public CreatureScript
events.ScheduleEvent(EVENT_CARRION_BEETELS, 6500ms);
events.ScheduleEvent(EVENT_LEECHING_SWARM, 20s);
events.ScheduleEvent(EVENT_POUND, 15s);
events.ScheduleEvent(EVENT_CHECK_HEALTH_75, 1s);
events.ScheduleEvent(EVENT_CHECK_HEALTH_50, 1s);
events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 1s);
events.ScheduleEvent(EVENT_CLOSE_DOORS, 5s);
}
void SummonHelpers(float x, float y, float z, uint32 spellId)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
me->SummonCreature(spellInfo->Effects[EFFECT_0].MiscValue, x, y, z);
me->SummonCreature(spellInfo->Effects[EFFECT_0].MiscValue, x, y, z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
}
void UpdateAI(uint32 diff) override
@@ -159,10 +192,12 @@ class boss_anub_arak : public CreatureScript
return;
events.Update(diff);
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (uint32 eventId = events.ExecuteEvent())
switch (events.ExecuteEvent())
{
case EVENT_CLOSE_DOORS:
_JustEngagedWith();
@@ -191,34 +226,14 @@ class boss_anub_arak : public CreatureScript
me->RemoveAurasDueToSpell(SPELL_SELF_ROOT);
me->DisableRotate(false);
break;
case EVENT_CHECK_HEALTH_25:
case EVENT_CHECK_HEALTH_50:
case EVENT_CHECK_HEALTH_75:
if (me->HealthBelowPct(eventId*25))
{
Talk(SAY_SUBMERGE);
DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true);
me->CastSpell(me, SPELL_IMPALE_PERIODIC, true);
me->CastSpell(me, SPELL_SUBMERGE, false);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
events.DelayEvents(46000, 0);
events.ScheduleEvent(EVENT_EMERGE, 45s);
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 2s);
events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4s);
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 15s);
events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 20s);
events.ScheduleEvent(EVENT_SUMMON_DARTER, 30s);
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 35s);
break;
}
events.ScheduleEvent(eventId, 500ms);
break;
case EVENT_EMERGE:
me->CastSpell(me, SPELL_EMERGE, true);
me->RemoveAura(SPELL_SUBMERGE);
me->RemoveAura(SPELL_IMPALE_PERIODIC);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
events.ScheduleEvent(EVENT_CARRION_BEETELS, 6500ms);
events.ScheduleEvent(EVENT_LEECHING_SWARM, 20s);
events.ScheduleEvent(EVENT_POUND, 15s);
break;
case EVENT_SUMMON_ASSASSINS:
SummonHelpers(509.32f, 247.42f, 239.48f, SPELL_SUMMON_ASSASSIN);
@@ -232,6 +247,7 @@ class boss_anub_arak : public CreatureScript
SummonHelpers(550.34f, 316.00f, 234.30f, SPELL_SUMMON_GUARDIAN);
break;
case EVENT_SUMMON_VENOMANCER:
_summonedMinions = true;
SummonHelpers(550.34f, 316.00f, 234.30f, SPELL_SUMMON_VENOMANCER);
break;
}
@@ -239,6 +255,10 @@ class boss_anub_arak : public CreatureScript
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
DoMeleeAttackIfReady();
}
private:
bool _intro;
bool _summonedMinions;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -75,21 +75,32 @@ class boss_slad_ran : public CreatureScript
public:
boss_slad_ran() : CreatureScript("boss_slad_ran") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetGundrakAI<boss_slad_ranAI>(creature);
}
struct boss_slad_ranAI : public BossAI
{
boss_slad_ranAI(Creature* creature) : BossAI(creature, DATA_SLAD_RAN)
{
}
boss_slad_ranAI(Creature* creature) : BossAI(creature, DATA_SLAD_RAN) { }
void Reset() override
{
BossAI::Reset();
_achievement = true;
ScheduleHealthCheckEvent(90, [&] {
Talk(SAY_SUMMON_SNAKES);
ScheduleTimedEvent(1s, [&] {
for (uint8 i = MAX_CONSTRICTOR; i < MAX_SUMMONS; ++i)
me->SummonCreature(NPC_SLADRAN_VIPER, SpawnLoc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20 * IN_MILLISECONDS);
}, 8s);
});
ScheduleHealthCheckEvent(DUNGEON_MODE(50, 75), [&] {
Talk(SAY_SUMMON_CONSTRICTORS);
ScheduleTimedEvent(1s, [&] {
for (uint8 i = 0; i < MAX_CONSTRICTOR; ++i)
me->SummonCreature(NPC_SLADRAN_CONSTRICTORS, SpawnLoc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20 * IN_MILLISECONDS);
}, 3s, 5s);
});
}
uint32 GetData(uint32 data) const override
@@ -110,11 +121,18 @@ public:
Talk(SAY_AGGRO);
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_POISON_NOVA, 10s);
events.ScheduleEvent(EVENT_POWERFULL_BITE, 3s);
events.ScheduleEvent(EVENT_VENOM_BOLT, 15s);
events.ScheduleEvent(EVENT_CHECK_HEALTH1, 1s);
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1s);
ScheduleTimedEvent(10s, [&]{
Talk(EMOTE_NOVA);
DoCastAOE(SPELL_POISON_NOVA);
}, 15s);
ScheduleTimedEvent(3s, [&] {
DoCastVictim(SPELL_POWERFULL_BITE);
}, 10s);
ScheduleTimedEvent(15s, [&] {
DoCastVictim(SPELL_VENOM_BOLT);
}, 10s);
}
void JustDied(Unit* killer) override
@@ -133,72 +151,14 @@ public:
}
}
void JustSummoned(Creature* summon) override
{
summon->SetInCombatWithZone();
summons.Summon(summon);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK_HEALTH1:
if (me->HealthBelowPct(70))
{
Talk(SAY_SUMMON_SNAKES);
events.ScheduleEvent(EVENT_SUMMON1, 1s);
break;
}
events.ScheduleEvent(EVENT_CHECK_HEALTH1, 1s);
break;
case EVENT_CHECK_HEALTH2:
if (me->HealthBelowPct(50))
{
Talk(SAY_SUMMON_CONSTRICTORS);
events.ScheduleEvent(EVENT_SUMMON2, 1s);
break;
}
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1s);
break;
case EVENT_POISON_NOVA:
Talk(EMOTE_NOVA);
me->CastSpell(me, SPELL_POISON_NOVA, false);
events.ScheduleEvent(EVENT_POISON_NOVA, 15s);
break;
case EVENT_POWERFULL_BITE:
me->CastSpell(me->GetVictim(), SPELL_POWERFULL_BITE, false);
events.ScheduleEvent(EVENT_POWERFULL_BITE, 10s);
break;
case EVENT_VENOM_BOLT:
me->CastSpell(me->GetVictim(), SPELL_VENOM_BOLT, false);
events.ScheduleEvent(EVENT_VENOM_BOLT, 10s);
break;
case EVENT_SUMMON1:
for (uint8 i = MAX_CONSTRICTOR; i < MAX_SUMMONS; ++i)
me->SummonCreature(NPC_SLADRAN_VIPER, SpawnLoc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SUMMON1, 8s);
break;
case EVENT_SUMMON2:
for (uint8 i = 0; i < MAX_CONSTRICTOR; ++i)
me->SummonCreature(NPC_SLADRAN_CONSTRICTORS, SpawnLoc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SUMMON2, 3s, 5s);
break;
}
DoMeleeAttackIfReady();
}
private:
bool _achievement;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetGundrakAI<boss_slad_ranAI>(creature);
}
};
class spell_sladran_grip_of_sladran_aura : public AuraScript
@@ -2271,6 +2271,66 @@ private:
}
};
enum DevourGhoulSpells
{
SPELL_DEVOUR_GHOUL_RIDE_VEHICLE = 50437,
SPELL_DEVOUR_PERIODIC = 50432,
SPELL_NOURISHMENT = 50443
};
// 50430 - Devour Ghoul
class spell_dragonblight_devour_ghoul: public SpellScript
{
PrepareSpellScript(spell_dragonblight_devour_ghoul);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_DEVOUR_GHOUL_RIDE_VEHICLE });
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (GetCaster())
{
GetHitUnit()->CastSpell(GetCaster(), SPELL_DEVOUR_GHOUL_RIDE_VEHICLE, true);
GetCaster()->CastSpell(GetHitUnit(), SPELL_DEVOUR_PERIODIC, true);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_dragonblight_devour_ghoul::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 50432 - Devour Ghoul
class spell_dragonblight_devour_ghoul_periodic : public AuraScript
{
PrepareAuraScript(spell_dragonblight_devour_ghoul_periodic);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_NOURISHMENT });
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && GetCaster())
GetCaster()->CastSpell(GetCaster(), SPELL_NOURISHMENT, true);
if (GetUnitOwner() && GetUnitOwner()->ToCreature())
{
GetUnitOwner()->ExitVehicle();
GetUnitOwner()->ToCreature()->DespawnOrUnsummon(2000);
}
}
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_dragonblight_devour_ghoul_periodic::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
}
};
void AddSC_dragonblight()
{
new npc_conversing_with_the_depths_trigger();
@@ -2299,4 +2359,6 @@ void AddSC_dragonblight()
RegisterSpellScript(spell_dragonblight_corrosive_spit);
RegisterSpellScript(spell_handover_reins);
RegisterSpellScript(spell_dragonblight_flame_fury);
RegisterSpellScript(spell_dragonblight_devour_ghoul);
RegisterSpellScript(spell_dragonblight_devour_ghoul_periodic);
}