@@ -48,6 +48,8 @@ pub struct IdleKickBomb;
4848pub struct LitKickBomb {
4949 arm_delay : Timer ,
5050 fuse_time : Timer ,
51+ kicking : bool ,
52+ kicks : u32 ,
5153}
5254
5355fn hydrate (
@@ -178,6 +180,8 @@ fn update_idle_kick_bombs(
178180 LitKickBomb {
179181 arm_delay : Timer :: new ( arm_delay, TimerMode :: Once ) ,
180182 fuse_time : Timer :: new ( fuse_time, TimerMode :: Once ) ,
183+ kicking : false ,
184+ kicks : 0 ,
181185 } ,
182186 ) ;
183187 } ,
@@ -199,8 +203,6 @@ fn update_lit_kick_bombs(
199203 mut sprites : CompMut < AtlasSprite > ,
200204 mut bodies : CompMut < KinematicBody > ,
201205 mut hydrated : CompMut < MapElementHydrated > ,
202- mut attachments : CompMut < PlayerBodyAttachment > ,
203- mut player_layers : CompMut < PlayerLayers > ,
204206 player_inventories : PlayerInventories ,
205207 mut transforms : CompMut < Transform > ,
206208 mut commands : Commands ,
@@ -214,7 +216,6 @@ fn update_lit_kick_bombs(
214216 let element_meta = assets. get ( element_handle. 0 ) ;
215217 let asset = assets. get ( element_meta. data ) ;
216218 let Ok ( KickBombMeta {
217- grab_offset,
218219 explosion_sound,
219220 explosion_volume,
220221 kick_velocity,
@@ -224,7 +225,6 @@ fn update_lit_kick_bombs(
224225 explosion_atlas,
225226 explosion_fps,
226227 explosion_frames,
227- fin_anim,
228228 ..
229229 } ) = asset. try_cast_ref ( )
230230 else {
@@ -234,59 +234,65 @@ fn update_lit_kick_bombs(
234234 kick_bomb. fuse_time . tick ( time. delta ( ) ) ;
235235 kick_bomb. arm_delay . tick ( time. delta ( ) ) ;
236236
237- let mut should_explode = false ;
238- // If the item is being held
239- if let Some ( Inv { player, .. } ) = player_inventories. find_item ( entity) {
240- let body = bodies. get_mut ( entity) . unwrap ( ) ;
241- player_layers. get_mut ( player) . unwrap ( ) . fin_anim = * fin_anim;
237+ let should_explode = ' should_explode: {
238+ if kick_bomb. fuse_time . finished ( ) {
239+ break ' should_explode true ;
240+ }
242241
243- // Deactivate held items
244- body. is_deactivated = true ;
242+ // If the item is being held
243+ if player_inventories. find_item ( entity) . is_some ( ) {
244+ kick_bomb. kicking = false ;
245+ break ' should_explode false ;
246+ }
245247
246- // Attach to the player
247- attachments. insert (
248- entity,
249- PlayerBodyAttachment {
250- player,
251- sync_color : false ,
252- sync_animation : false ,
253- head : false ,
254- offset : grab_offset. extend ( 1.0 ) ,
255- } ,
256- ) ;
257- }
258- // The item is on the ground
259- else if let Some ( player_entity) = collision_world
260- . actor_collisions_filtered ( entity, |e| invincibles. get ( e) . is_none ( ) )
261- . into_iter ( )
262- . find ( |& x| player_indexes. contains ( x) )
263- {
264- let body = bodies. get_mut ( entity) . unwrap ( ) ;
265- let translation = transforms. get_mut ( entity) . unwrap ( ) . translation ;
248+ // If the item is colliding with a non-invincible player
249+ if let Some ( player_entity) = collision_world
250+ . actor_collisions_filtered ( entity, |e| !invincibles. contains ( e) )
251+ . into_iter ( )
252+ . find ( |& x| player_indexes. contains ( x) )
253+ {
254+ if !std:: mem:: replace ( & mut kick_bomb. kicking , true ) {
255+ kick_bomb. kicks += 1 ;
256+ }
257+
258+ // Explode on the 3rd kick.
259+ // Dropping the bomb is detected as a kick so we explode when
260+ // the counter reaches 4.
261+ if kick_bomb. kicks > 3 {
262+ break ' should_explode true ;
263+ }
266264
267- let player_sprite = sprites . get_mut ( player_entity ) . unwrap ( ) ;
268- let player_translation = transforms. get ( player_entity ) . unwrap ( ) . translation ;
265+ let body = bodies . get_mut ( entity ) . unwrap ( ) ;
266+ let translation = transforms. get_mut ( entity ) . unwrap ( ) . translation ;
269267
270- let player_standing_left = player_translation. x <= translation. x ;
268+ let player_sprite = sprites. get_mut ( player_entity) . unwrap ( ) ;
269+ let player_translation = transforms. get ( player_entity) . unwrap ( ) . translation ;
271270
272- if body. velocity . x == 0.0 {
273- body. velocity = * kick_velocity;
274- if player_sprite. flip_x {
275- body. velocity . x *= -1.0 ;
271+ let player_standing_left = player_translation. x <= translation. x ;
272+
273+ if body. velocity . x == 0.0 {
274+ body. velocity = * kick_velocity;
275+ if player_sprite. flip_x {
276+ body. velocity . x *= -1.0 ;
277+ }
278+ } else if player_standing_left && !player_sprite. flip_x {
279+ body. velocity . x = kick_velocity. x ;
280+ body. velocity . y = kick_velocity. y ;
281+ } else if !player_standing_left && player_sprite. flip_x {
282+ body. velocity . x = -kick_velocity. x ;
283+ body. velocity . y = kick_velocity. y ;
284+ } else if kick_bomb. arm_delay . finished ( ) {
285+ break ' should_explode true ;
276286 }
277- } else if player_standing_left && !player_sprite. flip_x {
278- body. velocity . x = kick_velocity. x ;
279- body. velocity . y = kick_velocity. y ;
280- } else if !player_standing_left && player_sprite. flip_x {
281- body. velocity . x = -kick_velocity. x ;
282- body. velocity . y = kick_velocity. y ;
283- } else if kick_bomb. arm_delay . finished ( ) {
284- should_explode = true ;
287+ } else {
288+ kick_bomb. kicking = false ;
285289 }
286- }
290+
291+ false
292+ } ;
287293
288294 // If it's time to explode
289- if kick_bomb . fuse_time . finished ( ) || should_explode {
295+ if should_explode {
290296 audio_events. play ( * explosion_sound, * explosion_volume) ;
291297
292298 trauma_events. send ( 7.5 ) ;
0 commit comments