aboutsummaryrefslogtreecommitdiff
path: root/azalea-core/src
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2025-01-10 16:45:27 -0600
committerGitHub <noreply@github.com>2025-01-10 16:45:27 -0600
commit0d16f01571ec8315f3979eae46981e559ade1cf9 (patch)
treeea43c32a57b0e6a67579d75a134dfbc009d09781 /azalea-core/src
parent615d8f9d2ac56b3244d328587243301da253eafd (diff)
downloadazalea-drasl-0d16f01571ec8315f3979eae46981e559ade1cf9.tar.xz
Fluid physics (#199)
* start implementing fluid physics * Initial implementation of fluid pushing * different travel function in water * bubble columns * jumping in water * cleanup * change ultrawarm to be required * fix for clippy
Diffstat (limited to 'azalea-core/src')
-rwxr-xr-xazalea-core/src/aabb.rs376
-rwxr-xr-xazalea-core/src/direction.rs43
-rw-r--r--azalea-core/src/math.rs19
-rwxr-xr-xazalea-core/src/position.rs49
-rw-r--r--azalea-core/src/registry_holder.rs35
5 files changed, 324 insertions, 198 deletions
diff --git a/azalea-core/src/aabb.rs b/azalea-core/src/aabb.rs
index 70829aa2..fe45c35e 100755
--- a/azalea-core/src/aabb.rs
+++ b/azalea-core/src/aabb.rs
@@ -8,13 +8,8 @@ use crate::{
/// A rectangular prism with a starting and ending point.
#[derive(Copy, Clone, Debug, PartialEq, Default)]
pub struct AABB {
- pub min_x: f64,
- pub min_y: f64,
- pub min_z: f64,
-
- pub max_x: f64,
- pub max_y: f64,
- pub max_z: f64,
+ pub min: Vec3,
+ pub max: Vec3,
}
pub struct ClipPointOpts<'a> {
@@ -23,8 +18,8 @@ pub struct ClipPointOpts<'a> {
pub delta: &'a Vec3,
pub begin: f64,
pub min_x: f64,
- pub max_x: f64,
pub min_z: f64,
+ pub max_x: f64,
pub max_z: f64,
pub result_dir: Direction,
pub start: &'a Vec3,
@@ -32,51 +27,38 @@ pub struct ClipPointOpts<'a> {
impl AABB {
pub fn contract(&self, x: f64, y: f64, z: f64) -> AABB {
- let mut min_x = self.min_x;
- let mut min_y = self.min_y;
- let mut min_z = self.min_z;
-
- let mut max_x = self.max_x;
- let mut max_y = self.max_y;
- let mut max_z = self.max_z;
+ let mut min = self.min;
+ let mut max = self.max;
if x < 0.0 {
- min_x -= x;
+ min.x -= x;
} else if x > 0.0 {
- max_x -= x;
+ max.x -= x;
}
if y < 0.0 {
- min_y -= y;
+ min.y -= y;
} else if y > 0.0 {
- max_y -= y;
+ max.y -= y;
}
if z < 0.0 {
- min_z -= z;
+ min.z -= z;
} else if z > 0.0 {
- max_z -= z;
+ max.z -= z;
}
- AABB {
- min_x,
- min_y,
- min_z,
-
- max_x,
- max_y,
- max_z,
- }
+ AABB { min, max }
}
pub fn expand_towards(&self, other: &Vec3) -> AABB {
- let mut min_x = self.min_x;
- let mut min_y = self.min_y;
- let mut min_z = self.min_z;
+ let mut min_x = self.min.x;
+ let mut min_y = self.min.y;
+ let mut min_z = self.min.z;
- let mut max_x = self.max_x;
- let mut max_y = self.max_y;
- let mut max_z = self.max_z;
+ let mut max_x = self.max.x;
+ let mut max_y = self.max.y;
+ let mut max_z = self.max.z;
if other.x < 0.0 {
min_x += other.x;
@@ -97,115 +79,93 @@ impl AABB {
}
AABB {
- min_x,
- min_y,
- min_z,
-
- max_x,
- max_y,
- max_z,
+ min: Vec3::new(min_x, min_y, min_z),
+ max: Vec3::new(max_x, max_y, max_z),
}
}
pub fn inflate(&self, x: f64, y: f64, z: f64) -> AABB {
- let min_x = self.min_x - x;
- let min_y = self.min_y - y;
- let min_z = self.min_z - z;
+ let min_x = self.min.x - x;
+ let min_y = self.min.y - y;
+ let min_z = self.min.z - z;
- let max_x = self.max_x + x;
- let max_y = self.max_y + y;
- let max_z = self.max_z + z;
+ let max_x = self.max.x + x;
+ let max_y = self.max.y + y;
+ let max_z = self.max.z + z;
AABB {
- min_x,
- min_y,
- min_z,
-
- max_x,
- max_y,
- max_z,
+ min: Vec3::new(min_x, min_y, min_z),
+ max: Vec3::new(max_x, max_y, max_z),
}
}
pub fn intersect(&self, other: &AABB) -> AABB {
- let min_x = self.min_x.max(other.min_x);
- let min_y = self.min_y.max(other.min_y);
- let min_z = self.min_z.max(other.min_z);
+ let min_x = self.min.x.max(other.min.x);
+ let min_y = self.min.y.max(other.min.y);
+ let min_z = self.min.z.max(other.min.z);
- let max_x = self.max_x.min(other.max_x);
- let max_y = self.max_y.min(other.max_y);
- let max_z = self.max_z.min(other.max_z);
+ let max_x = self.max.x.min(other.max.x);
+ let max_y = self.max.y.min(other.max.y);
+ let max_z = self.max.z.min(other.max.z);
AABB {
- min_x,
- min_y,
- min_z,
-
- max_x,
- max_y,
- max_z,
+ min: Vec3::new(min_x, min_y, min_z),
+ max: Vec3::new(max_x, max_y, max_z),
}
}
pub fn minmax(&self, other: &AABB) -> AABB {
- let min_x = self.min_x.min(other.min_x);
- let min_y = self.min_y.min(other.min_y);
- let min_z = self.min_z.min(other.min_z);
+ let min_x = self.min.x.min(other.min.x);
+ let min_y = self.min.y.min(other.min.y);
+ let min_z = self.min.z.min(other.min.z);
- let max_x = self.max_x.max(other.max_x);
- let max_y = self.max_y.max(other.max_y);
- let max_z = self.max_z.max(other.max_z);
+ let max_x = self.max.x.max(other.max.x);
+ let max_y = self.max.y.max(other.max.y);
+ let max_z = self.max.z.max(other.max.z);
AABB {
- min_x,
- min_y,
- min_z,
-
- max_x,
- max_y,
- max_z,
+ min: Vec3::new(min_x, min_y, min_z),
+ max: Vec3::new(max_x, max_y, max_z),
}
}
- pub fn move_relative(&self, delta: &Vec3) -> AABB {
+ pub fn move_relative(&self, delta: Vec3) -> AABB {
AABB {
- min_x: self.min_x + delta.x,
- min_y: self.min_y + delta.y,
- min_z: self.min_z + delta.z,
-
- max_x: self.max_x + delta.x,
- max_y: self.max_y + delta.y,
- max_z: self.max_z + delta.z,
+ min: self.min + delta,
+ max: self.max + delta,
}
}
pub fn intersects_aabb(&self, other: &AABB) -> bool {
- self.min_x < other.max_x
- && self.max_x > other.min_x
- && self.min_y < other.max_y
- && self.max_y > other.min_y
- && self.min_z < other.max_z
- && self.max_z > other.min_z
+ self.min.x < other.max.x
+ && self.max.x > other.min.x
+ && self.min.y < other.max.y
+ && self.max.y > other.min.y
+ && self.min.z < other.max.z
+ && self.max.z > other.min.z
}
pub fn intersects_vec3(&self, other: &Vec3, other2: &Vec3) -> bool {
self.intersects_aabb(&AABB {
- min_x: other.x.min(other2.x),
- min_y: other.y.min(other2.y),
- min_z: other.z.min(other2.z),
-
- max_x: other.x.max(other2.x),
- max_y: other.y.max(other2.y),
- max_z: other.z.max(other2.z),
+ min: Vec3::new(
+ other.x.min(other2.x),
+ other.y.min(other2.y),
+ other.z.min(other2.z),
+ ),
+ max: Vec3::new(
+ other.x.max(other2.x),
+ other.y.max(other2.y),
+ other.z.max(other2.z),
+ ),
})
}
- pub fn contains(&self, x: f64, y: f64, z: f64) -> bool {
- x >= self.min_x
- && x < self.max_x
- && y >= self.min_y
- && y < self.max_y
- && z >= self.min_z
- && z < self.max_z
+ pub fn contains(&self, point: &Vec3) -> bool {
+ point.x >= self.min.x
+ && point.x < self.max.x
+ && point.y >= self.min.y
+ && point.y < self.max.y
+ && point.z >= self.min.z
+ && point.z < self.max.z
}
pub fn size(&self) -> f64 {
@@ -217,9 +177,9 @@ impl AABB {
pub fn get_size(&self, axis: Axis) -> f64 {
axis.choose(
- self.max_x - self.min_x,
- self.max_y - self.min_y,
- self.max_z - self.min_z,
+ self.max.x - self.min.x,
+ self.max.y - self.min.y,
+ self.max.z - self.min.z,
)
}
@@ -227,13 +187,24 @@ impl AABB {
self.inflate(-x, -y, -z)
}
+ pub fn deflate_all(&mut self, amount: f64) -> AABB {
+ self.deflate(amount, amount, amount)
+ }
+
pub fn clip(&self, min: &Vec3, max: &Vec3) -> Option<Vec3> {
let mut t = 1.0;
let delta = max - min;
- let _dir = Self::get_direction(self, min, &mut t, None, &delta)?;
+ let _dir = Self::get_direction_aabb(self, min, &mut t, None, &delta)?;
Some(min + &(delta * t))
}
+ pub fn clip_with_from_and_to(min: &Vec3, max: &Vec3, from: &Vec3, to: &Vec3) -> Option<Vec3> {
+ let mut t = 1.0;
+ let delta = to - from;
+ let _dir = Self::get_direction(min, max, from, &mut t, None, &delta)?;
+ Some(from + &(delta * t))
+ }
+
pub fn clip_iterable(
boxes: &Vec<AABB>,
from: &Vec3,
@@ -245,8 +216,8 @@ impl AABB {
let delta = to - from;
for aabb in boxes {
- dir = Self::get_direction(
- &aabb.move_relative(&pos.to_vec3_floored()),
+ dir = Self::get_direction_aabb(
+ &aabb.move_relative(pos.to_vec3_floored()),
from,
&mut t,
dir,
@@ -264,8 +235,19 @@ impl AABB {
})
}
+ fn get_direction_aabb(
+ &self,
+ from: &Vec3,
+ t: &mut f64,
+ dir: Option<Direction>,
+ delta: &Vec3,
+ ) -> Option<Direction> {
+ AABB::get_direction(&self.min, &self.max, from, t, dir, delta)
+ }
+
fn get_direction(
- aabb: &AABB,
+ min: &Vec3,
+ max: &Vec3,
from: &Vec3,
t: &mut f64,
mut dir: Option<Direction>,
@@ -276,11 +258,11 @@ impl AABB {
t,
approach_dir: dir,
delta,
- begin: aabb.min_x,
- min_x: aabb.min_y,
- max_x: aabb.max_y,
- min_z: aabb.min_z,
- max_z: aabb.max_z,
+ begin: min.x,
+ min_x: min.y,
+ max_x: max.y,
+ min_z: min.z,
+ max_z: max.z,
result_dir: Direction::West,
start: from,
});
@@ -289,11 +271,11 @@ impl AABB {
t,
approach_dir: dir,
delta,
- begin: aabb.max_x,
- min_x: aabb.min_y,
- max_x: aabb.max_y,
- min_z: aabb.min_z,
- max_z: aabb.max_z,
+ begin: max.x,
+ min_x: min.y,
+ max_x: max.y,
+ min_z: min.z,
+ max_z: max.z,
result_dir: Direction::East,
start: from,
});
@@ -308,11 +290,11 @@ impl AABB {
y: delta.z,
z: delta.x,
},
- begin: aabb.min_y,
- min_x: aabb.min_z,
- max_x: aabb.max_z,
- min_z: aabb.min_x,
- max_z: aabb.max_x,
+ begin: min.y,
+ min_x: min.z,
+ max_x: max.z,
+ min_z: min.x,
+ max_z: max.x,
result_dir: Direction::Down,
start: &Vec3 {
x: from.y,
@@ -329,11 +311,11 @@ impl AABB {
y: delta.z,
z: delta.x,
},
- begin: aabb.max_y,
- min_x: aabb.min_z,
- max_x: aabb.max_z,
- min_z: aabb.min_x,
- max_z: aabb.max_x,
+ begin: max.y,
+ min_x: min.z,
+ max_x: max.z,
+ min_z: min.x,
+ max_z: max.x,
result_dir: Direction::Up,
start: &Vec3 {
x: from.y,
@@ -352,11 +334,11 @@ impl AABB {
y: delta.x,
z: delta.y,
},
- begin: aabb.min_z,
- min_x: aabb.min_x,
- max_x: aabb.max_x,
- min_z: aabb.min_y,
- max_z: aabb.max_y,
+ begin: min.z,
+ min_x: min.x,
+ max_x: max.x,
+ min_z: min.y,
+ max_z: max.y,
result_dir: Direction::North,
start: &Vec3 {
x: from.z,
@@ -373,11 +355,11 @@ impl AABB {
y: delta.x,
z: delta.y,
},
- begin: aabb.max_z,
- min_x: aabb.min_x,
- max_x: aabb.max_x,
- min_z: aabb.min_y,
- max_z: aabb.max_y,
+ begin: max.z,
+ min_x: min.x,
+ max_x: max.x,
+ min_z: min.y,
+ max_z: max.y,
result_dir: Direction::South,
start: &Vec3 {
x: from.z,
@@ -409,38 +391,96 @@ impl AABB {
}
pub fn has_nan(&self) -> bool {
- self.min_x.is_nan()
- || self.min_y.is_nan()
- || self.min_z.is_nan()
- || self.max_x.is_nan()
- || self.max_y.is_nan()
- || self.max_z.is_nan()
+ self.min.x.is_nan()
+ || self.min.y.is_nan()
+ || self.min.z.is_nan()
+ || self.max.x.is_nan()
+ || self.max.y.is_nan()
+ || self.max.z.is_nan()
}
pub fn get_center(&self) -> Vec3 {
Vec3::new(
- (self.min_x + self.max_x) / 2.0,
- (self.min_y + self.max_y) / 2.0,
- (self.min_z + self.max_z) / 2.0,
+ (self.min.x + self.max.x) / 2.0,
+ (self.min.y + self.max.y) / 2.0,
+ (self.min.z + self.max.z) / 2.0,
)
}
pub fn of_size(center: Vec3, dx: f64, dy: f64, dz: f64) -> AABB {
AABB {
- min_x: center.x - dx / 2.0,
- min_y: center.y - dy / 2.0,
- min_z: center.z - dz / 2.0,
- max_x: center.x + dx / 2.0,
- max_y: center.y + dy / 2.0,
- max_z: center.z + dz / 2.0,
+ min: Vec3::new(
+ center.x - dx / 2.0,
+ center.y - dy / 2.0,
+ center.z - dz / 2.0,
+ ),
+ max: Vec3::new(
+ center.x + dx / 2.0,
+ center.y + dy / 2.0,
+ center.z + dz / 2.0,
+ ),
}
}
pub fn max(&self, axis: &Axis) -> f64 {
- axis.choose(self.max_x, self.max_y, self.max_z)
+ axis.choose(self.max.x, self.max.y, self.max.z)
}
pub fn min(&self, axis: &Axis) -> f64 {
- axis.choose(self.min_x, self.min_y, self.min_z)
+ axis.choose(self.min.x, self.min.y, self.min.z)
+ }
+
+ pub fn collided_along_vector(&self, vector: Vec3, boxes: &Vec<AABB>) -> bool {
+ let center = self.get_center();
+ let new_center = center + vector;
+
+ for aabb in boxes {
+ let inflated = aabb.inflate(
+ self.get_size(Axis::X) * 0.5,
+ self.get_size(Axis::Y) * 0.5,
+ self.get_size(Axis::Z) * 0.5,
+ );
+ if inflated.contains(&new_center) || inflated.contains(&center) {
+ return true;
+ }
+
+ if inflated.clip(&center, &new_center).is_some() {
+ return true;
+ }
+ }
+
+ false
+ }
+}
+
+impl BlockPos {
+ pub fn between_closed_aabb(aabb: &AABB) -> Vec<BlockPos> {
+ BlockPos::between_closed(BlockPos::from(aabb.min), BlockPos::from(aabb.max))
+ }
+
+ pub fn between_closed(min: BlockPos, max: BlockPos) -> Vec<BlockPos> {
+ assert!(min.x <= max.x);
+ assert!(min.y <= max.y);
+ assert!(min.z <= max.z);
+
+ let length_x = max.x - min.x + 1;
+ let length_y = max.y - min.y + 1;
+ let length_z = max.z - min.z + 1;
+ let volume = length_x * length_y * length_z;
+
+ let mut result = Vec::with_capacity(volume as usize);
+ for index in 0..volume {
+ let index_x = index % length_x;
+ let remaining_after_x = index / length_x;
+ let index_y = remaining_after_x % length_y;
+ let index_z = remaining_after_x / length_y;
+ result.push(BlockPos::new(
+ min.x + index_x,
+ min.y + index_y,
+ min.z + index_z,
+ ));
+ }
+
+ result
}
}
@@ -453,12 +493,8 @@ mod tests {
assert_ne!(
AABB::clip_iterable(
&vec![AABB {
- min_x: 0.,
- min_y: 0.,
- min_z: 0.,
- max_x: 1.,
- max_y: 1.,
- max_z: 1.,
+ min: Vec3::new(0., 0., 0.),
+ max: Vec3::new(1., 1., 1.),
}],
&Vec3::new(-1., -1., -1.),
&Vec3::new(1., 1., 1.),
diff --git a/azalea-core/src/direction.rs b/azalea-core/src/direction.rs
index 6ff55615..d458f487 100755
--- a/azalea-core/src/direction.rs
+++ b/azalea-core/src/direction.rs
@@ -1,6 +1,6 @@
use azalea_buf::AzBuf;
-use crate::position::Vec3;
+use crate::position::{BlockPos, Vec3};
#[derive(Clone, Copy, Debug, AzBuf, Default, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
@@ -15,6 +15,14 @@ pub enum Direction {
}
impl Direction {
+ pub const HORIZONTAL: [Direction; 4] = [
+ Direction::North,
+ Direction::South,
+ Direction::West,
+ Direction::East,
+ ];
+ pub const VERTICAL: [Direction; 2] = [Direction::Down, Direction::Up];
+
pub fn nearest(vec: Vec3) -> Direction {
let mut best_direction = Direction::North;
let mut best_direction_amount = 0.0;
@@ -29,7 +37,7 @@ impl Direction {
]
.iter()
{
- let amount = dir.normal().dot(vec);
+ let amount = dir.normal_vec3().dot(vec);
if amount > best_direction_amount {
best_direction = *dir;
best_direction_amount = amount;
@@ -39,17 +47,23 @@ impl Direction {
best_direction
}
- pub fn normal(self) -> Vec3 {
+ #[inline]
+ pub fn normal(self) -> BlockPos {
match self {
- Direction::Down => Vec3::new(0.0, -1.0, 0.0),
- Direction::Up => Vec3::new(0.0, 1.0, 0.0),
- Direction::North => Vec3::new(0.0, 0.0, -1.0),
- Direction::South => Vec3::new(0.0, 0.0, 1.0),
- Direction::West => Vec3::new(-1.0, 0.0, 0.0),
- Direction::East => Vec3::new(1.0, 0.0, 0.0),
+ Direction::Down => BlockPos::new(0, -1, 0),
+ Direction::Up => BlockPos::new(0, 1, 0),
+ Direction::North => BlockPos::new(0, 0, -1),
+ Direction::South => BlockPos::new(0, 0, 1),
+ Direction::West => BlockPos::new(-1, 0, 0),
+ Direction::East => BlockPos::new(1, 0, 0),
}
}
+ #[inline]
+ pub fn normal_vec3(self) -> Vec3 {
+ self.normal().to_vec3_floored()
+ }
+
pub fn opposite(self) -> Direction {
match self {
Direction::Down => Direction::Up,
@@ -60,6 +74,16 @@ impl Direction {
Direction::East => Direction::West,
}
}
+
+ pub fn x(self) -> i32 {
+ self.normal().x
+ }
+ pub fn y(self) -> i32 {
+ self.normal().y
+ }
+ pub fn z(self) -> i32 {
+ self.normal().z
+ }
}
/// The four cardinal directions.
@@ -75,6 +99,7 @@ pub enum CardinalDirection {
East,
}
+/// A 3D axis like x, y, z.
#[derive(Clone, Copy, Debug)]
pub enum Axis {
X = 0,
diff --git a/azalea-core/src/math.rs b/azalea-core/src/math.rs
index 67ece5cc..a763fc49 100644
--- a/azalea-core/src/math.rs
+++ b/azalea-core/src/math.rs
@@ -86,6 +86,25 @@ pub fn to_degrees(radians: f64) -> f64 {
radians * 57.29577951308232
}
+/// Returns either -1, 0, or 1, depending on whether the number is negative,
+/// zero, or positive.
+///
+/// This function exists because f64::signum doesn't check for 0.
+pub fn sign(num: f64) -> f64 {
+ if num == 0. {
+ 0.
+ } else {
+ num.signum()
+ }
+}
+pub fn sign_as_int(num: f64) -> i32 {
+ if num == 0. {
+ 0
+ } else {
+ num.signum() as i32
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs
index 819d72cf..cba58415 100755
--- a/azalea-core/src/position.rs
+++ b/azalea-core/src/position.rs
@@ -8,11 +8,12 @@ use std::{
fmt,
hash::Hash,
io::{Cursor, Write},
- ops::{Add, AddAssign, Mul, Rem, Sub},
+ ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, Sub},
};
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
+use crate::direction::Direction;
use crate::math;
use crate::resource_location::ResourceLocation;
@@ -138,7 +139,6 @@ macro_rules! vec3_impl {
}
}
}
-
impl Add for $name {
type Output = $name;
@@ -147,6 +147,18 @@ macro_rules! vec3_impl {
(&self).add(&rhs)
}
}
+ impl Add<$type> for $name {
+ type Output = Self;
+
+ #[inline]
+ fn add(self, rhs: $type) -> Self::Output {
+ Self {
+ x: self.x + rhs,
+ y: self.y + rhs,
+ z: self.z + rhs,
+ }
+ }
+ }
impl AddAssign for $name {
#[inline]
@@ -203,6 +215,35 @@ macro_rules! vec3_impl {
}
}
}
+ impl MulAssign<$type> for $name {
+ #[inline]
+ fn mul_assign(&mut self, multiplier: $type) {
+ self.x *= multiplier;
+ self.y *= multiplier;
+ self.z *= multiplier;
+ }
+ }
+
+ impl Div<$type> for $name {
+ type Output = Self;
+
+ #[inline]
+ fn div(self, divisor: $type) -> Self::Output {
+ Self {
+ x: self.x / divisor,
+ y: self.y / divisor,
+ z: self.z / divisor,
+ }
+ }
+ }
+ impl DivAssign<$type> for $name {
+ #[inline]
+ fn div_assign(&mut self, divisor: $type) {
+ self.x /= divisor;
+ self.y /= divisor;
+ self.z /= divisor;
+ }
+ }
impl From<($type, $type, $type)> for $name {
#[inline]
@@ -345,6 +386,10 @@ impl BlockPos {
z: self.z.max(other.z),
}
}
+
+ pub fn offset_with_direction(self, direction: Direction) -> Self {
+ self + direction.normal()
+ }
}
/// Chunk coordinates are used to represent where a chunk is in the world. You
diff --git a/azalea-core/src/registry_holder.rs b/azalea-core/src/registry_holder.rs
index 8b3dd4e6..0d2588cf 100644
--- a/azalea-core/src/registry_holder.rs
+++ b/azalea-core/src/registry_holder.rs
@@ -39,6 +39,23 @@ impl RegistryHolder {
}
}
+ /// Get the dimension type registry, or `None` if it doesn't exist. You
+ /// should do some type of error handling if this returns `None`.
+ pub fn dimension_type(&self) -> Option<RegistryType<DimensionTypeElement>> {
+ let name = ResourceLocation::new("minecraft:dimension_type");
+ match self.get(&name) {
+ Some(Ok(registry)) => Some(registry),
+ Some(Err(err)) => {
+ error!(
+ "Error deserializing dimension type registry: {err:?}\n{:?}",
+ self.map.get(&name)
+ );
+ None
+ }
+ None => None,
+ }
+ }
+
fn get<T: Deserialize>(
&self,
name: &ResourceLocation,
@@ -66,23 +83,6 @@ impl RegistryHolder {
Some(Ok(RegistryType { map }))
}
-
- /// Get the dimension type registry, or `None` if it doesn't exist. You
- /// should do some type of error handling if this returns `None`.
- pub fn dimension_type(&self) -> Option<RegistryType<DimensionTypeElement>> {
- let name = ResourceLocation::new("minecraft:dimension_type");
- match self.get(&name) {
- Some(Ok(registry)) => Some(registry),
- Some(Err(err)) => {
- error!(
- "Error deserializing dimension type registry: {err:?}\n{:?}",
- self.map.get(&name)
- );
- None
- }
- None => None,
- }
- }
}
/// A collection of values for a certain type of registry data.
@@ -161,6 +161,7 @@ pub struct DimensionTypeElement {
pub struct DimensionTypeElement {
pub height: u32,
pub min_y: i32,
+ pub ultrawarm: bool,
#[simdnbt(flatten)]
pub _extra: HashMap<String, NbtTag>,
}