j148: bound the corridor by speed x ticks (TR_{TFIL,STRAFE}_CORRIDOR_TICKS, default 0 = to the wall); UNTESTED

This commit is contained in:
2026-09-27 08:23:16 +02:00
parent 32ec040e90
commit 5e213df8d9
5 changed files with 62 additions and 0 deletions
@@ -269,6 +269,31 @@ proc loadTfilHeatEnv*() =
loadTfilHeatEnv()
# ── Corridor LENGTH bound (TR_TFIL_CORRIDOR_TICKS, default 0 = to the wall) ──
#
# WHY: the shipped corridor is the rotated rectangle from the bullet to the
# ARENA WALL, so one distant bullet blankets a 40px-wide swath across the whole
# map. That is not physical: in `t` ticks a bullet covers `speed * t` px, and
# `speed = 20 - 3*power`, so a fast (low-power) bullet's reach is LONG and a
# slow one's is SHORT.
#
# WHAT: bound the corridor's LENGTH, nothing else — the heat inside the
# surviving corridor is EXACTLY today's (`heatDecay(along/speed)` is unchanged),
# so unlike the j119 time-indexed heat model this does NOT decay heat along the
# corridor; it only removes corridor that no bullet will reach.
var TfilCorridorTicks* = 0.0 ## 0 (default) = to the wall: byte-for-byte shipped
proc loadTfilCorridorEnv*() =
TfilCorridorTicks = getEnvFloat("TR_TFIL_CORRIDOR_TICKS", 0.0)
loadTfilCorridorEnv()
proc corridorReach*(tWall, speed: float): float =
## The ONE place the corridor length is decided, so the heat field and the
## drawn outline can never disagree. `tWall` = distance to the wall along the
## heading, `speed` = the ghost's own px/tick. 0 = to the wall (shipped).
if TfilCorridorTicks <= 0.0: tWall else: min(tWall, speed * TfilCorridorTicks)
proc heatDecay*(dt: float): float =
## Fraction of a bullet's heat still present `dt` ticks before it arrives.
## Exactly 1.0 when the time model is off, so the default field is
@@ -506,6 +531,9 @@ type CorridorGeom = object
bx, by: float ## bullet origin
proc corridorGeom(b: TrackedBullet, arenaWidth, arenaHeight: float): CorridorGeom =
## `tMin` is the corridor LENGTH: the distance to the wall, bounded by
## `corridorReach` (TR_TFIL_CORRIDOR_TICKS). Unset (0) -> exactly the wall
## distance, so the shipped field and outline are byte-for-byte unchanged.
let speed = sqrt(b.velX * b.velX + b.velY * b.velY)
if speed < 0.001: return
let dx = b.velX / speed
@@ -515,6 +543,7 @@ proc corridorGeom(b: TrackedBullet, arenaWidth, arenaHeight: float): CorridorGeo
elif dx < 0.0: tMin = min(tMin, (0.0 - b.x) / dx)
if dy > 0.0: tMin = min(tMin, (arenaHeight - b.y) / dy)
elif dy < 0.0: tMin = min(tMin, (0.0 - b.y) / dy)
tMin = corridorReach(tMin, speed)
CorridorGeom(dx: dx, dy: dy, px: -dy, py: dx, tMin: tMin, bx: b.x, by: b.y)
proc lavaAt(m: TFILModule, col, row: int): float =