aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent_Michael <Vincent_Michael@gmx.de>2012-12-30 03:01:12 +0100
committerVincent_Michael <Vincent_Michael@gmx.de>2012-12-30 03:02:39 +0100
commit834f98f6bb766524ae0009407dd004a2f41e5b86 (patch)
treeed6981e909279792345bdc2c2aa9ad2e86220fbd /src
parent7ceb7c8b813a72ba8da0cbca0df031c77fc2b63a (diff)
Core/ZulGurub: Added script for Bloodlord Mandokir
ToDo: Remove hack :P
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp698
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp44
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h76
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
-