75 lines
2.6 KiB
Text
75 lines
2.6 KiB
Text
# mirror.ludic - a guest draws the host's people: no routine and no census here, a slot filled or
|
|
# emptied as the host says, and each one eased toward where it was last heard to be
|
|
|
|
# on: this machine's own walkers leave, and only the host's are drawn until it is turned off
|
|
export function npc_mirror(npc_st: mut NpcState, on: bool) -> void {
|
|
if npc_st.np_mirror == on { return }
|
|
npc_st.np_mirror = on
|
|
for i in 0 .. len(npc_st.np_walkers) { npc_retire(npc_st, npc_st.np_walkers[i]) }
|
|
if not on { npc_census_now(npc_st) }
|
|
}
|
|
|
|
export function npc_mirroring(npc_st: NpcState) -> bool { return npc_st.np_mirror }
|
|
|
|
# the host's slot: somebody new in it (born), or nobody (gone)
|
|
export function npc_put(npc_st: mut NpcState, slot: int, id: int, kind: int, look: int, seed: float, name: string, hx: float, hz: float) -> NpcPerson {
|
|
if slot < 0 or slot >= npc_st.np_max or kind < 0 or kind >= NPCK_COUNT { return null }
|
|
@alloc_ok("a guest's copy of the host's slots, no more than np_max")
|
|
while len(npc_st.np_walkers) <= slot {
|
|
let q = new NpcPerson
|
|
q.slot = len(npc_st.np_walkers)
|
|
push(npc_st.np_walkers, q)
|
|
}
|
|
let p = npc_st.np_walkers[slot]
|
|
if p.active and p.id == id { return p }
|
|
if p.active { npc_retire(npc_st, p) }
|
|
np_fresh(p, kind, look)
|
|
p.id = id
|
|
p.seed = seed
|
|
p.name = name
|
|
npc_set_at(p, hx, hz)
|
|
p.active = true
|
|
npc_st.np_n += 1
|
|
NpcWorld.born(p)
|
|
return p
|
|
}
|
|
|
|
# where the host says it is now, and what it is doing
|
|
export function npc_heard(npc_st: NpcState, slot: int, x: float, y: float, z: float, yaw: float, speed: float, act: int, stalk: bool) -> void {
|
|
let p = npc_at(npc_st, slot)
|
|
if p == null or not p.active { return }
|
|
if not p.heard {
|
|
p.x = x
|
|
p.y = y
|
|
p.z = z
|
|
p.yaw = yaw
|
|
}
|
|
p.heard = true
|
|
p.heard_t = npc_st.np_clock
|
|
p.nx = x
|
|
p.ny = y
|
|
p.nz = z
|
|
p.nyaw = yaw
|
|
p.speed = speed
|
|
p.act = act
|
|
p.stalk = stalk
|
|
}
|
|
|
|
# heard from in the last six seconds: drawn; not, and it is not drawn until it is again
|
|
export function npc_heard_lately(npc_st: NpcState, p: NpcPerson) -> bool { return p.heard and npc_st.np_clock - p.heard_t <= 6.0 }
|
|
|
|
export function npc_mirror_tick(npc_st: mut NpcState, dt: float) -> void {
|
|
npc_st.np_clock = npc_st.np_clock + dt
|
|
let k = Math.min(1.0, dt * 8.0)
|
|
for i in 0 .. len(npc_st.np_walkers) {
|
|
let p = npc_st.np_walkers[i]
|
|
if not p.active or not npc_heard_lately(npc_st, p) { continue }
|
|
let ox = p.x
|
|
let oz = p.z
|
|
p.x = p.x + (p.nx - p.x) * k
|
|
p.y = p.y + (p.ny - p.y) * k
|
|
p.z = p.z + (p.nz - p.z) * k
|
|
p.yaw = p.yaw + npc_wrap(p.nyaw - p.yaw) * k
|
|
if p.act == NPCA_WALK { p.phase = p.phase + npc_d(ox, oz, p.x, p.z) * 2.6 }
|
|
}
|
|
}
|