diff --git a/src/render/shaders/lookup_texture.glsl b/src/render/shaders/lookup_texture.glsl index 3bb6a9f..33121e8 100644 --- a/src/render/shaders/lookup_texture.glsl +++ b/src/render/shaders/lookup_texture.glsl @@ -5,4 +5,4 @@ vec4 atlasTexture() { tPos += vTextureInfo.xy; tPos *= invAtlasSize; return texture(textures, vec3(tPos, vAtlas)); -} \ No newline at end of file +} diff --git a/src/world/block/mod.rs b/src/world/block/mod.rs index 87dde07..c2d8c87 100644 --- a/src/world/block/mod.rs +++ b/src/world/block/mod.rs @@ -39,6 +39,7 @@ macro_rules! define_blocks { $(variant $variant:expr,)* $(tint $tint:expr,)* $(collision $collision:expr,)* + $(update_state $update_state:expr,)* } )+ ) => ( @@ -208,6 +209,22 @@ macro_rules! define_blocks { )+ } } + + #[allow(unused_variables, unreachable_code)] + pub fn update_state(&self, world: &super::World, x: i32, y: i32, z: i32) -> Block { + match *self { + $( + Block::$name { + $($fname,)* + } => { + $(return $update_state;)* + return Block::$name { + $($fname: $fname,)* + }; + } + )+ + } + } } lazy_static! { diff --git a/src/world/mod.rs b/src/world/mod.rs index d1569c3..7912491 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -46,6 +46,11 @@ impl World { } pub fn set_block(&mut self, x: i32, y: i32, z: i32, b: block::Block) { + self.set_block_raw(x, y, z, b); + self.update_block(x, y, z); + } + + fn set_block_raw(&mut self, x: i32, y: i32, z: i32, b: block::Block) { let cpos = CPos(x >> 4, z >> 4); if !self.chunks.contains_key(&cpos) { self.chunks.insert(cpos, Chunk::new(cpos)); @@ -54,6 +59,35 @@ impl World { chunk.set_block(x & 0xF, y, z & 0xF, b); } + pub fn update_block(&mut self, x: i32, y: i32, z: i32) { + for yy in -1 .. 2 { + for zz in -1 .. 2 { + for xx in -1 .. 2 { + let (bx, by, bz) = (x+xx, y+yy, z+zz); + let current = self.get_block(bx, by, bz); + let new = current.update_state(self, bx, by, bz); + if current != new { + self.set_block_raw(bx, by, bz, new); + } + } + } + } + } + + fn update_range(&mut self, x1: i32, y1: i32, z1: i32, x2: i32, y2: i32, z2: i32) { + for by in y1 .. y2 { + for bz in z1 .. z2 { + for bx in x1 .. x2 { + let current = self.get_block(bx, by, bz); + let new = current.update_state(self, bx, by, bz); + if current != new { + self.set_block_raw(bx, by, bz, new); + } + } + } + } + } + pub fn get_block(&self, x: i32, y: i32, z: i32) -> block::Block { match self.chunks.get(&CPos(x >> 4, z >> 4)) { Some(ref chunk) => chunk.get_block(x & 0xF, y, z & 0xF), @@ -356,6 +390,10 @@ impl World { (0, 0, -1), (0, 0, 1)].into_iter() { self.flag_section_dirty(x + pos.0, i as i32 + pos.1, z + pos.2); } + self.update_range( + (x<<4) - 1, (i<<4) - 1, (z<<4) - 1, + (x<<4) + 17, (i<<4) + 17, (z<<4) + 17 + ); } Ok(()) }