Add CanBuild component, Block placing client messages and build mode command

This commit is contained in:
Piotr Korgól 2019-07-02 20:19:16 +02:00
parent 9977322ba6
commit bf748ae742
7 changed files with 85 additions and 6 deletions

View File

@ -12,7 +12,7 @@ use common::{
msg::{ClientMsg, ClientState, ServerInfo, ServerMsg},
net::PostBox,
state::State,
terrain::{chonk::ChonkMetrics, TerrainChunk, TerrainChunkSize},
terrain::{block::Block, chonk::ChonkMetrics, TerrainChunk, TerrainChunkSize},
vol::VolSize,
};
use log::{info, log_enabled, warn};
@ -185,6 +185,14 @@ impl Client {
self.pending_chunks.clear();
}
pub fn place_block(&mut self, pos: Vec3<i32>, block: Block) {
self.postbox.send_message(ClientMsg::PlaceBlock(pos, block));
}
pub fn remove_block(&mut self, pos: Vec3<i32>) {
self.postbox.send_message(ClientMsg::BreakBlock(pos));
}
/// Execute a single client tick, handle input and update the game state by the given duration.
#[allow(dead_code)]
pub fn tick(

View File

@ -28,6 +28,9 @@ pub struct Rolling {
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct OnGround;
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct CanBuild;
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct Jumping;
@ -85,6 +88,10 @@ impl Component for OnGround {
type Storage = NullStorage<Self>;
}
impl Component for CanBuild {
type Storage = NullStorage<Self>;
}
impl Component for Jumping {
type Storage = NullStorage<Self>;
}

View File

@ -15,7 +15,9 @@ pub use agent::Agent;
pub use animation::{Animation, AnimationInfo};
pub use body::{humanoid, quadruped, quadruped_medium, Body};
pub use controller::Controller;
pub use inputs::{Attacking, Gliding, Jumping, MoveDir, OnGround, Respawning, Rolling, Wielding};
pub use inputs::{
Attacking, CanBuild, Gliding, Jumping, MoveDir, OnGround, Respawning, Rolling, Wielding,
};
pub use inventory::{item, Inventory};
pub use phys::{ForceUpdate, Ori, Pos, Vel};
pub use player::Player;

View File

@ -1,5 +1,6 @@
use super::ClientState;
use crate::comp;
use crate::terrain::block::Block;
use vek::*;
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -14,6 +15,8 @@ pub enum ClientMsg {
Controller(comp::Controller),
RequestState(ClientState),
SetViewDistance(u32),
BreakBlock(Vec3<i32>),
PlaceBlock(Vec3<i32>, Block),
Ping,
Pong,
Chat(String),

View File

@ -46,7 +46,7 @@ pub struct DeltaTime(pub f32);
const MAX_DELTA_TIME: f32 = 1.0;
pub struct TerrainChange {
blocks: HashMap<Vec3<i32>, Block>,
pub blocks: HashMap<Vec3<i32>, Block>,
}
impl Default for TerrainChange {
@ -136,6 +136,7 @@ impl State {
ecs.register::<comp::Ori>();
ecs.register::<comp::MoveDir>();
ecs.register::<comp::OnGround>();
ecs.register::<comp::CanBuild>();
ecs.register::<comp::Controller>();
ecs.register::<comp::Attacking>();
ecs.register::<comp::Wielding>();

View File

@ -125,7 +125,13 @@ lazy_static! {
"{}",
"/health : Set your current health",
handle_health,
)
),
ChatCommand::new(
"build",
"",
"/build : Toggles build mode on and off",
handle_build,
),
];
}
@ -397,6 +403,33 @@ fn handle_empty(server: &mut Server, entity: EcsEntity, _args: String, _action:
}
}
fn handle_build(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
match server.state.read_component_cloned::<comp::CanBuild>(entity) {
Some(_build_perms) => {
server
.state
.ecs()
.write_storage::<comp::CanBuild>()
.remove(entity);
server.clients.notify(
entity,
ServerMsg::Chat(String::from("Toggled on build mode!")),
);
}
None => {
let _ = server
.state
.ecs()
.write_storage::<comp::CanBuild>()
.insert(entity, comp::CanBuild);
server.clients.notify(
entity,
ServerMsg::Chat(String::from("Toggled off build mode!")),
);
}
}
}
fn handle_help(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
for cmd in CHAT_COMMANDS.iter() {
server

View File

@ -16,9 +16,10 @@ use common::{
comp,
msg::{ClientMsg, ClientState, RequestStateError, ServerInfo, ServerMsg},
net::PostOffice,
state::{State, Uid},
terrain::{TerrainChunk, TerrainChunkSize, TerrainMap},
state::{State, TerrainChange, Uid},
terrain::{block::Block, TerrainChunk, TerrainChunkSize, TerrainMap},
vol::VolSize,
vol::Vox,
};
use log::debug;
use specs::{join::Join, world::EntityBuilder as EcsEntityBuilder, Builder, Entity as EcsEntity};
@ -500,6 +501,30 @@ impl Server {
// Only characters can send positions.
_ => client.error_state(RequestStateError::Impossible),
},
ClientMsg::BreakBlock(pos) => {
if state
.ecs_mut()
.read_storage::<comp::CanBuild>()
.get(entity)
.is_some()
{
let mut terrain_change =
state.ecs().write_resource::<TerrainChange>();
terrain_change.set(pos, Block::empty());
}
}
ClientMsg::PlaceBlock(pos, block) => {
if state
.ecs_mut()
.read_storage::<comp::CanBuild>()
.get(entity)
.is_some()
{
let mut terrain_change =
state.ecs().write_resource::<TerrainChange>();
terrain_change.set(pos, block);
}
}
ClientMsg::TerrainChunkRequest { key } => match client.client_state {
ClientState::Connected
| ClientState::Registered