[7668] Cleanup In CreatureAI function descriptions and AttackStart/AttackedBy use. Author: VladimirMangos
* Use AI::AttackStart calls only in case explicit request creature attack from core or AI code "attack it if can".
Like taunt, pet handler attack command.
* Use AI::AttackedBy for reaction at hostile action "do something at hostile action"
Like non-dot damage, swing, negative spell landing, or fade fear/etc.
And provided by default call AttackStart if no current target.
This fix some problems, like:
* Civilian will react propertly at attack by another creature (not pet or player).
* Will not cases (at least triggred by core) when attack target start run to attacker before any real hostile action apply.
*Note: AttackBy is still disabled until proved useful to TC.
--HG--
branch : trunk
This commit is contained in:
@@ -167,3 +167,8 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
|
|||||||
AttackStart(charmer->SelectNearestTarget());
|
AttackStart(charmer->SelectNearestTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*void CreatureAI::AttackedBy( Unit* attacker )
|
||||||
|
{
|
||||||
|
if(!m_creature->getVictim())
|
||||||
|
AttackStart(attacker);
|
||||||
|
}*/
|
||||||
|
|||||||
+34
-8
@@ -73,7 +73,7 @@ enum SelectAggroTarget
|
|||||||
class TRINITY_DLL_SPEC UnitAI
|
class TRINITY_DLL_SPEC UnitAI
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Unit *me;
|
Unit* const me;
|
||||||
public:
|
public:
|
||||||
explicit UnitAI(Unit *u) : me(u) {}
|
explicit UnitAI(Unit *u) : me(u) {}
|
||||||
virtual void AttackStart(Unit *);
|
virtual void AttackStart(Unit *);
|
||||||
@@ -95,7 +95,7 @@ class TRINITY_DLL_SPEC UnitAI
|
|||||||
class TRINITY_DLL_SPEC PlayerAI : public UnitAI
|
class TRINITY_DLL_SPEC PlayerAI : public UnitAI
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Player *me;
|
Player* const me;
|
||||||
public:
|
public:
|
||||||
explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {}
|
explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {}
|
||||||
|
|
||||||
@@ -111,8 +111,8 @@ class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI
|
|||||||
class TRINITY_DLL_SPEC CreatureAI : public UnitAI
|
class TRINITY_DLL_SPEC CreatureAI : public UnitAI
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Creature *me;
|
Creature* const me;
|
||||||
Creature *m_creature;
|
Creature* const m_creature;
|
||||||
|
|
||||||
bool UpdateVictim();
|
bool UpdateVictim();
|
||||||
public:
|
public:
|
||||||
@@ -120,13 +120,17 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
|
|||||||
|
|
||||||
virtual ~CreatureAI() {}
|
virtual ~CreatureAI() {}
|
||||||
|
|
||||||
// Called if IsVisible(Unit *who) is true at each *who move
|
///== Reactions At =================================
|
||||||
|
|
||||||
|
// Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter
|
||||||
virtual void MoveInLineOfSight(Unit *);
|
virtual void MoveInLineOfSight(Unit *);
|
||||||
|
|
||||||
// Called at stopping attack by any attacker
|
// Called for reaction at stopping attack at no attackers or targets
|
||||||
virtual void EnterEvadeMode();
|
virtual void EnterEvadeMode();
|
||||||
|
|
||||||
// Called at any Damage from any attacker (before damage apply)
|
// Called at any Damage from any attacker (before damage apply)
|
||||||
|
// Note: it for recalculation damage or special reaction at damage
|
||||||
|
// for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
|
||||||
virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) {}
|
virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) {}
|
||||||
|
|
||||||
// Called when the creature is killed
|
// Called when the creature is killed
|
||||||
@@ -146,8 +150,8 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
|
|||||||
// Called when spell hits a target
|
// Called when spell hits a target
|
||||||
virtual void SpellHitTarget(Unit* target, const SpellEntry*) {}
|
virtual void SpellHitTarget(Unit* target, const SpellEntry*) {}
|
||||||
|
|
||||||
// Called when vitim entered water and creature can not enter water
|
// Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
|
||||||
virtual bool canReachByRangeAttack(Unit*) { return false; }
|
//virtual void AttackedBy(Unit* attacker);
|
||||||
|
|
||||||
// Called when creature is spawned or respawned (for reseting variables)
|
// Called when creature is spawned or respawned (for reseting variables)
|
||||||
virtual void JustRespawned() {}
|
virtual void JustRespawned() {}
|
||||||
@@ -161,6 +165,28 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
|
|||||||
virtual void JustReachedHome() {}
|
virtual void JustReachedHome() {}
|
||||||
|
|
||||||
void DoZoneInCombat(Unit* pUnit = NULL);
|
void DoZoneInCombat(Unit* pUnit = NULL);
|
||||||
|
|
||||||
|
///== Triggered Actions Requested ==================
|
||||||
|
|
||||||
|
// Called when creature attack expected (if creature can and no have current victim)
|
||||||
|
// Note: for reaction at hostile action must be called AttackedBy function.
|
||||||
|
virtual void AttackStart(Unit *) {}
|
||||||
|
|
||||||
|
// Called at World update tick
|
||||||
|
virtual void UpdateAI(const uint32 diff ) {}
|
||||||
|
|
||||||
|
///== State checks =================================
|
||||||
|
|
||||||
|
// Is unit visible for MoveInLineOfSight
|
||||||
|
//virtual bool IsVisible(Unit *) const { return false; }
|
||||||
|
|
||||||
|
// Called when victim entered water and creature can not enter water
|
||||||
|
virtual bool canReachByRangeAttack(Unit*) { return false; }
|
||||||
|
|
||||||
|
///== Fields =======================================
|
||||||
|
|
||||||
|
// Pointer to controlled by AI creature
|
||||||
|
//Creature* const m_creature;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
|
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
|
||||||
|
|||||||
@@ -3425,7 +3425,7 @@ void AuraEffect::HandleAuraModScale(bool apply, bool Real)
|
|||||||
((Creature*)m_target)->AIM_Initialize();
|
((Creature*)m_target)->AIM_Initialize();
|
||||||
|
|
||||||
if (((Creature*)m_target)->AI())
|
if (((Creature*)m_target)->AI())
|
||||||
((Creature*)m_target)->AI()->AttackStart(caster);
|
((Creature*)m_target)->AI()->AttackedBy(caster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3581,7 +3581,7 @@ void AuraEffect::HandleAuraModPetTalentsPoints(bool Apply, bool Real)
|
|||||||
{
|
{
|
||||||
((Creature*)m_target)->AIM_Initialize();
|
((Creature*)m_target)->AIM_Initialize();
|
||||||
if (((Creature*)m_target)->AI())
|
if (((Creature*)m_target)->AI())
|
||||||
((Creature*)m_target)->AI()->AttackStart(caster);
|
((Creature*)m_target)->AI()->AttackedBy(caster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3483,8 +3483,7 @@ void Spell::EffectPickPocket(uint32 /*i*/)
|
|||||||
{
|
{
|
||||||
// Reveal action + get attack
|
// Reveal action + get attack
|
||||||
m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
|
m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
|
||||||
if (((Creature*)unitTarget)->IsAIEnabled)
|
m_caster->CombatStart(unitTarget);
|
||||||
((Creature*)unitTarget)->AI()->AttackStart(m_caster);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,12 +101,6 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
|
|||||||
i_victimGuid = 0;
|
i_victimGuid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
TotemAI::IsVisible(Unit *) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TotemAI::AttackStart(Unit *)
|
TotemAI::AttackStart(Unit *)
|
||||||
{
|
{
|
||||||
@@ -120,4 +114,3 @@ TotemAI::AttackStart(Unit *)
|
|||||||
((Player*)m_creature->GetOwner())->GetSession()->SendPacket(&data);
|
((Player*)m_creature->GetOwner())->GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,9 @@ class TRINITY_DLL_DECL TotemAI : public CreatureAI
|
|||||||
void MoveInLineOfSight(Unit *);
|
void MoveInLineOfSight(Unit *);
|
||||||
void AttackStart(Unit *);
|
void AttackStart(Unit *);
|
||||||
void EnterEvadeMode();
|
void EnterEvadeMode();
|
||||||
bool IsVisible(Unit *) const;
|
|
||||||
|
|
||||||
void UpdateAI(const uint32);
|
void UpdateAI(const uint32);
|
||||||
static int Permissible(const Creature *);
|
static int Permissible(const Creature *);
|
||||||
protected:
|
|
||||||
Totem& getTotem();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64 i_victimGuid;
|
uint64 i_victimGuid;
|
||||||
|
|||||||
+11
-25
@@ -574,10 +574,8 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pVictim->GetTypeId() != TYPEID_PLAYER)
|
|
||||||
{
|
|
||||||
// no xp,health if type 8 /critters/
|
// no xp,health if type 8 /critters/
|
||||||
if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
|
if(pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
|
||||||
{
|
{
|
||||||
// allow loot only if has loot_id in creature_template
|
// allow loot only if has loot_id in creature_template
|
||||||
if(damage >= pVictim->GetHealth())
|
if(damage >= pVictim->GetHealth())
|
||||||
@@ -598,7 +596,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||||||
|
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG("DealDamageStart");
|
DEBUG_LOG("DealDamageStart");
|
||||||
|
|
||||||
@@ -835,22 +832,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||||||
|
|
||||||
pVictim->ModifyHealth(- (int32)damage);
|
pVictim->ModifyHealth(- (int32)damage);
|
||||||
|
|
||||||
if(damagetype != DOT)
|
|
||||||
{
|
|
||||||
if(!getVictim())
|
|
||||||
/*{
|
|
||||||
// if have target and damage pVictim just call AI reaction
|
|
||||||
if(pVictim != getVictim() && pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsAIEnabled)
|
|
||||||
((Creature*)pVictim)->AI()->AttackedBy(this);
|
|
||||||
}
|
|
||||||
else*/
|
|
||||||
{
|
|
||||||
// if not have main target then attack state with target (including AI call)
|
|
||||||
//start melee attacks only after melee hit
|
|
||||||
Attack(pVictim,(damagetype == DIRECT_DAMAGE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE)
|
if(damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE)
|
||||||
{
|
{
|
||||||
//TODO: This is from procflag, I do not know which spell needs this
|
//TODO: This is from procflag, I do not know which spell needs this
|
||||||
@@ -2268,6 +2249,10 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if damage pVictim call AI reaction
|
||||||
|
//if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
|
||||||
|
// ((Creature*)pVictim)->AI()->AttackedBy(this);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2295,6 +2280,10 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
|
|||||||
--m_extraAttacks;
|
--m_extraAttacks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if damage pVictim call AI reaction
|
||||||
|
//if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
|
||||||
|
// ((Creature*)pVictim)->AI()->AttackedBy(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const
|
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const
|
||||||
@@ -7817,9 +7806,6 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
|
|||||||
//if(GetTypeId()==TYPEID_UNIT)
|
//if(GetTypeId()==TYPEID_UNIT)
|
||||||
// ((Creature*)this)->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
|
// ((Creature*)this)->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||||
|
|
||||||
//if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->IsAIEnabled)
|
|
||||||
// ((Creature*)m_attacking)->AI()->AttackedBy(this);
|
|
||||||
|
|
||||||
if(GetTypeId()==TYPEID_UNIT)
|
if(GetTypeId()==TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
// should not let player enter combat by right clicking target
|
// should not let player enter combat by right clicking target
|
||||||
@@ -11835,8 +11821,8 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
|
|||||||
|
|
||||||
// attack caster if can
|
// attack caster if can
|
||||||
Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL);
|
Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL);
|
||||||
if(caster && caster != getVictim() && ((Creature*)this)->IsAIEnabled)
|
if(caster && ((Creature*)this)->AI())
|
||||||
((Creature*)this)->AI()->AttackStart(caster);
|
((Creature*)this)->AI()->AttackedBy(caster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user