2023-01-27 21:51:54 +01:00
|
|
|
use std::{
|
|
|
|
fmt::Debug,
|
2023-02-12 12:14:10 +01:00
|
|
|
ops::{Div, Index, IndexMut, Rem},
|
2023-01-27 21:51:54 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
use itertools::iproduct;
|
2023-01-27 21:21:09 +01:00
|
|
|
|
2023-02-12 20:17:20 +01:00
|
|
|
pub const BLOCKS_PER_CHUNK: usize = 16;
|
2023-02-12 12:17:46 +01:00
|
|
|
|
|
|
|
/// A block X coordinate relative to a chunk
|
2023-02-12 17:56:44 +01:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
2023-02-12 12:17:46 +01:00
|
|
|
pub struct BlockX(pub u8);
|
|
|
|
|
|
|
|
/// A block Y coordinate relative to a chunk section
|
2023-02-12 17:56:44 +01:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
2023-02-12 12:17:46 +01:00
|
|
|
pub struct BlockY(pub u8);
|
|
|
|
|
|
|
|
/// A block Z coordinate relative to a chunk
|
2023-02-12 17:56:44 +01:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
2023-02-12 12:17:46 +01:00
|
|
|
pub struct BlockZ(pub u8);
|
|
|
|
|
2023-02-12 17:56:44 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
2023-02-12 12:17:46 +01:00
|
|
|
pub struct BlockCoords {
|
|
|
|
pub x: BlockX,
|
|
|
|
pub y: BlockY,
|
|
|
|
pub z: BlockZ,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BlockCoords {
|
|
|
|
pub fn offset(&self) -> usize {
|
2023-02-12 20:17:20 +01:00
|
|
|
use BLOCKS_PER_CHUNK as N;
|
2023-02-12 12:17:46 +01:00
|
|
|
let x = self.x.0 as usize;
|
|
|
|
let y = self.y.0 as usize;
|
|
|
|
let z = self.z.0 as usize;
|
|
|
|
((y * N) + z) * N + x
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Debug for BlockCoords {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
write!(f, "({}, {}, {})", self.x.0, self.y.0, self.z.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A section Y coordinate
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
|
|
pub struct SectionY(pub i32);
|
|
|
|
|
2023-02-12 20:17:20 +01:00
|
|
|
pub const CHUNKS_PER_REGION: usize = 32;
|
2023-01-25 21:41:08 +01:00
|
|
|
|
|
|
|
/// A chunk X coordinate relative to a region
|
2023-02-12 17:56:44 +01:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
2023-01-25 21:41:08 +01:00
|
|
|
pub struct ChunkX(pub u8);
|
|
|
|
|
|
|
|
/// A chunk Z coordinate relative to a region
|
2023-02-12 17:56:44 +01:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
2023-01-25 21:41:08 +01:00
|
|
|
pub struct ChunkZ(pub u8);
|
2023-01-27 21:21:09 +01:00
|
|
|
|
|
|
|
/// A pair of chunk coordinates relative to a region
|
2023-02-12 17:56:44 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
2023-01-27 21:21:09 +01:00
|
|
|
pub struct ChunkCoords {
|
|
|
|
pub x: ChunkX,
|
|
|
|
pub z: ChunkZ,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Debug for ChunkCoords {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
write!(f, "({}, {})", self.x.0, self.z.0)
|
|
|
|
}
|
|
|
|
}
|
2023-01-27 21:51:54 +01:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, Default)]
|
2023-02-12 20:17:20 +01:00
|
|
|
pub struct ChunkArray<T>(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]);
|
2023-01-27 21:51:54 +01:00
|
|
|
|
|
|
|
impl<T> ChunkArray<T> {
|
|
|
|
pub fn keys() -> impl Iterator<Item = ChunkCoords> {
|
2023-02-12 20:17:20 +01:00
|
|
|
iproduct!(0..(CHUNKS_PER_REGION as u8), 0..(CHUNKS_PER_REGION as u8)).map(|(z, x)| {
|
|
|
|
ChunkCoords {
|
|
|
|
x: ChunkX(x),
|
|
|
|
z: ChunkZ(z),
|
|
|
|
}
|
2023-01-27 21:51:54 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn values(&self) -> impl Iterator<Item = &T> {
|
|
|
|
Self::keys().map(|k| &self[k])
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn iter(&self) -> impl Iterator<Item = (ChunkCoords, &T)> {
|
|
|
|
Self::keys().map(|k| (k, &self[k]))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Index<ChunkCoords> for ChunkArray<T> {
|
|
|
|
type Output = T;
|
|
|
|
|
|
|
|
fn index(&self, index: ChunkCoords) -> &Self::Output {
|
|
|
|
&self.0[index.z.0 as usize][index.x.0 as usize]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> IndexMut<ChunkCoords> for ChunkArray<T> {
|
|
|
|
fn index_mut(&mut self, index: ChunkCoords) -> &mut Self::Output {
|
|
|
|
&mut self.0[index.z.0 as usize][index.x.0 as usize]
|
|
|
|
}
|
|
|
|
}
|
2023-02-12 12:14:10 +01:00
|
|
|
|
2023-02-12 21:01:28 +01:00
|
|
|
pub trait DivRem<Rhs>
|
|
|
|
where
|
|
|
|
Self: Div<Rhs>,
|
|
|
|
Self: Rem<Rhs>,
|
|
|
|
{
|
|
|
|
fn div_rem(self, rhs: Rhs) -> (<Self as Div<Rhs>>::Output, <Self as Rem<Rhs>>::Output);
|
2023-02-12 12:14:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<Lhs, Rhs> DivRem<Rhs> for Lhs
|
|
|
|
where
|
|
|
|
Self: Div<Rhs>,
|
|
|
|
Self: Rem<Rhs>,
|
|
|
|
Self: Copy,
|
|
|
|
Rhs: Copy,
|
|
|
|
{
|
2023-02-12 21:01:28 +01:00
|
|
|
fn div_rem(self, rhs: Rhs) -> (<Self as Div<Rhs>>::Output, <Self as Rem<Rhs>>::Output) {
|
2023-02-12 12:14:10 +01:00
|
|
|
(self / rhs, self % rhs)
|
|
|
|
}
|
|
|
|
}
|