diff --git a/rtsim/src/data/npc.rs b/rtsim/src/data/npc.rs index bb68a6c742..6c0c26e6f1 100644 --- a/rtsim/src/data/npc.rs +++ b/rtsim/src/data/npc.rs @@ -3,7 +3,7 @@ pub use common::rtsim::{NpcId, Profession}; use common::{ comp, grid::Grid, - rtsim::{FactionId, SiteId, VehicleId, Personality}, + rtsim::{FactionId, Personality, SiteId, VehicleId}, store::Id, vol::RectVolSize, }; diff --git a/rtsim/src/gen/mod.rs b/rtsim/src/gen/mod.rs index 8bc2677125..bbe7d43d6c 100644 --- a/rtsim/src/gen/mod.rs +++ b/rtsim/src/gen/mod.rs @@ -11,7 +11,7 @@ use common::{ comp::{self, Body}, grid::Grid, resources::TimeOfDay, - rtsim::{WorldSettings, Personality}, + rtsim::{Personality, WorldSettings}, terrain::TerrainChunkSize, vol::RectVolSize, }; diff --git a/rtsim/src/rule/npc_ai.rs b/rtsim/src/rule/npc_ai.rs index bb87d3b028..1e0977b681 100644 --- a/rtsim/src/rule/npc_ai.rs +++ b/rtsim/src/rule/npc_ai.rs @@ -350,7 +350,7 @@ fn goto_2d(wpos2d: Vec2, speed_factor: f32, goal_dist: f32) -> impl Action }) } -fn traverse_points(mut next_point: F) -> impl Action<()> +fn traverse_points(mut next_point: F) -> impl Action where F: FnMut(&mut NpcCtx) -> Option> + Send + Sync + 'static, { @@ -397,7 +397,11 @@ fn travel_to_point(wpos: Vec2) -> impl Action { let diff = wpos - start; let n = (diff.magnitude() / WAYPOINT).max(1.0); let mut points = (1..n as usize + 1).map(move |i| start + diff * (i as f32 / n)); - traverse_points(move |_| points.next()) + if diff.magnitude() > 1.0 { + traverse_points(move |_| points.next()).boxed() + } else { + finish().boxed() + } }) .debug(|| "travel to point") } @@ -538,7 +542,17 @@ fn adventure() -> impl Action { fn villager(visiting_site: SiteId) -> impl Action { choose(move |ctx| { - if ctx.npc.current_site != Some(visiting_site) { + if ctx + .state + .data() + .sites + .get(visiting_site) + .map_or(true, |s| s.world_site.is_none()) + { + casual( + idle().debug(|| "idling (visiting site does not exist, perhaps it's stale data?)"), + ) + } else if ctx.npc.current_site != Some(visiting_site) { let npc_home = ctx.npc.home; // Travel to the site we're supposed to be in urgent(travel_to_site(visiting_site).debug(move || { diff --git a/rtsim/src/rule/simulate_npcs.rs b/rtsim/src/rule/simulate_npcs.rs index 081b3d634d..2703c1d8b9 100644 --- a/rtsim/src/rule/simulate_npcs.rs +++ b/rtsim/src/rule/simulate_npcs.rs @@ -6,8 +6,9 @@ use crate::{ use common::{ comp::{self, Body}, grid::Grid, + rtsim::Personality, terrain::TerrainChunkSize, - vol::RectVolSize, rtsim::Personality, + vol::RectVolSize, }; use rand::{rngs::ThreadRng, seq::SliceRandom, Rng}; use tracing::warn; @@ -155,7 +156,9 @@ impl Rule for SimulateNpcs { .world .sim() .get(npc.wpos.xy().as_::() / TerrainChunkSize::RECT_SIZE.as_()) - .and_then(|chunk| data.sites.world_site_map.get(chunk.sites.first()?).copied()); + .and_then(|chunk| chunk.sites + .iter() + .find_map(|site| data.sites.world_site_map.get(site).copied())); let chunk_pos = npc.wpos.xy().as_::() / TerrainChunkSize::RECT_SIZE.as_::();