Compare commits

...

10 Commits

Author SHA1 Message Date
Smirnov Sergey
6321e695be
Merge de6e4875c29dab46f1bdc4eb8f4fe0160856f5fc into 835283bf26b02bd3c6e88505b123ad65aa9d0e98 2025-02-24 12:10:16 +03:00
Andrew
835283bf26
feat(Core/Scripting): Implement ScheduleEnrageTimer() helper (#21597) 2025-02-24 09:59:18 +01:00
Andrew
8f6d651471
fix(Scripts/SunwellPlateau): Felmyst should cast Noxious Cloud only a… (#21596) 2025-02-24 02:36:22 -03:00
github-actions[bot]
f6c29614d5 chore(DB): import pending files
Referenced commit(s): 96e7a20bd9325618b7adbd1381aa4e0e50bdba23
2025-02-24 05:19:56 +00:00
Andrew
96e7a20bd9
fix(DB/Creature): Fix Felmyst flying animation in p1 and add despawn on evade (#21396) 2025-02-24 06:18:55 +01:00
Kitzunu
cd8761796f
fix(CI/Codestyle): skip SQL keyword 'NOT' (#21591) 2025-02-24 06:16:20 +01:00
Smirnov Sergey
de6e4875c2
Update zone_borean_tundra.cpp 2025-02-11 02:23:14 +03:00
Smirnov Sergey
35e19265bb
Merge branch 'master' into fix-issue-npc25316-issues21314 2025-02-11 02:16:06 +03:00
zzlyns
240463aa24 fix(CORE/Scripts): NPC Beryl Sorcerer, Blink ability 2025-02-11 02:05:15 +03:00
zzlyns
92c541f662 fix(CORE/Scripts): NPC Beryl Sorcerer, Blink ability
Issue 21314. Beryl Sorcerer doesn't have Blink ability.
2025-02-11 01:22:24 +03:00
7 changed files with 48 additions and 14 deletions

View File

@ -234,7 +234,7 @@ def backtick_check(file: io, file_path: str) -> None:
# Skip SQL keywords # Skip SQL keywords
if word.upper() in {"SELECT", "FROM", "JOIN", "WHERE", "GROUP", "BY", "ORDER", if word.upper() in {"SELECT", "FROM", "JOIN", "WHERE", "GROUP", "BY", "ORDER",
"DELETE", "UPDATE", "INSERT", "INTO", "SET", "VALUES", "AND", "DELETE", "UPDATE", "INSERT", "INTO", "SET", "VALUES", "AND",
"IN", "OR", "REPLACE"}: "IN", "OR", "REPLACE", "NOT"}:
continue continue
# Make sure the word is enclosed in backticks # Make sure the word is enclosed in backticks

View File

@ -0,0 +1,3 @@
-- DB update 2025_02_22_00 -> 2025_02_24_00
--
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|512|2147483648 WHERE `entry` = 25038;

View File

@ -633,6 +633,7 @@ void BossAI::_Reset()
me->ResetLootMode(); me->ResetLootMode();
events.Reset(); events.Reset();
scheduler.CancelAll(); scheduler.CancelAll();
me->m_Events.KillAllEvents(false);
summons.DespawnAll(); summons.DespawnAll();
ClearUniqueTimedEventsDone(); ClearUniqueTimedEventsDone();
_healthCheckEvents.clear(); _healthCheckEvents.clear();
@ -787,6 +788,20 @@ void BossAI::ScheduleHealthCheckEvent(std::initializer_list<uint8> healthPct, st
_nextHealthCheck = _healthCheckEvents.front(); _nextHealthCheck = _healthCheckEvents.front();
} }
void BossAI::ScheduleEnrageTimer(uint32 spellId, Milliseconds timer, uint8 textId /*= 0*/)
{
me->m_Events.AddEventAtOffset([this, spellId, textId]
{
if (!me->IsAlive())
return;
if (textId)
Talk(textId);
DoCastSelf(spellId, true);
}, timer);
}
// WorldBossAI - for non-instanced bosses // WorldBossAI - for non-instanced bosses
WorldBossAI::WorldBossAI(Creature* creature) : WorldBossAI::WorldBossAI(Creature* creature) :

View File

@ -485,6 +485,12 @@ public:
void ScheduleHealthCheckEvent(uint32 healthPct, std::function<void()> exec); void ScheduleHealthCheckEvent(uint32 healthPct, std::function<void()> exec);
void ScheduleHealthCheckEvent(std::initializer_list<uint8> healthPct, std::function<void()> exec); void ScheduleHealthCheckEvent(std::initializer_list<uint8> healthPct, std::function<void()> exec);
// @brief Casts the spell after the fixed time and says the text id if provided. Timer will run even if the creature is casting or out of combat.
// @param spellId The spell to cast.
// @param timer The time to wait before casting the spell.
// @param textId The text id to say.
void ScheduleEnrageTimer(uint32 spellId, Milliseconds timer, uint8 textId = 0);
// Hook used to execute events scheduled into EventMap without the need // Hook used to execute events scheduled into EventMap without the need
// to override UpdateAI // to override UpdateAI
// note: You must re-schedule the event within this method if the event // note: You must re-schedule the event within this method if the event

View File

@ -83,7 +83,6 @@ struct boss_sacrolash : public BossAI
_isSisterDead = false; _isSisterDead = false;
BossAI::Reset(); BossAI::Reset();
me->SetLootMode(0); me->SetLootMode(0);
me->m_Events.KillAllEvents(false);
} }
void DoAction(int32 param) override void DoAction(int32 param) override
@ -124,10 +123,7 @@ struct boss_sacrolash : public BossAI
if (alythess->IsAlive() && !alythess->IsInCombat()) if (alythess->IsAlive() && !alythess->IsInCombat())
alythess->AI()->AttackStart(who); alythess->AI()->AttackStart(who);
me->m_Events.AddEventAtOffset([&] { ScheduleEnrageTimer(SPELL_ENRAGE, 6min, YELL_BERSERK);
Talk(YELL_BERSERK);
DoCastSelf(SPELL_ENRAGE, true);
}, 6min);
ScheduleTimedEvent(10s, [&] { ScheduleTimedEvent(10s, [&] {
DoCastSelf(SPELL_SHADOW_BLADES); DoCastSelf(SPELL_SHADOW_BLADES);
@ -195,7 +191,6 @@ struct boss_alythess : public BossAI
_isSisterDead = false; _isSisterDead = false;
BossAI::Reset(); BossAI::Reset();
me->SetLootMode(0); me->SetLootMode(0);
me->m_Events.KillAllEvents(false);
} }
void DoAction(int32 param) override void DoAction(int32 param) override
@ -236,10 +231,7 @@ struct boss_alythess : public BossAI
if (sacrolash->IsAlive() && !sacrolash->IsInCombat()) if (sacrolash->IsAlive() && !sacrolash->IsInCombat())
sacrolash->AI()->AttackStart(who); sacrolash->AI()->AttackStart(who);
me->m_Events.AddEventAtOffset([&] { ScheduleEnrageTimer(SPELL_ENRAGE, 6min, YELL_BERSERK);
Talk(YELL_BERSERK);
DoCastSelf(SPELL_ENRAGE, true);
}, 6min);
ScheduleTimedEvent(1s, [&] { ScheduleTimedEvent(1s, [&] {
DoCastVictim(SPELL_BLAZE); DoCastVictim(SPELL_BLAZE);

View File

@ -134,7 +134,7 @@ struct boss_felmyst : public BossAI
void JustEngagedWith(Unit* who) override void JustEngagedWith(Unit* who) override
{ {
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
me->CastSpell(me, SPELL_NOXIOUS_FUMES, true);
me->m_Events.AddEventAtOffset([&] { me->m_Events.AddEventAtOffset([&] {
Talk(YELL_BERSERK); Talk(YELL_BERSERK);
DoCastSelf(SPELL_BERSERK, true); DoCastSelf(SPELL_BERSERK, true);
@ -144,7 +144,7 @@ struct boss_felmyst : public BossAI
Position landPos = who->GetPosition(); Position landPos = who->GetPosition();
me->m_Events.AddEventAtOffset([&, landPos] { me->m_Events.AddEventAtOffset([&, landPos] {
me->GetMotionMaster()->MovePoint(POINT_GROUND, landPos, false, true); me->GetMotionMaster()->MoveLand(POINT_GROUND, landPos);
}, 2s); }, 2s);
} }
@ -168,11 +168,14 @@ struct boss_felmyst : public BossAI
void MovementInform(uint32 type, uint32 point) override void MovementInform(uint32 type, uint32 point) override
{ {
if (type != POINT_MOTION_TYPE) if (type != EFFECT_MOTION_TYPE && type != POINT_MOTION_TYPE)
return; return;
if (point == POINT_GROUND) if (point == POINT_GROUND)
{ {
if (!me->HasAura(SPELL_NOXIOUS_FUMES))
DoCastSelf(SPELL_NOXIOUS_FUMES, true);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->SetCanFly(false); me->SetCanFly(false);
me->SetDisableGravity(false); me->SetDisableGravity(false);

View File

@ -486,6 +486,7 @@ enum BerylSorcerer
NPC_LIBRARIAN_DONATHAN = 25262, NPC_LIBRARIAN_DONATHAN = 25262,
NPC_CAPTURED_BERLY_SORCERER = 25474, NPC_CAPTURED_BERLY_SORCERER = 25474,
SPELL_FROSTBOLT = 9672, SPELL_FROSTBOLT = 9672,
SPELL_BLINK = 50648,
SPELL_ARCANE_CHAINS = 45611, SPELL_ARCANE_CHAINS = 45611,
SPELL_ARCANE_CHAINS_CHARACTER_FORCE_CAST = 45625, SPELL_ARCANE_CHAINS_CHARACTER_FORCE_CAST = 45625,
SPELL_ARCANE_CHAINS_SUMMON_CHAINED_MAGE_HUNTER = 45626, SPELL_ARCANE_CHAINS_SUMMON_CHAINED_MAGE_HUNTER = 45626,
@ -509,6 +510,7 @@ struct npc_beryl_sorcererAI : public CreatureAI
{ {
_playerGUID.Clear(); _playerGUID.Clear();
_chainsCast = false; _chainsCast = false;
_blinkUsed = false;
} }
void Reset() override void Reset() override
@ -547,6 +549,18 @@ struct npc_beryl_sorcererAI : public CreatureAI
return; return;
} }
if (me->GetHealthPct() < 70.0f && !_blinkUsed)
{
if (Unit* victim = me->GetVictim())
{
if (me->IsWithinMeleeRange(victim) && urand(0, 99) < 20)
{
me->CastSpell(me, SPELL_BLINK, true);
}
_blinkUsed = true;
}
}
_events.Update(diff); _events.Update(diff);
if (uint32 eventId = _events.ExecuteEvent()) if (uint32 eventId = _events.ExecuteEvent())
@ -577,6 +591,7 @@ struct npc_beryl_sorcererAI : public CreatureAI
EventMap _events; EventMap _events;
ObjectGuid _playerGUID; ObjectGuid _playerGUID;
bool _chainsCast; bool _chainsCast;
bool _blinkUsed;
}; };
CreatureAI* GetAI(Creature* creature) const override CreatureAI* GetAI(Creature* creature) const override