Merge pull request #245 from liyunfan1223/attack_target

Attack target
This commit is contained in:
Yunfan Li
2024-06-07 00:08:26 +08:00
committed by GitHub
25 changed files with 219 additions and 78 deletions

View File

@@ -3090,6 +3090,10 @@ bool PlayerbotAI::IsInterruptableSpellCasting(Unit* target, std::string const sp
bool PlayerbotAI::HasAuraToDispel(Unit* target, uint32 dispelType)
{
if (!target->IsInWorld())
{
return false;
}
bool isFriend = bot->IsFriendlyTo(target);
for (uint32 type = SPELL_AURA_NONE; type < TOTAL_AURAS; ++type)
{

View File

@@ -178,10 +178,10 @@ void PlayerbotFactory::Randomize(bool incremental)
// {
// return;
// }
LOG_INFO("playerbots", "Preparing to {} randomize...", (incremental ? "incremental" : "full"));
LOG_INFO("playerbots", "{} randomizing {} (level {} class = {})...", (incremental ? "Incremental" : "Full"), bot->GetName().c_str(), bot->GetLevel(), bot->getClass());
// LOG_DEBUG("playerbots", "Preparing to {} randomize...", (incremental ? "incremental" : "full"));
Prepare();
LOG_INFO("playerbots", "Resetting player...");
LOG_DEBUG("playerbots", "Resetting player...");
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Reset");
bot->resetTalents(true);
// bot->SaveToDB(false, false);
@@ -221,14 +221,14 @@ void PlayerbotFactory::Randomize(bool incremental)
}
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells1");
LOG_INFO("playerbots", "Initializing spells (step 1)...");
LOG_DEBUG("playerbots", "Initializing spells (step 1)...");
// bot->LearnDefaultSkills();
InitClassSpells();
InitAvailableSpells();
if (pmo)
pmo->finish();
LOG_INFO("playerbots", "Initializing skills (step 1)...");
LOG_DEBUG("playerbots", "Initializing skills (step 1)...");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills1");
InitSkills();
InitSpecialSpells();
@@ -238,7 +238,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Talents");
LOG_INFO("playerbots", "Initializing talents...");
LOG_DEBUG("playerbots", "Initializing talents...");
if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel) {
InitTalentsTree();
}
@@ -252,13 +252,13 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells2");
LOG_INFO("playerbots", "Initializing spells (step 2)...");
LOG_DEBUG("playerbots", "Initializing spells (step 2)...");
InitAvailableSpells();
if (pmo)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Mounts");
LOG_INFO("playerbots", "Initializing mounts...");
LOG_DEBUG("playerbots", "Initializing mounts...");
InitMounts();
bot->SaveToDB(false, false);
if (pmo)
@@ -271,7 +271,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Equip");
LOG_INFO("playerbots", "Initializing equipmemt...");
LOG_DEBUG("playerbots", "Initializing equipmemt...");
if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel) {
InitEquipment(incremental);
}
@@ -289,38 +289,38 @@ void PlayerbotFactory::Randomize(bool incremental)
// }
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Bags");
LOG_INFO("playerbots", "Initializing bags...");
LOG_DEBUG("playerbots", "Initializing bags...");
InitBags();
// bot->SaveToDB(false, false);
if (pmo)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Ammo");
LOG_INFO("playerbots", "Initializing ammo...");
LOG_DEBUG("playerbots", "Initializing ammo...");
InitAmmo();
if (pmo)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Food");
LOG_INFO("playerbots", "Initializing food...");
LOG_DEBUG("playerbots", "Initializing food...");
InitFood();
if (pmo)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Potions");
LOG_INFO("playerbots", "Initializing potions...");
LOG_DEBUG("playerbots", "Initializing potions...");
InitPotions();
if (pmo)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Reagents");
LOG_INFO("playerbots", "Initializing reagents...");
LOG_DEBUG("playerbots", "Initializing reagents...");
InitReagents();
if (pmo)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_EqSets");
LOG_INFO("playerbots", "Initializing second equipment set...");
LOG_DEBUG("playerbots", "Initializing second equipment set...");
// InitSecondEquipmentSet();
if (pmo)
pmo->finish();
@@ -337,18 +337,18 @@ void PlayerbotFactory::Randomize(bool incremental)
// }
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Inventory");
LOG_INFO("playerbots", "Initializing inventory...");
LOG_DEBUG("playerbots", "Initializing inventory...");
// InitInventory();
if (pmo)
pmo->finish();
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Consumable");
LOG_INFO("playerbots", "Initializing consumables...");
LOG_DEBUG("playerbots", "Initializing consumables...");
AddConsumables();
if (pmo)
pmo->finish();
LOG_INFO("playerbots", "Initializing glyphs...");
LOG_DEBUG("playerbots", "Initializing glyphs...");
bot->SaveToDB(false, false);
InitGlyphs();
@@ -385,12 +385,12 @@ void PlayerbotFactory::Randomize(bool incremental)
}
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Save");
LOG_INFO("playerbots", "Saving to DB...");
LOG_DEBUG("playerbots", "Saving to DB...");
bot->SetMoney(urand(level * 100000, level * 5 * 100000));
bot->SetHealth(bot->GetMaxHealth());
bot->SetPower(POWER_MANA, bot->GetMaxPower(POWER_MANA));
bot->SaveToDB(false, false);
LOG_INFO("playerbots", "Done.");
LOG_INFO("playerbots", "Initialization Done.");
if (pmo)
pmo->finish();
}
@@ -587,7 +587,7 @@ void PlayerbotFactory::InitPetTalents()
// LOG_INFO("playerbots", "{} init pet talents failed with petTalentType < 0({})", bot->GetName().c_str(), pet_family->petTalentType);
return;
}
pet->resetTalents();
// pet->resetTalents();
std::unordered_map<uint32, std::vector<TalentEntry const*> > spells;
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
{

View File

@@ -1196,8 +1196,8 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
z = 0.05f + ground;
LOG_INFO("playerbots", "Random teleporting bot {} to {} {},{},{} ({}/{} locations)",
bot->GetName().c_str(), zone->area_name[0], x, y, z, attemtps, tlocs.size());
LOG_INFO("playerbots", "Random teleporting bot {} (level {}) to {} {},{},{} ({}/{} locations)",
bot->GetName().c_str(), bot->GetLevel(), zone->area_name[0], x, y, z, attemtps, tlocs.size());
if (hearth)
{
@@ -1387,7 +1387,7 @@ void RandomPlayerbotMgr::RandomTeleportForLevel(Player* bot)
uint32 level = bot->getLevel();
uint8 race = bot->getRace();
LOG_INFO("playerbots", "Random teleporting bot {} for level {} ({} locations available)", bot->GetName().c_str(), bot->GetLevel(), locsPerLevelCache[level].size());
LOG_DEBUG("playerbots", "Random teleporting bot {} for level {} ({} locations available)", bot->GetName().c_str(), bot->GetLevel(), locsPerLevelCache[level].size());
if (urand(0, 100) < sPlayerbotAIConfig->probTeleToBankers * 100) {
RandomTeleport(bot, bankerLocsPerLevelCache[level], true);
} else {
@@ -1402,7 +1402,7 @@ void RandomPlayerbotMgr::RandomTeleportGrindForLevel(Player* bot)
uint32 level = bot->getLevel();
uint8 race = bot->getRace();
LOG_INFO("playerbots", "Random teleporting bot {} for level {} ({} locations available)", bot->GetName().c_str(), bot->GetLevel(), locsPerLevelCache[level].size());
LOG_DEBUG("playerbots", "Random teleporting bot {} for level {} ({} locations available)", bot->GetName().c_str(), bot->GetLevel(), locsPerLevelCache[level].size());
RandomTeleport(bot, locsPerLevelCache[level]);
}
@@ -1642,7 +1642,7 @@ void RandomPlayerbotMgr::Refresh(Player* bot)
if (bot->InBattleground())
return;
LOG_INFO("playerbots", "Refreshing bot {} <{}>", bot->GetGUID().ToString().c_str(), bot->GetName().c_str());
LOG_DEBUG("playerbots", "Refreshing bot {} <{}>", bot->GetGUID().ToString().c_str(), bot->GetName().c_str());
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "Refresh");
@@ -2482,7 +2482,7 @@ void RandomPlayerbotMgr::RandomTeleportForRpg(Player* bot)
{
uint32 race = bot->getRace();
uint32 level = bot->GetLevel();
LOG_INFO("playerbots", "Random teleporting bot {} for RPG ({} locations available)", bot->GetName().c_str(), rpgLocsCacheLevel[race].size());
LOG_DEBUG("playerbots", "Random teleporting bot {} for RPG ({} locations available)", bot->GetName().c_str(), rpgLocsCacheLevel[race].size());
RandomTeleport(bot, rpgLocsCacheLevel[race][level], true);
}

View File

@@ -72,6 +72,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
creators["potions"] = &StrategyContext::potions;
creators["cast time"] = &StrategyContext::cast_time;
creators["threat"] = &StrategyContext::threat;
creators["focus"] = &StrategyContext::focus;
creators["tell target"] = &StrategyContext::tell_target;
creators["pvp"] = &StrategyContext::pvp;
creators["return"] = &StrategyContext::_return;
@@ -120,6 +121,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
static Strategy* mark_rti(PlayerbotAI* botAI) { return new MarkRtiStrategy(botAI); }
static Strategy* tell_target(PlayerbotAI* botAI) { return new TellTargetStrategy(botAI); }
static Strategy* threat(PlayerbotAI* botAI) { return new ThreatStrategy(botAI); }
static Strategy* focus(PlayerbotAI* botAI) { return new FocusStrategy(botAI); }
static Strategy* cast_time(PlayerbotAI* botAI) { return new CastTimeStrategy(botAI); }
static Strategy* potions(PlayerbotAI* botAI) { return new UsePotionsStrategy(botAI); }
static Strategy* kite(PlayerbotAI* botAI) { return new KiteStrategy(botAI); }

View File

@@ -136,4 +136,12 @@ Unit* UnitCalculatedValue::Get()
if (value && value->IsInWorld())
return value;
return nullptr;
}
Unit* UnitManualSetValue::Get()
{
// Prevent crashing by InWorld check
if (value && value->IsInWorld())
return value;
return nullptr;
}

