88 lines
2.4 KiB
Rust
88 lines
2.4 KiB
Rust
use crate::{
|
|
GameState,
|
|
tb_entities::{Movable, MoveTarget},
|
|
};
|
|
use bevy::{prelude::*, utils::HashSet};
|
|
use bevy_trenchbroom::class::Target;
|
|
|
|
#[derive(Component, Reflect, Default, Debug)]
|
|
#[reflect(Component)]
|
|
struct ActiveMovable {
|
|
pub start: Transform,
|
|
pub target: Transform,
|
|
pub start_time: f32,
|
|
pub duration: f32,
|
|
}
|
|
|
|
#[derive(Event)]
|
|
pub struct TriggerMovableEvent(pub HashSet<String>);
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.register_type::<ActiveMovable>();
|
|
app.add_systems(Update, move_active.run_if(in_state(GameState::Playing)));
|
|
app.add_observer(trigger);
|
|
}
|
|
|
|
fn trigger(
|
|
trigger: Trigger<TriggerMovableEvent>,
|
|
mut commands: Commands,
|
|
uninit_movables: Query<
|
|
(Entity, &Target, &Transform, &Movable),
|
|
(Without<ActiveMovable>, With<Movable>),
|
|
>,
|
|
targets: Query<(&MoveTarget, &Transform)>,
|
|
time: Res<Time>,
|
|
) {
|
|
info!("trigger: {:?}", trigger.0);
|
|
|
|
for (e, target, transform, movable) in uninit_movables.iter() {
|
|
if !trigger.0.contains(&movable.name) {
|
|
continue;
|
|
}
|
|
|
|
let target_name = target.target.clone().unwrap_or_default();
|
|
|
|
let Some(target) = targets
|
|
.iter()
|
|
.find(|(t, _)| t.targetname == target_name)
|
|
.map(|(_, t)| *t)
|
|
else {
|
|
continue;
|
|
};
|
|
|
|
info!("found target: {:?}", target_name);
|
|
|
|
let target: Transform =
|
|
Transform::from_translation(transform.translation).with_rotation(target.rotation);
|
|
|
|
let platform = ActiveMovable {
|
|
start: *transform,
|
|
target,
|
|
start_time: time.elapsed_secs(),
|
|
//TODO: make this configurable
|
|
duration: 2.,
|
|
};
|
|
|
|
commands.entity(e).insert(platform);
|
|
}
|
|
}
|
|
|
|
fn move_active(
|
|
mut commands: Commands,
|
|
mut platforms: Query<(Entity, &mut Transform, &mut ActiveMovable)>,
|
|
time: Res<Time>,
|
|
) {
|
|
let elapsed = time.elapsed_secs();
|
|
for (e, mut transform, active) in platforms.iter_mut() {
|
|
if elapsed < active.start_time + active.duration {
|
|
let t = (elapsed - active.start_time) / active.duration;
|
|
transform.rotation = active.start.rotation.lerp(active.target.rotation, t);
|
|
} else {
|
|
info!("movable done");
|
|
*transform = active.target;
|
|
|
|
commands.entity(e).remove::<(ActiveMovable, Movable)>();
|
|
}
|
|
}
|
|
}
|