aboutsummaryrefslogtreecommitdiff
path: root/azalea-core/src
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2022-06-25 05:09:26 +0000
committerGitHub <noreply@github.com>2022-06-25 05:09:26 +0000
commit7d3e57763e32ac9cf94180b1c714704cfbc3034d (patch)
tree2dcfe72bf09a42f6614f9dc988dc0254162ea0bf /azalea-core/src
parent69c47eda4c496b13dadd80976bffd2fab7ea5894 (diff)
parentca7067e173129f3044ebc8c77634f06da29a086e (diff)
downloadazalea-drasl-7d3e57763e32ac9cf94180b1c714704cfbc3034d.tar.xz
Merge pull request #10 from mat-1/azalea-entity
azalea-entity
Diffstat (limited to 'azalea-core/src')
-rw-r--r--azalea-core/src/delta.rs68
-rwxr-xr-xazalea-core/src/difficulty.rs27
-rw-r--r--azalea-core/src/direction.rs4
-rwxr-xr-xazalea-core/src/game_type.rs54
-rwxr-xr-xazalea-core/src/lib.rs18
-rw-r--r--azalea-core/src/particle/mod.rs262
-rw-r--r--azalea-core/src/position.rs258
-rwxr-xr-xazalea-core/src/resource_location.rs33
-rwxr-xr-xazalea-core/src/serializable_uuid.rs51
-rw-r--r--azalea-core/src/slot.rs30
10 files changed, 678 insertions, 127 deletions
diff --git a/azalea-core/src/delta.rs b/azalea-core/src/delta.rs
new file mode 100644
index 00000000..c0056411
--- /dev/null
+++ b/azalea-core/src/delta.rs
@@ -0,0 +1,68 @@
+use crate::EntityPos;
+pub use azalea_buf::McBuf;
+
+pub trait PositionDeltaTrait {
+ fn x(&self) -> f64;
+ fn y(&self) -> f64;
+ fn z(&self) -> f64;
+}
+
+#[derive(Clone, Debug, McBuf, Default)]
+pub struct PositionDelta {
+ pub xa: f64,
+ pub ya: f64,
+ pub za: f64,
+}
+
+/// Only works for up to 8 blocks
+#[derive(Clone, Debug, McBuf, Default)]
+pub struct PositionDelta8 {
+ pub xa: i16,
+ pub ya: i16,
+ pub za: i16,
+}
+
+impl PositionDeltaTrait for PositionDelta {
+ fn x(&self) -> f64 {
+ self.xa
+ }
+ fn y(&self) -> f64 {
+ self.ya
+ }
+ fn z(&self) -> f64 {
+ self.za
+ }
+}
+
+impl PositionDelta8 {
+ #[deprecated]
+ pub fn float(&self) -> (f64, f64, f64) {
+ (
+ (self.xa as f64) / 4096.0,
+ (self.ya as f64) / 4096.0,
+ (self.za as f64) / 4096.0,
+ )
+ }
+}
+
+impl PositionDeltaTrait for PositionDelta8 {
+ fn x(&self) -> f64 {
+ (self.xa as f64) / 4096.0
+ }
+ fn y(&self) -> f64 {
+ (self.ya as f64) / 4096.0
+ }
+ fn z(&self) -> f64 {
+ (self.za as f64) / 4096.0
+ }
+}
+
+impl EntityPos {
+ pub fn with_delta(&self, delta: &dyn PositionDeltaTrait) -> EntityPos {
+ EntityPos {
+ x: self.x + delta.x(),
+ y: self.y + delta.y(),
+ z: self.z + delta.z(),
+ }
+ }
+}
diff --git a/azalea-core/src/difficulty.rs b/azalea-core/src/difficulty.rs
index 5d869325..ebbb7708 100755
--- a/azalea-core/src/difficulty.rs
+++ b/azalea-core/src/difficulty.rs
@@ -1,11 +1,16 @@
-use std::fmt::{Debug, Error, Formatter};
+use std::{
+ fmt::{Debug, Error, Formatter},
+ io::{Read, Write},
+};
+
+use azalea_buf::{McBufReadable, McBufWritable};
#[derive(Hash, Clone, Debug, PartialEq)]
pub enum Difficulty {
- PEACEFUL,
- EASY,
- NORMAL,
- HARD,
+ PEACEFUL = 0,
+ EASY = 1,
+ NORMAL = 2,
+ HARD = 3,
}
pub enum Err {
@@ -61,6 +66,18 @@ impl Difficulty {
}
}
+impl McBufReadable for Difficulty {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ Ok(Difficulty::by_id(u8::read_into(buf)?))
+ }
+}
+
+impl McBufWritable for Difficulty {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ u8::write_into(&self.id(), buf)
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/azalea-core/src/direction.rs b/azalea-core/src/direction.rs
index 721f21a0..d3083922 100644
--- a/azalea-core/src/direction.rs
+++ b/azalea-core/src/direction.rs
@@ -1,4 +1,6 @@
-#[derive(Clone, Copy, Debug)]
+use azalea_buf::McBuf;
+
+#[derive(Clone, Copy, Debug, McBuf)]
pub enum Direction {
Down = 0,
Up = 1,
diff --git a/azalea-core/src/game_type.rs b/azalea-core/src/game_type.rs
index f5b9fb38..67c392b2 100755
--- a/azalea-core/src/game_type.rs
+++ b/azalea-core/src/game_type.rs
@@ -1,4 +1,7 @@
-#[derive(Hash, Clone, Debug)]
+use azalea_buf::{McBufReadable, McBufWritable};
+use std::io::{Read, Write};
+
+#[derive(Hash, Copy, Clone, Debug)]
pub enum GameType {
SURVIVAL,
CREATIVE,
@@ -17,8 +20,8 @@ impl GameType {
}
/// Get the id of the game type, but return -1 if the game type is invalid.
- pub fn to_optional_id(game_type: &Option<GameType>) -> i8 {
- match game_type {
+ pub fn to_optional_id<T: Into<Option<GameType>>>(game_type: T) -> i8 {
+ match game_type.into() {
Some(game_type) => game_type.to_id() as i8,
None => -1,
}
@@ -34,11 +37,12 @@ impl GameType {
})
}
- pub fn from_optional_id(id: i8) -> Result<Option<GameType>, String> {
+ pub fn from_optional_id(id: i8) -> Result<OptionalGameType, String> {
Ok(match id {
-1 => None,
id => Some(GameType::from_id(id as u8)?),
- })
+ }
+ .into())
}
pub fn short_name(&self) -> &'static str {
@@ -71,3 +75,43 @@ impl GameType {
}
}
}
+
+impl McBufReadable for GameType {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ GameType::from_id(u8::read_into(buf)?)
+ }
+}
+
+impl McBufWritable for GameType {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ u8::write_into(&self.to_id(), buf)
+ }
+}
+
+/// Rust doesn't let us `impl McBufReadable for Option<GameType>` so we have to make a new type :(
+#[derive(Hash, Copy, Clone, Debug)]
+pub struct OptionalGameType(Option<GameType>);
+
+impl From<Option<GameType>> for OptionalGameType {
+ fn from(game_type: Option<GameType>) -> Self {
+ OptionalGameType(game_type)
+ }
+}
+
+impl From<OptionalGameType> for Option<GameType> {
+ fn from(optional_game_type: OptionalGameType) -> Self {
+ optional_game_type.0
+ }
+}
+
+impl McBufReadable for OptionalGameType {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ GameType::from_optional_id(i8::read_into(buf)?)
+ }
+}
+
+impl McBufWritable for OptionalGameType {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ GameType::to_optional_id(*self).write_into(buf)
+ }
+}
diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs
index a2632871..a1fa1fca 100755
--- a/azalea-core/src/lib.rs
+++ b/azalea-core/src/lib.rs
@@ -2,10 +2,14 @@
#![feature(int_roundings)]
-pub mod difficulty;
-pub mod game_type;
-pub mod resource_location;
-pub mod serializable_uuid;
+mod difficulty;
+pub use difficulty::*;
+
+mod resource_location;
+pub use resource_location::*;
+
+mod game_type;
+pub use game_type::*;
mod slot;
pub use slot::{Slot, SlotData};
@@ -15,3 +19,9 @@ pub use position::*;
mod direction;
pub use direction::Direction;
+
+mod delta;
+pub use delta::*;
+
+mod particle;
+pub use particle::*;
diff --git a/azalea-core/src/particle/mod.rs b/azalea-core/src/particle/mod.rs
new file mode 100644
index 00000000..6eb53955
--- /dev/null
+++ b/azalea-core/src/particle/mod.rs
@@ -0,0 +1,262 @@
+use crate::{BlockPos, Slot};
+use azalea_buf::{McBuf, McBufReadable, McBufVarReadable, McBufWritable};
+use std::io::{Read, Write};
+
+#[derive(Debug, Clone, McBuf)]
+pub struct Particle {
+ #[var]
+ pub id: i32,
+ pub data: ParticleData,
+}
+
+#[derive(Clone, Debug)]
+pub enum ParticleData {
+ AmbientEntityEffect,
+ AngryVillager,
+ Block(BlockParticle),
+ BlockMarker(BlockParticle),
+ Bubble,
+ Cloud,
+ Crit,
+ DamageIndicator,
+ DragonBreath,
+ DrippingLava,
+ FallingLava,
+ LandingLava,
+ DrippingWater,
+ FallingWater,
+ Dust(DustParticle),
+ DustColorTransition(DustColorTransitionParticle),
+ Effect,
+ ElderGuardian,
+ EnchantedHit,
+ Enchant,
+ EndRod,
+ EntityEffect,
+ ExplosionEmitter,
+ Explosion,
+ FallingDust(BlockParticle),
+ Firework,
+ Fishing,
+ Flame,
+ SoulFireFlame,
+ Soul,
+ Flash,
+ HappyVillager,
+ Composter,
+ Heart,
+ InstantEffect,
+ Item(ItemParticle),
+ Vibration(VibrationParticle),
+ ItemSlime,
+ ItemSnowball,
+ LargeSmoke,
+ Lava,
+ Mycelium,
+ Note,
+ Poof,
+ Portal,
+ Rain,
+ Smoke,
+ Sneeze,
+ Spit,
+ SquidInk,
+ SweepAttack,
+ TotemOfUndying,
+ Underwater,
+ Splash,
+ Witch,
+ BubblePop,
+ CurrentDown,
+ BubbleColumnUp,
+ Nautilus,
+ Dolphin,
+ CampfireCozySmoke,
+ CampfireSignalSmoke,
+ DrippingHoney,
+ FallingHoney,
+ LandingHoney,
+ FallingNectar,
+ FallingSporeBlossom,
+ Ash,
+ CrimsonSpore,
+ WarpedSpore,
+ SporeBlossomAir,
+ DrippingObsidianTear,
+ FallingObsidianTear,
+ LandingObsidianTear,
+ ReversePortal,
+ WhiteAsh,
+ SmallFlame,
+ Snowflake,
+ DrippingDripstoneLava,
+ FallingDripstoneLava,
+ DrippingDripstoneWater,
+ FallingDripstoneWater,
+ GlowSquidInk,
+ Glow,
+ WaxOn,
+ WaxOff,
+ ElectricSpark,
+ Scrape,
+}
+
+#[derive(Debug, Clone, McBuf)]
+pub struct BlockParticle {
+ #[var]
+ pub block_state: i32,
+}
+#[derive(Debug, Clone, McBuf)]
+pub struct DustParticle {
+ /// Red value, 0-1
+ pub red: f32,
+ /// Green value, 0-1
+ pub green: f32,
+ /// Blue value, 0-1
+ pub blue: f32,
+ /// The scale, will be clamped between 0.01 and 4.
+ pub scale: f32,
+}
+
+#[derive(Debug, Clone, McBuf)]
+pub struct DustColorTransitionParticle {
+ /// Red value, 0-1
+ pub from_red: f32,
+ /// Green value, 0-1
+ pub from_green: f32,
+ /// Blue value, 0-1
+ pub from_blue: f32,
+ /// The scale, will be clamped between 0.01 and 4.
+ pub scale: f32,
+ /// Red value, 0-1
+ pub to_red: f32,
+ /// Green value, 0-1
+ pub to_green: f32,
+ /// Blue value, 0-1
+ pub to_blue: f32,
+}
+
+#[derive(Debug, Clone, McBuf)]
+pub struct ItemParticle {
+ pub item: Slot,
+}
+
+#[derive(Debug, Clone, McBuf)]
+pub struct VibrationParticle {
+ pub origin: BlockPos,
+ pub position_type: String,
+ pub block_position: BlockPos,
+ #[var]
+ pub entity_id: u32,
+ #[var]
+ pub ticks: u32,
+}
+
+impl ParticleData {
+ pub fn read_from_particle_id(buf: &mut impl Read, id: u32) -> Result<Self, String> {
+ Ok(match id {
+ 0 => ParticleData::AmbientEntityEffect,
+ 1 => ParticleData::AngryVillager,
+ 2 => ParticleData::Block(BlockParticle::read_into(buf)?),
+ 3 => ParticleData::BlockMarker(BlockParticle::read_into(buf)?),
+ 4 => ParticleData::Bubble,
+ 5 => ParticleData::Cloud,
+ 6 => ParticleData::Crit,
+ 7 => ParticleData::DamageIndicator,
+ 8 => ParticleData::DragonBreath,
+ 9 => ParticleData::DrippingLava,
+ 10 => ParticleData::FallingLava,
+ 11 => ParticleData::LandingLava,
+ 12 => ParticleData::DrippingWater,
+ 13 => ParticleData::FallingWater,
+ 14 => ParticleData::Dust(DustParticle::read_into(buf)?),
+ 15 => ParticleData::DustColorTransition(DustColorTransitionParticle::read_into(buf)?),
+ 16 => ParticleData::Effect,
+ 17 => ParticleData::ElderGuardian,
+ 18 => ParticleData::EnchantedHit,
+ 19 => ParticleData::Enchant,
+ 20 => ParticleData::EndRod,
+ 21 => ParticleData::EntityEffect,
+ 22 => ParticleData::ExplosionEmitter,
+ 23 => ParticleData::Explosion,
+ 24 => ParticleData::FallingDust(BlockParticle::read_into(buf)?),
+ 25 => ParticleData::Firework,
+ 26 => ParticleData::Fishing,
+ 27 => ParticleData::Flame,
+ 28 => ParticleData::SoulFireFlame,
+ 29 => ParticleData::Soul,
+ 30 => ParticleData::Flash,
+ 31 => ParticleData::HappyVillager,
+ 32 => ParticleData::Composter,
+ 33 => ParticleData::Heart,
+ 34 => ParticleData::InstantEffect,
+ 35 => ParticleData::Item(ItemParticle::read_into(buf)?),
+ 36 => ParticleData::Vibration(VibrationParticle::read_into(buf)?),
+ 37 => ParticleData::ItemSlime,
+ 38 => ParticleData::ItemSnowball,
+ 39 => ParticleData::LargeSmoke,
+ 40 => ParticleData::Lava,
+ 41 => ParticleData::Mycelium,
+ 42 => ParticleData::Note,
+ 43 => ParticleData::Poof,
+ 44 => ParticleData::Portal,
+ 45 => ParticleData::Rain,
+ 46 => ParticleData::Smoke,
+ 47 => ParticleData::Sneeze,
+ 48 => ParticleData::Spit,
+ 49 => ParticleData::SquidInk,
+ 50 => ParticleData::SweepAttack,
+ 51 => ParticleData::TotemOfUndying,
+ 52 => ParticleData::Underwater,
+ 53 => ParticleData::Splash,
+ 54 => ParticleData::Witch,
+ 55 => ParticleData::BubblePop,
+ 56 => ParticleData::CurrentDown,
+ 57 => ParticleData::BubbleColumnUp,
+ 58 => ParticleData::Nautilus,
+ 59 => ParticleData::Dolphin,
+ 60 => ParticleData::CampfireCozySmoke,
+ 61 => ParticleData::CampfireSignalSmoke,
+ 62 => ParticleData::DrippingHoney,
+ 63 => ParticleData::FallingHoney,
+ 64 => ParticleData::LandingHoney,
+ 65 => ParticleData::FallingNectar,
+ 66 => ParticleData::FallingSporeBlossom,
+ 67 => ParticleData::Ash,
+ 68 => ParticleData::CrimsonSpore,
+ 69 => ParticleData::WarpedSpore,
+ 70 => ParticleData::SporeBlossomAir,
+ 71 => ParticleData::DrippingObsidianTear,
+ 72 => ParticleData::FallingObsidianTear,
+ 73 => ParticleData::LandingObsidianTear,
+ 74 => ParticleData::ReversePortal,
+ 75 => ParticleData::WhiteAsh,
+ 76 => ParticleData::SmallFlame,
+ 77 => ParticleData::Snowflake,
+ 78 => ParticleData::DrippingDripstoneLava,
+ 79 => ParticleData::FallingDripstoneLava,
+ 80 => ParticleData::DrippingDripstoneWater,
+ 81 => ParticleData::FallingDripstoneWater,
+ 82 => ParticleData::GlowSquidInk,
+ 83 => ParticleData::Glow,
+ 84 => ParticleData::WaxOn,
+ 85 => ParticleData::WaxOff,
+ 86 => ParticleData::ElectricSpark,
+ 87 => ParticleData::Scrape,
+ _ => return Err(format!("Unknown particle id: {}", id)),
+ })
+ }
+}
+
+impl McBufReadable for ParticleData {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ let id = u32::var_read_into(buf)?;
+ ParticleData::read_from_particle_id(buf, id)
+ }
+}
+
+impl McBufWritable for ParticleData {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ todo!()
+ }
+}
diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs
index 24be5f6a..de8e2516 100644
--- a/azalea-core/src/position.rs
+++ b/azalea-core/src/position.rs
@@ -1,8 +1,17 @@
-use std::ops::Rem;
+use crate::ResourceLocation;
+use azalea_buf::{McBufReadable, McBufWritable};
+use std::{
+ io::{Read, Write},
+ ops::Rem,
+};
-use crate::resource_location::ResourceLocation;
+pub trait PositionXYZ<T> {
+ fn add_x(&self, n: T) -> Self;
+ fn add_y(&self, n: T) -> Self;
+ fn add_z(&self, n: T) -> Self;
+}
-#[derive(Clone, Copy, Debug, Default)]
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct BlockPos {
pub x: i32,
pub y: i32,
@@ -27,7 +36,31 @@ impl Rem<i32> for BlockPos {
}
}
-#[derive(Clone, Copy, Debug, Default, PartialEq)]
+impl PositionXYZ<i32> for BlockPos {
+ fn add_x(&self, n: i32) -> Self {
+ BlockPos {
+ x: self.x + n,
+ y: self.y,
+ z: self.z,
+ }
+ }
+ fn add_y(&self, n: i32) -> Self {
+ BlockPos {
+ x: self.x,
+ y: self.y + n,
+ z: self.z,
+ }
+ }
+ fn add_z(&self, n: i32) -> Self {
+ BlockPos {
+ x: self.x,
+ y: self.y,
+ z: self.z + n,
+ }
+ }
+}
+
+#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct ChunkPos {
pub x: i32,
pub z: i32,
@@ -39,15 +72,6 @@ impl ChunkPos {
}
}
-impl From<&BlockPos> for ChunkPos {
- fn from(pos: &BlockPos) -> Self {
- ChunkPos {
- x: pos.x.div_floor(16),
- z: pos.z.div_floor(16),
- }
- }
-}
-
/// The coordinates of a chunk section in the world.
#[derive(Clone, Copy, Debug, Default)]
pub struct ChunkSectionPos {
@@ -61,23 +85,6 @@ impl ChunkSectionPos {
ChunkSectionPos { x, y, z }
}
}
-
-impl From<BlockPos> for ChunkSectionPos {
- fn from(pos: BlockPos) -> Self {
- ChunkSectionPos {
- x: pos.x.div_floor(16),
- y: pos.y.div_floor(16),
- z: pos.z.div_floor(16),
- }
- }
-}
-
-impl From<ChunkSectionPos> for ChunkPos {
- fn from(pos: ChunkSectionPos) -> Self {
- ChunkPos { x: pos.x, z: pos.z }
- }
-}
-
/// The coordinates of a block inside a chunk.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct ChunkBlockPos {
@@ -91,17 +98,6 @@ impl ChunkBlockPos {
ChunkBlockPos { x, y, z }
}
}
-
-impl From<&BlockPos> for ChunkBlockPos {
- fn from(pos: &BlockPos) -> Self {
- ChunkBlockPos {
- x: pos.x.rem_euclid(16).abs() as u8,
- y: pos.y,
- z: pos.z.rem_euclid(16).abs() as u8,
- }
- }
-}
-
/// The coordinates of a block inside a chunk section.
#[derive(Clone, Copy, Debug, Default)]
pub struct ChunkSectionBlockPos {
@@ -119,6 +115,80 @@ impl ChunkSectionBlockPos {
}
}
+/// A block pos with an attached dimension
+#[derive(Debug, Clone)]
+pub struct GlobalPos {
+ pub pos: BlockPos,
+ // this is actually a ResourceKey in Minecraft, but i don't think it matters?
+ pub dimension: ResourceLocation,
+}
+
+#[derive(Debug, Clone, Copy, Default)]
+pub struct EntityPos {
+ pub x: f64,
+ pub y: f64,
+ pub z: f64,
+}
+
+impl PositionXYZ<f64> for EntityPos {
+ fn add_x(&self, n: f64) -> Self {
+ EntityPos {
+ x: self.x + n,
+ y: self.y,
+ z: self.z,
+ }
+ }
+ fn add_y(&self, n: f64) -> Self {
+ EntityPos {
+ x: self.x,
+ y: self.y + n,
+ z: self.z,
+ }
+ }
+ fn add_z(&self, n: f64) -> Self {
+ EntityPos {
+ x: self.x,
+ y: self.y,
+ z: self.z + n,
+ }
+ }
+}
+
+impl From<&BlockPos> for ChunkPos {
+ fn from(pos: &BlockPos) -> Self {
+ ChunkPos {
+ x: pos.x.div_floor(16),
+ z: pos.z.div_floor(16),
+ }
+ }
+}
+
+impl From<BlockPos> for ChunkSectionPos {
+ fn from(pos: BlockPos) -> Self {
+ ChunkSectionPos {
+ x: pos.x.div_floor(16),
+ y: pos.y.div_floor(16),
+ z: pos.z.div_floor(16),
+ }
+ }
+}
+
+impl From<ChunkSectionPos> for ChunkPos {
+ fn from(pos: ChunkSectionPos) -> Self {
+ ChunkPos { x: pos.x, z: pos.z }
+ }
+}
+
+impl From<&BlockPos> for ChunkBlockPos {
+ fn from(pos: &BlockPos) -> Self {
+ ChunkBlockPos {
+ x: pos.x.rem_euclid(16).abs() as u8,
+ y: pos.y,
+ z: pos.z.rem_euclid(16).abs() as u8,
+ }
+ }
+}
+
impl From<&BlockPos> for ChunkSectionBlockPos {
fn from(pos: &BlockPos) -> Self {
ChunkSectionBlockPos {
@@ -138,29 +208,77 @@ impl From<&ChunkBlockPos> for ChunkSectionBlockPos {
}
}
}
+impl From<&EntityPos> for BlockPos {
+ fn from(pos: &EntityPos) -> Self {
+ BlockPos {
+ x: pos.x.floor() as i32,
+ y: pos.y.floor() as i32,
+ z: pos.z.floor() as i32,
+ }
+ }
+}
-/// A block pos with an attached dimension
-#[derive(Debug, Clone)]
-pub struct GlobalPos {
- pub pos: BlockPos,
- // this is actually a ResourceKey in Minecraft, but i don't think it matters?
- pub dimension: ResourceLocation,
+impl From<&EntityPos> for ChunkPos {
+ fn from(pos: &EntityPos) -> Self {
+ ChunkPos::from(&BlockPos::from(pos))
+ }
}
-#[derive(Debug, Clone, Default)]
-pub struct EntityPos {
- pub x: f64,
- pub y: f64,
- pub z: f64,
+impl McBufReadable for BlockPos {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ let val = u64::read_into(buf)?;
+ let x = (val >> 38) as i32;
+ let y = (val & 0xFFF) as i32;
+ let z = ((val >> 12) & 0x3FFFFFF) as i32;
+ Ok(BlockPos { x, y, z })
+ }
}
-impl From<&EntityPos> for BlockPos {
- fn from(pos: &EntityPos) -> Self {
- BlockPos {
- x: pos.x as i32,
- y: pos.y as i32,
- z: pos.z as i32,
- }
+impl McBufReadable for GlobalPos {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ Ok(GlobalPos {
+ dimension: ResourceLocation::read_into(buf)?,
+ pos: BlockPos::read_into(buf)?,
+ })
+ }
+}
+
+impl McBufReadable for ChunkSectionPos {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ let long = i64::read_into(buf)?;
+ Ok(ChunkSectionPos {
+ x: (long >> 42) as i32,
+ y: (long << 44 >> 44) as i32,
+ z: (long << 22 >> 42) as i32,
+ })
+ }
+}
+
+impl McBufWritable for BlockPos {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ let data = (((self.x & 0x3FFFFFF) as i64) << 38)
+ | (((self.z & 0x3FFFFFF) as i64) << 12)
+ | ((self.y & 0xFFF) as i64);
+ data.write_into(buf)
+ }
+}
+
+impl McBufWritable for GlobalPos {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ ResourceLocation::write_into(&self.dimension, buf)?;
+ BlockPos::write_into(&self.pos, buf)?;
+
+ Ok(())
+ }
+}
+
+impl McBufWritable for ChunkSectionPos {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ let long = (((self.x & 0x3FFFFF) as i64) << 42)
+ | (self.y & 0xFFFFF) as i64
+ | (((self.z & 0x3FFFFF) as i64) << 20);
+ long.write_into(buf)?;
+ Ok(())
}
}
@@ -181,4 +299,26 @@ mod tests {
let chunk_block_pos = ChunkBlockPos::from(&block_pos);
assert_eq!(chunk_block_pos, ChunkBlockPos::new(5, 78, 14));
}
+
+ #[test]
+ fn test_from_entity_pos_to_block_pos() {
+ let entity_pos = EntityPos {
+ x: 31.5,
+ y: 80.0,
+ z: -16.1,
+ };
+ let block_pos = BlockPos::from(&entity_pos);
+ assert_eq!(block_pos, BlockPos::new(31, 80, -17));
+ }
+
+ #[test]
+ fn test_from_entity_pos_to_chunk_pos() {
+ let entity_pos = EntityPos {
+ x: 31.5,
+ y: 80.0,
+ z: -16.1,
+ };
+ let chunk_pos = ChunkPos::from(&entity_pos);
+ assert_eq!(chunk_pos, ChunkPos::new(1, -2));
+ }
}
diff --git a/azalea-core/src/resource_location.rs b/azalea-core/src/resource_location.rs
index cdf8f381..acca0c58 100755
--- a/azalea-core/src/resource_location.rs
+++ b/azalea-core/src/resource_location.rs
@@ -1,5 +1,8 @@
//! A resource, like minecraft:stone
+use azalea_buf::{McBufReadable, McBufWritable};
+use std::io::{Read, Write};
+
#[derive(Hash, Clone, PartialEq, Eq)]
pub struct ResourceLocation {
pub namespace: String,
@@ -42,8 +45,22 @@ impl std::fmt::Debug for ResourceLocation {
}
}
+impl McBufReadable for ResourceLocation {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ let location_string = String::read_into(buf)?;
+ ResourceLocation::new(&location_string)
+ }
+}
+impl McBufWritable for ResourceLocation {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ self.to_string().write_into(buf)
+ }
+}
+
#[cfg(test)]
mod tests {
+ use std::io::Cursor;
+
use super::*;
#[test]
@@ -70,4 +87,20 @@ mod tests {
assert_eq!(r.namespace, "azalea");
assert_eq!(r.path, "");
}
+
+ #[test]
+ fn mcbuf_resource_location() {
+ let mut buf = Vec::new();
+ ResourceLocation::new("minecraft:dirt")
+ .unwrap()
+ .write_into(&mut buf)
+ .unwrap();
+
+ let mut buf = Cursor::new(buf);
+
+ assert_eq!(
+ ResourceLocation::read_into(&mut buf).unwrap(),
+ ResourceLocation::new("minecraft:dirt").unwrap()
+ );
+ }
}
diff --git a/azalea-core/src/serializable_uuid.rs b/azalea-core/src/serializable_uuid.rs
deleted file mode 100755
index f8c03b60..00000000
--- a/azalea-core/src/serializable_uuid.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-use uuid::Uuid;
-
-pub trait SerializableUuid {
- fn to_int_array(&self) -> [u32; 4];
- fn from_int_array(array: [u32; 4]) -> Self;
-}
-
-fn least_most_to_int_array(most: u64, least: u64) -> [u32; 4] {
- [
- (most >> 32) as u32,
- most as u32,
- (least >> 32) as u32,
- least as u32,
- ]
-}
-
-impl SerializableUuid for Uuid {
- fn to_int_array(&self) -> [u32; 4] {
- let most_significant_bits = (self.as_u128() >> 64) as u64;
- let least_significant_bits = (self.as_u128() & 0xffffffffffffffff) as u64;
-
- least_most_to_int_array(most_significant_bits, least_significant_bits)
- }
-
- fn from_int_array(array: [u32; 4]) -> Self {
- let most = ((array[0] as u64) << 32) | ((array[1] as u64) & 0xFFFFFFFF);
- let least = ((array[2] as u64) << 32) | ((array[3] as u64) & 0xFFFFFFFF);
-
- Uuid::from_u128(((most as u128) << 64) | least as u128)
- }
-}
-
-#[cfg(tests)]
-mod tests {
- use super::*;
-
- #[test]
- fn to_int_array() {
- let u = Uuid::parse_str("6536bfed-8695-48fd-83a1-ecd24cf2a0fd").unwrap();
- assert_eq!(
- u.to_int_array(),
- [0x6536bfed, 0x869548fd, 0x83a1ecd2, 0x4cf2a0fd]
- );
- }
-
- #[test]
- fn from_int_array() {
- let u = Uuid::from_int_array([0x6536bfed, 0x869548fd, 0x83a1ecd2, 0x4cf2a0fd]);
- assert_eq!(u.to_string(), "6536bfed-8695-48fd-83a1-ecd24cf2a0fd");
- }
-}
diff --git a/azalea-core/src/slot.rs b/azalea-core/src/slot.rs
index 5e42f558..6e622872 100644
--- a/azalea-core/src/slot.rs
+++ b/azalea-core/src/slot.rs
@@ -1,14 +1,40 @@
// TODO: have an azalea-inventory or azalea-container crate and put this there
+use azalea_buf::{McBuf, McBufReadable, McBufWritable};
+use std::io::{Read, Write};
+
#[derive(Debug, Clone)]
pub enum Slot {
- Present(SlotData),
Empty,
+ Present(SlotData),
}
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, McBuf)]
pub struct SlotData {
+ #[var]
pub id: i32,
pub count: u8,
pub nbt: azalea_nbt::Tag,
}
+
+impl McBufReadable for Slot {
+ fn read_into(buf: &mut impl Read) -> Result<Self, String> {
+ let present = bool::read_into(buf)?;
+ if !present {
+ return Ok(Slot::Empty);
+ }
+ let slot = SlotData::read_into(buf)?;
+ Ok(Slot::Present(slot))
+ }
+}
+
+impl McBufWritable for Slot {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ match self {
+ Slot::Empty => 0u8.write_into(buf)?,
+ Slot::Present(i) => i.write_into(buf)?,
+ }
+
+ Ok(())
+ }
+}