@@ -34,7 +34,9 @@ local FAKE_LAG_SUPPRESS_TICKS_66HZ = 66.0
3434local DT_EVIDENCE_WEIGHT = 30.0
3535local DT_LATE_DELAY_PENALTY_MAX = 0.2 -- up to -20% weight at end of 48t confirm window
3636local DT_EVIDENCE_COOLDOWN_S = 0.5
37- local REJECT_LOG_INTERVAL_S = 0.35
37+ local REJECT_LOG_INTERVAL_S = 0.35
38+ local HURT_LOG_INTERVAL_S = 1.0
39+ local WATCH_BURST_SCAN_INTERVAL = 4 -- ticks between scans while waiting for post-hit burst
3840
3941local cachedTickInterval = nil
4042local cachedBurstMinTicks = nil
@@ -173,6 +175,7 @@ local function getState(id)
173175 lastBurstSignature = nil ,
174176 lastRejectTag = nil ,
175177 lastRejectLogTime = 0 ,
178+ lastHurtLogTime = 0 ,
176179 }
177180 end
178181 return playerState [id ]
@@ -314,20 +317,27 @@ local function logBurstScanFailure(id, tag, detail)
314317 end
315318end
316319
317- local function findRecentDtBurst (id )
320+ local function findRecentDtBurst (id , scanDepthOverride , quietOnMiss )
318321 local history = HistoryManager .GetPlayerHistory (id )
319322 if not history or history ._count < 2 then
320- logBurstScanFailure (id , " no_history" , string.format (
321- " history missing or count=%s" , history and tostring (history ._count ) or " nil" ))
323+ if not quietOnMiss then
324+ logBurstScanFailure (id , " no_history" , string.format (
325+ " history missing or count=%s" , history and tostring (history ._count ) or " nil" ))
326+ end
322327 return 0 , 1 , nil , 0
323328 end
324329
325330 local burstMin , burstMax = getBurstThresholds ()
326- local scanDepth = isWatchingForBurst (id ) and WATCHING_DT_BURST_SCAN or RECENT_DT_BURST_SCAN
331+ local scanDepth = scanDepthOverride
332+ if not scanDepth then
333+ scanDepth = isWatchingForBurst (id ) and WATCHING_DT_BURST_SCAN or RECENT_DT_BURST_SCAN
334+ end
327335 local deltaTicks , deltaCount = HistoryManager .GetSimDeltaDeltas (history , scanDepth )
328336 if deltaCount < 1 then
329- logBurstScanFailure (id , " no_deltas" , string.format (
330- " history count=%d but no simtime gaps" , history ._count ))
337+ if not quietOnMiss then
338+ logBurstScanFailure (id , " no_deltas" , string.format (
339+ " history count=%d but no simtime gaps" , history ._count ))
340+ end
331341 return 0 , 1 , deltaTicks , 0
332342 end
333343
@@ -356,12 +366,14 @@ local function findRecentDtBurst(id)
356366 end
357367 end
358368
359- if rhythmBlocked then
360- logBurstScanFailure (id , " rhythm" , rhythmBlocked .. " | deltas=" .. formatDeltaPreview (deltaTicks , 8 ))
361- else
362- logBurstScanFailure (id , " no_dt_band" , string.format (
363- " scan=%d band=[%d,%d) sawDtBand=%s maxInScan=%d deltas=%s" ,
364- scanLimit , burstMin , burstMax , tostring (sawDtBand ), maxInScan , formatDeltaPreview (deltaTicks , 8 )))
369+ if not quietOnMiss then
370+ if rhythmBlocked then
371+ logBurstScanFailure (id , " rhythm" , rhythmBlocked .. " | deltas=" .. formatDeltaPreview (deltaTicks , 8 ))
372+ else
373+ logBurstScanFailure (id , " no_dt_band" , string.format (
374+ " scan=%d band=[%d,%d) sawDtBand=%s maxInScan=%d deltas=%s" ,
375+ scanLimit , burstMin , burstMax , tostring (sawDtBand ), maxInScan , formatDeltaPreview (deltaTicks , 8 )))
376+ end
365377 end
366378
367379 return 0 , 1 , deltaTicks , deltaCount
@@ -400,16 +412,52 @@ local function onBurstDetected(id, burstAmount, curTick, burstIndex)
400412 end
401413end
402414
415+ local function shouldScanBurstThisTick (id , curTick )
416+ if not isWatchingForBurst (id ) then
417+ return true
418+ end
419+ return (curTick % WATCH_BURST_SCAN_INTERVAL ) == 0
420+ end
421+
422+ local function tryDetectBurstForPlayer (id , curTick , forceScan )
423+ if not forceScan and not shouldScanBurstThisTick (id , curTick ) then
424+ return
425+ end
426+
427+ local scanDepth = forceScan and RECENT_DT_BURST_SCAN or nil
428+ local quietOnMiss = forceScan == true
429+ local burstAmount , burstIndex = findRecentDtBurst (id , scanDepth , quietOnMiss )
430+ if burstAmount == 0 then
431+ return
432+ end
433+
434+ cleanBurstTable (curTick )
435+ recordBurstTick (curTick , id )
436+
437+ if isInHitchWindow (curTick ) then
438+ return
439+ end
440+
441+ if isServerHitch (curTick ) then
442+ lastServerHitchTick = curTick
443+ if isDtLogEnabled () then
444+ print (string.format (
445+ " [DoubleTap] server hitch suppressed burst for %s (tick=%d)" ,
446+ id , curTick ))
447+ end
448+ return
449+ end
450+
451+ onBurstDetected (id , burstAmount , curTick , burstIndex )
452+ end
453+
403454function DoubleTap .HasWork (playerState )
404455 if not isEnabled () then
405456 return false
406457 end
407458 if not playerState or not playerState .id then
408459 return false
409460 end
410- if Common .IsLogCategoryEnabled (" DoubleTap" ) or Common .IsLogCategoryEnabled (" Warp/DT" ) then
411- return true
412- end
413461 local id = playerState .id
414462 local weight = Evidence .GetMethodWeight (id , " double_tap" )
415463 if weight <= 0 then
@@ -423,7 +471,7 @@ function DoubleTap.HasWork(playerState)
423471 return true
424472 end
425473 if isWatchingForBurst (id ) then
426- return true
474+ return ( globals . TickCount () % WATCH_BURST_SCAN_INTERVAL ) == 0
427475 end
428476 return (globals .TickCount () % 4 ) == 0
429477end
@@ -459,30 +507,7 @@ function DoubleTap.ProcessPlayer(playerState)
459507
460508 local curTick = globals .TickCount ()
461509 clearStaleBurstState (getState (id ), curTick )
462-
463- local burstAmount , burstIndex = findRecentDtBurst (id )
464- if burstAmount == 0 then
465- return
466- end
467-
468- cleanBurstTable (curTick )
469- recordBurstTick (curTick , id )
470-
471- if isInHitchWindow (curTick ) then
472- return
473- end
474-
475- if isServerHitch (curTick ) then
476- lastServerHitchTick = curTick
477- if isDtLogEnabled () then
478- print (string.format (
479- " [DoubleTap] server hitch suppressed burst for %s (tick=%d)" ,
480- id , curTick ))
481- end
482- return
483- end
484-
485- onBurstDetected (id , burstAmount , curTick , burstIndex )
510+ tryDetectBurstForPlayer (id , curTick )
486511end
487512
488513function DoubleTap .Tick ()
@@ -518,11 +543,16 @@ Events.Subscribe("OnHitscanHit", function(hit)
518543 end
519544
520545 data .lastDamageTick = curTick
546+ tryDetectBurstForPlayer (attackerID , curTick , true )
521547
522548 if isDtLogEnabled () then
523- print (string.format (
524- " [DoubleTap] %s dealt dmg=%d — watching for burst within %d ticks" ,
525- attackerID , hit .damage , getConfirmWindowTicks ()))
549+ local now = globals .RealTime ()
550+ if (now - data .lastHurtLogTime ) >= HURT_LOG_INTERVAL_S then
551+ data .lastHurtLogTime = now
552+ print (string.format (
553+ " [DoubleTap] %s dealt dmg=%d — watching for burst within %d ticks" ,
554+ attackerID , hit .damage , getConfirmWindowTicks ()))
555+ end
526556 end
527557end )
528558
0 commit comments