aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/characters/2012_11_18_00_character_calendar.sql (renamed from sql/updates/characters/2012_11_11_00_character_calendar.sql)0
-rw-r--r--sql/updates/world/2012_11_18_00_world_ormorok.sql56
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp376
3 files changed, 232 insertions, 200 deletions
diff --git a/sql/updates/characters/2012_11_11_00_character_calendar.sql b/sql/updates/characters/2012_11_18_00_character_calendar.sql
index a3e7c352788..a3e7c352788 100644
--- a/sql/updates/characters/2012_11_11_00_character_calendar.sql
+++ b/sql/updates/characters/2012_11_18_00_character_calendar.sql
diff --git a/sql/updates/world/2012_11_18_00_world_ormorok.sql b/sql/updates/world/2012_11_18_00_world_ormorok.sql
new file mode 100644
index 00000000000..0ec8d13fd64
--- /dev/null
+++ b/sql/updates/world/2012_11_18_00_world_ormorok.sql
@@ -0,0 +1,56 @@
+-- Crystal Spikes - Script Effect - Spell casted by Ormorok - Triggers one summon spell in every direction
+DELETE FROM `spell_scripts` WHERE `id` IN (47958,57082);
+INSERT INTO `spell_scripts`(`id`,`command`,`datalong`,`datalong2`) VALUES
+-- Non heroic
+(47958,15,47954,1),
+(47958,15,47955,1),
+(47958,15,47956,1),
+(47958,15,47957,1),
+-- Heroic
+(57082,15,57077,1),
+(57082,15,57078,1),
+(57082,15,57080,1),
+(57082,15,57081,1);
+
+DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (47958,48016,48017) OR `spellid0` IN (47958,48016,48017);
+INSERT INTO `spelldifficulty_dbc`(`id`,`spellid0`,`spellid1`) VALUES
+(47958,47958,57082), -- Crystal Spikes
+(48016,48016,57066), -- Trample
+(48017,48017,57086); -- Frenzy
+
+-- Assign aura script for spawning Crystal Spike rows
+DELETE FROM `spell_script_names` WHERE `spell_id`=47941;
+INSERT INTO `spell_script_names`(`spell_id`,`ScriptName`) VALUES
+(47941,'spell_crystal_spike');
+
+-- Apply aura to triggers
+DELETE FROM `creature_template_addon` WHERE `entry` IN (27101,27079);
+INSERT INTO `creature_template_addon`(`entry`,`auras`) VALUES
+(27101,'47941'), -- Aura to summon the next trigger after 250ms
+(27079,'47941'); -- Aura to summon the next trigger after 250ms and visual effect
+
+-- Assign core scripts and SmartAI to trigger
+UPDATE `creature_template` SET `AIName`='',`ScriptName`='npc_crystal_spike_trigger' WHERE `entry` IN (27101,27079);
+UPDATE `creature_template` SET `AIName`='SmartAI',`ScriptName`='' WHERE `entry`=27099;
+
+-- SAI for Crystal Spike (Damage dealer)
+DELETE FROM `smart_scripts` WHERE `entryorguid`=27099 AND `source_type`=0;
+INSERT INTO `smart_scripts`(`entryorguid`,`event_type`,`action_type`,`action_param1`,`action_param2`,`target_type`,`comment`) VALUES
+(27099,54,80,2709900,2,1,'Crystal Spike - Is summoned - Call timed action list');
+
+-- Timed action list
+DELETE FROM `smart_scripts` WHERE `entryorguid`=2709900 AND `source_type`=9;
+INSERT INTO `smart_scripts`(`entryorguid`,`source_type`,`id`,`event_param1`,`event_param2`,`action_type`,`action_param1`,`action_param2`,`target_type`,`comment`) VALUES
+(2709900,9,1,2100,2100,11,47944,2,1,'Crystal Spike - Timed action list - Cast damage spell'),
+(2709900,9,2,0,0,41,0,0,1,'Crystal Spike - Timed action list - Despawn');
+
+-- Creature texts for the boss
+DELETE FROM `script_texts` WHERE `entry` BETWEEN -1576024 AND -1576020;
+
+DELETE FROM `creature_text` WHERE `entry`=26794;
+INSERT INTO `creature_text`(`entry`,`groupid`,`text`,`type`,`sound`,`comment`) VALUES
+(26794,1,'Noo!',14,13328,'ormorok SAY_AGGRO'),
+(26794,2,'Aaggh!',14,13330,'ormorok SAY_DEATH'),
+(26794,3,'Back!',14,13331,'ormorok SAY_REFLECT'),
+(26794,4,'Bleed!',14,13332,'ormorok SAY_CRYSTAL_SPIKES'),
+(26794,5,'Aaggh! Kill!',14,13329,'ormorok SAY_KILL');
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();
}