diff options
7 files changed, 418 insertions, 2 deletions
diff --git a/sql/updates/world/2013_08_14_00_world_occuthar_434.sql b/sql/updates/world/2013_08_14_00_world_occuthar_434.sql new file mode 100644 index 00000000000..f523a688600 --- /dev/null +++ b/sql/updates/world/2013_08_14_00_world_occuthar_434.sql @@ -0,0 +1,39 @@ +UPDATE `creature_template` SET `ScriptName`='boss_occuthar' WHERE `entry`=52363; +UPDATE `creature_template` SET `minlevel`=87,`maxlevel`=87,`exp`=3,`faction_A`=14,`faction_H`=14,`ScriptName`='npc_eyestalk',`flags_extra`=128 WHERE `entry`=52369; +UPDATE `creature_template` SET `minlevel`=87,`maxlevel`=87,`exp`=3,`faction_A`=14,`faction_H`=14,`ScriptName`='' WHERE `entry`=52389; +UPDATE `creature_template` SET `flags_extra`=128 WHERE `entry`=52368; + +UPDATE `creature_template` SET `unit_flags`=33554432 WHERE `entry`=52369; +UPDATE `creature_template` SET `unit_flags`=2048 WHERE `entry`=52389; + +DELETE FROM `creature_template_addon` WHERE `entry`=52389; +INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES +(52389, 0, 0x0, 0x1, '96995'); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (96872,96931,96932,96942,101009); +INSERT INTO `spell_script_names`(`spell_id`, `ScriptName`) VALUES +(96872 ,'spell_occuthar_focused_fire'), +(96931 ,'spell_occuthar_eyes_of_occuthar'), +(96932 ,'spell_occuthar_eyes_of_occuthar_vehicle'), +(96942 ,'spell_occuthar_occuthars_destruction'), +(101009 ,'spell_occuthar_occuthars_destruction'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=96931; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition` ,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,1,96931,0,0,31,0,3,52368,0,0,0,'',''); + +DELETE FROM `creature` WHERE `id`=52368; + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry`=52363; +INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES +(52363, 46598, 1, 0); + +DELETE FROM `vehicle_template_accessory` WHERE `entry`=52363; +INSERT INTO `vehicle_template_accessory` (`entry`, `accessory_entry`, `seat_id`, `minion`, `description`, `summontype`, `summontimer`) VALUES +(52363, 52368, 0, 1, 'Occu''thar - Eyestalk (Seat 1)', 8, 0), +(52363, 52368, 1, 1, 'Occu''thar - Eyestalk (Seat 2)', 8, 0), +(52363, 52368, 2, 1, 'Occu''thar - Eyestalk (Seat 3)', 8, 0), +(52363, 52368, 3, 1, 'Occu''thar - Eyestalk (Seat 4)', 8, 0), +(52363, 52368, 4, 1, 'Occu''thar - Eyestalk (Seat 5)', 8, 0), +(52363, 52368, 5, 1, 'Occu''thar - Eyestalk (Seat 6)', 8, 0), +(52363, 52368, 6, 1, 'Occu''thar - Eyestalk (Seat 7)', 8, 0); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index dbed7d990b5..8d155badd6d 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -102,6 +102,7 @@ void AddSC_boss_drekthar(); void AddSC_boss_galvangar(); void AddSC_boss_vanndar(); void AddSC_boss_alizabal(); //Baradin Hold +void AddSC_boss_occuthar(); void AddSC_boss_pit_lord_argaloth(); void AddSC_instance_baradin_hold(); void AddSC_blackrock_depths(); //Blackrock Depths @@ -762,6 +763,7 @@ void AddEasternKingdomsScripts() AddSC_boss_galvangar(); AddSC_boss_vanndar(); AddSC_boss_alizabal(); //Baradin Hold + AddSC_boss_occuthar(); AddSC_boss_pit_lord_argaloth(); AddSC_instance_baradin_hold(); AddSC_blackrock_depths(); //Blackrock Depths diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 08b44c933bc..0fb463f222c 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1172,7 +1172,7 @@ bool SpellInfo::NeedsExplicitUnitTarget() const bool SpellInfo::NeedsToBeTriggeredByCaster() const { - if (NeedsExplicitUnitTarget()) + if (NeedsExplicitUnitTarget() || Id == 96946 || Id == 101005) return true; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 0b1ad422a21..c6aba4853ee 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3754,6 +3754,10 @@ void SpellMgr::LoadSpellInfoCorrections() // Crashes client on pressing ESC spellInfo->AttributesEx4 &= ~SPELL_ATTR4_TRIGGERED; break; + case 96942: // Gaze of Occu'thar + case 101009: // Gaze of Occu'thar + spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_1; + break; default: break; } diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp new file mode 100644 index 00000000000..678bd884cb7 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Vehicle.h" +#include "baradin_hold.h" + +enum Spells +{ + SPELL_SEARING_SHADOWS = 96913, + SPEll_FOCUSED_FIRE_FIRST_DAMAGE = 97212, + SPEll_FOCUSED_FIRE_TRIGGER = 96872, + SPEll_FOCUSED_FIRE_VISUAL = 96886, + SPELL_FOCUSED_FIRE = 96884, + SPELL_EYES_OF_OCCUTHAR = 96920, + SPELL_GAZE_OF_OCCUTHAR = 96942, + SPELL_OCCUTHARS_DESTUCTION = 96968, + SPELL_BERSERK = 47008 +}; + +enum Events +{ + EVENT_SEARING_SHADOWS = 1, + EVENT_FOCUSED_FIRE = 2, + EVENT_EYES_OF_OCCUTHAR = 3, + EVENT_BERSERK = 4, + + EVENT_FOCUSED_FIRE_FIRST_DAMAGE = 1 +}; + +enum Misc +{ + MAX_OCCUTHAR_VEHICLE_SEATS = 7 +}; + +class boss_occuthar : public CreatureScript +{ + public: + boss_occuthar() : CreatureScript("boss_occuthar") { } + + struct boss_occutharAI : public BossAI + { + boss_occutharAI(Creature* creature) : BossAI(creature, DATA_OCCUTHAR), + _vehicle(me->GetVehicleKit()) + { + ASSERT(_vehicle); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + events.ScheduleEvent(EVENT_SEARING_SHADOWS, 35 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_FOCUSED_FIRE, 40 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_EYES_OF_OCCUTHAR, 60 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_BERSERK, 5 * MINUTE * IN_MILLISECONDS); + } + + void EnterEvadeMode() OVERRIDE + { + BossAI::EnterEvadeMode(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _DespawnAtEvade(); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + } + + void JustSummoned(Creature* summon) OVERRIDE + { + summons.Summon(summon); + + if (summon->GetEntry() == NPC_FOCUS_FIRE_DUMMY) + { + DoCast(summon, SPELL_FOCUSED_FIRE); + + for (uint8 i = 0; i < MAX_OCCUTHAR_VEHICLE_SEATS; ++i) + { + if (Unit* vehicle = _vehicle->GetPassenger(i)) + vehicle->CastSpell(summon, SPEll_FOCUSED_FIRE_VISUAL); + } + } + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SEARING_SHADOWS: + DoCastAOE(SPELL_SEARING_SHADOWS); + events.ScheduleEvent(EVENT_SEARING_SHADOWS, 25 * IN_MILLISECONDS); + break; + case EVENT_FOCUSED_FIRE: + DoCastAOE(SPEll_FOCUSED_FIRE_TRIGGER, true); + events.ScheduleEvent(EVENT_FOCUSED_FIRE, 15 * IN_MILLISECONDS); + break; + case EVENT_EYES_OF_OCCUTHAR: + DoCastAOE(SPELL_EYES_OF_OCCUTHAR); + events.RescheduleEvent(EVENT_FOCUSED_FIRE, 15 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_EYES_OF_OCCUTHAR, 60 * IN_MILLISECONDS); + break; + case EVENT_BERSERK: + DoCast(me, SPELL_BERSERK, true); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + Vehicle* _vehicle; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetBaradinHoldAI<boss_occutharAI>(creature); + } +}; + +class npc_eyestalk : public CreatureScript +{ + public: + npc_eyestalk() : CreatureScript("npc_eyestalk") { } + + struct npc_eyestalkAI : public ScriptedAI + { + npc_eyestalkAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + _damageCount = 0; + } + + void IsSummonedBy(Unit* /*summoner*/) OVERRIDE + { + // player is the spellcaster so register summon manually + if (Creature* occuthar = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_OCCUTHAR))) + occuthar->AI()->JustSummoned(me); + } + + void Reset() OVERRIDE + { + _events.Reset(); + _events.ScheduleEvent(EVENT_FOCUSED_FIRE_FIRST_DAMAGE, 0); + } + + void UpdateAI(uint32 diff) OVERRIDE + { + _events.Update(diff); + + if (_events.ExecuteEvent() == EVENT_FOCUSED_FIRE_FIRST_DAMAGE) + { + DoCastAOE(SPEll_FOCUSED_FIRE_FIRST_DAMAGE); + if (++_damageCount < 2) + _events.ScheduleEvent(EVENT_FOCUSED_FIRE_FIRST_DAMAGE, 1 * IN_MILLISECONDS); + } + } + + void EnterEvadeMode() OVERRIDE { } // Never evade + + private: + InstanceScript* _instance; + EventMap _events; + uint8 _damageCount; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetBaradinHoldAI<npc_eyestalkAI>(creature); + } +}; + +// 96872 - Focused Fire +class spell_occuthar_focused_fire : public SpellScriptLoader +{ + public: + spell_occuthar_focused_fire() : SpellScriptLoader("spell_occuthar_focused_fire") { } + + class spell_occuthar_focused_fire_SpellScript : public SpellScript + { + PrepareSpellScript(spell_occuthar_focused_fire_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_occuthar_focused_fire_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_occuthar_focused_fire_SpellScript(); + } +}; + +// ID - 96931 Eyes of Occu'thar +class spell_occuthar_eyes_of_occuthar : public SpellScriptLoader +{ + public: + spell_occuthar_eyes_of_occuthar() : SpellScriptLoader("spell_occuthar_eyes_of_occuthar") { } + + class spell_occuthar_eyes_of_occuthar_SpellScript : public SpellScript + { + PrepareSpellScript(spell_occuthar_eyes_of_occuthar_SpellScript); + + bool Validate(SpellInfo const* spellInfo) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue())) + return false; + return true; + } + + bool Load() OVERRIDE + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetCaster(), GetEffectValue(), true); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_occuthar_eyes_of_occuthar_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_occuthar_eyes_of_occuthar_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_occuthar_eyes_of_occuthar_SpellScript(); + } +}; + +// ID - 96932 Eyes of Occu'thar +class spell_occuthar_eyes_of_occuthar_vehicle : public SpellScriptLoader +{ + public: + spell_occuthar_eyes_of_occuthar_vehicle() : SpellScriptLoader("spell_occuthar_eyes_of_occuthar_vehicle") { } + + class spell_occuthar_eyes_of_occuthar_vehicle_SpellScript : public SpellScript + { + PrepareSpellScript(spell_occuthar_eyes_of_occuthar_vehicle_SpellScript); + + bool Load() OVERRIDE + { + return GetCaster()->GetInstanceScript() != NULL; + } + + void HandleScript() + { + Position pos; + GetHitUnit()->GetPosition(&pos); + + if (Creature* occuthar = ObjectAccessor::GetCreature(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_OCCUTHAR))) + { + if (Creature* creature = occuthar->SummonCreature(NPC_EYE_OF_OCCUTHAR, pos)) + creature->CastSpell(GetHitUnit(), SPELL_GAZE_OF_OCCUTHAR, false); + } + } + + void Register() OVERRIDE + { + AfterHit += SpellHitFn(spell_occuthar_eyes_of_occuthar_vehicle_SpellScript::HandleScript); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_occuthar_eyes_of_occuthar_vehicle_SpellScript(); + } +}; + +// 96942 / 101009 - Gaze of Occu'thar +class spell_occuthar_occuthars_destruction : public SpellScriptLoader +{ + public: + spell_occuthar_occuthars_destruction() : SpellScriptLoader("spell_occuthar_occuthars_destruction") { } + + class spell_occuthar_occuthars_destruction_AuraScript : public AuraScript + { + PrepareAuraScript(spell_occuthar_occuthars_destruction_AuraScript); + + bool Load() OVERRIDE + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + { + if (IsExpired()) + caster->CastSpell((Unit*)NULL, SPELL_OCCUTHARS_DESTUCTION, true, NULL, aurEff); + + caster->ToCreature()->DespawnOrUnsummon(500); + } + } + + void Register() OVERRIDE + { + OnEffectRemove += AuraEffectRemoveFn(spell_occuthar_occuthars_destruction_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_occuthar_occuthars_destruction_AuraScript(); + } +}; + +void AddSC_boss_occuthar() +{ + new boss_occuthar(); + new npc_eyestalk(); + new spell_occuthar_focused_fire(); + new spell_occuthar_eyes_of_occuthar(); + new spell_occuthar_eyes_of_occuthar_vehicle(); + new spell_occuthar_occuthars_destruction(); +} diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp index 7a005e8d97b..d69c9e4d7e6 100644 --- a/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp +++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt index bf650f7c64d..7bdcaf56523 100644 --- a/src/server/scripts/EasternKingdoms/CMakeLists.txt +++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt @@ -18,6 +18,7 @@ set(scripts_STAT_SRCS EasternKingdoms/AlteracValley/boss_vanndar.cpp EasternKingdoms/AlteracValley/alterac_valley.cpp EasternKingdoms/BaradinHold/boss_alizabal.cpp + EasternKingdoms/BaradinHold/boss_occuthar.cpp EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp EasternKingdoms/BaradinHold/instance_baradin_hold.cpp EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp |