From c932961566bc0f008268aacec3de5d618e3cc4bf Mon Sep 17 00:00:00 2001
From: jugeeya <jugeeya@live.com>
Date: Fri, 10 Feb 2023 14:22:29 -0800
Subject: [PATCH] Frame Advantage only on shield for now; fix menu soft-lock
 with frame-by-frame

---
 src/common/menu.rs            | 36 ++++++++++-------------------------
 src/training/combo.rs         |  6 +++---
 src/training/frame_counter.rs | 14 +++++++++-----
 src/training/ui/menu.rs       |  4 ++++
 4 files changed, 26 insertions(+), 34 deletions(-)

diff --git a/src/common/menu.rs b/src/common/menu.rs
index 7910541..e253eb9 100644
--- a/src/common/menu.rs
+++ b/src/common/menu.rs
@@ -6,34 +6,21 @@ use crate::training::frame_counter;
 use skyline::nn::hid::{GetNpadStyleSet, NpadGcState};
 use training_mod_consts::MenuJsonStruct;
 
-static mut FRAME_COUNTER_INDEX: usize = 0;
-pub static mut QUICK_MENU_FRAME_COUNTER_INDEX: usize = 0;
-const MENU_LOCKOUT_FRAMES: u32 = 15;
+// This is a special frame counter that will tick on draw()
+// We'll count how long the menu has been open
+pub static mut FRAME_COUNTER_INDEX: usize = 0;
+const MENU_INPUT_WAIT_FRAMES : u32 = 30;
+const MENU_CLOSE_WAIT_FRAMES : u32 = 60;
 pub static mut QUICK_MENU_ACTIVE: bool = false;
 
 pub fn init() {
     unsafe {
         FRAME_COUNTER_INDEX = frame_counter::register_counter();
-        QUICK_MENU_FRAME_COUNTER_INDEX = frame_counter::register_counter();
     }
 }
 
-pub unsafe fn menu_condition(module_accessor: &mut smash::app::BattleObjectModuleAccessor) -> bool {
-    // also ensure quick menu is reset
-    if frame_counter::get_frame_count(QUICK_MENU_FRAME_COUNTER_INDEX) > 60 {
-        frame_counter::full_reset(QUICK_MENU_FRAME_COUNTER_INDEX);
-    }
-
-    // Only check for button combination if the counter is 0 (not locked out)
-    match frame_counter::get_frame_count(FRAME_COUNTER_INDEX) {
-        0 => button_config::combo_passes(module_accessor, button_config::ButtonCombo::OpenMenu),
-        1..MENU_LOCKOUT_FRAMES => false,
-        _ => {
-            // Waited longer than the lockout time, reset the counter so the menu can be opened again
-            frame_counter::full_reset(FRAME_COUNTER_INDEX);
-            false
-        }
-    }
+pub unsafe fn menu_condition(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
+    button_config::combo_passes(module_accessor, button_config::ButtonCombo::OpenMenu)
 }
 
 const MENU_CONF_PATH: &str = "sd:/TrainingModpack/training_modpack_menu.json";
@@ -62,9 +49,6 @@ pub unsafe fn set_menu_from_json(message: &str) {
 pub fn spawn_menu() {
     unsafe {
         frame_counter::reset_frame_count(FRAME_COUNTER_INDEX);
-        frame_counter::start_counting(FRAME_COUNTER_INDEX);
-        frame_counter::reset_frame_count(QUICK_MENU_FRAME_COUNTER_INDEX);
-        frame_counter::start_counting(QUICK_MENU_FRAME_COUNTER_INDEX);
 
         QUICK_MENU_ACTIVE = true;
     }
@@ -184,7 +168,7 @@ pub fn handle_get_npad_state(state: *mut NpadGcState, _controller_id: *const u32
             // BUTTON_PRESSES.down.is_pressed = (*state).Buttons & ((1 << 15) | (1 << 19)) > 0;
             // BUTTON_PRESSES.up.is_pressed = (*state).Buttons & ((1 << 13) | (1 << 17)) > 0;
 
-            if frame_counter::get_frame_count(FRAME_COUNTER_INDEX) != 0 {
+            if frame_counter::get_frame_count(FRAME_COUNTER_INDEX) < MENU_INPUT_WAIT_FRAMES {
                 return;
             }
 
@@ -276,10 +260,10 @@ pub unsafe fn quick_menu_loop() {
                 received_input = true;
                 if app.page != AppPage::SUBMENU {
                     app.on_b()
-                } else if frame_counter::get_frame_count(QUICK_MENU_FRAME_COUNTER_INDEX) == 0
-                {
+                } else if frame_counter::get_frame_count(FRAME_COUNTER_INDEX) > MENU_CLOSE_WAIT_FRAMES {
                     // Leave menu.
                     QUICK_MENU_ACTIVE = false;
+                    frame_counter::reset_frame_count(FRAME_COUNTER_INDEX);
                     let menu_json = app.get_menu_selections();
                     set_menu_from_json(&menu_json);
                     EVENT_QUEUE.push(Event::menu_open(menu_json));
diff --git a/src/training/combo.rs b/src/training/combo.rs
index 9677ca3..046ff65 100644
--- a/src/training/combo.rs
+++ b/src/training/combo.rs
@@ -20,7 +20,7 @@ pub fn init() {
     }
 }
 
-unsafe fn was_in_hitstun(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
+unsafe fn _was_in_hitstun(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
     let prev_status = StatusModule::prev_status_kind(module_accessor, 0);
     (*FIGHTER_STATUS_KIND_DAMAGE..*FIGHTER_STATUS_KIND_DAMAGE_FALL).contains(&prev_status)
 }
@@ -96,7 +96,7 @@ pub unsafe fn is_enable_transition_term(
         // if both are now active
         if PLAYER_ACTIONABLE && CPU_ACTIONABLE && FRAME_ADVANTAGE_CHECK {
             let cpu_module_accessor = get_module_accessor(FighterId::CPU);
-            if was_in_hitstun(cpu_module_accessor) || was_in_shieldstun(cpu_module_accessor) {
+            if was_in_shieldstun(cpu_module_accessor) {
                 update_frame_advantage(
                     (CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32,
                 );
@@ -147,7 +147,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
 
     // if both are now active
     if PLAYER_ACTIONABLE && CPU_ACTIONABLE && FRAME_ADVANTAGE_CHECK {
-        if was_in_hitstun(cpu_module_accessor) || was_in_shieldstun(cpu_module_accessor) {
+        if was_in_shieldstun(cpu_module_accessor) {
             update_frame_advantage((CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32);
         }
 
diff --git a/src/training/frame_counter.rs b/src/training/frame_counter.rs
index 749d342..08e37f7 100644
--- a/src/training/frame_counter.rs
+++ b/src/training/frame_counter.rs
@@ -34,8 +34,8 @@ pub fn reset_frame_count(index: usize) {
 }
 
 pub fn full_reset(index: usize) {
-    frame_counter::reset_frame_count(index);
-    frame_counter::stop_counting(index);
+    reset_frame_count(index);
+    stop_counting(index);
 }
 
 /**
@@ -46,10 +46,10 @@ pub fn should_delay(delay: u32, index: usize) -> bool {
         return false;
     }
 
-    let current_frame = frame_counter::get_frame_count(index);
+    let current_frame = get_frame_count(index);
 
     if current_frame == 0 {
-        frame_counter::start_counting(index);
+        start_counting(index);
     }
 
     if current_frame >= delay {
@@ -64,13 +64,17 @@ pub fn get_frame_count(index: usize) -> u32 {
     unsafe { COUNTERS[index] }
 }
 
+pub fn tick_idx(index: usize) {
+    unsafe { COUNTERS[index] += 1; }
+}
+
 fn tick() {
     unsafe {
         for (index, _frame) in COUNTERS.iter().enumerate() {
             if !SHOULD_COUNT[index] {
                 continue;
             }
-            COUNTERS[index] += 1;
+            tick_idx(index);
         }
     }
 }
diff --git a/src/training/ui/menu.rs b/src/training/ui/menu.rs
index 4ad094d..17cc2bb 100644
--- a/src/training/ui/menu.rs
+++ b/src/training/ui/menu.rs
@@ -3,6 +3,7 @@ use skyline::nn::ui2d::*;
 use smash::ui2d::{SmashPane, SmashTextBox};
 use training_mod_tui::{App, AppPage};
 use training_mod_tui::gauge::GaugeState;
+use crate::training::frame_counter;
 
 pub static NUM_MENU_TEXT_OPTIONS: usize = 33;
 pub static _NUM_MENU_TABS: usize = 3;
@@ -256,6 +257,9 @@ pub unsafe fn draw(root_pane: &mut Pane) {
     }
 
     root_pane.find_pane_by_name_recursive("TrModMenu").unwrap().set_visible(QUICK_MENU_ACTIVE);
+    if QUICK_MENU_ACTIVE {
+        frame_counter::tick_idx(crate::common::menu::FRAME_COUNTER_INDEX);
+    }
 
     // Make all invisible first
     (0..NUM_MENU_TEXT_OPTIONS).for_each(|idx| {