View File

@@ -323,6 +323,7 @@ class UnitManualSetValue : public ManualSetValue<Unit*>
ManualSetValue<Unit*>(botAI, defaultValue, name) { }
std::string const Format() override;
Unit* Get() override;
};
#endif

View File

@@ -36,7 +36,8 @@ bool AttackMyTargetAction::Execute(Event event)
return false;
}
botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Set({guid});
bool result = Attack(botAI->GetUnit(guid));
if (result)
context->GetValue<ObjectGuid>("pull target")->Set(guid);
@@ -62,6 +63,10 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/)
return false;
}
if (!target->IsInWorld())
{
return false;
}
std::ostringstream msg;
msg << target->GetName();

View File

@@ -23,10 +23,10 @@ bool ChangeTalentsAction::Execute(Event event)
if (param.find("help") != std::string::npos) {
out << TalentsHelp();
} else if (param.find("switch") != std::string::npos) {
if (param == "1") {
if (param.find("switch 1")) {
bot->ActivateSpec(0);
out << "Active first talent";
} else if (param == "2") {
} else if (param.find("switch 2")) {
bot->ActivateSpec(1);
out << "Active second talent";
}

View File

@@ -829,7 +829,7 @@ bool MovementAction::Follow(Unit* target, float distance)
void MovementAction::UpdateMovementState()
{
if (bot->Unit::IsInWater() || bot->Unit::IsUnderWater())
if (bot->Unit::IsUnderWater())
{
bot->SetSwim(true);
}

View File

@@ -300,7 +300,7 @@ bool SpiritHealerAction::Execute(Event event)
Unit* unit = botAI->GetUnit(*i);
if (unit && unit->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER))
{
LOG_INFO("playerbots", "Bot {} {}:{} <{}> revives at spirit healer",
LOG_DEBUG("playerbots", "Bot {} {}:{} <{}> revives at spirit healer",
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName());
PlayerbotChatHandler ch(bot);
bot->ResurrectPlayer(0.5f);

View File

@@ -234,6 +234,8 @@ class CastDeathAndDecayAction : public CastSpellAction
{
public:
CastDeathAndDecayAction(PlayerbotAI* botAI) : CastSpellAction(botAI, "death and decay") { }
ActionThreatType getThreatType() override { return ActionThreatType::Aoe; }
};
class CastHornOfWinterAction : public CastSpellAction

View File

@@ -4,6 +4,7 @@
#include "ThreatStrategy.h"
#include "GenericSpellActions.h"
#include "Map.h"
#include "Playerbots.h"
float ThreatMultiplier::GetValue(Action* action)
@@ -36,3 +37,22 @@ void ThreatStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
{
multipliers.push_back(new ThreatMultiplier(botAI));
}
float FocusMultiplier::GetValue(Action* action)
{
if (!action) {
return 1.0f;
}
if (action->getThreatType() == Action::ActionThreatType::Aoe && !dynamic_cast<CastHealingSpellAction*>(action)) {
return 0.0f;
}
if (dynamic_cast<CastDebuffSpellOnAttackerAction*>(action)) {
return 0.0f;
}
return 1.0f;
}
void FocusStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
{
multipliers.push_back(new FocusMultiplier(botAI));
}

View File

@@ -26,4 +26,21 @@ class ThreatStrategy : public Strategy
std::string const getName() override { return "threat"; }
};
class FocusMultiplier : public Multiplier
{
public:
FocusMultiplier(PlayerbotAI* botAI) : Multiplier(botAI, "focus") { }
float GetValue(Action* action) override;
};
class FocusStrategy : public Strategy
{
public:
FocusStrategy(PlayerbotAI* botAI) : Strategy(botAI) { }
void InitMultipliers(std::vector<Multiplier*>& multipliers) override;
std::string const getName() override { return "focus"; }
};
#endif

View File

@@ -19,6 +19,18 @@
#include "WarriorActions.h"
#include "DruidBearActions.h"
float GrobbulusMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "grobbulus");
if (!boss) {
return 1.0f;
}
if (dynamic_cast<AvoidAoeAction*>(action)) {
return 0.0f;
}
return 1.0f;
}
float HeiganDanceMultiplier::GetValue(Action* action)
{
Unit* boss = AI_VALUE2(Unit*, "find target", "heigan the unclean");

View File

@@ -5,22 +5,30 @@
#include "Multiplier.h"
#include "raids/naxxramas/RaidNaxxBossHelper.h"
class GrobbulusMultiplier : public Multiplier
{
public:
GrobbulusMultiplier(PlayerbotAI* ai) : Multiplier(ai, "grobbulus") {}
public:
virtual float GetValue(Action* action);
};
class HeiganDanceMultiplier : public Multiplier
{
public:
HeiganDanceMultiplier(PlayerbotAI* ai) : Multiplier(ai, "helgan dance") {}
public:
HeiganDanceMultiplier(PlayerbotAI* ai) : Multiplier(ai, "helgan dance") {}
public:
virtual float GetValue(Action* action);
public:
virtual float GetValue(Action* action);
};
class LoathebGenericMultiplier : public Multiplier
{
public:
LoathebGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "loatheb generic") {}
public:
LoathebGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "loatheb generic") {}
public:
virtual float GetValue(Action* action);
public:
virtual float GetValue(Action* action);
};
class ThaddiusGenericMultiplier : public Multiplier

