From 63a3358a0f55e542eec9d29c289e67323774e182 Mon Sep 17 00:00:00 2001 From: sidschingis Date: Sat, 27 Jun 2020 16:22:02 +0200 Subject: [PATCH] Add Frame Counter Module (#98) * Add Frame Counter Module * Allow Multiple Frame Counters * Apply Frame Counter * Add Enum For Fighter Id * Simplify Calculation * Restore Original Indentation --- src/common/consts.rs | 8 +++ src/training/combo.rs | 95 ++++++++++++++++++----------------- src/training/frame_counter.rs | 60 ++++++++++++++++++++++ src/training/mod.rs | 4 ++ 4 files changed, 122 insertions(+), 45 deletions(-) create mode 100644 src/training/frame_counter.rs diff --git a/src/common/consts.rs b/src/common/consts.rs index dde9710..890cb2d 100644 --- a/src/common/consts.rs +++ b/src/common/consts.rs @@ -277,3 +277,11 @@ pub struct TrainingModpackMenu { pub mash_in_neutral: MashInNeutral, pub fast_fall: FastFall, } + +// Fighter Ids +#[repr(i32)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum FighterId { + Player = 0, + CPU = 1, +} diff --git a/src/training/combo.rs b/src/training/combo.rs index c1c8e51..7ba0bf5 100644 --- a/src/training/combo.rs +++ b/src/training/combo.rs @@ -1,15 +1,23 @@ +use crate::common::consts::FighterId; use crate::common::FIGHTER_MANAGER_ADDR; use crate::common::*; use crate::training::*; pub static mut FRAME_ADVANTAGE: i32 = 0; -static mut FRAME_COUNTER: u64 = 0; static mut PLAYER_ACTIONABLE: bool = false; static mut CPU_ACTIONABLE: bool = false; -static mut PLAYER_ACTIVE_FRAME: u64 = 0; -static mut CPU_ACTIVE_FRAME: u64 = 0; +static mut PLAYER_ACTIVE_FRAME: u32 = 0; +static mut CPU_ACTIVE_FRAME: u32 = 0; static mut FRAME_ADVANTAGE_CHECK: bool = false; +static mut FRAME_COUNTER_INDEX: usize = 0; + +pub fn init() { + unsafe { + FRAME_COUNTER_INDEX = frame_counter::register_counter(); + } +} + 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) @@ -20,7 +28,8 @@ unsafe fn was_in_shieldstun(module_accessor: *mut app::BattleObjectModuleAccesso prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE } -unsafe fn get_module_accessor(entry_id_int: i32) -> *mut app::BattleObjectModuleAccessor { +unsafe fn get_module_accessor(fighter_id: FighterId) -> *mut app::BattleObjectModuleAccessor { + let entry_id_int = fighter_id as i32; let entry_id = app::FighterEntryID(entry_id_int); let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager); let fighter_entry = FighterManager::get_fighter_entry(mgr, entry_id) as *mut app::FighterEntry; @@ -59,53 +68,49 @@ pub unsafe fn get_command_flag_cat( let entry_id_int = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32; // do only once. - if entry_id_int == 0 { - let player_module_accessor = get_module_accessor(0); - let cpu_module_accessor = get_module_accessor(1); + if entry_id_int != (FighterId::Player as i32) { + return; + } - // Use to factor in that we should only update frame advantage if - // there's been a hit that connects - // if AttackModule::is_infliction( - // player_module_accessor, - // *COLLISION_KIND_MASK_HIT | *COLLISION_KIND_MASK_SHIELD) { + let player_module_accessor = get_module_accessor(FighterId::Player); + let cpu_module_accessor = get_module_accessor(FighterId::CPU); - // } + // Use to factor in that we should only update frame advantage if + // there's been a hit that connects + // if AttackModule::is_infliction( + // player_module_accessor, + // *COLLISION_KIND_MASK_HIT | *COLLISION_KIND_MASK_SHIELD) { - // the frame the fighter *becomes* actionable - if !CPU_ACTIONABLE && is_actionable(cpu_module_accessor) { - CPU_ACTIVE_FRAME = FRAME_COUNTER; + // the frame the fighter *becomes* actionable + if !CPU_ACTIONABLE && is_actionable(cpu_module_accessor) { + CPU_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX); + } + + if !PLAYER_ACTIONABLE && is_actionable(player_module_accessor) { + PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX); + } + + CPU_ACTIONABLE = is_actionable(cpu_module_accessor); + PLAYER_ACTIONABLE = is_actionable(player_module_accessor); + + // if neither are active + if !CPU_ACTIONABLE && !PLAYER_ACTIONABLE { + if !FRAME_ADVANTAGE_CHECK { + frame_counter::reset_frame_count(FRAME_COUNTER_INDEX); + frame_counter::start_counting(FRAME_COUNTER_INDEX); } + FRAME_ADVANTAGE_CHECK = true; + } - if !PLAYER_ACTIONABLE && is_actionable(player_module_accessor) { - PLAYER_ACTIVE_FRAME = FRAME_COUNTER; - } - - CPU_ACTIONABLE = is_actionable(cpu_module_accessor); - PLAYER_ACTIONABLE = is_actionable(player_module_accessor); - - // if neither are active - if !CPU_ACTIONABLE && !PLAYER_ACTIONABLE { - FRAME_ADVANTAGE_CHECK = true; - } - - // if both are now active - if PLAYER_ACTIONABLE && CPU_ACTIONABLE { - if FRAME_ADVANTAGE_CHECK { - if was_in_hitstun(cpu_module_accessor) || was_in_shieldstun(cpu_module_accessor) { - let frame_advantage: i64; - if PLAYER_ACTIVE_FRAME > CPU_ACTIVE_FRAME { - frame_advantage = (PLAYER_ACTIVE_FRAME - CPU_ACTIVE_FRAME) as i64 * -1; - } else { - frame_advantage = (CPU_ACTIVE_FRAME - PLAYER_ACTIVE_FRAME) as i64; - } - - FRAME_ADVANTAGE = frame_advantage as i32; - } - - FRAME_ADVANTAGE_CHECK = false; + // if both are now active + if PLAYER_ACTIONABLE && CPU_ACTIONABLE { + if FRAME_ADVANTAGE_CHECK { + if was_in_hitstun(cpu_module_accessor) || was_in_shieldstun(cpu_module_accessor) { + FRAME_ADVANTAGE = (CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32; } - } - FRAME_COUNTER += 1; + frame_counter::stop_counting(FRAME_COUNTER_INDEX); + FRAME_ADVANTAGE_CHECK = false; + } } } diff --git a/src/training/frame_counter.rs b/src/training/frame_counter.rs new file mode 100644 index 0000000..f57efa6 --- /dev/null +++ b/src/training/frame_counter.rs @@ -0,0 +1,60 @@ +use crate::common::*; +use crate::training::*; + +static mut SHOULD_COUNT: Vec = vec![]; +static mut COUNTERS: Vec = vec![]; + +pub unsafe fn register_counter() -> usize { + let index = COUNTERS.len(); + + COUNTERS.push(0); + SHOULD_COUNT.push(false); + + index +} + +pub unsafe fn start_counting(index:usize) { + SHOULD_COUNT[index] = true; +} + +pub unsafe fn stop_counting(index:usize) { + SHOULD_COUNT[index] = false; +} + +pub unsafe fn reset_frame_count(index:usize) { + COUNTERS[index] = 0; +} + +pub unsafe fn get_frame_count(index:usize) -> u32 { + COUNTERS[index] +} + +pub unsafe fn tick() { + for (index, _frame) in COUNTERS.iter().enumerate() { + if !SHOULD_COUNT[index]{ + continue; + } + COUNTERS[index] += 1; + } +} + +pub unsafe fn get_command_flag_cat( + module_accessor: &mut app::BattleObjectModuleAccessor, + category: i32, +) { + if !is_training_mode() { + return; + } + + // Only do once per frame + if category != 0 { + return; + } + + if !is_operation_cpu(module_accessor) { + return; + } + //~ + + tick(); +} diff --git a/src/training/mod.rs b/src/training/mod.rs index dfe4308..a025318 100644 --- a/src/training/mod.rs +++ b/src/training/mod.rs @@ -10,6 +10,7 @@ pub mod tech; pub mod combo; mod fast_fall; +mod frame_counter; mod ledge; mod left_stick; mod mash; @@ -55,6 +56,7 @@ pub unsafe fn handle_get_command_flag_cat( let mut flag = original!()(module_accessor, category); + frame_counter::get_command_flag_cat(module_accessor, category); combo::get_command_flag_cat(module_accessor, category); // bool replace; @@ -222,6 +224,8 @@ pub fn training_mods() { get_stick_y, ); + combo::init(); + // // Input recorder // SaltySD_function_replace_sym( // "_ZN3app8lua_bind31ControlModule__get_stick_x_implEPNS_26BattleObjectModuleAccessorE",