Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions data/sql/updates/db_world/2026_03_05_00.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- DB update 2026_03_04_03 -> 2026_03_05_00
DELETE FROM `spell_script_names` WHERE `spell_id` IN (64436, 64444);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(64436, 'spell_mimiron_magnetic_core_aura'),
(64444, 'spell_mimiron_magnetic_core_summon');

DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 64436;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 2, 64436, 0, 0, 31, 0, 3, 33670, 0, 0, 0, 0, '', 'Mimiron - Magnetic Core hits Aerial Command Unit only');

UPDATE `creature_template` SET `unit_flags` = `unit_flags`&~4 WHERE `entry` IN (33670, 34109);

UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 34068;

DELETE FROM `smart_scripts` WHERE `entryorguid` = 34068 AND `source_type` = 0;
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(34068, 0, 0, 1, 25, 0, 100, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mimiron - Magnetic Core - On Reset - Set React State Passive'),
(34068, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 11, 64436, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Mimiron - Magnetic Core - Linked - Cast Magnetic Core Triggered');
1 change: 1 addition & 0 deletions src/server/game/Maps/Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ class Map : public GridRefMgr<MapGridType>
// some calls like isInWater should not use vmaps due to processor power
// can return INVALID_HEIGHT if under z+2 z coord not found height
[[nodiscard]] float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
[[nodiscard]] float GetHeight(Position const& pos, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const { return GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), checkVMap, maxSearchDist); }
[[nodiscard]] float GetGridHeight(float x, float y) const;
[[nodiscard]] float GetMinHeight(float x, float y) const;
Transport* GetTransportForPos(uint32 phase, float x, float y, float z, WorldObject* worldobject = nullptr);
Expand Down
3 changes: 1 addition & 2 deletions src/server/game/Spells/SpellInfoCorrections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1885,9 +1885,8 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_1].Effect = 0;
});

// Ulduar, Mimiron, Magnetic Core (summon)
// Meeting Stone Summon
ApplySpellFix({ 64444, 23598 }, [](SpellInfo* spellInfo)
ApplySpellFix({ 23598 }, [](SpellInfo* spellInfo)
{
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
});
Expand Down
226 changes: 104 additions & 122 deletions src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ enum SpellData
SPELL_SPINNING_UP = 63414,

// PHASE 3:
SPELL_PLASMA_BALL = 63689,
SPELL_PLASMA_BALL_P1 = 63689,
SPELL_PLASMA_BALL_P2 = 65647,

SPELL_MAGNETIC_CORE = 64436,
SPELL_SPINNING = 64438,
SPELL_MAGNETIC_CORE_VISUAL = 64438,
SPELL_MAGNETIC_CORE_SUMMON = 64444,

SPELL_SUMMON_BOMB_BOT = 63811,
SPELL_BB_EXPLODE = 63801,
Expand Down Expand Up @@ -194,9 +196,6 @@ enum EVENTS
EVENT_BOMB_BOT_RELOCATE = 30,
EVENT_SUMMON_ASSAULT_BOT = 40,
EVENT_SUMMON_JUNK_BOT = 41,
EVENT_MAGNETIC_CORE_PULL_DOWN = 42,
EVENT_MAGNETIC_CORE_FREE = 43,
EVENT_MAGNETIC_CORE_REMOVE_IMMOBILIZE = 44,

// Hard mode:
EVENT_COMPUTER_SAY_INITIATED = 60,
Expand All @@ -212,6 +211,12 @@ enum EVENTS
EVENT_EMERGENCY_BOT_ATTACK = 70,
};

enum Actions
{
DO_DISABLE_AERIAL = 1,
DO_ENABLE_AERIAL,
};

