ludic/packages/ludic.npc/person.ludic
Orkuncakilkaya b247603b7e merge lang/foundations into lang/native-jolt (seeds regenerated)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 03:20:44 +03:00

109 lines
3.5 KiB
Text

# person.ludic - the people: walkers in slots the census fills and empties, and the fixed ones at
# their posts; the package's own dice and its facts
export state NpcState {
np_px: float = 0.0
np_pz: float = 0.0
np_wx: float = 0.0
np_wz: float = 0.0
np_clock: float = 0.0
np_recent: []string = new []string # the last few names that left
np_walkers: []NpcPerson = new []NpcPerson
np_posts: []NpcPerson = new []NpcPerson
np_max: int = 10 # walkers at most
np_n: int = 0 # walkers about
np_dice: Rng = rng_new(20260925)
np_facts: Queue<NpcFact> = np_facts__new()
np_next_h: float = 0.0 # the hour the census is next looked at
np_hold: bool = false # held where they stand (a shot of their poses)
np_mirror: bool = false # a guest drawing a host's: no routine runs here
nw_ids: int = 0
np_near_i: int = -1
np_said: string = ""
np_ask_x: float = 0.0 # the point handed to NpcWorld.push, then where it came out
np_ask_z: float = 0.0
}
const NP_PI: float = 3.1415927
const NP_TAU: float = 6.2831853
export function npc_facts(npc_st: NpcState) -> Queue<NpcFact> {
return npc_st.np_facts
}
function np_fact(npc_st: NpcState, what: int, p: NpcPerson, player: int) -> NpcFact {
let f = new NpcFact
f.what = what
f.person = p.id
f.slot = p.slot
f.fixed = p.fixed
f.player = player
f.act = p.act
q_push(npc_facts(npc_st), f)
return f
}
# how many walkers the place can hold at once
export function npc_config(npc_st: mut NpcState, max: int) -> void { npc_st.np_max = max }
export function npc_seed(npc_st: NpcState, n: int) -> void {
rng_seed(npc_st.np_dice, n)
}
# 0 .. 1, and whole seconds lo .. hi, off the package's dice
export function npc_rnd(npc_st: NpcState) -> float {
return rng_float(npc_st.np_dice)
}
export function npc_between(npc_st: NpcState, lo: int, hi: int) -> int {
return rng_between(npc_st.np_dice, lo, hi)
}
export function npc_secs(npc_st: NpcState, lo: int, hi: int) -> float { return float(npc_between(npc_st, lo, np_hi(lo, hi))) }
export function npc_walkers(npc_st: NpcState) -> []NpcPerson {
return npc_st.np_walkers
}
export function npc_posts(npc_st: NpcState) -> []NpcPerson {
return npc_st.np_posts
}
export function npc_count(npc_st: NpcState) -> int { return npc_st.np_n }
export function npc_max(npc_st: NpcState) -> int { return npc_st.np_max }
# a walker's slot or a post, and anyone by id
export function npc_at(npc_st: NpcState, slot: int) -> NpcPerson {
if slot < 0 or slot >= len(npc_st.np_walkers) { return null }
return npc_st.np_walkers[slot]
}
export function npc_post(npc_st: NpcState, i: int) -> NpcPerson {
if i < 0 or i >= len(npc_st.np_posts) { return null }
return npc_st.np_posts[i]
}
export function npc_by_id(npc_st: NpcState, id: int) -> NpcPerson {
for i in 0 .. len(npc_st.np_walkers) { if npc_st.np_walkers[i].active and npc_st.np_walkers[i].id == id { return npc_st.np_walkers[i] } }
for i in 0 .. len(npc_st.np_posts) { if npc_st.np_posts[i].active and npc_st.np_posts[i].id == id { return npc_st.np_posts[i] } }
return null
}
export function npc_d(ax: float, az: float, bx: float, bz: float) -> float {
let dx = ax - bx
let dz = az - bz
return Math.sqrt(dx * dx + dz * dz)
}
export function npc_wrap(a: float) -> float {
var r = a
while r > NP_PI { r = r - NP_TAU }
while r < -NP_PI { r = r + NP_TAU }
return r
}
function np_hi(lo: int, hi: int) -> int {
if hi < lo { return lo }
return hi
}
function np_facts__new() -> Queue<NpcFact> { return queue_new("npc.facts") }