mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -323,6 +323,7 @@ class UnitManualSetValue : public ManualSetValue<Unit*>
|
||||
ManualSetValue<Unit*>(botAI, defaultValue, name) { }
|
||||
|
||||
std::string const Format() override;
|
||||
Unit* Get() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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); }
|
||||
|
||||
Reference in New Issue
Block a user