mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-17 16:10:49 +01:00
Core/PlayerAI: Some adjustments:
- Add a 2 second delay before the AI begins using spells. This should provide opportunity for counterplay before that rogue activates cloak and goes on an unstoppable rampage among your healers. (Sorry, guys.) - Stopped the AI from attacking invalid targets under some conditions. It should now properly leash back and follow the charmer if we try to select an invalid target. - Stopped the AI from constantly re-creating the follow movement generator (and thus spamming movesplines).
This commit is contained in:
@@ -769,18 +769,30 @@ Unit* PlayerAI::SelectAttackTarget() const
|
||||
return me->GetCharmer() ? me->GetCharmer()->GetVictim() : nullptr;
|
||||
}
|
||||
|
||||
struct UncontrolledTargetSelectPredicate
|
||||
struct ValidTargetSelectPredicate
|
||||
{
|
||||
ValidTargetSelectPredicate(UnitAI const* ai) : _ai(ai) { }
|
||||
UnitAI const* const _ai;
|
||||
bool operator()(Unit const* target) const
|
||||
{
|
||||
return !target->HasBreakableByDamageCrowdControlAura();
|
||||
return _ai->CanAIAttack(target);
|
||||
}
|
||||
};
|
||||
|
||||
bool SimpleCharmedPlayerAI::CanAIAttack(Unit const* who) const
|
||||
{
|
||||
if (!me->IsValidAttackTarget(who) || who->HasBreakableByDamageCrowdControlAura())
|
||||
return false;
|
||||
if (Unit* charmer = me->GetCharmer())
|
||||
if (!charmer->IsValidAttackTarget(who))
|
||||
return false;
|
||||
return UnitAI::CanAIAttack(who);
|
||||
}
|
||||
|
||||
Unit* SimpleCharmedPlayerAI::SelectAttackTarget() const
|
||||
{
|
||||
if (Unit* charmer = me->GetCharmer())
|
||||
return charmer->IsAIEnabled ? charmer->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, UncontrolledTargetSelectPredicate()) : charmer->GetVictim();
|
||||
return charmer->IsAIEnabled ? charmer->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, ValidTargetSelectPredicate(this)) : charmer->GetVictim();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1316,11 +1328,23 @@ void SimpleCharmedPlayerAI::UpdateAI(const uint32 diff)
|
||||
if (charmer->IsEngaged())
|
||||
{
|
||||
Unit* target = me->GetVictim();
|
||||
if (!target || !charmer->IsValidAttackTarget(target) || !me->IsValidAttackTarget(target) || target->HasBreakableByDamageCrowdControlAura())
|
||||
if (!target || !CanAIAttack(target))
|
||||
{
|
||||
target = SelectAttackTarget();
|
||||
if (!target)
|
||||
if (!target || !CanAIAttack(target))
|
||||
{
|
||||
if (!_isFollowing)
|
||||
{
|
||||
_isFollowing = true;
|
||||
me->AttackStop();
|
||||
me->CastStop();
|
||||
me->StopMoving();
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
_isFollowing = false;
|
||||
|
||||
if (IsRangedAttacker())
|
||||
{
|
||||
@@ -1373,8 +1397,9 @@ void SimpleCharmedPlayerAI::UpdateAI(const uint32 diff)
|
||||
|
||||
DoAutoAttackIfReady();
|
||||
}
|
||||
else
|
||||
else if (!_isFollowing)
|
||||
{
|
||||
_isFollowing = true;
|
||||
me->AttackStop();
|
||||
me->CastStop();
|
||||
me->StopMoving();
|
||||
|
||||
@@ -97,11 +97,12 @@ class TC_GAME_API PlayerAI : public UnitAI
|
||||
class TC_GAME_API SimpleCharmedPlayerAI : public PlayerAI
|
||||
{
|
||||
public:
|
||||
SimpleCharmedPlayerAI(Player* player) : PlayerAI(player), _castCheckTimer(500), _chaseCloser(false), _forceFacing(true) { }
|
||||
SimpleCharmedPlayerAI(Player* player) : PlayerAI(player), _castCheckTimer(2500), _chaseCloser(false), _forceFacing(true), _isFollowing(false) { }
|
||||
void UpdateAI(uint32 diff) override;
|
||||
void OnCharmed(bool apply) override;
|
||||
|
||||
protected:
|
||||
bool CanAIAttack(Unit const* who) const override;
|
||||
Unit* SelectAttackTarget() const override;
|
||||
|
||||
private:
|
||||
@@ -109,6 +110,7 @@ class TC_GAME_API SimpleCharmedPlayerAI : public PlayerAI
|
||||
uint32 _castCheckTimer;
|
||||
bool _chaseCloser;
|
||||
bool _forceFacing;
|
||||
bool _isFollowing;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -57,26 +57,6 @@ enum Events
|
||||
class BlackheartCharmedPlayerAI : public SimpleCharmedPlayerAI
|
||||
{
|
||||
using SimpleCharmedPlayerAI::SimpleCharmedPlayerAI;
|
||||
Unit* SelectAttackTarget() const override
|
||||
{
|
||||
if (Unit* charmer = me->GetCharmer())
|
||||
{
|
||||
std::list<Player*> targets;
|
||||
for (ThreatReference const* ref : charmer->GetThreatManager().GetUnsortedThreatList())
|
||||
{
|
||||
if (Player* victim = ref->GetVictim()->ToPlayer())
|
||||
if (me->IsValidAttackTarget(victim))
|
||||
targets.push_back(victim);
|
||||
}
|
||||
if (targets.empty())
|
||||
return nullptr;
|
||||
|
||||
auto it = targets.begin();
|
||||
std::advance(it, urand(0, targets.size() - 1));
|
||||
return *it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void OnCharmed(bool apply) override
|
||||
{
|
||||
SimpleCharmedPlayerAI::OnCharmed(apply);
|
||||
|
||||
Reference in New Issue
Block a user