diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 6592f19588..b58dc142d4 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -8,7 +8,7 @@ use crate::{ Direction, Error, GlobalState, PlayState, PlayStateResult, }; use client::{self, Client}; -use common::{clock::Clock, comp, comp::Pos, msg::ClientState}; +use common::{terrain::block::Block, ray::Ray, vol::ReadVol, clock::Clock, comp, comp::Pos, msg::ClientState}; use log::{error, warn}; use std::{cell::RefCell, rc::Rc, time::Duration}; use vek::*; @@ -108,15 +108,54 @@ impl PlayState for SessionState { return PlayStateResult::Shutdown; } Event::InputUpdate(GameInput::Attack, state) => { - if state { - if let ClientState::Character = current_client_state { - self.controller.attack = state; - } else { - self.controller.respawn = state; // TODO: Don't do both + // Check the existence of CanBuild component. If it's here, use LMB to + // place blocks, if not, use it to attack + match self.client.borrow().state().read_component_cloned::(self.client.borrow().entity()) { + Some(_build_perms) => { + println!("Placing block"); + let (view_mat, _, dist) = self.scene.camera().compute_dependents(&self.client.borrow()); + let cam_pos = self.scene.camera().compute_dependents(&self.client.borrow()).2; + let cam_dir = (view_mat.inverted() * Vec4::unit_z()).normalized(); + match self.client + .borrow() + .state() + .terrain() + .ray(cam_pos, cam_pos + cam_dir * 100.0) + .cast() + { + (d, Ok(Some((_)))) => { + let cam_pos = self.scene.camera().compute_dependents(&self.client.borrow()).2; + let cam_dir = (view_mat.inverted() * Vec4::unit_z()).normalized(); + let pos = (cam_pos + cam_dir * d).map(|e| e.floor() as i32); + self.client.borrow_mut().place_block(pos, Block::new(1, Rgb::broadcast(255)));// TODO: Handle block color with a command + }, + (_, Err(_)) => {}, + (_, Ok(None)) => {}, + }; + + }, + None => { + if state { + if let ClientState::Character = current_client_state { + self.controller.attack = state + } else { + self.controller.respawn = state; // TODO: Don't do both + } + } else { + self.controller.attack = state; + self.controller.respawn = state; + } + } + } + } + Event::InputUpdate(GameInput::SecondAttack, state) => { + match self.client.borrow().state().read_component_cloned::(self.client.borrow().entity()) { + Some(_build_perms) => { + + } + None => { + // TODO: Handle secondary attack here } - } else { - self.controller.attack = state; - self.controller.respawn = state; } } Event::InputUpdate(GameInput::Roll, state) => { diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 17f08105cd..251e904453 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -31,6 +31,7 @@ pub struct ControlSettings { pub screenshot: KeyMouse, pub toggle_ingame_ui: KeyMouse, pub attack: KeyMouse, + pub second_attack: KeyMouse, pub roll: KeyMouse, } @@ -60,6 +61,7 @@ impl Default for ControlSettings { screenshot: KeyMouse::Key(VirtualKeyCode::F4), toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6), attack: KeyMouse::Mouse(MouseButton::Left), + second_attack: KeyMouse::Mouse(MouseButton::Right), roll: KeyMouse::Mouse(MouseButton::Middle), } } diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 7259b0b72f..2a6673bcc3 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -34,6 +34,7 @@ pub enum GameInput { Screenshot, ToggleIngameUi, Attack, + SecondAttack, Roll, Respawn, } @@ -138,6 +139,7 @@ impl Window { GameInput::ToggleIngameUi, ); key_map.insert(settings.controls.attack, GameInput::Attack); + key_map.insert(settings.controls.second_attack, GameInput::SecondAttack); key_map.insert(settings.controls.roll, GameInput::Roll); let keypress_map = HashMap::new();