diff --git a/src/hud.rs b/src/hud.rs index 3b0a20f..2351378 100644 --- a/src/hud.rs +++ b/src/hud.rs @@ -75,6 +75,7 @@ impl Plugin for HudPlugin { #[derive(Component)] struct NodeHud; #[derive(Component)] struct NodeConsole; #[derive(Component)] struct NodeChoiceText; +#[derive(Component)] struct NodeSpeedometerText; #[derive(Component)] struct NodeCurrentChatLine; #[derive(Component)] struct Reticule; #[derive(Component)] struct Speedometer; @@ -224,6 +225,12 @@ fn setup( color: settings.hud_color_choices, ..default() }; + let style_speedometer = TextStyle { + font: font_handle.clone(), + font_size: settings.font_size_speedometer, + color: settings.hud_color_speedometer, + ..default() + }; let style = TextStyle { font: font_handle, font_size: settings.font_size_hud, @@ -325,7 +332,6 @@ fn setup( }); // Add Speedometer - let speedometer_height = 10.0; let speedometer_handle: Handle = asset_server.load("sprites/speedometer.png"); commands.spawn(( NodeBundle { @@ -382,6 +388,21 @@ fn setup( }, )); }); + let mut bundle_speedometer_text = TextBundle::from_sections([ + TextSection::new("", style_speedometer.clone()), // speed relative to target + TextSection::new("", style_speedometer.clone()), // speed relative to orbit + ]).with_style(Style { + position_type: PositionType::Absolute, + left: Val::VMin(2.0), + bottom: Val::VMin(4.0), + ..default() + }).with_text_justify(JustifyText::Left); + bundle_speedometer_text.visibility = visibility; + commands.spawn(( + NodeSpeedometerText, + ToggleableHudElement, + bundle_speedometer_text, + )); // Chat "subtitles" and choices commands.spawn(NodeBundle { @@ -446,11 +467,14 @@ fn setup( fn update_speedometer( q_camera: Query<&LinearVelocity, With>, + q_target: Query<&LinearVelocity, With>, mut q_speedometer: Query<&mut Style, (With, Without)>, mut q_speedometer2: Query<&mut Style, (With, Without)>, + mut q_node_speed: Query<&mut Text, With>, ) { if let Ok(cam_v) = q_camera.get_single() { let speed = cam_v.length(); + let speed_readable = nature::readable_speed(speed); let speedometer_split = 5_000.0; if let Ok(mut speedometer) = q_speedometer.get_single_mut() { @@ -465,6 +489,15 @@ fn update_speedometer( let wid = (fraction * SPEEDOMETER_WIDTH).clamp(0.0, 100.0); speedometer2.width = Val::VMin(wid); } + if let Ok(mut speed_text) = q_node_speed.get_single_mut() { + speed_text.sections[0].value = if let Ok(target_v) = q_target.get_single() { + let delta_v = (target_v.0 - cam_v.0).length(); + format!("Δv {}\n", nature::readable_speed(delta_v)) + } else { + "".to_string() + }; + speed_text.sections[1].value = speed_readable; + } } } @@ -492,7 +525,7 @@ fn update_hud( let mut freshest_line: f64 = 0.0; if player.is_ok() && q_camera_result.is_ok() { let (hp, suit, gforce) = player.unwrap(); - let (pos, cam_v) = q_camera_result.unwrap(); + let (pos, _) = q_camera_result.unwrap(); for mut text in &mut q_node_hud { text.sections[0].value = format!("2524-03-12 03:02"); if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) { @@ -578,9 +611,7 @@ fn update_hud( // }; let dev_speed = ""; let gforce = gforce.gforce; - let speed = cam_v.length(); - let speed_readable = nature::readable_distance(speed); - text.sections[14].value = format!("\n{speed_readable}/s\n{gforce:.1}g{dev_speed}"); + text.sections[14].value = format!("\n{gforce:.1}g{dev_speed}"); if target_multiple { text.sections[15].value = "\n\nERROR: MULTIPLE TARGETS".to_string(); @@ -588,7 +619,7 @@ fn update_hud( else if target_error { text.sections[15].value = "\n\nERROR: FAILED TO AQUIRE TARGET".to_string(); } - else if let Ok((clickable, _, target_v_maybe)) = q_target.get_single() { + else if let Ok((clickable, _, _)) = q_target.get_single() { let distance = if dist_scalar.is_nan() { "UNKNOWN".to_string() } else if dist_scalar != 0.0 { @@ -596,19 +627,13 @@ fn update_hud( } else { "ERROR".to_string() }; - let speed: f64 = if let Some(target_v) = target_v_maybe { - (target_v.0 - cam_v.0).length() - } else { - cam_v.length() - }; - let speed_readable = nature::readable_distance(speed); let target_name = clickable.name.clone().unwrap_or("Unnamed".to_string()); let pronoun = if let Some(pronoun) = &clickable.pronoun { format!("Pronoun: {pronoun}\n") } else { "".to_string() }; - text.sections[15].value = format!("\n\nTarget: {target_name}\n{pronoun}Distance: {distance}\nΔv {speed_readable}/s"); + text.sections[15].value = format!("\n\nTarget: {target_name}\n{pronoun}Distance: {distance}"); } else { text.sections[15].value = "".to_string(); diff --git a/src/nature.rs b/src/nature.rs index c9bccaa..fdc9f21 100644 --- a/src/nature.rs +++ b/src/nature.rs @@ -120,6 +120,18 @@ pub fn readable_distance(distance: f64) -> String { return format!("{distance:.1}m"); } +pub fn readable_speed(speed: f64) -> String { + let abs = speed.abs(); + if abs > C * 0.0005 { + let lightyears = abs / C; + return format!("{lightyears:.4} c"); + } + else { + let kmh = abs * 1.0e-3 * 3600.0; + return format!("{kmh:.0} km/h"); + } +} + pub fn lorenz_factor(speed: f64) -> f64 { (1.0 - (speed.powf(2.0) / C.powf(2.0))).sqrt() } diff --git a/src/var.rs b/src/var.rs index 46199a8..74c30cc 100644 --- a/src/var.rs +++ b/src/var.rs @@ -44,6 +44,7 @@ pub struct Settings { pub font_size_conversations: f32, pub font_size_choices: f32, pub font_size_console: f32, + pub font_size_speedometer: f32, pub hud_color: Color, pub hud_color_console: Color, pub hud_color_console_warn: Color, @@ -51,6 +52,7 @@ pub struct Settings { pub hud_color_alert: Color, pub hud_color_subtitles: Color, pub hud_color_choices: Color, + pub hud_color_speedometer: Color, pub chat_speed: f32, pub hud_active: bool, pub map_active: bool, @@ -147,6 +149,7 @@ impl Default for Settings { font_size_conversations: 32.0, font_size_choices: 28.0, font_size_console: 20.0, + font_size_speedometer: 34.0, hud_color: Color::rgb(0.1, 0.5, 0.1), hud_color_console: Color::rgb(0.1, 0.5, 0.1), hud_color_console_warn: Color::rgb(1.0, 0.3, 0.3), @@ -154,6 +157,7 @@ impl Default for Settings { hud_color_alert: Color::rgb(0.6, 0.094, 0.322), hud_color_subtitles: Color::rgb(0.8, 0.8, 0.8), hud_color_choices: Color::rgb(0.45, 0.45, 0.45), + hud_color_speedometer: Color::rgb(0.749, 0.0745, 0.31765), chat_speed: DEFAULT_CHAT_SPEED * if dev_mode { 2.5 } else { 1.0 }, hud_active: false, map_active: false,