diff options
Diffstat (limited to 'src/game/CreatureAIImpl.h')
-rw-r--r-- | src/game/CreatureAIImpl.h | 243 |
1 files changed, 234 insertions, 9 deletions
diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index 2f82522f426..f6653ce40f7 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -1,7 +1,5 @@ /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> - * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,14 +18,241 @@ #ifndef CREATUREAIIMPL_H #define CREATUREAIIMPL_H -#include "CreatureAI.h" +#include "Common.h" +#include "Platform/Define.h" + +#define HEROIC(n,h) (HeroicMode ? h : n) + +template<class T> +inline +const T& RAND(const T& v1, const T& v2) +{ + return (rand()%2) ? v1 : v2; +} + +template<class T> +inline +const T& RAND(const T& v1, const T& v2, const T& v3) +{ + switch(rand()%3) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + } +} -template<class REAL_AI> -inline CreatureAI* -CreatureAIFactory<REAL_AI>::Create(void *data) const +template<class T> +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) { - Creature* creature = reinterpret_cast<Creature *>(data); - return (new REAL_AI(creature)); + switch(rand()%4) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + } } + +template<class T> +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) +{ + switch(rand()%5) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + case 4: return v5; + } +} + +template<class T> +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6) +{ + switch(rand()%6) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + case 4: return v5; + case 5: return v6; + } +} + +class EventMap : private std::map<uint32, uint32> +{ + private: + uint32 m_time, m_phase; + public: + explicit EventMap() : m_phase(0), m_time(0) {} + + uint32 GetTimer() const { return m_time; } + + void Reset() { clear(); m_time = 0; m_phase = 0; } + + void Update(uint32 time) { m_time += time; } + + void SetPhase(uint32 phase) + { + if(phase && phase < 9) + m_phase = (1 << (phase + 24)); + } + + void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) + { + time += m_time; + if(gcd && gcd < 9) + eventId |= (1 << (gcd + 16)); + if(phase && phase < 9) + eventId |= (1 << (phase + 24)); + iterator itr = find(time); + while(itr != end()) + { + ++time; + itr = find(time); + } + insert(std::make_pair(time, eventId)); + } + + void RescheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) + { + CancelEvent(eventId); + ScheduleEvent(eventId, time, gcd, phase); + } + + void RepeatEvent(uint32 time) + { + if(empty()) + return; + uint32 eventId = begin()->second; + erase(begin()); + time += m_time; + iterator itr = find(time); + while(itr != end()) + { + ++time; + itr = find(time); + } + insert(std::make_pair(time, eventId)); + } + + void PopEvent() + { + erase(begin()); + } + + uint32 ExecuteEvent() + { + while(!empty()) + { + if(begin()->first > m_time) + return 0; + else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase)) + erase(begin()); + else + { + uint32 eventId = (begin()->second & 0x0000FFFF); + erase(begin()); + return eventId; + } + } + return 0; + } + + uint32 GetEvent() + { + while(!empty()) + { + if(begin()->first > m_time) + return 0; + else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase)) + erase(begin()); + else + { + return (begin()->second & 0x0000FFFF); + } + } + return 0; + } + + void DelayEvents(uint32 time, uint32 gcd) + { + time += m_time; + gcd = (1 << (gcd + 16)); + for(iterator itr = begin(); itr != end();) + { + if(itr->first >= time) + break; + if(itr->second & gcd) + { + ScheduleEvent(time, itr->second); + erase(itr++); + } + else + ++itr; + } + } + + void CancelEvent(uint32 eventId) + { + for(iterator itr = begin(); itr != end();) + { + if(eventId == (itr->second & 0x0000FFFF)) + erase(itr++); + else + ++itr; + } + } + + void CancelEventsByGCD(uint32 gcd) + { + for(iterator itr = begin(); itr != end();) + { + if(itr->second & gcd) + erase(itr++); + else + ++itr; + } + } +}; + +enum AITarget +{ + AITARGET_SELF, + AITARGET_VICTIM, + AITARGET_ENEMY, + AITARGET_ALLY, + AITARGET_BUFF, + AITARGET_DEBUFF, +}; + +enum AICondition +{ + AICOND_AGGRO, + AICOND_COMBAT, + AICOND_DIE, +}; + +#define AI_DEFAULT_COOLDOWN 5000 + +struct AISpellInfoType +{ + AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} + AITarget target; + AICondition condition; + uint32 cooldown; +}; + +TRINITY_DLL_SPEC AISpellInfoType * GetAISpellInfo(uint32 i); + #endif |