mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-20 08:54:15 +00:00
Frame Advantage Refactor (#91)
* Auto Format * Remove unused include * Add Module Moved Frame advantage code to separate module
This commit is contained in:
parent
ab211a7aee
commit
7befc07555
5 changed files with 121 additions and 107 deletions
|
@ -19,8 +19,6 @@ pub static mut MENU_STRUCT: consts::TrainingModpackMenu = consts::TrainingModpac
|
|||
mash_in_neutral: MashInNeutral::Off
|
||||
};
|
||||
|
||||
pub static mut FRAME_ADVANTAGE: i32 = 0;
|
||||
|
||||
pub static mut MENU: &'static mut consts::TrainingModpackMenu = unsafe { &mut MENU_STRUCT };
|
||||
|
||||
pub static mut FIGHTER_MANAGER_ADDR: usize = 0;
|
||||
|
|
|
@ -7,8 +7,9 @@ mod hitbox_visualizer;
|
|||
mod training;
|
||||
|
||||
use crate::common::*;
|
||||
use training::combo::FRAME_ADVANTAGE;
|
||||
|
||||
use skyline::libc::{c_void, fclose, fopen, fwrite, mkdir, remove, access};
|
||||
use skyline::libc::{c_void, fclose, fopen, fwrite, mkdir, remove};
|
||||
use skyline::nro::{self, NroInfo};
|
||||
|
||||
fn nro_main(nro: &NroInfo<'_>) {
|
||||
|
|
111
src/training/combo.rs
Normal file
111
src/training/combo.rs
Normal file
|
@ -0,0 +1,111 @@
|
|||
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 FRAME_ADVANTAGE_CHECK: bool = false;
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
unsafe fn was_in_shieldstun(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0);
|
||||
prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
}
|
||||
|
||||
unsafe fn get_module_accessor(entry_id_int: i32) -> *mut app::BattleObjectModuleAccessor {
|
||||
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;
|
||||
let current_fighter_id = FighterEntry::current_fighter_id(fighter_entry);
|
||||
app::sv_battle_object::module_accessor(current_fighter_id as u32)
|
||||
}
|
||||
|
||||
unsafe fn is_actionable(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||
WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE_AIR,
|
||||
) || WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ATTACK_AIR,
|
||||
) || WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_GUARD_ON,
|
||||
) || WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE,
|
||||
) || CancelModule::is_enable_cancel(module_accessor)
|
||||
}
|
||||
|
||||
pub unsafe fn get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32,
|
||||
) {
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
if category != 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
FRAME_COUNTER += 1;
|
||||
}
|
||||
}
|
|
@ -87,8 +87,10 @@ pub unsafe fn get_command_flag_cat(
|
|||
Nair | Fair | Bair | UpAir | Dair => {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N;
|
||||
// If we are shielding we also need to jump
|
||||
if is_in_shieldstun(module_accessor) ||
|
||||
(is_grounded(module_accessor) && MENU.mash_in_neutral == MashInNeutral::On) {
|
||||
if is_in_shieldstun(module_accessor)
|
||||
|| (is_grounded(module_accessor)
|
||||
&& MENU.mash_in_neutral == MashInNeutral::On)
|
||||
{
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,15 @@ use crate::common::FIGHTER_MANAGER_ADDR;
|
|||
use crate::hitbox_visualizer;
|
||||
use skyline::nn::ro::LookupSymbol;
|
||||
use smash::app::{self, lua_bind::*};
|
||||
use smash::lib::{lua_const::*};
|
||||
use crate::common::*;
|
||||
use smash::lib::lua_const::*;
|
||||
|
||||
pub mod directional_influence;
|
||||
pub mod shield;
|
||||
pub mod tech;
|
||||
|
||||
mod left_stick;
|
||||
pub mod combo;
|
||||
mod ledge;
|
||||
mod left_stick;
|
||||
mod mash;
|
||||
mod save_states;
|
||||
|
||||
|
@ -35,49 +35,6 @@ pub unsafe fn handle_get_attack_air_kind(
|
|||
mash::get_attack_air_kind(module_accessor).unwrap_or_else(|| original!()(module_accessor))
|
||||
}
|
||||
|
||||
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 FRAME_ADVANTAGE_CHECK : bool = false;
|
||||
|
||||
pub 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)
|
||||
}
|
||||
|
||||
pub unsafe fn was_in_shieldstun(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0);
|
||||
prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
}
|
||||
|
||||
pub unsafe fn get_module_accessor(entry_id_int: i32) -> *mut app::BattleObjectModuleAccessor {
|
||||
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;
|
||||
let current_fighter_id = FighterEntry::current_fighter_id(fighter_entry);
|
||||
app::sv_battle_object::module_accessor(current_fighter_id as u32)
|
||||
|
||||
}
|
||||
|
||||
pub unsafe fn is_actionable(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||
WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE_AIR) ||
|
||||
WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ATTACK_AIR) ||
|
||||
WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_GUARD_ON) ||
|
||||
WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE) ||
|
||||
CancelModule::is_enable_cancel(module_accessor)
|
||||
}
|
||||
|
||||
#[skyline::hook(replace = ControlModule::get_command_flag_cat)]
|
||||
pub unsafe fn handle_get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
|
@ -87,62 +44,7 @@ pub unsafe fn handle_get_command_flag_cat(
|
|||
|
||||
let mut flag = original!()(module_accessor, category);
|
||||
|
||||
if is_training_mode() {
|
||||
if category == 0 {
|
||||
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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
FRAME_COUNTER += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
combo::get_command_flag_cat(module_accessor, category);
|
||||
|
||||
// bool replace;
|
||||
// int ret = InputRecorder::get_command_flag_cat(module_accessor, category, flag, replace);
|
||||
|
|
Loading…
Reference in a new issue