aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CreatureAIImpl.h68
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp35
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;
}
}