View File

@@ -112,6 +112,7 @@ void RaidNaxxStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
void RaidNaxxStrategy::InitMultipliers(std::vector<Multiplier*> &multipliers)
{
multipliers.push_back(new GrobbulusMultiplier(botAI));
multipliers.push_back(new HeiganDanceMultiplier(botAI));
multipliers.push_back(new LoathebGenericMultiplier(botAI));
multipliers.push_back(new ThaddiusGenericMultiplier(botAI));

View File

@@ -469,14 +469,16 @@ bool PossibleAddsTrigger::IsActive()
bool NotDpsTargetActiveTrigger::IsActive()
{
Unit* dps = AI_VALUE(Unit*, "dps target");
Unit* target = AI_VALUE(Unit*, "current target");
Unit* enemy = AI_VALUE(Unit*, "enemy player target");
// do not switch if enemy target
if (target && target == enemy && target->IsAlive())
return false;
if (target && target->IsAlive()) {
Unit* enemy = AI_VALUE(Unit*, "enemy player target");
if (target == enemy)
return false;
}
Unit* dps = AI_VALUE(Unit*, "dps target");
return dps && target != dps;
}

View File

@@ -29,7 +29,10 @@ uint8 AoeHealValue::Calculate()
Player* player = ObjectAccessor::FindPlayer(itr->guid);
if (!player || !player->IsAlive())
continue;
if (player->GetDistance(bot) >= sPlayerbotAIConfig->sightDistance)
continue;
float percent = (static_cast<float> (player->GetHealth()) / player->GetMaxHealth()) * 100;
if (percent <= range)
++count;

View File

@@ -23,14 +23,31 @@ GuidVector AttackersValue::Calculate()
if (Group* group = bot->GetGroup())
AddAttackersOf(group, targets);
RemoveNonThreating(targets);
// prioritized target
GuidVector prioritizedTargets = AI_VALUE(GuidVector, "prioritized targets");
for (ObjectGuid target : prioritizedTargets) {
Unit* unit = botAI->GetUnit(target);
if (unit && IsValidTarget(unit, bot)) {
targets.insert(unit);
}
}
if (Group* group = bot->GetGroup()) {
ObjectGuid skullGuid = group->GetTargetIcon(4);
Unit* skullTarget = botAI->GetUnit(skullGuid);
if (skullTarget && IsValidTarget(skullTarget, bot)) {
targets.insert(skullTarget);
}
}
for (Unit* unit : targets)
result.push_back(unit->GetGUID());
if (bot->duel && bot->duel->Opponent)
result.push_back(bot->duel->Opponent->GetGUID());
return result;
}
@@ -114,7 +131,7 @@ bool AttackersValue::hasRealThreat(Unit *attacker)
attacker->IsAlive() &&
!attacker->IsPolymorphed() &&
// !attacker->isInRoots() &&
!attacker->IsFriendlyTo(bot) &&
!attacker->IsFriendlyTo(bot);
(attacker->GetThreatMgr().getCurrentVictim() || dynamic_cast<Player*>(attacker));
}

