# 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 } } }