diff --git a/src/actor.rs b/src/actor.rs index a13eb6b..53b1ccd 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -1,7 +1,8 @@ use bevy::prelude::*; use bevy_xpbd_3d::prelude::*; +use bevy::scene::SceneInstance; use bevy::math::DVec3; -use crate::{actor, audio, chat, nature, settings}; +use crate::{actor, audio, chat, commands, nature, settings, world}; pub const ENGINE_SPEED_FACTOR: f32 = 30.0; const MIN_INTERACT_DISTANCE: f32 = 30.0; @@ -10,6 +11,9 @@ const NO_RIDE: u32 = 0; pub struct ActorPlugin; impl Plugin for ActorPlugin { fn build(&self, app: &mut App) { + app.add_systems(PreUpdate, ( + handle_player_death, + )); app.add_systems(FixedUpdate, ( update_physics_lifeforms, handle_wants_maxrotation, @@ -23,9 +27,11 @@ impl Plugin for ActorPlugin { handle_vehicle_enter_exit, )); app.add_event::(); + app.add_event::(); } } +#[derive(Event)] pub struct PlayerDiesEvent; #[derive(Event)] pub struct VehicleEnterExitEvent { vehicle: Entity, @@ -186,9 +192,13 @@ pub fn handle_input( mut q_vehicles: Query<(Entity, &mut Visibility, &Transform), (With, Without)>, mut ew_conv: EventWriter, mut ew_vehicle: EventWriter, + mut ew_playerdies: EventWriter, q_player_drives: Query>, ) { let mindist = MIN_INTERACT_DISTANCE * MIN_INTERACT_DISTANCE; + if keyboard_input.just_pressed(settings.key_cheat_die) { + ew_playerdies.send(PlayerDiesEvent); + } if keyboard_input.just_pressed(settings.key_interact) { // Talking to people if let Ok((_player_entity, _player_actor, player)) = player.get_single() { @@ -345,3 +355,26 @@ fn handle_wants_maxvelocity( } } } + +fn handle_player_death( + mut cmd: Commands, + mut er_playerdies: EventReader, + q_scenes: Query<(Entity, &SceneInstance), With>, + q_noscenes: Query, Without)>, + ew_spawn: EventWriter, + mut scene_spawner: ResMut, + mut ew_sfx: EventWriter, +) { + for _ in er_playerdies.read() { + for entity in &q_noscenes { + cmd.entity(entity).despawn(); + } + for (entity, sceneinstance) in &q_scenes { + cmd.entity(entity).despawn(); + scene_spawner.despawn_instance(**sceneinstance); + } + //cmd.run_system(commands::load_defs); // why is it so complicated to get SystemId? + commands::load_defs(ew_spawn); + return; + } +} diff --git a/src/camera.rs b/src/camera.rs index 520d668..923b6c7 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -69,7 +69,7 @@ pub fn setup_camera( pub fn sync_camera_to_player( settings: Res, - mut q_camera: Query<&mut Transform, With>, + mut q_camera: Query<&mut Transform, (With, Without)>, q_playercam: Query<(&actor::Actor, &Transform), (With, Without)>, ) { if q_camera.is_empty() || q_playercam.is_empty() { diff --git a/src/chat.rs b/src/chat.rs index f33118a..1d1c86b 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use crate::{actor, audio, hud, settings}; +use crate::{actor, audio, hud, settings, world}; pub struct ChatPlugin; impl Plugin for ChatPlugin { @@ -193,12 +193,15 @@ pub fn handle_send_messages( .collect(); for choice in choices { if choice.choice.as_str() != hud::CHOICE_NONE { - commands.spawn(ChoiceAvailable { - conv_id: choice.id.clone(), - conv_label: choice.label.clone(), - recipient: choice.name.clone(), - text: choice.choice.clone(), - }); + commands.spawn(( + ChoiceAvailable { + conv_id: choice.id.clone(), + conv_label: choice.label.clone(), + recipient: choice.name.clone(), + text: choice.choice.clone(), + }, + world::DespawnOnPlayerDeath, + )); } } if !branch.script.is_empty() { @@ -269,12 +272,15 @@ pub fn handle_conversations( .collect(); for choice in choices { if choice.choice.as_str() != hud::CHOICE_NONE { - commands.spawn(ChoiceAvailable { - conv_id: choice.id.clone(), - conv_label: choice.label.clone(), - recipient: choice.name.clone(), - text: choice.choice.clone(), - }); + commands.spawn(( + ChoiceAvailable { + conv_id: choice.id.clone(), + conv_label: choice.label.clone(), + recipient: choice.name.clone(), + text: choice.choice.clone(), + }, + world::DespawnOnPlayerDeath, + )); } } diff --git a/src/commands.rs b/src/commands.rs index 7a0ce51..2d78c86 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -571,7 +571,8 @@ fn spawn_entities( let state = &state_wrapper.0; if state.class == DefClass::Chat { if state.stores_item { - commands.spawn(state.as_chatbranch()); + let mut chat = commands.spawn(state.as_chatbranch()); + chat.insert(world::DespawnOnPlayerDeath); } } else if state.class == DefClass::Actor { @@ -581,6 +582,7 @@ fn spawn_entities( camdistance: state.camdistance, ..default() }); + actor.insert(world::DespawnOnPlayerDeath); actor.insert(Position::from(state.pos)); actor.insert(Rotation::from(state.rotation)); if state.is_sphere { diff --git a/src/settings.rs b/src/settings.rs index 0c70617..911ea3b 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -54,6 +54,7 @@ pub struct Settings { pub key_cheat_adrenaline_zero: KeyCode, pub key_cheat_adrenaline_mid: KeyCode, pub key_cheat_adrenaline_max: KeyCode, + pub key_cheat_die: KeyCode, } impl Default for Settings { @@ -126,6 +127,7 @@ impl Default for Settings { key_cheat_adrenaline_zero: KeyCode::F5, key_cheat_adrenaline_mid: KeyCode::F6, key_cheat_adrenaline_max: KeyCode::F7, + key_cheat_die: KeyCode::KeyZ, } } } diff --git a/src/world.rs b/src/world.rs index 186afc5..f3b6a11 100644 --- a/src/world.rs +++ b/src/world.rs @@ -71,6 +71,7 @@ impl Plugin for WorldPlugin { #[derive(Resource)] struct ActiveAsteroids(HashMap); #[derive(Component)] struct Asteroid; +#[derive(Component)] pub struct DespawnOnPlayerDeath; struct AsteroidData { entity: Entity,