diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp | 376 |
1 files changed, 176 insertions, 200 deletions
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp index eb0b3692f01..b17494800f1 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp @@ -19,96 +19,86 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "nexus.h" +#include "SpellScript.h" enum Spells { - SPELL_CRYSTAL_SPIKES = 47958, //Don't work, using walkaround - H_SPELL_CRYSTAL_SPIKES = 57082, //Don't work, using walkaround - SPELL_CRYSTALL_SPIKE_DAMAGE = 47944, - H_SPELL_CRYSTALL_SPIKE_DAMAGE = 57067, - SPELL_CRYSTAL_SPIKE_PREVISUAL = 50442, - MOB_CRYSTAL_SPIKE = 27099, - SPELL_SPELL_REFLECTION = 47981, - SPELL_TRAMPLE = 48016, - H_SPELL_TRAMPLE = 57066, - SPELL_FRENZY = 48017, - SPELL_SUMMON_CRYSTALLINE_TANGLER = 61564, //summons npc 32665 - SPELL_ROOTS = 28858 //proper spell id is unknown + SPELL_SPELL_REFLECTION = 47981, + SPELL_TRAMPLE = 48016, + SPELL_FRENZY = 48017, + SPELL_SUMMON_CRYSTALLINE_TANGLER = 61564, + SPELL_CRYSTAL_SPIKES = 47958, }; enum Yells { - SAY_AGGRO = -1576020, - SAY_DEATH = -1576021, - SAY_REFLECT = -1576022, - SAY_CRYSTAL_SPIKES = -1576023, - SAY_KILL = -1576024 + SAY_AGGRO = 1, + SAY_DEATH = 2, + SAY_REFLECT = 3, + SAY_CRYSTAL_SPIKES = 4, + SAY_KILL = 5, }; -enum Creatures + +enum Events { - MOB_CRYSTALLINE_TANGLER = 32665 + EVENT_CRYSTAL_SPIKES = 1, + EVENT_TRAMPLE = 2, + EVENT_SPELL_REFLECTION = 3, + EVENT_CRYSTALLINE_TANGLER = 4, }; -#define SPIKE_DISTANCE 5.0f +class OrmorokTanglerPredicate +{ + public: + OrmorokTanglerPredicate(Unit* unit) : me(unit) {} + + bool operator() (WorldObject* object) const + { + return object->GetDistance2d(me) >= 5.0f; + } + + private: + Unit* me; +}; class boss_ormorok : public CreatureScript { public: boss_ormorok() : CreatureScript("boss_ormorok") { } - CreatureAI* GetAI(Creature* creature) const + struct boss_ormorokAI : public BossAI { - return new boss_ormorokAI (creature); - } + boss_ormorokAI(Creature* creature) : BossAI(creature, DATA_ORMOROK_EVENT) {} - struct boss_ormorokAI : public ScriptedAI - { - boss_ormorokAI(Creature* creature) : ScriptedAI(creature) + void EnterCombat(Unit* /*who*/) { - instance = creature->GetInstanceScript(); - } + _EnterCombat(); - InstanceScript* instance; - - bool bFrenzy; - bool bCrystalSpikes; - uint8 uiCrystalSpikesCount; - float fBaseX; - float fBaseY; - float fBaseZ; - float fBaseO; - float fSpikeXY[4][2]; - - uint32 uiCrystalSpikesTimer; - uint32 uiCrystalSpikesTimer2; - uint32 uiTrampleTimer; - uint32 uiFrenzyTimer; - uint32 uiSpellReflectionTimer; - uint32 uiSummonCrystallineTanglerTimer; - - void Reset() - { - uiCrystalSpikesTimer = 12*IN_MILLISECONDS; - uiTrampleTimer = 10*IN_MILLISECONDS; - uiSpellReflectionTimer = 30*IN_MILLISECONDS; - uiSummonCrystallineTanglerTimer = 17*IN_MILLISECONDS; - bFrenzy = false; - bCrystalSpikes = false; + events.ScheduleEvent(EVENT_CRYSTAL_SPIKES, 12000); + events.ScheduleEvent(EVENT_TRAMPLE, 10000); + events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000); + if (IsHeroic()) + events.ScheduleEvent(EVENT_CRYSTALLINE_TANGLER, 17000); + + Talk(SAY_AGGRO); if (instance) - instance->SetData(DATA_ORMOROK_EVENT, NOT_STARTED); + instance->SetData(DATA_ORMOROK_EVENT, IN_PROGRESS); } - void EnterCombat(Unit* /*who*/) + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { - DoScriptText(SAY_AGGRO, me); - - if (instance) - instance->SetData(DATA_ORMOROK_EVENT, IN_PROGRESS); + if (!frenzy && HealthBelowPct(25)) + { + DoCast(me, SPELL_FRENZY); + frenzy = true; + } } void JustDied(Unit* /*killer*/) { - DoScriptText(SAY_DEATH, me); + _JustDied(); + + Talk(SAY_DEATH); if (instance) instance->SetData(DATA_ORMOROK_EVENT, DONE); @@ -116,195 +106,181 @@ public: void KilledUnit(Unit* /*victim*/) { - DoScriptText(SAY_KILL, me); + Talk(SAY_KILL); } void UpdateAI(const uint32 diff) { if (!UpdateVictim()) - { return; - } - if (bCrystalSpikes) - { - if (uiCrystalSpikesTimer2 <= diff) - { - fSpikeXY[0][0] = fBaseX+(SPIKE_DISTANCE*uiCrystalSpikesCount* std::cos(fBaseO)); - fSpikeXY[0][1] = fBaseY+(SPIKE_DISTANCE*uiCrystalSpikesCount* std::sin(fBaseO)); - fSpikeXY[1][0] = fBaseX-(SPIKE_DISTANCE*uiCrystalSpikesCount* std::cos(fBaseO)); - fSpikeXY[1][1] = fBaseY-(SPIKE_DISTANCE*uiCrystalSpikesCount* std::sin(fBaseO)); - fSpikeXY[2][0] = fBaseX+(SPIKE_DISTANCE*uiCrystalSpikesCount* std::cos(fBaseO-(M_PI/2))); - fSpikeXY[2][1] = fBaseY+(SPIKE_DISTANCE*uiCrystalSpikesCount* std::sin(fBaseO-(M_PI/2))); - fSpikeXY[3][0] = fBaseX-(SPIKE_DISTANCE*uiCrystalSpikesCount* std::cos(fBaseO-(M_PI/2))); - fSpikeXY[3][1] = fBaseY-(SPIKE_DISTANCE*uiCrystalSpikesCount* std::sin(fBaseO-(M_PI/2))); - for (uint8 i = 0; i < 4; ++i) - me->SummonCreature(MOB_CRYSTAL_SPIKE, fSpikeXY[i][0], fSpikeXY[i][1], fBaseZ, 0, TEMPSUMMON_TIMED_DESPAWN, 7*IN_MILLISECONDS); - if (++uiCrystalSpikesCount >= 13) - bCrystalSpikes = false; - uiCrystalSpikesTimer2 = 200; - } else uiCrystalSpikesTimer2 -= diff; - } - if (!bFrenzy && HealthBelowPct(25)) - { - DoCast(me, SPELL_FRENZY); - bFrenzy = true; - } + events.Update(diff); - if (uiTrampleTimer <= diff) - { - DoCast(me, SPELL_TRAMPLE); - uiTrampleTimer = 10*IN_MILLISECONDS; - } else uiTrampleTimer -= diff; - - if (uiSpellReflectionTimer <= diff) - { - DoScriptText(SAY_REFLECT, me); - DoCast(me, SPELL_SPELL_REFLECTION); - uiSpellReflectionTimer = 30*IN_MILLISECONDS; - } else uiSpellReflectionTimer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (uiCrystalSpikesTimer <= diff) - { - DoScriptText(SAY_CRYSTAL_SPIKES, me); - bCrystalSpikes = true; - uiCrystalSpikesCount = 1; - uiCrystalSpikesTimer2 = 0; - fBaseX = me->GetPositionX(); - fBaseY = me->GetPositionY(); - fBaseZ = me->GetPositionZ(); - fBaseO = me->GetOrientation(); - uiCrystalSpikesTimer = 20*IN_MILLISECONDS; - } else uiCrystalSpikesTimer -= diff; - - if (IsHeroic() && (uiSummonCrystallineTanglerTimer <= diff)) + while (uint32 eventId = events.ExecuteEvent()) { - Creature* Crystalline_Tangler = me->SummonCreature(MOB_CRYSTALLINE_TANGLER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); - if (Crystalline_Tangler) + switch (eventId) { - Unit* target = NULL; - uint8 Healer = 0; - for (uint8 j = 1; j <= 4; j++) - { - switch (j) - { - case 1: Healer = CLASS_PRIEST; break; - case 2: Healer = CLASS_PALADIN; break; - case 3: Healer = CLASS_DRUID; break; - case 4: Healer = CLASS_SHAMAN; break; - } - std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); - for (; i != me->getThreatManager().getThreatList().end(); ++i) - { - Unit* temp = Unit::GetUnit(*me, (*i)->getUnitGuid()); - if (temp && temp->GetTypeId() == TYPEID_PLAYER && temp->getClass() == Healer) - { - target = temp; - break; - } - } - if (target) - break; - } - if (!target) - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) - { - Crystalline_Tangler->AI()->AttackStart(target); - Crystalline_Tangler->getThreatManager().addThreat(target, 1000000000.0f); - } + case EVENT_TRAMPLE: + DoCast(me, SPELL_TRAMPLE); + events.ScheduleEvent(EVENT_TRAMPLE, 10000); + break; + case EVENT_SPELL_REFLECTION: + Talk(SAY_REFLECT); + DoCast(me, SPELL_SPELL_REFLECTION); + events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000); + break; + case EVENT_CRYSTAL_SPIKES: + Talk(SAY_CRYSTAL_SPIKES); + DoCast(SPELL_CRYSTAL_SPIKES); + events.ScheduleEvent(EVENT_CRYSTAL_SPIKES, 12000); + break; + case EVENT_CRYSTALLINE_TANGLER: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, OrmorokTanglerPredicate(me))) + DoCast(target, SPELL_SUMMON_CRYSTALLINE_TANGLER); + events.ScheduleEvent(EVENT_CRYSTALLINE_TANGLER, 17000); + break; + default: + break; } - uiSummonCrystallineTanglerTimer = 17*IN_MILLISECONDS; - } else uiSummonCrystallineTanglerTimer -= diff; + } DoMeleeAttackIfReady(); } + + private: + bool frenzy; + }; + CreatureAI* GetAI(Creature* creature) const + { + return new boss_ormorokAI (creature); + } +}; + +enum CrystalSpikes +{ + NPC_CRYSTAL_SPIKE_INITIAL = 27101, + NPC_CRYSTAL_SPIKE_TRIGGER = 27079, + + DATA_COUNT = 1, + MAX_COUNT = 5, + + SPELL_CRYSTAL_SPIKE_DAMAGE = 47944, + + GO_CRYSTAL_SPIKE_TRAP = 188537, +}; + +uint32 const crystalSpikeSummon[3] = +{ + 47936, + 47942, + 47943 }; -class mob_crystal_spike : public CreatureScript +class npc_crystal_spike_trigger : public CreatureScript { public: - mob_crystal_spike() : CreatureScript("mob_crystal_spike") { } + npc_crystal_spike_trigger() : CreatureScript("npc_crystal_spike_trigger") { } - CreatureAI* GetAI(Creature* creature) const + struct npc_crystal_spike_triggerAI : public ScriptedAI { - return new mob_crystal_spikeAI (creature); - } + npc_crystal_spike_triggerAI(Creature* creature) : ScriptedAI(creature) {} - struct mob_crystal_spikeAI : public Scripted_NoMovementAI - { - mob_crystal_spikeAI(Creature* creature) : Scripted_NoMovementAI(creature) + void IsSummonedBy(Unit* owner) { - } + switch (me->GetEntry()) + { + case NPC_CRYSTAL_SPIKE_INITIAL: + _count = 0; + me->SetFacingToObject(owner); + break; + case NPC_CRYSTAL_SPIKE_TRIGGER: + if (Creature* trigger = owner->ToCreature()) + _count = trigger->AI()->GetData(DATA_COUNT) + 1; + break; + default: + _count = MAX_COUNT; + break; + } - uint32 SpellCrystalSpikeDamageTimer; - uint32 SpellCrystalSpikePrevisualTimer; + if (me->GetEntry() == NPC_CRYSTAL_SPIKE_TRIGGER) + if (GameObject* trap = me->FindNearestGameObject(GO_CRYSTAL_SPIKE_TRAP, 1.0f)) + trap->Use(me); - void Reset() + _despawntimer = 2000; + } + + uint32 GetData(uint32 type) { - SpellCrystalSpikeDamageTimer = 3700; - SpellCrystalSpikePrevisualTimer = 1*IN_MILLISECONDS; + return type == DATA_COUNT ? _count : 0; } void UpdateAI(const uint32 diff) { - if (SpellCrystalSpikePrevisualTimer <= diff) + if (_despawntimer <= diff) { - DoCast(me, SPELL_CRYSTAL_SPIKE_PREVISUAL); - SpellCrystalSpikePrevisualTimer = 10*IN_MILLISECONDS; - } else SpellCrystalSpikePrevisualTimer -= diff; + if (me->GetEntry() == NPC_CRYSTAL_SPIKE_TRIGGER) + if (GameObject* trap = me->FindNearestGameObject(GO_CRYSTAL_SPIKE_TRAP, 1.0f)) + trap->Delete(); - if (SpellCrystalSpikeDamageTimer <= diff) - { - DoCast(me, SPELL_CRYSTALL_SPIKE_DAMAGE); - SpellCrystalSpikeDamageTimer = 10*IN_MILLISECONDS; - } else SpellCrystalSpikeDamageTimer -= diff; + me->DespawnOrUnsummon(); + } + else + _despawntimer -= diff; } - }; -}; + private: + uint32 _count; + uint32 _despawntimer; -class mob_crystalline_tangler : public CreatureScript -{ -public: - mob_crystalline_tangler() : CreatureScript("mob_crystalline_tangler") { } + }; CreatureAI* GetAI(Creature* creature) const { - return new mob_crystalline_tanglerAI (creature); + return new npc_crystal_spike_triggerAI(creature); } +}; - struct mob_crystalline_tanglerAI : public ScriptedAI - { - mob_crystalline_tanglerAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 uiRootsTimer; +class spell_crystal_spike : public SpellScriptLoader +{ + public: + spell_crystal_spike() : SpellScriptLoader("spell_crystal_spike") { } - void Reset() + class spell_crystal_spike_AuraScript : public AuraScript { - uiRootsTimer = 1*IN_MILLISECONDS; - } + PrepareAuraScript(spell_crystal_spike_AuraScript); - void UpdateAI(const uint32 diff) - { - if (uiRootsTimer <= diff) + void HandlePeriodic(AuraEffect const* /*aurEff*/) { - if (me->IsWithinDist(me->getVictim(), 5.0f, false)) - { - DoCast(me->getVictim(), SPELL_ROOTS); - uiRootsTimer = 15*IN_MILLISECONDS; - } - } else uiRootsTimer -= diff; - } - }; + Unit* target = GetTarget(); + if (target->GetEntry() == NPC_CRYSTAL_SPIKE_INITIAL || target->GetEntry() == NPC_CRYSTAL_SPIKE_TRIGGER) + if (Creature* trigger = target->ToCreature()) + { + uint32 spell = target->GetEntry() == NPC_CRYSTAL_SPIKE_INITIAL ? crystalSpikeSummon[0] : crystalSpikeSummon[urand(0, 2)]; + if (trigger->AI()->GetData(DATA_COUNT) < MAX_COUNT) + trigger->CastSpell(trigger, spell, true); + } + } + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_crystal_spike_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_crystal_spike_AuraScript(); + } }; void AddSC_boss_ormorok() { new boss_ormorok(); - new mob_crystal_spike(); - new mob_crystalline_tangler(); + new npc_crystal_spike_trigger(); + new spell_crystal_spike(); } |
