trigger system

This commit is contained in:
Jonas H
2026-03-05 15:05:49 +01:00
parent bab54b6f21
commit 350fddc2af
6 changed files with 134 additions and 0 deletions

82
src/systems/trigger.rs Normal file
View File

@@ -0,0 +1,82 @@
use glam::Vec3;
use crate::components::trigger::{TriggerEvent, TriggerEventKind, TriggerFilter, TriggerShape, TriggerState};
use crate::entity::EntityHandle;
use crate::world::World;
pub fn trigger_system(world: &mut World)
{
world.trigger_events.clear();
let trigger_entities: Vec<EntityHandle> = world.triggers.all();
let mut pending_events: Vec<TriggerEvent> = Vec::new();
for trigger_entity in trigger_entities
{
let trigger_pos = match world.transforms.get(trigger_entity)
{
Some(t) => t.position,
None => continue,
};
let candidate_entities: Vec<EntityHandle> = match world.triggers.get(trigger_entity)
{
Some(trigger) => match &trigger.filter
{
TriggerFilter::Player => world.player_tags.all(),
},
None => continue,
};
let activator_positions: Vec<(EntityHandle, Vec3)> = candidate_entities
.into_iter()
.filter_map(|e| world.transforms.get(e).map(|t| (e, t.position)))
.collect();
let overlapping = match world.triggers.get(trigger_entity)
{
Some(trigger) => activator_positions.iter().any(|(_, pos)| match &trigger.shape
{
TriggerShape::Sphere { radius } => (trigger_pos - *pos).length() < *radius,
}),
None => continue,
};
let first_activator = activator_positions.first().map(|(e, _)| *e);
if let Some(trigger) = world.triggers.get_mut(trigger_entity)
{
match (&trigger.state, overlapping)
{
(TriggerState::Idle, true) =>
{
trigger.state = TriggerState::Inside;
if let Some(activator_entity) = first_activator
{
pending_events.push(TriggerEvent {
trigger_entity,
activator_entity,
kind: TriggerEventKind::Entered,
});
}
}
(TriggerState::Inside, false) =>
{
trigger.state = TriggerState::Idle;
if let Some(activator_entity) = first_activator
{
pending_events.push(TriggerEvent {
trigger_entity,
activator_entity,
kind: TriggerEventKind::Exited,
});
}
}
_ =>
{}
}
}
}
world.trigger_events.extend(pending_events);
}