[Bots] Fix creation limit, spawn limit, level requirement checks (#4868)

* [Bots] Fix creation limit, spawn limit, level requirement checks

- Previously if buckets were being used to control any of these values and the appropriate rule was set to 0, unset class specific buckets would override the main limit buckets.
- For example, if `Bots:SpawnLimit` is set to `0` and a player has their `bot_spawn_limit` set to `5` but they don't have a class bucket set for the class they're attempting to spawn a Cleric, the unset `bot_spawn_limit_Cleric` would return 0 and prevent Clerics from being spawned.
- This affected spawn limits, creation limits and level requirements to use bots if controlled by buckets.
- `#gm on` is required to be on for those beyond the ruled min status requirements to bypass the limits.

Rewrote checks and tested every scenario of set unset rules/buckets.

* Cleanup, fix bot count

- Fixes QueryBotCount to not account for soft deleted bots (`-deleted-`)
This commit is contained in:
nytmyr 2025-05-14 20:13:50 -05:00 committed by GitHub
parent 780120036d
commit 4de8fbbd56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 181 additions and 255 deletions

View File

@ -878,6 +878,7 @@ RULE_INT(Bots, MinStatusToBypassSpawnLimit, 100, "Minimum status to bypass spawn
RULE_INT(Bots, MinStatusBypassSpawnLimit, 120, "Spawn limit with status bypass. Default 120.") RULE_INT(Bots, MinStatusBypassSpawnLimit, 120, "Spawn limit with status bypass. Default 120.")
RULE_INT(Bots, MinStatusToBypassCreateLimit, 100, "Minimum status to bypass create limit. Default 100.") RULE_INT(Bots, MinStatusToBypassCreateLimit, 100, "Minimum status to bypass create limit. Default 100.")
RULE_INT(Bots, MinStatusBypassCreateLimit, 120, "Create limit with status bypass. Default 120.") RULE_INT(Bots, MinStatusBypassCreateLimit, 120, "Create limit with status bypass. Default 120.")
RULE_INT(Bots, MinStatusToBypassBotLevelRequirement, 100, "Minimum status to bypass level requirement for bots. Default 100.")
RULE_BOOL(Bots, EnableBotTGB, true, "If enabled bots will cast group buffs as TGB.") RULE_BOOL(Bots, EnableBotTGB, true, "If enabled bots will cast group buffs as TGB.")
RULE_BOOL(Bots, DoResponseAnimations, true, "If enabled bots will do animations to certain responses or commands.") RULE_BOOL(Bots, DoResponseAnimations, true, "If enabled bots will do animations to certain responses or commands.")
RULE_INT(Bots, DefaultFollowDistance, 20, "Default 20. Distance a bot will follow behind.") RULE_INT(Bots, DefaultFollowDistance, 20, "Default 20. Distance a bot will follow behind.")

View File

@ -8715,6 +8715,86 @@ bool Bot::CheckCampSpawnConditions(Client* c) {
return true; return true;
} }
bool Bot::CheckHighEnoughLevelForBots(Client* c, uint8 bot_class) {
auto bot_character_level = c->GetBotRequiredLevel(bot_class);
bool not_high_enough_level = bot_character_level >= 0 && c->GetLevel() < bot_character_level;
if (not_high_enough_level) {
c->Message(
Chat::White,
fmt::format(
"You must be level {} to spawn {}bots.",
bot_character_level,
bot_class ? GetClassIDName(bot_class) : ""
).c_str()
);
return false;
}
return true;
}
bool Bot::CheckCreateLimit(Client* c, uint32 bot_count, uint8 bot_class) {
auto bot_creation_limit = c->GetBotCreationLimit(bot_class);
bool is_beyond_spawn_limit = bot_creation_limit >= 0 && bot_count >= bot_creation_limit;
if (is_beyond_spawn_limit) {
std::string message;
if (bot_creation_limit) {
message = fmt::format(
"You cannot create anymore than {} {}bot{}.",
bot_creation_limit,
bot_class ? GetClassIDName(bot_class) : "",
bot_creation_limit != 1 ? "s" : ""
);
} else {
message = fmt::format(
"You cannot create any {}bots.",
bot_class ? GetClassIDName(bot_class) : ""
);
}
c->Message(Chat::Yellow, message.c_str());
return false;
}
return true;
}
bool Bot::CheckSpawnLimit(Client* c, uint8 bot_class) {
auto bot_spawn_limit = c->GetBotSpawnLimit(bot_class);
auto spawned_bot_count = Bot::SpawnedBotCount(c->CharacterID(), bot_class);
bool is_beyond_spawn_limit = bot_spawn_limit >= 0 && spawned_bot_count >= bot_spawn_limit;
if (is_beyond_spawn_limit) {
std::string message;
if (bot_spawn_limit) {
message = fmt::format(
"You cannot have more than {} spawned {}bot{}.",
bot_spawn_limit,
bot_class ? GetClassIDName(bot_class) : "",
bot_spawn_limit != 1 ? "s" : ""
);
}
else {
message = fmt::format(
"You are not currently allowed to spawn any {}bots.",
bot_class ? GetClassIDName(bot_class) : ""
);
}
c->Message(Chat::White, message.c_str());
return false;
}
return true;
}
void Bot::AddBotStartingItems(uint16 race_id, uint8 class_id) void Bot::AddBotStartingItems(uint16 race_id, uint8 class_id)
{ {
if (!IsPlayerRace(race_id) || !IsPlayerClass(class_id)) { if (!IsPlayerRace(race_id) || !IsPlayerClass(class_id)) {

View File

@ -1105,6 +1105,9 @@ public:
// Public "Refactor" Methods // Public "Refactor" Methods
static bool CheckCampSpawnConditions(Client* c); static bool CheckCampSpawnConditions(Client* c);
static bool CheckHighEnoughLevelForBots(Client* c, uint8 bot_class = Class::None);
static bool CheckCreateLimit(Client* c, uint32 bot_count, uint8 bot_class = Class::None);
static bool CheckSpawnLimit(Client* c, uint8 bot_class = Class::None);
protected: protected:
void BotMeditate(bool is_sitting); void BotMeditate(bool is_sitting);

View File

@ -517,88 +517,31 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
return bot_id; return bot_id;
} }
auto bot_creation_limit = bot_owner->GetBotCreationLimit(); if (!Bot::CheckHighEnoughLevelForBots(bot_owner)) {
auto bot_creation_limit_class = bot_owner->GetBotCreationLimit(bot_class); return bot_id;
}
if (!Bot::CheckHighEnoughLevelForBots(bot_owner, bot_class)) {
return bot_id;
}
uint32 bot_count = 0; uint32 bot_count = 0;
uint32 bot_class_count = 0; uint32 bot_class_count = 0;
if (!database.botdb.QueryBotCount(bot_owner->CharacterID(), bot_class, bot_count, bot_class_count)) { if (!database.botdb.QueryBotCount(bot_owner->CharacterID(), bot_class, bot_count, bot_class_count)) {
bot_owner->Message(Chat::Yellow, "Failed to query bot count."); bot_owner->Message(Chat::Yellow, "Failed to query bot count.");
return bot_id; return bot_id;
} }
if (bot_creation_limit >= 0 && bot_count >= bot_creation_limit) { if (!Bot::CheckCreateLimit(bot_owner, bot_count)) {
std::string message;
if (bot_creation_limit) {
message = fmt::format(
"You cannot create anymore than {} bot{}.",
bot_creation_limit,
bot_creation_limit != 1 ? "s" : ""
);
} else {
message = "You cannot create any bots.";
}
bot_owner->Message(Chat::Yellow, message.c_str());
return bot_id; return bot_id;
} }
if (bot_creation_limit_class >= 0 && bot_class_count >= bot_creation_limit_class) { if (!Bot::CheckCreateLimit(bot_owner, bot_class_count, bot_class)) {
std::string message;
if (bot_creation_limit_class) {
message = fmt::format(
"You cannot create anymore than {} {} bot{}.",
bot_creation_limit_class,
GetClassIDName(bot_class),
bot_creation_limit_class != 1 ? "s" : ""
);
} else {
message = fmt::format(
"You cannot create any {} bots.",
GetClassIDName(bot_class)
);
}
bot_owner->Message(Chat::Yellow, message.c_str());
return bot_id; return bot_id;
} }
auto bot_character_level = bot_owner->GetBotRequiredLevel();
if (
bot_character_level >= 0 &&
bot_owner->GetLevel() < bot_character_level
) {
bot_owner->Message(
Chat::Yellow,
fmt::format(
"You must be level {} to use bots.",
bot_character_level
).c_str()
);
return bot_id;
}
auto bot_character_level_class = bot_owner->GetBotRequiredLevel(bot_class);
if (
bot_character_level_class >= 0 &&
bot_owner->GetLevel() < bot_character_level_class
) {
bot_owner->Message(
Chat::Yellow,
fmt::format(
"You must be level {} to use {} bots.",
bot_character_level_class,
GetClassIDName(bot_class)
).c_str()
);
return bot_id;
}
auto my_bot = new Bot(Bot::CreateDefaultNPCTypeStructForBot(bot_name, "", bot_owner->GetLevel(), bot_race, bot_class, bot_gender), bot_owner); auto my_bot = new Bot(Bot::CreateDefaultNPCTypeStructForBot(bot_name, "", bot_owner->GetLevel(), bot_race, bot_class, bot_gender), bot_owner);
if (!my_bot->Save()) { if (!my_bot->Save()) {

View File

@ -144,55 +144,25 @@ void bot_command_clone(Client *c, const Seperator *sep)
return; return;
} }
auto bot_creation_limit = c->GetBotCreationLimit();
auto bot_creation_limit_class = c->GetBotCreationLimit(my_bot->GetClass());
uint32 bot_count = 0; uint32 bot_count = 0;
uint32 bot_class_count = 0; uint32 bot_class_count = 0;
if (!database.botdb.QueryBotCount(c->CharacterID(), my_bot->GetClass(), bot_count, bot_class_count)) { if (!database.botdb.QueryBotCount(c->CharacterID(), my_bot->GetClass(), bot_count, bot_class_count)) {
c->Message(Chat::White, "Failed to query bot count."); c->Message(Chat::Yellow, "Failed to query bot count.");
return; return;
} }
if (bot_creation_limit >= 0 && bot_count >= bot_creation_limit) { if (!Bot::CheckCreateLimit(c, bot_count)) {
std::string message;
if (bot_creation_limit) {
message = fmt::format(
"You have reached the maximum limit of {} bot{}.",
bot_creation_limit,
bot_creation_limit != 1 ? "s" : ""
);
} else {
message = "You cannot create any bots.";
}
c->Message(Chat::White, message.c_str());
return; return;
} }
if (bot_creation_limit_class >= 0 && bot_class_count >= bot_creation_limit_class) { if (!Bot::CheckCreateLimit(c, bot_class_count, my_bot->GetClass())) {
std::string message;
if (bot_creation_limit_class) {
message = fmt::format(
"You cannot create anymore than {} {} bot{}.",
bot_creation_limit_class,
GetClassIDName(my_bot->GetClass()),
bot_creation_limit_class != 1 ? "s" : ""
);
} else {
message = fmt::format(
"You cannot create any {} bots.",
GetClassIDName(my_bot->GetClass())
);
}
c->Message(Chat::White, message.c_str());
return; return;
} }
uint32 clone_id = 0; uint32 clone_id = 0;
if (!database.botdb.CreateCloneBot(my_bot->GetBotID(), bot_name, clone_id) || !clone_id) { if (!database.botdb.CreateCloneBot(my_bot->GetBotID(), bot_name, clone_id) || !clone_id) {
c->Message( c->Message(
Chat::White, Chat::White,
@ -205,6 +175,7 @@ void bot_command_clone(Client *c, const Seperator *sep)
} }
int clone_stance = Stance::Passive; int clone_stance = Stance::Passive;
if (!database.botdb.LoadStance(my_bot->GetBotID(), clone_stance)) { if (!database.botdb.LoadStance(my_bot->GetBotID(), clone_stance)) {
c->Message( c->Message(
Chat::White, Chat::White,
@ -729,6 +700,7 @@ void bot_command_list_bots(Client *c, const Seperator *sep)
return; return;
} }
int NO_BOT_LIMIT = -1;
bool Account = false; bool Account = false;
int seps = 1; int seps = 1;
uint32 filter_value[FilterCount]; uint32 filter_value[FilterCount];
@ -867,7 +839,7 @@ void bot_command_list_bots(Client *c, const Seperator *sep)
for (uint8 class_id = Class::Warrior; class_id <= Class::Berserker; class_id++) { for (uint8 class_id = Class::Warrior; class_id <= Class::Berserker; class_id++) {
auto class_creation_limit = c->GetBotCreationLimit(class_id); auto class_creation_limit = c->GetBotCreationLimit(class_id);
if (class_creation_limit != overall_bot_creation_limit) { if (class_creation_limit != NO_BOT_LIMIT && class_creation_limit != overall_bot_creation_limit) {
c->Message( c->Message(
Chat::White, Chat::White,
fmt::format( fmt::format(
@ -938,20 +910,7 @@ void bot_command_spawn(Client *c, const Seperator *sep)
return; return;
} }
auto bot_character_level = c->GetBotRequiredLevel(); if (!Bot::CheckHighEnoughLevelForBots(c)) {
if (
bot_character_level >= 0 &&
c->GetLevel() < bot_character_level &&
!c->GetGM()
) {
c->Message(
Chat::White,
fmt::format(
"You must be level {} to spawn bots.",
bot_character_level
).c_str()
);
return; return;
} }
@ -959,27 +918,7 @@ void bot_command_spawn(Client *c, const Seperator *sep)
return; return;
} }
auto bot_spawn_limit = c->GetBotSpawnLimit(); if (!Bot::CheckSpawnLimit(c)) {
auto spawned_bot_count = Bot::SpawnedBotCount(c->CharacterID());
if (
bot_spawn_limit >= 0 &&
spawned_bot_count >= bot_spawn_limit &&
!c->GetGM()
) {
std::string message;
if (bot_spawn_limit) {
message = fmt::format(
"You cannot have more than {} spawned bot{}.",
bot_spawn_limit,
bot_spawn_limit != 1 ? "s" : ""
);
} else {
message = "You are not currently allowed to spawn any bots.";
}
c->Message(Chat::White, message.c_str());
return; return;
} }
@ -1004,52 +943,6 @@ void bot_command_spawn(Client *c, const Seperator *sep)
return; return;
} }
auto bot_spawn_limit_class = c->GetBotSpawnLimit(bot_class);
auto spawned_bot_count_class = Bot::SpawnedBotCount(c->CharacterID(), bot_class);
if (
bot_spawn_limit_class >= 0 &&
spawned_bot_count_class >= bot_spawn_limit_class &&
!c->GetGM()
) {
std::string message;
if (bot_spawn_limit_class) {
message = fmt::format(
"You cannot have more than {} spawned {} bot{}.",
bot_spawn_limit_class,
GetClassIDName(bot_class),
bot_spawn_limit_class != 1 ? "s" : ""
);
} else {
message = fmt::format(
"You are not currently allowed to spawn any {} bots.",
GetClassIDName(bot_class)
);
}
c->Message(Chat::White, message.c_str());
return;
}
auto bot_character_level_class = c->GetBotRequiredLevel(bot_class);
if (
bot_character_level_class >= 0 &&
c->GetLevel() < bot_character_level_class &&
!c->GetGM()
) {
c->Message(
Chat::White,
fmt::format(
"You must be level {} to spawn {} bots.",
bot_character_level_class,
GetClassIDName(bot_class)
).c_str()
);
return;
}
if (!bot_id) { if (!bot_id) {
c->Message( c->Message(
Chat::White, Chat::White,
@ -1061,6 +954,14 @@ void bot_command_spawn(Client *c, const Seperator *sep)
return; return;
} }
if (!Bot::CheckHighEnoughLevelForBots(c, bot_class)) {
return;
}
if (!Bot::CheckSpawnLimit(c, bot_class)) {
return;
}
if (entity_list.GetMobByBotID(bot_id)) { if (entity_list.GetMobByBotID(bot_id)) {
c->Message( c->Message(
Chat::White, Chat::White,
@ -1069,6 +970,7 @@ void bot_command_spawn(Client *c, const Seperator *sep)
bot_name bot_name
).c_str() ).c_str()
); );
return; return;
} }
@ -1083,6 +985,7 @@ void bot_command_spawn(Client *c, const Seperator *sep)
bot_id bot_id
).c_str() ).c_str()
); );
return; return;
} }
@ -1097,6 +1000,7 @@ void bot_command_spawn(Client *c, const Seperator *sep)
); );
safe_delete(my_bot); safe_delete(my_bot);
return; return;
} }
@ -1121,6 +1025,7 @@ void bot_command_spawn(Client *c, const Seperator *sep)
}; };
uint8 message_index = 0; uint8 message_index = 0;
if (c->GetBotOption(Client::booSpawnMessageClassSpecific)) { if (c->GetBotOption(Client::booSpawnMessageClassSpecific)) {
message_index = VALIDATECLASSID(my_bot->GetClass()); message_index = VALIDATECLASSID(my_bot->GetClass());
} }

