@@ -29,17 +29,41 @@ impl Default for FovModifier {
29
29
}
30
30
}
31
31
32
+ /// Send if the client sends [`UpdatePlayerAbilitiesC2s::StartFlying`]
33
+ #[ derive( Event ) ]
34
+ pub struct PlayerStartFlyingEvent {
35
+ pub client : Entity ,
36
+ }
37
+
38
+ /// Send if the client sends [`UpdatePlayerAbilitiesC2s::StopFlying`]
39
+ #[ derive( Event ) ]
40
+ pub struct PlayerStopFlyingEvent {
41
+ pub client : Entity ,
42
+ }
43
+
44
+ /// Order of execution :
45
+ /// 1. [`update_game_mode`] : Watch [`GameMode`] changes => Send
46
+ /// [`GameStateChangeS2c`] to update the client's gamemode
47
+ /// 2. [`update_client_player_abilities`] : Watch [`PlayerAbilitiesFlags`],
48
+ /// [`FlyingSpeed`] and [`FovModifier`] changes => Send [`PlayerAbilitiesS2c`]
49
+ /// to update the client's abilities 3. [`update_player_abilities`] : Watch
50
+ /// [`GameMode`] changes => Update [`PlayerAbilitiesFlags`] according to the
51
+ /// [`GameMode`] 4. [`update_server_player_abilities`] : Watch
52
+ /// [`UpdatePlayerAbilitiesC2s`] packets => Update [`PlayerAbilitiesFlags`]
53
+ /// according to the packet
32
54
pub ( super ) fn build ( app : & mut App ) {
33
- app. add_systems (
34
- PostUpdate ,
35
- (
36
- update_client_player_abilities,
37
- update_player_abilities. before ( update_client_player_abilities) ,
55
+ app. add_event :: < PlayerStartFlyingEvent > ( )
56
+ . add_event :: < PlayerStopFlyingEvent > ( )
57
+ . add_systems (
58
+ PostUpdate ,
59
+ (
60
+ update_client_player_abilities,
61
+ update_player_abilities. before ( update_client_player_abilities) ,
62
+ )
63
+ . in_set ( UpdateClientsSet )
64
+ . after ( update_game_mode) ,
38
65
)
39
- . in_set ( UpdateClientsSet )
40
- . after ( update_game_mode) ,
41
- )
42
- . add_systems ( EventLoopPreUpdate , update_server_player_abilities) ;
66
+ . add_systems ( EventLoopPreUpdate , update_server_player_abilities) ;
43
67
}
44
68
45
69
fn update_client_player_abilities (
@@ -66,10 +90,15 @@ fn update_client_player_abilities(
66
90
}
67
91
}
68
92
93
+ /// /!\ This system does not trigger change detection on
94
+ /// [`PlayerAbilitiesFlags`]
69
95
fn update_player_abilities (
70
- mut client_query : Query < ( & mut PlayerAbilitiesFlags , & GameMode ) , Changed < GameMode > > ,
96
+ mut player_start_flying_event_writer : EventWriter < PlayerStartFlyingEvent > ,
97
+ mut player_stop_flying_event_writer : EventWriter < PlayerStopFlyingEvent > ,
98
+ mut client_query : Query < ( Entity , & mut PlayerAbilitiesFlags , & GameMode ) , Changed < GameMode > > ,
71
99
) {
72
- for ( mut flags, gamemode) in client_query. iter_mut ( ) {
100
+ for ( entity, mut mut_flags, gamemode) in client_query. iter_mut ( ) {
101
+ let flags = mut_flags. bypass_change_detection ( ) ;
73
102
match gamemode {
74
103
GameMode :: Creative => {
75
104
flags. set_invulnerable ( true ) ;
@@ -81,25 +110,52 @@ fn update_player_abilities(
81
110
flags. set_allow_flying ( true ) ;
82
111
flags. set_instant_break ( false ) ;
83
112
flags. set_flying ( true ) ;
113
+ player_start_flying_event_writer. send ( PlayerStartFlyingEvent { client : entity } ) ;
114
+ }
115
+ GameMode :: Survival => {
116
+ flags. set_invulnerable ( false ) ;
117
+ flags. set_allow_flying ( false ) ;
118
+ flags. set_instant_break ( false ) ;
119
+ flags. set_flying ( false ) ;
120
+ player_stop_flying_event_writer. send ( PlayerStopFlyingEvent { client : entity } ) ;
84
121
}
85
- _ => {
122
+ GameMode :: Adventure => {
86
123
flags. set_invulnerable ( false ) ;
87
124
flags. set_allow_flying ( false ) ;
88
125
flags. set_instant_break ( false ) ;
126
+ flags. set_flying ( false ) ;
127
+ player_stop_flying_event_writer. send ( PlayerStopFlyingEvent { client : entity } ) ;
89
128
}
90
129
}
91
130
}
92
131
}
93
132
133
+ /// /!\ This system does not trigger change detection on
134
+ /// [`PlayerAbilitiesFlags`]
94
135
fn update_server_player_abilities (
95
136
mut packet_events : EventReader < PacketEvent > ,
137
+ mut player_start_flying_event_writer : EventWriter < PlayerStartFlyingEvent > ,
138
+ mut player_stop_flying_event_writer : EventWriter < PlayerStopFlyingEvent > ,
96
139
mut client_query : Query < & mut PlayerAbilitiesFlags > ,
97
140
) {
98
141
for packets in packet_events. iter ( ) {
99
142
if let Some ( pkt) = packets. decode :: < UpdatePlayerAbilitiesC2s > ( ) {
100
- if let Ok ( mut flags) = client_query. get_mut ( packets. client ) {
101
- flags. set_flying ( UpdatePlayerAbilitiesC2s :: StartFlying . eq ( & pkt) ) ;
102
- flags. bypass_change_detection ( ) ;
143
+ if let Ok ( mut mut_flags) = client_query. get_mut ( packets. client ) {
144
+ let flags = mut_flags. bypass_change_detection ( ) ;
145
+ match pkt {
146
+ UpdatePlayerAbilitiesC2s :: StartFlying => {
147
+ flags. set_flying ( true ) ;
148
+ player_start_flying_event_writer. send ( PlayerStartFlyingEvent {
149
+ client : packets. client ,
150
+ } ) ;
151
+ }
152
+ UpdatePlayerAbilitiesC2s :: StopFlying => {
153
+ flags. set_flying ( false ) ;
154
+ player_stop_flying_event_writer. send ( PlayerStopFlyingEvent {
155
+ client : packets. client ,
156
+ } ) ;
157
+ }
158
+ }
103
159
}
104
160
}
105
161
}
0 commit comments