View File

@@ -37,4 +37,10 @@ class PossibleAddsValue : public BoolCalculatedValue
bool Calculate() override;
};
class PrioritizedTargetsValue : public ManualSetValue<GuidVector>
{
public:
PrioritizedTargetsValue(PlayerbotAI* botAI, std::string const name = "prioritized targets"): ManualSetValue(botAI, GuidVector(), name) {}
};
#endif

View File

@@ -13,15 +13,17 @@ class FindLeastHpTargetStrategy : public FindTargetStrategy
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;
}
if (foundHighPriority) {
return;
}
if (IsHighPriority(attacker)) {
result = attacker;
foundHighPriority = true;
return;
}
if (!result || result->GetHealth() > attacker->GetHealth())
result = attacker;
}
@@ -37,15 +39,17 @@ class FindMaxThreatGapTargetStrategy : public FindTargetStrategy
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;
}
if (foundHighPriority) {
return;
}
if (IsHighPriority(attacker)) {
result = attacker;
foundHighPriority = true;
return;
}
Unit* victim = attacker->GetVictim();
if (!result || CalcThreatGap(attacker, threatMgr) > CalcThreatGap(result, &result->GetThreatMgr()))
result = attacker;
@@ -67,15 +71,17 @@ class CasterFindTargetSmartStrategy : public FindTargetStrategy
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;
}
if (foundHighPriority) {
return;
}
if (IsHighPriority(attacker)) {
result = attacker;
foundHighPriority = true;
return;
}
float expectedLifeTime = attacker->GetHealth() / dps_;
// Unit* victim = attacker->GetVictim();
if (!result || IsBetter(attacker, result)) {
@@ -132,15 +138,17 @@ class NonCasterFindTargetSmartStrategy : public FindTargetStrategy
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;
}
if (foundHighPriority) {
return;
}
if (IsHighPriority(attacker)) {
result = attacker;
foundHighPriority = true;
return;
}
float expectedLifeTime = attacker->GetHealth() / dps_;
// Unit* victim = attacker->GetVictim();
if (!result || IsBetter(attacker, result)) {
@@ -185,15 +193,17 @@ class ComboFindTargetSmartStrategy : public FindTargetStrategy
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;
}
if (foundHighPriority) {
return;
}
if (IsHighPriority(attacker)) {
result = attacker;
foundHighPriority = true;
return;
}
float expectedLifeTime = attacker->GetHealth() / dps_;
// Unit* victim = attacker->GetVictim();
if (!result || IsBetter(attacker, result)) {

View File

@@ -27,6 +27,7 @@ bool InvalidTargetValue::Calculate()
target->isFeared() ||
target->HasUnitState(UNIT_STATE_ISOLATED) ||
target->IsFriendlyTo(bot) ||
!AttackersValue::IsValidTarget(target, bot) ||
// !bot->IsWithinDistInMap(target, sPlayerbotAIConfig->sightDistance) ||
!bot->IsWithinLOSInMap(target);
}

