diff --git a/r5dev/tier1/IConVar.cpp b/r5dev/tier1/IConVar.cpp index 5d2a866b..e299672d 100644 --- a/r5dev/tier1/IConVar.cpp +++ b/r5dev/tier1/IConVar.cpp @@ -98,6 +98,7 @@ void ConVar::Init(void) const sv_rcon_maxsockets = new ConVar("sv_rcon_maxsockets" , "32", FCVAR_RELEASE, "Max number of accepted sockets before the server starts closing redundant sockets.", false, 0.f, false, 0.f, nullptr, nullptr); sv_rcon_whitelist_address = new ConVar("sv_rcon_whitelist_address", "", FCVAR_RELEASE, "This address is not considered a 'redundant' socket and will never be banned for failed authentications.", false, 0.f, false, 0.f, nullptr, "Format: '::ffff:127.0.0.1'."); #endif // DEDICATED + bhit_abs_origin = new ConVar("bhit_abs_origin", "0", FCVAR_RELEASE, "Use player's absolute origin for bhit tracing.", false, 0.f, false, 0.f, nullptr, nullptr); //------------------------------------------------------------------------- // CLIENT | #ifndef DEDICATED @@ -204,6 +205,7 @@ void ConVar::InitShipped(void) const staticProp_gather_size_weight = g_pCVar->FindVar("staticProp_gather_size_weight"); stream_overlay = g_pCVar->FindVar("stream_overlay"); stream_overlay_mode = g_pCVar->FindVar("stream_overlay_mode"); + sv_visualizetraces = g_pCVar->FindVar("sv_visualizetraces"); old_gather_props = g_pCVar->FindVar("old_gather_props"); mp_gamemode = g_pCVar->FindVar("mp_gamemode"); hostname = g_pCVar->FindVar("hostname"); diff --git a/r5dev/tier1/cmd.cpp b/r5dev/tier1/cmd.cpp index 3eb19048..bc547544 100644 --- a/r5dev/tier1/cmd.cpp +++ b/r5dev/tier1/cmd.cpp @@ -302,6 +302,7 @@ void ConCommand::Init(void) { //------------------------------------------------------------------------- // ENGINE DLL | + new ConCommand("bhit", "Bullet-hit trajectory debug.", FCVAR_GAMEDLL | FCVAR_CHEAT, BHit_f, nullptr); #ifndef DEDICATED new ConCommand("line", "Draw a debug line.", FCVAR_GAMEDLL | FCVAR_CHEAT, Line_f, nullptr); new ConCommand("sphere", "Draw a debug sphere.", FCVAR_GAMEDLL | FCVAR_CHEAT, Sphere_f, nullptr); diff --git a/r5dev/tier1/cvar.cpp b/r5dev/tier1/cvar.cpp index 13e4cc6f..7c27bde6 100644 --- a/r5dev/tier1/cvar.cpp +++ b/r5dev/tier1/cvar.cpp @@ -66,6 +66,9 @@ ConVar* sv_pylonRefreshInterval = nullptr; ConVar* sv_banlistRefreshInterval = nullptr; ConVar* sv_statusRefreshInterval = nullptr; +ConVar* sv_visualizetraces = nullptr; +ConVar* bhit_abs_origin = nullptr; + #ifdef DEDICATED ConVar* sv_rcon_debug = nullptr; ConVar* sv_rcon_banpenalty = nullptr; // TODO diff --git a/r5dev/tier1/cvar.h b/r5dev/tier1/cvar.h index db41b847..584ad79e 100644 --- a/r5dev/tier1/cvar.h +++ b/r5dev/tier1/cvar.h @@ -64,6 +64,9 @@ extern ConVar* sv_pylonVisibility; extern ConVar* sv_pylonRefreshInterval; extern ConVar* sv_banlistRefreshInterval; extern ConVar* sv_statusRefreshInterval; + +extern ConVar* sv_visualizetraces; +extern ConVar* bhit_abs_origin; #ifdef DEDICATED extern ConVar* sv_rcon_debug; extern ConVar* sv_rcon_banpenalty; diff --git a/r5dev/vstdlib/callback.cpp b/r5dev/vstdlib/callback.cpp index c3cfbc96..5c428b52 100644 --- a/r5dev/vstdlib/callback.cpp +++ b/r5dev/vstdlib/callback.cpp @@ -17,6 +17,9 @@ #endif // !DEDICATED #include "engine/client/client.h" #include "engine/net.h" +#ifndef DEDICATED +#include "client/cdll_engine_int.h" +#endif // !DEDICATED #include "rtech/rtech_game.h" #include "rtech/rtech_utils.h" #include "filesystem/basefilesystem.h" @@ -30,13 +33,18 @@ #ifndef CLIENT_DLL #include "public/include/bansystem.h" #endif // !CLIENT_DLL +#include "public/include/worldsize.h" #include "mathlib/crc32.h" +#include "mathlib/mathlib.h" #include "vstdlib/completion.h" #include "vstdlib/callback.h" #ifndef DEDICATED #include "materialsystem/cmaterialglue.h" #include "public/include/idebugoverlay.h" #endif // !DEDICATED +#ifndef DEDICATED +#include "game/client/view.h" +#endif // !DEDICATED /* @@ -1007,3 +1015,56 @@ void Capsule_f(const CCommand& args) g_pDebugOverlay->AddCapsuleOverlay(start, end, radius, { 0,0,0 }, { 0,0,0 }, 141, 233, 135, 0, 100); } #endif // !DEDICATED + +/* +===================== +BHit_f + + Bullet trajectory tracing + from shooter to target entity. +===================== +*/ +void BHit_f(const CCommand& args) +{ + if (args.ArgC() != 9) + return; + +#ifndef DEDICATED + if (sv_visualizetraces->GetBool()) + { + Vector3D vecAbsStart; + Vector3D vecAbsEnd; + + for (int i = 0; i < 3; ++i) + vecAbsStart[i] = atof(args[i + 4]); + + if (bhit_abs_origin->GetBool()) + { + int iEnt = atof(args[2]); + if (IClientEntity* pEntity = g_pClientEntityList->GetClientEntity(atof(args[2]))) + vecAbsEnd = pEntity->GetAbsOrigin(); + else + goto VEC_RENDER; + } + else VEC_RENDER: + { + QAngle vecBulletAngles; + for (int i = 0; i < 2; ++i) + vecBulletAngles[i] = atof(args[i + 7]); + + vecBulletAngles.z = 180.f; // Flipped axis. + AngleVectors(vecBulletAngles, &vecAbsEnd); + } + + static char szBuf[2048]; + snprintf(szBuf, sizeof(szBuf), "drawline %g %g %g %g %g %g", + vecAbsStart.x, vecAbsStart.y, vecAbsStart.z, + vecAbsStart.x + vecAbsEnd.x * MAX_COORD_RANGE, + vecAbsStart.y + vecAbsEnd.y * MAX_COORD_RANGE, + vecAbsStart.z + vecAbsEnd.z * MAX_COORD_RANGE); + + Cbuf_AddText(Cbuf_GetCurrentPlayer(), szBuf, cmd_source_t::kCommandSrcCode); + Cbuf_Execute(); + } +#endif // !DEDICATED +} diff --git a/r5dev/vstdlib/callback.h b/r5dev/vstdlib/callback.h index 22bf910c..ace80bca 100644 --- a/r5dev/vstdlib/callback.h +++ b/r5dev/vstdlib/callback.h @@ -52,6 +52,7 @@ void Line_f(const CCommand& args); void Sphere_f(const CCommand& args); void Capsule_f(const CCommand& args); #endif // !DEDICATED +void BHit_f(const CCommand& args); /////////////////////////////////////////////////////////////////////////////// class VCallback : public IDetour {