Fixed crash, added more cvars

This commit is contained in:
RGreenlees 2024-03-13 11:08:24 +00:00 committed by pierow
parent 3220533c44
commit b6ac4431ed
10 changed files with 144 additions and 196 deletions

View File

@ -2389,7 +2389,7 @@ dtStatus dtNavMeshQuery::getPortalPoints(dtPolyRef from, const dtPoly* fromPoly,
break;
}
}
if (!link)
if (!link || fromPoly->vertCount == 0)
return DT_FAILURE | DT_INVALID_PARAM;
// Handle off-mesh connections.
@ -2672,7 +2672,7 @@ dtStatus dtNavMeshQuery::raycast(dtPolyRef startRef, const float* startPos, cons
const dtLink* link = &tile->links[i];
// Find link which contains this edge.
if ((int)link->edge != segMax)
if ((int)link->edge != segMax || poly->vertCount == 0)
continue;
// Get pointer to the next polygon.
@ -3699,7 +3699,7 @@ dtStatus dtNavMeshQuery::findDistanceToWall(dtPolyRef startRef, const float* cen
const dtLink* link = &bestTile->links[i];
dtPolyRef neighbourRef = link->ref;
// Skip invalid neighbours and do not follow back to parent.
if (!neighbourRef || neighbourRef == parentRef)
if (!neighbourRef || neighbourRef == parentRef || bestPoly->vertCount == 0)
continue;
// Expand to neighbour.

View File

@ -128,11 +128,16 @@ cvar_t avh_version = {kvVersion, "330", FCVAR_SERVER};
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_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,"0", FCVAR_SERVER }; // Sets the skill for the bots (0 = easiest, 3 = hardest)
cvar_t avh_botskill = { kvBotSkill,"1", FCVAR_SERVER }; // Sets the skill for the bots (0 = easiest, 3 = hardest)
cvar_t avh_botusemapdefaults = { kvBotUseMapDefaults,"0", 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_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
cvar_t avh_botallowonos = { kvBotAllowOnos,"1", FCVAR_SERVER }; // 0 = Bot will never evolve onos, 1 = Bot will go onos when appropriate
cvar_t avh_botcommanderwait = { kvBotCommWait,"10", FCVAR_SERVER }; // If mp_botcommandermode == 1 then how long the bot will wait before taking command, to give a human a chance
cvar_t avh_botlerkcooldown = { kvBotLerkCooldown,"60", FCVAR_SERVER }; // If the team's lerk is killed, how long the bot will wait before going lerk again.
cvar_t avh_botmaxstucktime = { kvBotMaxStuckTime,"15", FCVAR_SERVER }; // If the team's lerk is killed, how long the bot will wait before going lerk again.
//playtest cvars
cvar_t avh_fastjp = {kvfastjp, "0", FCVAR_SERVER};
@ -224,6 +229,12 @@ void GameDLLInit( void )
CVAR_REGISTER(&avh_botskill);
CVAR_REGISTER(&avh_botcommandermode);
CVAR_REGISTER(&avh_botdebugmode);
CVAR_REGISTER(&avh_botallowlerk);
CVAR_REGISTER(&avh_botallowfade);
CVAR_REGISTER(&avh_botallowonos);
CVAR_REGISTER(&avh_botcommanderwait);
CVAR_REGISTER(&avh_botlerkcooldown);
CVAR_REGISTER(&avh_botmaxstucktime);
// Register AvH variables
CVAR_REGISTER (&avh_drawdamage);

View File

@ -6,56 +6,52 @@
#include <unordered_map>
float fCommanderWaitTime = 10.0f;
float fLerkCooldown = 60.0f;
float MaxStuckTime = 30.0f;
bool bLerkAllowed = true;
bool bFadeAllowed = true;
bool bOnosAllowed = true;
BotFillTiming CurrentBotFillTiming = FILLTIMING_MAPLOAD;
BotFillTiming CurrentBotFillTiming = FILLTIMING_ALLHUMANS;
std::unordered_map<std::string, TeamSizeDefinitions> TeamSizeMap;
std::unordered_map<std::string, bot_skill> BotSkillLevelsMap;
std::string CurrentSkillLevel;
std::string GlobalSkillLevel = "default";
bot_skill BotSkillLevels[4];
AvHMessageID ChamberSequence[3] = { ALIEN_BUILD_DEFENSE_CHAMBER, ALIEN_BUILD_MOVEMENT_CHAMBER, ALIEN_BUILD_SENSORY_CHAMBER };
char BotPrefix[32] = "";
extern cvar_t avh_botskill;
extern cvar_t avh_botallowlerk;
extern cvar_t avh_botallowfade;
extern cvar_t avh_botallowonos;
extern cvar_t avh_botcommanderwait;
extern cvar_t avh_botlerkcooldown;
extern cvar_t avh_botmaxstucktime;
float CONFIG_GetCommanderWaitTime()
{
return fCommanderWaitTime;
return avh_botcommanderwait.value;
}
float CONFIG_GetLerkCooldown()
{
return fLerkCooldown;
return avh_botlerkcooldown.value;
}
bool CONFIG_IsLerkAllowed()
{
return bLerkAllowed;
return avh_botallowlerk.value > 0;
}
bool CONFIG_IsFadeAllowed()
{
return bFadeAllowed;
return avh_botallowfade.value > 0;
}
bool CONFIG_IsOnosAllowed()
{
return bOnosAllowed;
return avh_botallowonos.value > 0;
}
float CONFIG_GetMaxStuckTime()
{
return MaxStuckTime;
return avh_botmaxstucktime.value;
}
string CONFIG_GetBotPrefix()
@ -100,52 +96,55 @@ AvHMessageID CONFIG_GetHiveTechAtIndex(const int Index)
return ChamberSequence[Index];
}
bot_skill CONFIG_GetBotSkillLevel(const char* SkillName)
bot_skill CONFIG_GetBotSkillLevel()
{
std::string s = SkillName;
std::unordered_map<std::string, bot_skill>::const_iterator got = BotSkillLevelsMap.find(s);
int index = clampi((int)avh_botskill.value, 0, 3);
if (got == BotSkillLevelsMap.end())
{
return BotSkillLevelsMap["default"];
}
else
{
return got->second;
}
}
bool CONFIG_BotSkillLevelExists(const char* SkillName)
{
std::string s = SkillName;
std::unordered_map<std::string, bot_skill>::const_iterator got = BotSkillLevelsMap.find(s);
return (got != BotSkillLevelsMap.end());
}
bot_skill CONFIG_GetGlobalBotSkillLevel()
{
return BotSkillLevelsMap[GlobalSkillLevel.c_str()];
return BotSkillLevels[index];
}
void CONFIG_ParseConfigFile()
{
TeamSizeMap.clear();
TeamSizeMap["default"].TeamASize = 6;
TeamSizeMap["default"].TeamBSize = 6;
BotSkillLevelsMap.clear();
BotSkillLevels[0].marine_bot_reaction_time = 0.4f;
BotSkillLevels[0].marine_bot_aim_skill = 0.1f;
BotSkillLevels[0].marine_bot_motion_tracking_skill = 0.1f;
BotSkillLevels[0].marine_bot_view_speed = 0.5f;
BotSkillLevelsMap["default"].marine_bot_aim_skill = 0.3f;
BotSkillLevelsMap["default"].marine_bot_motion_tracking_skill = 0.3f;
BotSkillLevelsMap["default"].marine_bot_reaction_time = 0.3f;
BotSkillLevelsMap["default"].marine_bot_view_speed = 1.0f;
BotSkillLevelsMap["default"].alien_bot_aim_skill = 0.5f;
BotSkillLevelsMap["default"].alien_bot_motion_tracking_skill = 0.5f;
BotSkillLevelsMap["default"].alien_bot_reaction_time = 0.3f;
BotSkillLevelsMap["default"].alien_bot_view_speed = 1.5f;
BotSkillLevels[0].alien_bot_reaction_time = 0.4f;
BotSkillLevels[0].alien_bot_aim_skill = 0.2f;
BotSkillLevels[0].alien_bot_motion_tracking_skill = 0.2f;
BotSkillLevels[0].alien_bot_view_speed = 0.75f;
CurrentSkillLevel = "default";
BotSkillLevels[1].marine_bot_reaction_time = 0.2f;
BotSkillLevels[1].marine_bot_aim_skill = 0.5f;
BotSkillLevels[1].marine_bot_motion_tracking_skill = 0.4f;
BotSkillLevels[1].marine_bot_view_speed = 1.0f;
BotSkillLevels[1].alien_bot_reaction_time = 0.2f;
BotSkillLevels[1].alien_bot_aim_skill = 0.5f;
BotSkillLevels[1].alien_bot_motion_tracking_skill = 0.5f;
BotSkillLevels[1].alien_bot_view_speed = 1.3f;
BotSkillLevels[2].marine_bot_reaction_time = 0.2f;
BotSkillLevels[2].marine_bot_aim_skill = 0.6f;
BotSkillLevels[2].marine_bot_motion_tracking_skill = 0.6f;
BotSkillLevels[2].marine_bot_view_speed = 1.5f;
BotSkillLevels[2].alien_bot_reaction_time = 0.2f;
BotSkillLevels[2].alien_bot_aim_skill = 0.8f;
BotSkillLevels[2].alien_bot_motion_tracking_skill = 0.8f;
BotSkillLevels[2].alien_bot_view_speed = 1.5f;
BotSkillLevels[3].marine_bot_reaction_time = 0.1f;
BotSkillLevels[3].marine_bot_aim_skill = 1.0f;
BotSkillLevels[3].marine_bot_motion_tracking_skill = 1.0f;
BotSkillLevels[3].marine_bot_view_speed = 2.0f;
BotSkillLevels[3].alien_bot_reaction_time = 0.1f;
BotSkillLevels[3].alien_bot_aim_skill = 1.0f;
BotSkillLevels[3].alien_bot_motion_tracking_skill = 1.0f;
BotSkillLevels[3].alien_bot_view_speed = 2.0f;
string BotConfigFile = string(getModDirectory()) + "/nsbots.cfg";
@ -156,6 +155,8 @@ void CONFIG_ParseConfigFile()
if (cFile.is_open())
{
std::string line;
int CurrSkillIndex = 0;
while (getline(cFile, line))
{
line.erase(std::remove_if(line.begin(), line.end(), isspace),
@ -204,45 +205,6 @@ void CONFIG_ParseConfigFile()
continue;
}
if (key.compare("CommanderWaitTime") == 0)
{
fCommanderWaitTime = (float)atoi(value.c_str());
fCommanderWaitTime = fmaxf(0.0f, fCommanderWaitTime);
continue;
}
if (key.compare("LerkCooldown") == 0)
{
fLerkCooldown = (float)atoi(value.c_str());
fLerkCooldown = fmaxf(0.0f, fLerkCooldown);
continue;
}
if (key.compare("AllowLerk") == 0)
{
bLerkAllowed = atoi(value.c_str()) > 0;
continue;
}
if (key.compare("AllowFade") == 0)
{
bFadeAllowed = atoi(value.c_str()) > 0;
continue;
}
if (key.compare("AllowOnos") == 0)
{
bOnosAllowed = atoi(value.c_str()) > 0;
continue;
}
if (key.compare("MaxStuckTime") == 0)
{
MaxStuckTime = (float)atoi(value.c_str());
MaxStuckTime = fmaxf(0.0f, MaxStuckTime);
continue;
}
if (key.compare("BotFillTiming") == 0)
{
int FillSetting = atoi(value.c_str());
@ -251,27 +213,18 @@ void CONFIG_ParseConfigFile()
continue;
}
if (key.compare("BotSkillName") == 0)
if (key.compare("BotSkillLevel") == 0)
{
BotSkillLevelsMap[value.c_str()].marine_bot_aim_skill = 0.5f;
BotSkillLevelsMap[value.c_str()].marine_bot_motion_tracking_skill = 0.5f;
BotSkillLevelsMap[value.c_str()].marine_bot_reaction_time = 0.2f;
BotSkillLevelsMap[value.c_str()].marine_bot_view_speed = 1.0f;
BotSkillLevelsMap[value.c_str()].alien_bot_aim_skill = 0.5f;
BotSkillLevelsMap[value.c_str()].alien_bot_motion_tracking_skill = 0.5f;
BotSkillLevelsMap[value.c_str()].alien_bot_reaction_time = 0.2f;
BotSkillLevelsMap[value.c_str()].alien_bot_view_speed = 1.0f;
CurrentSkillLevel = value;
CurrSkillIndex = std::stoi(value.c_str());
CurrSkillIndex = clampi(CurrSkillIndex, 0, 3);
continue;
}
if (key.compare("MarineReactionTime") == 0)
{
float NewValue = std::stof(value.c_str());
BotSkillLevelsMap[CurrentSkillLevel.c_str()].marine_bot_reaction_time = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].marine_bot_reaction_time = clampf(NewValue, 0.0f, 1.0f);
continue;
}
@ -281,7 +234,7 @@ void CONFIG_ParseConfigFile()
float NewValue = std::stof(value.c_str());
BotSkillLevelsMap[CurrentSkillLevel.c_str()].alien_bot_reaction_time = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].alien_bot_reaction_time = clampf(NewValue, 0.0f, 1.0f);
continue;
}
@ -291,7 +244,7 @@ void CONFIG_ParseConfigFile()
float NewValue = std::stof(value.c_str());
BotSkillLevelsMap[CurrentSkillLevel.c_str()].marine_bot_aim_skill = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].marine_bot_aim_skill = clampf(NewValue, 0.0f, 1.0f);
continue;
}
@ -301,7 +254,7 @@ void CONFIG_ParseConfigFile()
float NewValue = std::stof(value.c_str());
BotSkillLevelsMap[CurrentSkillLevel.c_str()].alien_bot_aim_skill = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].alien_bot_aim_skill = clampf(NewValue, 0.0f, 1.0f);
continue;
}
@ -311,7 +264,7 @@ void CONFIG_ParseConfigFile()
float NewValue = std::stof(value.c_str());
BotSkillLevelsMap[CurrentSkillLevel.c_str()].marine_bot_motion_tracking_skill = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].marine_bot_motion_tracking_skill = clampf(NewValue, 0.0f, 1.0f);
continue;
}
@ -321,7 +274,7 @@ void CONFIG_ParseConfigFile()
float NewValue = std::stof(value.c_str());
BotSkillLevelsMap[CurrentSkillLevel.c_str()].alien_bot_motion_tracking_skill = clampf(NewValue, 0.0f, 1.0f);
BotSkillLevels[CurrSkillIndex].alien_bot_motion_tracking_skill = clampf(NewValue, 0.0f, 1.0f);
continue;
}
@ -331,7 +284,7 @@ void CONFIG_ParseConfigFile()
float NewValue = std::stof(value.c_str());
BotSkillLevelsMap[CurrentSkillLevel.c_str()].marine_bot_view_speed = clampf(NewValue, 0.0f, 5.0f);
BotSkillLevels[CurrSkillIndex].marine_bot_view_speed = clampf(NewValue, 0.0f, 5.0f);
continue;
}
@ -341,14 +294,7 @@ void CONFIG_ParseConfigFile()
float NewValue = std::stof(value.c_str());
BotSkillLevelsMap[CurrentSkillLevel.c_str()].alien_bot_view_speed = clampf(NewValue, 0.0f, 5.0f);
continue;
}
if (key.compare("DefaultSkillLevel") == 0)
{
GlobalSkillLevel = value;
BotSkillLevels[CurrSkillIndex].alien_bot_view_speed = clampf(NewValue, 0.0f, 5.0f);
continue;
}
@ -483,11 +429,6 @@ void CONFIG_ParseConfigFile()
}
}
}
if (!CONFIG_BotSkillLevelExists(GlobalSkillLevel.c_str()))
{
GlobalSkillLevel = "default";
}
}
BotFillTiming CONFIG_GetBotFillTiming()