View File

@@ -100,6 +100,24 @@ void FindTargetStrategy::GetPlayerCount(Unit* creature, uint32* tankCount, uint3
dpsCountCache[creature] = *dpsCount;
}
bool FindTargetStrategy::IsHighPriority(Unit* attacker)
{
if (Group* group = botAI->GetBot()->GetGroup())
{
ObjectGuid guid = group->GetTargetIcon(4);
if (guid && attacker->GetGUID() == guid) {
return true;
}
}
GuidVector prioritizedTargets = botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Get();
for (ObjectGuid targetGuid : prioritizedTargets) {
if (targetGuid && attacker->GetGUID() == targetGuid) {
return true;
}
}
return false;
}
WorldPosition LastLongMoveValue::Calculate()
{
LastMovement& lastMove = *context->GetValue<LastMovement&>("last movement");

View File

@@ -21,12 +21,14 @@ class FindTargetStrategy
Unit* GetResult();
virtual void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) = 0;
void GetPlayerCount(Unit* creature, uint32* tankCount, uint32* dpsCount);
bool IsHighPriority(Unit* attacker);
protected:
Unit* result;
PlayerbotAI* botAI;
std::map<Unit*, uint32> tankCountCache;
std::map<Unit*, uint32> dpsCountCache;
bool foundHighPriority = false;
};
class FindNonCcTargetStrategy : public FindTargetStrategy

View File

@@ -112,6 +112,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
creators["possible targets no los"] = &ValueContext::possible_targets_no_los;
creators["possible triggers"] = &ValueContext::possible_triggers;
creators["possible adds"] = &ValueContext::possible_adds;
creators["prioritized targets"] = &ValueContext::prioritized_targets;
creators["all targets"] = &ValueContext::all_targets;
creators["possible rpg targets"] = &ValueContext::possible_rpg_targets;
creators["nearest adds"] = &ValueContext::nearest_adds;
@@ -382,6 +383,7 @@ class ValueContext : public NamedObjectContext<UntypedValue>
static UntypedValue* possible_triggers(PlayerbotAI* botAI) { return new PossibleTriggersValue(botAI); }
static UntypedValue* possible_targets_no_los(PlayerbotAI* botAI) { return new PossibleTargetsValue(botAI, "possible targets", sPlayerbotAIConfig->sightDistance, true); }
static UntypedValue* possible_adds(PlayerbotAI* botAI) { return new PossibleAddsValue(botAI); }
static UntypedValue* prioritized_targets(PlayerbotAI* botAI) { return new PrioritizedTargetsValue(botAI); }
static UntypedValue* all_targets(PlayerbotAI* botAI) { return new AllTargetsValue(botAI); }
static UntypedValue* nearest_adds(PlayerbotAI* botAI) { return new NearestAddsValue(botAI); }
static UntypedValue* party_member_without_aura(PlayerbotAI* botAI) { return new PartyMemberWithoutAuraValue(botAI); }