1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-24 10:54:16 +00:00

Frame Counter Refactor (#612)

* Initial

* Fixes and formatting

* FIX FOR MENU
This commit is contained in:
jugeeya 2023-08-24 13:59:33 -07:00 committed by GitHub
parent b519152ce7
commit 8d8292ffc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 128 additions and 134 deletions

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use crate::common::*; use crate::common::*;
use crate::input::{ControllerStyle::*, *}; use crate::input::{ControllerStyle::*, *};
use crate::training::frame_counter;
use crate::training::ui::menu::VANILLA_MENU_ACTIVE; use crate::training::ui::menu::VANILLA_MENU_ACTIVE;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -136,7 +137,7 @@ pub fn handle_final_input_mapping(player_idx: i32, controller_struct: &mut SomeC
let p1_controller = &mut *controller_struct.controller; let p1_controller = &mut *controller_struct.controller;
let mut start_menu_request = false; let mut start_menu_request = false;
let menu_close_wait_frame = unsafe { *menu::VISUAL_FRAME_COUNTER.data_ptr() }; let menu_close_wait_frame = frame_counter::get_frame_count(*menu::MENU_CLOSE_FRAME_COUNTER);
if unsafe { MENU.menu_open_start_press == OnOff::On } { if unsafe { MENU.menu_open_start_press == OnOff::On } {
let start_hold_frames = &mut *START_HOLD_FRAMES.lock(); let start_hold_frames = &mut *START_HOLD_FRAMES.lock();
if p1_controller.current_buttons.plus() { if p1_controller.current_buttons.plus() {

View file

@ -1,3 +1,4 @@
use once_cell::sync::Lazy;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs; use std::fs;
@ -13,6 +14,7 @@ use crate::consts::MENU_OPTIONS_PATH;
use crate::events::{Event, EVENT_QUEUE}; use crate::events::{Event, EVENT_QUEUE};
use crate::input::*; use crate::input::*;
use crate::logging::*; use crate::logging::*;
use crate::training::frame_counter;
pub const MENU_CLOSE_WAIT_FRAMES: u32 = 15; pub const MENU_CLOSE_WAIT_FRAMES: u32 = 15;
pub static mut QUICK_MENU_ACTIVE: bool = false; pub static mut QUICK_MENU_ACTIVE: bool = false;
@ -109,10 +111,11 @@ lazy_static! {
(RUp, 0), (RUp, 0),
])) ]))
}; };
pub static ref VISUAL_FRAME_COUNTER: Mutex<u32> = Mutex::new(0);
pub static ref VISUAL_FRAME_COUNTER_SHOULD_COUNT: Mutex<bool> = Mutex::new(false);
} }
pub static MENU_CLOSE_FRAME_COUNTER: Lazy<usize> =
Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::Real));
pub fn handle_final_input_mapping( pub fn handle_final_input_mapping(
player_idx: i32, player_idx: i32,
controller_struct: &mut SomeControllerStruct, controller_struct: &mut SomeControllerStruct,
@ -122,7 +125,7 @@ pub fn handle_final_input_mapping(
if player_idx == 0 { if player_idx == 0 {
let p1_controller = &mut *controller_struct.controller; let p1_controller = &mut *controller_struct.controller;
*P1_CONTROLLER_STYLE.lock() = p1_controller.style; *P1_CONTROLLER_STYLE.lock() = p1_controller.style;
let visual_frame_count = *VISUAL_FRAME_COUNTER.data_ptr(); let visual_frame_count = frame_counter::get_frame_count(*MENU_CLOSE_FRAME_COUNTER);
if visual_frame_count > 0 && visual_frame_count < MENU_CLOSE_WAIT_FRAMES { if visual_frame_count > 0 && visual_frame_count < MENU_CLOSE_WAIT_FRAMES {
// If we just closed the menu, kill all inputs to avoid accidental presses // If we just closed the menu, kill all inputs to avoid accidental presses
*out = MappedInputs::empty(); *out = MappedInputs::empty();
@ -131,7 +134,8 @@ pub fn handle_final_input_mapping(
p1_controller.just_down = ButtonBitfield::default(); p1_controller.just_down = ButtonBitfield::default();
p1_controller.just_release = ButtonBitfield::default(); p1_controller.just_release = ButtonBitfield::default();
} else if visual_frame_count >= MENU_CLOSE_WAIT_FRAMES { } else if visual_frame_count >= MENU_CLOSE_WAIT_FRAMES {
*VISUAL_FRAME_COUNTER_SHOULD_COUNT.lock() = false; frame_counter::stop_counting(*MENU_CLOSE_FRAME_COUNTER);
frame_counter::reset_frame_count(*MENU_CLOSE_FRAME_COUNTER);
} }
if QUICK_MENU_ACTIVE { if QUICK_MENU_ACTIVE {
@ -190,7 +194,7 @@ pub fn handle_final_input_mapping(
app.on_b() app.on_b()
} else { } else {
// Leave menu. // Leave menu.
*VISUAL_FRAME_COUNTER_SHOULD_COUNT.lock() = true; frame_counter::start_counting(*MENU_CLOSE_FRAME_COUNTER);
QUICK_MENU_ACTIVE = false; QUICK_MENU_ACTIVE = false;
let menu_json = app.get_menu_selections(); let menu_json = app.get_menu_selections();
set_menu_from_json(&menu_json); set_menu_from_json(&menu_json);
@ -202,7 +206,7 @@ pub fn handle_final_input_mapping(
.then(|| { .then(|| {
received_input = true; received_input = true;
// Leave menu. // Leave menu.
*VISUAL_FRAME_COUNTER_SHOULD_COUNT.lock() = true; frame_counter::start_counting(*MENU_CLOSE_FRAME_COUNTER);
QUICK_MENU_ACTIVE = false; QUICK_MENU_ACTIVE = false;
let menu_json = app.get_menu_selections(); let menu_json = app.get_menu_selections();
set_menu_from_json(&menu_json); set_menu_from_json(&menu_json);

View file

@ -6,7 +6,7 @@ use crate::is_operation_cpu;
use crate::training::frame_counter; use crate::training::frame_counter;
use crate::training::handle_add_limit; use crate::training::handle_add_limit;
static mut BUFF_DELAY_COUNTER: usize = 0; use once_cell::sync::Lazy;
static mut BUFF_REMAINING_PLAYER: i32 = 0; static mut BUFF_REMAINING_PLAYER: i32 = 0;
static mut BUFF_REMAINING_CPU: i32 = 0; static mut BUFF_REMAINING_CPU: i32 = 0;
@ -14,11 +14,8 @@ static mut BUFF_REMAINING_CPU: i32 = 0;
static mut IS_BUFFING_PLAYER: bool = false; static mut IS_BUFFING_PLAYER: bool = false;
static mut IS_BUFFING_CPU: bool = false; static mut IS_BUFFING_CPU: bool = false;
pub fn init() { static BUFF_DELAY_COUNTER: Lazy<usize> =
unsafe { Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
BUFF_DELAY_COUNTER = frame_counter::register_counter();
}
}
pub unsafe fn restart_buff(module_accessor: &mut app::BattleObjectModuleAccessor) { pub unsafe fn restart_buff(module_accessor: &mut app::BattleObjectModuleAccessor) {
if is_operation_cpu(module_accessor) { if is_operation_cpu(module_accessor) {
@ -107,7 +104,7 @@ unsafe fn buff_hero(module_accessor: &mut app::BattleObjectModuleAccessor, statu
} }
if get_buff_rem(module_accessor) <= 0 { if get_buff_rem(module_accessor) <= 0 {
// If there are no buffs selected/left, we're done // If there are no buffs selected/left, we're done
if frame_counter::should_delay(3_u32, BUFF_DELAY_COUNTER) { if frame_counter::should_delay(3_u32, *BUFF_DELAY_COUNTER) {
// Need to wait 3 frames to make sure we stop the spell SFX, since it's a bit delayed // Need to wait 3 frames to make sure we stop the spell SFX, since it's a bit delayed
return false; return false;
} }
@ -160,7 +157,7 @@ unsafe fn buff_cloud(module_accessor: &mut app::BattleObjectModuleAccessor) -> b
start_buff(module_accessor); start_buff(module_accessor);
handle_add_limit(100.0, module_accessor, 0); handle_add_limit(100.0, module_accessor, 0);
} }
if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) { if frame_counter::should_delay(2_u32, *BUFF_DELAY_COUNTER) {
// Need to wait 2 frames to make sure we stop the limit SFX, since it's a bit delayed // Need to wait 2 frames to make sure we stop the limit SFX, since it's a bit delayed
return false; return false;
} }
@ -175,7 +172,7 @@ unsafe fn buff_joker(module_accessor: &mut app::BattleObjectModuleAccessor) -> b
// Strangely, this doesn't actually matter and works for both fighters // Strangely, this doesn't actually matter and works for both fighters
app::FighterSpecializer_Jack::add_rebel_gauge(module_accessor, entry_id, 120.0); app::FighterSpecializer_Jack::add_rebel_gauge(module_accessor, entry_id, 120.0);
} }
if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) { if frame_counter::should_delay(2_u32, *BUFF_DELAY_COUNTER) {
// Need to wait 2 frames to make sure we stop the voice call, since it's a bit delayed // Need to wait 2 frames to make sure we stop the voice call, since it's a bit delayed
return false; return false;
} }
@ -192,7 +189,7 @@ unsafe fn buff_mac(module_accessor: &mut app::BattleObjectModuleAccessor) -> boo
*FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_FLOAT_KO_GAGE, *FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_FLOAT_KO_GAGE,
); );
} }
if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) { if frame_counter::should_delay(2_u32, *BUFF_DELAY_COUNTER) {
// Need to wait 2 frames to make sure we stop the KO sound, since it's a bit delayed // Need to wait 2 frames to make sure we stop the KO sound, since it's a bit delayed
return false; return false;
} }
@ -242,7 +239,7 @@ unsafe fn buff_shulk(module_accessor: &mut app::BattleObjectModuleAccessor, stat
start_buff(module_accessor); start_buff(module_accessor);
let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0); let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0);
if prev_status_kind == FIGHTER_SHULK_STATUS_KIND_SPECIAL_N_ACTION { if prev_status_kind == FIGHTER_SHULK_STATUS_KIND_SPECIAL_N_ACTION {
if frame_counter::should_delay(3_u32, BUFF_DELAY_COUNTER) { if frame_counter::should_delay(3_u32, *BUFF_DELAY_COUNTER) {
// Need to continue to be buffing to make sure we stop "JUMP!" voice line // Need to continue to be buffing to make sure we stop "JUMP!" voice line
return false; return false;
} }

View file

@ -5,6 +5,8 @@ use crate::common::consts::FighterId;
use crate::common::*; use crate::common::*;
use crate::training::*; use crate::training::*;
use once_cell::sync::Lazy;
pub static mut FRAME_ADVANTAGE: i32 = 0; pub static mut FRAME_ADVANTAGE: i32 = 0;
static mut PLAYER_ACTIONABLE: bool = false; static mut PLAYER_ACTIONABLE: bool = false;
static mut CPU_ACTIONABLE: bool = false; static mut CPU_ACTIONABLE: bool = false;
@ -12,13 +14,8 @@ static mut PLAYER_ACTIVE_FRAME: u32 = 0;
static mut CPU_ACTIVE_FRAME: u32 = 0; static mut CPU_ACTIVE_FRAME: u32 = 0;
static mut FRAME_ADVANTAGE_CHECK: bool = false; static mut FRAME_ADVANTAGE_CHECK: bool = false;
static mut FRAME_COUNTER_INDEX: usize = 0; static FRAME_COUNTER_INDEX: Lazy<usize> =
Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
pub fn init() {
unsafe {
FRAME_COUNTER_INDEX = frame_counter::register_counter();
}
}
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); let prev_status = StatusModule::prev_status_kind(module_accessor, 0);
@ -105,7 +102,7 @@ pub unsafe fn is_enable_transition_term(
.any(|actionable_transition| *actionable_transition == transition_term)) .any(|actionable_transition| *actionable_transition == transition_term))
|| (CancelModule::is_enable_cancel(module_accessor))) || (CancelModule::is_enable_cancel(module_accessor)))
{ {
PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX); PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(*FRAME_COUNTER_INDEX);
PLAYER_ACTIONABLE = true; PLAYER_ACTIONABLE = true;
// if both are now active // if both are now active
@ -117,7 +114,7 @@ pub unsafe fn is_enable_transition_term(
); );
} }
frame_counter::stop_counting(FRAME_COUNTER_INDEX); frame_counter::stop_counting(*FRAME_COUNTER_INDEX);
FRAME_ADVANTAGE_CHECK = false; FRAME_ADVANTAGE_CHECK = false;
} }
} }
@ -141,11 +138,11 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
// the frame the fighter *becomes* actionable // the frame the fighter *becomes* actionable
if !CPU_ACTIONABLE && is_actionable(cpu_module_accessor) { if !CPU_ACTIONABLE && is_actionable(cpu_module_accessor) {
CPU_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX); CPU_ACTIVE_FRAME = frame_counter::get_frame_count(*FRAME_COUNTER_INDEX);
} }
if !PLAYER_ACTIONABLE && is_actionable(player_module_accessor) { if !PLAYER_ACTIONABLE && is_actionable(player_module_accessor) {
PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX); PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(*FRAME_COUNTER_INDEX);
} }
CPU_ACTIONABLE = is_actionable(cpu_module_accessor); CPU_ACTIONABLE = is_actionable(cpu_module_accessor);
@ -154,8 +151,8 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
// if neither are active // if neither are active
if !CPU_ACTIONABLE && !PLAYER_ACTIONABLE { if !CPU_ACTIONABLE && !PLAYER_ACTIONABLE {
if !FRAME_ADVANTAGE_CHECK { if !FRAME_ADVANTAGE_CHECK {
frame_counter::reset_frame_count(FRAME_COUNTER_INDEX); frame_counter::reset_frame_count(*FRAME_COUNTER_INDEX);
frame_counter::start_counting(FRAME_COUNTER_INDEX); frame_counter::start_counting(*FRAME_COUNTER_INDEX);
} }
FRAME_ADVANTAGE_CHECK = true; FRAME_ADVANTAGE_CHECK = true;
} }
@ -166,7 +163,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
update_frame_advantage((CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32); update_frame_advantage((CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32);
} }
frame_counter::stop_counting(FRAME_COUNTER_INDEX); frame_counter::stop_counting(*FRAME_COUNTER_INDEX);
FRAME_ADVANTAGE_CHECK = false; FRAME_ADVANTAGE_CHECK = false;
} }
} }