View File

@ -54,13 +54,7 @@ int CONFIG_GetTeamBSizeForMap(const char* MapName);
// Returns the configured hive tech at that index (chamber build sequence)
AvHMessageID CONFIG_GetHiveTechAtIndex(const int Index);
bot_skill CONFIG_GetBotSkillLevel(const char* SkillName);
bool CONFIG_BotSkillLevelExists(const char* SkillName);
bot_skill CONFIG_GetGlobalBotSkillLevel();
void CONFIG_SetGlobalBotSkillLevel(const char* NewSkillLevel);
bot_skill CONFIG_GetBotSkillLevel();
BotFillTiming CONFIG_GetBotFillTiming();

View File

@ -14,6 +14,7 @@
#include "AvHAITactical.h"
#include "AvHAITask.h"
#include "AvHAIWeaponHelper.h"
#include "AvHAIConfig.h"
#include "../AvHWeldable.h"
#include "../AvHServerUtil.h"
@ -5452,7 +5453,7 @@ void UpdateBotStuck(AvHAIPlayer* pBot)
if (pBot->BotNavInfo.StuckInfo.TotalStuckTime > 0.25f)
{
if (pBot->BotNavInfo.StuckInfo.TotalStuckTime > 15.0f)
if (pBot->BotNavInfo.StuckInfo.TotalStuckTime > CONFIG_GetMaxStuckTime())
{
BotSuicide(pBot);
return;

View File

@ -1902,30 +1902,37 @@ void UpdateAIPlayerCORole(AvHAIPlayer* pBot)
return;
}
int NumLerks = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER3, pBot->Edict);
int NumHarassers = AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_HARASS, pBot);
if (NumLerks + NumHarassers == 0)
if (CONFIG_IsLerkAllowed())
{
float LastSeenTime;
edict_t* PreviousLerk = AITAC_GetLastSeenLerkForTeam(BotTeam, LastSeenTime);
// We only go lerk if the last lerk we had in the match was either us, or we've not had another lerk in 30 seconds
// This prevents a situation where a human is lerk, gets killed, and a bot immediately takes over.
// This is undesireable as it pressures the human to pick something else to avoid too many lerks
if (LastSeenTime > 30.0f || PreviousLerk == pBot->Edict)
int NumLerks = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER3, pBot->Edict);
int NumHarassers = AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_HARASS, pBot);
if (NumLerks + NumHarassers == 0)
{
SetNewAIPlayerRole(pBot, BOT_ROLE_HARASS);
return;
float LastSeenTime;
edict_t* PreviousLerk = AITAC_GetLastSeenLerkForTeam(BotTeam, LastSeenTime);
// We only go lerk if the last lerk we had in the match was either us, or we've not had another lerk in 30 seconds
// This prevents a situation where a human is lerk, gets killed, and a bot immediately takes over.
// This is undesireable as it pressures the human to pick something else to avoid too many lerks
if (FNullEnt(PreviousLerk) || (gpGlobals->time - LastSeenTime > CONFIG_GetLerkCooldown()) || PreviousLerk == pBot->Edict)
{
SetNewAIPlayerRole(pBot, BOT_ROLE_HARASS);
return;
}
}
}
int MaxOnos = (int)(ceilf((float)(AIMGR_GetNumPlayersOnTeam(BotTeam) - 2)) * 0.3f);
if (AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_BOMBARDIER, pBot) < MaxOnos)
if (CONFIG_IsOnosAllowed())
{
SetNewAIPlayerRole(pBot, BOT_ROLE_BOMBARDIER);
return;
int MaxOnos = (int)(ceilf((float)(AIMGR_GetNumPlayersOnTeam(BotTeam) - 2)) * 0.3f);
if (AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_BOMBARDIER, pBot) < MaxOnos)
{
SetNewAIPlayerRole(pBot, BOT_ROLE_BOMBARDIER);
return;
}
}
}
@ -4329,7 +4336,7 @@ AvHMessageID GetNextAIPlayerCOAlienUpgrade(AvHAIPlayer* pBot)
// If we're going assault then make sure we've saved up enough for fade
if (pBot->BotRole == BOT_ROLE_ASSAULT)
{
if (NumPointsAvailable <= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FOUR))
if (CONFIG_IsFadeAllowed() && NumPointsAvailable <= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FOUR))
{
return MESSAGE_NULL;
}
@ -5609,7 +5616,7 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (Task->TaskType == TASK_EVOLVE) { return; }
if (!IsPlayerOnos(pBot->Edict) && pBot->Player->GetResources() >= BALANCE_VAR(kOnosCost))
if (CONFIG_IsOnosAllowed() && !IsPlayerOnos(pBot->Edict) && pBot->Player->GetResources() >= BALANCE_VAR(kOnosCost))
{
int NumOnos = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER5, pBot->Edict);
@ -5625,7 +5632,7 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
}
}
if (!IsPlayerFade(pBot->Edict) && pBot->Player->GetResources() >= BALANCE_VAR(kFadeCost))
if (CONFIG_IsFadeAllowed() && !IsPlayerFade(pBot->Edict) && pBot->Player->GetResources() >= BALANCE_VAR(kFadeCost))
{
int NumFades = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER4, pBot->Edict);
int NumOnos = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER5, pBot->Edict);

