use bevy::platform::collections::HashSet;
use bevy::prelude::*;
use bevy_tnua_physics_integration_layer::math::Float;
use crate::TnuaGhostSensor;
use crate::ghost_overrides::TnuaGhostOverwrite;
#[derive(Component, Default)]
pub struct TnuaSimpleFallThroughPlatformsHelper {
currently_falling_through: HashSet<Entity>,
}
impl TnuaSimpleFallThroughPlatformsHelper {
pub fn with<'a>(
&'a mut self,
ghost_overwrite: &'a mut TnuaGhostOverwrite,
ghost_sensor: &'a TnuaGhostSensor,
min_proximity: Float,
) -> TnuaHandleForSimpleFallThroughPlatformsHelper<'a> {
TnuaHandleForSimpleFallThroughPlatformsHelper {
parent: self,
ghost_overwrite,
ghost_sensor,
min_proximity,
}
}
}
pub struct TnuaHandleForSimpleFallThroughPlatformsHelper<'a> {
parent: &'a mut TnuaSimpleFallThroughPlatformsHelper,
ghost_overwrite: &'a mut TnuaGhostOverwrite,
ghost_sensor: &'a TnuaGhostSensor,
min_proximity: Float,
}
impl TnuaHandleForSimpleFallThroughPlatformsHelper<'_> {
pub fn dont_fall(&mut self) {
let mut already_falling_through_not_yet_seen =
self.parent.currently_falling_through.clone();
self.ghost_overwrite
.set(self.ghost_sensor.iter().find(|ghost_platform| {
self.min_proximity <= ghost_platform.proximity
&& !already_falling_through_not_yet_seen.remove(&ghost_platform.entity)
}));
self.parent
.currently_falling_through
.retain(|entity| !already_falling_through_not_yet_seen.contains(entity));
}
pub fn try_falling(&mut self, just_pressed: bool) -> bool {
if !just_pressed && !self.parent.currently_falling_through.is_empty() {
self.ghost_overwrite
.set(self.ghost_sensor.iter().find(|ghost_platform| {
self.min_proximity <= ghost_platform.proximity
&& !self
.parent
.currently_falling_through
.contains(&ghost_platform.entity)
}));
true
} else {
self.ghost_overwrite.set(None);
self.parent.currently_falling_through.clear();
for ghost_platform in self.ghost_sensor.iter() {
if self.min_proximity <= ghost_platform.proximity {
self.parent
.currently_falling_through
.insert(ghost_platform.entity);
}
}
!self.parent.currently_falling_through.is_empty()
}
}
}