diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp | 607 | ||||
| -rw-r--r-- | src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h | 4 | 
2 files changed, 301 insertions, 310 deletions
| diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp index dd2e8bae1ed..ba57c41e0a0 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp @@ -124,379 +124,368 @@ Position const SpawnLocations[3]=      {-145.950f, -212.831f, -68.659f, 0.0f}  }; -class boss_onyxia : public CreatureScript +struct boss_onyxia : public BossAI  { -public: -    boss_onyxia() : CreatureScript("boss_onyxia") { } +    boss_onyxia(Creature* creature) : BossAI(creature, DATA_ONYXIA) +    { +        Initialize(); +    } -    struct boss_onyxiaAI : public BossAI +    void Initialize()      { -        boss_onyxiaAI(Creature* creature) : BossAI(creature, DATA_ONYXIA) -        { -            Initialize(); -        } +        Phase = PHASE_START; +        MovePoint = urand(0, 5); +        PointData = GetMoveData(); +        SummonWhelpCount = 0; +        triggerGUID.Clear(); +        tankGUID.Clear(); +        IsMoving = false; +    } -        void Initialize() -        { -            Phase = PHASE_START; -            MovePoint = urand(0, 5); -            PointData = GetMoveData(); -            SummonWhelpCount = 0; -            triggerGUID.Clear(); -            tankGUID.Clear(); -            IsMoving = false; -        } +    void Reset() override +    { +        Initialize(); -        void Reset() override -        { -            Initialize(); +        if (!IsCombatMovementAllowed()) +            SetCombatMovement(true); -            if (!IsCombatMovementAllowed()) -                SetCombatMovement(true); +        _Reset(); +        me->SetReactState(REACT_AGGRESSIVE); +        instance->SetData(DATA_ONYXIA_PHASE, Phase); +        instance->DoStopCriteriaTimer(CriteriaStartEvent::SendEvent, ACHIEV_TIMED_START_EVENT); +    } -            _Reset(); -            me->SetReactState(REACT_AGGRESSIVE); -            instance->SetData(DATA_ONYXIA_PHASE, Phase); -            instance->DoStopCriteriaTimer(CriteriaStartEvent::SendEvent, ACHIEV_TIMED_START_EVENT); -        } +    void JustEngagedWith(Unit* who) override +    { +        BossAI::JustEngagedWith(who); +        Talk(SAY_AGGRO); +        events.ScheduleEvent(EVENT_FLAME_BREATH, 10s, 20s); +        events.ScheduleEvent(EVENT_TAIL_SWEEP, 15s, 20s); +        events.ScheduleEvent(EVENT_CLEAVE, 2s, 5s); +        events.ScheduleEvent(EVENT_WING_BUFFET, 10s, 20s); +        instance->DoStartCriteriaTimer(CriteriaStartEvent::SendEvent, ACHIEV_TIMED_START_EVENT); +    } + +    void JustSummoned(Creature* summoned) override +    { +        DoZoneInCombat(summoned); +        if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) +            summoned->AI()->AttackStart(target); -        void JustEngagedWith(Unit* who) override +        switch (summoned->GetEntry())          { -            BossAI::JustEngagedWith(who); -            Talk(SAY_AGGRO); -            events.ScheduleEvent(EVENT_FLAME_BREATH, 10s, 20s); -            events.ScheduleEvent(EVENT_TAIL_SWEEP, 15s, 20s); -            events.ScheduleEvent(EVENT_CLEAVE, 2s, 5s); -            events.ScheduleEvent(EVENT_WING_BUFFET, 10s, 20s); -            instance->DoStartCriteriaTimer(CriteriaStartEvent::SendEvent, ACHIEV_TIMED_START_EVENT); +            case NPC_WHELP: +                ++SummonWhelpCount; +                break; +            case NPC_LAIRGUARD: +                summoned->setActive(true); +                summoned->SetFarVisible(true); +                break;          } +        summons.Summon(summoned); +    } -        void JustSummoned(Creature* summoned) override +    void KilledUnit(Unit* /*victim*/) override +    { +        Talk(SAY_KILL); +    } + +    void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override +    { +        if (spellInfo->Id == SPELL_BREATH_EAST_TO_WEST || +            spellInfo->Id == SPELL_BREATH_WEST_TO_EAST || +            spellInfo->Id == SPELL_BREATH_SE_TO_NW || +            spellInfo->Id == SPELL_BREATH_NW_TO_SE || +            spellInfo->Id == SPELL_BREATH_SW_TO_NE || +            spellInfo->Id == SPELL_BREATH_NE_TO_SW)          { -            DoZoneInCombat(summoned); -            if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) -                summoned->AI()->AttackStart(target); +            PointData = GetMoveData(); +            MovePoint = PointData->LocIdEnd; + +            me->SetSpeedRate(MOVE_FLIGHT, 1.5f); +            me->GetMotionMaster()->MovePoint(8, MiddleRoomLocation); +        } +    } -            switch (summoned->GetEntry()) +    void MovementInform(uint32 type, uint32 id) override +    { +        if (type == POINT_MOTION_TYPE) +        { +            switch (id)              { -                case NPC_WHELP: -                    ++SummonWhelpCount; +                case 8: +                    PointData = GetMoveData(); +                    if (PointData) +                    { +                        me->SetSpeedRate(MOVE_FLIGHT, 1.0f); +                        me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); +                    } +                    break; +                case 9: +                    me->SetCanFly(false); +                    me->SetDisableGravity(false); +                    if (Creature* trigger = ObjectAccessor::GetCreature(*me, triggerGUID)) +                        Unit::Kill(me, trigger); +                    me->SetReactState(REACT_AGGRESSIVE); +                    // tank selection based on phase one. If tank is not there i take nearest one +                    if (Unit* tank = ObjectAccessor::GetUnit(*me, tankGUID)) +                        me->GetMotionMaster()->MoveChase(tank); +                    else if (Unit* newtarget = SelectTarget(SelectTargetMethod::MinDistance, 0)) +                        me->GetMotionMaster()->MoveChase(newtarget); +                    events.ScheduleEvent(EVENT_BELLOWING_ROAR, 5s); +                    events.ScheduleEvent(EVENT_FLAME_BREATH, 10s, 20s); +                    events.ScheduleEvent(EVENT_TAIL_SWEEP, 15s, 20s); +                    events.ScheduleEvent(EVENT_CLEAVE, 2s, 5s); +                    events.ScheduleEvent(EVENT_WING_BUFFET, 15s, 30s); +                    break; +                case 10: +                    me->SetCanFly(true); +                    me->SetDisableGravity(true); +                    me->SetFacingTo(me->GetOrientation() + float(M_PI)); +                    if (Creature * trigger = me->SummonCreature(NPC_TRIGGER, MiddleRoomLocation, TEMPSUMMON_CORPSE_DESPAWN)) +                        triggerGUID = trigger->GetGUID(); +                    me->GetMotionMaster()->MoveTakeoff(11, Phase2Floating); +                    me->SetSpeedRate(MOVE_FLIGHT, 1.0f); +                    Talk(SAY_PHASE_2_TRANS); +                    instance->SetData(DATA_ONYXIA_PHASE, Phase); +                    events.ScheduleEvent(EVENT_WHELP_SPAWN, 5s); +                    events.ScheduleEvent(EVENT_LAIR_GUARD, 15s); +                    events.ScheduleEvent(EVENT_DEEP_BREATH, 75s); +                    events.ScheduleEvent(EVENT_MOVEMENT, 10s); +                    events.ScheduleEvent(EVENT_FIREBALL, 18s);                      break; -                case NPC_LAIRGUARD: -                    summoned->setActive(true); -                    summoned->SetFarVisible(true); +                case 11: +                    if (PointData) +                        me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); +                    me->GetMotionMaster()->MoveIdle(); +                    break; +                default: +                    IsMoving = false;                      break;              } -            summons.Summon(summoned);          } +    } -        void KilledUnit(Unit* /*victim*/) override +    void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override +    { +        //Workaround - Couldn't find a way to group this spells (All Eruption) +        if (((spellInfo->Id >= 17086 && spellInfo->Id <= 17095) || +            (spellInfo->Id == 17097) || +            (spellInfo->Id >= 18351 && spellInfo->Id <= 18361) || +            (spellInfo->Id >= 18564 && spellInfo->Id <= 18576) || +            (spellInfo->Id >= 18578 && spellInfo->Id <= 18607) || +            (spellInfo->Id == 18609) || +            (spellInfo->Id >= 18611 && spellInfo->Id <= 18628) || +            (spellInfo->Id >= 21132 && spellInfo->Id <= 21133) || +            (spellInfo->Id >= 21135 && spellInfo->Id <= 21139) || +            (spellInfo->Id >= 22191 && spellInfo->Id <= 22202) || +            (spellInfo->Id >= 22267 && spellInfo->Id <= 22268)) && +            (target->GetTypeId() == TYPEID_PLAYER))          { -            Talk(SAY_KILL); +            instance->SetData(DATA_SHE_DEEP_BREATH_MORE, FAIL);          } +    } -        void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override -        { -            if (spellInfo->Id == SPELL_BREATH_EAST_TO_WEST || -                spellInfo->Id == SPELL_BREATH_WEST_TO_EAST || -                spellInfo->Id == SPELL_BREATH_SE_TO_NW || -                spellInfo->Id == SPELL_BREATH_NW_TO_SE || -                spellInfo->Id == SPELL_BREATH_SW_TO_NE || -                spellInfo->Id == SPELL_BREATH_NE_TO_SW) -            { -                PointData = GetMoveData(); -                MovePoint = PointData->LocIdEnd; +    OnyxMove* GetMoveData() +    { +        uint8 MaxCount = sizeof(MoveData) / sizeof(OnyxMove); -                me->SetSpeedRate(MOVE_FLIGHT, 1.5f); -                me->GetMotionMaster()->MovePoint(8, MiddleRoomLocation); -            } +        for (uint8 i = 0; i < MaxCount; ++i) +        { +            if (MoveData[i].LocId == MovePoint) +                return &MoveData[i];          } -        void MovementInform(uint32 type, uint32 id) override +        return nullptr; +    } + +    void SetNextRandomPoint() +    { +        uint8 MaxCount = sizeof(MoveData) / sizeof(OnyxMove); + +        uint8 iTemp = urand(0, MaxCount - 1); + +        if (iTemp >= MovePoint) +            ++iTemp; + +        MovePoint = iTemp; +    } + +    void UpdateAI(uint32 diff) override +    { +        if (!UpdateVictim()) +            return; + +        //Common to PHASE_START && PHASE_END +        if (Phase == PHASE_START || Phase == PHASE_END)          { -            if (type == POINT_MOTION_TYPE) +            //Specific to PHASE_START || PHASE_END +            if (Phase == PHASE_START)              { -                switch (id) +                if (HealthBelowPct(65))                  { -                    case 8: -                        PointData = GetMoveData(); -                        if (PointData) -                        { -                            me->SetSpeedRate(MOVE_FLIGHT, 1.0f); -                            me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); -                        } +                    if (Unit* target = me->GetVictim()) +                        tankGUID = target->GetGUID(); +                    SetCombatMovement(false); +                    Phase = PHASE_BREATH; +                    me->SetReactState(REACT_PASSIVE); +                    me->AttackStop(); +                    me->GetMotionMaster()->MovePoint(10, Phase2Location); +                    return; +                } +            } + +            events.Update(diff); + +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return; + +            while (uint32 eventId = events.ExecuteEvent()) +            { +                switch (eventId) +                { +                    case EVENT_BELLOWING_ROAR: // Phase PHASE_END +                    { +                        DoCastVictim(SPELL_BELLOWING_ROAR); +                        // Eruption +                        GameObject* Floor = nullptr; +                        Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15); +                        Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, Floor, check); +                        Cell::VisitGridObjects(me, searcher, 30.0f); +                        if (Floor) +                            instance->SetGuidData(DATA_FLOOR_ERUPTION_GUID, Floor->GetGUID()); +                        events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30s);                          break; -                    case 9: -                        me->SetCanFly(false); -                        me->SetDisableGravity(false); -                        if (Creature* trigger = ObjectAccessor::GetCreature(*me, triggerGUID)) -                            Unit::Kill(me, trigger); -                        me->SetReactState(REACT_AGGRESSIVE); -                        // tank selection based on phase one. If tank is not there i take nearest one -                        if (Unit* tank = ObjectAccessor::GetUnit(*me, tankGUID)) -                            me->GetMotionMaster()->MoveChase(tank); -                        else if (Unit* newtarget = SelectTarget(SelectTargetMethod::MinDistance, 0)) -                            me->GetMotionMaster()->MoveChase(newtarget); -                        events.ScheduleEvent(EVENT_BELLOWING_ROAR, 5s); +                    } +                    case EVENT_FLAME_BREATH:   // Phase PHASE_START and PHASE_END +                        DoCastVictim(SPELL_FLAME_BREATH);                          events.ScheduleEvent(EVENT_FLAME_BREATH, 10s, 20s); +                        break; +                    case EVENT_TAIL_SWEEP:     // Phase PHASE_START and PHASE_END +                        DoCastAOE(SPELL_TAIL_SWEEP);                          events.ScheduleEvent(EVENT_TAIL_SWEEP, 15s, 20s); -                        events.ScheduleEvent(EVENT_CLEAVE, 2s, 5s); -                        events.ScheduleEvent(EVENT_WING_BUFFET, 15s, 30s);                          break; -                    case 10: -                        me->SetCanFly(true); -                        me->SetDisableGravity(true); -                        me->SetFacingTo(me->GetOrientation() + float(M_PI)); -                        if (Creature * trigger = me->SummonCreature(NPC_TRIGGER, MiddleRoomLocation, TEMPSUMMON_CORPSE_DESPAWN)) -                            triggerGUID = trigger->GetGUID(); -                        me->GetMotionMaster()->MoveTakeoff(11, Phase2Floating); -                        me->SetSpeedRate(MOVE_FLIGHT, 1.0f); -                        Talk(SAY_PHASE_2_TRANS); -                        instance->SetData(DATA_ONYXIA_PHASE, Phase); -                        events.ScheduleEvent(EVENT_WHELP_SPAWN, 5s); -                        events.ScheduleEvent(EVENT_LAIR_GUARD, 15s); -                        events.ScheduleEvent(EVENT_DEEP_BREATH, 75s); -                        events.ScheduleEvent(EVENT_MOVEMENT, 10s); -                        events.ScheduleEvent(EVENT_FIREBALL, 18s); +                    case EVENT_CLEAVE:         // Phase PHASE_START and PHASE_END +                        DoCastVictim(SPELL_CLEAVE); +                        events.ScheduleEvent(EVENT_CLEAVE, 2s, 5s);                          break; -                    case 11: -                        if (PointData) -                            me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); -                        me->GetMotionMaster()->MoveIdle(); +                    case EVENT_WING_BUFFET:    // Phase PHASE_START and PHASE_END +                        DoCastVictim(SPELL_WING_BUFFET); +                        events.ScheduleEvent(EVENT_WING_BUFFET, 15s, 30s);                          break;                      default: -                        IsMoving = false;                          break;                  } -            } -        } -        void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override -        { -            //Workaround - Couldn't find a way to group this spells (All Eruption) -            if (((spellInfo->Id >= 17086 && spellInfo->Id <= 17095) || -                (spellInfo->Id == 17097) || -                (spellInfo->Id >= 18351 && spellInfo->Id <= 18361) || -                (spellInfo->Id >= 18564 && spellInfo->Id <= 18576) || -                (spellInfo->Id >= 18578 && spellInfo->Id <= 18607) || -                (spellInfo->Id == 18609) || -                (spellInfo->Id >= 18611 && spellInfo->Id <= 18628) || -                (spellInfo->Id >= 21132 && spellInfo->Id <= 21133) || -                (spellInfo->Id >= 21135 && spellInfo->Id <= 21139) || -                (spellInfo->Id >= 22191 && spellInfo->Id <= 22202) || -                (spellInfo->Id >= 22267 && spellInfo->Id <= 22268)) && -                (target->GetTypeId() == TYPEID_PLAYER)) -            { -                instance->SetData(DATA_SHE_DEEP_BREATH_MORE, FAIL); +                if (me->HasUnitState(UNIT_STATE_CASTING)) +                    return;              } +            DoMeleeAttackIfReady();          } - -        OnyxMove* GetMoveData() +        else          { -            uint8 MaxCount = sizeof(MoveData) / sizeof(OnyxMove); - -            for (uint8 i = 0; i < MaxCount; ++i) +            if (HealthBelowPct(40))              { -                if (MoveData[i].LocId == MovePoint) -                    return &MoveData[i]; +                Phase = PHASE_END; +                instance->SetData(DATA_ONYXIA_PHASE, PHASE_END); +                Talk(SAY_PHASE_3_TRANS); +                SetCombatMovement(true); +                IsMoving = false; +                Position const pos = me->GetHomePosition(); +                me->GetMotionMaster()->MovePoint(9, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 12.0f); +                events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30s); +                return;              } -            return nullptr; -        } - -        void SetNextRandomPoint() -        { -            uint8 MaxCount = sizeof(MoveData) / sizeof(OnyxMove); - -            uint8 iTemp = urand(0, MaxCount - 1); - -            if (iTemp >= MovePoint) -                ++iTemp; +            if (!me->isMoving()) +                if (Creature* trigger = ObjectAccessor::GetCreature(*me, triggerGUID)) +                    me->SetFacingToObject(trigger); -            MovePoint = iTemp; -        } +            events.Update(diff); -        void UpdateAI(uint32 diff) override -        { -            if (!UpdateVictim()) +            if (me->HasUnitState(UNIT_STATE_CASTING))                  return; -            //Common to PHASE_START && PHASE_END -            if (Phase == PHASE_START || Phase == PHASE_END) +            while (uint32 eventId = events.ExecuteEvent())              { -                //Specific to PHASE_START || PHASE_END -                if (Phase == PHASE_START) +                switch (eventId)                  { -                    if (HealthBelowPct(65)) -                    { -                        if (Unit* target = me->GetVictim()) -                            tankGUID = target->GetGUID(); -                        SetCombatMovement(false); -                        Phase = PHASE_BREATH; -                        me->SetReactState(REACT_PASSIVE); -                        me->AttackStop(); -                        me->GetMotionMaster()->MovePoint(10, Phase2Location); -                        return; -                    } -                } +                    case EVENT_DEEP_BREATH:      // Phase PHASE_BREATH +                        if (!IsMoving) +                        { +                            if (me->IsNonMeleeSpellCast(false)) +                                me->InterruptNonMeleeSpells(false); -                events.Update(diff); +                            Talk(EMOTE_BREATH); +                            if (PointData) /// @todo: In what cases is this null? What should we do? +                                DoCast(me, PointData->SpellId); +                            events.ScheduleEvent(EVENT_DEEP_BREATH, 75s); +                        } +                        else +                            events.ScheduleEvent(EVENT_DEEP_BREATH, 1s); +                        break; +                    case EVENT_MOVEMENT:         // Phase PHASE_BREATH +                        if (!IsMoving && !(me->HasUnitState(UNIT_STATE_CASTING))) +                        { +                            SetNextRandomPoint(); +                            PointData = GetMoveData(); -                if (me->HasUnitState(UNIT_STATE_CASTING)) -                    return; +                            if (!PointData) +                                return; -                while (uint32 eventId = events.ExecuteEvent()) -                { -                    switch (eventId) -                    { -                        case EVENT_BELLOWING_ROAR: // Phase PHASE_END +                            me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); +                            IsMoving = true; +                            events.ScheduleEvent(EVENT_MOVEMENT, 25s); +                        } +                        else +                            events.ScheduleEvent(EVENT_MOVEMENT, 500ms); +                        break; +                    case EVENT_FIREBALL:         // Phase PHASE_BREATH +                        if (!IsMoving)                          { -                            DoCastVictim(SPELL_BELLOWING_ROAR); -                            // Eruption -                            GameObject* Floor = nullptr; -                            Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15); -                            Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, Floor, check); -                            Cell::VisitGridObjects(me, searcher, 30.0f); -                            if (Floor) -                                instance->SetGuidData(DATA_FLOOR_ERUPTION_GUID, Floor->GetGUID()); -                            events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30s); -                            break; +                            if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) +                                DoCast(target, SPELL_FIREBALL); +                            events.ScheduleEvent(EVENT_FIREBALL, 8s);                          } -                        case EVENT_FLAME_BREATH:   // Phase PHASE_START and PHASE_END -                            DoCastVictim(SPELL_FLAME_BREATH); -                            events.ScheduleEvent(EVENT_FLAME_BREATH, 10s, 20s); -                            break; -                        case EVENT_TAIL_SWEEP:     // Phase PHASE_START and PHASE_END -                            DoCastAOE(SPELL_TAIL_SWEEP); -                            events.ScheduleEvent(EVENT_TAIL_SWEEP, 15s, 20s); -                            break; -                        case EVENT_CLEAVE:         // Phase PHASE_START and PHASE_END -                            DoCastVictim(SPELL_CLEAVE); -                            events.ScheduleEvent(EVENT_CLEAVE, 2s, 5s); -                            break; -                        case EVENT_WING_BUFFET:    // Phase PHASE_START and PHASE_END -                            DoCastVictim(SPELL_WING_BUFFET); -                            events.ScheduleEvent(EVENT_WING_BUFFET, 15s, 30s); -                            break; -                        default: -                            break; -                    } - -                    if (me->HasUnitState(UNIT_STATE_CASTING)) -                        return; -                } -                DoMeleeAttackIfReady(); -            } -            else -            { -                if (HealthBelowPct(40)) -                { -                    Phase = PHASE_END; -                    instance->SetData(DATA_ONYXIA_PHASE, PHASE_END); -                    Talk(SAY_PHASE_3_TRANS); -                    SetCombatMovement(true); -                    IsMoving = false; -                    Position const pos = me->GetHomePosition(); -                    me->GetMotionMaster()->MovePoint(9, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 12.0f); -                    events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30s); -                    return; +                        else +                            events.ScheduleEvent(EVENT_FIREBALL, 1s); +                        break; +                    case EVENT_LAIR_GUARD:       // Phase PHASE_BREATH +                        me->SummonCreature(NPC_LAIRGUARD, SpawnLocations[2], TEMPSUMMON_CORPSE_DESPAWN); +                        events.ScheduleEvent(EVENT_LAIR_GUARD, 30s); +                        break; +                    case EVENT_WHELP_SPAWN:      // Phase PHASE_BREATH +                        me->SummonCreature(NPC_WHELP, SpawnLocations[0], TEMPSUMMON_CORPSE_DESPAWN); +                        me->SummonCreature(NPC_WHELP, SpawnLocations[1], TEMPSUMMON_CORPSE_DESPAWN); +                        if (SummonWhelpCount >= RAID_MODE(20, 40)) +                        { +                            SummonWhelpCount = 0; +                            events.ScheduleEvent(EVENT_WHELP_SPAWN, 90s); +                        } +                        else +                            events.ScheduleEvent(EVENT_WHELP_SPAWN, 500ms); +                        break; +                    default: +                        break;                  } -                if (!me->isMoving()) -                    if (Creature* trigger = ObjectAccessor::GetCreature(*me, triggerGUID)) -                        me->SetFacingToObject(trigger); - -                events.Update(diff); -                  if (me->HasUnitState(UNIT_STATE_CASTING))                      return; - -                while (uint32 eventId = events.ExecuteEvent()) -                { -                    switch (eventId) -                    { -                        case EVENT_DEEP_BREATH:      // Phase PHASE_BREATH -                            if (!IsMoving) -                            { -                                if (me->IsNonMeleeSpellCast(false)) -                                    me->InterruptNonMeleeSpells(false); - -                                Talk(EMOTE_BREATH); -                                if (PointData) /// @todo: In what cases is this null? What should we do? -                                    DoCast(me, PointData->SpellId); -                                events.ScheduleEvent(EVENT_DEEP_BREATH, 75s); -                            } -                            else -                                events.ScheduleEvent(EVENT_DEEP_BREATH, 1s); -                            break; -                        case EVENT_MOVEMENT:         // Phase PHASE_BREATH -                            if (!IsMoving && !(me->HasUnitState(UNIT_STATE_CASTING))) -                            { -                                SetNextRandomPoint(); -                                PointData = GetMoveData(); - -                                if (!PointData) -                                    return; - -                                me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); -                                IsMoving = true; -                                events.ScheduleEvent(EVENT_MOVEMENT, 25s); -                            } -                            else -                                events.ScheduleEvent(EVENT_MOVEMENT, 500ms); -                            break; -                        case EVENT_FIREBALL:         // Phase PHASE_BREATH -                            if (!IsMoving) -                            { -                                if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) -                                    DoCast(target, SPELL_FIREBALL); -                                events.ScheduleEvent(EVENT_FIREBALL, 8s); -                            } -                            else -                                events.ScheduleEvent(EVENT_FIREBALL, 1s); -                            break; -                        case EVENT_LAIR_GUARD:       // Phase PHASE_BREATH -                            me->SummonCreature(NPC_LAIRGUARD, SpawnLocations[2], TEMPSUMMON_CORPSE_DESPAWN); -                            events.ScheduleEvent(EVENT_LAIR_GUARD, 30s); -                            break; -                        case EVENT_WHELP_SPAWN:      // Phase PHASE_BREATH -                            me->SummonCreature(NPC_WHELP, SpawnLocations[0], TEMPSUMMON_CORPSE_DESPAWN); -                            me->SummonCreature(NPC_WHELP, SpawnLocations[1], TEMPSUMMON_CORPSE_DESPAWN); -                            if (SummonWhelpCount >= RAID_MODE(20, 40)) -                            { -                                SummonWhelpCount = 0; -                                events.ScheduleEvent(EVENT_WHELP_SPAWN, 90s); -                            } -                            else -                                events.ScheduleEvent(EVENT_WHELP_SPAWN, 500ms); -                            break; -                        default: -                            break; -                    } - -                    if (me->HasUnitState(UNIT_STATE_CASTING)) -                        return; -                }              }          } - -        private: -            OnyxMove* PointData; -            uint8 Phase; -            uint8 MovePoint; -            uint8 SummonWhelpCount; -            ObjectGuid triggerGUID; -            ObjectGuid tankGUID; -            bool IsMoving; -    }; - -    CreatureAI* GetAI(Creature* creature) const override -    { -        return GetOnyxiaAI<boss_onyxiaAI>(creature);      } + +    private: +        OnyxMove* PointData; +        uint8 Phase; +        uint8 MovePoint; +        uint8 SummonWhelpCount; +        ObjectGuid triggerGUID; +        ObjectGuid tankGUID; +        bool IsMoving;  };  void AddSC_boss_onyxia()  { -    new boss_onyxia(); +    RegisterOnyxiasLairCreatureAI(boss_onyxia);  } diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h b/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h index 69fff591ad8..78a4581a3c4 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h +++ b/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h @@ -74,9 +74,11 @@ enum OLAchievementData  };  template <class AI, class T> -inline AI* GetOnyxiaAI(T* obj) +inline AI* GetOnyxiasLairAI(T* obj)  {      return GetInstanceAI<AI>(obj, OnyxiaScriptName);  } +#define RegisterOnyxiasLairCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetOnyxiasLairAI) +  #endif | 
