diff options
author | QAston <none@none> | 2009-05-15 18:00:50 +0200 |
---|---|---|
committer | QAston <none@none> | 2009-05-15 18:00:50 +0200 |
commit | a796012723dd2410a150264a4f32f00bc570ef76 (patch) | |
tree | d55cada7db3c9c752815c79d9d164069acd99edc /src/game/AggressorAI.cpp | |
parent | ae461a4158d6376e28e7bc53d3f7ad5690a5064e (diff) | |
parent | ad92f5e210b7a2c0584cdabd30560fe723d160be (diff) |
*Merge some fixes from tc1
--HG--
branch : trunk
Diffstat (limited to 'src/game/AggressorAI.cpp')
-rw-r--r-- | src/game/AggressorAI.cpp | 125 |
1 files changed, 61 insertions, 64 deletions
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index a637e7e40f0..22ebe87cdc6 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -19,16 +19,9 @@ */ #include "AggressorAI.h" -#include "Errors.h" -#include "Creature.h" -#include "ObjectAccessor.h" -#include "VMapFactory.h" -#include "World.h" +#include "SpellMgr.h" -#include <list> - -int -AggressorAI::Permissible(const Creature *creature) +int AggressorAI::Permissible(const Creature *creature) { // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight if( !creature->isCivilian() && !creature->IsNeutralToAll() ) @@ -37,79 +30,83 @@ AggressorAI::Permissible(const Creature *creature) return PERMIT_BASE_NO; } -AggressorAI::AggressorAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) +void AggressorAI::UpdateAI(const uint32 /*diff*/) { + if(!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); } -void AggressorAI::EnterEvadeMode() +int SpellAI::Permissible(const Creature *creature) { - if( !m_creature->isAlive() ) - { - DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow()); - i_victimGuid = 0; - m_creature->CombatStop(true); - m_creature->DeleteThreatList(); - return; - } + return PERMIT_BASE_NO; +} - Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid ); +void SpellAI::InitializeAI() +{ + for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + if(me->m_spells[i] && GetSpellStore()->LookupEntry(me->m_spells[i])) + spells.push_back(me->m_spells[i]); +} - if( !victim ) - { - DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow()); - } - else if( !victim->isAlive() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", m_creature->GetGUIDLow()); - } - else if( victim->HasStealthAura() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow()); - } - else if( victim->isInFlight() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow()); - } - else - { - DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", m_creature->GetGUIDLow()); - //i_state = STATE_LOOK_AT_VICTIM; - //i_tracker.Reset(TIME_INTERVAL_LOOK); - } +void SpellAI::Reset() +{ + events.Reset(); +} - if(!m_creature->GetCharmerOrOwner()) - { - m_creature->RemoveAllAuras(); +void SpellAI::JustDied(Unit *killer) +{ + for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) + if(AISpellInfo[*i].condition == AICOND_DIE) + me->CastSpell(killer, *i, true); +} - // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead - if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE ) - m_creature->GetMotionMaster()->MoveTargetedHome(); +void SpellAI::EnterCombat(Unit *who) +{ + for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) + { + if(AISpellInfo[*i].condition == AICOND_AGGRO) + me->CastSpell(who, *i, true); + else if(AISpellInfo[*i].condition == AICOND_COMBAT) + events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown); } - else if (m_creature->GetOwner() && m_creature->GetOwner()->isAlive()) - m_creature->GetMotionMaster()->MoveFollow(m_creature->GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); - - m_creature->DeleteThreatList(); - i_victimGuid = 0; - m_creature->CombatStop(true); - m_creature->SetLootRecipient(NULL); } -void -AggressorAI::UpdateAI(const uint32 /*diff*/) +void SpellAI::UpdateAI(const uint32 diff) { - // update i_victimGuid if m_creature->getVictim() !=0 and changed if(!UpdateVictim()) return; - i_victimGuid = m_creature->getVictim()->GetGUID(); + events.Update(diff); - if( m_creature->isAttackReady() ) + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + + if(uint32 spellId = events.ExecuteEvent()) { - if( m_creature->IsWithinMeleeRange(m_creature->getVictim())) + Unit *target = NULL; + //sLog.outError("aggre %u %u", spellId, (uint32)AISpellInfo[spellId].target); + switch(AISpellInfo[spellId].target) { - m_creature->AttackerStateUpdate(m_creature->getVictim()); - m_creature->resetAttackTimer(); + default: + case AITARGET_SELF: target = me; break; + case AITARGET_VICTIM: target = me->getVictim(); break; + case AITARGET_ENEMY: target = SelectTarget(SELECT_TARGET_RANDOM); break; + case AITARGET_ALLY: target = me; break; + case AITARGET_BUFF: target = me; break; + case AITARGET_DEBUFF: + { + const SpellEntry * spellInfo = GetSpellStore()->LookupEntry(spellId); + bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY; + float range = GetSpellMaxRange(spellInfo, false); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, range, playerOnly, -(int32)spellId); + break; + } } + if(target) me->CastSpell(target, spellId, false); + events.ScheduleEvent(spellId, AISpellInfo[spellId].cooldown + rand()%AISpellInfo[spellId].cooldown); } + else + DoMeleeAttackIfReady(); } - |