diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index ae8b3790..4f52bd1f 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -151,6 +151,25 @@ void CL_DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ) PM_Move( ppmove, server ); } +void SaveEngineVersion() +{ + cvar_t *sv_version = gEngfuncs.pfnGetCvarPointer("sv_version"); + if (sv_version) + { + strncpy(gHUD.m_szEngineVersion, sv_version->string, sizeof(gHUD.m_szEngineVersion) - 1); + + // Parse build number + std::string version = gHUD.m_szEngineVersion; + size_t lastComma = version.rfind(','); + + if (lastComma != std::string::npos) + { + const char *buildStr = gHUD.m_szEngineVersion + lastComma + 1; + gHUD.m_iEngineBuildNumber = atoi(buildStr); + } + } +} + int CL_DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ) { gEngfuncs = *pEnginefuncs; @@ -162,6 +181,8 @@ int CL_DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ) memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t)); + SaveEngineVersion(); + update_checker::check_for_updates(); discord_integration::initialize(); diff --git a/cl_dll/cl_util.h b/cl_dll/cl_util.h index f558de63..40b1611a 100644 --- a/cl_dll/cl_util.h +++ b/cl_dll/cl_util.h @@ -29,6 +29,16 @@ #include // " #include // for strncpy() +#ifdef _WIN32 +#define BUILD_OFFSET_LINUX 0 +#else +#define BUILD_OFFSET_LINUX 1 +#endif + +constexpr int ENGINE_BUILD_ANNIVERSARY_FIRST = 9884 + BUILD_OFFSET_LINUX; + +#undef BUILD_OFFSET_LINUX + // Macros to hook function calls into the HUD object #define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x ); diff --git a/cl_dll/entity.cpp b/cl_dll/entity.cpp index c5ceb91c..a44de492 100644 --- a/cl_dll/entity.cpp +++ b/cl_dll/entity.cpp @@ -21,11 +21,14 @@ #include "particleman.h" +#include "com_model.h" #include "r_studioint.h" #undef min #undef max +extern engine_studio_api_t IEngineStudio; + extern IParticleMan *g_pParticleMan; void Game_AddObjects( void ); @@ -59,8 +62,14 @@ int CL_DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *m // show triggers that would be transferred from server-side with specific value in renderfx to differ it from other entities // update: there is a new implementation of displaying triggers that allows you to display even when planes is stripped due to optimizations in updated map compiler - // so this code will only work if the value 2 is specified in the cvar, but it should not be deleted imo - if ((ent->curstate.rendermode == kRenderTransColor) && (ent->curstate.renderfx == kRenderFxTrigger) && (gHUD.m_pShowServerTriggers->value == 2.0f) && !gHUD.IsTriggerForSinglePlayer(ent->curstate.rendercolor)) + // update 2: we use that code if we know that client is uses software engine and number model surfaces data is available + // for hardware engine there is more advanced code that can for example changing alpha per side + if ((gHUD.m_pShowServerTriggers->value > 0) && + (!IEngineStudio.IsHardware()) && + (ent->model && ent->model->nummodelsurfaces) && + (ent->curstate.rendermode == kRenderTransColor) && + (ent->curstate.renderfx == kRenderFxTrigger) && + !gHUD.IsTriggerForSinglePlayer(ent->curstate.rendercolor)) ent->curstate.renderamt = std::min(255.0f, std::max(0.0f, gHUD.m_pShowServerTriggersAlpha->value)); // hide corpses option diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 1964a126..08578783 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -787,6 +787,9 @@ class CHud bool IsTriggerForSinglePlayer(color24 rendercolor); HSPRITE white_sprite = 0; + + char m_szEngineVersion[256]; + int m_iEngineBuildNumber = -1; }; extern CHud gHUD; diff --git a/cl_dll/tri.cpp b/cl_dll/tri.cpp index 1e180d10..6ba7eec4 100644 --- a/cl_dll/tri.cpp +++ b/cl_dll/tri.cpp @@ -42,6 +42,8 @@ extern IParticleMan *g_pParticleMan; #undef min #undef max +extern engine_studio_api_t IEngineStudio; + /* ================= HUD_DrawNormalTriangles @@ -105,9 +107,47 @@ void DrawAACuboid(triangleapi_s *pTriAPI, Vector corner1, Vector corner2) pTriAPI->End(); } +void DrawPolyOrCuboid(model_t *model, Vector corner1, Vector corner2) +{ + auto pTriAPI = gEngfuncs.pTriAPI; + + if (model && !model->nummodelsurfaces) + { + DrawAACuboid(pTriAPI, corner1, corner2); + return; + } + + #ifndef SOFTWARE_BUILD + if (IEngineStudio.IsHardware() && model && model->nummodelsurfaces) + { + #define DrawPolygons(surfs) \ + for (int i = 0; i < model->nummodelsurfaces; ++i) \ + { \ + pTriAPI->Begin(TRI_POLYGON); \ + for (int j = 0; j < surfs[i].polys->numverts; ++j) \ + { \ + pTriAPI->Vertex3fv(surfs[i].polys->verts[j]); \ + } \ + pTriAPI->End(); \ + } + + if (gHUD.m_iEngineBuildNumber >= ENGINE_BUILD_ANNIVERSARY_FIRST) + { + const msurface_hw_25th_anniversary_t *surfs = (msurface_hw_25th_anniversary_t*)model->surfaces + model->firstmodelsurface; + DrawPolygons(surfs); + } + else + { + const msurface_t *surfs = model->surfaces + model->firstmodelsurface; + DrawPolygons(surfs); + } + } + #endif +} + void DrawServerTriggers() { - if ((gHUD.m_pShowServerTriggers->value > 0) && (gHUD.m_pShowServerTriggers->value != 2.0f)) + if (gHUD.m_pShowServerTriggers->value > 0) { for (int e = 0; e < MAX_EDICTS; ++e) { @@ -134,7 +174,7 @@ void DrawServerTriggers() Vector absmin = origin + mins; Vector absmax = origin + maxs; - DrawAACuboid(gEngfuncs.pTriAPI, absmin, absmax); + DrawPolyOrCuboid(ent->model, absmin, absmax); } } } diff --git a/common/com_model.h b/common/com_model.h index 94aaa7ed..6918b915 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -278,9 +278,20 @@ struct msurface_s color24 *samples; // note: this is the actual lightmap data for this surface decal_t *pdecals; +}; +#endif - //mdisplaylist_t displaylist; // Half-Life 25th Anniversary Update +#ifdef __cplusplus +struct msurface_hw_25th_anniversary_t : public msurface_t +{ + mdisplaylist_t displaylist; }; +#else +typedef struct +{ + msurface_t surface; + mdisplaylist_t displaylist; +} msurface_hw_25th_anniversary_t; #endif typedef struct