enum Texts
{
// Mimiron
Expand Down Expand Up @@ -255,6 +260,8 @@ enum Texts
#define GetVX001() instance->GetCreature(DATA_MIMIRON_VX001)
#define GetACU() instance->GetCreature(DATA_MIMIRON_ACU)

Position const ACUSummonPos = { 2742.6265f, 2568.0571f, 377.22076f, 0.0f }; /// @todo: replace with sniffed position

struct boss_mimiron : public BossAI
{
boss_mimiron(Creature* pCreature) : BossAI(pCreature, BOSS_MIMIRON)
Expand Down Expand Up @@ -563,12 +570,9 @@ struct boss_mimiron : public BossAI
break;
case EVENT_GET_OUT_VX001:
if (Creature* VX001 = GetVX001())
if (Creature* ACU = me->SummonCreature(NPC_AERIAL_COMMAND_UNIT, 2743.91f, 2568.78f, 391.34f, M_PI, TEMPSUMMON_MANUAL_DESPAWN))
if (me->SummonCreature(NPC_AERIAL_COMMAND_UNIT, ACUSummonPos, TEMPSUMMON_MANUAL_DESPAWN))
{
me->EnterVehicle(VX001, 4);
float speed = ACU->GetDistance(2737.75f, 2574.22f, 381.34f) / 2.0f;
ACU->GetMotionMaster()->MovePoint(0, 2737.75f, 2574.22f, 381.34f, FORCED_MOVEMENT_NONE, speed);
ACU->SetPosition(2737.75f, 2574.22f, 381.34f, M_PI);
events.ScheduleEvent(EVENT_SAY_VX001_DEAD, 2s);
break;
}
Expand Down Expand Up @@ -1499,7 +1503,6 @@ struct npc_ulduar_aerial_command_unit : public ScriptedAI
{
instance = me->GetInstanceScript();
bIsEvading = false;
immobilized = false;
me->SetDisableGravity(true);
}

Expand All @@ -1508,19 +1511,13 @@ struct npc_ulduar_aerial_command_unit : public ScriptedAI
SummonList summons;
bool bIsEvading;
uint8 Phase;
bool immobilized;

void Reset() override
{
Phase = 0;
events.Reset();
summons.DespawnAll();
}

void AttackStart(Unit* who) override
{
if (who)
me->Attack(who, true); // skip following
me->SetCombatMovement(false); /// @todo: research ACU behaviour
}

void SetData(uint32 id, uint32 value) override
Expand All @@ -1532,16 +1529,12 @@ struct npc_ulduar_aerial_command_unit : public ScriptedAI
case 0:
Phase = 0;
events.Reset();
immobilized = false;
break;
case 3:
Phase = 3;
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
if (Unit* target = SelectTargetFromPlayerList(75.0f))
AttackStart(target);
DoZoneInCombat();
events.Reset();
events.ScheduleEvent(EVENT_SPELL_PLASMA_BALL, 0ms);
events.ScheduleEvent(EVENT_SUMMON_BOMB_BOT, 15s);
events.ScheduleEvent(EVENT_SUMMON_ASSAULT_BOT, 1s);
events.ScheduleEvent(EVENT_SUMMON_JUNK_BOT, 10s);
Expand All @@ -1561,17 +1554,31 @@ struct npc_ulduar_aerial_command_unit : public ScriptedAI
events.ScheduleEvent(EVENT_SPELL_PLASMA_BALL, 0ms);
}
}
else if (id == 2 && !immobilized && Phase == 3) // magnetic core
{
immobilized = true;
events.ScheduleEvent(EVENT_MAGNETIC_CORE_PULL_DOWN, 2s);
}
}

void DoAction(int32 param) override
{
if (param == 1337)
summons.DespawnAll();
switch (param)
{
case DO_DISABLE_AERIAL:
me->CastStop();
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
me->SetDisableGravity(false);
me->GetMotionMaster()->MoveFall();
events.DelayEvents(25s);
break;
case DO_ENABLE_AERIAL:
me->SetDisableGravity(true);
me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10.0f);
me->m_Events.AddEventAtOffset([&] {
me->SetReactState(REACT_AGGRESSIVE);
}, 2s);
break;
case 1337:
summons.DespawnAll();
break;
}
}

