mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
fix(Scripts/Northrend): quest Thrusting Hodir's Spear (#23810)
Co-authored-by: ariel- <ariel-@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
--
|
||||
-- Quest: Thrusting Hodir's Spear - 13003
|
||||
SET @ENTRY := 30275;
|
||||
|
||||
UPDATE `creature_template` SET `HoverHeight`=5.2 WHERE `entry`=@ENTRY;
|
||||
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id` IN (60603, 56689, 60533, 56690, 60586, 60596, 60864, 60776, 56705, 60587, 55795, 56672);
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(60603, 'spell_eject_passenger_wild_wyrm'),
|
||||
(56689, 'spell_grip'),
|
||||
(60533, 'spell_grab_on'),
|
||||
(56690, 'spell_thrust_spear'),
|
||||
(60586, 'spell_mighty_spear_thrust'),
|
||||
(60596, 'spell_low_health_trigger'),
|
||||
(60864, 'spell_jaws_of_death_claw_swipe_pct_damage'),
|
||||
(60776, 'spell_jaws_of_death_claw_swipe_pct_damage'),
|
||||
(56705, 'spell_claw_swipe_check'),
|
||||
(60587, 'spell_fatal_strike'),
|
||||
(55795, 'spell_gen_feign_death_all_flags'),
|
||||
(56672, 'spell_player_mount_wyrm');
|
||||
|
||||
DELETE FROM `spell_custom_attr` WHERE `spell_id` IN (56690,60586,60776,60881,60864);
|
||||
INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES
|
||||
(56690, 0x8000),
|
||||
(60586, 0x8000),
|
||||
(60776, 0x8000),
|
||||
(60881, 0x8000),
|
||||
(60864, 0x8000);
|
||||
|
||||
DELETE FROM `creature_template_spell` WHERE (`CreatureID` = 30275) AND (`Index` IN (4, 5));
|
||||
@@ -5170,6 +5170,16 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
|
||||
});
|
||||
|
||||
ApplySpellFix({
|
||||
60586, // Mighty Spear Thrust
|
||||
60776, // Claw Swipe
|
||||
60881, // Fatal Strike
|
||||
60864, // Jaws of Death
|
||||
}, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS;
|
||||
});
|
||||
|
||||
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||
{
|
||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||
|
||||
@@ -315,300 +315,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum eWildWyrm
|
||||
{
|
||||
SPELL_FIGHT_WYRM_BASE = 56673,
|
||||
SPELL_FIGHT_WYRM_NEXT = 60863,
|
||||
SPELL_SPEAR_OF_HODIR = 56671,
|
||||
SPELL_DODGE_CLAWS = 56704,
|
||||
SPELL_WYRM_GRIP = 56689,
|
||||
SPELL_GRAB_ON = 60533,
|
||||
SPELL_THRUST_SPEAR = 56690,
|
||||
SPELL_MIGHTY_SPEAR_THRUST = 60586,
|
||||
SPELL_FATAL_STRIKE = 60587,
|
||||
SPELL_PRY_JAWS_OPEN = 56706,
|
||||
SPELL_JAWS_OF_DEATH = 56692,
|
||||
};
|
||||
|
||||
class npc_wild_wyrm : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_wild_wyrm() : CreatureScript("npc_wild_wyrm") { }
|
||||
|
||||
struct npc_wild_wyrmAI : public ScriptedAI
|
||||
{
|
||||
npc_wild_wyrmAI(Creature* creature) : ScriptedAI(creature) {}
|
||||
|
||||
ObjectGuid playerGUID;
|
||||
uint32 checkTimer;
|
||||
uint32 announceAttackTimer;
|
||||
uint32 attackTimer;
|
||||
bool setCharm;
|
||||
bool switching;
|
||||
bool startPath;
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (switching || me->HasControlVehicleAura())
|
||||
return;
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetRegeneratingHealth(true);
|
||||
me->SetSpeed(MOVE_RUN, 1.14f, true); // ZOMG!
|
||||
setCharm = false;
|
||||
switching = false;
|
||||
startPath = false;
|
||||
checkTimer = 0;
|
||||
playerGUID.Clear();
|
||||
attackTimer = 0;
|
||||
announceAttackTimer = 0;
|
||||
me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD);
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit*, int8, bool apply) override
|
||||
{
|
||||
if (!apply && me->IsAlive() && me->HasAura(SPELL_WYRM_GRIP))
|
||||
me->RemoveAurasDueToSpell(SPELL_WYRM_GRIP);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 pointId) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && pointId == 1 && !me->GetCharmerGUID())
|
||||
{
|
||||
if (Player* player = GetValidPlayer())
|
||||
{
|
||||
checkTimer = 1;
|
||||
me->SetFullHealth();
|
||||
player->CastSpell(me, SPELL_FIGHT_WYRM_BASE, true);
|
||||
me->CastSpell(me, SPELL_WYRM_GRIP, true);
|
||||
me->SetRegeneratingHealth(false);
|
||||
}
|
||||
}
|
||||
else if (type == ESCORT_MOTION_TYPE && me->movespline->Finalized())
|
||||
startPath = true;
|
||||
else if (type == EFFECT_MOTION_TYPE && pointId == me->GetEntry())
|
||||
me->KillSelf();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (who != me)
|
||||
{
|
||||
damage = 0;
|
||||
if (!GetValidPlayer())
|
||||
setCharm = true; // will enter evade on next update
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit*) override { }
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
void OnCharmed(bool apply) override
|
||||
{
|
||||
if (apply)
|
||||
setCharm = true;
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (!playerGUID && spellInfo->Id == SPELL_SPEAR_OF_HODIR)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(1, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ() + 12.0f);
|
||||
playerGUID = caster->GetGUID();
|
||||
}
|
||||
else if (spellInfo->Id == SPELL_GRAB_ON)
|
||||
{
|
||||
if (Aura* aura = me->GetAura(SPELL_WYRM_GRIP))
|
||||
aura->ModStackAmount(10);
|
||||
}
|
||||
else if (spellInfo->Id == SPELL_THRUST_SPEAR)
|
||||
{
|
||||
if (Aura* aura = me->GetAura(SPELL_WYRM_GRIP))
|
||||
aura->ModStackAmount(-5);
|
||||
}
|
||||
else if (spellInfo->Id == SPELL_MIGHTY_SPEAR_THRUST)
|
||||
{
|
||||
if (Aura* aura = me->GetAura(SPELL_WYRM_GRIP))
|
||||
aura->ModStackAmount(-15);
|
||||
}
|
||||
else if (spellInfo->Id == SPELL_FATAL_STRIKE)
|
||||
{
|
||||
if (roll_chance_i(me->GetAuraCount(SPELL_PRY_JAWS_OPEN) * 10))
|
||||
{
|
||||
if (Player* player = GetValidPlayer())
|
||||
{
|
||||
player->KilledMonsterCredit(30415);
|
||||
player->RemoveAurasDueToSpell(SPELL_JAWS_OF_DEATH);
|
||||
}
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
me->GetMotionMaster()->MoveFall(me->GetEntry());
|
||||
}
|
||||
else
|
||||
Talk(2);
|
||||
}
|
||||
}
|
||||
|
||||
Player* GetValidPlayer()
|
||||
{
|
||||
Player* charmer = ObjectAccessor::GetPlayer(*me, playerGUID);
|
||||
if (charmer && charmer->IsAlive() && me->GetDistance(charmer) < 20.0f)
|
||||
return charmer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (startPath)
|
||||
{
|
||||
startPath = false;
|
||||
me->GetMotionMaster()->MovePath(me->GetWaypointPath(), FORCED_MOVEMENT_NONE, PathSource::WAYPOINT_MGR);
|
||||
}
|
||||
if (setCharm)
|
||||
{
|
||||
setCharm = false;
|
||||
|
||||
if (Player* charmer = GetValidPlayer())
|
||||
{
|
||||
me->SetFaction(FACTION_MONSTER_2);
|
||||
charmer->SetClientControl(me, 0, true);
|
||||
|
||||
me->SetSpeed(MOVE_RUN, 2.0f, true);
|
||||
startPath = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!checkTimer)
|
||||
return;
|
||||
|
||||
if (checkTimer < 10000)
|
||||
{
|
||||
checkTimer += diff;
|
||||
if (checkTimer >= 2000)
|
||||
{
|
||||
checkTimer = 1;
|
||||
if (me->HealthBelowPct(25))
|
||||
{
|
||||
if (Player* player = GetValidPlayer())
|
||||
{
|
||||
Talk(3);
|
||||
switching = true;
|
||||
me->RemoveAllAuras();
|
||||
me->CastSpell(me, SPELL_JAWS_OF_DEATH, true);
|
||||
player->CastSpell(me, SPELL_FIGHT_WYRM_NEXT, true);
|
||||
checkTimer = 10000;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (checkTimer < 20000)
|
||||
{
|
||||
checkTimer += diff;
|
||||
if (checkTimer >= 13000)
|
||||
{
|
||||
switching = false;
|
||||
checkTimer = 20000;
|
||||
}
|
||||
}
|
||||
else if (checkTimer < 30000)
|
||||
{
|
||||
checkTimer += diff;
|
||||
if (checkTimer >= 22000)
|
||||
{
|
||||
checkTimer = 20000;
|
||||
Player* player = GetValidPlayer();
|
||||
if (!player)
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
announceAttackTimer += diff;
|
||||
if (announceAttackTimer >= 7000)
|
||||
{
|
||||
announceAttackTimer = urand(0, 3000);
|
||||
Talk(0);
|
||||
attackTimer = 1;
|
||||
}
|
||||
if (attackTimer)
|
||||
{
|
||||
attackTimer += diff;
|
||||
if (attackTimer > 2000)
|
||||
{
|
||||
attackTimer = 0;
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, playerGUID);
|
||||
if (player && player->HasAura(SPELL_DODGE_CLAWS))
|
||||
Talk(1);
|
||||
else if (player)
|
||||
me->AttackerStateUpdate(player);
|
||||
else
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_wild_wyrmAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_q13003_thursting_hodirs_spear_aura : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_q13003_thursting_hodirs_spear_aura);
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
ModStackAmount(60);
|
||||
}
|
||||
|
||||
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Creature* creature = GetUnitOwner()->ToCreature())
|
||||
{
|
||||
if (!creature->IsInEvadeMode())
|
||||
{
|
||||
creature->RemoveAllAuras();
|
||||
creature->AI()->EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePeriodic(AuraEffect const* /* aurEff */)
|
||||
{
|
||||
ModStackAmount(-1);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_q13003_thursting_hodirs_spear_aura::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
OnEffectApply += AuraEffectApplyFn(spell_q13003_thursting_hodirs_spear_aura::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_q13003_thursting_hodirs_spear_aura::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
enum q13007IronColossus
|
||||
{
|
||||
SPELL_JORMUNGAR_SUBMERGE = 56504,
|
||||
@@ -1171,13 +877,509 @@ class spell_mammoth_explosion : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
/*#####
|
||||
# Quest 13003 Thrusting Hodir's Spear
|
||||
#####*/
|
||||
|
||||
enum WildWyrm
|
||||
{
|
||||
// Phase 1
|
||||
SPELL_PLAYER_MOUNT_WYRM = 56672,
|
||||
SPELL_FIGHT_WYRM = 56673,
|
||||
SPELL_SPEAR_OF_HODIR = 56671,
|
||||
SPELL_GRIP = 56689,
|
||||
SPELL_GRAB_ON = 60533,
|
||||
SPELL_DODGE_CLAWS = 56704,
|
||||
SPELL_THRUST_SPEAR = 56690,
|
||||
SPELL_MIGHTY_SPEAR_THRUST = 60586,
|
||||
SPELL_CLAW_SWIPE_PERIODIC = 60689,
|
||||
SPELL_CLAW_SWIPE_DAMAGE = 60776,
|
||||
SPELL_FULL_HEAL_MANA = 32432,
|
||||
SPELL_LOW_HEALTH_TRIGGER = 60596,
|
||||
|
||||
// Phase 2
|
||||
SPELL_EJECT_PASSENGER_1 = 60603,
|
||||
SPELL_PRY_JAWS_OPEN = 56706,
|
||||
SPELL_FATAL_STRIKE = 60587,
|
||||
SPELL_FATAL_STRIKE_DAMAGE = 60881,
|
||||
SPELL_JAWS_OF_DEATH_PERIODIC = 56692,
|
||||
SPELL_FLY_STATE_VISUAL = 60865,
|
||||
|
||||
// Dead phase
|
||||
SPELL_WYRM_KILL_CREDIT = 56703,
|
||||
SPELL_FALLING_DRAGON_FEIGN_DEATH = 55795,
|
||||
SPELL_EJECT_ALL_PASSENGERS = 50630,
|
||||
|
||||
SAY_SWIPE = 0,
|
||||
SAY_DODGED = 1,
|
||||
SAY_PHASE_2 = 2,
|
||||
SAY_GRIP_WARN = 3,
|
||||
SAY_STRIKE_MISS = 4,
|
||||
|
||||
ACTION_CLAW_SWIPE_WARN = 1,
|
||||
ACTION_CLAW_SWIPE_DODGE = 2,
|
||||
ACTION_GRIP_FAILING = 3,
|
||||
ACTION_GRIP_LOST = 4,
|
||||
ACTION_FATAL_STRIKE_MISS = 5,
|
||||
|
||||
POINT_START_FIGHT = 1,
|
||||
POINT_FALL = 2,
|
||||
|
||||
SEAT_INITIAL = 0,
|
||||
SEAT_MOUTH = 1,
|
||||
|
||||
PHASE_INITIAL = 0,
|
||||
PHASE_MOUTH = 1,
|
||||
PHASE_DEAD = 2,
|
||||
PHASE_MAX = 3
|
||||
};
|
||||
|
||||
constexpr uint8 ControllableSpellsCount = 4;
|
||||
constexpr uint32 WyrmControlSpells[PHASE_MAX][ControllableSpellsCount] =
|
||||
{
|
||||
{ SPELL_GRAB_ON, SPELL_DODGE_CLAWS, SPELL_THRUST_SPEAR, SPELL_MIGHTY_SPEAR_THRUST },
|
||||
{ SPELL_PRY_JAWS_OPEN, 0, SPELL_FATAL_STRIKE, 0 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
struct npc_wild_wyrm : public VehicleAI
|
||||
{
|
||||
explicit npc_wild_wyrm(Creature* creature) : VehicleAI(creature) { }
|
||||
|
||||
void InitSpellsForPhase()
|
||||
{
|
||||
ASSERT(_phase < PHASE_MAX);
|
||||
for (uint8 i = 0; i < ControllableSpellsCount; ++i)
|
||||
me->m_spells[i] = WyrmControlSpells[_phase][i];
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_phase = PHASE_INITIAL;
|
||||
|
||||
_playerGuid.Clear();
|
||||
scheduler.CancelAll();
|
||||
|
||||
InitSpellsForPhase();
|
||||
|
||||
me->SetImmuneToPC(false);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, _playerGuid);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_CLAW_SWIPE_WARN:
|
||||
Talk(SAY_SWIPE, player);
|
||||
break;
|
||||
case ACTION_CLAW_SWIPE_DODGE:
|
||||
Talk(SAY_DODGED, player);
|
||||
break;
|
||||
case ACTION_GRIP_FAILING:
|
||||
Talk(SAY_GRIP_WARN, player);
|
||||
break;
|
||||
case ACTION_GRIP_LOST:
|
||||
DoCastAOE(SPELL_EJECT_PASSENGER_1, true);
|
||||
break;
|
||||
case ACTION_FATAL_STRIKE_MISS:
|
||||
Talk(SAY_STRIKE_MISS, player);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (!_playerGuid.IsEmpty() || spellInfo->Id != SPELL_SPEAR_OF_HODIR)
|
||||
return;
|
||||
|
||||
_playerGuid = caster->GetGUID();
|
||||
DoCastAOE(SPELL_FULL_HEAL_MANA, true);
|
||||
me->SetImmuneToPC(true);
|
||||
|
||||
me->GetMotionMaster()->MovePoint(POINT_START_FIGHT, *caster);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case POINT_START_FIGHT:
|
||||
{
|
||||
Player* player = ObjectAccessor::GetPlayer(*me, _playerGuid);
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
DoCast(player, SPELL_PLAYER_MOUNT_WYRM);
|
||||
me->GetMotionMaster()->Clear();
|
||||
break;
|
||||
}
|
||||
case POINT_FALL:
|
||||
DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
|
||||
me->KillSelf();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
damage = me->GetHealth() - 1;
|
||||
|
||||
if (_phase == PHASE_DEAD)
|
||||
return;
|
||||
|
||||
_phase = PHASE_DEAD;
|
||||
scheduler.CancelAll().Async([this]
|
||||
{
|
||||
InitSpellsForPhase();
|
||||
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGuid))
|
||||
player->VehicleSpellInitialize();
|
||||
|
||||
DoCastAOE(SPELL_WYRM_KILL_CREDIT);
|
||||
DoCastAOE(SPELL_FALLING_DRAGON_FEIGN_DEATH);
|
||||
|
||||
me->RemoveAurasDueToSpell(SPELL_JAWS_OF_DEATH_PERIODIC);
|
||||
me->RemoveAurasDueToSpell(SPELL_PRY_JAWS_OPEN);
|
||||
|
||||
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
|
||||
|
||||
me->GetMotionMaster()->MoveFall(POINT_FALL, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit* passenger, int8 seatId, bool apply) override
|
||||
{
|
||||
if (!apply)
|
||||
{
|
||||
// The player is automatically moved from SEAT_INITIAL to SEAT_MOUTH during phase transition.
|
||||
// Only evade if player exits during the respective active phase.
|
||||
bool initialPhaseExit = (seatId == SEAT_INITIAL && _phase == PHASE_INITIAL);
|
||||
bool mouthPhaseExit = (seatId == SEAT_MOUTH && _phase == PHASE_MOUTH);
|
||||
if (initialPhaseExit || mouthPhaseExit)
|
||||
EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
|
||||
return;
|
||||
}
|
||||
|
||||
if (passenger->GetGUID() != _playerGuid)
|
||||
return;
|
||||
|
||||
if (seatId == SEAT_INITIAL)
|
||||
{
|
||||
me->CastCustomSpell(SPELL_GRIP, SPELLVALUE_AURA_STACK, 50);
|
||||
DoCastAOE(SPELL_CLAW_SWIPE_PERIODIC, true);
|
||||
|
||||
scheduler.Async([this]
|
||||
{
|
||||
me->GetMotionMaster()->MoveWaypoint(me->GetWaypointPath(), true);
|
||||
}).Schedule(500ms, [this](TaskContext context)
|
||||
{
|
||||
if (_phase == PHASE_MOUTH)
|
||||
return;
|
||||
|
||||
if (me->HealthBelowPct(25))
|
||||
{
|
||||
_phase = PHASE_MOUTH;
|
||||
context.Async([this]
|
||||
{
|
||||
InitSpellsForPhase();
|
||||
DoCastAOE(SPELL_LOW_HEALTH_TRIGGER, true);
|
||||
me->RemoveAurasDueToSpell(SPELL_CLAW_SWIPE_PERIODIC);
|
||||
me->RemoveAurasDueToSpell(SPELL_GRIP);
|
||||
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGuid))
|
||||
Talk(SAY_PHASE_2, player);
|
||||
|
||||
DoCastAOE(SPELL_EJECT_PASSENGER_1, true);
|
||||
DoCastAOE(SPELL_JAWS_OF_DEATH_PERIODIC);
|
||||
DoCastAOE(SPELL_FLY_STATE_VISUAL);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
context.Repeat();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!_playerGuid)
|
||||
{
|
||||
if (UpdateVictim())
|
||||
DoMeleeAttackIfReady();
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _phase{PHASE_INITIAL};
|
||||
ObjectGuid _playerGuid;
|
||||
};
|
||||
|
||||
// 56689 - Grip
|
||||
class spell_grip : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_grip);
|
||||
|
||||
void HandlePeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
++_tickNumber;
|
||||
|
||||
// each 15 ticks stack reduction increases by 2 (increases by 1 at each 7th and 15th tick)
|
||||
// except for the first 15 ticks that remove 1 stack each
|
||||
uint32 const period = ((_tickNumber - 1) % 15) + 1;
|
||||
uint32 const sequence = (_tickNumber - 1) / 15;
|
||||
|
||||
uint32 stacksToRemove;
|
||||
if (sequence == 0)
|
||||
stacksToRemove = 1;
|
||||
else
|
||||
{
|
||||
stacksToRemove = sequence * 2;
|
||||
if (period > 7)
|
||||
++stacksToRemove;
|
||||
}
|
||||
|
||||
// while we could do ModStackAmount(-stacksToRemove), this is how it's done in sniffs :)
|
||||
for (uint32 i = 0; i < stacksToRemove; ++i)
|
||||
ModStackAmount(-1, AURA_REMOVE_BY_EXPIRE);
|
||||
|
||||
if (GetStackAmount() < 15 && !_warning)
|
||||
{
|
||||
_warning = true;
|
||||
GetTarget()->GetAI()->DoAction(ACTION_GRIP_FAILING);
|
||||
}
|
||||
else if (GetStackAmount() > 30)
|
||||
_warning = false;
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
|
||||
return;
|
||||
|
||||
GetTarget()->GetAI()->DoAction(ACTION_GRIP_LOST);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_grip::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_grip::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
|
||||
// tick number in the AuraEffect gets reset each time we stack the aura, so keep track of it locally
|
||||
uint32 _tickNumber = 0;
|
||||
|
||||
bool _warning = false;
|
||||
};
|
||||
|
||||
// 60533 - Grab On
|
||||
class spell_grab_on : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_grab_on);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Aura* grip = GetCaster()->GetAura(SPELL_GRIP, GetCaster()->GetGUID()))
|
||||
grip->ModStackAmount(GetEffectValue(), AURA_REMOVE_BY_DEFAULT, false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_grab_on::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
// 56690 - Thrust Spear
|
||||
// 60586 - Mighty Spear Thrust
|
||||
class spell_loosen_grip : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_loosen_grip);
|
||||
|
||||
public:
|
||||
explicit spell_loosen_grip(int8 stacksToLose) : SpellScript(), _stacksToLose(stacksToLose) { }
|
||||
private:
|
||||
int32 _stacksToLose;
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Aura* grip = GetCaster()->GetAura(SPELL_GRIP))
|
||||
grip->ModStackAmount(-_stacksToLose, AURA_REMOVE_BY_EXPIRE);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_loosen_grip::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
// 60596 - Low Health Trigger
|
||||
class spell_low_health_trigger : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_low_health_trigger);
|
||||
|
||||
bool Validate(SpellInfo const* spellInfo) override
|
||||
{
|
||||
return ValidateSpellInfo({ static_cast<uint32>(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetHitUnit()->CastSpell(static_cast<Unit*>(nullptr), GetEffectValue(), true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_low_health_trigger::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
// 60776 - Claw Swipe
|
||||
// 60864 - Jaws of Death
|
||||
class spell_jaws_of_death_claw_swipe_pct_damage : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_jaws_of_death_claw_swipe_pct_damage);
|
||||
|
||||
void HandleDamage(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
SetEffectValue(static_cast<int32>(GetHitUnit()->CountPctFromMaxHealth(GetEffectValue())));
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectLaunchTarget += SpellEffectFn(spell_jaws_of_death_claw_swipe_pct_damage::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
// 56705 - Claw Swipe
|
||||
class spell_claw_swipe_check : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_claw_swipe_check);
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetTarget()->GetAI()->DoAction(ACTION_CLAW_SWIPE_WARN);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Vehicle* vehicle = GetTarget()->GetVehicleKit())
|
||||
{
|
||||
if (Unit* player = vehicle->GetPassenger(SEAT_INITIAL))
|
||||
{
|
||||
if (player->HasAura(SPELL_DODGE_CLAWS))
|
||||
{
|
||||
GetTarget()->GetAI()->DoAction(ACTION_CLAW_SWIPE_DODGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetTarget()->CastSpell(nullptr, aurEff->GetAmount());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_claw_swipe_check::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectApplyFn(spell_claw_swipe_check::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 60587 - Fatal Strike
|
||||
class spell_fatal_strike : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_fatal_strike);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_FATAL_STRIKE_DAMAGE });
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
int32 chance = 0;
|
||||
if (AuraEffect const* aurEff = GetCaster()->GetAuraEffect(SPELL_PRY_JAWS_OPEN, EFFECT_0))
|
||||
chance = aurEff->GetAmount();
|
||||
|
||||
if (!roll_chance_i(chance))
|
||||
{
|
||||
GetCaster()->GetAI()->DoAction(ACTION_FATAL_STRIKE_MISS);
|
||||
return;
|
||||
}
|
||||
|
||||
GetCaster()->CastSpell(static_cast<Unit*>(nullptr), SPELL_FATAL_STRIKE_DAMAGE, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_fatal_strike::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
// 56672 - Player Mount Wyrm
|
||||
class spell_player_mount_wyrm : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_player_mount_wyrm);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_FIGHT_WYRM });
|
||||
}
|
||||
|
||||
void HandleDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetTarget()->CastSpell(static_cast<Unit*>(nullptr), SPELL_FIGHT_WYRM, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectApplyFn(spell_player_mount_wyrm::HandleDummy, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 60603 - Eject Passenger 1
|
||||
class spell_eject_passenger_wild_wyrm : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_eject_passenger_wild_wyrm);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_FIGHT_WYRM });
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetHitUnit()->RemoveAurasDueToSpell(SPELL_FIGHT_WYRM);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_eject_passenger_wild_wyrm::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_storm_peaks()
|
||||
{
|
||||
RegisterCreatureAI(npc_frosthound);
|
||||
new npc_iron_watcher();
|
||||
new npc_time_lost_proto_drake();
|
||||
new npc_wild_wyrm();
|
||||
RegisterSpellScript(spell_q13003_thursting_hodirs_spear_aura);
|
||||
RegisterSpellScript(spell_q13007_iron_colossus);
|
||||
new npc_roxi_ramrocket();
|
||||
new npc_brunnhildar_prisoner();
|
||||
@@ -1189,4 +1391,15 @@ void AddSC_storm_peaks()
|
||||
RegisterSpellScript(spell_q12823_remove_collapsing_cave_aura);
|
||||
RegisterSpellScript(spell_feed_stormcrest_eagle);
|
||||
RegisterSpellScript(spell_mammoth_explosion);
|
||||
RegisterCreatureAI(npc_wild_wyrm);
|
||||
RegisterSpellScript(spell_grip);
|
||||
RegisterSpellScript(spell_grab_on);
|
||||
RegisterSpellScriptWithArgs(spell_loosen_grip, "spell_thrust_spear", 5);
|
||||
RegisterSpellScriptWithArgs(spell_loosen_grip, "spell_mighty_spear_thrust", 15);
|
||||
RegisterSpellScript(spell_low_health_trigger);
|
||||
RegisterSpellScript(spell_jaws_of_death_claw_swipe_pct_damage);
|
||||
RegisterSpellScript(spell_claw_swipe_check);
|
||||
RegisterSpellScript(spell_fatal_strike);
|
||||
RegisterSpellScript(spell_player_mount_wyrm);
|
||||
RegisterSpellScript(spell_eject_passenger_wild_wyrm);
|
||||
}
|
||||
|
||||
@@ -3659,7 +3659,6 @@ class spell_gen_ds_flush_knockback : public SpellScript
|
||||
56698 - Shadow Blast (spell_gen_default_count_pct_from_max_hp)
|
||||
59102 - Shadow Blast (spell_gen_default_count_pct_from_max_hp)
|
||||
60532 - Heart Explosion Effects (spell_gen_default_count_pct_from_max_hp)
|
||||
60864 - Jaws of Death (spell_gen_default_count_pct_from_max_hp)
|
||||
38441 - Cataclysmic Bolt (spell_gen_50pct_count_pct_from_max_hp)
|
||||
66316, 67100, 67101, 67102 - Spinning Pain Spike (spell_gen_50pct_count_pct_from_max_hp)
|
||||
33711/38794 - Murmur's Touch
|
||||
|
||||
Reference in New Issue
Block a user