fix(Scripts/The Underbog): Rewritten The Black Stalker's Levitate mec… (#14541)

* fix(Scripts/The Underbog): Rewritten The Black Stalker's Levitate mechanic.

Fixes #13988

* buildfix.

* Update src/server/scripts/Outland/CoilfangReservoir/underbog/boss_the_black_stalker.cpp

Co-authored-by: offl <offl@gmail.com>
Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com>
This commit is contained in:
UltraNix
2023-01-07 20:28:22 +01:00
committed by GitHub
parent 777a1be394
commit 8cb88cce52
3 changed files with 132 additions and 48 deletions

View File

@@ -0,0 +1,11 @@
--
DELETE FROM `spell_script_names` WHERE `spell_id` IN (31704,31701,31702,31703);
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(31704,'spell_the_black_stalker_levitate'),
(31701,'spell_the_black_stalker_levitation_pulse'),
(31702,'spell_the_black_stalker_someone_grab_me'),
(31703,'spell_the_black_stalker_magnetic_pull');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 31702;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
(13,1,31702,0,0,31,0,3,17992,0,0,0,0,"","Group 0: Spell 'Someone Grab Me' (Effect 0) targets creature 'Coilfang Invisible Vacuum Dummy'");

View File

@@ -5176,7 +5176,7 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex)
pos.Relocate(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ() + 1.0f, m_caster->GetOrientation());
}
float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f;
float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);

View File

