Skip to content

Commit 1f8b3f3

Browse files
Add files via upload
1 parent df81a74 commit 1f8b3f3

File tree

1 file changed

+105
-90
lines changed

1 file changed

+105
-90
lines changed

A_Swing_Prediction.lua

+105-90
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ local Menu = {
7777
},
7878
Keybind = KEY_NONE,
7979
KeybindName = "Always On",
80-
Is_Listening_For_Key = false,
8180
}
8281

8382
local Lua__fullPath = GetScriptName()
@@ -181,6 +180,7 @@ local pLocalPath = {}
181180
local vPlayerPath = {}
182181
local PredPath = {}
183182
local vHitbox = { Vector3(-24, -24, 0), Vector3(24, 24, 82) }
183+
local drawVhitbox = {}
184184
local gravity = client.GetConVar("sv_gravity") or 800 -- Get the current gravity
185185
local stepSize = pLocal:GetPropFloat("localdata", "m_flStepSize") or 18
186186
local backtrackTicks = {}
@@ -212,66 +212,68 @@ local settings = {
212212

213213
local latency = 0
214214
local lerp = 0
215-
local lastAngles = {} ---@type table<number, EulerAngles>
215+
local lastAngles = {} ---@type table<number, Vector3>
216+
local lastDeltas = {} ---@type table<number, number>
217+
local avgDeltas = {} ---@type table<number, number>
216218
local strafeAngles = {} ---@type table<number, number>
217-
local strafeAngleHistories = {} ---@type table<number, table<number, number>>
218-
local MAX_ANGLE_HISTORY = 3 -- Number of past angles to consider for averaging
219+
local inaccuracy = {} ---@type table<number, number>
219220

220-
---@param me WPlayer
221-
local function CalcStrafe(me)
221+
local function CalcStrafe()
222222
local players = entities.FindByClass("CTFPlayer")
223223
for idx, entity in ipairs(players) do
224224
local entityIndex = entity:GetIndex()
225225

226226
if entity:IsDormant() or not entity:IsAlive() then
227227
lastAngles[entityIndex] = nil
228+
lastDeltas[entityIndex] = nil
229+
avgDeltas[entityIndex] = nil
228230
strafeAngles[entityIndex] = nil
229-
strafeAngleHistories[entityIndex] = nil
230-
goto continue
231-
end
232-
233-
if entity:GetTeamNumber() == me:GetTeamNumber() then
231+
inaccuracy[entityIndex] = nil
234232
goto continue
235233
end
236234

237235
local v = entity:EstimateAbsVelocity()
238236
local angle = v:Angles()
239237

240-
strafeAngleHistories[entityIndex] = strafeAngleHistories[entityIndex] or {}
241-
242238
if lastAngles[entityIndex] == nil then
243239
lastAngles[entityIndex] = angle
244240
goto continue
245241
end
246242

247243
local delta = angle.y - lastAngles[entityIndex].y
248244

249-
-- Filtering out excessive changes
250-
if #strafeAngleHistories[entityIndex] > 0 then
251-
local lastDelta = strafeAngleHistories[entityIndex][#strafeAngleHistories[entityIndex]]
252-
if math.abs(delta - lastDelta) <= 90 then
253-
table.insert(strafeAngleHistories[entityIndex], delta)
254-
end
255-
else
256-
table.insert(strafeAngleHistories[entityIndex], delta)
257-
end
245+
-- Calculate the average delta using exponential smoothing
246+
local smoothingFactor = 0.2
247+
local avgDelta = (lastDeltas[entityIndex] or delta) * (1 - smoothingFactor) + delta * smoothingFactor
258248

259-
if #strafeAngleHistories[entityIndex] > MAX_ANGLE_HISTORY then
260-
table.remove(strafeAngleHistories[entityIndex], 1)
261-
end
249+
-- Save the average delta
250+
avgDeltas[entityIndex] = avgDelta
262251

263-
-- Smoothing
264-
local weightedSum = 0
265-
local weight = 0.5
266-
local totalWeight = 0
267-
for i, delta1 in ipairs(strafeAngleHistories[entityIndex]) do
268-
weightedSum = weightedSum + delta1 * weight
269-
totalWeight = totalWeight + weight
270-
weight = weight * 0.9
271-
end
272-
local avgDelta = weightedSum / totalWeight
252+
-- Create two vectors adjusted by their past and current average delta in the yaw direction at a distance of 12 units
253+
local vector1 = Vector3(math.cos(math.rad(lastDeltas[entityIndex] or delta)) * 12, math.sin(math.rad(lastDeltas[entityIndex] or delta)) * 12, 0)
254+
local vector2 = Vector3(math.cos(math.rad(avgDelta)) * 12, math.sin(math.rad(avgDelta)) * 12, 0)
255+
256+
-- Apply deviation
257+
local ang1 = vector1:Angles()
258+
ang1.y = ang1.y + (lastDeltas[entityIndex] or delta)
259+
vector1 = ang1:Forward() * vector1:Length()
260+
261+
local ang2 = vector2:Angles()
262+
ang2.y = ang2.y + avgDelta
263+
vector2 = ang2:Forward() * vector2:Length()
264+
265+
-- Calculate the distance between the two vectors
266+
local distance = (vector1 - vector2):Length()
273267

268+
-- Save the strafe angle
274269
strafeAngles[entityIndex] = avgDelta
270+
271+
-- Calculate the inaccuracy as the distance between the two vectors
272+
inaccuracy[entityIndex] = distance
273+
274+
-- Save the last delta
275+
lastDeltas[entityIndex] = delta
276+
275277
lastAngles[entityIndex] = angle
276278

277279
::continue::
@@ -302,7 +304,7 @@ end
302304
---@param d number?
303305
---@param shouldHitEntity fun(entity: WEntity, contentsMask: integer): boolean?
304306
---@return { pos : Vector3[], vel: Vector3[], onGround: boolean[] }?
305-
local function PredictPlayer(player, t, d, shouldHitEntity)
307+
local function PredictPlayer(player, t, d, Hitbox, shouldHitEntity)
306308
if not gravity or not stepSize then return nil end
307309
local vUp = Vector3(0, 0, 1)
308310
local vStep = Vector3(0, 0, stepSize)
@@ -332,7 +334,7 @@ end
332334

333335
--[[ Forward collision ]]
334336

335-
local wallTrace = engine.TraceHull(lastP + vStep, pos + vStep, vHitbox[1], vHitbox[2], MASK_PLAYERSOLID_BRUSHONLY, shouldHitEntity)
337+
local wallTrace = engine.TraceHull(lastP + vStep, pos + vStep, Hitbox[1], Hitbox[2], MASK_PLAYERSOLID_BRUSHONLY, shouldHitEntity)
336338
--DrawLine(last.p + vStep, pos + vStep)
337339
if wallTrace.fraction < 1 then
338340
-- We'll collide
@@ -357,15 +359,15 @@ end
357359
if not onGround1 then downStep = Vector3() end
358360

359361
-- Ground collision
360-
local groundTrace = engine.TraceHull(pos + vStep, pos - downStep, vHitbox[1], vHitbox[2], MASK_PLAYERSOLID_BRUSHONLY, shouldHitEntity)
362+
local groundTrace = engine.TraceHull(pos + vStep, pos - downStep, Hitbox[1], Hitbox[2], MASK_PLAYERSOLID_BRUSHONLY, shouldHitEntity)
361363
if groundTrace.fraction < 1 then
362364
-- We'll hit the ground
363365
local normal = groundTrace.plane
364366
local angle = math.deg(math.acos(normal:Dot(vUp)))
365367

366368
-- Check the ground angle
367369
if angle < 45 then
368-
if onGround1 and player:GetName() == pLocal:GetName() and gui.GetValue("Bunny Hop") and input.IsButtonDown(KEY_SPACE) then
370+
if onGround1 and player:GetName() == pLocal:GetName() and gui.GetValue("Bunny Hop") == 1 and input.IsButtonDown(KEY_SPACE) then
369371
-- Jump
370372
vel.z = 271
371373
onGround1 = false
@@ -478,10 +480,15 @@ local function GetBestTarget(me)
478480
end
479481

480482
-- Define function to check InRange between the hitbox and the sphere
481-
local function checkInRange(targetPos, spherePos, sphereRadius, isAdvanced)
483+
local function checkInRange(targetPos, spherePos, sphereRadius)
482484

483-
local hitbox_min_trigger = (targetPos + vHitbox[1])
484-
local hitbox_max_trigger = (targetPos + vHitbox[2])
485+
local inaccuracyValue = inaccuracy[vPlayer:GetIndex()]
486+
if not inaccuracyValue then return nil end
487+
488+
print(inaccuracyValue)
489+
490+
local hitbox_min_trigger = Vector3(drawVhitbox[1].x + inaccuracyValue, drawVhitbox[1].y + inaccuracyValue, drawVhitbox[1].z)
491+
local hitbox_max_trigger = Vector3(drawVhitbox[2].x - inaccuracyValue, drawVhitbox[2].y - inaccuracyValue, drawVhitbox[2].z)
485492

486493
-- Calculate the closest point on the hitbox to the sphere
487494
local closestPoint = Vector3(
@@ -497,13 +504,7 @@ end
497504

498505
-- Compare the distance along the vector to the sum of the radius
499506
if sphereRadius > distanceAlongVector then
500-
local swingtrace = engine.TraceHull(spherePos, atackPos, Vector3(-18,-18,-18),Vector3(18,18,18), MASK_SHOT_HULL)
501-
-- InRange detected (including intersecting)
502-
if swingtrace.entity == vPlayer then
503-
return true, closestPoint
504-
else
505-
return false, nil
506-
end
507+
return true, closestPoint
507508
else
508509
-- Not InRange
509510
return false, nil
@@ -563,7 +564,7 @@ local function checkInRangeWithLatency(playerIndex, swingRange)
563564

564565
if Backtrack == 0 and fakelatencyON == 0 then
565566
-- If latency is disabled, check if vPlayerOrigin is in range from pLocalOrigin
566-
inRange, point = checkInRange(vPlayerOrigin, pLocalOrigin, swingRange - 18, true)
567+
inRange, point = checkInRange(vPlayerOrigin, pLocalOrigin, swingRange - 18)
567568

568569
if inRange then
569570
return inRange, point
@@ -758,40 +759,44 @@ end
758759
gravity = client.GetConVar("sv_gravity")
759760
stepSize = pLocal:GetPropFloat("localdata", "m_flStepSize")
760761

762+
CalcStrafe()
763+
761764
-- Local player prediction
762765
if pLocal:EstimateAbsVelocity() == 0 then
763766
-- If the local player is not accelerating, set the predicted position to the current position
764767
pLocalFuture = pLocalOrigin
765768
else
766769
local player = WPlayer.FromEntity(pLocal)
767-
CalcStrafe(player)
768770

769771
strafeAngle = strafeAngles[pLocal:GetIndex()] or 0
770772

771-
local predData = PredictPlayer(player, time, strafeAngle)
773+
local predData = PredictPlayer(player, time, strafeAngle, vHitbox)
772774

773775
pLocalPath = predData.pos
774776
pLocalFuture = predData.pos[time] + viewOffset
775777
end
776778

777779
-- stop if no target
778-
if CurrentTarget == nil then
780+
if CurrentTarget == nil then
779781
vPlayerFuture = nil
780-
return
782+
return
781783
end
782-
783784
vPlayerOrigin = CurrentTarget:GetAbsOrigin() -- Get closest player origin
785+
786+
drawVhitbox = {}
787+
drawVhitbox[1] = vPlayerOrigin + vHitbox[1]
788+
drawVhitbox[2] = vPlayerOrigin + vHitbox[2]
789+
784790
-- Target player prediction
785791
if CurrentTarget:EstimateAbsVelocity() == 0 then
786792
-- If the target player is not accelerating, set the predicted position to their current position
787793
vPlayerFuture = CurrentTarget:GetAbsOrigin()
788794
else
789795
local player = WPlayer.FromEntity(CurrentTarget)
790-
CalcStrafe(player)
791796

792797
strafeAngle = strafeAngles[CurrentTarget:GetIndex()] or 0
793798

794-
local predData = PredictPlayer(player, time, strafeAngle)
799+
local predData = PredictPlayer(player, time, strafeAngle, drawVhitbox)
795800

796801
vPlayerPath = predData.pos
797802
vPlayerFuture = predData.pos[time]
@@ -989,7 +994,7 @@ Menu.KeybindName = "Always On"
989994

990995
local function handleKeybind(noKeyText, keybind, keybindName)
991996
if KeybindName ~= "Press The Key" and ImMenu.Button(KeybindName or noKeyText) then
992-
bindTimer = os.clock() + 0.1
997+
bindTimer = os.clock() + 0.4
993998
KeybindName = "Press The Key"
994999
elseif KeybindName == "Press The Key" then
9951000
ImMenu.Text("Press the key")
@@ -1168,39 +1173,49 @@ end
11681173
end
11691174
end
11701175

1171-
-- Calculate trigger box vertices
1172-
local vertices = {
1173-
client.WorldToScreen(vPlayerFuture + Vector3(hitbox_Width, hitbox_Width, 0)),
1174-
client.WorldToScreen(vPlayerFuture + Vector3(-hitbox_Width, hitbox_Width, 0)),
1175-
client.WorldToScreen(vPlayerFuture + Vector3(-hitbox_Width, -hitbox_Width, 0)),
1176-
client.WorldToScreen(vPlayerFuture + Vector3(hitbox_Width, -hitbox_Width, 0)),
1177-
client.WorldToScreen(vPlayerFuture + Vector3(hitbox_Width, hitbox_Width, hitbox_Height)),
1178-
client.WorldToScreen(vPlayerFuture + Vector3(-hitbox_Width, hitbox_Width, hitbox_Height)),
1179-
client.WorldToScreen(vPlayerFuture + Vector3(-hitbox_Width, -hitbox_Width, hitbox_Height)),
1180-
client.WorldToScreen(vPlayerFuture + Vector3(hitbox_Width, -hitbox_Width, hitbox_Height))
1181-
}
1182-
1183-
-- Check if vertices are not nil
1184-
if vertices[1] and vertices[2] and vertices[3] and vertices[4] and vertices[5] and vertices[6] and vertices[7] and vertices[8] then
1185-
-- Draw front face
1186-
draw.Line(vertices[1][1], vertices[1][2], vertices[2][1], vertices[2][2])
1187-
draw.Line(vertices[2][1], vertices[2][2], vertices[3][1], vertices[3][2])
1188-
draw.Line(vertices[3][1], vertices[3][2], vertices[4][1], vertices[4][2])
1189-
draw.Line(vertices[4][1], vertices[4][2], vertices[1][1], vertices[1][2])
1190-
1191-
-- Draw back face
1192-
draw.Line(vertices[5][1], vertices[5][2], vertices[6][1], vertices[6][2])
1193-
draw.Line(vertices[6][1], vertices[6][2], vertices[7][1], vertices[7][2])
1194-
draw.Line(vertices[7][1], vertices[7][2], vertices[8][1], vertices[8][2])
1195-
draw.Line(vertices[8][1], vertices[8][2], vertices[5][1], vertices[5][2])
1196-
1197-
-- Draw connecting lines
1198-
if vertices[1] and vertices[5] then draw.Line(vertices[1][1], vertices[1][2], vertices[5][1], vertices[5][2]) end
1199-
if vertices[2] and vertices[6] then draw.Line(vertices[2][1], vertices[2][2], vertices[6][1], vertices[6][2]) end
1200-
if vertices[3] and vertices[7] then draw.Line(vertices[3][1], vertices[3][2], vertices[7][1], vertices[7][2]) end
1201-
if vertices[4] and vertices[8] then draw.Line(vertices[4][1], vertices[4][2], vertices[8][1], vertices[8][2]) end
1202-
end
1176+
-- Calculate min and max points
1177+
local minPoint = drawVhitbox[1]
1178+
local maxPoint = drawVhitbox[2]
1179+
1180+
-- Calculate vertices of the AABB
1181+
-- Assuming minPoint and maxPoint are the minimum and maximum points of the AABB:
1182+
local vertices = {
1183+
Vector3(minPoint.x, minPoint.y, minPoint.z), -- Bottom-back-left
1184+
Vector3(minPoint.x, maxPoint.y, minPoint.z), -- Bottom-front-left
1185+
Vector3(maxPoint.x, maxPoint.y, minPoint.z), -- Bottom-front-right
1186+
Vector3(maxPoint.x, minPoint.y, minPoint.z), -- Bottom-back-right
1187+
Vector3(minPoint.x, minPoint.y, maxPoint.z), -- Top-back-left
1188+
Vector3(minPoint.x, maxPoint.y, maxPoint.z), -- Top-front-left
1189+
Vector3(maxPoint.x, maxPoint.y, maxPoint.z), -- Top-front-right
1190+
Vector3(maxPoint.x, minPoint.y, maxPoint.z) -- Top-back-right
1191+
}
1192+
1193+
-- Convert 3D coordinates to 2D screen coordinates
1194+
for i, vertex in ipairs(vertices) do
1195+
vertices[i] = client.WorldToScreen(vertex)
1196+
end
1197+
1198+
-- Draw lines between vertices to visualize the box
1199+
if vertices[1] and vertices[2] and vertices[3] and vertices[4] and vertices[5] and vertices[6] and vertices[7] and vertices[8] then
1200+
-- Draw front face
1201+
draw.Line(vertices[1][1], vertices[1][2], vertices[2][1], vertices[2][2])
1202+
draw.Line(vertices[2][1], vertices[2][2], vertices[3][1], vertices[3][2])
1203+
draw.Line(vertices[3][1], vertices[3][2], vertices[4][1], vertices[4][2])
1204+
draw.Line(vertices[4][1], vertices[4][2], vertices[1][1], vertices[1][2])
1205+
1206+
-- Draw back face
1207+
draw.Line(vertices[5][1], vertices[5][2], vertices[6][1], vertices[6][2])
1208+
draw.Line(vertices[6][1], vertices[6][2], vertices[7][1], vertices[7][2])
1209+
draw.Line(vertices[7][1], vertices[7][2], vertices[8][1], vertices[8][2])
1210+
draw.Line(vertices[8][1], vertices[8][2], vertices[5][1], vertices[5][2])
1211+
1212+
-- Draw connecting lines
1213+
draw.Line(vertices[1][1], vertices[1][2], vertices[5][1], vertices[5][2])
1214+
draw.Line(vertices[2][1], vertices[2][2], vertices[6][1], vertices[6][2])
1215+
draw.Line(vertices[3][1], vertices[3][2], vertices[7][1], vertices[7][2])
1216+
draw.Line(vertices[4][1], vertices[4][2], vertices[8][1], vertices[8][2])
12031217
end
1218+
end
12041219
end
12051220
end
12061221
end

0 commit comments

Comments
 (0)