From 25b2e4793723995a242e15dae2f50a9a5b94c4b3 Mon Sep 17 00:00:00 2001 From: Ch40zz <3965591+Ch40zz@users.noreply.github.com> Date: Fri, 27 Sep 2024 00:37:46 +0200 Subject: [PATCH] Fix solid entity list and massive performance improvements for visible check --- CCHookReloaded/ETSDK/src/game/bg_public.h | 2 +- CCHookReloaded/dllmain.cpp | 14 +- CCHookReloaded/engine.cpp | 182 ++++++++++++---------- CCHookReloaded/engine.h | 6 +- CCHookReloaded/ui.cpp | 2 +- 5 files changed, 112 insertions(+), 94 deletions(-) diff --git a/CCHookReloaded/ETSDK/src/game/bg_public.h b/CCHookReloaded/ETSDK/src/game/bg_public.h index a6bbc28..1a92414 100644 --- a/CCHookReloaded/ETSDK/src/game/bg_public.h +++ b/CCHookReloaded/ETSDK/src/game/bg_public.h @@ -648,7 +648,7 @@ typedef enum { #define EF_TAGCONNECT 0x00008000 // connected to another entity via tag #define EF_MOUNTEDTANK EF_TAGCONNECT // Gordon: duplicated for clarity -#define EF_SPARE3 0x00010000 // Gordon: freed +#define EF_FAKEBMODEL 0x00010000 // from etpro #define EF_PATH_LINK 0x00020000 // Gordon: linking trains together #define EF_ZOOMING 0x00040000 // client is zooming #define EF_PRONE 0x00080000 // player is prone diff --git a/CCHookReloaded/dllmain.cpp b/CCHookReloaded/dllmain.cpp index 4ee448e..c4239e2 100644 --- a/CCHookReloaded/dllmain.cpp +++ b/CCHookReloaded/dllmain.cpp @@ -530,7 +530,7 @@ intptr_t hooked_CL_CgameSystemCalls(intptr_t *args) if (ent.hModel != media.pickupModels[i]) continue; - const bool isVisible = eng::IsPointVisible(cg_refdef.vieworg, ent.origin); + const bool isVisible = eng::IsPointVisible(cg_refdef.vieworg, ent.origin, cg_snapshot.ps.clientNum); ent.renderfx |= isVisible ? RF_DEPTHHACK : 0; DoSyscall(CG_R_ADDREFENTITYTOSCENE, &ent); @@ -548,7 +548,7 @@ intptr_t hooked_CL_CgameSystemCalls(intptr_t *args) { if (cg_missiles[ent.entityNum]) { - const bool isVisible = eng::IsPointVisible(cg_refdef.vieworg, ent.origin); + const bool isVisible = eng::IsPointVisible(cg_refdef.vieworg, ent.origin, cg_snapshot.ps.clientNum); ent.renderfx |= isVisible ? RF_DEPTHHACK : 0; DoSyscall(CG_R_ADDREFENTITYTOSCENE, &ent); @@ -852,6 +852,8 @@ intptr_t hooked_CL_CgameSystemCalls(intptr_t *args) VectorCopy(ent.pos.trDelta, ci.velocity); } } + + eng::CG_BuildSolidList(); } return success; @@ -1413,7 +1415,7 @@ intptr_t __cdecl hooked_vmMain(intptr_t id, intptr_t a1, intptr_t a2, intptr_t a VectorAdd(maxs, offset, maxs); // SnapVector(ent->s.pos.trBase + ent->client->ps.viewheight) - if (eng::IsBoxVisible(cg_refdef.vieworg, mins, maxs, cfg.aimbotHeadBoxTraceStep, aimPos)) + if (eng::IsBoxVisible(cg_refdef.vieworg, mins, maxs, cfg.aimbotHeadBoxTraceStep, aimPos, ci.id)) return true; } else @@ -1428,7 +1430,7 @@ intptr_t __cdecl hooked_vmMain(intptr_t id, intptr_t a1, intptr_t a2, intptr_t a VectorAdd(mins, origin, mins); VectorAdd(maxs, origin, maxs); - if (eng::IsBoxVisible(cg_refdef.vieworg, mins, maxs, cfg.aimbotBodyBoxTraceStep, aimPos)) + if (eng::IsBoxVisible(cg_refdef.vieworg, mins, maxs, cfg.aimbotBodyBoxTraceStep, aimPos, ci.id)) return true; } } @@ -1443,7 +1445,7 @@ intptr_t __cdecl hooked_vmMain(intptr_t id, intptr_t a1, intptr_t a2, intptr_t a PredictAimPos(ci, aimPos); - if (eng::IsPointVisible(cg_refdef.vieworg, aimPos)) + if (eng::IsPointVisible(cg_refdef.vieworg, aimPos, ci.id)) return true; } @@ -1700,7 +1702,7 @@ intptr_t __cdecl hooked_vmMain(intptr_t id, intptr_t a1, intptr_t a2, intptr_t a if (totalTime > MISSILE_PRESTEP_TIME) { - const vec4_t& color = eng::IsPointVisible(cg_refdef.vieworg, predictedPos) ? colorYellow : colorRed; + const vec4_t& color = eng::IsPointVisible(cg_refdef.vieworg, predictedPos, cg_snapshot.ps.clientNum) ? colorYellow : colorRed; //ui::DrawLine3D(lastPredictedPos, predictedPos, 2.0f, color); draw3dCommands.emplace_back(lastPredictedPos, predictedPos, color, RF_DEPTHHACK); diff --git a/CCHookReloaded/engine.cpp b/CCHookReloaded/engine.cpp index f256f20..7d6ad10 100644 --- a/CCHookReloaded/engine.cpp +++ b/CCHookReloaded/engine.cpp @@ -8,6 +8,13 @@ namespace eng { + static int cg_numSolidEntities = 0; + static int cg_numSolidFTEntities = 0; + static int cg_numTriggerEntities = 0; + static const entityState_t* cg_solidEntities[MAX_ENTITIES_IN_SNAPSHOT]; + static const entityState_t* cg_solidFTEntities[MAX_ENTITIES_IN_SNAPSHOT]; + static const entityState_t* cg_triggerEntities[MAX_ENTITIES_IN_SNAPSHOT]; + void CG_ParseReinforcementTimes(const char *pszReinfSeedString) { const char *tmp = pszReinfSeedString, *tmp2; @@ -68,77 +75,81 @@ namespace eng DoSyscall(CG_R_ADDREFENTITYTOSCENE, &ent); } - void CG_Trace(trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask) + void CG_BuildSolidList() { - int cg_numSolidEntities = 0, - cg_numSolidFTEntities = 0, - cg_numTriggerEntities = 0; - - const entityState_t *cg_solidEntities[MAX_ENTITIES_IN_SNAPSHOT], - *cg_solidFTEntities[MAX_ENTITIES_IN_SNAPSHOT], - *cg_triggerEntities[MAX_ENTITIES_IN_SNAPSHOT]; + cg_numSolidEntities = 0; + cg_numSolidFTEntities = 0; + cg_numTriggerEntities = 0; - auto CG_BuildSolidList = [&]() -> void { - const size_t numEntities = std::min(cg_snapshot.numEntities, MAX_ENTITIES_IN_SNAPSHOT); - for (size_t i = 0 ; i < numEntities; i++) + const size_t numEntities = std::min(cg_snapshot.numEntities, MAX_ENTITIES_IN_SNAPSHOT); + for (size_t i = 0; i < numEntities; i++) + { + const entityState_t* ent = &cg_snapshot.entities[i]; + + if (ent->solid == SOLID_BMODEL && (ent->eFlags & EF_NONSOLID_BMODEL)) + continue; + + if (ent->eType == ET_ITEM || + ent->eType == ET_PUSH_TRIGGER || + ent->eType == ET_TELEPORT_TRIGGER || + ent->eType == ET_CONCUSSIVE_TRIGGER || + ent->eType == ET_OID_TRIGGER +#ifdef VISIBLE_TRIGGERS + || ent->eType == ET_TRIGGER_MULTIPLE + || ent->eType == ET_TRIGGER_FLAGONLY + || ent->eType == ET_TRIGGER_FLAGONLY_MULTIPLE +#endif + ) { - const entityState_t *ent = &cg_snapshot.entities[i]; - - if(ent->solid == SOLID_BMODEL && (ent->eFlags & EF_NONSOLID_BMODEL)) - continue; - - if (ent->eType == ET_ITEM || - ent->eType == ET_PUSH_TRIGGER || - ent->eType == ET_TELEPORT_TRIGGER || - ent->eType == ET_CONCUSSIVE_TRIGGER || - ent->eType == ET_OID_TRIGGER - #ifdef VISIBLE_TRIGGERS - || ent->eType == ET_TRIGGER_MULTIPLE - || ent->eType == ET_TRIGGER_FLAGONLY - || ent->eType == ET_TRIGGER_FLAGONLY_MULTIPLE - #endif - ) - { - cg_triggerEntities[cg_numTriggerEntities] = ent; - cg_numTriggerEntities++; - continue; - } + cg_triggerEntities[cg_numTriggerEntities] = ent; + cg_numTriggerEntities++; + continue; + } - if(ent->eType == ET_CONSTRUCTIBLE) - { - cg_triggerEntities[cg_numTriggerEntities] = ent; - cg_numTriggerEntities++; - } + if (ent->eType == ET_CONSTRUCTIBLE) + { + cg_triggerEntities[cg_numTriggerEntities] = ent; + cg_numTriggerEntities++; + } - if (ent->solid) - { - cg_solidEntities[cg_numSolidEntities] = ent; - cg_numSolidEntities++; + if (ent->solid) + { + cg_solidEntities[cg_numSolidEntities] = ent; + cg_numSolidEntities++; - cg_solidFTEntities[cg_numSolidFTEntities] = ent; - cg_numSolidFTEntities++; - } + cg_solidFTEntities[cg_numSolidFTEntities] = ent; + cg_numSolidFTEntities++; } - }; - auto CG_ClipMoveToEntities = [&](const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask, int capsule, trace_t *tr) -> void { - trace_t trace; + } + } + void CG_ClipMoveToEntities(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask, int capsule, trace_t* tr) + { + for (int i = 0; i < cg_numSolidEntities; i++) + { + const entityState_t* ent = cg_solidEntities[i]; + + if (ent->number == skipNumber) + continue; + + clipHandle_t cmodel; vec3_t origin, angles; - for (int i = 0; i < cg_numSolidEntities; i++) + if (ent->solid == SOLID_BMODEL) { - const entityState_t *ent = cg_solidEntities[i]; - - if (ent->number == skipNumber) - continue; + cmodel = DoSyscall(CG_CM_INLINEMODEL, ent->modelindex); - clipHandle_t cmodel; - if (ent->solid == SOLID_BMODEL) + BG_EvaluateTrajectory(&ent->apos, cg_time, angles, qtrue, ent->effect2Time); + BG_EvaluateTrajectory(&ent->pos, cg_time, origin, qfalse, ent->effect2Time); + } + else + { + vec3_t bmins, bmaxs; + if (ent->eFlags & EF_FAKEBMODEL) { - cmodel = DoSyscall(CG_CM_INLINEMODEL, ent->modelindex); - - VectorCopy(ent->angles, angles); - VectorCopy(ent->origin, origin); + // repurposed origin2 and angles2 to receive mins and maxs of func_fakebrush + VectorCopy(ent->origin2, bmins); + VectorCopy(ent->angles2, bmaxs); } else { @@ -146,58 +157,61 @@ namespace eng int zd = ((ent->solid >> 8) & 255); int zu = ((ent->solid >> 16) & 255) - 32; - vec3_t bmins, bmaxs; bmins[0] = bmins[1] = -x; bmaxs[0] = bmaxs[1] = x; bmins[2] = -zd; bmaxs[2] = zu; - cmodel = DoSyscall(CG_CM_TEMPBOXMODEL, bmins, bmaxs); - - VectorCopy(vec3_origin, angles); - VectorCopy(ent->origin, origin); } - DoSyscall(CG_CM_TRANSFORMEDBOXTRACE, &trace, start, end, mins, maxs, cmodel, mask, origin, angles); - - if (trace.allsolid || trace.fraction < tr->fraction) - { - trace.entityNum = ent->number; - *tr = trace; - } - else if (trace.startsolid) - { - tr->startsolid = qtrue; - } + cmodel = DoSyscall(CG_CM_TEMPBOXMODEL, bmins, bmaxs); - if (tr->allsolid) - return; + VectorCopy(vec3_origin, angles); + VectorCopy(ent->pos.trBase, origin); } - }; + trace_t trace; + if (capsule) + DoSyscall(CG_CM_TRANSFORMEDCAPSULETRACE, &trace, start, end, mins, maxs, cmodel, mask, origin, angles); + else + DoSyscall(CG_CM_TRANSFORMEDBOXTRACE, &trace, start, end, mins, maxs, cmodel, mask, origin, angles); - CG_BuildSolidList(); + if (trace.allsolid || trace.fraction < tr->fraction) + { + trace.entityNum = ent->number; + *tr = trace; + } + else if (trace.startsolid) + { + tr->startsolid = qtrue; + } + if (tr->allsolid) + return; + } + } + void CG_Trace(trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask) + { DoSyscall(CG_CM_BOXTRACE, result, start, end, mins, maxs, 0, mask); result->entityNum = result->fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE; CG_ClipMoveToEntities(start, mins, maxs, end, skipNumber, mask, qfalse, result); } - bool IsPointVisible(const vec3_t start, const vec3_t pt) + bool IsPointVisible(const vec3_t start, const vec3_t pt, int skipNumber) { trace_t t; - eng::CG_Trace(&t, start, NULL, NULL, pt, cg_snapshot.ps.clientNum, MASK_SHOT); + eng::CG_Trace(&t, start, NULL, NULL, pt, skipNumber, MASK_SHOT); return (t.fraction == 1.f); } - bool IsBoxVisible(const vec3_t start, const vec3_t mins, const vec3_t maxs, float step, vec3_t visOut) + bool IsBoxVisible(const vec3_t start, const vec3_t mins, const vec3_t maxs, float step, vec3_t visOut, int skipNumber) { // Trivial case: Middle is visible VectorAdd(mins, maxs, visOut); VectorScale(visOut, 0.5f, visOut); - if (IsPointVisible(start, visOut)) + if (IsPointVisible(start, visOut, skipNumber)) return true; @@ -239,7 +253,7 @@ namespace eng VectorAdd(boxCorner[i], boxCorner[i + 1], mid); VectorScale(mid, 0.5f, mid); - if (IsPointVisible(start, mid)) + if (IsPointVisible(start, mid, skipNumber)) { VectorCopy(mid, visOut); return true; @@ -249,7 +263,7 @@ namespace eng // Try all corners last for (size_t i = 0; i < std::size(boxCorner); i++) { - if (IsPointVisible(start, boxCorner[i])) + if (IsPointVisible(start, boxCorner[i], skipNumber)) { VectorCopy(boxCorner[i], visOut); return true; diff --git a/CCHookReloaded/engine.h b/CCHookReloaded/engine.h index b247aa1..3228ff7 100644 --- a/CCHookReloaded/engine.h +++ b/CCHookReloaded/engine.h @@ -5,9 +5,11 @@ namespace eng void CG_ParseReinforcementTimes(const char *pszReinfSeedString); int CG_CalculateReinfTime(team_t team); void CG_RailTrail(const vec3_t from, const vec3_t to, const vec4_t col, int renderfx=0); + void CG_BuildSolidList(); + void CG_ClipMoveToEntities(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask, int capsule, trace_t* tr); void CG_Trace(trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask); - bool IsPointVisible(const vec3_t start, const vec3_t pt); - bool IsBoxVisible(const vec3_t start, const vec3_t mins, const vec3_t maxs, float step, vec3_t visOut); + bool IsPointVisible(const vec3_t start, const vec3_t pt, int skipNumber); + bool IsBoxVisible(const vec3_t start, const vec3_t mins, const vec3_t maxs, float step, vec3_t visOut, int skipNumber); bool AimAtTarget(const vec3_t target); bool IsKeyActionActive(const char *action); hitbox_t GetHeadHitbox(const SClientInfo &ci); diff --git a/CCHookReloaded/ui.cpp b/CCHookReloaded/ui.cpp index 4593f45..b597bdc 100644 --- a/CCHookReloaded/ui.cpp +++ b/CCHookReloaded/ui.cpp @@ -405,7 +405,7 @@ namespace ui DrawCheckbox(menuX + 10, menuY + 35, XorString("Spectator Warning"), &cfg.spectatorWarning); DrawCheckbox(menuX + 10, menuY + 45, XorString("Enemy Spawntimer"), &cfg.enemySpawnTimer); DrawCheckbox(menuX + 10, menuY + 55, XorString("Custom Damage Sounds"), &cfg.customDmgSounds); - DrawCheckbox(menuX + 10, menuY + 65, XorString("Quick Unban-Reconnect"), &cfg.quickUnbanReconnect); + DrawCheckbox(menuX + 10, menuY + 65, XorString("Quick Unban-Reconnect (F10)"), &cfg.quickUnbanReconnect); DrawCheckbox(menuX + 10, menuY + 75, XorString("Clean Screenshots"), &cfg.cleanScreenshots); break; }