void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
Expand Down Expand Up @@ -1624,42 +1631,11 @@ struct npc_ulduar_aerial_command_unit : public ScriptedAI

void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
if (me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) || me->HasAura(SPELL_MAGNETIC_CORE))
return;

// following :D
if (Phase == 3 && !immobilized)
if (Unit* victim = me->GetVictim())
if (me->GetExactDist2d(victim) > 25.0f )
{
float angle = victim->GetAngle(me->GetPositionX(), me->GetPositionY());
me->SetOrientation( me->GetAngle(victim->GetPositionX(), victim->GetPositionY()));
float x = victim->GetPositionX() + 15.0f * cos(angle);
float y = victim->GetPositionY() + 15.0f * std::sin(angle);

// check if there's magnetic core in line of movement
Creature* mc = nullptr;
std::list<Creature*> cl;
me->GetCreaturesWithEntryInRange(cl, me->GetExactDist2d(victim), NPC_MAGNETIC_CORE);
for( std::list<Creature*>::iterator itr = cl.begin(); itr != cl.end(); ++itr )
{
if ((*itr)->IsInBetween(me, victim, 4.0f) && (*itr)->GetExactDist2d(victim) >= 10.0f) // don't come very close just because there's a magnetic core
{
x = (*itr)->GetPositionX();
y = (*itr)->GetPositionY();
mc = (*itr);
break;
}
}

float speed = me->GetExactDist(x, y, 381.34f);
me->GetMotionMaster()->MovePoint(0, x, y, 381.34f, FORCED_MOVEMENT_NONE, speed);
if (mc)
{
mc->AI()->SetData(0, 0);
SetData(2, 1);
}
}
if (!UpdateVictim())
return;

events.Update(diff);

Expand All @@ -1670,14 +1646,8 @@ struct npc_ulduar_aerial_command_unit : public ScriptedAI
{
case 0:
break;
case EVENT_SPELL_PLASMA_BALL:
if (!immobilized)
DoCastVictim(SPELL_PLASMA_BALL);
events.Repeat(3s);
break;
case EVENT_SUMMON_BOMB_BOT:
if (!immobilized)
me->CastSpell(me, SPELL_SUMMON_BOMB_BOT, false);
me->CastSpell(me, SPELL_SUMMON_BOMB_BOT, false);
events.Repeat(15s);
break;
case EVENT_SUMMON_ASSAULT_BOT:
Expand All @@ -1702,21 +1672,9 @@ struct npc_ulduar_aerial_command_unit : public ScriptedAI
events.Repeat(45s);
}
break;
case EVENT_MAGNETIC_CORE_PULL_DOWN:
me->CastSpell(me, SPELL_MAGNETIC_CORE, true);
me->CastSpell(me, SPELL_SPINNING, true);
me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), 365.34f, FORCED_MOVEMENT_NONE, me->GetExactDist(me->GetPositionX(), me->GetPositionY(), 365.34f));
events.ScheduleEvent(EVENT_MAGNETIC_CORE_FREE, 20s);
break;
case EVENT_MAGNETIC_CORE_FREE:
me->RemoveAura(SPELL_SPINNING);
me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), 381.34f, FORCED_MOVEMENT_NONE, me->GetDistance(me->GetPositionX(), me->GetPositionY(), 381.34f));
events.ScheduleEvent(EVENT_MAGNETIC_CORE_REMOVE_IMMOBILIZE, 1s);
break;
case EVENT_MAGNETIC_CORE_REMOVE_IMMOBILIZE:
immobilized = false;
break;
}

DoSpellAttackIfReady(Phase == 3 ? SPELL_PLASMA_BALL_P1 : SPELL_PLASMA_BALL_P2);
}

void MoveInLineOfSight(Unit* /*mover*/) override {}
Expand Down Expand Up @@ -1871,44 +1829,6 @@ struct npc_ulduar_mimiron_rocket : public NullCreatureAI
}
};

