diff --git a/src/main.rs b/src/main.rs index f02d5d9..7b2efc6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -339,6 +339,11 @@ fn handle_window_event(window: &sdl2::video::Window, ui_container.click_at(game, x as f64, y as f64, width as f64, height as f64); } } + Event::MouseButtonDown{mouse_btn: Mouse::Right, ..} => { + if game.focused { + game.server.on_right_click(&mut game.renderer); + } + } Event::MouseWheel{x, y, ..} => { game.screen_sys.on_scroll(x as f64, y as f64); } diff --git a/src/server/mod.rs b/src/server/mod.rs index d556ec2..27c612b 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -348,7 +348,7 @@ impl Server { self.world.tick(&mut self.entities); - if let Some((pos, bl)) = target::trace_ray(&self.world, 4.0, renderer.camera.pos.to_vec(), renderer.view_vector.cast(), target::test_block) { + if let Some((pos, bl, _, _)) = target::trace_ray(&self.world, 4.0, renderer.camera.pos.to_vec(), renderer.view_vector.cast(), target::test_block) { self.target_info.update(renderer, pos, bl); } else { self.target_info.clear(renderer); @@ -502,6 +502,30 @@ impl Server { } } + pub fn on_right_click(&mut self, renderer: &mut render::Renderer) { + use shared::Direction; + if self.player.is_some() { + if let Some((pos, _, face, at)) = target::trace_ray(&self.world, 4.0, renderer.camera.pos.to_vec(), renderer.view_vector.cast(), target::test_block) { + self.write_packet(packet::play::serverbound::PlayerBlockPlacement { + location: pos, + face: protocol::VarInt(match face { + Direction::Down => 0, + Direction::Up => 1, + Direction::North => 2, + Direction::South => 3, + Direction::West => 4, + Direction::East => 5, + _ => unreachable!(), + }), + hand: protocol::VarInt(0), + cursor_x: (at.x * 16.0) as u8, + cursor_y: (at.y * 16.0) as u8, + cursor_z: (at.z * 16.0) as u8, + }); + } + } + } + pub fn write_packet(&mut self, p: T) { let _ = self.conn.as_mut().unwrap().write_packet(p); // TODO handle errors } diff --git a/src/server/target.rs b/src/server/target.rs index b7fdebd..75a6a4e 100644 --- a/src/server/target.rs +++ b/src/server/target.rs @@ -1,7 +1,7 @@ use world; use world::block; -use shared::Position; +use shared::{Position, Direction}; use cgmath; use render; use render::model; @@ -105,19 +105,38 @@ impl Info { } } -pub fn test_block(world: &world::World, pos: Position, s: cgmath::Vector3, d: cgmath::Vector3) -> (bool, Option<(Position, block::Block)>) { +pub fn test_block(world: &world::World, pos: Position, s: cgmath::Vector3, d: cgmath::Vector3) -> (bool, Option<(Position, block::Block, Direction, cgmath::Vector3)>) { let block = world.get_block(pos); + let posf = cgmath::Vector3::new(pos.x as f64, pos.y as f64, pos.z as f64); for bound in block.get_collision_boxes() { - let bound = bound.add_v(cgmath::Vector3::new(pos.x as f64, pos.y as f64, pos.z as f64)); + let bound = bound.add_v(posf); if let Some(hit) = intersects_line(bound, s, d) { - // TODO: Face/cursor - let _ = hit; - return (true, Some((pos, block))); + let cursor = hit - posf; + let face = find_face(bound, hit); + return (true, Some((pos, block, face, cursor))); } } (false, None) } +fn find_face(bound: collision::Aabb3, hit: cgmath::Vector3) -> Direction { + if (bound.min.x - hit.x).abs() < 0.01 { + Direction::West + } else if (bound.max.x - hit.x).abs() < 0.01 { + Direction::East + } else if (bound.min.y - hit.y).abs() < 0.01 { + Direction::Down + } else if (bound.max.y - hit.y).abs() < 0.01 { + Direction::Up + } else if (bound.min.z - hit.z).abs() < 0.01 { + Direction::North + } else if (bound.max.z - hit.z).abs() < 0.01 { + Direction::South + } else { + Direction::Up + } +} + fn intersects_line(bound: collision::Aabb3, origin: cgmath::Vector3, dir: cgmath::Vector3) -> Option> { const RIGHT: usize = 0; const LEFT: usize = 1;