Set player head yaw when spawning

This commit is contained in:
Ryan 2022-10-05 15:02:40 -07:00
parent 1f996f7549
commit 1fcc5bd527
2 changed files with 48 additions and 45 deletions

View file

@ -1457,11 +1457,7 @@ impl<C: Config> Client<C> {
&& entity.uuid() != self.uuid && entity.uuid() != self.uuid
&& self.loaded_entities.insert(id) && self.loaded_entities.insert(id)
{ {
self.send_packet( entity.spawn_packets(id, |pkt| self.send_packet(pkt));
entity
.spawn_packet(id)
.expect("should not be a marker entity"),
);
if let Some(meta) = entity.initial_tracked_data_packet(id) { if let Some(meta) = entity.initial_tracked_data_packet(id) {
self.send_packet(meta); self.send_packet(meta);

View file

@ -14,7 +14,7 @@ use vek::{Aabb, Vec3};
use crate::config::Config; use crate::config::Config;
use crate::entity::types::{Facing, PaintingKind, Pose}; use crate::entity::types::{Facing, PaintingKind, Pose};
use crate::protocol::packets::s2c::play::{ 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::protocol::{ByteAngle, RawBytes, VarInt};
use crate::slab_versioned::{Key, VersionedSlab}; use crate::slab_versioned::{Key, VersionedSlab};
@ -737,9 +737,14 @@ impl<C: Config> Entity<C> {
}) })
} }
pub(crate) fn spawn_packet(&self, this_id: EntityId) -> Option<EntitySpawnPacket> { /// 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| { let with_object_data = |data| {
Some(EntitySpawnPacket::Entity(SpawnEntity { S2cPlayPacket::from(SpawnEntity {
entity_id: VarInt(this_id.to_network_id()), entity_id: VarInt(this_id.to_network_id()),
object_uuid: self.uuid, object_uuid: self.uuid,
kind: VarInt(self.kind() as i32), kind: VarInt(self.kind() as i32),
@ -749,39 +754,57 @@ impl<C: Config> Entity<C> {
head_yaw: ByteAngle::from_degrees(self.head_yaw), head_yaw: ByteAngle::from_degrees(self.head_yaw),
data: VarInt(data), data: VarInt(data),
velocity: velocity_to_packet_units(self.velocity), velocity: velocity_to_packet_units(self.velocity),
})) })
}; };
match &self.variants { match &self.variants {
TrackedData::Marker(_) => None, TrackedData::Marker(_) => {}
TrackedData::ExperienceOrb(_) => { TrackedData::ExperienceOrb(_) => push_packet(
Some(EntitySpawnPacket::ExperienceOrb(SpawnExperienceOrb { SpawnExperienceOrb {
entity_id: VarInt(this_id.to_network_id()), entity_id: VarInt(this_id.to_network_id()),
position: self.new_position, position: self.new_position,
count: 0, // TODO count: 0, // TODO
}))
} }
TrackedData::Player(_) => Some(EntitySpawnPacket::Player(SpawnPlayer { .into(),
),
TrackedData::Player(_) => {
push_packet(
SpawnPlayer {
entity_id: VarInt(this_id.to_network_id()), entity_id: VarInt(this_id.to_network_id()),
player_uuid: self.uuid, player_uuid: self.uuid,
position: self.new_position, position: self.new_position,
yaw: ByteAngle::from_degrees(self.yaw), yaw: ByteAngle::from_degrees(self.yaw),
pitch: ByteAngle::from_degrees(self.pitch), pitch: ByteAngle::from_degrees(self.pitch),
})), }
TrackedData::ItemFrame(e) => with_object_data(e.get_rotation()), .into(),
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 { // 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::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, 0 => 3,
1 => 4, 1 => 4,
2 => 2, 2 => 2,
_ => 5, _ => 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. _ => push_packet(with_object_data(0)),
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),
} }
} }
} }
@ -791,22 +814,6 @@ pub(crate) fn velocity_to_packet_units(vel: Vec3<f32>) -> Vec3<i16> {
(8000.0 / STANDARD_TPS as f32 * vel).as_() (8000.0 / STANDARD_TPS as f32 * vel).as_()
} }
pub(crate) enum EntitySpawnPacket {
Entity(SpawnEntity),
ExperienceOrb(SpawnExperienceOrb),
Player(SpawnPlayer),
}
impl From<EntitySpawnPacket> 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)] #[cfg(test)]
mod tests { mod tests {
use std::num::NonZeroU32; use std::num::NonZeroU32;