[NEED HELP] Scripts/ZulGurub: Bloodlord Mandokir

Trying to improve the script and can use some help. I’m too unexperienced to do it alone.

[CODE]
– Bloodlord Mandokir SQL fix by nelegalno

Bloodlord Mandokir 1-Man Solo (Death Knight) - YouTube
UPDATE script_texts SET content_default=“$N! I’m watching you!” WHERE entry=-1309018;

Bloodlord Mandokir 1-Man Solo (Death Knight) - YouTube
DELETE FROM script_texts WHERE entry=-1309024;
INSERT INTO script_texts (npc_entry,entry,content_default,content_loc1,content_loc2,content_loc3,content_loc4,content_loc5,content_loc6,content_loc7,content_loc8,sound,type,language,emote,comment) VALUES
(11382,-1309024,“Bloodlord Mandokir goes into a rage after seeing his raptor fall in battle!”,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,8413,2,0,0,“mandokir SAY_EMOTE_ENRAGE”);

[/SQL][/CODE]


/*

* 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

* 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/>.

*/


/* ScriptData

SDName: Boss_Mandokir

SD%Complete: 90

SDComment: Ohgan function needs improvements.

SDCategory: Zul'Gurub

EndScriptData */


#include "ScriptMgr.h"

#include "ScriptedCreature.h"

#include "zulgurub.h"


enum Texts

{        

     SAY_AGGRO                 = -1309015,

     SAY_DING_KILL             = -1309016,

     SAY_GRATS_JINDO             = -1309017,

     SAY_WATCH                 = -1309018,

     SAY_WATCH_WHISPER         = -1309019, // is this text for real? easter egg?

     SAY_EMOTE_ENRAGE         = -1309024, // -1309020 to -1309023 are in use

};


enum Spells

{

     SPELL_CHARGE             = 24408,

     SPELL_CLEAVE             = 7160,     // [is this correct?] shouldnt 20691 replace 7160 == Execute ( http://old.wowhead.com/spell=7160 )

     SPELL_FEAR                 = 29321,

     SPELL_WHIRLWIND             = 15589, // 15589 is triggered by 13736 ( http://old.wowhead.com/spell=15589#triggered-by )

     SPELL_MORTAL_STRIKE         = 16856,

     SPELL_ENRAGE             = 24318,

     SPELL_WATCH                 = 24314,

     SPELL_LEVEL_UP             = 24312, // 96662 for v4 ( http://www.wowpedia.org/Bloodlord_Mandokir_(tactics)#Attacks_.26_Abilities )

     SPELL_MOUNT_UP             = 23243,

     SPELL_GUILLOTINE         = 24316, // Used when charge fails


     SPELL_SUNDERARMOR         = 24317, // Used by Ohgan

};


enum Creatures

{

     NPC_OHGAN                 = 14988,

     NPC_VILEBRANCH_SPEAKER     = 11391, // When killed, Mandokir comes down

};



class boss_mandokir : public CreatureScript

{

public:


     boss_mandokir()

         : CreatureScript("boss_mandokir") {}


     struct boss_mandokirAI : public ScriptedAI

     {

         boss_mandokirAI(Creature* creature) : ScriptedAI(creature)

         {

             instance = creature->GetInstanceScript();

         }


         uint32 KillCount;

         uint32 Watch_Timer;

         uint32 TargetInRange;

         uint32 Cleave_Timer;

         uint32 Whirlwind_Timer;

         uint32 Fear_Timer;

         uint32 MortalStrike_Timer;

         uint32 Check_Timer;

         float targetX;

         float targetY;

         float targetZ;


         InstanceScript* instance;


         bool endWatch;

         bool someWatched;

         bool RaptorDead;

         bool CombatStart;

         bool SpeakerDead;


         uint64 WatchTarget;


         void Reset()

