Add sv_load_all_maps & sv_stop_loading_all_maps to help automate node graph generation

This commit is contained in:
Sam V 2023-10-29 14:31:56 +01:00
parent 1261294189
commit 19d94e479a
4 changed files with 116 additions and 0 deletions

View file

@ -12,6 +12,10 @@
* Fixed crash when +USEing NPCs that have just exited a scripted sequence (Thanks malortie)
* Fixed talk monsters resetting other talk monsters' dying schedule if they are both killed at the same time (Thanks FreeSlave)
### Features
* Added sv_load_all_maps & sv_stop_loading_all_maps to help automate node graph generation
## Changes in V1.0.0 Release Candidate 002
### Bug fixes

View file

@ -23,8 +23,13 @@
*/
#include <algorithm>
#include <string>
#include <vector>
#include "extdll.h"
#include "util.h"
#include "filesystem_utils.h"
#include "cbase.h"
#include "com_model.h"
#include "saverestore.h"
@ -40,6 +45,7 @@
#include "usercmd.h"
#include "netadr.h"
#include "pm_shared.h"
#include "pm_defs.h"
#include "UserMessages.h"
DLL_GLOBAL unsigned int g_ulFrameCount;
@ -773,6 +779,101 @@ void ParmsChangeLevel()
pSaveData->connectionCount = BuildChangeList(pSaveData->levelList, MAX_LEVEL_CONNECTIONS);
}
static std::vector<std::string> g_MapsToLoad;
static void LoadNextMap()
{
const std::string mapName = std::move(g_MapsToLoad.back());
g_MapsToLoad.pop_back();
pmove->Con_Printf("Loading map \"%s\" automatically (%d left)\n",
mapName.c_str(), static_cast<int>(g_MapsToLoad.size() + 1));
if (g_MapsToLoad.empty())
{
pmove->Con_Printf("Loading last map\n");
g_MapsToLoad.shrink_to_fit();
}
SERVER_COMMAND(UTIL_VarArgs("map \"%s\"\n", mapName.c_str()));
}
static void LoadAllMaps()
{
if (!g_MapsToLoad.empty())
{
pmove->Con_Printf("Already loading all maps (%d remaining)\nUse sv_stop_loading_all_maps to stop\n",
static_cast<int>(g_MapsToLoad.size()));
return;
}
FileFindHandle_t handle = FILESYSTEM_INVALID_FIND_HANDLE;
const char* fileName = g_pFileSystem->FindFirst("maps/*.bsp", &handle);
if (fileName != nullptr)
{
do
{
std::string mapName = fileName;
mapName.resize(mapName.size() - 4);
if (std::find_if(g_MapsToLoad.begin(), g_MapsToLoad.end(), [=](const auto& candidate)
{ return 0 == stricmp(candidate.c_str(), mapName.c_str()); }) == g_MapsToLoad.end())
{
g_MapsToLoad.push_back(std::move(mapName));
}
} while ((fileName = g_pFileSystem->FindNext(handle)) != nullptr);
g_pFileSystem->FindClose(handle);
// Sort in reverse order so the first map in alphabetic order is loaded first.
std::sort(g_MapsToLoad.begin(), g_MapsToLoad.end(), [](const auto& lhs, const auto& rhs)
{ return rhs < lhs; });
}
if (!g_MapsToLoad.empty())
{
if (CMD_ARGC() == 2)
{
const char* firstMapToLoad = CMD_ARGV(1);
// Clear out all maps that would have been loaded before this one.
if (auto it = std::find(g_MapsToLoad.begin(), g_MapsToLoad.end(), firstMapToLoad);
it != g_MapsToLoad.end())
{
const std::size_t numberOfMapsToSkip = g_MapsToLoad.size() - (it - g_MapsToLoad.begin());
g_MapsToLoad.erase(it + 1, g_MapsToLoad.end());
pmove->Con_Printf("Skipping %d maps to start with \"%s\"\n",
static_cast<int>(numberOfMapsToSkip), g_MapsToLoad.back().c_str());
}
else
{
pmove->Con_Printf("Unknown map \"%s\", starting from beginning\n", firstMapToLoad);
}
}
pmove->Con_Printf("Loading %d maps one at a time to generate files\n", static_cast<int>(g_MapsToLoad.size()));
// Load the first map right now.
LoadNextMap();
}
else
{
pmove->Con_Printf("No maps to load\n");
}
}
void InitMapLoadingUtils()
{
g_engfuncs.pfnAddServerCommand("sv_load_all_maps", &LoadAllMaps);
// Escape hatch in case the command is executed in error.
g_engfuncs.pfnAddServerCommand("sv_stop_loading_all_maps", []()
{ g_MapsToLoad.clear(); });
}
static bool g_LastAllowBunnyHoppingState = false;
//
@ -807,6 +908,13 @@ void StartFrame()
g_engfuncs.pfnSetPhysicsKeyValue(player->edict(), "bj", UTIL_dtos1(allowBunnyHopping ? 1 : 0));
}
}
// If we're loading all maps then change maps after 3 seconds (time starts at 1)
// to give the game time to generate files.
if (!g_MapsToLoad.empty() && gpGlobals->time > 4)
{
LoadNextMap();
}
}

View file

@ -24,6 +24,7 @@ extern void ClientCommand(edict_t* pEntity);
extern void ClientUserInfoChanged(edict_t* pEntity, char* infobuffer);
extern void ServerActivate(edict_t* pEdictList, int edictCount, int clientMax);
extern void ServerDeactivate();
void InitMapLoadingUtils();
extern void StartFrame();
extern void PlayerPostThink(edict_t* pEntity);
extern void PlayerPreThink(edict_t* pEntity);

View file

@ -15,6 +15,7 @@
#include "extdll.h"
#include "eiface.h"
#include "util.h"
#include "client.h"
#include "game.h"
#include "filesystem_utils.h"
@ -903,6 +904,8 @@ void GameDLLInit()
CVAR_REGISTER(&sk_player_leg3);
// END REGISTER CVARS FOR SKILL LEVEL STUFF
InitMapLoadingUtils();
SERVER_COMMAND("exec skill.cfg\n");
}