From e66550904203b36bccb2ad6e35d68ab1d2aef61f Mon Sep 17 00:00:00 2001 From: sidschingis Date: Tue, 30 Jun 2020 01:00:01 +0200 Subject: [PATCH] Add Fast Fall Frame Delay + OOS Reaction Frame Delay (#105) * Fix Full Hop Rising Aerials * Add Fast Fall Delay * Fix Frame Counter Reset Fixed not resetting if landing before being able to fastfall * Update Frame Counter Moved delay logic to frame counter module Update unsafe blocks * Add OOS Reaction Time --- TrainingModpackOverlay | 2 +- src/common/consts.rs | 4 ++- src/common/mod.rs | 4 ++- src/training/fast_fall.rs | 17 +++++++++- src/training/frame_counter.rs | 61 +++++++++++++++++++++++++++-------- src/training/mash.rs | 6 ++++ src/training/mod.rs | 1 + src/training/shield.rs | 9 +++++- 8 files changed, 86 insertions(+), 18 deletions(-) diff --git a/TrainingModpackOverlay b/TrainingModpackOverlay index 3e021a3..99b5ab2 160000 --- a/TrainingModpackOverlay +++ b/TrainingModpackOverlay @@ -1 +1 @@ -Subproject commit 3e021a300d05516600fbee9c11eefa539ecfcdea +Subproject commit 99b5ab29e4a2eda39a8f71e10a084418121f0019 diff --git a/src/common/consts.rs b/src/common/consts.rs index ac13fe4..7182fb8 100644 --- a/src/common/consts.rs +++ b/src/common/consts.rs @@ -279,9 +279,11 @@ pub struct TrainingModpackMenu { pub mash_state: Mash, pub shield_state: Shield, pub defensive_state: Defensive, - pub oos_offset: i32, + pub oos_offset: u32, + pub reaction_time: u32, pub mash_in_neutral: OnOff, pub fast_fall: OnOff, + pub fast_fall_delay: u32, pub falling_aerials: OnOff, pub full_hop: OnOff, } diff --git a/src/common/mod.rs b/src/common/mod.rs index 5729773..ed345c7 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -15,8 +15,10 @@ pub static mut MENU_STRUCT: consts::TrainingModpackMenu = consts::TrainingModpac shield_state: Shield::None, defensive_state: Defensive::Random, oos_offset: 0, + reaction_time: 0, mash_in_neutral: OnOff::Off, fast_fall: OnOff::Off, + fast_fall_delay: 0, falling_aerials: OnOff::Off, full_hop: OnOff::Off, }; @@ -77,7 +79,7 @@ pub unsafe fn is_in_hitstun(module_accessor: &mut app::BattleObjectModuleAccesso } pub fn is_shielding(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool { - unsafe{ + unsafe { let status_kind = StatusModule::status_kind(module_accessor) as i32; (*FIGHTER_STATUS_KIND_GUARD_ON..=*FIGHTER_STATUS_KIND_GUARD_DAMAGE).contains(&status_kind) } diff --git a/src/training/fast_fall.rs b/src/training/fast_fall.rs index 7dc0c31..4ce1d1b 100644 --- a/src/training/fast_fall.rs +++ b/src/training/fast_fall.rs @@ -1,9 +1,18 @@ use crate::common::consts::OnOff; use crate::common::*; +use crate::training::frame_counter; use smash::app::{self, lua_bind::*}; use smash::lib::lua_const::*; use smash::phx::{Hash40, Vector3f}; +static mut FRAME_COUNTER: usize = 0; + +pub fn init() { + unsafe { + FRAME_COUNTER = frame_counter::register_counter(); + } +} + pub unsafe fn get_command_flag_cat( module_accessor: &mut app::BattleObjectModuleAccessor, category: i32, @@ -31,6 +40,7 @@ pub unsafe fn get_command_flag_cat( // Need to be falling if !is_falling(module_accessor) { + frame_counter::full_reset(FRAME_COUNTER); return; } @@ -44,6 +54,11 @@ pub unsafe fn get_command_flag_cat( return; } + // Check delay + if frame_counter::should_delay(MENU.fast_fall_delay,FRAME_COUNTER) { + return; + } + // Set Fast Fall Flag WorkModule::set_flag( module_accessor, @@ -54,7 +69,7 @@ pub unsafe fn get_command_flag_cat( add_spark_effect(module_accessor); } -pub fn is_falling(module_accessor: &mut app::BattleObjectModuleAccessor)->bool { +pub fn is_falling(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { unsafe { let y_speed = KineticModule::get_sum_speed_y(module_accessor, *FIGHTER_KINETIC_ENERGY_ID_GRAVITY); diff --git a/src/training/frame_counter.rs b/src/training/frame_counter.rs index 60080ff..277d7d6 100644 --- a/src/training/frame_counter.rs +++ b/src/training/frame_counter.rs @@ -4,29 +4,64 @@ use crate::training::*; static mut SHOULD_COUNT: Vec = vec![]; static mut COUNTERS: Vec = vec![]; -pub unsafe fn register_counter() -> usize { - let index = COUNTERS.len(); +pub fn register_counter() -> usize { + unsafe { + let index = COUNTERS.len(); - COUNTERS.push(0); - SHOULD_COUNT.push(false); + COUNTERS.push(0); + SHOULD_COUNT.push(false); - index + index + } } -pub unsafe fn start_counting(index: usize) { - SHOULD_COUNT[index] = true; +pub fn start_counting(index: usize) { + unsafe { + SHOULD_COUNT[index] = true; + } } -pub unsafe fn stop_counting(index: usize) { - SHOULD_COUNT[index] = false; +pub fn stop_counting(index: usize) { + unsafe { + SHOULD_COUNT[index] = false; + } } -pub unsafe fn reset_frame_count(index: usize) { - COUNTERS[index] = 0; +pub fn reset_frame_count(index: usize) { + unsafe { + COUNTERS[index] = 0; + } } -pub unsafe fn get_frame_count(index: usize) -> u32 { - COUNTERS[index] +pub fn full_reset(index: usize) { + frame_counter::reset_frame_count(index); + frame_counter::stop_counting(index); +} + +/** + * Returns true until a certain number of frames have passed + */ +pub fn should_delay(delay: u32, index: usize) -> bool { + if delay == 0 { + return false; + } + + let current_frame = frame_counter::get_frame_count(index); + + if current_frame == 0 { + frame_counter::start_counting(index); + } + + if current_frame >= delay { + full_reset(index); + return false; + } + + return true; +} + +pub fn get_frame_count(index: usize) -> u32 { + unsafe { COUNTERS[index] } } pub unsafe fn tick() { diff --git a/src/training/mash.rs b/src/training/mash.rs index d2dadbd..5159162 100644 --- a/src/training/mash.rs +++ b/src/training/mash.rs @@ -270,6 +270,12 @@ unsafe fn get_aerial_flag( return 0; } + // Delay attack until we are airborne to get a full hop + if MENU.full_hop == OnOff::On { + buffer_action(Mash::Attack); + return flag; + } + transition_flag = 0; } else { transition_flag = *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ATTACK_AIR; diff --git a/src/training/mod.rs b/src/training/mod.rs index 7a99733..f8bd29b 100644 --- a/src/training/mod.rs +++ b/src/training/mod.rs @@ -225,6 +225,7 @@ pub fn training_mods() { combo::init(); shield::init(); + fast_fall::init(); // // Input recorder // SaltySD_function_replace_sym( diff --git a/src/training/shield.rs b/src/training/shield.rs index 5a65ba8..27c25c9 100644 --- a/src/training/shield.rs +++ b/src/training/shield.rs @@ -11,11 +11,12 @@ use smash::lib::L2CValue; use smash::lua2cpp::L2CFighterCommon; // How many hits to hold shield until picking an Out Of Shield option -static mut MULTI_HIT_OFFSET: i32 = unsafe { MENU.oos_offset }; +static mut MULTI_HIT_OFFSET: u32 = unsafe { MENU.oos_offset }; // Used to only decrease once per shieldstun change static mut WAS_IN_SHIELDSTUN: bool = false; static mut FRAME_COUNTER_INDEX: usize = 0; +static mut REACTION_INDEX: usize = 0; // For how many frames should the shield hold be overwritten static mut SHIELD_SUSPEND_FRAMES: u32 = 0; @@ -23,6 +24,7 @@ static mut SHIELD_SUSPEND_FRAMES: u32 = 0; pub fn init() { unsafe { FRAME_COUNTER_INDEX = frame_counter::register_counter(); + REACTION_INDEX = frame_counter::register_counter(); } } @@ -188,6 +190,11 @@ unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) { } if !is_shielding(module_accessor) { + frame_counter::full_reset(REACTION_INDEX); + return; + } + + if frame_counter::should_delay(MENU.reaction_time, REACTION_INDEX){ return; }