         {

             KillCount             = 0;

             Watch_Timer         = 33000;

             Cleave_Timer         = 7000;

             Whirlwind_Timer     = 20000;

             Fear_Timer             = 1000;

             MortalStrike_Timer     = 1000;

             Check_Timer         = 1000;


             targetX = 0.0f;

             targetY = 0.0f;

             targetZ = 0.0f;

             TargetInRange = 0;


             // He no longer watches anyone when he resets

             WatchTarget = 0;


             // Set back all bools

             someWatched = false;

             endWatch = false;

             RaptorDead = false;

             CombatStart = false;

             SpeakerDead = false;


         }


         void JustReachedHome()

         {

             // Cast mount once we reach home, not when we reset

             DoCast(me, SPELL_MOUNT_UP);

         }


         void KilledUnit(Unit* victim)

         {

             if (victim->GetTypeId() == TYPEID_PLAYER)

             {

                 ++KillCount;


                 if (KillCount == 3)

                 {

                     // Make Mandokir yell 'DING!' to everyone in Zul'gurub

                     DoScriptText(SAY_DING_KILL, me);


                     if (instance)

                     {

                         uint64 JindoGUID = instance->GetData64(DATA_JINDO);

                         if (JindoGUID)

                         {

                             if (Unit* jTemp = Unit::GetUnit(*me, JindoGUID))

                             {

                                 if (jTemp->isAlive())

                                     // Make Jin'do yell 'GRATS!' to everyone in Zul'gurub. (only if Jin'do is still alive)

                                     DoScriptText(SAY_GRATS_JINDO, jTemp);

                             }

                         }

                     }

                     DoCast(me, SPELL_LEVEL_UP, true);

                     KillCount = 0;

                 }

             }

         }


         void EnterCombat(Unit* /*who*/)

         {

             DoScriptText(SAY_AGGRO, me);

         }


         void UpdateAI(const uint32 diff)

         {

             if (!SpeakerDead)

             {

                 if (!me->FindNearestCreature(NPC_VILEBRANCH_SPEAKER, 100.0f, true))

                 {

                     me->GetMotionMaster()->MovePoint(0, -12196.3f, -1948.37f, 130.36f);

                     SpeakerDead = true;

                 }

             }


             if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE && SpeakerDead)

                 me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);


             if (!UpdateVictim())

                 return;


             if (me->getVictim() && me->isAlive())

             {

                 if (!CombatStart)

                 {

                     // At combat Start Mandokir is mounted so we must unmount it first

                     me->Dismount();


                     // And summon his raptor

                     me->SummonCreature(NPC_OHGAN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000);

                     CombatStart = true;

                 }


                 if (Watch_Timer <= diff)             // Every 20 Sec Mandokir will check this

                 {

                     // If someone is 'watched' and he moved (different point from the point when spell was casted) or casted a spell, we will charge that player

                     // Cast Guillotine if player is in melee range making Mandokir unable to charge that player

                     if (WatchTarget)

                     {

                         Unit* unit = Unit::GetUnit(*me, WatchTarget);


                         if (unit && (

                             targetX != unit->GetPositionX() ||

                             targetY != unit->GetPositionY() ||

                             targetZ != unit->GetPositionZ() ||

                             unit->isInCombat()))

                         {

                             if (me->IsWithinMeleeRange(unit))

                             {

                                 // Cast Guillotine since we can not charge the watched player

                                 DoCast(unit, SPELL_GUILLOTINE);

                             }

                             else

                             {

                                 DoCast(unit, SPELL_CHARGE);

                                 // Summon a player

                                 //me->SendMonsterMove(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), 0, true, 1);

                                 AttackStart(unit);

                             }

                         }

                     }

                     someWatched = false;

                     Watch_Timer = 20000;

                 } else Watch_Timer -= diff;


                 if ((Watch_Timer < 8000) && !someWatched)     // 8 sec (cast time + expire time) before the check for the watch effect mandokir will cast watch debuff on a random target

                 {

                     if (Unit* p = SelectTarget(SELECT_TARGET_RANDOM, 0))

                     {

                         DoScriptText(SAY_WATCH, me, p);

                         DoCast(p, SPELL_WATCH);

                         WatchTarget = p->GetGUID();

                         someWatched = true;

                         endWatch = true;

                     }

                 }


                 // One second before the buff expires we will store the position. If moved, we will charge, or cast Guillotine if player is in melee range.

                 if ((Watch_Timer < 1000) && endWatch)

                 {

                     Unit* unit = Unit::GetUnit(*me, WatchTarget);

                     if (unit)

                     {

                         targetX = unit->GetPositionX();

                         targetY = unit->GetPositionY();

                         targetZ = unit->GetPositionZ();

                     }

                     endWatch = false;

                 }


                 if (!someWatched)

                 {

                     // Cleave

                     if (Cleave_Timer <= diff)

                     {

                         DoCast(me->getVictim(), SPELL_CLEAVE);

                         Cleave_Timer = 7000;

                     } else Cleave_Timer -= diff;


                     // Whirlwind

                     if (Whirlwind_Timer <= diff)

                     {

                         DoCast(me, SPELL_WHIRLWIND);

                         Whirlwind_Timer = 18000;

                     } else Whirlwind_Timer -= diff;


                     // If more than 3 targets are within melee range, mandokir will cast Fear

                     if (Fear_Timer <= diff)

                     {

                         TargetInRange = 0;


                         std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();

                         for (; i != me->getThreatManager().getThreatList().end(); ++i)

                         {

                             Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid());

                             if (unit && me->IsWithinMeleeRange(unit))

                                 ++TargetInRange;

                         }


                         if (TargetInRange > 3)

                             DoCast(me->getVictim(), SPELL_FEAR);


                         Fear_Timer = 4000;

                     } else Fear_Timer -=diff;


                     // Mortal Strike if target is at or below 50% HP

                     if (me->getVictim() && me->getVictim()->HealthBelowPct(50))

                     {

                         if (MortalStrike_Timer <= diff)

                         {

                             DoCast(me->getVictim(), SPELL_MORTAL_STRIKE);

                             MortalStrike_Timer = 15000;

                         } else MortalStrike_Timer -= diff;

                     }

                 }

