refactor(Scripts/Ulduar): leverage DoorData, persistent data, and code standards (#25163)

Co-authored-by: joschiwald <joschiwald@online.de>
Co-authored-by: Shauren <shauren.trinity@gmail.com>
Co-authored-by: ariel- <ariel-@users.noreply.github.com>
Co-authored-by: Unholychick <lucas__jensen@hotmail.com>
Co-authored-by: horn <pankrac.ja@seznam.cz>
Co-authored-by: Machiavelli <machiavelli.trinity@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Andrew
2026-03-25 21:20:04 -03:00
committed by GitHub
parent 200e24c66e
commit 3e0c360338
10 changed files with 342 additions and 444 deletions

View File

@@ -267,12 +267,12 @@ struct boss_algalon_the_observer : public ScriptedAI
_fedOnTears = true;
_firstPull = true;
_fightWon = false;
m_pInstance = me->GetInstanceScript();
_instance = me->GetInstanceScript();
}
EventMap events;
SummonList summons;
InstanceScript* m_pInstance;
InstanceScript* _instance;
bool _firstPull;
bool _fightWon;
@@ -363,8 +363,8 @@ struct boss_algalon_the_observer : public ScriptedAI
return;
}
if (m_pInstance)
m_pInstance->SetData(BOSS_ALGALON, FAIL);
if (_instance)
_instance->SetData(BOSS_ALGALON, FAIL);
ScriptedAI::EnterEvadeMode(why);
}
@@ -385,13 +385,13 @@ struct boss_algalon_the_observer : public ScriptedAI
_phaseTwo = false;
_heraldOfTheTitans = true;
if (m_pInstance->GetBossState(BOSS_ALGALON) == FAIL)
if (_instance->GetBossState(BOSS_ALGALON) == FAIL)
{
_firstPull = false;
}
if (m_pInstance)
m_pInstance->SetData(BOSS_ALGALON, NOT_STARTED);
if (_instance)
_instance->SetData(BOSS_ALGALON, NOT_STARTED);
}
void KilledUnit(Unit* victim) override
@@ -445,8 +445,8 @@ struct boss_algalon_the_observer : public ScriptedAI
me->SetFaction(FACTION_FRIENDLY);
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->InterruptNonMeleeSpells(false);
if (m_pInstance)
m_pInstance->SetData(BOSS_ALGALON, NOT_STARTED);
if (_instance)
_instance->SetData(BOSS_ALGALON, NOT_STARTED);
break;
case ACTION_INIT_ALGALON:
_firstPull = false;
@@ -473,7 +473,7 @@ struct boss_algalon_the_observer : public ScriptedAI
if (_fightWon)
return;
if (!m_pInstance)
if (!_instance)
{
EnterEvadeMode(EVADE_REASON_OTHER);
return;
@@ -499,7 +499,7 @@ struct boss_algalon_the_observer : public ScriptedAI
Talk(SAY_ALGALON_START_TIMER);
introDelay = 22s;
events.ScheduleEvent(EVENT_START_COMBAT, 14s);
m_pInstance->SetData(DATA_DESPAWN_ALGALON, 0);
_instance->SetData(DATA_DESPAWN_ALGALON, 0);
}
events.ScheduleEvent(EVENT_REMOVE_UNNATTACKABLE, introDelay - 500ms);
@@ -656,11 +656,11 @@ struct boss_algalon_the_observer : public ScriptedAI
case EVENT_INTRO_FINISH:
events.Reset();
me->SetImmuneToPC(false);
if (Creature* brann = m_pInstance->GetCreature(DATA_BRANN_BRONZEBEARD_ALG))
if (Creature* brann = _instance->GetCreature(DATA_BRANN_BRONZEBEARD_ALG))
brann->AI()->DoAction(ACTION_FINISH_INTRO);
break;
case EVENT_START_COMBAT:
m_pInstance->SetData(BOSS_ALGALON, IN_PROGRESS);
_instance->SetData(BOSS_ALGALON, IN_PROGRESS);
Talk(SAY_ALGALON_AGGRO);
break;
case EVENT_REMOVE_UNNATTACKABLE:
@@ -735,10 +735,10 @@ struct boss_algalon_the_observer : public ScriptedAI
ScriptedAI::EnterEvadeMode();
return;
case EVENT_OUTRO_START:
if (m_pInstance)
if (_instance)
{
m_pInstance->SetData(BOSS_ALGALON, DONE);
m_pInstance->SetData(DATA_ALGALON_DEFEATED, 1);
_instance->SetData(BOSS_ALGALON, DONE);
_instance->SetData(DATA_ALGALON_DEFEATED, 1);
}
break;
case EVENT_OUTRO_1:

View File

@@ -187,7 +187,7 @@ const Position homePos = {322.39f, -14.5f, 409.8f, 3.14f};
struct boss_flame_leviathan : public BossAI
{
boss_flame_leviathan(Creature* pCreature) : BossAI(pCreature, BOSS_LEVIATHAN), vehicle(me->GetVehicleKit())
boss_flame_leviathan(Creature* creature) : BossAI(creature, BOSS_LEVIATHAN), vehicle(me->GetVehicleKit())
{
assert(vehicle);
}
@@ -214,7 +214,7 @@ struct boss_flame_leviathan : public BossAI
{
_JustReachedHome();
// For achievement
instance->SetData(DATA_UNBROKEN_ACHIEVEMENT, 0);
instance->StorePersistentData(PERSISTENT_DATA_UNBROKEN, 0);
me->setActive(false);
}
@@ -1239,7 +1239,7 @@ class spell_auto_repair : public SpellScript
// Achievement
if (InstanceScript* instance = vehicle->GetBase()->GetInstanceScript())
instance->SetData(DATA_UNBROKEN_ACHIEVEMENT, 0);
instance->StorePersistentData(PERSISTENT_DATA_UNBROKEN, 0);
}
void Register() override
@@ -1717,10 +1717,9 @@ public:
bool OnCheck(Player* player, Unit*, uint32 /*criteria_id*/) override
{
if (player->GetInstanceScript())
if (player->GetInstanceScript()->GetData(DATA_UNBROKEN_ACHIEVEMENT))
return true;
return false;
InstanceScript* instance = player->GetInstanceScript();
return instance
&& instance->GetPersistentData(PERSISTENT_DATA_UNBROKEN);
}
};

View File

