diff --git a/src/actor.rs b/src/actor.rs index 547bb9b..5a7edac 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -2,10 +2,11 @@ use bevy::prelude::*; use bevy_xpbd_3d::prelude::*; use bevy::scene::SceneInstance; use bevy::math::DVec3; -use crate::{actor, audio, chat, commands, effects, hud, nature, settings, world}; +use crate::{actor, audio, camera, chat, commands, effects, hud, nature, settings, world}; pub const ENGINE_SPEED_FACTOR: f32 = 30.0; -const MIN_INTERACT_DISTANCE: f32 = 30.0; +const MAX_TRANSMISSION_DISTANCE: f32 = 60.0; +const MAX_INTERACT_DISTANCE: f32 = 30.0; const NO_RIDE: u32 = 0; pub struct ActorPlugin; @@ -206,22 +207,30 @@ pub fn handle_input( mut commands: Commands, keyboard_input: Res>, settings: ResMut, - q_talker: Query<(&chat::Talker, &Transform), Without>, - mut player: Query<(Entity, &mut Actor, &mut Transform), With>, - mut q_vehicles: Query<(Entity, &mut Visibility, &Transform), (With, Without)>, + q_talker: Query<(&chat::Talker, &Transform), (Without, Without)>, + mut player: Query<(Entity, &mut Actor, &mut Transform), (With, Without)>, + q_camera: Query<&Transform, With>, + mut q_vehicles: Query<(Entity, &mut Visibility, &Transform), (With, Without, Without)>, mut ew_conv: EventWriter, mut ew_vehicle: EventWriter, q_player_drives: Query>, ) { - let mindist = MIN_INTERACT_DISTANCE * MIN_INTERACT_DISTANCE; + if q_camera.is_empty() { + return; + } + let camtrans = q_camera.get_single().unwrap(); + if keyboard_input.just_pressed(settings.key_interact) { // Talking to people - if let Ok((_player_entity, _player_actor, player)) = player.get_single() { - for (talker, transform) in &q_talker { - // TODO: replace Transform.translation with Position - if transform.translation.distance_squared(player.translation) <= mindist { + if let Ok((_player_entity, _player_actor, _player)) = player.get_single() { + let objects: Vec<(chat::Talker, &Transform)> = q_talker + .iter() + .map(|(talker, transform)| (talker.clone(), transform)) + .collect(); + // TODO: replace Transform.translation with Position + if let (Some(talker), dist) = camera::find_closest_target::(objects, camtrans) { + if dist <= MAX_TRANSMISSION_DISTANCE { ew_conv.send(chat::StartConversationEvent{talker: talker.clone()}); - break; } } } @@ -229,7 +238,7 @@ pub fn handle_input( 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 { + if vehicle_transform.translation.distance_squared(player.translation) <= MAX_INTERACT_DISTANCE * MAX_INTERACT_DISTANCE { commands.entity(vehicle_entity).insert(ActorVehicleBeingEntered); commands.entity(player_entity).insert(ActorEnteringVehicle); ew_vehicle.send(VehicleEnterExitEvent{ diff --git a/src/camera.rs b/src/camera.rs index 414833e..f218476 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -8,7 +8,7 @@ use bevy::transform::TransformSystem; use bevy::math::{DVec3, DQuat}; use bevy_xpbd_3d::prelude::*; use std::f32::consts::PI; -use crate::{actor, audio, hud, settings}; +use crate::{actor, audio, settings}; pub struct CameraPlugin; @@ -340,6 +340,7 @@ pub fn find_closest_target( objects: Vec<(TargetSpecifier, &Transform)>, camera_transform: &Transform, ) -> (Option, f32) + where TargetSpecifier: Clone { let mut closest_entity: Option = None; let mut closest_distance: f32 = f32::MAX; @@ -360,7 +361,7 @@ pub fn find_closest_target( let distance = trans.translation.distance(camera_transform.translation); if distance < closest_distance { closest_distance = distance; - closest_entity = Some(entity); + closest_entity = Some(entity.clone()); } } } diff --git a/src/hud.rs b/src/hud.rs index 299c179..12e12b9 100644 --- a/src/hud.rs +++ b/src/hud.rs @@ -601,7 +601,10 @@ fn handle_input( //ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch)); if q_target.is_empty() { if let Ok(camtrans) = q_camera.get_single() { - let objects: Vec<(Entity, &Transform)> = q_objects.iter().collect(); + let objects: Vec<(Entity, &Transform)> = q_objects + .iter() + .map(|(entity, transform)| (entity, transform)) + .collect(); if let (Some(entity), _dist) = camera::find_closest_target::(objects, camtrans) { commands.entity(entity).insert(IsTargeted); }