Merge pull request #12135 from Trisjdc/event_map_extension

Core/Util: A couple useful new functions for EventMap
This commit is contained in:
Sebastian Valle Herrera
2014-06-02 18:10:08 -05:00
2 changed files with 45 additions and 58 deletions

View File

@@ -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;
}
@@ -496,28 +492,6 @@ class EventMap
return 0;
}
/**
* @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.
@@ -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

View File

@@ -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;
}
}