Skip to content

Commit e889def

Browse files
authored
Fix update_entity_position and fix writing of Angles to client. (#490)
* update_entity_position sends Entity Position packet instead of Teleport Entity packet. * Wraps angles correctly.
1 parent 4639f83 commit e889def

File tree

3 files changed

+45
-24
lines changed

3 files changed

+45
-24
lines changed

feather/protocol/src/io.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,11 @@ impl Readable for Angle {
833833

834834
impl Writeable for Angle {
835835
fn write(&self, buffer: &mut Vec<u8>, version: ProtocolVersion) -> anyhow::Result<()> {
836-
let val = (self.0 / 360.0 * 256.0).round() as u8;
836+
let temp = (256.0 / 360.0) * (self.0 % 360.0);
837+
// Wrap negative values 'x' in the range [-256.0 to 0] to the
838+
// correct angle in the range [0 to 256.0 ) by changing 'x' to
839+
// x = 256.0 - x
840+
let val = ((temp + 256.0) % 256.0) as u8;
837841
val.write(buffer, version)?;
838842

839843
Ok(())

feather/server/src/client.rs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,26 @@ use common::{
1818
Window,
1919
};
2020
use packets::server::{Particle, SetSlot, SpawnLivingEntity, UpdateLight, WindowConfirmation};
21-
use protocol::packets::server::{HeldItemChange, PlayerAbilities};
21+
use protocol::packets::server::{
22+
EntityPosition, EntityPositionAndRotation, HeldItemChange, PlayerAbilities,
23+
};
2224
use protocol::{
2325
packets::{
2426
self,
2527
server::{
2628
AddPlayer, Animation, BlockChange, ChatPosition, ChunkData, ChunkDataKind,
27-
DestroyEntities, Disconnect, EntityAnimation, EntityHeadLook, EntityTeleport, JoinGame,
28-
KeepAlive, PlayerInfo, PlayerPositionAndLook, PluginMessage, SendEntityMetadata,
29-
SpawnPlayer, Title, UnloadChunk, UpdateViewPosition, WindowItems,
29+
DestroyEntities, Disconnect, EntityAnimation, EntityHeadLook, JoinGame, KeepAlive,
30+
PlayerInfo, PlayerPositionAndLook, PluginMessage, SendEntityMetadata, SpawnPlayer,
31+
Title, UnloadChunk, UpdateViewPosition, WindowItems,
3032
},
3133
},
3234
ClientPlayPacket, Nbt, ProtocolVersion, ServerPlayPacket, Writeable,
3335
};
3436
use quill_common::components::{OnGround, PreviousGamemode};
3537

36-
use crate::{initial_handler::NewPlayer, network_id_registry::NetworkId, Options};
38+
use crate::{
39+
entities::PreviousPosition, initial_handler::NewPlayer, network_id_registry::NetworkId, Options,
40+
};
3741
use slab::Slab;
3842

3943
/// Max number of chunks to send to a client per tick.
@@ -379,6 +383,7 @@ impl Client {
379383
&self,
380384
network_id: NetworkId,
381385
position: Position,
386+
prev_position: PreviousPosition,
382387
on_ground: OnGround,
383388
) {
384389
if self.network_id == Some(network_id) {
@@ -390,23 +395,35 @@ impl Client {
390395
}
391396
return;
392397
}
393-
// Consider using the relative movement packets in the future.
394-
// (Entity Teleport works fine, but the relative movement packets
395-
// save bandwidth.)
396-
self.send_packet(EntityTeleport {
397-
entity_id: network_id.0,
398-
x: position.x,
399-
y: position.y,
400-
z: position.z,
401-
yaw: position.yaw,
402-
pitch: position.pitch,
403-
on_ground: on_ground.0,
404-
});
405-
// Needed for head orientation
406-
self.send_packet(EntityHeadLook {
407-
entity_id: network_id.0,
408-
head_yaw: position.yaw,
409-
});
398+
399+
let no_change_yaw = (position.yaw - prev_position.0.yaw).abs() < 0.001;
400+
let no_change_pitch = (position.pitch - prev_position.0.pitch).abs() < 0.001;
401+
402+
if no_change_yaw && no_change_pitch {
403+
self.send_packet(EntityPosition {
404+
entity_id: network_id.0,
405+
delta_x: ((position.x * 32.0 - prev_position.0.x * 32.0) * 128.0) as i16,
406+
delta_y: ((position.y * 32.0 - prev_position.0.y * 32.0) * 128.0) as i16,
407+
delta_z: ((position.z * 32.0 - prev_position.0.z * 32.0) * 128.0) as i16,
408+
on_ground: on_ground.0,
409+
});
410+
} else {
411+
self.send_packet(EntityPositionAndRotation {
412+
entity_id: network_id.0,
413+
delta_x: ((position.x * 32.0 - prev_position.0.x * 32.0) * 128.0) as i16,
414+
delta_y: ((position.y * 32.0 - prev_position.0.y * 32.0) * 128.0) as i16,
415+
delta_z: ((position.z * 32.0 - prev_position.0.z * 32.0) * 128.0) as i16,
416+
yaw: position.yaw,
417+
pitch: position.pitch,
418+
on_ground: on_ground.0,
419+
});
420+
421+
// Needed for head orientation
422+
self.send_packet(EntityHeadLook {
423+
entity_id: network_id.0,
424+
head_yaw: position.yaw,
425+
});
426+
}
410427
}
411428

412429
pub fn send_keepalive(&self) {

feather/server/src/systems/entity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn send_entity_movement(game: &mut Game, server: &mut Server) -> SysResult {
2424
{
2525
if position != prev_position.0 {
2626
server.broadcast_nearby_with(position, |client| {
27-
client.update_entity_position(network_id, position, on_ground);
27+
client.update_entity_position(network_id, position, *prev_position, on_ground);
2828
});
2929
prev_position.0 = position;
3030
}

0 commit comments

Comments
 (0)