From ca10d8906811da9b84c5b3c1fedd16bc9a397bae Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Thu, 22 Jul 2021 23:03:52 -0400 Subject: [PATCH 1/2] Further improve handling of underground waypoints: - Set the waypoint to the valid position after chunk load, so that respawns work. - Search for the nearest valid surface before falling back to the top of the chunk, so that waypoints inside caves/buildings work. --- common/src/terrain/mod.rs | 5 ++++- server/src/sys/terrain.rs | 15 +++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/common/src/terrain/mod.rs b/common/src/terrain/mod.rs index aabb5d56a4..4b5280fc10 100644 --- a/common/src/terrain/mod.rs +++ b/common/src/terrain/mod.rs @@ -159,6 +159,10 @@ impl TerrainGrid { /// Find a location suitable for spawning an entity near the given /// position (but in the same chunk). pub fn find_space(&self, pos: Vec3) -> Vec3 { + self.find_space_opt(pos).unwrap_or(pos) + } + + pub fn find_space_opt(&self, pos: Vec3) -> Option> { const SEARCH_DIST: i32 = 63; (0..SEARCH_DIST * 2 + 1) .map(|i| if i % 2 == 0 { i } else { -i } / 2) @@ -171,7 +175,6 @@ impl TerrainGrid { .map_or(true, |b| !b.is_solid()) }) }) - .unwrap_or(pos) } } diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index 25ce94cd7f..7964828669 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -8,10 +8,11 @@ use crate::{ SpawnPoint, Tick, }; use common::{ - comp::{self, agent, bird_medium, Alignment, BehaviorCapability, ForceUpdate, Pos}, + comp::{self, agent, bird_medium, Alignment, BehaviorCapability, ForceUpdate, Pos, Waypoint}, event::{EventBus, ServerEvent}, generation::{get_npc_name, EntityInfo}, npc::NPC_NAMES, + resources::Time, terrain::TerrainGrid, LoadoutBuilder, SkillSetBuilder, }; @@ -104,6 +105,8 @@ impl<'a> System<'a> for Sys { Entities<'a>, WriteStorage<'a, RepositionOnChunkLoad>, WriteStorage<'a, ForceUpdate>, + WriteStorage<'a, Waypoint>, + ReadExpect<'a, Time>, ); const NAME: &'static str = "terrain"; @@ -128,6 +131,8 @@ impl<'a> System<'a> for Sys { entities, mut reposition_on_load, mut force_update, + mut waypoints, + time, ): Self::SystemData, ) { let mut server_emitter = server_event_bus.emitter(); @@ -330,11 +335,13 @@ impl<'a> System<'a> for Sys { let chunk_pos = terrain.pos_key(pos.0.map(|e| e as i32)); if let Some(chunk) = terrain.get_key(chunk_pos) { - pos.0 = chunk - .find_accessible_pos(pos.0.xy().as_::(), false) - .as_::(); + pos.0 = terrain + .find_space_opt(pos.0.as_::()) + .map(|x| x.as_::()) + .unwrap_or_else(|| chunk.find_accessible_pos(pos.0.xy().as_::(), false)); repositioned.push(entity); let _ = force_update.insert(entity, ForceUpdate); + let _ = waypoints.insert(entity, Waypoint::new(pos.0, *time)); } } for entity in repositioned { From 5dd56b724cd5ee102ad003fa2bee4cfaedb19ddf Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Sat, 24 Jul 2021 13:09:10 -0400 Subject: [PATCH 2/2] Rename `find_space_opt` to `try_find_space`. --- common/src/terrain/mod.rs | 4 ++-- server/src/sys/terrain.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/src/terrain/mod.rs b/common/src/terrain/mod.rs index 4b5280fc10..0bb91f5c9b 100644 --- a/common/src/terrain/mod.rs +++ b/common/src/terrain/mod.rs @@ -159,10 +159,10 @@ impl TerrainGrid { /// Find a location suitable for spawning an entity near the given /// position (but in the same chunk). pub fn find_space(&self, pos: Vec3) -> Vec3 { - self.find_space_opt(pos).unwrap_or(pos) + self.try_find_space(pos).unwrap_or(pos) } - pub fn find_space_opt(&self, pos: Vec3) -> Option> { + pub fn try_find_space(&self, pos: Vec3) -> Option> { const SEARCH_DIST: i32 = 63; (0..SEARCH_DIST * 2 + 1) .map(|i| if i % 2 == 0 { i } else { -i } / 2) diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index 7964828669..ce1b16c31b 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -336,7 +336,7 @@ impl<'a> System<'a> for Sys { let chunk_pos = terrain.pos_key(pos.0.map(|e| e as i32)); if let Some(chunk) = terrain.get_key(chunk_pos) { pos.0 = terrain - .find_space_opt(pos.0.as_::()) + .try_find_space(pos.0.as_::()) .map(|x| x.as_::()) .unwrap_or_else(|| chunk.find_accessible_pos(pos.0.xy().as_::(), false)); repositioned.push(entity);