mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
@@ -97,6 +97,10 @@ AiPlayerbot.SummonWhenGroup = 1
|
|||||||
AiPlayerbot.RandomBotShowHelmet = 1
|
AiPlayerbot.RandomBotShowHelmet = 1
|
||||||
AiPlayerbot.RandomBotShowCloak = 1
|
AiPlayerbot.RandomBotShowCloak = 1
|
||||||
|
|
||||||
|
# Fix the level of random bot (won't level up by grinding)
|
||||||
|
# Default: 0 (disable)
|
||||||
|
AiPlayerbot.RandomBotFixedLevel = 0
|
||||||
|
|
||||||
# Disable random levels for randombots
|
# Disable random levels for randombots
|
||||||
# Every bots started on the specified level and level up by killing mobs.
|
# Every bots started on the specified level and level up by killing mobs.
|
||||||
AiPlayerbot.DisableRandomLevels = 0
|
AiPlayerbot.DisableRandomLevels = 0
|
||||||
@@ -125,7 +129,7 @@ AiPlayerbot.MinEnchantingBotLevel = 60
|
|||||||
AiPlayerbot.LimitEnchantExpansion = 1
|
AiPlayerbot.LimitEnchantExpansion = 1
|
||||||
|
|
||||||
# Randombots checking players gear score level and deny the group invite if it's too low
|
# Randombots checking players gear score level and deny the group invite if it's too low
|
||||||
# Default: 1 (enabled)
|
# Default: 0 (disabled)
|
||||||
AiPlayerbot.GearScoreCheck = 0
|
AiPlayerbot.GearScoreCheck = 0
|
||||||
|
|
||||||
# Quest that will be completed and rewarded to all random bots
|
# Quest that will be completed and rewarded to all random bots
|
||||||
@@ -338,8 +342,8 @@ AiPlayerbot.AutoSaveMana = 1
|
|||||||
AiPlayerbot.SaveManaThreshold = 60
|
AiPlayerbot.SaveManaThreshold = 60
|
||||||
|
|
||||||
# Enable auto avoid aoe (experimental)
|
# Enable auto avoid aoe (experimental)
|
||||||
# Default: 0 (disable)
|
# Default: 1 (enable)
|
||||||
AiPlayerbot.AutoAvoidAoe = 0
|
AiPlayerbot.AutoAvoidAoe = 1
|
||||||
|
|
||||||
# Tell which spell is avoiding (experimental)
|
# Tell which spell is avoiding (experimental)
|
||||||
# Default: 1 (enable)
|
# Default: 1 (enable)
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
mediumMana = sConfigMgr->GetOption<int32>("AiPlayerbot.MediumMana", 40);
|
mediumMana = sConfigMgr->GetOption<int32>("AiPlayerbot.MediumMana", 40);
|
||||||
autoSaveMana = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoSaveMana", true);
|
autoSaveMana = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoSaveMana", true);
|
||||||
saveManaThreshold = sConfigMgr->GetOption<int32>("AiPlayerbot.SaveManaThreshold", 60);
|
saveManaThreshold = sConfigMgr->GetOption<int32>("AiPlayerbot.SaveManaThreshold", 60);
|
||||||
autoAvoidAoe = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoAvoidAoe", false);
|
autoAvoidAoe = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoAvoidAoe", true);
|
||||||
tellWhenAvoidAoe = sConfigMgr->GetOption<bool>("AiPlayerbot.TellWhenAvoidAoe", true);
|
tellWhenAvoidAoe = sConfigMgr->GetOption<bool>("AiPlayerbot.TellWhenAvoidAoe", true);
|
||||||
|
|
||||||
randomGearLoweringChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomGearLoweringChance", 0.15f);
|
randomGearLoweringChance = sConfigMgr->GetOption<float>("AiPlayerbot.RandomGearLoweringChance", 0.15f);
|
||||||
@@ -265,6 +265,7 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
// SPP switches
|
// SPP switches
|
||||||
enableGreet = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableGreet", true);
|
enableGreet = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableGreet", true);
|
||||||
summonWhenGroup = sConfigMgr->GetOption<bool>("AiPlayerbot.SummonWhenGroup", true);
|
summonWhenGroup = sConfigMgr->GetOption<bool>("AiPlayerbot.SummonWhenGroup", true);
|
||||||
|
randomBotFixedLevel = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotFixedLevel", false);
|
||||||
disableRandomLevels = sConfigMgr->GetOption<bool>("AiPlayerbot.DisableRandomLevels", false);
|
disableRandomLevels = sConfigMgr->GetOption<bool>("AiPlayerbot.DisableRandomLevels", false);
|
||||||
randomBotRandomPassword = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotRandomPassword", true);
|
randomBotRandomPassword = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotRandomPassword", true);
|
||||||
downgradeMaxLevelBot = sConfigMgr->GetOption<bool>("AiPlayerbot.DowngradeMaxLevelBot", true);
|
downgradeMaxLevelBot = sConfigMgr->GetOption<bool>("AiPlayerbot.DowngradeMaxLevelBot", true);
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ class PlayerbotAIConfig
|
|||||||
bool summonWhenGroup;
|
bool summonWhenGroup;
|
||||||
bool randomBotShowHelmet;
|
bool randomBotShowHelmet;
|
||||||
bool randomBotShowCloak;
|
bool randomBotShowCloak;
|
||||||
|
bool randomBotFixedLevel;
|
||||||
bool disableRandomLevels;
|
bool disableRandomLevels;
|
||||||
uint32 playerbotsXPrate;
|
uint32 playerbotsXPrate;
|
||||||
bool disableDeathKnightLogin;
|
bool disableDeathKnightLogin;
|
||||||
|
|||||||
@@ -2502,8 +2502,7 @@ void PlayerbotFactory::InitAmmo()
|
|||||||
case ITEM_SUBCLASS_WEAPON_CROSSBOW:
|
case ITEM_SUBCLASS_WEAPON_CROSSBOW:
|
||||||
subClass = ITEM_SUBCLASS_ARROW;
|
subClass = ITEM_SUBCLASS_ARROW;
|
||||||
break;
|
break;
|
||||||
case ITEM_SUBCLASS_WEAPON_THROWN:
|
default:
|
||||||
subClass = ITEM_SUBCLASS_THROWN;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2512,7 +2511,7 @@ void PlayerbotFactory::InitAmmo()
|
|||||||
|
|
||||||
uint32 entry = sRandomItemMgr->GetAmmo(level, subClass);
|
uint32 entry = sRandomItemMgr->GetAmmo(level, subClass);
|
||||||
uint32 count = bot->GetItemCount(entry);
|
uint32 count = bot->GetItemCount(entry);
|
||||||
uint32 maxCount = 5000;
|
uint32 maxCount = 6000;
|
||||||
|
|
||||||
if (count < maxCount / 2)
|
if (count < maxCount / 2)
|
||||||
{
|
{
|
||||||
@@ -3879,10 +3878,9 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
|
|||||||
score *= 0.1;
|
score *= 0.1;
|
||||||
}
|
}
|
||||||
// spec with double hand
|
// spec with double hand
|
||||||
// fury with titan's grip, fury without duel wield, arms, bear, retribution, blood dk
|
// fury without duel wield, arms, bear, retribution, blood dk
|
||||||
if (isDoubleHand &&
|
if (isDoubleHand &&
|
||||||
((cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && bot->CanTitanGrip()) ||
|
((cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && !bot->CanDualWield()) ||
|
||||||
(cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && !bot->CanDualWield()) ||
|
|
||||||
(cls == CLASS_WARRIOR && tab == WARRIOR_TAB_ARMS) ||
|
(cls == CLASS_WARRIOR && tab == WARRIOR_TAB_ARMS) ||
|
||||||
(cls == CLASS_DRUID && tab == 1) ||
|
(cls == CLASS_DRUID && tab == 1) ||
|
||||||
(cls == CLASS_PALADIN && tab == 2) ||
|
(cls == CLASS_PALADIN && tab == 2) ||
|
||||||
@@ -3890,6 +3888,11 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
|
|||||||
(cls == CLASS_SHAMAN && tab == 1 && !bot->CanDualWield()))) {
|
(cls == CLASS_SHAMAN && tab == 1 && !bot->CanDualWield()))) {
|
||||||
score *= 10;
|
score *= 10;
|
||||||
}
|
}
|
||||||
|
// fury with titan's grip
|
||||||
|
if (isDoubleHand && proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM &&
|
||||||
|
(cls == CLASS_WARRIOR && tab == WARRIOR_TAB_FURY && bot->CanTitanGrip())) {
|
||||||
|
score *= 10;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (proto->Class == ITEM_CLASS_WEAPON) {
|
if (proto->Class == ITEM_CLASS_WEAPON) {
|
||||||
if (cls == CLASS_HUNTER && proto->SubClass == ITEM_SUBCLASS_WEAPON_THROWN) {
|
if (cls == CLASS_HUNTER && proto->SubClass == ITEM_SUBCLASS_WEAPON_THROWN) {
|
||||||
|
|||||||
@@ -448,6 +448,12 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
|||||||
uint32 accountId = bot->GetSession()->GetAccountId();
|
uint32 accountId = bot->GetSession()->GetAccountId();
|
||||||
bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(accountId);
|
bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(accountId);
|
||||||
|
|
||||||
|
if (isRandomAccount && sPlayerbotAIConfig->randomBotFixedLevel) {
|
||||||
|
bot->SetPlayerFlag(PLAYER_FLAGS_NO_XP_GAIN);
|
||||||
|
} else if (isRandomAccount && !sPlayerbotAIConfig->randomBotFixedLevel) {
|
||||||
|
bot->RemovePlayerFlag(PLAYER_FLAGS_NO_XP_GAIN);
|
||||||
|
}
|
||||||
|
|
||||||
bot->SaveToDB(false, false);
|
bot->SaveToDB(false, false);
|
||||||
if (master && isRandomAccount && master->GetLevel() < bot->GetLevel()) {
|
if (master && isRandomAccount && master->GetLevel() < bot->GetLevel()) {
|
||||||
// PlayerbotFactory factory(bot, master->getLevel());
|
// PlayerbotFactory factory(bot, master->getLevel());
|
||||||
|
|||||||
@@ -2159,6 +2159,9 @@ void RandomItemMgr::BuildEquipCacheNew()
|
|||||||
if (IsTestItem(itemId)) {
|
if (IsTestItem(itemId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (itemId == 22784) { // Sunwell Orb
|
||||||
|
continue;
|
||||||
|
}
|
||||||
equipCacheNew[proto->RequiredLevel][proto->InventoryType].push_back(itemId);
|
equipCacheNew[proto->RequiredLevel][proto->InventoryType].push_back(itemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2199,9 +2202,7 @@ RandomItemList RandomItemMgr::Query(uint32 level, uint8 clazz, uint8 slot, uint3
|
|||||||
|
|
||||||
void RandomItemMgr::BuildAmmoCache()
|
void RandomItemMgr::BuildAmmoCache()
|
||||||
{
|
{
|
||||||
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
|
uint32 maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
||||||
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
|
||||||
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
|
||||||
|
|
||||||
LOG_INFO("server.loading", "Building ammo cache for {} levels", maxLevel);
|
LOG_INFO("server.loading", "Building ammo cache for {} levels", maxLevel);
|
||||||
|
|
||||||
@@ -2238,9 +2239,9 @@ uint32 RandomItemMgr::GetAmmo(uint32 level, uint32 subClass)
|
|||||||
|
|
||||||
void RandomItemMgr::BuildPotionCache()
|
void RandomItemMgr::BuildPotionCache()
|
||||||
{
|
{
|
||||||
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
|
uint32 maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
||||||
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
// if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||||
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
// maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
||||||
|
|
||||||
LOG_INFO("server.loading", "Building potion cache for {} levels", maxLevel);
|
LOG_INFO("server.loading", "Building potion cache for {} levels", maxLevel);
|
||||||
|
|
||||||
|
|||||||
@@ -1191,6 +1191,10 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
|||||||
if (!zone)
|
if (!zone)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
AreaTableEntry const* area = sAreaTableStore.LookupEntry(map->GetAreaId(bot->GetPhaseMask(), x, y, z));
|
||||||
|
if (!area)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Do not teleport to enemy zones if level is low
|
// Do not teleport to enemy zones if level is low
|
||||||
if (zone->team == 4 && bot->GetTeamId() == TEAM_ALLIANCE)
|
if (zone->team == 4 && bot->GetTeamId() == TEAM_ALLIANCE)
|
||||||
continue;
|
continue;
|
||||||
@@ -1218,9 +1222,14 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
|||||||
if (bot->GetLevel() <= 18 && (loc.GetMapId() != pInfo->mapId || dis > 10000.0f)) {
|
if (bot->GetLevel() <= 18 && (loc.GetMapId() != pInfo->mapId || dis > 10000.0f)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
LocaleConstant locale = sWorld->GetDefaultDbcLocale();
|
||||||
|
|
||||||
LOG_INFO("playerbots", "Random teleporting bot {} (level {}) to {} {},{},{} ({}/{} locations)",
|
LOG_INFO("playerbots", "Random teleporting bot {} (level {}) to Map: {} ({}) Zone: {} ({}) Area: {} ({}) {},{},{} ({}/{} locations)",
|
||||||
bot->GetName().c_str(), bot->GetLevel(), zone->area_name[0], x, y, z, i + 1, tlocs.size());
|
bot->GetName().c_str(), bot->GetLevel(),
|
||||||
|
map->GetId(), map->GetMapName(),
|
||||||
|
zone->ID, zone->area_name[locale],
|
||||||
|
area->ID, area->area_name[locale],
|
||||||
|
x, y, z, i + 1, tlocs.size());
|
||||||
|
|
||||||
if (hearth)
|
if (hearth)
|
||||||
{
|
{
|
||||||
@@ -1248,9 +1257,7 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
|||||||
|
|
||||||
void RandomPlayerbotMgr::PrepareTeleportCache()
|
void RandomPlayerbotMgr::PrepareTeleportCache()
|
||||||
{
|
{
|
||||||
uint8 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
|
uint32 maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
||||||
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
|
||||||
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
|
||||||
|
|
||||||
LOG_INFO("playerbots", "Preparing random teleport caches for {} levels...", maxLevel);
|
LOG_INFO("playerbots", "Preparing random teleport caches for {} levels...", maxLevel);
|
||||||
|
|
||||||
|
|||||||
@@ -1495,6 +1495,8 @@ void TravelTarget::setStatus(TravelStatus status)
|
|||||||
break;
|
break;
|
||||||
case TRAVEL_STATUS_COOLDOWN:
|
case TRAVEL_STATUS_COOLDOWN:
|
||||||
statusTime = tDestination->getCooldownDelay();
|
statusTime = tDestination->getCooldownDelay();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3687,7 +3689,7 @@ void TravelMgr::LoadQuestTravelTable()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
"all";
|
out << "all";
|
||||||
|
|
||||||
out << "\n";
|
out << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
|
|||||||
ActionBasket* basket = nullptr;
|
ActionBasket* basket = nullptr;
|
||||||
|
|
||||||
time_t currentTime = time(nullptr);
|
time_t currentTime = time(nullptr);
|
||||||
aiObjectContext->Update();
|
// aiObjectContext->Update();
|
||||||
ProcessTriggers(minimal);
|
ProcessTriggers(minimal);
|
||||||
PushDefaultActions();
|
PushDefaultActions();
|
||||||
|
|
||||||
@@ -469,7 +469,7 @@ bool Engine::HasStrategy(std::string const name)
|
|||||||
|
|
||||||
void Engine::ProcessTriggers(bool minimal)
|
void Engine::ProcessTriggers(bool minimal)
|
||||||
{
|
{
|
||||||
std::unordered_map<Trigger*, Event> fires;
|
// std::unordered_map<Trigger*, Event> fires;
|
||||||
for (std::vector<TriggerNode*>::iterator i = triggers.begin(); i != triggers.end(); i++)
|
for (std::vector<TriggerNode*>::iterator i = triggers.begin(); i != triggers.end(); i++)
|
||||||
{
|
{
|
||||||
TriggerNode* node = *i;
|
TriggerNode* node = *i;
|
||||||
@@ -499,21 +499,22 @@ void Engine::ProcessTriggers(bool minimal)
|
|||||||
if (!event)
|
if (!event)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fires[trigger] = event;
|
// fires[trigger] = event;
|
||||||
LogAction("T:%s", trigger->getName().c_str());
|
LogAction("T:%s", trigger->getName().c_str());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::vector<TriggerNode*>::iterator i = triggers.begin(); i != triggers.end(); i++)
|
|
||||||
{
|
|
||||||
TriggerNode* node = *i;
|
|
||||||
Trigger* trigger = node->getTrigger();
|
|
||||||
Event event = fires[trigger];
|
|
||||||
if (!event)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MultiplyAndPush(node->getHandlers(), 0.0f, false, event, "trigger");
|
MultiplyAndPush(node->getHandlers(), 0.0f, false, event, "trigger");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (std::vector<TriggerNode*>::iterator i = triggers.begin(); i != triggers.end(); i++)
|
||||||
|
// {
|
||||||
|
// TriggerNode* node = *i;
|
||||||
|
// Trigger* trigger = node->getTrigger();
|
||||||
|
// if (fires.find(trigger) == fires.end())
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// Event event = fires[trigger];
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
for (std::vector<TriggerNode*>::iterator i = triggers.begin(); i != triggers.end(); i++)
|
for (std::vector<TriggerNode*>::iterator i = triggers.begin(); i != triggers.end(); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,10 +23,15 @@ bool ChangeTalentsAction::Execute(Event event)
|
|||||||
if (param.find("help") != std::string::npos) {
|
if (param.find("help") != std::string::npos) {
|
||||||
out << TalentsHelp();
|
out << TalentsHelp();
|
||||||
} else if (param.find("switch") != std::string::npos) {
|
} else if (param.find("switch") != std::string::npos) {
|
||||||
if (param.find("switch 1")) {
|
if (param.find("switch 1") != std::string::npos) {
|
||||||
bot->ActivateSpec(0);
|
bot->ActivateSpec(0);
|
||||||
out << "Active first talent";
|
out << "Active first talent";
|
||||||
} else if (param.find("switch 2")) {
|
} else if (param.find("switch 2") != std::string::npos) {
|
||||||
|
if (bot->GetSpecsCount() == 1 && bot->GetLevel() >= sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL))
|
||||||
|
{
|
||||||
|
bot->CastSpell(bot, 63680, true, nullptr, nullptr, bot->GetGUID());
|
||||||
|
bot->CastSpell(bot, 63624, true, nullptr, nullptr, bot->GetGUID());
|
||||||
|
}
|
||||||
bot->ActivateSpec(1);
|
bot->ActivateSpec(1);
|
||||||
out << "Active second talent";
|
out << "Active second talent";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ class ChatActionContext : public NamedObjectContext<Action>
|
|||||||
creators["de"] = &ChatActionContext::dead;
|
creators["de"] = &ChatActionContext::dead;
|
||||||
creators["trainer"] = &ChatActionContext::trainer;
|
creators["trainer"] = &ChatActionContext::trainer;
|
||||||
creators["maintenance"] = &ChatActionContext::maintenance;
|
creators["maintenance"] = &ChatActionContext::maintenance;
|
||||||
|
creators["remove glyph"] = &ChatActionContext::remove_glyph;
|
||||||
creators["autogear"] = &ChatActionContext::autogear;
|
creators["autogear"] = &ChatActionContext::autogear;
|
||||||
creators["equip upgrade"] = &ChatActionContext::equip_upgrade;
|
creators["equip upgrade"] = &ChatActionContext::equip_upgrade;
|
||||||
creators["attack my target"] = &ChatActionContext::attack_my_target;
|
creators["attack my target"] = &ChatActionContext::attack_my_target;
|
||||||
@@ -215,6 +216,7 @@ class ChatActionContext : public NamedObjectContext<Action>
|
|||||||
static Action* attack_my_target(PlayerbotAI* botAI) { return new AttackMyTargetAction(botAI); }
|
static Action* attack_my_target(PlayerbotAI* botAI) { return new AttackMyTargetAction(botAI); }
|
||||||
static Action* trainer(PlayerbotAI* botAI) { return new TrainerAction(botAI); }
|
static Action* trainer(PlayerbotAI* botAI) { return new TrainerAction(botAI); }
|
||||||
static Action* maintenance(PlayerbotAI* botAI) { return new MaintenanceAction(botAI); }
|
static Action* maintenance(PlayerbotAI* botAI) { return new MaintenanceAction(botAI); }
|
||||||
|
static Action* remove_glyph(PlayerbotAI* botAI) { return new RemoveGlyphAction(botAI); }
|
||||||
static Action* autogear(PlayerbotAI* botAI) { return new AutoGearAction(botAI); }
|
static Action* autogear(PlayerbotAI* botAI) { return new AutoGearAction(botAI); }
|
||||||
static Action* equip_upgrade(PlayerbotAI* botAI) { return new EquipUpgradeAction(botAI); }
|
static Action* equip_upgrade(PlayerbotAI* botAI) { return new EquipUpgradeAction(botAI); }
|
||||||
static Action* co(PlayerbotAI* botAI) { return new ChangeCombatStrategyAction(botAI); }
|
static Action* co(PlayerbotAI* botAI) { return new ChangeCombatStrategyAction(botAI); }
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ bool FollowChatShortcutAction::Execute(Event event)
|
|||||||
botAI->Reset();
|
botAI->Reset();
|
||||||
botAI->ChangeStrategy("+follow,-passive,-grind", BOT_STATE_NON_COMBAT);
|
botAI->ChangeStrategy("+follow,-passive,-grind", BOT_STATE_NON_COMBAT);
|
||||||
botAI->ChangeStrategy("-follow,-passive,-grind", BOT_STATE_COMBAT);
|
botAI->ChangeStrategy("-follow,-passive,-grind", BOT_STATE_COMBAT);
|
||||||
|
botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Set({});
|
||||||
|
|
||||||
PositionMap& posMap = context->GetValue<PositionMap&>("position")->Get();
|
PositionMap& posMap = context->GetValue<PositionMap&>("position")->Get();
|
||||||
PositionInfo pos = posMap["return"];
|
PositionInfo pos = posMap["return"];
|
||||||
|
|||||||
@@ -1645,34 +1645,107 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvoidAoeAction::FleePosition(Position pos, float radius, std::string name)
|
Position AvoidAoeAction::BestPositionForMelee(Position pos, float radius)
|
||||||
{
|
{
|
||||||
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
||||||
std::vector<float> possibleAngles;
|
std::vector<CheckAngle> possibleAngles;
|
||||||
if (currentTarget) {
|
if (currentTarget) {
|
||||||
// Normally, move to left or right is the best position
|
// Normally, move to left or right is the best position
|
||||||
float angleLeft = bot->GetAngle(currentTarget) + M_PI / 2;
|
bool isTanking = (currentTarget->CanFreeMove()) && (currentTarget->GetVictim() == bot);
|
||||||
float angleRight = bot->GetAngle(currentTarget) - M_PI / 2;
|
float angle = bot->GetAngle(currentTarget);
|
||||||
possibleAngles.push_back(angleLeft);
|
float angleLeft = angle + (float)M_PI / 2;
|
||||||
possibleAngles.push_back(angleRight);
|
float angleRight = angle - (float)M_PI / 2;
|
||||||
|
possibleAngles.push_back({angleLeft, false});
|
||||||
|
possibleAngles.push_back({angleRight, false});
|
||||||
|
possibleAngles.push_back({angle, true});
|
||||||
|
if (isTanking) {
|
||||||
|
possibleAngles.push_back({angle + (float)M_PI, false});
|
||||||
|
possibleAngles.push_back({bot->GetAngle(&pos) - (float)M_PI, false});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
float angleTo = bot->GetAngle(&pos) - M_PI;
|
float angleTo = bot->GetAngle(&pos) - (float)M_PI;
|
||||||
possibleAngles.push_back(angleTo);
|
possibleAngles.push_back({angleTo, false});
|
||||||
}
|
}
|
||||||
float farestDis = 0.0f;
|
float farestDis = 0.0f;
|
||||||
Position bestPos;
|
Position bestPos;
|
||||||
for (float &angle : possibleAngles) {
|
for (CheckAngle &checkAngle : possibleAngles) {
|
||||||
|
float angle = checkAngle.angle;
|
||||||
|
bool strict = checkAngle.strict;
|
||||||
float fleeDis = sPlayerbotAIConfig->fleeDistance;
|
float fleeDis = sPlayerbotAIConfig->fleeDistance;
|
||||||
Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis,
|
Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis,
|
||||||
bot->GetPositionY() + sin(angle) * fleeDis,
|
bot->GetPositionY() + sin(angle) * fleeDis,
|
||||||
bot->GetPositionZ()};
|
bot->GetPositionZ()};
|
||||||
// todo (Yunfan): check carefully
|
if (strict && currentTarget
|
||||||
|
&& fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() > sPlayerbotAIConfig->tooCloseDistance) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (pos.GetExactDist(fleePos) > farestDis) {
|
if (pos.GetExactDist(fleePos) > farestDis) {
|
||||||
farestDis = pos.GetExactDist(fleePos);
|
farestDis = pos.GetExactDist(fleePos);
|
||||||
bestPos = fleePos;
|
bestPos = fleePos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (farestDis > 0.0f) {
|
if (farestDis > 0.0f) {
|
||||||
|
return bestPos;
|
||||||
|
}
|
||||||
|
return Position();
|
||||||
|
}
|
||||||
|
|
||||||
|
Position AvoidAoeAction::BestPositionForRanged(Position pos, float radius)
|
||||||
|
{
|
||||||
|
Unit* currentTarget = AI_VALUE(Unit*, "current target");
|
||||||
|
std::vector<CheckAngle> possibleAngles;
|
||||||
|
float angleToTarget = 0.0f;
|
||||||
|
float angleFleeFromCenter = bot->GetAngle(&pos) - (float)M_PI;
|
||||||
|
if (currentTarget) {
|
||||||
|
// Normally, move to left or right is the best position
|
||||||
|
angleToTarget = bot->GetAngle(currentTarget);
|
||||||
|
float angleLeft = angleToTarget + (float)M_PI / 2;
|
||||||
|
float angleRight = angleToTarget - (float)M_PI / 2;
|
||||||
|
possibleAngles.push_back({angleLeft, false});
|
||||||
|
possibleAngles.push_back({angleRight, false});
|
||||||
|
possibleAngles.push_back({angleToTarget + (float)M_PI, true});
|
||||||
|
possibleAngles.push_back({angleToTarget, true});
|
||||||
|
possibleAngles.push_back({angleFleeFromCenter, true});
|
||||||
|
} else {
|
||||||
|
possibleAngles.push_back({angleFleeFromCenter, false});
|
||||||
|
}
|
||||||
|
float farestDis = 0.0f;
|
||||||
|
Position bestPos;
|
||||||
|
for (CheckAngle &checkAngle : possibleAngles) {
|
||||||
|
float angle = checkAngle.angle;
|
||||||
|
bool strict = checkAngle.strict;
|
||||||
|
float fleeDis = sPlayerbotAIConfig->fleeDistance;
|
||||||
|
Position fleePos{bot->GetPositionX() + cos(angle) * fleeDis,
|
||||||
|
bot->GetPositionY() + sin(angle) * fleeDis,
|
||||||
|
bot->GetPositionZ()};
|
||||||
|
if (strict && currentTarget
|
||||||
|
&& fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() > sPlayerbotAIConfig->spellDistance) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strict && currentTarget
|
||||||
|
&& fleePos.GetExactDist(currentTarget) - currentTarget->GetCombatReach() < (sPlayerbotAIConfig->tooCloseDistance)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pos.GetExactDist(fleePos) > farestDis) {
|
||||||
|
farestDis = pos.GetExactDist(fleePos);
|
||||||
|
bestPos = fleePos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (farestDis > 0.0f) {
|
||||||
|
return bestPos;
|
||||||
|
}
|
||||||
|
return Position();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AvoidAoeAction::FleePosition(Position pos, float radius, std::string name)
|
||||||
|
{
|
||||||
|
Position bestPos;
|
||||||
|
if (botAI->IsMelee(bot)) {
|
||||||
|
bestPos = BestPositionForMelee(pos, radius);
|
||||||
|
} else {
|
||||||
|
bestPos = BestPositionForRanged(pos, radius);
|
||||||
|
}
|
||||||
|
if (bestPos != Position()) {
|
||||||
if (MoveTo(bot->GetMapId(), bestPos.GetPositionX(), bestPos.GetPositionY(), bestPos.GetPositionZ(), false, false, true)) {
|
if (MoveTo(bot->GetMapId(), bestPos.GetPositionX(), bestPos.GetPositionY(), bestPos.GetPositionZ(), false, false, true)) {
|
||||||
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
||||||
lastTellTimer = time(NULL);
|
lastTellTimer = time(NULL);
|
||||||
|
|||||||
@@ -78,11 +78,14 @@ class AvoidAoeAction : public MovementAction
|
|||||||
bool AvoidAuraWithDynamicObj();
|
bool AvoidAuraWithDynamicObj();
|
||||||
bool AvoidGameObjectWithDamage();
|
bool AvoidGameObjectWithDamage();
|
||||||
bool AvoidUnitWithDamageAura();
|
bool AvoidUnitWithDamageAura();
|
||||||
// Position PositionForTank(Position pos, float radius);
|
Position BestPositionForMelee(Position pos, float radius);
|
||||||
// Position PositionForMelee(Position pos, float radius);
|
Position BestPositionForRanged(Position pos, float radius);
|
||||||
// Position PositionForRanged(Position pos, float radius);
|
|
||||||
bool FleePosition(Position pos, float radius, std::string name);
|
bool FleePosition(Position pos, float radius, std::string name);
|
||||||
time_t lastTellTimer = 0;
|
time_t lastTellTimer = 0;
|
||||||
|
struct CheckAngle {
|
||||||
|
float angle;
|
||||||
|
bool strict;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class RunAwayAction : public MovementAction
|
class RunAwayAction : public MovementAction
|
||||||
|
|||||||
@@ -175,6 +175,15 @@ bool MaintenanceAction::Execute(Event event)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RemoveGlyphAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
for (uint32 slotIndex = 0; slotIndex < MAX_GLYPH_SLOT_INDEX; ++slotIndex)
|
||||||
|
{
|
||||||
|
bot->SetGlyph(slotIndex, 0, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool AutoGearAction::Execute(Event event)
|
bool AutoGearAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->autoGearCommand) {
|
if (!sPlayerbotAIConfig->autoGearCommand) {
|
||||||
|
|||||||
@@ -35,6 +35,13 @@ class MaintenanceAction : public Action
|
|||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RemoveGlyphAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RemoveGlyphAction(PlayerbotAI* botAI) : Action(botAI, "remove glyph") { }
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
class AutoGearAction : public Action
|
class AutoGearAction : public Action
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -81,8 +81,10 @@ bool SummonAction::Execute(Event event)
|
|||||||
pet->GetCharmInfo()->IsReturning();
|
pet->GetCharmInfo()->IsReturning();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (master->GetSession()->GetSecurity() >= SEC_PLAYER)
|
if (master->GetSession()->GetSecurity() >= SEC_PLAYER) {
|
||||||
|
botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Set({});
|
||||||
return Teleport(master, bot);
|
return Teleport(master, bot);
|
||||||
|
}
|
||||||
|
|
||||||
if (SummonUsingGos(master, bot) || SummonUsingNpcs(master, bot))
|
if (SummonUsingGos(master, bot) || SummonUsingNpcs(master, bot))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "XpGainAction.h"
|
#include "XpGainAction.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
#include "PlayerbotAIConfig.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
|
||||||
bool XpGainAction::Execute(Event event)
|
bool XpGainAction::Execute(Event event)
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas
|
|||||||
supported.push_back("de");
|
supported.push_back("de");
|
||||||
supported.push_back("trainer");
|
supported.push_back("trainer");
|
||||||
supported.push_back("maintenance");
|
supported.push_back("maintenance");
|
||||||
|
supported.push_back("remove glyph");
|
||||||
supported.push_back("autogear");
|
supported.push_back("autogear");
|
||||||
supported.push_back("equip upgrade");
|
supported.push_back("equip upgrade");
|
||||||
supported.push_back("chat");
|
supported.push_back("chat");
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ class ChatTriggerContext : public NamedObjectContext<Trigger>
|
|||||||
creators["de"] = &ChatTriggerContext::dead;
|
creators["de"] = &ChatTriggerContext::dead;
|
||||||
creators["trainer"] = &ChatTriggerContext::trainer;
|
creators["trainer"] = &ChatTriggerContext::trainer;
|
||||||
creators["maintenance"] = &ChatTriggerContext::maintenance;
|
creators["maintenance"] = &ChatTriggerContext::maintenance;
|
||||||
|
creators["remove glyph"] = &ChatTriggerContext::remove_glyph;
|
||||||
creators["autogear"] = &ChatTriggerContext::autogear;
|
creators["autogear"] = &ChatTriggerContext::autogear;
|
||||||
creators["equip upgrade"] = &ChatTriggerContext::equip_upgrade;
|
creators["equip upgrade"] = &ChatTriggerContext::equip_upgrade;
|
||||||
creators["attack"] = &ChatTriggerContext::attack;
|
creators["attack"] = &ChatTriggerContext::attack;
|
||||||
@@ -168,6 +169,7 @@ class ChatTriggerContext : public NamedObjectContext<Trigger>
|
|||||||
static Trigger* attack(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "attack"); }
|
static Trigger* attack(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "attack"); }
|
||||||
static Trigger* trainer(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "trainer"); }
|
static Trigger* trainer(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "trainer"); }
|
||||||
static Trigger* maintenance(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "maintenance"); }
|
static Trigger* maintenance(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "maintenance"); }
|
||||||
|
static Trigger* remove_glyph(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "remove glyph"); }
|
||||||
static Trigger* autogear(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "autogear"); }
|
static Trigger* autogear(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "autogear"); }
|
||||||
static Trigger* equip_upgrade(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "equip upgrade"); }
|
static Trigger* equip_upgrade(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "equip upgrade"); }
|
||||||
static Trigger* co(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "co"); }
|
static Trigger* co(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "co"); }
|
||||||
|
|||||||
@@ -125,7 +125,8 @@ Aura* AreaDebuffValue::Calculate()
|
|||||||
Unit::AuraEffectList const& aurasPeriodicDamagePercent = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
|
Unit::AuraEffectList const& aurasPeriodicDamagePercent = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
|
||||||
Unit::AuraEffectList const& aurasPeriodicTriggerSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
Unit::AuraEffectList const& aurasPeriodicTriggerSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||||
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
|
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell = bot->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE);
|
||||||
for (const Unit::AuraEffectList& list : {aurasPeriodicDamage, aurasPeriodicDamagePercent, aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell}) {
|
Unit::AuraEffectList const& aurasDummy = bot->GetAuraEffectsByType(SPELL_AURA_DUMMY);
|
||||||
|
for (const Unit::AuraEffectList& list : {aurasPeriodicDamage, aurasPeriodicDamagePercent, aurasPeriodicTriggerSpell, aurasPeriodicTriggerWithValueSpell, aurasDummy}) {
|
||||||
for (auto i = list.begin(); i != list.end(); ++i)
|
for (auto i = list.begin(); i != list.end(); ++i)
|
||||||
{
|
{
|
||||||
AuraEffect* aurEff = *i;
|
AuraEffect* aurEff = *i;
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ void AttackersValue::RemoveNonThreating(std::unordered_set<Unit*>& targets)
|
|||||||
for(std::unordered_set<Unit *>::iterator tIter = targets.begin(); tIter != targets.end();)
|
for(std::unordered_set<Unit *>::iterator tIter = targets.begin(); tIter != targets.end();)
|
||||||
{
|
{
|
||||||
Unit* unit = *tIter;
|
Unit* unit = *tIter;
|
||||||
if(bot->GetMapId() != unit->GetMapId() || !hasRealThreat(unit) || !IsValidTarget(unit, bot) || !bot->IsWithinLOSInMap(unit))
|
if(bot->GetMapId() != unit->GetMapId() || !hasRealThreat(unit) || !IsValidTarget(unit, bot))
|
||||||
{
|
{
|
||||||
std::unordered_set<Unit *>::iterator tIter2 = tIter;
|
std::unordered_set<Unit *>::iterator tIter2 = tIter;
|
||||||
++tIter;
|
++tIter;
|
||||||
@@ -113,15 +113,6 @@ void AttackersValue::RemoveNonThreating(std::unordered_set<Unit*>& targets)
|
|||||||
else
|
else
|
||||||
++tIter;
|
++tIter;
|
||||||
}
|
}
|
||||||
// Unit* unit = *tIter;
|
|
||||||
// if (!IsValidTarget(unit, bot) || !bot->IsWithinLOSInMap(unit))
|
|
||||||
// {
|
|
||||||
// std::unordered_set<Unit*>::iterator tIter2 = tIter;
|
|
||||||
// ++tIter;
|
|
||||||
// targets.erase(tIter2);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// ++tIter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttackersValue::hasRealThreat(Unit *attacker)
|
bool AttackersValue::hasRealThreat(Unit *attacker)
|
||||||
@@ -160,7 +151,7 @@ bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float range)
|
|||||||
// bool inCannon = botAI->IsInVehicle(false, true);
|
// bool inCannon = botAI->IsInVehicle(false, true);
|
||||||
// bool enemy = botAI->GetAiObjectContext()->GetValue<Unit*>("enemy player target")->Get();
|
// bool enemy = botAI->GetAiObjectContext()->GetValue<Unit*>("enemy player target")->Get();
|
||||||
|
|
||||||
return attacker &&
|
return attacker && attacker->IsVisible() &&
|
||||||
attacker->IsInWorld() &&
|
attacker->IsInWorld() &&
|
||||||
attacker->GetMapId() == bot->GetMapId() &&
|
attacker->GetMapId() == bot->GetMapId() &&
|
||||||
!attacker->isDead() &&
|
!attacker->isDead() &&
|
||||||
@@ -183,10 +174,9 @@ bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float range)
|
|||||||
|
|
||||||
bool AttackersValue::IsValidTarget(Unit *attacker, Player *bot)
|
bool AttackersValue::IsValidTarget(Unit *attacker, Player *bot)
|
||||||
{
|
{
|
||||||
return attacker->IsVisible() &&
|
return IsPossibleTarget(attacker, bot) && bot->IsWithinLOSInMap(attacker);
|
||||||
IsPossibleTarget(attacker, bot) &&
|
// (attacker->GetThreatMgr().getCurrentVictim() || attacker->GetGuidValue(UNIT_FIELD_TARGET) ||
|
||||||
(attacker->GetThreatMgr().getCurrentVictim() || attacker->GetGuidValue(UNIT_FIELD_TARGET) ||
|
// attacker->GetGUID().IsPlayer() || attacker->GetGUID() == GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<ObjectGuid>("pull target")->Get());
|
||||||
attacker->GetGUID().IsPlayer() || attacker->GetGUID() == GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<ObjectGuid>("pull target")->Get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PossibleAddsValue::Calculate()
|
bool PossibleAddsValue::Calculate()
|
||||||
|
|||||||
@@ -71,6 +71,12 @@ class CasterFindTargetSmartStrategy : public FindTargetStrategy
|
|||||||
|
|
||||||
void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
|
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()) {
|
if (!attacker->IsAlive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -138,6 +144,12 @@ class NonCasterFindTargetSmartStrategy : public FindTargetStrategy
|
|||||||
|
|
||||||
void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
|
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()) {
|
if (!attacker->IsAlive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -193,6 +205,12 @@ class ComboFindTargetSmartStrategy : public FindTargetStrategy
|
|||||||
|
|
||||||
void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
|
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()) {
|
if (!attacker->IsAlive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,7 @@ bool InvalidTargetValue::Calculate()
|
|||||||
target->isFeared() ||
|
target->isFeared() ||
|
||||||
target->HasUnitState(UNIT_STATE_ISOLATED) ||
|
target->HasUnitState(UNIT_STATE_ISOLATED) ||
|
||||||
target->IsFriendlyTo(bot) ||
|
target->IsFriendlyTo(bot) ||
|
||||||
!AttackersValue::IsValidTarget(target, bot) ||
|
!AttackersValue::IsValidTarget(target, bot);
|
||||||
// !bot->IsWithinDistInMap(target, sPlayerbotAIConfig->sightDistance) ||
|
|
||||||
!bot->IsWithinLOSInMap(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !target;
|
return !target;
|
||||||
|
|||||||
Reference in New Issue
Block a user