# probe.ludic - does the aim agree with the ground about what it hides? From (px, pz) and a ring of # eight points 250 m round it, at 60, 120 and 200 m on 36 bearings, the answer worked out by walking # the ground under each line against aim_clear_to. Lines the ground merely grazes are left out: that # is the probe's sampling against the aim's, not a disagreement. Moves the camera (AimView's) through # `look`, which the game binds to put its camera at a point. var am_seen: int = 0 var am_blocked: int = 0 var am_disagree: int = 0 export function aim_probe_seen() -> int { return am_seen } export function aim_probe_blocked() -> int { return am_blocked } export function aim_probe_disagree() -> int { return am_disagree } # true when at least one line is hidden and the aim disagrees with the ground on at most one in fifty export function aim_probe_ground(px: float, pz: float, look: fn(float, float, float) -> void) -> bool { am_seen = 0 am_blocked = 0 am_disagree = 0 for sp in 0 .. 9 { var sx = px var sz = pz if sp > 0 { let sa = float(sp - 1) / 8.0 * 6.2831853 sx = px + Math.sin(sa) * 250.0 sz = pz + Math.cos(sa) * 250.0 } if AimView.dry(sx, sz) { am_probe_from(sx, AimView.ground(sx, sz) + 1.6, sz, look) } } return am_blocked >= 1 and not (am_disagree > am_seen / 50) } function am_probe_from(sx: float, sy: float, sz: float, look: fn(float, float, float) -> void) -> void { for di in 0 .. 3 { var dist = 60.0 if di == 1 { dist = 120.0 } if di == 2 { dist = 200.0 } for b in 0 .. 36 { let bearing = float(b) / 36.0 * 6.2831853 let ex = sx + Math.sin(bearing) * dist let ez = sz + Math.cos(bearing) * dist let ey = AimView.ground(ex, ez) + 0.4 let truth = am_probe_gap(sx, sy, sz, ex, ey, ez, 0.5, 10000.0) if am_probe_gap(sx, sy, sz, ex, ey, ez, -0.5, 0.5) and not truth { continue } look(sx, sy, sz) am_seen += 1 let clear = aim_clear_to(ex, ey, ez) if not clear { am_blocked += 1 } if clear == truth { am_disagree += 1 } } } } # somewhere between the ends (excluded), the ground stands between lo and hi above the line function am_probe_gap(sx: float, sy: float, sz: float, ex: float, ey: float, ez: float, lo: float, hi: float) -> bool { for k in 2 .. 38 { let t = float(k) / 40.0 let gap = AimView.ground(Math.lerp(sx, ex, t), Math.lerp(sz, ez, t)) - Math.lerp(sy, ey, t) if gap > lo and gap < hi { return true } } return false }