View file

@ -5,7 +5,7 @@ use smash::phx::{Hash40, Vector3f};
use crate::common::*; use crate::common::*;
use crate::training::{frame_counter, input_record}; use crate::training::{frame_counter, input_record};
static mut FRAME_COUNTER: usize = 0; use once_cell::sync::Lazy;
// The current fastfall delay // The current fastfall delay
static mut DELAY: u32 = 0; static mut DELAY: u32 = 0;
@ -22,11 +22,8 @@ pub fn roll_fast_fall() {
} }
} }
pub fn init() { static FRAME_COUNTER_INDEX: Lazy<usize> =
unsafe { Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
FRAME_COUNTER = frame_counter::register_counter();
}
}
pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) { pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
if !should_fast_fall() { if !should_fast_fall() {
@ -46,7 +43,7 @@ pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccesso
if !is_falling(module_accessor) { if !is_falling(module_accessor) {
// Roll FF delay // Roll FF delay
DELAY = MENU.fast_fall_delay.get_random().into_delay(); DELAY = MENU.fast_fall_delay.get_random().into_delay();
frame_counter::full_reset(FRAME_COUNTER); frame_counter::full_reset(*FRAME_COUNTER_INDEX);
return; return;
} }
@ -60,7 +57,7 @@ pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccesso
} }
// Check delay // Check delay
if frame_counter::should_delay(DELAY, FRAME_COUNTER) { if frame_counter::should_delay(DELAY, *FRAME_COUNTER_INDEX) {
return; return;
} }

View file

@ -1,42 +1,49 @@
static mut SHOULD_COUNT: Vec<bool> = vec![]; #[derive(PartialEq, Eq)]
static mut NO_RESET: Vec<bool> = vec![]; pub enum FrameCounterType {
static mut COUNTERS: Vec<u32> = vec![]; InGame,
// "Reset" occurs when we enter training mode and when we run L+R+A or save state load
// Some frame counters need in-game frames that do not reset when this occurs
InGameNoReset,
Real,
}
fn _register_counter(no_reset: bool) -> usize { pub struct FrameCounter {
count: u32,
should_count: bool,
counter_type: FrameCounterType,
}
static mut COUNTERS: Vec<FrameCounter> = vec![];
pub fn register_counter(counter_type: FrameCounterType) -> usize {
unsafe { unsafe {
let index = COUNTERS.len(); let index = COUNTERS.len();
COUNTERS.push(0); COUNTERS.push(FrameCounter {
SHOULD_COUNT.push(false); count: 0,
NO_RESET.push(no_reset); should_count: false,
counter_type,
});
index index
} }
} }
pub fn _register_counter_no_reset() -> usize {
_register_counter(true)
}
pub fn register_counter() -> usize {
_register_counter(false)
}
pub fn start_counting(index: usize) { pub fn start_counting(index: usize) {
unsafe { unsafe {
SHOULD_COUNT[index] = true; COUNTERS[index].should_count = true;
} }
} }
pub fn stop_counting(index: usize) { pub fn stop_counting(index: usize) {
unsafe { unsafe {
SHOULD_COUNT[index] = false; COUNTERS[index].should_count = false;
} }
} }
pub fn reset_frame_count(index: usize) { pub fn reset_frame_count(index: usize) {
unsafe { unsafe {
COUNTERS[index] = 0; COUNTERS[index].count = 0;
} }
} }
@ -68,19 +75,33 @@ pub fn should_delay(delay: u32, index: usize) -> bool {
} }
pub fn get_frame_count(index: usize) -> u32 { pub fn get_frame_count(index: usize) -> u32 {
unsafe { COUNTERS[index] } unsafe { COUNTERS[index].count }
} }
pub fn tick_idx(index: usize) { pub fn tick_idx(index: usize) {
unsafe { unsafe {
COUNTERS[index] += 1; COUNTERS[index].count += 1;
} }
} }
pub fn tick() { pub fn tick_ingame() {
unsafe { unsafe {
for (index, _frame) in COUNTERS.iter().enumerate() { for (index, counter) in COUNTERS.iter().enumerate() {
if !SHOULD_COUNT[index] { if !counter.should_count || counter.counter_type == FrameCounterType::Real {
continue;
}
tick_idx(index);
}
}
}
pub fn tick_real() {
unsafe {
for (index, counter) in COUNTERS.iter().enumerate() {
if !counter.should_count
|| (counter.counter_type == FrameCounterType::InGame
|| counter.counter_type == FrameCounterType::InGameNoReset)
{
continue; continue;
} }
tick_idx(index); tick_idx(index);
@ -90,8 +111,8 @@ pub fn tick() {
pub fn reset_all() { pub fn reset_all() {
unsafe { unsafe {
for (index, _frame) in COUNTERS.iter().enumerate() { for (index, counter) in COUNTERS.iter().enumerate() {
if NO_RESET[index] { if counter.counter_type != FrameCounterType::InGame {
continue; continue;
} }
full_reset(index); full_reset(index);

View file

@ -5,22 +5,20 @@ use crate::common::consts::*;
use crate::common::*; use crate::common::*;
use crate::training::{frame_counter, input_record, mash}; use crate::training::{frame_counter, input_record, mash};
use once_cell::sync::Lazy;
const NOT_SET: u32 = 9001; const NOT_SET: u32 = 9001;
static mut LEDGE_DELAY: u32 = NOT_SET; static mut LEDGE_DELAY: u32 = NOT_SET;
static mut LEDGE_DELAY_COUNTER: usize = 0;
static mut LEDGE_CASE: LedgeOption = LedgeOption::empty(); static mut LEDGE_CASE: LedgeOption = LedgeOption::empty();
pub fn init() { static LEDGE_DELAY_COUNTER: Lazy<usize> =
unsafe { Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
LEDGE_DELAY_COUNTER = frame_counter::register_counter();
}
}
pub fn reset_ledge_delay() { pub fn reset_ledge_delay() {
unsafe { unsafe {
if LEDGE_DELAY != NOT_SET { if LEDGE_DELAY != NOT_SET {
LEDGE_DELAY = NOT_SET; LEDGE_DELAY = NOT_SET;
frame_counter::full_reset(LEDGE_DELAY_COUNTER); frame_counter::full_reset(*LEDGE_DELAY_COUNTER);
} }
} }
} }
@ -154,7 +152,7 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor
return; return;
} }
if frame_counter::should_delay(LEDGE_DELAY, LEDGE_DELAY_COUNTER) { if frame_counter::should_delay(LEDGE_DELAY, *LEDGE_DELAY_COUNTER) {
// Not yet time to perform the ledge action // Not yet time to perform the ledge action
return; return;
} }
@ -189,7 +187,7 @@ pub unsafe fn is_enable_transition_term(
// Disallow the default cliff-climb if we are waiting or we didn't get up during a recording // Disallow the default cliff-climb if we are waiting or we didn't get up during a recording
if term == *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB if term == *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB
&& ((LEDGE_CASE == LedgeOption::WAIT && ((LEDGE_CASE == LedgeOption::WAIT
|| frame_counter::get_frame_count(LEDGE_DELAY_COUNTER) < LEDGE_DELAY) || frame_counter::get_frame_count(*LEDGE_DELAY_COUNTER) < LEDGE_DELAY)
|| (LEDGE_CASE.is_playback() && !input_record::is_playback())) || (LEDGE_CASE.is_playback() && !input_record::is_playback()))
{ {
return Some(false); return Some(false);

View file

@ -11,6 +11,8 @@ use crate::training::input_record;
use crate::training::shield; use crate::training::shield;
use crate::training::{attack_angle, save_states}; use crate::training::{attack_angle, save_states};
use once_cell::sync::Lazy;
const DISTANCE_CLOSE_THRESHOLD: f32 = 16.0; const DISTANCE_CLOSE_THRESHOLD: f32 = 16.0;
const DISTANCE_MID_THRESHOLD: f32 = 37.0; const DISTANCE_MID_THRESHOLD: f32 = 37.0;
const DISTANCE_FAR_THRESHOLD: f32 = 64.0; const DISTANCE_FAR_THRESHOLD: f32 = 64.0;
@ -20,9 +22,11 @@ static mut QUEUE: Vec<Action> = vec![];
static mut FALLING_AERIAL: bool = false; static mut FALLING_AERIAL: bool = false;
static mut AERIAL_DELAY_COUNTER: usize = 0;
static mut AERIAL_DELAY: u32 = 0; static mut AERIAL_DELAY: u32 = 0;
static AERIAL_DELAY_COUNTER: Lazy<usize> =
Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
// Track if we're about to do another command flag cat run in the same frame for a dash or dash attack // Track if we're about to do another command flag cat run in the same frame for a dash or dash attack
static mut IS_TRANSITIONING_DASH: bool = false; static mut IS_TRANSITIONING_DASH: bool = false;
@ -138,7 +142,7 @@ pub fn reset() {
shield::suspend_shield(get_current_buffer()); shield::suspend_shield(get_current_buffer());
unsafe { unsafe {
frame_counter::full_reset(AERIAL_DELAY_COUNTER); frame_counter::full_reset(*AERIAL_DELAY_COUNTER);
AERIAL_DELAY = 0; AERIAL_DELAY = 0;
} }
} }
@ -577,12 +581,6 @@ unsafe fn get_aerial_flag(
flag flag
} }
pub fn init() {
unsafe {
AERIAL_DELAY_COUNTER = frame_counter::register_counter();
}
}
fn roll_aerial_delay(action: Action) { fn roll_aerial_delay(action: Action) {
if !shield::is_aerial(action) { if !shield::is_aerial(action) {
return; return;
@ -609,7 +607,7 @@ fn should_delay_aerial(module_accessor: &mut app::BattleObjectModuleAccessor) ->
return true; return true;
} }
frame_counter::should_delay(AERIAL_DELAY, AERIAL_DELAY_COUNTER) frame_counter::should_delay(AERIAL_DELAY, *AERIAL_DELAY_COUNTER)
} }
} }

View file

@ -676,7 +676,7 @@ static OPCF_OFFSET: usize = 0x06b7fdc;
// One instruction after the CPU Control function completes // One instruction after the CPU Control function completes
#[skyline::hook(offset = OPCF_OFFSET, inline)] #[skyline::hook(offset = OPCF_OFFSET, inline)]
unsafe fn handle_once_per_cpu_frame(_ctx: &mut InlineCtx) { unsafe fn handle_once_per_cpu_frame(_ctx: &mut InlineCtx) {
frame_counter::tick(); frame_counter::tick_ingame();
// Tick notifications // Tick notifications
let queue = &mut ui::notifications::QUEUE; let queue = &mut ui::notifications::QUEUE;
let notification = queue.first(); let notification = queue.first();
@ -806,15 +806,7 @@ pub fn training_mods() {
handle_final_input_mapping handle_final_input_mapping
); );
combo::init();
shield::init();
fast_fall::init();
mash::init();
ledge::init();
throw::init();
buff::init();
items::init(); items::init();
tech::init();
input_record::init(); input_record::init();
ui::init(); ui::init();
} }

View file

@ -10,6 +10,8 @@ use crate::common::consts::*;
use crate::common::*; use crate::common::*;
use crate::training::{frame_counter, input_record, mash, save_states}; use crate::training::{frame_counter, input_record, mash, save_states};
use once_cell::sync::Lazy;
// How many hits to hold shield until picking an Out Of Shield option // How many hits to hold shield until picking an Out Of Shield option
static mut MULTI_HIT_OFFSET: u32 = 0; static mut MULTI_HIT_OFFSET: u32 = 0;
@ -19,16 +21,11 @@ static mut SHIELD_DELAY: u32 = 0;
// Used to only decrease once per shieldstun change // Used to only decrease once per shieldstun change
static mut WAS_IN_SHIELDSTUN: bool = false; static mut WAS_IN_SHIELDSTUN: bool = false;
static mut REACTION_INDEX: usize = 0;
// For how many frames should the shield hold be overwritten // For how many frames should the shield hold be overwritten
static mut SUSPEND_SHIELD: bool = false; static mut SUSPEND_SHIELD: bool = false;
pub fn init() { static REACTION_COUNTER_INDEX: Lazy<usize> =
unsafe { Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
REACTION_INDEX = frame_counter::register_counter();
}
}
// Toggle for shield decay // Toggle for shield decay
static mut SHIELD_DECAY: bool = false; static mut SHIELD_DECAY: bool = false;
@ -236,11 +233,11 @@ unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) {
} }
if !is_shielding(module_accessor) { if !is_shielding(module_accessor) {
frame_counter::full_reset(REACTION_INDEX); frame_counter::full_reset(*REACTION_COUNTER_INDEX);
return; return;
} }
if frame_counter::should_delay(SHIELD_DELAY, REACTION_INDEX) { if frame_counter::should_delay(SHIELD_DELAY, *REACTION_COUNTER_INDEX) {
return; return;
} }

View file

@ -8,15 +8,13 @@ use crate::common::consts::*;
use crate::common::*; use crate::common::*;
use crate::training::{frame_counter, mash}; use crate::training::{frame_counter, mash};
use once_cell::sync::Lazy;
static mut TECH_ROLL_DIRECTION: Direction = Direction::empty(); static mut TECH_ROLL_DIRECTION: Direction = Direction::empty();
static mut MISS_TECH_ROLL_DIRECTION: Direction = Direction::empty(); static mut MISS_TECH_ROLL_DIRECTION: Direction = Direction::empty();
static mut FRAME_COUNTER: usize = 0;
pub fn init() { static FRAME_COUNTER: Lazy<usize> =
unsafe { Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
FRAME_COUNTER = frame_counter::register_counter();
}
}
unsafe fn is_enable_passive(module_accessor: &mut BattleObjectModuleAccessor) -> bool { unsafe fn is_enable_passive(module_accessor: &mut BattleObjectModuleAccessor) -> bool {
let fighter = get_fighter_common_from_accessor(module_accessor); let fighter = get_fighter_common_from_accessor(module_accessor);
@ -237,7 +235,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
} else if status == *FIGHTER_STATUS_KIND_LAY_DOWN { } else if status == *FIGHTER_STATUS_KIND_LAY_DOWN {
// Snake down throw // Snake down throw
let lockout_time = get_snake_laydown_lockout_time(module_accessor); let lockout_time = get_snake_laydown_lockout_time(module_accessor);
if frame_counter::should_delay(lockout_time, FRAME_COUNTER) { if frame_counter::should_delay(lockout_time, *FRAME_COUNTER) {
return; return;
}; };
requested_status = match MENU.miss_tech_state.get_random() { requested_status = match MENU.miss_tech_state.get_random() {
@ -264,7 +262,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
}; };
} else { } else {
// Not in a tech situation, make sure the snake dthrow counter is fully reset. // Not in a tech situation, make sure the snake dthrow counter is fully reset.
frame_counter::full_reset(FRAME_COUNTER); frame_counter::full_reset(*FRAME_COUNTER);
}; };
if requested_status != 0 { if requested_status != 0 {

View file

@ -6,20 +6,17 @@ use crate::common::*;
use crate::training::frame_counter; use crate::training::frame_counter;
use crate::training::mash; use crate::training::mash;
use once_cell::sync::Lazy;
const NOT_SET: u32 = 9001; const NOT_SET: u32 = 9001;
static mut THROW_DELAY: u32 = NOT_SET; static mut THROW_DELAY: u32 = NOT_SET;
static mut THROW_DELAY_COUNTER: usize = 0; static mut PUMMEL_DELAY: u32 = NOT_SET;
static mut THROW_CASE: ThrowOption = ThrowOption::empty(); static mut THROW_CASE: ThrowOption = ThrowOption::empty();
static mut PUMMEL_DELAY: u32 = NOT_SET; static THROW_DELAY_COUNTER: Lazy<usize> =
static mut PUMMEL_DELAY_COUNTER: usize = 0; Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
static PUMMEL_DELAY_COUNTER: Lazy<usize> =
pub fn init() { Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
unsafe {
THROW_DELAY_COUNTER = frame_counter::register_counter();
PUMMEL_DELAY_COUNTER = frame_counter::register_counter();
}
}
// Rolling Throw Delays and Pummel Delays separately // Rolling Throw Delays and Pummel Delays separately
@ -27,7 +24,7 @@ pub fn reset_throw_delay() {
unsafe { unsafe {
if THROW_DELAY != NOT_SET { if THROW_DELAY != NOT_SET {
THROW_DELAY = NOT_SET; THROW_DELAY = NOT_SET;
frame_counter::full_reset(THROW_DELAY_COUNTER); frame_counter::full_reset(*THROW_DELAY_COUNTER);
} }
} }
} }
@ -36,7 +33,7 @@ pub fn reset_pummel_delay() {
unsafe { unsafe {
if PUMMEL_DELAY != NOT_SET { if PUMMEL_DELAY != NOT_SET {
PUMMEL_DELAY = NOT_SET; PUMMEL_DELAY = NOT_SET;
frame_counter::full_reset(PUMMEL_DELAY_COUNTER); frame_counter::full_reset(*PUMMEL_DELAY_COUNTER);
} }
} }
} }
@ -120,9 +117,9 @@ pub unsafe fn get_command_flag_throw_direction(
return 0; return 0;
} }
if frame_counter::should_delay(THROW_DELAY, THROW_DELAY_COUNTER) { if frame_counter::should_delay(THROW_DELAY, *THROW_DELAY_COUNTER) {
// Not yet time to perform the throw action // Not yet time to perform the throw action
if frame_counter::should_delay(PUMMEL_DELAY, PUMMEL_DELAY_COUNTER) { if frame_counter::should_delay(PUMMEL_DELAY, *PUMMEL_DELAY_COUNTER) {
// And not yet time to pummel either, so don't do anything // And not yet time to pummel either, so don't do anything
return 0; return 0;
} }

View file

@ -6,9 +6,8 @@ use smash::ui2d::{SmashPane, SmashTextBox};
use training_mod_tui::gauge::GaugeState; use training_mod_tui::gauge::GaugeState;
use training_mod_tui::{App, AppPage, NUM_LISTS}; use training_mod_tui::{App, AppPage, NUM_LISTS};
use crate::common::menu::{ use crate::common::menu::{MENU_CLOSE_FRAME_COUNTER, MENU_CLOSE_WAIT_FRAMES};
MENU_CLOSE_WAIT_FRAMES, VISUAL_FRAME_COUNTER, VISUAL_FRAME_COUNTER_SHOULD_COUNT, use crate::training::frame_counter;
};
use crate::{common, common::menu::QUICK_MENU_ACTIVE, input::*}; use crate::{common, common::menu::QUICK_MENU_ACTIVE, input::*};
use super::fade_out; use super::fade_out;
@ -353,12 +352,6 @@ unsafe fn render_slider_page(app: &App, root_pane: &Pane) {
} }
pub unsafe fn draw(root_pane: &Pane) { pub unsafe fn draw(root_pane: &Pane) {
if *VISUAL_FRAME_COUNTER_SHOULD_COUNT.data_ptr() {
*VISUAL_FRAME_COUNTER.lock() += 1;
} else {
*VISUAL_FRAME_COUNTER.lock() = 0;
}
// Determine if we're in the menu by seeing if the "help" footer has // Determine if we're in the menu by seeing if the "help" footer has
// begun moving upward. It starts at -80 and moves to 0 over 10 frames // begun moving upward. It starts at -80 and moves to 0 over 10 frames
// in info_training_in_menu.bflan // in info_training_in_menu.bflan
@ -381,7 +374,7 @@ pub unsafe fn draw(root_pane: &Pane) {
let overall_parent_pane = root_pane.find_pane_by_name_recursive("TrModMenu").unwrap(); let overall_parent_pane = root_pane.find_pane_by_name_recursive("TrModMenu").unwrap();
overall_parent_pane.set_visible(true); overall_parent_pane.set_visible(true);
let menu_close_wait_frame = *VISUAL_FRAME_COUNTER.data_ptr(); let menu_close_wait_frame = frame_counter::get_frame_count(*MENU_CLOSE_FRAME_COUNTER);
if QUICK_MENU_ACTIVE { if QUICK_MENU_ACTIVE {
overall_parent_pane.alpha = 255; overall_parent_pane.alpha = 255;
overall_parent_pane.global_alpha = 255; overall_parent_pane.global_alpha = 255;

View file

@ -4,9 +4,12 @@ use sarc::SarcFile;
use skyline::nn::ui2d::*; use skyline::nn::ui2d::*;
use training_mod_consts::{OnOff, MENU}; use training_mod_consts::{OnOff, MENU};
use crate::common::{is_ready_go, is_training_mode, menu::QUICK_MENU_ACTIVE};
#[cfg(feature = "layout_arc_from_file")] #[cfg(feature = "layout_arc_from_file")]
use crate::consts::LAYOUT_ARC_PATH; use crate::consts::LAYOUT_ARC_PATH;
use crate::{
common::{is_ready_go, is_training_mode, menu::QUICK_MENU_ACTIVE},
training::frame_counter,
};
mod damage; mod damage;
mod display; mod display;
@ -56,6 +59,7 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
damage::draw(root_pane, &layout_name); damage::draw(root_pane, &layout_name);
if layout_name == "info_training" { if layout_name == "info_training" {
frame_counter::tick_real();
display::draw(root_pane); display::draw(root_pane);
menu::draw(root_pane); menu::draw(root_pane);
} }