From 80517df9a167a9114ede8d842709fae149a85fc3 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sat, 23 Sep 2023 23:55:27 +0800 Subject: [PATCH] talents initialization --- conf/playerbots.conf.dist | 112 +++++++++++++++++++++++++------------- src/PlayerbotAIConfig.cpp | 96 +++++++++++++++++++++++++++++--- src/PlayerbotAIConfig.h | 3 +- src/PlayerbotFactory.cpp | 39 ++++++++++++- 4 files changed, 204 insertions(+), 46 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index efce23da..0a1897b0 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -244,11 +244,11 @@ AiPlayerbot.PremadeSpecLink.3.3.80 = -005305101-3300132510233330532135001031 AiPlayerbot.PremadeSpecName.3.4 = BM Pve AiPlayerbot.PremadeSpecProb.3.4 = 100 -AiPlayerbot.PremadeSpecLink.3.4.80 = 51200201505112253100531351015305021 +AiPlayerbot.PremadeSpecLink.3.4.80 = 51200201505112253100531351-015305021 AiPlayerbot.PremadeSpecName.3.5 = MM Pve AiPlayerbot.PremadeSpecProb.3.5 = 100 -AiPlayerbot.PremadeSpecLink.3.5.80 = 502-0353051012300132331350313515000002 +AiPlayerbot.PremadeSpecLink.3.5.80 = 502-035305101230013233135031351-5000002 AiPlayerbot.PremadeSpecName.3.6 = Surv Pve AiPlayerbot.PremadeSpecProb.3.6 = 100 @@ -270,7 +270,7 @@ AiPlayerbot.PremadeSpecLink.4.3.80 = 0053031-1-5020232033322121350105131251 AiPlayerbot.PremadeSpecName.4.4 = Assassination Pve AiPlayerbot.PremadeSpecProb.4.4 = 100 -AiPlayerbot.PremadeSpecLink.4.4.80 = 005323005350100520103331051005005003-502 +AiPlayerbot.PremadeSpecLink.4.4.80 = 005323005350100520103331051-005005003-502 AiPlayerbot.PremadeSpecName.4.5 = Combat Pve AiPlayerbot.PremadeSpecProb.4.5 = 100 @@ -296,7 +296,7 @@ AiPlayerbot.PremadeSpecLink.5.3.80 = 050320313030051233132323125100550103 AiPlayerbot.PremadeSpecName.5.4 = Disc PvE renew build AiPlayerbot.PremadeSpecProb.5.4 = 100 -AiPlayerbot.PremadeSpecLink.5.4.80 = 050320313030051233132323125103530003 +AiPlayerbot.PremadeSpecLink.5.4.80 = 0503203130300512331323231251-03530003 AiPlayerbot.PremadeSpecName.5.5 = Holy PvE AiPlayerbot.PremadeSpecProb.5.5 = 100 @@ -688,88 +688,126 @@ Logger.playerbots=5,Console Playerbots # TalentSpec # ############################################## +# DefaultTalentsOrder: tab - row - col - lvl + # Warrior AiPlayerbot.RandomClassSpecProbability.1.0 = 20 -AiPlayerbot.DefaultTalentsOrder.1.0 = +AiPlayerbot.DefaultTalentsOrderLowLevel.1.0 = +AiPlayerbot.DefaultTalentsOrder.1.0 = 3022032123335100202012013031251-32505010002 AiPlayerbot.RandomClassSpecProbability.1.1 = 40 -AiPlayerbot.DefaultTalentsOrder.1.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.1.1 = +AiPlayerbot.DefaultTalentsOrder.1.1 = 30202300233-305053000500310153120511351 AiPlayerbot.RandomClassSpecProbability.1.2 = 40 -AiPlayerbot.DefaultTalentsOrder.1.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.1.2 = +AiPlayerbot.DefaultTalentsOrder.1.2 = 3500030023-301-053351225000210521030113321 # Paladin AiPlayerbot.RandomClassSpecProbability.2.0 = 30 -AiPlayerbot.DefaultTalentsOrder.2.0 = +AiPlayerbot.DefaultTalentsOrderLowLevel.2.0 = +AiPlayerbot.DefaultTalentsOrder.2.0 = 50350152220013053100515221-503201312 AiPlayerbot.RandomClassSpecProbability.2.1 = 40 -AiPlayerbot.DefaultTalentsOrder.2.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.2.1 = +AiPlayerbot.DefaultTalentsOrder.2.1 = -05005135203132311333312321-5023005 AiPlayerbot.RandomClassSpecProbability.2.2 = 30 -AiPlayerbot.DefaultTalentsOrder.2.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.2.2 = +AiPlayerbot.DefaultTalentsOrder.2.2 = 050501-05-05232051203331302133231331 # Hunter AiPlayerbot.RandomClassSpecProbability.3.0 = 33 -AiPlayerbot.DefaultTalentsOrder.3.0 = +AiPlayerbot.DefaultTalentsOrderLowLevel.3.0 = 51200201505112243100511351 +AiPlayerbot.DefaultTalentsOrder.3.0 = 51200201505112253100531351-015305021 AiPlayerbot.RandomClassSpecProbability.3.1 = 33 -AiPlayerbot.DefaultTalentsOrder.3.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.3.1 = +AiPlayerbot.DefaultTalentsOrder.3.1 = 502-035305101230013233135031351-5000002 AiPlayerbot.RandomClassSpecProbability.3.2 = 33 -AiPlayerbot.DefaultTalentsOrder.3.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.3.2 = +AiPlayerbot.DefaultTalentsOrder.3.2 = -0053041-5000032500033330523134321331 # Rogue AiPlayerbot.RandomClassSpecProbability.4.0 = 40 -AiPlayerbot.DefaultTalentsOrder.4.0 = 0-0-2-5, 0-1-3-3, 0-1-0-3, 0-2-2-5, 0-3-2-5, 0-3-1-3, 0-4-1-1, 0-5-2-2, 0-5-1-5, 0-6-1-1, 0-2-1-2, 0-7-2-3, 0-7-0-3, 0-8-1-1, 0-8-0-3, 0-9-1-5, 0-10-1-1, 1-0-2-5, 1-1-3-5, 1-2-2-5, 1-3-2-3, 2-0-0-2 +AiPlayerbot.DefaultTalentsOrderLowLevel.4.0 = +AiPlayerbot.DefaultTalentsOrder.4.0 = 005323005350100520103331051-005005003-502 # 0-0-2-5, 0-1-3-3, 0-1-0-3, 0-2-2-5, 0-3-2-5, 0-3-1-3, 0-4-1-1, 0-5-2-2, 0-5-1-5, 0-6-1-1, 0-2-1-2, 0-7-2-3, 0-7-0-3, 0-8-1-1, 0-8-0-3, 0-9-1-5, 0-10-1-1, 1-0-2-5, 1-1-3-5, 1-2-2-5, 1-3-2-3, 2-0-0-2 AiPlayerbot.RandomClassSpecProbability.4.1 = 40 -AiPlayerbot.DefaultTalentsOrder.4.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.4.1 = +AiPlayerbot.DefaultTalentsOrder.4.1 = 30530000522-0252051000035015223100501251 AiPlayerbot.RandomClassSpecProbability.4.2 = 20 -AiPlayerbot.DefaultTalentsOrder.4.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.4.2 = +AiPlayerbot.DefaultTalentsOrder.4.2 = 0053231-2-5120222030321121050135231251 # Priest AiPlayerbot.RandomClassSpecProbability.5.0 = 40 -AiPlayerbot.DefaultTalentsOrder.5.0 = +AiPlayerbot.DefaultTalentsOrderLowLevel.5.0 = +AiPlayerbot.DefaultTalentsOrder.5.0 = 0503203130300512331323231251-03530003 AiPlayerbot.RandomClassSpecProbability.5.1 = 30 -AiPlayerbot.DefaultTalentsOrder.5.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.5.1 = +AiPlayerbot.DefaultTalentsOrder.5.1 = 05032031-235050032302152530000331351 AiPlayerbot.RandomClassSpecProbability.5.2 = 30 -AiPlayerbot.DefaultTalentsOrder.5.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.5.2 = +AiPlayerbot.DefaultTalentsOrder.5.2 = 0503203--325023051223010323152301351 # DeathKnight AiPlayerbot.RandomClassSpecProbability.6.0 = 30 -AiPlayerbot.DefaultTalentsOrder.6.0 = +AiPlayerbot.DefaultTalentsOrderLowLevel.6.0 = +AiPlayerbot.DefaultTalentsOrder.6.0 = 0355220530003313221020131351305-0052 AiPlayerbot.RandomClassSpecProbability.6.1 = 40 -AiPlayerbot.DefaultTalentsOrder.6.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.6.1 = +AiPlayerbot.DefaultTalentsOrder.6.1 = 03-32002350352203012300033101351-230200305 AiPlayerbot.RandomClassSpecProbability.6.2 = 30 -AiPlayerbot.DefaultTalentsOrder.6.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.6.2 = +AiPlayerbot.DefaultTalentsOrder.6.2 = 23050202--2302003350032152003150003133151 # Shaman AiPlayerbot.RandomClassSpecProbability.7.0 = 33 -AiPlayerbot.DefaultTalentsOrder.7.0 = +AiPlayerbot.DefaultTalentsOrderLowLevel.7.0 = +AiPlayerbot.DefaultTalentsOrder.7.0 = 3530001523213351322301351-005050031 AiPlayerbot.RandomClassSpecProbability.7.1 = 33 -AiPlayerbot.DefaultTalentsOrder.7.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.7.1 = +AiPlayerbot.DefaultTalentsOrder.7.1 = 053030052-30205033005021333031131131051 AiPlayerbot.RandomClassSpecProbability.7.2 = 33 -AiPlayerbot.DefaultTalentsOrder.7.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.7.2 = +AiPlayerbot.DefaultTalentsOrder.7.2 = -00505031-50005331335310501022331251 # Mage -AiPlayerbot.RandomClassSpecProbability.8.0 = 20 -AiPlayerbot.DefaultTalentsOrder.8.0 = -AiPlayerbot.RandomClassSpecProbability.8.1 = 20 -AiPlayerbot.DefaultTalentsOrder.8.1 = -AiPlayerbot.RandomClassSpecProbability.8.2 = 60 -AiPlayerbot.DefaultTalentsOrder.8.2 = +AiPlayerbot.RandomClassSpecProbability.8.0 = 30 +AiPlayerbot.DefaultTalentsOrderLowLevel.8.0 = +AiPlayerbot.DefaultTalentsOrder.8.0 = 235005030100230150323102505321-03-203023001 +AiPlayerbot.RandomClassSpecProbability.8.1 = 30 +AiPlayerbot.DefaultTalentsOrderLowLevel.8.1 = +AiPlayerbot.DefaultTalentsOrder.8.1 = 23000503310003-0055030012303330053120300351 +AiPlayerbot.RandomClassSpecProbability.8.2 = 40 +AiPlayerbot.DefaultTalentsOrderLowLevel.8.2 = +AiPlayerbot.DefaultTalentsOrder.8.2 = 23002322010203--3533103310203100232102231151 # Warlock AiPlayerbot.RandomClassSpecProbability.9.0 = 40 -AiPlayerbot.DefaultTalentsOrder.9.0 = +AiPlayerbot.DefaultTalentsOrderLowLevel.9.0 = +AiPlayerbot.DefaultTalentsOrder.9.0 = 2350020021123510253500331151--55000005 AiPlayerbot.RandomClassSpecProbability.9.1 = 40 -AiPlayerbot.DefaultTalentsOrder.9.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.9.1 = +AiPlayerbot.DefaultTalentsOrder.9.1 = -003203301135212530135211351-55000005 # 1-0-2-3, 1-0-3-2, 1-1-1-3, 1-1-2-3, 1-2-1-1, 1-2-2-1, 1-2-2-3, 1-3-1-5, 1-3-2-2, 1-4-0-1, 1-4-2-2 AiPlayerbot.RandomClassSpecProbability.9.2 = 20 -AiPlayerbot.DefaultTalentsOrder.9.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.9.2 = +AiPlayerbot.DefaultTalentsOrder.9.2 = -03310030003-05203205210331051335230351 # Druid AiPlayerbot.RandomClassSpecProbability.11.0 = 20 -AiPlayerbot.DefaultTalentsOrder.11.0 = +AiPlayerbot.DefaultTalentsOrderLowLevel.11.0 = +AiPlayerbot.DefaultTalentsOrder.11.0 = 5012203125331103213305301231--205003212 AiPlayerbot.RandomClassSpecProbability.11.1 = 40 -AiPlayerbot.DefaultTalentsOrder.11.1 = +AiPlayerbot.DefaultTalentsOrderLowLevel.11.1 = +AiPlayerbot.DefaultTalentsOrder.11.1 = -501232130322110353120303313511-20350001 AiPlayerbot.RandomClassSpecProbability.11.2 = 40 -AiPlayerbot.DefaultTalentsOrder.11.2 = +AiPlayerbot.DefaultTalentsOrderLowLevel.11.2 = +AiPlayerbot.DefaultTalentsOrder.11.2 = 05320001--230033312031512531153313051 # no idea - TC was requesting these.. so.. AiPlayerbot.RandomClassSpecProbability.0.0 = 33 +AiPlayerbot.DefaultTalentsOrderLowLevel.0.0 = AiPlayerbot.DefaultTalentsOrder.0.0 = AiPlayerbot.RandomClassSpecProbability.0.1 = 33 +AiPlayerbot.DefaultTalentsOrderLowLevel.0.1 = AiPlayerbot.DefaultTalentsOrder.0.1 = AiPlayerbot.RandomClassSpecProbability.0.2 = 33 +AiPlayerbot.DefaultTalentsOrderLowLevel.0.2 = AiPlayerbot.DefaultTalentsOrder.0.2 = AiPlayerbot.RandomClassSpecProbability.10.0 = 33 +AiPlayerbot.DefaultTalentsOrderLowLevel.10.0 = AiPlayerbot.DefaultTalentsOrder.10.0 = AiPlayerbot.RandomClassSpecProbability.10.1 = 33 +AiPlayerbot.DefaultTalentsOrderLowLevel.10.1 = AiPlayerbot.DefaultTalentsOrder.10.1 = AiPlayerbot.RandomClassSpecProbability.10.2 = 33 +AiPlayerbot.DefaultTalentsOrderLowLevel.10.2 = AiPlayerbot.DefaultTalentsOrder.10.2 = diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index cc30d8f5..95dd91fd 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -169,11 +169,25 @@ bool PlayerbotAIConfig::Initialize() os.clear(); os << "AiPlayerbot.DefaultTalentsOrder." << cls << "." << spec; std::string temp_talents_order = sConfigMgr->GetOption(os.str().c_str(), ""); - defaultTalentsOrder[cls][spec] = ParseTempTalentsOrder(temp_talents_order); + defaultTalentsOrder[cls][spec] = ParseTempTalentsOrder(cls, temp_talents_order); if (defaultTalentsOrder[cls][spec].size() > 0) { sLog->outMessage("playerbot", LOG_LEVEL_INFO, "default talents order for cls %d spec %d loaded.", cls, spec); } } + for (uint32 spec = 0; spec < 3; ++spec) + { + std::ostringstream os; + os << "AiPlayerbot.RandomClassSpecProbability." << cls << "." << spec; + specProbability[cls][spec] = sConfigMgr->GetOption(os.str().c_str(), 33); + os.str(""); + os.clear(); + os << "AiPlayerbot.DefaultTalentsOrderLowLevel." << cls << "." << spec; + std::string temp_talents_order = sConfigMgr->GetOption(os.str().c_str(), ""); + defaultTalentsOrderLowLevel[cls][spec] = ParseTempTalentsOrder(cls, temp_talents_order); + if (defaultTalentsOrderLowLevel[cls][spec].size() > 0) { + sLog->outMessage("playerbot", LOG_LEVEL_INFO, "default low level talents order for cls %d spec %d loaded.", cls, spec); + } + } } for (uint32 cls = 1; cls < MAX_CLASSES; ++cls) @@ -539,15 +553,83 @@ static std::vector split(const std::string &str, const std::string return res; } -std::vector> PlayerbotAIConfig::ParseTempTalentsOrder(std::string temp_talents_order) { +std::vector> PlayerbotAIConfig::ParseTempTalentsOrder(uint32 cls, std::string tab_link) { + // check bad link + uint32 classMask = 1 << (cls - 1); std::vector> res; - std::vector pieces = split(temp_talents_order, ","); - for (std::string piece : pieces) { - uint32 tab, row, col, lvl; - if (sscanf(piece.c_str(), "%u-%u-%u-%u", &tab, &row, &col, &lvl) == -1) { + std::vector tab_links = split(tab_link, "-"); + std::map> spells; + std::vector>> orders(3); + // orders.assign(3); + for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + if(!talentInfo) + continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + if(!talentTabInfo) + continue; + + if( (classMask & talentTabInfo->ClassMask) == 0 ) + continue; + + spells[talentTabInfo->tabpage].push_back(talentInfo); + } + for (int tab = 0; tab < 3; tab++) { + if (tab_links.size() <= tab) { break; } - res.push_back({tab, row, col, lvl}); + std::sort(spells[tab].begin(), spells[tab].end(), [&](TalentEntry const* lhs, TalentEntry const* rhs) { + return lhs->Row != rhs->Row ? lhs->Row < rhs->Row : lhs->Col < rhs->Col; + }); + for (int i = 0; i < tab_links[tab].size(); i++) { + if (i >= spells[tab].size()) { + break; + } + int lvl = tab_links[tab][i] - '0'; + if (lvl == 0) continue; + orders[tab].push_back({tab, spells[tab][i]->Row, spells[tab][i]->Col, lvl}); + } } + // sort by talent tab size + std::sort(orders.begin(), orders.end(), [&](auto &lhs, auto &rhs) { + return lhs.size() > rhs.size(); + }); + for (auto &order : orders) { + res.insert(res.end(), order.begin(), order.end()); + } + // for (std::vector &p : sPlayerbotAIConfig->defaultTalentsOrder[bot->getClass()][specNo]) { + // uint32 tab = p[0], row = p[1], col = p[2], lvl = p[3]; + // uint32 talentID = -1; + + // std::vector &spells = spells_row[row]; + // assert(spells.size() > 0); + // for (TalentEntry const* talentInfo : spells) { + // if (talentInfo->Col != col) { + // continue; + // } + // TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + // if (talentTabInfo->tabpage != tab) { + // continue; + // } + // talentID = talentInfo->TalentID; + // } + // assert(talentID != -1); + // bot->LearnTalent(talentID, std::min(lvl, bot->GetFreeTalentPoints()) - 1); + // if (bot->GetFreeTalentPoints() == 0) { + // break; + // } + // } + // // for (int tab = 0; tab < 3; tab++) { + + // // } + // for (std::string piece : pieces) { + // uint32 tab, row, col, lvl; + // if (sscanf(piece.c_str(), "%u-%u-%u-%u", &tab, &row, &col, &lvl) == -1) { + // break; + // } + // res.push_back({tab, row, col, lvl}); + // } return res; } \ No newline at end of file diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index 92368088..2f8bfdc9 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -87,6 +87,7 @@ class PlayerbotAIConfig uint32 specProbability[MAX_CLASSES][10]; // [(tab, row, col, level)] std::vector> defaultTalentsOrder[MAX_CLASSES][3]; + std::vector> defaultTalentsOrderLowLevel[MAX_CLASSES][3]; std::string premadeLevelSpec[MAX_CLASSES][10][91]; //lvl 10 - 100 ClassSpecs classSpecs[MAX_CLASSES]; std::string commandPrefix, commandSeparator; @@ -177,7 +178,7 @@ class PlayerbotAIConfig void loadWorldBuf(uint32 factionId, uint32 classId, uint32 minLevel, uint32 maxLevel); private: - std::vector> ParseTempTalentsOrder(std::string temp_talents_order); + std::vector> ParseTempTalentsOrder(uint32 cls, std::string temp_talents_order); }; #define sPlayerbotAIConfig PlayerbotAIConfig::instance() diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 689dbd15..d297de82 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -2053,12 +2053,46 @@ void PlayerbotFactory::InitTalentsByTemplate(uint32 specNo) } // bot->SaveToDB(); + if (bot->GetLevel() < 80 && sPlayerbotAIConfig->defaultTalentsOrder[bot->getClass()][specNo].size() != 0) { + for (std::vector &p : sPlayerbotAIConfig->defaultTalentsOrderLowLevel[bot->getClass()][specNo]) { + uint32 tab = p[0], row = p[1], col = p[2], lvl = p[3]; + uint32 talentID = -1; + + std::vector &spells = spells_row[row]; + if (spells.size() <= 0) { + return; + } + // assert(spells.size() > 0); + for (TalentEntry const* talentInfo : spells) { + if (talentInfo->Col != col) { + continue; + } + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + if (talentTabInfo->tabpage != tab) { + continue; + } + if (talentInfo->DependsOn) { + bot->LearnTalent(talentInfo->DependsOn, std::min(talentInfo->DependsOnRank, bot->GetFreeTalentPoints() - 1)); + } + talentID = talentInfo->TalentID; + } + assert(talentID != -1); + bot->LearnTalent(talentID, std::min(lvl, bot->GetFreeTalentPoints()) - 1); + if (bot->GetFreeTalentPoints() == 0) { + break; + } + } + } + for (std::vector &p : sPlayerbotAIConfig->defaultTalentsOrder[bot->getClass()][specNo]) { uint32 tab = p[0], row = p[1], col = p[2], lvl = p[3]; uint32 talentID = -1; std::vector &spells = spells_row[row]; - assert(spells.size() > 0); + if (spells.size() <= 0) { + return; + } + // assert(spells.size() > 0); for (TalentEntry const* talentInfo : spells) { if (talentInfo->Col != col) { continue; @@ -2067,6 +2101,9 @@ void PlayerbotFactory::InitTalentsByTemplate(uint32 specNo) if (talentTabInfo->tabpage != tab) { continue; } + if (talentInfo->DependsOn) { + bot->LearnTalent(talentInfo->DependsOn, std::min(talentInfo->DependsOnRank, bot->GetFreeTalentPoints() - 1)); + } talentID = talentInfo->TalentID; } assert(talentID != -1);