From 1fcc5bd527d45a101f46e30a9ca452b61ebf8866 Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 5 Oct 2022 15:02:40 -0700 Subject: [PATCH] Set player head yaw when spawning --- src/client.rs | 6 +--- src/entity.rs | 87 ++++++++++++++++++++++++++++----------------------- 2 files changed, 48 insertions(+), 45 deletions(-) diff --git a/src/client.rs b/src/client.rs index 72977a7..90aacdc 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1457,11 +1457,7 @@ impl Client { && entity.uuid() != self.uuid && self.loaded_entities.insert(id) { - self.send_packet( - entity - .spawn_packet(id) - .expect("should not be a marker entity"), - ); + entity.spawn_packets(id, |pkt| self.send_packet(pkt)); if let Some(meta) = entity.initial_tracked_data_packet(id) { self.send_packet(meta); diff --git a/src/entity.rs b/src/entity.rs index 6524a20..e45f72e 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -14,7 +14,7 @@ use vek::{Aabb, Vec3}; use crate::config::Config; use crate::entity::types::{Facing, PaintingKind, Pose}; use crate::protocol::packets::s2c::play::{ - S2cPlayPacket, SetEntityMetadata, SpawnEntity, SpawnExperienceOrb, SpawnPlayer, + S2cPlayPacket, SetEntityMetadata, SetHeadRotation, SpawnEntity, SpawnExperienceOrb, SpawnPlayer, }; use crate::protocol::{ByteAngle, RawBytes, VarInt}; use crate::slab_versioned::{Key, VersionedSlab}; @@ -737,9 +737,14 @@ impl Entity { }) } - pub(crate) fn spawn_packet(&self, this_id: EntityId) -> Option { + /// Sends the appropriate packets to spawn the entity. + pub(crate) fn spawn_packets( + &self, + this_id: EntityId, + mut push_packet: impl FnMut(S2cPlayPacket), + ) { let with_object_data = |data| { - Some(EntitySpawnPacket::Entity(SpawnEntity { + S2cPlayPacket::from(SpawnEntity { entity_id: VarInt(this_id.to_network_id()), object_uuid: self.uuid, kind: VarInt(self.kind() as i32), @@ -749,39 +754,57 @@ impl Entity { head_yaw: ByteAngle::from_degrees(self.head_yaw), data: VarInt(data), velocity: velocity_to_packet_units(self.velocity), - })) + }) }; match &self.variants { - TrackedData::Marker(_) => None, - TrackedData::ExperienceOrb(_) => { - Some(EntitySpawnPacket::ExperienceOrb(SpawnExperienceOrb { + TrackedData::Marker(_) => {} + TrackedData::ExperienceOrb(_) => push_packet( + SpawnExperienceOrb { entity_id: VarInt(this_id.to_network_id()), position: self.new_position, count: 0, // TODO - })) + } + .into(), + ), + TrackedData::Player(_) => { + push_packet( + SpawnPlayer { + entity_id: VarInt(this_id.to_network_id()), + player_uuid: self.uuid, + position: self.new_position, + yaw: ByteAngle::from_degrees(self.yaw), + pitch: ByteAngle::from_degrees(self.pitch), + } + .into(), + ); + + // Player spawn packet doesn't include head yaw for some reason. + push_packet( + SetHeadRotation { + entity_id: VarInt(this_id.to_network_id()), + head_yaw: ByteAngle::from_degrees(self.head_yaw), + } + .into(), + ); } - TrackedData::Player(_) => Some(EntitySpawnPacket::Player(SpawnPlayer { - entity_id: VarInt(this_id.to_network_id()), - player_uuid: self.uuid, - position: self.new_position, - yaw: ByteAngle::from_degrees(self.yaw), - pitch: ByteAngle::from_degrees(self.pitch), - })), - TrackedData::ItemFrame(e) => with_object_data(e.get_rotation()), - TrackedData::GlowItemFrame(e) => with_object_data(e.get_rotation()), - TrackedData::Painting(_) => { - with_object_data(match ((self.yaw + 45.0).rem_euclid(360.0) / 90.0) as u8 { + TrackedData::ItemFrame(e) => push_packet(with_object_data(e.get_rotation())), + TrackedData::GlowItemFrame(e) => push_packet(with_object_data(e.get_rotation())), + TrackedData::Painting(_) => push_packet(with_object_data( + match ((self.yaw + 45.0).rem_euclid(360.0) / 90.0) as u8 { 0 => 3, 1 => 4, 2 => 2, _ => 5, - }) + }, + )), + // TODO: set block state ID for falling block. + TrackedData::FallingBlock(_) => push_packet(with_object_data(1)), + TrackedData::FishingBobber(e) => push_packet(with_object_data(e.get_hook_entity_id())), + TrackedData::Warden(e) => { + push_packet(with_object_data((e.get_pose() == Pose::Emerging).into())) } - TrackedData::FallingBlock(_) => with_object_data(1), // TODO: set block state ID. - TrackedData::FishingBobber(e) => with_object_data(e.get_hook_entity_id()), - TrackedData::Warden(e) => with_object_data((e.get_pose() == Pose::Emerging).into()), - _ => with_object_data(0), + _ => push_packet(with_object_data(0)), } } } @@ -791,22 +814,6 @@ pub(crate) fn velocity_to_packet_units(vel: Vec3) -> Vec3 { (8000.0 / STANDARD_TPS as f32 * vel).as_() } -pub(crate) enum EntitySpawnPacket { - Entity(SpawnEntity), - ExperienceOrb(SpawnExperienceOrb), - Player(SpawnPlayer), -} - -impl From for S2cPlayPacket { - fn from(pkt: EntitySpawnPacket) -> Self { - match pkt { - EntitySpawnPacket::Entity(pkt) => pkt.into(), - EntitySpawnPacket::ExperienceOrb(pkt) => pkt.into(), - EntitySpawnPacket::Player(pkt) => pkt.into(), - } - } -} - #[cfg(test)] mod tests { use std::num::NonZeroU32;