From c42a5e2df558553529b6c7f2d4c49edffc493280 Mon Sep 17 00:00:00 2001 From: VirxEC Date: Sat, 10 Jun 2023 16:15:59 -0400 Subject: [PATCH] Better camera Add director mode (press 9) and ball cam --- Cargo.lock | 2 +- Cargo.toml | 3 +- src/bytes.rs | 136 +++++++++++++++++++++++++---------------------- src/camera.rs | 1 + src/gui.rs | 31 ++++++++++- src/rocketsim.rs | 1 + src/udp.rs | 58 ++++++++++++++++---- 7 files changed, 155 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 520e958..10266f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2318,7 +2318,7 @@ checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" [[package]] name = "rlviser" -version = "0.2.1" +version = "0.3.0" dependencies = [ "bevy", "bevy_asset_loader", diff --git a/Cargo.toml b/Cargo.toml index 2094e05..24c4ecb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "rlviser" -version = "0.2.1" +version = "0.3.0" edition = "2021" +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/bytes.rs b/src/bytes.rs index 541990b..38511e8 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -135,76 +135,81 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarState { bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4 + f32::NUM_BYTES ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4 + f32::NUM_BYTES * 2] .copy_from_slice(&self.flip_time.to_le_bytes()); - // is_jumping: bool, + // is_flipping: bool, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4 + f32::NUM_BYTES * 2 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 2] + .copy_from_slice(&(self.is_flipping as u8).to_le_bytes()); + // is_jumping: bool, + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 2 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 2] .copy_from_slice(&(self.is_jumping as u8).to_le_bytes()); // air_time_since_jump: f32, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 2 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 3] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 2 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 3] .copy_from_slice(&self.air_time_since_jump.to_le_bytes()); // boost: f32, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 3 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 4] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 3 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 4] .copy_from_slice(&self.boost.to_le_bytes()); // time_spent_boosting: f32, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 4 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 5] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 4 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5] .copy_from_slice(&self.time_spent_boosting.to_le_bytes()); // is_supersonic: bool, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 5 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 5] .copy_from_slice(&(self.is_supersonic as u8).to_le_bytes()); // supersonic_time: f32, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 6] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 5 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 6] .copy_from_slice(&self.supersonic_time.to_le_bytes()); // handbrake_val: f32, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 6 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 7] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 6 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 7] .copy_from_slice(&self.handbrake_val.to_le_bytes()); // is_auto_flipping: bool, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 7 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 7] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 7 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 7] .copy_from_slice(&(self.is_auto_flipping as u8).to_le_bytes()); // auto_flip_timer: f32, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 7 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 8] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 7 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 8] .copy_from_slice(&self.auto_flip_timer.to_le_bytes()); // auto_flip_torque_scale: f32, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 8 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 9] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 8 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9] .copy_from_slice(&self.auto_flip_torque_scale.to_le_bytes()); // has_contact: bool, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 9 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9] .copy_from_slice(&(self.has_contact as u8).to_le_bytes()); // contact_normal: Vec3, - bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9 - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9] + bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9 + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9] .copy_from_slice(&self.contact_normal.to_bytes()); // other_car_id: u32, - bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9 - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9 + u32::NUM_BYTES] + bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9 + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9 + u32::NUM_BYTES] .copy_from_slice(&self.other_car_id.to_le_bytes()); // cooldown_timer: f32, - bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9 + u32::NUM_BYTES - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 10 + u32::NUM_BYTES] + bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9 + u32::NUM_BYTES + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 10 + u32::NUM_BYTES] .copy_from_slice(&self.cooldown_timer.to_le_bytes()); // is_demoed: bool, - bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 10 + u32::NUM_BYTES - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 10 + u32::NUM_BYTES] + bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 10 + u32::NUM_BYTES + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 10 + u32::NUM_BYTES] .copy_from_slice(&(self.is_demoed as u8).to_le_bytes()); // demo_respawn_timer: f32, - bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 10 + u32::NUM_BYTES - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 11 + u32::NUM_BYTES] + bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 10 + u32::NUM_BYTES + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES] .copy_from_slice(&self.demo_respawn_timer.to_le_bytes()); // ball_hit_info: BallHitInfo, - bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 11 + u32::NUM_BYTES - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + BallHitInfo::NUM_BYTES] + bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + BallHitInfo::NUM_BYTES] .copy_from_slice(&self.ball_hit_info.to_bytes()); // last_controls: CarControls, - bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + BallHitInfo::NUM_BYTES..] + bytes + [Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + BallHitInfo::NUM_BYTES..] .copy_from_slice(&self.last_controls.to_bytes()); bytes } @@ -415,7 +420,7 @@ impl FromBytesExact for CarControls { impl FromBytesExact for CarState { const NUM_BYTES: usize = Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES - + 9 + + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + BallHitInfo::NUM_BYTES @@ -445,60 +450,61 @@ impl FromBytesExact for CarState { &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4 + f32::NUM_BYTES ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4 + f32::NUM_BYTES * 2], ), - is_jumping: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4 + f32::NUM_BYTES * 2] != 0, + is_flipping: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4 + f32::NUM_BYTES * 2] != 0, + is_jumping: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 2] != 0, air_time_since_jump: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 2 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 3], + &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 2 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 3], ), boost: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 3 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 4], + &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 3 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 4], ), time_spent_boosting: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 4 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 5], + &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 4 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5], ), - is_supersonic: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 5] != 0, + is_supersonic: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5] != 0, supersonic_time: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 6], + &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 5 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 6], ), handbrake_val: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 7], + &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 5 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 7], ), - is_auto_flipping: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 7] != 0, + is_auto_flipping: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 7] != 0, auto_flip_timer: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 6 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 8], + &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 6 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 8], ), auto_flip_torque_scale: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 7 - ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 9], + &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 7 + ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9], ), - has_contact: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 9] != 0, + has_contact: bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9] != 0, contact_normal: Vec3::from_bytes( - &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 8 - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9], + &bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 8 + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9], ), other_car_id: u32::from_bytes( - &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 8 - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9 + u32::NUM_BYTES], + &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 8 + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9 + u32::NUM_BYTES], ), cooldown_timer: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 8 + u32::NUM_BYTES - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 10 + u32::NUM_BYTES], + &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 8 + u32::NUM_BYTES + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 10 + u32::NUM_BYTES], ), - is_demoed: bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 10 + u32::NUM_BYTES] != 0, + is_demoed: bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 10 + u32::NUM_BYTES] != 0, demo_respawn_timer: f32::from_bytes( - &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9 + u32::NUM_BYTES - ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 11 + u32::NUM_BYTES], + &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 9 + u32::NUM_BYTES + ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES], ), ball_hit_info: BallHitInfo::from_bytes( - &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES - + 9 + + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + BallHitInfo::NUM_BYTES], @@ -506,7 +512,7 @@ impl FromBytesExact for CarState { last_controls: CarControls::from_bytes( &bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES - + 9 + + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES + BallHitInfo::NUM_BYTES..], diff --git a/src/camera.rs b/src/camera.rs index 2a2f1ed..9ca1bb3 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -17,6 +17,7 @@ struct CycleTimer(Timer); pub enum PrimaryCamera { #[default] Spectator, + Director(u32), TrackCar(u32), } diff --git a/src/gui.rs b/src/gui.rs index cdce476..ce2a65e 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -15,15 +15,23 @@ use crate::camera::{DaylightOffset, EntityName, HighlightedEntity, PrimaryCamera pub struct DebugOverlayPlugin; +#[derive(Resource)] +pub struct BallCam { + pub enabled: bool, +} + impl Plugin for DebugOverlayPlugin { fn build(&self, app: &mut App) { app.add_plugin(EguiPlugin) .insert_resource(Msaa::default()) + .insert_resource(BallCam { enabled: true }) .insert_resource(Options::read_from_file().unwrap_or_else(|_| Options::create_file_from_defualt())) .add_system(listen) .add_system(ui_system) .add_system(toggle_vsync.after(ui_system)) .add_system(toggle_vsync) + .add_system(toggle_ballcam.after(ui_system)) + .add_system(toggle_ballcam) .add_system(update_daytime.after(ui_system)) .add_system(update_daytime) .add_system(update_msaa.after(ui_system)) @@ -42,6 +50,7 @@ struct Options { uncap_fps: bool, fps_limit: f64, fps: (usize, [f32; 25]), + ball_cam: bool, stop_day: bool, daytime: f32, day_speed: f32, @@ -58,6 +67,7 @@ impl Default for Options { uncap_fps: false, fps_limit: 120., fps: Default::default(), + ball_cam: true, stop_day: false, daytime: 0., day_speed: 1., @@ -90,6 +100,7 @@ impl Options { "vsync" => options.vsync = value.parse().unwrap(), "uncap_fps" => options.uncap_fps = value.parse().unwrap(), "fps_limit" => options.fps_limit = value.parse().unwrap(), + "ball_cam" => options.ball_cam = value.parse().unwrap(), "stop_day" => options.stop_day = value.parse().unwrap(), "daytime" => options.daytime = value.parse().unwrap(), "day_speed" => options.day_speed = value.parse().unwrap(), @@ -117,6 +128,7 @@ impl Options { file.write_fmt(format_args!("vsync={}\n", self.vsync))?; file.write_fmt(format_args!("uncap_fps={}\n", self.uncap_fps))?; file.write_fmt(format_args!("fps_limit={}\n", self.fps_limit))?; + file.write_fmt(format_args!("ball_cam={}\n", self.ball_cam))?; file.write_fmt(format_args!("stop_day={}\n", self.stop_day))?; file.write_fmt(format_args!("daytime={}\n", self.daytime))?; file.write_fmt(format_args!("day_speed={}\n", self.day_speed))?; @@ -128,7 +140,9 @@ impl Options { #[inline] fn is_not_similar(&self, other: &Options) -> bool { self.vsync != other.vsync + || self.uncap_fps != other.uncap_fps || self.fps_limit != other.fps_limit + || self.ball_cam != other.ball_cam || self.stop_day != other.stop_day || self.daytime != other.daytime || self.day_speed != other.day_speed @@ -202,6 +216,7 @@ fn ui_system( .speed(5.) .clamp_range(30.0..=600.), ); + 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")); @@ -255,6 +270,14 @@ fn ui_system( // .insert((AtmosphereCamera::default(), Spectator, RaycastPickCamera::default())); // } +fn toggle_ballcam(options: Res, mut ballcam: ResMut) { + if options.focus { + return; + } + + ballcam.enabled = options.ball_cam; +} + fn toggle_vsync(options: Res, mut framepace: ResMut) { if options.focus { return; @@ -320,7 +343,11 @@ fn write_settings_to_file( } } -fn listen(key: Res>, mut primary_camera: Query<&mut PrimaryCamera>) { +fn listen(key: Res>, mut primary_camera: Query<&mut PrimaryCamera>, options: Res) { + if !options.focus { + return; + } + let mut state = primary_camera.single_mut(); if key.just_pressed(KeyCode::Key1) || key.just_pressed(KeyCode::Numpad1) { @@ -335,6 +362,8 @@ fn listen(key: Res>, mut primary_camera: Query<&mut PrimaryCamera *state = PrimaryCamera::TrackCar(5); } else if key.just_pressed(KeyCode::Key6) || key.just_pressed(KeyCode::Numpad2) { *state = PrimaryCamera::TrackCar(6); + } else if key.just_pressed(KeyCode::Key9) || key.just_pressed(KeyCode::Numpad9) { + *state = PrimaryCamera::Director(0); } else if key.just_pressed(KeyCode::Key0) || key.just_pressed(KeyCode::Numpad0) { *state = PrimaryCamera::Spectator; } diff --git a/src/rocketsim.rs b/src/rocketsim.rs index d2a2e78..7ab470b 100644 --- a/src/rocketsim.rs +++ b/src/rocketsim.rs @@ -80,6 +80,7 @@ pub struct CarState { pub last_rel_dodge_torque: Vec3, pub jump_time: f32, pub flip_time: f32, + pub is_flipping: bool, pub is_jumping: bool, pub air_time_since_jump: f32, pub boost: f32, diff --git a/src/udp.rs b/src/udp.rs index cb5202f..6282bf9 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -1,4 +1,4 @@ -use std::{cmp::Ordering, f32::consts::PI, fs, net::UdpSocket}; +use std::{cmp::Ordering, f32::consts::PI, fs, net::UdpSocket, time::Duration}; use bevy::{ app::AppExit, @@ -11,6 +11,7 @@ use crate::{ assets::{get_material, get_mesh_info, BoostPickupGlows}, bytes::{FromBytes, ToBytes}, camera::{EntityName, HighlightedEntity, PrimaryCamera}, + gui::BallCam, mesh::{ChangeCarPos, LargeBoostPadLocRots}, rocketsim::{CarInfo, GameState, Team}, LoadState, ServerPort, @@ -31,6 +32,8 @@ impl Car { self.0 } } +#[derive(Resource)] +struct DirectorTimer(Timer); #[derive(Resource)] pub struct UdpConnection(pub UdpSocket); @@ -458,15 +461,41 @@ fn update_ball( transform.rotation = state.ball_rot.to_bevy(); } +const MIN_DIST_FROM_BALL: f32 = 175.; +const MIN_DIST_FROM_BALL_SQ: f32 = MIN_DIST_FROM_BALL * MIN_DIST_FROM_BALL; + +const MIN_CAMERA_BALLCAM_HEIGHT: f32 = 10.; + fn update_car( state: Res, + ballcam: Res, mut cars: Query<(&mut Transform, &Car)>, - mut camera_query: Query<(&PrimaryCamera, &mut Transform), Without>, + mut camera_query: Query<(&mut PrimaryCamera, &mut Transform), Without>, + mut timer: ResMut, + time: Res