refactor(packages): 0.R5 - a question no longer starts its state - 64 lazy starts ('if st.x == null { st.x = ... }' inside a getter) are the state's defaults, gear__ensure is gone, and ludic migrate state --tighten took mut off 208 package parameters: things_all, thing_find, gear_charge, gear_level, jobs_state and the rest read
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
54f5efb23f
commit
9862ec82e3
102 changed files with 320 additions and 351 deletions
|
|
@ -30,7 +30,7 @@ function np_turns(act: int) -> bool {
|
|||
}
|
||||
|
||||
# a player who came within notice since the last look is greeted - once, until they walk off
|
||||
export function npc_notice(npc_st: mut NpcState, p: NpcPerson) -> void {
|
||||
export function npc_notice(npc_st: NpcState, p: NpcPerson) -> void {
|
||||
let reach = NpcKinds[p.kind].notice
|
||||
for i in 0 .. NpcWorld.players() {
|
||||
if i >= 30 { break }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# census.ludic - making one (a slot reused before a new one, a look, a name, a start on its own
|
||||
# ground out of the players' sight where that can be had), a post's fixed person, and leaving
|
||||
export function npc_spawn(npc_st: mut NpcState, kind: int) -> NpcPerson {
|
||||
np_ensure(npc_st)
|
||||
np_ensure()
|
||||
if npc_st.np_n >= npc_st.np_max or kind < 0 or kind >= NPCK_COUNT { return null }
|
||||
var p: NpcPerson = null
|
||||
for i in 0 .. len(npc_st.np_walkers) {
|
||||
|
|
@ -94,7 +94,7 @@ export function npc_set_at(p: NpcPerson, x: float, z: float) -> void {
|
|||
# somebody fixed at a post (a vendor behind the counter): never walks, never counted, never leaves,
|
||||
# turns to a player within its kind's notice and back to `yaw` when they go
|
||||
export function npc_place(npc_st: mut NpcState, kind: int, x: float, z: float, yaw: float, name: string, look: int) -> NpcPerson {
|
||||
np_ensure(npc_st)
|
||||
np_ensure()
|
||||
let p = new NpcPerson
|
||||
p.slot = len(npc_st.np_posts)
|
||||
np_fresh(p, kind, look)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
# 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 {
|
||||
np_ensure(npc_st)
|
||||
np_ensure()
|
||||
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]) }
|
||||
|
|
@ -14,7 +14,7 @@ export function npc_mirroring(npc_st: NpcState) -> bool { return npc_st.np_mirro
|
|||
|
||||
# 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 {
|
||||
np_ensure(npc_st)
|
||||
np_ensure()
|
||||
if slot < 0 or slot >= npc_st.np_max or kind < 0 or kind >= NPCK_COUNT { return null }
|
||||
while len(npc_st.np_walkers) <= slot {
|
||||
let q = new NpcPerson
|
||||
|
|
@ -36,7 +36,7 @@ export function npc_put(npc_st: mut NpcState, slot: int, id: int, kind: int, loo
|
|||
}
|
||||
|
||||
# where the host says it is now, and what it is doing
|
||||
export function npc_heard(npc_st: mut NpcState, slot: int, x: float, y: float, z: float, yaw: float, speed: float, act: int, stalk: bool) -> void {
|
||||
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 {
|
||||
|
|
@ -60,7 +60,7 @@ export function npc_heard(npc_st: mut NpcState, slot: int, x: float, y: float, z
|
|||
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 {
|
||||
np_ensure(npc_st)
|
||||
np_ensure()
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# names.ludic - a name nobody else in the place is using: not another person, not one the place
|
||||
# keeps for itself (NpcWorld.taken: a vendor), and not somebody who left a little while ago
|
||||
|
||||
export function npc_name_used(npc_st: mut NpcState, n: string) -> bool {
|
||||
export function npc_name_used(npc_st: NpcState, n: string) -> bool {
|
||||
if NpcWorld.taken(n) { return true }
|
||||
let all = npc_walkers(npc_st)
|
||||
for i in 0 .. len(all) { if all[i].active and all[i].name == n { return true } }
|
||||
|
|
@ -12,7 +12,7 @@ export function npc_name_used(npc_st: mut NpcState, n: string) -> bool {
|
|||
}
|
||||
|
||||
# a free name from the body's pool, from a place in it the dice choose ("" when the pool is empty)
|
||||
export function npc_pick_name(npc_st: mut NpcState, body: int) -> string {
|
||||
export function npc_pick_name(npc_st: NpcState, body: int) -> string {
|
||||
let pool = new []string
|
||||
for i in 0 .. NPCN_COUNT { if NpcNames[i].body == body { push(pool, NpcNames[i].name) } }
|
||||
let n = len(pool)
|
||||
|
|
@ -26,7 +26,6 @@ export function npc_pick_name(npc_st: mut NpcState, body: int) -> string {
|
|||
}
|
||||
|
||||
function np_left(npc_st: mut NpcState, name: string) -> void {
|
||||
if npc_st.np_recent == null { npc_st.np_recent = new []string }
|
||||
push(npc_st.np_recent, name)
|
||||
if len(npc_st.np_recent) <= 8 { return }
|
||||
let keep = new []string
|
||||
|
|
@ -35,7 +34,7 @@ function np_left(npc_st: mut NpcState, name: string) -> void {
|
|||
}
|
||||
|
||||
# how many pairs share a name, the place's own names included
|
||||
export function npc_name_clashes(npc_st: mut NpcState) -> int {
|
||||
export function npc_name_clashes(npc_st: NpcState) -> int {
|
||||
var dup = 0
|
||||
let all = npc_walkers(npc_st)
|
||||
for i in 0 .. len(all) {
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ export state NpcState {
|
|||
np_wx: float = 0.0
|
||||
np_wz: float = 0.0
|
||||
np_clock: float = 0.0
|
||||
np_recent: []string = null # the last few names that left
|
||||
np_walkers: []NpcPerson = null
|
||||
np_posts: []NpcPerson = null
|
||||
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 = null
|
||||
np_facts: Queue<NpcFact> = null
|
||||
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
|
||||
|
|
@ -23,12 +23,11 @@ export state NpcState {
|
|||
const NP_PI: float = 3.1415927
|
||||
const NP_TAU: float = 6.2831853
|
||||
|
||||
export function npc_facts(npc_st: mut NpcState) -> Queue<NpcFact> {
|
||||
if npc_st.np_facts == null { npc_st.np_facts = queue_new("npc.facts") }
|
||||
export function npc_facts(npc_st: NpcState) -> Queue<NpcFact> {
|
||||
return npc_st.np_facts
|
||||
}
|
||||
|
||||
function np_fact(npc_st: mut NpcState, what: int, p: NpcPerson, player: int) -> NpcFact {
|
||||
function np_fact(npc_st: NpcState, what: int, p: NpcPerson, player: int) -> NpcFact {
|
||||
let f = new NpcFact
|
||||
f.what = what
|
||||
f.person = p.id
|
||||
|
|
@ -40,40 +39,37 @@ function np_fact(npc_st: mut NpcState, what: int, p: NpcPerson, player: int) ->
|
|||
return f
|
||||
}
|
||||
|
||||
function np_ensure(npc_st: mut NpcState) -> void {
|
||||
if npc_st.np_walkers == null { npc_st.np_walkers = new []NpcPerson }
|
||||
if npc_st.np_posts == null { npc_st.np_posts = new []NpcPerson }
|
||||
if npc_st.np_dice == null { npc_st.np_dice = rng_new(20260925) }
|
||||
function np_ensure() -> void {
|
||||
}
|
||||
|
||||
# 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: mut NpcState, n: int) -> void {
|
||||
np_ensure(npc_st)
|
||||
export function npc_seed(npc_st: NpcState, n: int) -> void {
|
||||
np_ensure()
|
||||
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: mut NpcState) -> float {
|
||||
np_ensure(npc_st)
|
||||
export function npc_rnd(npc_st: NpcState) -> float {
|
||||
np_ensure()
|
||||
return rng_float(npc_st.np_dice)
|
||||
}
|
||||
|
||||
export function npc_between(npc_st: mut NpcState, lo: int, hi: int) -> int {
|
||||
np_ensure(npc_st)
|
||||
export function npc_between(npc_st: NpcState, lo: int, hi: int) -> int {
|
||||
np_ensure()
|
||||
return rng_between(npc_st.np_dice, lo, hi)
|
||||
}
|
||||
|
||||
export function npc_secs(npc_st: mut NpcState, lo: int, hi: int) -> float { return float(npc_between(npc_st, lo, np_hi(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: mut NpcState) -> []NpcPerson {
|
||||
np_ensure(npc_st)
|
||||
export function npc_walkers(npc_st: NpcState) -> []NpcPerson {
|
||||
np_ensure()
|
||||
return npc_st.np_walkers
|
||||
}
|
||||
|
||||
export function npc_posts(npc_st: mut NpcState) -> []NpcPerson {
|
||||
np_ensure(npc_st)
|
||||
export function npc_posts(npc_st: NpcState) -> []NpcPerson {
|
||||
np_ensure()
|
||||
return npc_st.np_posts
|
||||
}
|
||||
|
||||
|
|
@ -82,20 +78,20 @@ 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: mut NpcState, slot: int) -> NpcPerson {
|
||||
np_ensure(npc_st)
|
||||
export function npc_at(npc_st: NpcState, slot: int) -> NpcPerson {
|
||||
np_ensure()
|
||||
if slot < 0 or slot >= len(npc_st.np_walkers) { return null }
|
||||
return npc_st.np_walkers[slot]
|
||||
}
|
||||
|
||||
export function npc_post(npc_st: mut NpcState, i: int) -> NpcPerson {
|
||||
np_ensure(npc_st)
|
||||
export function npc_post(npc_st: NpcState, i: int) -> NpcPerson {
|
||||
np_ensure()
|
||||
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: mut NpcState, id: int) -> NpcPerson {
|
||||
np_ensure(npc_st)
|
||||
export function npc_by_id(npc_st: NpcState, id: int) -> NpcPerson {
|
||||
np_ensure()
|
||||
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
|
||||
|
|
@ -118,3 +114,4 @@ 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") }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# routine.ludic - going somewhere to do something, doing it here, and deciding what is next: the
|
||||
# kind's own plan first, then a weighted draw among its steps for this hour, falling through to the
|
||||
# next step whose spot can be found, and standing a while when none can
|
||||
export function npc_go(npc_st: mut NpcState, p: NpcPerson, x: float, z: float, act: int, dur: float) -> void {
|
||||
export function npc_go(npc_st: NpcState, p: NpcPerson, x: float, z: float, act: int, dur: float) -> void {
|
||||
p.tx = x
|
||||
p.tz = z
|
||||
p.next_act = act
|
||||
|
|
@ -76,7 +76,7 @@ export function npc_plan(npc_st: mut NpcState, p: NpcPerson) -> void {
|
|||
|
||||
# a weighted draw among the steps whose hours hold now; a step whose spot cannot be found
|
||||
# gives way to the next one in the table, round to the start
|
||||
export function npc_steps(npc_st: mut NpcState, p: NpcPerson, steps: []NpcStep) -> bool {
|
||||
export function npc_steps(npc_st: NpcState, p: NpcPerson, steps: []NpcStep) -> bool {
|
||||
let h = NpcWorld.hour()
|
||||
var total = 0
|
||||
for i in 0 .. len(steps) { if np_in_hours(steps[i], h) { total += np_pos(steps[i].weight) } }
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ 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: mut NpcState, p: NpcPerson, s: NpcStep, x: float, z: float) -> void {
|
||||
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))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ function fk_player_at(npc_tests_fake_st: mut NpcTestsFakeState, x: float, z: flo
|
|||
# seconds of the place, in twentieths
|
||||
function fk_run(npc_st: mut NpcState, secs: float) -> void { for k in 0 .. int(secs * 20.0) { npc_tick(npc_st, 0.05) } }
|
||||
|
||||
function fk_count(npc_st: mut NpcState, what: int) -> int {
|
||||
function fk_count(npc_st: NpcState, what: int) -> int {
|
||||
let fs = q_drain(npc_facts(npc_st))
|
||||
var n = 0
|
||||
for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# tick.ludic - a step of everyone, on the machine that runs the place: the census on the half hour,
|
||||
# the day's end (only ever out of every player's sight), the walk or the act, and who noticed whom
|
||||
export function npc_tick(npc_st: mut NpcState, dt: float) -> void {
|
||||
np_ensure(npc_st)
|
||||
np_ensure()
|
||||
for i in 0 .. len(npc_st.np_posts) { if npc_st.np_posts[i].active { np_step_post(npc_st, npc_st.np_posts[i], dt) } }
|
||||
if npc_st.np_hold or npc_st.np_mirror { return }
|
||||
np_census(npc_st)
|
||||
|
|
@ -15,7 +15,7 @@ export function npc_tick(npc_st: mut NpcState, dt: float) -> void {
|
|||
|
||||
# the posts alone: a machine that does not run the place still turns its vendors to whoever comes
|
||||
export function npc_posts_tick(npc_st: mut NpcState, dt: float) -> void {
|
||||
np_ensure(npc_st)
|
||||
np_ensure()
|
||||
for i in 0 .. len(npc_st.np_posts) { if npc_st.np_posts[i].active { np_step_post(npc_st, npc_st.np_posts[i], dt) } }
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ function np_census(npc_st: mut NpcState) -> void {
|
|||
|
||||
function np_is_night(h: float) -> bool { return h >= 21.0 or h < 5.0 }
|
||||
|
||||
function np_draw_kind(npc_st: mut NpcState, night: bool) -> int {
|
||||
function np_draw_kind(npc_st: NpcState, night: bool) -> int {
|
||||
var total = 0
|
||||
for k in 0 .. NPCK_COUNT { if np_drawn(k, night) { total += NpcKinds[k].weight } }
|
||||
if total <= 0 { return -1 }
|
||||
|
|
@ -82,7 +82,7 @@ export function npc_hold(npc_st: mut NpcState, on: bool) -> void { npc_st.np_hol
|
|||
|
||||
# everyone gone, as a new trip starts; the posts are the place's and stay
|
||||
export function npc_reset(npc_st: mut NpcState) -> void {
|
||||
np_ensure(npc_st)
|
||||
np_ensure()
|
||||
for i in 0 .. len(npc_st.np_walkers) { npc_retire(npc_st, npc_st.np_walkers[i]) }
|
||||
npc_st.np_n = 0
|
||||
npc_st.np_next_h = 0.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue