diff --git a/src/actor.rs b/src/actor.rs index ebf0630..7d3ddf4 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -18,10 +18,12 @@ impl Plugin for ActorPlugin { handle_conversations, handle_input, handle_chat_scripts, + handle_vehicle_enter_exit, )); app.add_event::(); app.add_event::(); app.add_event::(); + app.add_event::(); } } @@ -44,6 +46,14 @@ pub struct ChatScriptEvent { param2: String, } +#[derive(Event)] +pub struct VehicleEnterExitEvent { + vehicle: Entity, + driver: Entity, + is_entering: bool, + is_player: bool +} + #[derive(Component)] pub struct Actor { pub id: String, @@ -71,6 +81,8 @@ impl Default for Actor { #[derive(Component)] pub struct PlayerDrivesThis; #[derive(Component)] pub struct PlayerInConversation; #[derive(Component)] pub struct InConversationWithPlayer; +#[derive(Component)] pub struct ActorEnteringVehicle; +#[derive(Component)] pub struct ActorVehicleBeingEntered; #[derive(Debug)] #[derive(Component, Reflect, Default)] @@ -225,15 +237,15 @@ pub fn handle_input( keyboard_input: Res>, settings: ResMut, q_talker: Query<(&Talker, &Transform), Without>, - mut player: Query<(&mut Actor, &mut Transform), With>, + mut player: Query<(Entity, &mut Actor, &mut Transform), With>, mut q_vehicles: Query<(Entity, &mut Visibility, &Transform), (With, Without)>, mut ew_conv: EventWriter, - mut ew_sfx: EventWriter, -) -{ + mut ew_vehicle: EventWriter, + q_player_drives: Query>, +) { let mindist = MIN_INTERACT_DISTANCE * MIN_INTERACT_DISTANCE; if keyboard_input.just_pressed(settings.key_interact) { - if let Ok((_player_actor, player)) = player.get_single() { + if let Ok((_player_entity, _player_actor, player)) = player.get_single() { for (talker, transform) in &q_talker { if transform.translation.distance_squared(player.translation) <= mindist { ew_conv.send(StartConversationEvent{talker: talker.clone()}); @@ -243,14 +255,36 @@ pub fn handle_input( } } else if keyboard_input.just_pressed(settings.key_vehicle) { - if let Ok((mut player_actor, mut player)) = player.get_single_mut() { - for (entity, mut visibility, vehicle_transform) in q_vehicles.iter_mut() { - if vehicle_transform.translation.distance_squared(player.translation) <= mindist { - player_actor.inside_entity = entity.index(); - ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::EnterVehicle)); - *player = *vehicle_transform; - *visibility = Visibility::Hidden; - commands.entity(entity).insert(PlayerDrivesThis); + // Entering Vehicles + if q_player_drives.is_empty() { + if let Ok((player_entity, _player_actor, player)) = player.get_single_mut() { + for (vehicle_entity, _visibility, vehicle_transform) in q_vehicles.iter_mut() { + if vehicle_transform.translation.distance_squared(player.translation) <= mindist { + commands.entity(vehicle_entity).insert(ActorVehicleBeingEntered); + commands.entity(player_entity).insert(ActorEnteringVehicle); + ew_vehicle.send(VehicleEnterExitEvent{ + vehicle: vehicle_entity, + driver: player_entity, + is_entering: q_player_drives.is_empty(), + is_player: true, + }); + break; + } + } + } + } + // Exiting Vehicles + else { + if let Ok((player_entity, _player_actor, _player)) = player.get_single_mut() { + for vehicle_entity in &q_player_drives { + commands.entity(vehicle_entity).insert(ActorVehicleBeingEntered); + commands.entity(player_entity).insert(ActorEnteringVehicle); + ew_vehicle.send(VehicleEnterExitEvent{ + vehicle: vehicle_entity, + driver: player_entity, + is_entering: false, + is_player: true, + }); break; } } @@ -258,6 +292,53 @@ pub fn handle_input( } } +pub fn handle_vehicle_enter_exit( + mut commands: Commands, + mut er_vehicle: EventReader, + mut q_drivers: Query<(Entity, &mut Actor, &mut Visibility, &mut Transform), (Without, With)>, + mut q_vehicles: Query<(Entity, &mut Actor, &mut Visibility, &mut Transform), (With, Without)>, + mut ew_sfx: EventWriter, +) { + for event in er_vehicle.read() { + for (driver, mut driver_actor, mut driver_vis, mut driver_trans) in q_drivers.iter_mut() { + if driver == event.driver { + for (vehicle, mut vehicle_actor, mut vehicle_vis, mut vehicle_trans) in q_vehicles.iter_mut() { + if vehicle == event.vehicle { + if event.is_entering { + // Entering Vehicle + ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::EnterVehicle)); + *driver_vis = Visibility::Hidden; + *driver_trans = vehicle_trans.clone(); + if event.is_player { + //player_actor.inside_entity = entity.index(); + *vehicle_vis = Visibility::Hidden; + driver_actor.v = vehicle_actor.v; + commands.entity(vehicle).insert(PlayerDrivesThis); + } + } + else { + // Exiting Vehicle + ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch)); + *driver_vis = Visibility::Inherited; + if event.is_player { + *vehicle_vis = Visibility::Inherited; + vehicle_actor.v = driver_actor.v; + vehicle_actor.angular_momentum = driver_actor.angular_momentum; + *vehicle_trans = driver_trans.clone(); + commands.entity(vehicle).remove::(); + } + else { + *driver_trans = vehicle_trans.clone(); + *driver_trans = vehicle_trans.clone(); + } + } + } + } + } + } + } +} + pub fn handle_new_conversations( mut commands: Commands, mut er_conv: EventReader, diff --git a/src/world.rs b/src/world.rs index a941ac1..14b132a 100644 --- a/src/world.rs +++ b/src/world.rs @@ -94,6 +94,7 @@ pub fn setup( thrust_forward: 1.2, ..default() }, + Visibility::Visible, Camera3dBundle { camera: Camera { hdr: true, // HDR is required for bloom