use bevy::{ ecs::query::QueryFilter, prelude::*, }; use bevy_rapier2d::prelude::*; use crate::{ player::Player, }; use super::*; fn get_interactive_id( tested_id: Entity, interactive_query: Query<(), F>, parent_query: Query<&ChildOf, With>, ) -> Option { if interactive_query.get(tested_id).is_ok() { return Some(tested_id); } let Ok(parent_id) = parent_query.get(tested_id) else { return None; }; match interactive_query.get(parent_id.0) { Ok(_) => Some(parent_id.0), Err(_) => None, } } fn interact_collisions_inner( first: Entity, second: Entity, interactive_query: Query<(), F>, player_query: Query<(), With>, parent_query: Query<&ChildOf, With>, ) -> Option { let Some(interactive_id) = get_interactive_id(first, interactive_query, parent_query) else { return None; }; if player_query.get(second).is_err() { return None; } Some(interactive_id) } pub fn detect_interact_collisions( mut commands: Commands, mut collision_events: MessageReader, player_query: Query<(), With>, interactive_query1: Query<(), (With, Without)>, interactive_query2: Query<(), (With, With)>, parent_query: Query<&ChildOf, With>, ) { for collision_event in collision_events.read() { match collision_event { CollisionEvent::Started(first, second, _) => { if let Some(interactive_id) = interact_collisions_inner(*first, *second, interactive_query1, player_query, parent_query) { commands.entity(interactive_id).insert(MayInteract); } if let Some(interactive_id) = interact_collisions_inner(*second, *first, interactive_query1, player_query, parent_query) { commands.entity(interactive_id).insert(MayInteract); } }, CollisionEvent::Stopped(first, second, _) => { if let Some(interactive_id) = interact_collisions_inner(*first, *second, interactive_query2, player_query, parent_query) { commands.entity(interactive_id).remove::(); } if let Some(interactive_id) = interact_collisions_inner(*second, *first, interactive_query2, player_query, parent_query) { commands.entity(interactive_id).remove::(); } }, } } } pub fn lock_door( mut commands: Commands, query: Query<&ChildOf, Added>, ) { for parent in query { commands.entity(parent.0).insert(Locked); } } pub fn setup_world( mut commands: Commands, asset_server: Res, ) { let level_handle = asset_server.load("levels/level.toml"); commands.insert_resource(LevelAssetHandle(level_handle)); }