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
|
||||
{
|
||||
ScriptedAI(Creature* creature) : m_creature(creature) {}
|
||||
explicit ScriptedAI(Creature* creature) : CreatureAI(creature) {}
|
||||
~ScriptedAI() {}
|
||||
|
||||
// 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
|
||||
void SpellHitTarget(Unit*, const SpellEntry*) {}
|
||||
|
||||
Creature* m_creature;
|
||||
|
||||
//= Some useful helpers =========================
|
||||
|
||||
// Start attack of victim and go to him
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ AggressorAI::Permissible(const Creature *creature)
|
|||
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)
|
||||
{
|
||||
// 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;
|
||||
|
||||
if( !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
|
||||
( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) &&
|
||||
u->isInAccessablePlaceFor(&i_creature) )
|
||||
if( !m_creature->hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
|
||||
( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) &&
|
||||
u->isInAccessablePlaceFor(m_creature) )
|
||||
{
|
||||
float attackRadius = i_creature.GetAttackDistance(u);
|
||||
if(i_creature.IsWithinDistInMap(u, attackRadius) && i_creature.IsWithinLOSInMap(u) )
|
||||
float attackRadius = m_creature->GetAttackDistance(u);
|
||||
if(m_creature->IsWithinDistInMap(u, attackRadius) && m_creature->IsWithinLOSInMap(u) )
|
||||
{
|
||||
if(!i_creature.getVictim())
|
||||
if(!m_creature->getVictim())
|
||||
{
|
||||
AttackStart(u);
|
||||
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);
|
||||
i_creature.AddThreat(u, 0.0f);
|
||||
u->SetInCombatWith(m_creature);
|
||||
m_creature->AddThreat(u, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -69,70 +69,70 @@ AggressorAI::MoveInLineOfSight(Unit *u)
|
|||
|
||||
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_creature.CombatStop();
|
||||
i_creature.DeleteThreatList();
|
||||
m_creature->CombatStop();
|
||||
m_creature->DeleteThreatList();
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
||||
Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
|
||||
|
||||
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() )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
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
|
||||
{
|
||||
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_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
|
||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
||||
if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
i_creature.DeleteThreatList();
|
||||
m_creature->DeleteThreatList();
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.SetLootRecipient(NULL);
|
||||
m_creature->CombatStop();
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
AggressorAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
||||
if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
|
||||
// update i_victimGuid if m_creature->getVictim() !=0 and changed
|
||||
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
|
||||
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());
|
||||
i_creature.resetAttackTimer();
|
||||
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||
m_creature->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -140,8 +140,8 @@ AggressorAI::UpdateAI(const uint32 /*diff*/)
|
|||
bool
|
||||
AggressorAI::IsVisible(Unit *pl) const
|
||||
{
|
||||
return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
||||
&& pl->isVisibleForOrDetect(&i_creature,true);
|
||||
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
||||
&& pl->isVisibleForOrDetect(m_creature,true);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -150,15 +150,15 @@ AggressorAI::AttackStart(Unit *u)
|
|||
if( !u )
|
||||
return;
|
||||
|
||||
if(i_creature.Attack(u,true))
|
||||
if(m_creature->Attack(u,true))
|
||||
{
|
||||
i_creature.SetInCombatWith(u);
|
||||
u->SetInCombatWith(&i_creature);
|
||||
m_creature->SetInCombatWith(u);
|
||||
u->SetInCombatWith(m_creature);
|
||||
|
||||
i_creature.AddThreat(u, 0.0f);
|
||||
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
|
||||
m_creature->AddThreat(u, 0.0f);
|
||||
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", m_creature->GetName(), u->GetGUIDLow());
|
||||
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:
|
||||
|
||||
AggressorAI(Creature &c);
|
||||
explicit AggressorAI(Creature *c);
|
||||
|
||||
void MoveInLineOfSight(Unit *);
|
||||
void AttackStart(Unit *);
|
||||
|
|
@ -45,7 +45,6 @@ class MANGOS_DLL_DECL AggressorAI : public CreatureAI
|
|||
static int Permissible(const Creature *);
|
||||
|
||||
private:
|
||||
Creature &i_creature;
|
||||
uint64 i_victimGuid;
|
||||
AggressorState i_state;
|
||||
TimeTracker i_tracker;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ struct SpellEntry;
|
|||
class MANGOS_DLL_SPEC CreatureAI
|
||||
{
|
||||
public:
|
||||
explicit CreatureAI(Creature* creature) : m_creature(creature) {}
|
||||
|
||||
virtual ~CreatureAI();
|
||||
|
||||
|
|
@ -94,6 +95,8 @@ class MANGOS_DLL_SPEC CreatureAI
|
|||
|
||||
// Called at waypoint reached or point movement finished
|
||||
virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
|
||||
|
||||
Creature* const m_creature;
|
||||
};
|
||||
|
||||
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,6 @@ inline CreatureAI*
|
|||
CreatureAIFactory<REAL_AI>::Create(void *data) const
|
||||
{
|
||||
Creature* creature = reinterpret_cast<Creature *>(data);
|
||||
return (new REAL_AI(*creature));
|
||||
return (new REAL_AI(creature));
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace FactorySelector
|
|||
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ int CreatureEventAI::Permissible(const Creature *creature)
|
|||
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())
|
||||
{
|
||||
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)
|
||||
continue;
|
||||
#endif
|
||||
if( m_creature.GetMap()->IsDungeon() )
|
||||
if (m_creature->GetMap()->IsDungeon())
|
||||
{
|
||||
if( (m_creature.GetMap()->IsHeroic() && (*i).event_flags & EFLAG_HEROIC) ||
|
||||
(!m_creature.GetMap()->IsHeroic() && (*i).event_flags & EFLAG_NORMAL))
|
||||
if( (m_creature->GetMap()->IsHeroic() && (*i).event_flags & EFLAG_HEROIC) ||
|
||||
(!m_creature->GetMap()->IsHeroic() && (*i).event_flags & EFLAG_NORMAL))
|
||||
{
|
||||
//event flagged for instance mode
|
||||
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
|
||||
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
|
||||
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();
|
||||
Phase = 0;
|
||||
|
|
@ -151,7 +151,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
pHolder.Time = urand(param3, param4);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -171,17 +171,17 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_T_HP:
|
||||
{
|
||||
if (!InCombat || !m_creature.GetMaxHealth())
|
||||
if (!InCombat || !m_creature->GetMaxHealth())
|
||||
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)
|
||||
return false;
|
||||
|
|
@ -196,17 +196,17 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_T_MANA:
|
||||
{
|
||||
if (!InCombat || !m_creature.GetMaxPower(POWER_MANA))
|
||||
if (!InCombat || !m_creature->GetMaxPower(POWER_MANA))
|
||||
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)
|
||||
return false;
|
||||
|
|
@ -221,7 +221,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -242,7 +242,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -268,7 +268,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -285,7 +285,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -302,7 +302,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -313,10 +313,10 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
break;
|
||||
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;
|
||||
|
||||
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)
|
||||
return false;
|
||||
|
|
@ -331,14 +331,14 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
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;
|
||||
|
||||
//Repeat Timers
|
||||
|
|
@ -351,7 +351,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -378,7 +378,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -407,7 +407,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
pHolder.Time = urand(param3, param4);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -434,7 +434,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -459,7 +459,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -474,7 +474,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
|
|||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -531,7 +531,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
target = owner;
|
||||
}
|
||||
}
|
||||
else if (target = m_creature.getVictim())
|
||||
else if (target = m_creature->getVictim())
|
||||
{
|
||||
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;
|
||||
case ACTION_T_SET_FACTION:
|
||||
{
|
||||
if (param1)
|
||||
m_creature.setFaction(param1);
|
||||
m_creature->setFaction(param1);
|
||||
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 (m_creature.getFaction() != ci->faction_A)
|
||||
m_creature.setFaction(ci->faction_A);
|
||||
if (m_creature->getFaction() != 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
|
||||
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)
|
||||
else
|
||||
m_creature.SetDisplayId(param2);
|
||||
m_creature->SetDisplayId(param2);
|
||||
}
|
||||
else
|
||||
m_creature.DeMorph();
|
||||
m_creature->DeMorph();
|
||||
}
|
||||
break;
|
||||
case ACTION_T_SOUND:
|
||||
m_creature.PlayDirectSound(param1);
|
||||
m_creature->PlayDirectSound(param1);
|
||||
break;
|
||||
case ACTION_T_EMOTE:
|
||||
m_creature.HandleEmoteCommand(param1);
|
||||
m_creature->HandleEmoteCommand(param1);
|
||||
break;
|
||||
case ACTION_T_RANDOM_SOUND:
|
||||
{
|
||||
uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
|
||||
|
||||
if (temp != uint32(0xffffffff))
|
||||
m_creature.PlayDirectSound( temp );
|
||||
m_creature->PlayDirectSound( temp );
|
||||
}
|
||||
break;
|
||||
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);
|
||||
|
||||
if (temp != uint32(0xffffffff))
|
||||
m_creature.HandleEmoteCommand(temp);
|
||||
m_creature->HandleEmoteCommand(temp);
|
||||
}
|
||||
break;
|
||||
case ACTION_T_CAST:
|
||||
{
|
||||
Unit* target = GetTargetByType(param2, pActionInvoker);
|
||||
Unit* caster = &m_creature;
|
||||
Unit* caster = m_creature;
|
||||
|
||||
if (!target)
|
||||
return;
|
||||
|
|
@ -646,13 +646,13 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
//Melee current victim if flag not set
|
||||
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;
|
||||
AttackAngle = 0;
|
||||
|
||||
m_creature.GetMotionMaster()->Clear(false);
|
||||
m_creature.GetMotionMaster()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
|
||||
m_creature->GetMotionMaster()->Clear(false);
|
||||
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -667,7 +667,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
}
|
||||
|
||||
}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;
|
||||
|
|
@ -678,14 +678,14 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
Creature* pCreature = NULL;
|
||||
|
||||
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
|
||||
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)
|
||||
{
|
||||
|
||||
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)
|
||||
pCreature->AI()->AttackStart(target);
|
||||
|
|
@ -696,19 +696,19 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
Unit* target = GetTargetByType(param2, pActionInvoker);
|
||||
|
||||
if (target)
|
||||
m_creature.getThreatManager().modifyThreatPercent(target, param1);
|
||||
m_creature->getThreatManager().modifyThreatPercent(target, param1);
|
||||
}
|
||||
break;
|
||||
case ACTION_T_THREAT_ALL_PCT:
|
||||
{
|
||||
Unit* Temp = NULL;
|
||||
|
||||
std::list<HostilReference*>::iterator i = m_creature.getThreatManager().getThreatList().begin();
|
||||
for (; i != m_creature.getThreatManager().getThreatList().end(); ++i)
|
||||
std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
|
||||
for (; i != m_creature->getThreatManager().getThreatList().end(); ++i)
|
||||
{
|
||||
Temp = Unit::GetUnit(m_creature,(*i)->getUnitGuid());
|
||||
Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
|
||||
if (Temp)
|
||||
m_creature.getThreatManager().modifyThreatPercent(Temp, param1);
|
||||
m_creature->getThreatManager().modifyThreatPercent(Temp, param1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -725,7 +725,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
Unit* target = GetTargetByType(param3, pActionInvoker);
|
||||
|
||||
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)target)->CastedCreatureOrGO(param1, m_creature.GetGUID(), param2);
|
||||
((Player*)target)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2);
|
||||
}
|
||||
break;
|
||||
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)
|
||||
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()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
|
||||
m_creature->GetMotionMaster()->Clear(false);
|
||||
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
|
||||
}
|
||||
}
|
||||
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()->MoveIdle();
|
||||
m_creature.StopMoving();
|
||||
m_creature->GetMotionMaster()->Clear(false);
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
m_creature->StopMoving();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -795,7 +795,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
|
||||
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;
|
||||
case ACTION_T_EVADE:
|
||||
|
|
@ -806,7 +806,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
case ACTION_T_FLEE:
|
||||
{
|
||||
//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;
|
||||
case ACTION_T_QUEST_EVENT_ALL:
|
||||
|
|
@ -814,9 +814,9 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
Unit* Temp = NULL;
|
||||
if( pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER )
|
||||
{
|
||||
Temp = Unit::GetUnit(m_creature,pActionInvoker->GetGUID());
|
||||
Temp = Unit::GetUnit(*m_creature,pActionInvoker->GetGUID());
|
||||
if( Temp )
|
||||
((Player*)Temp)->GroupEventHappens(param1,&m_creature);
|
||||
((Player*)Temp)->GroupEventHappens(param1,m_creature);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -824,12 +824,12 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
{
|
||||
Unit* Temp = NULL;
|
||||
|
||||
std::list<HostilReference*>::iterator i = m_creature.getThreatManager().getThreatList().begin();
|
||||
for (; i != m_creature.getThreatManager().getThreatList().end(); ++i)
|
||||
std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
|
||||
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)
|
||||
((Player*)Temp)->CastedCreatureOrGO(param1, m_creature.GetGUID(), param2);
|
||||
((Player*)Temp)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -848,11 +848,11 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
|
||||
if (CombatMovementEnabled)
|
||||
{
|
||||
if (m_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
{
|
||||
//Drop current movement gen
|
||||
m_creature.GetMotionMaster()->Clear(false);
|
||||
m_creature.GetMotionMaster()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
|
||||
m_creature->GetMotionMaster()->Clear(false);
|
||||
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));
|
||||
}
|
||||
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;
|
||||
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())
|
||||
{
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
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)
|
||||
pCreature->AI()->AttackStart(target);
|
||||
|
|
@ -905,24 +905,24 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
case ACTION_T_KILLED_MONSTER:
|
||||
{
|
||||
//first attempt player who tapped creature
|
||||
if (Player* pPlayer = m_creature.GetLootRecipient())
|
||||
pPlayer->RewardPlayerAndGroupAtEvent(param1, &m_creature);
|
||||
if (Player* pPlayer = m_creature->GetLootRecipient())
|
||||
pPlayer->RewardPlayerAndGroupAtEvent(param1, m_creature);
|
||||
else
|
||||
{
|
||||
//if not available, use pActionInvoker
|
||||
Unit* pTarget = GetTargetByType(param2, pActionInvoker);
|
||||
|
||||
if (Player* pPlayer = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
pPlayer->RewardPlayerAndGroupAtEvent(param1, &m_creature);
|
||||
pPlayer->RewardPlayerAndGroupAtEvent(param1, m_creature);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_T_SET_INST_DATA:
|
||||
{
|
||||
InstanceData* pInst = (InstanceData*)m_creature.GetInstanceData();
|
||||
InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -934,14 +934,14 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
Unit* target = GetTargetByType(param2, pActionInvoker);
|
||||
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;
|
||||
}
|
||||
|
||||
InstanceData* pInst = (InstanceData*)m_creature.GetInstanceData();
|
||||
InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -950,37 +950,37 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
|||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
m_creature.UpdateEntry(param1, param2 ? HORDE : ALLIANCE);
|
||||
m_creature->UpdateEntry(param1, param2 ? HORDE : ALLIANCE);
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
DoZoneInCombat(&m_creature);
|
||||
DoZoneInCombat(m_creature);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1029,7 +1029,7 @@ void CreatureEventAI::Reset()
|
|||
(*i).Enabled = true;
|
||||
}
|
||||
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;
|
||||
//default:
|
||||
|
|
@ -1043,7 +1043,7 @@ void CreatureEventAI::Reset()
|
|||
|
||||
void CreatureEventAI::JustReachedHome()
|
||||
{
|
||||
m_creature.LoadCreaturesAddon();
|
||||
m_creature->LoadCreaturesAddon();
|
||||
|
||||
if (!bEmptyList)
|
||||
{
|
||||
|
|
@ -1059,15 +1059,15 @@ void CreatureEventAI::JustReachedHome()
|
|||
|
||||
void CreatureEventAI::EnterEvadeMode()
|
||||
{
|
||||
m_creature.InterruptNonMeleeSpells(true);
|
||||
m_creature.RemoveAllAuras();
|
||||
m_creature.DeleteThreatList();
|
||||
m_creature.CombatStop();
|
||||
m_creature->InterruptNonMeleeSpells(true);
|
||||
m_creature->RemoveAllAuras();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop();
|
||||
|
||||
if (m_creature.isAlive())
|
||||
m_creature.GetMotionMaster()->MoveTargetedHome();
|
||||
if (m_creature->isAlive())
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
|
||||
m_creature.SetLootRecipient(NULL);
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
|
||||
InCombat = false;
|
||||
|
||||
|
|
@ -1148,7 +1148,7 @@ void CreatureEventAI::Aggro(Unit *who)
|
|||
(*i).Enabled = true;
|
||||
}
|
||||
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;
|
||||
//All normal events need to be re-enabled and their time set to 0
|
||||
default:
|
||||
|
|
@ -1168,11 +1168,11 @@ void CreatureEventAI::AttackStart(Unit *who)
|
|||
if (!who)
|
||||
return;
|
||||
|
||||
if (m_creature.Attack(who, MeleeEnabled))
|
||||
if (m_creature->Attack(who, MeleeEnabled))
|
||||
{
|
||||
m_creature.AddThreat(who, 0.0f);
|
||||
m_creature.SetInCombatWith(who);
|
||||
who->SetInCombatWith(&m_creature);
|
||||
m_creature->AddThreat(who, 0.0f);
|
||||
m_creature->SetInCombatWith(who);
|
||||
who->SetInCombatWith(m_creature);
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
|
|
@ -1182,12 +1182,12 @@ void CreatureEventAI::AttackStart(Unit *who)
|
|||
|
||||
if (CombatMovementEnabled)
|
||||
{
|
||||
m_creature.GetMotionMaster()->MoveChase(who, AttackDistance, AttackAngle);
|
||||
m_creature->GetMotionMaster()->MoveChase(who, AttackDistance, AttackAngle);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_creature.GetMotionMaster()->MoveIdle();
|
||||
m_creature.StopMoving();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
m_creature->StopMoving();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1198,7 +1198,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
|
|||
return;
|
||||
|
||||
//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)
|
||||
{
|
||||
|
|
@ -1208,38 +1208,38 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
|
|||
float fMaxAllowedRange = (*itr).Event.event_param2;
|
||||
|
||||
//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 (((*itr).Event.event_param1 && !m_creature.IsHostileTo(who)) ||
|
||||
((!(*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)))
|
||||
ProcessEvent(*itr, who);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_creature.isCivilian() && m_creature.IsNeutralToAll())
|
||||
if (m_creature->isCivilian() && m_creature->IsNeutralToAll())
|
||||
return;
|
||||
|
||||
if (!m_creature.hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() &&
|
||||
m_creature.IsHostileTo(who) && who->isInAccessablePlaceFor(&m_creature))
|
||||
if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() &&
|
||||
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;
|
||||
|
||||
float attackRadius = m_creature.GetAttackDistance(who);
|
||||
if (m_creature.IsWithinDistInMap(who, attackRadius) && m_creature.IsWithinLOSInMap(who))
|
||||
float attackRadius = m_creature->GetAttackDistance(who);
|
||||
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
|
||||
{
|
||||
if (!m_creature.getVictim())
|
||||
if (!m_creature->getVictim())
|
||||
{
|
||||
AttackStart(who);
|
||||
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
}
|
||||
else if (m_creature.GetMap()->IsDungeon())
|
||||
else if (m_creature->GetMap()->IsDungeon())
|
||||
{
|
||||
who->SetInCombatWith(&m_creature);
|
||||
m_creature.AddThreat(who, 0.0f);
|
||||
who->SetInCombatWith(m_creature);
|
||||
m_creature->AddThreat(who, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1268,10 +1268,10 @@ void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
|
|||
void CreatureEventAI::UpdateAI(const uint32 diff)
|
||||
{
|
||||
//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
|
||||
if (!m_creature.isAlive())
|
||||
if (!m_creature->isAlive())
|
||||
return;
|
||||
|
||||
if (!bEmptyList)
|
||||
|
|
@ -1317,9 +1317,9 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
|||
case EVENT_T_RANGE:
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1344,14 +1344,14 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
|
|||
|
||||
bool CreatureEventAI::IsVisible(Unit *pl) const
|
||||
{
|
||||
return m_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
||||
&& pl->isVisibleForOrDetect(&m_creature,true);
|
||||
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
||||
&& pl->isVisibleForOrDetect(m_creature,true);
|
||||
}
|
||||
|
||||
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
|
||||
{
|
||||
//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*>::reverse_iterator r = m_threatlist.rbegin();
|
||||
|
||||
|
|
@ -1363,17 +1363,17 @@ inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position
|
|||
case ATTACKING_TARGET_RANDOM:
|
||||
{
|
||||
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:
|
||||
{
|
||||
advance ( i , position);
|
||||
return Unit::GetUnit(m_creature,(*i)->getUnitGuid());
|
||||
return Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
|
||||
}
|
||||
case ATTACKING_TARGET_BOTTOMAGGRO:
|
||||
{
|
||||
advance ( r , position);
|
||||
return Unit::GetUnit(m_creature,(*r)->getUnitGuid());
|
||||
return Unit::GetUnit(*m_creature,(*r)->getUnitGuid());
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -1401,10 +1401,10 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke
|
|||
switch (Target)
|
||||
{
|
||||
case TARGET_T_SELF:
|
||||
return &m_creature;
|
||||
return m_creature;
|
||||
break;
|
||||
case TARGET_T_HOSTILE:
|
||||
return m_creature.getVictim();
|
||||
return m_creature->getVictim();
|
||||
break;
|
||||
case TARGET_T_HOSTILE_SECOND_AGGRO:
|
||||
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)
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_creature.GetPositionX(), m_creature.GetPositionY()));
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
Unit* pUnit = NULL;
|
||||
|
||||
MaNGOS::MostHPMissingInRange u_check(&m_creature, range, MinHPDiff);
|
||||
MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(&m_creature, pUnit, u_check);
|
||||
MaNGOS::MostHPMissingInRange u_check(m_creature, range, MinHPDiff);
|
||||
MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(m_creature, pUnit, u_check);
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
MaNGOS::FriendlyCCedInRange u_check(&m_creature, range);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange> searcher(&m_creature, _list, u_check);
|
||||
MaNGOS::FriendlyCCedInRange u_check(m_creature, range);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange> searcher(m_creature, _list, u_check);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||
|
||||
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)
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_creature.GetPositionX(), m_creature.GetPositionY()));
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
MaNGOS::FriendlyMissingBuffInRange u_check(&m_creature, range, spellid);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(&m_creature, _list, u_check);
|
||||
MaNGOS::FriendlyMissingBuffInRange u_check(m_creature, range, spellid);
|
||||
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(m_creature, _list, u_check);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||
|
||||
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)
|
||||
{
|
||||
if (!pUnit)
|
||||
pUnit = &m_creature;
|
||||
pUnit = m_creature;
|
||||
|
||||
Map *map = pUnit->GetMap();
|
||||
|
||||
|
|
@ -1589,13 +1589,13 @@ void CreatureEventAI::DoZoneInCombat(Unit* pUnit)
|
|||
void CreatureEventAI::DoMeleeAttackIfReady()
|
||||
{
|
||||
//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 (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.resetAttackTimer();
|
||||
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||
m_creature->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1607,11 +1607,11 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
|
|||
return false;
|
||||
|
||||
//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;
|
||||
|
||||
//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;
|
||||
|
||||
SpellRangeEntry const *TempRange = NULL;
|
||||
|
|
@ -1623,7 +1623,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
|
|||
return false;
|
||||
|
||||
//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 true;
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
|||
{
|
||||
|
||||
public:
|
||||
CreatureEventAI(Creature &c);
|
||||
explicit CreatureEventAI(Creature *c);
|
||||
~CreatureEventAI()
|
||||
{
|
||||
CreatureEventAIList.clear();
|
||||
|
|
@ -283,12 +283,8 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
|
|||
void DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid);
|
||||
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 InCombat;
|
||||
|
||||
//Holder for events (stores enabled, time, and eventid)
|
||||
std::list<CreatureEventAIHolder> CreatureEventAIList;
|
||||
uint32 EventUpdateTime; //Time between event updates
|
||||
|
|
|
|||
|
|
@ -31,22 +31,22 @@ int GuardAI::Permissible(const Creature *creature)
|
|||
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)
|
||||
{
|
||||
// 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;
|
||||
|
||||
if( !i_creature.getVictim() && u->isTargetableForAttack() &&
|
||||
( u->IsHostileToPlayers() || i_creature.IsHostileTo(u) /*|| u->getVictim() && i_creature.IsFriendlyTo(u->getVictim())*/ ) &&
|
||||
u->isInAccessablePlaceFor(&i_creature))
|
||||
if (!m_creature->getVictim() && u->isTargetableForAttack() &&
|
||||
( u->IsHostileToPlayers() || m_creature->IsHostileTo(u) /*|| u->getVictim() && m_creature->IsFriendlyTo(u->getVictim())*/ ) &&
|
||||
u->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
float attackRadius = i_creature.GetAttackDistance(u);
|
||||
if(i_creature.IsWithinDistInMap(u,attackRadius))
|
||||
float attackRadius = m_creature->GetAttackDistance(u);
|
||||
if (m_creature->IsWithinDistInMap(u,attackRadius))
|
||||
{
|
||||
//Need add code to let guard support player
|
||||
AttackStart(u);
|
||||
|
|
@ -57,76 +57,76 @@ void GuardAI::MoveInLineOfSight(Unit *u)
|
|||
|
||||
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());
|
||||
i_creature.StopMoving();
|
||||
i_creature.GetMotionMaster()->MoveIdle();
|
||||
DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", m_creature->GetGUIDLow());
|
||||
m_creature->StopMoving();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
|
||||
i_state = STATE_NORMAL;
|
||||
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.DeleteThreatList();
|
||||
m_creature->CombatStop();
|
||||
m_creature->DeleteThreatList();
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
||||
Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
|
||||
|
||||
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())
|
||||
{
|
||||
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())
|
||||
{
|
||||
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())
|
||||
{
|
||||
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
|
||||
{
|
||||
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();
|
||||
i_creature.DeleteThreatList();
|
||||
m_creature->RemoveAllAuras();
|
||||
m_creature->DeleteThreatList();
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
m_creature->CombatStop();
|
||||
i_state = STATE_NORMAL;
|
||||
|
||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
void GuardAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
// 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;
|
||||
|
||||
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());
|
||||
i_creature.resetAttackTimer();
|
||||
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||
m_creature->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GuardAI::IsVisible(Unit *pl) const
|
||||
{
|
||||
return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
||||
&& pl->isVisibleForOrDetect(&i_creature,true);
|
||||
return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
||||
&& pl->isVisibleForOrDetect(m_creature,true);
|
||||
}
|
||||
|
||||
void GuardAI::AttackStart(Unit *u)
|
||||
|
|
@ -135,19 +135,19 @@ void GuardAI::AttackStart(Unit *u)
|
|||
return;
|
||||
|
||||
// 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);
|
||||
u->SetInCombatWith(&i_creature);
|
||||
m_creature->SetInCombatWith(u);
|
||||
u->SetInCombatWith(m_creature);
|
||||
|
||||
i_creature.AddThreat(u, 0.0f);
|
||||
m_creature->AddThreat(u, 0.0f);
|
||||
i_victimGuid = u->GetGUID();
|
||||
i_creature.GetMotionMaster()->MoveChase(u);
|
||||
m_creature->GetMotionMaster()->MoveChase(u);
|
||||
}
|
||||
}
|
||||
|
||||
void GuardAI::JustDied(Unit *killer)
|
||||
{
|
||||
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:
|
||||
|
||||
GuardAI(Creature &c);
|
||||
explicit GuardAI(Creature *c);
|
||||
|
||||
void MoveInLineOfSight(Unit *);
|
||||
void AttackStart(Unit *);
|
||||
|
|
@ -46,7 +46,6 @@ class MANGOS_DLL_DECL GuardAI : public CreatureAI
|
|||
static int Permissible(const Creature *);
|
||||
|
||||
private:
|
||||
Creature &i_creature;
|
||||
uint64 i_victimGuid;
|
||||
GuardState i_state;
|
||||
TimeTracker i_tracker;
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ class MANGOS_DLL_DECL NullCreatureAI : public CreatureAI
|
|||
{
|
||||
public:
|
||||
|
||||
NullCreatureAI(Creature &) {}
|
||||
NullCreatureAI() {}
|
||||
|
||||
explicit NullCreatureAI(Creature* c) : CreatureAI(c) {}
|
||||
~NullCreatureAI();
|
||||
|
||||
void MoveInLineOfSight(Unit *) {}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ int PetAI::Permissible(const Creature *creature)
|
|||
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();
|
||||
UpdateAllies();
|
||||
|
|
@ -44,15 +44,15 @@ PetAI::PetAI(Creature &c) : i_pet(c), i_tracker(TIME_INTERVAL_LOOK), inCombat(fa
|
|||
|
||||
void PetAI::MoveInLineOfSight(Unit *u)
|
||||
{
|
||||
if( !i_pet.getVictim() && i_pet.GetCharmInfo() &&
|
||||
i_pet.GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) &&
|
||||
u->isTargetableForAttack() && i_pet.IsHostileTo( u ) &&
|
||||
u->isInAccessablePlaceFor(&i_pet))
|
||||
if( !m_creature->getVictim() && m_creature->GetCharmInfo() &&
|
||||
m_creature->GetCharmInfo()->HasReactState(REACT_AGGRESSIVE) &&
|
||||
u->isTargetableForAttack() && m_creature->IsHostileTo( u ) &&
|
||||
u->isInAccessablePlaceFor(m_creature))
|
||||
{
|
||||
float attackRadius = i_pet.GetAttackDistance(u);
|
||||
if(i_pet.IsWithinDistInMap(u, attackRadius) && i_pet.GetDistanceZ(u) <= CREATURE_Z_ATTACK_RANGE)
|
||||
float attackRadius = m_creature->GetAttackDistance(u);
|
||||
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);
|
||||
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
|
|
@ -63,17 +63,17 @@ void PetAI::MoveInLineOfSight(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;
|
||||
|
||||
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
|
||||
// thus with the following clear the original TMG gets invalidated and crash, doh
|
||||
// hope it doesn't start to leak memory without this :-/
|
||||
//i_pet->Clear();
|
||||
i_pet.GetMotionMaster()->MoveChase(u);
|
||||
m_creature->GetMotionMaster()->MoveChase(u);
|
||||
inCombat = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -90,48 +90,48 @@ bool PetAI::IsVisible(Unit *pl) const
|
|||
bool PetAI::_needToStop() const
|
||||
{
|
||||
// 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 !i_pet.getVictim()->isTargetableForAttack();
|
||||
return !m_creature->getVictim()->isTargetableForAttack();
|
||||
}
|
||||
|
||||
void PetAI::_stopAttack()
|
||||
{
|
||||
inCombat = false;
|
||||
if( !i_pet.isAlive() )
|
||||
if( !m_creature->isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_pet.GetGUIDLow());
|
||||
i_pet.StopMoving();
|
||||
i_pet.GetMotionMaster()->Clear();
|
||||
i_pet.GetMotionMaster()->MoveIdle();
|
||||
i_pet.CombatStop();
|
||||
i_pet.getHostilRefManager().deleteReferences();
|
||||
DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
|
||||
m_creature->StopMoving();
|
||||
m_creature->GetMotionMaster()->Clear();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
m_creature->CombatStop();
|
||||
m_creature->getHostilRefManager().deleteReferences();
|
||||
|
||||
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
|
||||
{
|
||||
i_pet.clearUnitState(UNIT_STAT_FOLLOW);
|
||||
i_pet.GetMotionMaster()->Clear();
|
||||
i_pet.GetMotionMaster()->MoveIdle();
|
||||
m_creature->clearUnitState(UNIT_STAT_FOLLOW);
|
||||
m_creature->GetMotionMaster()->Clear();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
i_pet.AttackStop();
|
||||
m_creature->AttackStop();
|
||||
}
|
||||
|
||||
void PetAI::UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!i_pet.isAlive())
|
||||
if (!m_creature->isAlive())
|
||||
return;
|
||||
|
||||
Unit* owner = i_pet.GetCharmerOrOwner();
|
||||
Unit* owner = m_creature->GetCharmerOrOwner();
|
||||
|
||||
if(m_updateAlliesTimer <= diff)
|
||||
// UpdateAllies self set update timer
|
||||
|
|
@ -139,67 +139,67 @@ void PetAI::UpdateAI(const uint32 diff)
|
|||
else
|
||||
m_updateAlliesTimer -= diff;
|
||||
|
||||
if (inCombat && !i_pet.getVictim())
|
||||
if (inCombat && !m_creature->getVictim())
|
||||
_stopAttack();
|
||||
|
||||
// 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())
|
||||
{
|
||||
DEBUG_LOG("Pet AI stoped attacking [guid=%u]", i_pet.GetGUIDLow());
|
||||
DEBUG_LOG("Pet AI stoped attacking [guid=%u]", m_creature->GetGUIDLow());
|
||||
_stopAttack();
|
||||
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
|
||||
if ( i_pet.IsStopped() && i_pet.IsNonMeleeSpellCasted(false) )
|
||||
if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
|
||||
{
|
||||
if( i_pet.hasUnitState(UNIT_STAT_FOLLOW) )
|
||||
i_pet.InterruptNonMeleeSpells(false);
|
||||
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
|
||||
m_creature->InterruptNonMeleeSpells(false);
|
||||
else
|
||||
return;
|
||||
}
|
||||
// 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;
|
||||
|
||||
//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() )
|
||||
_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());
|
||||
}
|
||||
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
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
|
@ -219,11 +219,11 @@ void PetAI::UpdateAI(const uint32 diff)
|
|||
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;
|
||||
}
|
||||
else
|
||||
|
|
@ -231,7 +231,7 @@ void PetAI::UpdateAI(const uint32 diff)
|
|||
bool spellUsed = false;
|
||||
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
|
||||
if(!Target)
|
||||
|
|
@ -262,19 +262,19 @@ void PetAI::UpdateAI(const uint32 diff)
|
|||
SpellCastTargets targets;
|
||||
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)
|
||||
i_pet.SendUpdateToPlayer( (Player*)target );
|
||||
m_creature->SendUpdateToPlayer((Player*)target);
|
||||
|
||||
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
|
||||
i_pet.SendUpdateToPlayer( (Player*)owner );
|
||||
m_creature->SendUpdateToPlayer( (Player*)owner );
|
||||
}
|
||||
|
||||
i_pet.AddCreatureSpellCooldown(spell->m_spellInfo->Id);
|
||||
if(i_pet.isPet())
|
||||
((Pet*)&i_pet)->CheckLearning(spell->m_spellInfo->Id);
|
||||
m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
|
||||
if (m_creature->isPet())
|
||||
((Pet&)m_creature).CheckLearning(spell->m_spellInfo->Id);
|
||||
|
||||
spell->prepare(&targets);
|
||||
}
|
||||
|
|
@ -289,13 +289,13 @@ void PetAI::UpdateAI(const uint32 diff)
|
|||
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 i_pet.GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
||||
&& u->isVisibleForOrDetect(&i_pet,true);
|
||||
return m_creature->GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
||||
&& u->isVisibleForOrDetect(m_creature,true);
|
||||
}
|
||||
|
||||
void PetAI::UpdateAllies()
|
||||
{
|
||||
Unit* owner = i_pet.GetCharmerOrOwner();
|
||||
Unit* owner = m_creature->GetCharmerOrOwner();
|
||||
Group *pGroup = NULL;
|
||||
|
||||
m_updateAlliesTimer = 10*IN_MILISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance
|
||||
|
|
@ -313,7 +313,7 @@ void PetAI::UpdateAllies()
|
|||
return;
|
||||
|
||||
m_AllySet.clear();
|
||||
m_AllySet.insert(i_pet.GetGUID());
|
||||
m_AllySet.insert(m_creature->GetGUID());
|
||||
if(pGroup) //add group
|
||||
{
|
||||
for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
|
|
@ -335,7 +335,7 @@ void PetAI::UpdateAllies()
|
|||
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
|
||||
if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
|
||||
(!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.canReachWithAttack(attacker)))
|
||||
if(!m_creature->getVictim() && m_creature->GetCharmInfo() && !m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
|
||||
(!m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY) || m_creature->canReachWithAttack(attacker)))
|
||||
AttackStart(attacker);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class MANGOS_DLL_DECL PetAI : public CreatureAI
|
|||
{
|
||||
public:
|
||||
|
||||
PetAI(Creature &c);
|
||||
explicit PetAI(Creature *c);
|
||||
|
||||
void MoveInLineOfSight(Unit *);
|
||||
void AttackStart(Unit *);
|
||||
|
|
@ -49,7 +49,6 @@ class MANGOS_DLL_DECL PetAI : public CreatureAI
|
|||
|
||||
void UpdateAllies();
|
||||
|
||||
Creature &i_pet;
|
||||
bool inCombat;
|
||||
TimeTracker i_tracker;
|
||||
std::set<uint64> m_AllySet;
|
||||
|
|
|
|||
|
|
@ -45,15 +45,15 @@ ReactorAI::AttackStart(Unit *p)
|
|||
if(!p)
|
||||
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());
|
||||
i_creature.SetInCombatWith(p);
|
||||
p->SetInCombatWith(&i_creature);
|
||||
m_creature->SetInCombatWith(p);
|
||||
p->SetInCombatWith(m_creature);
|
||||
|
||||
i_creature.AddThreat(p, 0.0f);
|
||||
m_creature->AddThreat(p, 0.0f);
|
||||
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*/)
|
||||
{
|
||||
// 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;
|
||||
|
||||
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());
|
||||
i_creature.resetAttackTimer();
|
||||
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||
m_creature->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,43 +85,43 @@ ReactorAI::UpdateAI(const uint32 /*time_diff*/)
|
|||
void
|
||||
ReactorAI::EnterEvadeMode()
|
||||
{
|
||||
if( !i_creature.isAlive() )
|
||||
if( !m_creature->isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
i_creature.GetMotionMaster()->MovementExpired();
|
||||
i_creature.GetMotionMaster()->MoveIdle();
|
||||
DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
|
||||
m_creature->GetMotionMaster()->MovementExpired();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.DeleteThreatList();
|
||||
m_creature->CombatStop();
|
||||
m_creature->DeleteThreatList();
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
||||
Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
|
||||
|
||||
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() )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
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
|
||||
{
|
||||
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();
|
||||
i_creature.DeleteThreatList();
|
||||
m_creature->RemoveAllAuras();
|
||||
m_creature->DeleteThreatList();
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.SetLootRecipient(NULL);
|
||||
m_creature->CombatStop();
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
|
||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
||||
if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class MANGOS_DLL_DECL ReactorAI : public CreatureAI
|
|||
{
|
||||
public:
|
||||
|
||||
ReactorAI(Creature &c) : i_creature(c), i_victimGuid(0) {}
|
||||
explicit ReactorAI(Creature *c) : CreatureAI(c), i_victimGuid(0) {}
|
||||
|
||||
void MoveInLineOfSight(Unit *);
|
||||
void AttackStart(Unit *);
|
||||
|
|
@ -38,7 +38,6 @@ class MANGOS_DLL_DECL ReactorAI : public CreatureAI
|
|||
static int Permissible(const Creature *);
|
||||
|
||||
private:
|
||||
Creature &i_creature;
|
||||
uint64 i_victimGuid;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ TotemAI::Permissible(const Creature *creature)
|
|||
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()
|
||||
{
|
||||
i_totem.CombatStop();
|
||||
m_creature->CombatStop();
|
||||
}
|
||||
|
||||
void
|
||||
TotemAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
if (i_totem.GetTotemType() != TOTEM_ACTIVE)
|
||||
if (getTotem().GetTotemType() != TOTEM_ACTIVE)
|
||||
return;
|
||||
|
||||
if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false))
|
||||
if (!m_creature->isAlive() || m_creature->IsNonMeleeSpellCasted(false))
|
||||
return;
|
||||
|
||||
// Search spell
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell());
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(getTotem().GetSpell());
|
||||
if (!spellInfo)
|
||||
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
|
||||
|
||||
// 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)
|
||||
if( !victim ||
|
||||
!victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) ||
|
||||
i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false) )
|
||||
!victim->isTargetableForAttack() || !m_creature->IsWithinDistInMap(victim, max_range) ||
|
||||
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.data.Part.reserved = ALL_DISTRICT;
|
||||
|
||||
victim = NULL;
|
||||
|
||||
MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range);
|
||||
MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck> checker(&i_totem,victim, u_check);
|
||||
MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(m_creature, m_creature, max_range);
|
||||
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>, WorldTypeMapContainer > world_object_checker(checker);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, grid_object_checker, *i_totem.GetMap());
|
||||
cell_lock->Visit(cell_lock, world_object_checker, *i_totem.GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_object_checker, *m_creature->GetMap());
|
||||
cell_lock->Visit(cell_lock, world_object_checker, *m_creature->GetMap());
|
||||
}
|
||||
|
||||
// If have target
|
||||
|
|
@ -102,8 +102,8 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
|
|||
i_victimGuid = victim->GetGUID();
|
||||
|
||||
// attack
|
||||
i_totem.SetInFront(victim); // client change orientation by self
|
||||
i_totem.CastSpell(victim, i_totem.GetSpell(), false);
|
||||
m_creature->SetInFront(victim); // client change orientation by self
|
||||
m_creature->CastSpell(victim, getTotem().GetSpell(), false);
|
||||
}
|
||||
else
|
||||
i_victimGuid = 0;
|
||||
|
|
@ -119,3 +119,8 @@ void
|
|||
TotemAI::AttackStart(Unit *)
|
||||
{
|
||||
}
|
||||
|
||||
Totem& TotemAI::getTotem()
|
||||
{
|
||||
return static_cast<Totem&>(*m_creature);
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ class MANGOS_DLL_DECL TotemAI : public CreatureAI
|
|||
{
|
||||
public:
|
||||
|
||||
TotemAI(Creature &c);
|
||||
explicit TotemAI(Creature *c);
|
||||
|
||||
void MoveInLineOfSight(Unit *);
|
||||
void AttackStart(Unit *);
|
||||
|
|
@ -38,9 +38,10 @@ class MANGOS_DLL_DECL TotemAI : public CreatureAI
|
|||
|
||||
void UpdateAI(const uint32);
|
||||
static int Permissible(const Creature *);
|
||||
protected:
|
||||
Totem& getTotem();
|
||||
|
||||
private:
|
||||
Totem &i_totem;
|
||||
uint64 i_victimGuid;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7666"
|
||||
#define REVISION_NR "7667"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue