From 86e33d0cb167b99c11f92cbef2312dde11292605 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Thu, 9 Jul 2015 13:36:53 +0200 Subject: [PATCH] Cstrike: cs_set_user_model - Add a param to choose whether modelindex should be updated --- modules/cstrike/cstrike/CstrikeHacks.cpp | 11 ++++-- modules/cstrike/cstrike/CstrikeHacks.h | 2 +- modules/cstrike/cstrike/CstrikeNatives.cpp | 41 ++++++++++++++++++++-- plugins/include/cstrike.inc | 17 +++++---- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/modules/cstrike/cstrike/CstrikeHacks.cpp b/modules/cstrike/cstrike/CstrikeHacks.cpp index 13e563ec..b654cf34 100644 --- a/modules/cstrike/cstrike/CstrikeHacks.cpp +++ b/modules/cstrike/cstrike/CstrikeHacks.cpp @@ -43,7 +43,7 @@ int TeamOffset; int MenuOffset; server_static_t *ServerStatic; -double *RealTime; +server_t *Server; void InitializeHacks() { @@ -531,8 +531,13 @@ void InitGlobalVars() ServerStatic = reinterpret_cast(address); } #endif - if (CommonConfig->GetAddress("realtime", &address)) + if (CommonConfig->GetAddress("sv", &address)) { - RealTime = reinterpret_cast(*reinterpret_cast(address)); + Server = *reinterpret_cast(address); + } + + if (!Server) + { + MF_Log("sv global variable is not available\n"); } } \ No newline at end of file diff --git a/modules/cstrike/cstrike/CstrikeHacks.h b/modules/cstrike/cstrike/CstrikeHacks.h index 29f79864..c7d91474 100644 --- a/modules/cstrike/cstrike/CstrikeHacks.h +++ b/modules/cstrike/cstrike/CstrikeHacks.h @@ -46,6 +46,6 @@ extern DLL_FUNCTIONS *g_pFunctionTable; extern bool NoKifesMode; extern server_static_t *ServerStatic; -extern double *RealTime; +extern server_t *Server; #endif // CSTRIKE_HACKS_H diff --git a/modules/cstrike/cstrike/CstrikeNatives.cpp b/modules/cstrike/cstrike/CstrikeNatives.cpp index e49b88c2..3feb12f3 100644 --- a/modules/cstrike/cstrike/CstrikeNatives.cpp +++ b/modules/cstrike/cstrike/CstrikeNatives.cpp @@ -856,7 +856,7 @@ static cell AMX_NATIVE_CALL cs_get_user_model(AMX *amx, cell *params) return MF_SetAmxString(amx, params[2], GETCLIENTKEYVALUE(GETINFOKEYBUFFER(pPlayer), "model"), params[3]); } -// native cs_set_user_model(index, const model[]); +// native cs_set_user_model(index, const model[], bool:update_index = false); static cell AMX_NATIVE_CALL cs_set_user_model(AMX *amx, cell *params) { int index = params[1]; @@ -874,8 +874,45 @@ static cell AMX_NATIVE_CALL cs_set_user_model(AMX *amx, cell *params) int length; const char *newModel = MF_GetAmxString(amx, params[2], 0, &length); + if (!*newModel) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Model can not be empty"); + return 0; + } + Players[index].SetModel(newModel); - Players[index].UpdateModel(MF_GetPlayerEdict(index)); + Players[index].UpdateModel(pPlayer); + + if (*params / sizeof(cell) >= 3 && params[3] != 0) + { + if (!Server) + { + MF_LogError(amx, AMX_ERR_NATIVE, "cs_set_user_model is disabled with update_index parameter set"); + return 0; + } + + GET_OFFSET("CBasePlayer", m_modelIndexPlayer); + + char model[260]; + UTIL_Format(model, sizeof(model), "models/player/%s/%s.mdl", newModel, newModel); + + for (size_t i = 0; i < HL_MODEL_MAX; ++i) + { + if (Server->model_precache[i] && !strcmp(Server->model_precache[i], model)) + { + if (pPlayer->v.modelindex != i) + { + SET_MODEL(pPlayer, model); + } + + set_pdata(pPlayer, m_modelIndexPlayer, i); + return 1; + } + } + + MF_LogError(amx, AMX_ERR_NATIVE, "Model must be precached"); + return 0; + } return 1; } diff --git a/plugins/include/cstrike.inc b/plugins/include/cstrike.inc index 92525345..d35dc478 100755 --- a/plugins/include/cstrike.inc +++ b/plugins/include/cstrike.inc @@ -342,16 +342,21 @@ native cs_get_user_model(index, model[], len); * @note This is not a one-time set. The CStrike module will remember the * selected model and try to prevent attempts at changing the player * model, or immediately re-apply it if necessary. + * @note Updating modelindex is useful for custom models which don't have + * the same structure as the default ones (hitbox, etc..). Model must + * be precached before. * - * @param index Client index - * @param model Model name + * @param index Client index + * @param model Model name + * @param update_index If true, the modelindex is updated as well * * @noreturn - * @error If the client index is not within the range of 1 to - * MaxClients, or the client is not connected, an error will be - * thrown. + * @error If the client index is not within the range of 1 to + * MaxClients, the client is not connected, the provided + * model is empty, or if modeindex is updated and the + * provided model is not precached, an error will be thrown. */ -native cs_set_user_model(index, const model[]); +native cs_set_user_model(index, const model[], bool:update_index = false); /** * Resets the client's model.