use bevy::{ecs::relationship::RelatedSpawner, prelude::*}; use bevy_rapier2d::prelude::*; use crate::{meters, player::Player}; use super::*; #[derive(Component, Debug, PartialEq, Eq, Default, Clone, Copy, Reflect)] #[reflect(Component, Debug, PartialEq, Default, Clone)] #[require(InteractiveObject, Collider, Sensor)] pub enum StairCollider { #[default] Up, Down, } #[derive(Component, Clone, Copy, Default, Reflect, Debug, PartialEq)] #[reflect(Component, Clone, Default, Debug, PartialEq)] #[require(Transform)] pub struct Stairs { pub up: Option, pub down: Option, } pub fn on_stairs_interact( event: On, collider_query: Query<(&ChildOf, &StairCollider)>, stairs_query: Query<&Stairs>, mut player_query: Query<&mut Transform, With>, ) { let Ok((parent, collider_type)) = collider_query.get(event.entity) else { return; }; let Ok(stairs) = stairs_query.get(parent.0) else { error!("StairCollider does not have Stairs parent"); return; }; let Ok(mut player_transform) = player_query.single_mut() else { error!("Player is not single"); return; }; let offset = match collider_type { StairCollider::Up => { let Some(offset) = stairs.up else { error!("StairCollider::Up triggered but Stairs.up is None"); return; }; offset }, StairCollider::Down => { let Some(offset) = stairs.down else { error!("StairCollider::Down triggered but Stairs.down is None"); return; }; offset }, }; player_transform.translation.x += offset.x; player_transform.translation.y += offset.y; } pub fn stairs_bundle( _asset_server: &Res, position: Vec2, up_position: Option, down_position: Option, ) -> impl Bundle { let (has_up, has_down) = (up_position.is_some(), down_position.is_some()); ( Stairs { up: up_position, down: down_position, }, Transform::from_xyz(position.x, position.y, -1.), Children::spawn( SpawnWith(move |parent: &mut RelatedSpawner| { if has_up { parent.spawn(( StairCollider::Up, Collider::cuboid(meters(1.), meters(1.)), Transform::from_xyz(meters(-1.), 0., 0.), )); } if has_down { parent.spawn(( StairCollider::Down, Collider::cuboid(meters(1.), meters(1.)), Transform::from_xyz(meters(1.), 0., 0.), )); } }) ), Name::new(format!("Stairs ({},{})", position.x, position.y)) ) }