Better bot config handling and logging

* Bot config is no longer case-sensitive
* Listen server hosts now get console notifications on bot status, errors etc.
* Added safeguards around parsing the file to prevent bad values crashing
* Made mp_botautomode default to 1 and mp_botcommandermode default to 1
This commit is contained in:
RGreenlees 2024-03-26 10:44:20 +00:00 committed by pierow
parent 67903b598e
commit b139fbf9b8
5 changed files with 335 additions and 86 deletions

View file

@ -128,11 +128,11 @@ cvar_t avh_randomrfk = {kvRandomRfk, "0", FCVAR_SERVER};
// AI Player Settings
cvar_t avh_botsenabled = { kvBotsEnabled,"0", FCVAR_SERVER }; // Bots can be added to the server Y/N
cvar_t avh_botautomode = { kvBotAutoMode,"0", FCVAR_SERVER }; // Defines automated behaviour for adding/removing bots. 0 = manual (must add via console), 1 = automatic (auto-fills teams), 2 = balance only (only keeps teams even)
cvar_t avh_botautomode = { kvBotAutoMode,"1", FCVAR_SERVER }; // Defines automated behaviour for adding/removing bots. 0 = manual (must add via console), 1 = automatic (auto-fills teams), 2 = balance only (only keeps teams even)
cvar_t avh_botminplayers = { kvBotMinPlayers,"0", FCVAR_SERVER }; // If bots are enabled and auto mode == 1 then it will maintain this player count by adding/removing as needed
cvar_t avh_botskill = { kvBotSkill,"1", FCVAR_SERVER }; // Sets the skill for the bots (0 = easiest, 3 = hardest)
cvar_t avh_botusemapdefaults = { kvBotUseMapDefaults,"1", FCVAR_SERVER }; // If bot auto mode == 1 then the min players will be taken from the config
cvar_t avh_botcommandermode = { kvBotCommanderMode,"0", FCVAR_SERVER }; // 0 = Bots never command, 1 = If nobody takes charge, 2 = Only if no humans on team
cvar_t avh_botcommandermode = { kvBotCommanderMode,"1", FCVAR_SERVER }; // 0 = Bots never command, 1 = If nobody takes charge, 2 = Only if no humans on team
cvar_t avh_botdebugmode = { kvBotDebugMode,"0", FCVAR_SERVER }; // 0 = Regular play, 1 = Drone mode, 2 = Test Navigation mode
cvar_t avh_botallowlerk = { kvBotAllowLerk,"1", FCVAR_SERVER }; // 0 = Bot will never evolve lerk, 1 = Bot will go lerk when appropriate
cvar_t avh_botallowfade = { kvBotAllowFade,"1", FCVAR_SERVER }; // 0 = Bot will never evolve fade, 1 = Bot will go fade when appropriate

View file

