Skip to content

Commit

Permalink
Fix solid entity list and massive performance improvements for visibl…
Browse files Browse the repository at this point in the history
…e check
  • Loading branch information
Ch40zz committed Sep 26, 2024
1 parent 3e79c43 commit 25b2e47
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 94 deletions.
2 changes: 1 addition & 1 deletion CCHookReloaded/ETSDK/src/game/bg_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 8 additions & 6 deletions CCHookReloaded/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -852,6 +852,8 @@ intptr_t hooked_CL_CgameSystemCalls(intptr_t *args)
VectorCopy(ent.pos.trDelta, ci.velocity);
}
}

eng::CG_BuildSolidList();
}

return success;
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down
182 changes: 98 additions & 84 deletions CCHookReloaded/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -68,136 +75,143 @@ 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<size_t>(cg_snapshot.numEntities, MAX_ENTITIES_IN_SNAPSHOT);
for (size_t i = 0 ; i < numEntities; i++)
const size_t numEntities = std::min<size_t>(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
{
int x = (ent->solid & 255);
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;


Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions CCHookReloaded/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion CCHookReloaded/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 25b2e47

Please sign in to comment.