diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index 22987ca..ae8b379 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -191,6 +191,8 @@ int CL_DLLEXPORT HUD_VidInit( void ) VGui_Startup(); + gHUD.white_sprite = gEngfuncs.pfnSPR_Load("sprites/white.spr"); + return 1; } diff --git a/cl_dll/entity.cpp b/cl_dll/entity.cpp index d6142d2..c5ceb91 100644 --- a/cl_dll/entity.cpp +++ b/cl_dll/entity.cpp @@ -1,5 +1,6 @@ // Client side entity management functions +#include #include #include "hud.h" @@ -19,6 +20,12 @@ #include "discord_integration.h" #include "particleman.h" + +#include "r_studioint.h" + +#undef min +#undef max + extern IParticleMan *g_pParticleMan; void Game_AddObjects( void ); @@ -50,6 +57,12 @@ int CL_DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *m break; } + // 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)) + ent->curstate.renderamt = std::min(255.0f, std::max(0.0f, gHUD.m_pShowServerTriggersAlpha->value)); + // hide corpses option if (gHUD.m_pCvarHideCorpses->value > 0 && ent->curstate.renderfx == kRenderFxDeadPlayer) return 0; diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 71f8958..8d06d50 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -531,6 +531,8 @@ void CHud :: Init( void ) m_pCvarHideOtherPlayers = CVAR_CREATE("cl_hide_other_players", "0", 0); m_pCvarColor = CVAR_CREATE( "hud_color", "", FCVAR_ARCHIVE ); m_pCvarPlayTeamSoundsVolume = CVAR_CREATE("cl_team_sounds_volume", "1.0", FCVAR_ARCHIVE); + m_pShowServerTriggers = CVAR_CREATE("cl_show_server_triggers", "0", FCVAR_ARCHIVE); + m_pShowServerTriggersAlpha = CVAR_CREATE("cl_show_server_triggers_alpha", "120", FCVAR_ARCHIVE); cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); CVAR_CREATE("showtriggers", "0", 0); @@ -937,3 +939,22 @@ float CHud::GetSensitivity( void ) return m_flMouseSensitivity; } +bool CHud::IsTriggerForSinglePlayer(color24 rendercolor) +{ + auto r = rendercolor.r; + auto g = rendercolor.g; + auto b = rendercolor.b; + + if ((r == 128) && (g == 128) && (b == 128)) // trigger_autosave + return true; + else if ((r == 79) && (g == 255) && (b == 10)) // trigger_changelevel + return true; + else if ((r == 150) && (g == 75) && (b == 0)) // trigger_endsection + return true; + else if ((r == 238) && (g == 154) && (b == 77)) // trigger_monsterjump + return true; + else if ((r == 203) && (g == 103) && (b == 212)) // trigger_transition + return true; + + return false; +} diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 7fe7ecb..1964a12 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -644,6 +644,9 @@ class CHud cvar_t *hud_classautokill; cvar_t *hud_centerid; + cvar_t *m_pShowServerTriggers; + cvar_t *m_pShowServerTriggersAlpha; + int m_iFontHeight; cvar_t* m_pCvarColor; @@ -781,6 +784,9 @@ class CHud float GetSensitivity(); + bool IsTriggerForSinglePlayer(color24 rendercolor); + + HSPRITE white_sprite = 0; }; extern CHud gHUD; diff --git a/cl_dll/hudgl.cpp b/cl_dll/hudgl.cpp index 93dd8ff..f971800 100644 --- a/cl_dll/hudgl.cpp +++ b/cl_dll/hudgl.cpp @@ -6,7 +6,9 @@ #include #ifdef _WIN32 +#include #include +#include #endif #ifdef __APPLE__ diff --git a/cl_dll/tri.cpp b/cl_dll/tri.cpp index 5332eb8..1e180d1 100644 --- a/cl_dll/tri.cpp +++ b/cl_dll/tri.cpp @@ -7,6 +7,20 @@ // Triangle rendering, if any +#include + +#ifdef _WIN32 +#include +#include +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + #include "hud.h" #include "cl_util.h" @@ -22,6 +36,12 @@ #include "tri.h" extern IParticleMan *g_pParticleMan; +#include "com_model.h" +#include "r_studioint.h" + +#undef min +#undef max + /* ================= HUD_DrawNormalTriangles @@ -40,6 +60,89 @@ void CL_DLLEXPORT HUD_DrawNormalTriangles( void ) void RunEventList( void ); #endif +void DivideRGBABy255(float &r, float &g, float &b, float &a) +{ + r /= 255.0f; + g /= 255.0f; + b /= 255.0f; + a /= 255.0f; +} + +void DrawAACuboid(triangleapi_s *pTriAPI, Vector corner1, Vector corner2) +{ + pTriAPI->Begin(TRI_QUADS); + + pTriAPI->Vertex3f(corner1.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner2.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner1.z); + + pTriAPI->Vertex3f(corner1.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner1.x, corner1.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner1.z); + + pTriAPI->Vertex3f(corner1.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner1.y, corner2.z); + + pTriAPI->Vertex3f(corner2.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner1.y, corner2.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner2.z); + + pTriAPI->Vertex3f(corner2.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner2.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner2.y, corner1.z); + + pTriAPI->Vertex3f(corner2.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner2.x, corner2.y, corner1.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner1.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner2.z); + + pTriAPI->End(); +} + +void DrawServerTriggers() +{ + if ((gHUD.m_pShowServerTriggers->value > 0) && (gHUD.m_pShowServerTriggers->value != 2.0f)) + { + for (int e = 0; e < MAX_EDICTS; ++e) + { + cl_entity_t* ent = gEngfuncs.GetEntityByIndex(e); + if (ent) + { + if (ent->model) + { + if ((ent->curstate.rendermode == kRenderTransColor) && (ent->curstate.renderfx == kRenderFxTrigger)) + { + color24 colors = ent->curstate.rendercolor; + if (!gHUD.IsTriggerForSinglePlayer(colors)) + { + gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); + gEngfuncs.pTriAPI->CullFace(TRI_NONE); + + float r = colors.r, g = colors.g, b = colors.b, a = std::min(255.0f, std::max(0.0f, gHUD.m_pShowServerTriggersAlpha->value)); + DivideRGBABy255(r, g, b, a); + gEngfuncs.pTriAPI->Color4f(r, g, b, a); + + Vector mins = ent->curstate.mins; + Vector maxs = ent->curstate.maxs; + Vector origin = ent->curstate.origin; + Vector absmin = origin + mins; + Vector absmax = origin + maxs; + + DrawAACuboid(gEngfuncs.pTriAPI, absmin, absmax); + } + } + } + } + } + } +} + /* ================= HUD_DrawTransparentTriangles @@ -57,4 +160,14 @@ void CL_DLLEXPORT HUD_DrawTransparentTriangles( void ) if ( g_pParticleMan ) g_pParticleMan->Update(); + + if (!gHUD.white_sprite) + return; + + if (!gEngfuncs.pTriAPI->SpriteTexture(const_cast(gEngfuncs.GetSpritePointer(gHUD.white_sprite)), 0)) + return; + + DrawServerTriggers(); + + gEngfuncs.pTriAPI->RenderMode(kRenderNormal); } diff --git a/common/com_model.h b/common/com_model.h index 39e8f1d..94aaa7e 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -16,7 +16,7 @@ #define STUDIO_EVENTS 2 #define MAX_CLIENTS 32 -#define MAX_EDICTS 900 +#define MAX_EDICTS 2048 #define MAX_MODEL_NAME 64 #define MAX_MAP_HULLS 4 diff --git a/common/const.h b/common/const.h index 6c5f35b..9eee1bd 100644 --- a/common/const.h +++ b/common/const.h @@ -713,6 +713,7 @@ enum kRenderFxGlowShell, // Glowing Shell kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!) kRenderFxLightMultiplier, //CTM !!!CZERO added to tell the studiorender that the value in iuser2 is a lightmultiplier + kRenderFxTrigger = 241, };