diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2022-06-25 05:09:26 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-25 05:09:26 +0000 |
| commit | 7d3e57763e32ac9cf94180b1c714704cfbc3034d (patch) | |
| tree | 2dcfe72bf09a42f6614f9dc988dc0254162ea0bf /azalea-core/src | |
| parent | 69c47eda4c496b13dadd80976bffd2fab7ea5894 (diff) | |
| parent | ca7067e173129f3044ebc8c77634f06da29a086e (diff) | |
| download | azalea-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.rs | 68 | ||||
| -rwxr-xr-x | azalea-core/src/difficulty.rs | 27 | ||||
| -rw-r--r-- | azalea-core/src/direction.rs | 4 | ||||
| -rwxr-xr-x | azalea-core/src/game_type.rs | 54 | ||||
| -rwxr-xr-x | azalea-core/src/lib.rs | 18 | ||||
| -rw-r--r-- | azalea-core/src/particle/mod.rs | 262 | ||||
| -rw-r--r-- | azalea-core/src/position.rs | 258 | ||||
| -rwxr-xr-x | azalea-core/src/resource_location.rs | 33 | ||||
| -rwxr-xr-x | azalea-core/src/serializable_uuid.rs | 51 | ||||
| -rw-r--r-- | azalea-core/src/slot.rs | 30 |
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(()) + } +} |
