diff options
4 files changed, 143 insertions, 248 deletions
diff --git a/sql/updates/world/3.3.5/2017_10_16_03_world.sql b/sql/updates/world/3.3.5/2017_10_16_03_world.sql new file mode 100644 index 00000000000..53105c9f425 --- /dev/null +++ b/sql/updates/world/3.3.5/2017_10_16_03_world.sql @@ -0,0 +1,15 @@ +-- Update boss Toravon the Ice Watcher +UPDATE `creature_template` SET `InhabitType`=11, `ScriptName`='' WHERE `entry`=38461; +UPDATE `spell_dbc` SET `Effect1`=3, `EffectImplicitTargetA1`=22, `EffectImplicitTargetB1`=15, `EffectRadiusIndex1`=28, `MaxAffectedTargets`=1 WHERE `Id`=46523; + +DELETE FROM `creature_template_addon` WHERE `entry`=38461; +INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES +(38461,0,0,0,1,0,72094); + +DELETE FROM `spell_proc` WHERE `SpellId`=71993; +INSERT INTO `spell_proc` (`SpellId`,`ProcFlags`,`HitMask`,`Cooldown`) VALUES +(71993,4,12287,4000); + +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_toravon_random_aggro'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(46523,'spell_toravon_random_aggro'); diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp index 0f785817e9b..d093bb65fa8 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp @@ -17,28 +17,26 @@ #include "ScriptMgr.h" #include "InstanceScript.h" -#include "ObjectAccessor.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "vault_of_archavon.h" enum Spells { // Toravon - SPELL_FREEZING_GROUND = 72090, // don't know cd... using 20 secs. + SPELL_FREEZING_GROUND = 72090, SPELL_FROZEN_ORB = 72091, - SPELL_WHITEOUT = 72034, // Every 38 sec. cast. (after SPELL_FROZEN_ORB) + SPELL_WHITEOUT = 72034, SPELL_FROZEN_MALLET = 71993, - // Frost Warder - SPELL_FROST_BLAST = 72123, // don't know cd... using 20 secs. - SPELL_FROZEN_MALLET_2 = 72122, - // Frozen Orb - SPELL_FROZEN_ORB_DMG = 72081, // priodic dmg aura - SPELL_FROZEN_ORB_AURA = 72067, // make visible + SPELL_FROZEN_ORB_DMG = 72081, + SPELL_FROZEN_ORB_AURA = 72067, + SPELL_RANDOM_AGGRO = 72084, - // Frozen Orb Stalker - SPELL_FROZEN_ORB_SUMMON = 72093, // summon orb + // Frost Warder + SPELL_FROST_BLAST = 72123, // don't know cd... using 20 secs. + SPELL_FROZEN_MALLET_2 = 72122 }; enum Events @@ -47,256 +45,159 @@ enum Events EVENT_FROZEN_ORB = 2, EVENT_WHITEOUT = 3, - EVENT_FROST_BLAST = 4, + EVENT_FROST_BLAST = 4 }; -enum Creatures +struct boss_toravon : public BossAI { - NPC_FROZEN_ORB = 38456 // 1 in 10 mode and 3 in 25 mode + boss_toravon(Creature* creature) : BossAI(creature, DATA_TORAVON) { } -}; + void EnterCombat(Unit* /*who*/) override + { + DoCastSelf(SPELL_FROZEN_MALLET); -class boss_toravon : public CreatureScript -{ - public: - boss_toravon() : CreatureScript("boss_toravon") { } + events.ScheduleEvent(EVENT_FROZEN_ORB, Seconds(12)); + events.ScheduleEvent(EVENT_WHITEOUT, Seconds(25)); + events.ScheduleEvent(EVENT_FREEZING_GROUND, Seconds(7)); - struct boss_toravonAI : public BossAI - { - boss_toravonAI(Creature* creature) : BossAI(creature, DATA_TORAVON) - { - } + _EnterCombat(); + } - void EnterCombat(Unit* /*who*/) override - { - DoCast(me, SPELL_FROZEN_MALLET); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - events.ScheduleEvent(EVENT_FROZEN_ORB, 11000); - events.ScheduleEvent(EVENT_WHITEOUT, 13000); - events.ScheduleEvent(EVENT_FREEZING_GROUND, 15000); + events.Update(diff); - _EnterCombat(); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void UpdateAI(uint32 diff) override + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FROZEN_ORB: - me->CastCustomSpell(SPELL_FROZEN_ORB, SPELLVALUE_MAX_TARGETS, 1, me); - events.ScheduleEvent(EVENT_FROZEN_ORB, 38000); - break; - case EVENT_WHITEOUT: - DoCast(me, SPELL_WHITEOUT); - events.ScheduleEvent(EVENT_WHITEOUT, 38000); - break; - case EVENT_FREEZING_GROUND: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) - DoCast(target, SPELL_FREEZING_GROUND); - events.ScheduleEvent(EVENT_FREEZING_GROUND, 20000); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); + case EVENT_FROZEN_ORB: + me->CastCustomSpell(SPELL_FROZEN_ORB, SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 3), me); + events.Repeat(Seconds(32)); + break; + case EVENT_WHITEOUT: + DoCastSelf(SPELL_WHITEOUT); + events.Repeat(Seconds(38)); + break; + case EVENT_FREEZING_GROUND: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) + DoCast(target, SPELL_FREEZING_GROUND); + events.Repeat(Seconds(38)); + break; + default: + break; } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetVaultOfArchavonAI<boss_toravonAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } + + DoMeleeAttackIfReady(); + } }; -/*###### -## Mob Frost Warder -######*/ -class npc_frost_warder : public CreatureScript +struct npc_frost_warder : public ScriptedAI { - public: - npc_frost_warder() : CreatureScript("npc_frost_warder") { } - - struct npc_frost_warderAI : public ScriptedAI - { - npc_frost_warderAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) override - { - DoZoneInCombat(); - - DoCast(me, SPELL_FROZEN_MALLET_2); + npc_frost_warder(Creature* creature) : ScriptedAI(creature) { } - events.ScheduleEvent(EVENT_FROST_BLAST, 5000); - } + void Reset() override + { + _events.Reset(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void EnterCombat(Unit* /*who*/) override + { + DoZoneInCombat(); - events.Update(diff); + DoCastSelf(SPELL_FROZEN_MALLET_2); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + _events.ScheduleEvent(EVENT_FROST_BLAST, 5000); + } - if (events.ExecuteEvent() == EVENT_FROST_BLAST) - { - DoCastVictim(SPELL_FROST_BLAST); - events.ScheduleEvent(EVENT_FROST_BLAST, 20000); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); - } + _events.Update(diff); - private: - EventMap events; - }; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - CreatureAI* GetAI(Creature* creature) const override + if (_events.ExecuteEvent() == EVENT_FROST_BLAST) { - return GetVaultOfArchavonAI<npc_frost_warderAI>(creature); + DoCastVictim(SPELL_FROST_BLAST); + _events.ScheduleEvent(EVENT_FROST_BLAST, 20000); } + + DoMeleeAttackIfReady(); + } + +private: + EventMap _events; }; -/*###### -## Mob Frozen Orb -######*/ -class npc_frozen_orb : public CreatureScript +struct npc_frozen_orb : public ScriptedAI { -public: - npc_frozen_orb() : CreatureScript("npc_frozen_orb") { } + npc_frozen_orb(Creature* creature) : ScriptedAI(creature) { } - struct npc_frozen_orbAI : public ScriptedAI + void IsSummonedBy(Unit* /*summoner*/) override { - npc_frozen_orbAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + DoCastSelf(SPELL_FROZEN_ORB_AURA, true); + DoCastSelf(SPELL_FROZEN_ORB_DMG, true); + DoCastSelf(SPELL_RANDOM_AGGRO, true); - void Initialize() + if (Creature* toravon = me->GetInstanceScript()->GetCreature(DATA_TORAVON)) { - done = false; - killTimer = 60000; // if after this time there is no victim -> destroy! - } - - void Reset() override - { - Initialize(); - } - - void EnterCombat(Unit* /*who*/) override - { - DoZoneInCombat(); - } - - void UpdateAI(uint32 diff) override - { - if (!done) - { - DoCast(me, SPELL_FROZEN_ORB_AURA, true); - DoCast(me, SPELL_FROZEN_ORB_DMG, true); - done = true; - } - - if (killTimer <= diff) + if (toravon->IsInCombat()) { - if (!UpdateVictim()) - me->DespawnOrUnsummon(); - killTimer = 10000; + toravon->AI()->JustSummoned(me); + me->SetInCombatWithZone(); } else - killTimer -= diff; + me->DespawnOrUnsummon(); } - - private: - uint32 killTimer; - bool done; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetVaultOfArchavonAI<npc_frozen_orbAI>(creature); } }; -/*###### -## Mob Frozen Orb Stalker -######*/ -class npc_frozen_orb_stalker : public CreatureScript +// 46523 - Random Aggro +class spell_toravon_random_aggro : public SpellScript { - public: - npc_frozen_orb_stalker() : CreatureScript("npc_frozen_orb_stalker") { } + PrepareSpellScript(spell_toravon_random_aggro); - struct npc_frozen_orb_stalkerAI : public ScriptedAI - { - npc_frozen_orb_stalkerAI(Creature* creature) : ScriptedAI(creature) - { - creature->SetVisible(false); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); - me->SetControlled(true, UNIT_STATE_ROOT); - creature->SetReactState(REACT_PASSIVE); - - instance = creature->GetInstanceScript(); - spawned = false; + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } - SetCombatMovement(false); - } + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + if (!caster->IsAIEnabled) + return; - void UpdateAI(uint32 /*diff*/) override - { - if (spawned) - return; - - spawned = true; - Unit* toravon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TORAVON)); - if (!toravon) - return; - - uint8 num_orbs = RAID_MODE(1, 3); - for (uint8 i = 0; i < num_orbs; ++i) - { - Position pos; - me->GetNearPoint(toravon, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, 10.0f, 0.0f); - me->UpdatePosition(pos); - DoCast(me, SPELL_FROZEN_ORB_SUMMON); - } - } + caster->GetThreatManager().resetAllAggro(); - private: - InstanceScript* instance; - bool spawned; - }; + if (Unit* target = caster->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1)) + caster->GetThreatManager().AddThreat(target, 1000000); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetVaultOfArchavonAI<npc_frozen_orb_stalkerAI>(creature); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_toravon_random_aggro::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; void AddSC_boss_toravon() { - new boss_toravon(); - new npc_frost_warder(); - new npc_frozen_orb(); - new npc_frozen_orb_stalker(); + RegisterVaultOfArchavonCreatureAI(boss_toravon); + RegisterVaultOfArchavonCreatureAI(npc_frost_warder); + RegisterVaultOfArchavonCreatureAI(npc_frozen_orb); + RegisterSpellScript(spell_toravon_random_aggro); } diff --git a/src/server/scripts/Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp index f399449932f..df562d81546 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp @@ -16,7 +16,6 @@ */ #include "ScriptMgr.h" -#include "Creature.h" #include "InstanceScript.h" #include "Map.h" #include "vault_of_archavon.h" @@ -28,6 +27,15 @@ 4 - Toravon the Ice Watcher event */ +ObjectData const creatureData[] = +{ + { NPC_ARCHAVON, DATA_ARCHAVON }, + { NPC_EMALON, DATA_EMALON }, + { NPC_KORALON, DATA_KORALON }, + { NPC_TORAVON, DATA_TORAVON }, + { 0, 0, } +}; + class instance_vault_of_archavon : public InstanceMapScript { public: @@ -39,42 +47,13 @@ class instance_vault_of_archavon : public InstanceMapScript { SetHeaders(DataHeader); SetBossNumber(EncounterCount); + LoadObjectData(creatureData, nullptr); ArchavonDeath = 0; EmalonDeath = 0; KoralonDeath = 0; } - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_EMALON: - EmalonGUID = creature->GetGUID(); - break; - case NPC_TORAVON: - ToravonGUID = creature->GetGUID(); - break; - default: - break; - } - } - - ObjectGuid GetGuidData(uint32 identifier) const override - { - switch (identifier) - { - case DATA_EMALON: - return EmalonGUID; - case DATA_TORAVON: - return ToravonGUID; - default: - break; - } - - return ObjectGuid::Empty; - } - bool SetBossState(uint32 type, EncounterState state) override { if (!InstanceScript::SetBossState(type, state)) @@ -127,8 +106,6 @@ class instance_vault_of_archavon : public InstanceMapScript } private: - ObjectGuid EmalonGUID; - ObjectGuid ToravonGUID; time_t ArchavonDeath; time_t EmalonDeath; time_t KoralonDeath; diff --git a/src/server/scripts/Northrend/VaultOfArchavon/vault_of_archavon.h b/src/server/scripts/Northrend/VaultOfArchavon/vault_of_archavon.h index d4f252d3715..491ef5dd82d 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/vault_of_archavon.h +++ b/src/server/scripts/Northrend/VaultOfArchavon/vault_of_archavon.h @@ -30,7 +30,7 @@ enum VAData DATA_ARCHAVON = 0, DATA_EMALON = 1, DATA_KORALON = 2, - DATA_TORAVON = 3, + DATA_TORAVON = 3 }; enum VACreatureIds @@ -44,12 +44,12 @@ enum VACreatureIds enum VAAchievementCriteriaIds { CRITERIA_EARTH_WIND_FIRE_10 = 12018, - CRITERIA_EARTH_WIND_FIRE_25 = 12019, + CRITERIA_EARTH_WIND_FIRE_25 = 12019 }; enum VAAchievementSpells { - SPELL_EARTH_WIND_FIRE_ACHIEVEMENT_CHECK = 68308, + SPELL_EARTH_WIND_FIRE_ACHIEVEMENT_CHECK = 68308 }; template <class AI, class T> @@ -58,4 +58,6 @@ inline AI* GetVaultOfArchavonAI(T* obj) return GetInstanceAI<AI>(obj, VoAScriptName); } +#define RegisterVaultOfArchavonCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetVaultOfArchavonAI) + #endif |