ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic 1804 vars into 126 states, 64 into lets; 23498 edits in 460 files Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
39 lines
1.6 KiB
Text
39 lines
1.6 KiB
Text
# safe.ludic - somewhere a body can be put down: the one answer every dismount, every stand-up and
|
|
# every landing asks. The wanted spot if it will do, else the nearest ring out that is clear of every
|
|
# collider, no deeper than max_depth, within CHAR_DROP of the height being left, and on ground
|
|
# gentle enough to walk off - a spot you can stand on but cannot leave is not a safe spot.
|
|
function chr_safe_ok(character_st: mut CharacterState, x: float, z: float, from_y: float, max_depth: float) -> bool {
|
|
let g = CharacterGround.height(x, z)
|
|
if Math.abs(g - from_y) > CHAR_DROP { return false }
|
|
if CharacterGround.water(x, z) - g > max_depth { return false }
|
|
if chr_push(character_st, x, z, 0.4, g, g + CHAR_BODY) { return false }
|
|
var lo = g
|
|
var hi = g
|
|
for k in 0 .. 4 {
|
|
let a = float(k) * (chr_pi * 0.5)
|
|
let h = CharacterGround.height(x + Math.sin(a) * CHAR_SLOPE_PROBE, z + Math.cos(a) * CHAR_SLOPE_PROBE)
|
|
lo = Math.min(lo, h)
|
|
hi = Math.max(hi, h)
|
|
}
|
|
return not (hi - lo > CHAR_SLOPE_PROBE * 2.0)
|
|
}
|
|
|
|
export function char_safe_spot(character_st: mut CharacterState, x: float, z: float, from_y: float, max_depth: float) -> bool {
|
|
character_st.chr_safe_x = x
|
|
character_st.chr_safe_z = z
|
|
if chr_safe_ok(character_st, x, z, from_y, max_depth) { return true }
|
|
for r in 0 .. 9 {
|
|
let rad = 0.8 + float(r) * 1.1
|
|
for k in 0 .. 16 {
|
|
let a = float(k) * (chr_pi / 8.0)
|
|
let px = x + Math.sin(a) * rad
|
|
let pz = z + Math.cos(a) * rad
|
|
if chr_safe_ok(character_st, px, pz, from_y, max_depth) {
|
|
character_st.chr_safe_x = px
|
|
character_st.chr_safe_z = pz
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|