*Let creature search nearby target before enter evade mode
*Add function canStartAttack to reduce code in MoveInLineOfSight *Fix a bug that cancelling bind sight auras may crash the server --HG-- branch : trunk
This commit is contained in:
@@ -73,17 +73,7 @@ bool ScriptedAI::IsVisible(Unit* who) const
|
||||
|
||||
void ScriptedAI::MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if(m_creature->getVictim() || !m_creature->IsHostileTo(who) || !who->isInAccessiblePlaceFor(m_creature))
|
||||
return;
|
||||
|
||||
if(!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
|
||||
return;
|
||||
|
||||
if(!m_creature->IsWithinDistInMap(who, m_creature->GetAttackDistance(who)) || !m_creature->IsWithinLOSInMap(who))
|
||||
return;
|
||||
|
||||
if(m_creature->canAttack(who))
|
||||
//who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
if(!m_creature->getVictim() && m_creature->canStartAttack(who))
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
|
||||
+20
-6
@@ -1543,6 +1543,19 @@ bool Creature::IsWithinSightDist(Unit const* u) const
|
||||
return IsWithinDistInMap(u, sWorld.getConfig(CONFIG_SIGHT_MONSTER));
|
||||
}
|
||||
|
||||
bool Creature::canStartAttack(Unit const* who) const
|
||||
{
|
||||
if(!who->isInAccessiblePlaceFor(this)
|
||||
|| !canFly() && GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE
|
||||
|| !IsWithinDistInMap(who, GetAttackDistance(who)))
|
||||
return false;
|
||||
|
||||
if(!canAttack(who))
|
||||
return false;
|
||||
|
||||
return IsWithinLOSInMap(who);
|
||||
}
|
||||
|
||||
float Creature::GetAttackDistance(Unit const* pl) const
|
||||
{
|
||||
float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO);
|
||||
@@ -1824,12 +1837,12 @@ void Creature::DoFleeToGetAssistance(float radius) // Optional parameter
|
||||
|
||||
Unit* Creature::SelectNearestTarget(float dist) const
|
||||
{
|
||||
/*CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
|
||||
CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
Unit *target;
|
||||
Unit *target = NULL;
|
||||
|
||||
{
|
||||
Trinity::NearestHostileUnitInAttackDistanceCheck u_check(this, dist);
|
||||
@@ -1839,10 +1852,11 @@ Unit* Creature::SelectNearestTarget(float dist) const
|
||||
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_unit_searcher, GetMap());
|
||||
}*/
|
||||
return NULL;
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap());
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void Creature::CallAssistence()
|
||||
|
||||
@@ -557,6 +557,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
||||
|
||||
bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const;
|
||||
bool IsWithinSightDist(Unit const* u) const;
|
||||
bool canStartAttack(Unit const* u) const;
|
||||
float GetAttackDistance(Unit const* pl) const;
|
||||
|
||||
Unit* SelectNearestTarget(float dist = 0) const;
|
||||
|
||||
+11
-12
@@ -701,35 +701,34 @@ namespace Trinity
|
||||
class NearestHostileUnitInAttackDistanceCheck
|
||||
{
|
||||
public:
|
||||
explicit NearestHostileUnitInAttackDistanceCheck(Creature* creature, float dist = 0) : m_creature(creature)
|
||||
explicit NearestHostileUnitInAttackDistanceCheck(Creature const* creature, float dist = 0) : m_creature(creature)
|
||||
{
|
||||
m_range = (dist == 0 ? 9999 : dist);
|
||||
m_force = (dist == 0 ? false : true);
|
||||
}
|
||||
bool operator()(Unit* u)
|
||||
{
|
||||
if(!u->isAlive() || !m_creature->IsHostileTo(u))
|
||||
// TODO: addthreat for every enemy in range?
|
||||
if(!m_creature->IsWithinDistInMap(u, m_range))
|
||||
return false;
|
||||
|
||||
float dist;
|
||||
if(m_force) dist = m_range;
|
||||
if(m_force)
|
||||
{
|
||||
if(!m_creature->canAttack(u))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = m_creature->GetAttackDistance(u);
|
||||
if(dist > m_range) dist = m_range;
|
||||
if(!m_creature->canStartAttack(u))
|
||||
return false;
|
||||
}
|
||||
if(!m_creature->IsWithinDistInMap(u, dist))
|
||||
return false;
|
||||
|
||||
if(!m_creature->canSeeOrDetect(u, true, false))
|
||||
return false;
|
||||
|
||||
m_range = m_creature->GetDistance(u);
|
||||
return true;
|
||||
}
|
||||
float GetLastRange() const { return m_range; }
|
||||
private:
|
||||
Creature* const m_creature;
|
||||
Creature const *m_creature;
|
||||
float m_range;
|
||||
bool m_force;
|
||||
NearestHostileUnitInAttackDistanceCheck(NearestHostileUnitInAttackDistanceCheck const&);
|
||||
|
||||
@@ -368,10 +368,11 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
|
||||
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_CHARM ||
|
||||
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_BIND_SIGHT)
|
||||
{
|
||||
// Fix me: creature may be killed during player aura cancel
|
||||
_player->RemoveAurasDueToSpellByCancel(spellId);
|
||||
if (_player->GetCharm())
|
||||
_player->GetCharm()->RemoveAurasDueToSpellByCancel(spellId);
|
||||
else if (_player->GetFarsightTarget()->GetTypeId() != TYPEID_DYNAMICOBJECT)
|
||||
else if (_player->GetFarsightTarget() && _player->GetFarsightTarget()->GetTypeId() != TYPEID_DYNAMICOBJECT)
|
||||
((Unit*)_player->GetFarsightTarget())->RemoveAurasDueToSpellByCancel(spellId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8542,6 +8542,9 @@ bool Unit::canAttack(Unit const* target) const
|
||||
{
|
||||
assert(target);
|
||||
|
||||
if(!IsHostileTo(target))
|
||||
return false;
|
||||
|
||||
if(!target->isAttackableByAOE() || target->hasUnitState(UNIT_STAT_DIED))
|
||||
return false;
|
||||
|
||||
@@ -9126,6 +9129,13 @@ bool Unit::SelectHostilTarget()
|
||||
}
|
||||
}
|
||||
|
||||
// search nearby enemy before enter evade mode
|
||||
if(Unit *target = ((Creature*)this)->SelectNearestTarget())
|
||||
{
|
||||
((Creature*)this)->AI()->AttackStart(target);
|
||||
return true;
|
||||
}
|
||||
|
||||
// enter in evade mode in other case
|
||||
((Creature*)this)->AI()->EnterEvadeMode();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user