rndbot teleport to city

This commit is contained in:
Yunfan Li
2023-10-27 21:54:35 +08:00
parent 966c33f944
commit 917e55c92a
5 changed files with 127 additions and 345 deletions

View File

@@ -99,6 +99,7 @@ bool PlayerbotAIConfig::Initialize()
randomBotMapsAsString = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotMaps", "0,1,530,571");
LoadList<std::vector<uint32>>(randomBotMapsAsString, randomBotMaps);
probTeleToBankers = sConfigMgr->GetOption<float>("AiPlayerbot.ProbTeleToBankers", 0.25f);
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestItems", "6948,5175,5176,5177,5178,16309,12382,13704,11000"), randomBotQuestItems);
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotSpellIds", "54197"), randomBotSpellIds);
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.PvpProhibitedZoneIds", "2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565,3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395"), pvpProhibitedZoneIds);
@@ -190,65 +191,65 @@ bool PlayerbotAIConfig::Initialize()
}
}
for (uint32 cls = 1; cls < MAX_CLASSES; ++cls)
{
classSpecs[cls] = ClassSpecs(1 << (cls - 1));
// for (uint32 cls = 1; cls < MAX_CLASSES; ++cls)
// {
// classSpecs[cls] = ClassSpecs(1 << (cls - 1));
for (uint32 spec = 0; spec < MAX_LEVEL; ++spec)
{
std::ostringstream os;
os << "AiPlayerbot.PremadeSpecName." << cls << "." << spec;
// for (uint32 spec = 0; spec < MAX_LEVEL; ++spec)
// {
// std::ostringstream os;
// os << "AiPlayerbot.PremadeSpecName." << cls << "." << spec;
std::string const specName = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
if (!specName.empty())
{
std::ostringstream os;
os << "AiPlayerbot.PremadeSpecProb." << cls << "." << spec;
uint32 probability = sConfigMgr->GetOption<int32>(os.str().c_str(), 100, false);
// std::string const specName = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
// if (!specName.empty())
// {
// std::ostringstream os;
// os << "AiPlayerbot.PremadeSpecProb." << cls << "." << spec;
// uint32 probability = sConfigMgr->GetOption<int32>(os.str().c_str(), 100, false);
TalentPath talentPath(spec, specName, probability);
// TalentPath talentPath(spec, specName, probability);
for (uint32 level = 10; level <= 80; level++)
{
std::ostringstream os;
os << "AiPlayerbot.PremadeSpecLink." << cls << "." << spec << "." << level;
// for (uint32 level = 10; level <= 80; level++)
// {
// std::ostringstream os;
// os << "AiPlayerbot.PremadeSpecLink." << cls << "." << spec << "." << level;
std::string specLink = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
specLink = specLink.substr(0, specLink.find("#", 0));;
specLink = specLink.substr(0, specLink.find(" ", 0));;
// std::string specLink = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
// specLink = specLink.substr(0, specLink.find("#", 0));;
// specLink = specLink.substr(0, specLink.find(" ", 0));;
if (!specLink.empty())
{
std::ostringstream out;
// if (!specLink.empty())
// {
// std::ostringstream out;
// Ignore bad specs.
if (!classSpecs[cls].baseSpec.CheckTalentLink(specLink, &out))
{
LOG_ERROR("playerbots", "Error with premade spec link: {}", specLink.c_str());
LOG_ERROR("playerbots", "{}", out.str().c_str());
continue;
}
// // Ignore bad specs.
// if (!classSpecs[cls].baseSpec.CheckTalentLink(specLink, &out))
// {
// LOG_ERROR("playerbots", "Error with premade spec link: {}", specLink.c_str());
// LOG_ERROR("playerbots", "{}", out.str().c_str());
// continue;
// }
TalentSpec linkSpec(&classSpecs[cls].baseSpec, specLink);
// TalentSpec linkSpec(&classSpecs[cls].baseSpec, specLink);
if (!linkSpec.CheckTalents(level, &out))
{
LOG_ERROR("playerbots", "Error with premade spec: {}", specLink.c_str());
LOG_ERROR("playerbots", "{}", out.str().c_str());
continue;
}
// if (!linkSpec.CheckTalents(level, &out))
// {
// LOG_ERROR("playerbots", "Error with premade spec: {}", specLink.c_str());
// LOG_ERROR("playerbots", "{}", out.str().c_str());
// continue;
// }
talentPath.talentSpec.push_back(linkSpec);
}
}
// talentPath.talentSpec.push_back(linkSpec);
// }
// }
// Only add paths that have atleast 1 spec.
if (talentPath.talentSpec.size() > 0)
classSpecs[cls].talentPath.push_back(talentPath);
}
}
}
// // Only add paths that have atleast 1 spec.
// if (talentPath.talentSpec.size() > 0)
// classSpecs[cls].talentPath.push_back(talentPath);
// }
// }
// }
botCheats.clear();
LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.BotCheats", "taxi"), botCheats);

View File

@@ -51,6 +51,7 @@ class PlayerbotAIConfig
bool randomBotAutologin;
bool botAutologin;
std::string randomBotMapsAsString;
float probTeleToBankers;
std::vector<uint32> randomBotMaps;
std::vector<uint32> randomBotQuestItems;
std::vector<uint32> randomBotAccounts;

View File

@@ -968,7 +968,7 @@ void RandomPlayerbotMgr::Revive(Player* player)
SetEventValue(bot, "revive", 0, 0);
RandomTeleportForLevel(player);
RandomTeleportGrindForLevel(player);
Refresh(player);
}
@@ -1004,30 +1004,12 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
std::vector<uint32>::iterator i = find(sPlayerbotAIConfig->randomBotMaps.begin(), sPlayerbotAIConfig->randomBotMaps.end(), l.getMapId());
return i == sPlayerbotAIConfig->randomBotMaps.end();
}), tlocs.end());
// LOG_INFO("playerbots", "Locs {} after disabled in config.", tlocs.size());
// Check locs again in case all possible locations were removed
if (tlocs.empty())
{
LOG_DEBUG("playerbots", "Cannot teleport bot {} - all locations removed by filter", bot->GetName().c_str());
return;
}
//Random shuffle based on distance. Closer distances are more likely (but not exclusivly) to be at the begin of the list.
// tlocs = sTravelMgr->getNextPoint(WorldPosition(bot), tlocs, 0);
// LOG_INFO("playerbots", "Locs {} after shuffled.", tlocs.size());
// 5% + 0.1% per level chance node on different map in selection.
// tlocs.erase(std::remove_if(tlocs.begin(), tlocs.end(), [bot](WorldLocation const& l)
// {
// return l.GetMapId() != bot->GetMapId() && urand(1, 100) > 5 + 0.1 * bot->getLevel();
// }), tlocs.end());
// LOG_INFO("playerbots", "Locs {} after remove different maps.", tlocs.size());
// Continent is about 20.000 large
// Bot will travel 0-5000 units + 75-150 units per level.
// tlocs.erase(std::remove_if(tlocs.begin(), tlocs.end(), [bot](WorldLocation const& l)
// {
// return sServerFacade->GetDistance2d(bot, l.GetPositionX(), l.GetPositionY()) > urand(0, 5000) + bot->getLevel() * 15 * urand(5, 10);
// }), tlocs.end());
// LOG_INFO("playerbots", "Locs {} after remove too far away.", tlocs.size());
if (tlocs.empty())
{
LOG_DEBUG("playerbots", "Cannot teleport bot {} - no locations available", bot->GetName().c_str());
@@ -1166,6 +1148,60 @@ void RandomPlayerbotMgr::PrepareTeleportCache()
}
LOG_INFO("playerbots", "{} locations for level collected.", collected_locs);
results = WorldDatabase.Query(
"SELECT "
"map, "
"position_x, "
"position_y, "
"position_z, "
"orientation, "
"t.minlevel "
"FROM "
"creature c "
"INNER JOIN creature_template t on c.id1 = t.entry "
"WHERE "
"t.npcflag & 131072 "
"AND t.npcflag != 135298 "
"AND t.minlevel != 55 "
"AND t.minlevel != 65 "
"AND t.faction != 35 "
"AND t.faction != 474 "
"AND map IN ({}) "
"ORDER BY "
"t.minlevel;", sPlayerbotAIConfig->randomBotMapsAsString.c_str());
collected_locs = 0;
if (results)
{
do
{
Field* fields = results->Fetch();
uint16 mapId = fields[0].Get<uint16>();
float x = fields[1].Get<float>();
float y = fields[2].Get<float>();
float z = fields[3].Get<float>();
float orient = fields[4].Get<float>();
uint32 level = fields[5].Get<uint32>();
WorldLocation loc(mapId, x + cos(orient) * 10.0f, y + sin(orient) * 10.0f, z, orient + M_PI);
collected_locs++;
for (int32 l = 1; l <= maxLevel; l++) {
if (l <= 60 && level >= 60) {
continue;
}
if (l <= 70 && level >= 70) {
continue;
}
if (l >= 70 && level >= 60 && level <= 70) {
continue;
}
if (l >= 30 && level <= 30) {
continue;
}
bankerLocsPerLevelCache[(uint8)l].push_back(loc);
}
} while (results->NextRow());
}
LOG_INFO("playerbots", "{} banker locations for level collected.", collected_locs);
// temporary only use locsPerLevelCache, so disable rpgLocsCacheLevel cache
// LOG_INFO("playerbots", "Preparing RPG teleport caches for {} factions...", sFactionTemplateStore.GetNumRows());
@@ -1208,6 +1244,22 @@ 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());
if (urand(0, 100) < sPlayerbotAIConfig->probTeleToBankers * 100) {
RandomTeleport(bot, bankerLocsPerLevelCache[level], true);
} else {
RandomTeleport(bot, locsPerLevelCache[level]);
}
}
void RandomPlayerbotMgr::RandomTeleportGrindForLevel(Player* bot)
{
if (bot->InBattleground())
return;
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());
RandomTeleport(bot, locsPerLevelCache[level]);
}

View File

@@ -69,6 +69,7 @@ class RandomPlayerbotMgr : public PlayerbotHolder
uint32 GetTradeDiscount(Player* bot, Player* master);
void Refresh(Player* bot);
void RandomTeleportForLevel(Player* bot);
void RandomTeleportGrindForLevel(Player* bot);
void RandomTeleportForRpg(Player* bot);
uint32 GetMaxAllowedBotCount();
bool ProcessBot(Player* player);
@@ -122,6 +123,8 @@ class RandomPlayerbotMgr : public PlayerbotHolder
std::vector<Player*> players;
uint32 processTicks;
std::map<uint8, std::vector<WorldLocation>> locsPerLevelCache;
std::map<uint8, std::vector<WorldLocation>> bankerLocsPerLevelCache;
// std::map<uint32, std::vector<WorldLocation>> rpgLocsCache;
std::map<uint32, std::map<uint32, std::vector<WorldLocation>>> rpgLocsCacheLevel;
std::map<TeamId, std::map<BattlegroundTypeId, std::vector<uint32>>> BattleMastersCache;