                 // If Ohgan is dead, Mandokir will cast Frenzy and say his enrage line

                 if (Check_Timer <= diff)

                 {

                     if (instance)

                     {

                         if (instance->GetData(DATA_OHGAN) == DONE)

                         {

                             if (!RaptorDead)

                             {

                                 // Say his enrage line once Ohgan is dead

                                 DoScriptText(SAY_EMOTE_ENRAGE, me);

                                 DoCast(me, SPELL_ENRAGE);

                                 RaptorDead = true;

                             }

                         }

                     }


                     Check_Timer = 1000;

                 } else Check_Timer -= diff;


                 DoMeleeAttackIfReady();

             }

         }

     };


     CreatureAI* GetAI(Creature* creature) const

     {

         return new boss_mandokirAI(creature);

     }

};


// Ohgan

class mob_ohgan : public CreatureScript

{

public:


     mob_ohgan()

         : CreatureScript("mob_ohgan") {}


     struct mob_ohganAI : public ScriptedAI

     {

         mob_ohganAI(Creature* creature) : ScriptedAI(creature)

         {

             instance = creature->GetInstanceScript();

         }


         uint32 SunderArmor_Timer;

         InstanceScript* instance;


         void Reset()

         {

             SunderArmor_Timer = 5000;

         }


         void EnterCombat(Unit* /*who*/) {}


         void JustDied(Unit* /*killer*/)

         {

             if (instance)

                 instance->SetData(DATA_OHGAN, DONE);

         }


         void UpdateAI (const uint32 diff)

         {

             // Return since we have no target

             if (!UpdateVictim())

                 return;


             // SunderArmor_Timer

             if (SunderArmor_Timer <= diff)

             {

                 DoCast(me->getVictim(), SPELL_SUNDERARMOR);

                 SunderArmor_Timer = urand(10000, 15000);

             } else SunderArmor_Timer -= diff;


             DoMeleeAttackIfReady();

         }

     };


     CreatureAI* GetAI(Creature* creature) const

     {

         return new mob_ohganAI(creature);

     }

};


void AddSC_boss_mandokir()

{

new boss_mandokir();

new mob_ohgan();

}

The initial discussion can be found here: Pull Request #7499: [Zul’Gurub] Bloodlord Mandokir fix by nelegalno · TrinityCore/TrinityCore · GitHub

