mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-27 22:16:11 +00:00
refactor(Scripts/Ulduar): Update Ulduar to use boss states and other modernizations (#24714)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
-- Remove unused ScriptName from Pure Saronite Deposit
|
||||
UPDATE `gameobject_template` SET `ScriptName` = '' WHERE `entry` = 195036;
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -97,7 +97,7 @@ enum Misc
|
||||
|
||||
struct boss_auriaya : public BossAI
|
||||
{
|
||||
boss_auriaya(Creature* creature) : BossAI(creature, TYPE_AURIAYA) { }
|
||||
boss_auriaya(Creature* creature) : BossAI(creature, BOSS_AURIAYA) { }
|
||||
|
||||
bool _feralDied{false};
|
||||
bool _nineLives{false};
|
||||
@@ -230,8 +230,8 @@ struct npc_auriaya_sanctum_sentry : public ScriptedAI
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA)))
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* cr = instance->GetCreature(BOSS_AURIAYA))
|
||||
cr->SetInCombatWithZone();
|
||||
|
||||
events.ScheduleEvent(EVENT_SAVAGE_POUNCE, 5s);
|
||||
@@ -241,7 +241,7 @@ struct npc_auriaya_sanctum_sentry : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
me->CastSpell(me, SPELL_STRENGTH_OF_THE_PACK, true);
|
||||
DoCastSelf(SPELL_STRENGTH_OF_THE_PACK, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -303,8 +303,8 @@ struct npc_auriaya_feral_defender : public ScriptedAI
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_AURIAYA)))
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* cr = instance->GetCreature(BOSS_AURIAYA))
|
||||
cr->AI()->DoAction(_feralEssenceStack ? ACTION_FERAL_DEATH_WITH_STACK : ACTION_FERAL_DEATH);
|
||||
|
||||
if (_feralEssenceStack)
|
||||
@@ -357,11 +357,11 @@ struct npc_auriaya_feral_defender : public ScriptedAI
|
||||
DoResetThreatList();
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
me->CastSpell(me->GetVictim(), SPELL_FERAL_RUSH, true);
|
||||
DoCastVictim(SPELL_FERAL_RUSH, true);
|
||||
events.Repeat(6s);
|
||||
break;
|
||||
case EVENT_FERAL_POUNCE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_FERAL_POUNCE, false);
|
||||
DoCastVictim(SPELL_FERAL_POUNCE);
|
||||
events.Repeat(6s);
|
||||
break;
|
||||
}
|
||||
@@ -394,8 +394,8 @@ public:
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_AURIAYA)))
|
||||
return cr->AI()->GetData(DATA_CRAZY_CAT);
|
||||
if (Creature* auriaya = instance->GetCreature(BOSS_AURIAYA))
|
||||
return auriaya->AI()->GetData(DATA_CRAZY_CAT);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -410,7 +410,7 @@ public:
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_AURIAYA)))
|
||||
if (Creature* cr = instance->GetCreature(BOSS_AURIAYA))
|
||||
return cr->AI()->GetData(DATA_NINE_LIVES);
|
||||
|
||||
return false;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -15,18 +15,14 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "AchievementCriteriaScript.h"
|
||||
#include "AreaDefines.h"
|
||||
#include "BanMgr.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "GameObjectScript.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "WorldSession.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum VezaxSpellData
|
||||
@@ -110,367 +106,307 @@ enum VaporsText
|
||||
SAY_EMOTE_VAPORS = 0,
|
||||
};
|
||||
|
||||
class boss_vezax : public CreatureScript
|
||||
struct boss_vezax : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_vezax() : CreatureScript("boss_vezax") { }
|
||||
boss_vezax(Creature* pCreature) : BossAI(pCreature, BOSS_VEZAX) { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
uint8 vaporsCount;
|
||||
bool hardmodeAvailable;
|
||||
bool berserk;
|
||||
bool bAchievShadowdodger;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
return GetUlduarAI<boss_vezaxAI>(pCreature);
|
||||
_Reset();
|
||||
vaporsCount = 0;
|
||||
hardmodeAvailable = true;
|
||||
berserk = false;
|
||||
bAchievShadowdodger = true;
|
||||
me->SetLootMode(1);
|
||||
}
|
||||
|
||||
struct boss_vezaxAI : public ScriptedAI
|
||||
void JustReachedHome() override
|
||||
{
|
||||
boss_vezaxAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me)
|
||||
_JustReachedHome();
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*pWho*/) override
|
||||
{
|
||||
me->setActive(true);
|
||||
_JustEngagedWith();
|
||||
|
||||
events.RescheduleEvent(EVENT_SPELL_VEZAX_SHADOW_CRASH, 13s);
|
||||
events.RescheduleEvent(EVENT_SPELL_SEARING_FLAMES, 10s, 1);
|
||||
events.RescheduleEvent(EVENT_SPELL_SURGE_OF_DARKNESS, 63s);
|
||||
events.RescheduleEvent(EVENT_SPELL_MARK_OF_THE_FACELESS, 20s);
|
||||
events.RescheduleEvent(EVENT_SPELL_SUMMON_SARONITE_VAPORS, 30s);
|
||||
events.RescheduleEvent(EVENT_BERSERK, 10min);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
me->CastSpell(me, SPELL_AURA_OF_DESPAIR_1, true);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
case 1:
|
||||
hardmodeAvailable = false;
|
||||
break;
|
||||
case 2:
|
||||
me->RemoveAura(SPELL_SARONITE_BARRIER);
|
||||
me->SetLootMode(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint8 vaporsCount;
|
||||
bool hardmodeAvailable;
|
||||
bool berserk;
|
||||
bool bAchievShadowdodger;
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void Reset() override
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
vaporsCount = 0;
|
||||
hardmodeAvailable = true;
|
||||
berserk = false;
|
||||
bAchievShadowdodger = true;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetLootMode(1);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, NOT_STARTED);
|
||||
case 1:
|
||||
return (me->GetLootMode() == 3 ? 1 : 0);
|
||||
case 2:
|
||||
return (bAchievShadowdodger ? 1 : 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
if (target && spell && target->IsPlayer() && spell->Id == SPELL_VEZAX_SHADOW_CRASH_DMG)
|
||||
bAchievShadowdodger = false;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!berserk && (me->GetPositionX() < 1720.0f || me->GetPositionX() > 1940.0f || me->GetPositionY() < 20.0f || me->GetPositionY() > 210.0f))
|
||||
events.RescheduleEvent(EVENT_BERSERK, 1ms);
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*pWho*/) override
|
||||
{
|
||||
me->setActive(true);
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_VEZAX_SHADOW_CRASH, 13s);
|
||||
events.RescheduleEvent(EVENT_SPELL_SEARING_FLAMES, 10s, 1);
|
||||
events.RescheduleEvent(EVENT_SPELL_SURGE_OF_DARKNESS, 63s);
|
||||
events.RescheduleEvent(EVENT_SPELL_MARK_OF_THE_FACELESS, 20s);
|
||||
events.RescheduleEvent(EVENT_SPELL_SUMMON_SARONITE_VAPORS, 30s);
|
||||
events.RescheduleEvent(EVENT_BERSERK, 10min);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, IN_PROGRESS);
|
||||
|
||||
me->CastSpell(me, SPELL_AURA_OF_DESPAIR_1, true);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case 1:
|
||||
hardmodeAvailable = false;
|
||||
break;
|
||||
case 2:
|
||||
me->RemoveAura(SPELL_SARONITE_BARRIER);
|
||||
me->SetLootMode(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 1:
|
||||
return (me->GetLootMode() == 3 ? 1 : 0);
|
||||
case 2:
|
||||
return (bAchievShadowdodger ? 1 : 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
if (target && spell && target->IsPlayer() && spell->Id == SPELL_VEZAX_SHADOW_CRASH_DMG)
|
||||
bAchievShadowdodger = false;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!berserk && (me->GetPositionX() < 1720.0f || me->GetPositionX() > 1940.0f || me->GetPositionY() < 20.0f || me->GetPositionY() > 210.0f))
|
||||
events.RescheduleEvent(EVENT_BERSERK, 1ms);
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
berserk = true;
|
||||
me->CastSpell(me, SPELL_VEZAX_BERSERK, true);
|
||||
Talk(SAY_BERSERK);
|
||||
break;
|
||||
case EVENT_SPELL_VEZAX_SHADOW_CRASH:
|
||||
{
|
||||
events.Repeat(10s);
|
||||
|
||||
std::vector<Player*> players;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
{
|
||||
Player* temp = itr->GetSource();
|
||||
if (temp->IsAlive() && temp->GetDistance(me) > 15.0f )
|
||||
players.push_back(temp);
|
||||
}
|
||||
if (!players.empty())
|
||||
{
|
||||
me->setAttackTimer(BASE_ATTACK, 2000);
|
||||
Player* target = players.at(urand(0, players.size() - 1));
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, target->GetGUID());
|
||||
me->CastSpell(target, SPELL_VEZAX_SHADOW_CRASH, false);
|
||||
events.ScheduleEvent(EVENT_RESTORE_TARGET, 750ms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_RESTORE_TARGET:
|
||||
if (me->GetVictim())
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, me->GetVictim()->GetGUID());
|
||||
break;
|
||||
case EVENT_SPELL_SEARING_FLAMES:
|
||||
if (!me->HasAura(SPELL_SARONITE_BARRIER))
|
||||
me->CastSpell(me->GetVictim(), SPELL_SEARING_FLAMES, false);
|
||||
events.Repeat(me->GetMap()->Is25ManRaid() ? 8s : 15s);
|
||||
break;
|
||||
case EVENT_SPELL_SURGE_OF_DARKNESS:
|
||||
Talk(SAY_SURGE_OF_DARKNESS);
|
||||
Talk(SAY_EMOTE_SURGE_OF_DARKNESS);
|
||||
me->CastSpell(me, SPELL_SURGE_OF_DARKNESS, false);
|
||||
events.Repeat(63s);
|
||||
events.DelayEvents(10s, 1);
|
||||
break;
|
||||
case EVENT_SPELL_MARK_OF_THE_FACELESS:
|
||||
{
|
||||
std::vector<Player*> outside;
|
||||
std::vector<Player*> inside;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if (Player* tmp = itr->GetSource())
|
||||
if (tmp->IsAlive())
|
||||
{
|
||||
if (tmp->GetDistance(me) > 15.0f )
|
||||
outside.push_back(tmp);
|
||||
else
|
||||
inside.push_back(tmp);
|
||||
}
|
||||
|
||||
Player* t = nullptr;
|
||||
if (outside.size() >= uint8(me->GetMap()->Is25ManRaid() ? 9 : 4))
|
||||
t = outside.at(urand(0, outside.size() - 1));
|
||||
else if (!inside.empty())
|
||||
t = inside.at(urand(0, inside.size() - 1));
|
||||
|
||||
if (t)
|
||||
me->CastSpell(t, SPELL_MARK_OF_THE_FACELESS_AURA, false);
|
||||
|
||||
events.Repeat(40s);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SARONITE_VAPORS:
|
||||
{
|
||||
vaporsCount++;
|
||||
me->CastSpell(me, SPELL_SUMMON_SARONITE_VAPORS, false);
|
||||
|
||||
if (vaporsCount < 6 || !hardmodeAvailable)
|
||||
events.Repeat(30s);
|
||||
else
|
||||
{
|
||||
for (ObjectGuid const& guid : summons)
|
||||
if (Creature* sv = ObjectAccessor::GetCreature(*me, guid))
|
||||
{
|
||||
sv->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
sv->GetMotionMaster()->MoveIdle();
|
||||
sv->GetMotionMaster()->MoveCharge(1852.78f, 81.38f, 342.461f, 28.0f);
|
||||
}
|
||||
|
||||
events.DelayEvents(12s, 0);
|
||||
events.DelayEvents(12s, 1);
|
||||
events.ScheduleEvent(EVENT_SARONITE_VAPORS_SWIRL, 6s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_SARONITE_VAPORS_SWIRL:
|
||||
if (summons.size())
|
||||
{
|
||||
Talk(SAY_EMOTE_ANIMUS);
|
||||
if (Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin())))
|
||||
sv->CastSpell(sv, SPELL_SARONITE_ANIMUS_FORMATION_VISUAL, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_SARONITE_ANIMUS, 2s);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SARONITE_ANIMUS:
|
||||
if (summons.size())
|
||||
{
|
||||
Talk(SAY_HARDMODE);
|
||||
Talk(SAY_EMOTE_BARRIER);
|
||||
me->CastSpell(me, SPELL_SARONITE_BARRIER, true);
|
||||
if (Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin())))
|
||||
sv->CastSpell(sv, SPELL_SUMMON_SARONITE_ANIMUS, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_DESPAWN_SARONITE_VAPORS, 2500ms);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_DESPAWN_SARONITE_VAPORS:
|
||||
summons.DespawnEntry(NPC_SARONITE_VAPORS);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_VEZAX, DONE);
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (GameObject* door = me->FindNearestGameObject(GO_VEZAX_DOOR, 500.0f))
|
||||
if (door->GetGoState() != GO_STATE_ACTIVE )
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
berserk = true;
|
||||
me->CastSpell(me, SPELL_VEZAX_BERSERK, true);
|
||||
Talk(SAY_BERSERK);
|
||||
break;
|
||||
case EVENT_SPELL_VEZAX_SHADOW_CRASH:
|
||||
{
|
||||
door->SetLootState(GO_READY);
|
||||
door->UseDoorOrButton(0, false);
|
||||
events.Repeat(10s);
|
||||
|
||||
std::vector<Player*> players;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
|
||||
{
|
||||
Player* temp = itr->GetSource();
|
||||
if (temp->IsAlive() && temp->GetDistance(me) > 15.0f)
|
||||
players.push_back(temp);
|
||||
}
|
||||
if (!players.empty())
|
||||
{
|
||||
me->setAttackTimer(BASE_ATTACK, 2000);
|
||||
Player* target = players.at(urand(0, players.size() - 1));
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, target->GetGUID());
|
||||
me->CastSpell(target, SPELL_VEZAX_SHADOW_CRASH, false);
|
||||
events.ScheduleEvent(EVENT_RESTORE_TARGET, 750ms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_RESTORE_TARGET:
|
||||
if (me->GetVictim())
|
||||
me->SetGuidValue(UNIT_FIELD_TARGET, me->GetVictim()->GetGUID());
|
||||
break;
|
||||
case EVENT_SPELL_SEARING_FLAMES:
|
||||
if (!me->HasAura(SPELL_SARONITE_BARRIER))
|
||||
me->CastSpell(me->GetVictim(), SPELL_SEARING_FLAMES, false);
|
||||
events.Repeat(me->GetMap()->Is25ManRaid() ? 8s : 15s);
|
||||
break;
|
||||
case EVENT_SPELL_SURGE_OF_DARKNESS:
|
||||
Talk(SAY_SURGE_OF_DARKNESS);
|
||||
Talk(SAY_EMOTE_SURGE_OF_DARKNESS);
|
||||
me->CastSpell(me, SPELL_SURGE_OF_DARKNESS, false);
|
||||
events.Repeat(63s);
|
||||
events.DelayEvents(10s, 1);
|
||||
break;
|
||||
case EVENT_SPELL_MARK_OF_THE_FACELESS:
|
||||
{
|
||||
std::vector<Player*> outside;
|
||||
std::vector<Player*> inside;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
|
||||
if (Player* tmp = itr->GetSource())
|
||||
if (tmp->IsAlive())
|
||||
{
|
||||
if (tmp->GetDistance(me) > 15.0f)
|
||||
outside.push_back(tmp);
|
||||
else
|
||||
inside.push_back(tmp);
|
||||
}
|
||||
|
||||
Player* t = nullptr;
|
||||
if (outside.size() >= uint8(me->GetMap()->Is25ManRaid() ? 9 : 4))
|
||||
t = outside.at(urand(0, outside.size() - 1));
|
||||
else if (!inside.empty())
|
||||
t = inside.at(urand(0, inside.size() - 1));
|
||||
|
||||
if (t)
|
||||
me->CastSpell(t, SPELL_MARK_OF_THE_FACELESS_AURA, false);
|
||||
|
||||
events.Repeat(40s);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SARONITE_VAPORS:
|
||||
{
|
||||
vaporsCount++;
|
||||
me->CastSpell(me, SPELL_SUMMON_SARONITE_VAPORS, false);
|
||||
|
||||
if (vaporsCount < 6 || !hardmodeAvailable)
|
||||
events.Repeat(30s);
|
||||
else
|
||||
{
|
||||
for (ObjectGuid const& guid : summons)
|
||||
if (Creature* sv = ObjectAccessor::GetCreature(*me, guid))
|
||||
{
|
||||
sv->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
sv->GetMotionMaster()->MoveIdle();
|
||||
sv->GetMotionMaster()->MoveCharge(1852.78f, 81.38f, 342.461f, 28.0f);
|
||||
}
|
||||
|
||||
events.DelayEvents(12s, 0);
|
||||
events.DelayEvents(12s, 1);
|
||||
events.ScheduleEvent(EVENT_SARONITE_VAPORS_SWIRL, 6s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_SARONITE_VAPORS_SWIRL:
|
||||
if (summons.size())
|
||||
{
|
||||
Talk(SAY_EMOTE_ANIMUS);
|
||||
if (Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin())))
|
||||
sv->CastSpell(sv, SPELL_SARONITE_ANIMUS_FORMATION_VISUAL, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_SARONITE_ANIMUS, 2s);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SARONITE_ANIMUS:
|
||||
if (summons.size())
|
||||
{
|
||||
Talk(SAY_HARDMODE);
|
||||
Talk(SAY_EMOTE_BARRIER);
|
||||
me->CastSpell(me, SPELL_SARONITE_BARRIER, true);
|
||||
if (Creature* sv = ObjectAccessor::GetCreature(*me, *(summons.begin())))
|
||||
sv->CastSpell(sv, SPELL_SUMMON_SARONITE_ANIMUS, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_DESPAWN_SARONITE_VAPORS, 2500ms);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_DESPAWN_SARONITE_VAPORS:
|
||||
summons.DespawnEntry(NPC_SARONITE_VAPORS);
|
||||
break;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->IsPlayer())
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* s) override
|
||||
{
|
||||
summons.Despawn(s);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_ulduar_saronite_vapors : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_saronite_vapors() : CreatureScript("npc_ulduar_saronite_vapors") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_saronite_vaporsAI>(pCreature);
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
struct npc_ulduar_saronite_vaporsAI : public NullCreatureAI
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
npc_ulduar_saronite_vaporsAI(Creature* pCreature) : NullCreatureAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
me->GetMotionMaster()->MoveRandom(4.0f);
|
||||
}
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->CastSpell(me, SPELL_SARONITE_VAPORS_AURA, true);
|
||||
|
||||
// killed saronite vapors, hard mode unavailable
|
||||
if (pInstance)
|
||||
if (Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)))
|
||||
vezax->AI()->DoAction(1);
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* /*summoner*/) override
|
||||
{
|
||||
Talk(SAY_EMOTE_VAPORS);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_ulduar_saronite_animus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_saronite_animus() : CreatureScript("npc_ulduar_saronite_animus") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_saronite_animusAI>(pCreature);
|
||||
}
|
||||
|
||||
struct npc_ulduar_saronite_animusAI : public ScriptedAI
|
||||
{
|
||||
npc_ulduar_saronite_animusAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
if (pInstance)
|
||||
if (Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)))
|
||||
vezax->AI()->JustSummoned(me);
|
||||
timer = 0;
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
uint16 timer;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->DespawnOrUnsummon(3s);
|
||||
|
||||
if (pInstance)
|
||||
if (Creature* vezax = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_VEZAX)))
|
||||
vezax->AI()->DoAction(2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
UpdateVictim();
|
||||
|
||||
timer += diff;
|
||||
if (timer >= 2000)
|
||||
if (GameObject* door = me->FindNearestGameObject(GO_VEZAX_DOOR, 500.0f))
|
||||
if (door->GetGoState() != GO_STATE_ACTIVE)
|
||||
{
|
||||
me->CastSpell(me, SPELL_PROFOUND_DARKNESS, true);
|
||||
timer -= 2000;
|
||||
door->SetLootState(GO_READY);
|
||||
door->UseDoorOrButton(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->IsPlayer())
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
};
|
||||
|
||||
struct npc_ulduar_saronite_vapors : public NullCreatureAI
|
||||
{
|
||||
npc_ulduar_saronite_vapors(Creature* pCreature) : NullCreatureAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
me->GetMotionMaster()->MoveRandom(4.0f);
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
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))
|
||||
vezax->AI()->DoAction(1);
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* /*summoner*/) override
|
||||
{
|
||||
Talk(SAY_EMOTE_VAPORS);
|
||||
}
|
||||
};
|
||||
|
||||
struct npc_ulduar_saronite_animus : public ScriptedAI
|
||||
{
|
||||
npc_ulduar_saronite_animus(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
if (pInstance)
|
||||
if (Creature* vezax = pInstance->GetCreature(BOSS_VEZAX))
|
||||
vezax->AI()->JustSummoned(me);
|
||||
timer = 0;
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
uint16 timer;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->DespawnOrUnsummon(3s);
|
||||
|
||||
if (pInstance)
|
||||
if (Creature* vezax = pInstance->GetCreature(BOSS_VEZAX))
|
||||
vezax->AI()->DoAction(2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
UpdateVictim();
|
||||
|
||||
timer += diff;
|
||||
if (timer >= 2000)
|
||||
{
|
||||
me->CastSpell(me, SPELL_PROFOUND_DARKNESS, true);
|
||||
timer -= 2000;
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_aura_of_despair_aura : public AuraScript
|
||||
@@ -630,34 +566,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class go_ulduar_pure_saronite_deposit : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_ulduar_pure_saronite_deposit() : GameObjectScript("go_ulduar_pure_saronite_deposit") { }
|
||||
|
||||
bool OnGossipHello(Player* plr, GameObject* go) override
|
||||
{
|
||||
if (plr->IsGameMaster())
|
||||
return false;
|
||||
|
||||
if (InstanceScript* pInstance = go->GetInstanceScript())
|
||||
if (pInstance->GetData(TYPE_XT002) != DONE && pInstance->GetData(TYPE_MIMIRON) != DONE && pInstance->GetData(TYPE_THORIM) != DONE && pInstance->GetData(TYPE_FREYA) != DONE && pInstance->GetData(TYPE_HODIR) != DONE)
|
||||
{
|
||||
std::string accountName;
|
||||
AccountMgr::GetName(plr->GetSession()->GetAccountId(), accountName);
|
||||
sBan->BanAccount(accountName, "0s", "Tele hack", "Server");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_vezax()
|
||||
{
|
||||
new boss_vezax();
|
||||
new npc_ulduar_saronite_vapors();
|
||||
new npc_ulduar_saronite_animus();
|
||||
RegisterUlduarCreatureAI(boss_vezax);
|
||||
RegisterUlduarCreatureAI(npc_ulduar_saronite_vapors);
|
||||
RegisterUlduarCreatureAI(npc_ulduar_saronite_animus);
|
||||
|
||||
RegisterSpellScript(spell_aura_of_despair_aura);
|
||||
RegisterSpellScript(spell_mark_of_the_faceless_periodic_aura);
|
||||
@@ -668,5 +581,4 @@ void AddSC_boss_vezax()
|
||||
new achievement_smell_saronite();
|
||||
new achievement_shadowdodger();
|
||||
|
||||
new go_ulduar_pure_saronite_deposit();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,6 @@ enum IgnisSpellData
|
||||
|
||||
enum IgnisNPCs
|
||||
{
|
||||
BOSS_IGNIS = 33118,
|
||||
NPC_IRON_CONSTRUCT = 33121,
|
||||
NPC_SCORCHED_GROUND = 33123,
|
||||
NPC_WATER_TRIGGER = 22515,
|
||||
@@ -78,155 +77,130 @@ enum eEvents
|
||||
EVENT_GRAB,
|
||||
};
|
||||
|
||||
class npc_ulduar_iron_construct : public CreatureScript
|
||||
struct npc_ulduar_iron_construct : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_ulduar_iron_construct() : CreatureScript("npc_ulduar_iron_construct") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
npc_ulduar_iron_construct(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_iron_constructAI>(pCreature);
|
||||
me->CastSpell(me, 38757, true);
|
||||
}
|
||||
|
||||
struct npc_ulduar_iron_constructAI : public ScriptedAI
|
||||
uint16 timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
npc_ulduar_iron_constructAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
me->CastSpell(me, 38757, true);
|
||||
}
|
||||
timer = 1000;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
uint16 timer;
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->CastSpell(me, 38757, true);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_ACTIVATE_CONSTRUCT)
|
||||
{
|
||||
timer = 1000;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->CastSpell(me, 38757, true);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_ACTIVATE_CONSTRUCT)
|
||||
{
|
||||
me->RemoveAura(38757);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
{
|
||||
ignis->CastSpell(ignis, SPELL_STRENGTH_OF_THE_CREATOR, true);
|
||||
AttackStart(ignis->GetVictim());
|
||||
DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
else if (spell->Id == SPELL_HEAT_BUFF)
|
||||
{
|
||||
if (Aura* heat = me->GetAura(SPELL_HEAT_BUFF))
|
||||
me->RemoveAura(38757);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = instance->GetCreature(BOSS_IGNIS))
|
||||
{
|
||||
if (heat->GetStackAmount() >= 10)
|
||||
ignis->CastSpell(ignis, SPELL_STRENGTH_OF_THE_CREATOR, true);
|
||||
AttackStart(ignis->GetVictim());
|
||||
DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
else if (spell->Id == SPELL_HEAT_BUFF)
|
||||
{
|
||||
if (Aura* heat = me->GetAura(SPELL_HEAT_BUFF))
|
||||
{
|
||||
if (heat->GetStackAmount() >= 10)
|
||||
{
|
||||
if (heat->GetStackAmount() > 10)
|
||||
{
|
||||
if (heat->GetStackAmount() > 10)
|
||||
{
|
||||
heat->ModStackAmount(-1);
|
||||
}
|
||||
me->CastSpell(me, SPELL_MOLTEN, true);
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
heat->ModStackAmount(-1);
|
||||
}
|
||||
me->CastSpell(me, SPELL_MOLTEN, true);
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (damage >= RAID_MODE(3000U, 5000U) && me->GetAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_BRITTLE, me)))
|
||||
{
|
||||
me->CastSpell(me, SPELL_SHATTER, true);
|
||||
Unit::Kill(attacker, me);
|
||||
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
ignis->AI()->SetData(1337, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_IGNIS)))
|
||||
ignis->RemoveAuraFromStack(SPELL_STRENGTH_OF_THE_CREATOR);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (timer <= diff)
|
||||
{
|
||||
timer = 1000;
|
||||
if (Aura* a = me->GetAura(SPELL_MOLTEN))
|
||||
if (me->FindNearestCreature(NPC_WATER_TRIGGER, 18.0f, true))
|
||||
{
|
||||
me->RemoveAura(a);
|
||||
me->CastSpell(me, SPELL_BRITTLE, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_ignis : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ignis() : CreatureScript("boss_ignis") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return GetUlduarAI<boss_ignisAI>(pCreature);
|
||||
}
|
||||
|
||||
struct boss_ignisAI : public ScriptedAI
|
||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
boss_ignisAI(Creature* pCreature) : ScriptedAI(pCreature) { }
|
||||
|
||||
EventMap events;
|
||||
uint8 counter;
|
||||
bool bShattered;
|
||||
uint32 lastShatterMSTime;
|
||||
|
||||
void Reset() override
|
||||
if (damage >= RAID_MODE(3000U, 5000U) && me->GetAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_BRITTLE, me)))
|
||||
{
|
||||
events.Reset();
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
counter = 0;
|
||||
bShattered = false;
|
||||
lastShatterMSTime = 0;
|
||||
me->CastSpell(me, SPELL_SHATTER, true);
|
||||
Unit::Kill(attacker, me);
|
||||
|
||||
if (InstanceScript* m_pInstance = me->GetInstanceScript())
|
||||
{
|
||||
m_pInstance->SetData(TYPE_IGNIS, NOT_STARTED);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
}
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = instance->GetCreature(BOSS_IGNIS))
|
||||
ignis->AI()->SetData(1337, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* ignis = instance->GetCreature(BOSS_IGNIS))
|
||||
ignis->RemoveAuraFromStack(SPELL_STRENGTH_OF_THE_CREATOR);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (timer <= diff)
|
||||
{
|
||||
me->setActive(true);
|
||||
timer = 1000;
|
||||
if (Aura* a = me->GetAura(SPELL_MOLTEN))
|
||||
if (me->FindNearestCreature(NPC_WATER_TRIGGER, 18.0f, true))
|
||||
{
|
||||
me->RemoveAura(a);
|
||||
me->CastSpell(me, SPELL_BRITTLE, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
timer -= diff;
|
||||
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
};
|
||||
|
||||
struct boss_ignis : public BossAI
|
||||
{
|
||||
boss_ignis(Creature* pCreature) : BossAI(pCreature, BOSS_IGNIS) { }
|
||||
|
||||
uint8 counter;
|
||||
bool bShattered;
|
||||
uint32 lastShatterMSTime;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
counter = 0;
|
||||
bShattered = false;
|
||||
lastShatterMSTime = 0;
|
||||
|
||||
if (instance)
|
||||
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->setActive(true);
|
||||
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr )
|
||||
{
|
||||
if (!(*itr)->IsAlive())
|
||||
@@ -240,185 +214,183 @@ public:
|
||||
(*itr)->CastSpell((*itr), 38757, true);
|
||||
}
|
||||
|
||||
bShattered = false;
|
||||
lastShatterMSTime = 0;
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_ACTIVATE_CONSTRUCT, RAID_MODE(40s, 30s));
|
||||
events.ScheduleEvent(EVENT_SPELL_SCORCH, 10s);
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAME_JETS, 32s);
|
||||
events.ScheduleEvent(EVENT_GRAB, 25s);
|
||||
bShattered = false;
|
||||
lastShatterMSTime = 0;
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_ACTIVATE_CONSTRUCT, RAID_MODE(40s, 30s));
|
||||
events.ScheduleEvent(EVENT_SPELL_SCORCH, 10s);
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAME_JETS, 32s);
|
||||
events.ScheduleEvent(EVENT_GRAB, 25s);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
|
||||
if (InstanceScript* m_pInstance = me->GetInstanceScript())
|
||||
{
|
||||
m_pInstance->SetData(TYPE_IGNIS, IN_PROGRESS);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
}
|
||||
if (instance)
|
||||
{
|
||||
instance->SetBossState(BOSS_IGNIS, IN_PROGRESS);
|
||||
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_STOKIN_THE_FURNACE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 /*value*/) override
|
||||
{
|
||||
if (id == 1337)
|
||||
{
|
||||
if (lastShatterMSTime)
|
||||
if (getMSTimeDiff(lastShatterMSTime, GameTime::GetGameTimeMS().count()) <= 5000)
|
||||
bShattered = true;
|
||||
|
||||
lastShatterMSTime = GameTime::GetGameTimeMS().count();
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
if (id == 1337)
|
||||
return (bShattered ? 1 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
_JustReachedHome();
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->IsPlayer())
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
for (std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr)
|
||||
if ((*itr)->IsAlive() && (*itr)->IsInCombat())
|
||||
Unit::Kill(*itr, *itr);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
||||
{
|
||||
if (caster && spell->Id == SPELL_GRAB_CONTROL_2)
|
||||
{
|
||||
//caster->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
me->CastSpell(caster, SPELL_SLAG_POT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f)
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 /*value*/) override
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
if (id == 1337)
|
||||
{
|
||||
if (lastShatterMSTime)
|
||||
if (getMSTimeDiff(lastShatterMSTime, GameTime::GetGameTimeMS().count()) <= 5000)
|
||||
bShattered = true;
|
||||
|
||||
lastShatterMSTime = GameTime::GetGameTimeMS().count();
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
if (id == 1337)
|
||||
return (bShattered ? 1 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->IsPlayer())
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
me->GetInstanceScript()->SetData(TYPE_IGNIS, DONE);
|
||||
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
for( std::list<Creature*>::iterator itr = icl.begin(); itr != icl.end(); ++itr )
|
||||
if ((*itr)->IsAlive() && (*itr)->IsInCombat())
|
||||
Unit::Kill(*itr, *itr);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
||||
{
|
||||
if (caster && spell->Id == SPELL_GRAB_CONTROL_2)
|
||||
{
|
||||
//caster->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
me->CastSpell(caster, SPELL_SLAG_POT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetPositionX() < 490.0f || me->GetPositionX() > 690.0f || me->GetPositionY() < 130.0f || me->GetPositionY() > 410.0f )
|
||||
{
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case 0:
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_ACTIVATE_CONSTRUCT:
|
||||
Talk(SAY_SUMMON);
|
||||
me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false);
|
||||
if (++counter >= 20)
|
||||
{
|
||||
Talk(SAY_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
case EVENT_ACTIVATE_CONSTRUCT:
|
||||
Talk(SAY_SUMMON);
|
||||
me->CastCustomSpell(SPELL_ACTIVATE_CONSTRUCT, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false);
|
||||
if (++counter >= 20)
|
||||
}
|
||||
events.Repeat(RAID_MODE(40s, 30s));
|
||||
break;
|
||||
case EVENT_SPELL_SCORCH:
|
||||
Talk(SAY_SCORCH);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(true);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->CastSpell(me->GetVictim(), SPELL_SCORCH, false);
|
||||
events.Repeat(20s);
|
||||
events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3s);
|
||||
break;
|
||||
case EVENT_ENABLE_ROTATE:
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
break;
|
||||
case EVENT_SPELL_FLAME_JETS:
|
||||
Talk(EMOTE_JETS);
|
||||
me->CastSpell(me->GetVictim(), SPELL_FLAME_JETS, false);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
case EVENT_GRAB:
|
||||
{
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
|
||||
GuidVector playerGUIDs;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
Player* temp = nullptr;
|
||||
|
||||
for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
|
||||
{
|
||||
Talk(SAY_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
}
|
||||
events.Repeat(RAID_MODE(40s, 30s));
|
||||
break;
|
||||
case EVENT_SPELL_SCORCH:
|
||||
Talk(SAY_SCORCH);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(true);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->CastSpell(me->GetVictim(), SPELL_SCORCH, false);
|
||||
events.Repeat(20s);
|
||||
events.RescheduleEvent(EVENT_ENABLE_ROTATE, 3s);
|
||||
break;
|
||||
case EVENT_ENABLE_ROTATE:
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
break;
|
||||
case EVENT_SPELL_FLAME_JETS:
|
||||
Talk(EMOTE_JETS);
|
||||
me->CastSpell(me->GetVictim(), SPELL_FLAME_JETS, false);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
case EVENT_GRAB:
|
||||
{
|
||||
std::list<Creature*> icl;
|
||||
me->GetCreaturesWithEntryInRange(icl, 300.0f, NPC_IRON_CONSTRUCT);
|
||||
|
||||
GuidVector playerGUIDs;
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
Player* temp = nullptr;
|
||||
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
temp = itr->GetSource();
|
||||
if (!temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f)
|
||||
continue;
|
||||
if (me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID())
|
||||
continue;
|
||||
bool found = false;
|
||||
for (std::list<Creature*>::iterator iterator = icl.begin(); iterator != icl.end(); ++iterator)
|
||||
{
|
||||
temp = itr->GetSource();
|
||||
if (!temp->IsAlive() || temp->GetExactDist2d(me) > 90.0f )
|
||||
continue;
|
||||
if (me->GetVictim() && temp->GetGUID() == me->GetVictim()->GetGUID())
|
||||
continue;
|
||||
bool found = false;
|
||||
for (std::list<Creature*>::iterator iterator = icl.begin(); iterator != icl.end(); ++iterator)
|
||||
if ((*iterator)->GetVictim() && (*iterator)->GetVictim()->GetGUID() == temp->GetGUID())
|
||||
{
|
||||
if ((*iterator)->GetVictim() && (*iterator)->GetVictim()->GetGUID() == temp->GetGUID())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
playerGUIDs.push_back(temp->GetGUID());
|
||||
}
|
||||
|
||||
if (!playerGUIDs.empty())
|
||||
{
|
||||
int8 pos = urand(0, playerGUIDs.size() - 1);
|
||||
if (Player* pTarget = ObjectAccessor::GetPlayer(*me, playerGUIDs.at(pos)))
|
||||
{
|
||||
Talk(SAY_SLAG_POT);
|
||||
me->CastSpell(pTarget, SPELL_GRAB, false);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
events.Repeat(24s);
|
||||
events.DelayEvents(6s);
|
||||
if (!found)
|
||||
playerGUIDs.push_back(temp->GetGUID());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
if (!playerGUIDs.empty())
|
||||
{
|
||||
int8 pos = urand(0, playerGUIDs.size() - 1);
|
||||
if (Player* pTarget = ObjectAccessor::GetPlayer(*me, playerGUIDs.at(pos)))
|
||||
{
|
||||
Talk(SAY_SLAG_POT);
|
||||
me->CastSpell(pTarget, SPELL_GRAB, false);
|
||||
}
|
||||
}
|
||||
|
||||
events.Repeat(24s);
|
||||
events.DelayEvents(6s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
}
|
||||
};
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
BossAI::EnterEvadeMode(why);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ignis_scorch_aura : public AuraScript
|
||||
@@ -541,8 +513,8 @@ public:
|
||||
|
||||
void AddSC_boss_ignis()
|
||||
{
|
||||
new boss_ignis();
|
||||
new npc_ulduar_iron_construct();
|
||||
RegisterUlduarCreatureAI(boss_ignis);
|
||||
RegisterUlduarCreatureAI(npc_ulduar_iron_construct);
|
||||
RegisterSpellScript(spell_ignis_scorch_aura);
|
||||
RegisterSpellScript(spell_ignis_grab_initial);
|
||||
RegisterSpellScript(spell_ignis_slag_pot_aura);
|
||||
|
||||
@@ -117,34 +117,19 @@ enum Misc
|
||||
DATA_KOLOGARN_ARMS_ACHIEV = 57,
|
||||
};
|
||||
|
||||
class boss_kologarn : public CreatureScript
|
||||
struct boss_kologarn : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_kologarn() : CreatureScript("boss_kologarn") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
boss_kologarn(Creature* creature) : BossAI(creature, BOSS_KOLOGARN), vehicle(me->GetVehicleKit()), breathReady(false)
|
||||
{
|
||||
return GetUlduarAI<boss_kologarnAI>(pCreature);
|
||||
assert(vehicle);
|
||||
me->SetStandState(UNIT_STAND_STATE_SUBMERGED);
|
||||
}
|
||||
|
||||
struct boss_kologarnAI : public ScriptedAI
|
||||
{
|
||||
boss_kologarnAI(Creature* pCreature) : ScriptedAI(pCreature), vehicle(me->GetVehicleKit()), summons(me), breathReady(false)
|
||||
{
|
||||
m_pInstance = me->GetInstanceScript();
|
||||
assert(vehicle);
|
||||
me->SetStandState(UNIT_STAND_STATE_SUBMERGED);
|
||||
}
|
||||
Vehicle* vehicle;
|
||||
ObjectGuid _left, _right;
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
|
||||
Vehicle* vehicle;
|
||||
ObjectGuid _left, _right;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
bool _looksAchievement, breathReady;
|
||||
uint8 _rubbleAchievement;
|
||||
bool _looksAchievement, breathReady;
|
||||
uint8 _rubbleAchievement;
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
@@ -158,13 +143,18 @@ public:
|
||||
}
|
||||
|
||||
if (me->GetExactDist2d(who) < 30.0f)
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
BossAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (!_EnterEvadeMode(why))
|
||||
if (!CreatureAI::_EnterEvadeMode(why))
|
||||
return;
|
||||
if (instance && instance->GetBossState(BOSS_KOLOGARN) != DONE)
|
||||
{
|
||||
instance->SetBossState(BOSS_KOLOGARN, NOT_STARTED);
|
||||
instance->SaveToDB();
|
||||
}
|
||||
Reset();
|
||||
me->setActive(false);
|
||||
}
|
||||
@@ -214,15 +204,12 @@ public:
|
||||
me->SetDisableGravity(true);
|
||||
me->DisableRotate(true);
|
||||
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
_Reset();
|
||||
|
||||
if (m_pInstance)
|
||||
if (instance)
|
||||
{
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, NOT_STARTED);
|
||||
|
||||
// Open the door inside Kologarn chamber
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
if (GameObject* door = instance->GetGameObject(DATA_KOLOGARN_DOORS))
|
||||
door->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
@@ -240,8 +227,8 @@ public:
|
||||
if (param == DATA_KOLOGARN_RUBBLE_ACHIEV)
|
||||
{
|
||||
// Means arm died
|
||||
if (m_pInstance && (!_left || !_right))
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_DISARMED_CRITERIA);
|
||||
if (instance && (!_left || !_right))
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_DISARMED_CRITERIA);
|
||||
|
||||
++_rubbleAchievement;
|
||||
}
|
||||
@@ -267,12 +254,12 @@ public:
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
if (cr->GetEntry() != NPC_LEFT_ARM && cr->GetEntry() != NPC_RIGHT_ARM)
|
||||
summons.Summon(cr);
|
||||
BossAI::JustSummoned(cr);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* cr) override
|
||||
{
|
||||
if (m_pInstance->GetData(TYPE_KOLOGARN) > NOT_STARTED)
|
||||
if (instance->GetBossState(BOSS_KOLOGARN) > NOT_STARTED)
|
||||
return;
|
||||
|
||||
if (cr->GetEntry() == NPC_LEFT_ARM)
|
||||
@@ -290,17 +277,15 @@ public:
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
_JustDied();
|
||||
me->StopMoving();
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, DONE);
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (m_pInstance)
|
||||
if (instance)
|
||||
{
|
||||
// Open the door inside Kologarn chamber
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
if (GameObject* door = instance->GetGameObject(DATA_KOLOGARN_DOORS))
|
||||
door->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
@@ -333,7 +318,7 @@ public:
|
||||
|
||||
void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override
|
||||
{
|
||||
if (!me->IsAlive() || m_pInstance->GetData(TYPE_KOLOGARN) != IN_PROGRESS)
|
||||
if (!me->IsAlive() || instance->GetBossState(BOSS_KOLOGARN) != IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!apply)
|
||||
@@ -375,8 +360,8 @@ public:
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, IN_PROGRESS);
|
||||
if (instance)
|
||||
instance->SetBossState(BOSS_KOLOGARN, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SMASH, 8s);
|
||||
events.ScheduleEvent(EVENT_SWEEP, 17s);
|
||||
@@ -389,9 +374,9 @@ public:
|
||||
me->setActive(true);
|
||||
|
||||
// Close the door inside Kologarn chamber
|
||||
if (m_pInstance)
|
||||
if (instance)
|
||||
{
|
||||
if (GameObject* door = m_pInstance->instance->GetGameObject(m_pInstance->GetGuidData(GO_KOLOGARN_DOORS)))
|
||||
if (GameObject* door = instance->GetGameObject(DATA_KOLOGARN_DOORS))
|
||||
{
|
||||
door->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
@@ -491,173 +476,151 @@ public:
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// also used for left arm, all functions except JustDied wont be used by left arm
|
||||
class boss_kologarn_arms : public CreatureScript
|
||||
struct boss_kologarn_arms : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
boss_kologarn_arms() : CreatureScript("boss_kologarn_arms") { }
|
||||
boss_kologarn_arms(Creature* c) : ScriptedAI(c) { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
int32 _damageDone;
|
||||
bool _combatStarted;
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override {}
|
||||
void MoveInLineOfSight(Unit*) override {}
|
||||
void AttackStart(Unit*) override {}
|
||||
void UpdateAI(uint32 /*diff*/) override {}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
return GetUlduarAI<boss_kologarn_armsAI>(pCreature);
|
||||
_combatStarted = false;
|
||||
_damageDone = 0;
|
||||
}
|
||||
|
||||
struct boss_kologarn_armsAI : public ScriptedAI
|
||||
void PassengerBoarded(Unit* /*who*/, int8 /*seatId*/, bool apply) override
|
||||
{
|
||||
boss_kologarn_armsAI(Creature* c) : ScriptedAI(c) { }
|
||||
|
||||
int32 _damageDone;
|
||||
bool _combatStarted;
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override {}
|
||||
void MoveInLineOfSight(Unit*) override {}
|
||||
void AttackStart(Unit*) override {}
|
||||
void UpdateAI(uint32 /*diff*/) override {}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_combatStarted = false;
|
||||
if (!apply)
|
||||
_damageDone = 0;
|
||||
else
|
||||
{
|
||||
//who->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
if (!_damageDone)
|
||||
_damageDone = RAID_MODE(80000, 380000);
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!_combatStarted)
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* cr = instance->GetCreature(BOSS_KOLOGARN))
|
||||
{
|
||||
_combatStarted = true;
|
||||
if (!cr->IsInCombat() && who)
|
||||
cr->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
if (_damageDone > 0)
|
||||
{
|
||||
_damageDone -= damage;
|
||||
if (_damageDone <= 0 || damage >= me->GetHealth())
|
||||
me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
float x, y, z;
|
||||
// left arm
|
||||
if (me->GetEntry() == NPC_LEFT_ARM )
|
||||
{
|
||||
x = 1776.97f;
|
||||
y = -44.8396f;
|
||||
z = 448.888f;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 1777.82f;
|
||||
y = -3.50803f;
|
||||
z = 448.888f;
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit* /*who*/, int8 /*seatId*/, bool apply) override
|
||||
if (Creature* cr = me->SummonTrigger(x, y, z, 0, 5000))
|
||||
{
|
||||
if (!apply)
|
||||
_damageDone = 0;
|
||||
else
|
||||
{
|
||||
//who->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
if (!_damageDone)
|
||||
_damageDone = RAID_MODE(80000, 380000);
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!_combatStarted)
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
{
|
||||
_combatStarted = true;
|
||||
if (!cr->IsInCombat() && who)
|
||||
cr->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
if (_damageDone > 0)
|
||||
{
|
||||
_damageDone -= damage;
|
||||
if (_damageDone <= 0 || damage >= me->GetHealth())
|
||||
me->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
float x, y, z;
|
||||
// left arm
|
||||
if (me->GetEntry() == NPC_LEFT_ARM )
|
||||
{
|
||||
x = 1776.97f;
|
||||
y = -44.8396f;
|
||||
z = 448.888f;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 1777.82f;
|
||||
y = -3.50803f;
|
||||
z = 448.888f;
|
||||
}
|
||||
|
||||
if (Creature* cr = me->SummonTrigger(x, y, z, 0, 5000))
|
||||
{
|
||||
cr->CastSpell(cr, SPELL_RUBBLE_FALL, true);
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* kologarn = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
if (Creature* cr2 = kologarn->SummonCreature(NPC_RUBBLE_SUMMON, cr->GetPositionX() + irand(-5, 5), cr->GetPositionY() + irand(-5, 5), cr->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000))
|
||||
{
|
||||
cr2->SetInCombatWithZone();
|
||||
if (Unit* target = SelectTargetFromPlayerList(100))
|
||||
cr2->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
cr->CastSpell(cr, SPELL_RUBBLE_FALL, true);
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
cr->AI()->DoAction(DATA_KOLOGARN_RUBBLE_ACHIEV);
|
||||
|
||||
me->ExitVehicle();
|
||||
if (Creature* kologarn = me->GetInstanceScript()->GetCreature(BOSS_KOLOGARN))
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
if (Creature* cr2 = kologarn->SummonCreature(NPC_RUBBLE_SUMMON, cr->GetPositionX() + irand(-5, 5), cr->GetPositionY() + irand(-5, 5), cr->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000))
|
||||
{
|
||||
cr2->SetInCombatWithZone();
|
||||
if (Unit* target = SelectTargetFromPlayerList(100))
|
||||
cr2->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
if (Creature* cr = me->GetInstanceScript()->GetCreature(BOSS_KOLOGARN))
|
||||
cr->AI()->DoAction(DATA_KOLOGARN_RUBBLE_ACHIEV);
|
||||
|
||||
me->ExitVehicle();
|
||||
}
|
||||
};
|
||||
|
||||
class boss_kologarn_eyebeam : public CreatureScript
|
||||
struct boss_kologarn_eyebeam : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
boss_kologarn_eyebeam() : CreatureScript("boss_kologarn_eyebeam") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
boss_kologarn_eyebeam(Creature* c) : ScriptedAI(c), _timer(1), _damaged(false)
|
||||
{
|
||||
return GetUlduarAI<boss_kologarn_eyebeamAI>(pCreature);
|
||||
m_pInstance = (InstanceScript*)c->GetInstanceScript();
|
||||
}
|
||||
struct boss_kologarn_eyebeamAI : public ScriptedAI
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
uint32 _timer;
|
||||
bool _damaged;
|
||||
|
||||
void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
boss_kologarn_eyebeamAI(Creature* c) : ScriptedAI(c), _timer(1), _damaged(false)
|
||||
if (damage > 0 && !_damaged && me->GetInstanceScript())
|
||||
{
|
||||
m_pInstance = (InstanceScript*)c->GetInstanceScript();
|
||||
_damaged = true;
|
||||
if (Creature* cr = me->GetInstanceScript()->GetCreature(BOSS_KOLOGARN))
|
||||
cr->AI()->DoAction(DATA_KOLOGARN_LOOKS_ACHIEV);
|
||||
}
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* summoner) override
|
||||
{
|
||||
if (!summoner)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InstanceScript* m_pInstance;
|
||||
uint32 _timer;
|
||||
bool _damaged;
|
||||
|
||||
void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
// Should only work on playable characters
|
||||
if (Player* player = summoner->ToPlayer())
|
||||
{
|
||||
if (damage > 0 && !_damaged && me->GetInstanceScript())
|
||||
me->Attack(player, false);
|
||||
me->GetMotionMaster()->MoveChase(player);
|
||||
|
||||
if (Creature* cr = m_pInstance->GetCreature(BOSS_KOLOGARN))
|
||||
{
|
||||
_damaged = true;
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_KOLOGARN)))
|
||||
cr->AI()->DoAction(DATA_KOLOGARN_LOOKS_ACHIEV);
|
||||
me->CastSpell(cr, me->GetEntry() == NPC_EYE_LEFT ? SPELL_FOCUSED_EYEBEAM_LEFT : SPELL_FOCUSED_EYEBEAM_RIGHT, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* summoner) override
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (_timer)
|
||||
{
|
||||
if (!summoner)
|
||||
_timer += diff;
|
||||
if (_timer >= 2000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Should only work on playable characters
|
||||
if (Player* player = summoner->ToPlayer())
|
||||
{
|
||||
me->Attack(player, false);
|
||||
me->GetMotionMaster()->MoveChase(player);
|
||||
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(TYPE_KOLOGARN)))
|
||||
{
|
||||
me->CastSpell(cr, me->GetEntry() == NPC_EYE_LEFT ? SPELL_FOCUSED_EYEBEAM_LEFT : SPELL_FOCUSED_EYEBEAM_RIGHT, true);
|
||||
}
|
||||
me->CastSpell(me, SPELL_FOCUSED_EYEBEAM, true);
|
||||
_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (_timer)
|
||||
{
|
||||
_timer += diff;
|
||||
if (_timer >= 2000)
|
||||
{
|
||||
me->CastSpell(me, SPELL_FOCUSED_EYEBEAM, true);
|
||||
_timer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class spell_kologarn_focused_eyebeam : public SpellScript
|
||||
@@ -867,7 +830,7 @@ public:
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
if (Creature* cr = instance->GetCreature(BOSS_KOLOGARN))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_LOOKS_ACHIEV);
|
||||
|
||||
return false;
|
||||
@@ -883,7 +846,7 @@ public:
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
if (Creature* cr = instance->GetCreature(BOSS_KOLOGARN))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_RUBBLE_ACHIEV);
|
||||
|
||||
return false;
|
||||
@@ -899,7 +862,7 @@ public:
|
||||
{
|
||||
if (target)
|
||||
if (InstanceScript* instance = target->GetInstanceScript())
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*target, instance->GetGuidData(TYPE_KOLOGARN)))
|
||||
if (Creature* cr = instance->GetCreature(BOSS_KOLOGARN))
|
||||
return cr->AI()->GetData(DATA_KOLOGARN_ARMS_ACHIEV);
|
||||
|
||||
return false;
|
||||
@@ -909,9 +872,9 @@ public:
|
||||
void AddSC_boss_kologarn()
|
||||
{
|
||||
// Npcs
|
||||
new boss_kologarn();
|
||||
new boss_kologarn_arms();
|
||||
new boss_kologarn_eyebeam();
|
||||
RegisterUlduarCreatureAI(boss_kologarn);
|
||||
RegisterUlduarCreatureAI(boss_kologarn_arms);
|
||||
RegisterUlduarCreatureAI(boss_kologarn_eyebeam);
|
||||
RegisterUlduarCreatureAI(boss_kologarn_pit_kill_bunny);
|
||||
|
||||
// Spells
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -300,56 +300,148 @@ private:
|
||||
uint8 _counter;
|
||||
};
|
||||
|
||||
class npc_ulduar_storm_tempered_keeper : public CreatureScript
|
||||
struct npc_ulduar_storm_tempered_keeper : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_ulduar_storm_tempered_keeper() : CreatureScript("npc_ulduar_storm_tempered_keeper") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
npc_ulduar_storm_tempered_keeper(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_storm_tempered_keeperAI>(creature);
|
||||
otherGUID.Clear();
|
||||
}
|
||||
|
||||
struct npc_ulduar_storm_tempered_keeperAI : public ScriptedAI
|
||||
EventMap events;
|
||||
ObjectGuid otherGUID;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
npc_ulduar_storm_tempered_keeperAI(Creature* creature) : ScriptedAI(creature)
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(1, 2s); // checking Separation Anxiety, Charged Sphere
|
||||
events.ScheduleEvent(2, 5s, 8s); // Forked Lightning
|
||||
events.ScheduleEvent(3, (me->GetEntry() == 33722 ? 20s : 50s)); // Summon Charged Sphere
|
||||
if (Creature* c = me->FindNearestCreature((me->GetEntry() == 33722 ? 33699 : 33722), 30.0f, true))
|
||||
otherGUID = c->GetGUID();
|
||||
else
|
||||
me->CastSpell(me, 63630, true); // Vengeful Surge
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID))
|
||||
c->CastSpell(c, 63630, true); // Vengeful Surge
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* s) override
|
||||
{
|
||||
if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID))
|
||||
s->GetMotionMaster()->MoveFollow(c, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
otherGUID.Clear();
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID))
|
||||
if (c->IsAlive() && me->GetExactDist2d(c) > 45.0f)
|
||||
me->CastSpell(me, 63539, true);
|
||||
if (Creature* c = me->FindNearestCreature(33715, 2.0f, true))
|
||||
if (c->IsSummon())
|
||||
if (c->ToTempSummon()->GetSummonerGUID() != me->GetGUID())
|
||||
me->CastSpell(me, 63528, true);
|
||||
events.Repeat(2s);
|
||||
break;
|
||||
case 2:
|
||||
me->CastSpell(me->GetVictim(), 63541, false);
|
||||
events.Repeat(10s, 14s);
|
||||
break;
|
||||
case 3:
|
||||
if (!me->HasAura(63630))
|
||||
me->CastSpell(me, 63527, false);
|
||||
events.Repeat(1min);
|
||||
break;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
ObjectGuid otherGUID;
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
void Reset() override
|
||||
struct npc_ulduar_arachnopod_destroyer : public ScriptedAI
|
||||
{
|
||||
npc_ulduar_arachnopod_destroyer(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
_spawnedMechanic = false;
|
||||
me->ApplySpellImmune(0, IMMUNITY_ID, 64919, true); // Ice Nova from Ice Turret
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
bool _spawnedMechanic;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(1, 5s, 8s); // Flame Spray
|
||||
events.ScheduleEvent(2, 3s, 6s); // Machine Gun
|
||||
events.ScheduleEvent(3, 1s); // Charged Leap
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit* p, int8 /*seat*/, bool /*apply*/) override
|
||||
{
|
||||
me->SetFaction(p->GetFaction());
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!_spawnedMechanic && me->HealthBelowPctDamaged(20, damage))
|
||||
{
|
||||
events.Reset();
|
||||
_spawnedMechanic = true;
|
||||
if (Creature* c = me->SummonCreature(34184, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN, 0))
|
||||
c->AI()->AttackStart(me->GetVictim());
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->CombatStop(true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetFaction(FACTION_PREY);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
|
||||
me->CastSpell(me, 64770, true);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (me->GetFaction() == FACTION_MONSTER_2)
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (me->GetFaction() == FACTION_MONSTER_2)
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
void OnCharmed(bool /*apply*/) override {}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (me->GetFaction() != FACTION_MONSTER_2)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(1, 2s); // checking Separation Anxiety, Charged Sphere
|
||||
events.ScheduleEvent(2, 5s, 8s); // Forked Lightning
|
||||
events.ScheduleEvent(3, (me->GetEntry() == 33722 ? 20s : 50s)); // Summon Charged Sphere
|
||||
if (Creature* c = me->FindNearestCreature((me->GetEntry() == 33722 ? 33699 : 33722), 30.0f, true))
|
||||
otherGUID = c->GetGUID();
|
||||
else
|
||||
me->CastSpell(me, 63630, true); // Vengeful Surge
|
||||
if (me->IsAlive() && (me->GetExactDist2dSq(2058.0f, 42.0f) < 25.0f * 25.0f || me->GetExactDist2dSq(2203.0f, 292.0f) < 25.0f * 25.0f || me->GetExactDist2dSq(2125.0f, 170.0f) > 160.0f * 160.0f))
|
||||
Unit::Kill(me, me, false);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID))
|
||||
c->CastSpell(c, 63630, true); // Vengeful Surge
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* s) override
|
||||
{
|
||||
if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID))
|
||||
s->GetMotionMaster()->MoveFollow(c, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
else
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
@@ -364,144 +456,30 @@ public:
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (Creature* c = ObjectAccessor::GetCreature(*me, otherGUID))
|
||||
if (c->IsAlive() && me->GetExactDist2d(c) > 45.0f)
|
||||
me->CastSpell(me, 63539, true);
|
||||
if (Creature* c = me->FindNearestCreature(33715, 2.0f, true))
|
||||
if (c->IsSummon())
|
||||
if (c->ToTempSummon()->GetSummonerGUID() != me->GetGUID())
|
||||
me->CastSpell(me, 63528, true);
|
||||
events.Repeat(2s);
|
||||
me->CastSpell(me->GetVictim(), SPELL_FLAME_SPRAY, false);
|
||||
events.Repeat(15s, 25s);
|
||||
break;
|
||||
case 2:
|
||||
me->CastSpell(me->GetVictim(), 63541, false);
|
||||
events.Repeat(10s, 14s);
|
||||
me->CastSpell(me->GetVictim(), SPELL_MACHINE_GUN, false);
|
||||
events.Repeat(10s, 15s);
|
||||
break;
|
||||
case 3:
|
||||
if (!me->HasAura(63630))
|
||||
me->CastSpell(me, 63527, false);
|
||||
events.Repeat(1min);
|
||||
{
|
||||
float dist = me->GetDistance(me->GetVictim());
|
||||
if (dist > 10.0f && dist < 40.0f)
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), 64779, false);
|
||||
events.Repeat(25s);
|
||||
}
|
||||
else
|
||||
events.Repeat(3s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_ulduar_arachnopod_destroyer : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ulduar_arachnopod_destroyer() : CreatureScript("npc_ulduar_arachnopod_destroyer") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetUlduarAI<npc_ulduar_arachnopod_destroyerAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_ulduar_arachnopod_destroyerAI : public ScriptedAI
|
||||
{
|
||||
npc_ulduar_arachnopod_destroyerAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
_spawnedMechanic = false;
|
||||
me->ApplySpellImmune(0, IMMUNITY_ID, 64919, true); // Ice Nova from Ice Turret
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
bool _spawnedMechanic;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(1, 5s, 8s); // Flame Spray
|
||||
events.ScheduleEvent(2, 3s, 6s); // Machine Gun
|
||||
events.ScheduleEvent(3, 1s); // Charged Leap
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit* p, int8 /*seat*/, bool /*apply*/) override
|
||||
{
|
||||
me->SetFaction(p->GetFaction());
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!_spawnedMechanic && me->HealthBelowPctDamaged(20, damage))
|
||||
{
|
||||
_spawnedMechanic = true;
|
||||
if (Creature* c = me->SummonCreature(34184, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN, 0))
|
||||
c->AI()->AttackStart(me->GetVictim());
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->CombatStop(true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetFaction(FACTION_PREY);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
|
||||
me->CastSpell(me, 64770, true);
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (me->GetFaction() == FACTION_MONSTER_2)
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (me->GetFaction() == FACTION_MONSTER_2)
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
void OnCharmed(bool /*apply*/) override {}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (me->GetFaction() != FACTION_MONSTER_2)
|
||||
{
|
||||
if (me->IsAlive() && (me->GetExactDist2dSq(2058.0f, 42.0f) < 25.0f * 25.0f || me->GetExactDist2dSq(2203.0f, 292.0f) < 25.0f * 25.0f || me->GetExactDist2dSq(2125.0f, 170.0f) > 160.0f * 160.0f))
|
||||
Unit::Kill(me, me, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
me->CastSpell(me->GetVictim(), SPELL_FLAME_SPRAY, false);
|
||||
events.Repeat(15s, 25s);
|
||||
break;
|
||||
case 2:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MACHINE_GUN, false);
|
||||
events.Repeat(10s, 15s);
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
float dist = me->GetDistance(me->GetVictim());
|
||||
if (dist > 10.0f && dist < 40.0f)
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), 64779, false);
|
||||
events.Repeat(25s);
|
||||
}
|
||||
else
|
||||
events.Repeat(3s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_ulduar_arachnopod_damaged_aura : public AuraScript
|
||||
@@ -571,8 +549,8 @@ void AddSC_ulduar()
|
||||
new npc_ulduar_keeper();
|
||||
RegisterSpellScript(spell_ulduar_energy_sap_aura);
|
||||
RegisterUlduarCreatureAI(npc_ulduar_snow_mound);
|
||||
new npc_ulduar_storm_tempered_keeper();
|
||||
new npc_ulduar_arachnopod_destroyer();
|
||||
RegisterUlduarCreatureAI(npc_ulduar_storm_tempered_keeper);
|
||||
RegisterUlduarCreatureAI(npc_ulduar_arachnopod_destroyer);
|
||||
RegisterSpellScript(spell_ulduar_arachnopod_damaged_aura);
|
||||
new AreaTrigger_at_celestial_planetarium_enterance();
|
||||
RegisterCreatureAI(npc_salvaged_siege_engine);
|
||||
|
||||
@@ -25,31 +25,38 @@
|
||||
|
||||
#define UlduarScriptName "instance_ulduar"
|
||||
|
||||
enum UlduarEncounters
|
||||
enum UlduarBossIds
|
||||
{
|
||||
MAX_ENCOUNTER = 15,
|
||||
|
||||
TYPE_LEVIATHAN = 0,
|
||||
TYPE_IGNIS = 1,
|
||||
TYPE_RAZORSCALE = 2,
|
||||
TYPE_XT002 = 3,
|
||||
TYPE_ASSEMBLY = 4,
|
||||
TYPE_KOLOGARN = 5,
|
||||
TYPE_AURIAYA = 6,
|
||||
TYPE_FREYA = 7,
|
||||
TYPE_HODIR = 8,
|
||||
TYPE_MIMIRON = 9,
|
||||
TYPE_THORIM = 10,
|
||||
TYPE_VEZAX = 11,
|
||||
TYPE_YOGGSARON = 12,
|
||||
TYPE_ALGALON = 13,
|
||||
TYPE_WATCHERS = 14,
|
||||
TYPE_HODIR_HM_FAIL = 15,
|
||||
TYPE_WINTER_CACHE = 16
|
||||
// Boss IDs used by SetBossNumber/SetBossState (0-indexed)
|
||||
BOSS_LEVIATHAN = 0,
|
||||
BOSS_IGNIS = 1,
|
||||
BOSS_RAZORSCALE = 2,
|
||||
BOSS_XT002 = 3,
|
||||
BOSS_ASSEMBLY = 4,
|
||||
BOSS_KOLOGARN = 5,
|
||||
BOSS_AURIAYA = 6,
|
||||
BOSS_FREYA = 7,
|
||||
BOSS_HODIR = 8,
|
||||
BOSS_MIMIRON = 9,
|
||||
BOSS_THORIM = 10,
|
||||
BOSS_VEZAX = 11,
|
||||
BOSS_YOGGSARON = 12,
|
||||
BOSS_ALGALON = 13,
|
||||
MAX_ENCOUNTER = 14
|
||||
};
|
||||
|
||||
enum UlduarData
|
||||
{
|
||||
// Non-boss encounter data
|
||||
TYPE_WATCHERS = 14,
|
||||
TYPE_HODIR_HM_FAIL = 15,
|
||||
TYPE_WINTER_CACHE = 16,
|
||||
|
||||
// Assembly of Iron
|
||||
DATA_STEELBREAKER = 20,
|
||||
DATA_MOLGEIM = 21,
|
||||
DATA_BRUNDIR = 22,
|
||||
|
||||
// Flame Leviathan
|
||||
DATA_VEHICLE_SPAWN = 100,
|
||||
DATA_LIGHTNING_WALL1 = 101,
|
||||
@@ -57,6 +64,7 @@ enum UlduarData
|
||||
DATA_REPAIR_STATION1 = 103,
|
||||
DATA_REPAIR_STATION2 = 104,
|
||||
DATA_UNBROKEN_ACHIEVEMENT = 105,
|
||||
DATA_LEVIATHAN_DOORS = 106,
|
||||
|
||||
// Razorscales Harpoon Fire State GUIDs
|
||||
DATA_HARPOON_FIRE_STATE_1 = 200,
|
||||
@@ -64,16 +72,31 @@ enum UlduarData
|
||||
DATA_HARPOON_FIRE_STATE_3 = 202,
|
||||
DATA_HARPOON_FIRE_STATE_4 = 203,
|
||||
|
||||
// Mimiron's first vehicle (spawned by default)
|
||||
// Mimiron creatures
|
||||
DATA_MIMIRON_LEVIATHAN_MKII = 301,
|
||||
DATA_MIMIRON_VX001 = 302,
|
||||
DATA_MIMIRON_ACU = 303,
|
||||
|
||||
// Mimiron's Doors
|
||||
// Mimiron doors
|
||||
DATA_GO_MIMIRON_DOOR_1 = 311,
|
||||
DATA_GO_MIMIRON_DOOR_2 = 312,
|
||||
DATA_GO_MIMIRON_DOOR_3 = 313,
|
||||
|
||||
// Mimiron tram
|
||||
DATA_MIMIRON_TRAM = 320,
|
||||
DATA_MIMIRON_ACTIVATE_TRAM = 321,
|
||||
DATA_MIMIRON_TRAM_ROCKET_BOOSTER = 322,
|
||||
DATA_MIMIRON_CALL_TRAM_CENTER = 323,
|
||||
DATA_MIMIRON_CALL_TRAM_MIMIRON = 324,
|
||||
DATA_MIMIRON_TRAM_TURNAROUND_1 = 325,
|
||||
DATA_MIMIRON_TRAM_TURNAROUND_2 = 326,
|
||||
|
||||
// XT-002
|
||||
DATA_XT002_DOORS = 400,
|
||||
|
||||
// Kologarn
|
||||
DATA_KOLOGARN_DOORS = 410,
|
||||
|
||||
// Thorim
|
||||
DATA_THORIM_LEVER_GATE = 500,
|
||||
DATA_THORIM_LEVER = 501,
|
||||
@@ -81,15 +104,18 @@ enum UlduarData
|
||||
DATA_THORIM_FIRST_DOORS = 503,
|
||||
DATA_THORIM_SECOND_DOORS = 504,
|
||||
|
||||
// Assembly of Iron
|
||||
DATA_STEELBREAKER = 20,
|
||||
DATA_MOLGEIM = 21,
|
||||
DATA_BRUNDIR = 22,
|
||||
|
||||
// Algalon the Observer
|
||||
DATA_ALGALON_SUMMON_STATE = 600,
|
||||
DATA_DESPAWN_ALGALON = 601,
|
||||
DATA_ALGALON_DEFEATED = 602,
|
||||
DATA_SIGILDOOR_01 = 603,
|
||||
DATA_SIGILDOOR_02 = 604,
|
||||
DATA_SIGILDOOR_03 = 605,
|
||||
DATA_UNIVERSE_FLOOR_01 = 606,
|
||||
DATA_UNIVERSE_FLOOR_02 = 607,
|
||||
DATA_UNIVERSE_GLOBE = 608,
|
||||
DATA_ALGALON_TRAPDOOR = 609,
|
||||
DATA_BRANN_BRONZEBEARD_ALG = 610,
|
||||
|
||||
// Achievements
|
||||
DATA_DWARFAGEDDON = 700,
|
||||
@@ -97,10 +123,32 @@ enum UlduarData
|
||||
// Tram
|
||||
DATA_CALL_TRAM = 710,
|
||||
|
||||
// Freya elders
|
||||
DATA_ELDER_IRONBRANCH = 750,
|
||||
DATA_ELDER_STONEBARK = 751,
|
||||
DATA_ELDER_BRIGHTLEAF = 752,
|
||||
|
||||
// Yogg-Saron
|
||||
DATA_SARA = 760,
|
||||
DATA_BRAIN_OF_YOGG_SARON = 761,
|
||||
DATA_YOGG_SARON_DOORS = 762,
|
||||
|
||||
// Middle section
|
||||
DATA_ASSEMBLY_DOORS = 770,
|
||||
DATA_ARCHIVUM_DOORS = 771,
|
||||
DATA_KEEPERS_GATE = 772,
|
||||
|
||||
// Hodir chests (dynamically spawned)
|
||||
DATA_HODIR_CHEST_NORMAL = 780,
|
||||
DATA_HODIR_CHEST_HARD = 781,
|
||||
DATA_HODIR_CHEST_NORMAL_HERO = 782,
|
||||
DATA_HODIR_CHEST_HARD_HERO = 783,
|
||||
|
||||
// Mage Barrier
|
||||
DATA_MAGE_BARRIER = 800,
|
||||
DATA_BRANN_MEMOTESAY = 801,
|
||||
DATA_BRANN_EASY_MODE = 802,
|
||||
DATA_BRANN_BASE_CAMP = 803,
|
||||
};
|
||||
|
||||
enum UlduarNPCs
|
||||
|
||||
Reference in New Issue
Block a user