mirror of
https://github.com/ENSL/NS.git
synced 2025-03-14 06:34:33 +00:00
Performance improvements
This commit is contained in:
parent
6883eb33b3
commit
ad1c5da03a
9 changed files with 174 additions and 52 deletions
|
@ -129,7 +129,7 @@ cvar_t avh_botsenabled = { kvBotsEnabled,"0", FCVAR_SERVER }; // Bots can b
|
|||
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,"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_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_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
|
||||
|
|
|
@ -212,6 +212,13 @@ typedef enum _AVHAICOMBATSTRATEGY
|
|||
COMBAT_STRATEGY_ATTACK // Attack the enemy
|
||||
} AvHAICombatStrategy;
|
||||
|
||||
typedef enum _AVHAINAVMESHSTATUS
|
||||
{
|
||||
NAVMESH_STATUS_PENDING = 0, // Waiting to try loading the navmesh
|
||||
NAVMESH_STATUS_FAILED, // Failed to load the navmesh
|
||||
NAVMESH_STATUS_SUCCESS // Successfully loaded the navmesh
|
||||
} AvHAINavMeshStatus;
|
||||
|
||||
typedef struct _OFF_MESH_CONN
|
||||
{
|
||||
unsigned int ConnectionRefs[2];
|
||||
|
|
|
@ -230,7 +230,8 @@ bool IsEdictStructure(const edict_t* edict)
|
|||
|
||||
bool IsEdictHive(const edict_t* edict)
|
||||
{
|
||||
return (GetDeployableObjectTypeFromEdict(edict) != STRUCTURE_ALIEN_HIVE);
|
||||
if (FNullEnt(edict)) { return false; }
|
||||
return (edict->v.iuser3 == AVH_USER3_HIVE);
|
||||
}
|
||||
|
||||
bool IsDamagingStructure(const edict_t* StructureEdict)
|
||||
|
|
|
@ -42,6 +42,8 @@ vector<AvHAIOffMeshConnection> BaseMapConnections;
|
|||
nav_mesh NavMeshes[MAX_NAV_MESHES] = { }; // Array of nav meshes. Currently only 3 are used (building, onos, and regular)
|
||||
nav_profile BaseNavProfiles[MAX_NAV_PROFILES] = { }; // Array of nav profiles
|
||||
|
||||
AvHAINavMeshStatus NavmeshStatus = NAVMESH_STATUS_PENDING;
|
||||
|
||||
vector<NavHint> MapNavHints;
|
||||
|
||||
extern bool bNavMeshModified;
|
||||
|
@ -833,6 +835,8 @@ void UnloadNavMeshes()
|
|||
|
||||
BaseMapConnections.clear();
|
||||
MapNavHints.clear();
|
||||
|
||||
NavmeshStatus = NAVMESH_STATUS_PENDING;
|
||||
}
|
||||
|
||||
void UnloadNavigationData()
|
||||
|
@ -860,7 +864,11 @@ bool LoadNavMesh(const char* mapname)
|
|||
|
||||
FILE* savedFile = fopen(filename, "rb");
|
||||
|
||||
if (!savedFile) { return false; }
|
||||
if (!savedFile)
|
||||
{
|
||||
ALERT(at_console, "No nav file found for %s in the navmeshes folder.", mapname);
|
||||
return false;
|
||||
}
|
||||
|
||||
LinearAllocator* m_talloc = new LinearAllocator(32000);
|
||||
FastLZCompressor* m_tcomp = new FastLZCompressor;
|
||||
|
@ -874,6 +882,7 @@ 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);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -881,6 +890,7 @@ 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);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -895,6 +905,7 @@ bool LoadNavMesh(const char* mapname)
|
|||
{
|
||||
fclose(savedFile);
|
||||
UnloadNavigationData();
|
||||
ALERT(at_console, "Unable to allocate memory for the nav mesh.", mapname);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -903,6 +914,7 @@ bool LoadNavMesh(const char* mapname)
|
|||
{
|
||||
fclose(savedFile);
|
||||
UnloadNavigationData();
|
||||
ALERT(at_console, "Could not initialise nav mesh, please try regenerating the nav file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -917,7 +929,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\n");
|
||||
ALERT(at_console, "Could not initialise tile cache, please try regenerating the nav file.\n");
|
||||
fclose(savedFile);
|
||||
UnloadNavigationData();
|
||||
return false;
|
||||
|
@ -933,6 +945,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");
|
||||
return false;
|
||||
}
|
||||
if (!tileHeader.tileRef || !tileHeader.dataSize)
|
||||
|
@ -947,6 +960,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");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -969,6 +983,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");
|
||||
return false;
|
||||
}
|
||||
if (!tileHeader.tileRef || !tileHeader.dataSize)
|
||||
|
@ -983,6 +998,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");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1005,6 +1021,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");
|
||||
return false;
|
||||
}
|
||||
if (!tileHeader.tileRef || !tileHeader.dataSize)
|
||||
|
@ -1019,6 +1036,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");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1103,6 +1121,7 @@ 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");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1254,8 +1273,11 @@ bool loadNavigationData(const char* mapname)
|
|||
|
||||
if (!LoadNavMesh(mapname))
|
||||
{
|
||||
NavmeshStatus = NAVMESH_STATUS_FAILED;
|
||||
return false;
|
||||
}
|
||||
|
||||
NavmeshStatus = NAVMESH_STATUS_SUCCESS;
|
||||
|
||||
UTIL_PopulateBaseNavProfiles();
|
||||
|
||||
|
@ -1267,6 +1289,11 @@ bool NavmeshLoaded()
|
|||
return NavMeshes[0].navMesh != nullptr;
|
||||
}
|
||||
|
||||
AvHAINavMeshStatus NAV_GetNavMeshStatus()
|
||||
{
|
||||
return NavmeshStatus;
|
||||
}
|
||||
|
||||
Vector UTIL_GetRandomPointOnNavmesh(const AvHAIPlayer* pBot)
|
||||
{
|
||||
const dtNavMeshQuery* m_navQuery = UTIL_GetNavMeshQueryForProfile(pBot->BotNavInfo.NavProfile);
|
||||
|
@ -3081,11 +3108,36 @@ DoorTrigger* UTIL_GetNearestDoorTrigger(const Vector Location, nav_door* Door, C
|
|||
|
||||
void CheckAndHandleBreakableObstruction(AvHAIPlayer* pBot, const Vector MoveFrom, const Vector MoveTo)
|
||||
{
|
||||
if (pBot->BotNavInfo.CurrentPathPoint > pBot->BotNavInfo.CurrentPath.size()) { return; }
|
||||
if (pBot->BotNavInfo.CurrentPathPoint >= pBot->BotNavInfo.CurrentPath.size()) { return; }
|
||||
|
||||
Vector MoveDir = UTIL_GetVectorNormal2D(MoveTo - pBot->Edict->v.origin);
|
||||
|
||||
if (vIsZero(MoveDir))
|
||||
{
|
||||
MoveDir = UTIL_GetForwardVector2D(pBot->Edict->v.angles);
|
||||
}
|
||||
|
||||
TraceResult breakableHit;
|
||||
|
||||
edict_t* BlockingBreakableEdict = nullptr;
|
||||
|
||||
UTIL_TraceLine(pBot->Edict->v.origin, pBot->Edict->v.origin + (MoveDir * 100.0f), dont_ignore_monsters, dont_ignore_glass, pBot->Edict->v.pContainingEntity, &breakableHit);
|
||||
|
||||
if (!FNullEnt(breakableHit.pHit))
|
||||
{
|
||||
if (strcmp(STRING(breakableHit.pHit->v.classname), "func_breakable") == 0)
|
||||
{
|
||||
BlockingBreakableEdict = breakableHit.pHit;
|
||||
}
|
||||
}
|
||||
|
||||
bot_path_node CurrentPathNode = pBot->BotNavInfo.CurrentPath[pBot->BotNavInfo.CurrentPathPoint];
|
||||
|
||||
edict_t* BlockingBreakableEdict = UTIL_GetBreakableBlockingPathPoint(pBot, pBot->Edict->v.origin, CurrentPathNode.Location, SAMPLE_POLYAREA_GROUND, nullptr);
|
||||
if (FNullEnt(BlockingBreakableEdict))
|
||||
{
|
||||
|
||||
BlockingBreakableEdict = UTIL_GetBreakableBlockingPathPoint(pBot, pBot->Edict->v.origin, CurrentPathNode.Location, SAMPLE_POLYAREA_GROUND, nullptr);
|
||||
}
|
||||
|
||||
if (FNullEnt(BlockingBreakableEdict))
|
||||
{
|
||||
|
@ -5912,13 +5964,18 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!vIsZero(BotNavInfo->UnstuckMoveLocation) && vDist2DSq(pBot->CurrentFloorPosition, BotNavInfo->UnstuckMoveLocation) < sqrf(8.0f))
|
||||
{
|
||||
BotNavInfo->UnstuckMoveLocation = ZERO_VECTOR;
|
||||
}
|
||||
|
||||
if (vIsZero(BotNavInfo->UnstuckMoveLocation))
|
||||
{
|
||||
BotNavInfo->UnstuckMoveLocation = FindClosestPointBackOnPath(pBot);
|
||||
}
|
||||
|
||||
if (!vIsZero(BotNavInfo->UnstuckMoveLocation))
|
||||
{
|
||||
{
|
||||
MoveDirectlyTo(pBot, BotNavInfo->UnstuckMoveLocation);
|
||||
return true;
|
||||
}
|
||||
|
@ -6020,17 +6077,17 @@ Vector FindClosestPointBackOnPath(AvHAIPlayer* pBot)
|
|||
|
||||
// Now we find a path backwards from the valid nav mesh point to our location, trying to get as close as we can to it
|
||||
|
||||
dtStatus BackwardFindingStatus = FindPathClosestToPoint(pBot->BotNavInfo.NavProfile, ValidNavmeshPoint, pBot->CurrentFloorPosition, BackwardsPath, 500.0f);
|
||||
dtStatus BackwardFindingStatus = FindPathClosestToPoint(pBot->BotNavInfo.NavProfile, ValidNavmeshPoint, pBot->CurrentFloorPosition, BackwardsPath, UTIL_MetresToGoldSrcUnits(50.0f));
|
||||
|
||||
if (dtStatusSucceed(BackwardFindingStatus))
|
||||
{
|
||||
|
||||
Vector NewMoveLocation = ZERO_VECTOR;
|
||||
Vector NewMoveFromLocation = ZERO_VECTOR;
|
||||
Vector NewMoveLocation = prev(BackwardsPath.end())->Location;
|
||||
Vector NewMoveFromLocation = prev(BackwardsPath.end())->FromLocation;
|
||||
|
||||
for (auto it = BackwardsPath.rbegin(); it != BackwardsPath.rend(); it++)
|
||||
{
|
||||
if (UTIL_QuickTrace(pBot->Edict, pBot->Edict->v.origin, it->Location))
|
||||
if (vDist2DSq(pBot->Edict->v.origin, it->Location) > sqrf(GetPlayerRadius(pBot->Edict)) && UTIL_QuickTrace(pBot->Edict, pBot->Edict->v.origin, it->Location))
|
||||
{
|
||||
NewMoveLocation = it->Location;
|
||||
NewMoveFromLocation = it->FromLocation;
|
||||
|
|
|
@ -152,6 +152,8 @@ bool LoadNavMesh(const char* mapname);
|
|||
// Unloads the nav meshes (UnloadNavMeshes()) and then reloads them (LoadNavMesh). Map data such as doors, hives, locations are not touched.
|
||||
void ReloadNavMeshes();
|
||||
|
||||
AvHAINavMeshStatus NAV_GetNavMeshStatus();
|
||||
|
||||
void SetBaseNavProfile(AvHAIPlayer* pBot);
|
||||
void UpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
void MarineUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle);
|
||||
|
|
|
@ -107,7 +107,6 @@ float AIMGR_GetCommanderAllowedTime(AvHTeamNumber Team)
|
|||
|
||||
void AIMGR_UpdateAIPlayerCounts()
|
||||
{
|
||||
if (!NavmeshLoaded()) { return; }
|
||||
|
||||
for (auto BotIt = ActiveAIPlayers.begin(); BotIt != ActiveAIPlayers.end();)
|
||||
{
|
||||
|
@ -137,7 +136,7 @@ void AIMGR_UpdateAIPlayerCounts()
|
|||
LastAIPlayerCountUpdate = gpGlobals->time;
|
||||
|
||||
// If bots are disabled, ensure we've removed all bots from the game
|
||||
if (avh_botsenabled.value == 0)
|
||||
if (!AIMGR_IsBotEnabled())
|
||||
{
|
||||
if (AIMGR_GetNumAIPlayers() > 0)
|
||||
{
|
||||
|
@ -591,7 +590,7 @@ void AIDEBUG_TestPathFind()
|
|||
void AIMGR_UpdateAIPlayers()
|
||||
{
|
||||
// If bots are not enabled then do nothing
|
||||
if (avh_botsenabled.value == 0) { return; }
|
||||
if (!AIMGR_IsBotEnabled()) { return; }
|
||||
|
||||
static float PrevTime = 0.0f;
|
||||
static float CurrTime = 0.0f;
|
||||
|
@ -600,6 +599,8 @@ void AIMGR_UpdateAIPlayers()
|
|||
|
||||
static int CurrentBotSkill = 1;
|
||||
|
||||
static bool bUpdateEven = false;
|
||||
|
||||
CurrTime = gpGlobals->time;
|
||||
|
||||
if (CurrTime < PrevTime)
|
||||
|
@ -642,12 +643,15 @@ void AIMGR_UpdateAIPlayers()
|
|||
memcpy(&bot->BotSkillSettings, &NewSkillSettings, sizeof(bot_skill));
|
||||
}
|
||||
|
||||
int BotIndex = distance(ActiveAIPlayers.begin(), BotIt);
|
||||
|
||||
BotUpdateViewRotation(bot, FrameDelta);
|
||||
|
||||
if (IS_DEDICATED_SERVER() || ThinkDelta >= BOT_MIN_FRAME_TIME)
|
||||
{
|
||||
BotDeltaTime = ThinkDelta;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (bot == AIMGR_GetDebugAIPlayer())
|
||||
{
|
||||
bool bBreak = true; // Add a break point here if you want to debug a specific bot
|
||||
|
@ -674,6 +678,7 @@ void AIMGR_UpdateAIPlayers()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bHasRoundStarted)
|
||||
{
|
||||
|
@ -707,25 +712,30 @@ void AIMGR_UpdateAIPlayers()
|
|||
BotResumePlay(bot);
|
||||
}
|
||||
|
||||
StartNewBotFrame(bot);
|
||||
bool bIsEvenBot = !(BotIndex % 2);
|
||||
|
||||
UpdateBotChat(bot);
|
||||
|
||||
if (avh_botdebugmode.value == 1)
|
||||
if (bIsEvenBot == bUpdateEven)
|
||||
{
|
||||
DroneThink(bot);
|
||||
StartNewBotFrame(bot);
|
||||
|
||||
UpdateBotChat(bot);
|
||||
|
||||
if (avh_botdebugmode.value == 1)
|
||||
{
|
||||
DroneThink(bot);
|
||||
}
|
||||
else if (avh_botdebugmode.value == 2)
|
||||
{
|
||||
TestNavThink(bot);
|
||||
}
|
||||
else
|
||||
{
|
||||
AIPlayerThink(bot);
|
||||
}
|
||||
|
||||
EndBotFrame(bot);
|
||||
}
|
||||
else if (avh_botdebugmode.value == 2)
|
||||
{
|
||||
TestNavThink(bot);
|
||||
}
|
||||
else
|
||||
{
|
||||
AIPlayerThink(bot);
|
||||
}
|
||||
|
||||
EndBotFrame(bot);
|
||||
|
||||
|
||||
BotUpdateDesiredViewRotation(bot);
|
||||
}
|
||||
else
|
||||
|
@ -763,7 +773,7 @@ void AIMGR_UpdateAIPlayers()
|
|||
}
|
||||
|
||||
PrevTime = CurrTime;
|
||||
|
||||
bUpdateEven = !bUpdateEven;
|
||||
}
|
||||
|
||||
float AIMGR_GetBotDeltaTime()
|
||||
|
@ -920,7 +930,7 @@ void AIMGR_RemoveBotsInReadyRoom()
|
|||
|
||||
void AIMGR_ResetRound()
|
||||
{
|
||||
if (avh_botsenabled.value == 0 || !NavmeshLoaded()) { return; } // Do nothing if we're not using bots
|
||||
if (!AIMGR_IsBotEnabled()) { return; } // Do nothing if we're not using bots
|
||||
|
||||
// AI Players would be 0 if the round is being reset because a new game is starting. If the round is reset
|
||||
// from a console command, or tournament mode readying up etc, then bot logic is unaffected
|
||||
|
@ -964,7 +974,7 @@ void AIMGR_ReloadNavigationData()
|
|||
|
||||
void AIMGR_RoundStarted()
|
||||
{
|
||||
if (avh_botsenabled.value == 0 || !NavmeshLoaded()) { return; } // Do nothing if we're not using bots
|
||||
if (!AIMGR_IsBotEnabled()) { return; } // Do nothing if we're not using bots
|
||||
|
||||
bHasRoundStarted = true;
|
||||
|
||||
|
@ -1038,7 +1048,12 @@ void AIMGR_ClearBotData()
|
|||
|
||||
void AIMGR_NewMap()
|
||||
{
|
||||
if (avh_botsenabled.value == 0) { return; } // Do nothing if we're not using bots
|
||||
if (NavmeshLoaded())
|
||||
{
|
||||
UnloadNavigationData();
|
||||
}
|
||||
|
||||
if (!AIMGR_IsBotEnabled()) { return; } // Do nothing if we're not using bots
|
||||
|
||||
bMapDataInitialised = false;
|
||||
|
||||
|
@ -1049,11 +1064,6 @@ void AIMGR_NewMap()
|
|||
|
||||
AITAC_ClearMapAIData(true);
|
||||
|
||||
if (NavmeshLoaded())
|
||||
{
|
||||
UnloadNavigationData();
|
||||
}
|
||||
|
||||
CONFIG_ParseConfigFile();
|
||||
|
||||
AIMGR_BotPrecache();
|
||||
|
@ -1063,6 +1073,21 @@ void AIMGR_NewMap()
|
|||
bPlayerSpawned = false;
|
||||
}
|
||||
|
||||
bool AIMGR_IsNavmeshLoaded()
|
||||
{
|
||||
return NavmeshLoaded();
|
||||
}
|
||||
|
||||
bool AIMGR_IsBotEnabled()
|
||||
{
|
||||
return avh_botsenabled.value > 0 && NAV_GetNavMeshStatus() != NAVMESH_STATUS_FAILED;
|
||||
}
|
||||
|
||||
AvHAINavMeshStatus AIMGR_GetNavMeshStatus()
|
||||
{
|
||||
return NAV_GetNavMeshStatus();
|
||||
}
|
||||
|
||||
void AIMGR_LoadNavigationData()
|
||||
{
|
||||
// Don't reload the nav mesh if it's already loaded
|
||||
|
@ -1072,7 +1097,7 @@ void AIMGR_LoadNavigationData()
|
|||
|
||||
if (!loadNavigationData(theCStrLevelName))
|
||||
{
|
||||
ALERT(at_console, "Failed to load navigation data for %s\n");
|
||||
ALERT(at_console, "Failed to load navigation data for %s\n", theCStrLevelName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,11 @@ int AIMGR_GetNumAIPlayersWithRoleOnTeam(AvHTeamNumber Team, AvHAIBotRole Role, A
|
|||
|
||||
int AIMGR_GetNumHumansOfClassOnTeam(AvHTeamNumber Team, AvHUser3 PlayerType);
|
||||
|
||||
bool AIMGR_IsNavmeshLoaded();
|
||||
AvHAINavMeshStatus AIMGR_GetNavMeshStatus();
|
||||
|
||||
bool AIMGR_IsBotEnabled();
|
||||
|
||||
void AIMGR_LoadNavigationData();
|
||||
void AIMGR_ReloadNavigationData();
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ bool AITASK_IsTaskUrgent(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
case TASK_GET_AMMO:
|
||||
return (UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) == 0);
|
||||
case TASK_GET_HEALTH:
|
||||
return (IsPlayerMarine(pBot->Edict)) ? (pBot->Edict->v.health < 50.0f) : (GetPlayerOverallHealthPercent(pBot->Edict) < 50.0f);
|
||||
return (IsPlayerMarine(pBot->Edict)) ? (pBot->Edict->v.health < 50.0f) : (GetPlayerOverallHealthPercent(pBot->Edict) < 0.5f);
|
||||
case TASK_ATTACK:
|
||||
case TASK_GET_WEAPON:
|
||||
case TASK_GET_EQUIPMENT:
|
||||
|
@ -978,13 +978,20 @@ bool AITASK_IsAlienGetHealthTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* T
|
|||
{
|
||||
if (FNullEnt(Task->TaskTarget) || (Task->TaskTarget->v.deadflag != DEAD_NO)) { return false; }
|
||||
|
||||
if (IsEdictHive(Task->TaskTarget))
|
||||
{
|
||||
AvHAIHiveDefinition* HiveRef = AITAC_GetHiveFromEdict(Task->TaskTarget);
|
||||
|
||||
if (!HiveRef || HiveRef->Status != HIVE_STATUS_BUILT) { return false; }
|
||||
}
|
||||
|
||||
if (IsEdictStructure(Task->TaskTarget) && !UTIL_IsBuildableStructureStillReachable(pBot, Task->TaskTarget)) { return false; }
|
||||
|
||||
if (IsEdictPlayer(Task->TaskTarget))
|
||||
{
|
||||
if (!IsPlayerGorge(Task->TaskTarget)) { return false; }
|
||||
}
|
||||
return (pBot->Edict->v.health < pBot->Edict->v.max_health) || (!IsPlayerSkulk(pBot->Edict) && pBot->Edict->v.armorvalue < (GetPlayerMaxArmour(pBot->Edict) * 0.7f));
|
||||
return (pBot->Edict->v.health < pBot->Edict->v.max_health) || (!IsPlayerSkulk(pBot->Edict) && pBot->Edict->v.armorvalue < (GetPlayerMaxArmour(pBot->Edict) * 0.8f));
|
||||
}
|
||||
|
||||
bool AITASK_IsAlienHealTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
|
|
|
@ -236,6 +236,8 @@ extern cvar_t avh_botsenabled;
|
|||
extern cvar_t avh_botautomode;
|
||||
extern cvar_t avh_botminplayers;
|
||||
extern cvar_t avh_botskill;
|
||||
extern cvar_t avh_botcommandermode;
|
||||
extern cvar_t avh_botdebugmode;
|
||||
|
||||
BOOL IsSpawnPointValid( CBaseEntity *pPlayer, CBaseEntity *pSpot );
|
||||
inline int FNullEnt( CBaseEntity *ent ) { return (ent == NULL) || FNullEnt( ent->edict() ); }
|
||||
|
@ -348,15 +350,19 @@ AvHGamerules::AvHGamerules() : mTeamA(TEAM_ONE), mTeamB(TEAM_TWO)
|
|||
RegisterServerVariable(&avh_fastjp);
|
||||
RegisterServerVariable(&avh_randomrfk);
|
||||
RegisterServerVariable(&avh_parasiteonmap);
|
||||
// AI Player cvars
|
||||
RegisterServerVariable(&avh_botsenabled);
|
||||
RegisterServerVariable(&avh_botautomode);
|
||||
RegisterServerVariable(&avh_botminplayers);
|
||||
RegisterServerVariable(&avh_botskill);
|
||||
RegisterServerVariable(&avh_botdebugmode);
|
||||
RegisterServerVariable(&avh_botcommandermode);
|
||||
|
||||
REGISTER_SERVER_FUNCTION("sv_addaiplayer", []()
|
||||
{
|
||||
if (avh_botsenabled.value == 0)
|
||||
if (!AIMGR_IsBotEnabled())
|
||||
{
|
||||
ALERT(at_console, "Bots are disabled, or the navmesh could not be loaded.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -377,6 +383,12 @@ AvHGamerules::AvHGamerules() : mTeamA(TEAM_ONE), mTeamB(TEAM_TWO)
|
|||
|
||||
REGISTER_SERVER_FUNCTION("sv_removeaiplayer", []()
|
||||
{
|
||||
if (!AIMGR_IsBotEnabled())
|
||||
{
|
||||
ALERT(at_console, "Bots are disabled, or the navmesh could not be loaded.");
|
||||
return;
|
||||
}
|
||||
|
||||
int DesiredTeam = 0;
|
||||
|
||||
if (CMD_ARGC() >= 2)
|
||||
|
@ -394,7 +406,14 @@ AvHGamerules::AvHGamerules() : mTeamA(TEAM_ONE), mTeamB(TEAM_TWO)
|
|||
|
||||
REGISTER_SERVER_FUNCTION("sv_reloadnavmesh", []()
|
||||
{
|
||||
AIMGR_ReloadNavigationData();
|
||||
if (avh_botsenabled.value > 0)
|
||||
{
|
||||
AIMGR_ReloadNavigationData();
|
||||
}
|
||||
else
|
||||
{
|
||||
ALERT(at_console, "Bots are disabled, enable first before loading the navmesh.");
|
||||
}
|
||||
});
|
||||
|
||||
g_VoiceGameMgr.Init(&gVoiceHelper, gpGlobals->maxClients);
|
||||
|
@ -2323,11 +2342,6 @@ void AvHGamerules::PostWorldPrecacheReset(bool inNewMap)
|
|||
// Must happen after processing spawn entities
|
||||
this->RecalculateMapMode();
|
||||
|
||||
if (avh_botsenabled.value > 0)
|
||||
{
|
||||
AIMGR_LoadNavigationData();
|
||||
}
|
||||
|
||||
// Loop through all players that are playing and respawn them
|
||||
|
||||
bool theJustResetGameAtCountdownStart = false;
|
||||
|
@ -3615,12 +3629,16 @@ void AvHGamerules::Think(void)
|
|||
this->UpdateGameTime();
|
||||
|
||||
if(GET_RUN_CODE(4))
|
||||
{
|
||||
|
||||
{
|
||||
AIMGR_UpdateAIPlayerCounts();
|
||||
|
||||
if (avh_botsenabled.value > 0)
|
||||
if (AIMGR_IsBotEnabled())
|
||||
{
|
||||
if (AIMGR_GetNavMeshStatus() == NAVMESH_STATUS_PENDING)
|
||||
{
|
||||
AIMGR_LoadNavigationData();
|
||||
}
|
||||
|
||||
AIMGR_UpdateAIMapData();
|
||||
|
||||
AIMGR_UpdateAIPlayers();
|
||||
|
|
Loading…
Reference in a new issue