1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

start adding get_block_state

This commit is contained in:
mat 2022-05-14 14:12:57 -05:00
parent 70271ede19
commit 6d2fd8afba
6 changed files with 127 additions and 15 deletions

View file

@ -9,7 +9,7 @@ mod slot;
pub use slot::{Slot, SlotData};
mod position;
pub use position::{BlockPos, ChunkPos, ChunkSectionPos};
pub use position::{BlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos};
mod direction;
pub use direction::Direction;

View file

@ -1,3 +1,5 @@
use std::ops::Rem;
#[derive(Clone, Copy, Debug, Default)]
pub struct BlockPos {
pub x: i32,
@ -11,6 +13,18 @@ impl BlockPos {
}
}
impl Rem<i32> for BlockPos {
type Output = Self;
fn rem(self, rhs: i32) -> Self {
BlockPos {
x: self.x % rhs,
y: self.y % rhs,
z: self.z % rhs,
}
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct ChunkPos {
pub x: i32,
@ -23,8 +37,8 @@ impl ChunkPos {
}
}
impl From<BlockPos> for ChunkPos {
fn from(pos: BlockPos) -> Self {
impl From<&BlockPos> for ChunkPos {
fn from(pos: &BlockPos) -> Self {
ChunkPos {
x: pos.x / 16,
z: pos.z / 16,
@ -32,6 +46,7 @@ impl From<BlockPos> for ChunkPos {
}
}
/// The coordinates of a chunk section in the world.
#[derive(Clone, Copy, Debug, Default)]
pub struct ChunkSectionPos {
pub x: i32,
@ -60,3 +75,27 @@ impl From<ChunkSectionPos> for ChunkPos {
ChunkPos { x: pos.x, z: pos.z }
}
}
/// The coordinates of a block inside a chunk section.
#[derive(Clone, Copy, Debug, Default)]
pub struct ChunkSectionBlockPos {
pub x: u8,
pub y: u8,
pub z: u8,
}
impl ChunkSectionBlockPos {
pub fn new(x: u8, y: u8, z: u8) -> Self {
ChunkSectionBlockPos { x, y, z }
}
}
impl From<&BlockPos> for ChunkSectionBlockPos {
fn from(pos: &BlockPos) -> Self {
ChunkSectionBlockPos {
x: pos.x.rem(16).abs() as u8,
y: pos.y.rem(16).abs() as u8,
z: pos.z.rem(16).abs() as u8,
}
}
}

View file

@ -103,6 +103,9 @@ impl BitStorage {
/// Create a new BitStorage with the given number of bits per entry.
/// `size` is the number of entries in the BitStorage.
pub fn new(bits: usize, size: usize, data: Option<Vec<u64>>) -> Result<Self, BitStorageError> {
// vanilla has this assert but it's not always true for some reason??
// assert!(bits >= 1 && bits <= 32);
if let Some(data) = &data {
if data.len() == 0 {
// TODO: make 0 bit storage actually work
@ -142,10 +145,12 @@ impl BitStorage {
}
pub fn cell_index(&self, index: u64) -> usize {
let first = self.divide_mul as u64;
// as unsigned wrap
let first = self.divide_mul as u32 as u64;
let second = self.divide_add as u64;
dbg!(first, second, index);
(index * first + second >> 32 >> self.divide_shift)
(((index * first) + second) >> 32 >> self.divide_shift)
.try_into()
.unwrap()
}
@ -157,7 +162,12 @@ impl BitStorage {
// int var5 = (var1 - var2 * this.valuesPerLong) * this.bits;
// return (int)(var3 >> var5 & this.mask);
assert!(index <= self.size - 1);
assert!(
index <= self.size - 1,
"Index {} out of bounds (max is {})",
index,
self.size - 1
);
let cell_index = self.cell_index(index as u64);
let cell = &self.data[cell_index as usize];
let bit_index = (index - cell_index * self.values_per_long as usize) * self.bits;

View file

@ -1,7 +1,8 @@
mod bit_storage;
mod palette;
use azalea_core::ChunkPos;
use crate::palette::PalettedContainerType;
use azalea_core::{BlockPos, ChunkPos, ChunkSectionBlockPos};
use azalea_protocol::mc_buf::{McBufReadable, McBufWritable};
pub use bit_storage::BitStorage;
use palette::PalettedContainer;
@ -11,8 +12,6 @@ use std::{
sync::{Arc, Mutex},
};
use crate::palette::PalettedContainerType;
#[cfg(test)]
mod tests {
#[test]
@ -54,6 +53,10 @@ impl World {
pub fn update_view_center(&mut self, pos: &ChunkPos) {
self.storage.view_center = *pos;
}
pub fn get_block_state(&self, pos: &BlockPos) -> Option<u32> {
self.storage.get_block_state(pos)
}
}
impl Index<&ChunkPos> for World {
type Output = Option<Arc<Mutex<Chunk>>>;
@ -115,6 +118,15 @@ impl ChunkStorage {
(chunk_pos.x - self.view_center.x).unsigned_abs() <= self.chunk_radius
&& (chunk_pos.z - self.view_center.z).unsigned_abs() <= self.chunk_radius
}
pub fn get_block_state(&self, pos: &BlockPos) -> Option<u32> {
let chunk_pos = ChunkPos::from(pos);
let chunk = &self[&chunk_pos];
match chunk {
Some(chunk) => Some(chunk.lock().unwrap().get(pos)),
None => None,
}
}
}
impl Index<&ChunkPos> for ChunkStorage {
@ -150,6 +162,23 @@ impl Chunk {
}
Ok(Chunk { sections })
}
pub fn section_index(&self, y: i32) -> u32 {
// TODO: check the build height and stuff, this code will be broken if the min build height is 0
// (LevelHeightAccessor.getMinSection in vanilla code)
assert!(y >= 0);
(y as u32) / 16
}
pub fn get(&self, pos: &BlockPos) -> u32 {
let section_index = self.section_index(pos.y);
println!("section index: {}", section_index);
// TODO: make sure the section exists
let section = &self.sections[section_index as usize];
let chunk_section_pos = ChunkSectionBlockPos::from(pos);
let block_state = section.get(chunk_section_pos);
block_state
}
}
impl McBufWritable for Chunk {
@ -194,3 +223,11 @@ impl McBufWritable for Section {
Ok(())
}
}
impl Section {
// TODO: return a BlockState instead of a u32
fn get(&self, pos: ChunkSectionBlockPos) -> u32 {
self.states
.get(pos.x as usize, pos.y as usize, pos.z as usize)
}
}

View file

@ -15,6 +15,7 @@ pub struct PalettedContainer {
pub palette: Palette,
/// Compacted list of indices pointing to entry IDs in the Palette.
pub storage: BitStorage,
pub container_type: PalettedContainerType,
}
impl PalettedContainer {
@ -47,9 +48,29 @@ impl PalettedContainer {
bits_per_entry,
palette,
storage,
container_type: *type_,
})
}
pub fn get_index(&self, x: usize, y: usize, z: usize) -> usize {
let size_bits = match self.container_type {
PalettedContainerType::BlockStates => 4,
PalettedContainerType::Biomes => 2,
};
(((y << size_bits) | z) << size_bits) | x
}
pub fn get(&self, x: usize, y: usize, z: usize) -> u32 {
println!(
"get: {} {} {}, bits per entry: {}",
x, y, z, self.bits_per_entry
);
let paletted_value = self.storage.get(self.get_index(x, y, z));
self.palette.value_for(paletted_value as usize)
}
}
impl McBufWritable for PalettedContainer {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
buf.write_byte(self.bits_per_entry)?;
@ -91,6 +112,15 @@ impl Palette {
_ => Palette::Global,
})
}
pub fn value_for(&self, value: usize) -> u32 {
match self {
Palette::SingleValue(v) => *v,
Palette::Linear(v) => v[value],
Palette::Hashmap(v) => v[value],
Palette::Global => value as u32,
}
}
}
impl McBufWritable for Palette {

View file

@ -25,12 +25,8 @@ async fn main() {
if p.message.to_ansi(None) == "<py5> ok" {
let state = client.state.lock().await;
let world = state.world.as_ref().unwrap();
// let c = world[&BlockPos::new(5, 78, -2)]
// .as_ref()
// .unwrap()
// .lock()
// .unwrap();
// println!("{:?}", c);
let c = world.get_block_state(&BlockPos::new(5, 78, -2)).unwrap();
println!("{:?}", c);
}
}
}