fix(Scripts/Ulduar): update Boss Keepers, Gossip Keepers, Yogg Keepers, Yogg-Saron (#18943)

* gossip keepers, keepers, sara

freya spell

improvements

better gossip

update

converter to update spellscript

refactor sanity wells spawn position, summons zonecombat

make sara summon sanity wells again

thorim casts start again, handle sanity wells only by sanity well spawn
script

refactor sanity

brackets

update comment

gossip keepers, keepers, sara

freya spell

improvements

better gossip

update

converter to update spellscript

refactor sanity wells spawn position, summons zonecombat

make sara summon sanity wells again

thorim casts start again, handle sanity wells only by sanity well spawn
script

refactor sanity

brackets

update comment

gossip keepers, keepers, sara

freya spell

improvements

better gossip

update

converter to update spellscript

refactor sanity wells spawn position, summons zonecombat

make sara summon sanity wells again

thorim casts start again, handle sanity wells only by sanity well spawn
script

refactor sanity

brackets

update comment

gossip keepers, keepers, sara

freya spell

improvements

better gossip

update

converter to update spellscript

refactor sanity wells spawn position, summons zonecombat

make sara summon sanity wells again

thorim casts start again, handle sanity wells only by sanity well spawn
script

refactor sanity

brackets

update comment

* refactor: remove _keepersGUID[4]

* make keeper auras only target players, remove apply scale immunity to well/keepers

include caster in cast

* update keeper flags

* summon and despawn gossip keepers

spawn only if fight done

add intro spell and handle outro

fix off by 1

fix casting simple teleport, only spawn after teleporting

remove empty line

* add teleport to shared ulduar.h

* each keeper triggers their own gossip spawn

* update is called in Reset(), no need to do it here

* add SpellHit override to Freya, Hodir

* Freya, Hodir: use scheduler to schedule post-fight teleport

* JustSummoned rename cr to summon

* sanity well summons are handled by freya instead of sara

* rename pCreature to creature

* keeper use RegisterUlduarCreatureAI

* Freya, Hodir, Thorim: increase despawn time

* despawn tentacles, sanity wells after fight

despawn tentacles after fight

* change order of teleport spells

* am missing header?
This commit is contained in:
Jelle Meeus
2024-05-25 17:06:21 +02:00
committed by GitHub
parent df688afaff
commit 845fa07aad
11 changed files with 313 additions and 153 deletions

View File

@@ -0,0 +1,20 @@
--
-- Remove encounter auras minus glow aura from Keepers, add glow aura to Gossip Keepers
UPDATE `creature_template_addon` SET `auras` = '62647' WHERE `entry` IN (33410,33411,33412,33413,33213,33241,33242,33244);
DELETE FROM `spell_script_names` WHERE `spell_id` = 64170;
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (64170, 'spell_keeper_freya_summon_sanity_well');
DELETE FROM `spell_script_names` WHERE `spell_id` IN (62650,62670,62671,62702);
DELETE FROM `spell_script_names` WHERE `spell_id` = 64174 AND `ScriptName` = 'spell_gen_area_aura_select_players';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(62650, 'spell_gen_area_aura_select_players_and_caster'),
(62670, 'spell_gen_area_aura_select_players_and_caster'),
(62671, 'spell_gen_area_aura_select_players_and_caster'),
(62702, 'spell_gen_area_aura_select_players_and_caster'),
(64174, 'spell_gen_area_aura_select_players');
-- Keeper: handle spawns with script
DELETE FROM `creature` WHERE `id1` IN (33213,33241,33242,33244);
-- Keeper: remove not selectable, immune to pc, immune to player; civilian
UPDATE `creature_template` SET `unit_flags` = `unit_flags` & ~(256 | 512 | 33554432), `flags_extra` = `flags_extra` & ~2 WHERE `entry` IN (33410,33411,33412,33413);

View File

@@ -46,7 +46,6 @@ enum Spells
SPELL_COSMIC_SMASH_VISUAL_STATE = 62300,
SPELL_SELF_STUN = 65256,
SPELL_KILL_CREDIT = 65184,
SPELL_TELEPORT = 62940,
SPELL_DUAL_WIELD = 42459,
// Algalon Stalker

View File

@@ -347,7 +347,6 @@ public:
uint32 chestId = RAID_MODE(GO_FREYA_CHEST, GO_FREYA_CHEST_HERO);
chestId -= 2 * _elderCount; // offset
me->DespawnOrUnsummon(5000);
if (GameObject* go = me->SummonGameObject(chestId, 2345.61f, -71.20f, 425.104f, 3.0f, 0, 0, 0, 0, 0))
{
go->ReplaceAllGameObjectFlags((GameObjectFlags)0);
@@ -360,10 +359,24 @@ public:
me->CastSpell(me, 65074, true); // credit
m_pInstance->SetData(TYPE_FREYA, DONE);
}
scheduler.Schedule(14s, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_TELEPORT);
});
}
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TELEPORT)
{
me->DespawnOrUnsummon();
m_pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE);
}
}
void JustSummoned(Creature* cr) override
{
if (cr->GetEntry() == NPC_FREYA_UNSTABLE_SUN_BEAM)
@@ -547,6 +560,7 @@ public:
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
if (!UpdateVictim())
return;

View File

@@ -346,6 +346,7 @@ public:
{
pInstance->SetData(TYPE_HODIR, DONE);
me->CastSpell(me, 64899, true); // credit
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA);
}
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
@@ -355,7 +356,6 @@ public:
me->CombatStop();
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA);
events.Reset();
summons.DespawnAll();
@@ -383,13 +383,17 @@ public:
}
Talk(TEXT_DEATH);
me->DespawnOrUnsummon(10000);
scheduler.Schedule(14s, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_TELEPORT);
});
}
}
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
if (me->GetPositionY() <= ENTRANCE_DOOR.GetPositionY() || me->GetPositionY() >= EXIT_DOOR.GetPositionY())
{
boss_hodirAI::EnterEvadeMode();
@@ -497,6 +501,15 @@ public:
DoMeleeAttackIfReady();
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TELEPORT)
{
me->DespawnOrUnsummon();
pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE);
}
}
Creature* GetHelper(uint8 index)
{
return Helpers[index] ? ObjectAccessor::GetCreature(*me, Helpers[index]) : nullptr;

View File

@@ -802,12 +802,21 @@ public:
case EVENT_DISAPPEAR:
if( pInstance )
pInstance->SetData(TYPE_MIMIRON, DONE);
DoCastSelf(SPELL_TELEPORT);
summons.DespawnAll();
me->DespawnOrUnsummon();
break;
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TELEPORT)
{
me->DespawnOrUnsummon();
pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE);
}
}
void MoveInLineOfSight(Unit* /*mover*/) override {}
void EnterEvadeMode(EvadeReason why) override