View File

@ -23,6 +23,7 @@ extern cvar_t avh_botminplayers;
extern cvar_t avh_botusemapdefaults;
extern cvar_t avh_botcommandermode;
extern cvar_t avh_botdebugmode;
extern cvar_t avh_botskill;
float LastAIPlayerCountUpdate = 0.0f;
@ -518,7 +519,7 @@ void AIMGR_AddAIPlayerToTeam(int Team)
NewAIPlayer.WantsAndNeedsTask.TaskType = TASK_NONE;
NewAIPlayer.CommanderTask.TaskType = TASK_NONE;
const bot_skill BotSkillSettings = CONFIG_GetGlobalBotSkillLevel();
const bot_skill BotSkillSettings = CONFIG_GetBotSkillLevel();
memcpy(&NewAIPlayer.BotSkillSettings, &BotSkillSettings, sizeof(bot_skill));
@ -595,6 +596,8 @@ void AIMGR_UpdateAIPlayers()
static float LastThinkTime = 0.0f;
static int CurrentBotSkill = 1;
CurrTime = gpGlobals->time;
if (CurrTime < PrevTime)
@ -610,6 +613,14 @@ void AIMGR_UpdateAIPlayers()
float FrameDelta = CurrTime - PrevTime;
float ThinkDelta = CurrTime - LastThinkTime;
int cvarBotSkill = clampi((int)avh_botskill.value, 0, 3);
bool bSkillChanged = (cvarBotSkill != CurrentBotSkill);
if (bSkillChanged)
{
CurrentBotSkill = cvarBotSkill;
}
for (auto BotIt = ActiveAIPlayers.begin(); BotIt != ActiveAIPlayers.end();)
@ -623,6 +634,12 @@ void AIMGR_UpdateAIPlayers()
AvHAIPlayer* bot = &(*BotIt);
if (bSkillChanged)
{
const bot_skill NewSkillSettings = CONFIG_GetBotSkillLevel();
memcpy(&bot->BotSkillSettings, &NewSkillSettings, sizeof(bot_skill));
}
BotUpdateViewRotation(bot, FrameDelta);
if (IS_DEDICATED_SERVER() || ThinkDelta >= BOT_MIN_FRAME_TIME)
@ -643,37 +660,6 @@ void AIMGR_UpdateAIPlayers()
}
}
if (!vIsZero(DebugVector1) && !vIsZero(DebugVector2))
{
UTIL_DrawLine(INDEXENT(1), DebugVector1, DebugVector2);
edict_t* PlayerEdict = INDEXENT(1);
bool bOnGround = (INDEXENT(1)->v.flags & FL_ONGROUND) || IsPlayerOnLadder(PlayerEdict);
bool Result = false;
if (!IsPlayerOnLadder(PlayerEdict))
{
if (IsPlayerClimbingWall(PlayerEdict)) { Result = true; }
if (bOnGround)
{
if (!UTIL_PointIsDirectlyReachable(GetPlayerBottomOfCollisionHull(PlayerEdict), DebugVector1) && !UTIL_PointIsDirectlyReachable(GetPlayerBottomOfCollisionHull(PlayerEdict), DebugVector2)) { Result = true; }
}
}
if (Result)
{
UTIL_DrawHUDText(PlayerEdict, 0, 0.1f, 0.1f, 255, 255, 255, "TRUE");
}
else
{
UTIL_DrawHUDText(PlayerEdict, 0, 0.1f, 0.1f, 255, 255, 255, "FALSE");
}
}
if (bHasRoundStarted)
{
AvHTeamNumber TeamANumber = GetGameRules()->GetTeamANumber();
@ -958,7 +944,7 @@ void AIMGR_RoundStarted()
bHasRoundStarted = true;
AvHTeamNumber TeamANumber = GetGameRules()->GetTeamANumber();
AvHTeamNumber TeamBNumber = GetGameRules()->GetTeamANumber();
AvHTeamNumber TeamBNumber = GetGameRules()->GetTeamBNumber();
// If our team has no humans on it, then we can take command right away. Otherwise, wait the allotted grace period to allow the human to take command

View File

@ -5,7 +5,7 @@
#include "AvHAIPlayer.h"
// Max rate bot can run its logic, default is 1/60th second. WARNING: Increasing the rate past 100hz causes bots to move and turn slowly due to GoldSrc limits!
static const double BOT_MIN_FRAME_TIME = (1.0 / 60.0);
static const double BOT_MIN_FRAME_TIME = 0;// (1.0 / 60.0);
// Once the first human player has joined the game, how long to wait before adding bots
static const float AI_GRACE_PERIOD = 5.0f;
// Max time to wait before spawning players if none connect (e.g. empty dedicated server)

View File

@ -4195,11 +4195,13 @@ bool AITAC_IsAlienHarasserNeeded(AvHAIPlayer* pBot)
{
if (IsPlayerLerk(pBot->Edict)) { return true; }
if (!CONFIG_IsLerkAllowed()) { return false; }
if (pBot->Player->GetResources() < BALANCE_VAR(kLerkCost)) { return false; }
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
if (pBot->BotRole == BOT_ROLE_ASSAULT)
if (pBot->BotRole == BOT_ROLE_ASSAULT && pBot->Player->GetResources() > (BALANCE_VAR(kFadeCost) * 0.8f))
{
int NumFades = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER4, pBot->Edict);
int NumOnos = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER5, pBot->Edict);
@ -4223,7 +4225,7 @@ bool AITAC_IsAlienHarasserNeeded(AvHAIPlayer* pBot)
// We only go lerk if the last lerk we had in the match was either us, or we've not had another lerk in 60 seconds
// It avoids aliens spending all their resources on evolving lerks if they keep dying
// It also means that if a human was playing lerk and died, a bot doesn't immediately take over that role, and lets the human try again if they want
return (LastSeenTime > 60.0f || PreviousLerk == pBot->Edict);
return (FNullEnt(PreviousLerk) || (gpGlobals->time - LastSeenTime > CONFIG_GetLerkCooldown()) || PreviousLerk == pBot->Edict);
}
return false;

View File

@ -149,6 +149,12 @@ float ns_cvar_float(const cvar_t *cvar);
#define kvBotAutoMode "mp_botautomode"
#define kvBotCommanderMode "mp_botcommandermode"
#define kvBotDebugMode "mp_botdebugmode"
#define kvBotAllowLerk "mp_botallowlerk"
#define kvBotAllowFade "mp_botallowfade"
#define kvBotAllowOnos "mp_botallowonos"
#define kvBotCommWait "mp_botcommanderwait"
#define kvBotLerkCooldown "mp_botlerkcooldown"
#define kvBotMaxStuckTime "mp_botmaxstucktime"
#define kvEasterEggChance "mp_eastereggchance"
#define kvUplink "mp_uplink"