[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:
VladimirMangos 2009-04-14 06:43:31 +04:00
parent 721e005b84
commit 69fb9736cc
18 changed files with 379 additions and 382 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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)

View file

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

View file

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

View file

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

View file

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

View file

@ -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 *) {}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7666"
#define REVISION_NR "7667"
#endif // __REVISION_NR_H__