@ -155,7 +155,8 @@ void CONFIG_ParseConfigFile()
if (cFile.is_open())
{
std::string line;
int CurrSkillIndex = 0;
int CurrSkillIndex = -1;
bool bSkillLevelWarningGiven = false;
while (getline(cFile, line))
{
@ -167,7 +168,9 @@ void CONFIG_ParseConfigFile()
auto key = line.substr(0, delimiterPos);
auto value = line.substr(delimiterPos + 1);
if (key.compare("TeamSize") == 0)
const char* keyChar = key.c_str();
if (!stricmp(keyChar, "TeamSize"))
{
auto mapDelimiterPos = value.find(":");
@ -186,120 +189,344 @@ void CONFIG_ParseConfigFile()
auto marineSize = teamSizes.substr(0, sizeDelimiterPos);
auto alienSize = teamSizes.substr(sizeDelimiterPos + 1);
int iMarineSize = atoi(marineSize.c_str());
int iAlienSize = atoi(alienSize.c_str());
if (iMarineSize >= 0 && iMarineSize <= 32 && iAlienSize >= 0 && iAlienSize <= 32)
try
{
TeamSizeMap[mapName].TeamASize = atoi(marineSize.c_str());
TeamSizeMap[mapName].TeamBSize = atoi(alienSize.c_str());
int iMarineSize = atoi(marineSize.c_str());
int iAlienSize = atoi(alienSize.c_str());
if (iMarineSize >= 0 && iMarineSize <= 32 && iAlienSize >= 0 && iAlienSize <= 32)
{
TeamSizeMap[mapName].TeamASize = atoi(marineSize.c_str());
TeamSizeMap[mapName].TeamBSize = atoi(alienSize.c_str());
}
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid team size setting. Team sizes must 'x/y' where x and y are valid numbers between 0 and 32\n", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid team size setting. Team sizes must 'x/y' where x and y are valid numbers between 0 and 32\n", value.c_str());
}
continue;
}
if (key.compare("prefix") == 0)
if (!stricmp(keyChar, "Prefix"))
{
sprintf(BotPrefix, value.c_str());
continue;
}
if (key.compare("BotFillTiming") == 0)
if (!stricmp(keyChar, "BotFillTiming"))
{
int FillSetting = atoi(value.c_str());
FillSetting = clampi(FillSetting, 0, 2);
CurrentBotFillTiming = (BotFillTiming)FillSetting;
try
{
int FillSetting = atoi(value.c_str());
FillSetting = clampi(FillSetting, 0, 2);
CurrentBotFillTiming = (BotFillTiming)FillSetting;
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid number. BotFillTiming must be a number between 0 and 2 inclusive\n", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid number. BotFillTiming must be a number between 0 and 2 inclusive\n", value.c_str());
}
continue;
}
if (key.compare("BotSkillLevel") == 0)
if (!stricmp(keyChar, "BotSkillLevel") || !stricmp(keyChar, "BotSkillName"))
{
CurrSkillIndex = std::stoi(value.c_str());
CurrSkillIndex = clampi(CurrSkillIndex, 0, 3);
continue;
}
if (key.compare("MarineReactionTime") == 0)
{
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].marine_bot_reaction_time = clampf(NewValue, 0.0f, 1.0f);
try
{
CurrSkillIndex = std::stoi(value.c_str());
CurrSkillIndex = clampi(CurrSkillIndex, 0, 3);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill level. Bot skill level must be a number between 0 and 3 inclusive.", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill level. Bot skill level must be a number between 0 and 3 inclusive.", value.c_str());
}
continue;
}
if (key.compare("AlienReactionTime") == 0)
if (!stricmp(keyChar, "MarineReactionTime"))
{
if (CurrSkillIndex > -1)
{
try
{
float NewValue = std::stof(value.c_str());
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].marine_bot_reaction_time = clampf(NewValue, 0.0f, 1.0f);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
}
else
{
if (!bSkillLevelWarningGiven)
{
ALERT(at_console, "No skill level has been defined in the config file. Use BotSkillLevel= followed by 0-3 before setting skill values");
bSkillLevelWarningGiven = true;
}
}
continue;
}
BotSkillLevels[CurrSkillIndex].alien_bot_reaction_time = clampf(NewValue, 0.0f, 1.0f);
if (!stricmp(keyChar, "AlienReactionTime"))
{
if (CurrSkillIndex > -1)
{
try
{
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].alien_bot_reaction_time = clampf(NewValue, 0.0f, 1.0f);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
}
else
{
if (!bSkillLevelWarningGiven)
{
ALERT(at_logged, "No skill level has been defined in the config file. Use BotSkillLevel= followed by 0-3 before setting skill values");
bSkillLevelWarningGiven = true;
}
}
continue;
}
if (key.compare("MarineAimSkill") == 0)
if (!stricmp(keyChar, "MarineAimSkill"))
{
if (CurrSkillIndex > -1)
{
try
{
float NewValue = std::stof(value.c_str());
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].marine_bot_aim_skill = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].marine_bot_aim_skill = clampf(NewValue, 0.0f, 1.0f);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_logged, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_logged, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
}
else
{
if (!bSkillLevelWarningGiven)
{
ALERT(at_logged, "No skill level has been defined in the config file. Use BotSkillLevel= followed by 0-3 before setting skill values");
bSkillLevelWarningGiven = true;
}
}
continue;
}
if (key.compare("AlienAimSkill") == 0)
if (!stricmp(keyChar, "AlienAimSkill"))
{
if (CurrSkillIndex > -1)
{
try
{
float NewValue = std::stof(value.c_str());
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].alien_bot_aim_skill = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].alien_bot_aim_skill = clampf(NewValue, 0.0f, 1.0f);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
}
else
{
if (!bSkillLevelWarningGiven)
{
ALERT(at_console, "No skill level has been defined in the config file. Use BotSkillLevel= followed by 0-3 before setting skill values");
bSkillLevelWarningGiven = true;
}
}
continue;
}
if (key.compare("MarineMovementTracking") == 0)
if (!stricmp(keyChar, "MarineMovementTracking"))
{
if (CurrSkillIndex > -1)
{
try
{
float NewValue = std::stof(value.c_str());
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].marine_bot_motion_tracking_skill = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].marine_bot_motion_tracking_skill = clampf(NewValue, 0.0f, 1.0f);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
}
else
{
if (!bSkillLevelWarningGiven)
{
ALERT(at_console, "No skill level has been defined in the config file. Use BotSkillLevel= followed by 0-3 before setting skill values");
bSkillLevelWarningGiven = true;
}
}
continue;
}
if (key.compare("AlienMovementTracking") == 0)
if (!stricmp(keyChar, "AlienMovementTracking"))
{
if (CurrSkillIndex > -1)
{
try
{
float NewValue = std::stof(value.c_str());
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].alien_bot_motion_tracking_skill = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].alien_bot_motion_tracking_skill = clampf(NewValue, 0.0f, 1.0f);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
}
else
{
if (!bSkillLevelWarningGiven)
{
ALERT(at_console, "No skill level has been defined in the config file. Use BotSkillLevel= followed by 0-3 before setting skill values");
bSkillLevelWarningGiven = true;
}
}
continue;
}
if (key.compare("MarineViewSpeed") == 0)
if (!stricmp(keyChar, "MarineViewSpeed"))
{
if (CurrSkillIndex > -1)
{
try
{
float NewValue = std::stof(value.c_str());
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].marine_bot_view_speed = clampf(NewValue, 0.0f, 5.0f);
BotSkillLevels[CurrSkillIndex].marine_bot_view_speed = clampf(NewValue, 0.0f, 5.0f);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
}
else
{
if (!bSkillLevelWarningGiven)
{
ALERT(at_console, "No skill level has been defined in the config file. Use BotSkillLevel= followed by 0-3 before setting skill values");
bSkillLevelWarningGiven = true;
}
}
continue;
}
if (key.compare("AlienViewSpeed") == 0)
if (!stricmp(keyChar, "AlienViewSpeed"))
{
if (CurrSkillIndex > -1)
{
try
{
float NewValue = std::stof(value.c_str());
float NewValue = std::stof(value.c_str());
BotSkillLevels[CurrSkillIndex].alien_bot_view_speed = clampf(NewValue, 0.0f, 5.0f);
BotSkillLevels[CurrSkillIndex].alien_bot_view_speed = clampf(NewValue, 0.0f, 5.0f);
}
catch (std::invalid_argument const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
catch (std::out_of_range const& ex)
{
(void)ex;
ALERT(at_console, "'%s' is not a valid skill setting. Bot skill settings should be a float. See nsbots.ini for more info", value.c_str());
}
}
else
{
if (!bSkillLevelWarningGiven)
{
ALERT(at_console, "No skill level has been defined in the config file. Use BotSkillLevel= followed by 0-3 before setting skill values");
bSkillLevelWarningGiven = true;
}
}
continue;
}
if (key.compare("ChamberSequence") == 0)
if (!stricmp(keyChar, "ChamberSequence"))
{
AvHMessageID HiveOneTech = MESSAGE_NULL;
AvHMessageID HiveTwoTech = MESSAGE_NULL;
@ -327,27 +554,31 @@ void CONFIG_ParseConfigFile()
auto SecondTech = NextTechs.substr(0, SecondTechDelimiter);
auto ThirdTech = NextTechs.substr(SecondTechDelimiter + 1);
if (FirstTech.compare("movement") == 0)
const char* FirstTechChar = FirstTech.c_str();
const char* SecondTechChar = SecondTech.c_str();
const char* ThirdTechChar = ThirdTech.c_str();
if (!stricmp(FirstTechChar, "movement"))
{
HiveOneTech = ALIEN_BUILD_MOVEMENT_CHAMBER;
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER), AvailableTechs.end());
}
else if (FirstTech.compare("defense") == 0)
else if (!stricmp(FirstTechChar, "defense"))
{
HiveOneTech = ALIEN_BUILD_DEFENSE_CHAMBER;
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER), AvailableTechs.end());
}
else if (FirstTech.compare("sensory") == 0)
else if (!stricmp(FirstTechChar, "sensory"))
{
HiveOneTech = ALIEN_BUILD_SENSORY_CHAMBER;
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_SENSORY_CHAMBER), AvailableTechs.end());
}
if (SecondTech.compare("movement") == 0)
if (!stricmp(SecondTechChar, "movement"))
{
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER) != AvailableTechs.end())
{
@ -355,7 +586,7 @@ void CONFIG_ParseConfigFile()
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER), AvailableTechs.end());
}
}
else if (SecondTech.compare("defense") == 0)
else if (!stricmp(SecondTechChar, "defense"))
{
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER) != AvailableTechs.end())
{
@ -363,7 +594,7 @@ void CONFIG_ParseConfigFile()
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER), AvailableTechs.end());
}
}
else if (SecondTech.compare("sensory") == 0)
else if (!stricmp(SecondTechChar, "sensory"))
{
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_SENSORY_CHAMBER) != AvailableTechs.end())
{
@ -372,7 +603,7 @@ void CONFIG_ParseConfigFile()
}
}
if (ThirdTech.compare("movement") == 0)
if (!stricmp(ThirdTechChar, "movement"))
{
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER) != AvailableTechs.end())
{
@ -380,7 +611,7 @@ void CONFIG_ParseConfigFile()
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER), AvailableTechs.end());
}
}
else if (ThirdTech.compare("defense") == 0)
else if (!stricmp(ThirdTechChar, "defense"))
{
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER) != AvailableTechs.end())
{
@ -388,7 +619,7 @@ void CONFIG_ParseConfigFile()
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER), AvailableTechs.end());
}
}
else if (ThirdTech.compare("sensory") == 0)
else if (!stricmp(ThirdTechChar, "sensory"))
{
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_SENSORY_CHAMBER) != AvailableTechs.end())
{
@ -450,14 +681,16 @@ void CONFIG_RegenerateIniFile()
if (!NewConfigFile)
{
ALERT(at_console, "Unable to write to %s, please ensure the user has privileges\n", filename);
char ErrMsg[256];
sprintf(ErrMsg, "Unable to write to %s, please ensure the user has privileges\n", filename);
g_engfuncs.pfnServerPrint(ErrMsg);
return;
}
fprintf(NewConfigFile, "### General bot settings ###\n\n");
fprintf(NewConfigFile, "# What prefix to put in front of a bot's name (can leave blank)\n");
fprintf(NewConfigFile, "prefix=[BOT]\n\n");
fprintf(NewConfigFile, "Prefix=[BOT]\n\n");
fprintf(NewConfigFile, "# When should the server start adding bots? Note: bots will always be added after round start regardless\n");
fprintf(NewConfigFile, "# 0 = On map load (after 5 second grace period)\n");
@ -543,4 +776,8 @@ void CONFIG_RegenerateIniFile()
fflush(NewConfigFile);
fclose(NewConfigFile);
char ErrMsg[256];
sprintf(ErrMsg, "Regenerated %s\n", filename);
g_engfuncs.pfnServerPrint(ErrMsg);
}