View File

@ -207,7 +207,7 @@ bool BotDatabase::QueryBotCount(const uint32 owner_id, int class_id, uint32& bot
bot_count = BotDataRepository::Count( bot_count = BotDataRepository::Count(
database, database,
fmt::format( fmt::format(
"`owner_id` = {}", "`owner_id` = {} AND `name` NOT LIKE '%-deleted-%'",
owner_id owner_id
) )
); );
@ -216,7 +216,7 @@ bool BotDatabase::QueryBotCount(const uint32 owner_id, int class_id, uint32& bot
bot_class_count = BotDataRepository::Count( bot_class_count = BotDataRepository::Count(
database, database,
fmt::format( fmt::format(
"`owner_id` = {} AND `class` = {}", "`owner_id` = {} AND `class` = {} AND `name` NOT LIKE '%-deleted-%'",
owner_id, owner_id,
class_id class_id
) )

View File

@ -1,6 +1,8 @@
#include "bot.h" #include "bot.h"
#include "client.h" #include "client.h"
#define NO_BOT_LIMIT -1;
bool Client::GetBotOption(BotOwnerOption boo) const { bool Client::GetBotOption(BotOwnerOption boo) const {
if (boo < _booCount) { if (boo < _booCount) {
return bot_owner_options[boo]; return bot_owner_options[boo];
@ -18,25 +20,25 @@ void Client::SetBotOption(BotOwnerOption boo, bool flag) {
uint32 Client::GetBotCreationLimit(uint8 class_id) { uint32 Client::GetBotCreationLimit(uint8 class_id) {
uint32 bot_creation_limit = RuleI(Bots, CreationLimit); uint32 bot_creation_limit = RuleI(Bots, CreationLimit);
if (Admin() >= RuleI(Bots, MinStatusToBypassCreateLimit)) { if (GetGM() && Admin() >= RuleI(Bots, MinStatusToBypassCreateLimit)) {
return RuleI(Bots, MinStatusBypassCreateLimit); return RuleI(Bots, MinStatusBypassCreateLimit);
} }
const auto bucket_name = fmt::format( const auto bucket_name = fmt::format(
"bot_creation_limit{}", "bot_creation_limit{}",
( class_id && IsPlayerClass(class_id) ?
class_id && IsPlayerClass(class_id) ? fmt::format("_{}", Strings::ToLower(GetClassIDName(class_id))) :
fmt::format(
"_{}",
Strings::ToLower(GetClassIDName(class_id))
) :
"" ""
)
); );
auto bucket_value = GetBucket(bucket_name); auto bucket_value = GetBucket(bucket_name);
if (!bucket_value.empty() && Strings::IsNumber(bucket_value)) { if (!bucket_value.empty() && Strings::IsNumber(bucket_value)) {
bot_creation_limit = Strings::ToUnsignedInt(bucket_value); bot_creation_limit = Strings::ToInt(bucket_value);
}
if (class_id && bucket_value.empty()) {
bot_creation_limit = NO_BOT_LIMIT;
} }
return bot_creation_limit; return bot_creation_limit;
@ -45,63 +47,55 @@ uint32 Client::GetBotCreationLimit(uint8 class_id) {
int Client::GetBotRequiredLevel(uint8 class_id) { int Client::GetBotRequiredLevel(uint8 class_id) {
int bot_character_level = RuleI(Bots, BotCharacterLevel); int bot_character_level = RuleI(Bots, BotCharacterLevel);
if (GetGM() && Admin() >= RuleI(Bots, MinStatusToBypassBotLevelRequirement)) {
return 0;
}
const auto bucket_name = fmt::format( const auto bucket_name = fmt::format(
"bot_required_level{}", "bot_required_level{}",
( class_id && IsPlayerClass(class_id) ?
class_id && IsPlayerClass(class_id) ? fmt::format("_{}", Strings::ToLower(GetClassIDName(class_id))) :
fmt::format(
"_{}",
Strings::ToLower(GetClassIDName(class_id))
) :
"" ""
)
); );
auto bucket_value = GetBucket(bucket_name); auto bucket_value = GetBucket(bucket_name);
if (!bucket_value.empty() && Strings::IsNumber(bucket_value)) { if (!bucket_value.empty() && Strings::IsNumber(bucket_value)) {
bot_character_level = Strings::ToInt(bucket_value); bot_character_level = Strings::ToInt(bucket_value);
} }
if (class_id && bucket_value.empty()) {
bot_character_level = NO_BOT_LIMIT;
}
return bot_character_level; return bot_character_level;
} }
int Client::GetBotSpawnLimit(uint8 class_id) { int Client::GetBotSpawnLimit(uint8 class_id)
{
int bot_spawn_limit = RuleI(Bots, SpawnLimit); int bot_spawn_limit = RuleI(Bots, SpawnLimit);
if (Admin() >= RuleI(Bots, MinStatusToBypassSpawnLimit)) { if (GetGM() && Admin() >= RuleI(Bots, MinStatusToBypassSpawnLimit)) {
return RuleI(Bots, MinStatusBypassSpawnLimit); return RuleI(Bots, MinStatusBypassSpawnLimit);
} }
const auto bucket_name = fmt::format( const auto bucket_name = fmt::format(
"bot_spawn_limit{}", "bot_spawn_limit{}",
( class_id && IsPlayerClass(class_id) ?
class_id && IsPlayerClass(class_id) ? fmt::format("_{}", Strings::ToLower(GetClassIDName(class_id))) :
fmt::format(
"_{}",
Strings::ToLower(GetClassIDName(class_id))
) :
"" ""
)
); );
auto bucket_value = GetBucket(bucket_name); auto bucket_value = GetBucket(bucket_name);
if (class_id && !bot_spawn_limit && bucket_value.empty()) {
const auto new_bucket_name = "bot_spawn_limit";
bucket_value = GetBucket(new_bucket_name);
if (!bucket_value.empty() && Strings::IsNumber(bucket_value)) {
bot_spawn_limit = Strings::ToInt(bucket_value);
return bot_spawn_limit;
}
}
if (!bucket_value.empty() && Strings::IsNumber(bucket_value)) { if (!bucket_value.empty() && Strings::IsNumber(bucket_value)) {
bot_spawn_limit = Strings::ToInt(bucket_value); bot_spawn_limit = Strings::ToInt(bucket_value);
} }
if (class_id && bucket_value.empty()) {
return NO_BOT_LIMIT;
}
if (RuleB(Bots, QuestableSpawnLimit)) { if (RuleB(Bots, QuestableSpawnLimit)) {
const auto query = fmt::format( const auto query = fmt::format(
"SELECT `value` FROM `quest_globals` WHERE `name` = '{}' AND `charid` = {} LIMIT 1", "SELECT `value` FROM `quest_globals` WHERE `name` = '{}' AND `charid` = {} LIMIT 1",
@ -111,53 +105,53 @@ int Client::GetBotSpawnLimit(uint8 class_id) {
auto results = database.QueryDatabase(query); // use 'database' for non-bot table calls auto results = database.QueryDatabase(query); // use 'database' for non-bot table calls
if (!results.Success() || !results.RowCount()) { if (results.Success() && results.RowCount()) {
return bot_spawn_limit; auto row = results.begin();
bot_spawn_limit = Strings::ToInt(row[0]);
} }
auto row = results.begin();
bot_spawn_limit = Strings::ToInt(row[0]);
} }
const auto& zones_list = Strings::Split(RuleS(Bots, ZonesWithSpawnLimits), ","); if (!class_id) {
const auto &zones_list = Strings::Split(RuleS(Bots, ZonesWithSpawnLimits), ",");
if (!zones_list.empty()) { if (!zones_list.empty()) {
auto it = std::find(zones_list.begin(), zones_list.end(), std::to_string(zone->GetZoneID())); auto it = std::find(zones_list.begin(), zones_list.end(), std::to_string(zone->GetZoneID()));
if (it != zones_list.end()) { if (it != zones_list.end()) {
const auto& zones_limits_list = Strings::Split(RuleS(Bots, ZoneSpawnLimits), ","); const auto &zones_limits_list = Strings::Split(RuleS(Bots, ZoneSpawnLimits), ",");
if (zones_list.size() == zones_limits_list.size()) { if (zones_list.size() == zones_limits_list.size()) {
try { try {
auto new_limit = std::stoul(zones_limits_list[std::distance(zones_list.begin(), it)]); auto new_limit = std::stoul(zones_limits_list[std::distance(zones_list.begin(), it)]);
if (new_limit < bot_spawn_limit) { if (new_limit < bot_spawn_limit) {
bot_spawn_limit = new_limit; bot_spawn_limit = new_limit;
}
} catch (const std::exception &e) {
LogInfo("Invalid entry in Rule Bots:ZoneSpawnLimits: [{}]", e.what());
} }
} catch (const std::exception& e) {
LogInfo("Invalid entry in Rule Bots:ZoneSpawnLimits: [{}]", e.what());
} }
} }
} }
}
const auto& zones_forced_list = Strings::Split(RuleS(Bots, ZonesWithForcedSpawnLimits), ","); const auto &zones_forced_list = Strings::Split(RuleS(Bots, ZonesWithForcedSpawnLimits), ",");
if (!zones_forced_list.empty()) { if (!zones_forced_list.empty()) {
auto it = std::find(zones_forced_list.begin(), zones_forced_list.end(), std::to_string(zone->GetZoneID())); auto it = std::find(zones_forced_list.begin(), zones_forced_list.end(), std::to_string(zone->GetZoneID()));
if (it != zones_forced_list.end()) { if (it != zones_forced_list.end()) {
const auto& zones_forced_limits_list = Strings::Split(RuleS(Bots, ZoneForcedSpawnLimits), ","); const auto &zones_forced_limits_list = Strings::Split(RuleS(Bots, ZoneForcedSpawnLimits), ",");
if (zones_forced_list.size() == zones_forced_limits_list.size()) { if (zones_forced_list.size() == zones_forced_limits_list.size()) {
try { try {
auto new_limit = std::stoul(zones_forced_limits_list[std::distance(zones_forced_list.begin(), it)]); auto new_limit = std::stoul(zones_forced_limits_list[std::distance(zones_forced_list.begin(), it)]);
if (new_limit != bot_spawn_limit) { if (new_limit != bot_spawn_limit) {
bot_spawn_limit = new_limit; bot_spawn_limit = new_limit;
}
} catch (const std::exception &e) {
LogInfo("Invalid entry in Rule Bots:ZoneForcedSpawnLimits: [{}]", e.what());
} }
} catch (const std::exception& e) {
LogInfo("Invalid entry in Rule Bots:ZoneForcedSpawnLimits: [{}]", e.what());
} }
} }
} }