@@ -108,7 +108,7 @@ enum VaporsText
struct boss_vezax : public BossAI
{
boss_vezax(Creature* pCreature) : BossAI(pCreature, BOSS_VEZAX) { }
boss_vezax(Creature* creature) : BossAI(creature, BOSS_VEZAX) { }
uint8 vaporsCount;
bool hardmodeAvailable;
@@ -131,7 +131,7 @@ struct boss_vezax : public BossAI
me->setActive(false);
}
void JustEngagedWith(Unit* /*pWho*/) override
void JustEngagedWith(Unit* /*who*/) override
{
me->setActive(true);
_JustEngagedWith();
@@ -326,13 +326,6 @@ struct boss_vezax : public BossAI
{
_JustDied();
Talk(SAY_DEATH);
if (GameObject* door = me->FindNearestGameObject(GO_VEZAX_DOOR, 500.0f))
if (door->GetGoState() != GO_STATE_ACTIVE)
{
door->SetLootState(GO_READY);
door->UseDoorOrButton(0, false);
}
}
void KilledUnit(Unit* who) override
@@ -346,21 +339,21 @@ struct boss_vezax : public BossAI
struct npc_ulduar_saronite_vapors : public NullCreatureAI
{
npc_ulduar_saronite_vapors(Creature* pCreature) : NullCreatureAI(pCreature)
npc_ulduar_saronite_vapors(Creature* creature) : NullCreatureAI(creature)
{
pInstance = pCreature->GetInstanceScript();
_instance = creature->GetInstanceScript();
me->GetMotionMaster()->MoveRandom(4.0f);
}
InstanceScript* pInstance;
InstanceScript* _instance;
void JustDied(Unit* /*killer*/) override
{
me->CastSpell(me, SPELL_SARONITE_VAPORS_AURA, true);
// killed saronite vapors, hard mode unavailable
if (pInstance)
if (Creature* vezax = pInstance->GetCreature(BOSS_VEZAX))
if (_instance)
if (Creature* vezax = _instance->GetCreature(BOSS_VEZAX))
vezax->AI()->DoAction(1);
}
@@ -372,25 +365,25 @@ struct npc_ulduar_saronite_vapors : public NullCreatureAI
struct npc_ulduar_saronite_animus : public ScriptedAI
{
npc_ulduar_saronite_animus(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_saronite_animus(Creature* creature) : ScriptedAI(creature)
{
pInstance = pCreature->GetInstanceScript();
if (pInstance)
if (Creature* vezax = pInstance->GetCreature(BOSS_VEZAX))
_instance = creature->GetInstanceScript();
if (_instance)
if (Creature* vezax = _instance->GetCreature(BOSS_VEZAX))
vezax->AI()->JustSummoned(me);
timer = 0;
me->SetInCombatWithZone();
}
InstanceScript* pInstance;
InstanceScript* _instance;
uint16 timer;
void JustDied(Unit* /*killer*/) override
{
me->DespawnOrUnsummon(3s);
if (pInstance)
if (Creature* vezax = pInstance->GetCreature(BOSS_VEZAX))
if (_instance)
if (Creature* vezax = _instance->GetCreature(BOSS_VEZAX))
vezax->AI()->DoAction(2);
}

View File

@@ -199,7 +199,7 @@ HodirHelperData hhd[4][4] =
struct boss_hodir : public BossAI
{
boss_hodir(Creature* pCreature) : BossAI(pCreature, BOSS_HODIR)
boss_hodir(Creature* creature) : BossAI(creature, BOSS_HODIR)
{
if (!me->IsAlive())
instance->SetBossState(BOSS_HODIR, DONE);
@@ -239,17 +239,12 @@ struct boss_hodir : public BossAI
me->RemoveAllAuras();
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BITING_COLD_PLAYER_AURA);
if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 900.0f))
{
go->SetGoState(GO_STATE_ACTIVE);
}
// Reset helpers
if (!summons.size())
SpawnHelpers();
}
void JustEngagedWith(Unit* /*pWho*/) override
void JustEngagedWith(Unit* /*who*/) override
{
me->CastSpell(me, SPELL_BITING_COLD_BOSS_AURA, true);
SmallIcicles(true);
@@ -261,14 +256,7 @@ struct boss_hodir : public BossAI
Talk(TEXT_AGGRO);
if (instance->GetBossState(BOSS_HODIR) != DONE)
{
instance->SetBossState(BOSS_HODIR, IN_PROGRESS);
}
if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 300.0f))
{
go->SetGoState(GO_STATE_READY);
}
}
GameObject* GetHardmodeChest()
@@ -350,28 +338,6 @@ struct boss_hodir : public BossAI
events.Reset();
summons.DespawnAll();
if (GameObject* d = me->FindNearestGameObject(GO_HODIR_FROZEN_DOOR, 250.0f))
{
if (d->GetGoState() != GO_STATE_ACTIVE )
{
d->SetLootState(GO_READY);
d->UseDoorOrButton(0, false);
}
}
if (GameObject* d = me->FindNearestGameObject(GO_HODIR_DOOR, 250.0f))
{
if (d->GetGoState() != GO_STATE_ACTIVE )
{
d->SetLootState(GO_READY);
d->UseDoorOrButton(0, false);
}
}
if (GameObject* go = me->FindNearestGameObject(GO_HODIR_FRONTDOOR, 300.0f))
{
go->SetGoState(GO_STATE_ACTIVE);
}
Talk(TEXT_DEATH);
scheduler.Schedule(14s, [this](TaskContext /*context*/)
{
@@ -600,7 +566,7 @@ struct boss_hodir : public BossAI
struct npc_ulduar_icicle : public NullCreatureAI
{
npc_ulduar_icicle(Creature* pCreature) : NullCreatureAI(pCreature)
npc_ulduar_icicle(Creature* creature) : NullCreatureAI(creature)
{
timer1 = 2000;
timer2 = 5000;
@@ -632,20 +598,20 @@ struct npc_ulduar_icicle : public NullCreatureAI
struct npc_ulduar_flash_freeze : public NullCreatureAI
{
npc_ulduar_flash_freeze(Creature* pCreature) : NullCreatureAI(pCreature)
npc_ulduar_flash_freeze(Creature* creature) : NullCreatureAI(creature)
{
timer = 2500;
pInstance = me->GetInstanceScript();
_instance = me->GetInstanceScript();
}
InstanceScript* pInstance;
InstanceScript* _instance;
uint16 timer;
void DamageTaken(Unit* doneBy, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override
{
if (pInstance && doneBy)
if (pInstance->GetBossState(BOSS_HODIR) == NOT_STARTED)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance && doneBy)
if (_instance->GetBossState(BOSS_HODIR) == NOT_STARTED)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
hodir->AI()->AttackStart(doneBy);
}
@@ -681,7 +647,7 @@ struct npc_ulduar_flash_freeze : public NullCreatureAI
struct npc_ulduar_toasty_fire : public NullCreatureAI
{
npc_ulduar_toasty_fire(Creature* pCreature) : NullCreatureAI(pCreature)
npc_ulduar_toasty_fire(Creature* creature) : NullCreatureAI(creature)
{
me->CastSpell(me, SPELL_MAGE_TOASTY_FIRE_AURA, true);
}
@@ -713,15 +679,15 @@ struct npc_ulduar_toasty_fire : public NullCreatureAI
struct npc_ulduar_hodir_priest : public ScriptedAI
{
npc_ulduar_hodir_priest(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_hodir_priest(Creature* creature) : ScriptedAI(creature)
{
pInstance = me->GetInstanceScript();
_instance = me->GetInstanceScript();
events.Reset();
me->SetReactState(REACT_PASSIVE);
}
EventMap events;
InstanceScript* pInstance;
InstanceScript* _instance;
void AttackStart(Unit* who) override
{
@@ -758,8 +724,8 @@ struct npc_ulduar_hodir_priest : public ScriptedAI
case EVENT_TRY_FREE_HELPER:
{
if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC))
if (pInstance)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
{
AttackStart(hodir);
ScheduleAbilities();
@@ -791,23 +757,23 @@ struct npc_ulduar_hodir_priest : public ScriptedAI
void JustDied(Unit* /*killer*/) override
{
if (pInstance)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
hodir->AI()->SetData(4, 1);
}
};
struct npc_ulduar_hodir_druid : public ScriptedAI
{
npc_ulduar_hodir_druid(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_hodir_druid(Creature* creature) : ScriptedAI(creature)
{
pInstance = me->GetInstanceScript();
_instance = me->GetInstanceScript();
events.Reset();
me->SetReactState(REACT_PASSIVE);
}
EventMap events;
InstanceScript* pInstance;
InstanceScript* _instance;
void AttackStart(Unit* who) override
{
@@ -843,8 +809,8 @@ struct npc_ulduar_hodir_druid : public ScriptedAI
case EVENT_TRY_FREE_HELPER:
{
if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC))
if (pInstance)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
{
AttackStart(hodir);
ScheduleAbilities();
@@ -877,23 +843,23 @@ struct npc_ulduar_hodir_druid : public ScriptedAI
void JustDied(Unit* /*killer*/) override
{
if (pInstance)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
hodir->AI()->SetData(4, 1);
}
};
struct npc_ulduar_hodir_shaman : public ScriptedAI
{
npc_ulduar_hodir_shaman(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_hodir_shaman(Creature* creature) : ScriptedAI(creature)
{
pInstance = me->GetInstanceScript();
_instance = me->GetInstanceScript();
events.Reset();
me->SetReactState(REACT_PASSIVE);
}
EventMap events;
InstanceScript* pInstance;
InstanceScript* _instance;
void AttackStart(Unit* who) override
{
@@ -937,8 +903,8 @@ struct npc_ulduar_hodir_shaman : public ScriptedAI
case EVENT_TRY_FREE_HELPER:
{
if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC))
if (pInstance)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
{
AttackStart(hodir);
ScheduleAbilities();
@@ -970,23 +936,23 @@ struct npc_ulduar_hodir_shaman : public ScriptedAI
void JustDied(Unit* /*killer*/) override
{
if (pInstance)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
hodir->AI()->SetData(4, 1);
}
};
struct npc_ulduar_hodir_mage : public ScriptedAI
{
npc_ulduar_hodir_mage(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_hodir_mage(Creature* creature) : ScriptedAI(creature)
{
pInstance = me->GetInstanceScript();
_instance = me->GetInstanceScript();
events.Reset();
me->SetReactState(REACT_PASSIVE);
}
EventMap events;
InstanceScript* pInstance;
InstanceScript* _instance;
void AttackStart(Unit* who) override
{
@@ -1023,8 +989,8 @@ struct npc_ulduar_hodir_mage : public ScriptedAI
case EVENT_TRY_FREE_HELPER:
{
if (!me->HasAura(SPELL_FLASH_FREEZE_TRAPPED_NPC))
if (pInstance)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
{
AttackStart(hodir);
ScheduleAbilities();
@@ -1074,8 +1040,8 @@ struct npc_ulduar_hodir_mage : public ScriptedAI
void JustDied(Unit* /*killer*/) override
{
if (pInstance)
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (_instance)
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
hodir->AI()->SetData(4, 1);
}
};
@@ -1170,8 +1136,8 @@ class spell_hodir_biting_cold_player_aura : public AuraScript
if (_counter >= 4)
{
if (GetStackAmount() == 2) // increasing from 2 to 3 (not checking >= to improve performance)
if (InstanceScript* pInstance = target->GetInstanceScript())
if (Creature* hodir = pInstance->GetCreature(BOSS_HODIR))
if (InstanceScript* _instance = target->GetInstanceScript())
if (Creature* hodir = _instance->GetCreature(BOSS_HODIR))
hodir->AI()->SetData(2, 1);
ModStackAmount(1);
_counter = 0;

View File

@@ -572,10 +572,10 @@ struct boss_kologarn_eyebeam : public ScriptedAI
{
boss_kologarn_eyebeam(Creature* c) : ScriptedAI(c), _timer(1), _damaged(false)
{
m_pInstance = (InstanceScript*)c->GetInstanceScript();
_instance = c->GetInstanceScript();
}
InstanceScript* m_pInstance;
InstanceScript* _instance;
uint32 _timer;
bool _damaged;
@@ -602,7 +602,7 @@ struct boss_kologarn_eyebeam : public ScriptedAI
me->Attack(player, false);
me->GetMotionMaster()->MoveChase(player);
if (Creature* cr = m_pInstance->GetCreature(BOSS_KOLOGARN))
if (Creature* cr = _instance->GetCreature(BOSS_KOLOGARN))
{
me->CastSpell(cr, me->GetEntry() == NPC_EYE_LEFT ? SPELL_FOCUSED_EYEBEAM_LEFT : SPELL_FOCUSED_EYEBEAM_RIGHT, true);
}

View File

@@ -264,7 +264,7 @@ Position const ACUSummonPos = { 2742.6265f, 2568.0571f, 377.22076f, 0.0f }; ///
struct boss_mimiron : public BossAI
{
boss_mimiron(Creature* pCreature) : BossAI(pCreature, BOSS_MIMIRON)
boss_mimiron(Creature* creature) : BossAI(creature, BOSS_MIMIRON)
{
if (!me->IsAlive())
instance->SetBossState(BOSS_MIMIRON, DONE);
@@ -729,15 +729,6 @@ struct boss_mimiron : public BossAI
DoCastSelf(SPELL_SLEEP_VISUAL_1);
if (instance)
for( uint16 i = 0; i < 3; ++i )
if (GameObject* door = instance->GetGameObject(DATA_GO_MIMIRON_DOOR_1 + i))
if (door->GetGoState() != GO_STATE_ACTIVE )
{
door->SetLootState(GO_READY);
door->UseDoorOrButton(0, false);
}
instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, NPC_LEVIATHAN_MKII, 1, me);
if (_hardmode)
@@ -817,14 +808,6 @@ struct boss_mimiron : public BossAI
void ResetGameObjects()
{
for (uint16 i = 0; i < 3; ++i)
if (GameObject* door = instance->GetGameObject(DATA_GO_MIMIRON_DOOR_1 + i))
if (door->GetGoState() != GO_STATE_ACTIVE)
{
door->SetLootState(GO_READY);
door->UseDoorOrButton(0, false);
}
if (GameObject* elevator = me->FindNearestGameObject(GO_MIMIRON_ELEVATOR, 200.0f))
{
if (elevator->GetGoState() != GO_STATE_ACTIVE )
@@ -846,14 +829,6 @@ struct boss_mimiron : public BossAI
void CloseDoorAndButton()
{
for (uint16 i = 0; i < 3; ++i)
if (GameObject* door = instance->GetGameObject(DATA_GO_MIMIRON_DOOR_1 + i))
if (door->GetGoState() != GO_STATE_READY)
{
door->SetLootState(GO_READY);
door->UseDoorOrButton(0, false);
}
if (GameObject* button = me->FindNearestGameObject(GO_BUTTON, 200.0f))
if (button->GetGoState() != GO_STATE_ACTIVE)
{
@@ -945,7 +920,7 @@ private:
struct npc_ulduar_leviathan_mkii : public ScriptedAI
{
npc_ulduar_leviathan_mkii(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_leviathan_mkii(Creature* creature) : ScriptedAI(creature)
{
instance = me->GetInstanceScript();
_isEvading = false;
@@ -1074,21 +1049,21 @@ struct npc_ulduar_leviathan_mkii : public ScriptedAI
break;
case EVENT_SPELL_NAPALM_SHELL:
{
Player* pTarget = nullptr;
std::vector<Player*> pList;
Player* target = nullptr;
std::vector<Player*> playerList;
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
if (Player* plr = itr->GetSource())
if (plr->IsAlive() && plr->GetDistance2d(me) > 15.0f )
pList.push_back(plr);
playerList.push_back(plr);
if (!pList.empty())
pTarget = pList[urand(0, pList.size() - 1)];
if (!playerList.empty())
target = playerList[urand(0, playerList.size() - 1)];
else
pTarget = (Player*)SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true);
target = (Player*)SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true);
if (pTarget)
cannon->CastSpell(pTarget, SPELL_NAPALM_SHELL, false);
if (target)
cannon->CastSpell(target, SPELL_NAPALM_SHELL, false);
_events.Repeat(14s);
}
@@ -1188,7 +1163,7 @@ private:
struct npc_ulduar_vx001 : public ScriptedAI
{
npc_ulduar_vx001(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_vx001(Creature* creature) : ScriptedAI(creature)
{
instance = me->GetInstanceScript();
_isEvading = false;
@@ -1503,7 +1478,7 @@ private:
struct npc_ulduar_aerial_command_unit : public ScriptedAI
{
npc_ulduar_aerial_command_unit(Creature* pCreature) : ScriptedAI(pCreature), _summons(me)
npc_ulduar_aerial_command_unit(Creature* creature) : ScriptedAI(creature), _summons(me)
{
instance = me->GetInstanceScript();
_isEvading = false;
@@ -1744,7 +1719,7 @@ private:
struct npc_ulduar_proximity_mine : public ScriptedAI
{
npc_ulduar_proximity_mine(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_proximity_mine(Creature* creature) : ScriptedAI(creature)
{
_exploded = false;
_timer = 2500;
@@ -1809,7 +1784,7 @@ class spell_ulduar_mimiron_mine_explosion : public SpellScript
struct npc_ulduar_mimiron_rocket : public NullCreatureAI
{
npc_ulduar_mimiron_rocket(Creature* pCreature) : NullCreatureAI(pCreature) {}
npc_ulduar_mimiron_rocket(Creature* creature) : NullCreatureAI(creature) {}
void InitializeAI() override
{
@@ -1841,7 +1816,7 @@ struct npc_ulduar_mimiron_rocket : public NullCreatureAI
struct npc_ulduar_bot_summon_trigger : public NullCreatureAI
{
npc_ulduar_bot_summon_trigger(Creature* pCreature) : NullCreatureAI(pCreature) { }
npc_ulduar_bot_summon_trigger(Creature* creature) : NullCreatureAI(creature) { }
void Reset() override
{
@@ -2062,7 +2037,7 @@ public:
struct npc_ulduar_flames_initial : public NullCreatureAI
{
npc_ulduar_flames_initial(Creature* pCreature) : NullCreatureAI(pCreature)
npc_ulduar_flames_initial(Creature* creature) : NullCreatureAI(creature)
{
_createTime = GameTime::GetGameTime().count();
_events.Reset();
@@ -2170,7 +2145,7 @@ private:
struct npc_ulduar_flames_spread : public NullCreatureAI
{
npc_ulduar_flames_spread(Creature* pCreature) : NullCreatureAI(pCreature) {}
npc_ulduar_flames_spread(Creature* creature) : NullCreatureAI(creature) {}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
@@ -2201,7 +2176,7 @@ struct npc_ulduar_flames_spread : public NullCreatureAI
struct npc_ulduar_emergency_fire_bot : public ScriptedAI
{
npc_ulduar_emergency_fire_bot(Creature* pCreature) : ScriptedAI(pCreature)
npc_ulduar_emergency_fire_bot(Creature* creature) : ScriptedAI(creature)
{
_events.Reset();
_events.ScheduleEvent(EVENT_EMERGENCY_BOT_CHECK, 1s);
@@ -2248,7 +2223,7 @@ private:
struct npc_ulduar_rocket_strike_trigger : public NullCreatureAI
{
npc_ulduar_rocket_strike_trigger(Creature* pCreature) : NullCreatureAI(pCreature) {}
npc_ulduar_rocket_strike_trigger(Creature* creature) : NullCreatureAI(creature) {}
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
{

View File

@@ -365,12 +365,12 @@ const Position Middle = {1980.28f, -25.5868f, 329.397f, M_PI * 1.5f};
struct boss_yoggsaron_sara : public ScriptedAI
{
boss_yoggsaron_sara(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature)
boss_yoggsaron_sara(Creature* creature) : ScriptedAI(creature), summons(creature)
{
m_pInstance = pCreature->GetInstanceScript();
_instance = creature->GetInstanceScript();
}
InstanceScript* m_pInstance;
InstanceScript* _instance;
EventMap events;
SummonList summons;
@@ -463,27 +463,27 @@ struct boss_yoggsaron_sara : public ScriptedAI
_currentIllusion = urand(1, 3);
_isIllusionReversed = urand(0, 1);
if (m_pInstance)
if (_instance)
{
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_NOT_GETTING_OLDER);
m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SANITY);
m_pInstance->SetData(BOSS_YOGGSARON, NOT_STARTED);
if (GameObject* go = m_pInstance->GetGameObject(DATA_YOGG_SARON_DOORS))
_instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_NOT_GETTING_OLDER);
_instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SANITY);
_instance->SetData(BOSS_YOGGSARON, NOT_STARTED);
if (GameObject* go = _instance->GetGameObject(DATA_YOGG_SARON_DOORS))
go->SetGoState(GO_STATE_ACTIVE);
}
}
void InitFight(Unit* target)
{
if (!m_pInstance)
if (!_instance)
return;
// some simple hack checks
if (m_pInstance->GetBossState(BOSS_VEZAX) != DONE || m_pInstance->GetBossState(BOSS_XT002) != DONE)
if (_instance->GetBossState(BOSS_VEZAX) != DONE || _instance->GetBossState(BOSS_XT002) != DONE)
return;
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_NOT_GETTING_OLDER);
m_pInstance->SetData(BOSS_YOGGSARON, IN_PROGRESS);
_instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, CRITERIA_NOT_GETTING_OLDER);
_instance->SetData(BOSS_YOGGSARON, IN_PROGRESS);
me->SetInCombatWithZone();
AttackStart(target);
@@ -512,16 +512,18 @@ struct boss_yoggsaron_sara : public ScriptedAI
for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++)
{
summons.DespawnEntry(TABLE_GOSSIP_ENTRY[i]);
if (Creature* keeper = m_pInstance->GetCreature(gossipData[i]))
if (Creature* keeper = _instance->GetCreature(gossipData[i]))
keeper->DespawnOrUnsummon();
}
}
void UpdateKeeperSpawns()
{
uint32 watchersMask = _instance->GetPersistentData(
PERSISTENT_DATA_WATCHERS_MASK);
for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; i++)
{
if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i))
if (watchersMask & (1 << i))
{
if (!summons.HasEntry(TABLE_KEEPER_ENTRY[i]))
me->SummonCreature(TABLE_KEEPER_ENTRY[i], KeepersPos[i]);
@@ -617,8 +619,10 @@ struct boss_yoggsaron_sara : public ScriptedAI
if (param == DATA_GET_KEEPERS_COUNT)
{
uint8 _count = 0;
uint32 watchersMask = _instance->GetPersistentData(
PERSISTENT_DATA_WATCHERS_MASK);
for (uint8 i = 0; i < 4; ++i)
if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i))
if (watchersMask & (1 << i))
++_count;
return _count;
}
@@ -741,7 +745,7 @@ struct boss_yoggsaron_sara : public ScriptedAI
if (!SelectTargetFromPlayerList(90, SPELL_INSANE1))
{
m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_INSANE1);
_instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_INSANE1);
EnterEvadeMode(EVADE_REASON_OTHER);
return;
}
@@ -787,8 +791,8 @@ struct boss_yoggsaron_sara : public ScriptedAI
// Whispers of YS
me->SummonCreature(NPC_VOICE_OF_YOGG_SARON, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
if (m_pInstance)
if (GameObject* go = m_pInstance->GetGameObject(DATA_YOGG_SARON_DOORS))
if (_instance)
if (GameObject* go = _instance->GetGameObject(DATA_YOGG_SARON_DOORS))
go->SetGoState(GO_STATE_READY);
events.ScheduleEvent(EVENT_SARA_P1_SPELLS, 0ms, 1, EVENT_PHASE_ONE);
@@ -912,7 +916,7 @@ struct boss_yoggsaron_sara : public ScriptedAI
struct boss_yoggsaron_cloud : public npc_escortAI
{
boss_yoggsaron_cloud(Creature* pCreature) : npc_escortAI(pCreature)
boss_yoggsaron_cloud(Creature* creature) : npc_escortAI(creature)
{
InitWaypoint();
Reset();
@@ -998,7 +1002,7 @@ struct boss_yoggsaron_cloud : public npc_escortAI
struct boss_yoggsaron_guardian_of_ys : public ScriptedAI
{
boss_yoggsaron_guardian_of_ys(Creature* pCreature) : ScriptedAI(pCreature) { }
boss_yoggsaron_guardian_of_ys(Creature* creature) : ScriptedAI(creature) { }
uint32 _spellTimer;
@@ -1031,9 +1035,9 @@ struct boss_yoggsaron_guardian_of_ys : public ScriptedAI
struct boss_yoggsaron : public ScriptedAI
{
boss_yoggsaron(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature)
boss_yoggsaron(Creature* creature) : ScriptedAI(creature), summons(creature)
{
m_pInstance = me->GetInstanceScript();
_instance = me->GetInstanceScript();
_thirdPhase = false;
_usedInsane = false;
summons.DespawnAll();
@@ -1041,10 +1045,12 @@ struct boss_yoggsaron : public ScriptedAI
uint8 _count = 4;
me->SetLootMode(31); // 1 + 2 + 4 + 8 + 16, remove with watchers addition
if (m_pInstance)
if (_instance)
{
uint32 watchersMask = _instance->GetPersistentData(
PERSISTENT_DATA_WATCHERS_MASK);
for (uint8 i = 0; i < 4; ++i)
if (m_pInstance->GetData(TYPE_WATCHERS) & (1 << i))
if (watchersMask & (1 << i))
{
me->RemoveLootMode(1 << _count);
--_count;
@@ -1052,7 +1058,7 @@ struct boss_yoggsaron : public ScriptedAI
}
}
InstanceScript* m_pInstance;
InstanceScript* _instance;
EventMap events;
SummonList summons;
bool _thirdPhase;
@@ -1077,17 +1083,17 @@ struct boss_yoggsaron : public ScriptedAI
Talk(SAY_YOGG_SARON_DEATH);
if (m_pInstance)
if (_instance)
{
m_pInstance->SetData(BOSS_YOGGSARON, DONE);
if (Creature* sara = m_pInstance->GetCreature(DATA_SARA))
_instance->SetData(BOSS_YOGGSARON, DONE);
if (Creature* sara = _instance->GetCreature(DATA_SARA))
sara->AI()->DoAction(ACTION_YOGG_SARON_DEATH);
if (GameObject* go = m_pInstance->GetGameObject(DATA_YOGG_SARON_DOORS))
if (GameObject* go = _instance->GetGameObject(DATA_YOGG_SARON_DOORS))
go->SetGoState(GO_STATE_ACTIVE);
}
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
for(Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
{
itr->GetSource()->RemoveAura(SPELL_SANITY);
itr->GetSource()->RemoveAura(SPELL_INSANE1);
@@ -1200,7 +1206,7 @@ struct boss_yoggsaron : public ScriptedAI
struct boss_yoggsaron_brain : public NullCreatureAI
{
boss_yoggsaron_brain(Creature* pCreature) : NullCreatureAI(pCreature), summons(pCreature)
boss_yoggsaron_brain(Creature* creature) : NullCreatureAI(creature), summons(creature)
{
me->SetDisableGravity(true);
_tentacleCount = 0;
@@ -1434,7 +1440,7 @@ struct boss_yoggsaron_brain : public NullCreatureAI
struct boss_yoggsaron_death_orb : public NullCreatureAI
{
boss_yoggsaron_death_orb(Creature* pCreature) : NullCreatureAI(pCreature)
boss_yoggsaron_death_orb(Creature* creature) : NullCreatureAI(creature)
{
me->CastSpell(me, SPELL_DEATH_RAY_WARNING, true);
_startTimer = 1;
@@ -1463,7 +1469,7 @@ struct boss_yoggsaron_death_orb : public NullCreatureAI
struct boss_yoggsaron_crusher_tentacle : public ScriptedAI
{
boss_yoggsaron_crusher_tentacle(Creature* pCreature) : ScriptedAI(pCreature)
boss_yoggsaron_crusher_tentacle(Creature* creature) : ScriptedAI(creature)
{
me->SetCombatMovement(false);
me->CastSpell(me, SPELL_CRUSH, true);
@@ -1514,7 +1520,7 @@ struct boss_yoggsaron_crusher_tentacle : public ScriptedAI
struct boss_yoggsaron_corruptor_tentacle : public ScriptedAI
{
boss_yoggsaron_corruptor_tentacle(Creature* pCreature) : ScriptedAI(pCreature)
boss_yoggsaron_corruptor_tentacle(Creature* creature) : ScriptedAI(creature)
{
me->SetCombatMovement(false);
}
@@ -1528,10 +1534,10 @@ struct boss_yoggsaron_corruptor_tentacle : public ScriptedAI
Unit* SelectCorruptionTarget()
{
Player* target = nullptr;
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
uint8 num = urand(0, pList.getSize() - 1);
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
uint8 num = urand(0, playerList.getSize() - 1);
uint8 count = 0;
for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++count)
for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr, ++count)
{
if (me->GetDistance(itr->GetSource()) > 200 || itr->GetSource()->GetPositionZ() < 300 || !itr->GetSource()->IsAlive() || itr->GetSource()->IsGameMaster())
continue;
@@ -1560,7 +1566,7 @@ struct boss_yoggsaron_corruptor_tentacle : public ScriptedAI
struct boss_yoggsaron_constrictor_tentacle : public ScriptedAI
{
boss_yoggsaron_constrictor_tentacle(Creature* pCreature) : ScriptedAI(pCreature)
boss_yoggsaron_constrictor_tentacle(Creature* creature) : ScriptedAI(creature)
{
me->SetCombatMovement(false);
_checkTimer = 1;
@@ -1573,10 +1579,10 @@ struct boss_yoggsaron_constrictor_tentacle : public ScriptedAI
Unit* SelectConstrictTarget()
{
Player* target = nullptr;
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
uint8 num = urand(0, pList.getSize() - 1);
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
uint8 num = urand(0, playerList.getSize() - 1);
uint8 count = 0;
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++count)
for(Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr, ++count)
{
if (me->GetDistance(itr->GetSource()) > 10 || !itr->GetSource()->IsAlive() || itr->GetSource()->IsGameMaster())
continue;
@@ -1713,7 +1719,7 @@ private:
struct boss_yoggsaron_influence_tentacle : public NullCreatureAI
{
boss_yoggsaron_influence_tentacle(Creature* pCreature) : NullCreatureAI(pCreature)
boss_yoggsaron_influence_tentacle(Creature* creature) : NullCreatureAI(creature)
{
me->CastSpell(me, SPELL_GRIM_REPRISAL, true);
}
@@ -1734,7 +1740,7 @@ struct boss_yoggsaron_influence_tentacle : public NullCreatureAI
struct boss_yoggsaron_immortal_guardian : public ScriptedAI
{
boss_yoggsaron_immortal_guardian(Creature* pCreature) : ScriptedAI(pCreature)
boss_yoggsaron_immortal_guardian(Creature* creature) : ScriptedAI(creature)
{
Reset();
}
@@ -2043,7 +2049,7 @@ struct boss_yoggsaron_neltharion : public ScriptedAI
struct boss_yoggsaron_voice : public NullCreatureAI
{
boss_yoggsaron_voice(Creature* pCreature) : NullCreatureAI(pCreature)
boss_yoggsaron_voice(Creature* creature) : NullCreatureAI(creature)
{
_targets.clear();
_current = 0;
@@ -2127,13 +2133,13 @@ class spell_yogg_saron_brain_link : public SpellScript
void FilterTargets(std::list<WorldObject*>& targets)
{
std::list<WorldObject*> tempList;
std::list<WorldObject*> templayerList;
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
if ((*itr)->GetPositionZ() > 300.0f)
tempList.push_back(*itr);
templayerList.push_back(*itr);
targets.clear();
for (std::list<WorldObject*>::iterator itr = tempList.begin(); itr != tempList.end(); ++itr)
for (std::list<WorldObject*>::iterator itr = templayerList.begin(); itr != templayerList.end(); ++itr)
targets.push_back(*itr);
}
@@ -2156,10 +2162,10 @@ class spell_yogg_saron_brain_link_aura : public AuraScript
{
PreventDefaultAction();
Player* target = nullptr;
Map::PlayerList const& pList = GetUnitOwner()->GetMap()->GetPlayers();
uint8 _offset = urand(0, pList.getSize() - 1);
Map::PlayerList const& playerList = GetUnitOwner()->GetMap()->GetPlayers();
uint8 _offset = urand(0, playerList.getSize() - 1);
uint8 _counter = 0;
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr, ++_counter)
for(Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr, ++_counter)
{
if (itr->GetSource() == GetUnitOwner() || GetUnitOwner()->GetDistance(itr->GetSource()) > 50.0f || !itr->GetSource()->IsAlive() || itr->GetSource()->IsGameMaster())
continue;

View File

@@ -30,13 +30,30 @@
DoorData const doorData[] =
{
{ GO_LEVIATHAN_DOORS, BOSS_LEVIATHAN, DOOR_TYPE_ROOM },
{ GO_XT002_DOORS, BOSS_XT002, DOOR_TYPE_ROOM },
{ GO_KOLOGARN_DOORS, BOSS_KOLOGARN, DOOR_TYPE_ROOM },
{ GO_ASSEMBLY_DOORS, BOSS_ASSEMBLY, DOOR_TYPE_ROOM },
{ GO_ARCHIVUM_DOORS, BOSS_ASSEMBLY, DOOR_TYPE_PASSAGE },
{ GO_YOGG_SARON_DOORS, BOSS_YOGGSARON, DOOR_TYPE_ROOM },
{ 0, 0, DOOR_TYPE_ROOM }
{ GO_LEVIATHAN_DOORS, BOSS_LEVIATHAN, DOOR_TYPE_ROOM },
{ GO_LIGHTNING_WALL1, BOSS_LEVIATHAN, DOOR_TYPE_PASSAGE },
{ GO_XT002_DOORS, BOSS_XT002, DOOR_TYPE_ROOM },
{ GO_KOLOGARN_DOORS, BOSS_KOLOGARN, DOOR_TYPE_ROOM },
{ GO_ASSEMBLY_DOORS, BOSS_ASSEMBLY, DOOR_TYPE_ROOM },
{ GO_ARCHIVUM_DOORS, BOSS_ASSEMBLY, DOOR_TYPE_PASSAGE },
{ GO_MIMIRON_DOOR_1, BOSS_MIMIRON, DOOR_TYPE_ROOM },
{ GO_MIMIRON_DOOR_2, BOSS_MIMIRON, DOOR_TYPE_ROOM },
{ GO_MIMIRON_DOOR_3, BOSS_MIMIRON, DOOR_TYPE_ROOM },
{ GO_HODIR_FRONTDOOR, BOSS_HODIR, DOOR_TYPE_ROOM },
{ GO_HODIR_FROZEN_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE },
{ GO_HODIR_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE },
{ GO_KEEPERS_GATE, BOSS_HODIR, DOOR_TYPE_PASSAGE },
{ GO_KEEPERS_GATE, BOSS_MIMIRON, DOOR_TYPE_PASSAGE },
{ GO_KEEPERS_GATE, BOSS_THORIM, DOOR_TYPE_PASSAGE },
{ GO_KEEPERS_GATE, BOSS_FREYA, DOOR_TYPE_PASSAGE },
{ GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE },
{ GO_YOGG_SARON_DOORS, BOSS_YOGGSARON, DOOR_TYPE_ROOM },
{ GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM },
{ GO_DOODAD_UL_UNIVERSEFLOOR_01, BOSS_ALGALON, DOOR_TYPE_ROOM },
{ GO_DOODAD_UL_UNIVERSEFLOOR_02, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE },
{ GO_DOODAD_UL_UNIVERSEGLOBE01, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE },
{ GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE },
{ 0, 0, DOOR_TYPE_ROOM }
};
// Observation Ring keeper positions, indexed by KEEPER_* constants
@@ -152,92 +169,68 @@ class instance_ulduar : public InstanceMapScript
public:
instance_ulduar() : InstanceMapScript("instance_ulduar", MAP_ULDUAR) { }
InstanceScript* GetInstanceScript(InstanceMap* pMap) const override
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_ulduar_InstanceMapScript(pMap);
return new instance_ulduar_InstanceMapScript(map);
}
struct instance_ulduar_InstanceMapScript : public InstanceScript
{
instance_ulduar_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
instance_ulduar_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTER);
SetPersistentDataCount(MAX_PERSISTENT_DATA);
LoadDoorData(doorData);
LoadObjectData(creatureData, gameobjectData);
Initialize();
// 0: 10 man difficulty
// 1: 25 man difficulty
m_difficulty = (pMap->Is25ManRaid() ? 0 : 1);
};
// Only used for TYPE_WATCHERS bitmask
uint32 m_watchersMask;
uint32 C_of_Ulduar_MASK;
int m_difficulty;
// Flame Leviathan
ObjectGuid m_leviathanVisualTowers[4][2];
ObjectGuid m_RepairSGUID[2];
bool m_leviathanTowers[4];
ObjectGuid _leviathanVisualTowers[4][2];
ObjectGuid _repairSGUID[2];
bool _leviathanTowers[4];
GuidList _leviathanVehicles;
uint32 m_unbrokenAchievement;
uint32 m_mageBarrier;
// Hodir
bool hmHodir;
bool _hmHodir;
Position normalChestPosition = { 1967.152588f, -204.188461f, 432.686951f, 5.50957f };
Position hardChestPosition = { 2035.94600f, -202.084885f, 432.686859f, 3.164077f };
// Freya
uint32 m_conspeedatoryAttempt;
// Yogg-Saron
// Algalon
uint32 m_algalonTimer;
// Ancient Gate
const Position triggerAncientGatePosition = { 1883.65f, 269.272f, 418.406f };
Position const triggerAncientGatePosition = { 1883.65f, 269.272f, 418.406f };
// Shared
EventMap _events;
bool m_mimironTramUsed;
bool _mimironTramUsed;
void Initialize() override
{
// Bosses
m_watchersMask = 0;
C_of_Ulduar_MASK = 0;
// Flame Leviathan
for (uint8 i = 0; i < 4; ++i)
m_leviathanTowers[i] = true;
_leviathanTowers[i] = true;
_leviathanVehicles.clear();
m_unbrokenAchievement = 1;
m_mageBarrier = 0;
// Hodir
hmHodir = true; // If players fail the Hardmode then becomes false
// Freya
m_conspeedatoryAttempt = 0;
// Algalon
m_algalonTimer = 0;
_hmHodir = true; // If players fail the Hardmode then becomes false
// Shared
_events.Reset();
m_mimironTramUsed = false;
_mimironTramUsed = false;
}
void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& packet) override
{
uint32 algalonTimer =
GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER);
packet.Worldstates.reserve(2);
packet.Worldstates.emplace_back(WORLD_STATE_ULDUAR_ALGALON_TIMER_ENABLED, (m_algalonTimer && m_algalonTimer <= 60) ? 1 : 0);
packet.Worldstates.emplace_back(WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER, std::min<int32>(m_algalonTimer, 60));
packet.Worldstates.emplace_back(
WORLD_STATE_ULDUAR_ALGALON_TIMER_ENABLED,
(algalonTimer && algalonTimer <= 60) ? 1 : 0);
packet.Worldstates.emplace_back(
WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER,
std::min<uint32>(algalonTimer, 60));
}
void OnPlayerEnter(Player* player) override
@@ -258,28 +251,36 @@ public:
}
// Spawn Observation Ring keepers for defeated bosses
uint32 watchersMask =
GetPersistentData(PERSISTENT_DATA_WATCHERS_MASK);
for (uint8 i = KEEPER_FREYA; i <= KEEPER_THORIM; ++i)
if (IsBossDone(ObservationRingKeeperBoss[i])
&& !(m_watchersMask & (1 << i))
&& !(watchersMask & (1 << i))
&& !GetObjectGuid(ObservationRingKeeperData[i]))
instance->SummonCreature(
ObservationRingKeeperEntry[i],
ObservationRingKeepersPos[i]);
if (!GetObjectGuid(BOSS_ALGALON) && m_algalonTimer && (m_algalonTimer <= 60 || m_algalonTimer == TIMER_ALGALON_TO_SUMMON))
uint32 algalonTimer =
GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER);
if (!GetObjectGuid(BOSS_ALGALON) && algalonTimer
&& (algalonTimer <= 60
|| algalonTimer == TIMER_ALGALON_TO_SUMMON))
{
TempSummon* algalon = instance->SummonCreature(NPC_ALGALON, AlgalonLandPos);
if (!algalon)
return;
if (m_algalonTimer <= 60)
if (algalonTimer <= 60)
{
_events.RescheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 1min);
algalon->AI()->DoAction(ACTION_INIT_ALGALON);
}
else // if (m_algalonTimer = TIMER_ALGALON_TO_SUMMON)
else // if (algalonTimer == TIMER_ALGALON_TO_SUMMON)
{
m_algalonTimer = TIMER_ALGALON_SUMMONED;
StorePersistentData(
PERSISTENT_DATA_ALGALON_TIMER,
TIMER_ALGALON_SUMMONED);
algalon->SetImmuneToPC(false);
}
}
@@ -329,15 +330,9 @@ public:
go->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
break;
case BOSS_ASSEMBLY:
// Assembly doors handled by DoorData, archivum
// doors stay open only after DONE
if (GameObject* go = GetGameObject(DATA_ARCHIVUM_DOORS))
go->SetGoState(state == DONE ? GO_STATE_ACTIVE : GO_STATE_READY);
break;
case BOSS_MIMIRON:
if (state == IN_PROGRESS)
m_mimironTramUsed = true;
_mimironTramUsed = true;
[[fallthrough]];
case BOSS_HODIR:
case BOSS_THORIM:
@@ -346,12 +341,8 @@ public:
{
scheduler.Schedule(45s, [this](TaskContext /*context*/)
{
if (GameObject* go = GetGameObject(DATA_KEEPERS_GATE))
{
go->RemoveGameObjectFlag(GO_FLAG_LOCKED);
if (Creature* trigger = instance->SummonCreature(NPC_ANCIENT_GATE_WORLD_TRIGGER, triggerAncientGatePosition, nullptr, 10 * IN_MILLISECONDS))
trigger->AI()->Talk(EMOTE_ANCIENT_GATE_UNLOCKED);
}
if (Creature* trigger = instance->SummonCreature(NPC_ANCIENT_GATE_WORLD_TRIGGER, triggerAncientGatePosition, nullptr, 10 * IN_MILLISECONDS))
trigger->AI()->Talk(EMOTE_ANCIENT_GATE_UNLOCKED);
});
}
if (type == BOSS_HODIR && state == DONE)
@@ -364,33 +355,6 @@ public:
ObservationRingKeepersPos[keeperIdx]);
}
break;
case BOSS_ALGALON:
if (GameObject* go = GetGameObject(DATA_SIGILDOOR_03))
{
go->SetGoState(state != IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY);
go->EnableCollision(false);
}
if (GameObject* go = GetGameObject(DATA_UNIVERSE_FLOOR_01))
{
go->SetGoState(state != IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY);
go->EnableCollision(false);
}
if (GameObject* go = GetGameObject(DATA_UNIVERSE_FLOOR_02))
{
go->SetGoState(state == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY);
go->EnableCollision(false);
}
if (GameObject* go = GetGameObject(DATA_UNIVERSE_GLOBE))
{
go->SetGoState(state == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY);
go->EnableCollision(false);
}
if (GameObject* go = GetGameObject(DATA_ALGALON_TRAPDOOR))
{
go->SetGoState(state == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY);
go->EnableCollision(false);
}
break;
default:
break;
}
@@ -408,9 +372,6 @@ public:
}
}
if (state == DONE)
SaveToDB();
if (type > BOSS_LEVIATHAN && type < MAX_ENCOUNTER && state == IN_PROGRESS)
{
instance->DoForAllPlayers([&](Player* player)
@@ -451,7 +412,7 @@ public:
hardChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
{
go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
hmHodir = true;
_hmHodir = true;
}
}
break;
@@ -480,7 +441,7 @@ public:
hardChestPosition.GetOrientation(), 0, 0, 0, 0, 0))
{
go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
hmHodir = true;
_hmHodir = true;
}
}
break;
@@ -512,7 +473,7 @@ public:
}
break;
case NPC_ALGALON:
if (!m_algalonTimer)
if (!GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER))
creature->DespawnOrUnsummon();
break;
//! These creatures are summoned by something else than Algalon
@@ -557,46 +518,43 @@ public:
// Flame Leviathan
case GO_REPAIR_STATION_TRAP:
{
if (m_RepairSGUID[0])
m_RepairSGUID[1] = gameObject->GetGUID();
if (_repairSGUID[0])
_repairSGUID[1] = gameObject->GetGUID();
else
m_RepairSGUID[0] = gameObject->GetGUID();
_repairSGUID[0] = gameObject->GetGUID();
break;
}
case GO_LIGHTNING_WALL1:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
break;
case GO_MIMIRONS_TARGETTING_CRYSTAL:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
m_leviathanVisualTowers[3][0] = gameObject->GetGUID();
_leviathanVisualTowers[3][0] = gameObject->GetGUID();
break;
case GO_FREYAS_TARGETTING_CRYSTAL:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
m_leviathanVisualTowers[0][0] = gameObject->GetGUID();
_leviathanVisualTowers[0][0] = gameObject->GetGUID();
break;
case GO_HODIRS_TARGETTING_CRYSTAL:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
m_leviathanVisualTowers[2][0] = gameObject->GetGUID();
_leviathanVisualTowers[2][0] = gameObject->GetGUID();
break;
case GO_THORIMS_TARGETTING_CRYSTAL:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
m_leviathanVisualTowers[1][0] = gameObject->GetGUID();
_leviathanVisualTowers[1][0] = gameObject->GetGUID();
break;
case GO_MIMIRONS_GENERATOR:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
m_leviathanVisualTowers[3][1] = gameObject->GetGUID();
_leviathanVisualTowers[3][1] = gameObject->GetGUID();
break;
case GO_FREYAS_GENERATOR:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
m_leviathanVisualTowers[0][1] = gameObject->GetGUID();
_leviathanVisualTowers[0][1] = gameObject->GetGUID();
break;
case GO_HODIRS_GENERATOR:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
m_leviathanVisualTowers[2][1] = gameObject->GetGUID();
_leviathanVisualTowers[2][1] = gameObject->GetGUID();
break;
case GO_THORIMS_GENERATOR:
OpenIfDone(BOSS_LEVIATHAN, gameObject, GO_STATE_ACTIVE);
m_leviathanVisualTowers[1][1] = gameObject->GetGUID();
_leviathanVisualTowers[1][1] = gameObject->GetGUID();
break;
case GO_LEVIATHAN_DOORS:
if (GetBossState(BOSS_LEVIATHAN) >= DONE)
@@ -605,9 +563,6 @@ public:
case GO_KOLOGARN_BRIDGE:
OpenIfDone(BOSS_KOLOGARN, gameObject, GO_STATE_READY);
break;
case GO_ARCHIVUM_DOORS:
OpenIfDone(BOSS_ASSEMBLY, gameObject, GO_STATE_ACTIVE);
break;
case GO_KEEPERS_GATE:
if (AllBossesDone({BOSS_MIMIRON, BOSS_FREYA, BOSS_HODIR, BOSS_THORIM}))
gameObject->RemoveGameObjectFlag(GO_FLAG_LOCKED);
@@ -616,43 +571,33 @@ public:
case GO_MIMIRON_ELEVATOR:
gameObject->EnableCollision(false);
break;
case GO_HODIR_FROZEN_DOOR:
case GO_HODIR_DOOR:
if (GetBossState(BOSS_HODIR) == DONE)
if (gameObject->GetGoState() != GO_STATE_ACTIVE )
{
gameObject->SetLootState(GO_READY);
gameObject->UseDoorOrButton(0, false);
}
break;
case GO_VEZAX_DOOR:
if (GetBossState(BOSS_VEZAX) == DONE )
if (gameObject->GetGoState() != GO_STATE_ACTIVE )
{
gameObject->SetLootState(GO_READY);
gameObject->UseDoorOrButton(0, false);
}
break;
case GO_SNOW_MOUND:
gameObject->EnableCollision(false);
break;
// Mimiron Tram
case GO_MIMIRON_TRAM:
if (GetBossState(BOSS_MIMIRON) == DONE)
m_mimironTramUsed = true;
_mimironTramUsed = true;
break;
// Algalon the Observer
case GO_CELESTIAL_PLANETARIUM_ACCESS_10:
case GO_CELESTIAL_PLANETARIUM_ACCESS_25:
if (m_algalonTimer)
if (GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER))
gameObject->SetGameObjectFlag(GO_FLAG_IN_USE);
break;
case GO_DOODAD_UL_SIGILDOOR_03:
case GO_DOODAD_UL_UNIVERSEFLOOR_01:
case GO_DOODAD_UL_UNIVERSEFLOOR_02:
case GO_DOODAD_UL_UNIVERSEGLOBE01:
case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03:
gameObject->EnableCollision(false);
break;
case GO_DOODAD_UL_SIGILDOOR_01:
if (m_algalonTimer)
if (GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER))
gameObject->SetGoState(GO_STATE_ACTIVE);
break;
case GO_DOODAD_UL_SIGILDOOR_02:
if (m_algalonTimer)
if (GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER))
gameObject->SetGoState(GO_STATE_ACTIVE);
break;
// Herbs
@@ -674,7 +619,7 @@ public:
switch (boss)
{
case BOSS_HODIR:
if (hmHodir)
if (_hmHodir)
{
if (GameObject* go = GetHodirChest(true))
{
@@ -699,30 +644,27 @@ public:
case TYPE_HODIR_HM_FAIL:
if (GameObject* go = GetHodirChest(true))
{
hmHodir = false;
_hmHodir = false;
go->Delete();
}
break;
case TYPE_WATCHERS:
m_watchersMask |= 1 << data;
[[fallthrough]];
case DATA_MAGE_BARRIER:
StorePersistentData(
PERSISTENT_DATA_MAGE_BARRIER, data);
break;
case EVENT_KEEPER_TELEPORTED:
if (Creature* sara = GetCreature(DATA_SARA))
sara->AI()->DoAction(ACTION_SARA_UPDATE_SUMMON_KEEPERS);
break;
case DATA_MAGE_BARRIER:
m_mageBarrier = data;
break;
case EVENT_TOWER_OF_LIFE_DESTROYED:
case EVENT_TOWER_OF_STORM_DESTROYED:
case EVENT_TOWER_OF_FROST_DESTROYED:
case EVENT_TOWER_OF_FLAMES_DESTROYED:
{
m_leviathanTowers[type - EVENT_TOWER_OF_LIFE_DESTROYED] = data;
_leviathanTowers[type - EVENT_TOWER_OF_LIFE_DESTROYED] = data;
for (uint8 i = 0; i < 2; ++i)
{
if (GameObject *gameObject = instance->GetGameObject(m_leviathanVisualTowers[type - EVENT_TOWER_OF_LIFE_DESTROYED][i]))
if (GameObject *gameObject = instance->GetGameObject(_leviathanVisualTowers[type - EVENT_TOWER_OF_LIFE_DESTROYED][i]))
{
gameObject->SetGoState(GO_STATE_ACTIVE);
}
@@ -733,23 +675,20 @@ public:
case DATA_VEHICLE_SPAWN:
SpawnLeviathanEncounterVehicles(data);
return;
case DATA_UNBROKEN_ACHIEVEMENT:
m_unbrokenAchievement = data;
SaveToDB();
return;
case DATA_DESPAWN_ALGALON:
DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_TIMER_ENABLED, 1);
DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER, 60);
m_algalonTimer = 60;
StorePersistentData(PERSISTENT_DATA_ALGALON_TIMER, 60);
_events.RescheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 1min);
SaveToDB();
return;
case DATA_ALGALON_SUMMON_STATE:
case DATA_ALGALON_DEFEATED:
DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_TIMER_ENABLED, 0);
m_algalonTimer = (type == DATA_ALGALON_DEFEATED ? TIMER_ALGALON_DEFEATED : TIMER_ALGALON_SUMMONED);
StorePersistentData(PERSISTENT_DATA_ALGALON_TIMER,
type == DATA_ALGALON_DEFEATED
? TIMER_ALGALON_DEFEATED
: TIMER_ALGALON_SUMMONED);
_events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER);
SaveToDB();
return;
// Achievement
case DATA_DWARFAGEDDON:
@@ -820,8 +759,6 @@ public:
break;
}
if (type == TYPE_WATCHERS)
SaveToDB();
}
ObjectGuid GetGuidData(uint32 data) const override
@@ -830,9 +767,9 @@ public:
{
// Flame Leviathan
case DATA_REPAIR_STATION1:
return m_RepairSGUID[0];
return _repairSGUID[0];
case DATA_REPAIR_STATION2:
return m_RepairSGUID[1];
return _repairSGUID[1];
}
@@ -843,23 +780,18 @@ public:
{
switch (type)
{
case TYPE_WATCHERS:
return m_watchersMask;
case EVENT_TOWER_OF_LIFE_DESTROYED:
case EVENT_TOWER_OF_STORM_DESTROYED:
case EVENT_TOWER_OF_FROST_DESTROYED:
case EVENT_TOWER_OF_FLAMES_DESTROYED:
return m_leviathanTowers[type - EVENT_TOWER_OF_LIFE_DESTROYED];
return _leviathanTowers[type - EVENT_TOWER_OF_LIFE_DESTROYED];
case DATA_MAGE_BARRIER:
return m_mageBarrier;
case DATA_UNBROKEN_ACHIEVEMENT:
return m_unbrokenAchievement;
return GetPersistentData(
PERSISTENT_DATA_MAGE_BARRIER);
case DATA_CALL_TRAM:
return m_mimironTramUsed;
return _mimironTramUsed;
}
return 0;
@@ -876,11 +808,15 @@ public:
}
else if (unit->IsCreature() && unit->GetAreaId() == AREA_THE_CONSERVATORY_OF_LIFE)
{
if (GameTime::GetGameTime().count() > (m_conspeedatoryAttempt + DAY))
uint32 conspeedatory =
GetPersistentData(PERSISTENT_DATA_CONSPEEDATORY);
if (GameTime::GetGameTime().count() > (conspeedatory + DAY))
{
DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, 21597 /*CON-SPEED-ATORY_TIMED_CRITERIA*/);
m_conspeedatoryAttempt = GameTime::GetGameTime().count();
SaveToDB();
DoStartTimedAchievement(
ACHIEVEMENT_TIMED_TYPE_EVENT,
21597 /*CON-SPEED-ATORY_TIMED_CRITERIA*/);
StorePersistentData(PERSISTENT_DATA_CONSPEEDATORY,
GameTime::GetGameTime().count());
}
}
@@ -888,55 +824,52 @@ public:
if (unit->IsPlayer())
for (uint8 i = 0; i <= 12; ++i)
{
bool go = false;
bool inCombat = false;
if (i == BOSS_LEVIATHAN)
{
if (Creature* c = GetCreature(BOSS_LEVIATHAN))
if (c->IsInCombat())
go = true;
inCombat = true;
}
else
go = (GetBossState(i) == IN_PROGRESS);
inCombat = (GetBossState(i) == IN_PROGRESS);
if (go && (C_of_Ulduar_MASK & (1 << i)) == 0)
{
C_of_Ulduar_MASK |= (1 << i);
SaveToDB();
}
uint32 mask =
GetPersistentData(PERSISTENT_DATA_C_OF_ULDUAR_MASK);
if (inCombat && (mask & (1 << i)) == 0)
StorePersistentData(
PERSISTENT_DATA_C_OF_ULDUAR_MASK,
mask | (1 << i));
}
}
void ReadSaveDataMore(std::istringstream& data) override
void Load(char const* data) override
{
// Boss states 0-13 are read by base InstanceScript.
data >> m_watchersMask;
data >> m_conspeedatoryAttempt;
data >> m_unbrokenAchievement;
data >> m_algalonTimer;
InstanceScript::Load(data);
if (m_algalonTimer == TIMER_ALGALON_SUMMONED)
m_algalonTimer = TIMER_ALGALON_TO_SUMMON;
if (!data)
StorePersistentData(PERSISTENT_DATA_UNBROKEN, 1);
if (m_algalonTimer && m_algalonTimer <= 60 && GetBossState(BOSS_ALGALON) != DONE)
uint32 algalonTimer =
GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER);
if (algalonTimer == TIMER_ALGALON_SUMMONED)
{
DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_TIMER_ENABLED, 1);
DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER, m_algalonTimer);
StorePersistentData(
PERSISTENT_DATA_ALGALON_TIMER,
TIMER_ALGALON_TO_SUMMON);
}
data >> C_of_Ulduar_MASK;
data >> m_mageBarrier;
}
void WriteSaveDataMore(std::ostringstream& data) override
{
// Boss states 0-13 are written by base InstanceScript.
// Only write extra non-boss data here.
data << m_watchersMask << ' '
<< m_conspeedatoryAttempt << ' '
<< m_unbrokenAchievement << ' '
<< m_algalonTimer << ' '
<< C_of_Ulduar_MASK << ' '
<< m_mageBarrier;
algalonTimer =
GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER);
if (algalonTimer && algalonTimer <= 60
&& GetBossState(BOSS_ALGALON) != DONE)
{
DoUpdateWorldState(
WORLD_STATE_ULDUAR_ALGALON_TIMER_ENABLED, 1);
DoUpdateWorldState(
WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER,
algalonTimer);
}
}
void Update(uint32 diff) override
@@ -950,12 +883,19 @@ public:
switch (_events.ExecuteEvent())
{
case EVENT_UPDATE_ALGALON_TIMER:
if (m_algalonTimer == TIMER_ALGALON_DEFEATED)
{
uint32 algalonTimer =
GetPersistentData(PERSISTENT_DATA_ALGALON_TIMER);
if (algalonTimer == TIMER_ALGALON_DEFEATED)
return;
SaveToDB();
DoUpdateWorldState(WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER, --m_algalonTimer);
if (m_algalonTimer)
StorePersistentData(
PERSISTENT_DATA_ALGALON_TIMER,
--algalonTimer);
DoUpdateWorldState(
WORLD_STATE_ULDUAR_ALGALON_DESPAWN_TIMER,
algalonTimer);
if (algalonTimer)
{
_events.Repeat(1min);
return;
@@ -964,6 +904,7 @@ public:
SetData(DATA_ALGALON_DEFEATED, 1);
if (Creature* algalon = GetCreature(BOSS_ALGALON))
algalon->AI()->DoAction(ACTION_DESPAWN_ALGALON);
}
}
}
@@ -971,47 +912,48 @@ public:
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override
{
uint32 mask = GetPersistentData(PERSISTENT_DATA_C_OF_ULDUAR_MASK);
switch (criteria_id)
{
case 10042:
case 10352:
return (C_of_Ulduar_MASK & (1 << BOSS_LEVIATHAN)) == 0;
return (mask & (1 << BOSS_LEVIATHAN)) == 0;
case 10342:
case 10355:
return (C_of_Ulduar_MASK & (1 << BOSS_IGNIS)) == 0;
return (mask & (1 << BOSS_IGNIS)) == 0;
case 10340:
case 10353:
return (C_of_Ulduar_MASK & (1 << BOSS_RAZORSCALE)) == 0;
return (mask & (1 << BOSS_RAZORSCALE)) == 0;
case 10341:
case 10354:
return (C_of_Ulduar_MASK & (1 << BOSS_XT002)) == 0;
return (mask & (1 << BOSS_XT002)) == 0;
case 10598:
case 10599:
return (C_of_Ulduar_MASK & (1 << BOSS_ASSEMBLY)) == 0;
return (mask & (1 << BOSS_ASSEMBLY)) == 0;
case 10348:
case 10357:
return (C_of_Ulduar_MASK & (1 << BOSS_KOLOGARN)) == 0;
return (mask & (1 << BOSS_KOLOGARN)) == 0;
case 10351:
case 10363:
return (C_of_Ulduar_MASK & (1 << BOSS_AURIAYA)) == 0;
return (mask & (1 << BOSS_AURIAYA)) == 0;
case 10439:
case 10719:
return (C_of_Ulduar_MASK & (1 << BOSS_HODIR)) == 0;
return (mask & (1 << BOSS_HODIR)) == 0;
case 10403:
case 10404:
return (C_of_Ulduar_MASK & (1 << BOSS_THORIM)) == 0;
return (mask & (1 << BOSS_THORIM)) == 0;
case 10582:
case 10583:
return (C_of_Ulduar_MASK & (1 << BOSS_FREYA)) == 0;
return (mask & (1 << BOSS_FREYA)) == 0;
case 10347:
case 10361:
return (C_of_Ulduar_MASK & (1 << BOSS_MIMIRON)) == 0;
return (mask & (1 << BOSS_MIMIRON)) == 0;
case 10349:
case 10362:
return (C_of_Ulduar_MASK & (1 << BOSS_VEZAX)) == 0;
return (mask & (1 << BOSS_VEZAX)) == 0;
case 10350:
case 10364:
return (C_of_Ulduar_MASK & (1 << BOSS_YOGGSARON)) == 0;
return (mask & (1 << BOSS_YOGGSARON)) == 0;
}
return false;
}

View File

@@ -137,7 +137,13 @@ public:
if (spellInfo->Id == SPELL_TELEPORT)
{
me->DespawnOrUnsummon();
me->GetInstanceScript()->SetData(TYPE_WATCHERS, _keeper);
InstanceScript* instance = me->GetInstanceScript();
uint32 mask = instance->GetPersistentData(
PERSISTENT_DATA_WATCHERS_MASK);
instance->StorePersistentData(
PERSISTENT_DATA_WATCHERS_MASK,
mask | (1 << _keeper));
instance->SetData(EVENT_KEEPER_TELEPORTED, 0);
}
}

View File

@@ -306,6 +306,17 @@ enum UlduarGameObjects
GO_GIFT_OF_THE_OBSERVER_25 = 194822,
};
enum UlduarPersistentData
{
PERSISTENT_DATA_WATCHERS_MASK = 0,
PERSISTENT_DATA_CONSPEEDATORY,
PERSISTENT_DATA_UNBROKEN,
PERSISTENT_DATA_ALGALON_TIMER,
PERSISTENT_DATA_C_OF_ULDUAR_MASK,
PERSISTENT_DATA_MAGE_BARRIER,
MAX_PERSISTENT_DATA
};
enum UlduarMisc
{
// Flame Leviathan