mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-04 22:07:52 +00:00
fix(Scripts/Ulduar): Mimiron Rocket Strike prefers ranged players (#26685)
Co-authored-by: Unholychick <lucas__jensen@hotmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
-- Mimiron Rocket Strike: spell-driven target selection (prefers ranged players)
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_mimiron_rocket_strike', 'spell_mimiron_rocket_strike_target_select');
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(64402, 'spell_mimiron_rocket_strike'),
|
||||
(65034, 'spell_mimiron_rocket_strike'),
|
||||
(63681, 'spell_mimiron_rocket_strike_target_select');
|
||||
@@ -16,9 +16,11 @@
|
||||
*/
|
||||
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "Containers.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "GameObjectScript.h"
|
||||
#include "GameTime.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "MapMgr.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
@@ -54,6 +56,10 @@ enum SpellData
|
||||
SPELL_HEAT_WAVE = 64533,
|
||||
|
||||
SPELL_ROCKET_STRIKE_AURA = 64064,
|
||||
SPELL_ROCKET_STRIKE_SINGLE = 64402, // VX-001 fires one of the two mounted rockets
|
||||
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
|
||||
NPC_ROCKET_VISUAL = 34050,
|
||||
NPC_ROCKET_STRIKE_N = 34047,
|
||||
|
||||
@@ -1342,38 +1348,19 @@ struct npc_ulduar_vx001 : public ScriptedAI
|
||||
_events.Repeat(10s);
|
||||
break;
|
||||
case EVENT_SPELL_ROCKET_STRIKE:
|
||||
if (Vehicle* vk = me->GetVehicleKit())
|
||||
{
|
||||
for( int i = 0; i < (_phase / 2); ++i )
|
||||
{
|
||||
uint8 index = (_phase == 2 ? rand() % 2 : i);
|
||||
if (Unit* r = vk->GetPassenger(5 + index))
|
||||
if (Player* temp = SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
if (Creature* trigger = me->SummonCreature(NPC_ROCKET_STRIKE_N, temp->GetPositionX(), temp->GetPositionY(), temp->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 6000))
|
||||
trigger->CastSpell(trigger, SPELL_ROCKET_STRIKE_AURA, true);
|
||||
Position exitPos = r->GetPosition();
|
||||
exitPos.m_positionX += cos(me->GetOrientation()) * 2.35f;
|
||||
exitPos.m_positionY += std::sin(me->GetOrientation()) * 2.35f;
|
||||
exitPos.m_positionZ += 2.0f * _phase;
|
||||
r->_ExitVehicle(&exitPos);
|
||||
me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE, r->GetGUID());
|
||||
if (r->IsCreature())
|
||||
r->ToCreature()->AI()->SetData(0, 0);
|
||||
}
|
||||
}
|
||||
_events.Repeat(20s);
|
||||
_events.ScheduleEvent(EVENT_REINSTALL_ROCKETS, 10s);
|
||||
}
|
||||
me->CastSpell(me, _phase == 2 ? SPELL_ROCKET_STRIKE_SINGLE : SPELL_ROCKET_STRIKE_BOTH, true);
|
||||
_events.Repeat(20s);
|
||||
_events.ScheduleEvent(EVENT_REINSTALL_ROCKETS, 10s);
|
||||
break;
|
||||
case EVENT_REINSTALL_ROCKETS:
|
||||
if (Vehicle* vk = me->GetVehicleKit())
|
||||
{
|
||||
for (uint8 i = 5; i <= 6; ++i)
|
||||
if (!vk->GetPassenger(i))
|
||||
if (TempSummon* accessory = me->SummonCreature(NPC_ROCKET_VISUAL, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 4.0f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN))
|
||||
if (!me->HandleSpellClick(accessory, i))
|
||||
accessory->UnSummon();
|
||||
if (Unit* rocket = vk->GetPassenger(i))
|
||||
rocket->SetDisplayId(rocket->GetNativeDisplayId()); // restore the fired rocket's visual
|
||||
else if (TempSummon* accessory = me->SummonCreature(NPC_ROCKET_VISUAL, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 4.0f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN))
|
||||
if (!me->HandleSpellClick(accessory, i))
|
||||
accessory->UnSummon();
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_RAPID_BURST:
|
||||
@@ -1822,6 +1809,75 @@ class spell_ulduar_mimiron_mine_explosion : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
// 64402, 65034 - Rocket Strike
|
||||
class spell_mimiron_rocket_strike : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mimiron_rocket_strike);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
// The single-rocket cast picks just one of the two mounted rockets; the "both" cast keeps both.
|
||||
if (GetSpellInfo()->Id == SPELL_ROCKET_STRIKE_SINGLE && GetCaster()->IsVehicle())
|
||||
if (Unit* rocket = GetCaster()->GetVehicleKit()->GetPassenger(urand(5, 6)))
|
||||
{
|
||||
targets.clear();
|
||||
targets.push_back(rocket);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
// The fired rocket resolves its own impact target, keeping VX-001 as the original caster for credit.
|
||||
GetHitUnit()->CastSpell((Unit*)nullptr, SPELL_ROCKET_STRIKE_TARGET, TRIGGERED_FULL_MASK, nullptr, nullptr, GetCaster()->GetGUID());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_rocket_strike::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_mimiron_rocket_strike::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
// 63681 - Rocket Strike
|
||||
class spell_mimiron_rocket_strike_target_select : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mimiron_rocket_strike_target_select);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if([](WorldObject* target) { return !target->IsPlayer(); });
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
WorldObject* target = Acore::Containers::SelectRandomContainerElement(targets);
|
||||
|
||||
// Prefer players out of melee range; only strike someone within 15y if nobody is further out (patch 3.1.3).
|
||||
targets.remove_if(Acore::AllWorldObjectsInRange(GetCaster(), 15.0f));
|
||||
|
||||
if (!targets.empty())
|
||||
target = Acore::Containers::SelectRandomContainerElement(targets);
|
||||
|
||||
targets.clear();
|
||||
targets.push_back(target);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_rocket_strike_target_select::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_mimiron_rocket_strike_target_select::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
struct npc_ulduar_mimiron_rocket : public NullCreatureAI
|
||||
{
|
||||
npc_ulduar_mimiron_rocket(Creature* creature) : NullCreatureAI(creature) {}
|
||||
@@ -2265,6 +2321,12 @@ struct npc_ulduar_rocket_strike_trigger : public NullCreatureAI
|
||||
{
|
||||
npc_ulduar_rocket_strike_trigger(Creature* creature) : NullCreatureAI(creature) {}
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
me->CastSpell(me, SPELL_ROCKET_STRIKE_AURA, true);
|
||||
me->DespawnOrUnsummon(6s);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
if (!target || !spell)
|
||||
@@ -2340,6 +2402,8 @@ void AddSC_boss_mimiron()
|
||||
RegisterSpellScript(spell_mimiron_rapid_burst_aura);
|
||||
RegisterSpellScript(spell_mimiron_p3wx2_laser_barrage_aura);
|
||||
RegisterSpellScript(spell_ulduar_mimiron_mine_explosion);
|
||||
RegisterSpellScript(spell_mimiron_rocket_strike);
|
||||
RegisterSpellScript(spell_mimiron_rocket_strike_target_select);
|
||||
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