diff options
author | Vincent_Michael <Vincent_Michael@gmx.de> | 2012-12-30 03:01:12 +0100 |
---|---|---|
committer | Vincent_Michael <Vincent_Michael@gmx.de> | 2012-12-30 03:02:39 +0100 |
commit | 834f98f6bb766524ae0009407dd004a2f41e5b86 (patch) | |
tree | ed6981e909279792345bdc2c2aa9ad2e86220fbd /src | |
parent | 7ceb7c8b813a72ba8da0cbca0df031c77fc2b63a (diff) |
Core/ZulGurub: Added script for Bloodlord Mandokir
ToDo: Remove hack :P
Diffstat (limited to 'src')
3 files changed, 780 insertions, 38 deletions
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index fde47a2ccb5..8d9ccd7bdfc 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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 @@ -18,26 +17,92 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "Player.h" #include "zulgurub.h" enum Yells { - SAY_AGGRO = 0, - SAY_PLAYER_KILL = 1, - SAY_DISMOUNT_OHGAN = 2, - EMOTE_DEVASTATING_SLAM = 3, // ID - 96739 Devastating Slam - SAY_REANIMATE_OHGAN = 4, // ID - 96724 Reanimate Ohgan - EMOTE_FRENZY = 5, // ID - 96800 Frenzy - SAY_FRENZY = 6, // ID - 96800 Frenzy - SAY_DEATH = 7 + SAY_AGGRO = 0, + SAY_PLAYER_KILL = 1, + SAY_DISMOUNT_OHGAN = 2, + EMOTE_DEVASTATING_SLAM = 3, + SAY_REANIMATE_OHGAN = 4, + EMOTE_FRENZY = 5, + SAY_FRENZY = 6, + SAY_DEATH = 7 }; enum Spells { + // Bloodlord Mandokir + SPELL_BLOODLORD_AURA = 96480, + SPELL_SUMMON_OHGAN = 96717, + SPELL_REANIMATE_OHGAN = 96724, + SPELL_DECAPITATE = 96682, + SPELL_BLOODLETTING = 96776, + SPELL_BLOODLETTING_DAMAGE = 96777, + SPELL_BLOODLETTING_HEAL = 96778, + SPELL_FRENZY = 96800, + SPELL_LEVEL_UP = 96662, + SPELL_DEVASTATING_SLAM = 96740, + SPELL_DEVASTATING_SLAM_TRIGGER = 96761, + SPELL_DEVASTATING_SLAM_DAMAGE = 97385, + SPELL_SPIRIT_VENGEANCE_CANCEL = 96821, + + // Chained Spirit + SPELL_REVIVE = 96484, + + // Ohgan + SPELL_OHGAN_HEART_VISUAL = 96727, + SPELL_PERMANENT_FEIGN_DEATH = 96733, + SPELL_CLEAR_ALL = 28471, + SPELL_OHGAN_ORDERS = 96721, + SPELL_OHGAN_ORDERS_TRIGGER = 96722 }; enum Events { + // Bloodlord Mandokir + EVENT_SUMMON_OHGAN = 1, + EVENT_DECAPITATE = 2, + EVENT_BLOODLETTING = 3, + EVENT_REANIMATE_OHGAN = 4, + EVENT_REANIMATE_OHGAN_COOLDOWN = 5, + EVENT_DEVASTATING_SLAM = 6 +}; + +enum Action +{ + // Bloodlord Mandokir + ACTION_OHGAN_IS_DEATH = 1, + ACTION_START_REVIVE = 2, + + // Chained Spirit + ACTION_REVIVE = 1 +}; + +enum Misc +{ + POINT_START_REVIVE = 1, + + DATA_OHGANOT_SO_FAST = 5762, + + FACTION_NONE = 1665 +}; + +// ToDo: Need better respawn support +Position const ChainedSpiritsSpawnPos[8] = +{ + { -12330.34f, -1878.406f, 127.3196f, 3.892084f }, + { -12351.94f, -1861.51f, 127.4807f, 4.677482f }, + { -12326.71f, -1904.328f, 127.4111f, 2.75762f }, + { -12347.41f, -1917.535f, 127.3196f, 1.553343f }, + { -12378.57f, -1861.222f, 127.5416f, 5.340707f }, + { -12397.79f, -1887.731f, 127.5453f, 0.03490658f }, + { -12372.36f, -1918.844f, 127.343f, 1.151917f }, + { -12391.23f, -1905.273f, 127.3196f, 0.6108652f } }; class boss_mandokir : public CreatureScript @@ -52,17 +117,44 @@ class boss_mandokir : public CreatureScript void Reset() { + DoCastAOE(SPELL_SPIRIT_VENGEANCE_CANCEL); + _Reset(); + + for (uint8 i = 0; i < 8; ++i) + me->SummonCreature(NPC_CHAINED_SPIRIT, ChainedSpiritsSpawnPos[i]); + + _ohganotSoFast = true; + _reanimateOhganCooldown = false; + _reviveGUID = 0; } void EnterCombat(Unit* /*who*/) { _EnterCombat(); Talk(SAY_AGGRO); + + DoCastAOE(SPELL_BLOODLORD_AURA); + + if (!summons.empty()) + { + for (std::list<uint64>::const_iterator itr = summons.begin(); itr != summons.end(); ++itr) + { + if (Creature* chainedSpirit = ObjectAccessor::GetCreature(*me, *itr)) + if (chainedSpirit->GetEntry() == NPC_CHAINED_SPIRIT && chainedSpirit->AI()) + chainedSpirit->setFaction(FACTION_NONE); + } + } + + events.ScheduleEvent(EVENT_DECAPITATE, 10000); + events.ScheduleEvent(EVENT_BLOODLETTING, 15000); + events.ScheduleEvent(EVENT_SUMMON_OHGAN, 20000); + events.ScheduleEvent(EVENT_DEVASTATING_SLAM, 25000); } void JustDied(Unit* /*killer*/) { + DoCastAOE(SPELL_SPIRIT_VENGEANCE_CANCEL); _JustDied(); Talk(SAY_DEATH); } @@ -70,7 +162,70 @@ class boss_mandokir : public CreatureScript void KilledUnit(Unit* victim) { if (victim->GetTypeId() == TYPEID_PLAYER) + { Talk(SAY_PLAYER_KILL); + DoCast(SPELL_LEVEL_UP); + _reviveGUID = victim->GetGUID(); + DoAction(ACTION_START_REVIVE); + } + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (me->HealthBelowPctDamaged(20, damage) && !me->HasAura(SPELL_FRENZY)) + { + DoCast(me, SPELL_FRENZY, true); + Talk(SAY_FRENZY); + Talk(EMOTE_FRENZY); + } + } + + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_OHGAN_IS_DEATH: + events.ScheduleEvent(EVENT_REANIMATE_OHGAN, 4000); + _ohganotSoFast = false; + break; + case ACTION_START_REVIVE: + { + std::list<Creature*> creatures; + GetCreatureListWithEntryInGrid(creatures, me, NPC_CHAINED_SPIRIT, 200.0f); + creatures.remove_if(Trinity::AnyDeadUnitCheck()); + creatures.remove_if(Trinity::UnitAuraCheck(true, SPELL_OHGAN_ORDERS_TRIGGER)); + Trinity::Containers::RandomResizeList(creatures, 1); + if (creatures.empty()) + return; + + for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + if (Creature* chainedSpirit = ObjectAccessor::GetCreature(*me, (*itr)->GetGUID())) + { + chainedSpirit->AI()->SetGUID(_reviveGUID); + chainedSpirit->AI()->DoAction(ACTION_REVIVE); + _reviveGUID = 0; + } + } + break; + } + default: + break; + + } + } + + uint32 GetData(uint32 type) const + { + if (type == DATA_OHGANOT_SO_FAST) + return _ohganotSoFast; + + return 0; + } + + void SetGUID(uint64 guid, int32 type/* = 0 */) + { + _reviveGUID = guid; } void UpdateAI(uint32 const diff) @@ -82,19 +237,58 @@ class boss_mandokir : public CreatureScript if (me->HasUnitState(UNIT_STATE_CASTING)) return; - /* + while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { + case EVENT_SUMMON_OHGAN: + me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); + DoCast(me, SPELL_SUMMON_OHGAN, true); + break; + case EVENT_DECAPITATE: + DoCastAOE(SPELL_DECAPITATE); + events.ScheduleEvent(EVENT_DECAPITATE, me->HasAura(SPELL_FRENZY) ? 17500 : 35000); + break; + case EVENT_BLOODLETTING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + { + DoCast(target, SPELL_BLOODLETTING, true); + me->ClearUnitState(UNIT_STATE_CASTING); + } + events.ScheduleEvent(EVENT_BLOODLETTING, 25000); + break; + case EVENT_REANIMATE_OHGAN: + if (_reanimateOhganCooldown) + events.ScheduleEvent(EVENT_REANIMATE_OHGAN, 1000); + else + { + DoCastAOE(SPELL_REANIMATE_OHGAN); + Talk(SAY_REANIMATE_OHGAN); + // Cooldown + _reanimateOhganCooldown = true; + events.ScheduleEvent(EVENT_REANIMATE_OHGAN_COOLDOWN, 20000); + } + break; + case EVENT_REANIMATE_OHGAN_COOLDOWN: + _reanimateOhganCooldown = false; + break; + case EVENT_DEVASTATING_SLAM: + DoCastAOE(SPELL_DEVASTATING_SLAM_TRIGGER); + events.ScheduleEvent(EVENT_DEVASTATING_SLAM, 30000); + break; default: break; } } - */ DoMeleeAttackIfReady(); } + + private: + bool _ohganotSoFast; + bool _reanimateOhganCooldown; + uint64 _reviveGUID; }; CreatureAI* GetAI(Creature* creature) const @@ -103,7 +297,489 @@ class boss_mandokir : public CreatureScript } }; +class npc_ohgan : public CreatureScript +{ + public: + npc_ohgan() : CreatureScript("npc_ohgan") { } + + struct npc_ohganAI : public ScriptedAI + { + npc_ohganAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } + + void EnterCombat(Unit* /*who*/) + { + DoCastAOE(SPELL_OHGAN_ORDERS, true); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (damage >= me->GetHealth()) + { + damage = 0; + me->AttackStop(); + me->SetHealth(0); + me->SetTarget(0); + DoCast(me, SPELL_CLEAR_ALL, true); + DoCast(me, SPELL_PERMANENT_FEIGN_DEATH); + + if (Creature* mandokir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MANDOKIR))) + mandokir->AI()->DoAction(ACTION_OHGAN_IS_DEATH); + } + } + + void KilledUnit(Unit* victim) + { + if (Creature* creature = victim->ToCreature()) + { + if (creature->GetEntry() == NPC_CHAINED_SPIRIT) + DoCastAOE(SPELL_OHGAN_ORDERS, true); + } + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + + private: + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetZulGurubAI<npc_ohganAI>(creature); + } +}; + +class npc_chained_spirit : public CreatureScript +{ + public: + npc_chained_spirit() : CreatureScript("npc_chained_spirit") { } + + struct npc_chained_spiritAI : public ScriptedAI + { + npc_chained_spiritAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + me->AddUnitMovementFlag(MOVEMENTFLAG_HOVER); + me->SetReactState(REACT_PASSIVE); // correct? + } + + void Reset() + { + _revivePlayerGUID = 0; + } + + void SetGUID(uint64 guid, int32 type/* = 0 */) + { + _revivePlayerGUID = guid; + } + + void DoAction(int32 const action) + { + if (action == ACTION_REVIVE) + { + Position pos; + if (Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID)) + { + target->GetNearPoint(me, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, 5.0f, target->GetAngle(me)); + me->GetMotionMaster()->MovePoint(POINT_START_REVIVE, pos); + } + } + } + + void MovementInform(uint32 type, uint32 pointId) + { + if (type != POINT_MOTION_TYPE || !_revivePlayerGUID) + return; + + if (pointId == POINT_START_REVIVE) + { + if (Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID)) + DoCast(target, SPELL_REVIVE); + + me->DespawnOrUnsummon(2000); + } + } + + void JustDied(Unit* /*killer*/) + { + Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID); + if (!target || target->isAlive()) + return; + + if (Creature* mandokir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MANDOKIR))) + { + mandokir->GetAI()->SetGUID(target->GetGUID()); + mandokir->GetAI()->DoAction(ACTION_START_REVIVE); + } + + me->DespawnOrUnsummon(); + } + + void UpdateAI(uint32 const /*diff*/) { } + + private: + InstanceScript* _instance; + uint64 _revivePlayerGUID; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetZulGurubAI<npc_chained_spiritAI>(creature); + } +}; + +class spell_mandokir_decapitate : public SpellScriptLoader +{ + public: + spell_mandokir_decapitate() : SpellScriptLoader("spell_mandokir_decapitate") { } + + class spell_mandokir_decapitate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_decapitate_SpellScript); + + 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*/) + { + Unit* caster = GetCaster(); + if (Player* target = GetHitPlayer()) + caster->CastSpell(target, uint32(GetEffectValue()), true); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_decapitate_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mandokir_decapitate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mandokir_decapitate_SpellScript(); + } +}; + +class spell_mandokir_bloodletting : public SpellScriptLoader +{ + public: + spell_mandokir_bloodletting() : SpellScriptLoader("spell_mandokir_bloodletting") { } + + class spell_mandokir_bloodletting_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mandokir_bloodletting_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_BLOODLETTING_DAMAGE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_BLOODLETTING_HEAL)) + return false; + return true; + } + + void HandleEffectPeriodic(AuraEffect const* aurEff) + { + Unit* target = GetTarget(); + Unit* caster = GetCaster(); + if (!caster) + return; + + int32 damage = std::max<int32>(7500, target->CountPctFromCurHealth(aurEff->GetAmount())); + + caster->CastCustomSpell(target, SPELL_BLOODLETTING_DAMAGE, &damage, 0, 0, true); + target->CastCustomSpell(caster, SPELL_BLOODLETTING_HEAL, &damage, 0, 0, true); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mandokir_bloodletting_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mandokir_bloodletting_AuraScript(); + } +}; + +class spell_mandokir_spirit_vengeance_cancel : public SpellScriptLoader +{ + public: + spell_mandokir_spirit_vengeance_cancel() : SpellScriptLoader("spell_mandokir_spirit_vengeance_cancel") { } + + class spell_mandokir_spirit_vengeance_cancel_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_spirit_vengeance_cancel_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Player* target = GetHitPlayer()) + target->RemoveAura(uint32(GetEffectValue())); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_mandokir_spirit_vengeance_cancel_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_mandokir_spirit_vengeance_cancel_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mandokir_spirit_vengeance_cancel_SpellScript(); + } +}; + +class DevastatingSlamTargetSelector : public std::unary_function<Unit *, bool> +{ + public: + DevastatingSlamTargetSelector(Creature* me, const Unit* victim) : _me(me), _victim(victim) {} + + bool operator() (WorldObject* target) + { + if (target == _victim && _me->getThreatManager().getThreatList().size() > 1) + return true; + + if (target->GetTypeId() != TYPEID_PLAYER) + return true; + + return false; + } + + Creature* _me; + Unit const* _victim; +}; + +class spell_mandokir_devastating_slam : public SpellScriptLoader +{ + public: + spell_mandokir_devastating_slam() : SpellScriptLoader("spell_mandokir_devastating_slam") { } + + class spell_mandokir_devastating_slam_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_devastating_slam_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(DevastatingSlamTargetSelector(GetCaster()->ToCreature(), GetCaster()->getVictim())); + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + float angle = 0.0f; + float x, y, z; + + if (Player* target = GetHitPlayer()) + { + caster->AttackStop(); + caster->SetOrientation(caster->GetAngle(target)); + caster->SetFacingTo(caster->GetAngle(target)); + + caster->CastSpell(caster, SPELL_DEVASTATING_SLAM, false); + + // HACK: Need better way for pos calculation + for (uint8 i = 0; i <= 50; ++i) + { + angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f); + caster->GetClosePoint(x, y, z, 4.0f, frand(-2.5f, 50.0f), angle); + + caster->CastSpell(x, y, z, SPELL_DEVASTATING_SLAM_DAMAGE, true); + } + } + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_devastating_slam_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mandokir_devastating_slam_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mandokir_devastating_slam_SpellScript(); + } +}; + +class spell_mandokir_ohgan_orders : public SpellScriptLoader +{ + public: + spell_mandokir_ohgan_orders() : SpellScriptLoader("spell_mandokir_ohgan_orders") { } + + class spell_mandokir_ohgan_orders_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_ohgan_orders_SpellScript); + + 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*/) + { + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) + caster->CastSpell(target, uint32(GetEffectValue()), true); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_ohgan_orders_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_mandokir_ohgan_orders_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mandokir_ohgan_orders_SpellScript(); + } +}; + +class spell_mandokir_ohgan_orders_trigger : public SpellScriptLoader +{ + public: + spell_mandokir_ohgan_orders_trigger() : SpellScriptLoader("spell_mandokir_ohgan_orders_trigger") { } + + class spell_mandokir_ohgan_orders_trigger_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mandokir_ohgan_orders_trigger_AuraScript); + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (Unit* caster = GetCaster()) + { + // HACK: research better way + caster->ClearUnitState(UNIT_STATE_CASTING); + caster->GetMotionMaster()->Clear(); + caster->DeleteThreatList(); + caster->AddThreat(target, 50000000.0f); + caster->TauntApply(target); + } + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_mandokir_ohgan_orders_trigger_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mandokir_ohgan_orders_trigger_AuraScript(); + } +}; + +class spell_mandokir_reanimate_ohgan : public SpellScriptLoader +{ + public: + spell_mandokir_reanimate_ohgan() : SpellScriptLoader("spell_mandokir_reanimate_ohgan") { } + + class spell_mandokir_reanimate_ohgan_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mandokir_reanimate_ohgan_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) + { + target->RemoveAura(SPELL_PERMANENT_FEIGN_DEATH); + target->CastSpell(target, SPELL_OHGAN_HEART_VISUAL, true); + target->CastSpell((Unit*)NULL, SPELL_OHGAN_ORDERS, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_mandokir_reanimate_ohgan_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mandokir_reanimate_ohgan_SpellScript(); + } +}; + +class spell_clear_all : public SpellScriptLoader +{ + public: + spell_clear_all() : SpellScriptLoader("spell_clear_all") { } + + class spell_clear_all_SpellScript : public SpellScript + { + PrepareSpellScript(spell_clear_all_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->RemoveAllAurasOnDeath(); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_clear_all_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_clear_all_SpellScript(); + } +}; + +class achievement_ohganot_so_fast : public AchievementCriteriaScript +{ + public: + achievement_ohganot_so_fast() : AchievementCriteriaScript("achievement_ohganot_so_fast") { } + + bool OnCheck(Player* /*player*/, Unit* target) + { + return target && target->GetAI()->GetData(DATA_OHGANOT_SO_FAST); + } +}; + void AddSC_boss_mandokir() { new boss_mandokir(); + new npc_ohgan(); + new npc_chained_spirit(); + new spell_mandokir_decapitate(); + new spell_mandokir_bloodletting(); + new spell_mandokir_spirit_vengeance_cancel(); + new spell_mandokir_devastating_slam(); + new spell_mandokir_ohgan_orders(); + new spell_mandokir_ohgan_orders_trigger(); + new spell_mandokir_reanimate_ohgan(); + new spell_clear_all(); + new achievement_ohganot_so_fast(); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index 953d9f392bd..f1c1444be8c 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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 @@ -20,6 +19,16 @@ #include "InstanceScript.h" #include "zulgurub.h" +DoorData const doorData[] = +{ + { GO_VENOXIS_COIL, DATA_VENOXIS, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_ARENA_DOOR_1, DATA_MANDOKIR, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_FORCEFIELD, DATA_KILNARA, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_ZANZIL_DOOR, DATA_ZANZIL, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + //{ GO_THE_CACHE_OF_MADNESS_DOOR, DATA_xxxxxxx, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } +}; + class instance_zulgurub : public InstanceMapScript { public: @@ -30,6 +39,7 @@ class instance_zulgurub : public InstanceMapScript instance_zulgurub_InstanceMapScript(Map* map) : InstanceScript(map) { SetBossNumber(EncounterCount); + LoadDoorData(doorData); venoxisGUID = 0; mandokirGUID = 0; kilnaraGUID = 0; @@ -81,6 +91,38 @@ class instance_zulgurub : public InstanceMapScript } } + void OnGameObjectCreate(GameObject* go) + { + switch (go->GetEntry()) + { + case GO_VENOXIS_COIL: + case GO_ARENA_DOOR_1: + case GO_FORCEFIELD: + case GO_ZANZIL_DOOR: + case GO_THE_CACHE_OF_MADNESS_DOOR: + AddDoor(go, true); + break; + default: + break; + } + } + + void OnGameObjectRemove(GameObject* go) + { + switch (go->GetEntry()) + { + case GO_VENOXIS_COIL: + case GO_ARENA_DOOR_1: + case GO_FORCEFIELD: + case GO_ZANZIL_DOOR: + case GO_THE_CACHE_OF_MADNESS_DOOR: + AddDoor(go, false); + break; + default: + break; + } + } + bool SetBossState(uint32 type, EncounterState state) { if (!InstanceScript::SetBossState(type, state)) diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index cdf4724dc35..e4d2d2e3902 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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 @@ -25,40 +24,66 @@ uint32 const EncounterCount = 5; enum DataTypes { - DATA_VENOXIS = 0, - DATA_MANDOKIR = 1, - DATA_KILNARA = 2, - DATA_ZANZIL = 3, - DATA_JINDO = 4, + DATA_VENOXIS = 0, + DATA_MANDOKIR = 1, + DATA_KILNARA = 2, + DATA_ZANZIL = 3, + DATA_JINDO = 4, // Cache of Madness - DATA_HAZZARAH = 5, - DATA_RENATAKI = 6, - DATA_WUSHOOLAY = 7, - DATA_GRILEK = 8, + DATA_HAZZARAH = 5, + DATA_RENATAKI = 6, + DATA_WUSHOOLAY = 7, + DATA_GRILEK = 8, - // Jin'do the Godbreaker + // Jin'do the Godbreaker DATA_JINDOR_TRIGGER, }; enum CreatureIds { - NPC_VENOXIS = 52155, - NPC_MANDOKIR = 52151, - NPC_KILNARA = 52059, - NPC_ZANZIL = 52053, - NPC_JINDO = 52148, + NPC_VENOXIS = 52155, + NPC_MANDOKIR = 52151, + NPC_KILNARA = 52059, + NPC_ZANZIL = 52053, + NPC_JINDO = 52148, // Cache of Madness - NPC_HAZZARAH = 52271, - NPC_RENATAKI = 52269, - NPC_WUSHOOLAY = 52286, - NPC_GRILEK = 52258, - - // Jin'do the Godbreaker - NPC_JINDO_TRIGGER = 52150, - NPC_SPIRIT_OF_HAKKAR = 52222, - NPC_SHADOW_OF_HAKKAR = 52650 + NPC_HAZZARAH = 52271, + NPC_RENATAKI = 52269, + NPC_WUSHOOLAY = 52286, + NPC_GRILEK = 52258, + + // Bloodlord Mandokir + NPC_CHAINED_SPIRIT = 52156, + NPC_OHGAN = 52157, + + // Jin'do the Godbreaker + NPC_JINDO_TRIGGER = 52150, + NPC_SPIRIT_OF_HAKKAR = 52222, + NPC_SHADOW_OF_HAKKAR = 52650 +}; + +enum GameObjectIds +{ + // High Priest Venoxis + GO_VENOXIS_COIL = 208844, + + // Bloodlord Mandokir + GO_ARENA_DOOR_1 = 208845, + GO_ARENA_DOOR_2 = 208847, + GO_ARENA_DOOR_3 = 208848, + GO_ARENA_DOOR_4 = 208846, + GO_ARENA_DOOR_5 = 208849, + + // High Priestess Kilnara + GO_FORCEFIELD = 180497, + + // Zanzil + GO_ZANZIL_DOOR = 208850, + + // Cache of Madness + GO_THE_CACHE_OF_MADNESS_DOOR = 208843 }; template<class AI> @@ -72,4 +97,3 @@ CreatureAI* GetZulGurubAI(Creature* creature) } #endif - |