Skip to content

Commit ce6ed17

Browse files
authored
Rock Trace: Address auto-aiming rock (#549)
Fix: - Fixed the proximity check logics to avoid issues regarding client index order. Change: - Control is added for a case where rock can auto-aim a survivor behind when released.
1 parent 9190f58 commit ce6ed17

2 files changed

Lines changed: 66 additions & 51 deletions

File tree

125 Bytes
Binary file not shown.

addons/sourcemod/scripting/l4d2_rock_trace_unblock.sp

Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <dhooks>
88
#include <sourcescramble>
99

10-
#define PLUGIN_VERSION "1.8"
10+
#define PLUGIN_VERSION "1.9"
1111

1212
public Plugin myinfo =
1313
{
@@ -75,9 +75,9 @@ public void OnPluginStart()
7575
"l4d2_rock_trace_unblock_flag",
7676
"5",
7777
"Prevent SI from blocking the rock radius check.\n"\
78-
... "1 = Unblock from all standing SI, 2 = Unblock from pounced, 4 = Unblock from jockeyed, 8 = Unblock from pummelled, 15 = All, 0 = Disable.",
78+
... "1 = Unblock from all standing SI, 2 = Unblock from pounced, 4 = Unblock from jockeyed, 8 = Unblock from pummelled, 16 = Unblock from thrower (Tank), 31 = All, 0 = Disable.",
7979
FCVAR_NOTIFY|FCVAR_SPONLY,
80-
true, 0.0, true, 15.0);
80+
true, 0.0, true, 31.0);
8181

