*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:
megamage
2008-11-21 10:07:11 -06:00
parent 5528b7c512
commit 71707df1de
6 changed files with 53 additions and 38 deletions
+1 -11
View File
@@ -73,17 +73,7 @@ bool ScriptedAI::IsVisible(Unit* who) const
void ScriptedAI::MoveInLineOfSight(Unit *who) void ScriptedAI::MoveInLineOfSight(Unit *who)
{ {
if(m_creature->getVictim() || !m_creature->IsHostileTo(who) || !who->isInAccessiblePlaceFor(m_creature)) if(!m_creature->getVictim() && m_creature->canStartAttack(who))
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);
AttackStart(who); AttackStart(who);
} }
+20 -6
View File
@@ -1543,6 +1543,19 @@ bool Creature::IsWithinSightDist(Unit const* u) const
return IsWithinDistInMap(u, sWorld.getConfig(CONFIG_SIGHT_MONSTER)); 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 Creature::GetAttackDistance(Unit const* pl) const
{ {
float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO); float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO);
@@ -1824,12 +1837,12 @@ void Creature::DoFleeToGetAssistance(float radius) // Optional parameter
Unit* Creature::SelectNearestTarget(float dist) const Unit* Creature::SelectNearestTarget(float dist) const
{ {
/*CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
Cell cell(p); Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT; cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate(); cell.SetNoCreate();
Unit *target; Unit *target = NULL;
{ {
Trinity::NearestHostileUnitInAttackDistanceCheck u_check(this, dist); 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); TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_unit_searcher, GetMap()); cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
cell_lock->Visit(cell_lock, grid_unit_searcher, GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap());
}*/ }
return NULL;
return target;
} }
void Creature::CallAssistence() void Creature::CallAssistence()
+1
View File
@@ -557,6 +557,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const;
bool IsWithinSightDist(Unit const* u) const; bool IsWithinSightDist(Unit const* u) const;
bool canStartAttack(Unit const* u) const;
float GetAttackDistance(Unit const* pl) const; float GetAttackDistance(Unit const* pl) const;
Unit* SelectNearestTarget(float dist = 0) const; Unit* SelectNearestTarget(float dist = 0) const;
+11 -12
View File
@@ -701,35 +701,34 @@ namespace Trinity
class NearestHostileUnitInAttackDistanceCheck class NearestHostileUnitInAttackDistanceCheck
{ {
public: 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_range = (dist == 0 ? 9999 : dist);
m_force = (dist == 0 ? false : true); m_force = (dist == 0 ? false : true);
} }
bool operator()(Unit* u) 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; return false;
float dist; if(m_force)
if(m_force) dist = m_range; {
if(!m_creature->canAttack(u))
return false;
}
else else
{ {
dist = m_creature->GetAttackDistance(u); if(!m_creature->canStartAttack(u))
if(dist > m_range) dist = m_range; 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); m_range = m_creature->GetDistance(u);
return true; return true;
} }
float GetLastRange() const { return m_range; } float GetLastRange() const { return m_range; }
private: private:
Creature* const m_creature; Creature const *m_creature;
float m_range; float m_range;
bool m_force; bool m_force;
NearestHostileUnitInAttackDistanceCheck(NearestHostileUnitInAttackDistanceCheck const&); NearestHostileUnitInAttackDistanceCheck(NearestHostileUnitInAttackDistanceCheck const&);
+2 -1
View File
@@ -368,10 +368,11 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_CHARM || spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_CHARM ||
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_BIND_SIGHT) spellInfo->EffectApplyAuraName[i] == SPELL_AURA_BIND_SIGHT)
{ {
// Fix me: creature may be killed during player aura cancel
_player->RemoveAurasDueToSpellByCancel(spellId); _player->RemoveAurasDueToSpellByCancel(spellId);
if (_player->GetCharm()) if (_player->GetCharm())
_player->GetCharm()->RemoveAurasDueToSpellByCancel(spellId); _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); ((Unit*)_player->GetFarsightTarget())->RemoveAurasDueToSpellByCancel(spellId);
return; return;
} }
+10
View File
@@ -8542,6 +8542,9 @@ bool Unit::canAttack(Unit const* target) const
{ {
assert(target); assert(target);
if(!IsHostileTo(target))
return false;
if(!target->isAttackableByAOE() || target->hasUnitState(UNIT_STAT_DIED)) if(!target->isAttackableByAOE() || target->hasUnitState(UNIT_STAT_DIED))
return false; 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 // enter in evade mode in other case
((Creature*)this)->AI()->EnterEvadeMode(); ((Creature*)this)->AI()->EnterEvadeMode();