mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-07 15:28:02 +00:00
fix(Scripts/Ulduar): sync Mimiron's Rocket Strike marker and detonation with the missile (#26844)
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "GameTime.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "MapMgr.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
@@ -60,6 +61,7 @@ enum SpellData
|
||||
SPELL_ROCKET_STRIKE_BOTH = 65034, // VX-001 fires both mounted rockets
|
||||
SPELL_ROCKET_STRIKE_TARGET = 63681, // Cast by a fired rocket; picks the impact target (prefers ranged)
|
||||
SPELL_SUMMON_ROCKET_STRIKE = 63036, // Summons the ground strike at the chosen target
|
||||
SPELL_ROCKET_STRIKE_DAMAGE = 63041,
|
||||
NPC_ROCKET_VISUAL = 34050,
|
||||
NPC_ROCKET_STRIKE_N = 34047,
|
||||
|
||||
@@ -219,6 +221,9 @@ enum EVENTS
|
||||
EVENT_SUMMON_EMERGENCY_FIRE_BOTS = 68,
|
||||
EVENT_EMERGENCY_BOT_CHECK = 69,
|
||||
EVENT_EMERGENCY_BOT_ATTACK = 70,
|
||||
|
||||
// Rocket (Mimiron Visual):
|
||||
EVENT_ROCKET_FIRE = 71,
|
||||
};
|
||||
|
||||
enum Actions
|
||||
@@ -1877,9 +1882,14 @@ class spell_mimiron_rocket_strike_target_select : public SpellScript
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
ObjectGuid originalCaster = GetOriginalCaster() ? GetOriginalCaster()->GetGUID() : GetCaster()->GetGUID();
|
||||
GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_ROCKET_STRIKE, TRIGGERED_FULL_MASK, nullptr, nullptr, originalCaster);
|
||||
GetCaster()->SetDisplayId(11686); // hide the spent rocket until it is reloaded
|
||||
// Spawn the strike trigger now, so its warning visual and 5s fuse run while the missile is still to come.
|
||||
// The rocket fires the missile later, timed to land as the fuse expires (see npc_ulduar_mimiron_rocket).
|
||||
if (Creature* rocket = GetCaster()->ToCreature())
|
||||
if (Creature* trigger = rocket->SummonCreature(NPC_ROCKET_STRIKE_N, *GetHitUnit(), TEMPSUMMON_TIMED_DESPAWN, 6000))
|
||||
{
|
||||
rocket->AI()->SetGUID(trigger->GetGUID(), 0);
|
||||
rocket->AI()->SetGUID(GetHitUnit()->GetGUID(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -1906,19 +1916,70 @@ struct npc_ulduar_mimiron_rocket : public NullCreatureAI
|
||||
me->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD);
|
||||
}
|
||||
|
||||
void SetData(uint32 /*id*/, uint32 /*value*/) override
|
||||
void SetGUID(ObjectGuid const& guid, int32 id) override
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 100.0f, FORCED_MOVEMENT_NONE, 0.f, false, true);
|
||||
if (id == 0)
|
||||
{
|
||||
_strikeTrigger = guid;
|
||||
// Delay the shot so the 63036 missile (7 yd/s client-side) lands as the strike trigger's 5s fuse expires.
|
||||
_travelMs = 0;
|
||||
if (Creature* trigger = ObjectAccessor::GetCreature(*me, guid))
|
||||
_travelMs = uint32(me->GetExactDist(trigger) / 7.0f * 1000.0f);
|
||||
_events.RescheduleEvent(EVENT_ROCKET_FIRE, Milliseconds(_travelMs < 5000 ? 5000 - _travelMs : 0));
|
||||
}
|
||||
else
|
||||
_strikeVictim = guid;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
ObjectGuid GetGUID(int32 /*id*/) const override
|
||||
{
|
||||
if (!me->GetVehicle())
|
||||
return _strikeTrigger;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
if (_events.ExecuteEvent() == EVENT_ROCKET_FIRE)
|
||||
{
|
||||
me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN) + 0.4f, false);
|
||||
me->SetSpeed(MOVE_FLIGHT, me->GetSpeedRate(MOVE_RUN), false);
|
||||
if (Unit* victim = ObjectAccessor::GetUnit(*me, _strikeVictim))
|
||||
me->CastSpell(victim, SPELL_SUMMON_ROCKET_STRIKE, true);
|
||||
if (Creature* trigger = ObjectAccessor::GetCreature(*me, _strikeTrigger))
|
||||
trigger->AI()->SetData(0, _travelMs);
|
||||
me->SetDisplayId(11686); // hide the spent rocket until it is reloaded
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
ObjectGuid _strikeTrigger;
|
||||
ObjectGuid _strikeVictim;
|
||||
uint32 _travelMs = 0;
|
||||
};
|
||||
|
||||
// 63036 - Summon Rocket Strike
|
||||
class spell_mimiron_summon_rocket_strike : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mimiron_summon_rocket_strike);
|
||||
|
||||
void SetDest(SpellDestination& dest)
|
||||
{
|
||||
// Land on the pre-spawned strike trigger, not on the target's current position.
|
||||
if (Creature* rocket = GetCaster()->ToCreature())
|
||||
if (Creature* trigger = ObjectAccessor::GetCreature(*rocket, rocket->AI()->GetGUID()))
|
||||
dest.Relocate(*trigger);
|
||||
}
|
||||
|
||||
void PreventSummon(SpellEffIndex effIndex)
|
||||
{
|
||||
// The strike trigger is pre-spawned on target selection; this cast only provides the missile visual.
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mimiron_summon_rocket_strike::SetDest, EFFECT_0, TARGET_DEST_TARGET_ENEMY);
|
||||
OnEffectHit += SpellEffectFn(spell_mimiron_summon_rocket_strike::PreventSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
|
||||
}
|
||||
};
|
||||
|
||||
struct npc_ulduar_bot_summon_trigger : public NullCreatureAI
|
||||
@@ -2338,11 +2399,24 @@ struct npc_ulduar_rocket_strike_trigger : public NullCreatureAI
|
||||
me->DespawnOrUnsummon(6s);
|
||||
}
|
||||
|
||||
void SetData(uint32 /*id*/, uint32 value) override
|
||||
{
|
||||
// Detonate in sync with the incoming missile; the 64064 tick is suppressed (spell_mimiron_rocket_strike_aura).
|
||||
_events.ScheduleEvent(1, Milliseconds(value));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
if (_events.ExecuteEvent() == 1)
|
||||
me->CastSpell(me, SPELL_ROCKET_STRIKE_DAMAGE, true);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
if (!target || !spell)
|
||||
return;
|
||||
if (spell->Id == 63041)
|
||||
if (spell->Id == SPELL_ROCKET_STRIKE_DAMAGE)
|
||||
{
|
||||
if (target->GetEntry() == NPC_ASSAULT_BOT)
|
||||
me->CastSpell(me, 65040, true); // achievement Not-So-Friendly Fire
|
||||
@@ -2352,6 +2426,26 @@ struct npc_ulduar_rocket_strike_trigger : public NullCreatureAI
|
||||
c->AI()->SetData(0, 13);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
// 64064 - Rocket Strike
|
||||
class spell_mimiron_rocket_strike_aura : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_mimiron_rocket_strike_aura);
|
||||
|
||||
void HandlePeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
// No fuse tick: the strike trigger detonates in sync with the missile impact (npc_ulduar_rocket_strike_trigger).
|
||||
PreventDefaultAction();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mimiron_rocket_strike_aura::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_mimiron_firefighter : public AchievementCriteriaScript
|
||||
@@ -2415,6 +2509,8 @@ void AddSC_boss_mimiron()
|
||||
RegisterSpellScript(spell_ulduar_mimiron_mine_explosion);
|
||||
RegisterSpellScript(spell_mimiron_rocket_strike);
|
||||
RegisterSpellScript(spell_mimiron_rocket_strike_target_select);
|
||||
RegisterSpellScript(spell_mimiron_summon_rocket_strike);
|
||||
RegisterSpellScript(spell_mimiron_rocket_strike_aura);
|
||||
new go_ulduar_do_not_push_this_button();
|
||||
RegisterUlduarCreatureAI(npc_ulduar_flames_initial);
|
||||
RegisterUlduarCreatureAI(npc_ulduar_flames_spread);
|
||||
|
||||
Reference in New Issue
Block a user