aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp28
-rw-r--r--src/game/Creature.cpp26
-rw-r--r--src/game/Creature.h1
-rw-r--r--src/game/GridNotifiers.h23
-rw-r--r--src/game/SpellHandler.cpp3
-rw-r--r--src/game/Unit.cpp10
6 files changed, 53 insertions, 38 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index 0c946b8f26d..ca7dc435b09 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -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);
}
@@ -679,10 +669,10 @@ void ScriptedAI::DoZoneInCombat(Unit* pUnit)
return;
}
- Map::PlayerList const &PlayerList = map->GetPlayers();
- for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* i_pl = i->getSource())
- if (!i_pl->isAlive())
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+ for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (Player* i_pl = i->getSource())
+ if (!i_pl->isAlive())
pUnit->AddThreat(i_pl, 0.0f);
}
@@ -725,10 +715,10 @@ void ScriptedAI::DoTeleportAll(float x, float y, float z, float o)
if (!map->IsDungeon())
return;
- Map::PlayerList const &PlayerList = map->GetPlayers();
- for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* i_pl = i->getSource())
- if (!i_pl->isAlive())
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+ for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (Player* i_pl = i->getSource())
+ if (!i_pl->isAlive())
i_pl->TeleportTo(m_creature->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT);
}
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();