struct npc_ulduar_magnetic_core : public NullCreatureAI
{
npc_ulduar_magnetic_core(Creature* pCreature) : NullCreatureAI(pCreature)
{
instance = me->GetInstanceScript();
if (Creature* c = GetACU())
if (c->GetExactDist2d(me) <= 10.0f)
{
me->SendMonsterMove(c->GetPositionX(), c->GetPositionY(), 364.313f, 1);
me->UpdatePosition(c->GetPositionX(), c->GetPositionY(), 364.313f, me->GetOrientation(), true);
me->StopMovingOnCurrentPos();
c->AI()->SetData(2, 1);
despawnTimer = 20000;
return;
}
despawnTimer = 60000;
}

InstanceScript* instance;
uint16 despawnTimer;

void SetData(uint32 /*id*/, uint32 /*value*/) override
{
despawnTimer = 20000;
}

void UpdateAI(uint32 diff) override
{
if (despawnTimer <= diff)
{
despawnTimer = 60000;
me->DespawnOrUnsummon(1ms);
}
else
despawnTimer -= diff;
}
};

struct npc_ulduar_bot_summon_trigger : public NullCreatureAI
{
npc_ulduar_bot_summon_trigger(Creature* pCreature) : NullCreatureAI(pCreature) { }
Expand Down Expand Up @@ -1965,6 +1885,67 @@ struct npc_ulduar_bot_summon_trigger : public NullCreatureAI
}
};

// 64444 - Magnetic Core Summon
class spell_mimiron_magnetic_core_summon : public SpellScript
{
PrepareSpellScript(spell_mimiron_magnetic_core_summon);

void ModDest(SpellDestination& dest)
{
Unit* caster = GetCaster();
Position pos = caster->GetPosition();
pos.m_positionZ = caster->GetMap()->GetHeight(pos);
dest.Relocate(pos);
}

void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mimiron_magnetic_core_summon::ModDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY);
}
};

// 64436 - Magnetic Core (aura)
class spell_mimiron_magnetic_core_aura : public AuraScript
{
PrepareAuraScript(spell_mimiron_magnetic_core_aura);

bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_MAGNETIC_CORE_VISUAL });
}

void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Creature* target = GetTarget()->ToCreature())
{
target->AI()->DoAction(DO_DISABLE_AERIAL);
target->CastSpell(target, SPELL_MAGNETIC_CORE_VISUAL, true);
}
}

void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Creature* target = GetTarget()->ToCreature())
{
target->AI()->DoAction(DO_ENABLE_AERIAL);
target->RemoveAurasDueToSpell(SPELL_MAGNETIC_CORE_VISUAL);
}
}

void OnRemoveSelf(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (TempSummon* summ = GetTarget()->ToTempSummon())
summ->DespawnOrUnsummon();
}

void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_mimiron_magnetic_core_aura::OnApply, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_mimiron_magnetic_core_aura::OnRemove, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_mimiron_magnetic_core_aura::OnRemoveSelf, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};

class spell_mimiron_rapid_burst_aura : public AuraScript
{
PrepareAuraScript(spell_mimiron_rapid_burst_aura);
Expand Down Expand Up @@ -2325,8 +2306,9 @@ void AddSC_boss_mimiron()

RegisterUlduarCreatureAI(npc_ulduar_proximity_mine);
RegisterUlduarCreatureAI(npc_ulduar_mimiron_rocket);
RegisterUlduarCreatureAI(npc_ulduar_magnetic_core);
RegisterUlduarCreatureAI(npc_ulduar_bot_summon_trigger);
RegisterSpellScript(spell_mimiron_magnetic_core_summon);
RegisterSpellScript(spell_mimiron_magnetic_core_aura);
RegisterSpellScript(spell_mimiron_rapid_burst_aura);
RegisterSpellScript(spell_mimiron_p3wx2_laser_barrage_aura);
RegisterSpellScript(spell_ulduar_mimiron_mine_explosion);
Expand Down