View file

@ -868,7 +868,10 @@ bool LoadNavMesh(const char* mapname)
if (!savedFile)
{
ALERT(at_console, "No nav file found for %s in the navmeshes folder.", mapname);
char ErrMsg[256];
sprintf(ErrMsg, "No nav file found for %s in the navmeshes folder\n", mapname);
g_engfuncs.pfnServerPrint(ErrMsg);
g_engfuncs.pfnServerPrint("You will need to create one using the Nav Editor tool in the navmeshes folder, or download one\n");
return false;
}
@ -884,7 +887,9 @@ bool LoadNavMesh(const char* mapname)
// Error or early EOF
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "The nav file found for %s is a different version to the current bot version. Please regenerate it.", mapname);
char ErrMsg[256];
sprintf(ErrMsg, "The nav file found for %s is a different version to the current bot version. Use the Nav Editor to regenerate it\n", mapname);
g_engfuncs.pfnServerPrint(ErrMsg);
return false;
}
@ -892,7 +897,9 @@ bool LoadNavMesh(const char* mapname)
{
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "The nav file found for %s is a different version to the current bot version. Please regenerate it.", mapname);
char ErrMsg[256];
sprintf(ErrMsg, "The nav file found for %s is a different version to the current bot version. Use the Nav Editor to regenerate it\n", mapname);
g_engfuncs.pfnServerPrint(ErrMsg);
return false;
}
@ -907,7 +914,7 @@ bool LoadNavMesh(const char* mapname)
{
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "Unable to allocate memory for the nav mesh.", mapname);
g_engfuncs.pfnServerPrint("Unable to allocate memory for the nav mesh\n");
return false;
}
@ -916,7 +923,7 @@ bool LoadNavMesh(const char* mapname)
{
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "Could not initialise nav mesh, please try regenerating the nav file.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
return false;
}
@ -931,7 +938,7 @@ bool LoadNavMesh(const char* mapname)
status = NavMeshes[i].tileCache->init(TileCacheParams[i], m_talloc, m_tcomp, m_tmproc);
if (dtStatusFailed(status))
{
ALERT(at_console, "Could not initialise tile cache, please try regenerating the nav file.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
fclose(savedFile);
UnloadNavigationData();
return false;
@ -947,7 +954,7 @@ bool LoadNavMesh(const char* mapname)
{
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "The nav file has been corrupted or is out of date. Please try regenerating it.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
return false;
}
if (!tileHeader.tileRef || !tileHeader.dataSize)
@ -962,7 +969,7 @@ bool LoadNavMesh(const char* mapname)
dtFree(data);
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "The nav file has been corrupted or is out of date. Please try regenerating it.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
return false;
}
@ -985,7 +992,7 @@ bool LoadNavMesh(const char* mapname)
{
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "The nav file has been corrupted or is out of date. Please try regenerating it.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
return false;
}
if (!tileHeader.tileRef || !tileHeader.dataSize)
@ -1000,7 +1007,7 @@ bool LoadNavMesh(const char* mapname)
dtFree(data);
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "The nav file has been corrupted or is out of date. Please try regenerating it.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
return false;
}
@ -1023,7 +1030,7 @@ bool LoadNavMesh(const char* mapname)
{
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "The nav file has been corrupted or is out of date. Please try regenerating it.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
return false;
}
if (!tileHeader.tileRef || !tileHeader.dataSize)
@ -1038,7 +1045,7 @@ bool LoadNavMesh(const char* mapname)
dtFree(data);
fclose(savedFile);
UnloadNavigationData();
ALERT(at_console, "The nav file has been corrupted or is out of date. Please try regenerating it.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
return false;
}
@ -1123,11 +1130,16 @@ bool LoadNavMesh(const char* mapname)
if (dtStatusFailed(initStatus))
{
UnloadNavigationData();
ALERT(at_console, "The nav file has been corrupted or is out of date. Please try regenerating it.\n");
g_engfuncs.pfnServerPrint("The nav file has been corrupted or is out of date. Use the Nav Editor to regenerate it\n");
return false;
}
}
char SuccMsg[128];
sprintf(SuccMsg, "Navigation data for %s loaded successfully\n", mapname);
g_engfuncs.pfnServerPrint(SuccMsg);
return true;
}

