From bc43e922a7a42f9bbaa2b4cf5498beeae9b65e00 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sun, 7 Jan 2024 00:43:21 +0800 Subject: [PATCH] Dps target --- src/PlayerbotAI.cpp | 5 ++ src/PlayerbotAI.h | 1 + src/strategy/values/DpsTargetValue.cpp | 65 ++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 09e1be09..9b1afd38 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -1372,6 +1372,11 @@ bool PlayerbotAI::IsRanged(Player* player) return true; } +bool PlayerbotAI::IsCaster(Player* player) +{ + return IsRanged(player) && player->getClass() != CLASS_HUNTER; +} + bool PlayerbotAI::IsRangedDps(Player* player) { return IsRanged(player) && IsDps(player); diff --git a/src/PlayerbotAI.h b/src/PlayerbotAI.h index e268914f..2952f43c 100644 --- a/src/PlayerbotAI.h +++ b/src/PlayerbotAI.h @@ -332,6 +332,7 @@ class PlayerbotAI : public PlayerbotAIBase bool IsHeal(Player* player); bool IsDps(Player* player); bool IsRanged(Player* player); + bool IsCaster(Player* player); bool IsRangedDps(Player* player); bool IsMainTank(Player* player); bool IsAssistTank(Player* player); diff --git a/src/strategy/values/DpsTargetValue.cpp b/src/strategy/values/DpsTargetValue.cpp index 644872c8..50922240 100644 --- a/src/strategy/values/DpsTargetValue.cpp +++ b/src/strategy/values/DpsTargetValue.cpp @@ -59,10 +59,11 @@ class FindMaxThreatGapTargetStrategy : public FindTargetStrategy float minThreat; }; -class FindTargetSmartStrategy : public FindTargetStrategy +// caster +class CasterFindTargetSmartStrategy : public FindTargetStrategy { public: - FindTargetSmartStrategy(PlayerbotAI* botAI, float dps) : FindTargetStrategy(botAI), dps_(dps), targetExpectedLifeTime(1000000) { } + CasterFindTargetSmartStrategy(PlayerbotAI* botAI, float dps) : FindTargetStrategy(botAI), dps_(dps), targetExpectedLifeTime(1000000) { } void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override { @@ -123,6 +124,59 @@ class FindTargetSmartStrategy : public FindTargetStrategy float targetExpectedLifeTime; }; +// non caster +class NonCasterFindTargetSmartStrategy : public FindTargetStrategy +{ + public: + NonCasterFindTargetSmartStrategy(PlayerbotAI* botAI, float dps) : FindTargetStrategy(botAI), dps_(dps), targetExpectedLifeTime(1000000) { } + + void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override + { + if (Group* group = botAI->GetBot()->GetGroup()) + { + ObjectGuid guid = group->GetTargetIcon(4); + if (guid && attacker->GetGUID() == guid) + return; + } + if (!attacker->IsAlive()) { + return; + } + float expectedLifeTime = attacker->GetHealth() / dps_; + // Unit* victim = attacker->GetVictim(); + if (!result || IsBetter(attacker, result)) { + targetExpectedLifeTime = expectedLifeTime; + result = attacker; + } + } + bool IsBetter(Unit* new_unit, Unit* old_unit) { + float new_time = new_unit->GetHealth() / dps_; + float old_time = old_unit->GetHealth() / dps_; + // [5-20] > (5-0] > (20-inf) + if (GetIntervalLevel(new_unit) > GetIntervalLevel(old_unit)) { + return true; + } + // attack enemy in range and with lowest health + int level = GetIntervalLevel(new_unit); + if (level == 0) { + return new_time < old_time; + } + // all targets are far away, choose the closest one + return botAI->GetBot()->GetDistance(new_unit) < botAI->GetBot()->GetDistance(old_unit); + } + int32_t GetIntervalLevel(Unit* unit) { + float time = unit->GetHealth() / dps_; + float dis = unit->GetDistance(botAI->GetBot()); + float attackRange = botAI->IsRanged(botAI->GetBot()) ? sPlayerbotAIConfig->spellDistance : sPlayerbotAIConfig->meleeDistance; + attackRange += 5.0f; + int level = dis < attackRange ? 10 : 0; + return level; + } + + protected: + float dps_; + float targetExpectedLifeTime; +}; + Unit* DpsTargetValue::Calculate() { Unit* rti = RtiTargetValue::Calculate(); @@ -131,8 +185,11 @@ Unit* DpsTargetValue::Calculate() // FindLeastHpTargetStrategy strategy(botAI); float dps = AI_VALUE(float, "expected group dps"); - FindTargetSmartStrategy strategy(botAI, dps); - // FindMaxThreatGapTargetStrategy strategy(botAI); + if (botAI->IsCaster(bot)) { + CasterFindTargetSmartStrategy strategy(botAI, dps); + return TargetValue::FindTarget(&strategy); + } + NonCasterFindTargetSmartStrategy strategy(botAI, dps); return TargetValue::FindTarget(&strategy); }