mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[7667] Add to CreatureAI field pointing to creature itself. Use it instead diff. fields in subclases.
Also send pointer to AI constructors ans mark constructors as explicit. This changes allow move now some generic often used AI code to CreatureAI helper functions.
This commit is contained in:
parent
721e005b84
commit
69fb9736cc
18 changed files with 379 additions and 382 deletions
|
|
@ -80,7 +80,7 @@ struct Script
|
||||||
|
|
||||||
struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI
|
struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI
|
||||||
{
|
{
|
||||||
ScriptedAI(Creature* creature) : m_creature(creature) {}
|
explicit ScriptedAI(Creature* creature) : CreatureAI(creature) {}
|
||||||
~ScriptedAI() {}
|
~ScriptedAI() {}
|
||||||
|
|
||||||
// Called if IsVisible(Unit *who) is true at each *who move
|
// Called if IsVisible(Unit *who) is true at each *who move
|
||||||
|
|
@ -122,8 +122,6 @@ struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI
|
||||||
// Called when spell hits creature's target
|
// Called when spell hits creature's target
|
||||||
void SpellHitTarget(Unit*, const SpellEntry*) {}
|
void SpellHitTarget(Unit*, const SpellEntry*) {}
|
||||||
|
|
||||||
Creature* m_creature;
|
|
||||||
|
|
||||||
//= Some useful helpers =========================
|
//= Some useful helpers =========================
|
||||||
|
|
||||||
// Start attack of victim and go to him
|
// Start attack of victim and go to him
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ AggressorAI::Permissible(const Creature *creature)
|
||||||
return PERMIT_BASE_NO;
|
return PERMIT_BASE_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
|
AggressorAI::AggressorAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,25 +43,25 @@ void
|
||||||
AggressorAI::MoveInLineOfSight(Unit *u)
|
AggressorAI::MoveInLineOfSight(Unit *u)
|
||||||
{
|
{
|
||||||
// Ignore Z for flying creatures
|
// Ignore Z for flying creatures
|
||||||
if( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
|
if( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
|
if( !m_creature->hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
|
||||||
( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) &&
|
( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) &&
|
||||||
u->isInAccessablePlaceFor(&i_creature) )
|
u->isInAccessablePlaceFor(m_creature) )
|
||||||
{
|
{
|
||||||
float attackRadius = i_creature.GetAttackDistance(u);
|
float attackRadius = m_creature->GetAttackDistance(u);
|
||||||
if(i_creature.IsWithinDistInMap(u, attackRadius) && i_creature.IsWithinLOSInMap(u) )
|
if(m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u) )
|
||||||
{
|
{
|
||||||
if(!i_creature.getVictim())
|
if(!m_creature->getVictim())
|
||||||
{
|
{
|
||||||
AttackStart(u);
|
AttackStart(u);
|
||||||
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||||
}
|
}
|
||||||
else if(sMapStore.LookupEntry(i_creature.GetMapId())->IsDungeon())
|
else if(sMapStore.LookupEntry(m_creature->GetMapId())->IsDungeon())
|
||||||
{
|
{
|
||||||
u->SetInCombatWith(&i_creature);
|
u->SetInCombatWith(m_creature);
|
||||||
i_creature.AddThreat(u, 0.0f);
|
m_creature->AddThreat(u, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -69,70 +69,70 @@ AggressorAI::MoveInLineOfSight(Unit *u)
|
||||||
|
|
||||||
void AggressorAI::EnterEvadeMode()
|
void AggressorAI::EnterEvadeMode()
|
||||||
{
|
{
|
||||||
if( !i_creature.isAlive() )
|
if( !m_creature->isAlive() )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
|
||||||
i_victimGuid = 0;
|
i_victimGuid = 0;
|
||||||
i_creature.CombatStop();
|
m_creature->CombatStop();
|
||||||
i_creature.DeleteThreatList();
|
m_creature->DeleteThreatList();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
|
||||||
|
|
||||||
if( !victim )
|
if( !victim )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else if( !victim->isAlive() )
|
else if( !victim->isAlive() )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else if( victim->HasStealthAura() )
|
else if( victim->HasStealthAura() )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else if( victim->isInFlight() )
|
else if( victim->isInFlight() )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", m_creature->GetGUIDLow());
|
||||||
//i_state = STATE_LOOK_AT_VICTIM;
|
//i_state = STATE_LOOK_AT_VICTIM;
|
||||||
//i_tracker.Reset(TIME_INTERVAL_LOOK);
|
//i_tracker.Reset(TIME_INTERVAL_LOOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!i_creature.isCharmed())
|
if(!m_creature->isCharmed())
|
||||||
{
|
{
|
||||||
i_creature.RemoveAllAuras();
|
m_creature->RemoveAllAuras();
|
||||||
|
|
||||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
i_creature.DeleteThreatList();
|
m_creature->DeleteThreatList();
|
||||||
i_victimGuid = 0;
|
i_victimGuid = 0;
|
||||||
i_creature.CombatStop();
|
m_creature->CombatStop();
|
||||||
i_creature.SetLootRecipient(NULL);
|
m_creature->SetLootRecipient(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AggressorAI::UpdateAI(const uint32 /*diff*/)
|
AggressorAI::UpdateAI(const uint32 /*diff*/)
|
||||||
{
|
{
|
||||||
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
// update i_victimGuid if m_creature->getVictim() !=0 and changed
|
||||||
if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
|
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i_victimGuid = i_creature.getVictim()->GetGUID();
|
i_victimGuid = m_creature->getVictim()->GetGUID();
|
||||||
|
|
||||||
if( i_creature.isAttackReady() )
|
if( m_creature->isAttackReady() )
|
||||||
{
|
{
|
||||||
if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
|
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
|
||||||
{
|
{
|
||||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||||
i_creature.resetAttackTimer();
|
m_creature->resetAttackTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,8 +140,8 @@ AggressorAI::UpdateAI(const uint32 /*diff*/)
|
||||||
bool
|
bool
|
||||||
AggressorAI::IsVisible(Unit *pl) const
|
AggressorAI::IsVisible(Unit *pl) const
|
||||||
{
|
{
|
||||||
return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
||||||
&& pl->isVisibleForOrDetect(&i_creature,true);
|
&& pl->isVisibleForOrDetect(m_creature,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -150,15 +150,15 @@ AggressorAI::AttackStart(Unit *u)
|
||||||
if( !u )
|
if( !u )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(i_creature.Attack(u,true))
|
if(m_creature->Attack(u,true))
|
||||||
{
|
{
|
||||||
i_creature.SetInCombatWith(u);
|
m_creature->SetInCombatWith(u);
|
||||||
u->SetInCombatWith(&i_creature);
|
u->SetInCombatWith(m_creature);
|
||||||
|
|
||||||
i_creature.AddThreat(u, 0.0f);
|
m_creature->AddThreat(u, 0.0f);
|
||||||
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
|
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", m_creature->GetName(), u->GetGUIDLow());
|
||||||
i_victimGuid = u->GetGUID();
|
i_victimGuid = u->GetGUID();
|
||||||
|
|
||||||
i_creature.GetMotionMaster()->MoveChase(u);
|
m_creature->GetMotionMaster()->MoveChase(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class MANGOS_DLL_DECL AggressorAI : public CreatureAI
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AggressorAI(Creature &c);
|
explicit AggressorAI(Creature *c);
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit *);
|
void MoveInLineOfSight(Unit *);
|
||||||
void AttackStart(Unit *);
|
void AttackStart(Unit *);
|
||||||
|
|
@ -45,7 +45,6 @@ class MANGOS_DLL_DECL AggressorAI : public CreatureAI
|
||||||
static int Permissible(const Creature *);
|
static int Permissible(const Creature *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Creature &i_creature;
|
|
||||||
uint64 i_victimGuid;
|
uint64 i_victimGuid;
|
||||||
AggressorState i_state;
|
AggressorState i_state;
|
||||||
TimeTracker i_tracker;
|
TimeTracker i_tracker;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ struct SpellEntry;
|
||||||
class MANGOS_DLL_SPEC CreatureAI
|
class MANGOS_DLL_SPEC CreatureAI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit CreatureAI(Creature* creature) : m_creature(creature) {}
|
||||||
|
|
||||||
virtual ~CreatureAI();
|
virtual ~CreatureAI();
|
||||||
|
|
||||||
|
|
@ -94,6 +95,8 @@ class MANGOS_DLL_SPEC CreatureAI
|
||||||
|
|
||||||
// Called at waypoint reached or point movement finished
|
// Called at waypoint reached or point movement finished
|
||||||
virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
|
virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
|
||||||
|
|
||||||
|
Creature* const m_creature;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
|
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,6 @@ inline CreatureAI*
|
||||||
CreatureAIFactory<REAL_AI>::Create(void *data) const
|
CreatureAIFactory<REAL_AI>::Create(void *data) const
|
||||||
{
|
{
|
||||||
Creature* creature = reinterpret_cast<Creature *>(data);
|
Creature* creature = reinterpret_cast<Creature *>(data);
|
||||||
return (new REAL_AI(*creature));
|
return (new REAL_AI(creature));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ namespace FactorySelector
|
||||||
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
|
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
|
||||||
|
|
||||||
DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
|
DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
|
||||||
return ( ai_factory == NULL ? new NullCreatureAI : ai_factory->Create(creature) );
|
return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) );
|
||||||
}
|
}
|
||||||
|
|
||||||
MovementGenerator* selectMovementGenerator(Creature *creature)
|
MovementGenerator* selectMovementGenerator(Creature *creature)
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,9 @@ int CreatureEventAI::Permissible(const Creature *creature)
|
||||||
return PERMIT_BASE_NO;
|
return PERMIT_BASE_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureEventAI::CreatureEventAI(Creature &c ) : m_creature(c), InCombat(false)
|
CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c), InCombat(false)
|
||||||
{
|
{
|
||||||
CreatureEventAI_Event_Map::iterator CreatureEvents = CreatureEAI_Mgr.GetCreatureEventAIMap().find(m_creature.GetEntry());
|
CreatureEventAI_Event_Map::iterator CreatureEvents = CreatureEAI_Mgr.GetCreatureEventAIMap().find(m_creature->GetEntry());
|
||||||
if (CreatureEvents != CreatureEAI_Mgr.GetCreatureEventAIMap().end())
|
if (CreatureEvents != CreatureEAI_Mgr.GetCreatureEventAIMap().end())
|
||||||
{
|
{
|
||||||
std::vector<CreatureEventAI_Event>::iterator i;
|
std::vector<CreatureEventAI_Event>::iterator i;
|
||||||
|
|
@ -51,10 +51,10 @@ CreatureEventAI::CreatureEventAI(Creature &c ) : m_creature(c), InCombat(false)
|
||||||
if ((*i).event_flags & EFLAG_DEBUG_ONLY)
|
if ((*i).event_flags & EFLAG_DEBUG_ONLY)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
if( m_creature.GetMap()->IsDungeon() )
|
if (m_creature->GetMap()->IsDungeon())
|
||||||
{
|
{
|
||||||
if( (m_creature.GetMap()->IsHeroic() && (*i).event_flags & EFLAG_HEROIC) ||
|
if( (m_creature->GetMap()->IsHeroic() && (*i).event_flags & EFLAG_HEROIC) ||
|
||||||
(!m_creature.GetMap()->IsHeroic() && (*i).event_flags & EFLAG_NORMAL))
|
(!m_creature->GetMap()->IsHeroic() && (*i).event_flags & EFLAG_NORMAL))
|
||||||
{
|
{
|
||||||
//event flagged for instance mode
|
//event flagged for instance mode
|
||||||
CreatureEventAIList.push_back(CreatureEventAIHolder(*i));
|
CreatureEventAIList.push_back(CreatureEventAIHolder(*i));
|
||||||
|
|
@ -65,10 +65,10 @@ CreatureEventAI::CreatureEventAI(Creature &c ) : m_creature(c), InCombat(false)
|
||||||
}
|
}
|
||||||
//EventMap had events but they were not added because they must be for instance
|
//EventMap had events but they were not added because they must be for instance
|
||||||
if (CreatureEventAIList.empty())
|
if (CreatureEventAIList.empty())
|
||||||
sLog.outError("CreatureEventAI: CreatureId has events but no events added to list because of instance flags.", m_creature.GetEntry());
|
sLog.outError("CreatureEventAI: CreatureId has events but no events added to list because of instance flags.", m_creature->GetEntry());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sLog.outError("CreatureEventAI: EventMap for Creature %u is empty but creature is using CreatureEventAI.", m_creature.GetEntry());
|
sLog.outError("CreatureEventAI: EventMap for Creature %u is empty but creature is using CreatureEventAI.", m_creature->GetEntry());
|
||||||
|
|
||||||
bEmptyList = CreatureEventAIList.empty();
|
bEmptyList = CreatureEventAIList.empty();
|
||||||
Phase = 0;
|
Phase = 0;
|
||||||
|
|
@ -151,7 +151,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
pHolder.Time = urand(param3, param4);
|
pHolder.Time = urand(param3, param4);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -171,17 +171,17 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_T_HP:
|
case EVENT_T_HP:
|
||||||
{
|
{
|
||||||
if (!InCombat || !m_creature.GetMaxHealth())
|
if (!InCombat || !m_creature->GetMaxHealth())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 perc = (m_creature.GetHealth()*100) / m_creature.GetMaxHealth();
|
uint32 perc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth();
|
||||||
|
|
||||||
if (perc > param1 || perc < param2)
|
if (perc > param1 || perc < param2)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -196,17 +196,17 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_T_MANA:
|
case EVENT_T_MANA:
|
||||||
{
|
{
|
||||||
if (!InCombat || !m_creature.GetMaxPower(POWER_MANA))
|
if (!InCombat || !m_creature->GetMaxPower(POWER_MANA))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 perc = (m_creature.GetPower(POWER_MANA)*100) / m_creature.GetMaxPower(POWER_MANA);
|
uint32 perc = (m_creature->GetPower(POWER_MANA)*100) / m_creature->GetMaxPower(POWER_MANA);
|
||||||
|
|
||||||
if (perc > param1 || perc < param2)
|
if (perc > param1 || perc < param2)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -221,7 +221,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -242,7 +242,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -268,7 +268,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -285,7 +285,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +302,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -313,10 +313,10 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
break;
|
break;
|
||||||
case EVENT_T_TARGET_HP:
|
case EVENT_T_TARGET_HP:
|
||||||
{
|
{
|
||||||
if (!InCombat || !m_creature.getVictim() || !m_creature.getVictim()->GetMaxHealth())
|
if (!InCombat || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxHealth())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 perc = (m_creature.getVictim()->GetHealth()*100) / m_creature.getVictim()->GetMaxHealth();
|
uint32 perc = (m_creature->getVictim()->GetHealth()*100) / m_creature->getVictim()->GetMaxHealth();
|
||||||
|
|
||||||
if (perc > param1 || perc < param2)
|
if (perc > param1 || perc < param2)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -331,14 +331,14 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_T_TARGET_CASTING:
|
case EVENT_T_TARGET_CASTING:
|
||||||
{
|
{
|
||||||
if (!InCombat || !m_creature.getVictim() || !m_creature.getVictim()->IsNonMeleeSpellCasted(false, false, true))
|
if (!InCombat || !m_creature->getVictim() || !m_creature->getVictim()->IsNonMeleeSpellCasted(false, false, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Repeat Timers
|
//Repeat Timers
|
||||||
|
|
@ -351,7 +351,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -378,7 +378,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -407,7 +407,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
pHolder.Time = urand(param3, param4);
|
pHolder.Time = urand(param3, param4);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -434,7 +434,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -459,7 +459,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
pHolder.Enabled = false;
|
pHolder.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -474,7 +474,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -531,7 +531,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
target = owner;
|
target = owner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (target = m_creature.getVictim())
|
else if (target = m_creature->getVictim())
|
||||||
{
|
{
|
||||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
|
|
@ -543,21 +543,21 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DoScriptText(temp, &m_creature, target);
|
DoScriptText(temp, m_creature, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_SET_FACTION:
|
case ACTION_T_SET_FACTION:
|
||||||
{
|
{
|
||||||
if (param1)
|
if (param1)
|
||||||
m_creature.setFaction(param1);
|
m_creature->setFaction(param1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (CreatureInfo const* ci = GetCreatureTemplateStore(m_creature.GetEntry()))
|
if (CreatureInfo const* ci = GetCreatureTemplateStore(m_creature->GetEntry()))
|
||||||
{
|
{
|
||||||
//if no id provided, assume reset and then use default
|
//if no id provided, assume reset and then use default
|
||||||
if (m_creature.getFaction() != ci->faction_A)
|
if (m_creature->getFaction() != ci->faction_A)
|
||||||
m_creature.setFaction(ci->faction_A);
|
m_creature->setFaction(ci->faction_A);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -573,29 +573,29 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
{
|
{
|
||||||
//use default display
|
//use default display
|
||||||
if (ci->DisplayID_A)
|
if (ci->DisplayID_A)
|
||||||
m_creature.SetDisplayId(ci->DisplayID_A);
|
m_creature->SetDisplayId(ci->DisplayID_A);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if no param1, then use value from param2 (modelId)
|
//if no param1, then use value from param2 (modelId)
|
||||||
else
|
else
|
||||||
m_creature.SetDisplayId(param2);
|
m_creature->SetDisplayId(param2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_creature.DeMorph();
|
m_creature->DeMorph();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_SOUND:
|
case ACTION_T_SOUND:
|
||||||
m_creature.PlayDirectSound(param1);
|
m_creature->PlayDirectSound(param1);
|
||||||
break;
|
break;
|
||||||
case ACTION_T_EMOTE:
|
case ACTION_T_EMOTE:
|
||||||
m_creature.HandleEmoteCommand(param1);
|
m_creature->HandleEmoteCommand(param1);
|
||||||
break;
|
break;
|
||||||
case ACTION_T_RANDOM_SOUND:
|
case ACTION_T_RANDOM_SOUND:
|
||||||
{
|
{
|
||||||
uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
|
uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
|
||||||
|
|
||||||
if (temp != uint32(0xffffffff))
|
if (temp != uint32(0xffffffff))
|
||||||
m_creature.PlayDirectSound( temp );
|
m_creature->PlayDirectSound( temp );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_RANDOM_EMOTE:
|
case ACTION_T_RANDOM_EMOTE:
|
||||||
|
|
@ -603,13 +603,13 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
|
uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
|
||||||
|
|
||||||
if (temp != uint32(0xffffffff))
|
if (temp != uint32(0xffffffff))
|
||||||
m_creature.HandleEmoteCommand(temp);
|
m_creature->HandleEmoteCommand(temp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_CAST:
|
case ACTION_T_CAST:
|
||||||
{
|
{
|
||||||
Unit* target = GetTargetByType(param2, pActionInvoker);
|
Unit* target = GetTargetByType(param2, pActionInvoker);
|
||||||
Unit* caster = &m_creature;
|
Unit* caster = m_creature;
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
return;
|
return;
|
||||||
|
|
@ -646,13 +646,13 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
//Melee current victim if flag not set
|
//Melee current victim if flag not set
|
||||||
if (!(param3 & CAST_NO_MELEE_IF_OOM))
|
if (!(param3 & CAST_NO_MELEE_IF_OOM))
|
||||||
{
|
{
|
||||||
if (m_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||||
{
|
{
|
||||||
AttackDistance = 0;
|
AttackDistance = 0;
|
||||||
AttackAngle = 0;
|
AttackAngle = 0;
|
||||||
|
|
||||||
m_creature.GetMotionMaster()->Clear(false);
|
m_creature->GetMotionMaster()->Clear(false);
|
||||||
m_creature.GetMotionMaster()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
|
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -667,7 +667,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
}
|
}
|
||||||
|
|
||||||
}else
|
}else
|
||||||
sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature.GetEntry(), param1);
|
sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), param1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -678,14 +678,14 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
Creature* pCreature = NULL;
|
Creature* pCreature = NULL;
|
||||||
|
|
||||||
if (param3)
|
if (param3)
|
||||||
pCreature = m_creature.SummonCreature(param1, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, param3);
|
pCreature = m_creature->SummonCreature(param1, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, param3);
|
||||||
else
|
else
|
||||||
pCreature = m_creature.SummonCreature(param1, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
pCreature = m_creature->SummonCreature(param1, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
||||||
|
|
||||||
if (!pCreature)
|
if (!pCreature)
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", param1, EventId, m_creature.GetEntry());
|
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", param1, EventId, m_creature->GetEntry());
|
||||||
}
|
}
|
||||||
else if (param2 != TARGET_T_SELF && target)
|
else if (param2 != TARGET_T_SELF && target)
|
||||||
pCreature->AI()->AttackStart(target);
|
pCreature->AI()->AttackStart(target);
|
||||||
|
|
@ -696,19 +696,19 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
Unit* target = GetTargetByType(param2, pActionInvoker);
|
Unit* target = GetTargetByType(param2, pActionInvoker);
|
||||||
|
|
||||||
if (target)
|
if (target)
|
||||||
m_creature.getThreatManager().modifyThreatPercent(target, param1);
|
m_creature->getThreatManager().modifyThreatPercent(target, param1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_THREAT_ALL_PCT:
|
case ACTION_T_THREAT_ALL_PCT:
|
||||||
{
|
{
|
||||||
Unit* Temp = NULL;
|
Unit* Temp = NULL;
|
||||||
|
|
||||||
std::list<HostilReference*>::iterator i = m_creature.getThreatManager().getThreatList().begin();
|
std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
|
||||||
for (; i != m_creature.getThreatManager().getThreatList().end(); ++i)
|
for (; i != m_creature->getThreatManager().getThreatList().end(); ++i)
|
||||||
{
|
{
|
||||||
Temp = Unit::GetUnit(m_creature,(*i)->getUnitGuid());
|
Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
|
||||||
if (Temp)
|
if (Temp)
|
||||||
m_creature.getThreatManager().modifyThreatPercent(Temp, param1);
|
m_creature->getThreatManager().modifyThreatPercent(Temp, param1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -725,7 +725,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
Unit* target = GetTargetByType(param3, pActionInvoker);
|
Unit* target = GetTargetByType(param3, pActionInvoker);
|
||||||
|
|
||||||
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
||||||
((Player*)target)->CastedCreatureOrGO(param1, m_creature.GetGUID(), param2);
|
((Player*)target)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_SET_UNIT_FIELD:
|
case ACTION_T_SET_UNIT_FIELD:
|
||||||
|
|
@ -769,18 +769,18 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
//Allow movement (create new targeted movement gen only if idle)
|
//Allow movement (create new targeted movement gen only if idle)
|
||||||
if (CombatMovementEnabled)
|
if (CombatMovementEnabled)
|
||||||
{
|
{
|
||||||
if (m_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE)
|
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE)
|
||||||
{
|
{
|
||||||
m_creature.GetMotionMaster()->Clear(false);
|
m_creature->GetMotionMaster()->Clear(false);
|
||||||
m_creature.GetMotionMaster()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
|
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (m_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||||
{
|
{
|
||||||
m_creature.GetMotionMaster()->Clear(false);
|
m_creature->GetMotionMaster()->Clear(false);
|
||||||
m_creature.GetMotionMaster()->MoveIdle();
|
m_creature->GetMotionMaster()->MoveIdle();
|
||||||
m_creature.StopMoving();
|
m_creature->StopMoving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -795,7 +795,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
|
|
||||||
if (Phase > 31)
|
if (Phase > 31)
|
||||||
|
|
||||||
sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above 31. Phase mask cannot be used with phases past 31. CreatureEntry = %d", EventId, m_creature.GetEntry());
|
sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above 31. Phase mask cannot be used with phases past 31. CreatureEntry = %d", EventId, m_creature->GetEntry());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_EVADE:
|
case ACTION_T_EVADE:
|
||||||
|
|
@ -806,7 +806,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
case ACTION_T_FLEE:
|
case ACTION_T_FLEE:
|
||||||
{
|
{
|
||||||
//TODO: Replace with Flee movement generator
|
//TODO: Replace with Flee movement generator
|
||||||
m_creature.CastSpell(&m_creature, SPELL_RUN_AWAY, true);
|
m_creature->CastSpell(m_creature, SPELL_RUN_AWAY, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_QUEST_EVENT_ALL:
|
case ACTION_T_QUEST_EVENT_ALL:
|
||||||
|
|
@ -814,9 +814,9 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
Unit* Temp = NULL;
|
Unit* Temp = NULL;
|
||||||
if( pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER )
|
if( pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER )
|
||||||
{
|
{
|
||||||
Temp = Unit::GetUnit(m_creature,pActionInvoker->GetGUID());
|
Temp = Unit::GetUnit(*m_creature,pActionInvoker->GetGUID());
|
||||||
if( Temp )
|
if( Temp )
|
||||||
((Player*)Temp)->GroupEventHappens(param1,&m_creature);
|
((Player*)Temp)->GroupEventHappens(param1,m_creature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -824,12 +824,12 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
{
|
{
|
||||||
Unit* Temp = NULL;
|
Unit* Temp = NULL;
|
||||||
|
|
||||||
std::list<HostilReference*>::iterator i = m_creature.getThreatManager().getThreatList().begin();
|
std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
|
||||||
for (; i != m_creature.getThreatManager().getThreatList().end(); ++i)
|
for (; i != m_creature->getThreatManager().getThreatList().end(); ++i)
|
||||||
{
|
{
|
||||||
Temp = Unit::GetUnit(m_creature,(*i)->getUnitGuid());
|
Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
|
||||||
if (Temp && Temp->GetTypeId() == TYPEID_PLAYER)
|
if (Temp && Temp->GetTypeId() == TYPEID_PLAYER)
|
||||||
((Player*)Temp)->CastedCreatureOrGO(param1, m_creature.GetGUID(), param2);
|
((Player*)Temp)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -848,11 +848,11 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
|
|
||||||
if (CombatMovementEnabled)
|
if (CombatMovementEnabled)
|
||||||
{
|
{
|
||||||
if (m_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||||
{
|
{
|
||||||
//Drop current movement gen
|
//Drop current movement gen
|
||||||
m_creature.GetMotionMaster()->Clear(false);
|
m_creature->GetMotionMaster()->Clear(false);
|
||||||
m_creature.GetMotionMaster()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
|
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -871,7 +871,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
Phase = param1 + (rnd % (param2 - param1));
|
Phase = param1 + (rnd % (param2 - param1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sLog.outErrorDb( "CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 <= Param1. Divide by Zero. Event = %d. CreatureEntry = %d", EventId, m_creature.GetEntry());
|
sLog.outErrorDb( "CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 <= Param1. Divide by Zero. Event = %d. CreatureEntry = %d", EventId, m_creature->GetEntry());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_SUMMON_ID:
|
case ACTION_T_SUMMON_ID:
|
||||||
|
|
@ -885,18 +885,18 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
if (i == CreatureEAI_Mgr.GetCreatureEventAISummonMap().end())
|
if (i == CreatureEAI_Mgr.GetCreatureEventAISummonMap().end())
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", param1, param3, EventId, m_creature.GetEntry());
|
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", param1, param3, EventId, m_creature->GetEntry());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*i).second.SpawnTimeSecs)
|
if ((*i).second.SpawnTimeSecs)
|
||||||
pCreature = m_creature.SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
|
pCreature = m_creature->SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
|
||||||
else pCreature = m_creature.SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
else pCreature = m_creature->SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
|
||||||
|
|
||||||
if (!pCreature)
|
if (!pCreature)
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", param1, EventId, m_creature.GetEntry());
|
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", param1, EventId, m_creature->GetEntry());
|
||||||
}
|
}
|
||||||
else if (param2 != TARGET_T_SELF && target)
|
else if (param2 != TARGET_T_SELF && target)
|
||||||
pCreature->AI()->AttackStart(target);
|
pCreature->AI()->AttackStart(target);
|
||||||
|
|
@ -905,24 +905,24 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
case ACTION_T_KILLED_MONSTER:
|
case ACTION_T_KILLED_MONSTER:
|
||||||
{
|
{
|
||||||
//first attempt player who tapped creature
|
//first attempt player who tapped creature
|
||||||
if (Player* pPlayer = m_creature.GetLootRecipient())
|
if (Player* pPlayer = m_creature->GetLootRecipient())
|
||||||
pPlayer->RewardPlayerAndGroupAtEvent(param1, &m_creature);
|
pPlayer->RewardPlayerAndGroupAtEvent(param1, m_creature);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//if not available, use pActionInvoker
|
//if not available, use pActionInvoker
|
||||||
Unit* pTarget = GetTargetByType(param2, pActionInvoker);
|
Unit* pTarget = GetTargetByType(param2, pActionInvoker);
|
||||||
|
|
||||||
if (Player* pPlayer = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself())
|
if (Player* pPlayer = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||||
pPlayer->RewardPlayerAndGroupAtEvent(param1, &m_creature);
|
pPlayer->RewardPlayerAndGroupAtEvent(param1, m_creature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_SET_INST_DATA:
|
case ACTION_T_SET_INST_DATA:
|
||||||
{
|
{
|
||||||
InstanceData* pInst = (InstanceData*)m_creature.GetInstanceData();
|
InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
|
||||||
if (!pInst)
|
if (!pInst)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", EventId, m_creature.GetEntry());
|
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", EventId, m_creature->GetEntry());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -934,14 +934,14 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
Unit* target = GetTargetByType(param2, pActionInvoker);
|
Unit* target = GetTargetByType(param2, pActionInvoker);
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature.GetEntry());
|
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature->GetEntry());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceData* pInst = (InstanceData*)m_creature.GetInstanceData();
|
InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
|
||||||
if (!pInst)
|
if (!pInst)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", EventId, m_creature.GetEntry());
|
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", EventId, m_creature->GetEntry());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -950,37 +950,37 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||||
break;
|
break;
|
||||||
case ACTION_T_UPDATE_TEMPLATE:
|
case ACTION_T_UPDATE_TEMPLATE:
|
||||||
{
|
{
|
||||||
if (m_creature.GetEntry() == param1)
|
if (m_creature->GetEntry() == param1)
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", EventId, m_creature.GetEntry());
|
sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", EventId, m_creature->GetEntry());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_creature.UpdateEntry(param1, param2 ? HORDE : ALLIANCE);
|
m_creature->UpdateEntry(param1, param2 ? HORDE : ALLIANCE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_DIE:
|
case ACTION_T_DIE:
|
||||||
{
|
{
|
||||||
if (m_creature.isDead())
|
if (m_creature->isDead())
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", EventId, m_creature.GetEntry());
|
sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", EventId, m_creature->GetEntry());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_creature.DealDamage(&m_creature, m_creature.GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_T_ZONE_COMBAT_PULSE:
|
case ACTION_T_ZONE_COMBAT_PULSE:
|
||||||
{
|
{
|
||||||
if (!m_creature.isInCombat() || !m_creature.GetMap()->IsDungeon())
|
if (!m_creature->isInCombat() || !m_creature->GetMap()->IsDungeon())
|
||||||
{
|
{
|
||||||
|
|
||||||
sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_ZONE_COMBAT_PULSE on creature out of combat or in non-dungeon map. Creature %d", EventId, m_creature.GetEntry());
|
sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_ZONE_COMBAT_PULSE on creature out of combat or in non-dungeon map. Creature %d", EventId, m_creature->GetEntry());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoZoneInCombat(&m_creature);
|
DoZoneInCombat(m_creature);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1029,7 +1029,7 @@ void CreatureEventAI::Reset()
|
||||||
(*i).Enabled = true;
|
(*i).Enabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature.GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
//default:
|
//default:
|
||||||
|
|
@ -1043,7 +1043,7 @@ void CreatureEventAI::Reset()
|
||||||
|
|
||||||
void CreatureEventAI::JustReachedHome()
|
void CreatureEventAI::JustReachedHome()
|
||||||
{
|
{
|
||||||
m_creature.LoadCreaturesAddon();
|
m_creature->LoadCreaturesAddon();
|
||||||
|
|
||||||
if (!bEmptyList)
|
if (!bEmptyList)
|
||||||
{
|
{
|
||||||
|
|
@ -1059,15 +1059,15 @@ void CreatureEventAI::JustReachedHome()
|
||||||
|
|
||||||
void CreatureEventAI::EnterEvadeMode()
|
void CreatureEventAI::EnterEvadeMode()
|
||||||
{
|
{
|
||||||
m_creature.InterruptNonMeleeSpells(true);
|
m_creature->InterruptNonMeleeSpells(true);
|
||||||
m_creature.RemoveAllAuras();
|
m_creature->RemoveAllAuras();
|
||||||
m_creature.DeleteThreatList();
|
m_creature->DeleteThreatList();
|
||||||
m_creature.CombatStop();
|
m_creature->CombatStop();
|
||||||
|
|
||||||
if (m_creature.isAlive())
|
if (m_creature->isAlive())
|
||||||
m_creature.GetMotionMaster()->MoveTargetedHome();
|
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||||
|
|
||||||
m_creature.SetLootRecipient(NULL);
|
m_creature->SetLootRecipient(NULL);
|
||||||
|
|
||||||
InCombat = false;
|
InCombat = false;
|
||||||
|
|
||||||
|
|
@ -1148,7 +1148,7 @@ void CreatureEventAI::Aggro(Unit *who)
|
||||||
(*i).Enabled = true;
|
(*i).Enabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature.GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
|
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
|
||||||
break;
|
break;
|
||||||
//All normal events need to be re-enabled and their time set to 0
|
//All normal events need to be re-enabled and their time set to 0
|
||||||
default:
|
default:
|
||||||
|
|
@ -1168,11 +1168,11 @@ void CreatureEventAI::AttackStart(Unit *who)
|
||||||
if (!who)
|
if (!who)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_creature.Attack(who, MeleeEnabled))
|
if (m_creature->Attack(who, MeleeEnabled))
|
||||||
{
|
{
|
||||||
m_creature.AddThreat(who, 0.0f);
|
m_creature->AddThreat(who, 0.0f);
|
||||||
m_creature.SetInCombatWith(who);
|
m_creature->SetInCombatWith(who);
|
||||||
who->SetInCombatWith(&m_creature);
|
who->SetInCombatWith(m_creature);
|
||||||
|
|
||||||
if (!InCombat)
|
if (!InCombat)
|
||||||
{
|
{
|
||||||
|
|
@ -1182,12 +1182,12 @@ void CreatureEventAI::AttackStart(Unit *who)
|
||||||
|
|
||||||
if (CombatMovementEnabled)
|
if (CombatMovementEnabled)
|
||||||
{
|
{
|
||||||
m_creature.GetMotionMaster()->MoveChase(who, AttackDistance, AttackAngle);
|
m_creature->GetMotionMaster()->MoveChase(who, AttackDistance, AttackAngle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_creature.GetMotionMaster()->MoveIdle();
|
m_creature->GetMotionMaster()->MoveIdle();
|
||||||
m_creature.StopMoving();
|
m_creature->StopMoving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1198,7 +1198,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Check for OOC LOS Event
|
//Check for OOC LOS Event
|
||||||
if (!bEmptyList && !m_creature.getVictim())
|
if (!bEmptyList && !m_creature->getVictim())
|
||||||
{
|
{
|
||||||
for (std::list<CreatureEventAIHolder>::iterator itr = CreatureEventAIList.begin(); itr != CreatureEventAIList.end(); ++itr)
|
for (std::list<CreatureEventAIHolder>::iterator itr = CreatureEventAIList.begin(); itr != CreatureEventAIList.end(); ++itr)
|
||||||
{
|
{
|
||||||
|
|
@ -1208,38 +1208,38 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
|
||||||
float fMaxAllowedRange = (*itr).Event.event_param2;
|
float fMaxAllowedRange = (*itr).Event.event_param2;
|
||||||
|
|
||||||
//if range is ok and we are actually in LOS
|
//if range is ok and we are actually in LOS
|
||||||
if (m_creature.IsWithinDistInMap(who, fMaxAllowedRange) && m_creature.IsWithinLOSInMap(who))
|
if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who))
|
||||||
{
|
{
|
||||||
//if friendly event&&who is not hostile OR hostile event&&who is hostile
|
//if friendly event&&who is not hostile OR hostile event&&who is hostile
|
||||||
if (((*itr).Event.event_param1 && !m_creature.IsHostileTo(who)) ||
|
if (((*itr).Event.event_param1 && !m_creature->IsHostileTo(who)) ||
|
||||||
((!(*itr).Event.event_param1) && m_creature.IsHostileTo(who)))
|
((!(*itr).Event.event_param1) && m_creature->IsHostileTo(who)))
|
||||||
ProcessEvent(*itr, who);
|
ProcessEvent(*itr, who);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_creature.isCivilian() && m_creature.IsNeutralToAll())
|
if (m_creature->isCivilian() && m_creature->IsNeutralToAll())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!m_creature.hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() &&
|
if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() &&
|
||||||
m_creature.IsHostileTo(who) && who->isInAccessablePlaceFor(&m_creature))
|
m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
if (!m_creature.canFly() && m_creature.GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
|
if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float attackRadius = m_creature.GetAttackDistance(who);
|
float attackRadius = m_creature->GetAttackDistance(who);
|
||||||
if (m_creature.IsWithinDistInMap(who, attackRadius) && m_creature.IsWithinLOSInMap(who))
|
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
|
||||||
{
|
{
|
||||||
if (!m_creature.getVictim())
|
if (!m_creature->getVictim())
|
||||||
{
|
{
|
||||||
AttackStart(who);
|
AttackStart(who);
|
||||||
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||||
}
|
}
|
||||||
else if (m_creature.GetMap()->IsDungeon())
|
else if (m_creature->GetMap()->IsDungeon())
|
||||||
{
|
{
|
||||||
who->SetInCombatWith(&m_creature);
|
who->SetInCombatWith(m_creature);
|
||||||
m_creature.AddThreat(who, 0.0f);
|
m_creature->AddThreat(who, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1268,10 +1268,10 @@ void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
|
||||||
void CreatureEventAI::UpdateAI(const uint32 diff)
|
void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||||
{
|
{
|
||||||
//Check if we are in combat (also updates calls threat update code)
|
//Check if we are in combat (also updates calls threat update code)
|
||||||
bool Combat = InCombat ? (m_creature.SelectHostilTarget() && m_creature.getVictim()) : false;
|
bool Combat = InCombat ? (m_creature->SelectHostilTarget() && m_creature->getVictim()) : false;
|
||||||
|
|
||||||
//Must return if creature isn't alive. Normally select hostil target and get victim prevent this
|
//Must return if creature isn't alive. Normally select hostil target and get victim prevent this
|
||||||
if (!m_creature.isAlive())
|
if (!m_creature->isAlive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bEmptyList)
|
if (!bEmptyList)
|
||||||
|
|
@ -1317,9 +1317,9 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||||
case EVENT_T_RANGE:
|
case EVENT_T_RANGE:
|
||||||
if (Combat)
|
if (Combat)
|
||||||
{
|
{
|
||||||
if (m_creature.IsWithinDistInMap(m_creature.getVictim(),(float)(*i).Event.event_param2))
|
if (m_creature->IsWithinDistInMap(m_creature->getVictim(),(float)(*i).Event.event_param2))
|
||||||
{
|
{
|
||||||
if (m_creature.GetDistance(m_creature.getVictim()) >= (float)(*i).Event.event_param1)
|
if (m_creature->GetDistance(m_creature->getVictim()) >= (float)(*i).Event.event_param1)
|
||||||
ProcessEvent(*i);
|
ProcessEvent(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1344,14 +1344,14 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||||
|
|
||||||
bool CreatureEventAI::IsVisible(Unit *pl) const
|
bool CreatureEventAI::IsVisible(Unit *pl) const
|
||||||
{
|
{
|
||||||
return m_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
||||||
&& pl->isVisibleForOrDetect(&m_creature,true);
|
&& pl->isVisibleForOrDetect(m_creature,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
|
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
|
||||||
{
|
{
|
||||||
//ThreatList m_threatlist;
|
//ThreatList m_threatlist;
|
||||||
std::list<HostilReference*>& m_threatlist = m_creature.getThreatManager().getThreatList();
|
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
|
||||||
std::list<HostilReference*>::iterator i = m_threatlist.begin();
|
std::list<HostilReference*>::iterator i = m_threatlist.begin();
|
||||||
std::list<HostilReference*>::reverse_iterator r = m_threatlist.rbegin();
|
std::list<HostilReference*>::reverse_iterator r = m_threatlist.rbegin();
|
||||||
|
|
||||||
|
|
@ -1363,17 +1363,17 @@ inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position
|
||||||
case ATTACKING_TARGET_RANDOM:
|
case ATTACKING_TARGET_RANDOM:
|
||||||
{
|
{
|
||||||
advance ( i , position + (rand() % (m_threatlist.size() - position ) ));
|
advance ( i , position + (rand() % (m_threatlist.size() - position ) ));
|
||||||
return Unit::GetUnit(m_creature,(*i)->getUnitGuid());
|
return Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
|
||||||
}
|
}
|
||||||
case ATTACKING_TARGET_TOPAGGRO:
|
case ATTACKING_TARGET_TOPAGGRO:
|
||||||
{
|
{
|
||||||
advance ( i , position);
|
advance ( i , position);
|
||||||
return Unit::GetUnit(m_creature,(*i)->getUnitGuid());
|
return Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
|
||||||
}
|
}
|
||||||
case ATTACKING_TARGET_BOTTOMAGGRO:
|
case ATTACKING_TARGET_BOTTOMAGGRO:
|
||||||
{
|
{
|
||||||
advance ( r , position);
|
advance ( r , position);
|
||||||
return Unit::GetUnit(m_creature,(*r)->getUnitGuid());
|
return Unit::GetUnit(*m_creature,(*r)->getUnitGuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1401,10 +1401,10 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke
|
||||||
switch (Target)
|
switch (Target)
|
||||||
{
|
{
|
||||||
case TARGET_T_SELF:
|
case TARGET_T_SELF:
|
||||||
return &m_creature;
|
return m_creature;
|
||||||
break;
|
break;
|
||||||
case TARGET_T_HOSTILE:
|
case TARGET_T_HOSTILE:
|
||||||
return m_creature.getVictim();
|
return m_creature->getVictim();
|
||||||
break;
|
break;
|
||||||
case TARGET_T_HOSTILE_SECOND_AGGRO:
|
case TARGET_T_HOSTILE_SECOND_AGGRO:
|
||||||
return SelectUnit(ATTACKING_TARGET_TOPAGGRO,1);
|
return SelectUnit(ATTACKING_TARGET_TOPAGGRO,1);
|
||||||
|
|
@ -1429,15 +1429,15 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke
|
||||||
|
|
||||||
Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
|
Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
|
||||||
{
|
{
|
||||||
CellPair p(MaNGOS::ComputeCellPair(m_creature.GetPositionX(), m_creature.GetPositionY()));
|
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
|
||||||
Cell cell(p);
|
Cell cell(p);
|
||||||
cell.data.Part.reserved = ALL_DISTRICT;
|
cell.data.Part.reserved = ALL_DISTRICT;
|
||||||
cell.SetNoCreate();
|
cell.SetNoCreate();
|
||||||
|
|
||||||
Unit* pUnit = NULL;
|
Unit* pUnit = NULL;
|
||||||
|
|
||||||
MaNGOS::MostHPMissingInRange u_check(&m_creature, range, MinHPDiff);
|
MaNGOS::MostHPMissingInRange u_check(m_creature, range, MinHPDiff);
|
||||||
MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(&m_creature, pUnit, u_check);
|
MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(m_creature, pUnit, u_check);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
typedef TYPELIST_4(GameObject, Creature*except pets*, DynamicObject, Corpse*Bones*) AllGridObjectTypes;
|
typedef TYPELIST_4(GameObject, Creature*except pets*, DynamicObject, Corpse*Bones*) AllGridObjectTypes;
|
||||||
|
|
@ -1446,40 +1446,40 @@ Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
|
||||||
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
|
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
|
||||||
|
|
||||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||||
cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature.GetMap());
|
cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap());
|
||||||
return pUnit;
|
return pUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureEventAI::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
|
void CreatureEventAI::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
|
||||||
{
|
{
|
||||||
CellPair p(MaNGOS::ComputeCellPair(m_creature.GetPositionX(), m_creature.GetPositionY()));
|
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
|
||||||
Cell cell(p);
|
Cell cell(p);
|
||||||
cell.data.Part.reserved = ALL_DISTRICT;
|
cell.data.Part.reserved = ALL_DISTRICT;
|
||||||
cell.SetNoCreate();
|
cell.SetNoCreate();
|
||||||
|
|
||||||
MaNGOS::FriendlyCCedInRange u_check(&m_creature, range);
|
MaNGOS::FriendlyCCedInRange u_check(m_creature, range);
|
||||||
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange> searcher(&m_creature, _list, u_check);
|
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange> searcher(m_creature, _list, u_check);
|
||||||
|
|
||||||
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||||
|
|
||||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||||
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature.GetMap());
|
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid)
|
void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid)
|
||||||
{
|
{
|
||||||
CellPair p(MaNGOS::ComputeCellPair(m_creature.GetPositionX(), m_creature.GetPositionY()));
|
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
|
||||||
Cell cell(p);
|
Cell cell(p);
|
||||||
cell.data.Part.reserved = ALL_DISTRICT;
|
cell.data.Part.reserved = ALL_DISTRICT;
|
||||||
cell.SetNoCreate();
|
cell.SetNoCreate();
|
||||||
|
|
||||||
MaNGOS::FriendlyMissingBuffInRange u_check(&m_creature, range, spellid);
|
MaNGOS::FriendlyMissingBuffInRange u_check(m_creature, range, spellid);
|
||||||
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(&m_creature, _list, u_check);
|
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(m_creature, _list, u_check);
|
||||||
|
|
||||||
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||||
|
|
||||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||||
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature.GetMap());
|
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
//*********************************
|
//*********************************
|
||||||
|
|
@ -1562,7 +1562,7 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit*
|
||||||
void CreatureEventAI::DoZoneInCombat(Unit* pUnit)
|
void CreatureEventAI::DoZoneInCombat(Unit* pUnit)
|
||||||
{
|
{
|
||||||
if (!pUnit)
|
if (!pUnit)
|
||||||
pUnit = &m_creature;
|
pUnit = m_creature;
|
||||||
|
|
||||||
Map *map = pUnit->GetMap();
|
Map *map = pUnit->GetMap();
|
||||||
|
|
||||||
|
|
@ -1589,13 +1589,13 @@ void CreatureEventAI::DoZoneInCombat(Unit* pUnit)
|
||||||
void CreatureEventAI::DoMeleeAttackIfReady()
|
void CreatureEventAI::DoMeleeAttackIfReady()
|
||||||
{
|
{
|
||||||
//Make sure our attack is ready before checking distance
|
//Make sure our attack is ready before checking distance
|
||||||
if (m_creature.isAttackReady())
|
if (m_creature->isAttackReady())
|
||||||
{
|
{
|
||||||
//If we are within range melee the target
|
//If we are within range melee the target
|
||||||
if (m_creature.IsWithinDistInMap(m_creature.getVictim(), ATTACK_DISTANCE))
|
if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
|
||||||
{
|
{
|
||||||
m_creature.AttackerStateUpdate(m_creature.getVictim());
|
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||||
m_creature.resetAttackTimer();
|
m_creature->resetAttackTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1607,11 +1607,11 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Silenced so we can't cast
|
//Silenced so we can't cast
|
||||||
if (!Triggered && m_creature.HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
|
if (!Triggered && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Check for power
|
//Check for power
|
||||||
if (!Triggered && m_creature.GetPower((Powers)Spell->powerType) < Spell->manaCost)
|
if (!Triggered && m_creature->GetPower((Powers)Spell->powerType) < Spell->manaCost)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SpellRangeEntry const *TempRange = NULL;
|
SpellRangeEntry const *TempRange = NULL;
|
||||||
|
|
@ -1623,7 +1623,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Unit is out of range of this spell
|
//Unit is out of range of this spell
|
||||||
if (m_creature.GetDistance(Target) > TempRange->maxRange || m_creature.GetDistance(Target) < TempRange->minRange)
|
if (m_creature->GetDistance(Target) > TempRange->maxRange || m_creature->GetDistance(Target) < TempRange->minRange)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CreatureEventAI(Creature &c);
|
explicit CreatureEventAI(Creature *c);
|
||||||
~CreatureEventAI()
|
~CreatureEventAI()
|
||||||
{
|
{
|
||||||
CreatureEventAIList.clear();
|
CreatureEventAIList.clear();
|
||||||
|
|
@ -283,12 +283,8 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
||||||
void DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid);
|
void DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid);
|
||||||
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
|
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
|
||||||
|
|
||||||
//Pointer to creature we are manipulating
|
|
||||||
Creature& m_creature;
|
|
||||||
|
|
||||||
//Bool for if we are in combat or not
|
//Bool for if we are in combat or not
|
||||||
bool InCombat;
|
bool InCombat;
|
||||||
|
|
||||||
//Holder for events (stores enabled, time, and eventid)
|
//Holder for events (stores enabled, time, and eventid)
|
||||||
std::list<CreatureEventAIHolder> CreatureEventAIList;
|
std::list<CreatureEventAIHolder> CreatureEventAIList;
|
||||||
uint32 EventUpdateTime; //Time between event updates
|
uint32 EventUpdateTime; //Time between event updates
|
||||||
|
|
|
||||||
|
|
@ -31,22 +31,22 @@ int GuardAI::Permissible(const Creature *creature)
|
||||||
return PERMIT_BASE_NO;
|
return PERMIT_BASE_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
GuardAI::GuardAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
|
GuardAI::GuardAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuardAI::MoveInLineOfSight(Unit *u)
|
void GuardAI::MoveInLineOfSight(Unit *u)
|
||||||
{
|
{
|
||||||
// Ignore Z for flying creatures
|
// Ignore Z for flying creatures
|
||||||
if ( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
|
if (!m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( !i_creature.getVictim() && u->isTargetableForAttack() &&
|
if (!m_creature->getVictim() && u->isTargetableForAttack() &&
|
||||||
( u->IsHostileToPlayers() || i_creature.IsHostileTo(u) /*|| u->getVictim() && i_creature.IsFriendlyTo(u->getVictim())*/ ) &&
|
( u->IsHostileToPlayers() || m_creature->IsHostileTo(u) /*|| u->getVictim() && m_creature->IsFriendlyTo(u->getVictim())*/ ) &&
|
||||||
u->isInAccessablePlaceFor(&i_creature))
|
u->isInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
float attackRadius = i_creature.GetAttackDistance(u);
|
float attackRadius = m_creature->GetAttackDistance(u);
|
||||||
if(i_creature.IsWithinDistInMap(u,attackRadius))
|
if (m_creature->IsWithinDistInMap(u,attackRadius))
|
||||||
{
|
{
|
||||||
//Need add code to let guard support player
|
//Need add code to let guard support player
|
||||||
AttackStart(u);
|
AttackStart(u);
|
||||||
|
|
@ -57,76 +57,76 @@ void GuardAI::MoveInLineOfSight(Unit *u)
|
||||||
|
|
||||||
void GuardAI::EnterEvadeMode()
|
void GuardAI::EnterEvadeMode()
|
||||||
{
|
{
|
||||||
if( !i_creature.isAlive() )
|
if (!m_creature->isAlive())
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", m_creature->GetGUIDLow());
|
||||||
i_creature.StopMoving();
|
m_creature->StopMoving();
|
||||||
i_creature.GetMotionMaster()->MoveIdle();
|
m_creature->GetMotionMaster()->MoveIdle();
|
||||||
|
|
||||||
i_state = STATE_NORMAL;
|
i_state = STATE_NORMAL;
|
||||||
|
|
||||||
i_victimGuid = 0;
|
i_victimGuid = 0;
|
||||||
i_creature.CombatStop();
|
m_creature->CombatStop();
|
||||||
i_creature.DeleteThreatList();
|
m_creature->DeleteThreatList();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
|
||||||
|
|
||||||
if( !victim )
|
if (!victim)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else if( !victim ->isAlive() )
|
else if (!victim->isAlive())
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else if( victim ->HasStealthAura() )
|
else if (victim->HasStealthAura())
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else if( victim ->isInFlight() )
|
else if (victim->isInFlight())
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
|
|
||||||
i_creature.RemoveAllAuras();
|
m_creature->RemoveAllAuras();
|
||||||
i_creature.DeleteThreatList();
|
m_creature->DeleteThreatList();
|
||||||
i_victimGuid = 0;
|
i_victimGuid = 0;
|
||||||
i_creature.CombatStop();
|
m_creature->CombatStop();
|
||||||
i_state = STATE_NORMAL;
|
i_state = STATE_NORMAL;
|
||||||
|
|
||||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuardAI::UpdateAI(const uint32 /*diff*/)
|
void GuardAI::UpdateAI(const uint32 /*diff*/)
|
||||||
{
|
{
|
||||||
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
||||||
if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
|
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i_victimGuid = i_creature.getVictim()->GetGUID();
|
i_victimGuid = m_creature->getVictim()->GetGUID();
|
||||||
|
|
||||||
if( i_creature.isAttackReady() )
|
if (m_creature->isAttackReady())
|
||||||
{
|
{
|
||||||
if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
|
if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
|
||||||
{
|
{
|
||||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||||
i_creature.resetAttackTimer();
|
m_creature->resetAttackTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuardAI::IsVisible(Unit *pl) const
|
bool GuardAI::IsVisible(Unit *pl) const
|
||||||
{
|
{
|
||||||
return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
||||||
&& pl->isVisibleForOrDetect(&i_creature,true);
|
&& pl->isVisibleForOrDetect(m_creature,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuardAI::AttackStart(Unit *u)
|
void GuardAI::AttackStart(Unit *u)
|
||||||
|
|
@ -135,19 +135,19 @@ void GuardAI::AttackStart(Unit *u)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
|
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
|
||||||
if(i_creature.Attack(u,true))
|
if(m_creature->Attack(u,true))
|
||||||
{
|
{
|
||||||
i_creature.SetInCombatWith(u);
|
m_creature->SetInCombatWith(u);
|
||||||
u->SetInCombatWith(&i_creature);
|
u->SetInCombatWith(m_creature);
|
||||||
|
|
||||||
i_creature.AddThreat(u, 0.0f);
|
m_creature->AddThreat(u, 0.0f);
|
||||||
i_victimGuid = u->GetGUID();
|
i_victimGuid = u->GetGUID();
|
||||||
i_creature.GetMotionMaster()->MoveChase(u);
|
m_creature->GetMotionMaster()->MoveChase(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuardAI::JustDied(Unit *killer)
|
void GuardAI::JustDied(Unit *killer)
|
||||||
{
|
{
|
||||||
if(Player* pkiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
|
if(Player* pkiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||||
i_creature.SendZoneUnderAttackMessage(pkiller);
|
m_creature->SendZoneUnderAttackMessage(pkiller);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class MANGOS_DLL_DECL GuardAI : public CreatureAI
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GuardAI(Creature &c);
|
explicit GuardAI(Creature *c);
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit *);
|
void MoveInLineOfSight(Unit *);
|
||||||
void AttackStart(Unit *);
|
void AttackStart(Unit *);
|
||||||
|
|
@ -46,7 +46,6 @@ class MANGOS_DLL_DECL GuardAI : public CreatureAI
|
||||||
static int Permissible(const Creature *);
|
static int Permissible(const Creature *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Creature &i_creature;
|
|
||||||
uint64 i_victimGuid;
|
uint64 i_victimGuid;
|
||||||
GuardState i_state;
|
GuardState i_state;
|
||||||
TimeTracker i_tracker;
|
TimeTracker i_tracker;
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,7 @@ class MANGOS_DLL_DECL NullCreatureAI : public CreatureAI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NullCreatureAI(Creature &) {}
|
explicit NullCreatureAI(Creature* c) : CreatureAI(c) {}
|
||||||
NullCreatureAI() {}
|
|
||||||
|
|
||||||
~NullCreatureAI();
|
~NullCreatureAI();
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit *) {}
|
void MoveInLineOfSight(Unit *) {}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ int PetAI::Permissible(const Creature *creature)
|
||||||
return PERMIT_BASE_NO;
|
return PERMIT_BASE_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
PetAI::PetAI(Creature &c) : i_pet(c), i_tracker(TIME_INTERVAL_LOOK), inCombat(false)
|
PetAI::PetAI(Creature *c) : CreatureAI(c), i_tracker(TIME_INTERVAL_LOOK), inCombat(false)
|
||||||
{
|
{
|
||||||
m_AllySet.clear();
|
m_AllySet.clear();
|
||||||
UpdateAllies();
|
UpdateAllies();
|
||||||
|
|
@ -44,15 +44,15 @@ PetAI::PetAI(Creature &c) : i_pet(c), i_tracker(TIME_INTERVAL_LOOK), inCombat(fa
|
||||||
|
|
||||||
void PetAI::MoveInLineOfSight(Unit *u)
|
void PetAI::MoveInLineOfSight(Unit *u)
|
||||||
{
|
{
|
||||||
if( !i_pet.getVictim() && i_pet.GetCharmInfo() &&
|
if( !m_creature->getVictim() && m_creature->GetCharmInfo() &&
|
||||||
i_pet.GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) &&
|
m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) &&
|
||||||
u->isTargetableForAttack() && i_pet.IsHostileTo( u ) &&
|
u->isTargetableForAttack() && m_creature->IsHostileTo( u ) &&
|
||||||
u->isInAccessablePlaceFor(&i_pet))
|
u->isInAccessablePlaceFor(m_creature))
|
||||||
{
|
{
|
||||||
float attackRadius = i_pet.GetAttackDistance(u);
|
float attackRadius = m_creature->GetAttackDistance(u);
|
||||||
if(i_pet.IsWithinDistInMap(u, attackRadius) && i_pet.GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
|
if(m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
|
||||||
{
|
{
|
||||||
if(i_pet.IsWithinLOSInMap(u))
|
if(m_creature->IsWithinLOSInMap(u))
|
||||||
{
|
{
|
||||||
AttackStart(u);
|
AttackStart(u);
|
||||||
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||||
|
|
@ -63,17 +63,17 @@ void PetAI::MoveInLineOfSight(Unit *u)
|
||||||
|
|
||||||
void PetAI::AttackStart(Unit *u)
|
void PetAI::AttackStart(Unit *u)
|
||||||
{
|
{
|
||||||
if( inCombat || !u || (i_pet.isPet() && ((Pet&)i_pet).getPetType() == MINI_PET) )
|
if( inCombat || !u || (m_creature->isPet() && ((Pet&)m_creature).getPetType() == MINI_PET) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(i_pet.Attack(u,true))
|
if(m_creature->Attack(u,true))
|
||||||
{
|
{
|
||||||
i_pet.clearUnitState(UNIT_STAT_FOLLOW);
|
m_creature->clearUnitState(UNIT_STAT_FOLLOW);
|
||||||
// TMGs call CreatureRelocation which via MoveInLineOfSight can call this function
|
// TMGs call CreatureRelocation which via MoveInLineOfSight can call this function
|
||||||
// thus with the following clear the original TMG gets invalidated and crash, doh
|
// thus with the following clear the original TMG gets invalidated and crash, doh
|
||||||
// hope it doesn't start to leak memory without this :-/
|
// hope it doesn't start to leak memory without this :-/
|
||||||
//i_pet->Clear();
|
//i_pet->Clear();
|
||||||
i_pet.GetMotionMaster()->MoveChase(u);
|
m_creature->GetMotionMaster()->MoveChase(u);
|
||||||
inCombat = true;
|
inCombat = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -90,48 +90,48 @@ bool PetAI::IsVisible(Unit *pl) const
|
||||||
bool PetAI::_needToStop() const
|
bool PetAI::_needToStop() const
|
||||||
{
|
{
|
||||||
// This is needed for charmed creatures, as once their target was reset other effects can trigger threat
|
// This is needed for charmed creatures, as once their target was reset other effects can trigger threat
|
||||||
if(i_pet.isCharmed() && i_pet.getVictim() == i_pet.GetCharmer())
|
if(m_creature->isCharmed() && m_creature->getVictim() == m_creature->GetCharmer())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return !i_pet.getVictim()->isTargetableForAttack();
|
return !m_creature->getVictim()->isTargetableForAttack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetAI::_stopAttack()
|
void PetAI::_stopAttack()
|
||||||
{
|
{
|
||||||
inCombat = false;
|
inCombat = false;
|
||||||
if( !i_pet.isAlive() )
|
if( !m_creature->isAlive() )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_pet.GetGUIDLow());
|
DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
|
||||||
i_pet.StopMoving();
|
m_creature->StopMoving();
|
||||||
i_pet.GetMotionMaster()->Clear();
|
m_creature->GetMotionMaster()->Clear();
|
||||||
i_pet.GetMotionMaster()->MoveIdle();
|
m_creature->GetMotionMaster()->MoveIdle();
|
||||||
i_pet.CombatStop();
|
m_creature->CombatStop();
|
||||||
i_pet.getHostilRefManager().deleteReferences();
|
m_creature->getHostilRefManager().deleteReferences();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* owner = i_pet.GetCharmerOrOwner();
|
Unit* owner = m_creature->GetCharmerOrOwner();
|
||||||
|
|
||||||
if(owner && i_pet.GetCharmInfo() && i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
|
if(owner && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
|
||||||
{
|
{
|
||||||
i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
|
m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i_pet.clearUnitState(UNIT_STAT_FOLLOW);
|
m_creature->clearUnitState(UNIT_STAT_FOLLOW);
|
||||||
i_pet.GetMotionMaster()->Clear();
|
m_creature->GetMotionMaster()->Clear();
|
||||||
i_pet.GetMotionMaster()->MoveIdle();
|
m_creature->GetMotionMaster()->MoveIdle();
|
||||||
}
|
}
|
||||||
i_pet.AttackStop();
|
m_creature->AttackStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetAI::UpdateAI(const uint32 diff)
|
void PetAI::UpdateAI(const uint32 diff)
|
||||||
{
|
{
|
||||||
if (!i_pet.isAlive())
|
if (!m_creature->isAlive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Unit* owner = i_pet.GetCharmerOrOwner();
|
Unit* owner = m_creature->GetCharmerOrOwner();
|
||||||
|
|
||||||
if(m_updateAlliesTimer <= diff)
|
if(m_updateAlliesTimer <= diff)
|
||||||
// UpdateAllies self set update timer
|
// UpdateAllies self set update timer
|
||||||
|
|
@ -139,67 +139,67 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||||
else
|
else
|
||||||
m_updateAlliesTimer -= diff;
|
m_updateAlliesTimer -= diff;
|
||||||
|
|
||||||
if (inCombat && !i_pet.getVictim())
|
if (inCombat && !m_creature->getVictim())
|
||||||
_stopAttack();
|
_stopAttack();
|
||||||
|
|
||||||
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
|
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
|
||||||
if( i_pet.getVictim() )
|
if (m_creature->getVictim())
|
||||||
{
|
{
|
||||||
if( _needToStop() )
|
if (_needToStop())
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Pet AI stoped attacking [guid=%u]", i_pet.GetGUIDLow());
|
DEBUG_LOG("Pet AI stoped attacking [guid=%u]", m_creature->GetGUIDLow());
|
||||||
_stopAttack();
|
_stopAttack();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if( i_pet.IsStopped() || i_pet.IsWithinDistInMap(i_pet.getVictim(), ATTACK_DISTANCE))
|
else if (m_creature->IsStopped() || m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
|
||||||
{
|
{
|
||||||
// required to be stopped cases
|
// required to be stopped cases
|
||||||
if ( i_pet.IsStopped() && i_pet.IsNonMeleeSpellCasted(false) )
|
if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
|
||||||
{
|
{
|
||||||
if( i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
|
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
|
||||||
i_pet.InterruptNonMeleeSpells(false);
|
m_creature->InterruptNonMeleeSpells(false);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// not required to be stopped case
|
// not required to be stopped case
|
||||||
else if( i_pet.isAttackReady() && i_pet.canReachWithAttack(i_pet.getVictim()) )
|
else if (m_creature->isAttackReady() && m_creature->canReachWithAttack(m_creature->getVictim()))
|
||||||
{
|
{
|
||||||
i_pet.AttackerStateUpdate(i_pet.getVictim());
|
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||||
|
|
||||||
i_pet.resetAttackTimer();
|
m_creature->resetAttackTimer();
|
||||||
|
|
||||||
if ( !i_pet.getVictim() )
|
if (!m_creature->getVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//if pet misses its target, it will also be the first in threat list
|
//if pet misses its target, it will also be the first in threat list
|
||||||
i_pet.getVictim()->AddThreat(&i_pet,0.0f);
|
m_creature->getVictim()->AddThreat(m_creature,0.0f);
|
||||||
|
|
||||||
if( _needToStop() )
|
if( _needToStop() )
|
||||||
_stopAttack();
|
_stopAttack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(owner && i_pet.GetCharmInfo())
|
else if (owner && m_creature->GetCharmInfo())
|
||||||
{
|
{
|
||||||
if(owner->isInCombat() && !(i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY)))
|
if (owner->isInCombat() && !(m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
|
||||||
{
|
{
|
||||||
AttackStart(owner->getAttackerForHelper());
|
AttackStart(owner->getAttackerForHelper());
|
||||||
}
|
}
|
||||||
else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
|
else if(m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
|
||||||
{
|
{
|
||||||
if (!i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
|
if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW) )
|
||||||
{
|
{
|
||||||
i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
|
m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i_pet.GetGlobalCooldown() == 0 && !i_pet.IsNonMeleeSpellCasted(false))
|
if (m_creature->GetGlobalCooldown() == 0 && !m_creature->IsNonMeleeSpellCasted(false))
|
||||||
{
|
{
|
||||||
//Autocast
|
//Autocast
|
||||||
for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++)
|
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); i++)
|
||||||
{
|
{
|
||||||
uint32 spellID = i_pet.GetPetAutoSpellOnPos(i);
|
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
|
||||||
if (!spellID)
|
if (!spellID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -219,11 +219,11 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Spell *spell = new Spell(&i_pet, spellInfo, false, 0);
|
Spell *spell = new Spell(m_creature, spellInfo, false, 0);
|
||||||
|
|
||||||
if(inCombat && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim()))
|
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
|
||||||
{
|
{
|
||||||
m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(i_pet.getVictim(), spell));
|
m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -231,7 +231,7 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||||
bool spellUsed = false;
|
bool spellUsed = false;
|
||||||
for(std::set<uint64>::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
|
for(std::set<uint64>::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
|
||||||
{
|
{
|
||||||
Unit* Target = ObjectAccessor::GetUnit(i_pet,*tar);
|
Unit* Target = ObjectAccessor::GetUnit(*m_creature,*tar);
|
||||||
|
|
||||||
//only buff targets that are in combat, unless the spell can only be cast while out of combat
|
//only buff targets that are in combat, unless the spell can only be cast while out of combat
|
||||||
if(!Target)
|
if(!Target)
|
||||||
|
|
@ -250,7 +250,7 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
//found units to cast on to
|
//found units to cast on to
|
||||||
if(!m_targetSpellStore.empty())
|
if (!m_targetSpellStore.empty())
|
||||||
{
|
{
|
||||||
uint32 index = urand(0, m_targetSpellStore.size() - 1);
|
uint32 index = urand(0, m_targetSpellStore.size() - 1);
|
||||||
|
|
||||||
|
|
@ -262,19 +262,19 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||||
SpellCastTargets targets;
|
SpellCastTargets targets;
|
||||||
targets.setUnitTarget( target );
|
targets.setUnitTarget( target );
|
||||||
|
|
||||||
if( !i_pet.HasInArc(M_PI, target) )
|
if (!m_creature->HasInArc(M_PI, target))
|
||||||
{
|
{
|
||||||
i_pet.SetInFront(target);
|
m_creature->SetInFront(target);
|
||||||
if( target->GetTypeId() == TYPEID_PLAYER )
|
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||||
i_pet.SendUpdateToPlayer( (Player*)target );
|
m_creature->SendUpdateToPlayer((Player*)target);
|
||||||
|
|
||||||
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
|
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
|
||||||
i_pet.SendUpdateToPlayer( (Player*)owner );
|
m_creature->SendUpdateToPlayer( (Player*)owner );
|
||||||
}
|
}
|
||||||
|
|
||||||
i_pet.AddCreatureSpellCooldown(spell->m_spellInfo->Id);
|
m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
|
||||||
if(i_pet.isPet())
|
if (m_creature->isPet())
|
||||||
((Pet*)&i_pet)->CheckLearning(spell->m_spellInfo->Id);
|
((Pet&)m_creature).CheckLearning(spell->m_spellInfo->Id);
|
||||||
|
|
||||||
spell->prepare(&targets);
|
spell->prepare(&targets);
|
||||||
}
|
}
|
||||||
|
|
@ -289,13 +289,13 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||||
bool PetAI::_isVisible(Unit *u) const
|
bool PetAI::_isVisible(Unit *u) const
|
||||||
{
|
{
|
||||||
//return false; //( ((Creature*)&i_pet)->GetDistanceSq(u) * 1.0<= sWorld.getConfig(CONFIG_SIGHT_GUARDER) && !u->m_stealth && u->isAlive());
|
//return false; //( ((Creature*)&i_pet)->GetDistanceSq(u) * 1.0<= sWorld.getConfig(CONFIG_SIGHT_GUARDER) && !u->m_stealth && u->isAlive());
|
||||||
return i_pet.GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
return m_creature->GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
||||||
&& u->isVisibleForOrDetect(&i_pet,true);
|
&& u->isVisibleForOrDetect(m_creature,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetAI::UpdateAllies()
|
void PetAI::UpdateAllies()
|
||||||
{
|
{
|
||||||
Unit* owner = i_pet.GetCharmerOrOwner();
|
Unit* owner = m_creature->GetCharmerOrOwner();
|
||||||
Group *pGroup = NULL;
|
Group *pGroup = NULL;
|
||||||
|
|
||||||
m_updateAlliesTimer = 10*IN_MILISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance
|
m_updateAlliesTimer = 10*IN_MILISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance
|
||||||
|
|
@ -313,7 +313,7 @@ void PetAI::UpdateAllies()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_AllySet.clear();
|
m_AllySet.clear();
|
||||||
m_AllySet.insert(i_pet.GetGUID());
|
m_AllySet.insert(m_creature->GetGUID());
|
||||||
if(pGroup) //add group
|
if(pGroup) //add group
|
||||||
{
|
{
|
||||||
for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||||
|
|
@ -335,7 +335,7 @@ void PetAI::UpdateAllies()
|
||||||
void PetAI::AttackedBy(Unit *attacker)
|
void PetAI::AttackedBy(Unit *attacker)
|
||||||
{
|
{
|
||||||
//when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway
|
//when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway
|
||||||
if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
|
if(!m_creature->getVictim() && m_creature->GetCharmInfo() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
|
||||||
(!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.canReachWithAttack(attacker)))
|
(!m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY) || m_creature->canReachWithAttack(attacker)))
|
||||||
AttackStart(attacker);
|
AttackStart(attacker);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class MANGOS_DLL_DECL PetAI : public CreatureAI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PetAI(Creature &c);
|
explicit PetAI(Creature *c);
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit *);
|
void MoveInLineOfSight(Unit *);
|
||||||
void AttackStart(Unit *);
|
void AttackStart(Unit *);
|
||||||
|
|
@ -49,7 +49,6 @@ class MANGOS_DLL_DECL PetAI : public CreatureAI
|
||||||
|
|
||||||
void UpdateAllies();
|
void UpdateAllies();
|
||||||
|
|
||||||
Creature &i_pet;
|
|
||||||
bool inCombat;
|
bool inCombat;
|
||||||
TimeTracker i_tracker;
|
TimeTracker i_tracker;
|
||||||
std::set<uint64> m_AllySet;
|
std::set<uint64> m_AllySet;
|
||||||
|
|
|
||||||
|
|
@ -45,15 +45,15 @@ ReactorAI::AttackStart(Unit *p)
|
||||||
if(!p)
|
if(!p)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(i_creature.Attack(p,true))
|
if(m_creature->Attack(p,true))
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Tag unit GUID: %u (TypeId: %u) as a victim", p->GetGUIDLow(), p->GetTypeId());
|
DEBUG_LOG("Tag unit GUID: %u (TypeId: %u) as a victim", p->GetGUIDLow(), p->GetTypeId());
|
||||||
i_creature.SetInCombatWith(p);
|
m_creature->SetInCombatWith(p);
|
||||||
p->SetInCombatWith(&i_creature);
|
p->SetInCombatWith(m_creature);
|
||||||
|
|
||||||
i_creature.AddThreat(p, 0.0f);
|
m_creature->AddThreat(p, 0.0f);
|
||||||
i_victimGuid = p->GetGUID();
|
i_victimGuid = p->GetGUID();
|
||||||
i_creature.GetMotionMaster()->MoveChase(p);
|
m_creature->GetMotionMaster()->MoveChase(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,17 +67,17 @@ void
|
||||||
ReactorAI::UpdateAI(const uint32 /*time_diff*/)
|
ReactorAI::UpdateAI(const uint32 /*time_diff*/)
|
||||||
{
|
{
|
||||||
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
||||||
if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
|
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i_victimGuid = i_creature.getVictim()->GetGUID();
|
i_victimGuid = m_creature->getVictim()->GetGUID();
|
||||||
|
|
||||||
if( i_creature.isAttackReady() )
|
if( m_creature->isAttackReady() )
|
||||||
{
|
{
|
||||||
if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
|
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
|
||||||
{
|
{
|
||||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||||
i_creature.resetAttackTimer();
|
m_creature->resetAttackTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -85,43 +85,43 @@ ReactorAI::UpdateAI(const uint32 /*time_diff*/)
|
||||||
void
|
void
|
||||||
ReactorAI::EnterEvadeMode()
|
ReactorAI::EnterEvadeMode()
|
||||||
{
|
{
|
||||||
if( !i_creature.isAlive() )
|
if( !m_creature->isAlive() )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
|
||||||
i_creature.GetMotionMaster()->MovementExpired();
|
m_creature->GetMotionMaster()->MovementExpired();
|
||||||
i_creature.GetMotionMaster()->MoveIdle();
|
m_creature->GetMotionMaster()->MoveIdle();
|
||||||
i_victimGuid = 0;
|
i_victimGuid = 0;
|
||||||
i_creature.CombatStop();
|
m_creature->CombatStop();
|
||||||
i_creature.DeleteThreatList();
|
m_creature->DeleteThreatList();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
|
||||||
|
|
||||||
if( !victim )
|
if( !victim )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else if( victim->HasStealthAura() )
|
else if( victim->HasStealthAura() )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else if( victim->isInFlight() )
|
else if( victim->isInFlight() )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", i_creature.GetGUIDLow());
|
DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", m_creature->GetGUIDLow());
|
||||||
}
|
}
|
||||||
|
|
||||||
i_creature.RemoveAllAuras();
|
m_creature->RemoveAllAuras();
|
||||||
i_creature.DeleteThreatList();
|
m_creature->DeleteThreatList();
|
||||||
i_victimGuid = 0;
|
i_victimGuid = 0;
|
||||||
i_creature.CombatStop();
|
m_creature->CombatStop();
|
||||||
i_creature.SetLootRecipient(NULL);
|
m_creature->SetLootRecipient(NULL);
|
||||||
|
|
||||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class MANGOS_DLL_DECL ReactorAI : public CreatureAI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ReactorAI(Creature &c) : i_creature(c), i_victimGuid(0) {}
|
explicit ReactorAI(Creature *c) : CreatureAI(c), i_victimGuid(0) {}
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit *);
|
void MoveInLineOfSight(Unit *);
|
||||||
void AttackStart(Unit *);
|
void AttackStart(Unit *);
|
||||||
|
|
@ -38,7 +38,6 @@ class MANGOS_DLL_DECL ReactorAI : public CreatureAI
|
||||||
static int Permissible(const Creature *);
|
static int Permissible(const Creature *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Creature &i_creature;
|
|
||||||
uint64 i_victimGuid;
|
uint64 i_victimGuid;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ TotemAI::Permissible(const Creature *creature)
|
||||||
return PERMIT_BASE_NO;
|
return PERMIT_BASE_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
TotemAI::TotemAI(Creature &c) : i_totem(static_cast<Totem&>(c)), i_victimGuid(0)
|
TotemAI::TotemAI(Creature *c) : CreatureAI(c), i_victimGuid(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,20 +47,20 @@ TotemAI::MoveInLineOfSight(Unit *)
|
||||||
|
|
||||||
void TotemAI::EnterEvadeMode()
|
void TotemAI::EnterEvadeMode()
|
||||||
{
|
{
|
||||||
i_totem.CombatStop();
|
m_creature->CombatStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TotemAI::UpdateAI(const uint32 /*diff*/)
|
TotemAI::UpdateAI(const uint32 /*diff*/)
|
||||||
{
|
{
|
||||||
if (i_totem.GetTotemType() != TOTEM_ACTIVE)
|
if (getTotem().GetTotemType() != TOTEM_ACTIVE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false))
|
if (!m_creature->isAlive() || m_creature->IsNonMeleeSpellCasted(false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Search spell
|
// Search spell
|
||||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell());
|
SpellEntry const *spellInfo = sSpellStore.LookupEntry(getTotem().GetSpell());
|
||||||
if (!spellInfo)
|
if (!spellInfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -71,28 +71,28 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
|
||||||
// SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems
|
// SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems
|
||||||
|
|
||||||
// pointer to appropriate target if found any
|
// pointer to appropriate target if found any
|
||||||
Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(i_totem, i_victimGuid) : NULL;
|
Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(*m_creature, i_victimGuid) : NULL;
|
||||||
|
|
||||||
// Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
|
// Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
|
||||||
if( !victim ||
|
if( !victim ||
|
||||||
!victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) ||
|
!victim->isTargetableForAttack() || !m_creature->IsWithinDistInMap(victim, max_range) ||
|
||||||
i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false) )
|
m_creature->IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(m_creature,false) )
|
||||||
{
|
{
|
||||||
CellPair p(MaNGOS::ComputeCellPair(i_totem.GetPositionX(),i_totem.GetPositionY()));
|
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(),m_creature->GetPositionY()));
|
||||||
Cell cell(p);
|
Cell cell(p);
|
||||||
cell.data.Part.reserved = ALL_DISTRICT;
|
cell.data.Part.reserved = ALL_DISTRICT;
|
||||||
|
|
||||||
victim = NULL;
|
victim = NULL;
|
||||||
|
|
||||||
MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range);
|
MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(m_creature, m_creature, max_range);
|
||||||
MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck> checker(&i_totem,victim, u_check);
|
MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck> checker(m_creature,victim, u_check);
|
||||||
|
|
||||||
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
|
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
|
||||||
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
|
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
|
||||||
|
|
||||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||||
cell_lock->Visit(cell_lock, grid_object_checker, *i_totem.GetMap());
|
cell_lock->Visit(cell_lock, grid_object_checker, *m_creature->GetMap());
|
||||||
cell_lock->Visit(cell_lock, world_object_checker, *i_totem.GetMap());
|
cell_lock->Visit(cell_lock, world_object_checker, *m_creature->GetMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If have target
|
// If have target
|
||||||
|
|
@ -102,8 +102,8 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
|
||||||
i_victimGuid = victim->GetGUID();
|
i_victimGuid = victim->GetGUID();
|
||||||
|
|
||||||
// attack
|
// attack
|
||||||
i_totem.SetInFront(victim); // client change orientation by self
|
m_creature->SetInFront(victim); // client change orientation by self
|
||||||
i_totem.CastSpell(victim, i_totem.GetSpell(), false);
|
m_creature->CastSpell(victim, getTotem().GetSpell(), false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i_victimGuid = 0;
|
i_victimGuid = 0;
|
||||||
|
|
@ -119,3 +119,8 @@ void
|
||||||
TotemAI::AttackStart(Unit *)
|
TotemAI::AttackStart(Unit *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Totem& TotemAI::getTotem()
|
||||||
|
{
|
||||||
|
return static_cast<Totem&>(*m_creature);
|
||||||
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ class MANGOS_DLL_DECL TotemAI : public CreatureAI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TotemAI(Creature &c);
|
explicit TotemAI(Creature *c);
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit *);
|
void MoveInLineOfSight(Unit *);
|
||||||
void AttackStart(Unit *);
|
void AttackStart(Unit *);
|
||||||
|
|
@ -38,9 +38,10 @@ class MANGOS_DLL_DECL TotemAI : public CreatureAI
|
||||||
|
|
||||||
void UpdateAI(const uint32);
|
void UpdateAI(const uint32);
|
||||||
static int Permissible(const Creature *);
|
static int Permissible(const Creature *);
|
||||||
|
protected:
|
||||||
|
Totem& getTotem();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Totem &i_totem;
|
|
||||||
uint64 i_victimGuid;
|
uint64 i_victimGuid;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7666"
|
#define REVISION_NR "7667"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue