Add permit_build command

This commit separates permission to build from building mode, allowing
build to become a NoAdmin command (since players will first need
permission from an Admin to enter build mode)
This commit is contained in:
Louis Pearson 2021-03-23 02:37:29 -06:00
parent da5c73c84b
commit eade0540b2
5 changed files with 130 additions and 29 deletions

View File

@ -68,6 +68,7 @@ pub enum ChatCommand {
MakeSprite,
Motd,
Object,
PermitBuild,
Players,
Region,
RemoveLights,
@ -122,6 +123,7 @@ pub static CHAT_COMMANDS: &[ChatCommand] = &[
ChatCommand::MakeSprite,
ChatCommand::Motd,
ChatCommand::Object,
ChatCommand::PermitBuild,
ChatCommand::Players,
ChatCommand::Region,
ChatCommand::RemoveLights,
@ -235,7 +237,7 @@ 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::Campfire => cmd(vec![], "Spawns a campfire", Admin),
ChatCommand::Debug => cmd(vec![], "Place all debug items into your pack.", Admin),
ChatCommand::DebugColumn => cmd(
@ -368,6 +370,19 @@ impl ChatCommand {
"Spawn an object",
Admin,
),
ChatCommand::PermitBuild => cmd(
vec![
PlayerName(Required),
Integer("xlo", 0, Required),
Integer("xhi", 10, Required),
Integer("ylo", 0, Required),
Integer("yhi", 10, Required),
Integer("ylo", 0, Required),
Integer("yhi", 10, 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)],
@ -488,6 +503,7 @@ 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",

View File

@ -1,8 +1,11 @@
use serde::{Deserialize, Serialize};
use specs::{Component, DerefFlaggedStorage, NullStorage};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct CanBuild;
impl Component for CanBuild {
type Storage = DerefFlaggedStorage<Self, NullStorage<Self>>;
pub struct CanBuild {
pub building_is_on: bool,
}
impl Component for CanBuild {
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -109,6 +109,7 @@ 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,
@ -1116,6 +1117,76 @@ fn handle_safezone(
}
}
fn handle_permit_build(
server: &mut Server,
client: EcsEntity,
_target: EcsEntity,
args: String,
action: &ChatCommand,
) {
if let (Some(target_alias), xlo_opt, xhi_opt, ylo_opt, yhi_opt, zlo_opt, zhi_opt) = scan_fmt_some!(
&args,
&action.arg_fmt(),
String,
i32,
i32,
i32,
i32,
i32,
i32
) {
let ecs = server.state.ecs();
let target_player_opt = (&ecs.entities(), &ecs.read_storage::<comp::Player>())
.join()
.find(|(_, player)| player.alias == target_alias)
.map(|(entity, _)| entity);
if let Some(target_player) = target_player_opt {
if server
.state
.read_storage::<comp::CanBuild>()
.get(target_player)
.is_some()
{
ecs.write_storage::<comp::CanBuild>().remove(target_player);
server.notify_client(
client,
ServerGeneral::server_msg(
ChatType::CommandInfo,
format!("Removed {}'s permission to build", target_alias),
),
);
} else {
let _ =
ecs.write_storage::<comp::CanBuild>()
.insert(target_player, comp::CanBuild {
building_is_on: false,
});
server.notify_client(
client,
ServerGeneral::server_msg(
ChatType::CommandInfo,
format!("Gave {} permission to build", target_alias),
),
);
}
} else {
server.notify_client(
client,
ServerGeneral::server_msg(
ChatType::CommandError,
format!("Player '{}' not found!", target_alias),
),
);
}
} else {
server.notify_client(
client,
ServerGeneral::server_msg(ChatType::CommandError, action.help_string()),
);
}
}
fn handle_players(
server: &mut Server,
client: EcsEntity,
@ -1150,32 +1221,34 @@ fn handle_build(
_args: String,
_action: &ChatCommand,
) {
if server
.state
.read_storage::<comp::CanBuild>()
.get(target)
.is_some()
{
server
if let Some(mut can_build) = server
.state
.ecs()
.write_storage::<comp::CanBuild>()
.remove(target);
.get_mut(target)
{
if can_build.building_is_on {
can_build.building_is_on = false;
server.notify_client(
client,
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled off build mode!"),
);
} else {
let _ = server
.state
.ecs()
.write_storage::<comp::CanBuild>()
.insert(target, comp::CanBuild);
can_build.building_is_on = true;
server.notify_client(
client,
ServerGeneral::server_msg(ChatType::CommandInfo, "Toggled on build mode!"),
);
}
} else {
server.notify_client(
client,
ServerGeneral::server_msg(
ChatType::CommandInfo,
"You do not have permission to build.",
),
);
}
}
fn handle_help(

View File

@ -102,14 +102,20 @@ impl Sys {
}
},
ClientGeneral::BreakBlock(pos) => {
if let Some(block) = can_build.get(entity).and_then(|_| terrain.get(pos).ok()) {
if let Some(comp_can_build) = can_build.get(entity) {
if comp_can_build.building_is_on {
if let Some(block) = terrain.get(pos).ok() {
block_changes.set(pos, block.into_vacant());
}
}
}
},
ClientGeneral::PlaceBlock(pos, block) => {
if can_build.get(entity).is_some() {
if let Some(comp_can_build) = can_build.get(entity) {
if comp_can_build.building_is_on {
block_changes.try_set(pos, block);
}
}
},
ClientGeneral::UnlockSkill(skill) => {
stats

View File

@ -317,7 +317,10 @@ impl PlayState for SessionState {
.state()
.read_storage::<comp::CanBuild>()
.get(player_entity)
.is_some();
.unwrap_or_else(|| &comp::CanBuild {
building_is_on: false,
})
.building_is_on;
let is_mining = self
.client