aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTrazom62 <none@none>2010-04-25 12:59:27 +0200
committerTrazom62 <none@none>2010-04-25 12:59:27 +0200
commiteccf5bf547c9b1648a453695189877c212071c70 (patch)
tree547c424a86c42bfd61944bc2d12d97f4146cec04 /src
parentb466819333eb551a64cdb02e9d8d25678fbb770e (diff)
Refactor Creature::SelectNearestTarget(float dist)
This function is used in many scripts to find the nearest enemy within the given distance. However, it had an implicit limit to the ATTACK_DISTANCE. so in many case the "dist" was in fact just ignored. In other case, the ATTACK_DISTANCE is required. So 2 functions are necessary to avoid ambiguities. The refactoring is the split of the function in 2: SelectNearestTarget and SelectNearestTargetInAttackDistance. --HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/game/Creature.cpp32
-rw-r--r--src/game/Creature.h2
-rw-r--r--src/game/CreatureAI.cpp9
-rw-r--r--src/game/CreatureAI.h2
-rw-r--r--src/game/GridNotifiers.h28
-rw-r--r--src/game/Unit.cpp2
-rw-r--r--src/game/UnitAI.cpp2
-rw-r--r--src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp7
-rw-r--r--src/scripts/northrend/naxxramas/boss_four_horsemen.cpp10
-rw-r--r--src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp2
10 files changed, 76 insertions, 20 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index f64cc29b116..91e21805d5c 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -1783,6 +1783,8 @@ bool Creature::IsVisibleInGridForPlayer(Player const* pl) const
return false;
}
+
+// select nearest hostile unit within the given distance (regardless of threat list).
Unit* Creature::SelectNearestTarget(float dist) const
{
CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
@@ -1793,6 +1795,36 @@ Unit* Creature::SelectNearestTarget(float dist) const
Unit *target = NULL;
{
+ if (dist == 0.0f || dist > MAX_VISIBILITY_DISTANCE)
+ dist = MAX_VISIBILITY_DISTANCE;
+
+ Trinity::NearestHostileUnitCheck u_check(this, dist);
+ Trinity::UnitLastSearcher<Trinity::NearestHostileUnitCheck> searcher(this, target, u_check);
+
+ TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
+ TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
+
+ cell.Visit(p, world_unit_searcher, *GetMap(), *this, dist);
+ cell.Visit(p, grid_unit_searcher, *GetMap(), *this, dist);
+ }
+
+ return target;
+}
+
+// select nearest hostile unit within the given attack distance (i.e. distance is ignored if > than ATTACK_DISTANCE), regardless of threat list.
+Unit* Creature::SelectNearestTargetInAttackDistance(float dist) const
+{
+ CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ Unit *target = NULL;
+
+ if (dist > ATTACK_DISTANCE)
+ sLog.outError("Creature (GUID: %u Entry: %u) SelectNearestTargetInAttackDistance called with dist > ATTACK_DISTANCE. Extra distance ignored.",GetGUIDLow(),GetEntry());
+
+ {
Trinity::NearestHostileUnitInAttackDistanceCheck u_check(this, dist);
Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck> searcher(this, target, u_check);
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 3ffaa5e401f..b2b51785956 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -557,6 +557,8 @@ class Creature : public Unit, public GridObject<Creature>
void SendAIReaction(AiReaction reactionType);
Unit* SelectNearestTarget(float dist = 0) const;
+ Unit* SelectNearestTargetInAttackDistance(float dist = 0) const;
+
void DoFleeToGetAssistance();
void CallForHelp(float fRadius);
void CallAssistance();
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index 62396d528be..fb8f37ae492 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -131,15 +131,6 @@ void CreatureAI::MoveInLineOfSight(Unit *who)
// me->GetMotionMaster()->MoveChase(who->getVictim());
}
-void CreatureAI::SelectNearestTarget(Unit *who)
-{
- if (me->getVictim() && me->GetDistanceOrder(who, me->getVictim()) && me->canAttack(who))
- {
- me->getThreatManager().modifyThreatPercent(me->getVictim(), -100);
- me->AddThreat(who, 1000000.0f);
- }
-}
-
void CreatureAI::EnterEvadeMode()
{
if (!_EnterEvadeMode())
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index d22bccfaf4d..c03d3dd09d0 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -73,8 +73,6 @@ class CreatureAI : public UnitAI
bool UpdateVictimWithGaze();
bool UpdateCombatState();
- void SelectNearestTarget(Unit *who);
-
void SetGazeOn(Unit *target);
Creature *DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index 7b860af1d1e..b0abf0aae79 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -940,6 +940,31 @@ namespace Trinity
// Creature checks
+ class NearestHostileUnitCheck
+ {
+ public:
+ explicit NearestHostileUnitCheck(Creature const* creature, float dist = 0) : me(creature)
+ {
+ m_range = (dist == 0 ? 9999 : dist);
+ }
+ bool operator()(Unit* u)
+ {
+ if (!me->IsWithinDistInMap(u, m_range))
+ return false;
+
+ if (!me->canAttack(u))
+ return false;
+
+ m_range = me->GetDistance(u); // use found unit range as new range limit for next check
+ return true;
+ }
+
+ private:
+ Creature const *me;
+ float m_range;
+ NearestHostileUnitCheck(NearestHostileUnitCheck const&);
+ };
+
class NearestHostileUnitInAttackDistanceCheck
{
public:
@@ -950,7 +975,6 @@ namespace Trinity
}
bool operator()(Unit* u)
{
- // TODO: addthreat for every enemy in range?
if (!me->IsWithinDistInMap(u, m_range))
return false;
@@ -965,7 +989,7 @@ namespace Trinity
return false;
}
- m_range = me->GetDistance(u);
+ m_range = me->GetDistance(u); // use found unit range as new range limit for next check
return true;
}
float GetLastRange() const { return m_range; }
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index aa84fe3ed8b..3c9dc12a5ee 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -12200,7 +12200,7 @@ Unit* Creature::SelectVictim()
// search nearby enemy before enter evade mode
if (HasReactState(REACT_AGGRESSIVE))
{
- target = SelectNearestTarget();
+ target = SelectNearestTargetInAttackDistance();
if (target && _IsTargetAcceptable(target))
return target;
}
diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp
index a8185453491..e70df50a56e 100644
--- a/src/game/UnitAI.cpp
+++ b/src/game/UnitAI.cpp
@@ -323,5 +323,5 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
Unit *target = me->getVictim();
if (!target || !charmer->canAttack(target))
- AttackStart(charmer->SelectNearestTarget());
+ AttackStart(charmer->SelectNearestTargetInAttackDistance());
}
diff --git a/src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp b/src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp
index a0a9723cd3c..73f17485f7f 100644
--- a/src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp
+++ b/src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp
@@ -258,12 +258,11 @@ struct boss_twinemperorsAI : public ScriptedAI
{
AfterTeleport = false;
me->clearUnitState(UNIT_STAT_STUNNED);
- Unit *nearu = me->SelectNearestTarget(100);
- //DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
- if (nearu)
+ if (Unit *nearu = me->SelectNearestTarget(100))
{
+ //DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
AttackStart(nearu);
- me->getThreatManager().addThreat(nearu, 10000);
+ me->AddThreat(nearu, 10000);
}
return true;
}
diff --git a/src/scripts/northrend/naxxramas/boss_four_horsemen.cpp b/src/scripts/northrend/naxxramas/boss_four_horsemen.cpp
index b88d45bf97a..f04b39040db 100644
--- a/src/scripts/northrend/naxxramas/boss_four_horsemen.cpp
+++ b/src/scripts/northrend/naxxramas/boss_four_horsemen.cpp
@@ -236,6 +236,16 @@ struct boss_four_horsemenAI : public BossAI
nextWP = id + 1;
}
+ // switch to "who" if nearer than current target.
+ void SelectNearestTarget(Unit *who)
+ {
+ if (me->getVictim() && me->GetDistanceOrder(who, me->getVictim()) && me->canAttack(who))
+ {
+ me->getThreatManager().modifyThreatPercent(me->getVictim(), -100);
+ me->AddThreat(who, 1000000.0f);
+ }
+ }
+
void MoveInLineOfSight(Unit *who)
{
BossAI::MoveInLineOfSight(who);
diff --git a/src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp b/src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp
index b26836b42e2..af5f1bd95c1 100644
--- a/src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp
+++ b/src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp
@@ -408,7 +408,7 @@ struct boss_alarAI : public ScriptedAI
else
{
Unit *pTarget = NULL;
- pTarget = me->SelectNearestTarget(5);
+ pTarget = me->SelectNearestTargetInAttackDistance(5);
if (pTarget)
me->AI()->AttackStart(pTarget);
else