wip(0.S3): packages and examples migrated again from their pre-0.S sources in one run

ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic
  1804 vars into 126 states, 64 into lets; 23498 edits in 460 files

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-25 15:31:34 +03:00
parent 5ffe50ed02
commit 19fcf60599
459 changed files with 17862 additions and 17603 deletions

View file

@ -1,37 +1,39 @@
# fake.ludic - a toy valley for the tests: flat ground at 10 m with a lake west of x = -300 (its
# surface at 10.5), forest north of z = 400, up to two players, and a table of things set out
var fk_px: []float = null
var fk_pz: []float = null
var fk_on: []bool = null
var fk_noise: float = 0.0
var fk_scent: float = 0.0
var fk_still: int = 0
var fk_hidden: bool = false
var fk_blocked: bool = false
var fk_wind: float = 0.0
var fk_wind_dir: float = 0.0
var fk_winter: float = 0.0
var fk_about: int = 0
var fk_born: int = 0
var fk_lures: []WildLure = null
var fk_gone: int = 0 # a uid the port says is no longer there
export state WildlifeTestsFakeState {
fk_px: []float = null
fk_pz: []float = null
fk_on: []bool = null
fk_noise: float = 0.0
fk_scent: float = 0.0
fk_still: int = 0
fk_hidden: bool = false
fk_blocked: bool = false
fk_wind: float = 0.0
fk_wind_dir: float = 0.0
fk_winter: float = 0.0
fk_about: int = 0
fk_born: int = 0
fk_lures: []WildLure = null
fk_gone: int = 0 # a uid the port says is no longer there
}
function fk_setup() -> void {
fk_px = floats(2)
fk_pz = floats(2)
fk_on = new []bool
push(fk_on, true)
push(fk_on, false)
fk_px[0] = 5000.0
fk_pz[0] = 5000.0
fk_lures = new []WildLure
wildlife_clear()
wildlife_species_clear()
fk_species()
function fk_setup(wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) -> void {
wildlife_tests_fake_st.fk_px = floats(2)
wildlife_tests_fake_st.fk_pz = floats(2)
wildlife_tests_fake_st.fk_on = new []bool
push(wildlife_tests_fake_st.fk_on, true)
push(wildlife_tests_fake_st.fk_on, false)
wildlife_tests_fake_st.fk_px[0] = 5000.0
wildlife_tests_fake_st.fk_pz[0] = 5000.0
wildlife_tests_fake_st.fk_lures = new []WildLure
wildlife_clear(wildlife_st)
wildlife_species_clear(wildlife_st)
fk_species(wildlife_st)
}
# 0 deer (meadow, tracks, medium), 1 bear (forest, charges), 2 hare (small), 3 jay (flies)
function fk_species() -> void {
function fk_species(wildlife_st: mut WildlifeState) -> void {
let d = new WildSpecies
d.key = "deer"
d.walk = 1.1
@ -41,7 +43,7 @@ function fk_species() -> void {
d.size = 1
d.range = 150.0
d.keep_away = 120.0
wildlife_species_add(d)
wildlife_species_add(wildlife_st, d)
let b = new WildSpecies
b.key = "bear"
b.habitat = WILD_FOREST
@ -50,10 +52,10 @@ function fk_species() -> void {
b.diet = WILD_FISH
b.forget = 1.6
b.run = 6.0
wildlife_species_add(b)
wildlife_species_add(wildlife_st, b)
let h = new WildSpecies
h.key = "hare"
wildlife_species_add(h)
wildlife_species_add(wildlife_st, h)
let j = new WildSpecies
j.key = "jay"
j.flies = true
@ -61,7 +63,7 @@ function fk_species() -> void {
j.flee = 8.0
j.land_shy = 0.0
j.land_chance = 1.0
wildlife_species_add(j)
wildlife_species_add(wildlife_st, j)
}
function fk_ground(x: float, z: float) -> float { return 10.0 }
@ -70,24 +72,24 @@ function fk_water(x: float, z: float) -> float {
return 0.0
}
function fk_forest(x: float, z: float) -> bool { return z > 400.0 }
function fk_sight(ax: float, ay: float, az: float, bx: float, by: float, bz: float) -> bool { return not fk_blocked }
function fk_sight(wildlife_tests_fake_st: WildlifeTestsFakeState, ax: float, ay: float, az: float, bx: float, by: float, bz: float) -> bool { return not wildlife_tests_fake_st.fk_blocked }
function fk_players() -> int { return 2 }
function fk_player_on(p: int) -> bool { return fk_on[p] }
function fk_x(p: int) -> float { return fk_px[p] }
function fk_player_on(wildlife_tests_fake_st: WildlifeTestsFakeState, p: int) -> bool { return wildlife_tests_fake_st.fk_on[p] }
function fk_x(wildlife_tests_fake_st: WildlifeTestsFakeState, p: int) -> float { return wildlife_tests_fake_st.fk_px[p] }
function fk_y(p: int) -> float { return 10.0 }
function fk_z(p: int) -> float { return fk_pz[p] }
function fk_is_hidden(p: int) -> bool { return fk_hidden }
function fk_noise_of(p: int) -> float { return fk_noise }
function fk_scent_of(p: int) -> float { return fk_scent }
function fk_still_of(p: int) -> int { return fk_still }
function fk_wind_of() -> float { return fk_wind }
function fk_wind_to() -> float { return fk_wind_dir }
function fk_winter_of() -> float { return fk_winter }
function fk_about_of(a: WildAnimal) -> int { return fk_about }
function fk_z(wildlife_tests_fake_st: WildlifeTestsFakeState, p: int) -> float { return wildlife_tests_fake_st.fk_pz[p] }
function fk_is_hidden(wildlife_tests_fake_st: WildlifeTestsFakeState, p: int) -> bool { return wildlife_tests_fake_st.fk_hidden }
function fk_noise_of(wildlife_tests_fake_st: WildlifeTestsFakeState, p: int) -> float { return wildlife_tests_fake_st.fk_noise }
function fk_scent_of(wildlife_tests_fake_st: WildlifeTestsFakeState, p: int) -> float { return wildlife_tests_fake_st.fk_scent }
function fk_still_of(wildlife_tests_fake_st: WildlifeTestsFakeState, p: int) -> int { return wildlife_tests_fake_st.fk_still }
function fk_wind_of(wildlife_tests_fake_st: WildlifeTestsFakeState) -> float { return wildlife_tests_fake_st.fk_wind }
function fk_wind_to(wildlife_tests_fake_st: WildlifeTestsFakeState) -> float { return wildlife_tests_fake_st.fk_wind_dir }
function fk_winter_of(wildlife_tests_fake_st: WildlifeTestsFakeState) -> float { return wildlife_tests_fake_st.fk_winter }
function fk_about_of(wildlife_tests_fake_st: WildlifeTestsFakeState, a: WildAnimal) -> int { return wildlife_tests_fake_st.fk_about }
function fk_one(sp: int) -> int { return 1 }
function fk_count() -> int { return len(fk_lures) }
function fk_lure(i: int, l: WildLure) -> bool {
let f = fk_lures[i]
function fk_count(wildlife_tests_fake_st: WildlifeTestsFakeState) -> int { return len(wildlife_tests_fake_st.fk_lures) }
function fk_lure(wildlife_tests_fake_st: WildlifeTestsFakeState, i: int, l: WildLure) -> bool {
let f = wildlife_tests_fake_st.fk_lures[i]
l.uid = f.uid
l.kind = f.kind
l.diet = f.diet
@ -95,10 +97,10 @@ function fk_lure(i: int, l: WildLure) -> bool {
l.x = f.x
l.z = f.z
l.owner = f.owner
return f.uid != fk_gone
return f.uid != wildlife_tests_fake_st.fk_gone
}
function fk_present(uid: int) -> bool { return uid != fk_gone }
function fk_on_born(a: WildAnimal) -> void { fk_born += 1 }
function fk_present(wildlife_tests_fake_st: WildlifeTestsFakeState, uid: int) -> bool { return uid != wildlife_tests_fake_st.fk_gone }
function fk_on_born(wildlife_tests_fake_st: mut WildlifeTestsFakeState, a: WildAnimal) -> void { wildlife_tests_fake_st.fk_born += 1 }
function fk_spot(a: WildAnimal, water: bool, s: WildSpot) -> bool {
s.uid = 900
s.x = a.x + 30.0

View file

@ -19,8 +19,8 @@ program LuresTest {
spot: fn fk_spot
}
function facts() -> []WildFact { return q_drain(wildlife_facts()) }
function set_out(uid: int, kind: int, diet: int, x: float, z: float, owner: int) -> WildLure {
function facts(base_st: mut BaseState, wildlife_st: mut WildlifeState) -> []WildFact { return q_drain(base_st, wildlife_facts(base_st, wildlife_st)) }
function set_out(wildlife_tests_fake_st: mut WildlifeTestsFakeState, uid: int, kind: int, diet: int, x: float, z: float, owner: int) -> WildLure {
let l = new WildLure
l.uid = uid
l.kind = kind
@ -28,24 +28,24 @@ program LuresTest {
l.x = x
l.z = z
l.owner = owner
push(fk_lures, l)
push(wildlife_tests_fake_st.fk_lures, l)
return l
}
function idle(sp: int, x: float, z: float) -> WildAnimal {
let a = wildlife_make(sp, x, z, false, 0.0, 0, 1.0, 7)
function idle(wildlife_st: mut WildlifeState, sp: int, x: float, z: float) -> WildAnimal {
let a = wildlife_make(wildlife_st, sp, x, z, false, 0.0, 0, 1.0, 7)
a.timer = 30.0
return a
}
function go(a: WildAnimal, secs: float) -> void {
for k in 0 .. int(secs * 20.0) { wildlife_tick_ground(a, 0.05, 0.05 / 60.0) }
function go(base_st: mut BaseState, wildlife_st: mut WildlifeState, a: WildAnimal, secs: float) -> void {
for k in 0 .. int(secs * 20.0) { wildlife_tick_ground(base_st, wildlife_st, a, 0.05, 0.05 / 60.0) }
}
test "food of its diet draws it in, it eats, and the fact names what and whose" {
fk_setup()
set_out(41, WILD_FEED, WILD_PLANTS, 20.0, 0.0, 3)
let a = idle(0, 0.0, 0.0)
go(a, 40.0)
let fs = facts()
test "food of its diet draws it in, it eats, and the fact names what and whose" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
set_out(wildlife_tests_fake_st, 41, WILD_FEED, WILD_PLANTS, 20.0, 0.0, 3)
let a = idle(wildlife_st, 0, 0.0, 0.0)
go(base_st, wildlife_st, a, 40.0)
let fs = facts(base_st, wildlife_st)
var fed = 0
for i in 0 .. len(fs) {
if fs[i].what == WILD_FED {
@ -58,70 +58,70 @@ program LuresTest {
expect(a.calm > 0.0)
}
test "food of another diet is left alone" {
fk_setup()
set_out(41, WILD_FEED, WILD_FISH, 20.0, 0.0, -1)
let a = idle(0, 0.0, 0.0)
go(a, 5.0)
test "food of another diet is left alone" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
set_out(wildlife_tests_fake_st, 41, WILD_FEED, WILD_FISH, 20.0, 0.0, -1)
let a = idle(wildlife_st, 0, 0.0, 0.0)
go(base_st, wildlife_st, a, 5.0)
expect(a.state != WILD_APPROACH)
expect_eq(a.lure, 0)
}
test "food taken away while it walks is given up" {
fk_setup()
set_out(41, WILD_FEED, WILD_PLANTS, 50.0, 0.0, -1)
let a = idle(0, 0.0, 0.0)
go(a, 1.0)
test "food taken away while it walks is given up" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
set_out(wildlife_tests_fake_st, 41, WILD_FEED, WILD_PLANTS, 50.0, 0.0, -1)
let a = idle(wildlife_st, 0, 0.0, 0.0)
go(base_st, wildlife_st, a, 1.0)
expect_eq(a.state, WILD_APPROACH)
fk_gone = 41
go(a, 0.2)
wildlife_tests_fake_st.fk_gone = 41
go(base_st, wildlife_st, a, 0.2)
expect(a.state != WILD_APPROACH)
}
test "a snare holds a small animal, the port can find it, and a release lets it go" {
fk_setup()
let l = set_out(55, WILD_SNARE, 0, 10.0, 0.0, -1)
test "a snare holds a small animal, the port can find it, and a release lets it go" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let l = set_out(wildlife_tests_fake_st, 55, WILD_SNARE, 0, 10.0, 0.0, -1)
l.size = 0
let h = idle(2, 0.0, 0.0)
let h = idle(wildlife_st, 2, 0.0, 0.0)
for k in 0 .. 40 {
if h.state == WILD_TRAPPED { break }
go(h, 2.0)
go(base_st, wildlife_st, h, 2.0)
}
expect_eq(h.state, WILD_TRAPPED)
expect(wildlife_in_snare(55) == h)
let fs = facts()
expect(wildlife_in_snare(wildlife_st, 55) == h)
let fs = facts(base_st, wildlife_st)
var held = false
for i in 0 .. len(fs) { if fs[i].what == WILD_CAUGHT and fs[i].lure == 55 { held = true } }
expect(held)
wildlife_release(h)
expect_eq(h.state, WILD_FLEE)
expect(wildlife_in_snare(55) == null)
expect(wildlife_in_snare(wildlife_st, 55) == null)
}
test "a thirsty animal walks to the water the port offers, and drinks it down" {
fk_setup()
let a = idle(0, 0.0, 0.0)
test "a thirsty animal walks to the water the port offers, and drinks it down" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let a = idle(wildlife_st, 0, 0.0, 0.0)
a.thirst = 90.0
a.state = WILD_WANDER
go(a, 0.1)
go(base_st, wildlife_st, a, 0.1)
expect_eq(a.state, WILD_GO_DRINK)
expect_eq(a.spot, 900)
go(a, 40.0)
go(base_st, wildlife_st, a, 40.0)
expect(a.thirst < 60.0)
}
test "seed down brings a bird out of the sky and it takes it" {
fk_setup()
set_out(77, WILD_FEED, WILD_SEED, 30.0, 0.0, -1)
let j = wildlife_new(3, 0.0, 0.0, false)
fk_px[0] = 200.0 # within 900 m: an animal nobody is near does not think
fk_pz[0] = 0.0
test "seed down brings a bird out of the sky and it takes it" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
set_out(wildlife_tests_fake_st, 77, WILD_FEED, WILD_SEED, 30.0, 0.0, -1)
let j = wildlife_new(wildlife_st, 3, 0.0, 0.0, false)
wildlife_tests_fake_st.fk_px[0] = 200.0 # within 900 m: an animal nobody is near does not think
wildlife_tests_fake_st.fk_pz[0] = 0.0
var landed = false
var ate = false
for k in 0 .. 4000 {
wildlife_tick(0.05, 0.0)
wildlife_tick(base_st, wildlife_st, 0.05, 0.0)
if j.state == WILD_PERCH { landed = true }
let fs = facts()
let fs = facts(base_st, wildlife_st)
for i in 0 .. len(fs) { if fs[i].what == WILD_FED and fs[i].diet == WILD_SEED { ate = true } }
if ate { break }
}

View file

@ -31,180 +31,180 @@ program WildlifeTest {
spot: fn fk_spot
}
function facts() -> []WildFact { return q_drain(wildlife_facts()) }
function facts(base_st: mut BaseState, wildlife_st: mut WildlifeState) -> []WildFact { return q_drain(base_st, wildlife_facts(base_st, wildlife_st)) }
function count(fs: []WildFact, what: int) -> int {
var n = 0
for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } }
return n
}
function deer_at(x: float, z: float) -> WildAnimal {
let a = wildlife_make(0, x, z, false, 0.0, 0, 1.0, 1)
function deer_at(wildlife_st: mut WildlifeState, x: float, z: float) -> WildAnimal {
let a = wildlife_make(wildlife_st, 0, x, z, false, 0.0, 0, 1.0, 1)
a.state = WILD_IDLE
a.timer = 30.0
return a
}
function player_at(x: float, z: float) -> void {
fk_px[0] = x
fk_pz[0] = z
function player_at(wildlife_tests_fake_st: mut WildlifeTestsFakeState, x: float, z: float) -> void {
wildlife_tests_fake_st.fk_px[0] = x
wildlife_tests_fake_st.fk_pz[0] = z
}
function go(a: WildAnimal, secs: float) -> void {
for k in 0 .. int(secs * 20.0) { wildlife_tick_ground(a, 0.05, 0.05 / 60.0) }
function go(base_st: mut BaseState, wildlife_st: mut WildlifeState, a: WildAnimal, secs: float) -> void {
for k in 0 .. int(secs * 20.0) { wildlife_tick_ground(base_st, wildlife_st, a, 0.05, 0.05 / 60.0) }
}
test "the table handed in numbers the species, and a new animal is born through the port" {
fk_setup()
expect_eq(wildlife_species_count(), 4)
expect(wildlife_species(3).flies)
let a = wildlife_new(0, 10.0, 20.0, false)
expect_eq(fk_born, 1)
test "the table handed in numbers the species, and a new animal is born through the port" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
expect_eq(wildlife_species_count(wildlife_st), 4)
expect(wildlife_species(wildlife_st, 3).flies)
let a = wildlife_new(wildlife_st, 0, 10.0, 20.0, false)
expect_eq(wildlife_tests_fake_st.fk_born, 1)
expect_near(a.y, 10.0, 0.001)
expect(a.variant >= 0 and a.variant <= 11)
expect(a.scale > 0.87 and a.scale < 1.13)
let j = wildlife_new(3, 0.0, 0.0, false)
let j = wildlife_new(wildlife_st, 3, 0.0, 0.0, false)
expect_eq(j.state, WILD_FLY)
expect(wildlife_new(9, 0.0, 0.0, false) == null)
expect(wildlife_new(wildlife_st, 9, 0.0, 0.0, false) == null)
}
test "a spawn sets ranges out on their own habitat, clear of the start, and fills them" {
fk_setup()
wildlife_spawn(0.0, 0.0)
let rs = wildlife_ranges()
test "a spawn sets ranges out on their own habitat, clear of the start, and fills them" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
wildlife_spawn(wildlife_st, 0.0, 0.0)
let rs = wildlife_ranges(wildlife_st)
expect(len(rs) >= 6)
for i in 0 .. len(rs) {
expect(wildlife_range_dist(rs[i], 0.0, 0.0) >= wildlife_species(rs[i].sp).keep_away)
expect(wildlife_range_dist(rs[i], 0.0, 0.0) >= wildlife_species(wildlife_st, rs[i].sp).keep_away)
if rs[i].sp == 1 { expect(rs[i].z > 400.0) }
expect(rs[i].sx > -300.0)
}
expect(wildlife_count(0) >= 1)
expect_eq(wildlife_count_all(), wildlife_count(0) + wildlife_count(1) + wildlife_count(2) + wildlife_count(3))
expect(wildlife_count(wildlife_st, 0) >= 1)
expect_eq(wildlife_count_all(wildlife_st), wildlife_count(wildlife_st, 0) + wildlife_count(wildlife_st, 1) + wildlife_count(wildlife_st, 2) + wildlife_count(wildlife_st, 3))
}
test "a player far off makes no difference that lasts: the alert settles under the unaware line" {
fk_setup()
let a = deer_at(0.0, 0.0)
player_at(55.0, 0.0)
fk_noise = 0.3
go(a, 60.0)
test "a player far off makes no difference that lasts: the alert settles under the unaware line" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let a = deer_at(wildlife_st, 0.0, 0.0)
player_at(wildlife_tests_fake_st, 55.0, 0.0)
wildlife_tests_fake_st.fk_noise = 0.3
go(base_st, wildlife_st, a, 60.0)
expect(a.alert < 25.0)
expect(a.state != WILD_FLEE)
}
test "close and in the open it is flushed, runs, and says so" {
fk_setup()
let a = deer_at(0.0, 0.0)
player_at(8.0, 0.0)
fk_noise = 0.8
go(a, 10.0)
test "close and in the open it is flushed, runs, and says so" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let a = deer_at(wildlife_st, 0.0, 0.0)
player_at(wildlife_tests_fake_st, 8.0, 0.0)
wildlife_tests_fake_st.fk_noise = 0.8
go(base_st, wildlife_st, a, 10.0)
expect(a.spook > 0.0)
let fs = facts()
let fs = facts(base_st, wildlife_st)
expect(count(fs, WILD_FLED) >= 1)
expect(a.x < 0.0)
}
test "cover hides a player from sight, a hide from everything but the nose" {
fk_setup()
let a = deer_at(0.0, 0.0)
let open = wildlife_alert_rate(a, 0, 30.0)
player_at(30.0, 0.0)
let open2 = wildlife_alert_rate(a, 0, 30.0)
fk_blocked = true
let covered = wildlife_alert_rate(a, 0, 30.0)
fk_blocked = false
fk_hidden = true
let hidden = wildlife_alert_rate(a, 0, 30.0)
test "cover hides a player from sight, a hide from everything but the nose" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let a = deer_at(wildlife_st, 0.0, 0.0)
let open = wildlife_alert_rate(wildlife_st, a, 0, 30.0)
player_at(wildlife_tests_fake_st, 30.0, 0.0)
let open2 = wildlife_alert_rate(wildlife_st, a, 0, 30.0)
wildlife_tests_fake_st.fk_blocked = true
let covered = wildlife_alert_rate(wildlife_st, a, 0, 30.0)
wildlife_tests_fake_st.fk_blocked = false
wildlife_tests_fake_st.fk_hidden = true
let hidden = wildlife_alert_rate(wildlife_st, a, 0, 30.0)
expect(open2 > 0.0)
expect(open >= open2)
expect_near(covered, 0.0, 0.0001)
expect_near(hidden, 0.0, 0.0001)
}
test "sitting still makes it forget faster, and the wind carries scent only downwind" {
fk_setup()
let a = deer_at(0.0, 0.0)
let moving = wildlife_alert_decay(a, 0)
fk_still = WILD_SITTING
expect(wildlife_alert_decay(a, 0) > moving * 2.0)
player_at(0.0, -60.0)
fk_blocked = true
fk_scent = 1.0
fk_wind = 0.5
fk_wind_dir = 3.1415927 # blowing toward +z: from the player to the deer
test "sitting still makes it forget faster, and the wind carries scent only downwind" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let a = deer_at(wildlife_st, 0.0, 0.0)
let moving = wildlife_alert_decay(wildlife_st, a, 0)
wildlife_tests_fake_st.fk_still = WILD_SITTING
expect(wildlife_alert_decay(wildlife_st, a, 0) > moving * 2.0)
player_at(wildlife_tests_fake_st, 0.0, -60.0)
wildlife_tests_fake_st.fk_blocked = true
wildlife_tests_fake_st.fk_scent = 1.0
wildlife_tests_fake_st.fk_wind = 0.5
wildlife_tests_fake_st.fk_wind_dir = 3.1415927 # blowing toward +z: from the player to the deer
expect(wildlife_downwind(a, 0) > 0.9)
expect(wildlife_alert_rate(a, 0, 60.0) > 0.0)
fk_wind_dir = 0.0
expect_near(wildlife_alert_rate(a, 0, 60.0), 0.0, 0.0001)
expect(wildlife_alert_rate(wildlife_st, a, 0, 60.0) > 0.0)
wildlife_tests_fake_st.fk_wind_dir = 0.0
expect_near(wildlife_alert_rate(wildlife_st, a, 0, 60.0), 0.0, 0.0001)
}
test "a charger comes at a player inside its reach, and a shove is a fact for the game" {
fk_setup()
let b = wildlife_make(1, 0.0, 0.0, false, 0.0, 0, 1.0, 2)
player_at(6.0, 0.0)
wildlife_tick_ground(b, 0.05, 0.001)
test "a charger comes at a player inside its reach, and a shove is a fact for the game" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let b = wildlife_make(wildlife_st, 1, 0.0, 0.0, false, 0.0, 0, 1.0, 2)
player_at(wildlife_tests_fake_st, 6.0, 0.0)
wildlife_tick_ground(base_st, wildlife_st, b, 0.05, 0.001)
expect_eq(b.state, WILD_CHARGE)
go(b, 2.0)
let fs = facts()
go(base_st, wildlife_st, b, 2.0)
let fs = facts(base_st, wildlife_st)
expect_eq(count(fs, WILD_CHARGED), 1)
expect_eq(count(fs, WILD_SHOVED), 1)
expect(b.calm > 0.0)
}
test "away is hidden and skipped, gone is removed and said" {
fk_setup()
let a = deer_at(0.0, 0.0)
player_at(10.0, 0.0)
fk_about = WILD_AWAY
wildlife_tick(0.05, 0.001)
test "away is hidden and skipped, gone is removed and said" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let a = deer_at(wildlife_st, 0.0, 0.0)
player_at(wildlife_tests_fake_st, 10.0, 0.0)
wildlife_tests_fake_st.fk_about = WILD_AWAY
wildlife_tick(base_st, wildlife_st, 0.05, 0.001)
expect(not a.shown and a.alive)
fk_about = WILD_GONE
wildlife_tick(0.05, 0.001)
wildlife_tests_fake_st.fk_about = WILD_GONE
wildlife_tick(base_st, wildlife_st, 0.05, 0.001)
expect(not a.alive)
expect_eq(count(facts(), WILD_WENT), 1)
expect_eq(count(facts(base_st, wildlife_st), WILD_WENT), 1)
}
test "a walker leaves a print every 2.8 m, and player 0 spots a species once" {
fk_setup()
let a = deer_at(0.0, 0.0)
player_at(40.0, 0.0)
fk_blocked = true
test "a walker leaves a print every 2.8 m, and player 0 spots a species once" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
let a = deer_at(wildlife_st, 0.0, 0.0)
player_at(wildlife_tests_fake_st, 40.0, 0.0)
wildlife_tests_fake_st.fk_blocked = true
a.state = WILD_WANDER
a.tx = 0.0
a.tz = -100.0
a.timer = 100.0
for k in 0 .. 200 { wildlife_tick(0.05, 0.0) }
let fs = facts()
for k in 0 .. 200 { wildlife_tick(base_st, wildlife_st, 0.05, 0.0) }
let fs = facts(base_st, wildlife_st)
expect(count(fs, WILD_PRINT) >= 3)
expect_eq(count(fs, WILD_SPOTTED), 1)
expect(wildlife_seen(0))
expect(wildlife_seen(wildlife_st, 0))
}
test "the record and the found ranges come back from the save section" {
fk_setup()
wildlife_spawn(0.0, 0.0)
wildlife_mark_fed(2)
wildlife_saw(0)
let r = wildlife_ranges()[0]
wildlife_ranges_visit(r.x, r.z)
let v = wildlife_save()
wildlife_reset()
expect(not wildlife_fed_any() and not wildlife_ranges()[0].found)
wildlife_load(v, 1)
expect(wildlife_fed_any())
expect_eq(wildlife_fed_mask(), 4)
expect(wildlife_seen(0))
expect(wildlife_ranges()[0].found)
test "the record and the found ranges come back from the save section" (base_st: mut BaseState, wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
wildlife_spawn(wildlife_st, 0.0, 0.0)
wildlife_mark_fed(wildlife_st, 2)
wildlife_saw(wildlife_st, 0)
let r = wildlife_ranges(wildlife_st)[0]
wildlife_ranges_visit(wildlife_st, r.x, r.z)
let v = wildlife_save(wildlife_st)
wildlife_reset(base_st, wildlife_st)
expect(not wildlife_fed_any(wildlife_st) and not wildlife_ranges(wildlife_st)[0].found)
wildlife_load(base_st, wildlife_st, v, 1)
expect(wildlife_fed_any(wildlife_st))
expect_eq(wildlife_fed_mask(wildlife_st), 4)
expect(wildlife_seen(wildlife_st, 0))
expect(wildlife_ranges(wildlife_st)[0].found)
}
test "a morning moves the ranges toward winter and brings one back to a range that lost its own" {
fk_setup()
wildlife_spawn(0.0, 0.0)
let r = wildlife_ranges()[0]
test "a morning moves the ranges toward winter and brings one back to a range that lost its own" (wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut WildlifeTestsFakeState) {
fk_setup(wildlife_st, wildlife_tests_fake_st)
wildlife_spawn(wildlife_st, 0.0, 0.0)
let r = wildlife_ranges(wildlife_st)[0]
let x0 = r.x
let all = wildlife_all()
let all = wildlife_all(wildlife_st)
for i in 0 .. len(all) { if all[i].rg == 0 { wildlife_remove(all[i]) } }
fk_winter = 1.0
let added = wildlife_morning()
wildlife_tests_fake_st.fk_winter = 1.0
let added = wildlife_morning(wildlife_st)
expect(added >= 1)
expect_eq(wildlife_range_alive(0), 1)
expect_eq(wildlife_range_alive(wildlife_st, 0), 1)
expect_near(r.x, r.wx, 0.001)
expect(r.x != x0 or r.wx == r.sx)
}