@@ -3,7 +3,6 @@ use bevy::prelude::*;
33
44use  crate :: { 
55    GRAVITY , 
6-     enemy:: Enemy , 
76    game_flow:: states:: InGameState , 
87    player:: { Player ,  camera:: components:: ViewModelCamera } , 
98} ; 
@@ -32,7 +31,12 @@ pub enum MovementStateEnum {
3231} 
3332
3433#[ derive( Message ) ]  
35- pub  enum  MovementAction  { 
34+ pub  struct  MovementAction  { 
35+     pub  direction :  MovementDirection , 
36+     pub  character_controller_entity :  Entity , 
37+ } 
38+ 
39+ pub  enum  MovementDirection  { 
3640    // TODO: should be possible to just have Vec2 
3741    Move ( Vec3 ) , 
3842    Jump , 
@@ -73,7 +77,7 @@ impl Default for CharacterControllerBundle {
7377                Quaternion :: default ( ) , 
7478                Dir3 :: NEG_Y , 
7579            ) 
76-             . with_max_distance ( 0.2  ) , 
80+             . with_max_distance ( 0.1  ) , 
7781        } 
7882    } 
7983} 
@@ -98,8 +102,7 @@ impl Plugin for CharacterControllerPlugin {
98102                    update_on_ground, 
99103                    apply_gravity_over_time, 
100104                    handle_keyboard_input_for_player, 
101-                     handle_movement_actions_for_player, 
102-                     debug_remove_grounded_from_enemies, 
105+                     handle_movement_actions_for_character_controllers, 
103106                ) 
104107                    . run_if ( in_state ( InGameState :: Playing ) ) , 
105108            ) 
@@ -120,9 +123,14 @@ fn handle_player_dead_velocity(
120123fn  handle_keyboard_input_for_player ( 
121124    keyboard_input :  Res < ButtonInput < KeyCode > > , 
122125    mut  movement_action_writer :  MessageWriter < MovementAction > , 
123-     player_query :  Single < ( & Transform ,  & mut  MovementState ) ,  With < Player > > , 
126+     player_query :  Single < 
127+         ( & Transform ,  & mut  MovementState ,  Entity ) , 
128+         With < Player > , 
129+     > , 
124130)  { 
125-     let  ( player_transform,  mut  movement_state)  = player_query. into_inner ( ) ; 
131+     let  ( player_transform,  mut  movement_state,  player_entity)  =
132+         player_query. into_inner ( ) ; 
133+ 
126134    let  speed = if  keyboard_input. pressed ( KeyCode :: ShiftLeft )  { 
127135        RUN_VELOCITY 
128136    }  else  { 
@@ -146,7 +154,11 @@ fn handle_keyboard_input_for_player(
146154
147155    let  world_velocity = player_transform. rotation  *  local_velocity; 
148156
149-     movement_action_writer. write ( MovementAction :: Move ( world_velocity) ) ; 
157+     movement_action_writer. write ( MovementAction  { 
158+         direction :  MovementDirection :: Move ( world_velocity) , 
159+         character_controller_entity :  player_entity, 
160+     } ) ; 
161+ 
150162    if  local_velocity. x  == 0.0  && local_velocity. z  == 0.0  { 
151163        if  movement_state. 0  != MovementStateEnum :: Idle  { 
152164            movement_state. 0  = MovementStateEnum :: Idle ; 
@@ -162,59 +174,78 @@ fn handle_keyboard_input_for_player(
162174    } 
163175
164176    if  keyboard_input. just_pressed ( KeyCode :: Space )  { 
165-         movement_action_writer. write ( MovementAction :: Jump ) ; 
177+         movement_action_writer. write ( MovementAction  { 
178+             direction :  MovementDirection :: Jump , 
179+             character_controller_entity :  player_entity, 
180+         } ) ; 
166181    } 
167182} 
168183
169- fn  handle_movement_actions_for_player ( 
184+ fn  handle_movement_actions_for_character_controllers ( 
170185    mut  movement_action_reader :  MessageReader < MovementAction > , 
171-     player_query :  Single < 
172-         ( & mut  LinearVelocity ,  & Grounded ,  & Transform ,  Entity ) , 
173-         With < Player > , 
174-     > , 
186+     mut  character_controller_query :  Query < ( 
187+         & mut  LinearVelocity , 
188+         & Grounded , 
189+         & Transform , 
190+         Entity , 
191+     ) > , 
192+     // TODO: i dont want this here 
175193    player_camera_entity :  Single < Entity ,  With < ViewModelCamera > > , 
176194    spatial_query :  SpatialQuery , 
177195    time :  Res < Time > , 
178196)  { 
179-     let  ( mut  player_velocity,  player_grounded,  player_transform,  player_entity)  =
180-         player_query. into_inner ( ) ; 
181197    for  movement_action in  movement_action_reader. read ( )  { 
182-         match  movement_action { 
183-             MovementAction :: Jump  => { 
184-                 if  player_grounded. 0  { 
185-                     player_velocity. y  = JUMP_VELOCITY ; 
198+         let  direction = & movement_action. direction ; 
199+         let  character_controller_entity =
200+             movement_action. character_controller_entity ; 
201+         let  Ok ( ( mut  velocity,  grounded,  transform,  entity) )  =
202+             character_controller_query. get_mut ( character_controller_entity) 
203+         else  { 
204+             // FIXME 
205+             warn ! ( "lkjdsflkjdsf" ) ; 
206+             continue ; 
207+         } ; 
208+ 
209+         match  * direction { 
210+             MovementDirection :: Jump  => { 
211+                 if  grounded. 0  { 
212+                     velocity. y  = JUMP_VELOCITY ; 
186213                } 
187214            } 
188215            // TODO: should probably move the content of this block elsewhere 
189-             MovementAction :: Move ( world_velocity)  => { 
216+             MovementDirection :: Move ( world_velocity)  => { 
190217                let  Ok ( direction_from_world_velocity)  =
191-                     Dir3 :: new ( * world_velocity) 
218+                     Dir3 :: new ( world_velocity) 
192219                else  { 
193-                     player_velocity . x  = 0.0 ; 
194-                     player_velocity . z  = 0.0 ; 
220+                     velocity . x  = 0.0 ; 
221+                     velocity . z  = 0.0 ; 
195222                    return ; 
196223                } ; 
197224
198-                 let  ray_origin = player_transform . translation 
225+                 let  ray_origin = transform . translation 
199226                    - direction_from_world_velocity. as_vec3 ( )  *  0.025 ; 
200227                let  max_distance = 0.3 ; 
201228
229+                 let  spatial_query_filter = & SpatialQueryFilter :: default ( ) 
230+                     . with_excluded_entities ( [ 
231+                         entity, 
232+                         // TODO: should only be excluded when we have player 
233+                         * player_camera_entity, 
234+                     ] ) ; 
235+ 
202236                if  let  Some ( hit_ahead)  = spatial_query. cast_shape ( 
203237                    & Collider :: capsule ( 
204238                        CHARACTER_CAPSULE_RADIUS , 
205239                        CHARACTER_CAPSULE_LENGTH , 
206240                    ) , 
207241                    ray_origin, 
208-                     player_transform . rotation , 
242+                     transform . rotation , 
209243                    direction_from_world_velocity, 
210244                    & ShapeCastConfig  { 
211245                        max_distance, 
212246                        ..default ( ) 
213247                    } , 
214-                     & SpatialQueryFilter :: default ( ) . with_excluded_entities ( [ 
215-                         player_entity, 
216-                         * player_camera_entity, 
217-                     ] ) , 
248+                     spatial_query_filter, 
218249                )  { 
219250                    // obstacle in the way, check if we can slimb it 
220251                    // a normal is just a direction something is facing 
@@ -226,12 +257,12 @@ fn handle_movement_actions_for_player(
226257                        debug ! ( "MOVEMENT: Climable slope!" ) ; 
227258                        // this is the most important part to make the slope climbing possible. 
228259                        // instead of trying to go straight, we slide along the ground 
229-                         player_velocity . 0  =
260+                         velocity . 0  =
230261                            world_velocity. reject_from_normalized ( normal) ; 
231262
232263                        // slope snapping 
233264                        let  ray_down_origin =
234-                             player_transform . translation  + Vec3 :: Y  *  0.5 ; 
265+                             transform . translation  + Vec3 :: Y  *  0.5 ; 
235266                        let  ray_down_direction = Dir3 :: NEG_Y ; 
236267                        let  max_down_distance = 1.0 ; 
237268
@@ -240,21 +271,16 @@ fn handle_movement_actions_for_player(
240271                            ray_down_direction, 
241272                            max_down_distance, 
242273                            true , 
243-                             & SpatialQueryFilter :: default ( ) 
244-                                 . with_excluded_entities ( [ 
245-                                     player_entity, 
246-                                     * player_camera_entity, 
247-                                 ] ) , 
274+                             spatial_query_filter, 
248275                        )  { 
249276                            let  hit_down_point = ray_down_origin
250277                                + ray_down_direction *  hit_down. distance ; 
251278                            let  hit_down_y = hit_down_point. y ; 
252-                             let  player_y = player_transform . translation . y ; 
279+                             let  player_y = transform . translation . y ; 
253280                            let  difference_y = hit_down_y - player_y; 
254281                            if  difference_y. abs ( )  < 0.3  { 
255-                                 info ! ( "Snapping player to slope" ) ; 
256-                                 player_velocity. y  =
257-                                     difference_y / time. delta_secs ( ) ; 
282+                                 info ! ( "Snapping character controller to slope" ) ; 
283+                                 velocity. y  = difference_y / time. delta_secs ( ) ; 
258284                            } 
259285                        } 
260286                    }  else  { 
@@ -267,14 +293,14 @@ fn handle_movement_actions_for_player(
267293                        // want to climb up 
268294                        let  impulse =
269295                            world_velocity. reject_from_normalized ( normal) ; 
270-                         player_velocity . x  = impulse. x ; 
271-                         player_velocity . z  = impulse. z 
296+                         velocity . x  = impulse. x ; 
297+                         velocity . z  = impulse. z 
272298                    } 
273299                }  else  { 
274300                    debug ! ( "MOVEMENT: No obstacle ahead, free movement" ) ; 
275301                    // no obstacle ahead, free movement 
276-                     player_velocity . x  = world_velocity. x ; 
277-                     player_velocity . z  = world_velocity. z ; 
302+                     velocity . x  = world_velocity. x ; 
303+                     velocity . z  = world_velocity. z ; 
278304                } 
279305            } 
280306        } 
@@ -283,20 +309,11 @@ fn handle_movement_actions_for_player(
283309
284310/// Updates the [`Grounded`] status for character controllers. 
285311fn  update_on_ground ( 
286-     mut  query :  Query < ( 
287-         & ShapeHits , 
288-         & Rotation , 
289-         & mut  Grounded , 
290-         & mut  LinearVelocity , 
291-     ) > , 
312+     mut  query :  Query < ( & ShapeHits ,  & mut  Grounded ,  & mut  LinearVelocity ) > , 
292313)  { 
293-     for  ( hits,  rotation,  mut  grounded,  mut  velocity)  in  & mut  query { 
294-         // The character is grounded if the shape caster has a hit with a normal 
295-         // that isn't too steep. 
296-         let  on_ground = hits. iter ( ) . any ( |hit| { 
297-             ( rotation *  -hit. normal2 ) . angle_between ( Vec3 :: Y ) . abs ( ) 
298-                 <= MAX_SLOPE_ANGLE 
299-         } ) ; 
314+     for  ( hits,  mut  grounded,  mut  velocity)  in  & mut  query { 
315+         let  on_ground = hits. 0 . len ( )  > 0 ; 
316+ 
300317        if  grounded. 0  != on_ground { 
301318            grounded. 0  = on_ground; 
302319        } 
@@ -318,15 +335,3 @@ fn apply_gravity_over_time(
318335        } 
319336    } 
320337} 
321- 
322- fn  debug_remove_grounded_from_enemies ( 
323-     mut  commands :  Commands , 
324-     keyboard_input :  Res < ButtonInput < KeyCode > > , 
325-     enemy_query :  Query < Entity ,  With < Enemy > > , 
326- )  { 
327-     if  keyboard_input. just_pressed ( KeyCode :: KeyU )  { 
328-         for  enemy in  enemy_query { 
329-             commands. entity ( enemy) . remove :: < Grounded > ( ) ; 
330-         } 
331-     } 
332- } 
0 commit comments