mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'maxicarlos08/dura-free-area' into 'master'
Durability free areas See merge request veloren/veloren!3936
This commit is contained in:
commit
19342daa8d
@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Some sprites can be sat on.
|
- Some sprites can be sat on.
|
||||||
- Pet birds can now sit on the player's shoulder as they explore the world.
|
- Pet birds can now sit on the player's shoulder as they explore the world.
|
||||||
- Adlet caves
|
- Adlet caves
|
||||||
|
- Durability free areas (`/area_add <area_name> no_durability ...`)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@ -65,6 +66,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- The game now starts in fullscreen by default
|
- The game now starts in fullscreen by default
|
||||||
- Default audio volume should be less likely to destroy ear drums
|
- Default audio volume should be less likely to destroy ear drums
|
||||||
- Creatures flee less quickly when low on health
|
- Creatures flee less quickly when low on health
|
||||||
|
- All `/build_area_*` commands have been renamed to `/area_*`, and you will have to pass an additional area type
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ use std::{
|
|||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
use strum::IntoEnumIterator;
|
use strum::{AsRefStr, EnumIter, EnumString, IntoEnumIterator};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
/// Struct representing a command that a user can run from server chat.
|
/// Struct representing a command that a user can run from server chat.
|
||||||
@ -66,6 +66,15 @@ impl assets::Asset for SkillPresetManifest {
|
|||||||
pub const KIT_MANIFEST_PATH: &str = "server.manifests.kits";
|
pub const KIT_MANIFEST_PATH: &str = "server.manifests.kits";
|
||||||
pub const PRESET_MANIFEST_PATH: &str = "server.manifests.presets";
|
pub const PRESET_MANIFEST_PATH: &str = "server.manifests.presets";
|
||||||
|
|
||||||
|
/// Enum for all possible area types
|
||||||
|
#[derive(Debug, Clone, EnumIter, EnumString, AsRefStr)]
|
||||||
|
pub enum AreaKind {
|
||||||
|
#[strum(serialize = "build")]
|
||||||
|
Build,
|
||||||
|
#[strum(serialize = "no_durability")]
|
||||||
|
NoDurability,
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref ALIGNMENTS: Vec<String> = vec!["wild", "enemy", "npc", "pet"]
|
static ref ALIGNMENTS: Vec<String> = vec!["wild", "enemy", "npc", "pet"]
|
||||||
.iter()
|
.iter()
|
||||||
@ -114,6 +123,7 @@ lazy_static! {
|
|||||||
|
|
||||||
souls
|
souls
|
||||||
};
|
};
|
||||||
|
static ref AREA_KINDS: Vec<String> = AreaKind::iter().map(|kind| kind.as_ref().to_string()).collect();
|
||||||
static ref OBJECTS: Vec<String> = comp::object::ALL_OBJECTS
|
static ref OBJECTS: Vec<String> = comp::object::ALL_OBJECTS
|
||||||
.iter()
|
.iter()
|
||||||
.map(|o| o.to_string().to_string())
|
.map(|o| o.to_string().to_string())
|
||||||
@ -247,15 +257,15 @@ pub enum ServerChatCommand {
|
|||||||
Adminify,
|
Adminify,
|
||||||
Airship,
|
Airship,
|
||||||
Alias,
|
Alias,
|
||||||
|
AreaAdd,
|
||||||
|
AreaList,
|
||||||
|
AreaRemove,
|
||||||
Ban,
|
Ban,
|
||||||
BattleMode,
|
BattleMode,
|
||||||
BattleModeForce,
|
BattleModeForce,
|
||||||
Body,
|
Body,
|
||||||
Buff,
|
Buff,
|
||||||
Build,
|
Build,
|
||||||
BuildAreaAdd,
|
|
||||||
BuildAreaList,
|
|
||||||
BuildAreaRemove,
|
|
||||||
Campfire,
|
Campfire,
|
||||||
CreateLocation,
|
CreateLocation,
|
||||||
DebugColumn,
|
DebugColumn,
|
||||||
@ -400,9 +410,10 @@ impl ServerChatCommand {
|
|||||||
Some(Admin),
|
Some(Admin),
|
||||||
),
|
),
|
||||||
ServerChatCommand::Build => cmd(vec![], "Toggles build mode on and off", None),
|
ServerChatCommand::Build => cmd(vec![], "Toggles build mode on and off", None),
|
||||||
ServerChatCommand::BuildAreaAdd => cmd(
|
ServerChatCommand::AreaAdd => cmd(
|
||||||
vec![
|
vec![
|
||||||
Any("name", Required),
|
Any("name", Required),
|
||||||
|
Enum("kind", AREA_KINDS.clone(), Required),
|
||||||
Integer("xlo", 0, Required),
|
Integer("xlo", 0, Required),
|
||||||
Integer("xhi", 10, Required),
|
Integer("xhi", 10, Required),
|
||||||
Integer("ylo", 0, Required),
|
Integer("ylo", 0, Required),
|
||||||
@ -413,9 +424,12 @@ impl ServerChatCommand {
|
|||||||
"Adds a new build area",
|
"Adds a new build area",
|
||||||
Some(Admin),
|
Some(Admin),
|
||||||
),
|
),
|
||||||
ServerChatCommand::BuildAreaList => cmd(vec![], "List all build areas", Some(Admin)),
|
ServerChatCommand::AreaList => cmd(vec![], "List all build areas", Some(Admin)),
|
||||||
ServerChatCommand::BuildAreaRemove => cmd(
|
ServerChatCommand::AreaRemove => cmd(
|
||||||
vec![Any("name", Required)],
|
vec![
|
||||||
|
Any("name", Required),
|
||||||
|
Enum("kind", AREA_KINDS.clone(), Required),
|
||||||
|
],
|
||||||
"Removes specified build area",
|
"Removes specified build area",
|
||||||
Some(Admin),
|
Some(Admin),
|
||||||
),
|
),
|
||||||
@ -807,9 +821,9 @@ impl ServerChatCommand {
|
|||||||
ServerChatCommand::Body => "body",
|
ServerChatCommand::Body => "body",
|
||||||
ServerChatCommand::Buff => "buff",
|
ServerChatCommand::Buff => "buff",
|
||||||
ServerChatCommand::Build => "build",
|
ServerChatCommand::Build => "build",
|
||||||
ServerChatCommand::BuildAreaAdd => "build_area_add",
|
ServerChatCommand::AreaAdd => "area_add",
|
||||||
ServerChatCommand::BuildAreaList => "build_area_list",
|
ServerChatCommand::AreaList => "area_list",
|
||||||
ServerChatCommand::BuildAreaRemove => "build_area_remove",
|
ServerChatCommand::AreaRemove => "area_remove",
|
||||||
ServerChatCommand::Campfire => "campfire",
|
ServerChatCommand::Campfire => "campfire",
|
||||||
ServerChatCommand::DebugColumn => "debug_column",
|
ServerChatCommand::DebugColumn => "debug_column",
|
||||||
ServerChatCommand::DebugWays => "debug_ways",
|
ServerChatCommand::DebugWays => "debug_ways",
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
//! This crate contains the [`State`] and shared between
|
//! This crate contains the [`State`] and shared between
|
||||||
//! server (`veloren-server`) and the client (`veloren-client`)
|
//! server (`veloren-server`) and the client (`veloren-client`)
|
||||||
|
|
||||||
mod build_areas;
|
|
||||||
#[cfg(feature = "plugins")] pub mod plugin;
|
#[cfg(feature = "plugins")] pub mod plugin;
|
||||||
|
mod special_areas;
|
||||||
mod state;
|
mod state;
|
||||||
// TODO: breakup state module and remove glob
|
// TODO: breakup state module and remove glob
|
||||||
pub use build_areas::{BuildAreaError, BuildAreas};
|
pub use special_areas::*;
|
||||||
pub use state::{BlockChange, BlockDiff, State, TerrainChanges};
|
pub use state::{BlockChange, BlockDiff, State, TerrainChanges};
|
||||||
|
@ -1,17 +1,30 @@
|
|||||||
use common::depot::{Depot, Id};
|
use common::depot::{Depot, Id};
|
||||||
use hashbrown::{hash_map, HashMap};
|
use hashbrown::{hash_map, HashMap};
|
||||||
|
use std::{
|
||||||
|
marker::PhantomData,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct AreasContainer<Kind>(Areas, PhantomData<Kind>);
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct BuildArea;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct NoDurabilityArea;
|
||||||
|
|
||||||
/// NOTE: Please don't add `Deserialize` without checking to make sure we
|
/// NOTE: Please don't add `Deserialize` without checking to make sure we
|
||||||
/// can guarantee the invariant that every entry in `area_names` points to a
|
/// can guarantee the invariant that every entry in `area_names` points to a
|
||||||
/// valid id in `areas`.
|
/// valid id in `areas`.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct BuildAreas {
|
pub struct Areas {
|
||||||
areas: Depot<Aabb<i32>>,
|
areas: Depot<Aabb<i32>>,
|
||||||
area_names: HashMap<String, Id<Aabb<i32>>>,
|
area_names: HashMap<String, Id<Aabb<i32>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BuildAreaError {
|
pub enum SpecialAreaError {
|
||||||
/// This build area name is reserved by the system.
|
/// This build area name is reserved by the system.
|
||||||
Reserved,
|
Reserved,
|
||||||
/// The build area name was not found.
|
/// The build area name was not found.
|
||||||
@ -21,10 +34,10 @@ pub enum BuildAreaError {
|
|||||||
/// Build area names that can only be inserted, not removed.
|
/// Build area names that can only be inserted, not removed.
|
||||||
const RESERVED_BUILD_AREA_NAMES: &[&str] = &["world"];
|
const RESERVED_BUILD_AREA_NAMES: &[&str] = &["world"];
|
||||||
|
|
||||||
impl BuildAreas {
|
impl Areas {
|
||||||
pub fn areas(&self) -> &Depot<Aabb<i32>> { &self.areas }
|
pub fn areas(&self) -> &Depot<Aabb<i32>> { &self.areas }
|
||||||
|
|
||||||
pub fn area_names(&self) -> &HashMap<String, Id<Aabb<i32>>> { &self.area_names }
|
pub fn area_metas(&self) -> &HashMap<String, Id<Aabb<i32>>> { &self.area_names }
|
||||||
|
|
||||||
/// If the area_name is already in the map, returns Err(area_name).
|
/// If the area_name is already in the map, returns Err(area_name).
|
||||||
pub fn insert(&mut self, area_name: String, area: Aabb<i32>) -> Result<Id<Aabb<i32>>, String> {
|
pub fn insert(&mut self, area_name: String, area: Aabb<i32>) -> Result<Id<Aabb<i32>>, String> {
|
||||||
@ -37,14 +50,14 @@ impl BuildAreas {
|
|||||||
Ok(bb_id)
|
Ok(bb_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, area_name: &str) -> Result<Aabb<i32>, BuildAreaError> {
|
pub fn remove(&mut self, area_name: &str) -> Result<Aabb<i32>, SpecialAreaError> {
|
||||||
if RESERVED_BUILD_AREA_NAMES.contains(&area_name) {
|
if RESERVED_BUILD_AREA_NAMES.contains(&area_name) {
|
||||||
return Err(BuildAreaError::Reserved);
|
return Err(SpecialAreaError::Reserved);
|
||||||
}
|
}
|
||||||
let bb_id = self
|
let bb_id = self
|
||||||
.area_names
|
.area_names
|
||||||
.remove(area_name)
|
.remove(area_name)
|
||||||
.ok_or(BuildAreaError::NotFound)?;
|
.ok_or(SpecialAreaError::NotFound)?;
|
||||||
let area = self.areas.remove(bb_id).expect(
|
let area = self.areas.remove(bb_id).expect(
|
||||||
"Entries in `areas` are added before entries in `area_names` in `insert`, and that is \
|
"Entries in `areas` are added before entries in `area_names` in `insert`, and that is \
|
||||||
the only exposed way to add elements to `area_names`.",
|
the only exposed way to add elements to `area_names`.",
|
||||||
@ -52,3 +65,31 @@ impl BuildAreas {
|
|||||||
Ok(area)
|
Ok(area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Kind> Deref for AreasContainer<Kind>
|
||||||
|
where
|
||||||
|
Kind: AreaKind,
|
||||||
|
{
|
||||||
|
type Target = Areas;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Kind> DerefMut for AreasContainer<Kind>
|
||||||
|
where
|
||||||
|
Kind: AreaKind,
|
||||||
|
{
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait AreaKind {
|
||||||
|
fn display() -> &'static str;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AreaKind for BuildArea {
|
||||||
|
fn display() -> &'static str { "build" }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AreaKind for NoDurabilityArea {
|
||||||
|
fn display() -> &'static str { "durability free" }
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
use crate::plugin::memory_manager::EcsWorld;
|
use crate::plugin::memory_manager::EcsWorld;
|
||||||
#[cfg(feature = "plugins")]
|
#[cfg(feature = "plugins")]
|
||||||
use crate::plugin::PluginMgr;
|
use crate::plugin::PluginMgr;
|
||||||
|
use crate::{BuildArea, NoDurabilityArea};
|
||||||
#[cfg(feature = "plugins")]
|
#[cfg(feature = "plugins")]
|
||||||
use common::uid::UidAllocator;
|
use common::uid::UidAllocator;
|
||||||
use common::{
|
use common::{
|
||||||
@ -275,7 +276,8 @@ impl State {
|
|||||||
ecs.insert(TerrainGrid::new(map_size_lg, default_chunk).unwrap());
|
ecs.insert(TerrainGrid::new(map_size_lg, default_chunk).unwrap());
|
||||||
ecs.insert(BlockChange::default());
|
ecs.insert(BlockChange::default());
|
||||||
ecs.insert(ScheduledBlockChange::default());
|
ecs.insert(ScheduledBlockChange::default());
|
||||||
ecs.insert(crate::build_areas::BuildAreas::default());
|
ecs.insert(crate::special_areas::AreasContainer::<BuildArea>::default());
|
||||||
|
ecs.insert(crate::special_areas::AreasContainer::<NoDurabilityArea>::default());
|
||||||
ecs.insert(TerrainChanges::default());
|
ecs.insert(TerrainChanges::default());
|
||||||
ecs.insert(EventBus::<LocalEvent>::default());
|
ecs.insert(EventBus::<LocalEvent>::default());
|
||||||
ecs.insert(game_mode);
|
ecs.insert(game_mode);
|
||||||
|
@ -21,8 +21,8 @@ use common::{
|
|||||||
assets,
|
assets,
|
||||||
calendar::Calendar,
|
calendar::Calendar,
|
||||||
cmd::{
|
cmd::{
|
||||||
KitSpec, ServerChatCommand, BUFF_PACK, BUFF_PARSER, ITEM_SPECS, KIT_MANIFEST_PATH,
|
AreaKind, KitSpec, ServerChatCommand, BUFF_PACK, BUFF_PARSER, ITEM_SPECS,
|
||||||
PRESET_MANIFEST_PATH,
|
KIT_MANIFEST_PATH, PRESET_MANIFEST_PATH,
|
||||||
},
|
},
|
||||||
comp::{
|
comp::{
|
||||||
self,
|
self,
|
||||||
@ -55,7 +55,7 @@ use common_net::{
|
|||||||
msg::{DisconnectReason, Notification, PlayerListUpdate, ServerGeneral},
|
msg::{DisconnectReason, Notification, PlayerListUpdate, ServerGeneral},
|
||||||
sync::WorldSyncExt,
|
sync::WorldSyncExt,
|
||||||
};
|
};
|
||||||
use common_state::{BuildAreaError, BuildAreas};
|
use common_state::{Areas, AreasContainer, BuildArea, NoDurabilityArea, SpecialAreaError, State};
|
||||||
use core::{cmp::Ordering, convert::TryFrom};
|
use core::{cmp::Ordering, convert::TryFrom};
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use humantime::Duration as HumanDuration;
|
use humantime::Duration as HumanDuration;
|
||||||
@ -63,7 +63,7 @@ use rand::{thread_rng, Rng};
|
|||||||
use specs::{
|
use specs::{
|
||||||
saveload::MarkerAllocator, storage::StorageEntry, Builder, Entity as EcsEntity, Join, WorldExt,
|
saveload::MarkerAllocator, storage::StorageEntry, Builder, Entity as EcsEntity, Join, WorldExt,
|
||||||
};
|
};
|
||||||
use std::{fmt::Write, str::FromStr, sync::Arc};
|
use std::{fmt::Write, ops::DerefMut, str::FromStr, sync::Arc};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use wiring::{Circuit, Wire, WireNode, WiringAction, WiringActionEffect, WiringElement};
|
use wiring::{Circuit, Wire, WireNode, WiringAction, WiringActionEffect, WiringElement};
|
||||||
use world::util::{Sampler, LOCALITY};
|
use world::util::{Sampler, LOCALITY};
|
||||||
@ -133,9 +133,9 @@ fn do_command(
|
|||||||
ServerChatCommand::Body => handle_body,
|
ServerChatCommand::Body => handle_body,
|
||||||
ServerChatCommand::Buff => handle_buff,
|
ServerChatCommand::Buff => handle_buff,
|
||||||
ServerChatCommand::Build => handle_build,
|
ServerChatCommand::Build => handle_build,
|
||||||
ServerChatCommand::BuildAreaAdd => handle_build_area_add,
|
ServerChatCommand::AreaAdd => handle_area_add,
|
||||||
ServerChatCommand::BuildAreaList => handle_build_area_list,
|
ServerChatCommand::AreaList => handle_area_list,
|
||||||
ServerChatCommand::BuildAreaRemove => handle_build_area_remove,
|
ServerChatCommand::AreaRemove => handle_area_remove,
|
||||||
ServerChatCommand::Campfire => handle_spawn_campfire,
|
ServerChatCommand::Campfire => handle_spawn_campfire,
|
||||||
ServerChatCommand::DebugColumn => handle_debug_column,
|
ServerChatCommand::DebugColumn => handle_debug_column,
|
||||||
ServerChatCommand::DebugWays => handle_debug_ways,
|
ServerChatCommand::DebugWays => handle_debug_ways,
|
||||||
@ -351,11 +351,9 @@ fn uid(server: &Server, target: EcsEntity, descriptor: &str) -> CmdResult<Uid> {
|
|||||||
.ok_or_else(|| format!("Cannot get uid for {:?}", descriptor))
|
.ok_or_else(|| format!("Cannot get uid for {:?}", descriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn area(server: &mut Server, area_name: &str) -> CmdResult<depot::Id<Aabb<i32>>> {
|
fn area(server: &mut Server, area_name: &str, kind: &str) -> CmdResult<depot::Id<Aabb<i32>>> {
|
||||||
server
|
get_areas_mut(kind, &mut server.state)?
|
||||||
.state
|
.area_metas()
|
||||||
.mut_resource::<BuildAreas>()
|
|
||||||
.area_names()
|
|
||||||
.get(area_name)
|
.get(area_name)
|
||||||
.copied()
|
.copied()
|
||||||
.ok_or_else(|| format!("Area name not found: {}", area_name))
|
.ok_or_else(|| format!("Area name not found: {}", area_name))
|
||||||
@ -1841,7 +1839,7 @@ fn handle_permit_build(
|
|||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
if let Some(area_name) = parse_cmd_args!(args, String) {
|
if let Some(area_name) = parse_cmd_args!(args, String) {
|
||||||
let bb_id = area(server, &area_name)?;
|
let bb_id = area(server, &area_name, "build")?;
|
||||||
let mut can_build = server.state.ecs().write_storage::<comp::CanBuild>();
|
let mut can_build = server.state.ecs().write_storage::<comp::CanBuild>();
|
||||||
let entry = can_build
|
let entry = can_build
|
||||||
.entry(target)
|
.entry(target)
|
||||||
@ -1882,7 +1880,7 @@ fn handle_revoke_build(
|
|||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
if let Some(area_name) = parse_cmd_args!(args, String) {
|
if let Some(area_name) = parse_cmd_args!(args, String) {
|
||||||
let bb_id = area(server, &area_name)?;
|
let bb_id = area(server, &area_name, "build")?;
|
||||||
let mut can_build = server.state.ecs_mut().write_storage::<comp::CanBuild>();
|
let mut can_build = server.state.ecs_mut().write_storage::<comp::CanBuild>();
|
||||||
if let Some(mut comp_can_build) = can_build.get_mut(target) {
|
if let Some(mut comp_can_build) = can_build.get_mut(target) {
|
||||||
comp_can_build.build_areas.retain(|&x| x != bb_id);
|
comp_can_build.build_areas.retain(|&x| x != bb_id);
|
||||||
@ -2006,27 +2004,47 @@ fn handle_build(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_build_area_add(
|
fn get_areas_mut<'l>(kind: &str, state: &'l mut State) -> CmdResult<&'l mut Areas> {
|
||||||
|
Ok(match AreaKind::from_str(kind).ok() {
|
||||||
|
Some(AreaKind::Build) => state
|
||||||
|
.mut_resource::<AreasContainer<BuildArea>>()
|
||||||
|
.deref_mut(),
|
||||||
|
Some(AreaKind::NoDurability) => state
|
||||||
|
.mut_resource::<AreasContainer<NoDurabilityArea>>()
|
||||||
|
.deref_mut(),
|
||||||
|
None => Err(format!("Invalid area type '{kind}'"))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_area_add(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
client: EcsEntity,
|
client: EcsEntity,
|
||||||
_target: EcsEntity,
|
_target: EcsEntity,
|
||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
if let (Some(area_name), Some(xlo), Some(xhi), Some(ylo), Some(yhi), Some(zlo), Some(zhi)) =
|
if let (
|
||||||
parse_cmd_args!(args, String, i32, i32, i32, i32, i32, i32)
|
Some(area_name),
|
||||||
|
Some(kind),
|
||||||
|
Some(xlo),
|
||||||
|
Some(xhi),
|
||||||
|
Some(ylo),
|
||||||
|
Some(yhi),
|
||||||
|
Some(zlo),
|
||||||
|
Some(zhi),
|
||||||
|
) = parse_cmd_args!(args, String, String, i32, i32, i32, i32, i32, i32)
|
||||||
{
|
{
|
||||||
let build_areas = server.state.mut_resource::<BuildAreas>();
|
let special_areas = get_areas_mut(&kind, &mut server.state)?;
|
||||||
let msg = ServerGeneral::server_msg(
|
let msg = ServerGeneral::server_msg(
|
||||||
ChatType::CommandInfo,
|
ChatType::CommandInfo,
|
||||||
format!("Created build zone {}", area_name),
|
format!("Created {kind} zone {}", area_name),
|
||||||
);
|
);
|
||||||
build_areas
|
special_areas
|
||||||
.insert(area_name, Aabb {
|
.insert(area_name, Aabb {
|
||||||
min: Vec3::new(xlo, ylo, zlo),
|
min: Vec3::new(xlo, ylo, zlo),
|
||||||
max: Vec3::new(xhi, yhi, zhi),
|
max: Vec3::new(xhi, yhi, zhi),
|
||||||
})
|
})
|
||||||
.map_err(|area_name| format!("Build zone {} already exists!", area_name))?;
|
.map_err(|area_name| format!("{kind} zone {} already exists!", area_name))?;
|
||||||
server.notify_client(client, msg);
|
server.notify_client(client, msg);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -2034,54 +2052,67 @@ fn handle_build_area_add(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_build_area_list(
|
fn handle_area_list(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
client: EcsEntity,
|
client: EcsEntity,
|
||||||
_target: EcsEntity,
|
_target: EcsEntity,
|
||||||
_args: Vec<String>,
|
_args: Vec<String>,
|
||||||
_action: &ServerChatCommand,
|
_action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
let build_areas = server.state.mut_resource::<BuildAreas>();
|
let format_areas = |areas: &Areas, kind: &str| {
|
||||||
let msg = ServerGeneral::server_msg(
|
areas
|
||||||
ChatType::CommandInfo,
|
.area_metas()
|
||||||
build_areas.area_names().iter().fold(
|
.iter()
|
||||||
"Build Areas:".to_string(),
|
.fold(format!("{kind} areas:"), |acc, (area_name, bb_id)| {
|
||||||
|acc, (area_name, bb_id)| {
|
if let Some(aabb) = areas.areas().get(*bb_id) {
|
||||||
if let Some(aabb) = build_areas.areas().get(*bb_id) {
|
format!("{}\n{}: {} to {} ()", acc, area_name, aabb.min, aabb.max,)
|
||||||
format!("{}\n{}: {} to {}", acc, area_name, aabb.min, aabb.max)
|
|
||||||
} else {
|
} else {
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
),
|
};
|
||||||
|
let build_message = format_areas(
|
||||||
|
server.state.mut_resource::<AreasContainer<BuildArea>>(),
|
||||||
|
"Build",
|
||||||
|
);
|
||||||
|
let no_dura_message = format_areas(
|
||||||
|
server
|
||||||
|
.state
|
||||||
|
.mut_resource::<AreasContainer<NoDurabilityArea>>(),
|
||||||
|
"Durability free",
|
||||||
|
);
|
||||||
|
|
||||||
|
let msg = ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
[build_message, no_dura_message].join("\n"),
|
||||||
);
|
);
|
||||||
|
|
||||||
server.notify_client(client, msg);
|
server.notify_client(client, msg);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_build_area_remove(
|
fn handle_area_remove(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
client: EcsEntity,
|
client: EcsEntity,
|
||||||
_target: EcsEntity,
|
_target: EcsEntity,
|
||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
action: &ServerChatCommand,
|
action: &ServerChatCommand,
|
||||||
) -> CmdResult<()> {
|
) -> CmdResult<()> {
|
||||||
if let Some(area_name) = parse_cmd_args!(args, String) {
|
if let (Some(area_name), Some(kind)) = parse_cmd_args!(args, String, String) {
|
||||||
let build_areas = server.state.mut_resource::<BuildAreas>();
|
let areas = get_areas_mut(&kind, &mut server.state)?;
|
||||||
|
|
||||||
build_areas.remove(&area_name).map_err(|err| match err {
|
areas.remove(&area_name).map_err(|err| match err {
|
||||||
BuildAreaError::Reserved => format!(
|
SpecialAreaError::Reserved => format!(
|
||||||
"Build area is reserved and cannot be removed: {}",
|
"Special area is reserved and cannot be removed: {}",
|
||||||
area_name
|
area_name
|
||||||
),
|
),
|
||||||
BuildAreaError::NotFound => format!("No such build area {}", area_name),
|
SpecialAreaError::NotFound => format!("No such build area {}", area_name),
|
||||||
})?;
|
})?;
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(
|
ServerGeneral::server_msg(
|
||||||
ChatType::CommandInfo,
|
ChatType::CommandInfo,
|
||||||
format!("Removed build zone {}", area_name),
|
format!("Removed {kind} zone {area_name}"),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -38,7 +38,7 @@ use common::{
|
|||||||
Damage, DamageKind, DamageSource, Explosion, GroupTarget, RadiusEffect,
|
Damage, DamageKind, DamageSource, Explosion, GroupTarget, RadiusEffect,
|
||||||
};
|
};
|
||||||
use common_net::{msg::ServerGeneral, sync::WorldSyncExt};
|
use common_net::{msg::ServerGeneral, sync::WorldSyncExt};
|
||||||
use common_state::BlockChange;
|
use common_state::{AreasContainer, BlockChange, NoDurabilityArea};
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use specs::{
|
use specs::{
|
||||||
@ -521,9 +521,28 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, last_change: Healt
|
|||||||
true
|
true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let resists_durability = state
|
||||||
|
.ecs()
|
||||||
|
.read_storage::<Pos>()
|
||||||
|
.get(entity)
|
||||||
|
.cloned()
|
||||||
|
.map_or(false, |our_pos| {
|
||||||
|
let areas_container = state
|
||||||
|
.ecs()
|
||||||
|
.read_resource::<AreasContainer<NoDurabilityArea>>();
|
||||||
|
let our_pos = our_pos.0.map(|i| i as i32);
|
||||||
|
|
||||||
|
let is_in_area = areas_container
|
||||||
|
.areas()
|
||||||
|
.iter()
|
||||||
|
.any(|(_, area)| area.contains_point(our_pos));
|
||||||
|
|
||||||
|
is_in_area
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: Do we need to do this if `should_delete` is true?
|
// TODO: Do we need to do this if `should_delete` is true?
|
||||||
// Modify durability on all equipped items
|
// Modify durability on all equipped items
|
||||||
if let Some(mut inventory) = state.ecs().write_storage::<Inventory>().get_mut(entity) {
|
if !resists_durability && let Some(mut inventory) = state.ecs().write_storage::<Inventory>().get_mut(entity) {
|
||||||
let ecs = state.ecs();
|
let ecs = state.ecs();
|
||||||
let ability_map = ecs.read_resource::<AbilityMap>();
|
let ability_map = ecs.read_resource::<AbilityMap>();
|
||||||
let msm = ecs.read_resource::<MaterialStatManifest>();
|
let msm = ecs.read_resource::<MaterialStatManifest>();
|
||||||
|
@ -89,7 +89,7 @@ use common_net::{
|
|||||||
msg::{ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerMsg},
|
msg::{ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerMsg},
|
||||||
sync::WorldSyncExt,
|
sync::WorldSyncExt,
|
||||||
};
|
};
|
||||||
use common_state::{BlockDiff, BuildAreas, State};
|
use common_state::{AreasContainer, BlockDiff, BuildArea, State};
|
||||||
use common_systems::add_local_systems;
|
use common_systems::add_local_systems;
|
||||||
use metrics::{EcsSystemMetrics, PhysicsMetrics, TickMetrics};
|
use metrics::{EcsSystemMetrics, PhysicsMetrics, TickMetrics};
|
||||||
use network::{ListenAddr, Network, Pid};
|
use network::{ListenAddr, Network, Pid};
|
||||||
@ -447,7 +447,7 @@ impl Server {
|
|||||||
|
|
||||||
state
|
state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_resource::<BuildAreas>()
|
.write_resource::<AreasContainer<BuildArea>>()
|
||||||
.insert("world".to_string(), world_aabb)
|
.insert("world".to_string(), world_aabb)
|
||||||
.expect("The initial insert should always work.");
|
.expect("The initial insert should always work.");
|
||||||
}
|
}
|
||||||
|
@ -496,6 +496,7 @@ impl StateExt for State {
|
|||||||
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
|
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
|
||||||
};
|
};
|
||||||
let time = self.get_time();
|
let time = self.get_time();
|
||||||
|
// TODO: Consider using the area system for this
|
||||||
self.ecs_mut()
|
self.ecs_mut()
|
||||||
.create_entity_synced()
|
.create_entity_synced()
|
||||||
.with(pos)
|
.with(pos)
|
||||||
|
@ -16,7 +16,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use common_ecs::{Job, Origin, Phase, System};
|
use common_ecs::{Job, Origin, Phase, System};
|
||||||
use common_net::msg::{ClientGeneral, ServerGeneral};
|
use common_net::msg::{ClientGeneral, ServerGeneral};
|
||||||
use common_state::{BlockChange, BuildAreas};
|
use common_state::{AreasContainer, BlockChange, BuildArea};
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage};
|
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage};
|
||||||
@ -62,7 +62,7 @@ impl Sys {
|
|||||||
orientation: Option<&mut Ori>,
|
orientation: Option<&mut Ori>,
|
||||||
controller: Option<&mut Controller>,
|
controller: Option<&mut Controller>,
|
||||||
settings: &Read<'_, Settings>,
|
settings: &Read<'_, Settings>,
|
||||||
build_areas: &Read<'_, BuildAreas>,
|
build_areas: &Read<'_, AreasContainer<BuildArea>>,
|
||||||
player_physics_setting: Option<&mut PlayerPhysicsSetting>,
|
player_physics_setting: Option<&mut PlayerPhysicsSetting>,
|
||||||
maybe_admin: &Option<&Admin>,
|
maybe_admin: &Option<&Admin>,
|
||||||
time_for_vd_changes: Instant,
|
time_for_vd_changes: Instant,
|
||||||
@ -335,7 +335,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
WriteStorage<'a, Client>,
|
WriteStorage<'a, Client>,
|
||||||
WriteStorage<'a, Controller>,
|
WriteStorage<'a, Controller>,
|
||||||
Read<'a, Settings>,
|
Read<'a, Settings>,
|
||||||
Read<'a, BuildAreas>,
|
Read<'a, AreasContainer<BuildArea>>,
|
||||||
Write<'a, PlayerPhysicsSettings>,
|
Write<'a, PlayerPhysicsSettings>,
|
||||||
TerrainPersistenceData<'a>,
|
TerrainPersistenceData<'a>,
|
||||||
ReadStorage<'a, Player>,
|
ReadStorage<'a, Player>,
|
||||||
|
Loading…
Reference in New Issue
Block a user