use crate::collision::*;
use bevy::prelude::*;
#[derive(Component, Default)]
pub struct SensorBox(pub f32, pub f32);
#[derive(Component, Default, Debug)]
pub struct SensorData {
pub activated: bool,
}
#[derive(Component, Default)]
pub struct SensorLayers {
pub layer_id: usize,
pub activates_with_ids: Vec<usize>,
}
impl SensorLayers {
fn can_activate(&self, activ_candidate: &Self) -> bool {
self.activates_with_ids.contains(&activ_candidate.layer_id)
}
}
#[derive(Bundle, Default)]
pub struct SensorBundle {
pub sensor_box: SensorBox,
pub sensor_data: SensorData,
pub sensor_layers: SensorLayers,
}
pub fn check_sensors(
query: Query<(Entity, &Transform, &SensorBox, &SensorLayers)>,
mut query_sensor_data: Query<(&mut SensorData,)>,
) {
let mut entity_sensor_activated: std::collections::HashMap<Entity, bool> =
std::collections::HashMap::new();
let mut iter = query.iter_combinations();
while let Some(
[(entity1, transform1, sensor_box1, sensor_layers1), (entity2, transform2, sensor_box2, sensor_layers2)],
) = iter.fetch_next()
{
for entity in [&entity1, &entity2] {
if entity_sensor_activated.get(entity).is_none() {
entity_sensor_activated.insert(*entity, false);
}
}
if !sensor_layers1.can_activate(sensor_layers2)
|| !sensor_layers2.can_activate(sensor_layers1)
{
continue;
}
let (pos1, pos2) = (
transform1.translation.truncate(),
transform2.translation.truncate(),
);
let is_activated = overlap(pos1.x, pos2.x, sensor_box1.0, sensor_box2.0)
&& overlap(pos1.y, pos2.y, sensor_box1.1, sensor_box2.1);
if is_activated {
entity_sensor_activated.insert(entity1, true);
entity_sensor_activated.insert(entity2, true);
}
}
for (entity, activated) in entity_sensor_activated {
if let Ok(mut sensor_data) = query_sensor_data.get_mut(entity) {
if sensor_data.0.activated != activated {
sensor_data.0.activated = activated;
}
}
}
}