diff --git a/src/game/systems/movement.rs b/src/game/systems/movement.rs index ba73e18..e912fc3 100644 --- a/src/game/systems/movement.rs +++ b/src/game/systems/movement.rs @@ -58,41 +58,72 @@ pub fn apply_piece_movement( blocks }; - let cast_shape = - |pos| collisions.cast_shape(pos, &blocks) || !game_area.is_shape_inside(pos, &blocks); + { + let cast_shape = |pos| { + collisions.cast_shape(pos, &blocks) || !game_area.is_shape_inside(pos, &blocks) + }; + let piece_pos = &mut transform_query.get_mut(entity).unwrap().0.translation; - let piece_pos = &mut transform_query.get_mut(entity).unwrap().0.translation; - - if controls.instant_drop { - let mut drop_pos = *piece_pos; - while !cast_shape(drop_pos + Vector2I::DOWN) { - drop_pos = drop_pos + Vector2I::DOWN; - } - *piece_pos = drop_pos; - commands.trigger_targets(OnPiecePlaced { piece: entity }, game_entity); - continue; - } - - let can_move_down = !cast_shape(*piece_pos + Vector2I::DOWN); - - if let Some(mut gravity) = maybe_gravity { - if gravity.cumulated >= 1.0 && can_move_down { - gravity.cumulated -= 1.0; - *piece_pos = *piece_pos + Vector2I::DOWN; - } - if gravity.cumulated >= 3.0 && !can_move_down { + if controls.instant_drop { + let mut drop_pos = *piece_pos; + while !cast_shape(drop_pos + Vector2I::DOWN) { + drop_pos = drop_pos + Vector2I::DOWN; + } + *piece_pos = drop_pos; commands.trigger_targets(OnPiecePlaced { piece: entity }, game_entity); continue; } + + let can_move_down = !cast_shape(*piece_pos + Vector2I::DOWN); + + if let Some(mut gravity) = maybe_gravity { + if gravity.cumulated >= 1.0 && can_move_down { + gravity.cumulated -= 1.0; + *piece_pos = *piece_pos + Vector2I::DOWN; + } + if gravity.cumulated >= 3.0 && !can_move_down { + commands.trigger_targets(OnPiecePlaced { piece: entity }, game_entity); + continue; + } + } + + if let Some(movement) = controls.movement { + let dir = match movement { + input::Move::Left => Vector2I::LEFT, + input::Move::Right => Vector2I::RIGHT, + }; + if !cast_shape(*piece_pos + dir) { + *piece_pos = *piece_pos + dir; + } + } } - if let Some(movement) = controls.movement { - let dir = match movement { - input::Move::Left => Vector2I::LEFT, - input::Move::Right => Vector2I::RIGHT, + { + let cast_shape = |pos, blocks| { + collisions.cast_shape(pos, blocks) || !game_area.is_shape_inside(pos, blocks) }; - if !cast_shape(*piece_pos + dir) { - *piece_pos = *piece_pos + dir; + let rotate = |point: Vector2I, rotation: input::Rotation| match rotation { + input::Rotation::Clockwise => Vector2I::new(point.y, -point.x), + input::Rotation::CounterClockwise => Vector2I::new(-point.y, point.x), + }; + let rotate_slice = |points: &[Vector2I], rotation: input::Rotation| { + points + .iter() + .map(|point| rotate(*point, rotation)) + .collect::>() + }; + let piece_pos = transform_query.get(entity).unwrap().0.translation; + if let Some(rotation) = controls.rotation { + let rotated = rotate_slice(&blocks, rotation); + if !cast_shape(piece_pos, &rotated) { + for child in children.iter() { + if let Ok((mut transform, has_block)) = transform_query.get_mut(child) { + if has_block { + transform.translation = rotate(transform.translation, rotation); + } + } + } + } } } }