From 5cf40812d974cfba3510e0eb3a1c5e0a15a905a4 Mon Sep 17 00:00:00 2001 From: Sam <samuelkeiffer@gmail.com> Date: Sat, 17 Apr 2021 17:33:54 -0400 Subject: [PATCH] Safezone is now permanently in existence at spawn. --- common/src/event.rs | 4 ++++ server/src/cmd.rs | 17 +---------------- server/src/events/entity_creation.rs | 4 ++++ server/src/events/mod.rs | 8 ++++++-- server/src/lib.rs | 14 +++++++++----- server/src/state_ext.rs | 26 ++++++++++++++++++++++++++ server/src/sys/terrain.rs | 18 +++++++++++++++++- 7 files changed, 67 insertions(+), 24 deletions(-) diff --git a/common/src/event.rs b/common/src/event.rs index f537e02150..bf5d43f3f4 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -172,6 +172,10 @@ pub enum ServerEvent { target: Uid, max_range: Option<f32>, }, + CreateSafezone { + range: Option<f32>, + pos: Pos, + }, } pub struct EventBus<E> { diff --git a/server/src/cmd.rs b/server/src/cmd.rs index f2805f1b47..313579730f 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1069,22 +1069,7 @@ fn handle_safezone( ) -> CmdResult<()> { let range = scan_fmt_some!(&args, &action.arg_fmt(), f32); let pos = position(server, target, "target")?; - server - .state - .create_object(pos, comp::object::Body::BoltNature) - .with(comp::Mass(10_f32.powi(10))) - .with(comp::Auras::new(vec![Aura::new( - AuraKind::Buff { - kind: BuffKind::Invulnerability, - data: BuffData::new(1.0, Some(Duration::from_secs(1))), - category: BuffCategory::Natural, - source: BuffSource::World, - }, - range.unwrap_or(100.0), - None, - AuraTarget::All, - )])) - .build(); + server.state.create_safezone(range, pos).build(); server.notify_client( client, diff --git a/server/src/events/entity_creation.rs b/server/src/events/entity_creation.rs index 284aebb86a..c42b2f86a5 100644 --- a/server/src/events/entity_creation.rs +++ b/server/src/events/entity_creation.rs @@ -255,3 +255,7 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) { )])) .build(); } + +pub fn handle_create_safezone(server: &mut Server, range: Option<f32>, pos: Pos) { + server.state.create_safezone(range, pos).build(); +} diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index 418cdd930d..9a3d6f1781 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -2,8 +2,9 @@ use crate::{state_ext::StateExt, Server}; use common::event::{EventBus, ServerEvent}; use common_base::span; use entity_creation::{ - handle_beam, handle_create_npc, handle_create_ship, handle_create_waypoint, - handle_initialize_character, handle_loaded_character_data, handle_shockwave, handle_shoot, + handle_beam, handle_create_npc, handle_create_safezone, handle_create_ship, + handle_create_waypoint, handle_initialize_character, handle_loaded_character_data, + handle_shockwave, handle_shoot, }; use entity_manipulation::{ handle_aura, handle_buff, handle_combo_change, handle_damage, handle_delete, handle_destroy, @@ -212,6 +213,9 @@ impl Server { target, max_range, } => handle_teleport_to(&self, entity, target, max_range), + ServerEvent::CreateSafezone { range, pos } => { + handle_create_safezone(self, range, pos) + }, } } diff --git a/server/src/lib.rs b/server/src/lib.rs index f14848d3ce..3cccef1e4f 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -114,7 +114,11 @@ use world::{ }; #[derive(Copy, Clone)] -struct SpawnPoint(Vec3<f32>); +pub struct SpawnPoint(Vec3<f32>); + +impl Default for SpawnPoint { + fn default() -> Self { Self(Vec3::new(0.0, 0.0, 256.0)) } +} // Tick count used for throttling network updates // Note this doesn't account for dt (so update rate changes with tick rate) @@ -299,7 +303,7 @@ impl Server { }; #[cfg(feature = "worldgen")] - let spawn_point = { + let spawn_point = SpawnPoint({ let index = index.as_index_ref(); // NOTE: all of these `.map(|e| e as [type])` calls should compile into no-ops, // but are needed to be explicit about casting (and to make the compiler stop @@ -327,12 +331,12 @@ impl Server { }; world.find_lowest_accessible_pos(index, spawn_chunk) - }; + }); #[cfg(not(feature = "worldgen"))] - let spawn_point = Vec3::new(0.0, 0.0, 256.0); + let spawn_point = SpawnPoint::default(); // Set the spawn point we calculated above - state.ecs_mut().insert(SpawnPoint(spawn_point)); + state.ecs_mut().insert(spawn_point); // Insert a default AABB for the world // TODO: prevent this from being deleted diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index 76cbddd317..93682f4870 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -24,6 +24,7 @@ use specs::{ saveload::MarkerAllocator, Builder, Entity as EcsEntity, EntityBuilder as EcsEntityBuilder, Join, WorldExt, }; +use std::time::Duration; use tracing::warn; use vek::*; @@ -72,6 +73,8 @@ pub trait StateExt { pos: comp::Pos, ori: comp::Ori, ) -> EcsEntityBuilder; + /// Creates a safezone + fn create_safezone(&mut self, range: Option<f32>, pos: comp::Pos) -> EcsEntityBuilder; // NOTE: currently only used for testing /// Queues chunk generation in the view distance of the persister, this /// entity must be built before those chunks are received (the builder @@ -318,6 +321,29 @@ impl StateExt for State { }) } + fn create_safezone(&mut self, range: Option<f32>, pos: comp::Pos) -> EcsEntityBuilder { + use comp::{ + aura::{Aura, AuraKind, AuraTarget, Auras}, + buff::{BuffCategory, BuffData, BuffKind, BuffSource}, + object, Body, + }; + self.ecs_mut() + .create_entity_synced() + .with(pos) + .with(Body::Object(object::Body::BoltNature)) + .with(Auras::new(vec![Aura::new( + AuraKind::Buff { + kind: BuffKind::Invulnerability, + data: BuffData::new(1.0, Some(Duration::from_secs(1))), + category: BuffCategory::Natural, + source: BuffSource::World, + }, + range.unwrap_or(100.0), + None, + AuraTarget::All, + )])) + } + // NOTE: currently only used for testing /// Queues chunk generation in the view distance of the persister, this /// entity must be built before those chunks are received (the builder diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index 9a43236f29..27afdda57f 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -1,5 +1,6 @@ use crate::{ - chunk_generator::ChunkGenerator, client::Client, presence::Presence, rtsim::RtSim, Tick, + chunk_generator::ChunkGenerator, client::Client, presence::Presence, rtsim::RtSim, SpawnPoint, + Tick, }; use common::{ comp::{ @@ -33,6 +34,7 @@ impl<'a> System<'a> for Sys { type SystemData = ( Read<'a, EventBus<ServerEvent>>, Read<'a, Tick>, + Read<'a, SpawnPoint>, WriteExpect<'a, ChunkGenerator>, WriteExpect<'a, TerrainGrid>, Write<'a, TerrainChanges>, @@ -51,6 +53,7 @@ impl<'a> System<'a> for Sys { ( server_event_bus, tick, + spawn_point, mut chunk_generator, mut terrain, mut terrain_changes, @@ -218,6 +221,14 @@ impl<'a> System<'a> for Sys { rtsim_entity: None, }) } + + // Insert a safezone if chunk contains the spawn position + if is_spawn_chunk(key, *spawn_point, &terrain) { + server_emitter.emit(ServerEvent::CreateSafezone { + range: Some(100.0), + pos: Pos(spawn_point.0), + }); + } } // Remove chunks that are too far from players. @@ -271,3 +282,8 @@ pub fn chunk_in_vd( adjusted_dist_sqr <= vd.pow(2) } + +fn is_spawn_chunk(chunk_pos: Vec2<i32>, spawn_pos: SpawnPoint, terrain: &TerrainGrid) -> bool { + let spawn_chunk_pos = terrain.pos_key(spawn_pos.0.map(|e| e as i32)); + chunk_pos == spawn_chunk_pos +}