Implement interaction with blocks

This commit is contained in:
Thinkofname 2016-04-21 20:25:58 +01:00
parent 98422678a3
commit 9c816c7ea1
3 changed files with 55 additions and 7 deletions

View File

@ -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);
}

View File

@ -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<T: protocol::PacketType>(&mut self, p: T) {
let _ = self.conn.as_mut().unwrap().write_packet(p); // TODO handle errors
}

View File

@ -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<f64>, d: cgmath::Vector3<f64>) -> (bool, Option<(Position, block::Block)>) {
pub fn test_block(world: &world::World, pos: Position, s: cgmath::Vector3<f64>, d: cgmath::Vector3<f64>) -> (bool, Option<(Position, block::Block, Direction, cgmath::Vector3<f64>)>) {
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<f64>, hit: cgmath::Vector3<f64>) -> 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<f64>, origin: cgmath::Vector3<f64>, dir: cgmath::Vector3<f64>) -> Option<cgmath::Vector3<f64>> {
const RIGHT: usize = 0;
const LEFT: usize = 1;