diff options
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/Creature.cpp | 26 | ||||
| -rw-r--r-- | src/game/Creature.h | 1 | ||||
| -rw-r--r-- | src/game/GridNotifiers.h | 23 | ||||
| -rw-r--r-- | src/game/SpellHandler.cpp | 3 | ||||
| -rw-r--r-- | src/game/Unit.cpp | 10 |
5 files changed, 44 insertions, 19 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 33d1fd2ea02..91eb04b07f5 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -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() diff --git a/src/game/Creature.h b/src/game/Creature.h index eb5b2d711f0..5d0ca5b5946 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -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; diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index 57abea4d5a2..3561f30861c 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -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&); diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 0e318eb5ddc..07d8b18b543 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -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; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9a78c50857f..94f647cdd46 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -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(); |
