mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'desttinghim/build-areas' into 'master'
Build Areas See merge request veloren/veloren!1978
This commit is contained in:
commit
973a2af753
@ -14,9 +14,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- You can now jump out of rolls for a slight jump boost
|
||||
- Dungeons now have multiple kinds of stairs.
|
||||
- Trades now display item prices in tooltips.
|
||||
- Admin designated build areas
|
||||
|
||||
### Changed
|
||||
|
||||
- Permission to build is no longer tied to being an admin
|
||||
|
||||
### Removed
|
||||
|
||||
### Fixed
|
||||
|
@ -40,6 +40,9 @@ pub enum ChatCommand {
|
||||
Alias,
|
||||
Ban,
|
||||
Build,
|
||||
BuildAreaAdd,
|
||||
BuildAreaList,
|
||||
BuildAreaRemove,
|
||||
Campfire,
|
||||
Debug,
|
||||
DebugColumn,
|
||||
@ -68,9 +71,12 @@ pub enum ChatCommand {
|
||||
MakeSprite,
|
||||
Motd,
|
||||
Object,
|
||||
PermitBuild,
|
||||
Players,
|
||||
Region,
|
||||
RemoveLights,
|
||||
RevokeBuild,
|
||||
RevokeBuildAll,
|
||||
Safezone,
|
||||
Say,
|
||||
SetMotd,
|
||||
@ -94,6 +100,9 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
|
||||
ChatCommand::Alias,
|
||||
ChatCommand::Ban,
|
||||
ChatCommand::Build,
|
||||
ChatCommand::BuildAreaAdd,
|
||||
ChatCommand::BuildAreaList,
|
||||
ChatCommand::BuildAreaRemove,
|
||||
ChatCommand::Campfire,
|
||||
ChatCommand::Debug,
|
||||
ChatCommand::DebugColumn,
|
||||
@ -122,9 +131,12 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
|
||||
ChatCommand::MakeSprite,
|
||||
ChatCommand::Motd,
|
||||
ChatCommand::Object,
|
||||
ChatCommand::PermitBuild,
|
||||
ChatCommand::Players,
|
||||
ChatCommand::Region,
|
||||
ChatCommand::RemoveLights,
|
||||
ChatCommand::RevokeBuild,
|
||||
ChatCommand::RevokeBuildAll,
|
||||
ChatCommand::Safezone,
|
||||
ChatCommand::Say,
|
||||
ChatCommand::SetMotd,
|
||||
@ -235,7 +247,26 @@ impl ChatCommand {
|
||||
"Ban a player with a given username",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::Build => cmd(vec![], "Toggles build mode on and off", Admin),
|
||||
ChatCommand::Build => cmd(vec![], "Toggles build mode on and off", NoAdmin),
|
||||
ChatCommand::BuildAreaAdd => cmd(
|
||||
vec![
|
||||
Any("name", Required),
|
||||
Integer("xlo", 0, Required),
|
||||
Integer("xhi", 10, Required),
|
||||
Integer("ylo", 0, Required),
|
||||
Integer("yhi", 10, Required),
|
||||
Integer("zlo", 0, Required),
|
||||
Integer("zhi", 10, Required),
|
||||
],
|
||||
"Adds a new build area",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::BuildAreaList => cmd(vec![], "List all build areas", Admin),
|
||||
ChatCommand::BuildAreaRemove => cmd(
|
||||
vec![Any("name", Required)],
|
||||
"Removes specified build area",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::Campfire => cmd(vec![], "Spawns a campfire", Admin),
|
||||
ChatCommand::Debug => cmd(vec![], "Place all debug items into your pack.", Admin),
|
||||
ChatCommand::DebugColumn => cmd(
|
||||
@ -368,12 +399,27 @@ impl ChatCommand {
|
||||
"Spawn an object",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::PermitBuild => cmd(
|
||||
vec![Any("area_name", Required)],
|
||||
"Grants player a bounded box they can build in",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::Players => cmd(vec![], "Lists players currently online", NoAdmin),
|
||||
ChatCommand::RemoveLights => cmd(
|
||||
vec![Float("radius", 20.0, Optional)],
|
||||
"Removes all lights spawned by players",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::RevokeBuild => cmd(
|
||||
vec![Any("area_name", Required)],
|
||||
"Revokes build area permission for player",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::RevokeBuildAll => cmd(
|
||||
vec![],
|
||||
"Revokes all build area permissions for player",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::Region => cmd(
|
||||
vec![Message(Optional)],
|
||||
"Send messages to everyone in your region of the world",
|
||||
@ -460,6 +506,9 @@ impl ChatCommand {
|
||||
ChatCommand::Alias => "alias",
|
||||
ChatCommand::Ban => "ban",
|
||||
ChatCommand::Build => "build",
|
||||
ChatCommand::BuildAreaAdd => "build_area_add",
|
||||
ChatCommand::BuildAreaList => "build_area_list",
|
||||
ChatCommand::BuildAreaRemove => "build_area_remove",
|
||||
ChatCommand::Campfire => "campfire",
|
||||
ChatCommand::Debug => "debug",
|
||||
ChatCommand::DebugColumn => "debug_column",
|
||||
@ -488,9 +537,12 @@ impl ChatCommand {
|
||||
ChatCommand::MakeSprite => "make_sprite",
|
||||
ChatCommand::Motd => "motd",
|
||||
ChatCommand::Object => "object",
|
||||
ChatCommand::PermitBuild => "permit_build",
|
||||
ChatCommand::Players => "players",
|
||||
ChatCommand::Region => "region",
|
||||
ChatCommand::RemoveLights => "remove_lights",
|
||||
ChatCommand::RevokeBuild => "revoke_build",
|
||||
ChatCommand::RevokeBuildAll => "revoke_build_all",
|
||||
ChatCommand::Safezone => "safezone",
|
||||
ChatCommand::Say => "say",
|
||||
ChatCommand::SetMotd => "set_motd",
|
||||
|
@ -1,8 +1,15 @@
|
||||
use crate::depot::Id;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, DerefFlaggedStorage, NullStorage};
|
||||
use specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::collections::HashSet;
|
||||
use vek::geom::Aabb;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct CanBuild;
|
||||
impl Component for CanBuild {
|
||||
type Storage = DerefFlaggedStorage<Self, NullStorage<Self>>;
|
||||
pub struct CanBuild {
|
||||
pub enabled: bool,
|
||||
pub build_areas: HashSet<Id<Aabb<i32>>>,
|
||||
}
|
||||
impl Component for CanBuild {
|
||||
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
|
||||
fmt, hash,
|
||||
@ -6,6 +7,7 @@ use std::{
|
||||
};
|
||||
|
||||
/// Type safe index into Depot
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Id<T> {
|
||||
idx: u32,
|
||||
gen: u32,
|
||||
|
@ -6,6 +6,7 @@ use crate::plugin::PluginMgr;
|
||||
use common::uid::UidAllocator;
|
||||
use common::{
|
||||
comp,
|
||||
depot::{Depot, Id},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
region::RegionMap,
|
||||
resources::{DeltaTime, GameMode, PlayerEntity, Time, TimeOfDay},
|
||||
@ -39,6 +40,21 @@ 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: Depot<geom::Aabb<i32>>,
|
||||
pub area_names: HashMap<String, Id<Aabb<i32>>>,
|
||||
}
|
||||
|
||||
impl BuildAreas {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
areas: Depot::default(),
|
||||
area_names: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BlockChange {
|
||||
blocks: HashMap<Vec3<i32>, Block>,
|
||||
@ -204,6 +220,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::<LocalEvent>::default());
|
||||
ecs.insert(game_mode);
|
||||
|
@ -30,9 +30,15 @@ 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::{
|
||||
collections::HashSet,
|
||||
convert::TryFrom,
|
||||
ops::{Deref, DerefMut},
|
||||
time::Duration,
|
||||
};
|
||||
use vek::*;
|
||||
use world::util::Sampler;
|
||||
|
||||
@ -81,6 +87,9 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
|
||||
ChatCommand::Alias => handle_alias,
|
||||
ChatCommand::Ban => handle_ban,
|
||||
ChatCommand::Build => handle_build,
|
||||
ChatCommand::BuildAreaAdd => handle_build_area_add,
|
||||
ChatCommand::BuildAreaList => handle_build_area_list,
|
||||
ChatCommand::BuildAreaRemove => handle_build_area_remove,
|
||||
ChatCommand::Campfire => handle_spawn_campfire,
|
||||
ChatCommand::Debug => handle_debug,
|
||||
ChatCommand::DebugColumn => handle_debug_column,
|
||||
@ -109,9 +118,12 @@ fn get_handler(cmd: &ChatCommand) -> CommandHandler {
|
||||
ChatCommand::MakeSprite => handle_make_sprite,
|
||||
ChatCommand::Motd => handle_motd,
|
||||
ChatCommand::Object => handle_object,
|
||||
ChatCommand::PermitBuild => handle_permit_build,
|
||||
ChatCommand::Players => handle_players,
|
||||
ChatCommand::Region => handle_region,
|
||||
ChatCommand::RemoveLights => handle_remove_lights,
|
||||
ChatCommand::RevokeBuild => handle_revoke_build,
|
||||
ChatCommand::RevokeBuildAll => handle_revoke_build_all,
|
||||
ChatCommand::Safezone => handle_safezone,
|
||||
ChatCommand::Say => handle_say,
|
||||
ChatCommand::SetMotd => handle_set_motd,
|
||||
@ -1116,6 +1128,105 @@ fn handle_safezone(
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_permit_build(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
target: EcsEntity,
|
||||
args: String,
|
||||
action: &ChatCommand,
|
||||
) {
|
||||
if let Some(area_name) = scan_fmt_some!(&args, &action.arg_fmt(), String) {
|
||||
let ecs = server.state.ecs();
|
||||
if server
|
||||
.state
|
||||
.read_storage::<comp::CanBuild>()
|
||||
.get(target)
|
||||
.is_none()
|
||||
{
|
||||
let _ = ecs
|
||||
.write_storage::<comp::CanBuild>()
|
||||
.insert(target, comp::CanBuild {
|
||||
enabled: false,
|
||||
build_areas: HashSet::new(),
|
||||
});
|
||||
}
|
||||
if let Some(bb_id) = ecs
|
||||
.read_resource::<BuildAreas>()
|
||||
.deref()
|
||||
.area_names
|
||||
.get(&area_name)
|
||||
{
|
||||
if let Some(mut comp_can_build) = ecs.write_storage::<comp::CanBuild>().get_mut(target)
|
||||
{
|
||||
comp_can_build.build_areas.insert(*bb_id);
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("Permission to build in {} granted", area_name),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, action.help_string()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_revoke_build(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
target: EcsEntity,
|
||||
args: String,
|
||||
action: &ChatCommand,
|
||||
) {
|
||||
if let Some(area_name) = scan_fmt_some!(&args, &action.arg_fmt(), String) {
|
||||
let ecs = server.state.ecs();
|
||||
if let Some(bb_id) = ecs
|
||||
.read_resource::<BuildAreas>()
|
||||
.deref()
|
||||
.area_names
|
||||
.get(&area_name)
|
||||
{
|
||||
if let Some(mut comp_can_build) = ecs.write_storage::<comp::CanBuild>().get_mut(target)
|
||||
{
|
||||
comp_can_build.build_areas.retain(|&x| x != *bb_id);
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("Permission to build in {} revoked", area_name),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, action.help_string()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_revoke_build_all(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
target: EcsEntity,
|
||||
_args: String,
|
||||
_action: &ChatCommand,
|
||||
) {
|
||||
let ecs = server.state.ecs();
|
||||
|
||||
ecs.write_storage::<comp::CanBuild>().remove(target);
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, "All build permissions revoked"),
|
||||
);
|
||||
}
|
||||
|
||||
fn handle_players(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
@ -1150,30 +1261,152 @@ fn handle_build(
|
||||
_args: String,
|
||||
_action: &ChatCommand,
|
||||
) {
|
||||
if server
|
||||
if let Some(mut can_build) = server
|
||||
.state
|
||||
.read_storage::<comp::CanBuild>()
|
||||
.get(target)
|
||||
.is_some()
|
||||
.ecs()
|
||||
.write_storage::<comp::CanBuild>()
|
||||
.get_mut(target)
|
||||
{
|
||||
server
|
||||
.state
|
||||
.ecs()
|
||||
.write_storage::<comp::CanBuild>()
|
||||
.remove(target);
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled off build mode!"),
|
||||
);
|
||||
if can_build.enabled {
|
||||
can_build.enabled = false;
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled off build mode!"),
|
||||
);
|
||||
} else {
|
||||
can_build.enabled = true;
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled on build mode!"),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let _ = server
|
||||
.state
|
||||
.ecs()
|
||||
.write_storage::<comp::CanBuild>()
|
||||
.insert(target, comp::CanBuild);
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled on build mode!"),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
"You do not have permission to build.",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_build_area_add(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
_target: EcsEntity,
|
||||
args: String,
|
||||
action: &ChatCommand,
|
||||
) {
|
||||
if let (Some(area_name), Some(xlo), Some(xhi), Some(ylo), Some(yhi), Some(zlo), Some(zhi)) = scan_fmt_some!(
|
||||
&args,
|
||||
&action.arg_fmt(),
|
||||
String,
|
||||
i32,
|
||||
i32,
|
||||
i32,
|
||||
i32,
|
||||
i32,
|
||||
i32
|
||||
) {
|
||||
let ecs = server.state.ecs();
|
||||
if ecs
|
||||
.read_resource::<BuildAreas>()
|
||||
.deref()
|
||||
.area_names
|
||||
.contains_key(&area_name)
|
||||
{
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("Build zone {} already exists!", area_name),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
let bb_id = ecs.write_resource::<BuildAreas>().deref_mut().areas.insert(
|
||||
Aabb {
|
||||
min: Vec3::new(xlo, ylo, zlo),
|
||||
max: Vec3::new(xhi, yhi, zhi),
|
||||
}
|
||||
.made_valid(),
|
||||
);
|
||||
ecs.write_resource::<BuildAreas>()
|
||||
.deref_mut()
|
||||
.area_names
|
||||
.insert(area_name.clone(), bb_id);
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("Created build zone {}", area_name),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_build_area_list(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
_target: EcsEntity,
|
||||
_args: String,
|
||||
_action: &ChatCommand,
|
||||
) {
|
||||
let ecs = server.state.ecs();
|
||||
let build_areas = ecs.read_resource::<BuildAreas>();
|
||||
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
build_areas.area_names.iter().fold(
|
||||
"Build Areas:".to_string(),
|
||||
|acc, (area_name, bb_id)| {
|
||||
if let Some(aabb) = build_areas.areas.get(*bb_id) {
|
||||
format!("{}\n{}: {} to {}", acc, area_name, aabb.min, aabb.max)
|
||||
} else {
|
||||
acc
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
fn handle_build_area_remove(
|
||||
server: &mut Server,
|
||||
client: EcsEntity,
|
||||
_target: EcsEntity,
|
||||
args: String,
|
||||
action: &ChatCommand,
|
||||
) {
|
||||
if let Some(area_name) = scan_fmt_some!(&args, &action.arg_fmt(), String) {
|
||||
let ecs = server.state.ecs();
|
||||
let mut build_areas = ecs.write_resource::<BuildAreas>();
|
||||
|
||||
let bb_id = match build_areas.area_names.get(&area_name) {
|
||||
Some(x) => *x,
|
||||
None => {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("No such build area '{}'", area_name),
|
||||
),
|
||||
);
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
let _ = build_areas.area_names.remove(&area_name);
|
||||
let _ = build_areas.areas.remove(bb_id);
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("Removed build zone {}", area_name),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -102,13 +103,39 @@ impl Sys {
|
||||
}
|
||||
},
|
||||
ClientGeneral::BreakBlock(pos) => {
|
||||
if let Some(block) = can_build.get(entity).and_then(|_| terrain.get(pos).ok()) {
|
||||
block_changes.set(pos, block.into_vacant());
|
||||
if let Some(comp_can_build) = can_build.get(entity) {
|
||||
if comp_can_build.enabled {
|
||||
for area in comp_can_build.build_areas.iter() {
|
||||
if let Some(block) = build_areas
|
||||
.areas
|
||||
.get(*area)
|
||||
// TODO: Make this an exclusive check on the upper bound of the AABB
|
||||
// Vek defaults to inclusive which is not optimal
|
||||
.filter(|aabb| aabb.contains_point(pos))
|
||||
.and_then(|_| terrain.get(pos).ok())
|
||||
{
|
||||
block_changes.set(pos, block.into_vacant());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ClientGeneral::PlaceBlock(pos, block) => {
|
||||
if can_build.get(entity).is_some() {
|
||||
block_changes.try_set(pos, block);
|
||||
if let Some(comp_can_build) = can_build.get(entity) {
|
||||
if comp_can_build.enabled {
|
||||
for area in comp_can_build.build_areas.iter() {
|
||||
if build_areas
|
||||
.areas
|
||||
.get(*area)
|
||||
// TODO: Make this an exclusive check on the upper bound of the AABB
|
||||
// Vek defaults to inclusive which is not optimal
|
||||
.filter(|aabb| aabb.contains_point(pos))
|
||||
.is_some()
|
||||
{
|
||||
block_changes.try_set(pos, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ClientGeneral::UnlockSkill(skill) => {
|
||||
@ -156,6 +183,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";
|
||||
@ -180,6 +208,7 @@ impl<'a> System<'a> for Sys {
|
||||
mut clients,
|
||||
mut controllers,
|
||||
settings,
|
||||
build_areas,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
let mut server_emitter = server_event_bus.emitter();
|
||||
@ -204,6 +233,7 @@ impl<'a> System<'a> for Sys {
|
||||
&mut orientations,
|
||||
&mut controllers,
|
||||
&settings,
|
||||
&build_areas,
|
||||
msg,
|
||||
)
|
||||
});
|
||||
|
@ -317,7 +317,7 @@ impl PlayState for SessionState {
|
||||
.state()
|
||||
.read_storage::<comp::CanBuild>()
|
||||
.get(player_entity)
|
||||
.is_some();
|
||||
.map_or_else(|| false, |cb| cb.enabled);
|
||||
|
||||
let is_mining = self
|
||||
.client
|
||||
|
Loading…
Reference in New Issue
Block a user