diff --git a/common/net/src/synced_components.rs b/common/net/src/synced_components.rs index bf8cc26a19..89bd7a17c0 100755 --- a/common/net/src/synced_components.rs +++ b/common/net/src/synced_components.rs @@ -46,6 +46,7 @@ macro_rules! synced_components { beam_segment: BeamSegment, alignment: Alignment, stance: Stance, + teleporter: Teleporter, // TODO: change this to `SyncFrom::ClientEntity` and sync the bare minimum // from other entities (e.g. just keys needed to show appearance // based on their loadout). Also, it looks like this actually has @@ -102,8 +103,6 @@ synced_components!(reexport_comps); // === NetSync implementations === // =============================== -use common::comp::Teleporter; - use crate::sync::{NetSync, SyncFrom}; impl NetSync for Body { diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 97b8c9e742..42ae04aef4 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -2055,7 +2055,7 @@ fn handle_spawn_portal( parse_cmd_args!(args, f32, f32, f32, bool, f64) { let requires_no_aggro = requires_no_aggro.unwrap_or(false); - let buildup_time = Secs(buildup_time.unwrap_or(0.)); + let buildup_time = Secs(buildup_time.unwrap_or(7.)); server .state .create_teleporter(pos, comp::Teleporter { diff --git a/server/src/sys/teleporter.rs b/server/src/sys/teleporter.rs index 97de8a41e4..0ec6345071 100644 --- a/server/src/sys/teleporter.rs +++ b/server/src/sys/teleporter.rs @@ -13,7 +13,7 @@ use common::{ CachedSpatialGrid, }; use common_ecs::{Origin, Phase, System}; -use specs::{Entities, Join, Read, ReadStorage, WriteStorage}; +use specs::{storage::StorageEntry, Entities, Join, Read, ReadStorage, WriteStorage}; use vek::Vec3; const TELEPORT_RADIUS: f32 = 3.; @@ -63,14 +63,13 @@ impl<'a> System<'a> for Sys { ) { let mut attempt_teleport = vec![]; let mut cancel_teleport = vec![]; - let mut start_teleporting = vec![]; let mut player_data = ( &entities, &positions, &players, &mut character_states, - teleporting.maybe(), + teleporting.entries(), ) .join(); @@ -106,24 +105,27 @@ impl<'a> System<'a> for Sys { }) { if teleporter.requires_no_aggro && check_aggro(entity, pos.0) { - if teleporting.is_some() { - cancel_teleport.push(entity) + if let StorageEntry::Occupied(entry) = teleporting { + entry.remove(); }; continue; } - if teleporting.is_none() { - start_teleporting.push((entity, Teleporting { + if let StorageEntry::Vacant(entry) = teleporting { + entry.insert(Teleporting { teleport_start: *time, portal: portal_entity, end_time: Time(time.0 + teleporter.buildup_time.0), - })); - } else if let Some(remaining) = teleporting.and_then(|teleporting| { + }); + } else if let Some(remaining) = if let StorageEntry::Occupied(entry) = teleporting { + let teleporting = entry.get(); ((time.0 - teleporting.teleport_start.0) >= teleporter.buildup_time.0 / 3. && !matches!(*character_state, CharacterState::Blink(_))) .then_some(teleporter.buildup_time.0 - (time.0 - teleporting.teleport_start.0)) - }) { + } else { + None + } { // Move into blink character state at half buildup time *character_state = CharacterState::Blink(blink::Data { timer: Duration::default(), @@ -156,10 +158,6 @@ impl<'a> System<'a> for Sys { } } - for (entity, teleporting_data) in start_teleporting { - let _ = teleporting.insert(entity, teleporting_data); - } - for (entity, position, _, teleporting) in (&entities, &positions, &players, &teleporting).join() { diff --git a/world/src/civ/mod.rs b/world/src/civ/mod.rs index d97726b476..b8939bd5b1 100644 --- a/world/src/civ/mod.rs +++ b/world/src/civ/mod.rs @@ -1894,8 +1894,8 @@ impl SiteKind { .chain(cave::tunnels_at(loc, 2, &land)) .filter(|tunnel| { dungeon_aabr.collides_with_aabr(Aabr { - min: tunnel.a.wpos, - max: tunnel.b.wpos, + min: tunnel.nodes().0.wpos, + max: tunnel.nodes().1.wpos, }) }); diff --git a/world/src/layer/cave.rs b/world/src/layer/cave.rs index a95e183bd7..7a1f40bbfa 100644 --- a/world/src/layer/cave.rs +++ b/world/src/layer/cave.rs @@ -76,8 +76,8 @@ pub fn surface_entrances<'a>(land: &'a Land) -> impl Iterator> } pub struct Tunnel { - pub a: Node, - pub b: Node, + a: Node, + b: Node, curve: f32, } @@ -215,6 +215,8 @@ impl Tunnel { depth, } } + + pub fn nodes(&self) -> (&Node, &Node) { (&self.a, &self.b) } } pub(crate) fn tunnels_at<'a>( diff --git a/world/src/site2/plot/dungeon.rs b/world/src/site2/plot/dungeon.rs index fa44e4709c..9b6d83f3e7 100644 --- a/world/src/site2/plot/dungeon.rs +++ b/world/src/site2/plot/dungeon.rs @@ -1155,8 +1155,6 @@ impl Floor { Tile::Solid => continue, }; - // TODO: Get outer tile aabb - let outer_tile_aabb = painter.prim(Primitive::Aabb(aabr_with_z( outer_tile_aabr(0), floor_z - 2..(floor_z + tunnel_height as i32) + 2, @@ -1192,8 +1190,8 @@ impl Floor { height = height.min(room.height); if let Tile::UpStair(_, kind) = tile && !self.final_level { // Construct the staircase that connects this tile to the matching DownStair - // tile on the floor above (or to the surface if this is the top floor), and - // a hollow bounding box to place air in + // tile on the floor above (or to the surface if this is the top floor), and a + // hollow bounding box to place air in let center = tile_center.with_z(floor_z); let radius = TILE_SIZE as f32 / 2.0; let aabb = aabr_with_z(tile_aabr, floor_z..floor_z + self.total_depth()); @@ -1292,10 +1290,9 @@ impl Floor { painter.fill(platform, Fill::Block(stone)); } - // If a room has pillars, the current tile aligns with the pillar spacing, - // and we're not too close to a wall (i.e. the - // adjacent tiles are rooms and not hallways/solid), - // place a pillar + // If a room has pillars, the current tile aligns with the pillar spacing, and + // we're not too close to a wall (i.e. the adjacent tiles are rooms and not + // hallways/solid), place a pillar if room .pillars .map(|pillar_space| {