80 lines
3.1 KiB
Text
80 lines
3.1 KiB
Text
# spots.ludic - the spots every place has: here, home, somewhere near home or near here, the shore
|
|
# near either, and a few steps anywhere that can be walked to. A game adds its own (a sign, an
|
|
# animal) as `def NpcSpots`; each sends the person with npc_go / npc_do and says whether it could.
|
|
def NpcSpots here { find: fn np_spot_here }
|
|
def NpcSpots home { find: fn np_spot_home }
|
|
def NpcSpots near_home { find: fn np_spot_near_home }
|
|
def NpcSpots near_here { find: fn np_spot_near_here }
|
|
def NpcSpots shore_home { find: fn np_spot_shore_home }
|
|
def NpcSpots shore_here { find: fn np_spot_shore_here }
|
|
def NpcSpots wander { find: fn np_spot_wander }
|
|
|
|
# the step's act for the step's time, at (x, z)
|
|
export function npc_step_go(npc_st: NpcState, p: NpcPerson, s: NpcStep, x: float, z: float) -> void {
|
|
npc_go(npc_st, p, x, z, s.act, npc_secs(npc_st, s.lo, s.hi))
|
|
}
|
|
|
|
function np_spot_here(npc_st: mut NpcState, p: NpcPerson, s: NpcStep) -> bool {
|
|
npc_face_ahead(p)
|
|
npc_do(npc_st, p, s.act, npc_secs(npc_st, s.lo, s.hi))
|
|
return true
|
|
}
|
|
|
|
function np_spot_home(npc_st: mut NpcState, p: NpcPerson, s: NpcStep) -> bool {
|
|
var fx = p.hx - Math.sin(p.yaw) * 5.0
|
|
var fz = p.hz - Math.cos(p.yaw) * 5.0
|
|
if p.home_face {
|
|
fx = p.hfx
|
|
fz = p.hfz
|
|
}
|
|
if npc_d(p.x, p.z, p.hx, p.hz) < 2.0 { npc_do(npc_st, p, s.act, npc_secs(npc_st, s.lo, s.hi)) } else { npc_step_go(npc_st, p, s, p.hx, p.hz) }
|
|
npc_face(p, fx, fz)
|
|
return true
|
|
}
|
|
|
|
function np_spot_near_home(npc_st: mut NpcState, p: NpcPerson, s: NpcStep) -> bool {
|
|
if not npc_spot_near(npc_st, p.hx, p.hz, s.near, s.far) { return false }
|
|
npc_step_go(npc_st, p, s, npc_st.np_px, npc_st.np_pz)
|
|
return true
|
|
}
|
|
|
|
function np_spot_near_here(npc_st: mut NpcState, p: NpcPerson, s: NpcStep) -> bool {
|
|
if not npc_spot_near(npc_st, p.x, p.z, s.near, s.far) { return false }
|
|
npc_step_go(npc_st, p, s, npc_st.np_px, npc_st.np_pz)
|
|
return true
|
|
}
|
|
|
|
# at the water's edge, facing out over it
|
|
function np_spot_shore(npc_st: mut NpcState, p: NpcPerson, s: NpcStep, x: float, z: float) -> bool {
|
|
if not npc_shore(npc_st, x, z, s.far) { return false }
|
|
let wx = npc_st.np_wx
|
|
let wz = npc_st.np_wz
|
|
npc_step_go(npc_st, p, s, npc_st.np_px, npc_st.np_pz)
|
|
npc_face(p, wx, wz)
|
|
return true
|
|
}
|
|
|
|
function np_spot_shore_home(npc_st: mut NpcState, p: NpcPerson, s: NpcStep) -> bool { return np_spot_shore(npc_st, p, s, p.hx, p.hz) }
|
|
|
|
function np_spot_shore_here(npc_st: mut NpcState, p: NpcPerson, s: NpcStep) -> bool { return np_spot_shore(npc_st, p, s, p.x, p.z) }
|
|
|
|
function np_spot_wander(npc_st: mut NpcState, p: NpcPerson, s: NpcStep) -> bool {
|
|
npc_wander(npc_st, p)
|
|
return true
|
|
}
|
|
|
|
# a few steps somewhere that can actually be walked to, after being stuck
|
|
export function npc_wander(npc_st: mut NpcState, p: NpcPerson) -> void {
|
|
for t in 0 .. 16 {
|
|
let ang = npc_rnd(npc_st) * NP_TAU
|
|
let d = 8.0 + npc_rnd(npc_st) * 18.0
|
|
let x = p.x + Math.cos(ang) * d
|
|
let z = p.z + Math.sin(ang) * d
|
|
if npc_walkable(x, z) and npc_line_ok(p.x, p.z, x, z) {
|
|
npc_go(npc_st, p, x, z, NPCA_IDLE, npc_secs(npc_st, 5, 12))
|
|
return
|
|
}
|
|
}
|
|
npc_face_ahead(p)
|
|
npc_do(npc_st, p, NPCA_IDLE, 8.0)
|
|
}
|