mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2025-04-09 11:10:07 +03:00
Add automatic precaching of model textures, groups and sounds
This commit is contained in:
parent
879b061bc8
commit
df4e565efd
@ -34,6 +34,7 @@
|
|||||||
#include "CoreConfig.h"
|
#include "CoreConfig.h"
|
||||||
#include <resdk/mod_rehlds_api.h>
|
#include <resdk/mod_rehlds_api.h>
|
||||||
#include <amtl/am-utility.h>
|
#include <amtl/am-utility.h>
|
||||||
|
#include <studio.h>
|
||||||
|
|
||||||
plugin_info_t Plugin_info =
|
plugin_info_t Plugin_info =
|
||||||
{
|
{
|
||||||
@ -157,6 +158,9 @@ int FF_ClientConnectEx = -1;
|
|||||||
IFileSystem* g_FileSystem;
|
IFileSystem* g_FileSystem;
|
||||||
HLTypeConversion TypeConversion;
|
HLTypeConversion TypeConversion;
|
||||||
|
|
||||||
|
bool HasReHLDS;
|
||||||
|
server_t *Server;
|
||||||
|
|
||||||
bool ColoredMenus(const char *ModName)
|
bool ColoredMenus(const char *ModName)
|
||||||
{
|
{
|
||||||
const char * pModNames[] = { "cstrike", "czero", "dmc", "dod", "tfc", "valve" };
|
const char * pModNames[] = { "cstrike", "czero", "dmc", "dod", "tfc", "valve" };
|
||||||
@ -679,6 +683,121 @@ void C_ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
|
|||||||
g_memreport_enabled = true;
|
g_memreport_enabled = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!HasReHLDS && Server)
|
||||||
|
{
|
||||||
|
const auto precacheTextures = [](const char *model, studiohdr_t *pStudioHeader)
|
||||||
|
{
|
||||||
|
if (pStudioHeader->textureindex)
|
||||||
|
{
|
||||||
|
return; // Skip if textures are internal
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto modelLength = strlen(model);
|
||||||
|
|
||||||
|
if (modelLength > MAX_MODEL_NAME - 2)
|
||||||
|
{
|
||||||
|
return; // Skip if model length goes above the max minus 'T' + EOS
|
||||||
|
}
|
||||||
|
|
||||||
|
char textureModel[MAX_MODEL_NAME];
|
||||||
|
ke::SafeStrcpy(textureModel, sizeof textureModel, model);
|
||||||
|
|
||||||
|
const auto modelExtensionLength = sizeof ".mdl" - 1;
|
||||||
|
const auto modelExtension = &textureModel[modelLength - modelExtensionLength];
|
||||||
|
ke::SafeStrcpy(modelExtension, sizeof textureModel - modelLength - modelExtensionLength, "T.mdl");
|
||||||
|
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
if (!g_FileSystem->FileExists(textureModel))
|
||||||
|
{
|
||||||
|
modelExtension[0] = 't';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PRECACHE_GENERIC(textureModel);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto precacheGroups = [](studiohdr_t *pStudioHeader)
|
||||||
|
{
|
||||||
|
if (pStudioHeader->numseqgroups <= 1)
|
||||||
|
{
|
||||||
|
return; // Skip if no available group
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto pSeqGroup = reinterpret_cast<mstudioseqgroup_t *>(reinterpret_cast<uintptr_t>(pStudioHeader) + pStudioHeader->seqgroupindex);
|
||||||
|
|
||||||
|
for (auto group = 1; group < pStudioHeader->numseqgroups; group++)
|
||||||
|
{
|
||||||
|
if (pSeqGroup[group].name[0] == '\0')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char seqGroupName[MAX_QPATH];
|
||||||
|
const auto length = ke::SafeStrcpy(seqGroupName, sizeof seqGroupName, pSeqGroup[group].name);
|
||||||
|
|
||||||
|
for (auto index = 0u; index < length; index++)
|
||||||
|
{
|
||||||
|
if (seqGroupName[index] == '\\')
|
||||||
|
{
|
||||||
|
seqGroupName[index] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRECACHE_GENERIC(seqGroupName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto precacheSounds = [](studiohdr_t *pStudioHeader)
|
||||||
|
{
|
||||||
|
const auto pSeqDesc = reinterpret_cast<mstudioseqdesc_t *>(reinterpret_cast<uintptr_t>(pStudioHeader) + pStudioHeader->seqindex);
|
||||||
|
|
||||||
|
for (auto sequence = 0; sequence < pStudioHeader->numseq; sequence++)
|
||||||
|
{
|
||||||
|
const auto pEvent = reinterpret_cast<mstudioevent_t *>(reinterpret_cast<uintptr_t>(pStudioHeader) + pSeqDesc[sequence].eventindex);
|
||||||
|
|
||||||
|
for (auto index = 0; index < pSeqDesc[sequence].numevents; index++)
|
||||||
|
{
|
||||||
|
if (pEvent[index].event != 5004 || pEvent[index].options[0] == '\0')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char sound[MAX_QPATH];
|
||||||
|
ke::SafeSprintf(sound, sizeof sound, "sound/%s", pEvent[index].options);
|
||||||
|
|
||||||
|
PRECACHE_GENERIC(sound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto pEntity = CREATE_ENTITY();
|
||||||
|
|
||||||
|
for (auto index = 1u; index < ARRAYSIZE(Server->model_precache); index++)
|
||||||
|
{
|
||||||
|
const auto model = Server->model_precache[index];
|
||||||
|
|
||||||
|
if (!model)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Server->models[index]->type != mod_studio)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pEntity->v.modelindex = index;
|
||||||
|
|
||||||
|
const auto pStudioHeader = static_cast<studiohdr_t *>(GET_MODEL_PTR(pEntity));
|
||||||
|
|
||||||
|
precacheTextures(model, pStudioHeader);
|
||||||
|
precacheGroups(pStudioHeader);
|
||||||
|
precacheSounds(pStudioHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
REMOVE_ENTITY(pEntity);
|
||||||
|
}
|
||||||
|
|
||||||
g_activated = true;
|
g_activated = true;
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
@ -1670,14 +1789,30 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
|||||||
|
|
||||||
if (RehldsApi_Init())
|
if (RehldsApi_Init())
|
||||||
{
|
{
|
||||||
|
HasReHLDS = true;
|
||||||
|
|
||||||
RehldsHookchains->SV_DropClient()->registerHook(SV_DropClient_RH);
|
RehldsHookchains->SV_DropClient()->registerHook(SV_DropClient_RH);
|
||||||
g_isDropClientHookAvailable = true;
|
g_isDropClientHookAvailable = true;
|
||||||
g_isDropClientHookEnabled = true;
|
g_isDropClientHookEnabled = true;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
HasReHLDS = false;
|
||||||
|
|
||||||
void *address = nullptr;
|
void *address = nullptr;
|
||||||
|
|
||||||
|
if (CommonConfig->GetAddress("sv", &address) && address)
|
||||||
|
{
|
||||||
|
Server = *reinterpret_cast<decltype(Server)*>(address);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AMXXLOG_Log("Automatic precaching of model textures and groups has been disabled - check your gamedata files.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (CommonConfig && CommonConfig->GetMemSig("SV_DropClient", &address) && address)
|
if (CommonConfig && CommonConfig->GetMemSig("SV_DropClient", &address) && address)
|
||||||
{
|
{
|
||||||
DropClientDetour = DETOUR_CREATE_STATIC_FIXED(SV_DropClient, address);
|
DropClientDetour = DETOUR_CREATE_STATIC_FIXED(SV_DropClient, address);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user