NPCs walk in when pathing in intrasite

This commit is contained in:
TaylorNAlbarnaz 2022-08-26 23:45:17 -03:00 committed by Joshua Barretto
parent 63f1ac0e31
commit 3a52cc1fa3
4 changed files with 21 additions and 12 deletions

View File

@ -57,7 +57,8 @@ pub struct Npc {
/// (wpos, speed_factor) /// (wpos, speed_factor)
#[serde(skip_serializing, skip_deserializing)] #[serde(skip_serializing, skip_deserializing)]
pub target: Option<(Vec3<f32>, f32)>, pub goto: Option<(Vec3<f32>, f32)>,
/// Whether the NPC is in simulated or loaded mode (when rtsim is run on the server, loaded corresponds to being /// Whether the NPC is in simulated or loaded mode (when rtsim is run on the server, loaded corresponds to being
/// within a loaded chunk). When in loaded mode, the interactions of the NPC should not be simulated but should /// within a loaded chunk). When in loaded mode, the interactions of the NPC should not be simulated but should
/// instead be derived from the game. /// instead be derived from the game.
@ -78,7 +79,7 @@ impl Npc {
faction: None, faction: None,
pathing: Default::default(), pathing: Default::default(),
current_site: None, current_site: None,
target: None, goto: None,
mode: NpcMode::Simulated, mode: NpcMode::Simulated,
} }
} }

View File

@ -241,12 +241,19 @@ impl Rule for NpcAi {
}); });
if let Some(home_id) = npc.home { if let Some(home_id) = npc.home {
if let Some((target, _)) = npc.target { if let Some((target, _)) = npc.goto {
// Walk to the current target // Walk to the current target
if target.xy().distance_squared(npc.wpos.xy()) < 4.0 { if target.xy().distance_squared(npc.wpos.xy()) < 4.0 {
npc.target = None; npc.goto = None;
} }
} else { } else {
// Walk slower when pathing in a site, and faster when between sites
if npc.pathing.intersite_path.is_none() {
npc.goto = Some((npc.goto.map_or(npc.wpos, |(wpos, _)| wpos), 0.7));
} else {
npc.goto = Some((npc.goto.map_or(npc.wpos, |(wpos, _)| wpos), 1.0));
}
if let Some((ref mut path, site)) = npc.pathing.intrasite_path { if let Some((ref mut path, site)) = npc.pathing.intrasite_path {
// If the npc walking in a site and want to reroll (because the path was // If the npc walking in a site and want to reroll (because the path was
// exhausted.) to try to find a complete path. // exhausted.) to try to find a complete path.
@ -256,6 +263,7 @@ impl Rule for NpcAi {
.map(|path| (path, site)); .map(|path| (path, site));
} }
} }
if let Some((ref mut path, site)) = npc.pathing.intrasite_path { if let Some((ref mut path, site)) = npc.pathing.intrasite_path {
if let Some(next_tile) = path.path.pop_front() { if let Some(next_tile) = path.path.pop_front() {
match &ctx.index.sites.get(site).kind { match &ctx.index.sites.get(site).kind {
@ -268,7 +276,7 @@ impl Rule for NpcAi {
ctx.world.sim().get_alt_approx(wpos).unwrap_or(0.0), ctx.world.sim().get_alt_approx(wpos).unwrap_or(0.0),
); );
npc.target = Some((wpos, 1.0)); npc.goto = Some((wpos, npc.goto.map_or(1.0, |(_, sf)| sf)));
}, },
_ => {}, _ => {},
} }
@ -373,7 +381,7 @@ impl Rule for NpcAi {
let wpos = wpos.as_::<f32>().with_z( let wpos = wpos.as_::<f32>().with_z(
ctx.world.sim().get_alt_approx(wpos).unwrap_or(0.0), ctx.world.sim().get_alt_approx(wpos).unwrap_or(0.0),
); );
npc.target = Some((wpos, 1.0)); npc.goto = Some((wpos, npc.goto.map_or(1.0, |(_, sf)| sf)));
*progress += 1; *progress += 1;
} }
} else { } else {
@ -417,14 +425,14 @@ impl Rule for NpcAi {
} }
} else { } else {
// TODO: Don't make homeless people walk around in circles // TODO: Don't make homeless people walk around in circles
npc.target = Some(( npc.goto = Some((
npc.wpos npc.wpos
+ Vec3::new( + Vec3::new(
ctx.event.time.0.sin() as f32 * 16.0, ctx.event.time.0.sin() as f32 * 16.0,
ctx.event.time.0.cos() as f32 * 16.0, ctx.event.time.0.cos() as f32 * 16.0,
0.0, 0.0,
), ),
1.0, 0.7,
)); ));
} }
} }

View File

@ -21,8 +21,8 @@ impl Rule for SimulateNpcs {
{ {
let body = npc.get_body(); let body = npc.get_body();
// Move NPCs if they have a target // Move NPCs if they have a target destination
if let Some((target, speed_factor)) = npc.target { if let Some((target, speed_factor)) = npc.goto {
let diff = target.xy() - npc.wpos.xy(); let diff = target.xy() - npc.wpos.xy();
let dist2 = diff.magnitude_squared(); let dist2 = diff.magnitude_squared();

View File

@ -254,8 +254,8 @@ impl<'a> System<'a> for Sys {
// Update entity state // Update entity state
if let Some(agent) = agent { if let Some(agent) = agent {
agent.rtsim_controller.travel_to = npc.target.map(|(wpos, _)| wpos); agent.rtsim_controller.travel_to = npc.goto.map(|(wpos, _)| wpos);
agent.rtsim_controller.speed_factor = npc.target.map_or(1.0, |(_, sf)| sf); agent.rtsim_controller.speed_factor = npc.goto.map_or(1.0, |(_, sf)| sf);
agent.rtsim_controller.heading_to = agent.rtsim_controller.heading_to =
npc.pathing.intersite_path.as_ref().and_then(|(path, _)| { npc.pathing.intersite_path.as_ref().and_then(|(path, _)| {
Some( Some(