From 77d48657c627e2587ede2cdad37ec937e6422feb Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Tue, 23 Mar 2021 17:59:18 -0600 Subject: [PATCH] Store build areas outside of CanBuild component --- common/src/comp/inputs.rs | 3 ++- common/sys/src/state.rs | 15 +++++++++++++ server/src/cmd.rs | 40 +++++++++++++++++++++++++++++------ server/src/sys/msg/in_game.rs | 24 +++++++++++++++------ 4 files changed, 68 insertions(+), 14 deletions(-) diff --git a/common/src/comp/inputs.rs b/common/src/comp/inputs.rs index 81ea5e4f39..541a45e502 100644 --- a/common/src/comp/inputs.rs +++ b/common/src/comp/inputs.rs @@ -2,11 +2,12 @@ use serde::{Deserialize, Serialize}; use specs::{Component, DerefFlaggedStorage}; use specs_idvs::IdvStorage; use vek::geom::Aabb; +use crate::store::Id; #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct CanBuild { pub building_is_on: bool, - pub build_area: Aabb, + pub build_areas: Vec>>, } impl Component for CanBuild { type Storage = DerefFlaggedStorage>; diff --git a/common/sys/src/state.rs b/common/sys/src/state.rs index 52c4bc356a..33195123e9 100644 --- a/common/sys/src/state.rs +++ b/common/sys/src/state.rs @@ -14,6 +14,7 @@ use common::{ time::DayPeriod, trade::Trades, vol::{ReadVol, WriteVol}, + store::Store, }; use common_base::span; use common_ecs::{run_now, PhysicsMetrics, SysMetrics}; @@ -39,6 +40,19 @@ const DAY_CYCLE_FACTOR: f64 = 24.0 * 2.0; /// avoid such a situation. const MAX_DELTA_TIME: f32 = 1.0; +#[derive(Default)] +pub struct BuildAreas { + pub areas: Store>, +} + +impl BuildAreas { + pub fn new() -> Self { + Self { + areas: Store::default() + } + } +} + #[derive(Default)] pub struct BlockChange { blocks: HashMap, Block>, @@ -204,6 +218,7 @@ impl State { ecs.insert(PlayerEntity(None)); ecs.insert(TerrainGrid::new().unwrap()); ecs.insert(BlockChange::default()); + ecs.insert(BuildAreas::new()); ecs.insert(TerrainChanges::default()); ecs.insert(EventBus::::default()); ecs.insert(game_mode); diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 93179389dd..95fc1c06bc 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -30,9 +30,10 @@ use common_net::{ msg::{DisconnectReason, Notification, PlayerListUpdate, ServerGeneral}, sync::WorldSyncExt, }; +use common_sys::state::BuildAreas; use rand::Rng; use specs::{Builder, Entity as EcsEntity, Join, WorldExt}; -use std::{convert::TryFrom, time::Duration}; +use std::{convert::TryFrom, ops::DerefMut, time::Duration}; use vek::*; use world::util::Sampler; @@ -1148,23 +1149,48 @@ fn handle_permit_build( .get(target_player) .is_some() { - ecs.write_storage::().remove(target_player); + // ecs.write_storage::().remove(target_player); + // server.notify_client( + // client, + // ServerGeneral::server_msg( + // ChatType::CommandInfo, + // format!("Removed {}'s permission to build", target_alias), + // ), + // ); + let bb_id = ecs + .write_resource::() + .deref_mut() + .areas + .insert(Aabb { + min: Vec3::new(xlo, ylo, zlo), + max: Vec3::new(xhi, yhi, zhi), + }); + if let Some(mut comp_can_build) = + ecs.write_storage::().get_mut(target_player) + { + comp_can_build.build_areas.push(bb_id); + } server.notify_client( client, ServerGeneral::server_msg( ChatType::CommandInfo, - format!("Removed {}'s permission to build", target_alias), + format!("Gave {} permission to build", target_alias), ), ); } else { + let bb_id = ecs + .write_resource::() + .deref_mut() + .areas + .insert(Aabb { + min: Vec3::new(xlo, ylo, zlo), + max: Vec3::new(xhi, yhi, zhi), + }); let _ = ecs.write_storage::() .insert(target_player, comp::CanBuild { building_is_on: false, - build_area: Aabb { - min: Vec3::new(xlo, ylo, zlo), - max: Vec3::new(xhi, yhi, zhi), - }, + build_areas: vec![bb_id], }); server.notify_client( client, diff --git a/server/src/sys/msg/in_game.rs b/server/src/sys/msg/in_game.rs index ea5561bb64..ed9c252f0a 100644 --- a/server/src/sys/msg/in_game.rs +++ b/server/src/sys/msg/in_game.rs @@ -7,7 +7,7 @@ use common::{ }; use common_ecs::{Job, Origin, Phase, System}; use common_net::msg::{ClientGeneral, PresenceKind, ServerGeneral}; -use common_sys::state::BlockChange; +use common_sys::state::{BlockChange, BuildAreas}; use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage}; use tracing::{debug, trace}; @@ -29,6 +29,7 @@ impl Sys { orientations: &mut WriteStorage<'_, Ori>, controllers: &mut WriteStorage<'_, Controller>, settings: &Read<'_, Settings>, + build_areas: &Read<'_, BuildAreas>, msg: ClientGeneral, ) -> Result<(), crate::error::Error> { let presence = match maybe_presence { @@ -103,17 +104,25 @@ impl Sys { }, ClientGeneral::BreakBlock(pos) => { if let Some(comp_can_build) = can_build.get(entity) { - if comp_can_build.building_is_on && comp_can_build.build_area.contains_point(pos) { - if let Ok(block) = terrain.get(pos) { - block_changes.set(pos, block.into_vacant()); + if comp_can_build.building_is_on { + for area in comp_can_build.build_areas.iter() { + if build_areas.areas.get(*area).contains_point(pos) { + if let Ok(block) = terrain.get(pos) { + block_changes.set(pos, block.into_vacant()); + } + } } } } }, ClientGeneral::PlaceBlock(pos, block) => { if let Some(comp_can_build) = can_build.get(entity) { - if comp_can_build.building_is_on && comp_can_build.build_area.contains_point(pos) { - block_changes.try_set(pos, block); + if comp_can_build.building_is_on { + for area in comp_can_build.build_areas.iter() { + if build_areas.areas.get(*area).contains_point(pos) { + block_changes.try_set(pos, block); + } + } } } }, @@ -162,6 +171,7 @@ impl<'a> System<'a> for Sys { WriteStorage<'a, Client>, WriteStorage<'a, Controller>, Read<'a, Settings>, + Read<'a, BuildAreas>, ); const NAME: &'static str = "msg::in_game"; @@ -186,6 +196,7 @@ impl<'a> System<'a> for Sys { mut clients, mut controllers, settings, + build_areas, ): Self::SystemData, ) { let mut server_emitter = server_event_bus.emitter(); @@ -210,6 +221,7 @@ impl<'a> System<'a> for Sys { &mut orientations, &mut controllers, &settings, + &build_areas, msg, ) });