use bevy::prelude::*;
use crate::prelude::*;
#[derive(Reflect, Default, Debug, Copy, Clone, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
reflect(Serialize, Deserialize)
)]
pub enum Picking
{
Ignore,
#[default]
Pass,
Block,
Sink,
}
impl Into<Pickable> for Picking
{
fn into(self) -> Pickable
{
match self {
Self::Ignore => Pickable { should_block_lower: false, is_hoverable: false },
Self::Pass => Pickable { should_block_lower: false, is_hoverable: true },
Self::Block => Pickable { should_block_lower: true, is_hoverable: false },
Self::Sink => Pickable { should_block_lower: true, is_hoverable: true },
}
}
}
impl From<Pickable> for Picking
{
fn from(behavior: Pickable) -> Self
{
match (behavior.should_block_lower, behavior.is_hoverable) {
(false, false) => Self::Ignore,
(false, true) => Self::Pass,
(true, false) => Self::Block,
(true, true) => Self::Sink,
}
}
}
impl Instruction for Picking
{
fn apply(self, entity: Entity, world: &mut World)
{
let Ok(mut emut) = world.get_entity_mut(entity) else { return };
let behavior: Pickable = self.into();
emut.insert(behavior);
}
fn revert(entity: Entity, world: &mut World)
{
let Ok(mut emut) = world.get_entity_mut(entity) else { return };
emut.remove::<Pickable>();
}
}
impl StaticAttribute for Picking
{
type Value = Self;
fn construct(value: Self::Value) -> Self
{
value
}
}
impl ResponsiveAttribute for Picking {}
pub(super) struct PickingPlugin;
impl Plugin for PickingPlugin
{
fn build(&self, app: &mut App)
{
app.register_responsive::<Picking>();
}
}