diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/CreatureAIImpl.h | 68 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp | 35 |
2 files changed, 45 insertions, 58 deletions
diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index 7447e290ba9..378d3ca18ab 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -327,7 +327,7 @@ class EventMap typedef std::multimap<uint32, uint32> EventStore; public: - EventMap() : _time(0), _phase(0) { } + EventMap() : _time(0), _phase(0), _lastEvent(0) { } /** * @name Reset @@ -447,27 +447,22 @@ class EventMap /** * @name RepeatEvent - * @brief Cancels the closest event and reschedules it. + * @brief Repeats the mostly recently executed event. * @param time Time until the event occurs. */ - void RepeatEvent(uint32 time) + void Repeat(uint32 time) { - if (Empty()) - return; - - uint32 eventId = _eventMap.begin()->second; - _eventMap.erase(_eventMap.begin()); - ScheduleEvent(eventId, time); + _eventMap.insert(EventStore::value_type(_time + time, _lastEvent)); } /** - * @name PopEvent - * @brief Remove the first event in the map. + * @name RepeatEvent + * @brief Repeats the mostly recently executed event. + * @param time Time until the event occurs. Equivalent to Repeat(urand(minTime, maxTime). */ - void PopEvent() + void Repeat(uint32 minTime, uint32 maxTime) { - if (!Empty()) - _eventMap.erase(_eventMap.begin()); + Repeat(urand(minTime, maxTime)); } /** @@ -488,6 +483,7 @@ class EventMap else { uint32 eventId = (itr->second & 0x0000FFFF); + _lastEvent = itr->second; // include phase/group _eventMap.erase(itr); return eventId; } @@ -497,28 +493,6 @@ class EventMap } /** - * @name GetEvent - * @brief Returns the next event to execute. - * @return Id of the event to execute. - */ - uint32 GetEvent() - { - while (!Empty()) - { - EventStore::iterator itr = _eventMap.begin(); - - if (itr->first > _time) - return 0; - else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24))) - _eventMap.erase(itr); - else - return (itr->second & 0x0000FFFF); - } - - return 0; - } - - /** * @name DelayEvents * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. * @param delay Amount of delay. @@ -631,6 +605,21 @@ class EventMap return phase <= 8 && (!phase || _phase & (1 << (phase - 1))); } + /** + * @name GetTimeUntilEvent + * @brief Returns time in milliseconds until next event. + * @param Id of the event. + * @return Time of next event. + */ + uint32 GetTimeUntilEvent(uint32 eventId) const + { + for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) + if (eventId == (itr->second & 0x0000FFFF)) + return itr->first - _time; + + return std::numeric_limits<uint32>::max(); + } + private: /** * @name _time @@ -662,6 +651,13 @@ class EventMap * details. */ EventStore _eventMap; + + + /** + * @name _lastEvent + * @brief Stores information on the most recently executed event + */ + uint32 _lastEvent; }; enum AITarget diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 8b3ac64fb89..c5c70cf3957 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -368,38 +368,33 @@ public: if (Phase == 1) { - while (uint32 eventId = events.GetEvent()) + while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_WASTE: DoSummon(NPC_WASTE, Pos[RAND(0, 3, 6, 9)]); - events.RepeatEvent(urand(2000, 5000)); + events.Repeat(2000, 5000); break; case EVENT_ABOMIN: if (nAbomination < 8) { DoSummon(NPC_ABOMINATION, Pos[RAND(1, 4, 7, 10)]); nAbomination++; - events.RepeatEvent(20000); + events.Repeat(20000); } - else - events.PopEvent(); break; case EVENT_WEAVER: if (nWeaver < 8) { DoSummon(NPC_WEAVER, Pos[RAND(0, 3, 6, 9)]); nWeaver++; - events.RepeatEvent(25000); + events.Repeat(25000); } - else - events.PopEvent(); break; case EVENT_TRIGGER: if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) trigger->SetPhaseMask(2, true); - events.PopEvent(); break; case EVENT_PHASE: events.Reset(); @@ -419,7 +414,6 @@ public: Phase = 2; break; default: - events.PopEvent(); break; } } @@ -461,17 +455,17 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - if (uint32 eventId = events.GetEvent()) + if (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BOLT: DoCastVictim(SPELL_FROST_BOLT); - events.RepeatEvent(urand(5000, 10000)); + events.Repeat(5000, 10000); break; case EVENT_NOVA: DoCastAOE(SPELL_FROST_BOLT_AOE); - events.RepeatEvent(urand(15000, 30000)); + events.Repeat(15000, 30000); break; case EVENT_CHAIN: { @@ -490,7 +484,7 @@ public: } if (!chained.empty()) Talk(SAY_CHAIN); - events.RepeatEvent(urand(100000, 180000)); + events.Repeat(100000, 180000); break; } case EVENT_CHAINED_SPELL: @@ -565,10 +559,8 @@ public: ++itr; } - if (chained.empty()) - events.PopEvent(); - else - events.RepeatEvent(5000); + if (!chained.empty()) + events.Repeat(5000); break; } @@ -596,23 +588,22 @@ public: Talk(SAY_SPECIAL); } - events.RepeatEvent(urand(20000, 50000)); + events.Repeat(20000, 50000); break; } case EVENT_FISSURE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_SHADOW_FISURE); - events.RepeatEvent(urand(10000, 45000)); + events.Repeat(10000, 45000); break; case EVENT_BLAST: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, RAID_MODE(1, 0), 0, true)) DoCast(target, SPELL_FROST_BLAST); if (rand()%2) Talk(SAY_FROST_BLAST); - events.RepeatEvent(urand(30000, 90000)); + events.Repeat(30000, 90000); break; default: - events.PopEvent(); break; } } |