use crate::{ camera::CameraState, tb_entities::{CameraTarget, CutsceneCamera, CutsceneCameraMovementEnd}, }; use bevy::prelude::*; use bevy_trenchbroom::class::Target; #[derive(Event, Debug)] pub struct StartCutscene(pub String); #[derive(Resource, Debug, Default)] enum CutsceneState { #[default] None, Playing { timer: Timer, camera_start: Transform, camera_end: Transform, }, } pub fn plugin(app: &mut App) { app.init_resource::(); app.add_systems(Update, update); app.add_observer(on_start_cutscene); } fn on_start_cutscene( trigger: Trigger, mut cam_state: ResMut, mut cutscene_state: ResMut, cutscenes: Query<(&Transform, &CutsceneCamera, &Target), Without>, cutscene_movement: Query<(&Transform, &CutsceneCameraMovementEnd, &Target), Without>, cam_target: Query<(&Transform, &CameraTarget), Without>, ) { let cutscene = trigger.event().0.clone(); cam_state.cutscene = true; // asumes `name` and `targetname` are equal let Some((t, _, target)) = cutscenes .iter() .find(|(_, cutscene_camera, _)| cutscene == cutscene_camera.name) else { return; }; let move_end = cutscene_movement .iter() .find(|(_, _, target)| cutscene == target.target.clone().unwrap_or_default()) .map(|(t, _, _)| t.clone()) .unwrap_or_else(|| t.clone()); let Some((target, _)) = cam_target.iter().find(|(_, camera_target)| { camera_target.targetname == target.target.clone().unwrap_or_default() }) else { return; }; *cutscene_state = CutsceneState::Playing { timer: Timer::from_seconds(2.0, TimerMode::Once), camera_start: t.looking_at(target.translation, Vec3::Y), camera_end: move_end.looking_at(target.translation, Vec3::Y), }; } fn update( mut cam_state: ResMut, mut cutscene_state: ResMut, mut cam: Query<&mut Transform, With>, time: Res