View File

@@ -197,6 +197,7 @@ enum ThorimEvents
EVENT_THORIM_OUTRO1 = 13,
EVENT_THORIM_OUTRO2 = 14,
EVENT_THORIM_OUTRO3 = 15,
EVENT_THORIM_OUTRO4 = 16,
EVENT_DR_ACOLYTE_GH = 20,
EVENT_DR_ACOLYTE_HS = 21,
@@ -630,6 +631,11 @@ public:
me->CastSpell(me, SPELL_LIGHTNING_CHARGE_BUFF, true);
events.RescheduleEvent(EVENT_THORIM_LIGHTNING_CHARGE, 10s, 0, EVENT_PHASE_RING);
}
else if (spellInfo->Id == SPELL_TELEPORT)
{
me->DespawnOrUnsummon();
m_pInstance->SetData(EVENT_KEEPER_TELEPORTED, DONE);
}
}
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
@@ -773,12 +779,13 @@ public:
{
Talk(SAY_END_NORMAL_3);
}
// Defeat credit
if (m_pInstance)
m_pInstance->SetData(TYPE_THORIM, DONE);
me->DespawnOrUnsummon(8000);
events.ScheduleEvent(EVENT_THORIM_OUTRO4, 14s, 0, 3);
break;
case EVENT_THORIM_OUTRO4:
DoCastSelf(SPELL_TELEPORT);
break;
}

View File

@@ -251,6 +251,8 @@ enum Misc
ACTION_ILLUSION_ICECROWN = 2,
ACTION_ILLUSION_STORMWIND = 3,
// ACTION_SARA_UPDATE_SUMMON_KEEPERS = 4, // defined in ulduar.h
EVENT_PHASE_ONE = 1,
EVENT_PHASE_TWO = 2,
EVENT_PHASE_THREE = 3,
@@ -271,6 +273,26 @@ struct LocationsXY
float x, y, z;
};
Position const GossipKeepersPos[4] =
{
{1945.6823f, 33.342014f, 411.44083f, 5.270895f}, // Freya
{1945.7609f, -81.52171f, 411.4407f, 1.029744f}, // Hodir
{2028.7656f, 17.42014f, 411.44458f, 3.857178f}, // Mimiron
{2028.8219f, -65.73573f, 411.44257f, 2.460914f} // Thorim
};
const Position KeepersPos[4] =
{
{1939.32f, 42.165f, 338.415f, 5.17955f}, // Freya
{1939.13f, -90.8332f, 338.415f, 1.00123f}, // Hodir
{2036.81f, 25.6646f, 338.415f, 3.74227f}, // Mimiron
{2036.59f, -73.8499f, 338.415f, 2.34819f} // Thorim
};
const uint32 TABLE_KEEPER_ENTRY[4] = {NPC_FREYA_KEEPER, NPC_HODIR_KEEPER, NPC_MIMIRON_KEEPER, NPC_THORIM_KEEPER};
const uint32 TABLE_GOSSIP_ENTRY[4] = {NPC_FREYA_GOSSIP, NPC_HODIR_GOSSIP, NPC_MIMIRON_GOSSIP, NPC_THORIM_GOSSIP};
const uint32 TABLE_KEEPER_TYPE[4] = {TYPE_FREYA, TYPE_HODIR, TYPE_MIMIRON, TYPE_THORIM};
static LocationsXY yoggPortalLoc[] =
{
{1970.48f, -9.75f, 325.5f},
@@ -344,7 +366,6 @@ enum Texts
SAY_LK_2 = 1,
SAY_YOGG_5 = 3,
SAY_YOGG_6 = 4,
};
const Position Middle = {1980.28f, -25.5868f, 329.397f, M_PI * 1.5f};
@@ -371,7 +392,6 @@ public:
SummonList summons;
uint32 _initFight;
ObjectGuid _keepersGUID[4];
uint8 _summonedGuardiansCount;
uint32 _p2TalkTimer;
bool _secondPhase;
@@ -382,17 +402,9 @@ public:
void AttackStart(Unit*) override { }
void MoveInLineOfSight(Unit*) override { }
void JustSummoned(Creature* cr) override
void JustSummoned(Creature* summon) override
{
summons.Summon(cr);
if (cr->GetEntry() >= NPC_FREYA_KEEPER && cr->GetEntry() <= NPC_THORIM_KEEPER)
{
if (cr->GetEntry() == NPC_FREYA_KEEPER)
cr->CastSpell(cr, SPELL_CONJURE_SANITY_WELL, false);
_keepersGUID[cr->GetEntry() - NPC_FREYA_KEEPER] = cr->GetGUID();
}
else if (cr->GetEntry() == NPC_SANITY_WELL)
cr->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_SCALE, true);
summons.Summon(summon);
}
void SpawnClouds()
@@ -407,15 +419,6 @@ public:
}
}
void SpawnWeels()
{
me->SummonCreature(NPC_SANITY_WELL, 2042.56f, -40.3667f, 329.274f, 0.0f);
me->SummonCreature(NPC_SANITY_WELL, 1975.89f, 40.0216f, 331.1f, 0.0f);
me->SummonCreature(NPC_SANITY_WELL, 1987.12f, -91.2702f, 330.186f, 0.0f);
me->SummonCreature(NPC_SANITY_WELL, 1900.48f, -51.2386f, 332.13f, 0.0f);
me->SummonCreature(NPC_SANITY_WELL, 1899.94f, 0.330621f, 332.296f, 0.0f);
}
void EnterEvadeMode(EvadeReason why) override
{
if (!_EnterEvadeMode(why))
@@ -469,9 +472,7 @@ public:
_initFight = 1;
for (uint8 i = 0; i < 4; ++i)
_keepersGUID[i].Clear();
UpdateKeeperSpawns();
_summonedGuardiansCount = 0;
_p2TalkTimer = 0;
_secondPhase = false;
@@ -503,9 +504,11 @@ public:
me->SetInCombatWithZone();
AttackStart(target);
me->CastSpell(me, SPELL_SANITY_BASE, true);
DespawnGossipKeepers();
// Engage Keepers
summons.DoZoneInCombat();
SaveKeepers();
me->CastSpell(me, SPELL_SANITY_BASE, true);
events.ScheduleEvent(EVENT_SARA_P1_DOORS_CLOSE, 15s, 0, EVENT_PHASE_ONE);
events.ScheduleEvent(EVENT_SARA_P1_BERSERK, 15min, 0, 0);
@@ -516,26 +519,27 @@ public:
me->setActive(true);
}
void SaveKeepers()
void DespawnGossipKeepers()
{
for (uint8 i = 0; i < 4; ++i)
for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++)
summons.DespawnEntry(TABLE_GOSSIP_ENTRY[i]);
}
void UpdateKeeperSpawns()
{
for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++)
{
if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i))
switch (i)
{
case KEEPER_FREYA:
SpawnWeels();
me->SummonCreature(NPC_FREYA_KEEPER, 1939.32f, 42.165f, 338.415f, 5.17955f);
break;
case KEEPER_HODIR:
me->SummonCreature(NPC_HODIR_KEEPER, 1939.13f, -90.8332f, 338.415f, 1.00123f);
break;
case KEEPER_MIMIRON:
me->SummonCreature(NPC_MIMIRON_KEEPER, 2036.81f, 25.6646f, 338.415f, 3.74227f);
break;
case KEEPER_THORIM:
me->SummonCreature(NPC_THORIM_KEEPER, 2036.59f, -73.8499f, 338.415f, 2.34819f);
break;
}
{
if (!summons.HasEntry(TABLE_KEEPER_ENTRY[i]))
me->SummonCreature(TABLE_KEEPER_ENTRY[i], KeepersPos[i]);
}
else if (m_pInstance->GetData(TABLE_KEEPER_TYPE[i]) == DONE)
{
if (!summons.HasEntry(TABLE_GOSSIP_ENTRY[i]))
me->SummonCreature(TABLE_GOSSIP_ENTRY[i], GossipKeepersPos[i]);
}
}
}
void InformCloud()
@@ -625,9 +629,8 @@ public:
{
uint8 _count = 0;
for (uint8 i = 0; i < 4; ++i)
if (_keepersGUID[i])
if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i))
++_count;
return _count;
}
else if (param == DATA_GET_SARA_PHASE)
@@ -638,7 +641,11 @@ public:
void DoAction(int32 param) override
{
if (param == ACTION_BRAIN_DAMAGED)
if (param == ACTION_SARA_UPDATE_SUMMON_KEEPERS)
{
UpdateKeeperSpawns();
}
else if (param == ACTION_BRAIN_DAMAGED)
{
summons.DoAction(ACTION_REMOVE_STUN);
@@ -648,7 +655,7 @@ public:
EntryCheckPredicate pred3(NPC_THORIM_KEEPER);
summons.DoAction(ACTION_THORIM_START_STORM, pred3);
if (!(_keepersGUID[0] && _keepersGUID[1] && _keepersGUID[2] && _keepersGUID[3]) && me->GetMap()->Is25ManRaid())
if (me->GetMap()->Is25ManRaid() && (GetData(DATA_GET_KEEPERS_COUNT) > 0))
summons.DoAction(ACTION_YOGG_SARON_HARD_MODE, pred2);
summons.DespawnEntry(NPC_DEATH_ORB);
@@ -660,8 +667,17 @@ public:
}
else if (param == ACTION_YOGG_SARON_DEATH)
{
// Despawn everything but Yogg-Saron's corpse
summons.DoAction(ACTION_DESPAWN_ADDS);
summons.DespawnEntry(NPC_CRUSHER_TENTACLE);
summons.DespawnEntry(NPC_CONSTRICTOR_TENTACLE);
summons.DespawnEntry(NPC_CORRUPTOR_TENTACLE);
summons.DespawnEntry(NPC_VOICE_OF_YOGG_SARON);
summons.DespawnEntry(NPC_BRAIN_OF_YOGG_SARON);
summons.DespawnEntry(NPC_MIMIRON_GOSSIP);
summons.DespawnEntry(NPC_HODIR_GOSSIP);
summons.DespawnEntry(NPC_FREYA_GOSSIP);
summons.DespawnEntry(NPC_THORIM_GOSSIP);
summons.DespawnEntry(NPC_MIMIRON_KEEPER);
summons.DespawnEntry(NPC_HODIR_KEEPER);
summons.DespawnEntry(NPC_FREYA_KEEPER);
@@ -1709,52 +1725,56 @@ public:
};
};
class boss_yoggsaron_keeper : public CreatureScript
struct boss_yoggsaron_keeper : public NullCreatureAI
{
public:
boss_yoggsaron_keeper() : CreatureScript("boss_yoggsaron_keeper") { }
boss_yoggsaron_keeper(Creature* creature) : NullCreatureAI(creature), _summons(creature) { }
CreatureAI* GetAI(Creature* pCreature) const override
void DoAction(int32 param) override
{
return GetUlduarAI<boss_yoggsaron_keeperAI>(pCreature);
if (me->GetEntry() == NPC_THORIM_KEEPER && param == ACTION_THORIM_START_STORM)
me->CastSpell(me, SPELL_TITANIC_STORM_PASSIVE, false);
else if (param == ACTION_DESPAWN_ADDS)
_summons.DespawnAll();
}
struct boss_yoggsaron_keeperAI : public NullCreatureAI
void JustSummoned(Creature* summon) override
{
boss_yoggsaron_keeperAI(Creature* pCreature) : NullCreatureAI(pCreature)
_summons.Summon(summon);
}
void JustEngagedWith(Unit* /*who*/) override
{
switch (me->GetEntry())
{
_checkTimer = 0;
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_SCALE, true);
}
uint32 _checkTimer;
void DoAction(int32 param) override
{
if (me->GetEntry() == NPC_THORIM_KEEPER && param == ACTION_THORIM_START_STORM)
me->CastSpell(me, SPELL_TITANIC_STORM_PASSIVE, false);
}
void UpdateAI(uint32 diff) override
{
if (me->GetInstanceScript())
if (me->GetInstanceScript()->GetData(TYPE_YOGGSARON) != IN_PROGRESS)
return;
_checkTimer += diff;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (me->GetEntry() == NPC_MIMIRON_KEEPER)
{
if (_checkTimer >= 2000)
case NPC_FREYA_KEEPER:
me->AddAura(SPELL_FREYA_PASSIVE, me);
me->CastSpell(me, SPELL_CONJURE_SANITY_WELL, false);
break;
case NPC_HODIR_KEEPER:
me->AddAura(SPELL_HODIR_PASSIVE, me);
me->AddAura(SPELL_PROTECTIVE_GAZE, me);
break;
case NPC_MIMIRON_KEEPER:
me->AddAura(SPELL_MIMIRON_PASSIVE, me);
scheduler.Schedule(2s, [this](TaskContext context)
{
me->CastSpell(me, SPELL_DESTABILIZATION_MATRIX, false);
_checkTimer = 0;
}
}
if (!me->HasUnitState(UNIT_STATE_CASTING))
me->CastSpell(me, SPELL_DESTABILIZATION_MATRIX, false);
context.Repeat(2s);
});
break;
case NPC_THORIM_KEEPER:
me->AddAura(SPELL_THORIM_PASSIVE, me);
break;
}
};
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
}
private:
SummonList _summons;
};
class boss_yoggsaron_descend_portal : public CreatureScript
@@ -2739,6 +2759,33 @@ public:
}
};
const Position SanityWellsPos[5] =
{
{2042.56f, -40.3667f, 329.274f, 0.0f},
{1975.89f, 40.0216f, 331.1f, 0.0f},
{1987.12f, -91.2702f, 330.186f, 0.0f},
{1900.48f, -51.2386f, 332.13f, 0.0f},
{1899.94f, 0.330621f, 332.296f, 0.0f}
};
// 64170 - Sanity Well
class spell_keeper_freya_summon_sanity_well : public SpellScript
{
PrepareSpellScript(spell_keeper_freya_summon_sanity_well);
void OnEffect(SpellEffIndex /*effIndex*/)
{
if (Unit* caster = GetCaster())
for (int i = 0; i < 5; i++)
caster->SummonCreature(NPC_SANITY_WELL, SanityWellsPos[i]);
}
void Register() override
{
OnEffectLaunch += SpellEffectFn(spell_keeper_freya_summon_sanity_well::OnEffect, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
}
};
/* 63881 - Malady of the Mind
63795 - Psychosis
63830 - Malady of the Mind
@@ -3032,7 +3079,7 @@ void AddSC_boss_yoggsaron()
new boss_yoggsaron_crusher_tentacle();
new boss_yoggsaron_corruptor_tentacle();
new boss_yoggsaron_constrictor_tentacle();
new boss_yoggsaron_keeper();
RegisterUlduarCreatureAI(boss_yoggsaron_keeper);
new boss_yoggsaron_descend_portal();
new boss_yoggsaron_influence_tentacle();
new boss_yoggsaron_immortal_guardian();
@@ -3053,6 +3100,7 @@ void AddSC_boss_yoggsaron()
new spell_yogg_saron_insane_periodic_trigger();
new spell_yogg_saron_insane();
new spell_yogg_saron_sanity_well();
RegisterSpellScript(spell_keeper_freya_summon_sanity_well);
new spell_yogg_saron_sanity_reduce();
new spell_yogg_saron_empowering_shadows();
new spell_yogg_saron_in_the_maws_of_the_old_god();

View File

@@ -370,22 +370,6 @@ public:
case NPC_MIMIRON_ACU:
m_MimironACUguid = creature->GetGUID();
break;
case NPC_FREYA_GOSSIP:
m_keepersGossipGUID[TYPE_FREYA - TYPE_FREYA] = creature->GetGUID();
ShowKeeperGossip(TYPE_FREYA, creature);
break;
case NPC_HODIR_GOSSIP:
m_keepersGossipGUID[TYPE_HODIR - TYPE_FREYA] = creature->GetGUID();
ShowKeeperGossip(TYPE_HODIR, creature);
break;
case NPC_THORIM_GOSSIP:
m_keepersGossipGUID[TYPE_THORIM - TYPE_FREYA] = creature->GetGUID();
ShowKeeperGossip(TYPE_THORIM, creature);
break;
case NPC_MIMIRON_GOSSIP:
m_keepersGossipGUID[TYPE_MIMIRON - TYPE_FREYA] = creature->GetGUID();
ShowKeeperGossip(TYPE_MIMIRON, creature);
break;
case NPC_ELDER_IRONBRANCH:
case NPC_ELDER_STONEBARK:
case NPC_ELDER_BRIGHTLEAF:
@@ -433,19 +417,6 @@ public:
go->SetGoState(state);
}
void ShowKeeperGossip(uint8 type, Creature* cr, ObjectGuid guid = ObjectGuid::Empty)
{
if (!cr)
{
cr = instance->GetCreature(guid);
if (!cr)
return;
}
bool on = (GetData(type) == DONE && !(GetData(TYPE_WATCHERS) & (1 << (type - TYPE_FREYA))));
cr->SetVisible(on);
}
void OnGameObjectCreate(GameObject* gameObject) override
{
switch (gameObject->GetEntry())
@@ -695,7 +666,6 @@ public:
case TYPE_THORIM:
case TYPE_FREYA:
m_auiEncounter[type] = data;
ShowKeeperGossip(type, nullptr, m_keepersGossipGUID[type - TYPE_FREYA]);
if (GetData(TYPE_MIMIRON) == DONE && GetData(TYPE_FREYA) == DONE && GetData(TYPE_HODIR) == DONE && GetData(TYPE_THORIM) == DONE)
{
if (GameObject* go = instance->GetGameObject(m_keepersgateGUID))
@@ -716,8 +686,11 @@ public:
break;
case TYPE_WATCHERS:
m_auiEncounter[type] |= 1 << data;
[[fallthrough]];
case EVENT_KEEPER_TELEPORTED:
if (Creature* sara = instance->GetCreature(m_saraGUID))
sara->AI()->DoAction(ACTION_SARA_UPDATE_SUMMON_KEEPERS);
break;
case DATA_MAGE_BARRIER:
m_mageBarrier = data;
break;

View File

@@ -21,6 +21,7 @@
#include "GameObjectScript.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "PassiveAI.h"
#include "ScriptedGossip.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
@@ -51,7 +52,14 @@ enum Texts
GOSSIP_MENU_CONFIRM = 10333,
NPC_TEXT_CONFIRM = 14325,
SAY_KEEPER_SELECTED = 1,
// Chosen
SAY_KEEPER_CHOSEN_TO_PLAYER = 0,
SAY_KEEPER_CHOSEN_ANNOUNCE = 1,
};
enum UldActions
{
ACTION_KEEPER_OUTRO = 0,
};
enum UldNPCs
@@ -69,6 +77,8 @@ enum UldGameObjects
enum UldSpells
{
SPELL_SIMPLE_TELEPORT = 12980,
SPELL_KEEPER_TELEPORT = 62940,
SPELL_SNOW_MOUND_PARTICLES = 64615
};
@@ -77,6 +87,68 @@ class npc_ulduar_keeper : public CreatureScript
public:
npc_ulduar_keeper() : CreatureScript("npc_ulduar_keeper_gossip") { }
struct npc_ulduar_keeperAI : public NullCreatureAI
{
npc_ulduar_keeperAI(Creature* creature) : NullCreatureAI(creature) { }
void Reset() override
{
scheduler.Schedule(250ms, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_SIMPLE_TELEPORT);
});
}
void DoAction(int32 param) override
{
if (param == ACTION_KEEPER_OUTRO)
{
switch (me->GetEntry())
{
case NPC_FREYA_GOSSIP:
_keeper = KEEPER_FREYA;
break;
case NPC_HODIR_GOSSIP:
_keeper = KEEPER_HODIR;
break;
case NPC_MIMIRON_GOSSIP:
_keeper = KEEPER_MIMIRON;
break;
case NPC_THORIM_GOSSIP:
_keeper = KEEPER_THORIM;
break;
default:
return;
}
scheduler.Schedule(1s, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_KEEPER_TELEPORT);
});
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TELEPORT)
{
me->DespawnOrUnsummon();
me->GetInstanceScript()->SetData(TYPE_WATCHERS, _keeper);
}
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
}
private:
uint8 _keeper;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetUlduarAI<npc_ulduar_keeperAI>(creature);
}
bool OnGossipHello(Player* player, Creature* creature) override
{
uint32 gossipMenuId = 0;
@@ -109,7 +181,6 @@ public:
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
uint8 _keeper = 0;
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
@@ -118,34 +189,12 @@ public:
break;
case GOSSIP_ACTION_INFO_DEF+2:
{
switch (creature->GetEntry())
{
case NPC_FREYA_GOSSIP:
creature->AI()->Talk(SAY_KEEPER_SELECTED);
_keeper = KEEPER_FREYA;
break;
case NPC_HODIR_GOSSIP:
creature->AI()->Talk(SAY_KEEPER_SELECTED);
_keeper = KEEPER_HODIR;
break;
case NPC_MIMIRON_GOSSIP:
creature->AI()->Talk(SAY_KEEPER_SELECTED);
_keeper = KEEPER_MIMIRON;
break;
case NPC_THORIM_GOSSIP:
creature->AI()->Talk(SAY_KEEPER_SELECTED);
_keeper = KEEPER_THORIM;
break;
}
creature->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
creature->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
CloseGossipMenuFor(player);
if (creature->GetInstanceScript())
{
creature->GetInstanceScript()->SetData(TYPE_WATCHERS, _keeper);
creature->DespawnOrUnsummon(6000);
}
creature->AI()->Talk(SAY_KEEPER_CHOSEN_TO_PLAYER, player);
creature->AI()->Talk(SAY_KEEPER_CHOSEN_ANNOUNCE);
creature->AI()->DoAction(ACTION_KEEPER_OUTRO);
}
}
return true;

View File

@@ -284,6 +284,14 @@ enum UlduarMisc
TIMER_ALGALON_TO_SUMMON = 200,
TIMER_ALGALON_SUMMONED = 100,
// Algalon the Observer, Freya, Hodir, Mimiron, Thorim, Gossip Keepers
SPELL_TELEPORT = 62940,
// Freya, Hodir, Mimiron, Thorim
EVENT_KEEPER_TELEPORTED = 62941,
// Yogg-Saron
ACTION_SARA_UPDATE_SUMMON_KEEPERS = 4,
KEEPER_FREYA = 0,
KEEPER_HODIR = 1,
KEEPER_MIMIRON = 2,

View File

@@ -628,6 +628,7 @@ class spell_gen_black_magic_enchant : public AuraScript
};
// 53642 - The Might of Mograine
// 64174 - Protective Gaze
class spell_gen_area_aura_select_players : public AuraScript
{
PrepareAuraScript(spell_gen_area_aura_select_players);
@@ -642,6 +643,24 @@ class spell_gen_area_aura_select_players : public AuraScript
}
};
// 62650 - Fortitude of Frost
// 62670 - Resilience of Nature
// 62671 - Speed of Invention
// 62702 - Fury of the Storm
class spell_gen_area_aura_select_players_and_caster : public AuraScript
{
PrepareAuraScript(spell_gen_area_aura_select_players_and_caster);
bool CheckAreaTarget(Unit* target)
{
return target->GetTypeId() == TYPEID_PLAYER || target == GetCaster();
}
void Register() override
{
DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_gen_area_aura_select_players_and_caster::CheckAreaTarget);
}
};
/* 29883 - Blink (spell_gen_select_target_count_15_1)
38573 - Spore Drop Effect (spell_gen_select_target_count_15_1)
38633 - Arcane Volley (spell_gen_select_target_count_15_1)
@@ -5193,6 +5212,7 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_disabled_above_63);
RegisterSpellScript(spell_gen_black_magic_enchant);
RegisterSpellScript(spell_gen_area_aura_select_players);
RegisterSpellScript(spell_gen_area_aura_select_players_and_caster);
RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_1", TARGET_UNIT_SRC_AREA_ENEMY, 1);
RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_2", TARGET_UNIT_SRC_AREA_ENEMY, 2);
RegisterSpellScriptWithArgs(spell_gen_select_target_count, "spell_gen_select_target_count_15_5", TARGET_UNIT_SRC_AREA_ENEMY, 5);