Share Pastebin
Guest
Public paste!

Gigatotem

By: a guest | Mar 21st, 2010 | Syntax: C++ | Size: 28.44 KB | Hits: 102 | Expires: Never
Copy text to clipboard
  1. /*
  2.  * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17.  */
  18.  
  19. /*
  20.     TODO:
  21.         Add achievments
  22.         Boombot explosion only hurt allies to the npc at the moment
  23.         Boombot explosion visual
  24.         Test the enrage timer
  25.         Fix gravity bomb - tractor beam.
  26.         Fix void zone spell
  27.         If the boss is to close to a scrap pile -> no summon
  28.         make the life sparks visible...
  29. */
  30.  
  31. #include "ScriptedPch.h"
  32. #include "ulduar.h"
  33.  
  34. enum Spells
  35. {
  36.     SPELL_TYMPANIC_TANTRUM                      = 62776,
  37.     SPELL_SEARING_LIGHT_10                      = 63018,
  38.     SPELL_SEARING_LIGHT_25                      = 65121,
  39.  
  40.     SPELL_GRAVITY_BOMB_10                       = 63024,
  41.     SPELL_GRAVITY_BOMB_25                       = 63234,
  42.     SPELL_GRAVITY_BOMB_AURA_10                  = 63025,
  43.     SPELL_GRAVITY_BOMB_AURA_25                  = 63233,
  44.  
  45.     SPELL_HEARTBREAK_10                         = 65737,
  46.     SPELL_HEARTBREAK_25                         = 64193,
  47.  
  48.     SPELL_ENRAGE                                = 26662,
  49.  
  50.     //------------------VOID ZONE--------------------
  51.     SPELL_VOID_ZONE_10                          = 64203,
  52.     SPELL_VOID_ZONE_25                          = 64235,
  53.  
  54.     // Life Spark
  55.     SPELL_STATIC_CHARGED_10                     = 64227,
  56.     SPELL_STATIC_CHARGED_25                     = 64236,
  57.     SPELL_SHOCK                                 = 64230,
  58.  
  59.     //----------------XT-002 HEART-------------------
  60.     SPELL_EXPOSED_HEART                         = 63849,
  61.  
  62.     //---------------XM-024 PUMMELLER----------------
  63.     SPELL_ARCING_SMASH                          = 8374,
  64.     SPELL_TRAMPLE                               = 5568,
  65.     SPELL_UPPERCUT                              = 10966,
  66.  
  67.     //------------------BOOMBOT-----------------------
  68.     SPELL_BOOM                                  = 62834,
  69. };
  70.  
  71. enum Timers
  72. {
  73.     TIMER_TYMPANIC_TANTRUM_MIN                  = 32000,
  74.     TIMER_TYMPANIC_TANTRUM_MAX                  = 36000,
  75.     TIMER_SEARING_LIGHT                         = 20000,
  76.     TIMER_SPAWN_LIFE_SPARK                      = 9000,
  77.     TIMER_GRAVITY_BOMB                          = 20000,
  78.     TIMER_HEART_PHASE                           = 30000,
  79.     TIMER_ENRAGE                                = 600000,
  80.     TIMER_GRAVITY_BOMB_AURA                     = 8900,
  81.  
  82.     TIMER_VOID_ZONE                             = 3000,
  83.  
  84.     // Life Spark
  85.     TIMER_SHOCK                                 = 12000,
  86.  
  87.     // Pummeller
  88.     // Timers may be off
  89.     TIMER_ARCING_SMASH                          = 27000,
  90.     TIMER_TRAMPLE                               = 22000,
  91.     TIMER_UPPERCUT                              = 17000,
  92.  
  93.     TIMER_SPAWN_ADD                             = 12000,
  94. };
  95.  
  96. enum Creatures
  97. {
  98.     NPC_VOID_ZONE                               = 34001,
  99.     NPC_LIFE_SPARK                              = 34004,
  100.     NPC_XT002_HEART                             = 33329,
  101.     NPC_XS013_SCRAPBOT                          = 33343,
  102.     NPC_XM024_PUMMELLER                         = 33344,
  103.     NPC_XE321_BOOMBOT                           = 33346,
  104. };
  105.  
  106. enum Actions
  107. {
  108.     ACTION_ENTER_HARD_MODE                      = 0,
  109. };
  110.  
  111. enum XT002Data
  112. {
  113.     DATA_TRANSFERED_HEALTH                      = 0,
  114. };
  115.  
  116. enum Yells
  117. {
  118.     SAY_AGGRO                                   = -1603300,
  119.     SAY_HEART_OPENED                            = -1603301,
  120.     SAY_HEART_CLOSED                            = -1603302,
  121.     SAY_TYMPANIC_TANTRUM                        = -1603303,
  122.     SAY_SLAY_1                                  = -1603304,
  123.     SAY_SLAY_2                                  = -1603305,
  124.     SAY_BERSERK                                 = -1603306,
  125.     SAY_DEATH                                   = -1603307,
  126.     SAY_SUMMON                                  = -1603308,
  127. };
  128.  
  129. //#define GRAVITY_BOMB_DMG_MIN_10                11700
  130. //#define GRAVITY_BOMB_DMG_MAX_10                12300
  131. //#define GRAVITY_BOMB_DMG_MIN_25                14625
  132. //#define GRAVITY_BOMB_DMG_MAX_25                15375
  133. //#define GRAVITY_BOMB_RADIUS                    12
  134.  
  135. //#define VOID_ZONE_DMG_10                      5000
  136. //#define VOID_ZONE_DMG_25                      7500
  137. //#define VOID_ZONE_RADIUS                      
  138.  
  139.  
  140. /************************************************
  141. -----------------SPAWN LOCATIONS-----------------
  142. ************************************************/
  143. //Shared Z-level
  144. #define SPAWN_Z                                 412
  145. //Lower right
  146. #define LR_X                                    796
  147. #define LR_Y                                    -94
  148. //Lower left
  149. #define LL_X                                    796
  150. #define LL_Y                                    57
  151. //Upper right
  152. #define UR_X                                    890
  153. #define UR_Y                                    -82
  154. //Upper left
  155. #define UL_X                                    894
  156. #define UL_Y                                    62
  157.  
  158. /*-------------------------------------------------------
  159.  *
  160.  *        XT-002 DECONSTRUCTOR
  161.  *
  162.  *///----------------------------------------------------
  163. struct boss_xt002_AI : public BossAI
  164. {
  165.     boss_xt002_AI(Creature *pCreature) : BossAI(pCreature, TYPE_XT002)
  166.     {
  167.     }
  168.  
  169.     uint32 uiSearingLightTimer;
  170.     uint32 uiSpawnLifeSparkTimer;
  171.     uint32 uiGravityBombTimer;
  172.     uint32 uiGravityBombAuraTimer;
  173.     uint32 uiTympanicTantrumTimer;
  174.     uint32 uiHeartPhaseTimer;
  175.     uint32 uiSpawnAddTimer;
  176.     uint32 uiEnrageTimer;
  177.    
  178.     bool searing_light_active;
  179.     uint64 uiSearingLightTarget;
  180.  
  181.     bool gravity_bomb_active;
  182.     uint64 uiGravityBombTarget;
  183.  
  184.     uint8 phase;
  185.     uint8 heart_exposed;
  186.     bool enraged;
  187.  
  188.     uint32 transferHealth;
  189.     bool enterHardMode;
  190.     bool hardMode;
  191.  
  192.     void Reset()
  193.     {
  194.         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
  195.  
  196.         //Makes XT-002 to cast a light bomb 10 seconds after aggro.
  197.         uiSearingLightTimer = TIMER_SEARING_LIGHT/2;
  198.         uiSpawnLifeSparkTimer = TIMER_SPAWN_LIFE_SPARK;
  199.         uiGravityBombTimer = TIMER_GRAVITY_BOMB;
  200.         uiGravityBombAuraTimer = TIMER_GRAVITY_BOMB_AURA;
  201.         uiHeartPhaseTimer = TIMER_HEART_PHASE;
  202.         uiSpawnAddTimer = TIMER_SPAWN_ADD;
  203.         uiEnrageTimer = TIMER_ENRAGE;
  204.  
  205.         //Tantrum is casted a bit slower the first time.
  206.         uiTympanicTantrumTimer = urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX) * 2;
  207.  
  208.         searing_light_active = false;
  209.         gravity_bomb_active = false;
  210.         enraged = false;
  211.         hardMode = false;
  212.         enterHardMode = false;
  213.  
  214.         phase = 1;
  215.         heart_exposed = 0;
  216.     }
  217.  
  218.     void EnterCombat(Unit* who)
  219.     {
  220.         DoScriptText(SAY_AGGRO, m_creature);
  221.         _EnterCombat();
  222.     }
  223.  
  224.     void DoAction(const int32 action)
  225.     {
  226.         switch (action)
  227.         {
  228.             case ACTION_ENTER_HARD_MODE:
  229.                 if (!hardMode)
  230.                 {
  231.                     hardMode = true;
  232.  
  233.                     // Enter hard mode
  234.                     enterHardMode = true;
  235.  
  236.                     // set max health
  237.                     m_creature->SetHealth(m_creature->GetMaxHealth());
  238.  
  239.                     // Get his heartbreak buff
  240.                     m_creature->CastSpell(m_creature, RAID_MODE(SPELL_HEARTBREAK_10, SPELL_HEARTBREAK_25), true);
  241.                 }
  242.                 break;
  243.         }
  244.     }
  245.  
  246.     void SetData(uint32 id, uint32 value)
  247.     {
  248.         switch(id)
  249.         {
  250.             case DATA_TRANSFERED_HEALTH:
  251.                 transferHealth = value;
  252.                 break;
  253.         }
  254.     }
  255.  
  256.     void KilledUnit(Unit* victim)
  257.     {
  258.         DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature);
  259.     }
  260.  
  261.     void JustDied(Unit *victim)
  262.     {
  263.         DoScriptText(SAY_DEATH, m_creature);
  264.         _JustDied();
  265.     }
  266.  
  267.     void UpdateAI(const uint32 diff)
  268.     {
  269.         if (!UpdateVictim())
  270.             return;
  271.  
  272.         if (enterHardMode)
  273.         {
  274.             SetPhaseOne();
  275.             enterHardMode = false;
  276.         }
  277.  
  278.         // Handles spell casting. These spells only occur during phase 1 and hard mode
  279.         if (phase == 1 || hardMode)
  280.         {
  281.             if (uiSearingLightTimer <= diff)
  282.             {
  283.                 if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
  284.                 {
  285.                     DoCast(pTarget, RAID_MODE(SPELL_SEARING_LIGHT_10, SPELL_SEARING_LIGHT_25));
  286.                     uiSearingLightTarget = pTarget->GetGUID();
  287.                 }
  288.                 uiSpawnLifeSparkTimer = TIMER_SPAWN_LIFE_SPARK;
  289.                 if (hardMode)
  290.                     searing_light_active = true;
  291.                 uiSearingLightTimer = TIMER_SEARING_LIGHT;
  292.             } else uiSearingLightTimer -= diff;
  293.  
  294.             if (uiGravityBombTimer <= diff)
  295.             {
  296.                 if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
  297.                 {
  298.                     DoCast(pTarget, RAID_MODE(SPELL_GRAVITY_BOMB_10,SPELL_GRAVITY_BOMB_25));
  299.                     uiGravityBombTarget = pTarget->GetGUID();
  300.                 }
  301.                 uiGravityBombTimer = TIMER_GRAVITY_BOMB;
  302.                 gravity_bomb_active = true;
  303.             } else uiGravityBombTimer -= diff;
  304.  
  305.             if (uiTympanicTantrumTimer <= 0)
  306.             {
  307.                 DoScriptText(SAY_TYMPANIC_TANTRUM, m_creature);
  308.                 DoCast(SPELL_TYMPANIC_TANTRUM);
  309.                 uiTympanicTantrumTimer = urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX);
  310.             } else uiTympanicTantrumTimer -= diff;
  311.         }
  312.  
  313.         if (!hardMode)
  314.         {
  315.             if (phase == 1)
  316.             {
  317.                 if (HealthBelowPct(75) && heart_exposed == 0)
  318.                 {
  319.                     exposeHeart();
  320.                 }
  321.                 else if (HealthBelowPct(50) && heart_exposed == 1)
  322.                 {
  323.                     exposeHeart();
  324.                 }
  325.                 else if (HealthBelowPct(25) && heart_exposed == 2)
  326.                 {
  327.                     exposeHeart();
  328.                 }
  329.  
  330.                 DoMeleeAttackIfReady();
  331.             }
  332.             else
  333.             {
  334.                 //Stop moving
  335.                 m_creature->StopMoving();
  336.  
  337.                 //Start summoning adds
  338.                 if (uiSpawnAddTimer <= diff)
  339.                 {
  340.                     DoScriptText(SAY_SUMMON, m_creature);
  341.  
  342.                     // Spawn Pummeller
  343.                     switch (rand() % 4)
  344.                     {
  345.                         case 0: m_creature->SummonCreature(NPC_XM024_PUMMELLER, LR_X, LR_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  346.                         case 1: m_creature->SummonCreature(NPC_XM024_PUMMELLER, LL_X, LL_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  347.                         case 2: m_creature->SummonCreature(NPC_XM024_PUMMELLER, UR_X, UR_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  348.                         case 3: m_creature->SummonCreature(NPC_XM024_PUMMELLER, UL_X, UL_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  349.                     }
  350.  
  351.                     // Spawn 5 Bombs
  352.                     for (int8 n = 0; n < 5; n++)
  353.                     {
  354.                         //Some randomes are added so they wont spawn in a pile
  355.                         switch(rand() % 4)
  356.                         {
  357.                             case 0: m_creature->SummonCreature(NPC_XS013_SCRAPBOT, irand(LR_X - 3, LR_X + 3), irand(LR_Y - 3, LR_Y + 3), SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  358.                             case 1: m_creature->SummonCreature(NPC_XS013_SCRAPBOT, irand(LL_X - 3, LL_X + 3), irand(LL_Y - 3, LL_Y + 3), SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  359.                             case 2: m_creature->SummonCreature(NPC_XS013_SCRAPBOT, irand(UR_X - 3, UR_X + 3), irand(UR_Y - 3, UR_Y + 3), SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  360.                             case 3: m_creature->SummonCreature(NPC_XS013_SCRAPBOT, irand(UL_X - 3, UL_X + 3), irand(UL_Y - 3, UL_Y + 3), SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  361.                         }
  362.                     }
  363.            
  364.                     //Spawn 5 Scrapbots
  365.                     switch (rand() % 4)
  366.                     {
  367.                         case 0: m_creature->SummonCreature(NPC_XE321_BOOMBOT, LR_X, LR_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  368.                         case 1: m_creature->SummonCreature(NPC_XE321_BOOMBOT, LL_X, LL_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  369.                         case 2: m_creature->SummonCreature(NPC_XE321_BOOMBOT, UR_X, UR_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  370.                         case 3: m_creature->SummonCreature(NPC_XE321_BOOMBOT, UL_X, UL_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
  371.                     }
  372.  
  373.                     uiSpawnAddTimer = TIMER_SPAWN_ADD;
  374.                 } else uiSpawnAddTimer -= diff;
  375.  
  376.                 // Is the phase over?
  377.                 if (uiHeartPhaseTimer <= diff)
  378.                 {
  379.                     DoScriptText(SAY_HEART_CLOSED, m_creature);
  380.                     SetPhaseOne();
  381.                 }
  382.                 else
  383.                     uiHeartPhaseTimer -= diff;
  384.             }
  385.         }
  386.         else
  387.         {
  388.             // Adding life sparks when searing light debuff runs out if hard mode
  389.             if (searing_light_active)
  390.             {
  391.                 if (uiSpawnLifeSparkTimer <= diff)
  392.                 {
  393.                     if (Unit *pSearingLightTarget = m_creature->GetUnit(*m_creature, uiSearingLightTarget))
  394.                         pSearingLightTarget->SummonCreature(NPC_LIFE_SPARK, pSearingLightTarget->GetPositionX(), pSearingLightTarget->GetPositionY(), pSearingLightTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
  395.                     uiSpawnLifeSparkTimer = TIMER_SPAWN_LIFE_SPARK;
  396.                     searing_light_active = false;
  397.                 } else uiSpawnLifeSparkTimer -= diff;
  398.             }
  399.  
  400.             DoMeleeAttackIfReady();
  401.         }
  402.        
  403.         if (gravity_bomb_active)
  404.         {
  405.             if (uiGravityBombAuraTimer <= diff)
  406.             {
  407.                 if (Unit *pGravityBombTarget = m_creature->GetUnit(*m_creature, uiGravityBombTarget))
  408.                 {
  409.                     pGravityBombTarget->RemoveAurasDueToSpell(RAID_MODE(SPELL_GRAVITY_BOMB_10,SPELL_GRAVITY_BOMB_25));
  410.                     if (hardMode)
  411.                     {
  412.                         //Remains spawned for 3 minutes
  413.                         pGravityBombTarget->SummonCreature(NPC_VOID_ZONE, pGravityBombTarget->GetPositionX(), pGravityBombTarget->GetPositionY(), pGravityBombTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
  414.                     }
  415.                 }
  416.  
  417.                 gravity_bomb_active = false;
  418.                 uiGravityBombAuraTimer = TIMER_GRAVITY_BOMB_AURA;
  419.                 //gravityBomb();
  420.             } else uiGravityBombAuraTimer -= diff;
  421.         }
  422.  
  423.         //Enrage stuff
  424.         if (!enraged)
  425.             if (uiEnrageTimer <= diff)
  426.             {
  427.                 DoScriptText(SAY_BERSERK, m_creature);
  428.                 DoCast(m_creature, SPELL_ENRAGE);
  429.                 enraged = true;
  430.             } else uiEnrageTimer -= diff;
  431.     }
  432.  
  433.     void exposeHeart()
  434.     {
  435.         //Make untargetable
  436.         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
  437.  
  438.         //Summon the heart npc
  439.         m_creature->SummonCreature(NPC_XT002_HEART, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ() + 7, 0, TEMPSUMMON_TIMED_DESPAWN, TIMER_HEART_PHASE);
  440.        
  441.         // Start "end of phase 2 timer"
  442.         uiHeartPhaseTimer = TIMER_HEART_PHASE;
  443.  
  444.         //Phase 2 has offically started
  445.         phase = 2;
  446.         heart_exposed++;
  447.  
  448.         //Reset the add spawning timer
  449.         uiSpawnAddTimer = TIMER_SPAWN_ADD;
  450.  
  451.         DoScriptText(SAY_HEART_OPENED, m_creature);
  452.     }
  453.  
  454.     void SetPhaseOne()
  455.     {
  456.         uiSearingLightTimer = TIMER_SEARING_LIGHT / 2;
  457.         uiGravityBombTimer = TIMER_GRAVITY_BOMB;
  458.         uiTympanicTantrumTimer = urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX);
  459.         uiSpawnAddTimer = TIMER_SPAWN_ADD;
  460.  
  461.         if (!hardMode)
  462.             m_creature->ModifyHealth(-transferHealth);
  463.  
  464.         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
  465.         phase = 1;
  466.     }
  467.  
  468.     // TODO: put in comment and kept for reference. The spell should be fixed properly in spell system, if necessary.
  469.     ////Have to do this the custom way since the original spell messes up player movement
  470.     //void gravityBomb()
  471.     //{
  472.     //    uint32 maxDamage = RAID_MODE(GRAVITY_BOMB_DMG_MAX_10, GRAVITY_BOMB_DMG_MAX_25);
  473.     //    uint32 minDamage = RAID_MODE(GRAVITY_BOMB_DMG_MIN_10, GRAVITY_BOMB_DMG_MIN_25);
  474.     //    uint16 range = GRAVITY_BOMB_RADIUS;
  475.     //    Map* pMap = me->GetMap();
  476.     //    if (pMap && pMap->IsDungeon())
  477.     //    {
  478.     //        Map::PlayerList const &PlayerList = pMap->GetPlayers();
  479.     //        for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
  480.     //        {
  481.     //            //If a player is within the range of the spell
  482.     //            if (i->getSource() && i->getSource()->GetDistance2d(pGravityBombTarget) <= range)
  483.     //            {
  484.     //                //Deal damage to the victim
  485.     //                int32 damage = urand(minDamage, maxDamage);
  486.     //                i->getSource()->ModifyHealth(-damage);
  487.     //                m_creature->SendSpellNonMeleeDamageLog(i->getSource(), SPELL_GRAVITY_BOMB_AURA_10, damage, SPELL_SCHOOL_MASK_SHADOW, 0, 0, false, 0);
  488.  
  489.     //                //Replacing the tractor beam effect
  490.     //                i->getSource()->JumpTo(pGravityBombTarget, 5);
  491.     //            }
  492.     //        }
  493.     //    }
  494.     //}
  495. };
  496.  
  497. CreatureAI* GetAI_boss_xt002(Creature* pCreature)
  498. {
  499.     return new boss_xt002_AI(pCreature);
  500. }
  501.  
  502. /*-------------------------------------------------------
  503.  *
  504.  *        XT-002 HEART
  505.  *
  506.  *///----------------------------------------------------
  507. struct mob_xt002_heartAI : public ScriptedAI
  508. {
  509.     mob_xt002_heartAI(Creature* pCreature) : ScriptedAI(pCreature)
  510.     {
  511.         m_pInstance = pCreature->GetInstanceData();
  512.         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED);
  513.         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
  514.         DoCast(m_creature, SPELL_EXPOSED_HEART);
  515.     }
  516.  
  517.     ScriptedInstance* m_pInstance;
  518.  
  519.     void JustDied(Unit *victim)
  520.     {
  521.         if (m_pInstance)
  522.             if (Creature* pXT002 = m_creature->GetCreature(*m_creature, m_pInstance->GetData64(TYPE_XT002)))
  523.                 if (pXT002->AI())
  524.                     pXT002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
  525.  
  526.         //removes the aura
  527.         m_creature->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART);
  528.     }
  529.  
  530.     void DamageTaken(Unit *pDone, uint32 &damage)
  531.     {
  532.         if (Creature* pXT002 = m_creature->GetCreature(*m_creature, m_pInstance->GetData64(TYPE_XT002)))
  533.             if (pXT002->AI())
  534.             {
  535.                 uint32 health = m_creature->GetHealth();
  536.                 health -= damage;
  537.                 if (health < 0)
  538.                     health = 0;
  539.  
  540.                 pXT002->AI()->SetData(DATA_TRANSFERED_HEALTH, m_creature->GetMaxHealth() - health);
  541.             }
  542.     }
  543. };
  544.  
  545. CreatureAI* GetAI_mob_xt002_heart(Creature* pCreature)
  546. {
  547.     return new mob_xt002_heartAI(pCreature);
  548. }
  549.  
  550. /*-------------------------------------------------------
  551.  *
  552.  *        XS-013 SCRAPBOT
  553.  *
  554.  *///----------------------------------------------------
  555. struct mob_scrapbotAI : public ScriptedAI
  556. {
  557.     mob_scrapbotAI(Creature* pCreature) : ScriptedAI(pCreature)
  558.     {
  559.         m_pInstance = m_creature->GetInstanceData();
  560.     }
  561.  
  562.     ScriptedInstance* m_pInstance;
  563.  
  564.     void Reset()
  565.     {
  566.         m_creature->SetReactState(REACT_PASSIVE);
  567.  
  568.         if (Creature* pXT002 = m_creature->GetCreature(*m_creature, m_pInstance->GetData64(TYPE_XT002)))
  569.             m_creature->GetMotionMaster()->MoveChase(pXT002);
  570.     }
  571.  
  572.     void UpdateAI(const uint32 diff)
  573.     {
  574.         if (Creature* pXT002 = m_creature->GetCreature(*m_creature, m_pInstance->GetData64(TYPE_XT002)))
  575.         {
  576.             if (m_creature->GetDistance2d(pXT002) <= 0.5)
  577.             {
  578.                 // TODO Send raid message
  579.  
  580.                 // Increase health with 1 percent
  581.                 pXT002->ModifyHealth(pXT002->GetMaxHealth() * 0.01);
  582.  
  583.                 // Despawns the scrapbot
  584.                 m_creature->ForcedDespawn();
  585.             }
  586.         }
  587.     }
  588. };
  589.  
  590. CreatureAI* GetAI_mob_scrapbot(Creature* pCreature)
  591. {
  592.     return new mob_scrapbotAI(pCreature);
  593. }
  594.  
  595. /*-------------------------------------------------------
  596.  *
  597.  *        XM-024 PUMMELLER
  598.  *
  599.  *///----------------------------------------------------
  600. struct mob_pummellerAI : public ScriptedAI
  601. {
  602.     mob_pummellerAI(Creature* pCreature) : ScriptedAI(pCreature)
  603.     {
  604.         m_pInstance = pCreature->GetInstanceData();
  605.     }
  606.  
  607.     ScriptedInstance* m_pInstance;
  608.     int32 uiArcingSmashTimer;
  609.     int32 uiTrampleTimer;
  610.     int32 uiUppercutTimer;
  611.  
  612.     void Reset()
  613.     {
  614.         uiArcingSmashTimer = TIMER_ARCING_SMASH;
  615.         uiTrampleTimer = TIMER_TRAMPLE;
  616.         uiUppercutTimer = TIMER_UPPERCUT;
  617.     }
  618.  
  619.     void UpdateAI(const uint32 diff)
  620.     {
  621.         if (!UpdateVictim())
  622.             return;
  623.        
  624.         if (m_creature->IsWithinMeleeRange(m_creature->getVictim()))
  625.         {
  626.             if (uiArcingSmashTimer <= diff)
  627.             {
  628.                 DoCast(m_creature->getVictim(), SPELL_ARCING_SMASH);
  629.                 uiArcingSmashTimer = TIMER_ARCING_SMASH;
  630.             } else uiArcingSmashTimer -= diff;
  631.  
  632.             if (uiTrampleTimer <= diff)
  633.             {
  634.                 DoCast(m_creature->getVictim(), SPELL_TRAMPLE);
  635.                 uiTrampleTimer = TIMER_TRAMPLE;
  636.             } else uiTrampleTimer -= diff;
  637.  
  638.             if (uiUppercutTimer <= diff)
  639.             {
  640.                 DoCast(m_creature->getVictim(), SPELL_UPPERCUT);
  641.                 uiUppercutTimer = TIMER_UPPERCUT;
  642.             } else uiUppercutTimer -= diff;
  643.         }
  644.  
  645.         DoMeleeAttackIfReady();
  646.     }
  647. };
  648.  
  649. CreatureAI* GetAI_mob_pummeller(Creature* pCreature)
  650. {
  651.     return new mob_pummellerAI(pCreature);
  652. }
  653.  
  654. /*-------------------------------------------------------
  655.  *
  656.  *        XE-321 BOOMBOT
  657.  *
  658.  *///----------------------------------------------------
  659. struct mob_boombotAI : public ScriptedAI
  660. {
  661.     mob_boombotAI(Creature* pCreature) : ScriptedAI(pCreature)
  662.     {
  663.         m_pInstance = pCreature->GetInstanceData();
  664.     }
  665.  
  666.     ScriptedInstance* m_pInstance;
  667.  
  668.     void Reset()
  669.     {
  670.         m_creature->SetReactState(REACT_PASSIVE);
  671.  
  672.         if (Creature* pXT002 = m_creature->GetCreature(*m_creature, m_pInstance->GetData64(TYPE_XT002)))
  673.             m_creature->GetMotionMaster()->MoveChase(pXT002);
  674.     }
  675.  
  676.     void JustDied(Unit *killer)
  677.     {
  678.         DoCast(SPELL_BOOM);
  679.     }
  680.  
  681.     void UpdateAI(const uint32 diff)
  682.     {
  683.         if (Creature* pXT002 = m_creature->GetCreature(*m_creature, m_pInstance->GetData64(TYPE_XT002)))
  684.         {
  685.             if (m_creature->GetDistance2d(pXT002) <= 0.5)
  686.             {
  687.                 //Explosion
  688.                 DoCast(m_creature, SPELL_BOOM);
  689.  
  690.                 //Despawns the boombot
  691.                 m_creature->ForcedDespawn();
  692.             }
  693.         }
  694.     }
  695. };
  696.  
  697. CreatureAI* GetAI_mob_boombot(Creature* pCreature)
  698. {
  699.     return new mob_boombotAI(pCreature);
  700. }
  701.  
  702. /*-------------------------------------------------------
  703.  *
  704.  *        VOID ZONE
  705.  *
  706.  *///----------------------------------------------------
  707. struct mob_void_zoneAI : public ScriptedAI
  708. {
  709.     mob_void_zoneAI(Creature* pCreature) : ScriptedAI(pCreature)
  710.     {
  711.         m_pInstance = pCreature->GetInstanceData();
  712.         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
  713.     }
  714.  
  715.     ScriptedInstance* m_pInstance;
  716.     uint32 uiVoidZoneTimer;
  717.  
  718.     void Reset()
  719.     {
  720.         uiVoidZoneTimer = TIMER_VOID_ZONE;
  721.     }
  722.  
  723.     void UpdateAI(const uint32 diff)
  724.     {
  725.         if (uiVoidZoneTimer <= diff)
  726.         {
  727.             //voidZone();
  728.             uiVoidZoneTimer = TIMER_VOID_ZONE;
  729.         } else uiVoidZoneTimer -= diff;
  730.     }
  731.  
  732.     // TODO: put in comment and kept for reference. The spell should be fixed properly in spell system, if necessary.
  733.     //void voidZone()
  734.     //{
  735.     //    Map* pMap = me->GetMap();
  736.     //    if (pMap && pMap->IsDungeon())
  737.     //    {
  738.     //        Map::PlayerList const &PlayerList = pMap->GetPlayers();
  739.     //        for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
  740.     //        {
  741.     //            // If a player is within the range of the spell
  742.     //            if (i->getSource() && i->getSource()->GetDistance2d(m_creature) <= 16)
  743.     //            {
  744.     //                // Deal damage to the victim
  745.     //                int32 damage = RAID_MODE(VOID_ZONE_DMG_10, VOID_ZONE_DMG_25);
  746.     //                m_creature->DealDamage(i->getSource(), damage, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW);
  747.     //            }
  748.     //        }
  749.     //    }
  750.     //}
  751. };
  752.  
  753. CreatureAI* GetAI_mob_void_zone(Creature* pCreature)
  754. {
  755.     return new mob_void_zoneAI(pCreature);
  756. }
  757.  
  758. /*-------------------------------------------------------
  759.  *
  760.  *        LIFE SPARK
  761.  *
  762.  *///----------------------------------------------------
  763. struct mob_life_sparkAI : public ScriptedAI
  764. {
  765.     mob_life_sparkAI(Creature* pCreature) : ScriptedAI(pCreature)
  766.     {
  767.         m_pInstance = pCreature->GetInstanceData();
  768.     }
  769.  
  770.     ScriptedInstance* m_pInstance;
  771.     uint32 uiShockTimer;
  772.  
  773.     void Reset()
  774.     {
  775.         DoCast(m_creature, RAID_MODE(SPELL_STATIC_CHARGED_10, SPELL_STATIC_CHARGED_25));
  776.         uiShockTimer = 0; // first one is immediate.
  777.     }
  778.  
  779.     void UpdateAI(const uint32 diff)
  780.     {
  781.         if (!UpdateVictim())
  782.             return;
  783.  
  784.         if (uiShockTimer <= diff)
  785.         {
  786.             if (m_creature->IsWithinMeleeRange(m_creature->getVictim()))
  787.             {
  788.                 DoCast(m_creature->getVictim(), SPELL_SHOCK);
  789.                 uiShockTimer = TIMER_SHOCK;
  790.             }
  791.         }
  792.         else uiShockTimer -= diff;
  793.     }
  794. };
  795.  
  796. CreatureAI* GetAI_mob_life_spark(Creature* pCreature)
  797. {
  798.     return new mob_life_sparkAI(pCreature);
  799. }
  800.  
  801. void AddSC_boss_xt002()
  802. {
  803.     Script *newscript;
  804.  
  805.     newscript = new Script;
  806.     newscript->Name = "boss_xt002";
  807.     newscript->GetAI = &GetAI_boss_xt002;
  808.     newscript->RegisterSelf();
  809.  
  810.     newscript = new Script;
  811.     newscript->Name = "mob_xt002_heart";
  812.     newscript->GetAI = &GetAI_mob_xt002_heart;
  813.     newscript->RegisterSelf();
  814.  
  815.     newscript = new Script;
  816.     newscript->Name = "mob_scrapbot";
  817.     newscript->GetAI = &GetAI_mob_scrapbot;
  818.     newscript->RegisterSelf();
  819.  
  820.     newscript = new Script;
  821.     newscript->Name = "mob_pummeller";
  822.     newscript->GetAI = &GetAI_mob_pummeller;
  823.     newscript->RegisterSelf();
  824.  
  825.     newscript = new Script;
  826.     newscript->Name = "mob_boombot";
  827.     newscript->GetAI = &GetAI_mob_boombot;
  828.     newscript->RegisterSelf();
  829.  
  830.     newscript = new Script;
  831.     newscript->Name = "mob_void_zone";
  832.     newscript->GetAI = &GetAI_mob_void_zone;
  833.     newscript->RegisterSelf();
  834.  
  835.     newscript = new Script;
  836.     newscript->Name = "mob_life_spark";
  837.     newscript->GetAI = &GetAI_mob_life_spark;
  838.     newscript->RegisterSelf();
  839. }