8282
g_cvJockeyFix = CreateConVar(
8383
"l4d2_rock_jockey_dismount",
@@ -148,22 +148,17 @@ public void L4D_TankRock_OnRelease_Post(int tank, int rock, const float vecPos[3
148148

149149
Action SDK_OnThink(int entity)
150150
{
151-
static float vOrigin[3], vLastOrigin[3], vPos[3];
152-
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", vOrigin);
151+
static float vOrigin[3], vLastOrigin[3], vPos[3], vClosestPos[3];
152+
GetEntPropVector(entity, Prop_Data, "m_vecAbsOrigin", vOrigin);
153153

154154
static int m_vLastPosition = -1;
155155
if (m_vLastPosition == -1)
156156
m_vLastPosition = FindSendPropInfo("CBaseCSGrenadeProjectile", "m_vInitialVelocity") + 24;
157157

158158
GetEntDataVector(entity, m_vLastPosition, vLastOrigin);
159159

160-
static Handle tr;
161-
static DataPack dp;
162-
163-
// Serves as a List for ignored entities in traces
164-
dp = new DataPack();
165-
dp.WriteCell(entity); // always self-ignored
166-
DataPackPos pos = dp.Position;
160+
float flMinDistSqr = g_fRockRadiusSquared;
161+
int iClosestSurvivor = -1;
167162

168163
for (int i = 1; i <= MaxClients; ++i)
169164
{
@@ -175,36 +170,46 @@ Action SDK_OnThink(int entity)
175170

176171
GetAbsOrigin(i, vPos, true);
177172
ComputeClosestPoint(vLastOrigin, vOrigin, vPos, vOrigin);
178-
if (GetVectorDistance(vOrigin, vPos, true) < g_fRockRadiusSquared)
173+
174+
float flDistSqr = GetVectorDistance(vOrigin, vPos, true);
175+
if (flDistSqr < flMinDistSqr)
176+
{
177+
flMinDistSqr = flDistSqr;
178+
iClosestSurvivor = i;
179+
vClosestPos[0] = vOrigin[0];
180+
vClosestPos[1] = vOrigin[1];
181+
vClosestPos[2] = vOrigin[2];
182+
}
183+
}
184+
185+
if (iClosestSurvivor != -1)
186+
{
187+
// Serves as a List for ignored entities in traces
188+
DataPack dp = new DataPack();
189+
dp.WriteCell(entity); // always self-ignored
190+
dp.WriteCell(iClosestSurvivor);
191+
dp.WriteCell(GetEntPropEnt(entity, Prop_Send, "m_hThrower"));
192+
193+
// See if there's any obstracle in the way
194+
GetAbsOrigin(iClosestSurvivor, vPos, true);
195+
Handle tr = TR_TraceRayFilterEx(vClosestPos, vPos, MASK_SOLID, RayType_EndPoint, ProximityThink_TraceFilter, dp);
196+
197+
if (!TR_DidHit(tr) && TR_GetFraction(tr) >= 1.0)
179198
{
180-
dp.Position = pos;
181-
dp.WriteCell(i);
199+
// Maybe "TeleportEntity" does the same, let it be.
200+
SetAbsOrigin(entity, vOrigin);
182201

183-
// See if there's any obstracle in the way
184-
tr = TR_TraceRayFilterEx(vOrigin, vPos, MASK_SOLID, RayType_EndPoint, ProximityThink_TraceFilterList, dp);
202+
// Hurt attackers first, based on flag setting
203+
HurtCappers(entity, iClosestSurvivor);
185204

186-
if (!TR_DidHit(tr) && TR_GetFraction(tr) >= 1.0)
187-
{
188-
// Maybe "TeleportEntity" does the same, let it be.
189-
SetAbsOrigin(entity, vOrigin);
190-
191-
// Hurt attackers first, based on flag setting
192-
HurtCappers(entity, i);
193-
194-
// Confirm landing
195-
BounceTouch(entity, i);
196-
197-
// Radius check succeeded in landing someone, exit the loop.
198-
delete tr;
199-
break;
200-
}
201-
202-
delete tr;
205+
// Confirm landing
206+
BounceTouch(entity, iClosestSurvivor);
203207
}
208+
209+
delete tr;
210+
delete dp;
204211
}
205212

206-
delete dp;
207-
208213
return Plugin_Continue;
209214
}
210215

@@ -222,8 +227,8 @@ Action SDK_OnThink(int entity)
222227
bool ComputeClosestPoint(const float vLeft[3], const float vRight[3], const float vPos[3], float result[3])
223228
{
224229
static float vLTarget[3], vLine[3];
225-
MakeVectorFromPoints(vLeft, vPos, vLTarget);
226-
MakeVectorFromPoints(vLeft, vRight, vLine);
230+
SubtractVectors(vPos, vLeft, vLTarget);
231+
SubtractVectors(vRight, vLeft, vLine);
227232

228233
static float fLength, fDot;
229234
fLength = NormalizeVector(vLine, vLine);
@@ -261,28 +266,38 @@ bool ComputeClosestPoint(const float vLeft[3], const float vRight[3], const floa
261266
}
262267
}
263268

264-
bool ProximityThink_TraceFilterList(int entity, int contentsMask, DataPack dp)
269+
bool ProximityThink_TraceFilter(int entity, int contentsMask, DataPack dp)
265270
{
266271
dp.Reset();
272+
273+
/**
274+
* dp[0] = rock
275+
* dp[1] = survivor
276+
* dp[2] = tank
277+
*/
278+
267279
if (entity == dp.ReadCell() || entity == dp.ReadCell())
268280
return false;
269281

282+
if (entity == dp.ReadCell())
283+
return !(g_iFlags & 16);
284+
270285
if (entity > 0 && entity <= MaxClients && IsClientInGame(entity))
271286
{
272-
/**
273-
* NOTE:
274-
*
275-
* This should not be possible as radius check runs every think
276-
* and survivors in between must be prior to be targeted.
277-
*
278-
* As far as I know, the only exception is that multiple survivors
279-
* are coinciding (like at a corner), and obstracle tracing ends up
280-
* with "true", kinda false positive.
281-
*
282-
* Treated as a bug here, no options.
283-
*/
284287
if (GetClientTeam(entity) == 2)
285288
{
289+
/**
290+
* NOTE:
291+
*
292+
* This should not be possible as radius check runs every think
293+
* and survivors in between must be prior to be targeted.
294+
*
295+
* As far as I know, the only exception is that multiple survivors
296+
* are coinciding (like at a corner), and obstracle tracing ends up
297+
* with "true", kinda false positive.
298+
*
299+
* Treated as a bug here, no options.
300+
*/
286301
return false;
287302
}
288303

0 commit comments

Comments
 (0)