feat(packages): ludic.wildlife - a valley's animals: species handed in as data, ranges placed against the ground and moved with the season, the day's steering, the senses and a net alert that settles, feeding, lures and snares, birds, spawning and repopulation, its own dice, facts and a save section
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
80f3468ff8
commit
c9dc592dcc
28 changed files with 1956 additions and 0 deletions
66
packages/ludic.wildlife/migrate.ludic
Normal file
66
packages/ludic.wildlife/migrate.ludic
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# 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() -> void {
|
||||
let rs = wildlife_ranges()
|
||||
let w = WildlifeWorld.winterness()
|
||||
for i in 0 .. len(rs) {
|
||||
rs[i].x = Math.lerp(rs[i].sx, rs[i].wx, w)
|
||||
rs[i].z = Math.lerp(rs[i].sz, rs[i].wz, w)
|
||||
}
|
||||
let all = wildlife_all()
|
||||
for i in 0 .. len(all) {
|
||||
let a = all[i]
|
||||
let r = wildlife_range(a.rg)
|
||||
if r == null { continue }
|
||||
wl_clamp(a)
|
||||
if wildlife_range_dist(r, a.home_x, a.home_z) > r.r * 1.2 {
|
||||
a.home_x = r.x
|
||||
a.home_z = r.z
|
||||
a.x = r.x
|
||||
a.z = r.z
|
||||
a.y = WildlifeWorld.ground(a.x, a.z)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# its home kept inside its range
|
||||
function wl_clamp(a: WildAnimal) -> void {
|
||||
let r = wildlife_range(a.rg)
|
||||
if r == null { return }
|
||||
let d = wildlife_range_dist(r, a.home_x, a.home_z)
|
||||
if d < r.r { return }
|
||||
a.home_x = r.x + (a.home_x - r.x) / d * (r.r * 0.9)
|
||||
a.home_z = r.z + (a.home_z - r.z) / d * (r.r * 0.9)
|
||||
}
|
||||
|
||||
# how many live in range `i`, legends apart
|
||||
export function wildlife_range_alive(i: int) -> int {
|
||||
var n = 0
|
||||
let all = wildlife_all()
|
||||
for k in 0 .. len(all) { if all[k].alive and not all[k].legend and all[k].rg == i { n += 1 } }
|
||||
return n
|
||||
}
|
||||
|
||||
# how many are alive in the whole valley, legends apart
|
||||
export function wildlife_total() -> int {
|
||||
var n = 0
|
||||
let all = wildlife_all()
|
||||
for k in 0 .. len(all) { if all[k].alive and not all[k].legend { n += 1 } }
|
||||
return n
|
||||
}
|
||||
|
||||
# the nearest range of `sp` a player has found, to (x, z), or -1
|
||||
export function wildlife_range_found_near(sp: int, x: float, z: float) -> int {
|
||||
var best = -1
|
||||
var bd = 99999.0
|
||||
let rs = wildlife_ranges()
|
||||
for i in 0 .. len(rs) {
|
||||
if rs[i].sp != sp or not rs[i].found { continue }
|
||||
let d = wildlife_range_dist(rs[i], x, z)
|
||||
if d < bd {
|
||||
bd = d
|
||||
best = i
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue