Pumpkin/pumpkin-world/src/coordinates.rs
Snowiiii d9b3d0494d Improved: Plains biome
- Flowers
- Grass
- More natural height variation
2024-10-22 16:41:53 +02:00

143 lines
3.5 KiB
Rust

use std::ops::Deref;
use crate::{WORLD_LOWEST_Y, WORLD_MAX_Y};
use derive_more::derive::{AsMut, AsRef, Display, Into};
use num_traits::{PrimInt, Signed, Unsigned};
use pumpkin_core::math::vector2::Vector2;
use pumpkin_core::math::vector3::Vector3;
use serde::{Deserialize, Serialize};
#[derive(
Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, AsRef, AsMut, Into, Display,
)]
#[serde(transparent)]
pub struct Height(pub i16);
impl Height {
pub fn from_absolute(height: u16) -> Self {
(height as i16 - WORLD_LOWEST_Y.abs()).into()
}
/// Absolute height ranges from `0..WORLD_HEIGHT`
/// instead of `WORLD_LOWEST_Y..WORLD_MAX_Y`
pub fn get_absolute(self) -> u16 {
(self.0 + WORLD_LOWEST_Y.abs()) as u16
}
}
impl<T: PrimInt + Signed> From<T> for Height {
fn from(height: T) -> Self {
let height = height.to_i16().unwrap();
assert!(height <= WORLD_MAX_Y);
assert!(height >= WORLD_LOWEST_Y);
Self(height)
}
}
impl Deref for Height {
type Target = i16;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(
Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, AsRef, AsMut, Into, Display,
)]
#[repr(transparent)]
pub struct ChunkRelativeOffset(u8);
impl<T: PrimInt + Unsigned> From<T> for ChunkRelativeOffset {
fn from(scalar: T) -> Self {
let scalar = scalar.to_u8().unwrap();
assert!(scalar < 16);
Self(scalar)
}
}
impl Deref for ChunkRelativeOffset {
type Target = u8;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BlockCoordinates {
pub x: i32,
pub y: Height,
pub z: i32,
}
/// BlockCoordinates that do not specify a height.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct XZBlockCoordinates {
pub x: i32,
pub z: i32,
}
impl XZBlockCoordinates {
pub fn with_y(self, height: Height) -> BlockCoordinates {
BlockCoordinates {
x: self.x,
y: height,
z: self.z,
}
}
}
/// Coordinates of a block relative to a chunk
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ChunkRelativeBlockCoordinates {
pub x: ChunkRelativeOffset,
pub y: Height,
pub z: ChunkRelativeOffset,
}
impl ChunkRelativeBlockCoordinates {
pub fn with_chunk_coordinates(self, chunk_coordinates: Vector2<i32>) -> BlockCoordinates {
BlockCoordinates {
x: *self.x as i32 + chunk_coordinates.x * 16,
y: self.y,
z: *self.z as i32 + chunk_coordinates.z * 16,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ChunkRelativeXZBlockCoordinates {
pub x: ChunkRelativeOffset,
pub z: ChunkRelativeOffset,
}
impl ChunkRelativeXZBlockCoordinates {
pub fn with_chunk_coordinates(&self, chunk_coordinates: Vector2<i32>) -> XZBlockCoordinates {
XZBlockCoordinates {
x: *self.x as i32 + chunk_coordinates.x * 16,
z: *self.z as i32 + chunk_coordinates.z * 16,
}
}
pub fn with_y(self, height: Height) -> ChunkRelativeBlockCoordinates {
ChunkRelativeBlockCoordinates {
x: self.x,
y: height,
z: self.z,
}
}
}
impl From<Vector3<i32>> for ChunkRelativeBlockCoordinates {
fn from(value: Vector3<i32>) -> Self {
Self {
x: (value.x as u8).into(),
z: (value.z as u8).into(),
y: value.y.into(),
}
}
}