alex/beta-minecraft-rust
Minecraft Beta 1.7.3 Rewrite
BRANCH main
SNAPSHOT Draw terrain GPU-driven from packed per-section buffers with GPU occlusion culling, add a render distance slider (2-128) with a quad/disk shape, cut chunk bookkeeping at high render distances, and fix a light underflow at y=0
DOWNLOAD
root crates server src level tiles.rs
use common::inventory::tick_furnace;
use common::world::{Block, ChunkPos, TileEntity};
use super::Level;
impl Level {
pub fn tick_tiles(&mut self) {
let mut positions = std::mem::take(&mut self.tile_tick_buffer);
positions.extend(self.ticking_tiles.iter().copied());
for &position in &positions {
match self.tile_entity(position[0], position[1], position[2]) {
Some(TileEntity::Furnace { .. }) => self.tick_furnace(position),
Some(TileEntity::MobSpawner { .. }) => self.tick_spawner(position),
Some(TileEntity::Piston { .. }) => crate::blocks::tick_piston(self, position),
_ => {}
}
}
positions.clear();
self.tile_tick_buffer = positions;
}
fn tick_furnace(&mut self, [x, y, z]: [i32; 3]) {
let pos = ChunkPos::containing(x, z);
let Some(chunk) = self.chunks.get_mut(&pos) else {
return;
};
let Some(tile @ TileEntity::Furnace { .. }) =
chunk.tile_entity_mut((x & 15) as usize, y as usize, (z & 15) as usize)
else {
return;
};
let state = |tile: &TileEntity| match *tile {
TileEntity::Furnace {
burn_time,
items,
cook_time,
..
} => (burn_time > 0, items, cook_time),
_ => unreachable!(),
};
let (was_burning, old_items, old_cook) = state(tile);
tick_furnace(tile);
let (burning, items, cook) = state(tile);
if was_burning || burning || cook != old_cook || items != old_items {
self.unsaved.insert(pos);
}
if was_burning != burning {
// `BlockFurnace.updateFurnaceBlockState` keeps the same furnace
let generation = self.tile_generation([x, y, z]);
let tile = self.remove_tile_entity(x, y, z).unwrap();
let metadata = self.metadata(x, y, z);
let block = if burning {
Block::LIT_FURNACE
} else {
Block::FURNACE
};
self.set_block_with_metadata_notify(x, y, z, block, metadata);
self.set_tile_entity(x, y, z, tile);
match generation {
Some(generation) => self.tile_generations.insert([x, y, z], generation),
None => self.tile_generations.remove(&[x, y, z]),
};
} else if items != old_items {
self.mark(x, y, z);
}
}
}