@@ -20,16 +20,33 @@
#include "SpellScript.h"
#include "the_underbog.h"
/*
How levitation sequence works: boss casts Levitate and it triggers a chain of spells, target(any target, player or pet, any position in
threat list) eventually gets pulled towards by randomly selected trigger. Then target becomes protected from Pull Towards by Suspension
aura which is triggered every 1 sec up to 4 times. Since it has stun mechanic, diminishing returns cuts off its duration every cast in
half (20 > 10 > 5 > 0). Eventually player becomes immune to Suspension and vulnerable to another pull towards.
Whole levitate sequence is designed to pull player towards up to 3 times. Usually it works like this: player gets pulled towards,
gets protected by Suspension from Pull Towards next 2 times. If player is unlucky, boss can cast Levitate on same player again, in that case
player can be pulled towards 2 times in a row without any protection from fall damage by Suspension(case from sniffs).
However currently diminishing returns affects Suspension after first cast, its duration is 10 instead of 20 seconds and player will be
immune to 4th cast. That allows to pull player towards when levitation sequence ends. Levitation sequence has sensetive design and looks
like lack of delays between packets makes it work differently too.
Of course as was said above player can be pulled towards 2 times in a row but that looks like a rare case.
*/
enum eBlackStalker
{
SPELL_LEVITATE = 31704,
SPELL_SUSPENSION = 31719,
SPELL_LEVITATION_PULSE = 31701,
SPELL_MAGNETIC_PULL = 31705,
SPELL_CHAIN_LIGHTNING = 31717,
SPELL_STATIC_CHARGE = 31715,
SPELL_SUMMON_SPORE_STRIDER = 38755,
SPELL_LEVITATION_PULSE = 31701,
SPELL_SOMEONE_GRAB_ME = 31702,
SPELL_MAGNETIC_PULL = 31703,
SPELL_SUSPENSION_PRIMER = 31720,
SPELL_SUSPENSION = 31719,
EVENT_LEVITATE = 1,
EVENT_SPELL_CHAIN = 2,
EVENT_SPELL_STATIC = 3,
@@ -47,15 +64,9 @@ struct boss_the_black_stalker : public BossAI
{
}
void Reset() override
{
lTarget.Clear();
BossAI::Reset();
}
void EnterCombat(Unit* who) override
{
events.ScheduleEvent(EVENT_LEVITATE, 12000);
events.ScheduleEvent(EVENT_LEVITATE, urand(8000, 12000));
events.ScheduleEvent(EVENT_SPELL_CHAIN, 6000);
events.ScheduleEvent(EVENT_SPELL_STATIC, 10000);
events.ScheduleEvent(EVENT_CHECK, 5000);
@@ -88,6 +99,10 @@ struct boss_the_black_stalker : public BossAI
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK:
@@ -107,7 +122,6 @@ struct boss_the_black_stalker : public BossAI
case EVENT_SPELL_CHAIN:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false);
events.DelayEvents(3000);
events.RepeatEvent(9000);
break;
case EVENT_SPELL_STATIC:
@@ -116,46 +130,16 @@ struct boss_the_black_stalker : public BossAI
events.RepeatEvent(10000);
break;
case EVENT_LEVITATE:
events.RepeatEvent(15000);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
{
me->CastSpell(target, SPELL_LEVITATE, false);
lTarget = target->GetGUID();
events.DelayEvents(5000);
events.ScheduleEvent(EVENT_LEVITATE_TARGET_1, 2000);
}
DoCastSelf(SPELL_LEVITATE);
events.RepeatEvent(urand(18000, 24000));
break;
case EVENT_LEVITATE_TARGET_1:
if (Unit* target = ObjectAccessor::GetUnit(*me, lTarget))
{
if (!target->HasAura(SPELL_LEVITATE))
lTarget.Clear();
else
{
target->CastSpell(target, SPELL_MAGNETIC_PULL, true);
events.ScheduleEvent(EVENT_LEVITATE_TARGET_2, 1500);
}
}
break;
case EVENT_LEVITATE_TARGET_2:
if (Unit* target = ObjectAccessor::GetUnit(*me, lTarget))
{
if (!target->HasAura(SPELL_LEVITATE))
lTarget.Clear();
else
{
target->AddAura(SPELL_SUSPENSION, target);
lTarget.Clear();
}
}
break;
}
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
private:
ObjectGuid lTarget;
};
class spell_gen_allergies : public AuraScript
@@ -180,8 +164,97 @@ class spell_gen_allergies : public AuraScript
}
};
// 31704 - Levitate
class spell_the_black_stalker_levitate : public SpellScript
{
PrepareSpellScript(spell_the_black_stalker_levitate);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_LEVITATION_PULSE });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_LEVITATION_PULSE, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_the_black_stalker_levitate::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 31701 - Levitation Pulse
class spell_the_black_stalker_levitation_pulse : public SpellScript
{
PrepareSpellScript(spell_the_black_stalker_levitation_pulse);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SOMEONE_GRAB_ME });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetCaster()->CastSpell(GetCaster(), SPELL_SOMEONE_GRAB_ME, true);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_the_black_stalker_levitation_pulse::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 31702 - Someone Grab Me
class spell_the_black_stalker_someone_grab_me : public SpellScript
{
PrepareSpellScript(spell_the_black_stalker_someone_grab_me);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_MAGNETIC_PULL, SPELL_SUSPENSION });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (!GetCaster()->HasAura(SPELL_SUSPENSION))
GetHitUnit()->CastSpell(GetCaster(), SPELL_MAGNETIC_PULL);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_the_black_stalker_someone_grab_me::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 31703 - Magnetic Pull
class spell_the_black_stalker_magnetic_pull : public SpellScript
{
PrepareSpellScript(spell_the_black_stalker_magnetic_pull);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SUSPENSION_PRIMER });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUSPENSION_PRIMER, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_the_black_stalker_magnetic_pull::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
void AddSC_boss_the_black_stalker()
{
RegisterUnderbogCreatureAI(boss_the_black_stalker);
RegisterSpellScript(spell_gen_allergies);
RegisterSpellScript(spell_the_black_stalker_levitate);
RegisterSpellScript(spell_the_black_stalker_levitation_pulse);
RegisterSpellScript(spell_the_black_stalker_someone_grab_me);
RegisterSpellScript(spell_the_black_stalker_magnetic_pull);
}