View file

@ -421,7 +421,7 @@ void AIMGR_AddAIPlayerToTeam(int Team)
if (ActiveAIPlayers.size() >= gpGlobals->maxClients)
{
ALERT(at_console, "Bot limit reached, cannot add more\n");
g_engfuncs.pfnServerPrint("Bot limit reached, cannot add more\n");
return;
}
@ -439,7 +439,7 @@ void AIMGR_AddAIPlayerToTeam(int Team)
if (FNullEnt(BotEnt))
{
ALERT(at_console, "Failed to create AI player: server is full\n");
g_engfuncs.pfnServerPrint("Failed to create AI player: server is full\n");
return;
}
@ -901,8 +901,6 @@ void AIMGR_ResetRound()
bTileCacheFullyUpdated = UTIL_UpdateTileCache();
}
ALERT(at_console, "AI Manager Reset Round\n");
bHasRoundStarted = false;
bMapDataInitialised = true;
@ -1042,7 +1040,9 @@ void AIMGR_LoadNavigationData()
if (!loadNavigationData(theCStrLevelName))
{
ALERT(at_console, "Failed to load navigation data for %s\n", theCStrLevelName);
char ErrMsg[128];
sprintf(ErrMsg, "Failed to load navigation data for %s\n", theCStrLevelName);
g_engfuncs.pfnServerPrint(ErrMsg);
}
}

View file

@ -365,7 +365,7 @@ AvHGamerules::AvHGamerules() : mTeamA(TEAM_ONE), mTeamB(TEAM_TWO)
{
if (!AIMGR_IsBotEnabled())
{
ALERT(at_console, "Bots are disabled, or the navmesh could not be loaded.");
g_engfuncs.pfnServerPrint("Bots are disabled, or the navmesh could not be loaded\n");
return;
}
@ -388,7 +388,7 @@ AvHGamerules::AvHGamerules() : mTeamA(TEAM_ONE), mTeamB(TEAM_TWO)
{
if (!AIMGR_IsBotEnabled())
{
ALERT(at_console, "Bots are disabled, or the navmesh could not be loaded.");
g_engfuncs.pfnServerPrint("Bots are disabled, or the navmesh could not be loaded\n");
return;
}
@ -415,7 +415,7 @@ AvHGamerules::AvHGamerules() : mTeamA(TEAM_ONE), mTeamB(TEAM_TWO)
}
else
{
ALERT(at_console, "Bots are disabled, enable first before loading the navmesh.");
g_engfuncs.pfnServerPrint("Bots are disabled, enable first with 'mp_botsenabled 1' before loading the navmesh\n");
}
});