diff options
-rw-r--r-- | src/game/Creature.cpp | 32 | ||||
-rw-r--r-- | src/game/Creature.h | 2 | ||||
-rw-r--r-- | src/game/CreatureAI.cpp | 9 | ||||
-rw-r--r-- | src/game/CreatureAI.h | 2 | ||||
-rw-r--r-- | src/game/GridNotifiers.h | 28 | ||||
-rw-r--r-- | src/game/Unit.cpp | 2 | ||||
-rw-r--r-- | src/game/UnitAI.cpp | 2 | ||||
-rw-r--r-- | src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp | 7 | ||||
-rw-r--r-- | src/scripts/northrend/naxxramas/boss_four_horsemen.cpp | 10 | ||||
-rw-r--r-- | src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp | 2 |
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 |