Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 6th, 2012  |  syntax: Diff  |  size: 83.09 KB  |  hits: 17  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*
  2.  * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
  3.  * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2 of the License, or (at your
  8.  * option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but WITHOUT
  11.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12.  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13.  * more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program. If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19. /* ScriptData
  20. SDName: faction_champions
  21. SD%Complete: ??%
  22. SDComment: Scripts by Selector, modified by /dev/rsa
  23. SDCategory: Crusader Coliseum
  24. EndScriptData */
  25.  
  26. // Known bugs:
  27. // All - untested
  28. // Pets aren't being summoned by their masters
  29.  
  30. #include "ScriptPCH.h"
  31. #include "trial_of_the_crusader.h"
  32.  
  33. enum eYell
  34. {
  35.     SAY_GARROSH_KILL_ALLIANCE_PLAYER4 = -1649118,
  36.     SAY_VARIAN_KILL_HORDE_PLAYER4     = -1649123,
  37. };
  38.  
  39. enum eAIs
  40. {
  41.     AI_MELEE    = 0,
  42.     AI_RANGED   = 1,
  43.     AI_HEALER   = 2,
  44.     AI_PET      = 3,
  45. };
  46.  
  47. enum eSpells
  48. {
  49.     SPELL_ANTI_AOE      = 68595,
  50.     SPELL_PVP_TRINKET   = 65547,
  51. };
  52.  
  53. enum eTimers
  54. {
  55.     BASE_TIME = 1000,  // 1000 == base values, 500 == 2 times faster etc..
  56. };
  57.  
  58. class boss_toc_champion_controller : public CreatureScript
  59. {
  60. public:
  61.     boss_toc_champion_controller() : CreatureScript("boss_toc_champion_controller") { }
  62.  
  63.     CreatureAI* GetAI(Creature* creature) const
  64.     {
  65.         return new boss_toc_champion_controllerAI (creature);
  66.     }
  67.  
  68.     struct boss_toc_champion_controllerAI : public ScriptedAI
  69.     {
  70.         boss_toc_champion_controllerAI(Creature* creature) : ScriptedAI(creature), Summons(me)
  71.         {
  72.             m_instance = (InstanceScript*) creature->GetInstanceScript();
  73.         }
  74.  
  75.         InstanceScript* m_instance;
  76.         SummonList Summons;
  77.         uint32 m_uiChampionsNotStarted;
  78.         uint32 m_uiChampionsFailed;
  79.         uint32 m_uiChampionsKilled;
  80.         bool   m_bInProgress;
  81.  
  82.         void Reset()
  83.         {
  84.             m_uiChampionsNotStarted = 0;
  85.             m_uiChampionsFailed = 0;
  86.             m_uiChampionsKilled = 0;
  87.             m_bInProgress = false;
  88.         }
  89.  
  90.         std::vector<uint32> SelectChampions(Team playerTeam)
  91.         {
  92.             std::vector<uint32> vHealersEntries;
  93.             vHealersEntries.clear();
  94.             vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_DRUID_RESTORATION : NPC_ALLIANCE_DRUID_RESTORATION);
  95.             vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_PALADIN_HOLY : NPC_ALLIANCE_PALADIN_HOLY);
  96.             vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_PRIEST_DISCIPLINE : NPC_ALLIANCE_PRIEST_DISCIPLINE);
  97.             vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_SHAMAN_RESTORATION : NPC_ALLIANCE_SHAMAN_RESTORATION);
  98.  
  99.             std::vector<uint32> vOtherEntries;
  100.             vOtherEntries.clear();
  101.             vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_DEATH_KNIGHT : NPC_ALLIANCE_DEATH_KNIGHT);
  102.             vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_HUNTER : NPC_ALLIANCE_HUNTER);
  103.             vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_MAGE : NPC_ALLIANCE_MAGE);
  104.             vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_ROGUE : NPC_ALLIANCE_ROGUE);
  105.             vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARLOCK : NPC_ALLIANCE_WARLOCK);
  106.             vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR);
  107.  
  108.             uint8 healersSubtracted = 2;
  109.             if (m_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL || m_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
  110.                 healersSubtracted = 1;
  111.             for (uint8 i = 0; i < healersSubtracted; ++i)
  112.             {
  113.                 uint8 pos = urand(0, vHealersEntries.size()-1);
  114.                 switch (vHealersEntries[pos])
  115.                 {
  116.                     case NPC_ALLIANCE_DRUID_RESTORATION:
  117.                         vOtherEntries.push_back(NPC_ALLIANCE_DRUID_BALANCE);
  118.                         break;
  119.                     case NPC_HORDE_DRUID_RESTORATION:
  120.                         vOtherEntries.push_back(NPC_HORDE_DRUID_BALANCE);
  121.                         break;
  122.                     case NPC_ALLIANCE_PALADIN_HOLY:
  123.                         vOtherEntries.push_back(NPC_ALLIANCE_PALADIN_RETRIBUTION);
  124.                         break;
  125.                     case NPC_HORDE_PALADIN_HOLY:
  126.                         vOtherEntries.push_back(NPC_HORDE_PALADIN_RETRIBUTION);
  127.                         break;
  128.                     case NPC_ALLIANCE_PRIEST_DISCIPLINE:
  129.                         vOtherEntries.push_back(NPC_ALLIANCE_PRIEST_SHADOW);
  130.                         break;
  131.                     case NPC_HORDE_PRIEST_DISCIPLINE:
  132.                         vOtherEntries.push_back(NPC_HORDE_PRIEST_SHADOW);
  133.                         break;
  134.                     case NPC_ALLIANCE_SHAMAN_RESTORATION:
  135.                         vOtherEntries.push_back(NPC_ALLIANCE_SHAMAN_ENHANCEMENT);
  136.                         break;
  137.                     case NPC_HORDE_SHAMAN_RESTORATION:
  138.                         vOtherEntries.push_back(NPC_HORDE_SHAMAN_ENHANCEMENT);
  139.                         break;
  140.                 }
  141.                 vHealersEntries.erase(vHealersEntries.begin()+pos);
  142.             }
  143.  
  144.             if (m_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL || m_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
  145.                 for (uint8 i = 0; i < 4; ++i)
  146.                     vOtherEntries.erase(vOtherEntries.begin()+urand(0, vOtherEntries.size()-1));
  147.  
  148.             std::vector<uint32> vChampionEntries;
  149.             vChampionEntries.clear();
  150.             for (uint8 i = 0; i < vHealersEntries.size(); ++i)
  151.                 vChampionEntries.push_back(vHealersEntries[i]);
  152.             for (uint8 i = 0; i < vOtherEntries.size(); ++i)
  153.                 vChampionEntries.push_back(vOtherEntries[i]);
  154.  
  155.             return vChampionEntries;
  156.         }
  157.  
  158.         void SummonChampions(Team playerTeam)
  159.         {
  160.             std::vector<Position> vChampionJumpOrigin;
  161.             if (playerTeam == ALLIANCE)
  162.                 for (uint8 i = 0; i < 5; i++)
  163.                     vChampionJumpOrigin.push_back(FactionChampionLoc[i]);
  164.             else
  165.                 for (uint8 i = 5; i < 10; i++)
  166.                     vChampionJumpOrigin.push_back(FactionChampionLoc[i]);
  167.  
  168.             std::vector<Position> vChampionJumpTarget;
  169.             for (uint8 i = 10; i < 20; i++)
  170.                 vChampionJumpTarget.push_back(FactionChampionLoc[i]);
  171.             std::vector<uint32> vChampionEntries = SelectChampions(playerTeam);
  172.  
  173.             for (uint8 i = 0; i < vChampionEntries.size(); ++i)
  174.             {
  175.                 uint8 pos = urand(0, vChampionJumpTarget.size()-1);
  176.                 if (Creature* temp = me->SummonCreature(vChampionEntries[i], vChampionJumpOrigin[urand(0, vChampionJumpOrigin.size()-1)], TEMPSUMMON_MANUAL_DESPAWN))
  177.                 {
  178.                     Summons.Summon(temp);
  179.                     temp->SetReactState(REACT_PASSIVE);
  180.                     temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
  181.                     if (playerTeam == ALLIANCE)
  182.                     {
  183.                         temp->SetHomePosition(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 0);
  184.                         temp->GetMotionMaster()->MoveJump(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 20.0f, 20.0f);
  185.                         temp->SetOrientation(0);
  186.                     }
  187.                     else
  188.                     {
  189.                         temp->SetHomePosition((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 3);
  190.                         temp->GetMotionMaster()->MoveJump((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 20.0f, 20.0f);
  191.                         temp->SetOrientation(3);
  192.                     }
  193.                 }
  194.                 vChampionJumpTarget.erase(vChampionJumpTarget.begin()+pos);
  195.             }
  196.         }
  197.  
  198.         void SetData(uint32 uiType, uint32 uiData)
  199.         {
  200.             switch (uiType)
  201.             {
  202.                 case 0:
  203.                     SummonChampions((Team)uiData);
  204.                     break;
  205.                 case 1:
  206.                     for (std::list<uint64>::iterator i = Summons.begin(); i != Summons.end(); ++i)
  207.                     {
  208.                         if (Creature* temp = Unit::GetCreature(*me, *i))
  209.                         {
  210.                             temp->SetReactState(REACT_AGGRESSIVE);
  211.                             temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
  212.                         }
  213.                     }
  214.                     break;
  215.                 case 2:
  216.                     switch (uiData)
  217.                     {
  218.                         case FAIL:
  219.                             m_uiChampionsFailed++;
  220.                             if (m_uiChampionsFailed + m_uiChampionsKilled >= Summons.size())
  221.                             {
  222.                                 m_instance->SetData(TYPE_CRUSADERS, FAIL);
  223.                                 Summons.DespawnAll();
  224.                                 me->DespawnOrUnsummon();
  225.                             }
  226.                             break;
  227.                         case IN_PROGRESS:
  228.                             if (!m_bInProgress)
  229.                             {
  230.                                 m_uiChampionsNotStarted = 0;
  231.                                 m_uiChampionsFailed = 0;
  232.                                 m_uiChampionsKilled = 0;
  233.                                 m_bInProgress = true;
  234.                                 Summons.DoZoneInCombat();
  235.                                 m_instance->SetData(TYPE_CRUSADERS, IN_PROGRESS);
  236.                             }
  237.                             break;
  238.                         case DONE:
  239.                             m_uiChampionsKilled++;
  240.                             if (m_uiChampionsKilled == 1)
  241.                                 m_instance->SetData(TYPE_CRUSADERS, SPECIAL);
  242.                             else if (m_uiChampionsKilled >= Summons.size())
  243.                             {
  244.                                 if (Creature* barrent = ObjectAccessor::GetCreature(*me, m_instance->GetData64(NPC_BARRENT)))
  245.                                     barrent->SummonGameobject(RAID_MODE(GO_CRUSADERS_CACHE_10, GO_CRUSADERS_CACHE_25, GO_CRUSADERS_CACHE_10_H, GO_CRUSADERS_CACHE_25_H), ToCCommonLoc[1], 7*DAY);
  246.                                 m_instance->SetData(TYPE_CRUSADERS, DONE);
  247.                                 Summons.DespawnAll();
  248.                                 me->DespawnOrUnsummon();
  249.                             }
  250.                             break;
  251.                     }
  252.                     break;
  253.             }
  254.         }
  255.     };
  256.  
  257. };
  258.  
  259. struct boss_faction_championsAI : public ScriptedAI
  260. {
  261.     boss_faction_championsAI(Creature* creature, uint32 aitype) : ScriptedAI(creature)
  262.     {
  263.         m_instance = (InstanceScript*) creature->GetInstanceScript();
  264.         mAIType = aitype;
  265.     }
  266.  
  267.     InstanceScript* m_instance;
  268.  
  269.     uint64 championControllerGUID;
  270.     uint32 mAIType;
  271.     uint32 ThreatTimer;
  272.     uint32 CCTimer;
  273.  
  274.     void Reset()
  275.     {
  276.         championControllerGUID = 0;
  277.         CCTimer = rand()%10000;
  278.         ThreatTimer = 5000;
  279.     }
  280.  
  281.     void JustReachedHome()
  282.     {
  283.         if (m_instance)
  284.             if (Creature* pChampionController = Unit::GetCreature((*me), m_instance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
  285.                 pChampionController->AI()->SetData(2, FAIL);
  286.         me->DespawnOrUnsummon();
  287.     }
  288.  
  289.     void EnterEvadeMode()
  290.     {
  291.         if (m_instance)
  292.             if (Creature* pChampionController = Unit::GetCreature((*me), m_instance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
  293.                 pChampionController->AI()->SetData(2, FAIL);
  294.         me->DespawnOrUnsummon(5000);
  295.     }
  296.  
  297.     float CalculateThreat(float distance, float armor, uint32 health)
  298.     {
  299.         float dist_mod = (mAIType == AI_MELEE || mAIType == AI_PET) ? 15.0f/(15.0f + distance) : 1.0f;
  300.         float armor_mod = (mAIType == AI_MELEE || mAIType == AI_PET) ? armor / 16635.0f : 0.0f;
  301.         float eh = (health+1) * (1.0f + armor_mod);
  302.         return dist_mod * 30000.0f / eh;
  303.     }
  304.  
  305.     void UpdateThreat()
  306.     {
  307.         std::list<HostileReference*> const& tList = me->getThreatManager().getThreatList();
  308.         for (std::list<HostileReference*>::const_iterator itr = tList.begin(); itr != tList.end(); ++itr)
  309.         {
  310.             Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid());
  311.             if (unit && me->getThreatManager().getThreat(unit))
  312.             {
  313.                 if (unit->GetTypeId()==TYPEID_PLAYER)
  314.                 {
  315.                     float threat = CalculateThreat(me->GetDistance2d(unit), (float)unit->GetArmor(), unit->GetHealth());
  316.                     me->getThreatManager().modifyThreatPercent(unit, -100);
  317.                     me->AddThreat(unit, 1000000.0f * threat);
  318.                 }
  319.             }
  320.         }
  321.     }
  322.  
  323.     void UpdatePower()
  324.     {
  325.         if (me->getPowerType() == POWER_MANA)
  326.             me->ModifyPower(POWER_MANA, me->GetMaxPower(POWER_MANA) / 3);
  327.         //else if (me->getPowerType() == POWER_ENERGY)
  328.         //    me->ModifyPower(POWER_ENERGY, 100);
  329.     }
  330.  
  331.     void RemoveCC()
  332.     {
  333.         me->RemoveAurasByType(SPELL_AURA_MOD_STUN);
  334.         me->RemoveAurasByType(SPELL_AURA_MOD_FEAR);
  335.         me->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
  336.         me->RemoveAurasByType(SPELL_AURA_MOD_PACIFY);
  337.         me->RemoveAurasByType(SPELL_AURA_MOD_CONFUSE);
  338.         //DoCast(me, SPELL_PVP_TRINKET);
  339.     }
  340.  
  341.     void JustDied(Unit* /*killer*/)
  342.     {
  343.         if (mAIType != AI_PET)
  344.             if (m_instance)
  345.                 if (Creature* pChampionController = Unit::GetCreature((*me), m_instance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
  346.                     pChampionController->AI()->SetData(2, DONE);
  347.     }
  348.  
  349.     void EnterCombat(Unit* /*who*/)
  350.     {
  351.         DoCast(me, SPELL_ANTI_AOE, true);
  352.         me->SetInCombatWithZone();
  353.         if (m_instance)
  354.             if (Creature* pChampionController = Unit::GetCreature((*me), m_instance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
  355.                 pChampionController->AI()->SetData(2, IN_PROGRESS);
  356.     }
  357.  
  358.     void KilledUnit(Unit* who)
  359.     {
  360.         if (who->GetTypeId() == TYPEID_PLAYER)
  361.         {
  362.             Map::PlayerList const &players = me->GetMap()->GetPlayers();
  363.             uint32 TeamInInstance = 0;
  364.  
  365.             if (!players.isEmpty())
  366.                 if (Player* player = players.begin()->getSource())
  367.                     TeamInInstance = player->GetTeam();
  368.  
  369.             if (m_instance)
  370.             {
  371.                 if (TeamInInstance == ALLIANCE)
  372.                 {
  373.                     if (Creature* temp = Unit::GetCreature(*me, m_instance->GetData64(NPC_VARIAN)))
  374.                         DoScriptText(SAY_VARIAN_KILL_HORDE_PLAYER4+urand(0, 3), temp); // + cause we are on negative
  375.                 }
  376.                 else
  377.                     if (Creature* temp = me->FindNearestCreature(NPC_GARROSH, 300.f))
  378.                         DoScriptText(SAY_GARROSH_KILL_ALLIANCE_PLAYER4+urand(0, 3), temp); // + cause we are on negative
  379.  
  380.                 m_instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
  381.             }
  382.         }
  383.     }
  384.  
  385.     Creature* SelectRandomFriendlyMissingBuff(uint32 spell)
  386.     {
  387.         std::list<Creature*> lst = DoFindFriendlyMissingBuff(40.0f, spell);
  388.         std::list<Creature*>::const_iterator itr = lst.begin();
  389.         if (lst.empty())
  390.             return NULL;
  391.         advance(itr, rand()%lst.size());
  392.         return (*itr);
  393.     }
  394.  
  395.         Unit* SelectEnemyWithAura(uint32 spell, bool applied)
  396.     {
  397.         std::list<HostileReference*> const& threatlist = me->getThreatManager().getThreatList();
  398.         if (threatlist.empty())
  399.             return NULL;
  400.  
  401.         std::list<Unit*> targetList;
  402.         for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
  403.         {
  404.             if (applied == (*itr)->getTarget()->HasAura(spell))
  405.                 targetList.push_back((*itr)->getTarget());
  406.         }
  407.         if (targetList.empty())
  408.             return NULL;
  409.         std::list<Unit*>::const_iterator itr = targetList.begin();
  410.         advance(itr, rand()%targetList.size());
  411.         return (*itr);
  412.     }
  413.    
  414.     Unit* SelectEnemyCaster(bool /*casting*/)
  415.     {
  416.         std::list<HostileReference*> const& tList = me->getThreatManager().getThreatList();
  417.         std::list<HostileReference*>::const_iterator iter;
  418.         Unit* target;
  419.         for (iter = tList.begin(); iter!=tList.end(); ++iter)
  420.         {
  421.             target = Unit::GetUnit((*me), (*iter)->getUnitGuid());
  422.             if (target && target->getPowerType() == POWER_MANA)
  423.                 return target;
  424.         }
  425.         return NULL;
  426.     }
  427.  
  428.     uint32 EnemiesInRange(float distance)
  429.     {
  430.         std::list<HostileReference*> const& tList = me->getThreatManager().getThreatList();
  431.         std::list<HostileReference*>::const_iterator iter;
  432.         uint32 count = 0;
  433.         Unit* target;
  434.         for (iter = tList.begin(); iter!=tList.end(); ++iter)
  435.         {
  436.             target = Unit::GetUnit((*me), (*iter)->getUnitGuid());
  437.                 if (target && me->GetDistance2d(target) < distance)
  438.                     ++count;
  439.         }
  440.         return count;
  441.     }
  442.  
  443.     void AttackStart(Unit* who)
  444.     {
  445.         if (!who) return;
  446.  
  447.         if (me->Attack(who, true))
  448.         {
  449.             me->AddThreat(who, 10.0f);
  450.             me->SetInCombatWith(who);
  451.             who->SetInCombatWith(me);
  452.  
  453.             if (mAIType == AI_MELEE || mAIType == AI_PET)
  454.                 DoStartMovement(who);
  455.             else
  456.                 DoStartMovement(who, 20.0f);
  457.             SetCombatMovement(true);
  458.         }
  459.     }
  460.  
  461.     void UpdateAI(const uint32 uiDiff)
  462.     {
  463.         if (ThreatTimer < uiDiff)
  464.         {
  465.             UpdatePower();
  466.             UpdateThreat();
  467.             ThreatTimer = 4000;
  468.  
  469.             if (me->GetDistance(me->GetHomePosition()) > 150.0f || fabs(me->GetPositionZ() - me->GetHomePosition().m_positionZ) > 20.0f)
  470.             {
  471.                 me->GetMotionMaster()->MovePoint(0, me->GetHomePosition());
  472.             }
  473.  
  474.             if (!m_instance || !me->GetMap())
  475.                 EnterEvadeMode();
  476.  
  477.             Map::PlayerList const &players = me->GetMap()->GetPlayers();
  478.  
  479.             if (players.isEmpty())
  480.                 EnterEvadeMode();
  481.  
  482.             bool evade = true;
  483.  
  484.             for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  485.                 if (itr->getSource()->isAlive())
  486.                 {
  487.                     evade = false;
  488.                     break;
  489.                 }
  490.  
  491.             if (evade)
  492.                 EnterEvadeMode();
  493.  
  494.         }
  495.         else ThreatTimer -= uiDiff;
  496.  
  497.         if (mAIType != AI_PET)
  498.         {
  499.             if (CCTimer < uiDiff)
  500.             {
  501.                 RemoveCC();
  502.                 CCTimer = 8000+rand()%2000;
  503.             }
  504.             else CCTimer -= uiDiff;
  505.         }
  506.  
  507.         if (mAIType == AI_MELEE || mAIType == AI_PET) DoMeleeAttackIfReady();
  508.     }
  509. };
  510.  
  511. /********************************************************************
  512.                             HEALERS
  513. ********************************************************************/
  514. enum eDruidSpells
  515. {
  516.     SPELL_LIFEBLOOM         = 66093,
  517.     SPELL_NOURISH           = 66066,
  518.     SPELL_REGROWTH          = 66067,
  519.     SPELL_REJUVENATION      = 66065,
  520.     SPELL_TRANQUILITY       = 66086, //10 min cd
  521.     SPELL_BARKSKIN          = 65860, //1 min cd
  522.     SPELL_THORNS            = 66068,
  523.     SPELL_NATURE_GRASP      = 66071, //1 min cd, self buff
  524. };
  525.  
  526. class mob_toc_druid : public CreatureScript
  527. {
  528. public:
  529.     mob_toc_druid() : CreatureScript("mob_toc_druid") { }
  530.  
  531.     CreatureAI* GetAI(Creature* creature) const
  532.     {
  533.         return new mob_toc_druidAI (creature);
  534.     }
  535.  
  536.     struct mob_toc_druidAI : public boss_faction_championsAI
  537.     {
  538.         mob_toc_druidAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
  539.  
  540.         uint32 m_uiNatureGraspTimer;
  541.         uint32 m_uiTranquilityTimer;
  542.         uint32 m_uiBarkskinTimer;
  543.         uint32 m_uiCommonTimer;
  544.  
  545.         void Reset()
  546.         {
  547.             boss_faction_championsAI::Reset();
  548.             m_uiNatureGraspTimer = 1*BASE_TIME;
  549.             m_uiTranquilityTimer = 5*BASE_TIME;
  550.             m_uiBarkskinTimer = 10*BASE_TIME;
  551.             m_uiCommonTimer = BASE_TIME;
  552.             SetEquipmentSlots(false, 51799, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  553.         }
  554.  
  555.         void UpdateAI(const uint32 uiDiff)
  556.         {
  557.             if (!UpdateVictim()) return;
  558.  
  559.             if (m_uiNatureGraspTimer <= uiDiff)
  560.             {
  561.                 DoCast(me, SPELL_NATURE_GRASP, true);
  562.                 m_uiNatureGraspTimer = urand(60*BASE_TIME, 80*BASE_TIME);
  563.             } else m_uiNatureGraspTimer -= uiDiff;
  564.  
  565.             if (me->GetMap()->IsHeroic() && m_uiTranquilityTimer <= uiDiff)
  566.             {
  567.                 //heroic only            
  568.                
  569.                 uint8 numOfLowHP = 0;
  570.                 uint8 numOfLeft = 0;
  571.                 if (Creature* controller = ObjectAccessor::GetCreature(*me, championControllerGUID))
  572.                 {
  573.                     //TODO: test
  574.                     if (boss_toc_champion_controller::boss_toc_champion_controllerAI* controllerAI = static_cast<boss_toc_champion_controller::boss_toc_champion_controllerAI*>(controller->GetAI()))
  575.                     {
  576.                         if (!controllerAI->Summons.empty())
  577.                         {
  578.                             for (std::list<uint64>::const_iterator itr = controllerAI->Summons.begin(); itr != controllerAI->Summons.end(); ++itr)
  579.                             {
  580.                                 numOfLeft++;
  581.                                 Creature* champion = Unit::GetCreature(*me, *itr);
  582.                                 if (champion && champion->isAlive() && champion->HealthBelowPct(50))
  583.                                     numOfLowHP++;                                    
  584.                             }
  585.                         }
  586.                     }
  587.                 }
  588.  
  589.                 //cast only, if druid has low hp or if more than 50% of champions have less than 50% HP
  590.                 if (me->HealthBelowPct(25) || (numOfLowHP/(double)numOfLeft) > 0.5)
  591.                 {
  592.                     DoCastAOE(SPELL_TRANQUILITY, true);
  593.                     m_uiTranquilityTimer = urand(600*BASE_TIME, 660*BASE_TIME);
  594.                 }
  595.                 else
  596.                     m_uiTranquilityTimer = 10*BASE_TIME; //try again in 10 seconds
  597.             } else m_uiTranquilityTimer -= uiDiff;
  598.  
  599.             if (m_uiBarkskinTimer <= uiDiff)
  600.             {
  601.                 if (HealthBelowPct(50))
  602.                     DoCast(me, SPELL_BARKSKIN, true);
  603.                 m_uiBarkskinTimer = urand(60*BASE_TIME, 90*BASE_TIME);
  604.             } else m_uiBarkskinTimer -= uiDiff;
  605.  
  606.             if (m_uiCommonTimer <= uiDiff)
  607.             {
  608.                 Creature* target=me;
  609.                 if (me->HealthAbovePct(40))
  610.                 {
  611.                     target=(Creature*)DoSelectLowestHpFriendly(40.0f);
  612.                 }
  613.  
  614.                 switch (urand(0, 7))
  615.                 {
  616.                     case 0:
  617.                         DoCast(target, SPELL_LIFEBLOOM);
  618.                         break;
  619.                     case 1: case 2:
  620.                         DoCast(target, SPELL_NOURISH);
  621.                         break;
  622.                     case 3: case 4: case 5:
  623.                         DoCast(target, SPELL_REGROWTH);
  624.                         break;
  625.                     case 6:
  626.                         if (Creature* target = SelectRandomFriendlyMissingBuff(SPELL_REJUVENATION))
  627.                             DoCast(target, SPELL_REJUVENATION);
  628.                         break;
  629.                     case 7:
  630.                         if (Creature* target = SelectRandomFriendlyMissingBuff(SPELL_THORNS))
  631.                             DoCast(target, SPELL_THORNS);
  632.                         break;
  633.                 }
  634.                 m_uiCommonTimer = urand(2.5*BASE_TIME, 3*BASE_TIME);
  635.             } else m_uiCommonTimer -= uiDiff;
  636.  
  637.             boss_faction_championsAI::UpdateAI(uiDiff);
  638.         }
  639.     };
  640.  
  641. };
  642.  
  643. enum eShamanSpells
  644. {
  645.     SPELL_HEALING_WAVE          = 66055,
  646.     SPELL_RIPTIDE               = 66053, //6 sec cd
  647.     /*SPELL_SPIRIT_CLEANSE        = 66056, //friendly only */
  648.     SPELL_HEROISM               = 65983,
  649.     SPELL_BLOODLUST             = 65980,
  650.     SPELL_HEX                   = 66054, //45 sec cd
  651.     SPELL_EARTH_SHIELD          = 66063,
  652.     SPELL_EARTH_SHOCK           = 65973, //6 sec cd
  653.     AURA_EXHAUSTION             = 57723,
  654.     AURA_SATED                  = 57724, //rozdávání aury nefunguje - nevadi - resi se cooldownem
  655. };
  656.  
  657. class mob_toc_shaman : public CreatureScript
  658. {
  659. public:
  660.     mob_toc_shaman() : CreatureScript("mob_toc_shaman") { }
  661.  
  662.     CreatureAI* GetAI(Creature* creature) const
  663.     {
  664.         return new mob_toc_shamanAI (creature);
  665.     }
  666.  
  667.     struct mob_toc_shamanAI : public boss_faction_championsAI
  668.     {
  669.         mob_toc_shamanAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
  670.  
  671.         uint32 m_uiHeroismOrBloodlustTimer;
  672.         uint32 m_uiHexTimer;
  673.         uint32 m_uiCommonTimer;
  674.  
  675.         void Reset()
  676.         {
  677.             boss_faction_championsAI::Reset();
  678.             m_uiHeroismOrBloodlustTimer = 4*BASE_TIME;
  679.             m_uiHexTimer = 2*BASE_TIME;
  680.             m_uiCommonTimer = BASE_TIME;
  681.             SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  682.         }
  683.  
  684.         void UpdateAI(const uint32 uiDiff)
  685.         {
  686.             if (!UpdateVictim()) return;
  687.  
  688.             if (m_uiHeroismOrBloodlustTimer <= uiDiff)
  689.             {
  690.                 if (me->getFaction()) //Am i alliance?
  691.                 {
  692.                     if (!me->HasAura(AURA_EXHAUSTION))
  693.                         DoCastAOE(SPELL_HEROISM, true);
  694.                 }
  695.                 else
  696.                     if (!me->HasAura(AURA_SATED))
  697.                         DoCastAOE(SPELL_BLOODLUST, true);
  698.                 m_uiHeroismOrBloodlustTimer = 600*BASE_TIME;
  699.             } else m_uiHeroismOrBloodlustTimer -= uiDiff;
  700.  
  701.             if (m_uiHexTimer <= uiDiff)
  702.             {
  703.                 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  704.                 {
  705.                     if (me->HasUnitState(UNIT_STATE_CASTING))
  706.                         me->CastStop();
  707.                     DoCast(target, SPELL_HEX);
  708.                 }
  709.                 m_uiHexTimer = urand(45*BASE_TIME, 50*BASE_TIME);
  710.             } else m_uiHexTimer -= uiDiff;
  711.  
  712.             if (m_uiCommonTimer <= uiDiff)
  713.             {
  714.                                 uint8 rnd = urand(0, 4) + (me->HasUnitState(UNIT_STATE_CASTING) ? 10 : 0);
  715.                 Creature* target=me;
  716.                 if (me->HealthAbovePct(60))
  717.                 {
  718.                     target=(Creature*)DoSelectLowestHpFriendly(40.0f);
  719.                 }
  720.                 switch (urand(0, 5))
  721.                 {
  722.                     case 0: case 1: case 2:
  723.                         DoCast(target, SPELL_HEALING_WAVE);
  724.                         break;
  725.                                         case 3: case 4:
  726.                         DoCast(target, SPELL_RIPTIDE);
  727.                         break;
  728.                     case 5:
  729.                         DoCast(target, SPELL_EARTH_SHOCK);
  730.                         break;
  731.                     /*case 5:
  732.                         DoCast(target, SPELL_SPIRIT_CLEANSE);
  733.                         break;*/
  734.                     case 6:
  735.                         if (Unit* target = SelectRandomFriendlyMissingBuff(SPELL_EARTH_SHIELD))
  736.                             DoCast(target, SPELL_EARTH_SHIELD);
  737.                         break;
  738.                 }
  739.                 m_uiCommonTimer = 0.5*BASE_TIME;
  740.             } else m_uiCommonTimer -= uiDiff;
  741.  
  742.             boss_faction_championsAI::UpdateAI(uiDiff);
  743.         }
  744.     };
  745.  
  746. };
  747.  
  748. enum ePaladinSpells
  749. {
  750.     SPELL_HAND_OF_FREEDOM     = 68757, //25 sec cd
  751.     SPELL_BUBBLE              = 66010, //5 min cd
  752.     /*SPELL_CLEANSE             = 66116,*/
  753.     SPELL_FLASH_OF_LIGHT      = 66113,
  754.     SPELL_HOLY_LIGHT          = 66112,
  755.     SPELL_HOLY_SHOCK          = 66114, //6 sec cd
  756.     SPELL_HAND_OF_PROTECTION  = 66009, //5 min cd
  757.     SPELL_HAMMER_OF_JUSTICE   = 66613, //40 sec cd
  758. };
  759.  
  760. class mob_toc_paladin : public CreatureScript
  761. {
  762. public:
  763.     mob_toc_paladin() : CreatureScript("mob_toc_paladin") { }
  764.  
  765.     CreatureAI* GetAI(Creature* creature) const
  766.     {
  767.         return new mob_toc_paladinAI (creature);
  768.     }
  769.  
  770.     struct mob_toc_paladinAI : public boss_faction_championsAI
  771.     {
  772.         mob_toc_paladinAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
  773.  
  774.         uint32 m_uiBubbleTimer;
  775.         uint32 m_uiHandOfProtectionTimer;
  776.         uint32 m_uiHolyShockTimer;
  777.         uint32 m_uiHandOfFreedomTimer;
  778.         uint32 m_uiHammerOfJusticeTimer;
  779.         uint32 m_uiCommonTimer;
  780.  
  781.         void Reset()
  782.         {
  783.             boss_faction_championsAI::Reset();
  784.             m_uiBubbleTimer = urand(0*BASE_TIME, 360*BASE_TIME);
  785.             m_uiHandOfProtectionTimer = urand(0*BASE_TIME, 360*BASE_TIME);
  786.             m_uiHolyShockTimer = urand(6*BASE_TIME, 15*BASE_TIME);
  787.             m_uiHandOfFreedomTimer = urand(10*BASE_TIME, 20*BASE_TIME);
  788.             m_uiHammerOfJusticeTimer = urand(10*BASE_TIME, 15*BASE_TIME);
  789.             m_uiCommonTimer = urand(10*BASE_TIME, 15*BASE_TIME);
  790.             SetEquipmentSlots(false, 50771, 47079, EQUIP_NO_CHANGE);
  791.         }
  792.  
  793.                 void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo)
  794.                 {
  795.                         if(spellInfo->Id == 66010) //bubble
  796.                                 timer = 360*BASE_TIME;
  797.                 }
  798.  
  799.         void UpdateAI(const uint32 uiDiff)
  800.         {
  801.             if (!UpdateVictim()) return;
  802.  
  803.             if (m_uiBubbleTimer <= uiDiff)
  804.             {
  805.                 //cast bubble at 20% hp
  806.                 if (HealthBelowPct(20))
  807.                     DoCast(me, SPELL_BUBBLE, true);
  808.                 m_uiBubbleTimer = 1*BASE_TIME;
  809.             } else m_uiBubbleTimer -= uiDiff;
  810.  
  811.             if (m_uiHandOfProtectionTimer <= uiDiff)
  812.             {
  813.                 if (Unit* target = DoSelectLowestHpFriendly(40.0f))
  814.                     if (target->HealthBelowPct(15))
  815.                         DoCast(target, SPELL_HAND_OF_PROTECTION, true);
  816.                 m_uiHandOfProtectionTimer = urand(360*BASE_TIME, 380*BASE_TIME);
  817.             } else m_uiHandOfProtectionTimer -= uiDiff;
  818.  
  819.             if (m_uiHolyShockTimer <= uiDiff)
  820.             {
  821.                 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  822.                     DoCast(target, SPELL_HOLY_SHOCK, true);
  823.                 m_uiHolyShockTimer = urand(6*BASE_TIME, 8*BASE_TIME);
  824.             } else m_uiHolyShockTimer -= uiDiff;
  825.  
  826.             if (m_uiHandOfFreedomTimer <= uiDiff)
  827.             {
  828.                 if (Unit* target = SelectRandomFriendlyMissingBuff(SPELL_HAND_OF_FREEDOM))
  829.                     DoCast(target, SPELL_HAND_OF_FREEDOM, true);
  830.                 m_uiHandOfFreedomTimer = urand(25*BASE_TIME, 40*BASE_TIME);
  831.             } else m_uiHandOfFreedomTimer -= uiDiff;
  832.  
  833.             if (m_uiHammerOfJusticeTimer <= uiDiff)
  834.             {
  835.                 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  836.                     DoCast(target, SPELL_HAMMER_OF_JUSTICE, true);
  837.                 m_uiHammerOfJusticeTimer = urand(40*BASE_TIME, 60*BASE_TIME);
  838.             } else m_uiHammerOfJusticeTimer -= uiDiff;
  839.  
  840.             if (m_uiCommonTimer <= uiDiff)
  841.             {
  842.                                 uint8 rnd = urand(0, 2) + (me->HasUnitState(UNIT_STATE_CASTING) ? 10 : 0);
  843.                 Creature* target=me;
  844.                 if (me->HealthAbovePct(40))
  845.                 {
  846.                     target=(Creature*)DoSelectLowestHpFriendly(40.0f);
  847.                 }
  848.                 switch (rnd)
  849.                 {
  850.                     case 0: case 1:
  851.                         DoCast(target, SPELL_FLASH_OF_LIGHT);
  852.                         break;
  853.                     case 2:
  854.                         if (HealthBelowPct(70))
  855.                             DoCast(target, SPELL_HOLY_LIGHT);
  856.                         break;
  857.                     /*case 5:
  858.                         DoCast(target, SPELL_CLEANSE);
  859.                         break;*/
  860.                 }
  861.                 m_uiCommonTimer = 0.5*BASE_TIME;
  862.             } else m_uiCommonTimer -= uiDiff;
  863.  
  864.             boss_faction_championsAI::UpdateAI(uiDiff);
  865.         }
  866.     };
  867.  
  868. };
  869.  
  870. enum ePriestSpells
  871. {
  872.     SPELL_RENEW             = 66177,
  873.     SPELL_SHIELD            = 66099, //15 sec cd
  874.     SPELL_FLASH_HEAL        = 66104,
  875.     /*SPELL_DISPEL            = 65546,*/
  876.     SPELL_PSYCHIC_SCREAM    = 65543, //30 sec cd
  877.     SPELL_MANA_BURN         = 66100,
  878.     SPELL_PENANCE           = 66097,
  879. };
  880.  
  881. class mob_toc_priest : public CreatureScript
  882. {
  883. public:
  884.     mob_toc_priest() : CreatureScript("mob_toc_priest") { }
  885.  
  886.     CreatureAI* GetAI(Creature* creature) const
  887.     {
  888.         return new mob_toc_priestAI (creature);
  889.     }
  890.  
  891.     struct mob_toc_priestAI : public boss_faction_championsAI
  892.     {
  893.         mob_toc_priestAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
  894.  
  895.         uint32 m_uiPsychicScreamTimer;
  896.         uint32 m_uiShieldTimer;
  897.         uint32 m_uiCommonTimer;
  898.  
  899.         void Reset()
  900.         {
  901.             boss_faction_championsAI::Reset();
  902.             m_uiPsychicScreamTimer = urand(4*BASE_TIME, 10*BASE_TIME);
  903.             m_uiShieldTimer = urand(2*BASE_TIME, 5*BASE_TIME);
  904.             m_uiCommonTimer = urand(5*BASE_TIME, 10*BASE_TIME);
  905.             SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  906.         }
  907.  
  908.         void UpdateAI(const uint32 uiDiff)
  909.         {
  910.             if (!UpdateVictim()) return;
  911.  
  912.             if (m_uiPsychicScreamTimer <= uiDiff)
  913.             {
  914.                 if (EnemiesInRange(10.0f) > 2)
  915.                 {
  916.                     DoCastAOE(SPELL_PSYCHIC_SCREAM, true);
  917.                     m_uiPsychicScreamTimer = urand(30*BASE_TIME, 40*BASE_TIME);
  918.                 }
  919.                 else
  920.                     m_uiPsychicScreamTimer = 5*BASE_TIME; //try again in 5sec, if casting failed
  921.                
  922.             } else m_uiPsychicScreamTimer -= uiDiff;            
  923.  
  924.             if (m_uiShieldTimer <= uiDiff)
  925.             {
  926.                 if (Creature* target = SelectRandomFriendlyMissingBuff(SPELL_SHIELD))
  927.                 {
  928.                     DoCast(target, SPELL_SHIELD);
  929.                     m_uiShieldTimer = urand(15*BASE_TIME, 20*BASE_TIME);
  930.                 }
  931.                 else
  932.                     m_uiShieldTimer = 2*BASE_TIME;
  933.             } else m_uiShieldTimer -= uiDiff;
  934.  
  935.             if (m_uiCommonTimer <= uiDiff)
  936.             {
  937.                                 uint8 rnd = urand(0, 7) + (me->HasUnitState(UNIT_STATE_CASTING) ? 10 : 0);
  938.                 Creature* target=me;
  939.                 if (me->HealthAbovePct(40))
  940.                 {
  941.                     target=(Creature*)DoSelectLowestHpFriendly(40.0f);
  942.                 }
  943.                 switch (rnd)
  944.                 {
  945.                     case 0: case 1:
  946.                         DoCast(target, SPELL_RENEW);
  947.                         break;
  948.                                         case 2: case 3: case 4:
  949.                         DoCast(target, SPELL_FLASH_HEAL);
  950.                         break;
  951.                     case 5: case 6:
  952.                         DoCast(target, SPELL_PENANCE);
  953.                         break;
  954.                     /*case 5:
  955.                         DoCast(target, SPELL_DISPEL);
  956.                         break;*/
  957.                     case 7:
  958.                         DoCast(target, SPELL_MANA_BURN);
  959.                         break;
  960.                 }
  961.                 m_uiCommonTimer = 0.5*BASE_TIME;
  962.             } else m_uiCommonTimer -= uiDiff;
  963.  
  964.             boss_faction_championsAI::UpdateAI(uiDiff);
  965.         }
  966.     };
  967.  
  968. };
  969.  
  970. /********************************************************************
  971.                             RANGED
  972. ********************************************************************/
  973. enum eShadowPriestSpells
  974. {
  975.     SPELL_SILENCE           = 65542, //45 sec cd
  976.     SPELL_VAMPIRIC_TOUCH    = 65490,
  977.     SPELL_SW_PAIN           = 65541, //6 sec cd
  978.     SPELL_MIND_FLAY         = 65488,
  979.     SPELL_MIND_BLAST        = 65492, //8 sec cd
  980.     SPELL_HORROR            = 65545, //120 sec cd
  981.     SPELL_DISPERSION        = 65544, //180 sec cd
  982.     SPELL_SHADOWFORM        = 16592,
  983. };
  984.  
  985. class mob_toc_shadow_priest : public CreatureScript
  986. {
  987. public:
  988.     mob_toc_shadow_priest() : CreatureScript("mob_toc_shadow_priest") { }
  989.  
  990.     CreatureAI* GetAI(Creature* creature) const
  991.     {
  992.         return new mob_toc_shadow_priestAI (creature);
  993.     }
  994.  
  995.     struct mob_toc_shadow_priestAI : public boss_faction_championsAI
  996.     {
  997.         mob_toc_shadow_priestAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
  998.  
  999.         uint32 m_uiPsychicScreamTimer;
  1000.         uint32 m_uiDispersionTimer;
  1001.         uint32 m_uiSilenceTimer;
  1002.         uint32 m_uiMindBlastTimer;
  1003.         uint32 m_uiHorrorTimer;
  1004.         uint32 m_uiCommonTimer;
  1005.  
  1006.         void Reset()
  1007.         {
  1008.             boss_faction_championsAI::Reset();
  1009.             m_uiPsychicScreamTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1010.             m_uiDispersionTimer = urand(1*BASE_TIME, 180*BASE_TIME);
  1011.             m_uiSilenceTimer = urand(8*BASE_TIME, 15*BASE_TIME);
  1012.             m_uiMindBlastTimer = urand(3*BASE_TIME, 8*BASE_TIME);
  1013.             m_uiHorrorTimer = urand(10*BASE_TIME, 30*BASE_TIME);
  1014.             m_uiCommonTimer = urand(5*BASE_TIME, 10*BASE_TIME);
  1015.             SetEquipmentSlots(false, 50040, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  1016.             DoCast(me, SPELL_SHADOWFORM);
  1017.         }
  1018.  
  1019.         void EnterCombat(Unit* who)
  1020.         {
  1021.             boss_faction_championsAI::EnterCombat(who);
  1022.         }
  1023.  
  1024.                 void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo)
  1025.                 {
  1026.                         if(spellInfo->Id == 65544) //Dispersion
  1027.                                 timer = 180*BASE_TIME;
  1028.                 }
  1029.  
  1030.         void UpdateAI(const uint32 uiDiff)
  1031.         {
  1032.             if (!UpdateVictim()) return;
  1033.  
  1034.             if (m_uiPsychicScreamTimer <= uiDiff)
  1035.             {
  1036.                 if (EnemiesInRange(10.0f) > 2)
  1037.                 {
  1038.                     DoCastAOE(SPELL_PSYCHIC_SCREAM, true);
  1039.                     m_uiPsychicScreamTimer = urand(30*BASE_TIME, 35*BASE_TIME);
  1040.                 }
  1041.                 else
  1042.                     m_uiPsychicScreamTimer = 5*BASE_TIME; //try again in 5sec, if casting failed                
  1043.             } else m_uiPsychicScreamTimer -= uiDiff;
  1044.  
  1045.             if (m_uiDispersionTimer <= uiDiff)
  1046.             {
  1047.                 if (HealthBelowPct(30))
  1048.                     DoCast(me, SPELL_DISPERSION, true);
  1049.                 m_uiDispersionTimer = 1*BASE_TIME;
  1050.             } else m_uiDispersionTimer -= uiDiff;
  1051.  
  1052.             if (m_uiSilenceTimer <= uiDiff)
  1053.             {
  1054.                 if (Unit* target = SelectEnemyCaster(false))
  1055.                     DoCast(target, SPELL_SILENCE, true);
  1056.                 m_uiSilenceTimer = urand(45*BASE_TIME, 50*BASE_TIME);
  1057.             } else m_uiSilenceTimer -= uiDiff;
  1058.  
  1059.             if (m_uiHorrorTimer <= uiDiff)
  1060.             {
  1061.                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1062.                     m_uiHorrorTimer = 1*BASE_TIME;
  1063.                 else
  1064.                 {
  1065.                     if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1066.                     {
  1067.                         DoCast(target, SPELL_HORROR);
  1068.                     }
  1069.                     m_uiHorrorTimer = urand(120*BASE_TIME, 130*BASE_TIME);
  1070.                 }
  1071.             } else m_uiHorrorTimer -= uiDiff;
  1072.  
  1073.             if (m_uiMindBlastTimer <= uiDiff)
  1074.             {
  1075.                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1076.                     m_uiMindBlastTimer = 1*BASE_TIME; //try again in 1 second
  1077.                 else
  1078.                 {
  1079.                     if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1080.                     {
  1081.                         DoCast(target, SPELL_MIND_BLAST);
  1082.                     }
  1083.                     m_uiMindBlastTimer = urand(8*BASE_TIME, 12*BASE_TIME);
  1084.                 }
  1085.             } else m_uiMindBlastTimer -= uiDiff;
  1086.  
  1087.             if (m_uiCommonTimer <= uiDiff)
  1088.             {
  1089.                                 uint8 rnd = urand(0, 3) + (me->HasUnitState(UNIT_STATE_CASTING) ? 10 : 0);
  1090.  
  1091.                 switch (rnd)
  1092.                 {
  1093.                     case 0: case 1:
  1094.                         if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1095.                             DoCast(target, SPELL_MIND_FLAY);
  1096.                         break;
  1097.                     case 2:
  1098.                         if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1099.                             DoCast(target, SPELL_VAMPIRIC_TOUCH);
  1100.                         break;
  1101.                    case 3:
  1102.                         if (Unit* target = SelectEnemyWithAura(SPELL_SW_PAIN, false))
  1103.                             DoCast(target, SPELL_SW_PAIN);
  1104.                         break;
  1105.                    /*case 4:
  1106.                         if (Unit* target = urand(0, 1) ? SelectTarget(SELECT_TARGET_RANDOM, 0) : DoSelectLowestHpFriendly(40.0f))
  1107.                             DoCast(target, SPELL_DISPEL);
  1108.                         break;*/
  1109.                 }
  1110.                 m_uiCommonTimer = 0.5*BASE_TIME;
  1111.             } else m_uiCommonTimer -= uiDiff;
  1112.  
  1113.             boss_faction_championsAI::UpdateAI(uiDiff);
  1114.         }
  1115.     };
  1116.  
  1117. };
  1118.  
  1119. enum eWarlockSpells
  1120. {
  1121.     SPELL_HELLFIRE              = 65816,
  1122.     SPELL_CORRUPTION            = 65810,
  1123.     SPELL_CURSE_OF_AGONY        = 65814,
  1124.     SPELL_CURSE_OF_EXHAUSTION   = 65815,
  1125.     SPELL_FEAR                  = 65809, //8s
  1126.     SPELL_SEARING_PAIN          = 65819,
  1127.     SPELL_SHADOW_BOLT           = 65821,
  1128.     SPELL_UNSTABLE_AFFLICTION   = 65812,
  1129.     SPELL_SUMMON_FELHUNTER      = 67514,
  1130.     H_SPELL_UNSTABLE_AFFLICTION  = 68155, //15s
  1131. };
  1132.  
  1133. class mob_toc_warlock : public CreatureScript
  1134. {
  1135. public:
  1136.     mob_toc_warlock() : CreatureScript("mob_toc_warlock") { }
  1137.  
  1138.     CreatureAI* GetAI(Creature* creature) const
  1139.     {
  1140.         return new mob_toc_warlockAI (creature);
  1141.     }
  1142.  
  1143.     struct mob_toc_warlockAI : public boss_faction_championsAI
  1144.     {
  1145.         mob_toc_warlockAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED), Summons(me) {}
  1146.  
  1147.         SummonList Summons;
  1148.  
  1149.         uint32 m_uiFearTimer;
  1150.         uint32 m_uiHellfireTimer;
  1151.         uint32 m_uiUnstableAfflictionTimer;
  1152.         uint32 m_uiCommonTimer;
  1153.         uint32 m_uiSummonPetTimer;
  1154.  
  1155.         void Reset()
  1156.         {
  1157.             boss_faction_championsAI::Reset();
  1158.             m_uiFearTimer = urand(4*BASE_TIME, 15*BASE_TIME);
  1159.             m_uiHellfireTimer = urand(15*BASE_TIME, 30*BASE_TIME);
  1160.             m_uiUnstableAfflictionTimer = urand(2*BASE_TIME, 5*BASE_TIME);
  1161.             m_uiCommonTimer = urand(10*BASE_TIME, 15*BASE_TIME);
  1162.             SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  1163.  
  1164.             m_uiSummonPetTimer = urand(10*BASE_TIME, 20*BASE_TIME);
  1165.             DoCast(SPELL_SUMMON_FELHUNTER);
  1166.         }
  1167.  
  1168.         void UpdateAI(const uint32 uiDiff)
  1169.         {
  1170.             if (!UpdateVictim()) return;
  1171.  
  1172.             if (m_uiFearTimer <= uiDiff)
  1173.             {
  1174.                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1175.                     m_uiFearTimer = 1*BASE_TIME;
  1176.                 else
  1177.                 {
  1178.                     if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1179.                         DoCast(target, SPELL_FEAR);
  1180.                     m_uiFearTimer = urand(8*BASE_TIME, 15*BASE_TIME);
  1181.                 }
  1182.             } else m_uiFearTimer -= uiDiff;
  1183.  
  1184.             if (m_uiHellfireTimer <= uiDiff)
  1185.             {
  1186.                 if (me->HasUnitState(UNIT_STATE_CASTING) || EnemiesInRange(10.0f) < 3)
  1187.                     m_uiHellfireTimer = 1*BASE_TIME;
  1188.                 else
  1189.                 {
  1190.                     DoCastAOE(SPELL_HELLFIRE);
  1191.                     m_uiHellfireTimer = urand(15*BASE_TIME, 30*BASE_TIME);
  1192.                 }
  1193.             } else m_uiHellfireTimer -= uiDiff;
  1194.  
  1195.             if (m_uiUnstableAfflictionTimer <= uiDiff)
  1196.             {
  1197.                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1198.                     m_uiUnstableAfflictionTimer = 1*BASE_TIME;
  1199.                 else
  1200.                 {
  1201.                     if (Unit* target = SelectEnemyWithAura(SPELL_UNSTABLE_AFFLICTION, false))
  1202.                         DoCast(target, SPELL_UNSTABLE_AFFLICTION);
  1203.                     m_uiUnstableAfflictionTimer = urand(2*BASE_TIME, 10*BASE_TIME);
  1204.                 }
  1205.             } else m_uiUnstableAfflictionTimer -= uiDiff;
  1206.  
  1207.             if (m_uiSummonPetTimer <= uiDiff)
  1208.             {
  1209.                 m_uiSummonPetTimer = urand(15*BASE_TIME, 30*BASE_TIME);
  1210.             } else m_uiSummonPetTimer -= uiDiff;
  1211.  
  1212.             if (m_uiCommonTimer <= uiDiff)
  1213.             {
  1214.                                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1215.                                 {
  1216.                                         m_uiCommonTimer = 1*BASE_TIME;
  1217.                                 }
  1218.                                 else
  1219.                                 {
  1220.                     switch (urand(0, 7))
  1221.                     {
  1222.                         case 0: case 1: case 2:
  1223.                             DoCastVictim(SPELL_SHADOW_BOLT);
  1224.                             break;
  1225.                         case 3: case 4:
  1226.                             DoCastVictim(SPELL_SEARING_PAIN);
  1227.                             break;
  1228.                         case 5:
  1229.                             if (Unit* target = SelectEnemyWithAura(SPELL_CORRUPTION, false))
  1230.                             DoCast(target, SPELL_CORRUPTION);
  1231.                             break;
  1232.                         case 6:
  1233.                             if (Unit* target = SelectEnemyWithAura(SPELL_CURSE_OF_AGONY, false))
  1234.                                 DoCast(target, SPELL_CURSE_OF_AGONY);
  1235.                             break;
  1236.                         case 7:
  1237.                             if (Unit* target = SelectEnemyWithAura(SPELL_CURSE_OF_EXHAUSTION, false))
  1238.                                 DoCast(target, SPELL_CURSE_OF_EXHAUSTION);
  1239.                             break;
  1240.                     }
  1241.                 m_uiCommonTimer = 0.5*BASE_TIME;)
  1242.                                         }
  1243.             } else m_uiCommonTimer -= uiDiff;
  1244.             boss_faction_championsAI::UpdateAI(uiDiff);
  1245.         }
  1246.     };
  1247.  
  1248. };
  1249.  
  1250. enum eMageSpells
  1251. {
  1252.     SPELL_ARCANE_BARRAGE    = 65799, //3s
  1253.     SPELL_ARCANE_BLAST      = 65791,
  1254.     SPELL_ARCANE_EXPLOSION  = 65800,
  1255.     SPELL_BLINK             = 65793, //15s
  1256.     SPELL_COUNTERSPELL      = 65790, //24s
  1257.     SPELL_FROST_NOVA        = 65792, //25s
  1258.     SPELL_FROSTBOLT         = 65807,
  1259.     SPELL_ICE_BLOCK         = 65802, //5min
  1260.     SPELL_POLYMORPH         = 65801, //15s
  1261. };
  1262.  
  1263. class mob_toc_mage : public CreatureScript
  1264. {
  1265. public:
  1266.     mob_toc_mage() : CreatureScript("mob_toc_mage") { }
  1267.  
  1268.     CreatureAI* GetAI(Creature* creature) const
  1269.     {
  1270.         return new mob_toc_mageAI (creature);
  1271.     }
  1272.  
  1273.     struct mob_toc_mageAI : public boss_faction_championsAI
  1274.     {
  1275.         mob_toc_mageAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
  1276.  
  1277.         uint32 m_uiCounterspellTimer;
  1278.         uint32 m_uiBlinkTimer;
  1279.         uint32 m_uiIceBlockTimer;
  1280.         uint32 m_uiPolymorphTimer;
  1281.         uint32 m_uiArcaneExplosionTimer;
  1282.         uint32 m_uiCommonTimer;
  1283.  
  1284.         void Reset()
  1285.         {
  1286.             boss_faction_championsAI::Reset();
  1287.             m_uiCounterspellTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1288.             m_uiBlinkTimer = urand(7*BASE_TIME, 25*BASE_TIME);
  1289.             m_uiIceBlockTimer = urand(0*BASE_TIME, 360*BASE_TIME);
  1290.             m_uiPolymorphTimer = urand(15*BASE_TIME, 40*BASE_TIME);
  1291.             m_uiCommonTimer = urand(10*BASE_TIME, 15*BASE_TIME);
  1292.             SetEquipmentSlots(false, 47524, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  1293.         }
  1294.  
  1295.                 void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo)
  1296.                 {
  1297.                         if(spellInfo->Id == 65802) //Ice Block
  1298.                                 timer = 360*BASE_TIME;
  1299.                 }
  1300.  
  1301.         void UpdateAI(const uint32 uiDiff)
  1302.         {
  1303.             if (!UpdateVictim()) return;
  1304.  
  1305.             if (m_uiCounterspellTimer <= uiDiff)
  1306.             {
  1307.                 if (Unit* target = SelectEnemyCaster(false))
  1308.                     DoCast(target, SPELL_COUNTERSPELL, true);
  1309.                 m_uiCounterspellTimer = urand(24*BASE_TIME, 27*BASE_TIME);
  1310.             } else m_uiCounterspellTimer -= uiDiff;
  1311.  
  1312.             if (m_uiBlinkTimer <= uiDiff)
  1313.             {
  1314.                 if (HealthBelowPct(50) && EnemiesInRange(10.0f) > 2)
  1315.                 {
  1316.                     DoCastAOE(SPELL_FROST_NOVA);
  1317.                     DoCastAOE(SPELL_BLINK);
  1318.                 }
  1319.                 m_uiBlinkTimer = urand(15*BASE_TIME, 25*BASE_TIME);
  1320.             } else m_uiBlinkTimer -= uiDiff;
  1321.  
  1322.             if (m_uiArcaneExplosionTimer <= uiDiff)
  1323.             {
  1324.                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1325.                     m_uiArcaneExplosionTimer = 1*BASE_TIME;
  1326.                 else
  1327.                 {
  1328.                     DoCastAOE(SPELL_ARCANE_EXPLOSION);
  1329.                     m_uiArcaneExplosionTimer = urand(10*BASE_TIME, 30*BASE_TIME);
  1330.                 }
  1331.             } else m_uiArcaneExplosionTimer -= uiDiff;
  1332.  
  1333.             if (m_uiIceBlockTimer <= uiDiff)
  1334.             {
  1335.                 if (HealthBelowPct(30))
  1336.                     DoCast(me, SPELL_ICE_BLOCK);
  1337.                 m_uiIceBlockTimer = 1*BASE_TIME;
  1338.             } else m_uiIceBlockTimer -= uiDiff;
  1339.  
  1340.             if (m_uiPolymorphTimer <= uiDiff)
  1341.             {
  1342.                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1343.                     m_uiPolymorphTimer = 1*BASE_TIME;
  1344.                 else
  1345.                 {
  1346.                     if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1347.                         DoCast(target, SPELL_POLYMORPH);
  1348.                     m_uiPolymorphTimer = urand(15*BASE_TIME, 40*BASE_TIME);
  1349.                 }
  1350.             } else m_uiPolymorphTimer -= uiDiff;
  1351.  
  1352.             if (m_uiCommonTimer <= uiDiff)
  1353.             {
  1354.                                 uint8 rnd = urand(0, 4) + (me->HasUnitState(UNIT_STATE_CASTING) ? 10 : 0);
  1355.  
  1356.                 switch (rnd)
  1357.                 {
  1358.                     case 0: case 1:
  1359.                         DoCastVictim(SPELL_ARCANE_BARRAGE);
  1360.                         break;
  1361.                     case 2: case 3:
  1362.                         DoCastVictim(SPELL_ARCANE_BLAST);
  1363.                         break;
  1364.                     case 4:
  1365.                         DoCastVictim(SPELL_FROSTBOLT);
  1366.                         break;
  1367.                 }
  1368.                 m_uiCommonTimer = 0.5*BASE_TIME;
  1369.             } else m_uiCommonTimer -= uiDiff;
  1370.  
  1371.             boss_faction_championsAI::UpdateAI(uiDiff);
  1372.         }
  1373.     };
  1374.  
  1375. };
  1376.  
  1377. enum eHunterSpells
  1378. {
  1379.     SPELL_AIMED_SHOT        = 65883,
  1380.     SPELL_DETERRENCE        = 65871, //90s
  1381.     SPELL_DISENGAGE         = 65869, //30s
  1382.     SPELL_EXPLOSIVE_SHOT    = 65866, //6s
  1383.     SPELL_FROST_TRAP        = 65880, //30s
  1384.     SPELL_SHOOT             = 65868, //1.7s
  1385.     SPELL_STEADY_SHOT       = 65867, //3s
  1386.     SPELL_WING_CLIP         = 66207, //6s
  1387.     SPELL_WYVERN_STING      = 65877, //60s
  1388.     SPELL_CALL_PET          = 67777,
  1389. };
  1390.  
  1391. class mob_toc_hunter : public CreatureScript
  1392. {
  1393. public:
  1394.     mob_toc_hunter() : CreatureScript("mob_toc_hunter") { }
  1395.  
  1396.     CreatureAI* GetAI(Creature* creature) const
  1397.     {
  1398.         return new mob_toc_hunterAI (creature);
  1399.     }
  1400.  
  1401.     struct mob_toc_hunterAI : public boss_faction_championsAI
  1402.     {
  1403.         mob_toc_hunterAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED), Summons(me) {}
  1404.  
  1405.         SummonList Summons;
  1406.  
  1407.         uint32 m_uiDisengageTimer;
  1408.         uint32 m_uiDeterrenceTimer;
  1409.         uint32 m_uiWyvernStingTimer;
  1410.         uint32 m_uiFrostTrapTimer;
  1411.         uint32 m_uiWingClipTimer;
  1412.         uint32 m_uiCommonTimer;
  1413.         uint32 m_uiSummonPetTimer;
  1414.  
  1415.         void Reset()
  1416.         {
  1417.             boss_faction_championsAI::Reset();
  1418.             m_uiDisengageTimer = urand(12*BASE_TIME, 20*BASE_TIME);
  1419.             m_uiDeterrenceTimer = urand(20*BASE_TIME, 30*BASE_TIME);
  1420.             m_uiWyvernStingTimer = urand(7*BASE_TIME, 20*BASE_TIME);
  1421.             m_uiFrostTrapTimer = urand(12*BASE_TIME, 20*BASE_TIME);
  1422.             m_uiWingClipTimer = urand(4*BASE_TIME, 8*BASE_TIME);
  1423.             m_uiCommonTimer = urand(10*BASE_TIME, 15*BASE_TIME);
  1424.             SetEquipmentSlots(false, 47156, EQUIP_NO_CHANGE, 48711);
  1425.  
  1426.             m_uiSummonPetTimer = urand(10*BASE_TIME, 20*BASE_TIME);
  1427.             DoCast(SPELL_CALL_PET);
  1428.         }
  1429.  
  1430.         void UpdateAI(const uint32 uiDiff)
  1431.         {
  1432.             if (!UpdateVictim()) return;
  1433.  
  1434.             if (m_uiDisengageTimer <= uiDiff)
  1435.             {
  1436.                 if (EnemiesInRange(10.0f) > 3)
  1437.                     DoCast(SPELL_DISENGAGE);
  1438.                 m_uiDisengageTimer = urand(30*BASE_TIME, 32*BASE_TIME);
  1439.             } else m_uiDisengageTimer -= uiDiff;
  1440.  
  1441.             if (m_uiDeterrenceTimer <= uiDiff)
  1442.             {
  1443.                 if (HealthBelowPct(80))
  1444.                     DoCast(SPELL_DETERRENCE);
  1445.                 m_uiDeterrenceTimer = urand(90*BASE_TIME, 95*BASE_TIME);
  1446.             } else m_uiDeterrenceTimer -= uiDiff;
  1447.  
  1448.             if (m_uiWyvernStingTimer <= uiDiff)
  1449.             {
  1450.                 DoCastVictim(SPELL_WYVERN_STING);
  1451.                 m_uiWyvernStingTimer = urand(60*BASE_TIME, 70*BASE_TIME);
  1452.             } else m_uiWyvernStingTimer -= uiDiff;
  1453.  
  1454.             if (m_uiFrostTrapTimer <= uiDiff)
  1455.             {
  1456.                 DoCast(SPELL_FROST_TRAP);
  1457.                 m_uiFrostTrapTimer = urand(12*BASE_TIME, 30*BASE_TIME);
  1458.             } else m_uiFrostTrapTimer -= uiDiff;
  1459.  
  1460.             if (m_uiWingClipTimer <= uiDiff)
  1461.             {
  1462.                 if (me->GetDistance2d(me->getVictim()) < 5.0f)
  1463.                     DoCastVictim(SPELL_WING_CLIP);
  1464.                 m_uiWingClipTimer = urand(6*BASE_TIME, 10*BASE_TIME);
  1465.             } else m_uiWingClipTimer -= uiDiff;
  1466.  
  1467.             if (m_uiSummonPetTimer <= uiDiff)
  1468.             {
  1469.                 m_uiSummonPetTimer = urand(15*BASE_TIME, 30*BASE_TIME);
  1470.             } else m_uiSummonPetTimer -= uiDiff;
  1471.  
  1472.             if (m_uiCommonTimer <= uiDiff)
  1473.             {
  1474.                 switch (urand(0, 5))
  1475.                 {
  1476.                     case 0: case 1:
  1477.                         DoCastVictim(SPELL_SHOOT);
  1478.                         break;
  1479.                     case 2:
  1480.                         DoCastVictim(SPELL_EXPLOSIVE_SHOT);
  1481.                         break;
  1482.                     case 3:
  1483.                         DoCastVictim(SPELL_AIMED_SHOT);
  1484.                         break;
  1485.                     case 4: case 5:
  1486.                         DoCastVictim(SPELL_STEADY_SHOT);
  1487.                         break;
  1488.                 }
  1489.                 m_uiCommonTimer = urand(3*BASE_TIME, 4*BASE_TIME);
  1490.             } else m_uiCommonTimer -= uiDiff;
  1491.  
  1492.             boss_faction_championsAI::UpdateAI(uiDiff);
  1493.         }
  1494.     };
  1495.  
  1496. };
  1497.  
  1498. enum eBoomkinSpells
  1499. {
  1500.     SPELL_CYCLONE           = 65859, //6s
  1501.     SPELL_ENTANGLING_ROOTS  = 65857, //10s
  1502.     SPELL_FAERIE_FIRE       = 65863,
  1503.     SPELL_FORCE_OF_NATURE   = 65861, //180s
  1504.     SPELL_INSECT_SWARM      = 65855,
  1505.     SPELL_MOONFIRE          = 65856, //5s
  1506.     SPELL_STARFIRE          = 65854,
  1507.     SPELL_WRATH             = 65862,
  1508. };
  1509.  
  1510. class mob_toc_boomkin : public CreatureScript
  1511. {
  1512. public:
  1513.     mob_toc_boomkin() : CreatureScript("mob_toc_boomkin") { }
  1514.  
  1515.     CreatureAI* GetAI(Creature* creature) const
  1516.     {
  1517.         return new mob_toc_boomkinAI (creature);
  1518.     }
  1519.  
  1520.     struct mob_toc_boomkinAI : public boss_faction_championsAI
  1521.     {
  1522.         mob_toc_boomkinAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
  1523.  
  1524.         uint32 m_uiBarkskinTimer;
  1525.         uint32 m_uiCycloneTimer;
  1526.         uint32 m_uiEntanglingRootsTimer;
  1527.         uint32 m_uiFaerieFireTimer;
  1528.         uint32 m_uiForceOfNatureTimer;
  1529.         uint32 m_uiCommonTimer;
  1530.  
  1531.         void Reset()
  1532.         {
  1533.             boss_faction_championsAI::Reset();
  1534.             m_uiBarkskinTimer = urand(5*BASE_TIME, 30*BASE_TIME);
  1535.             m_uiCycloneTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1536.             m_uiEntanglingRootsTimer = urand(5*BASE_TIME, 10*BASE_TIME);
  1537.             m_uiFaerieFireTimer = urand(10*BASE_TIME, 20*BASE_TIME);
  1538.             m_uiForceOfNatureTimer = urand(10*BASE_TIME, 20*BASE_TIME);
  1539.             m_uiCommonTimer = urand(10*BASE_TIME, 15*BASE_TIME);
  1540.             SetEquipmentSlots(false, 50966, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  1541.         }
  1542.  
  1543.         void UpdateAI(const uint32 uiDiff)
  1544.         {
  1545.             if (!UpdateVictim()) return;
  1546.  
  1547.             if (m_uiBarkskinTimer <= uiDiff)
  1548.             {
  1549.                 if (HealthBelowPct(50))
  1550.                     DoCast(me, SPELL_BARKSKIN, true);
  1551.                 m_uiBarkskinTimer = urand(60*BASE_TIME, 70*BASE_TIME);
  1552.             } else m_uiBarkskinTimer -= uiDiff;
  1553.  
  1554.             if (m_uiForceOfNatureTimer <= uiDiff)
  1555.             {
  1556.                 DoCast(me, SPELL_FORCE_OF_NATURE, true);
  1557.                 m_uiForceOfNatureTimer = urand(180*BASE_TIME, 190*BASE_TIME);
  1558.             } else m_uiForceOfNatureTimer -= uiDiff;
  1559.  
  1560.             if (m_uiCycloneTimer <= uiDiff)
  1561.             {
  1562.                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1563.                     m_uiCycloneTimer = 1*BASE_TIME;
  1564.                 else
  1565.                 {
  1566.                     if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1567.                         DoCast(target, SPELL_CYCLONE);
  1568.                     m_uiCycloneTimer = urand(10*BASE_TIME, 20*BASE_TIME);
  1569.                 }
  1570.             } else m_uiCycloneTimer -= uiDiff;
  1571.  
  1572.             if (m_uiEntanglingRootsTimer <= uiDiff)
  1573.             {
  1574.                 if (me->HasUnitState(UNIT_STATE_CASTING))
  1575.                     m_uiEntanglingRootsTimer = 1*BASE_TIME;
  1576.                 else
  1577.                 {
  1578.                     if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1579.                         DoCast(target, SPELL_ENTANGLING_ROOTS);
  1580.                     m_uiEntanglingRootsTimer = urand(5*BASE_TIME, 20*BASE_TIME);
  1581.                 }
  1582.             } else m_uiEntanglingRootsTimer -= uiDiff;
  1583.  
  1584.             if (m_uiFaerieFireTimer <= uiDiff)
  1585.             {
  1586.                 DoCastVictim(SPELL_FAERIE_FIRE, true);
  1587.                 m_uiFaerieFireTimer = urand(10*BASE_TIME, 30*BASE_TIME);
  1588.             } else m_uiFaerieFireTimer -= uiDiff;
  1589.  
  1590.             if (m_uiCommonTimer <= uiDiff)
  1591.             {
  1592.                                 uint8 rnd = urand(0, 6) + (me->HasUnitState(UNIT_STATE_CASTING) ? 10 : 0);
  1593.  
  1594.                 switch (rnd)
  1595.                 {
  1596.                     case 0:
  1597.                         DoCastVictim(SPELL_MOONFIRE);
  1598.                         break;
  1599.                     case 1:
  1600.                         DoCastVictim(SPELL_INSECT_SWARM);
  1601.                         break;
  1602.                     case 2: case 3:
  1603.                         DoCastVictim(SPELL_STARFIRE);
  1604.                         break;
  1605.                     case 4: case 5: case 6:
  1606.                         DoCastVictim(SPELL_WRATH);
  1607.                         break;
  1608.                 }
  1609.                 m_uiCommonTimer = 0.5*BASE_TIME;
  1610.             } else m_uiCommonTimer -= uiDiff;
  1611.  
  1612.             boss_faction_championsAI::UpdateAI(uiDiff);
  1613.         }
  1614.     };
  1615.  
  1616. };
  1617.  
  1618. /********************************************************************
  1619.                             MELEE
  1620. ********************************************************************/
  1621. enum eWarriorSpells
  1622. {
  1623.     SPELL_BLADESTORM            = 65947, //90s
  1624.     SPELL_INTIMIDATING_SHOUT    = 65930, //120s
  1625.     SPELL_MORTAL_STRIKE         = 65926, //6s
  1626.     SPELL_CHARGE                = 68764, //10s
  1627.     SPELL_DISARM                = 65935, //60s
  1628.     SPELL_OVERPOWER             = 65924, //5s
  1629.     SPELL_SUNDER_ARMOR          = 65936,
  1630.     SPELL_SHATTERING_THROW      = 65940, //90s
  1631.     SPELL_RETALIATION           = 65932, //360s
  1632. };
  1633.  
  1634. class mob_toc_warrior : public CreatureScript
  1635. {
  1636. public:
  1637.     mob_toc_warrior() : CreatureScript("mob_toc_warrior") { }
  1638.  
  1639.     CreatureAI* GetAI(Creature* creature) const
  1640.     {
  1641.         return new mob_toc_warriorAI (creature);
  1642.     }
  1643.  
  1644.     struct mob_toc_warriorAI : public boss_faction_championsAI
  1645.     {
  1646.         mob_toc_warriorAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
  1647.  
  1648.         uint32 m_uiBladestormTimer;
  1649.         uint32 m_uiIntimidatingShoutTimer;
  1650.         uint32 m_uiMortalStrikeTimer;
  1651.         uint32 m_uiSunderArmorTimer;
  1652.         uint32 m_uiChargeTimer;
  1653.         uint32 m_uiRetaliationTimer;
  1654.         uint32 m_uiOverpowerTimer;
  1655.         uint32 m_uiShatteringThrowTimer;
  1656.         uint32 m_uiDisarmTimer;
  1657.  
  1658.         void Reset()
  1659.         {
  1660.             boss_faction_championsAI::Reset();
  1661.             m_uiBladestormTimer = urand(20*BASE_TIME, 30*BASE_TIME);
  1662.             m_uiIntimidatingShoutTimer = urand(10*BASE_TIME, 50*BASE_TIME);
  1663.             m_uiMortalStrikeTimer = urand(6*BASE_TIME, 25*BASE_TIME);
  1664.             m_uiSunderArmorTimer = urand(5*BASE_TIME, 25*BASE_TIME);
  1665.             m_uiChargeTimer = urand(3*BASE_TIME, 25*BASE_TIME);
  1666.             m_uiRetaliationTimer = urand(30*BASE_TIME, 50*BASE_TIME);
  1667.             m_uiOverpowerTimer = urand(30*BASE_TIME, 50*BASE_TIME);
  1668.             m_uiShatteringThrowTimer = urand(10*BASE_TIME, 25*BASE_TIME);
  1669.             m_uiDisarmTimer = urand(20*BASE_TIME, 40*BASE_TIME);
  1670.             SetEquipmentSlots(false, 47427, 46964, EQUIP_NO_CHANGE);
  1671.         }
  1672.  
  1673.         void UpdateAI(const uint32 uiDiff)
  1674.         {
  1675.             if (!UpdateVictim()) return;
  1676.  
  1677.             if (m_uiBladestormTimer <= uiDiff)
  1678.             {
  1679.                 DoCastVictim(SPELL_BLADESTORM);
  1680.                 m_uiBladestormTimer = urand(90*BASE_TIME, 100*BASE_TIME);
  1681.             } else m_uiBladestormTimer -= uiDiff;
  1682.  
  1683.             if (m_uiIntimidatingShoutTimer <= uiDiff)
  1684.             {
  1685.                 DoCast(me, SPELL_INTIMIDATING_SHOUT);
  1686.                 m_uiIntimidatingShoutTimer = urand(120*BASE_TIME, 130*BASE_TIME);
  1687.             } else m_uiIntimidatingShoutTimer -= uiDiff;
  1688.  
  1689.             if (m_uiMortalStrikeTimer <= uiDiff)
  1690.             {
  1691.                 DoCastVictim(SPELL_MORTAL_STRIKE);
  1692.                 m_uiMortalStrikeTimer = urand(6*BASE_TIME, 15*BASE_TIME);
  1693.             } else m_uiMortalStrikeTimer -= uiDiff;
  1694.  
  1695.             if (m_uiSunderArmorTimer <= uiDiff)
  1696.             {
  1697.                 DoCastVictim(SPELL_SUNDER_ARMOR);
  1698.                 m_uiSunderArmorTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1699.             } else m_uiSunderArmorTimer -= uiDiff;
  1700.  
  1701.             if (m_uiChargeTimer <= uiDiff)
  1702.             {
  1703.                 DoCastVictim(SPELL_CHARGE);
  1704.                 m_uiChargeTimer = urand(10*BASE_TIME, 20*BASE_TIME);
  1705.             } else m_uiChargeTimer -= uiDiff;
  1706.  
  1707.             if (m_uiRetaliationTimer <= uiDiff)
  1708.             {
  1709.                 DoCastVictim(SPELL_RETALIATION);
  1710.                 m_uiRetaliationTimer = urand(360*BASE_TIME, 365*BASE_TIME);
  1711.             } else m_uiRetaliationTimer -= uiDiff;
  1712.  
  1713.             if (m_uiOverpowerTimer <= uiDiff)
  1714.             {
  1715.                 DoCastVictim(SPELL_OVERPOWER);
  1716.                 m_uiOverpowerTimer = urand(5*BASE_TIME, 12*BASE_TIME);
  1717.             } else m_uiOverpowerTimer -= uiDiff;
  1718.  
  1719.             if (m_uiShatteringThrowTimer <= uiDiff)
  1720.             {
  1721.                 DoCastVictim(SPELL_SHATTERING_THROW);
  1722.                 m_uiShatteringThrowTimer = urand(90*BASE_TIME, 100*BASE_TIME);
  1723.             } else m_uiShatteringThrowTimer -= uiDiff;
  1724.  
  1725.             if (m_uiDisarmTimer <= uiDiff)
  1726.             {
  1727.                 DoCastVictim(SPELL_DISARM);
  1728.                 m_uiDisarmTimer = urand(60*BASE_TIME, 80*BASE_TIME);
  1729.             } else m_uiDisarmTimer -= uiDiff;
  1730.  
  1731.             boss_faction_championsAI::UpdateAI(uiDiff);
  1732.         }
  1733.     };
  1734.  
  1735. };
  1736.  
  1737. enum eDeathKnightSpells
  1738. {
  1739.     SPELL_CHAINS_OF_ICE       = 66020, //8sec
  1740.     SPELL_DEATH_COIL          = 66019, //5sec
  1741.     SPELL_DEATH_GRIP          = 66017, //35sec
  1742.     SPELL_FROST_STRIKE        = 66047, //6sec
  1743.     SPELL_ICEBOUND_FORTITUDE  = 66023, //1min
  1744.     SPELL_ICY_TOUCH           = 66021, //8sec
  1745.     SPELL_STRANGULATE         = 66018, //2min
  1746. };
  1747.  
  1748. class mob_toc_dk : public CreatureScript
  1749. {
  1750. public:
  1751.     mob_toc_dk() : CreatureScript("mob_toc_dk") { }
  1752.  
  1753.     CreatureAI* GetAI(Creature* creature) const
  1754.     {
  1755.         return new mob_toc_dkAI (creature);
  1756.     }
  1757.  
  1758.     struct mob_toc_dkAI : public boss_faction_championsAI
  1759.     {
  1760.         mob_toc_dkAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
  1761.  
  1762.         uint32 m_uiIceboundFortitudeTimer;
  1763.         uint32 m_uiChainsOfIceTimer;
  1764.         uint32 m_uiDeathCoilTimer;
  1765.         uint32 m_uiStrangulateTimer;
  1766.         uint32 m_uiFrostStrikeTimer;
  1767.         uint32 m_uiIcyTouchTimer;
  1768.         uint32 m_uiDeathGripTimer;
  1769.  
  1770.         void Reset()
  1771.         {
  1772.             boss_faction_championsAI::Reset();
  1773.             m_uiIceboundFortitudeTimer = urand(5*BASE_TIME, 300*BASE_TIME);
  1774.             m_uiChainsOfIceTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1775.             m_uiDeathCoilTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1776.             m_uiStrangulateTimer = urand(10*BASE_TIME, 30*BASE_TIME);
  1777.             m_uiFrostStrikeTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1778.             m_uiIcyTouchTimer = urand(8*BASE_TIME, 12*BASE_TIME);
  1779.             m_uiDeathGripTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1780.             SetEquipmentSlots(false, 47518, 51021, EQUIP_NO_CHANGE);
  1781.         }
  1782.  
  1783.         void UpdateAI(const uint32 uiDiff)
  1784.         {
  1785.             if (!UpdateVictim()) return;
  1786.  
  1787.             if (m_uiIceboundFortitudeTimer <= uiDiff)
  1788.             {
  1789.                 if (HealthBelowPct(50))
  1790.                 {
  1791.                     DoCast(me, SPELL_ICEBOUND_FORTITUDE);
  1792.                     m_uiIceboundFortitudeTimer = urand(60*BASE_TIME, 90*BASE_TIME);
  1793.                 }
  1794.                 else
  1795.                     m_uiIceboundFortitudeTimer = urand(6*BASE_TIME, 9*BASE_TIME);
  1796.             } else m_uiIceboundFortitudeTimer -= uiDiff;
  1797.  
  1798.             if (m_uiChainsOfIceTimer <= uiDiff)
  1799.             {
  1800.                 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  1801.                     DoCast(target, SPELL_CHAINS_OF_ICE);
  1802.                 m_uiChainsOfIceTimer = urand(8*BASE_TIME, 15*BASE_TIME);
  1803.             } else m_uiChainsOfIceTimer -= uiDiff;
  1804.  
  1805.             if (m_uiDeathCoilTimer <= uiDiff)
  1806.             {
  1807.                 DoCastVictim(SPELL_DEATH_COIL);
  1808.                 m_uiDeathCoilTimer = urand(5*BASE_TIME, 10*BASE_TIME);
  1809.             } else m_uiDeathCoilTimer -= uiDiff;
  1810.  
  1811.             if (m_uiStrangulateTimer <= uiDiff)
  1812.             {
  1813.                 if (Unit* target = SelectEnemyCaster(false))
  1814.                     DoCast(target, SPELL_STRANGULATE);
  1815.                 m_uiStrangulateTimer = urand(180*BASE_TIME, 190*BASE_TIME);
  1816.             } else m_uiStrangulateTimer -= uiDiff;
  1817.  
  1818.             if (m_uiFrostStrikeTimer <= uiDiff)
  1819.             {
  1820.                 DoCastVictim(SPELL_FROST_STRIKE);
  1821.                 m_uiFrostStrikeTimer = urand(6*BASE_TIME, 15*BASE_TIME);
  1822.             } else m_uiFrostStrikeTimer -= uiDiff;
  1823.  
  1824.             if (m_uiIcyTouchTimer <= uiDiff)
  1825.             {
  1826.                 DoCastVictim(SPELL_ICY_TOUCH);
  1827.                 m_uiIcyTouchTimer = urand(8*BASE_TIME, 12*BASE_TIME);
  1828.             } else m_uiIcyTouchTimer -= uiDiff;
  1829.  
  1830.             if (m_uiDeathGripTimer <= uiDiff)
  1831.             {
  1832.                 if (me->IsInRange(me->getVictim(), 10.0f, 30.0f, false))
  1833.                 {
  1834.                     DoCastVictim(SPELL_DEATH_GRIP);
  1835.                     m_uiDeathGripTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1836.                 }
  1837.                 else
  1838.                     m_uiDeathGripTimer = 2*BASE_TIME;
  1839.             } else m_uiDeathGripTimer -= uiDiff;
  1840.  
  1841.             boss_faction_championsAI::UpdateAI(uiDiff);
  1842.         }
  1843.     };
  1844.  
  1845. };
  1846.  
  1847. enum eRogueSpells
  1848. {
  1849.     SPELL_FAN_OF_KNIVES         = 65955, //2sec
  1850.     SPELL_BLIND                 = 65960, //2min
  1851.     SPELL_CLOAK                 = 65961, //90sec
  1852.     SPELL_BLADE_FLURRY          = 65956, //2min
  1853.     SPELL_SHADOWSTEP            = 66178, //30sec
  1854.     SPELL_HEMORRHAGE            = 65954,
  1855.     SPELL_EVISCERATE            = 65957,
  1856.     SPELL_WOUND                 = 65962,
  1857. };
  1858.  
  1859. class mob_toc_rogue : public CreatureScript
  1860. {
  1861. public:
  1862.     mob_toc_rogue() : CreatureScript("mob_toc_rogue") { }
  1863.  
  1864.     CreatureAI* GetAI(Creature* creature) const
  1865.     {
  1866.         return new mob_toc_rogueAI (creature);
  1867.     }
  1868.  
  1869.     struct mob_toc_rogueAI : public boss_faction_championsAI
  1870.     {
  1871.         mob_toc_rogueAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
  1872.  
  1873.         uint32 m_uiFanOfKnivesTimer;
  1874.         uint32 m_uiHemorrhageTimer;
  1875.         uint32 m_uiEviscerateTimer;
  1876.         uint32 m_uiShadowstepTimer;
  1877.         uint32 m_uiBlindTimer;
  1878.         uint32 m_uiCloakTimer;
  1879.         uint32 m_uiWoundTimer;
  1880.         uint32 m_uiBladeFlurryTimer;
  1881.  
  1882.         void Reset()
  1883.         {
  1884.             boss_faction_championsAI::Reset();
  1885.             m_uiFanOfKnivesTimer = urand(8*BASE_TIME, 10*BASE_TIME);
  1886.             m_uiHemorrhageTimer = urand(5*BASE_TIME, 8*BASE_TIME);
  1887.             m_uiEviscerateTimer = urand(15*BASE_TIME, 20*BASE_TIME);
  1888.             m_uiShadowstepTimer = urand(10*BASE_TIME, 30*BASE_TIME);
  1889.             m_uiBlindTimer = urand(7*BASE_TIME, 8*BASE_TIME);
  1890.             m_uiCloakTimer = urand(20*BASE_TIME, 40*BASE_TIME);
  1891.             m_uiWoundTimer = urand(1*BASE_TIME, 5*BASE_TIME);
  1892.             m_uiBladeFlurryTimer = urand(12*BASE_TIME, 40*BASE_TIME);
  1893.             SetEquipmentSlots(false, 47422, 49982, EQUIP_NO_CHANGE);
  1894.         }
  1895.  
  1896.         void UpdateAI(const uint32 uiDiff)
  1897.         {
  1898.             if (!UpdateVictim()) return;
  1899.  
  1900.             if (m_uiFanOfKnivesTimer <= uiDiff)
  1901.             {
  1902.                 if (EnemiesInRange(15.0f) > 2)
  1903.                     DoCastAOE(SPELL_FAN_OF_KNIVES);
  1904.                 m_uiFanOfKnivesTimer = urand(8*BASE_TIME, 10*BASE_TIME);
  1905.             } else m_uiFanOfKnivesTimer -= uiDiff;
  1906.  
  1907.             if (m_uiHemorrhageTimer <= uiDiff)
  1908.             {
  1909.                 DoCastVictim(SPELL_HEMORRHAGE);
  1910.                 m_uiHemorrhageTimer = urand(5*BASE_TIME, 8*BASE_TIME);
  1911.             } else m_uiHemorrhageTimer -= uiDiff;
  1912.  
  1913.             if (m_uiEviscerateTimer <= uiDiff)
  1914.             {
  1915.                 DoCastVictim(SPELL_EVISCERATE);
  1916.                 m_uiEviscerateTimer = urand(5*BASE_TIME, 15*BASE_TIME);
  1917.             } else m_uiEviscerateTimer -= uiDiff;
  1918.  
  1919.             if (m_uiShadowstepTimer <= uiDiff)
  1920.             {
  1921.                 if (me->IsInRange(me->getVictim(), 10.0f, 40.0f))
  1922.                     DoCastVictim(SPELL_SHADOWSTEP);
  1923.                 m_uiShadowstepTimer = urand(30*BASE_TIME, 60*BASE_TIME);
  1924.             } else m_uiShadowstepTimer -= uiDiff;
  1925.  
  1926.             if (m_uiBlindTimer <= uiDiff)
  1927.             {
  1928.                 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
  1929.                     if (me->IsInRange(target, 0.0f, 15.0f, false))
  1930.                         DoCast(target, SPELL_BLIND);
  1931.                 m_uiBlindTimer = urand(120*BASE_TIME, 130*BASE_TIME);
  1932.             } else m_uiBlindTimer -= uiDiff;
  1933.  
  1934.             if (m_uiCloakTimer <= uiDiff)
  1935.             {
  1936.                 if (HealthBelowPct(50))
  1937.                     DoCast(me, SPELL_CLOAK);
  1938.                 m_uiCloakTimer = urand(120*BASE_TIME, 130*BASE_TIME);
  1939.             } else m_uiCloakTimer -= uiDiff;
  1940.  
  1941.             if (m_uiWoundTimer <= uiDiff)
  1942.             {
  1943.                 DoCastVictim(SPELL_WOUND);
  1944.                 m_uiWoundTimer = urand(1*BASE_TIME, 5*BASE_TIME);
  1945.             } else m_uiWoundTimer -= uiDiff;
  1946.  
  1947.             if (m_uiBladeFlurryTimer <= uiDiff)
  1948.             {
  1949.                 DoCastVictim(SPELL_BLADE_FLURRY);
  1950.                 m_uiBladeFlurryTimer = urand(180*BASE_TIME, 190*BASE_TIME);
  1951.             } else m_uiBladeFlurryTimer -= uiDiff;
  1952.  
  1953.             boss_faction_championsAI::UpdateAI(uiDiff);
  1954.         }
  1955.     };
  1956.  
  1957. };
  1958.  
  1959. enum eEnhShamanSpells
  1960. {
  1961.     SPELL_EARTH_SHOCK_ENH   = 65973, //6s
  1962.     SPELL_LAVA_LASH         = 65974, //6s
  1963.     SPELL_STORMSTRIKE       = 65970, //8s
  1964. };
  1965.  
  1966. class mob_toc_enh_shaman : public CreatureScript
  1967. {
  1968. public:
  1969.     mob_toc_enh_shaman() : CreatureScript("mob_toc_enh_shaman") { }
  1970.  
  1971.     CreatureAI* GetAI(Creature* creature) const
  1972.     {
  1973.         return new mob_toc_enh_shamanAI (creature);
  1974.     }
  1975.  
  1976.     struct mob_toc_enh_shamanAI : public boss_faction_championsAI
  1977.     {
  1978.         mob_toc_enh_shamanAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE), Summons(me) {}
  1979.  
  1980.         SummonList Summons;
  1981.  
  1982.         uint32 m_uiHeroismOrBloodlustTimer;
  1983.         uint32 m_uiEarthShockTimer;
  1984.         uint32 m_uiStormstrikeTimer;
  1985.         uint32 m_uiLavaLashTimer;
  1986.         uint32 m_uiDeployTotemTimer;
  1987.         uint8  m_uiTotemCount;
  1988.         float  m_fTotemOldCenterX, m_fTotemOldCenterY;
  1989.  
  1990.         void Reset()
  1991.         {
  1992.             boss_faction_championsAI::Reset();
  1993.             m_uiHeroismOrBloodlustTimer = urand(25*BASE_TIME, 50*BASE_TIME);
  1994.             m_uiEarthShockTimer = urand(5*BASE_TIME, 8*BASE_TIME);
  1995.             m_uiStormstrikeTimer = urand(5*BASE_TIME, 10*BASE_TIME);
  1996.             m_uiLavaLashTimer = urand(5*BASE_TIME, 8*BASE_TIME);
  1997.             m_uiDeployTotemTimer = urand(1*BASE_TIME, 3*BASE_TIME);
  1998.             m_uiTotemCount = 0;
  1999.             m_fTotemOldCenterX = me->GetPositionX();
  2000.             m_fTotemOldCenterY = me->GetPositionY();
  2001.             SetEquipmentSlots(false, 51803, 48013, EQUIP_NO_CHANGE);
  2002.             Summons.DespawnAll();
  2003.         }
  2004.  
  2005.         void JustSummoned(Creature* summoned)
  2006.         {
  2007.             Summons.Summon(summoned);
  2008.         }
  2009.  
  2010.         void SummonedCreatureDespawn(Creature* /*pSummoned*/)
  2011.         {
  2012.             --m_uiTotemCount;
  2013.         }
  2014.  
  2015.         void DeployTotem()
  2016.         {
  2017.             m_uiTotemCount = 4;
  2018.             m_fTotemOldCenterX = me->GetPositionX();
  2019.             m_fTotemOldCenterY = me->GetPositionY();
  2020.             /*
  2021.             -Windfury (16% melee haste)
  2022.             -Grounding (redirects one harmful magic spell to the totem)
  2023.  
  2024.             -Healing Stream (unable to find amount of healing in our logs)
  2025.  
  2026.             -Tremor (prevents fear effects)
  2027.             -Strength of Earth (155 strength and agil for the opposing team)
  2028.  
  2029.             -Searing (average ~3500 damage on a random target every ~3.5 seconds)
  2030.             */
  2031.         }
  2032.  
  2033.         void JustDied(Unit* killer)
  2034.         {
  2035.             boss_faction_championsAI::JustDied(killer);
  2036.             Summons.DespawnAll();
  2037.         }
  2038.  
  2039.         void UpdateAI(const uint32 uiDiff)
  2040.         {
  2041.             if (!UpdateVictim()) return;
  2042.  
  2043.             if (m_uiHeroismOrBloodlustTimer <= uiDiff)
  2044.             {
  2045.                 if (me->getFaction()) //Am i alliance?
  2046.                 {
  2047.                     if (!me->HasAura(AURA_EXHAUSTION))
  2048.                         DoCastAOE(SPELL_HEROISM);
  2049.                 }
  2050.                 else
  2051.                     if (!me->HasAura(AURA_SATED))
  2052.                         DoCastAOE(SPELL_BLOODLUST);
  2053.                 m_uiHeroismOrBloodlustTimer = 360*BASE_TIME;
  2054.             } else m_uiHeroismOrBloodlustTimer -= uiDiff;
  2055.  
  2056.             if (m_uiEarthShockTimer <= uiDiff)
  2057.             {
  2058.                 DoCastVictim(SPELL_EARTH_SHOCK_ENH);
  2059.                 m_uiEarthShockTimer = urand(6*BASE_TIME, 9*BASE_TIME);
  2060.             } else m_uiEarthShockTimer -= uiDiff;
  2061.  
  2062.             if (m_uiStormstrikeTimer <= uiDiff)
  2063.             {
  2064.                 DoCastVictim(SPELL_STORMSTRIKE);
  2065.                 m_uiStormstrikeTimer = urand(8*BASE_TIME, 15*BASE_TIME);
  2066.             } else m_uiStormstrikeTimer -= uiDiff;
  2067.  
  2068.             if (m_uiLavaLashTimer <= uiDiff)
  2069.             {
  2070.                 DoCastVictim(SPELL_LAVA_LASH);
  2071.                 m_uiLavaLashTimer = urand(6*BASE_TIME, 9*BASE_TIME);
  2072.             } else m_uiLavaLashTimer -= uiDiff;
  2073.  
  2074.             if (m_uiDeployTotemTimer <= uiDiff)
  2075.             {
  2076.                 if (m_uiTotemCount < 4 || me->GetDistance2d(m_fTotemOldCenterX, m_fTotemOldCenterY) > 20.0f)
  2077.                     DeployTotem();
  2078.                 m_uiDeployTotemTimer = urand(1*BASE_TIME, 3*BASE_TIME);
  2079.             } else m_uiDeployTotemTimer -= uiDiff;
  2080.  
  2081.             boss_faction_championsAI::UpdateAI(uiDiff);
  2082.         }
  2083.     };
  2084.  
  2085. };
  2086.  
  2087. enum eRetroPaladinSpells
  2088. {
  2089.     SPELL_AVENGING_WRATH        = 66011, //3min cd
  2090.     SPELL_CRUSADER_STRIKE       = 66003, //6sec cd
  2091.     SPELL_DIVINE_SHIELD         = 66010, //5min cd
  2092.     SPELL_DIVINE_STORM          = 66006, //10sec cd
  2093.     SPELL_HAMMER_OF_JUSTICE_RET = 66007, //40sec cd
  2094.     SPELL_HAND_OF_PROTECTION_RET = 66009, //5min cd
  2095.     SPELL_JUDGEMENT_OF_COMMAND  = 66005, //8sec cd
  2096.     SPELL_REPENTANCE            = 66008, //60sec cd
  2097.     SPELL_SEAL_OF_COMMAND       = 66004,
  2098. };
  2099.  
  2100. class mob_toc_retro_paladin : public CreatureScript
  2101. {
  2102. public:
  2103.     mob_toc_retro_paladin() : CreatureScript("mob_toc_retro_paladin") { }
  2104.  
  2105.     CreatureAI* GetAI(Creature* creature) const
  2106.     {
  2107.         return new mob_toc_retro_paladinAI (creature);
  2108.     }
  2109.  
  2110.     struct mob_toc_retro_paladinAI : public boss_faction_championsAI
  2111.     {
  2112.         mob_toc_retro_paladinAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
  2113.  
  2114.         uint32 m_uiRepeteanceTimer;
  2115.         uint32 m_uiCrusaderStrikeTimer;
  2116.         uint32 m_uiAvengingWrathTimer;
  2117.         uint32 m_uiDivineShieldTimer;
  2118.         uint32 m_uiDivineStormTimer;
  2119.         uint32 m_uiJudgementOfCommandTimer;
  2120.  
  2121.         void Reset()
  2122.         {
  2123.             boss_faction_championsAI::Reset();
  2124.             m_uiRepeteanceTimer = 30*BASE_TIME;
  2125.             m_uiCrusaderStrikeTimer = urand(6*BASE_TIME, 13*BASE_TIME);
  2126.             m_uiAvengingWrathTimer = urand(5*BASE_TIME, 25*BASE_TIME);
  2127.             m_uiDivineShieldTimer = urand(0*BASE_TIME, 360*BASE_TIME);
  2128.             m_uiDivineStormTimer = 10*BASE_TIME;
  2129.             m_uiJudgementOfCommandTimer = urand(8*BASE_TIME, 15*BASE_TIME);
  2130.             SetEquipmentSlots(false, 47519, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  2131.         }
  2132.  
  2133.         void EnterCombat(Unit* who)
  2134.         {
  2135.             boss_faction_championsAI::EnterCombat(who);
  2136.             DoCast(SPELL_SEAL_OF_COMMAND);
  2137.         }
  2138.  
  2139.         void UpdateAI(const uint32 uiDiff)
  2140.         {
  2141.             if (!UpdateVictim()) return;
  2142.  
  2143.             if (m_uiRepeteanceTimer <= uiDiff)
  2144.             {
  2145.                 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
  2146.                     DoCast(target, SPELL_REPENTANCE);
  2147.                 m_uiRepeteanceTimer = 60*BASE_TIME;
  2148.             } else m_uiRepeteanceTimer -= uiDiff;
  2149.  
  2150.             if (m_uiCrusaderStrikeTimer <= uiDiff)
  2151.             {
  2152.                 DoCastVictim(SPELL_CRUSADER_STRIKE);
  2153.                 m_uiCrusaderStrikeTimer = urand(6*BASE_TIME, 13*BASE_TIME);
  2154.             } else m_uiCrusaderStrikeTimer -= uiDiff;
  2155.  
  2156.             if (m_uiAvengingWrathTimer <= uiDiff)
  2157.             {
  2158.                 DoCastVictim(SPELL_AVENGING_WRATH);
  2159.                 m_uiAvengingWrathTimer = 180*BASE_TIME;
  2160.             } else m_uiAvengingWrathTimer -= uiDiff;
  2161.  
  2162.             if (m_uiDivineShieldTimer <= uiDiff)
  2163.             {
  2164.                 if (HealthBelowPct(20))
  2165.                     DoCast(me, SPELL_DIVINE_SHIELD);
  2166.                 m_uiDivineShieldTimer = urand(0*BASE_TIME, 360*BASE_TIME);
  2167.             } else m_uiDivineShieldTimer -= uiDiff;
  2168.  
  2169.             if (m_uiDivineStormTimer <= uiDiff)
  2170.             {
  2171.                 DoCastVictim(SPELL_DIVINE_STORM);
  2172.                 m_uiDivineStormTimer = urand(10*BASE_TIME, 15*BASE_TIME);
  2173.             } else m_uiDivineStormTimer -= uiDiff;
  2174.  
  2175.             if (m_uiJudgementOfCommandTimer <= uiDiff)
  2176.             {
  2177.                 DoCastVictim(SPELL_JUDGEMENT_OF_COMMAND);
  2178.                 m_uiJudgementOfCommandTimer = urand(8*BASE_TIME, 15*BASE_TIME);
  2179.             } else m_uiJudgementOfCommandTimer -= uiDiff;
  2180.  
  2181.             boss_faction_championsAI::UpdateAI(uiDiff);
  2182.         }
  2183.     };
  2184.  
  2185. };
  2186.  
  2187. enum eWarlockPetSpells
  2188. {
  2189.     SPELL_DEVOUR_MAGIC  = 67518, //8s
  2190.     SPELL_SPELL_LOCK  = 67519, //24s
  2191. };
  2192.  
  2193. class mob_toc_pet_warlock : public CreatureScript
  2194. {
  2195. public:
  2196.     mob_toc_pet_warlock() : CreatureScript("mob_toc_pet_warlock") { }
  2197.  
  2198.     CreatureAI* GetAI(Creature* creature) const
  2199.     {
  2200.         return new mob_toc_pet_warlockAI (creature);
  2201.     }
  2202.  
  2203.     struct mob_toc_pet_warlockAI : public boss_faction_championsAI
  2204.     {
  2205.         mob_toc_pet_warlockAI(Creature* creature) : boss_faction_championsAI(creature, AI_PET) {}
  2206.  
  2207.         uint32 m_uiDevourMagicTimer;
  2208.         uint32 m_uiSpellLockTimer;
  2209.  
  2210.         void Reset()
  2211.         {
  2212.             boss_faction_championsAI::Reset();
  2213.             m_uiDevourMagicTimer = urand(8*BASE_TIME, 20*BASE_TIME);
  2214.             m_uiSpellLockTimer = urand(15*BASE_TIME, 30*BASE_TIME);
  2215.         }
  2216.  
  2217.         void UpdateAI(const uint32 uiDiff)
  2218.         {
  2219.             if (!UpdateVictim()) return;
  2220.  
  2221.             if (m_uiDevourMagicTimer <= uiDiff)
  2222.             {
  2223.                 DoCastVictim(SPELL_DEVOUR_MAGIC);
  2224.                 m_uiDevourMagicTimer = urand(8*BASE_TIME, 20*BASE_TIME);
  2225.             } else m_uiDevourMagicTimer -= uiDiff;
  2226.  
  2227.             if (m_uiSpellLockTimer <= uiDiff)
  2228.             {
  2229.                 DoCastVictim(SPELL_SPELL_LOCK);
  2230.                 m_uiSpellLockTimer = urand(24*BASE_TIME, 30*BASE_TIME);
  2231.             } else m_uiSpellLockTimer -= uiDiff;
  2232.  
  2233.             boss_faction_championsAI::UpdateAI(uiDiff);
  2234.         }
  2235.     };
  2236.  
  2237. };
  2238.  
  2239. enum eHunterPetSpells
  2240. {
  2241.     SPELL_CLAW  = 67793,
  2242. };
  2243.  
  2244. class mob_toc_pet_hunter : public CreatureScript
  2245. {
  2246. public:
  2247.     mob_toc_pet_hunter() : CreatureScript("mob_toc_pet_hunter") { }
  2248.  
  2249.     CreatureAI* GetAI(Creature* creature) const
  2250.     {
  2251.         return new mob_toc_pet_hunterAI (creature);
  2252.     }
  2253.  
  2254.     struct mob_toc_pet_hunterAI : public boss_faction_championsAI
  2255.     {
  2256.         mob_toc_pet_hunterAI(Creature* creature) : boss_faction_championsAI(creature, AI_PET) {}
  2257.  
  2258.         uint32 m_uiClawTimer;
  2259.  
  2260.         void Reset()
  2261.         {
  2262.             boss_faction_championsAI::Reset();
  2263.             m_uiClawTimer = urand(5*BASE_TIME, 10*BASE_TIME);
  2264.         }
  2265.  
  2266.         void UpdateAI(const uint32 uiDiff)
  2267.         {
  2268.             if (!UpdateVictim()) return;
  2269.  
  2270.             if (m_uiClawTimer <= uiDiff)
  2271.             {
  2272.                 DoCastVictim(SPELL_CLAW);
  2273.                 m_uiClawTimer = urand(5*BASE_TIME, 10*BASE_TIME);
  2274.             } else m_uiClawTimer -= uiDiff;
  2275.  
  2276.             boss_faction_championsAI::UpdateAI(uiDiff);
  2277.         }
  2278.     };
  2279.  
  2280. };
  2281.  
  2282. /*========================================================*/
  2283.  
  2284. void AddSC_boss_faction_champions()
  2285. {
  2286.     new boss_toc_champion_controller();
  2287.     new mob_toc_druid();
  2288.     new mob_toc_shaman();
  2289.     new mob_toc_paladin();
  2290.     new mob_toc_priest();
  2291.     new mob_toc_shadow_priest();
  2292.     new mob_toc_mage();
  2293.     new mob_toc_warlock();
  2294.     new mob_toc_hunter();
  2295.     new mob_toc_boomkin();
  2296.     new mob_toc_warrior();
  2297.     new mob_toc_dk();
  2298.     new mob_toc_rogue();
  2299.     new mob_toc_enh_shaman();
  2300.     new mob_toc_retro_paladin();
  2301.     new mob_toc_pet_warlock();
  2302.     new mob_toc_pet_hunter();
  2303. }