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
|
|
@ -42,7 +42,7 @@ function wl_come_down(a: WildAnimal, x: float, z: float) -> void {
|
|||
}
|
||||
|
||||
# a circle about home, climbing to its height: the eagle wide and high, the jay low
|
||||
function wl_circle(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> void {
|
||||
function wl_circle(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> void {
|
||||
let s = wl_sp(wildlife_st, a.sp)
|
||||
a.fly_h = a.fly_h + (8.0 + s.home * 0.12 - a.fly_h) * Math.min(1.0, 0.4 * dt)
|
||||
let r = s.home * 0.5
|
||||
|
|
@ -57,13 +57,13 @@ function wl_circle(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) ->
|
|||
a.bank = 0.35
|
||||
}
|
||||
|
||||
function wl_take_off(wildlife_st: mut WildlifeState, a: WildAnimal, h: float) -> void {
|
||||
function wl_take_off(wildlife_st: WildlifeState, a: WildAnimal, h: float) -> void {
|
||||
a.state = WILD_FLY
|
||||
a.timer = 20.0 + wl_rnd(wildlife_st) * 40.0
|
||||
a.fly_h = Math.max(a.fly_h, h)
|
||||
}
|
||||
|
||||
function wl_land(wildlife_st: mut WildlifeState, a: WildAnimal, dh: float, dt: float) -> void {
|
||||
function wl_land(wildlife_st: WildlifeState, a: WildAnimal, dh: float, dt: float) -> void {
|
||||
let s = wl_sp(wildlife_st, a.sp)
|
||||
a.fly_h = Math.max(0.0, a.fly_h - dt * 3.2)
|
||||
a.speed = s.walk * 0.8
|
||||
|
|
@ -84,7 +84,7 @@ function wl_land(wildlife_st: mut WildlifeState, a: WildAnimal, dh: float, dt: f
|
|||
}
|
||||
|
||||
# on the ground it pecks at seed or takes a drink at the water's edge; it leaves no droppings
|
||||
function wl_perch(wildlife_st: mut WildlifeState, a: WildAnimal, dh: float, dt: float) -> void {
|
||||
function wl_perch(wildlife_st: WildlifeState, a: WildAnimal, dh: float, dt: float) -> void {
|
||||
a.speed = 0.0
|
||||
a.y = WildlifeWorld.ground(a.x, a.z)
|
||||
a.bank = 0.0
|
||||
|
|
|
|||
|
|
@ -28,12 +28,11 @@ export property WildFact {
|
|||
}
|
||||
|
||||
|
||||
export function wildlife_facts(wildlife_st: mut WildlifeState) -> Queue<WildFact> {
|
||||
if wildlife_st.wl_facts == null { wildlife_st.wl_facts = queue_new("wildlife.facts") }
|
||||
export function wildlife_facts(wildlife_st: WildlifeState) -> Queue<WildFact> {
|
||||
return wildlife_st.wl_facts
|
||||
}
|
||||
|
||||
function wl_fact(wildlife_st: mut WildlifeState, what: int, a: WildAnimal) -> WildFact {
|
||||
function wl_fact(wildlife_st: WildlifeState, what: int, a: WildAnimal) -> WildFact {
|
||||
let f = new WildFact
|
||||
f.what = what
|
||||
f.key = a.key
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export function wildlife_tick_ground(wildlife_st: mut WildlifeState, a: WildAnim
|
|||
}
|
||||
|
||||
# a charger close enough comes at the nearest player; true while it is charging
|
||||
function wl_charge(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dh: float, dt: float) -> bool {
|
||||
function wl_charge(wildlife_st: WildlifeState, a: WildAnimal, np: int, dh: float, dt: float) -> bool {
|
||||
let s = wl_sp(wildlife_st, a.sp)
|
||||
if s.charges and a.state != WILD_CHARGE and dh < WildlifeWorld.charge_reach() and not (a.calm > 0.0) {
|
||||
a.state = WILD_CHARGE
|
||||
|
|
@ -63,7 +63,7 @@ function wl_charge(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dh: f
|
|||
|
||||
# Four postures read off the alert. Staring is a REACTION, not a condition: each times out and
|
||||
# hands the animal back to its business, and only a fresh rise above `seen` looks up again.
|
||||
function wl_posture(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dt: float) -> void {
|
||||
function wl_posture(wildlife_st: WildlifeState, a: WildAnimal, np: int, dt: float) -> void {
|
||||
if wl_sp(wildlife_st, a.sp).tame or a.state == WILD_EAT { return }
|
||||
if a.alert > 95.0 {
|
||||
if a.state != WILD_FLEE {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
# lures.ludic - what an animal would walk to: food of its diet, a lure of its diet, a snare it is
|
||||
# small enough for (half the time: a curiosity), within 70 m - 175 m for food while feeding is taught
|
||||
|
||||
function wl_lure_scratch(wildlife_st: mut WildlifeState) -> void {
|
||||
if wildlife_st.wl_ask == null { wildlife_st.wl_ask = new WildLure }
|
||||
if wildlife_st.wl_best == null { wildlife_st.wl_best = new WildLure }
|
||||
function wl_lure_scratch() -> void {
|
||||
}
|
||||
|
||||
function wl_copy_lure(from: WildLure, to: WildLure) -> void {
|
||||
|
|
@ -16,15 +14,15 @@ function wl_copy_lure(from: WildLure, to: WildLure) -> void {
|
|||
to.owner = from.owner
|
||||
}
|
||||
|
||||
function wl_draws(wildlife_st: mut WildlifeState, a: WildAnimal, l: WildLure) -> bool {
|
||||
function wl_draws(wildlife_st: WildlifeState, a: WildAnimal, l: WildLure) -> bool {
|
||||
let s = wl_sp(wildlife_st, a.sp)
|
||||
if l.kind == WILD_SNARE { return s.size <= l.size and wl_rnd(wildlife_st) > 0.5 }
|
||||
return l.diet == s.diet and l.diet != WILD_SEED
|
||||
}
|
||||
|
||||
# the nearest thing set out that draws it, into `wl_best`; false when none does
|
||||
function wl_attraction(wildlife_st: mut WildlifeState, a: WildAnimal) -> bool {
|
||||
wl_lure_scratch(wildlife_st)
|
||||
function wl_attraction(wildlife_st: WildlifeState, a: WildAnimal) -> bool {
|
||||
wl_lure_scratch()
|
||||
var bd = 70.0
|
||||
var got = false
|
||||
let taught = WildlifeWorld.taught()
|
||||
|
|
@ -58,7 +56,7 @@ function wl_seed_scan(wildlife_st: mut WildlifeState, dt: float) -> void {
|
|||
if wildlife_st.wl_seed_t > 0.0 { return }
|
||||
wildlife_st.wl_seed_t = 1.0
|
||||
wildlife_st.wl_seed_any = false
|
||||
wl_lure_scratch(wildlife_st)
|
||||
wl_lure_scratch()
|
||||
for i in 0 .. WildlifeWorld.lures() {
|
||||
if WildlifeWorld.lure(i, wildlife_st.wl_ask) and wildlife_st.wl_ask.kind == WILD_FEED and wildlife_st.wl_ask.diet == WILD_SEED {
|
||||
wildlife_st.wl_seed_any = true
|
||||
|
|
@ -68,9 +66,9 @@ function wl_seed_scan(wildlife_st: mut WildlifeState, dt: float) -> void {
|
|||
}
|
||||
|
||||
# the nearest seed within 120 m, into `wl_best`: the one thing that brings an animal TO you
|
||||
function wl_bird_seed(wildlife_st: mut WildlifeState, a: WildAnimal) -> bool {
|
||||
function wl_bird_seed(wildlife_st: WildlifeState, a: WildAnimal) -> bool {
|
||||
if not wildlife_st.wl_seed_any { return false }
|
||||
wl_lure_scratch(wildlife_st)
|
||||
wl_lure_scratch()
|
||||
var bd = 120.0
|
||||
var got = false
|
||||
for i in 0 .. WildlifeWorld.lures() {
|
||||
|
|
@ -88,7 +86,7 @@ function wl_bird_seed(wildlife_st: mut WildlifeState, a: WildAnimal) -> bool {
|
|||
}
|
||||
|
||||
# it ate what was set out: calm for three game hours, and the game credits whoever left it
|
||||
function wl_ate(wildlife_st: mut WildlifeState, a: WildAnimal, uid: int, owner: int, diet: int) -> void {
|
||||
function wl_ate(wildlife_st: WildlifeState, a: WildAnimal, uid: int, owner: int, diet: int) -> void {
|
||||
a.calm = 180.0
|
||||
a.fed += 1
|
||||
let f = wl_fact(wildlife_st, WILD_FED, a)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# migrate.ludic - each morning the ranges slide toward where the season wants them, and the animals
|
||||
# that live in them are dragged along rather than teleported; an animal keeps inside its own
|
||||
export function wildlife_ranges_migrate(wildlife_st: mut WildlifeState) -> void {
|
||||
export function wildlife_ranges_migrate(wildlife_st: WildlifeState) -> void {
|
||||
let rs = wildlife_ranges(wildlife_st)
|
||||
let w = WildlifeWorld.winterness()
|
||||
for i in 0 .. len(rs) {
|
||||
|
|
@ -24,7 +24,7 @@ export function wildlife_ranges_migrate(wildlife_st: mut WildlifeState) -> void
|
|||
}
|
||||
|
||||
# its home kept inside its range
|
||||
function wl_clamp(wildlife_st: mut WildlifeState, a: WildAnimal) -> void {
|
||||
function wl_clamp(wildlife_st: WildlifeState, a: WildAnimal) -> void {
|
||||
let r = wildlife_range(wildlife_st, a.rg)
|
||||
if r == null { return }
|
||||
let d = wildlife_range_dist(r, a.home_x, a.home_z)
|
||||
|
|
@ -34,7 +34,7 @@ function wl_clamp(wildlife_st: mut WildlifeState, a: WildAnimal) -> void {
|
|||
}
|
||||
|
||||
# how many live in range `i`, legends apart
|
||||
export function wildlife_range_alive(wildlife_st: mut WildlifeState, i: int) -> int {
|
||||
export function wildlife_range_alive(wildlife_st: WildlifeState, i: int) -> int {
|
||||
var n = 0
|
||||
let all = wildlife_all(wildlife_st)
|
||||
for k in 0 .. len(all) { if all[k].alive and not all[k].legend and all[k].rg == i { n += 1 } }
|
||||
|
|
@ -42,7 +42,7 @@ export function wildlife_range_alive(wildlife_st: mut WildlifeState, i: int) ->
|
|||
}
|
||||
|
||||
# how many are alive in the whole valley, legends apart
|
||||
export function wildlife_total(wildlife_st: mut WildlifeState) -> int {
|
||||
export function wildlife_total(wildlife_st: WildlifeState) -> int {
|
||||
var n = 0
|
||||
let all = wildlife_all(wildlife_st)
|
||||
for k in 0 .. len(all) { if all[k].alive and not all[k].legend { n += 1 } }
|
||||
|
|
@ -50,7 +50,7 @@ export function wildlife_total(wildlife_st: mut WildlifeState) -> int {
|
|||
}
|
||||
|
||||
# the nearest range of `sp` a player has found, to (x, z), or -1
|
||||
export function wildlife_range_found_near(wildlife_st: mut WildlifeState, sp: int, x: float, z: float) -> int {
|
||||
export function wildlife_range_found_near(wildlife_st: WildlifeState, sp: int, x: float, z: float) -> int {
|
||||
var best = -1
|
||||
var bd = 99999.0
|
||||
let rs = wildlife_ranges(wildlife_st)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
# ranges.ludic - a species keeps to discs placed once, against the ground, 120-700 m out from where
|
||||
# the valley starts; each winters lower, toward the timber, as far down as it summered high
|
||||
|
||||
export function wildlife_ranges(wildlife_st: mut WildlifeState) -> []WildRange {
|
||||
if wildlife_st.wl_ranges == null { wildlife_st.wl_ranges = new []WildRange }
|
||||
export function wildlife_ranges(wildlife_st: WildlifeState) -> []WildRange {
|
||||
return wildlife_st.wl_ranges
|
||||
}
|
||||
|
||||
export function wildlife_range(wildlife_st: mut WildlifeState, i: int) -> WildRange {
|
||||
export function wildlife_range(wildlife_st: WildlifeState, i: int) -> WildRange {
|
||||
if i < 0 or i >= len(wildlife_ranges(wildlife_st)) { return null }
|
||||
return wildlife_ranges(wildlife_st)[i]
|
||||
}
|
||||
|
|
@ -17,7 +16,7 @@ export function wildlife_range_dist(r: WildRange, x: float, z: float) -> float {
|
|||
return Math.sqrt(dx * dx + dz * dz)
|
||||
}
|
||||
|
||||
function wl_range_clashes(wildlife_st: mut WildlifeState, sp: int, x: float, z: float) -> bool {
|
||||
function wl_range_clashes(wildlife_st: WildlifeState, sp: int, x: float, z: float) -> bool {
|
||||
let rs = wildlife_ranges(wildlife_st)
|
||||
for j in 0 .. len(rs) { if rs[j].sp == sp and wildlife_range_dist(rs[j], x, z) < wl_sp(wildlife_st, sp).range * 1.6 { return true } }
|
||||
return false
|
||||
|
|
@ -83,12 +82,12 @@ function wl_pick_winter(r: WildRange) -> void {
|
|||
}
|
||||
|
||||
# a player stood at (x, z): any range they are inside is found
|
||||
export function wildlife_ranges_visit(wildlife_st: mut WildlifeState, x: float, z: float) -> void {
|
||||
export function wildlife_ranges_visit(wildlife_st: WildlifeState, x: float, z: float) -> void {
|
||||
let rs = wildlife_ranges(wildlife_st)
|
||||
for i in 0 .. len(rs) { if not rs[i].found and wildlife_range_dist(rs[i], x, z) < rs[i].r { rs[i].found = true } }
|
||||
}
|
||||
|
||||
function wl_found_apply(wildlife_st: mut WildlifeState) -> void {
|
||||
function wl_found_apply(wildlife_st: WildlifeState) -> void {
|
||||
if wildlife_st.wl_found == null { return }
|
||||
let rs = wildlife_ranges(wildlife_st)
|
||||
for i in 0 .. len(rs) { if i < len(wildlife_st.wl_found) { rs[i].found = wildlife_st.wl_found[i] != 0 } }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# react.ludic - alert (it stops and looks: the window the camera wants), wary (it puts ground between
|
||||
# you without running) and fleeing; true when it is doing one of them, which is all it does this tick
|
||||
function wl_react(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dt: float) -> bool {
|
||||
function wl_react(wildlife_st: WildlifeState, a: WildAnimal, np: int, dt: float) -> bool {
|
||||
let s = wl_sp(wildlife_st, a.sp)
|
||||
if a.state == WILD_ALERT {
|
||||
a.speed = 0.0
|
||||
|
|
@ -29,7 +29,7 @@ function wl_react(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dt: fl
|
|||
}
|
||||
|
||||
# walking to (or reached) something set out; true while it is
|
||||
function wl_approach(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bool {
|
||||
function wl_approach(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> bool {
|
||||
if (a.state == WILD_IDLE or a.state == WILD_WANDER) and wl_attraction(wildlife_st, a) { wl_take_lure(wildlife_st, a) }
|
||||
if a.state != WILD_APPROACH { return false }
|
||||
if a.lure == 0 or not WildlifeWorld.present(a.lure) {
|
||||
|
|
@ -52,7 +52,7 @@ function wl_approach(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -
|
|||
}
|
||||
|
||||
# at a snare it is held; at food it eats for 14 s; at a lure it stands curious for 9
|
||||
function wl_arrive(wildlife_st: mut WildlifeState, a: WildAnimal) -> void {
|
||||
function wl_arrive(wildlife_st: WildlifeState, a: WildAnimal) -> void {
|
||||
a.state = WILD_EAT
|
||||
a.timer = 9.0
|
||||
if a.lure_kind == WILD_FEED { a.timer = 14.0 }
|
||||
|
|
@ -67,7 +67,7 @@ function wl_arrive(wildlife_st: mut WildlifeState, a: WildAnimal) -> void {
|
|||
}
|
||||
|
||||
# eating what it came to; when it is done, food is credited and it wanders off
|
||||
function wl_eat(wildlife_st: mut WildlifeState, a: WildAnimal) -> bool {
|
||||
function wl_eat(wildlife_st: WildlifeState, a: WildAnimal) -> bool {
|
||||
if a.state != WILD_EAT { return false }
|
||||
a.speed = 0.0
|
||||
if a.timer < 0.0 {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ function wl_tick_one(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float, g
|
|||
}
|
||||
|
||||
# the gait advanced by a copy the game moves itself (a guest's copy of the host's animal)
|
||||
export function wildlife_stride(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> void {
|
||||
export function wildlife_stride(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> void {
|
||||
var stride = 1.2 * a.scale
|
||||
if wl_sp(wildlife_st, a.sp).flies { stride = 0.6 }
|
||||
a.phase = (a.phase + a.speed * dt / stride * WL_TAU) % WL_TAU
|
||||
|
|
@ -48,7 +48,7 @@ export function wildlife_release(a: WildAnimal) -> void {
|
|||
}
|
||||
|
||||
# the animal a snare holds, by the snare's uid
|
||||
export function wildlife_in_snare(wildlife_st: mut WildlifeState, uid: int) -> WildAnimal {
|
||||
export function wildlife_in_snare(wildlife_st: WildlifeState, uid: int) -> WildAnimal {
|
||||
let all = wildlife_all(wildlife_st)
|
||||
for i in 0 .. len(all) {
|
||||
let a = all[i]
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ function wl_near_sq(d: float, reach: float) -> float {
|
|||
}
|
||||
|
||||
# alert points a second from player p at `dh` metres; 0 when nothing of them reaches it
|
||||
export function wildlife_alert_rate(wildlife_st: mut WildlifeState, a: WildAnimal, p: int, dh: float) -> float {
|
||||
export function wildlife_alert_rate(wildlife_st: WildlifeState, a: WildAnimal, p: int, dh: float) -> float {
|
||||
let s = wl_sp(wildlife_st, a.sp)
|
||||
if s.tame or a.calm > 0.0 { return 0.0 }
|
||||
if (a.state == WILD_APPROACH or a.state == WILD_EAT) and a.lure != 0 and a.lure_kind == WILD_FEED and dh > 5.0 and WildlifeWorld.taught() { return 0.0 }
|
||||
|
|
@ -65,7 +65,7 @@ export function wildlife_alert_rate(wildlife_st: mut WildlifeState, a: WildAnima
|
|||
}
|
||||
|
||||
# how fast it forgets player p: standing still buys it, sitting down buys more
|
||||
export function wildlife_alert_decay(wildlife_st: mut WildlifeState, a: WildAnimal, p: int) -> float {
|
||||
export function wildlife_alert_decay(wildlife_st: WildlifeState, a: WildAnimal, p: int) -> float {
|
||||
var d = wl_sp(wildlife_st, a.sp).forget
|
||||
let still = WildlifeWorld.stillness(p)
|
||||
if still == WILD_SITTING { d = d * 2.5 } else if still == WILD_STILL { d = d * 1.6 }
|
||||
|
|
@ -74,7 +74,7 @@ export function wildlife_alert_decay(wildlife_st: mut WildlifeState, a: WildAnim
|
|||
}
|
||||
|
||||
# the alert rises and falls with the player who nets it the most, and it watches them
|
||||
function wl_alert(wildlife_st: mut WildlifeState, a: WildAnimal, np: int, dh: float, dt: float) -> void {
|
||||
function wl_alert(wildlife_st: WildlifeState, a: WildAnimal, np: int, dh: float, dt: float) -> void {
|
||||
var rise = wildlife_alert_rate(wildlife_st, a, np, dh)
|
||||
var fall = wildlife_alert_decay(wildlife_st, a, np)
|
||||
var who = np
|
||||
|
|
|
|||
|
|
@ -33,47 +33,47 @@ export property WildSpecies {
|
|||
}
|
||||
|
||||
export state WildlifeState {
|
||||
wl_facts: Queue<WildFact> = null
|
||||
wl_facts: Queue<WildFact> = wl_facts__new()
|
||||
wl_own: []WildAnimal = null
|
||||
wl_px: float = 0.0
|
||||
wl_pz: float = 0.0
|
||||
wl_ask: WildLure = null
|
||||
wl_best: WildLure = null
|
||||
wl_ask: WildLure = new WildLure
|
||||
wl_best: WildLure = new WildLure
|
||||
wl_seed_any: bool = false
|
||||
wl_seed_t: float = 0.0
|
||||
wl_ids: int = 0
|
||||
wl_ranges: []WildRange = null
|
||||
wl_ranges: []WildRange = new []WildRange
|
||||
wl_found: []int = null # found flags a load brought before the ranges were set out
|
||||
wl_seen: int = 0
|
||||
wl_fed: int = 0
|
||||
wl_fed_any: bool = false
|
||||
wl_near_i: int = 0
|
||||
wl_species: []WildSpecies = null
|
||||
wl_list: []WildAnimal = null
|
||||
wl_species: []WildSpecies = new []WildSpecies
|
||||
wl_list: []WildAnimal = new []WildAnimal
|
||||
wl_keys: int = 0
|
||||
wl_dice: Rng = null
|
||||
wl_dice: Rng = rng_new(97)
|
||||
wl_hold: bool = false # staged: nobody thinks, everybody keeps their speed
|
||||
wl_spot_ask: WildSpot = null
|
||||
wl_spot_ask: WildSpot = new WildSpot
|
||||
}
|
||||
|
||||
function wl_sp_all(wildlife_st: mut WildlifeState) -> []WildSpecies {
|
||||
if wildlife_st.wl_species == null { wildlife_st.wl_species = new []WildSpecies }
|
||||
function wl_sp_all(wildlife_st: WildlifeState) -> []WildSpecies {
|
||||
return wildlife_st.wl_species
|
||||
}
|
||||
|
||||
export function wildlife_species_clear(wildlife_st: mut WildlifeState) -> void { wildlife_st.wl_species = new []WildSpecies }
|
||||
|
||||
# the next species; returns its number
|
||||
export function wildlife_species_add(wildlife_st: mut WildlifeState, s: WildSpecies) -> int {
|
||||
export function wildlife_species_add(wildlife_st: WildlifeState, s: WildSpecies) -> int {
|
||||
push(wl_sp_all(wildlife_st), s)
|
||||
return len(wl_sp_all(wildlife_st)) - 1
|
||||
}
|
||||
|
||||
export function wildlife_species_count(wildlife_st: mut WildlifeState) -> int { return len(wl_sp_all(wildlife_st)) }
|
||||
export function wildlife_species_count(wildlife_st: WildlifeState) -> int { return len(wl_sp_all(wildlife_st)) }
|
||||
|
||||
export function wildlife_species(wildlife_st: mut WildlifeState, sp: int) -> WildSpecies {
|
||||
export function wildlife_species(wildlife_st: WildlifeState, sp: int) -> WildSpecies {
|
||||
if sp < 0 or sp >= len(wl_sp_all(wildlife_st)) { return null }
|
||||
return wl_sp_all(wildlife_st)[sp]
|
||||
}
|
||||
|
||||
function wl_sp(wildlife_st: mut WildlifeState, sp: int) -> WildSpecies { return wl_sp_all(wildlife_st)[sp] }
|
||||
function wl_sp(wildlife_st: WildlifeState, sp: int) -> WildSpecies { return wl_sp_all(wildlife_st)[sp] }
|
||||
function wl_facts__new() -> Queue<WildFact> { return queue_new("wildlife.facts") }
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ function wl_face(a: WildAnimal, tx: float, tz: float, rate: float, dt: float) ->
|
|||
}
|
||||
|
||||
# true when it moved
|
||||
function wl_step(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bool {
|
||||
function wl_step(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> bool {
|
||||
let d = a.speed * dt
|
||||
if d < 0.0001 { return false }
|
||||
let nx = a.x - Math.sin(a.yaw) * d
|
||||
|
|
@ -36,7 +36,7 @@ function wl_step(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bo
|
|||
return true
|
||||
}
|
||||
|
||||
function wl_pick_target(wildlife_st: mut WildlifeState, a: WildAnimal, radius: float) -> void {
|
||||
function wl_pick_target(wildlife_st: WildlifeState, a: WildAnimal, radius: float) -> void {
|
||||
let ang = wl_rnd(wildlife_st) * WL_TAU
|
||||
let d = wl_rnd(wildlife_st) * radius
|
||||
a.tx = a.home_x + Math.cos(ang) * d
|
||||
|
|
@ -50,14 +50,14 @@ function wl_at_target(a: WildAnimal, r: float) -> bool {
|
|||
}
|
||||
|
||||
# back to wandering about home after `t` seconds of whatever it was doing
|
||||
function wl_wander(wildlife_st: mut WildlifeState, a: WildAnimal, t: float) -> void {
|
||||
function wl_wander(wildlife_st: WildlifeState, a: WildAnimal, t: float) -> void {
|
||||
a.state = WILD_WANDER
|
||||
a.timer = t
|
||||
wl_pick_target(wildlife_st, a, wl_sp(wildlife_st, a.sp).home)
|
||||
}
|
||||
|
||||
# home where it stands now, kept inside its range
|
||||
function wl_rehome(wildlife_st: mut WildlifeState, a: WildAnimal) -> void {
|
||||
function wl_rehome(wildlife_st: WildlifeState, a: WildAnimal) -> void {
|
||||
a.home_x = a.x
|
||||
a.home_z = a.z
|
||||
wl_clamp(wildlife_st, a)
|
||||
|
|
|
|||
|
|
@ -1,25 +1,23 @@
|
|||
# store.ludic - the animals, their own dice, and the verbs that make and take one away
|
||||
const WL_TAU: float = 6.2831853
|
||||
|
||||
export function wildlife_all(wildlife_st: mut WildlifeState) -> []WildAnimal {
|
||||
if wildlife_st.wl_list == null { wildlife_st.wl_list = new []WildAnimal }
|
||||
export function wildlife_all(wildlife_st: WildlifeState) -> []WildAnimal {
|
||||
return wildlife_st.wl_list
|
||||
}
|
||||
|
||||
export function wildlife_count_all(wildlife_st: mut WildlifeState) -> int { return len(wildlife_all(wildlife_st)) }
|
||||
export function wildlife_count_all(wildlife_st: WildlifeState) -> int { return len(wildlife_all(wildlife_st)) }
|
||||
|
||||
# a new valley: every animal forgotten, quietly (the game has already let its drawings go)
|
||||
export function wildlife_clear(wildlife_st: mut WildlifeState) -> void { wildlife_st.wl_list = new []WildAnimal }
|
||||
|
||||
function wl_rng(wildlife_st: mut WildlifeState) -> Rng {
|
||||
if wildlife_st.wl_dice == null { wildlife_st.wl_dice = rng_new(97) }
|
||||
function wl_rng(wildlife_st: WildlifeState) -> Rng {
|
||||
return wildlife_st.wl_dice
|
||||
}
|
||||
|
||||
function wl_rnd(wildlife_st: mut WildlifeState) -> float { return rng_float(wl_rng(wildlife_st)) }
|
||||
function wl_rnd(wildlife_st: WildlifeState) -> float { return rng_float(wl_rng(wildlife_st)) }
|
||||
|
||||
# the package's dice from a known place (a spawn, a test)
|
||||
export function wildlife_seed(wildlife_st: mut WildlifeState, seed: int) -> void { rng_seed(wl_rng(wildlife_st), seed) }
|
||||
export function wildlife_seed(wildlife_st: WildlifeState, seed: int) -> void { rng_seed(wl_rng(wildlife_st), seed) }
|
||||
|
||||
# an individual exactly as given: the host's own, or the host's on a guest
|
||||
export function wildlife_make(wildlife_st: mut WildlifeState, sp: int, x: float, z: float, legend: bool, yaw: float, variant: int, scale: float, nid: int) -> WildAnimal {
|
||||
|
|
@ -76,14 +74,14 @@ export function wildlife_remove(a: WildAnimal) -> void {
|
|||
# staged for a picture: nobody thinks, and everybody keeps the speed they were given
|
||||
export function wildlife_hold(wildlife_st: mut WildlifeState, on: bool) -> void { wildlife_st.wl_hold = on }
|
||||
|
||||
export function wildlife_by_nid(wildlife_st: mut WildlifeState, nid: int) -> WildAnimal {
|
||||
export function wildlife_by_nid(wildlife_st: WildlifeState, nid: int) -> WildAnimal {
|
||||
let all = wildlife_all(wildlife_st)
|
||||
for i in 0 .. len(all) { if all[i].nid == nid { return all[i] } }
|
||||
return null
|
||||
}
|
||||
|
||||
# how many of a species are alive, legends apart
|
||||
export function wildlife_count(wildlife_st: mut WildlifeState, sp: int) -> int {
|
||||
export function wildlife_count(wildlife_st: WildlifeState, sp: int) -> int {
|
||||
var n = 0
|
||||
let all = wildlife_all(wildlife_st)
|
||||
for i in 0 .. len(all) { if all[i].alive and all[i].sp == sp and not all[i].legend { n += 1 } }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export function wildlife_reset(wildlife_st: mut WildlifeState) -> void {
|
|||
q_clear(wildlife_facts(wildlife_st))
|
||||
}
|
||||
|
||||
export function wildlife_save(wildlife_st: mut WildlifeState) -> Val {
|
||||
export function wildlife_save(wildlife_st: WildlifeState) -> Val {
|
||||
let v = Value.object()
|
||||
sv_put_int(v, "seen", wildlife_st.wl_seen)
|
||||
sv_put_int(v, "fed", wildlife_st.wl_fed)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ function fk_setup(wildlife_st: mut WildlifeState, wildlife_tests_fake_st: mut Wi
|
|||
}
|
||||
|
||||
# 0 deer (meadow, tracks, medium), 1 bear (forest, charges), 2 hare (small), 3 jay (flies)
|
||||
function fk_species(wildlife_st: mut WildlifeState) -> void {
|
||||
function fk_species(wildlife_st: WildlifeState) -> void {
|
||||
let d = new WildSpecies
|
||||
d.key = "deer"
|
||||
d.walk = 1.1
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ program LuresTest {
|
|||
spot: fn fk_spot
|
||||
}
|
||||
|
||||
function facts(wildlife_st: mut WildlifeState) -> []WildFact { return q_drain(wildlife_facts(wildlife_st)) }
|
||||
function facts(wildlife_st: WildlifeState) -> []WildFact { return q_drain(wildlife_facts(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
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ program WildlifeTest {
|
|||
spot: fn fk_spot
|
||||
}
|
||||
|
||||
function facts(wildlife_st: mut WildlifeState) -> []WildFact { return q_drain(wildlife_facts(wildlife_st)) }
|
||||
function facts(wildlife_st: WildlifeState) -> []WildFact { return q_drain(wildlife_facts(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 } }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# want.ludic - thirst and hunger over sixty send it to the water or the forage the game offers for
|
||||
# it (a hungry one on its way turns to food put down nearer); it drinks or grazes there
|
||||
|
||||
function wl_seek(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bool {
|
||||
function wl_seek(wildlife_st: WildlifeState, a: WildAnimal, dt: float) -> bool {
|
||||
if a.state == WILD_GO_FEED and wl_attraction(wildlife_st, a) and wildlife_st.wl_best.kind == WILD_FEED { wl_take_lure(wildlife_st, a) }
|
||||
if a.state != WILD_GO_DRINK and a.state != WILD_GO_FEED { return false }
|
||||
if a.spot == 0 or not WildlifeWorld.present(a.spot) {
|
||||
|
|
@ -28,7 +28,7 @@ function wl_seek(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float) -> bo
|
|||
}
|
||||
|
||||
# true while it drinks or grazes, or when it has just set off
|
||||
function wl_drink(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float, gh: float) -> bool {
|
||||
function wl_drink(wildlife_st: WildlifeState, a: WildAnimal, dt: float, gh: float) -> bool {
|
||||
if a.state == WILD_DRINK {
|
||||
a.speed = 0.0
|
||||
a.timer = a.timer - dt
|
||||
|
|
@ -41,7 +41,6 @@ function wl_drink(wildlife_st: mut WildlifeState, a: WildAnimal, dt: float, gh:
|
|||
}
|
||||
if a.state != WILD_IDLE and a.state != WILD_WANDER { return false }
|
||||
if not (a.thirst > 60.0 or a.hunger > 60.0) { return false }
|
||||
if wildlife_st.wl_spot_ask == null { wildlife_st.wl_spot_ask = new WildSpot }
|
||||
let water = a.thirst > a.hunger
|
||||
if not WildlifeWorld.spot(a, water, wildlife_st.wl_spot_ask) { return false }
|
||||
a.spot = wildlife_st.wl_spot_ask.uid
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue