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
This commit is contained in:
@@ -1783,6 +1783,8 @@ bool Creature::IsVisibleInGridForPlayer(Player const* pl) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// select nearest hostile unit within the given distance (regardless of threat list).
|
||||||
Unit* Creature::SelectNearestTarget(float dist) const
|
Unit* Creature::SelectNearestTarget(float dist) const
|
||||||
{
|
{
|
||||||
CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
|
CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
|
||||||
@@ -1792,6 +1794,36 @@ Unit* Creature::SelectNearestTarget(float dist) const
|
|||||||
|
|
||||||
Unit *target = NULL;
|
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::NearestHostileUnitInAttackDistanceCheck u_check(this, dist);
|
||||||
Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck> searcher(this, target, u_check);
|
Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck> searcher(this, target, u_check);
|
||||||
|
|||||||
@@ -557,6 +557,8 @@ class Creature : public Unit, public GridObject<Creature>
|
|||||||
void SendAIReaction(AiReaction reactionType);
|
void SendAIReaction(AiReaction reactionType);
|
||||||
|
|
||||||
Unit* SelectNearestTarget(float dist = 0) const;
|
Unit* SelectNearestTarget(float dist = 0) const;
|
||||||
|
Unit* SelectNearestTargetInAttackDistance(float dist = 0) const;
|
||||||
|
|
||||||
void DoFleeToGetAssistance();
|
void DoFleeToGetAssistance();
|
||||||
void CallForHelp(float fRadius);
|
void CallForHelp(float fRadius);
|
||||||
void CallAssistance();
|
void CallAssistance();
|
||||||
|
|||||||
@@ -131,15 +131,6 @@ void CreatureAI::MoveInLineOfSight(Unit *who)
|
|||||||
// me->GetMotionMaster()->MoveChase(who->getVictim());
|
// 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()
|
void CreatureAI::EnterEvadeMode()
|
||||||
{
|
{
|
||||||
if (!_EnterEvadeMode())
|
if (!_EnterEvadeMode())
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ class CreatureAI : public UnitAI
|
|||||||
bool UpdateVictimWithGaze();
|
bool UpdateVictimWithGaze();
|
||||||
bool UpdateCombatState();
|
bool UpdateCombatState();
|
||||||
|
|
||||||
void SelectNearestTarget(Unit *who);
|
|
||||||
|
|
||||||
void SetGazeOn(Unit *target);
|
void SetGazeOn(Unit *target);
|
||||||
|
|
||||||
Creature *DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
Creature *DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
||||||
|
|||||||
@@ -940,6 +940,31 @@ namespace Trinity
|
|||||||
|
|
||||||
// Creature checks
|
// 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
|
class NearestHostileUnitInAttackDistanceCheck
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -950,7 +975,6 @@ namespace Trinity
|
|||||||
}
|
}
|
||||||
bool operator()(Unit* u)
|
bool operator()(Unit* u)
|
||||||
{
|
{
|
||||||
// TODO: addthreat for every enemy in range?
|
|
||||||
if (!me->IsWithinDistInMap(u, m_range))
|
if (!me->IsWithinDistInMap(u, m_range))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -965,7 +989,7 @@ namespace Trinity
|
|||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
float GetLastRange() const { return m_range; }
|
float GetLastRange() const { return m_range; }
|
||||||
|
|||||||
+1
-1
@@ -12200,7 +12200,7 @@ Unit* Creature::SelectVictim()
|
|||||||
// search nearby enemy before enter evade mode
|
// search nearby enemy before enter evade mode
|
||||||
if (HasReactState(REACT_AGGRESSIVE))
|
if (HasReactState(REACT_AGGRESSIVE))
|
||||||
{
|
{
|
||||||
target = SelectNearestTarget();
|
target = SelectNearestTargetInAttackDistance();
|
||||||
if (target && _IsTargetAcceptable(target))
|
if (target && _IsTargetAcceptable(target))
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -323,5 +323,5 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
|
|||||||
|
|
||||||
Unit *target = me->getVictim();
|
Unit *target = me->getVictim();
|
||||||
if (!target || !charmer->canAttack(target))
|
if (!target || !charmer->canAttack(target))
|
||||||
AttackStart(charmer->SelectNearestTarget());
|
AttackStart(charmer->SelectNearestTargetInAttackDistance());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,12 +258,11 @@ struct boss_twinemperorsAI : public ScriptedAI
|
|||||||
{
|
{
|
||||||
AfterTeleport = false;
|
AfterTeleport = false;
|
||||||
me->clearUnitState(UNIT_STAT_STUNNED);
|
me->clearUnitState(UNIT_STAT_STUNNED);
|
||||||
Unit *nearu = me->SelectNearestTarget(100);
|
if (Unit *nearu = me->SelectNearestTarget(100))
|
||||||
//DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
|
|
||||||
if (nearu)
|
|
||||||
{
|
{
|
||||||
|
//DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
|
||||||
AttackStart(nearu);
|
AttackStart(nearu);
|
||||||
me->getThreatManager().addThreat(nearu, 10000);
|
me->AddThreat(nearu, 10000);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,6 +236,16 @@ struct boss_four_horsemenAI : public BossAI
|
|||||||
nextWP = id + 1;
|
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)
|
void MoveInLineOfSight(Unit *who)
|
||||||
{
|
{
|
||||||
BossAI::MoveInLineOfSight(who);
|
BossAI::MoveInLineOfSight(who);
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ struct boss_alarAI : public ScriptedAI
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Unit *pTarget = NULL;
|
Unit *pTarget = NULL;
|
||||||
pTarget = me->SelectNearestTarget(5);
|
pTarget = me->SelectNearestTargetInAttackDistance(5);
|
||||||
if (pTarget)
|
if (pTarget)
|
||||||
me->AI()->AttackStart(pTarget);
|
me->AI()->AttackStart(pTarget);
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user