feat(base): 0.R4 - a queue keeps its own count, so every package verb takes only its own state; ludic migrate state --prune
ludic.base's Queue<T> carries a QueueTag (its name and pending count): queue_new(name), q_push(q, v), q_drain(q), q_clear(q) take no BaseState, and core_undrained(tags) names the given queues still holding facts. A reducer on a package's state can now call that package's verbs (wallet_earn(wallet_st, n)). ludic migrate state --prune (ludicc --migrate-prune) takes out each state parameter a function no longer uses, nor anything it calls, and the argument that fills it - including an argument for a parameter the callee has dropped, which is taken out before the call is checked, so a generic's T is told by the argument that says it. A reducer keeps its state. --dry-run now counts the edits it would make. Every package was moved with it: 608 base_st parameters and their arguments, 1889 edits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8cf4b3fed6
commit
71735b10a2
151 changed files with 58668 additions and 54719 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(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPerson) -> void {
|
||||
export function npc_notice(npc_st: mut NpcState, p: NpcPerson) -> void {
|
||||
let reach = NpcKinds[p.kind].notice
|
||||
for i in 0 .. NpcWorld.players() {
|
||||
if i >= 30 { break }
|
||||
|
|
@ -39,7 +39,7 @@ export function npc_notice(base_st: mut BaseState, npc_st: mut NpcState, p: NpcP
|
|||
if NpcWorld.player_on(i) { d = npc_d(p.x, p.z, NpcWorld.player_x(i), NpcWorld.player_z(i)) }
|
||||
if d < reach and (p.near & bit) == 0 {
|
||||
p.near = p.near | bit
|
||||
np_fact(base_st, npc_st, NPC_F_GREETED, p, i)
|
||||
np_fact(npc_st, NPC_F_GREETED, p, i)
|
||||
}
|
||||
if d > reach * 1.5 and (p.near & bit) != 0 { p.near = p.near - bit }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ export state NpcState {
|
|||
const NP_PI: float = 3.1415927
|
||||
const NP_TAU: float = 6.2831853
|
||||
|
||||
export function npc_facts(base_st: mut BaseState, npc_st: mut NpcState) -> Queue<NpcFact> {
|
||||
if npc_st.np_facts == null { npc_st.np_facts = queue_new(base_st, "npc.facts") }
|
||||
export function npc_facts(npc_st: mut NpcState) -> Queue<NpcFact> {
|
||||
if npc_st.np_facts == null { npc_st.np_facts = queue_new("npc.facts") }
|
||||
return npc_st.np_facts
|
||||
}
|
||||
|
||||
function np_fact(base_st: mut BaseState, npc_st: mut NpcState, what: int, p: NpcPerson, player: int) -> NpcFact {
|
||||
function np_fact(npc_st: mut NpcState, what: int, p: NpcPerson, player: int) -> NpcFact {
|
||||
let f = new NpcFact
|
||||
f.what = what
|
||||
f.person = p.id
|
||||
|
|
@ -36,7 +36,7 @@ function np_fact(base_st: mut BaseState, npc_st: mut NpcState, what: int, p: Npc
|
|||
f.fixed = p.fixed
|
||||
f.player = player
|
||||
f.act = p.act
|
||||
q_push(base_st, npc_facts(base_st, npc_st), f)
|
||||
q_push(npc_facts(npc_st), f)
|
||||
return f
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ export function npc_said(npc_st: NpcState) -> string { return npc_st.np_said }
|
|||
|
||||
# a player talks to them: the line (-1: nothing to say), its words in npc_said(), a Talked fact,
|
||||
# and `said` marked for the day
|
||||
export function npc_talk(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPerson, player: int) -> int {
|
||||
export function npc_talk(npc_st: mut NpcState, p: NpcPerson, player: int) -> int {
|
||||
let line = npc_line_for(npc_st, p)
|
||||
let f = np_fact(base_st, npc_st, NPC_F_TALKED, p, player)
|
||||
let f = np_fact(npc_st, NPC_F_TALKED, p, player)
|
||||
f.line = line
|
||||
p.said = NpcWorld.day()
|
||||
return line
|
||||
|
|
@ -70,13 +70,13 @@ export function npc_talk(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPer
|
|||
|
||||
# the answer to choice c of a line: the line it leads to (-1: the talk is over), its words in
|
||||
# npc_said(), and a Talked fact carrying the choice's code
|
||||
export function npc_choose(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPerson, line: int, c: int, player: int) -> int {
|
||||
export function npc_choose(npc_st: mut NpcState, p: NpcPerson, line: int, c: int, player: int) -> int {
|
||||
npc_st.np_said = ""
|
||||
if line < 0 or line >= NPCL_COUNT { return -1 }
|
||||
let cs = NpcLines[line].choices
|
||||
if cs == null or c < 0 or c >= len(cs) { return -1 }
|
||||
let next = npc_lines_find(cs[c].line)
|
||||
let f = np_fact(base_st, npc_st, NPC_F_TALKED, p, player)
|
||||
let f = np_fact(npc_st, NPC_F_TALKED, p, player)
|
||||
f.line = next
|
||||
f.choice = cs[c].code
|
||||
if next >= 0 { npc_st.np_said = npc_words(p, next) }
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export state NpcTestsFakeState {
|
|||
fk_gone: int = 0
|
||||
}
|
||||
|
||||
function fk_setup(base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) -> void {
|
||||
function fk_setup(npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) -> void {
|
||||
npc_tests_fake_st.fk_hour = 12.0
|
||||
npc_tests_fake_st.fk_day = 1
|
||||
npc_tests_fake_st.fk_want = 0
|
||||
|
|
@ -24,7 +24,7 @@ function fk_setup(base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_s
|
|||
npc_tests_fake_st.fk_born = 0
|
||||
npc_tests_fake_st.fk_gone = 0
|
||||
npc_clear(npc_st)
|
||||
npc_reset(base_st, npc_st)
|
||||
npc_reset(npc_st)
|
||||
npc_seed(npc_st, 7)
|
||||
npc_config(npc_st, 10)
|
||||
}
|
||||
|
|
@ -53,10 +53,10 @@ function fk_player_at(npc_tests_fake_st: mut NpcTestsFakeState, x: float, z: flo
|
|||
}
|
||||
|
||||
# seconds of the place, in twentieths
|
||||
function fk_run(base_st: mut BaseState, npc_st: mut NpcState, secs: float) -> void { for k in 0 .. int(secs * 20.0) { npc_tick(base_st, npc_st, 0.05) } }
|
||||
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(base_st: mut BaseState, npc_st: mut NpcState, what: int) -> int {
|
||||
let fs = q_drain(base_st, npc_facts(base_st, npc_st))
|
||||
function fk_count(npc_st: mut 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 } }
|
||||
return n
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ program NpcTest {
|
|||
function tk_greeting(p: NpcPerson) -> string { return "What'll it be?" }
|
||||
function tk_start(npc_st: mut NpcState, p: NpcPerson) -> void { npc_start_near(npc_st, p, 0.0, 0.0, 0.0, 10.0) }
|
||||
|
||||
function one(base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState, kind: int) -> NpcPerson {
|
||||
fk_setup(base_st, npc_st, npc_tests_fake_st)
|
||||
function one(npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState, kind: int) -> NpcPerson {
|
||||
fk_setup(npc_st, npc_tests_fake_st)
|
||||
npc_tests_fake_st.fk_want = 1
|
||||
let p = npc_spawn(npc_st, kind)
|
||||
npc_set_at(p, 0.0, 0.0)
|
||||
|
|
@ -58,56 +58,56 @@ program NpcTest {
|
|||
expect_eq(NPCN_COUNT, 14)
|
||||
}
|
||||
|
||||
test "the census fills to what the place wants, by weight, and after dark only who stays out" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
fk_setup(base_st, npc_st, npc_tests_fake_st)
|
||||
test "the census fills to what the place wants, by weight, and after dark only who stays out" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
fk_setup(npc_st, npc_tests_fake_st)
|
||||
npc_tests_fake_st.fk_want = 4
|
||||
npc_tick(base_st, npc_st, 0.05)
|
||||
npc_tick(npc_st, 0.05)
|
||||
expect_eq(npc_count(npc_st), 4)
|
||||
expect_eq(npc_tests_fake_st.fk_born, 4)
|
||||
expect_eq(npc_name_clashes(npc_st), 0)
|
||||
for i in 0 .. len(npc_walkers(npc_st)) { expect(npc_walkers(npc_st)[i].kind != NPCK_VENDOR) }
|
||||
fk_setup(base_st, npc_st, npc_tests_fake_st)
|
||||
fk_setup(npc_st, npc_tests_fake_st)
|
||||
npc_tests_fake_st.fk_want = 3
|
||||
npc_tests_fake_st.fk_hour = 23.0
|
||||
npc_tick(base_st, npc_st, 0.05)
|
||||
npc_tick(npc_st, 0.05)
|
||||
expect_eq(npc_count(npc_st), 3)
|
||||
for i in 0 .. len(npc_walkers(npc_st)) { expect_eq(npc_walkers(npc_st)[i].kind, NPCK_CAMPER) }
|
||||
}
|
||||
|
||||
test "no name twice, and never one the place keeps" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
fk_setup(base_st, npc_st, npc_tests_fake_st)
|
||||
test "no name twice, and never one the place keeps" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
fk_setup(npc_st, npc_tests_fake_st)
|
||||
npc_tests_fake_st.fk_want = 6
|
||||
npc_tick(base_st, npc_st, 0.05)
|
||||
npc_tick(npc_st, 0.05)
|
||||
expect_eq(npc_count(npc_st), 6)
|
||||
expect_eq(npc_name_clashes(npc_st), 0)
|
||||
for i in 0 .. 6 { expect(npc_walkers(npc_st)[i].name != "Ada") }
|
||||
}
|
||||
|
||||
test "it walks to where it is going and begins there, facing what it came for" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(base_st, npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
test "it walks to where it is going and begins there, facing what it came for" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
npc_go(npc_st, p, 20.0, 0.0, NPCA_SIT, 30.0)
|
||||
npc_face(p, 30.0, 0.0)
|
||||
fk_run(base_st, npc_st, 30.0)
|
||||
fk_run(npc_st, 30.0)
|
||||
expect_eq(p.act, NPCA_SIT)
|
||||
expect(npc_d(p.x, p.z, 20.0, 0.0) < 1.3)
|
||||
expect(p.phase > 20.0)
|
||||
expect_eq(fk_count(base_st, npc_st, NPC_F_ARRIVED), 1)
|
||||
expect_eq(fk_count(npc_st, NPC_F_ARRIVED), 1)
|
||||
expect_near(p.fx, 30.0, 0.01)
|
||||
}
|
||||
|
||||
test "nobody walks into the lake" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(base_st, npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
test "nobody walks into the lake" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
npc_go(npc_st, p, -80.0, 0.0, NPCA_SIT, 30.0)
|
||||
var west = 0.0
|
||||
for k in 0 .. 1200 {
|
||||
npc_tick(base_st, npc_st, 0.05)
|
||||
npc_tick(npc_st, 0.05)
|
||||
west = Math.min(west, p.x)
|
||||
}
|
||||
expect(west > -50.5)
|
||||
}
|
||||
|
||||
test "a step's spot is where its hours say: the shore by day, home by night" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(base_st, npc_st, npc_tests_fake_st, NPCK_CAMPER)
|
||||
test "a step's spot is where its hours say: the shore by day, home by night" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(npc_st, npc_tests_fake_st, NPCK_CAMPER)
|
||||
npc_set_at(p, -20.0, 0.0)
|
||||
npc_tests_fake_st.fk_hour = 12.0
|
||||
npc_plan(npc_st, p)
|
||||
|
|
@ -119,65 +119,65 @@ program NpcTest {
|
|||
expect_eq(p.act, NPCA_SIT)
|
||||
}
|
||||
|
||||
test "an act is not begun where the place says nobody stops" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(base_st, npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
test "an act is not begun where the place says nobody stops" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
npc_set_at(p, 40.0, 0.0)
|
||||
npc_do(npc_st, p, NPCA_SIT, 30.0)
|
||||
expect_eq(p.act, NPCA_WALK)
|
||||
expect(fk_allowed(p.tx, p.tz))
|
||||
}
|
||||
|
||||
test "it turns to a player who comes near, greets them once, and again after they have gone" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(base_st, npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
test "it turns to a player who comes near, greets them once, and again after they have gone" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
npc_do(npc_st, p, NPCA_IDLE, 100.0)
|
||||
p.yaw = 0.0
|
||||
fk_player_at(npc_tests_fake_st, 0.0, 0.0 - 5.0)
|
||||
fk_run(base_st, npc_st, 2.0)
|
||||
fk_run(npc_st, 2.0)
|
||||
expect(Math.abs(p.yaw) < 0.05)
|
||||
fk_player_at(npc_tests_fake_st, 5.0, 0.0)
|
||||
fk_run(base_st, npc_st, 3.0)
|
||||
fk_run(npc_st, 3.0)
|
||||
expect(Math.abs(npc_wrap(p.yaw + 1.5707963)) < 0.05)
|
||||
fk_run(base_st, npc_st, 1.0)
|
||||
expect_eq(fk_count(base_st, npc_st, NPC_F_GREETED), 1)
|
||||
fk_run(npc_st, 1.0)
|
||||
expect_eq(fk_count(npc_st, NPC_F_GREETED), 1)
|
||||
fk_player_at(npc_tests_fake_st, 40.0, 0.0)
|
||||
fk_run(base_st, npc_st, 0.5)
|
||||
fk_run(npc_st, 0.5)
|
||||
fk_player_at(npc_tests_fake_st, 5.0, 0.0)
|
||||
fk_run(base_st, npc_st, 0.5)
|
||||
expect_eq(fk_count(base_st, npc_st, NPC_F_GREETED), 1)
|
||||
fk_run(npc_st, 0.5)
|
||||
expect_eq(fk_count(npc_st, NPC_F_GREETED), 1)
|
||||
}
|
||||
|
||||
test "a fisher keeps its eyes on the water, whoever is near" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(base_st, npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
test "a fisher keeps its eyes on the water, whoever is near" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
npc_do(npc_st, p, NPCA_FISH, 100.0)
|
||||
p.yaw = 0.0
|
||||
npc_face(p, 0.0, -10.0)
|
||||
fk_player_at(npc_tests_fake_st, 5.0, 0.0)
|
||||
fk_run(base_st, npc_st, 2.0)
|
||||
fk_run(npc_st, 2.0)
|
||||
expect(Math.abs(p.yaw) < 0.05)
|
||||
}
|
||||
|
||||
test "the day ends out of sight, and not in it" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(base_st, npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
test "the day ends out of sight, and not in it" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(npc_st, npc_tests_fake_st, NPCK_HIKER)
|
||||
npc_do(npc_st, p, NPCA_IDLE, 1000.0)
|
||||
npc_tests_fake_st.fk_hour = 22.5
|
||||
fk_player_at(npc_tests_fake_st, 20.0, 0.0)
|
||||
fk_run(base_st, npc_st, 0.5)
|
||||
fk_run(npc_st, 0.5)
|
||||
expect(p.active)
|
||||
fk_player_at(npc_tests_fake_st, 500.0, 0.0)
|
||||
fk_run(base_st, npc_st, 0.5)
|
||||
fk_run(npc_st, 0.5)
|
||||
expect(not p.active)
|
||||
expect_eq(npc_tests_fake_st.fk_gone, 1)
|
||||
let c = one(base_st, npc_st, npc_tests_fake_st, NPCK_CAMPER)
|
||||
let c = one(npc_st, npc_tests_fake_st, NPCK_CAMPER)
|
||||
npc_do(npc_st, c, NPCA_IDLE, 1000.0)
|
||||
npc_tests_fake_st.fk_hour = 22.5
|
||||
fk_run(base_st, npc_st, 0.5)
|
||||
fk_run(npc_st, 0.5)
|
||||
expect(c.active)
|
||||
}
|
||||
|
||||
test "lines: the highest that has something to say, the story's words, and choices" (base_st: mut BaseState, npc_st: mut NpcState, npc_test_st: mut NpcTestState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(base_st, npc_st, npc_tests_fake_st, NPCK_CAMPER)
|
||||
test "lines: the highest that has something to say, the story's words, and choices" (npc_st: mut NpcState, npc_test_st: mut NpcTestState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
let p = one(npc_st, npc_tests_fake_st, NPCK_CAMPER)
|
||||
npc_do(npc_st, p, NPCA_FISH, 100.0)
|
||||
expect_eq(npc_talk(base_st, npc_st, p, 0), NPCL_HUSH)
|
||||
expect_eq(npc_talk(npc_st, p, 0), NPCL_HUSH)
|
||||
expect(npc_said(npc_st) == "Shh.")
|
||||
expect(npc_talked_today(p))
|
||||
npc_do(npc_st, p, NPCA_IDLE, 100.0)
|
||||
|
|
@ -186,34 +186,34 @@ program NpcTest {
|
|||
expect_eq(npc_line_for(npc_st, p), NPCL_NEWS)
|
||||
expect(npc_said(npc_st) == `{p.name} saw a bear.`)
|
||||
npc_test_st.news_on = false
|
||||
expect_eq(npc_choose(base_st, npc_st, p, NPCL_HELLO, 0, 0), NPCL_FISH_NO)
|
||||
expect_eq(npc_choose(npc_st, p, NPCL_HELLO, 0, 0), NPCL_FISH_NO)
|
||||
expect(npc_said(npc_st) == "Not today.")
|
||||
expect_eq(npc_choose(base_st, npc_st, p, NPCL_HELLO, 1, 0), -1)
|
||||
let fs = q_drain(base_st, npc_facts(base_st, npc_st))
|
||||
expect_eq(npc_choose(npc_st, p, NPCL_HELLO, 1, 0), -1)
|
||||
let fs = q_drain(npc_facts(npc_st))
|
||||
expect_eq(len(fs), 3)
|
||||
expect_eq(fs[1].choice, 7)
|
||||
expect(npc_greeting(p) == "What'll it be?")
|
||||
}
|
||||
|
||||
test "a post stands where it was put, is not counted, and turns back when nobody is near" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
fk_setup(base_st, npc_st, npc_tests_fake_st)
|
||||
test "a post stands where it was put, is not counted, and turns back when nobody is near" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
fk_setup(npc_st, npc_tests_fake_st)
|
||||
let v = npc_place(npc_st, NPCK_VENDOR, 0.0, 0.0, 0.0, "Mateo", 5)
|
||||
expect(v.fixed)
|
||||
expect_eq(npc_count(npc_st), 0)
|
||||
fk_player_at(npc_tests_fake_st, 8.0, 0.0)
|
||||
fk_run(base_st, npc_st, 3.0)
|
||||
fk_run(npc_st, 3.0)
|
||||
expect(Math.abs(npc_wrap(v.yaw + 1.5707963)) < 0.05)
|
||||
fk_player_at(npc_tests_fake_st, 300.0, 0.0)
|
||||
fk_run(base_st, npc_st, 3.0)
|
||||
fk_run(npc_st, 3.0)
|
||||
expect(Math.abs(v.yaw) < 0.05)
|
||||
expect(npc_d(v.x, v.z, 0.0, 0.0) < 0.001)
|
||||
expect(npc_by_id(npc_st, v.id).name == "Mateo")
|
||||
}
|
||||
|
||||
test "a guest's copy: the host's slot put, heard and eased toward, and not drawn once it goes quiet" (base_st: mut BaseState, npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
fk_setup(base_st, npc_st, npc_tests_fake_st)
|
||||
test "a guest's copy: the host's slot put, heard and eased toward, and not drawn once it goes quiet" (npc_st: mut NpcState, npc_tests_fake_st: mut NpcTestsFakeState) {
|
||||
fk_setup(npc_st, npc_tests_fake_st)
|
||||
npc_tests_fake_st.fk_want = 2
|
||||
npc_tick(base_st, npc_st, 0.05)
|
||||
npc_tick(npc_st, 0.05)
|
||||
npc_mirror(npc_st, true)
|
||||
expect_eq(npc_count(npc_st), 0)
|
||||
let p = npc_put(npc_st, 3, 99, NPCK_HIKER, 12, 1.5, "Wren", 10.0, 10.0)
|
||||
|
|
@ -224,7 +224,7 @@ program NpcTest {
|
|||
for k in 0 .. 40 { npc_mirror_tick(npc_st, 0.05) }
|
||||
expect_near(p.x, 12.0, 0.01)
|
||||
expect(p.phase > 0.0)
|
||||
npc_tick(base_st, npc_st, 0.05)
|
||||
npc_tick(npc_st, 0.05)
|
||||
expect_near(p.x, 12.0, 0.01)
|
||||
for k in 0 .. 140 { npc_mirror_tick(npc_st, 0.05) }
|
||||
expect(not npc_heard_lately(npc_st, p))
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
# 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(base_st: mut BaseState, npc_st: mut NpcState, dt: float) -> void {
|
||||
export function npc_tick(npc_st: mut NpcState, dt: float) -> void {
|
||||
np_ensure(npc_st)
|
||||
for i in 0 .. len(npc_st.np_posts) { if npc_st.np_posts[i].active { np_step_post(base_st, npc_st, npc_st.np_posts[i], dt) } }
|
||||
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)
|
||||
for i in 0 .. len(npc_st.np_walkers) {
|
||||
let p = npc_st.np_walkers[i]
|
||||
if not p.active or np_leaves(npc_st, p) { continue }
|
||||
if p.act == NPCA_WALK { npc_walk(base_st, npc_st, p, dt) } else { npc_act(npc_st, p, dt) }
|
||||
npc_notice(base_st, npc_st, p)
|
||||
if p.act == NPCA_WALK { npc_walk(npc_st, p, dt) } else { npc_act(npc_st, p, dt) }
|
||||
npc_notice(npc_st, p)
|
||||
}
|
||||
}
|
||||
|
||||
# the posts alone: a machine that does not run the place still turns its vendors to whoever comes
|
||||
export function npc_posts_tick(base_st: mut BaseState, npc_st: mut NpcState, dt: float) -> void {
|
||||
export function npc_posts_tick(npc_st: mut NpcState, dt: float) -> void {
|
||||
np_ensure(npc_st)
|
||||
for i in 0 .. len(npc_st.np_posts) { if npc_st.np_posts[i].active { np_step_post(base_st, npc_st, npc_st.np_posts[i], dt) } }
|
||||
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) } }
|
||||
}
|
||||
|
||||
function np_step_post(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPerson, dt: float) -> void {
|
||||
function np_step_post(npc_st: mut NpcState, p: NpcPerson, dt: float) -> void {
|
||||
npc_act(npc_st, p, dt)
|
||||
npc_notice(base_st, npc_st, p)
|
||||
npc_notice(npc_st, p)
|
||||
}
|
||||
|
||||
# counted, not tallied, so it cannot drift; the census fills to what the place wants from the kinds
|
||||
|
|
@ -81,14 +81,14 @@ export function npc_census_now(npc_st: mut NpcState) -> void { npc_st.np_next_h
|
|||
export function npc_hold(npc_st: mut NpcState, on: bool) -> void { npc_st.np_hold = on }
|
||||
|
||||
# everyone gone, as a new trip starts; the posts are the place's and stay
|
||||
export function npc_reset(base_st: mut BaseState, npc_st: mut NpcState) -> void {
|
||||
export function npc_reset(npc_st: mut NpcState) -> void {
|
||||
np_ensure(npc_st)
|
||||
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
|
||||
npc_st.np_hold = false
|
||||
npc_st.np_recent = new []string
|
||||
q_clear(base_st, npc_facts(base_st, npc_st))
|
||||
q_clear(npc_facts(npc_st))
|
||||
}
|
||||
|
||||
# forgotten altogether, walkers and posts (the place itself was replaced)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 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
|
||||
export function npc_walk(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPerson, dt: float) -> void {
|
||||
export function npc_walk(npc_st: mut NpcState, p: NpcPerson, dt: float) -> void {
|
||||
var gx = p.tx
|
||||
var gz = p.tz
|
||||
if p.via_on {
|
||||
|
|
@ -10,7 +10,7 @@ export function npc_walk(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPer
|
|||
let dx = gx - p.x
|
||||
let dz = gz - p.z
|
||||
if Math.sqrt(dx * dx + dz * dz) < 1.2 {
|
||||
np_arrive(base_st, npc_st, p)
|
||||
np_arrive(npc_st, p)
|
||||
return
|
||||
}
|
||||
let dg = npc_d(p.x, p.z, p.tx, p.tz)
|
||||
|
|
@ -50,7 +50,7 @@ export function npc_walk(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPer
|
|||
}
|
||||
|
||||
# there: a step round something ends, or the errand begins, facing what it came for
|
||||
function np_arrive(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPerson) -> void {
|
||||
function np_arrive(npc_st: mut NpcState, p: NpcPerson) -> void {
|
||||
if p.via_on {
|
||||
p.via_on = false
|
||||
return
|
||||
|
|
@ -61,7 +61,7 @@ function np_arrive(base_st: mut BaseState, npc_st: mut NpcState, p: NpcPerson) -
|
|||
p.fx = fx
|
||||
p.fz = fz
|
||||
p.stall = 0.0
|
||||
if p.act != NPCA_WALK { np_fact(base_st, npc_st, NPC_F_ARRIVED, p, -1) }
|
||||
if p.act != NPCA_WALK { np_fact(npc_st, NPC_F_ARRIVED, p, -1) }
|
||||
}
|
||||
|
||||
function np_detour(p: NpcPerson, want: float) -> bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue