mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Use KeyValues system for level settings file instead
Previously we used Json, however the rest of the game features KeyValues. I changed the system to feature KeyValues instead, to maintain consistency. Also improved the logic behind loading/parsing so we don't reparse the same level settings file if the pointer is still valid and we are on the same level.
This commit is contained in:
parent
d3b2893cdc
commit
a7c33d4df3
@ -10,6 +10,7 @@
|
||||
#include "tier0/jobthread.h"
|
||||
#include "engine/sys_dll2.h"
|
||||
#include "engine/host_cmd.h"
|
||||
#include "engine/host_state.h"
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
#include "rtech/rtech_game.h"
|
||||
@ -17,18 +18,20 @@
|
||||
#include "datacache/mdlcache.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
|
||||
string g_svLevelName;
|
||||
vector<string> g_vAllMaps;
|
||||
string s_svLevelName;
|
||||
bool s_bLevelResourceInitialized = false;
|
||||
bool s_bBasePaksInitialized = false;
|
||||
KeyValues* s_pLevelSetKV = nullptr;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: checks if level has changed
|
||||
// Input : &svLevelName -
|
||||
// Input : *pszLevelName -
|
||||
// Output : true if level name deviates from previous level
|
||||
//-----------------------------------------------------------------------------
|
||||
bool MOD_LevelHasChanged(const string& svLevelName)
|
||||
bool MOD_LevelHasChanged(const char* pszLevelName)
|
||||
{
|
||||
return (g_svLevelName.compare(svLevelName) != 0);
|
||||
return (s_svLevelName.compare(pszLevelName) != 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -240,6 +243,9 @@ void MOD_ProcessPakQueue()
|
||||
|
||||
g_pakLoadApi->UnloadPak(*(RPakHandle_t*)v10);
|
||||
MOD_UnloadPakFile(); // Unload mod pak files.
|
||||
|
||||
s_pLevelSetKV->DeleteThis(); // Delete current level settings if we drop all paks..
|
||||
s_pLevelSetKV = nullptr;
|
||||
}
|
||||
if (v13 && (unsigned int)(v13 - 13) > 1)
|
||||
return;
|
||||
@ -315,7 +321,7 @@ void MOD_ProcessPakQueue()
|
||||
if (s_bBasePaksInitialized && !s_bLevelResourceInitialized)
|
||||
{
|
||||
s_bLevelResourceInitialized = true;
|
||||
MOD_PreloadPakFile(g_svLevelName);
|
||||
MOD_PreloadLevelPaks(g_pHostState->m_levelName);
|
||||
}
|
||||
*(_DWORD*)v15 = g_pakLoadApi->LoadAsync(v17, g_pMallocPool.GetPtr(), 4, 0);
|
||||
|
||||
@ -352,60 +358,65 @@ bool MOD_LoadPakForMap(const char* szLevelName)
|
||||
if (MOD_LevelHasChanged(szLevelName))
|
||||
s_bLevelResourceInitialized = false;
|
||||
|
||||
g_svLevelName = szLevelName;
|
||||
s_svLevelName = szLevelName;
|
||||
return v_MOD_LoadPakForMap(szLevelName);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads required pakfile assets for specified BSP
|
||||
// Purpose: loads the level settings file, returns current if level hasn't changed.
|
||||
// Input : *pszLevelName -
|
||||
// Output : KeyValues*
|
||||
//-----------------------------------------------------------------------------
|
||||
KeyValues* MOD_GetLevelSettings(const char* pszLevelName)
|
||||
{
|
||||
if (s_pLevelSetKV)
|
||||
{
|
||||
if (!MOD_LevelHasChanged(pszLevelName))
|
||||
{
|
||||
return s_pLevelSetKV;
|
||||
}
|
||||
|
||||
s_pLevelSetKV->DeleteThis();
|
||||
}
|
||||
|
||||
char szPathBuffer[MAX_PATH];
|
||||
snprintf(szPathBuffer, sizeof(szPathBuffer), "scripts/levels/settings/%s.kv", pszLevelName);
|
||||
|
||||
s_pLevelSetKV = FileSystem()->LoadKeyValues(IFileSystem::TYPE_LEVELSETTINGS, szPathBuffer, "GAME");
|
||||
return s_pLevelSetKV;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads required pakfile assets for specified BSP level
|
||||
// Input : &svSetFile -
|
||||
//-----------------------------------------------------------------------------
|
||||
void MOD_PreloadPakFile(const string& svLevelName)
|
||||
void MOD_PreloadLevelPaks(const char* pszLevelName)
|
||||
{
|
||||
ostringstream ostream;
|
||||
ostream << "scripts/levels/settings/" << svLevelName << ".json";
|
||||
KeyValues* pSettingsKV = MOD_GetLevelSettings(pszLevelName);
|
||||
|
||||
FileHandle_t pFile = FileSystem()->Open(ostream.str().c_str(), "rt");
|
||||
if (!pFile)
|
||||
if (!pSettingsKV)
|
||||
return;
|
||||
|
||||
uint32_t nLen = FileSystem()->Size(pFile);
|
||||
uint8_t* pBuf = MemAllocSingleton()->Alloc<uint8_t>(nLen);
|
||||
KeyValues* pPakListKV = pSettingsKV->FindKey("PakList");
|
||||
|
||||
int nRead = FileSystem()->Read(pBuf, nLen, pFile);
|
||||
FileSystem()->Close(pFile);
|
||||
if (!pPakListKV)
|
||||
return;
|
||||
|
||||
pBuf[nRead] = '\0';
|
||||
char szPathBuffer[MAX_PATH];
|
||||
|
||||
try
|
||||
for (KeyValues* pSubKey = pPakListKV->GetFirstSubKey(); pSubKey != nullptr; pSubKey = pSubKey->GetNextKey())
|
||||
{
|
||||
nlohmann::json jsIn = nlohmann::json::parse(pBuf);
|
||||
if (!jsIn.is_null())
|
||||
{
|
||||
if (!jsIn["rpak"].is_null())
|
||||
{
|
||||
for (auto& it : jsIn["rpak"])
|
||||
{
|
||||
if (it.is_string())
|
||||
{
|
||||
string svToLoad = it.get<string>() + ".rpak";
|
||||
RPakHandle_t nPakId = g_pakLoadApi->LoadAsync(svToLoad.c_str(), g_pMallocPool.GetPtr(), 4, 0);
|
||||
if (!pSubKey->GetBool())
|
||||
continue;
|
||||
|
||||
if (nPakId == INVALID_PAK_HANDLE)
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "%s: unable to load pak '%s' results '%d'\n", __FUNCTION__, svToLoad.c_str(), nPakId);
|
||||
else
|
||||
g_vLoadedPakHandle.push_back(nPakId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Warning(eDLL_T::RTECH, "Exception while parsing RPak load list: '%s'\n", ex.what());
|
||||
}
|
||||
snprintf(szPathBuffer, sizeof(szPathBuffer), "%s.rpak", pSubKey->GetName());
|
||||
RPakHandle_t nPakId = g_pakLoadApi->LoadAsync(szPathBuffer, g_pMallocPool.GetPtr(), 4, 0);
|
||||
|
||||
MemAllocSingleton()->Free(pBuf);
|
||||
if (nPakId == INVALID_PAK_HANDLE)
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "%s: unable to load pak '%s' results '%d'\n", __FUNCTION__, szPathBuffer, nPakId);
|
||||
else
|
||||
g_vLoadedPakHandle.push_back(nPakId);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1,6 +1,11 @@
|
||||
#pragma once
|
||||
#include "tier0/jobthread.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class KeyValues;
|
||||
|
||||
inline CMemory p_MOD_LoadPakForMap;
|
||||
inline auto v_MOD_LoadPakForMap = p_MOD_LoadPakForMap.RCast<bool(*)(const char* szLevelName)>();
|
||||
|
||||
@ -24,12 +29,12 @@ inline auto sub_14045A1D0 = p_MOD_ProcessPakQueue.RCast<__int64(*)(unsigned __in
|
||||
inline auto sub_140441220 = p_MOD_ProcessPakQueue.RCast<void(*)(__int64 a1, __int64 a2)>();
|
||||
|
||||
extern bool s_bBasePaksInitialized;
|
||||
extern string g_svLevelName;
|
||||
extern vector<string> g_vAllMaps;
|
||||
|
||||
bool MOD_LevelHasChanged(const string& svLevelName);
|
||||
bool MOD_LevelHasChanged(const char* pszLevelName);
|
||||
void MOD_GetAllInstalledMaps();
|
||||
void MOD_PreloadPakFile(const string& svLevelName);
|
||||
KeyValues* MOD_GetLevelSettings(const char* pszLevelName);
|
||||
void MOD_PreloadLevelPaks(const char* pszLevelName);
|
||||
void MOD_UnloadPakFile(void);
|
||||
|
||||
void CModelBsp_Attach();
|
||||
|
@ -5,8 +5,9 @@
|
||||
//===========================================================================//
|
||||
#include "core/stdafx.h"
|
||||
#include "tier1/cvar.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "rtech/rtech_utils.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
#include "engine/cmodel_bsp.h"
|
||||
#include "materialsystem/cmaterialglue.h"
|
||||
#include "materialsystem/cmaterialsystem.h"
|
||||
|
||||
@ -18,46 +19,23 @@
|
||||
//---------------------------------------------------------------------------------
|
||||
void StreamDB_Init(const char* pszLevelName)
|
||||
{
|
||||
ostringstream ostream;
|
||||
ostream << "scripts/levels/settings/" << pszLevelName << ".json";
|
||||
KeyValues* pSettingsKV = MOD_GetLevelSettings(pszLevelName);
|
||||
|
||||
FileHandle_t pFile = FileSystem()->Open(ostream.str().c_str(), "rt");
|
||||
if (pFile)
|
||||
if (pSettingsKV)
|
||||
{
|
||||
uint32_t nLen = FileSystem()->Size(pFile);
|
||||
uint8_t* pBuf = MemAllocSingleton()->Alloc<uint8_t>(nLen);
|
||||
KeyValues* pStreamKV = pSettingsKV->FindKey("StreamDB");
|
||||
|
||||
int nRead = FileSystem()->Read(pBuf, nLen, pFile);
|
||||
FileSystem()->Close(pFile);
|
||||
|
||||
pBuf[nRead] = '\0';
|
||||
|
||||
try
|
||||
if (pStreamKV)
|
||||
{
|
||||
nlohmann::json jsIn = nlohmann::json::parse(pBuf);
|
||||
if (!jsIn.is_null())
|
||||
{
|
||||
if (!jsIn[STREAM_DB_EXT].is_null())
|
||||
{
|
||||
string svStreamDBFile = jsIn[STREAM_DB_EXT].get<string>();
|
||||
DevMsg(eDLL_T::MS, "%s: Loading override STBSP file '%s.%s'\n", __FUNCTION__, svStreamDBFile.c_str(), STREAM_DB_EXT);
|
||||
const char* pszColumnName = pStreamKV->GetString();
|
||||
DevMsg(eDLL_T::MS, "%s: Loading override STBSP file '%s.stbsp'\n", __FUNCTION__, pszColumnName);
|
||||
|
||||
v_StreamDB_Init(svStreamDBFile.c_str());
|
||||
MemAllocSingleton()->Free(pBuf);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
v_StreamDB_Init(pszColumnName);
|
||||
return;
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
Warning(eDLL_T::MS, "%s: Exception while parsing STBSP override:\n%s\n", __FUNCTION__, ex.what());
|
||||
}
|
||||
|
||||
MemAllocSingleton()->Free(pBuf);
|
||||
}
|
||||
|
||||
DevMsg(eDLL_T::MS, "%s: Loading STBSP file '%s.%s'\n", __FUNCTION__, pszLevelName, STREAM_DB_EXT);
|
||||
DevMsg(eDLL_T::MS, "%s: Loading STBSP file '%s.stbsp'\n", __FUNCTION__, pszLevelName);
|
||||
v_StreamDB_Init(pszLevelName);
|
||||
}
|
||||
|
||||
|
@ -364,6 +364,7 @@ public:
|
||||
TYPE_SOUNDEMITTER,
|
||||
TYPE_SOUNDSCAPE,
|
||||
TYPE_SOUNDOPERATORS,
|
||||
TYPE_LEVELSETTINGS,
|
||||
TYPE_COMMON,
|
||||
NUM_PRELOAD_TYPES
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user