nav_crowd_add_fixed adds a walker with no steering, and nav_crowd_place puts it (snapped to the mesh) where the player is, with the velocity they have, each frame. The others plan round it by that velocity, and whatever it was pushed by is undone at the next placement. crowd_test: six walkers aimed through a standing player come no closer than 1.71 m and all get past, and the player stays where it was put. nav 16/16 on the Mac and the PC; DLL KERNEL32 only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
73 lines
3.8 KiB
Text
73 lines
3.8 KiB
Text
# crowd.ludic - a crowd per kind of walker (phase 18): many walkers steered along their paths at
|
|
# once, each kept clear of the others. The mechanic decides where and how fast; the crowd moves.
|
|
|
|
# a crowd on kind's mesh for at most max walkers, none wider than max_radius; false with no mesh
|
|
export function nav_crowd_start(nav_st: mut NavState, kind: int, max: int, max_radius: float) -> bool {
|
|
let h = nv_mesh(nav_st, kind)
|
|
if h == null { return false }
|
|
nv_crowd_drop(nav_st, kind)
|
|
nav_st.nv_crowds[kind] = nvc_crowd_new(h, max, max_radius)
|
|
return nav_st.nv_crowds[kind] != null
|
|
}
|
|
function nv_crowd(nav_st: NavState, kind: int) -> pointer {
|
|
if kind < 0 or kind >= NAV_KINDS { return null }
|
|
return nav_st.nv_crowds[kind]
|
|
}
|
|
# let kind's crowd go (before its mesh, which it walks on)
|
|
function nv_crowd_drop(nav_st: mut NavState, kind: int) -> void {
|
|
if kind < 0 or kind >= NAV_KINDS or nav_st.nv_crowds[kind] == null { return }
|
|
nvc_crowd_free(nav_st.nv_crowds[kind])
|
|
nav_st.nv_crowds[kind] = null
|
|
}
|
|
|
|
# a walker at (x, y, z) with its width, height, top speed, taste and how hard it keeps its distance
|
|
# from the others (2 an ordinary walker): its index, or -1
|
|
export function nav_crowd_add(nav_st: NavState, kind: int, x: float, y: float, z: float, radius: float, height: float, speed: float, filter: int, separation: float) -> int {
|
|
let c = nv_crowd(nav_st, kind)
|
|
if c == null { return -1 }
|
|
return nvc_crowd_add(c, x, y, z, radius, height, speed, filter, separation)
|
|
}
|
|
# a walker the crowd avoids but never moves (a player): put where it is each frame with nav_crowd_place
|
|
export function nav_crowd_add_fixed(nav_st: NavState, kind: int, x: float, y: float, z: float, radius: float, height: float) -> int {
|
|
let c = nv_crowd(nav_st, kind)
|
|
if c == null { return -1 }
|
|
return nvc_crowd_add_fixed(c, x, y, z, radius, height)
|
|
}
|
|
# walker i put at (x, y, z) going (vx, vz); false off the mesh
|
|
export function nav_crowd_place(nav_st: NavState, kind: int, i: int, x: float, y: float, z: float, vx: float, vz: float) -> bool {
|
|
let c = nv_crowd(nav_st, kind)
|
|
return c != null and i >= 0 and nvc_crowd_place(c, i, x, y, z, vx, vz) == 1
|
|
}
|
|
export function nav_crowd_remove(nav_st: NavState, kind: int, i: int) -> void {
|
|
let c = nv_crowd(nav_st, kind)
|
|
if c != null and i >= 0 { nvc_crowd_remove(c, i) }
|
|
}
|
|
# where walker i is going, snapped to the mesh; false off it
|
|
export function nav_crowd_target(nav_st: NavState, kind: int, i: int, x: float, y: float, z: float) -> bool {
|
|
let c = nv_crowd(nav_st, kind)
|
|
return c != null and i >= 0 and nvc_crowd_target(c, i, x, y, z) == 1
|
|
}
|
|
export function nav_crowd_speed(nav_st: NavState, kind: int, i: int, speed: float) -> void {
|
|
let c = nv_crowd(nav_st, kind)
|
|
if c != null and i >= 0 { nvc_crowd_speed(c, i, speed) }
|
|
}
|
|
# every crowd one step on
|
|
export function nav_crowd_step(nav_st: NavState, dt: float) -> void {
|
|
for k in 0 .. NAV_KINDS { if nav_st.nv_crowds[k] != null { nvc_crowd_update(nav_st.nv_crowds[k], dt) } }
|
|
}
|
|
# walker i read into nav_agent_*; false when there is none
|
|
export function nav_crowd_read(nav_st: NavState, kind: int, i: int) -> bool {
|
|
let c = nv_crowd(nav_st, kind)
|
|
return c != null and i >= 0 and nvc_crowd_read(c, i, nav_st.nv_agent) == 1
|
|
}
|
|
export function nav_agent_x(nav_st: NavState) -> float { return nav_st.nv_agent[0] }
|
|
export function nav_agent_y(nav_st: NavState) -> float { return nav_st.nv_agent[1] }
|
|
export function nav_agent_z(nav_st: NavState) -> float { return nav_st.nv_agent[2] }
|
|
export function nav_agent_vx(nav_st: NavState) -> float { return nav_st.nv_agent[3] }
|
|
export function nav_agent_vz(nav_st: NavState) -> float { return nav_st.nv_agent[5] }
|
|
# microseconds the crowds have spent stepping
|
|
export function nav_crowd_us(nav_st: NavState) -> int {
|
|
var us = 0
|
|
for k in 0 .. NAV_KINDS { if nav_st.nv_crowds[k] != null { us += nvc_crowd_us(nav_st.nv_crowds[k]) } }
|
|
return us
|
|
}
|