feat(senses): walkers slide round still things, and lines of sight are the world's to answer
- ludic.wildlife: WildlifeWorld.push / pushed_x / pushed_z (defaults change nothing); a ground walker's step is slid clear of a still thing with a body from its species' size and scale, and a step that gets nowhere turns away as the water does. Birds are not pushed; no dice added. - ludic.npc: NpcWorld.push / pushed_x / pushed_z (a person 0.35 m round) in npc_walk, and NpcWorld.clear (default true), which npc_line_ok asks at 1 m so a detour does not cut a trunk. - ludic.aim: AimView.clear replaces AimView.ground and the ground march; the pick asks the line a body's width short of where the ray enters the thing (aim_clear_at(t, back)), so a solid thing does not hide itself. probe.ludic (the ground-agreement probe) and AimView.dry are gone. - ludic.photo: PhotoLens.clear replaces PhotoLens.ground, PhotoLens.trunk and the march. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d2cd775309
commit
56e4b6d688
24 changed files with 230 additions and 152 deletions
|
|
@ -1,5 +1,8 @@
|
|||
# walk.ludic - walking to the target: turn toward it, step, never into the water and never up a
|
||||
# scramble - step round it instead - and give up on a target that gets no closer for twenty seconds
|
||||
# walk.ludic - walking to the target: turn toward it, step, slid round a trunk or a tent, never into
|
||||
# the water and never up a scramble - step round it instead - and give up on a target that gets no
|
||||
# closer for twenty seconds
|
||||
const NP_BODY_R: float = 0.35 # a person's width, for the still things
|
||||
|
||||
export function npc_walk(npc_st: mut NpcState, p: NpcPerson, dt: float) -> void {
|
||||
var gx = p.tx
|
||||
var gz = p.tz
|
||||
|
|
@ -29,10 +32,12 @@ export function npc_walk(npc_st: mut NpcState, p: NpcPerson, dt: float) -> void
|
|||
let r = 3.0 * dt
|
||||
p.yaw = p.yaw + Math.clamp(npc_wrap(want - p.yaw), -r, r)
|
||||
let step = sp * dt
|
||||
let nx = p.x - Math.sin(p.yaw) * step
|
||||
let nz = p.z - Math.cos(p.yaw) * step
|
||||
np_slide(npc_st, p, p.x - Math.sin(p.yaw) * step, p.z - Math.cos(p.yaw) * step)
|
||||
let nx = npc_st.np_ask_x
|
||||
let nz = npc_st.np_ask_z
|
||||
let nh = NpcWorld.ground(nx, nz)
|
||||
if nh < NpcWorld.water(nx, nz) + 0.4 or nh - p.y > step * 1.4 {
|
||||
let slid = Math.abs(nx - p.x) + Math.abs(nz - p.z)
|
||||
if nh < NpcWorld.water(nx, nz) + 0.4 or nh - p.y > step * 1.4 or slid < step * 0.2 {
|
||||
p.stall = p.stall + dt
|
||||
if p.stall > p.stall_max { p.stall_max = p.stall }
|
||||
if p.detours < 10 and np_detour(p, want) {
|
||||
|
|
@ -49,6 +54,17 @@ export function npc_walk(npc_st: mut NpcState, p: NpcPerson, dt: float) -> void
|
|||
p.phase = p.phase + step * 2.6
|
||||
}
|
||||
|
||||
# (x, z) slid clear of every still thing for a person; np_ask_x / _z hold where it came out
|
||||
function np_slide(npc_st: mut NpcState, p: NpcPerson, x: float, z: float) -> void {
|
||||
npc_st.np_ask_x = x
|
||||
npc_st.np_ask_z = z
|
||||
if not NpcWorld.push(x, z, NP_BODY_R, p.y + 0.1, p.y + 1.8) { return }
|
||||
let ox = NpcWorld.pushed_x()
|
||||
let oz = NpcWorld.pushed_z()
|
||||
npc_st.np_ask_x = ox
|
||||
npc_st.np_ask_z = oz
|
||||
}
|
||||
|
||||
# there: a step round something ends, or the errand begins, facing what it came for
|
||||
function np_arrive(npc_st: mut NpcState, p: NpcPerson) -> void {
|
||||
if p.via_on {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue