mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-28 12:50:16 +00:00
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
This commit is contained in:
parent
099ae06e89
commit
63a3358a0f
4 changed files with 122 additions and 45 deletions
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
60
src/training/frame_counter.rs
Normal file
60
src/training/frame_counter.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use crate::common::*;
|
||||
use crate::training::*;
|
||||
|
||||
static mut SHOULD_COUNT: Vec<bool> = vec![];
|
||||
static mut COUNTERS: Vec<u32> = 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();
|
||||
}
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue