diff --git a/bxt-strafe/src/steps.rs b/bxt-strafe/src/steps.rs index 5141e1e..021fc1b 100644 --- a/bxt-strafe/src/steps.rs +++ b/bxt-strafe/src/steps.rs @@ -350,7 +350,7 @@ impl Step for Strafe { frame_bulk.auto_actions.movement { let theta = match type_ { - StrafeType::MaxAccel | StrafeType::MaxAccelYawOffset(_, _, _) => match dir { + StrafeType::MaxAccel | StrafeType::MaxAccelYawOffset { .. } => match dir { StrafeDir::Left => max_accel_theta(parameters, &state), StrafeDir::Right => -max_accel_theta(parameters, &state), StrafeDir::Yaw(yaw) => { @@ -447,7 +447,7 @@ impl Step for Strafe { (camera_yaw, entry) }; - let camera_yaw = if matches!(type_, StrafeType::MaxAccelYawOffset(_, _, _)) { + let camera_yaw = if matches!(type_, StrafeType::MaxAccelYawOffset { .. }) { // theta < 0. = is right // If is right then we decreases yaw by offset. // Therefore, positive offset in framebulk mean going more on that side. @@ -560,12 +560,22 @@ impl Step for ResetFields { // If we have some acceleration, then this kicks in. // It will preserve the final value across split segments. if let Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(start, target, accel), + type_: + StrafeType::MaxAccelYawOffset { + start, + target, + accel, + }, dir, })) = frame_bulk.auto_actions.movement { let right = matches!(dir, StrafeDir::Right); + // Flip start and target when accel is negative. + state.max_accel_yaw_offset_value = (state.max_accel_yaw_offset_value + accel) + .max(start) + .min(target); + // Reset value if we have different inputs. // This means that if we split a s5x bulk, // there won't be any side effects. @@ -574,12 +584,10 @@ impl Step for ResetFields { || accel != state.prev_max_accel_yaw_offset_accel || right != state.prev_max_accel_yaw_offset_right { - // Terrible hack to have 0 as the start and target at the end and - // vice versa. state.max_accel_yaw_offset_value = if accel.is_sign_negative() { - target - accel + target } else { - start - accel + start }; // Update so next time we know what to compare against. @@ -588,16 +596,6 @@ impl Step for ResetFields { state.prev_max_accel_yaw_offset_accel = accel; state.prev_max_accel_yaw_offset_right = right; }; - - state.max_accel_yaw_offset_value = if accel.is_sign_negative() { - // accel is negative so addition is subtraction. - (state.max_accel_yaw_offset_value + accel).max(start) - } else { - // .max(start) to avoid negative and be consistent with HLStrafe. - (state.max_accel_yaw_offset_value + accel) - .max(start) - .min(target) - }; } self.0 diff --git a/src/hooks/bxt.rs b/src/hooks/bxt.rs index 282b1f3..c557dda 100644 --- a/src/hooks/bxt.rs +++ b/src/hooks/bxt.rs @@ -141,8 +141,17 @@ pub struct OnTasPlaybackFrameData { pub strafe_cycle_frame_count: u32, pub prev_predicted_trace_fractions: [f32; 4], pub prev_predicted_trace_normal_zs: [f32; 4], - // [value, start, target, accel, dir] - pub accel_yawspeed: [f32; 5], + pub max_accel_yaw_offset: OnTasPlaybackFrameMaxAccelYawOffset, +} + +#[derive(Debug, Clone, Copy)] +#[repr(C)] +pub struct OnTasPlaybackFrameMaxAccelYawOffset { + pub value: f32, + pub start: f32, + pub target: f32, + pub accel: f32, + pub dir: u8, } unsafe extern "C" fn on_tas_playback_frame(data: OnTasPlaybackFrameData) -> c_int { diff --git a/src/modules/tas_optimizer/optimizer.rs b/src/modules/tas_optimizer/optimizer.rs index c7a505b..5e989c0 100644 --- a/src/modules/tas_optimizer/optimizer.rs +++ b/src/modules/tas_optimizer/optimizer.rs @@ -430,6 +430,8 @@ impl Optimizer { Line::Change(_) => (), Line::TargetYawOverride(_) => (), Line::RenderYawOverride(_) => (), + Line::PitchOverride(_) => (), + Line::RenderPitchOverride(_) => (), } } diff --git a/src/modules/tas_optimizer/simulator.rs b/src/modules/tas_optimizer/simulator.rs index e7488d9..5665791 100644 --- a/src/modules/tas_optimizer/simulator.rs +++ b/src/modules/tas_optimizer/simulator.rs @@ -125,6 +125,8 @@ impl<'a, T: Trace> Iterator for Simulator<'a, T> { Line::Change(_) => (), Line::TargetYawOverride(_) => (), Line::RenderYawOverride(_) => (), + Line::PitchOverride(_) => (), + Line::RenderPitchOverride(_) => (), } // Advance to the next line for non-frame-bulks. @@ -294,7 +296,11 @@ mod tests { let lines = [Line::FrameBulk(FrameBulk { auto_actions: AutoActions { movement: Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(0., 210., 10.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 210., + accel: 10., + }, dir: StrafeDir::Left, })), leave_ground_action: None, @@ -319,7 +325,11 @@ mod tests { Line::FrameBulk(FrameBulk { auto_actions: AutoActions { movement: Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(0., 210., 10.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 210., + accel: 10., + }, dir: StrafeDir::Left, })), leave_ground_action: None, @@ -338,7 +348,11 @@ mod tests { Line::FrameBulk(FrameBulk { auto_actions: AutoActions { movement: Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(0., 210., 10.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 210., + accel: 10., + }, dir: StrafeDir::Left, })), leave_ground_action: None, @@ -369,7 +383,11 @@ mod tests { let mut lines = vec![Line::FrameBulk(FrameBulk { auto_actions: AutoActions { movement: Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(0., 200., 10.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 200., + accel: 10., + }, dir: StrafeDir::Left, })), leave_ground_action: None, @@ -393,7 +411,11 @@ mod tests { lines.push(Line::FrameBulk(FrameBulk { auto_actions: AutoActions { movement: Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(0., 210., 10.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 210., + accel: 10., + }, dir: StrafeDir::Left, })), leave_ground_action: None, @@ -418,7 +440,11 @@ mod tests { lines.push(Line::FrameBulk(FrameBulk { auto_actions: AutoActions { movement: Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(0., 210., 9.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 210., + accel: 9., + }, dir: StrafeDir::Left, })), leave_ground_action: None, @@ -443,7 +469,11 @@ mod tests { lines.push(Line::FrameBulk(FrameBulk { auto_actions: AutoActions { movement: Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(0., 210., 9.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 210., + accel: 9., + }, dir: StrafeDir::Right, })), leave_ground_action: None, @@ -468,7 +498,11 @@ mod tests { lines.push(Line::FrameBulk(FrameBulk { auto_actions: AutoActions { movement: Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(10., 210., 9.), + type_: StrafeType::MaxAccelYawOffset { + start: 10., + target: 210., + accel: 9., + }, dir: StrafeDir::Right, })), leave_ground_action: None, diff --git a/src/modules/tas_studio/editor/mod.rs b/src/modules/tas_studio/editor/mod.rs index cd25692..0c0bfe2 100644 --- a/src/modules/tas_studio/editor/mod.rs +++ b/src/modules/tas_studio/editor/mod.rs @@ -24,11 +24,12 @@ use self::toggle_auto_action::ToggleAutoActionTarget; use self::utils::{ bulk_and_first_frame_idx, bulk_and_first_frame_idx_mut, bulk_idx_and_is_last, bulk_idx_and_repeat_at_frame, join_lines, line_first_frame_idx, line_idx_and_repeat_at_frame, - FrameBulkExt, + FrameBulkExt, MaxAccelOffsetValuesMut, }; use super::remote::{AccurateFrame, PlayRequest}; use crate::hooks::sdl::MouseState; use crate::modules::tas_optimizer::simulator::Simulator; +use crate::modules::tas_studio::editor::utils::MaxAccelOffsetValues; use crate::modules::triangle_drawing::triangle_api::{Primitive, RenderMode}; use crate::modules::triangle_drawing::TriangleApi; @@ -317,7 +318,7 @@ pub enum MaxAccelYawOffsetMode { Target, Acceleration, Start, - /// Alt is for not left or right strafing. + /// Alt is for adjusting the yaw field value of the strafe direction. Alt, } @@ -326,11 +327,11 @@ pub struct MaxAccelYawOffsetMouseAdjustment { pub start: f32, pub target: f32, pub accel: f32, - pub alt: MaxAccelYawoffsetAlt, + pub alt: MaxAccelYawOffsetYawField, } #[derive(Debug, Clone, Copy)] -pub enum MaxAccelYawoffsetAlt { +pub enum MaxAccelYawOffsetYawField { None, Yaw(f32), LeftRight(NonZeroU32), @@ -1012,19 +1013,25 @@ impl Editor { _ => Vec2::X, }; - if let Some((start, target, accel)) = bulk.max_accel_yaw_offset() { + if let Some(MaxAccelOffsetValues { + start, + target, + accel, + .. + }) = bulk.max_accel_yaw_offset() + { // Mode to know which to switch to. // For left or right, it would be TargetAndEnd so we can turn better. - // For left-right and yaw, it would bet Alt where we can change the + // For left-right and yaw, it would be Alt where we can change the // first yaw field value. - let (mode, adjustment_dir, alt) = - if let Some(AutoMovement::Strafe(StrafeSettings { dir, .. })) = - bulk.auto_actions.movement - { - // Match StrafiDir so we can get adjustment mode and - // adjustment_dir. - // Then match StrafeType to get values for alt. - match dir { + let (mode, adjustment_dir, alt) = if let Some(AutoMovement::Strafe( + StrafeSettings { dir, .. }, + )) = bulk.auto_actions.movement + { + // Match StrafiDir so we can get adjustment mode and + // adjustment_dir. + // Then match StrafeType to get values for alt. + match dir { StrafeDir::Left | StrafeDir::Right | StrafeDir::Best => { let adjustment_dir = if matches!(dir, StrafeDir::Right) { -adjustment_dir @@ -1035,13 +1042,13 @@ impl Editor { ( MaxAccelYawOffsetMode::StartAndTarget, adjustment_dir, - MaxAccelYawoffsetAlt::None, + MaxAccelYawOffsetYawField::None, ) } StrafeDir::Yaw(yaw) | StrafeDir::Line { yaw } => ( MaxAccelYawOffsetMode::Alt, adjustment_dir, - MaxAccelYawoffsetAlt::Yaw(yaw), + MaxAccelYawOffsetYawField::Yaw(yaw), ), StrafeDir::LeftRight(count) | StrafeDir::RightLeft(count) => { let adjustment_dir = @@ -1054,17 +1061,17 @@ impl Editor { ( MaxAccelYawOffsetMode::Alt, adjustment_dir, - MaxAccelYawoffsetAlt::LeftRight(count), + MaxAccelYawOffsetYawField::LeftRight(count), ) } _ => return Err(ManualOpError::UserError( - "Max accel yaw offset does not support current strafe dir." + "Editor does not support current strafe dir for max accel yaw offset." .to_owned(), )), } - } else { - unreachable!() - }; + } else { + unreachable!() + }; self.max_accel_yaw_offset_adjustment = Some(MaxAccelYawOffsetAdjustment { @@ -1831,7 +1838,13 @@ impl Editor { .nth(bulk_idx) .unwrap(); - let (start, target, accel, mut yaw, mut count) = bulk.max_accel_yaw_offset_mut().unwrap(); + let MaxAccelOffsetValuesMut { + start, + target, + accel, + mut yaw, + mut count, + } = bulk.max_accel_yaw_offset_mut().unwrap(); if !mouse.buttons.is_right_down() { if !adjustment.mouse_adjustment.changed_once { @@ -1840,25 +1853,27 @@ impl Editor { } let op = match adjustment.mode { - MaxAccelYawOffsetMode::StartAndTarget => Operation::SetMaxAccelStartAndTarget { - bulk_idx, - from: ( - adjustment.mouse_adjustment.original_value.start, - adjustment.mouse_adjustment.original_value.target, - ), - to: (*start, *target), - }, - MaxAccelYawOffsetMode::Start => Operation::SetMaxAccelStart { + MaxAccelYawOffsetMode::StartAndTarget => { + Operation::SetMaxAccelOffsetStartAndTarget { + bulk_idx, + from: ( + adjustment.mouse_adjustment.original_value.start, + adjustment.mouse_adjustment.original_value.target, + ), + to: (*start, *target), + } + } + MaxAccelYawOffsetMode::Start => Operation::SetMaxAccelOffsetStart { bulk_idx, from: adjustment.mouse_adjustment.original_value.start, to: *start, }, - MaxAccelYawOffsetMode::Target => Operation::SetMaxAccelTarget { + MaxAccelYawOffsetMode::Target => Operation::SetMaxAccelOffsetTarget { bulk_idx, from: adjustment.mouse_adjustment.original_value.target, to: *target, }, - MaxAccelYawOffsetMode::Acceleration => Operation::SetMaxAccelAccel { + MaxAccelYawOffsetMode::Acceleration => Operation::SetMaxAccelOffsetAccel { bulk_idx, from: adjustment.mouse_adjustment.original_value.accel, to: *accel, @@ -1866,20 +1881,22 @@ impl Editor { MaxAccelYawOffsetMode::Alt => { match adjustment.mouse_adjustment.original_value.alt { // Can't do anything. - MaxAccelYawoffsetAlt::None => { + MaxAccelYawOffsetYawField::None => { self.max_accel_yaw_offset_adjustment = None; return Ok(()); } - MaxAccelYawoffsetAlt::Yaw(from) => Operation::SetYaw { + MaxAccelYawOffsetYawField::Yaw(from) => Operation::SetYaw { bulk_idx, from, to: *yaw.unwrap(), }, - MaxAccelYawoffsetAlt::LeftRight(from) => Operation::SetLeftRightCount { - bulk_idx, - from: from.get(), - to: count.unwrap().get(), - }, + MaxAccelYawOffsetYawField::LeftRight(from) => { + Operation::SetLeftRightCount { + bulk_idx, + from: from.get(), + to: count.unwrap().get(), + } + } } } }; @@ -1903,14 +1920,14 @@ impl Editor { *target = adjustment.mouse_adjustment.original_value.target; *accel = adjustment.mouse_adjustment.original_value.accel; - if let MaxAccelYawoffsetAlt::Yaw(original) = + if let MaxAccelYawOffsetYawField::Yaw(original) = adjustment.mouse_adjustment.original_value.alt { let binding = yaw.as_deref_mut(); *binding.unwrap() = original; } - if let MaxAccelYawoffsetAlt::LeftRight(original) = + if let MaxAccelYawOffsetYawField::LeftRight(original) = adjustment.mouse_adjustment.original_value.alt { let binding = count.as_deref_mut(); @@ -1990,10 +2007,10 @@ impl Editor { let delta = delta * 50. * 0.1; match adjustment.mouse_adjustment.original_value.alt { - MaxAccelYawoffsetAlt::None => { + MaxAccelYawOffsetYawField::None => { adjustment.cycle_again = true; } - MaxAccelYawoffsetAlt::Yaw(from) => { + MaxAccelYawOffsetYawField::Yaw(from) => { let new_yaw = from + delta; // We make sure the original_value.alt is correct. @@ -2003,7 +2020,7 @@ impl Editor { should_invalidate = true; } } - MaxAccelYawoffsetAlt::LeftRight(from) => { + MaxAccelYawOffsetYawField::LeftRight(from) => { let new_count = from .get() .saturating_add_signed((delta).round() as i32) @@ -2365,40 +2382,44 @@ impl Editor { .nth(bulk_idx) .unwrap(); - let mut values = bulk.max_accel_yaw_offset_mut().unwrap(); + let MaxAccelOffsetValuesMut { + start, + target, + accel, + yaw, + count, + } = bulk.max_accel_yaw_offset_mut().unwrap(); let mut should_invalidate = false; - if (*values.0, *values.1, *values.2) + if (*start, *target, *accel) != ( original_value.start, original_value.target, original_value.accel, ) { - *values.0 = original_value.start; - *values.1 = original_value.target; - *values.2 = original_value.accel; + *start = original_value.start; + *target = original_value.target; + *accel = original_value.accel; should_invalidate = true; } - if let MaxAccelYawoffsetAlt::Yaw(original) = + if let MaxAccelYawOffsetYawField::Yaw(original) = adjustment.mouse_adjustment.original_value.alt { - let binding = values.3.as_deref_mut(); - if *binding.as_deref().unwrap() != original { - *binding.unwrap() = original; + if *yaw.as_deref().unwrap() != original { + *yaw.unwrap() = original; } should_invalidate = true; } - if let MaxAccelYawoffsetAlt::LeftRight(original) = + if let MaxAccelYawOffsetYawField::LeftRight(original) = adjustment.mouse_adjustment.original_value.alt { - let binding = values.4.as_deref_mut(); - if *binding.as_deref().unwrap() != original { - *binding.unwrap() = original; + if *count.as_deref().unwrap() != original { + *count.unwrap() = original; } should_invalidate = true; diff --git a/src/modules/tas_studio/editor/operation.rs b/src/modules/tas_studio/editor/operation.rs index ce023c4..cb5f279 100644 --- a/src/modules/tas_studio/editor/operation.rs +++ b/src/modules/tas_studio/editor/operation.rs @@ -8,11 +8,12 @@ use serde::{Deserialize, Serialize}; use super::utils::{line_first_frame_idx, line_first_frame_idx_and_frame_count}; use crate::modules::tas_studio::editor::utils::{ bulk_and_first_frame_idx_mut, line_idx_and_repeat_at_frame, FrameBulkExt, + MaxAccelOffsetValuesMut, }; // This enum is stored in a SQLite DB as bincode bytes. All changes MUST BE BACKWARDS COMPATIBLE to // be able to load old projects. -// Make sure that newer operations must be added at the end of the enum. +// Make sure that newer operations are added at the end of the enum. /// A basic operation on a HLTAS. /// /// All operations can be applied and undone. They therefore store enough information to be able to @@ -103,22 +104,22 @@ pub enum Operation { from: Option, to: Option, }, - SetMaxAccelStart { + SetMaxAccelOffsetStart { bulk_idx: usize, from: f32, to: f32, }, - SetMaxAccelTarget { + SetMaxAccelOffsetTarget { bulk_idx: usize, from: f32, to: f32, }, - SetMaxAccelAccel { + SetMaxAccelOffsetAccel { bulk_idx: usize, from: f32, to: f32, }, - SetMaxAccelStartAndTarget { + SetMaxAccelOffsetStartAndTarget { bulk_idx: usize, from: (f32, f32), to: (f32, f32), @@ -392,7 +393,7 @@ impl Operation { *yawspeed = to; return Some(first_frame_idx); } - Operation::SetMaxAccelStart { bulk_idx, from, to } => { + Operation::SetMaxAccelOffsetStart { bulk_idx, from, to } => { let (bulk, first_frame_idx) = bulk_and_first_frame_idx_mut(hltas) .nth(bulk_idx) .expect("invalid bulk index"); @@ -400,7 +401,7 @@ impl Operation { let start = bulk .max_accel_yaw_offset_mut() .expect("frame bulk should have starting yaw offset") - .0; + .start; assert_eq!(from, *start, "wrong current starting yaw offset"); if from != to { @@ -408,7 +409,7 @@ impl Operation { return Some(first_frame_idx); } } - Operation::SetMaxAccelTarget { bulk_idx, from, to } => { + Operation::SetMaxAccelOffsetTarget { bulk_idx, from, to } => { let (bulk, first_frame_idx) = bulk_and_first_frame_idx_mut(hltas) .nth(bulk_idx) .expect("invalid bulk index"); @@ -416,7 +417,7 @@ impl Operation { let target = bulk .max_accel_yaw_offset_mut() .expect("frame bulk should have target yaw offset") - .1; + .target; assert_eq!(from, *target, "wrong current target yaw offset"); if from != to { @@ -424,7 +425,7 @@ impl Operation { return Some(first_frame_idx); } } - Operation::SetMaxAccelAccel { bulk_idx, from, to } => { + Operation::SetMaxAccelOffsetAccel { bulk_idx, from, to } => { let (bulk, first_frame_idx) = bulk_and_first_frame_idx_mut(hltas) .nth(bulk_idx) .expect("invalid bulk index"); @@ -432,7 +433,7 @@ impl Operation { let accel = bulk .max_accel_yaw_offset_mut() .expect("frame bulk should have yaw acceleration") - .2; + .accel; assert_eq!(from, *accel, "wrong current yaw acceleration"); if from != to { @@ -440,12 +441,12 @@ impl Operation { return Some(first_frame_idx); } } - Operation::SetMaxAccelStartAndTarget { bulk_idx, from, to } => { + Operation::SetMaxAccelOffsetStartAndTarget { bulk_idx, from, to } => { let (bulk, first_frame_idx) = bulk_and_first_frame_idx_mut(hltas) .nth(bulk_idx) .expect("invalid bulk index"); - let (start, target, ..) = bulk + let MaxAccelOffsetValuesMut { start, target, .. } = bulk .max_accel_yaw_offset_mut() .expect("frame bulk should have starting and target yaw offset"); @@ -748,7 +749,7 @@ impl Operation { *yawspeed = from; return Some(first_frame_idx); } - Operation::SetMaxAccelStart { bulk_idx, from, to } => { + Operation::SetMaxAccelOffsetStart { bulk_idx, from, to } => { let (bulk, first_frame_idx) = bulk_and_first_frame_idx_mut(hltas) .nth(bulk_idx) .expect("invalid bulk index"); @@ -756,7 +757,7 @@ impl Operation { let start = bulk .max_accel_yaw_offset_mut() .expect("frame bulk should have starting yaw offset") - .0; + .start; assert_eq!(to, *start, "wrong current starting yaw offset"); if from != to { @@ -764,7 +765,7 @@ impl Operation { return Some(first_frame_idx); } } - Operation::SetMaxAccelTarget { bulk_idx, from, to } => { + Operation::SetMaxAccelOffsetTarget { bulk_idx, from, to } => { let (bulk, first_frame_idx) = bulk_and_first_frame_idx_mut(hltas) .nth(bulk_idx) .expect("invalid bulk index"); @@ -772,7 +773,7 @@ impl Operation { let target = bulk .max_accel_yaw_offset_mut() .expect("frame bulk should have target yaw offset") - .1; + .target; assert_eq!(to, *target, "wrong current target yaw offset"); if from != to { @@ -780,7 +781,7 @@ impl Operation { return Some(first_frame_idx); } } - Operation::SetMaxAccelAccel { bulk_idx, from, to } => { + Operation::SetMaxAccelOffsetAccel { bulk_idx, from, to } => { let (bulk, first_frame_idx) = bulk_and_first_frame_idx_mut(hltas) .nth(bulk_idx) .expect("invalid bulk index"); @@ -788,7 +789,7 @@ impl Operation { let accel = bulk .max_accel_yaw_offset_mut() .expect("frame bulk should have yaw acceleration") - .2; + .accel; assert_eq!(to, *accel, "wrong current yaw acceleration"); if from != to { @@ -796,12 +797,12 @@ impl Operation { return Some(first_frame_idx); } } - Operation::SetMaxAccelStartAndTarget { bulk_idx, from, to } => { + Operation::SetMaxAccelOffsetStartAndTarget { bulk_idx, from, to } => { let (bulk, first_frame_idx) = bulk_and_first_frame_idx_mut(hltas) .nth(bulk_idx) .expect("invalid bulk index"); - let (start, target, ..) = bulk + let MaxAccelOffsetValuesMut { start, target, .. } = bulk .max_accel_yaw_offset_mut() .expect("frame bulk should have starting and target yaw offset"); @@ -1384,7 +1385,7 @@ s41-------|------|------|0.004|70|-|10 ----------|------|------|0.004|10|-|6 s50-------|------|------|0.004|- 0 0 0|-|10 s51-------|------|------|0.004|- 0 70 10|-|10", - Operation::SetMaxAccelStart { + Operation::SetMaxAccelOffsetStart { bulk_idx: 1, from: 0., to: 69., @@ -1403,7 +1404,7 @@ s51-------|------|------|0.004|- 0 70 10|-|10", ----------|------|------|0.004|10|-|6 s50-------|------|------|0.004|- 0 0 0|-|10 s51-------|------|------|0.004|- 0 70 10|-|10", - Operation::SetMaxAccelStartAndTarget { + Operation::SetMaxAccelOffsetStartAndTarget { bulk_idx: 1, from: (0., 0.), to: (69., -89.34), @@ -1460,7 +1461,7 @@ s51-------|------|------|0.004|- 0 70 10|-|10", ----------|------|------|0.004|10|-|6 s53-------|------|------|0.004|13 0 0 0|-|10 s51-------|------|------|0.004|- 0 70 10|-|10", - Operation::SetMaxAccelAccel { + Operation::SetMaxAccelOffsetAccel { bulk_idx: 1, from: 0., to: -14.3, diff --git a/src/modules/tas_studio/editor/utils.rs b/src/modules/tas_studio/editor/utils.rs index 17ba897..7fa6437 100644 --- a/src/modules/tas_studio/editor/utils.rs +++ b/src/modules/tas_studio/editor/utils.rs @@ -27,19 +27,28 @@ pub trait FrameBulkExt { /// Return a reference to the starting yaw offset, target yaw offset, and acceleration stored in /// the framebulk, if any. - fn max_accel_yaw_offset(&self) -> Option<(&f32, &f32, &f32)>; + fn max_accel_yaw_offset(&self) -> Option; // Return a mutable reference to the starting yaw offset, target yaw offset, acceleration, // and original yaw field value stored in the framebulk, if any. - fn max_accel_yaw_offset_mut( - &mut self, - ) -> Option<( - &mut f32, - &mut f32, - &mut f32, - Option<&mut f32>, - Option<&mut NonZeroU32>, - )>; + fn max_accel_yaw_offset_mut(&mut self) -> Option; +} + +#[allow(dead_code)] +pub struct MaxAccelOffsetValues<'a> { + pub start: &'a f32, + pub target: &'a f32, + pub accel: &'a f32, + pub yaw: Option<&'a f32>, + pub count: Option<&'a NonZeroU32>, +} + +pub struct MaxAccelOffsetValuesMut<'a> { + pub start: &'a mut f32, + pub target: &'a mut f32, + pub accel: &'a mut f32, + pub yaw: Option<&'a mut f32>, + pub count: Option<&'a mut NonZeroU32>, } impl FrameBulkExt for FrameBulk { @@ -105,28 +114,46 @@ impl FrameBulkExt for FrameBulk { } } - fn max_accel_yaw_offset(&self) -> Option<(&f32, &f32, &f32)> { + fn max_accel_yaw_offset(&self) -> Option { match &self.auto_actions.movement { Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(start, target, accel), - .. - })) => Some((start, target, accel)), + type_: + StrafeType::MaxAccelYawOffset { + start, + target, + accel, + }, + dir, + })) => { + let (yaw, count) = match dir { + StrafeDir::Yaw(yaw) | StrafeDir::Line { yaw } => (Some(yaw), None), + StrafeDir::LeftRight(count) | StrafeDir::RightLeft(count) => { + (None, Some(count)) + } + _ => (None, None), + }; + + Some(MaxAccelOffsetValues { + start, + target, + accel, + yaw, + count, + }) + } _ => None, } } - fn max_accel_yaw_offset_mut( - &mut self, - ) -> Option<( - &mut f32, - &mut f32, - &mut f32, - Option<&mut f32>, - Option<&mut NonZeroU32>, - )> { + fn max_accel_yaw_offset_mut(&mut self) -> Option { match &mut self.auto_actions.movement { Some(AutoMovement::Strafe(StrafeSettings { - type_: StrafeType::MaxAccelYawOffset(start, target, accel), + type_: + StrafeType::MaxAccelYawOffset { + start, + target, + accel, + }, dir, })) => { let (yaw, count) = match dir { @@ -137,7 +164,13 @@ impl FrameBulkExt for FrameBulk { _ => (None, None), }; - Some((start, target, accel, yaw, count)) + Some(MaxAccelOffsetValuesMut { + start, + target, + accel, + yaw, + count, + }) } _ => None, } diff --git a/src/modules/tas_studio/mod.rs b/src/modules/tas_studio/mod.rs index a8ca7ec..ebb29d8 100644 --- a/src/modules/tas_studio/mod.rs +++ b/src/modules/tas_studio/mod.rs @@ -1050,8 +1050,8 @@ Values that you can toggle: - s07: right-left strafing - s40: constant turn rate to the left - s41: constant turn rate to the right -- s50: accelerated turn rate to the left -- s51: accelerated turn rate to the right +- s50: accelerated turn to the left +- s51: accelerated turn to the right - lgagst: makes autojump and ducktap trigger at optimal speed - autojump - ducktap @@ -1131,11 +1131,19 @@ fn toggle(marker: MainThreadMarker, what: String) { }, "s50" => ToggleAutoActionTarget::Strafe { dir: StrafeDir::Left, - type_: StrafeType::MaxAccelYawOffset(0., 0., 0.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 0., + accel: 0., + }, }, "s51" => ToggleAutoActionTarget::Strafe { dir: StrafeDir::Right, - type_: StrafeType::MaxAccelYawOffset(0., 0., 0.), + type_: StrafeType::MaxAccelYawOffset { + start: 0., + target: 0., + accel: 0., + }, }, "lgagst" => ToggleAutoActionTarget::LeaveGroundAtOptimalSpeed, "autojump" => ToggleAutoActionTarget::AutoJump, @@ -1604,12 +1612,12 @@ pub unsafe fn on_tas_playback_frame( // TODO: prev_frame_input, which is not set here, is important. let mut strafe_state = bxt_strafe::State::new(&tracer, params, player); strafe_state.strafe_cycle_frame_count = data.strafe_cycle_frame_count; - strafe_state.max_accel_yaw_offset_value = data.accel_yawspeed[0]; - strafe_state.prev_max_accel_yaw_offset_start = data.accel_yawspeed[1]; - strafe_state.prev_max_accel_yaw_offset_target = data.accel_yawspeed[2]; - strafe_state.prev_max_accel_yaw_offset_accel = data.accel_yawspeed[3]; - // LEFT = 0, RIGHT = 1. Very nice. But it is float though. - strafe_state.prev_max_accel_yaw_offset_right = data.accel_yawspeed[4] == 1.; + strafe_state.max_accel_yaw_offset_value = data.max_accel_yaw_offset.value; + strafe_state.prev_max_accel_yaw_offset_start = data.max_accel_yaw_offset.start; + strafe_state.prev_max_accel_yaw_offset_target = data.max_accel_yaw_offset.target; + strafe_state.prev_max_accel_yaw_offset_accel = data.max_accel_yaw_offset.accel; + // LEFT = 0, RIGHT = 1. Very nice. + strafe_state.prev_max_accel_yaw_offset_right = data.max_accel_yaw_offset.dir == 1; // Get view angles for this frame. unsafe { @@ -1887,7 +1895,11 @@ fn add_frame_bulk_hud_lines(text: &mut Vec, bulk: &FrameBulk) { StrafeType::ConstYawspeed(yawspeed) => { write!(text, "turn rate: {yawspeed:.0}").unwrap(); } - StrafeType::MaxAccelYawOffset(start, target, accel) => { + StrafeType::MaxAccelYawOffset { + start, + target, + accel, + } => { // The values are so tiny that only this would make it sensible. let start = start * 100.; let target = target * 100.;