diff options
| -rw-r--r-- | sql/updates/world/2012_11_27_00_world_misc.sql | 24 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp | 589 | 
2 files changed, 328 insertions, 285 deletions
diff --git a/sql/updates/world/2012_11_27_00_world_misc.sql b/sql/updates/world/2012_11_27_00_world_misc.sql new file mode 100644 index 00000000000..5e47deaf993 --- /dev/null +++ b/sql/updates/world/2012_11_27_00_world_misc.sql @@ -0,0 +1,24 @@ +DELETE FROM `disables` WHERE `sourceType`=4 AND `entry` IN (7568,7568); + +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (7567,7568); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(7567,11,0,0,'achievement_the_hundred_club'), +(7567,12,0,0,''), +(7568,11,0,0,'achievement_the_hundred_club'), +(7568,12,1,0,''); + +DELETE FROM `script_texts` WHERE `entry` IN (-1533082,-1533083); + +DELETE FROM `creature_text` WHERE `entry`=15989; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(15989,0,0,'Sapphiron lifts off into the air!',41,0,100,254,0,0,'Sapphiron'), +(15989,1,0,'Sapphiron resumes his attacks!',41,0,100,0,0,0,'Sapphiron'), +(15989,2,0,'%s takes a deep breath.',41,7,100,0,0,0,'Sapphiron'), +(15989,3,0,'%s enrages!',41,0,100,0,0,0,'Sapphiron'); + +DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (28531,55697,28542,28547) OR `spellid0` IN (28531,55697,28542,28547); +INSERT INTO `spelldifficulty_dbc`(`id`,`spellid0`,`spellid1`) VALUES +(28531,28531,55799), -- Frost Aura +(55697,55697,55696), -- Tail Sweep +(28542,28542,55665), -- Life Drain +(28547,28547,55699); -- Chill diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp index c027dd3a97d..10f518462ac 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp @@ -15,48 +15,47 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -#include "AchievementMgr.h"  #include "ScriptMgr.h"  #include "ScriptedCreature.h" -#include "naxxramas.h"  #include "Player.h"  #include "SpellInfo.h" +#include "naxxramas.h" -#define EMOTE_BREATH            -1533082 -#define EMOTE_ENRAGE            -1533083 - -#define SPELL_FROST_AURA        RAID_MODE(28531, 55799) -#define SPELL_CLEAVE            19983 -#define SPELL_TAIL_SWEEP        RAID_MODE(55697, 55696) -#define SPELL_SUMMON_BLIZZARD   28560 -#define SPELL_LIFE_DRAIN        RAID_MODE(28542, 55665) -#define SPELL_ICEBOLT           28522 -#define SPELL_FROST_BREATH      29318 -#define SPELL_FROST_EXPLOSION   28524 -#define SPELL_FROST_MISSILE     30101 -#define SPELL_BERSERK           26662 -#define SPELL_DIES              29357 - -#define SPELL_CHILL             RAID_MODE(28547, 55699) - -#define MOB_BLIZZARD            16474 -#define GO_ICEBLOCK             181247 +enum Yells +{ +    EMOTE_AIR_PHASE         = 0, +    EMOTE_GROUND_PHASE      = 1, +    EMOTE_BREATH            = 2, +    EMOTE_ENRAGE            = 3 +}; -#define ACHIEVEMENT_THE_HUNDRED_CLUB    RAID_MODE(2146, 2147) -#define MAX_FROST_RESISTANCE            100 +enum Spells +{ +    SPELL_FROST_AURA        = 28531, +    SPELL_CLEAVE            = 19983, +    SPELL_TAIL_SWEEP        = 55697, +    SPELL_SUMMON_BLIZZARD   = 28560, +    SPELL_LIFE_DRAIN        = 28542, +    SPELL_ICEBOLT           = 28522, +    SPELL_FROST_BREATH      = 29318, +    SPELL_FROST_EXPLOSION   = 28524, +    SPELL_FROST_MISSILE     = 30101, +    SPELL_BERSERK           = 26662, +    SPELL_DIES              = 29357, +    SPELL_CHILL             = 28547, +};  enum Phases  { -    PHASE_NULL = 0, +    PHASE_NULL          = 0,      PHASE_BIRTH,      PHASE_GROUND, -    PHASE_FLIGHT, +    PHASE_FLIGHT  };  enum Events  { -    EVENT_NONE, -    EVENT_BERSERK, +    EVENT_BERSERK       = 1,      EVENT_CLEAVE,      EVENT_TAIL,      EVENT_DRAIN, @@ -68,342 +67,362 @@ enum Events      EVENT_EXPLOSION,      EVENT_LAND,      EVENT_GROUND, -    EVENT_BIRTH, +    EVENT_BIRTH +}; + +enum Misc +{ +    NPC_BLIZZARD            = 16474, +    GO_ICEBLOCK             = 181247, + +    // The Hundred Club +    DATA_THE_HUNDRED_CLUB   = 21462147, +    MAX_FROST_RESISTANCE    = 100  };  typedef std::map<uint64, uint64> IceBlockMap;  class boss_sapphiron : public CreatureScript  { -public: -    boss_sapphiron() : CreatureScript("boss_sapphiron") { } - -    CreatureAI* GetAI(Creature* creature) const -    { -        return new boss_sapphironAI (creature); -    } - -    struct boss_sapphironAI : public BossAI -    { -        boss_sapphironAI(Creature* creature) : BossAI(creature, BOSS_SAPPHIRON) -            , phase(PHASE_NULL) +    public: +        boss_sapphiron() : CreatureScript("boss_sapphiron") { } + +        struct boss_sapphironAI : public BossAI          { -            map = me->GetMap(); -        } +            boss_sapphironAI(Creature* creature) : BossAI(creature, BOSS_SAPPHIRON) +                , _phase(PHASE_NULL) +            { +                _map = me->GetMap(); +            } -        Phases phase; -        uint32 iceboltCount; -        IceBlockMap iceblocks; +            void InitializeAI() +            { +                float x, y, z; +                me->GetPosition(x, y, z); +                me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0); +                me->SetVisible(false); +                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); +                me->SetReactState(REACT_PASSIVE); + +                BossAI::InitializeAI(); +            } -        bool CanTheHundredClub; // needed for achievement: The Hundred Club(2146, 2147) -        uint32 CheckFrostResistTimer; -        Map* map; +            void Reset() +            { +                _Reset(); -        void InitializeAI() -        { -            float x, y, z; -            me->GetPosition(x, y, z); -            me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0); -            me->SetVisible(false); -            me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); -            me->SetReactState(REACT_PASSIVE); - -            ScriptedAI::InitializeAI(); -        } +                if (_phase == PHASE_FLIGHT) +                    ClearIceBlock(); -        void Reset() -        { -            _Reset(); +                _phase = PHASE_NULL; -            if (phase == PHASE_FLIGHT) -                ClearIceBlock(); +                _canTheHundredClub = true; +                _checkFrostResistTimer = 5 * IN_MILLISECONDS; +            } -            phase = PHASE_NULL; +            void EnterCombat(Unit* /*who*/) +            { +                _EnterCombat(); -            CanTheHundredClub = true; -            CheckFrostResistTimer = 5000; -        } +                me->CastSpell(me, SPELL_FROST_AURA, true); +             +                events.ScheduleEvent(EVENT_BERSERK, 15 * MINUTE * IN_MILLISECONDS); +                EnterPhaseGround(); -        void EnterCombat(Unit* /*who*/) -        { -            _EnterCombat(); +                CheckPlayersFrostResist(); +            } + +            void SpellHitTarget(Unit* target, SpellInfo const* spell) +            { +                if (spell->Id == SPELL_ICEBOLT) +                { +                    IceBlockMap::iterator itr = _iceblocks.find(target->GetGUID()); +                    if (itr != _iceblocks.end() && !itr->second) +                    { +                        if (GameObject* iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25000)) +                            itr->second = iceblock->GetGUID(); +                    } +                } +            } -            me->CastSpell(me, SPELL_FROST_AURA, true); +            void JustDied(Unit* /*killer*/) +            { +                _JustDied(); +                me->CastSpell(me, SPELL_DIES, true); -            events.ScheduleEvent(EVENT_BERSERK, 15*60000); -            EnterPhaseGround(); +                CheckPlayersFrostResist(); +            } -            CheckPlayersFrostResist(); -        } +            void MovementInform(uint32 /*type*/, uint32 id) +            { +                if (id == 1) +                    events.ScheduleEvent(EVENT_LIFTOFF, 0); +            } -        void SpellHitTarget(Unit* target, const SpellInfo* spell) -        { -            if (spell->Id == SPELL_ICEBOLT) +            void DoAction(int32 const param)              { -                IceBlockMap::iterator itr = iceblocks.find(target->GetGUID()); -                if (itr != iceblocks.end() && !itr->second) +                if (param == DATA_SAPPHIRON_BIRTH)                  { -                    if (GameObject* iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25000)) -                        itr->second = iceblock->GetGUID(); +                    _phase = PHASE_BIRTH; +                    events.ScheduleEvent(EVENT_BIRTH, 23 * IN_MILLISECONDS);                  }              } -        } -        void JustDied(Unit* /*killer*/) -        { -            _JustDied(); -            me->CastSpell(me, SPELL_DIES, true); - -            CheckPlayersFrostResist(); -            if (CanTheHundredClub) +            void CheckPlayersFrostResist()              { -                AchievementEntry const* AchievTheHundredClub = sAchievementMgr->GetAchievement(ACHIEVEMENT_THE_HUNDRED_CLUB); -                if (AchievTheHundredClub) +                if (_canTheHundredClub && _map && _map->IsRaid())                  { -                    if (map && map->IsDungeon()) +                    Map::PlayerList const &players = _map->GetPlayers(); +                    for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)                      { -                        Map::PlayerList const &players = map->GetPlayers(); -                        for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) -                            itr->getSource()->CompletedAchievement(AchievTheHundredClub); +                        if (itr->getSource()->GetResistance(SPELL_SCHOOL_FROST) > MAX_FROST_RESISTANCE) +                        { +                            _canTheHundredClub = false; +                            break; +                        }                      }                  }              } -        } - -        void MovementInform(uint32, uint32 id) -        { -            if (id == 1) -                events.ScheduleEvent(EVENT_LIFTOFF, 0); -        } -        void DoAction(const int32 param) -        { -            if (param == DATA_SAPPHIRON_BIRTH) +            void EnterPhaseGround()              { -                phase = PHASE_BIRTH; -                events.ScheduleEvent(EVENT_BIRTH, 23000); +                _phase = PHASE_GROUND; +                me->SetReactState(REACT_AGGRESSIVE); +                events.SetPhase(PHASE_GROUND); +                events.ScheduleEvent(EVENT_CLEAVE, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND); +                events.ScheduleEvent(EVENT_TAIL, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND); +                events.ScheduleEvent(EVENT_DRAIN, 24 * IN_MILLISECONDS, 0, PHASE_GROUND); +                events.ScheduleEvent(EVENT_BLIZZARD, urand(5, 10) * IN_MILLISECONDS, 0, PHASE_GROUND); +                events.ScheduleEvent(EVENT_FLIGHT, 45 * IN_MILLISECONDS);              } -        } -        void CheckPlayersFrostResist() -        { -            if (CanTheHundredClub && map && map->IsDungeon()) +            void ClearIceBlock()              { -                Map::PlayerList const &players = map->GetPlayers(); -                for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) +                for (IceBlockMap::const_iterator itr = _iceblocks.begin(); itr != _iceblocks.end(); ++itr)                  { -                    if (itr->getSource()->GetResistance(SPELL_SCHOOL_FROST) > MAX_FROST_RESISTANCE) -                    { -                        CanTheHundredClub = false; -                        break; -                    } +                    if (Player* player = ObjectAccessor::GetPlayer(*me, itr->first)) +                        player->RemoveAura(SPELL_ICEBOLT); + +                    if (GameObject* go = GameObject::GetGameObject(*me, itr->second)) +                        go->Delete();                  } +                _iceblocks.clear();              } -        } -        void EnterPhaseGround() -        { -            phase = PHASE_GROUND; -            me->SetReactState(REACT_AGGRESSIVE); -            events.SetPhase(PHASE_GROUND); -            events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND); -            events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND); -            events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND); -            events.ScheduleEvent(EVENT_BLIZZARD, 5000+rand()%5000, 0, PHASE_GROUND); -            events.ScheduleEvent(EVENT_FLIGHT, 45000); -        } - -        void ClearIceBlock() -        { -            for (IceBlockMap::const_iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr) +            uint32 GetData(uint32 data) const              { -                if (Player* player = Unit::GetPlayer(*me, itr->first)) -                    player->RemoveAura(SPELL_ICEBOLT); -                if (GameObject* go = GameObject::GetGameObject(*me, itr->second)) -                    go->Delete(); +                if (data == DATA_THE_HUNDRED_CLUB) +                    return _canTheHundredClub; + +                return 0;              } -            iceblocks.clear(); -        } -        void UpdateAI(const uint32 diff) -        { -            if (!phase) -                return; +            void UpdateAI(uint32 const diff) +            { +                if (!_phase) +                    return; -            events.Update(diff); +                events.Update(diff); -            if ((phase != PHASE_BIRTH && !UpdateVictim()) || !CheckInRoom()) -                return; +                if ((_phase != PHASE_BIRTH && !UpdateVictim()) || !CheckInRoom()) +                    return; -            if (CanTheHundredClub) -            { -                if (CheckFrostResistTimer <= diff) +                if (_canTheHundredClub)                  { -                    CheckPlayersFrostResist(); -                    CheckFrostResistTimer = (rand() % 5 + 5) * 1000; -                } else CheckFrostResistTimer -= diff; -            } +                    if (_checkFrostResistTimer <= diff) +                    { +                        CheckPlayersFrostResist(); +                        _checkFrostResistTimer = 5 * IN_MILLISECONDS; +                    } +                    else +                        _checkFrostResistTimer -= diff; +                 } -            if (phase == PHASE_GROUND) -            { -                while (uint32 eventId = events.ExecuteEvent()) +                if (_phase == PHASE_GROUND)                  { -                    switch (eventId) +                    while (uint32 eventId = events.ExecuteEvent())                      { -                        case EVENT_BERSERK: -                            DoScriptText(EMOTE_ENRAGE, me); -                            DoCast(me, SPELL_BERSERK); -                            return; -                        case EVENT_CLEAVE: -                            DoCast(me->getVictim(), SPELL_CLEAVE); -                            events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND); -                            return; -                        case EVENT_TAIL: -                            DoCastAOE(SPELL_TAIL_SWEEP); -                            events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND); -                            return; -                        case EVENT_DRAIN: -                            DoCastAOE(SPELL_LIFE_DRAIN); -                            events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND); -                            return; -                        case EVENT_BLIZZARD: +                        switch (eventId)                          { -                            //DoCastAOE(SPELL_SUMMON_BLIZZARD); -                            if (Creature* summon = DoSummon(MOB_BLIZZARD, me, 0.0f, urand(25000, 30000), TEMPSUMMON_TIMED_DESPAWN)) -                                summon->GetMotionMaster()->MoveRandom(40); -                            events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20000, 7000), 0, PHASE_GROUND); -                            break; -                        } -                        case EVENT_FLIGHT: -                            if (HealthAbovePct(10)) -                            { -                                phase = PHASE_FLIGHT; -                                events.SetPhase(PHASE_FLIGHT); -                                me->SetReactState(REACT_PASSIVE); -                                me->AttackStop(); -                                float x, y, z, o; -                                me->GetHomePosition(x, y, z, o); -                                me->GetMotionMaster()->MovePoint(1, x, y, z); +                            case EVENT_BERSERK: +                                DoScriptText(EMOTE_ENRAGE, me); +                                DoCast(me, SPELL_BERSERK);                                  return; +                            case EVENT_CLEAVE: +                                DoCastVictim(SPELL_CLEAVE); +                                events.ScheduleEvent(EVENT_CLEAVE, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND); +                                return; +                            case EVENT_TAIL: +                                DoCastAOE(SPELL_TAIL_SWEEP); +                                events.ScheduleEvent(EVENT_TAIL, urand(5, 15) * IN_MILLISECONDS, 0, PHASE_GROUND); +                                return; +                            case EVENT_DRAIN: +                                DoCastAOE(SPELL_LIFE_DRAIN); +                                events.ScheduleEvent(EVENT_DRAIN, 24 * IN_MILLISECONDS, 0, PHASE_GROUND); +                                return; +                            case EVENT_BLIZZARD: +                            { +                                //DoCastAOE(SPELL_SUMMON_BLIZZARD); +                                if (Creature* summon = DoSummon(NPC_BLIZZARD, me, 0.0f, urand(25, 30) * IN_MILLISECONDS, TEMPSUMMON_TIMED_DESPAWN)) +                                    summon->GetMotionMaster()->MoveRandom(40); +                                events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20, 7) * IN_MILLISECONDS, 0, PHASE_GROUND); +                                break;                              } -                            break; +                            case EVENT_FLIGHT: +                                if (HealthAbovePct(10)) +                                { +                                    _phase = PHASE_FLIGHT; +                                    events.SetPhase(PHASE_FLIGHT); +                                    me->SetReactState(REACT_PASSIVE); +                                    me->AttackStop(); +                                    float x, y, z, o; +                                    me->GetHomePosition(x, y, z, o); +                                    me->GetMotionMaster()->MovePoint(1, x, y, z); +                                    return; +                                } +                                break; +                        }                      } -                } -                DoMeleeAttackIfReady(); -            } -            else -            { -                if (uint32 eventId = events.ExecuteEvent()) +                    DoMeleeAttackIfReady(); +                } +                else                  { -                    switch (eventId) +                    if (uint32 eventId = events.ExecuteEvent())                      { -                        case EVENT_LIFTOFF: -                            me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); -                            me->SetDisableGravity(true); -                            me->SendMovementFlagUpdate(); -                            events.ScheduleEvent(EVENT_ICEBOLT, 1500); -                            iceboltCount = RAID_MODE(2, 3); -                            return; -                        case EVENT_ICEBOLT: +                        switch (eventId)                          { -                            std::vector<Unit*> targets; -                            std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); -                            for (; i != me->getThreatManager().getThreatList().end(); ++i) -                                if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT)) -                                    targets.push_back((*i)->getTarget()); - -                            if (targets.empty()) -                                iceboltCount = 0; -                            else +                            case EVENT_LIFTOFF: +                                Talk(EMOTE_AIR_PHASE); +                                me->SetDisableGravity(true); +                                me->SendMovementFlagUpdate(); +                                events.ScheduleEvent(EVENT_ICEBOLT, 1500); +                                _iceboltCount = RAID_MODE(2, 3); +                                return; +                            case EVENT_ICEBOLT:                              { -                                std::vector<Unit*>::const_iterator itr = targets.begin(); -                                advance(itr, rand()%targets.size()); -                                iceblocks.insert(std::make_pair((*itr)->GetGUID(), 0)); -                                DoCast(*itr, SPELL_ICEBOLT); -                                --iceboltCount; +                                std::vector<Unit*> targets; +                                std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); +                                for (; i != me->getThreatManager().getThreatList().end(); ++i) +                                    if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT)) +                                        targets.push_back((*i)->getTarget()); + +                                if (targets.empty()) +                                    _iceboltCount = 0; +                                else +                                { +                                    std::vector<Unit*>::const_iterator itr = targets.begin(); +                                    advance(itr, rand()%targets.size()); +                                    _iceblocks.insert(std::make_pair((*itr)->GetGUID(), 0)); +                                    DoCast(*itr, SPELL_ICEBOLT); +                                    --_iceboltCount; +                                } + +                                if (_iceboltCount) +                                    events.ScheduleEvent(EVENT_ICEBOLT, 1 * IN_MILLISECONDS); +                                else +                                    events.ScheduleEvent(EVENT_BREATH, 1 * IN_MILLISECONDS); +                                return;                              } - -                            if (iceboltCount) -                                events.ScheduleEvent(EVENT_ICEBOLT, 1000); -                            else -                                events.ScheduleEvent(EVENT_BREATH, 1000); -                            return; -                        } -                        case EVENT_BREATH: -                        { -                            DoScriptText(EMOTE_BREATH, me); -                            DoCastAOE(SPELL_FROST_MISSILE); -                            events.ScheduleEvent(EVENT_EXPLOSION, 8000); -                            return; +                            case EVENT_BREATH: +                            { +                                Talk(EMOTE_BREATH); +                                DoCastAOE(SPELL_FROST_MISSILE); +                                events.ScheduleEvent(EVENT_EXPLOSION, 8 * IN_MILLISECONDS); +                                return; +                            } +                            case EVENT_EXPLOSION: +                                CastExplosion(); +                                ClearIceBlock(); +                                events.ScheduleEvent(EVENT_LAND, 3 * IN_MILLISECONDS); +                                return; +                            case EVENT_LAND: +                                me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); +                                Talk(EMOTE_GROUND_PHASE); +                                me->SetDisableGravity(false); +                                me->SendMovementFlagUpdate(); +                                events.ScheduleEvent(EVENT_GROUND, 1500); +                                return; +                            case EVENT_GROUND: +                                EnterPhaseGround(); +                                return; +                            case EVENT_BIRTH: +                                me->SetVisible(true); +                                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); +                                me->SetReactState(REACT_AGGRESSIVE); +                                return;                          } -                        case EVENT_EXPLOSION: -                            CastExplosion(); -                            ClearIceBlock(); -                            events.ScheduleEvent(EVENT_LAND, 3000); -                            return; -                        case EVENT_LAND: -                            me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); -                            me->SetDisableGravity(false); -                            me->SendMovementFlagUpdate(); -                            events.ScheduleEvent(EVENT_GROUND, 1500); -                            return; -                        case EVENT_GROUND: -                            EnterPhaseGround(); -                            return; -                        case EVENT_BIRTH: -                            me->SetVisible(true); -                            me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); -                            me->SetReactState(REACT_AGGRESSIVE); -                            return;                      } -                }//if (uint32 eventId = events.ExecuteEvent()) -            }//if (phase == PHASE_GROUND) -        } +                } +            } -        void CastExplosion() -        { -            DoZoneInCombat(); // make sure everyone is in threatlist -            std::vector<Unit*> targets; -            std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); -            for (; i != me->getThreatManager().getThreatList().end(); ++i) +            void CastExplosion()              { -                Unit* target = (*i)->getTarget(); -                if (target->GetTypeId() != TYPEID_PLAYER) -                    continue; - -                if (target->HasAura(SPELL_ICEBOLT)) +                DoZoneInCombat(); // make sure everyone is in threatlist +                std::vector<Unit*> targets; +                std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); +                for (; i != me->getThreatManager().getThreatList().end(); ++i)                  { -                    target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); -                    targets.push_back(target); -                    continue; -                } +                    Unit* target = (*i)->getTarget(); +                    if (target->GetTypeId() != TYPEID_PLAYER) +                        continue; -                for (IceBlockMap::const_iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr) -                { -                    if (GameObject* go = GameObject::GetGameObject(*me, itr->second)) +                    if (target->HasAura(SPELL_ICEBOLT))                      { -                        if (go->IsInBetween(me, target, 2.0f) -                            && me->GetExactDist2d(target->GetPositionX(), target->GetPositionY()) - me->GetExactDist2d(go->GetPositionX(), go->GetPositionY()) < 5.0f) +                        target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); +                        targets.push_back(target); +                        continue; +                    } + +                    for (IceBlockMap::const_iterator itr = _iceblocks.begin(); itr != _iceblocks.end(); ++itr) +                    { +                        if (GameObject* go = GameObject::GetGameObject(*me, itr->second))                          { -                            target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); -                            targets.push_back(target); -                            break; +                            if (go->IsInBetween(me, target, 2.0f) +                                && me->GetExactDist2d(target->GetPositionX(), target->GetPositionY()) - me->GetExactDist2d(go->GetPositionX(), go->GetPositionY()) < 5.0f) +                            { +                                target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); +                                targets.push_back(target); +                                break; +                            }                          }                      }                  } + +                me->CastSpell(me, SPELL_FROST_EXPLOSION, true); + +                for (std::vector<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) +                    (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false);              } -            me->CastSpell(me, SPELL_FROST_EXPLOSION, true); +        private: +            Phases _phase; +            uint32 _iceboltCount; +            IceBlockMap _iceblocks; +            bool _canTheHundredClub; +            uint32 _checkFrostResistTimer; +            Map* _map; +        }; -            for (std::vector<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) -                (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false); +        CreatureAI* GetAI(Creature* creature) const +        { +            return new boss_sapphironAI (creature);          } -    }; +}; +class achievement_the_hundred_club : public AchievementCriteriaScript +{ +    public: +        achievement_the_hundred_club() : AchievementCriteriaScript("achievement_the_hundred_club") { } + +        bool OnCheck(Player* /*source*/, Unit* target) +        { +            return target && target->GetAI()->GetData(DATA_THE_HUNDRED_CLUB); +        }  };  void AddSC_boss_sapphiron()  {      new boss_sapphiron(); +    new achievement_the_hundred_club();  }  | 
