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:
parent
70271ede19
commit
6d2fd8afba
6 changed files with 127 additions and 15 deletions
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue