1
1
//! Sends entity-related packets to clients.
2
2
//! Spawn packets, position updates, equipment, animations, etc.
3
3
4
- use base:: Position ;
4
+ use base:: {
5
+ metadata:: { EntityBitMask , Pose , META_INDEX_ENTITY_BITMASK , META_INDEX_POSE } ,
6
+ EntityMetadata , Position ,
7
+ } ;
5
8
use common:: Game ;
6
9
use ecs:: { SysResult , SystemExecutor } ;
7
- use quill_common:: components:: OnGround ;
10
+ use quill_common:: {
11
+ components:: { OnGround , Sprinting } ,
12
+ events:: { SneakEvent , SprintEvent } ,
13
+ } ;
8
14
9
15
use crate :: { entities:: PreviousPosition , NetworkId , Server } ;
10
16
11
17
mod spawn_packet;
12
18
13
19
pub fn register ( game : & mut Game , systems : & mut SystemExecutor < Game > ) {
14
20
spawn_packet:: register ( game, systems) ;
15
- systems. group :: < Server > ( ) . add_system ( send_entity_movement) ;
21
+ systems
22
+ . group :: < Server > ( )
23
+ . add_system ( send_entity_movement)
24
+ . add_system ( send_entity_sneak_metadata)
25
+ . add_system ( send_entity_sprint_metadata) ;
16
26
}
17
27
18
28
/// Sends entity movement packets.
@@ -31,3 +41,51 @@ fn send_entity_movement(game: &mut Game, server: &mut Server) -> SysResult {
31
41
}
32
42
Ok ( ( ) )
33
43
}
44
+
45
+ /// Sends [SendEntityMetadata](protocol::packets::server::play::SendEntityMetadata) packet for when an entity is sneaking.
46
+ fn send_entity_sneak_metadata ( game : & mut Game , server : & mut Server ) -> SysResult {
47
+ for ( _, ( & position, & SneakEvent { is_sneaking } , is_sprinting, & network_id) ) in game
48
+ . ecs
49
+ . query :: < ( & Position , & SneakEvent , & Sprinting , & NetworkId ) > ( )
50
+ . iter ( )
51
+ {
52
+ let mut metadata = EntityMetadata :: entity_base ( ) ;
53
+ let mut bit_mask = EntityBitMask :: empty ( ) ;
54
+
55
+ // The Entity can sneak and sprint at the same time, what happens is that when it stops sneaking you immediately start running again.
56
+ bit_mask. set ( EntityBitMask :: CROUCHED , is_sneaking) ;
57
+ bit_mask. set ( EntityBitMask :: SPRINTING , is_sprinting. 0 ) ;
58
+ metadata. set ( META_INDEX_ENTITY_BITMASK , bit_mask. bits ( ) ) ;
59
+
60
+ if is_sneaking {
61
+ metadata. set ( META_INDEX_POSE , Pose :: Sneaking ) ;
62
+ } else {
63
+ metadata. set ( META_INDEX_POSE , Pose :: Standing ) ;
64
+ }
65
+
66
+ server. broadcast_nearby_with ( position, |client| {
67
+ client. send_entity_metadata ( network_id, metadata. clone ( ) ) ;
68
+ } ) ;
69
+ }
70
+ Ok ( ( ) )
71
+ }
72
+
73
+ /// Sends [SendEntityMetadata](protocol::packets::server::play::SendEntityMetadata) packet for when an entity is sprinting.
74
+ fn send_entity_sprint_metadata ( game : & mut Game , server : & mut Server ) -> SysResult {
75
+ for ( _, ( & position, & SprintEvent { is_sprinting } , & network_id) ) in game
76
+ . ecs
77
+ . query :: < ( & Position , & SprintEvent , & NetworkId ) > ( )
78
+ . iter ( )
79
+ {
80
+ let mut metadata = EntityMetadata :: entity_base ( ) ;
81
+ let mut bit_mask = EntityBitMask :: empty ( ) ;
82
+
83
+ bit_mask. set ( EntityBitMask :: SPRINTING , is_sprinting) ;
84
+ metadata. set ( META_INDEX_ENTITY_BITMASK , bit_mask. bits ( ) ) ;
85
+
86
+ server. broadcast_nearby_with ( position, |client| {
87
+ client. send_entity_metadata ( network_id, metadata. clone ( ) ) ;
88
+ } ) ;
89
+ }
90
+ Ok ( ( ) )
91
+ }
0 commit comments