# 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() -> void { } function wl_copy_lure(from: WildLure, to: WildLure) -> void { to.uid = from.uid to.kind = from.kind to.diet = from.diet to.size = from.size to.x = from.x to.z = from.z to.owner = from.owner } 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: WildlifeState, a: WildAnimal) -> bool { wl_lure_scratch() var bd = 70.0 var got = false let taught = WildlifeWorld.taught() for i in 0 .. WildlifeWorld.lures() { if not WildlifeWorld.lure(i, wildlife_st.wl_ask) or not wl_draws(wildlife_st, a, wildlife_st.wl_ask) { continue } let dx = wildlife_st.wl_ask.x - a.x let dz = wildlife_st.wl_ask.z - a.z var d = Math.sqrt(dx * dx + dz * dz) if taught and wildlife_st.wl_ask.kind == WILD_FEED { d = d * 0.4 } if d < bd { bd = d got = true wl_copy_lure(wildlife_st.wl_ask, wildlife_st.wl_best) } } return got } function wl_take_lure(wildlife_st: WildlifeState, a: WildAnimal) -> void { a.lure = wildlife_st.wl_best.uid a.lure_kind = wildlife_st.wl_best.kind a.lure_x = wildlife_st.wl_best.x a.lure_z = wildlife_st.wl_best.z a.lure_owner = wildlife_st.wl_best.owner a.state = WILD_APPROACH } # Is there ANY seed down? Asked once a second for the whole flock rather than per bird per tick. function wl_seed_scan(wildlife_st: mut WildlifeState, dt: float) -> void { wildlife_st.wl_seed_t = wildlife_st.wl_seed_t - dt 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() 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 return } } } # the nearest seed within 120 m, into `wl_best`: the one thing that brings an animal TO you function wl_bird_seed(wildlife_st: WildlifeState, a: WildAnimal) -> bool { if not wildlife_st.wl_seed_any { return false } wl_lure_scratch() var bd = 120.0 var got = false for i in 0 .. WildlifeWorld.lures() { if not WildlifeWorld.lure(i, wildlife_st.wl_ask) or wildlife_st.wl_ask.kind != WILD_FEED or wildlife_st.wl_ask.diet != WILD_SEED { continue } let dx = wildlife_st.wl_ask.x - a.x let dz = wildlife_st.wl_ask.z - a.z let d = Math.sqrt(dx * dx + dz * dz) if d < bd { bd = d got = true wl_copy_lure(wildlife_st.wl_ask, wildlife_st.wl_best) } } return got } # 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 { a.calm = 180.0 a.fed += 1 let f = wl_fact(wildlife_st, WILD_FED, a) f.lure = uid f.owner = owner f.diet = diet }