diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 813c89dd..8b1bed28 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -561,7 +561,7 @@ AiPlayerbot.MinRandomBotInWorldTime = 3600 AiPlayerbot.MaxRandomBotInWorldTime = 1209600 AiPlayerbot.MinRandomBotRandomizeTime = 7200 AiPlayerbot.MaxRandomRandomizeTime = 1209600 -AiPlayerbot.RandomBotsPerInterval = 60 +AiPlayerbot.RandomBotsPerInterval = 500 AiPlayerbot.MinRandomBotsPriceChangeInterval = 7200 AiPlayerbot.MaxRandomBotsPriceChangeInterval = 172800 AiPlayerbot.MinRandomBotChangeStrategyTime = 180 diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index d5ee476d..2a0aa7af 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -91,39 +91,24 @@ uint8 AiFactory::GetPlayerSpecTab(Player* bot) std::map AiFactory::GetPlayerSpecTabs(Player* bot) { - std::map tabs; - for (uint32 i = 0; i < 3; i++) - tabs[i] = 0; - - uint32 classMask = bot->getClassMask(); - for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) + std::map tabs = {{0, 0}, {0, 0}, {0, 0}}; + const PlayerTalentMap& talentMap = bot->GetTalentMap(); + for (PlayerTalentMap::const_iterator i = talentMap.begin(); i != talentMap.end(); ++i) { - TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + uint32 spellId = i->first; + TalentSpellPos const* talentPos = GetTalentSpellPos(spellId); + if(!talentPos) + continue; + + TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id); if (!talentInfo) continue; - TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); - if (!talentTabInfo) - continue; - - if ((classMask & talentTabInfo->ClassMask) == 0) - continue; - - uint32 maxRank = 0; - for (int32 rank = MAX_TALENT_RANK - 1; rank >= 0; --rank) - { - if (!talentInfo->RankID[rank]) - continue; - - uint32 spellid = talentInfo->RankID[rank]; - if (spellid && bot->HasSpell(spellid)) - maxRank = rank + 1; - - } - - tabs[talentTabInfo->tabpage] += maxRank; + uint32 const* talentTabIds = GetTalentTabPages(bot->getClass()); + if (talentInfo->TalentTab == talentTabIds[0]) tabs[0]++; + if (talentInfo->TalentTab == talentTabIds[1]) tabs[1]++; + if (talentInfo->TalentTab == talentTabIds[2]) tabs[2]++; } - return tabs; } @@ -554,7 +539,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const if (!player->InBattleground()) { nonCombatEngine->addStrategies("nc", "food", "chat", "follow", - "default", "quest", "loot", "gather", "duel", "emote", "buff", "mount", nullptr); + "default", "quest", "loot", "gather", "duel", "buff", "mount", nullptr); } if ((facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground()) @@ -578,7 +563,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const nonCombatEngine->addStrategy("collision"); nonCombatEngine->addStrategy("grind"); // nonCombatEngine->addStrategy("group"); - nonCombatEngine->addStrategy("guild"); + // nonCombatEngine->addStrategy("guild"); if (sPlayerbotAIConfig->autoDoQuests) { @@ -607,7 +592,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const nonCombatEngine->addStrategy("collision"); nonCombatEngine->addStrategy("grind"); // nonCombatEngine->addStrategy("group"); - nonCombatEngine->addStrategy("guild"); + // nonCombatEngine->addStrategy("guild"); if (sPlayerbotAIConfig->autoDoQuests) { @@ -634,7 +619,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const // Battleground switch if (player->InBattleground() && player->GetBattleground()) { - nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "collision", "dps assist", "attack tagged", "emote", nullptr); + nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "collision", "dps assist", "attack tagged", nullptr); nonCombatEngine->removeStrategy("custom::say"); nonCombatEngine->removeStrategy("travel"); nonCombatEngine->removeStrategy("rpg"); diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 31c7a6b9..aebf53ee 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -76,18 +76,19 @@ void PlayerbotFactory::Prepare() { if (!itemQuality) { - if (level < 20) - itemQuality = urand(ITEM_QUALITY_NORMAL, ITEM_QUALITY_UNCOMMON); - else if (level < 40) - itemQuality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_RARE); - else if (level < 60) - itemQuality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_EPIC); - else if (level < 70) - itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC); - else if (level < 80) - itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC); - else - itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC); + itemQuality = ITEM_QUALITY_RARE; + // if (level < 20) + // itemQuality = urand(ITEM_QUALITY_NORMAL, ITEM_QUALITY_UNCOMMON); + // else if (level < 40) + // itemQuality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_RARE); + // else if (level < 60) + // itemQuality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_EPIC); + // else if (level < 70) + // itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC); + // else if (level < 80) + // itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC); + // else + // itemQuality = urand(ITEM_QUALITY_RARE, ITEM_QUALITY_EPIC); } if (bot->isDead()) @@ -177,6 +178,7 @@ void PlayerbotFactory::Randomize(bool incremental) pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells1"); LOG_INFO("playerbots", "Initializing spells (step 1)..."); + // InitClassSpells(); InitAvailableSpells(); if (pmo) pmo->finish(); @@ -184,7 +186,7 @@ void PlayerbotFactory::Randomize(bool incremental) LOG_INFO("playerbots", "Initializing skills (step 1)..."); pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills1"); InitSkills(); - InitTradeSkills(); + // InitTradeSkills(); if (pmo) pmo->finish(); @@ -213,7 +215,7 @@ void PlayerbotFactory::Randomize(bool incremental) pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills2"); LOG_INFO("playerbots", "Initializing skills (step 2)..."); - UpdateTradeSkills(); + // UpdateTradeSkills(); bot->SaveToDB(false, false); if (pmo) pmo->finish(); @@ -281,7 +283,7 @@ void PlayerbotFactory::Randomize(bool incremental) pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Inventory"); LOG_INFO("playerbots", "Initializing inventory..."); - InitInventory(); + // InitInventory(); if (pmo) pmo->finish(); @@ -1793,6 +1795,100 @@ void PlayerbotFactory::InitAvailableSpells() bot->learnSpell(20271, false); } +void PlayerbotFactory::InitClassSpells() +{ + int32_t level = bot->getLevel(); + switch (bot->getClass()) + { + case CLASS_WARRIOR: + bot->learnSpell(78, false); + bot->learnSpell(2457, false); + if (level >= 10) { + bot->learnSpell(71, false); // Defensive Stance + bot->learnSpell(355, false); // Taunt + bot->learnSpell(7386, false); // Sunder Armor + } + if (level >= 30) { + bot->learnSpell(2458, false); // Berserker Stance + } + break; + case CLASS_PALADIN: + bot->learnSpell(21084, false); + bot->learnSpell(635, false); + if (level >= 12) { + bot->learnSpell(7328, false); // Redemption + } + break; + case CLASS_ROGUE: + bot->learnSpell(1752, false); + bot->learnSpell(2098, false); + break; + case CLASS_DEATH_KNIGHT: + bot->learnSpell(45477, false); + bot->learnSpell(47541, false); + bot->learnSpell(45462, false); + bot->learnSpell(45902, false); + //to leave DK starting area + bot->learnSpell(50977, false); + break; + case CLASS_HUNTER: + bot->learnSpell(2973, false); + bot->learnSpell(75, false); + if (level >= 10) { + bot->learnSpell(883, false); // call pet + bot->learnSpell(1515, false); // tame pet + bot->learnSpell(6991, false); // feed pet + bot->learnSpell(982, false); // revive pet + } + break; + case CLASS_PRIEST: + bot->learnSpell(585, false); + bot->learnSpell(2050, false); + break; + case CLASS_MAGE: + bot->learnSpell(133, false); + bot->learnSpell(168, false); + break; + case CLASS_WARLOCK: + bot->learnSpell(687, false); + bot->learnSpell(686, false); + if (level >= 10) { + bot->learnSpell(697, false); // summon voidwalker + } + if (level >= 20) { + bot->learnSpell(712, false); // summon succubus + } + if (level >= 30) { + bot->learnSpell(691, false); // summon felhunter + } + break; + case CLASS_DRUID: + bot->learnSpell(5176, false); + bot->learnSpell(5185, false); + if (level >= 10) { + bot->learnSpell(5487, false); // bear form + bot->learnSpell(6795, false); // Growl + bot->learnSpell(6807, false); // Maul + } + break; + case CLASS_SHAMAN: + bot->learnSpell(403, false); + bot->learnSpell(331, false); + if (level >= 4) { + bot->learnSpell(8071, false); // stoneskin totem + } + if (level >= 10) { + bot->learnSpell(3599, false); // searing totem + } + if (level >= 20) { + bot->learnSpell(5394, false); // healing stream totem + } + break; + default: + break; + } +} + void PlayerbotFactory::InitSpecialSpells() { for (std::vector::iterator i = sPlayerbotAIConfig->randomBotSpellIds.begin(); i != sPlayerbotAIConfig->randomBotSpellIds.end(); ++i) @@ -1800,6 +1896,11 @@ void PlayerbotFactory::InitSpecialSpells() uint32 spellId = *i; bot->learnSpell(spellId); } + // to leave DK starting area + if (bot->getClass() == CLASS_DEATH_KNIGHT) + { + bot->learnSpell(50977, false); + } } void PlayerbotFactory::InitTalents(uint32 specNo) diff --git a/src/PlayerbotFactory.h b/src/PlayerbotFactory.h index b51278ec..029b33ca 100644 --- a/src/PlayerbotFactory.h +++ b/src/PlayerbotFactory.h @@ -128,6 +128,7 @@ class PlayerbotFactory : public InventoryAction void ClearSpells(); void ClearSkills(); void InitAvailableSpells(); + void InitClassSpells(); void InitSpecialSpells(); void InitTalentsTree(bool incremental); void InitTalents(uint32 specNo); diff --git a/src/RandomItemMgr.cpp b/src/RandomItemMgr.cpp index 2ac34154..a0bba9a4 100644 --- a/src/RandomItemMgr.cpp +++ b/src/RandomItemMgr.cpp @@ -152,7 +152,7 @@ RandomItemMgr::RandomItemMgr() void RandomItemMgr::Init() { BuildItemInfoCache(); - BuildEquipCache(); + // BuildEquipCache(); BuildAmmoCache(); BuildPotionCache(); BuildFoodCache(); @@ -285,7 +285,7 @@ void RandomItemMgr::BuildRandomItemCache() if (!proto) continue; - LOG_INFO("playerbots", " [{}] {}", itemId, proto->Name1.c_str()); + LOG_DEBUG("playerbots", " [{}] {}", itemId, proto->Name1.c_str()); } } } @@ -332,30 +332,29 @@ bool RandomItemMgr::CanEquipItem(BotEquipKey key, ItemTemplate const* proto) requiredLevel = key.level; uint32 level = key.level; + uint32 delta = 2; if (level < 15) - delta = urand(7, 15); - else if (proto->Class == ITEM_CLASS_WEAPON || proto->SubClass == ITEM_SUBCLASS_ARMOR_SHIELD) - delta = urand(2, 3); - else if (!(level % 10) || (level % 10) == 9) - delta = 2; + delta = 15; else if (level < 40) - delta = urand(5, 10); + delta = 10; //urand(5, 10); else if (level < 60) - delta = urand(3, 7); + delta = 6; // urand(3, 7); else if (level < 70) - delta = urand(2, 5); + delta = 9; // urand(2, 5); else if (level < 80) - delta = urand(2, 4); + delta = 9; // urand(2, 4); + else if (level == 80) + delta = 2; // urand(2, 4); if (key.quality > ITEM_QUALITY_NORMAL && (requiredLevel > level || requiredLevel < level - delta)) return false; - for (uint32 gap = 60; gap <= 80; gap += 10) - { - if (level > gap && requiredLevel <= gap) - return false; - } + // for (uint32 gap = 60; gap <= 80; gap += 10) + // { + // if (level > gap && requiredLevel <= gap) + // return false; + // } return true; } @@ -1026,7 +1025,7 @@ void RandomItemMgr::BuildItemInfoCache() //statWeight.weight = statW; // save item statWeight into ItemCache cacheInfo.weights[statWeight.id] = statWeight.weight; - LOG_INFO("playerbots", "Item: {}, weight: {}, class: {}, spec: {}", proto->ItemId, statWeight.weight, clazz, m_weightScales[clazz][spec].info.name); + LOG_DEBUG("playerbots", "Item: {}, weight: {}, class: {}, spec: {}", proto->ItemId, statWeight.weight, clazz, m_weightScales[clazz][spec].info.name); } } @@ -1051,7 +1050,7 @@ void RandomItemMgr::BuildItemInfoCache() } if (cacheInfo.team < TEAM_NEUTRAL) - LOG_INFO("playerbots", "Item: {}, team (item): {}", proto->ItemId, cacheInfo.team == TEAM_ALLIANCE ? "Alliance" : "Horde"); + LOG_DEBUG("playerbots", "Item: {}, team (item): {}", proto->ItemId, cacheInfo.team == TEAM_ALLIANCE ? "Alliance" : "Horde"); // check min level if (proto->RequiredLevel) @@ -1062,7 +1061,7 @@ void RandomItemMgr::BuildItemInfoCache() if (proto->Flags & ITEM_FLAG_NO_DISENCHANT) { cacheInfo.source = ITEM_SOURCE_PVP; - LOG_INFO("playerbots", "Item: {}, source: PvP Reward", proto->ItemId); + LOG_DEBUG("playerbots", "Item: {}, source: PvP Reward", proto->ItemId); } // check quests @@ -1105,13 +1104,13 @@ void RandomItemMgr::BuildItemInfoCache() else if (isHorde) cacheInfo.team = TEAM_HORDE; - LOG_INFO("playerbots", "Item: {}, team (quest): {}", proto->ItemId, cacheInfo.team == TEAM_ALLIANCE ? "Alliance" : cacheInfo.team == TEAM_HORDE ? "Horde" : "Both"); - LOG_INFO("playerbots", "Item: {}, source: quest {}, minlevel: {}", proto->ItemId, cacheInfo.sourceId, cacheInfo.minLevel); + LOG_DEBUG("playerbots", "Item: {}, team (quest): {}", proto->ItemId, cacheInfo.team == TEAM_ALLIANCE ? "Alliance" : cacheInfo.team == TEAM_HORDE ? "Horde" : "Both"); + LOG_DEBUG("playerbots", "Item: {}, source: quest {}, minlevel: {}", proto->ItemId, cacheInfo.sourceId, cacheInfo.minLevel); } } if (cacheInfo.minLevel) - LOG_INFO("playerbots", "Item: {}, minlevel: {}", proto->ItemId, cacheInfo.minLevel); + LOG_DEBUG("playerbots", "Item: {}, minlevel: {}", proto->ItemId, cacheInfo.minLevel); // check vendors if (cacheInfo.source == ITEM_SOURCE_NONE) @@ -1121,7 +1120,7 @@ void RandomItemMgr::BuildItemInfoCache() if (proto->ItemId == *i) { cacheInfo.source = ITEM_SOURCE_VENDOR; - LOG_INFO("playerbots", "Item: {} source: vendor", proto->ItemId); + LOG_DEBUG("playerbots", "Item: {} source: vendor", proto->ItemId); break; } } @@ -1149,12 +1148,12 @@ void RandomItemMgr::BuildItemInfoCache() { cacheInfo.source = ITEM_SOURCE_DROP; cacheInfo.sourceId = creatures.front(); - LOG_INFO("playerbots", "Item: {}, source: creature drop, ID: {}", proto->ItemId, creatures.front()); + LOG_DEBUG("playerbots", "Item: {}, source: creature drop, ID: {}", proto->ItemId, creatures.front()); } else { cacheInfo.source = ITEM_SOURCE_DROP; - LOG_INFO("playerbots", "Item: {}, source: creatures drop, number: {}", proto->ItemId, creatures.size()); + LOG_DEBUG("playerbots", "Item: {}, source: creatures drop, number: {}", proto->ItemId, creatures.size()); } } } @@ -1548,9 +1547,9 @@ uint32 RandomItemMgr::CalculateSingleStatWeight(uint8 playerclass, uint8 spec, s if (stat == i->stat) { statWeight = i->weight * value; - if (statWeight) - LOG_INFO("playerbots", "stat: {}, val: {}, weight: {}, total: {}, class: {}, spec: {}", - stat, value, i->weight, statWeight, playerclass, m_weightScales[playerclass][spec].info.name); + // if (statWeight) + // LOG_INFO("playerbots", "stat: {}, val: {}, weight: {}, total: {}, class: {}, spec: {}", + // stat, value, i->weight, statWeight, playerclass, m_weightScales[playerclass][spec].info.name); return statWeight; } } @@ -2121,7 +2120,7 @@ void RandomItemMgr::BuildEquipCache() equipCache[key] = items; - LOG_INFO("playerbots", "Equipment cache for class: {}, level {}, slot {}, quality {}: {} items", + LOG_DEBUG("playerbots", "Equipment cache for class: {}, level {}, slot {}, quality {}: {} items", class_, level, slot, quality, items.size()); } } @@ -2134,8 +2133,36 @@ void RandomItemMgr::BuildEquipCache() RandomItemList RandomItemMgr::Query(uint32 level, uint8 clazz, uint8 slot, uint32 quality) { + // return equipCache[key]; BotEquipKey key(level, clazz, slot, quality); - return equipCache[key]; + RandomItemList items; + ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore(); + for (auto const& itr : *itemTemplates) + { + ItemTemplate const* proto = &itr.second; + if (!proto) + continue; + + if (proto->Class != ITEM_CLASS_WEAPON && proto->Class != ITEM_CLASS_ARMOR && proto->Class != ITEM_CLASS_CONTAINER && proto->Class != ITEM_CLASS_PROJECTILE) + continue; + + if (!CanEquipItem(key, proto)) + continue; + + if (proto->Class == ITEM_CLASS_ARMOR && (slot == EQUIPMENT_SLOT_HEAD || slot == EQUIPMENT_SLOT_SHOULDERS || slot == EQUIPMENT_SLOT_CHEST || + slot == EQUIPMENT_SLOT_WAIST || slot == EQUIPMENT_SLOT_LEGS || slot == EQUIPMENT_SLOT_FEET || slot == EQUIPMENT_SLOT_WRISTS || + slot == EQUIPMENT_SLOT_HANDS) && !CanEquipArmor(key.clazz, key.level, proto)) + continue; + + if (proto->Class == ITEM_CLASS_WEAPON && !CanEquipWeapon(key.clazz, proto)) + continue; + + if (slot == EQUIPMENT_SLOT_OFFHAND && key.clazz == CLASS_ROGUE && proto->Class != ITEM_CLASS_WEAPON) + continue; + + items.push_back(itr.first); + } + return items; } void RandomItemMgr::BuildAmmoCache() @@ -2238,7 +2265,7 @@ void RandomItemMgr::BuildPotionCache() uint32 size = potionCache[level / 10][effect].size(); ++counter; - LOG_INFO("server.loading", "Potion cache for level={}, effect={}: {} items", level, effect, size); + LOG_DEBUG("server.loading", "Potion cache for level={}, effect={}: {} items", level, effect, size); } } @@ -2298,7 +2325,7 @@ void RandomItemMgr::BuildFoodCache() uint32 category = categories[i]; uint32 size = foodCache[level / 10][category].size(); ++counter; - LOG_INFO("server.loading", "Food cache for level={}, category={}: {} items", level, category, size); + LOG_DEBUG("server.loading", "Food cache for level={}, category={}: {} items", level, category, size); } } @@ -2414,7 +2441,7 @@ void RandomItemMgr::BuildTradeCache() for (uint32 level = 1; level <= maxLevel + 1; level += 10) { uint32 size = tradeCache[level / 10].size(); - LOG_INFO("server.loading", "Trade cache for level={}: {} items", level, size); + LOG_DEBUG("server.loading", "Trade cache for level={}: {} items", level, size); ++counter; } diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index 5033b352..d1cda297 100644 --- a/src/RandomPlayerbotMgr.cpp +++ b/src/RandomPlayerbotMgr.cpp @@ -428,7 +428,7 @@ void RandomPlayerbotMgr::LoadBattleMastersCache() bmTeam = TEAM_HORDE; BattleMastersCache[bmTeam][BattlegroundTypeId(bgTypeId)].insert(BattleMastersCache[bmTeam][BattlegroundTypeId(bgTypeId)].end(), entry); - LOG_INFO("playerbots", "Cached Battmemaster #{} for BG Type {} ({})", entry, bgTypeId, bmTeam == TEAM_ALLIANCE ? "Alliance" : bmTeam == TEAM_HORDE ? "Horde" : "Neutral"); + LOG_DEBUG("playerbots", "Cached Battmemaster #{} for BG Type {} ({})", entry, bgTypeId, bmTeam == TEAM_ALLIANCE ? "Alliance" : bmTeam == TEAM_HORDE ? "Horde" : "Neutral"); } while (result->NextRow()); diff --git a/src/Talentspec.cpp b/src/Talentspec.cpp index a7985037..fcf08445 100644 --- a/src/Talentspec.cpp +++ b/src/Talentspec.cpp @@ -140,22 +140,11 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out) //Set the talents for the bots to the current spec. void TalentSpec::ApplyTalents(Player* bot, std::ostringstream* out) { - for (auto& entry : talents) - for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank) - { - uint32 spellId = entry.talentInfo->RankID[rank]; - if (!spellId) - continue; - - if (bot->HasSpell(spellId) && entry.rank - 1 != rank) - { - bot->removeSpell(spellId, false, false); - } - else if (!bot->HasSpell(spellId) && entry.rank - 1 == rank) - { - bot->learnSpell(spellId); - } - } + for (auto& entry : talents) { + if (entry.rank == 0) + continue; + bot->LearnTalent(entry.talentInfo->TalentID, entry.rank - 1); + } } //Returns a base talentlist for a class. diff --git a/src/strategy/Engine.cpp b/src/strategy/Engine.cpp index 414a94b1..d3943b60 100644 --- a/src/strategy/Engine.cpp +++ b/src/strategy/Engine.cpp @@ -643,7 +643,7 @@ void Engine::LogAction(char const* format, ...) if (sPlayerbotAIConfig->logInGroupOnly && !bot->GetGroup()) return; - LOG_INFO("playerbots", "{} {} {} {}", bot->GetName().c_str(), buf, sPlayerbotAIConfig->logInGroupOnly, bot->GetGroup()->GetGroupType()); + LOG_DEBUG("playerbots", "{} {}", bot->GetName().c_str(), buf); } } diff --git a/src/strategy/actions/ChooseRpgTargetAction.cpp b/src/strategy/actions/ChooseRpgTargetAction.cpp index 57091017..14b8e865 100644 --- a/src/strategy/actions/ChooseRpgTargetAction.cpp +++ b/src/strategy/actions/ChooseRpgTargetAction.cpp @@ -188,7 +188,7 @@ bool ChooseRpgTargetAction::Execute(Event event) if (targets.empty()) { - LOG_INFO("playerbots", "{} can't choose RPG target: all {} are not available", bot->GetName().c_str(), possibleTargets.size()); + LOG_DEBUG("playerbots", "{} can't choose RPG target: all {} are not available", bot->GetName().c_str(), possibleTargets.size()); RESET_AI_VALUE(GuidSet&, "ignore rpg target"); RESET_AI_VALUE(GuidPosition, "rpg target"); return false; diff --git a/src/strategy/actions/FollowActions.cpp b/src/strategy/actions/FollowActions.cpp index af69c5ff..62aa933b 100644 --- a/src/strategy/actions/FollowActions.cpp +++ b/src/strategy/actions/FollowActions.cpp @@ -23,7 +23,7 @@ bool FollowAction::Execute(Event event) WorldLocation loc = formation->GetLocation(); if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1) return false; - + moved = MoveTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ()); } diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index d951929d..604c8515 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -128,7 +128,7 @@ bool MovementAction::MoveToLOS(WorldObject* target, bool ranged) bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react) { UpdateMovementState(); - + LOG_DEBUG("playerbots", "IsMovingAllowed {}", IsMovingAllowed()); if (!IsMovingAllowed()) return false; @@ -137,6 +137,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, if (Vehicle* vehicle = bot->GetVehicle()) { VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(bot); + LOG_DEBUG("playerbots", "!seat || !seat->CanControl() {}", !seat || !seat->CanControl()); if (!seat || !seat->CanControl()) return false; @@ -150,6 +151,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, time_t now = time(nullptr); if (AI_VALUE(LastMovement&, "last movement").nextTeleport > now) // We can not teleport yet. Wait. { + LOG_DEBUG("playerbots", "AI_VALUE(LastMovement&, \"last movement\").nextTeleport > now"); botAI->SetNextCheckDelay((AI_VALUE(LastMovement&, "last movement").nextTeleport - now) * 1000); return true; } @@ -169,6 +171,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, if (!isVehicle && !IsMovingAllowed() && bot->isDead()) { bot->StopMoving(); + LOG_DEBUG("playerbots", "!isVehicle && !IsMovingAllowed() && bot->isDead()"); return false; } @@ -176,6 +179,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, { if (!bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) bot->StopMoving(); + LOG_DEBUG("playerbots", "!isVehicle && bot->isMoving() && !IsMovingAllowed()"); return false; } @@ -194,6 +198,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, AI_VALUE(LastMovement&, "last movement").clear(); mover->StopMoving(); + LOG_DEBUG("playerbots", "totalDistance < minDist"); return false; } @@ -222,6 +227,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, else { lastMove.future = std::async(&TravelNodeMap::getFullPath, startPosition, endPosition, bot); + LOG_DEBUG("playerbots", "lastMove.future = std::async(&TravelNodeMap::getFullPath, startPosition, endPosition, bot);"); return true; } } @@ -240,6 +246,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bot->StopMoving(); if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) botAI->TellMasterNoFacing("I have no path"); + LOG_DEBUG("playerbots", "sServerFacade->IsDistanceGreaterThan(totalDistance, maxDist * 3)"); return false; } @@ -276,7 +283,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) botAI->TellMasterNoFacing("Too far from path. Rebuilding."); - + LOG_DEBUG("playerbots", "movePath.empty()"); return true; } @@ -318,8 +325,10 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, { AI_VALUE(LastMovement&, "last area trigger").lastAreaTrigger = entry; } - else + else { + LOG_DEBUG("playerbots", "!entry"); return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), movePosition.getO(), 0); + } } if (pathType == TravelNodePathType::transport && entry) @@ -331,6 +340,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, transport->AddPassenger(bot, true); } WaitForReach(100.0f); + LOG_DEBUG("playerbots", "pathType == TravelNodePathType::transport && entry"); return true; } @@ -367,7 +377,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, { bot->SetMoney(botMoney); } - + LOG_DEBUG("playerbots", "goTaxi"); return goTaxi; } } @@ -384,6 +394,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, { movePath.clear(); AI_VALUE(LastMovement&, "last movement").setPath(movePath); + LOG_DEBUG("playerbots", "bot->HasSpellCooldown(8690)"); return false; } } @@ -402,6 +413,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) botAI->TellMasterNoFacing("No point. Rebuilding."); + LOG_DEBUG("playerbots", "!movePosition || movePosition.getMapId() != bot->GetMapId()"); return false; } @@ -465,7 +477,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, sPlayerbotAIConfig->log("bot_movement.csv", out.str().c_str()); } - + LOG_DEBUG("playerbots", "({}, {}) -> ({}, {})", startPosition.getX(), startPosition.getY(), movePosition.getX(), movePosition.getY()); if (!react) if (totalDistance > maxDist) WaitForReach(startPosition.distance(movePosition) - 10.0f); @@ -514,7 +526,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, time_t now = time(nullptr); AI_VALUE(LastMovement&, "last movement").nextTeleport = now + (time_t)MoveDelay(startPosition.distance(movePosition)); - + LOG_DEBUG("playerbots", "totalDistance > maxDist && !detailedMove && !botAI->HasPlayerNearby(&movePosition)"); return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), startPosition.getAngleTo(movePosition)); } @@ -530,11 +542,13 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bot->SetWalk(true); bot->SendMovementFlagUpdate(); - + LOG_DEBUG("playerbots", "normal move? {} {} {}", !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY), + bot->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE), bot->getStandState()); if (!bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY)) { bot->SetWalk(masterWalking); bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), generatePath); + LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY()); } else { @@ -580,6 +594,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, } bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), Position(movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0.f)); + LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY()); } AI_VALUE(LastMovement&, "last movement").setShort(movePosition); @@ -587,6 +602,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, if (!idle) ClearIdleState(); + LOG_DEBUG("playerbots", "return true in the end"); return true; } @@ -990,8 +1006,9 @@ bool MovementAction::ChaseTo(WorldObject* obj, float distance, float angle) botAI->InterruptSpell(); } - bot->GetMotionMaster()->Clear(); + // bot->GetMotionMaster()->Clear(); bot->GetMotionMaster()->MoveChase((Unit*) obj, distance, angle); + WaitForReach(bot->GetExactDist2d(obj) - distance); return true; } diff --git a/src/strategy/actions/NonCombatActions.cpp b/src/strategy/actions/NonCombatActions.cpp index 7dcc11d4..c1513e64 100644 --- a/src/strategy/actions/NonCombatActions.cpp +++ b/src/strategy/actions/NonCombatActions.cpp @@ -29,8 +29,7 @@ bool DrinkAction::Execute(Event event) botAI->SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown); return false; } - - bot->AddUnitState(UNIT_STAND_STATE_SIT); + bot->SetStandState(UNIT_STAND_STATE_SIT); botAI->InterruptSpell(); //float hp = bot->GetHealthPercent(); @@ -82,7 +81,7 @@ bool EatAction::Execute(Event event) return false; } - bot->AddUnitState(UNIT_STAND_STATE_SIT); + bot->SetStandState(UNIT_STAND_STATE_SIT); botAI->InterruptSpell(); float hp = bot->GetHealthPct(); diff --git a/src/strategy/actions/ReleaseSpiritAction.cpp b/src/strategy/actions/ReleaseSpiritAction.cpp index 22814933..cfe4a4db 100644 --- a/src/strategy/actions/ReleaseSpiritAction.cpp +++ b/src/strategy/actions/ReleaseSpiritAction.cpp @@ -124,7 +124,7 @@ bool AutoReleaseSpiritAction::isUseful() bool RepopAction::Execute(Event event) { - LOG_INFO("playerbots", "Bot {} {}:{} <{}> repops at graveyard", bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str()); + LOG_DEBUG("playerbots", "Bot {} {}:{} <{}> repops at graveyard", bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str()); int64 deadTime; diff --git a/src/strategy/actions/UseItemAction.cpp b/src/strategy/actions/UseItemAction.cpp index 3cb08bd2..4032c31a 100644 --- a/src/strategy/actions/UseItemAction.cpp +++ b/src/strategy/actions/UseItemAction.cpp @@ -266,7 +266,7 @@ bool UseItemAction::UseItem(Item* item, ObjectGuid goGuid, Item* itemTarget, Uni if (bot->IsInCombat()) return false; - bot->AddUnitState(UNIT_STAND_STATE_SIT); + bot->SetStandState(UNIT_STAND_STATE_SIT); botAI->InterruptSpell(); float hp = bot->GetHealthPct(); diff --git a/src/strategy/hunter/HunterTriggers.cpp b/src/strategy/hunter/HunterTriggers.cpp index a73af972..76da6c1b 100644 --- a/src/strategy/hunter/HunterTriggers.cpp +++ b/src/strategy/hunter/HunterTriggers.cpp @@ -53,13 +53,13 @@ bool HunterHasAmmoTrigger::IsActive() bool SwitchToRangedTrigger::IsActive() { Unit* target = AI_VALUE(Unit*, "current target"); - return botAI->HasStrategy("close", BOT_STATE_COMBAT) && target && (target->GetVictim() != bot || + return botAI->HasStrategy("close", BOT_STATE_COMBAT) && target && (target->GetVictim() != bot && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "current target"), 8.0f)); } bool SwitchToMeleeTrigger::IsActive() { Unit* target = AI_VALUE(Unit*, "current target"); - return botAI->HasStrategy("ranged", BOT_STATE_COMBAT) && target && (target->GetVictim() == bot || + return botAI->HasStrategy("ranged", BOT_STATE_COMBAT) && target && (target->GetVictim() == bot && sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"), 8.0f)); } diff --git a/src/strategy/values/AttackersValue.cpp b/src/strategy/values/AttackersValue.cpp index f87baf32..54d1dd71 100644 --- a/src/strategy/values/AttackersValue.cpp +++ b/src/strategy/values/AttackersValue.cpp @@ -135,9 +135,10 @@ bool AttackersValue::IsPossibleTarget(Unit* attacker, Player* bot, float range) bool AttackersValue::IsValidTarget(Unit *attacker, Player *bot) { - return IsPossibleTarget(attacker, bot) && (attacker->GetThreatMgr().getCurrentVictim() || attacker->GetGuidValue(UNIT_FIELD_TARGET) || + return IsPossibleTarget(attacker, bot) && (attacker->GetThreatMgr().getCurrentVictim() || attacker->GetGuidValue(UNIT_FIELD_TARGET) || attacker->GetGUID().IsPlayer() || attacker->GetGUID() == GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue("pull target")->Get()); } + bool PossibleAddsValue::Calculate() { GuidVector possible = botAI->GetAiObjectContext()->GetValue("possible targets no los")->Get(); diff --git a/src/strategy/values/AttackersValue.h b/src/strategy/values/AttackersValue.h index 756a8873..014dd383 100644 --- a/src/strategy/values/AttackersValue.h +++ b/src/strategy/values/AttackersValue.h @@ -16,7 +16,7 @@ class Unit; class AttackersValue : public ObjectGuidListCalculatedValue { public: - AttackersValue(PlayerbotAI* botAI) : ObjectGuidListCalculatedValue(botAI, "attackers", 2) { } + AttackersValue(PlayerbotAI* botAI) : ObjectGuidListCalculatedValue(botAI, "attackers", 1) { } GuidVector Calculate(); static bool IsPossibleTarget(Unit* attacker, Player* bot, float range = sPlayerbotAIConfig->sightDistance); diff --git a/src/strategy/values/InvalidTargetValue.cpp b/src/strategy/values/InvalidTargetValue.cpp index b76d0fcc..13c25796 100644 --- a/src/strategy/values/InvalidTargetValue.cpp +++ b/src/strategy/values/InvalidTargetValue.cpp @@ -15,7 +15,15 @@ bool InvalidTargetValue::Calculate() if (target && qualifier == "current target") { - return !AttackersValue::IsValidTarget(target, bot); + return target->GetMapId() != bot->GetMapId() || + !target->IsAlive() || + target->IsPolymorphed() || + target->IsCharmed() || + target->isFeared() || + target->HasUnitState(UNIT_STATE_ISOLATED) || + target->IsFriendlyTo(bot) || + !bot->IsWithinDistInMap(target, sPlayerbotAIConfig->sightDistance) || + !bot->IsWithinLOSInMap(target); } return !target;