diff --git a/src/block_placement.rs b/src/block_placement.rs new file mode 100644 index 0000000..725472f --- /dev/null +++ b/src/block_placement.rs @@ -0,0 +1,36 @@ +use glam::Vec3; +use shipyard::{UniqueViewMut, UniqueView, View, IntoIter}; +use crate::{ + player::MainPlayer, + world::{raycast::LookingAtBlock, ChunkStorage, block::Block}, + input::Inputs +}; + +pub fn block_placement_system( + main_player: View, + raycast: View, + input: UniqueView, + mut world: UniqueViewMut +) { + //this cant process both place and break btw + if input.action_a || input.action_b { + //get raycast info + let Some(ray) = (&main_player, &raycast).iter().next().unwrap().1/**/.0 else { return }; + //update block + let is_place = input.action_b; + let place_position = if is_place { + let position = (ray.position - ray.direction * 0.5).floor().as_ivec3(); + let Some(block) = world.get_block_mut(position) else { return }; + *block = Block::Dirt; + position + } else { + let Some(block) = world.get_block_mut(ray.block_position) else { return }; + *block = Block::Air; + ray.block_position + }; + //mark chunk as dirty + let (chunk_pos, _) = ChunkStorage::to_chunk_coords(place_position); + let chunk = world.chunks.get_mut(&chunk_pos).unwrap(); + chunk.dirty = true; + } +} diff --git a/src/main.rs b/src/main.rs index 2027324..2cda345 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ pub(crate) mod camera; pub(crate) mod events; pub(crate) mod input; pub(crate) mod fly_controller; +pub(crate) mod block_placement; use rendering::{ Renderer, @@ -34,7 +35,7 @@ use rendering::{ use world::{ init_game_world, loading::update_loaded_world_around_player, - raycast::{update_raycasts, break_block_test_only} + raycast::update_raycasts }; use player::spawn_player; use prefabs::load_prefabs; @@ -47,6 +48,7 @@ use rendering::{ selection_box::render_selection_box, world::draw_world, }; +use block_placement::block_placement_system; #[derive(Unique)] pub(crate) struct DeltaTime(Duration); @@ -65,7 +67,7 @@ fn update() -> Workload { update_controllers, update_loaded_world_around_player, update_raycasts, - break_block_test_only, + block_placement_system, compute_cameras ).into_workload() } diff --git a/src/world/block.rs b/src/world/block.rs index e16641c..92fba77 100644 --- a/src/world/block.rs +++ b/src/world/block.rs @@ -47,7 +47,6 @@ impl Block { collision: CollisionType::Solid, raycast_collision: true, }, - _ => todo!() } } } @@ -59,11 +58,11 @@ pub struct BlockDescriptor { pub collision: CollisionType, pub raycast_collision: bool, } -impl BlockDescriptor { - pub fn of(block: Block) -> Self { - block.descriptor() - } -} +// impl BlockDescriptor { +// pub fn of(block: Block) -> Self { +// block.descriptor() +// } +// } #[derive(Clone, Copy, Debug)] pub struct CubeTexture { diff --git a/src/world/loading.rs b/src/world/loading.rs index 1a0af1c..a686316 100644 --- a/src/world/loading.rs +++ b/src/world/loading.rs @@ -42,7 +42,12 @@ pub fn update_chunks_if_player_moved( //If it did, get it's position and current chunk let player_position = transform.0.to_scale_rotation_translation().2; - let player_at_chunk = player_position.as_ivec3() / CHUNK_SIZE as i32; + let player_position_ivec3 = player_position.as_ivec3(); + let player_at_chunk = ivec3( + player_position_ivec3.x.div_euclid(CHUNK_SIZE as i32), + player_position_ivec3.y.div_euclid(CHUNK_SIZE as i32), + player_position_ivec3.z.div_euclid(CHUNK_SIZE as i32), + ); //Then, mark *ALL* chunks with ToUnload for (_, chunk) in &mut vm_world.chunks { diff --git a/src/world/raycast.rs b/src/world/raycast.rs index 8da93d6..3f2f407 100644 --- a/src/world/raycast.rs +++ b/src/world/raycast.rs @@ -1,6 +1,6 @@ use glam::{Vec3, IVec3}; -use shipyard::{View, Component, ViewMut, IntoIter, UniqueView, UniqueViewMut}; -use crate::{player::MainPlayer, transform::Transform, input::Inputs}; +use shipyard::{View, Component, ViewMut, IntoIter, UniqueView}; +use crate::transform::Transform; use super::{ChunkStorage, block::Block}; @@ -10,6 +10,7 @@ const RAYCAST_STEP: f32 = 0.25; pub struct RaycastReport { pub length: f32, pub position: Vec3, + pub direction: Vec3, pub block_position: IVec3, pub block: Block, } @@ -24,7 +25,13 @@ impl ChunkStorage { let block_position = position.floor().as_ivec3(); if let Some(block) = self.get_block(block_position) { if block.descriptor().raycast_collision { - return Some(RaycastReport { length, position, block_position, block }); + return Some(RaycastReport { + length, + position, + direction, + block_position, + block + }); } } length += RAYCAST_STEP; @@ -56,21 +63,3 @@ pub fn update_raycasts( *report = LookingAtBlock(world.raycast(position, direction, Some(30.))); } } - -pub fn break_block_test_only( - raycast: View, - input: UniqueView, - mut world: UniqueViewMut -) { - if input.action_a { - //get raycast info - let Some(ray) = raycast.iter().next().unwrap().0 else { return }; - //update block - let Some(block) = world.get_block_mut(ray.block_position) else { return }; - *block = Block::Air; - //mark chunk as dirty - let (chunk_pos, _) = ChunkStorage::to_chunk_coords(ray.block_position); - let chunk = world.chunks.get_mut(&chunk_pos).unwrap(); - chunk.dirty = true; - } -}