j148: bound the corridor by speed x ticks (TR_{TFIL,STRAFE}_CORRIDOR_TICKS, default 0 = to the wall); UNTESTED
This commit is contained in:
@@ -105,6 +105,7 @@ TR_TFIL_RANGE_HI=200.0 # px; upper edge of that band
|
|||||||
TR_TFIL_RANGE_TEMP=0.4 # sharpness of the ring mover's weighted random draw
|
TR_TFIL_RANGE_TEMP=0.4 # sharpness of the ring mover's weighted random draw
|
||||||
TR_TFIL_RANGE_K=60.0 # px; how fast the weight falls off outside the band
|
TR_TFIL_RANGE_K=60.0 # px; how fast the weight falls off outside the band
|
||||||
TR_TFIL_CORRIDOR_HEAT=10.0 # lava painted per corridor-overlapping tile
|
TR_TFIL_CORRIDOR_HEAT=10.0 # lava painted per corridor-overlapping tile
|
||||||
|
TR_TFIL_CORRIDOR_TICKS=0.0 # corridor length in ticks: 0 = to the wall (shipped); N>0 = min(to wall, bullet speed * N)
|
||||||
TR_TFIL_WALL_HOTNESS=15.0 # peak heat painted on tiles next to a wall
|
TR_TFIL_WALL_HOTNESS=15.0 # peak heat painted on tiles next to a wall
|
||||||
TR_TFIL_WALL_RADIANCE=10.0 # how fast wall heat falls off with distance
|
TR_TFIL_WALL_RADIANCE=10.0 # how fast wall heat falls off with distance
|
||||||
TR_TFIL_BULLET_CORE=10.0 # tfil only: lava per bullet-overlapping tile (== PathDangerThreshold, so a bullet is never hot on its own)
|
TR_TFIL_BULLET_CORE=10.0 # tfil only: lava per bullet-overlapping tile (== PathDangerThreshold, so a bullet is never hot on its own)
|
||||||
@@ -147,6 +148,7 @@ TR_STRAFE_HEAT_GRID=on # draw the whole heat grid; 0 leaves only the chosen til
|
|||||||
TR_STRAFE_BULLET_CORE=20.0 # strafe's own retune: lava per bullet-overlapping tile
|
TR_STRAFE_BULLET_CORE=20.0 # strafe's own retune: lava per bullet-overlapping tile
|
||||||
TR_STRAFE_BULLET_AURA=10.0 # strafe's own retune: lava for the bullet aura ring
|
TR_STRAFE_BULLET_AURA=10.0 # strafe's own retune: lava for the bullet aura ring
|
||||||
TR_STRAFE_CORRIDOR_HEAT=10.0 # strafe's own retune: lava per corridor tile
|
TR_STRAFE_CORRIDOR_HEAT=10.0 # strafe's own retune: lava per corridor tile
|
||||||
|
TR_STRAFE_CORRIDOR_TICKS=0.0 # same length bound for strafe: 0 = to the wall (shipped)
|
||||||
TR_STRAFE_WALL_HOTNESS=15.0 # strafe's own retune: peak wall heat
|
TR_STRAFE_WALL_HOTNESS=15.0 # strafe's own retune: peak wall heat
|
||||||
TR_STRAFE_WALL_RADIANCE=5.0 # strafe's own retune: wall heat falloff
|
TR_STRAFE_WALL_RADIANCE=5.0 # strafe's own retune: wall heat falloff
|
||||||
|
|
||||||
|
|||||||
@@ -311,6 +311,8 @@ proc printEffectiveValues(ctx: EnvReportContext) =
|
|||||||
emit("TR_TFIL_RANGE_K", $RangeK, sourceOf("TR_TFIL_RANGE_K"))
|
emit("TR_TFIL_RANGE_K", $RangeK, sourceOf("TR_TFIL_RANGE_K"))
|
||||||
emit("TR_TFIL_CORRIDOR_HEAT", $the_floor_is_lava_ring.CorridorHeat,
|
emit("TR_TFIL_CORRIDOR_HEAT", $the_floor_is_lava_ring.CorridorHeat,
|
||||||
sourceOf("TR_TFIL_CORRIDOR_HEAT"))
|
sourceOf("TR_TFIL_CORRIDOR_HEAT"))
|
||||||
|
emit("TR_TFIL_CORRIDOR_TICKS", $the_floor_is_lava.TfilCorridorTicks,
|
||||||
|
sourceOf("TR_TFIL_CORRIDOR_TICKS"))
|
||||||
emit("TR_TFIL_WALL_HOTNESS", $the_floor_is_lava_ring.WallHotness,
|
emit("TR_TFIL_WALL_HOTNESS", $the_floor_is_lava_ring.WallHotness,
|
||||||
sourceOf("TR_TFIL_WALL_HOTNESS"))
|
sourceOf("TR_TFIL_WALL_HOTNESS"))
|
||||||
emit("TR_TFIL_WALL_RADIANCE", $the_floor_is_lava.WallRadiance,
|
emit("TR_TFIL_WALL_RADIANCE", $the_floor_is_lava.WallRadiance,
|
||||||
@@ -373,6 +375,7 @@ proc printEffectiveValues(ctx: EnvReportContext) =
|
|||||||
emit("TR_STRAFE_BULLET_CORE", $StrafeBulletCore, sourceOf("TR_STRAFE_BULLET_CORE"))
|
emit("TR_STRAFE_BULLET_CORE", $StrafeBulletCore, sourceOf("TR_STRAFE_BULLET_CORE"))
|
||||||
emit("TR_STRAFE_BULLET_AURA", $StrafeBulletAura, sourceOf("TR_STRAFE_BULLET_AURA"))
|
emit("TR_STRAFE_BULLET_AURA", $StrafeBulletAura, sourceOf("TR_STRAFE_BULLET_AURA"))
|
||||||
emit("TR_STRAFE_CORRIDOR_HEAT", $StrafeCorridorHeat, sourceOf("TR_STRAFE_CORRIDOR_HEAT"))
|
emit("TR_STRAFE_CORRIDOR_HEAT", $StrafeCorridorHeat, sourceOf("TR_STRAFE_CORRIDOR_HEAT"))
|
||||||
|
emit("TR_STRAFE_CORRIDOR_TICKS", $StrafeCorridorTicks, sourceOf("TR_STRAFE_CORRIDOR_TICKS"))
|
||||||
emit("TR_STRAFE_WALL_HOTNESS", $StrafeWallHotness, sourceOf("TR_STRAFE_WALL_HOTNESS"))
|
emit("TR_STRAFE_WALL_HOTNESS", $StrafeWallHotness, sourceOf("TR_STRAFE_WALL_HOTNESS"))
|
||||||
emit("TR_STRAFE_WALL_RADIANCE", $StrafeWallRadiance, sourceOf("TR_STRAFE_WALL_RADIANCE"))
|
emit("TR_STRAFE_WALL_RADIANCE", $StrafeWallRadiance, sourceOf("TR_STRAFE_WALL_RADIANCE"))
|
||||||
|
|
||||||
@@ -646,6 +649,7 @@ proc knownEnvNames*(): seq[string] =
|
|||||||
"TR_RAM_PLAN_MARGIN", "TR_RAM_PLAN_HITRATE", "TR_RAM_LOG",
|
"TR_RAM_PLAN_MARGIN", "TR_RAM_PLAN_HITRATE", "TR_RAM_LOG",
|
||||||
"TR_TFIL_RANGE_LO", "TR_TFIL_RANGE_HI", "TR_TFIL_RANGE_TEMP",
|
"TR_TFIL_RANGE_LO", "TR_TFIL_RANGE_HI", "TR_TFIL_RANGE_TEMP",
|
||||||
"TR_TFIL_RANGE_K", "TR_TFIL_CORRIDOR_HEAT", "TR_TFIL_WALL_HOTNESS",
|
"TR_TFIL_RANGE_K", "TR_TFIL_CORRIDOR_HEAT", "TR_TFIL_WALL_HOTNESS",
|
||||||
|
"TR_TFIL_CORRIDOR_TICKS",
|
||||||
"TR_TFIL_WALL_RADIANCE", "TR_TFIL_BULLET_CORE", "TR_TFIL_BULLET_AURA",
|
"TR_TFIL_WALL_RADIANCE", "TR_TFIL_BULLET_CORE", "TR_TFIL_BULLET_AURA",
|
||||||
"TR_TFIL_TILE_REPLAN", "TR_TFIL_COMMIT_TICKS", "TR_TFIL_NO_REV",
|
"TR_TFIL_TILE_REPLAN", "TR_TFIL_COMMIT_TICKS", "TR_TFIL_NO_REV",
|
||||||
"TR_TFIL_COMMIT_LOG", "TR_TFIL_COMMIT_ARRIVAL", "TR_TFIL_COMMIT_MARGIN",
|
"TR_TFIL_COMMIT_LOG", "TR_TFIL_COMMIT_ARRIVAL", "TR_TFIL_COMMIT_MARGIN",
|
||||||
@@ -664,6 +668,7 @@ proc knownEnvNames*(): seq[string] =
|
|||||||
"TR_FIRE_LAG",
|
"TR_FIRE_LAG",
|
||||||
"TR_STRAFE_HEAT_GRID", "TR_STRAFE_BULLET_CORE", "TR_STRAFE_BULLET_AURA",
|
"TR_STRAFE_HEAT_GRID", "TR_STRAFE_BULLET_CORE", "TR_STRAFE_BULLET_AURA",
|
||||||
"TR_STRAFE_CORRIDOR_HEAT", "TR_STRAFE_WALL_HOTNESS",
|
"TR_STRAFE_CORRIDOR_HEAT", "TR_STRAFE_WALL_HOTNESS",
|
||||||
|
"TR_STRAFE_CORRIDOR_TICKS",
|
||||||
"TR_STRAFE_WALL_RADIANCE",
|
"TR_STRAFE_WALL_RADIANCE",
|
||||||
SurfPrefDistEnv, SurfDistBandEnv, SurfWallMarginEnv, SurfRadialFracEnv,
|
SurfPrefDistEnv, SurfDistBandEnv, SurfWallMarginEnv, SurfRadialFracEnv,
|
||||||
SurfLogEnv,
|
SurfLogEnv,
|
||||||
|
|||||||
@@ -226,6 +226,13 @@ const CorridorHeatDefault = 10.0 ## corridor heat (== PathDangerThreshold)
|
|||||||
const WallHotnessDefault = 15.0 ## wall radiance peak (retune)
|
const WallHotnessDefault = 15.0 ## wall radiance peak (retune)
|
||||||
const WallRadianceDefault = 5.0 ## wall radiance falloff (retune)
|
const WallRadianceDefault = 5.0 ## wall radiance falloff (retune)
|
||||||
|
|
||||||
|
## j148: the corridor LENGTH bound, `TR_STRAFE_CORRIDOR_TICKS`. The shipped
|
||||||
|
## corridor runs from the bullet to the ARENA WALL; a bullet only covers
|
||||||
|
## `speed * t` px in `t` ticks, so a fixed TIME window is the physical length.
|
||||||
|
## 0 (the default) = to the wall, byte-for-byte shipped.
|
||||||
|
const DefaultStrafeCorridorTicks = 0.0
|
||||||
|
var StrafeCorridorTicks* = DefaultStrafeCorridorTicks
|
||||||
|
|
||||||
## Heat shape is override-able so the shipped field and the retune can be
|
## Heat shape is override-able so the shipped field and the retune can be
|
||||||
## compared on one binary. The DEFAULTS are the retune (see the block above);
|
## compared on one binary. The DEFAULTS are the retune (see the block above);
|
||||||
## the knobs are strafe-specific, so the ring mover's own `TR_TFIL_*` names do
|
## the knobs are strafe-specific, so the ring mover's own `TR_TFIL_*` names do
|
||||||
@@ -374,6 +381,15 @@ proc loadStrafeHeatEnv*() =
|
|||||||
StrafeCorridorHeat = getEnvFloat("TR_STRAFE_CORRIDOR_HEAT", CorridorHeatDefault)
|
StrafeCorridorHeat = getEnvFloat("TR_STRAFE_CORRIDOR_HEAT", CorridorHeatDefault)
|
||||||
StrafeWallHotness = getEnvFloat("TR_STRAFE_WALL_HOTNESS", WallHotnessDefault)
|
StrafeWallHotness = getEnvFloat("TR_STRAFE_WALL_HOTNESS", WallHotnessDefault)
|
||||||
StrafeWallRadiance = getEnvFloat("TR_STRAFE_WALL_RADIANCE", WallRadianceDefault)
|
StrafeWallRadiance = getEnvFloat("TR_STRAFE_WALL_RADIANCE", WallRadianceDefault)
|
||||||
|
StrafeCorridorTicks = getEnvFloat("TR_STRAFE_CORRIDOR_TICKS", DefaultStrafeCorridorTicks)
|
||||||
|
|
||||||
|
proc strafeCorridorReach*(tWall, speed: float): float =
|
||||||
|
## The ONE place the strafe corridor length is decided (same rule as tfil's
|
||||||
|
## `corridorReach`, same physics: a bullet covers `speed * t` px in `t` ticks).
|
||||||
|
## 0 (default) = to the arena wall, byte-for-byte shipped; N > 0 = N ticks.
|
||||||
|
## Only the LENGTH changes: the heat inside the surviving corridor is today's
|
||||||
|
## (`heatDecay(along / speed)` untouched) — this is NOT the j119 time-heat model.
|
||||||
|
if StrafeCorridorTicks <= 0.0: tWall else: min(tWall, speed * StrafeCorridorTicks)
|
||||||
|
|
||||||
proc loadStrafeEnv*() =
|
proc loadStrafeEnv*() =
|
||||||
## Read the strafe knobs. Called once at module init; callable again after
|
## Read the strafe knobs. Called once at module init; callable again after
|
||||||
@@ -700,6 +716,7 @@ proc buildHeat(m: var StrafeModule, ws: WorldState) =
|
|||||||
elif dx < 0.0: tMin = min(tMin, (0.0 - b.x) / dx)
|
elif dx < 0.0: tMin = min(tMin, (0.0 - b.x) / dx)
|
||||||
if dy > 0.0: tMin = min(tMin, (m.arenaHeight - b.y) / dy)
|
if dy > 0.0: tMin = min(tMin, (m.arenaHeight - b.y) / dy)
|
||||||
elif dy < 0.0: tMin = min(tMin, (0.0 - b.y) / dy)
|
elif dy < 0.0: tMin = min(tMin, (0.0 - b.y) / dy)
|
||||||
|
tMin = strafeCorridorReach(tMin, speed)
|
||||||
if tMin == 0.0: continue
|
if tMin == 0.0: continue
|
||||||
let (_, auraR) = bulletRadii(b.power)
|
let (_, auraR) = bulletRadii(b.power)
|
||||||
let bMag = bulletMagScale(b.power)
|
let bMag = bulletMagScale(b.power)
|
||||||
|
|||||||
@@ -269,6 +269,31 @@ proc loadTfilHeatEnv*() =
|
|||||||
|
|
||||||
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 =
|
proc heatDecay*(dt: float): float =
|
||||||
## Fraction of a bullet's heat still present `dt` ticks before it arrives.
|
## 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
|
## 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
|
bx, by: float ## bullet origin
|
||||||
|
|
||||||
proc corridorGeom(b: TrackedBullet, arenaWidth, arenaHeight: float): CorridorGeom =
|
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)
|
let speed = sqrt(b.velX * b.velX + b.velY * b.velY)
|
||||||
if speed < 0.001: return
|
if speed < 0.001: return
|
||||||
let dx = b.velX / speed
|
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)
|
elif dx < 0.0: tMin = min(tMin, (0.0 - b.x) / dx)
|
||||||
if dy > 0.0: tMin = min(tMin, (arenaHeight - b.y) / dy)
|
if dy > 0.0: tMin = min(tMin, (arenaHeight - b.y) / dy)
|
||||||
elif dy < 0.0: tMin = min(tMin, (0.0 - 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)
|
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 =
|
proc lavaAt(m: TFILModule, col, row: int): float =
|
||||||
|
|||||||
@@ -3660,3 +3660,12 @@ isolates the knob):**
|
|||||||
the known strafe-over-tfil gap reproducing itself, and it is exactly why the
|
the known strafe-over-tfil gap reproducing itself, and it is exactly why the
|
||||||
pre-registration demanded the within-mover reference: read against `tfil_off`
|
pre-registration demanded the within-mover reference: read against `tfil_off`
|
||||||
alone, the knob looks like a winner it is not.
|
alone, the knob looks like a winner it is not.
|
||||||
|
|
||||||
|
**j148 — corridor LENGTH bound (unmeasured).** `TR_TFIL_CORRIDOR_TICKS` and
|
||||||
|
`TR_STRAFE_CORRIDOR_TICKS` (both default `0`) bound the corridor — the rotated
|
||||||
|
rectangle from the ghost bullet along its heading — by `min(distance to the wall,
|
||||||
|
bulletSpeed * TICKS)`, so a fast (low-power) bullet's corridor is long and a
|
||||||
|
slow one's is short, instead of every bullet blanketing the arena to the wall.
|
||||||
|
`0` is exactly today's behaviour; only the LENGTH changes, the heat inside the
|
||||||
|
surviving corridor is untouched. **Untested** — no battle, no measurement, the
|
||||||
|
parity guard only says the default path is byte-for-byte unchanged.
|
||||||
|
|||||||
Reference in New Issue
Block a user