71 lines
2.8 KiB
Text
71 lines
2.8 KiB
Text
# 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: WildlifeState) -> []WildRange {
|
|
return wildlife_st.wl_ranges
|
|
}
|
|
|
|
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]
|
|
}
|
|
|
|
export function wildlife_range_dist(r: WildRange, x: float, z: float) -> float {
|
|
let dx = r.x - x
|
|
let dz = r.z - z
|
|
return Math.sqrt(dx * dx + dz * dz)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
function wl_range_try(wildlife_st: mut WildlifeState, sp: int, x0: float, z0: float) -> bool {
|
|
let s = wl_sp(wildlife_st, sp)
|
|
for tries in 0 .. 80 {
|
|
if not wildlife_find_spot_of(wildlife_st, sp, s.habitat, x0, z0, 120.0, 700.0) { continue }
|
|
let dx = wildlife_st.wl_px - x0
|
|
let dz = wildlife_st.wl_pz - z0
|
|
if Math.sqrt(dx * dx + dz * dz) < s.keep_away or wl_range_clashes(wildlife_st, sp, wildlife_st.wl_px, wildlife_st.wl_pz) { continue }
|
|
let r = new WildRange
|
|
r.sp = sp
|
|
r.x = wildlife_st.wl_px
|
|
r.z = wildlife_st.wl_pz
|
|
r.r = s.range
|
|
r.sx = wildlife_st.wl_px
|
|
r.sz = wildlife_st.wl_pz
|
|
wl_pick_winter(r)
|
|
push(wildlife_ranges(wildlife_st), r)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
# every species' ranges about (x0, z0), then the game told of each (WildlifeWorld.placed)
|
|
export function wildlife_ranges_setup(wildlife_st: mut WildlifeState, x0: float, z0: float) -> void {
|
|
wildlife_seed(wildlife_st, 613)
|
|
wildlife_st.wl_ranges = new []WildRange
|
|
for sp in 0 .. wildlife_species_count(wildlife_st) {
|
|
for k in 0 .. WildlifeWorld.ranges(sp) {
|
|
if wl_range_painted(wildlife_st, sp, k) { continue }
|
|
if not wl_range_try(wildlife_st, sp, x0, z0) { break }
|
|
}
|
|
}
|
|
wl_found_apply(wildlife_st)
|
|
let rs = wildlife_ranges(wildlife_st)
|
|
for i in 0 .. len(rs) { WildlifeWorld.placed(rs[i], i) }
|
|
}
|
|
|
|
# a player stood at (x, z): any range they are inside is found
|
|
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: 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 } }
|
|
}
|