Problems:

  1. Ohgan doesn’t atack the player once spawned

  2. Ghosts aren’t spawned

A while ago I’ve done some work on spawning him the blizzlike way and succeeded in some way. However the code might still need improvements.

What I did is that I added code for handling the Vilebranch speaker, when he is killed Mandokir will come down the stairs and become attackable. However that is all I did because of a lack of time. I will post my boss_mandokir.cpp file later when I have access to a pc since I’m posting from my phone.

Edit:

I added the code from all the files involving the mandokir encounter at the bottom of my post. However, I’m unsure if everything is still working since I wrote this about 3 months ago and I haven’t kept track with changes to the core, but I’m pretty sure you can take some parts of it to change your code to make him attackable. Regarding the spirits/ghosts, I can’t help since I haven’t had time to take a look at them.

SQL changes:

[SPOILER]DELETE FROM creature_template WHERE entry = 11391;

INSERT INTO creature_template (entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName, WDBVerified) VALUES

(‘11391’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘28254’, ‘0’, ‘0’, ‘0’, ‘Vilebranch Speaker’, ‘Vilebranch Troll Ambassador’, NULL, ‘0’, ‘61’, ‘61’, ‘0’, ‘28’, ‘28’, ‘2’, ‘1.32’, ‘1.14286’, ‘1’, ‘0’, ‘159’, ‘221’, ‘0’, ‘258’, ‘1’, ‘2000’, ‘0’, ‘1’, ‘32832’, ‘8’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘127’, ‘188’, ‘28’, ‘7’, ‘8’, ‘11391’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘13730’, ‘8599’, ‘15284’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘136’, ‘182’, ‘’, ‘1’, ‘1’, ‘1’, ‘1’, ‘1’, ‘1’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘1’, ‘708’, ‘0’, ‘0’, ‘mob_vilebranch_speaker’, ‘12340’);

[/SPOILER]

zulgurub.h

[SPOILER]/* * Copyright © 2008-2012 TrinityCore <http://www.trinitycore.org/> * Copyright © 2006-2009 ScriptDev2 <https://scriptdev2.s…urceforge.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 * 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/>. */#ifndef DEF_ZULGURUB_H#define DEF_ZULGURUB_Henum DataTypes{ MAX_ENCOUNTERS = 8, DATA_ARLOKK = 1, DATA_JEKLIK = 2, DATA_VENOXIS = 3, DATA_MARLI = 4, DATA_OHGAN = 5, DATA_THEKAL = 6, DATA_ZATH = 7, DATA_LORKHAN = 8, DATA_JINDO = 10, DATA_VILEBRANCHSPEAKER = 11, DATA_BLOODLORDMANDOKIR = 12,};#endif

[/SPOILER]

instance_zulgurub.cpp

[SPOILER]/* * Copyright © 2008-2012 TrinityCore <http://www.trinitycore.org/> * Copyright © 2006-2009 ScriptDev2 <https://scriptdev2.s…urceforge.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 * 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/>. // ScriptDataSDName: Instance_ZulGurubSD%Complete: 80SDComment: Missing reset function after killing a boss for Ohgan, Thekal.SDCategory: Zul’GurubEndScriptData /#include “ScriptPCH.h”#include "zulgurub.h"class instance_zulgurub : public InstanceMapScript{ public: instance_zulgurub() : InstanceMapScript(“instance_zulgurub”, 309) { } struct instance_zulgurub_InstanceMapScript : public InstanceScript { instance_zulgurub_InstanceMapScript(Map map) : InstanceScript(map) {} //If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too. uint32 m_auiEncounter[MAX_ENCOUNTERS]; //Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too. uint64 m_uiLorKhanGUID; uint64 m_uiZathGUID; uint64 m_uiThekalGUID; uint64 m_uiJindoGUID; uint64 m_uiBloodlordMandokirGUID; uint64 m_uiVilebranchSpeakerGUID; void Initialize() { memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); m_uiLorKhanGUID = 0; m_uiZathGUID = 0; m_uiThekalGUID = 0; m_uiJindoGUID = 0; m_uiBloodlordMandokirGUID = 0; m_uiVilebranchSpeakerGUID = 0; } bool IsEncounterInProgress() const { //not active in Zul’Gurub return false; } void OnCreatureCreate(Creature* creature) { switch (creature->GetEntry()) { case 11347: m_uiLorKhanGUID = creature->GetGUID(); break; case 11348: m_uiZathGUID = creature->GetGUID(); break; case 14509: m_uiThekalGUID = creature->GetGUID(); break; case 11380: m_uiJindoGUID = creature->GetGUID(); break; case 11391: m_uiVilebranchSpeakerGUID = creature->GetGUID(); break; case 11382: m_uiBloodlordMandokirGUID = creature->GetGUID(); break; } } void SetData(uint32 uiType, uint32 uiData) { switch (uiType) { case DATA_ARLOKK: m_auiEncounter[0] = uiData; break; case DATA_JEKLIK: m_auiEncounter[1] = uiData; break; case DATA_VENOXIS: m_auiEncounter[2] = uiData; break; case DATA_MARLI: m_auiEncounter[3] = uiData; break; case DATA_THEKAL: m_auiEncounter[4] = uiData; break; case DATA_LORKHAN: m_auiEncounter[5] = uiData; break; case DATA_ZATH: m_auiEncounter[6] = uiData; break; case DATA_OHGAN: m_auiEncounter[7] = uiData; break; } } uint32 GetData(uint32 uiType) { switch (uiType) { case DATA_ARLOKK: return m_auiEncounter[0]; case DATA_JEKLIK: return m_auiEncounter[1]; case DATA_VENOXIS: return m_auiEncounter[2]; case DATA_MARLI: return m_auiEncounter[3]; case DATA_THEKAL: return m_auiEncounter[4]; case DATA_LORKHAN: return m_auiEncounter[5]; case DATA_ZATH: return m_auiEncounter[6]; case DATA_OHGAN: return m_auiEncounter[7]; } return 0; } uint64 GetData64(uint32 uiData) { switch (uiData) { case DATA_LORKHAN: return m_uiLorKhanGUID; case DATA_ZATH: return m_uiZathGUID; case DATA_THEKAL: return m_uiThekalGUID; case DATA_JINDO: return m_uiJindoGUID; case DATA_VILEBRANCHSPEAKER: return m_uiVilebranchSpeakerGUID; case DATA_BLOODLORDMANDOKIR: return m_uiBloodlordMandokirGUID; } return 0; } }; InstanceScript* GetInstanceScript(InstanceMap* map) const { return new instance_zulgurub_InstanceMapScript(map); }};void AddSC_instance_zulgurub(){ new instance_zulgurub();}

[/SPOILER]

boss_mandokir.cpp

[SPOILER]/* * Copyright © 2008-2012 TrinityCore <http://www.trinitycore.org/> * Copyright © 2006-2009 ScriptDev2 <https://scriptdev2.s…urceforge.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 * 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/>. // ScriptDataSDName: Boss_MandokirSD%Complete: 90SDComment: Ohgan function needs improvements.SDCategory: Zul’GurubEndScriptData /#include “ScriptPCH.h”#include “zulgurub.h”// Bloodlord Mandokir’s speech table#define SAY_AGGRO -1309015#define SAY_DING_KILL -1309016#define SAY_GRATS_JINDO -1309017#define SAY_WATCH -1309018#define SAY_WATCH_WHISPER -1309019 //is this text for real? easter egg?// Bloodlord Mandokir’s abilities#define SPELL_CHARGE 24408#define SPELL_CLEAVE 7160#define SPELL_FEAR 29321#define SPELL_WHIRLWIND 15589#define SPELL_MORTAL_STRIKE 16856#define SPELL_ENRAGE 24318#define SPELL_WATCH 24314#define SPELL_LEVEL_UP 24312#define SPELL_GUILLOTINE 24316#define SPELL_MOUNT 23243// Oghan#define CREATURE_OGHAN 14988// Ohgan’s Spells#define SPELL_SUNDERARMOR 24317// Movepoint for Bloodlord Mandokir when the Vilebranch Speaker diesstatic Position MovePos[1]={ {-12197.459961f, -1949.169067f, 130.285904f, 3.768346f}};static float Orientation = 3.768346f;// Vilebranch Speakerclass mob_vilebranch_speaker : public CreatureScript{ public: mob_vilebranch_speaker() : CreatureScript(“mob_vilebranch_speaker”) { } struct mob_vilebranch_speakerAI : public ScriptedAI { mob_vilebranch_speakerAI(Creature creature) : ScriptedAI(creature) { instance = creature->GetInstanceScript(); } InstanceScript* instance; void Reset() { } void EnterCombat(Unit* /* Who /) { } void JustDied(Unit /* Killer /) { if (instance) { Creature pBloodlordMandokir = me->GetCreature(me, instance->GetData64(DATA_BLOODLORDMANDOKIR)); pBloodlordMandokir->GetMotionMaster()->MovePoint(0, MovePos[0]); pBloodlordMandokir->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); pBloodlordMandokir->SetReactState(REACT_AGGRESSIVE); } } void UpdateAI(const uint32 diff) { } }; CreatureAI GetAI(Creature* creature) const { return new mob_vilebranch_speakerAI(creature); }};// Bloodlord Mandokirclass boss_mandokir : public CreatureScript{ public: boss_mandokir() : CreatureScript(“boss_mandokir”) { } struct boss_mandokirAI : public ScriptedAI { boss_mandokirAI(Creature* creature) : ScriptedAI(creature) { instance = creature->GetInstanceScript(); } uint32 KillCount; uint32 Watch_Timer; uint32 TargetInRange; uint32 Cleave_Timer; uint32 Whirlwind_Timer; uint32 Fear_Timer; uint32 MortalStrike_Timer; uint32 Check_Timer; float targetX; float targetY; float targetZ; InstanceScript* instance; bool endWatch; bool someWatched; bool RaptorDead; bool CombatStart; uint64 WatchTarget; void Reset() { KillCount = 0; Watch_Timer = 33000; Cleave_Timer = 7000; Whirlwind_Timer = 20000; Fear_Timer = 1000; MortalStrike_Timer = 1000; Check_Timer = 1000; targetX = 0.0f; targetY = 0.0f; targetZ = 0.0f; TargetInRange = 0; WatchTarget = 0; someWatched = false; endWatch = false; RaptorDead = false; CombatStart = false; Creature* pVilebranchSpeaker = me->GetCreature(me, instance->GetData64(DATA_VILEBRANCHSPEAKER)); if (!pVilebranchSpeaker->isAlive()) { me->GetMotionMaster()->MovePoint(0, MovePos[0]); me->SetOrientation(Orientation); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED); me->SetReactState(REACT_AGGRESSIVE); } DoCast(me, SPELL_MOUNT); } void KilledUnit(Unit victim) { if (victim->GetTypeId() == TYPEID_PLAYER) { ++KillCount; if (KillCount == 3) { DoScriptText(SAY_DING_KILL, me); if (instance) { uint64 JindoGUID = instance->GetData64(DATA_JINDO); if (JindoGUID) { if (Unit* jTemp = Unit::GetUnit(me, JindoGUID)) { if (jTemp->isAlive()) DoScriptText(SAY_GRATS_JINDO, jTemp); } } } DoCast(me, SPELL_LEVEL_UP, true); KillCount = 0; } } } void EnterCombat(Unit /who/) { DoScriptText(SAY_AGGRO, me); } void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (me->getVictim() && me->isAlive()) { if (!CombatStart) { //At combat Start Mandokir is mounted so we must unmount it first me->Dismount(); //And summon his raptor me->SummonCreature(CREATURE_OGHAN, me->getVictim()->GetPositionX(), me->getVictim()->GetPositionY(), me->getVictim()->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); CombatStart = true; } if (Watch_Timer <= diff) //Every 20 Sec Mandokir will check this { if (WatchTarget) //If someone is watched and If the Position of the watched target is different from the one stored, or are attacking, mandokir will charge him { Unit* unit = Unit::GetUnit(me, WatchTarget); if (unit && ( targetX != unit->GetPositionX() || targetY != unit->GetPositionY() || targetZ != unit->GetPositionZ() || unit->isInCombat())) { if (me->IsWithinMeleeRange(unit)) { DoCast(unit, SPELL_GUILLOTINE); } else { DoCast(unit, SPELL_CHARGE); //me->SendMonsterMove(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), 0, true, 1); AttackStart(unit); } } } someWatched = false; Watch_Timer = 20000; } else Watch_Timer -= diff; if ((Watch_Timer < 8000) && !someWatched) //8 sec(cast time + expire time) before the check for the watch effect mandokir will cast watch debuff on a random target { if (Unit p = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoScriptText(SAY_WATCH, me, p); DoCast(p, SPELL_WATCH); WatchTarget = p->GetGUID(); someWatched = true; endWatch = true; } } if ((Watch_Timer < 1000) && endWatch) //1 sec before the debuf expire, store the target position { Unit* unit = Unit::GetUnit(me, WatchTarget); if (unit) { targetX = unit->GetPositionX(); targetY = unit->GetPositionY(); targetZ = unit->GetPositionZ(); } endWatch = false; } if (!someWatched) { //Cleave if (Cleave_Timer <= diff) { DoCast(me->getVictim(), SPELL_CLEAVE); Cleave_Timer = 7000; } else Cleave_Timer -= diff; //Whirlwind if (Whirlwind_Timer <= diff) { DoCast(me, SPELL_WHIRLWIND); Whirlwind_Timer = 18000; } else Whirlwind_Timer -= diff; //If more then 3 targets in melee range mandokir will cast fear if (Fear_Timer <= diff) { TargetInRange = 0; std::list<HostileReference>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { Unit* unit = Unit::GetUnit(me, (i)->getUnitGuid()); if (unit && me->IsWithinMeleeRange(unit)) ++TargetInRange; } if (TargetInRange > 3) DoCast(me->getVictim(), SPELL_FEAR); Fear_Timer = 4000; } else Fear_Timer -=diff; //Mortal Strike if target below 50% hp if (me->getVictim() && me->getVictim()->HealthBelowPct(50)) { if (MortalStrike_Timer <= diff) { DoCast(me->getVictim(), SPELL_MORTAL_STRIKE); MortalStrike_Timer = 15000; } else MortalStrike_Timer -= diff; } } //Checking if Ohgan is dead. If yes Mandokir will enrage. if (Check_Timer <= diff) { if (instance) { if (instance->GetData(DATA_OHGAN) == DONE) { if (!RaptorDead) { DoCast(me, SPELL_ENRAGE); RaptorDead = true; } } } Check_Timer = 1000; } else Check_Timer -= diff; DoMeleeAttackIfReady(); } } }; CreatureAI GetAI(Creature creature) const { return new boss_mandokirAI(creature); }};// Bloodlord Mandokir’s pet, Oghanclass mob_ohgan : public CreatureScript{ public: mob_ohgan() : CreatureScript(“mob_ohgan”) { } struct mob_ohganAI : public ScriptedAI { mob_ohganAI(Creature* creature) : ScriptedAI(creature) { instance = creature->GetInstanceScript(); } uint32 SunderArmor_Timer; InstanceScript* instance; void Reset() { SunderArmor_Timer = 5000; } void EnterCombat(Unit* /who/) {} void JustDied(Unit* /killer/) { if (instance) instance->SetData(DATA_OHGAN, DONE); } void UpdateAI (const uint32 diff) { //Return since we have no target if (!UpdateVictim()) return; //SunderArmor_Timer if (SunderArmor_Timer <= diff) { DoCast(me->getVictim(), SPELL_SUNDERARMOR); SunderArmor_Timer = urand(10000, 15000); } else SunderArmor_Timer -= diff; DoMeleeAttackIfReady(); } }; CreatureAI* GetAI(Creature* creature) const { return new mob_ohganAI(creature); }};void AddSC_boss_mandokir(){ new mob_vilebranch_speaker(); new boss_mandokir(); new mob_ohgan();}

[/SPOILER]

This is not longer needed no?