From d9cec22d33199dfe5ed385a3a055430700a52c33 Mon Sep 17 00:00:00 2001 From: VirxEC Date: Wed, 13 Sep 2023 21:02:46 -0400 Subject: [PATCH] Actually fix director cam boost meter Add option to hide in-game timer Add ui scale option Fix error message printing --- src/assets.rs | 15 +++++------- src/camera.rs | 3 ++- src/gui.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/udp.rs | 41 ++++++++++++++++++++++---------- 4 files changed, 103 insertions(+), 22 deletions(-) diff --git a/src/assets.rs b/src/assets.rs index c1c2454..7238678 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -569,23 +569,20 @@ const UMODEL: &str = if cfg!(windows) { ".\\umodel.exe" } else { "./umodel" }; const OUT_DIR: &str = "./assets/"; const OUT_DIR_VER: &str = "./assets/files.txt"; -fn get_input_dir() -> Option { +fn get_input_dir() -> String { let Ok(input_file) = fs::read_to_string("assets.path") else { - error!("Couldn't find 'assets.path' file in your base folder! Create the file with the path to your 'rocketleague/TAGame/CookedPCConsole' folder."); - return None; + panic!("Couldn't find 'assets.path' file in your base folder! Create the file with the path to your 'rocketleague/TAGame/CookedPCConsole' folder."); }; let Some(assets_dir) = input_file.lines().next() else { - error!("Your 'assets.path' file is empty! Create the file with the path to your 'rocketleague/TAGame/CookedPCConsole' folder."); - return None; + panic!("Your 'assets.path' file is empty! Create the file with the path to your 'rocketleague/TAGame/CookedPCConsole' folder."); }; let assets_path = Path::new(assets_dir); if assets_path.is_dir() && assets_path.exists() { - Some(assets_dir.to_string()) + assets_dir.to_string() } else { - error!("Couldn't find the directory specified in your 'assets.path'!"); - None + panic!("Couldn't find the directory specified in your 'assets.path'!"); } } @@ -615,7 +612,7 @@ pub fn uncook() -> io::Result<()> { return Ok(()); } - let input_dir = get_input_dir().unwrap(); + let input_dir = get_input_dir(); info!("Uncooking assets from Rocket League..."); diff --git a/src/camera.rs b/src/camera.rs index bb00672..7220b40 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -39,6 +39,7 @@ pub enum PrimaryCamera { } pub const BOOST_INDICATOR_POS: Vec2 = Vec2::new(150., 150.); +pub const BOOST_INDICATOR_FONT_SIZE: f32 = 60.0; pub const TIME_DISPLAY_POS: Vec2 = Vec2::new(0., 60.); fn setup(mut commands: Commands) { @@ -125,7 +126,7 @@ fn setup(mut commands: Commands) { TextBundle::from_section( "", TextStyle { - font_size: 60.0, + font_size: BOOST_INDICATOR_FONT_SIZE, color: Color::SILVER, ..default() }, diff --git a/src/gui.rs b/src/gui.rs index d047267..0a6b4ee 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -29,11 +29,37 @@ impl Default for BallCam { } } +#[derive(Resource)] +pub struct ShowTime { + pub enabled: bool, +} + +impl Default for ShowTime { + #[inline] + fn default() -> Self { + Self { enabled: true } + } +} + +#[derive(Resource)] +pub struct UiScale { + pub scale: f32, +} + +impl Default for UiScale { + #[inline] + fn default() -> Self { + Self { scale: 1. } + } +} + impl Plugin for DebugOverlayPlugin { fn build(&self, app: &mut App) { app.add_plugins(EguiPlugin) .insert_resource(if cfg!(feature = "ssao") { Msaa::Off } else { Msaa::default() }) .insert_resource(BallCam::default()) + .insert_resource(UiScale::default()) + .insert_resource(ShowTime::default()) .insert_resource(Options::default_read_file()) .add_systems( Update, @@ -45,11 +71,13 @@ impl Plugin for DebugOverlayPlugin { ui_system, toggle_vsync, toggle_ballcam, + toggle_show_time, update_daytime, #[cfg(not(feature = "ssao"))] update_msaa, write_settings_to_file, update_camera_state, + update_ui_scale, // update_draw_distance, ), ) @@ -71,6 +99,8 @@ struct Options { day_speed: f32, msaa: u8, camera_state: PrimaryCamera, + show_time: bool, + ui_scale: f32, // draw_distance: u8, } @@ -89,6 +119,8 @@ impl Default for Options { day_speed: 1., msaa: 2, camera_state: PrimaryCamera::Spectator, + show_time: true, + ui_scale: 1., // draw_distance: 3, } } @@ -128,6 +160,8 @@ impl Options { "day_speed" => options.day_speed = value.parse().unwrap(), "msaa" => options.msaa = value.parse().unwrap(), "camera_state" => options.camera_state = serde_json::from_str(value).unwrap(), + "show_time" => options.show_time = value.parse().unwrap(), + "ui_scale" => options.ui_scale = value.parse().unwrap(), _ => println!("Unknown key {key} with value {value}"), } } @@ -157,6 +191,8 @@ impl Options { file.write_fmt(format_args!("day_speed={}\n", self.day_speed))?; file.write_fmt(format_args!("msaa={}\n", self.msaa))?; file.write_fmt(format_args!("camera_state={}\n", serde_json::to_string(&self.camera_state)?))?; + file.write_fmt(format_args!("show_time={}\n", self.show_time))?; + file.write_fmt(format_args!("ui_scale={}\n", self.ui_scale))?; Ok(()) } @@ -172,6 +208,8 @@ impl Options { || self.day_speed != other.day_speed || self.msaa != other.msaa || self.camera_state != other.camera_state + || self.show_time != other.show_time + || self.ui_scale != other.ui_scale } } @@ -225,10 +263,12 @@ fn ui_system(mut options: ResMut, mut contexts: EguiContexts, time: Res ui.checkbox(&mut options.vsync, "vsync"); ui.checkbox(&mut options.uncap_fps, "Uncap FPS"); ui.add(egui::DragValue::new(&mut options.fps_limit).speed(5.).clamp_range(30..=600)); + ui.checkbox(&mut options.show_time, "In-game time"); ui.checkbox(&mut options.ball_cam, "Ball cam"); ui.checkbox(&mut options.stop_day, "Stop day cycle"); ui.add(egui::Slider::new(&mut options.daytime, 0.0..=150.0).text("Daytime")); ui.add(egui::Slider::new(&mut options.day_speed, 0.0..=10.0).text("Day speed")); + ui.add(egui::Slider::new(&mut options.ui_scale, 0.4..=4.0).text("UI scale")); #[cfg(not(feature = "ssao"))] ui.add(egui::Slider::new(&mut options.msaa, 0..=3).text("MSAA")); // ui.add(egui::Slider::new(&mut options.draw_distance, 0..=4).text("Draw distance")); @@ -315,6 +355,26 @@ fn update_msaa(options: Res, mut msaa: ResMut) { }; } +fn toggle_show_time(options: Res, mut show_time: ResMut) { + if options.focus { + return; + } + + show_time.enabled = options.show_time; +} + +fn update_ui_scale(options: Res, mut ui_scale: ResMut) { + if options.focus { + return; + } + + if options.ui_scale == ui_scale.scale { + return; + } + + ui_scale.scale = options.ui_scale; +} + fn update_daytime(options: Res, mut daytime: ResMut) { if options.focus { return; @@ -349,6 +409,12 @@ fn write_settings_to_file( } fn update_camera_state(mut primary_camera: Query<&mut PrimaryCamera>, options: Res) { + if PrimaryCamera::Director(0) == options.camera_state { + if let PrimaryCamera::Director(_) = primary_camera.single() { + return; + } + } + *primary_camera.single_mut() = options.camera_state; } diff --git a/src/udp.rs b/src/udp.rs index 19b6706..be053f7 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -12,8 +12,11 @@ use bevy_vector_shapes::prelude::*; use crate::{ assets::{get_material, get_mesh_info, BoostPickupGlows}, bytes::{FromBytes, ToBytes}, - camera::{BoostAmount, EntityName, HighlightedEntity, PrimaryCamera, TimeDisplay, BOOST_INDICATOR_POS}, - gui::BallCam, + camera::{ + BoostAmount, EntityName, HighlightedEntity, PrimaryCamera, TimeDisplay, BOOST_INDICATOR_FONT_SIZE, + BOOST_INDICATOR_POS, + }, + gui::{BallCam, ShowTime, UiScale}, mesh::{ChangeCarPos, LargeBoostPadLocRots}, rocketsim::{CarInfo, GameState, Team}, LoadState, ServerPort, @@ -468,13 +471,16 @@ fn update_car( if *id == 0 || timer.0.finished() { // get the car closest to the ball let mut min_dist = f32::MAX; + let mut new_id = *id; for car in state.cars.iter() { let dist = car.state.pos.distance_squared(state.ball.pos); if dist < min_dist { - *id = car.id; + new_id = car.id; min_dist = dist; } } + + *id = new_id; } *id @@ -626,10 +632,11 @@ fn update_pads( fn update_boost_meter( state: Res, + ui_scale: Res, camera: Query<&PrimaryCamera>, windows: Query<&Window, With>, mut painter: ShapePainter, - mut boost_amount: Query<&mut Text, With>, + mut boost_amount: Query<(&mut Text, &mut Style), With>, mut was_last_director: Local, ) { let id = match camera.single() { @@ -640,8 +647,9 @@ fn update_boost_meter( if id == 0 { if *was_last_director { *was_last_director = false; - boost_amount.single_mut().sections[0].value.clear(); + boost_amount.single_mut().0.sections[0].value.clear(); } + return; } @@ -651,11 +659,11 @@ fn update_boost_meter( let primary_window = windows.single(); let window_res = Vec2::new(primary_window.width(), primary_window.height()); - let painter_pos = (window_res / 2. - (BOOST_INDICATOR_POS + 25.)) * Vec2::new(1., -1.); + let painter_pos = (window_res / 2. - (BOOST_INDICATOR_POS + 25.) * ui_scale.scale) * Vec2::new(1., -1.); painter.set_translation(painter_pos.extend(0.)); painter.color = Color::rgb(0.075, 0.075, 0.15); - painter.circle(100.0); + painter.circle(100.0 * ui_scale.scale); let scale = car_state.boost / 100.; @@ -666,16 +674,21 @@ fn update_boost_meter( painter.color = Color::rgb(1., 0.84 * scale, 0.); painter.hollow = true; painter.thickness = 4.; - painter.arc(80., start_angle, end_angle); + painter.arc(80. * ui_scale.scale, start_angle, end_angle); painter.reset(); - boost_amount.single_mut().sections[0].value = car_state.boost.round().to_string(); + let (mut text_display, mut style) = boost_amount.single_mut(); + style.right = Val::Px((BOOST_INDICATOR_POS.x - 25.) * ui_scale.scale); + style.bottom = Val::Px(BOOST_INDICATOR_POS.y * ui_scale.scale); + + text_display.sections[0].value = car_state.boost.round().to_string(); + text_display.sections[0].style.font_size = BOOST_INDICATOR_FONT_SIZE * ui_scale.scale; *was_last_director = true; } -fn update_time(state: Res, mut text_display: Query<&mut Text, With>) { +fn update_time(state: Res, show_time: Res, mut text_display: Query<&mut Text, With>) { const MINUTE: u64 = 60; const HOUR: u64 = 60 * MINUTE; const DAY: u64 = 24 * HOUR; @@ -683,6 +696,11 @@ fn update_time(state: Res, mut text_display: Query<&mut Text, With| updated.0), - listen, + (listen, update_boost_meter), ), ) .chain(), - update_boost_meter, update_time, ) .run_if(in_state(LoadState::None)),