diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bea2f38 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "rust-analyzer.checkOnSave.overrideCommand": [ + "xargo", + "check", + "--workspace", + "--message-format=json", + "--all-features" + ], + "rust-analyzer.updates.channel": "nightly", +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index e52b74a..140310b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,93 +6,19 @@ mod common; mod hitbox_visualizer; mod training; -use crate::common::consts::*; use crate::common::*; use skyline::c_str; use skyline::libc::{c_void, mkdir, fclose, fopen, fwrite}; use skyline::nro::{self, NroInfo}; -use smash::app::lua_bind::*; -use smash::app::sv_system; -use smash::lib::lua_const::*; -use smash::lib::L2CValue; -use smash::lua2cpp::L2CFighterCommon; - -#[skyline::hook(replace = smash::lua2cpp::L2CFighterCommon_sub_guard_cont)] -pub unsafe fn handle_sub_guard_cont(fighter: &mut L2CFighterCommon) -> L2CValue { - let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent); - if is_training_mode() && is_operation_cpu(module_accessor) { - if MENU.mash_state == Mash::Attack && MENU.mash_attack_state == Attack::Grab { - if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE { - if WorkModule::get_int( - module_accessor, - *FIGHTER_INSTANCE_WORK_ID_INT_INVALID_CATCH_FRAME, - ) == 0 - { - if WorkModule::is_enable_transition_term( - module_accessor, - *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CATCH, - ) { - fighter.fighter_base.change_status( - L2CValue::new_int(*FIGHTER_STATUS_KIND_CATCH as u64), - L2CValue::new_bool(true), - ); - } - } - } - } - if MENU.mash_state == Mash::Spotdodge { - if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE { - if WorkModule::is_enable_transition_term( - module_accessor, - *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE, - ) { - fighter.fighter_base.change_status( - L2CValue::new_int(*FIGHTER_STATUS_KIND_ESCAPE as u64), - L2CValue::new_bool(true), - ); - } - } - } - - if MENU.mash_state == Mash::Attack { - if MENU.mash_attack_state == Attack::UpB { - if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE { - // if WorkModule::is_enable_transition_term( - // module_accessor, - // *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_JUMP_SQUAT_BUTTON, - // ) { - fighter.fighter_base.change_status( - L2CValue::new_int(*FIGHTER_STATUS_KIND_SPECIAL_HI as u64), - L2CValue::new_bool(false), - ); - // } - } - } - if MENU.mash_attack_state == Attack::UpSmash { - if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE { - // if WorkModule::is_enable_transition_term( - // module_accessor, - // *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_JUMP_SQUAT_BUTTON, - // ) { - fighter.fighter_base.change_status( - L2CValue::new_int(*FIGHTER_STATUS_KIND_ATTACK_HI4_START as u64), - L2CValue::new_bool(false), - ); - // } - } - } - } - } - - original!()(fighter) -} fn nro_main(nro: &NroInfo<'_>) { match nro.name { "common" => { - println!("Loaded common NRO!"); - skyline::install_hook!(handle_sub_guard_cont); + skyline::install_hooks!( + training::shield::handle_sub_guard_cont, + training::directional_influence::handle_correct_damage_vector_common, + ); } _ => (), } @@ -100,14 +26,14 @@ fn nro_main(nro: &NroInfo<'_>) { #[skyline::main(name = "training_modpack")] pub fn main() { - println!("Training modpack initialized."); + println!("[Training Modpack] Initialized."); hitbox_visualizer::hitbox_visualization(); training::training_mods(); nro::add_hook(nro_main).unwrap(); unsafe { let buffer = format!("{:x}", MENU as *const _ as u64); - println!("Writing training_modpack.log with {}...\n", buffer); + println!("[Training Modpack] Writing training_modpack.log with {}...", buffer); mkdir("sd:/TrainingModpack/\u{0}".as_bytes().as_ptr(), 0777); let f = fopen( "sd:/TrainingModpack/training_modpack.log\u{0}".as_bytes().as_ptr(), diff --git a/src/training/directional_influence.rs b/src/training/directional_influence.rs index 624270e..a4bb024 100644 --- a/src/training/directional_influence.rs +++ b/src/training/directional_influence.rs @@ -1,42 +1,43 @@ -use crate::common::consts::*; use crate::common::*; +use crate::common::consts::*; use core::f64::consts::PI; -use smash::app::{self, lua_bind::*}; +use smash::app::{self, sv_system, lua_bind::*}; use smash::hash40; use smash::lib::lua_const::*; +use smash::lib::L2CValue; +use smash::lua2cpp::L2CFighterCommon; -pub unsafe fn get_float( - module_accessor: &mut app::BattleObjectModuleAccessor, - var: i32, -) -> Option { - if var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X - || var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y - { - if is_training_mode() && is_operation_cpu(module_accessor) && is_in_hitstun(module_accessor) - { - if MENU.di_state != DirectionalInfluence::None { - let mut angle = (MENU.di_state as i32 - 1) as f64 * PI / 4.0; +pub static mut DI_ANGLE : f64 = 0.0; +pub static NO_DI : f64 = -69.0; +#[skyline::hook(replace = smash::lua2cpp::L2CFighterCommon_FighterStatusDamage__correctDamageVectorCommon)] +pub unsafe fn handle_correct_damage_vector_common(fighter: &mut L2CFighterCommon, arg1: L2CValue) -> L2CValue { + let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent); + if is_training_mode() && is_operation_cpu(module_accessor) { + if MENU.di_state != DirectionalInfluence::None { + DI_ANGLE = (MENU.di_state as i32 - 1) as f64 * PI / 4.0; + + // Either left, right, or none + if MENU.di_state == DirectionalInfluence::RandomInAway { + let rand = app::sv_math::rand(hash40("fighter"), 3) ; // Either 0 (right) or PI (left) - if MENU.di_state == DirectionalInfluence::RandomInAway { - angle = app::sv_math::rand(hash40("fighter"), 2) as f64 * PI; + if [0, 1].contains(&rand) { + DI_ANGLE = rand as f64 * PI; + } else { + DI_ANGLE = NO_DI; } + } + // If facing left, reverse angle + if DI_ANGLE != NO_DI && PostureModule::lr(module_accessor) != -1.0 { + DI_ANGLE -= PI; + } - // If facing left, reverse angle - if PostureModule::lr(module_accessor) != -1.0 { - angle -= PI; - } - - if var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X { - return Some(angle.cos() as f32); - } - - if var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y { - return Some(angle.sin() as f32); - } + if DI_ANGLE != NO_DI { + WorkModule::set_float(module_accessor, DI_ANGLE.cos() as f32, *FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X); + WorkModule::set_float(module_accessor, DI_ANGLE.sin() as f32, *FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y); } } } - None + original!()(fighter, arg1) } diff --git a/src/training/mod.rs b/src/training/mod.rs index 9197bf1..02358a7 100644 --- a/src/training/mod.rs +++ b/src/training/mod.rs @@ -3,22 +3,13 @@ use crate::hitbox_visualizer; use skyline::{c_str, nn::ro::LookupSymbol}; use smash::app::{self, lua_bind::*}; -mod directional_influence; +pub mod directional_influence; mod ledge; mod mash; mod save_states; -mod shield; +pub mod shield; mod tech; -#[skyline::hook(replace = WorkModule::get_float)] -pub unsafe fn handle_get_float( - module_accessor: &mut app::BattleObjectModuleAccessor, - var: i32, -) -> f32 { - directional_influence::get_float(module_accessor, var) - .unwrap_or_else(|| original!()(module_accessor, var)) -} - #[skyline::hook(replace = WorkModule::get_param_float)] pub unsafe fn handle_get_param_float( module_accessor: &mut app::BattleObjectModuleAccessor, @@ -191,7 +182,7 @@ pub fn training_mods() { handle_get_command_flag_cat, // Set DI - handle_get_float, + // handle_get_float, // Hold/Infinite shield handle_check_button_on, diff --git a/src/training/shield.rs b/src/training/shield.rs index 0aa70e9..c506943 100644 --- a/src/training/shield.rs +++ b/src/training/shield.rs @@ -3,6 +3,10 @@ use crate::common::*; use smash::app; use smash::hash40; use smash::lib::lua_const::*; +use smash::app::lua_bind::*; +use smash::app::sv_system; +use smash::lib::L2CValue; +use smash::lua2cpp::L2CFighterCommon; pub unsafe fn get_param_float( _module_accessor: &mut app::BattleObjectModuleAccessor, @@ -32,8 +36,8 @@ pub unsafe fn get_param_float( pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { // We should hold shield if the state requires it if [Shield::Hold, Shield::Infinite].contains(&MENU.shield_state) { - // If we are not mashing then we will always hold shield - if MENU.mash_state == Mash::None { + // If we are not mashing attack then we will always hold shield + if MENU.mash_state != Mash::Attack { return true; } @@ -45,21 +49,85 @@ pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAc if MENU.mash_state == Mash::Attack { if [Attack::NeutralB, Attack::SideB, Attack::DownB].contains(&MENU.mash_attack_state) { return false; - } - - if MENU.mash_attack_state == Attack::Grab { + } else { return true; } } - - if MENU.mash_state == Mash::Spotdodge { - return true; - } } false } +#[skyline::hook(replace = smash::lua2cpp::L2CFighterCommon_sub_guard_cont)] +pub unsafe fn handle_sub_guard_cont(fighter: &mut L2CFighterCommon) -> L2CValue { + let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent); + if is_training_mode() && is_operation_cpu(module_accessor) { + if MENU.mash_state == Mash::Attack && MENU.mash_attack_state == Attack::Grab { + if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE { + if WorkModule::get_int( + module_accessor, + *FIGHTER_INSTANCE_WORK_ID_INT_INVALID_CATCH_FRAME, + ) == 0 + { + if WorkModule::is_enable_transition_term( + module_accessor, + *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CATCH, + ) { + fighter.fighter_base.change_status( + L2CValue::new_int(*FIGHTER_STATUS_KIND_CATCH as u64), + L2CValue::new_bool(true), + ); + } + } + } + } + if MENU.mash_state == Mash::Spotdodge { + if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE { + if WorkModule::is_enable_transition_term( + module_accessor, + *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE, + ) { + fighter.fighter_base.change_status( + L2CValue::new_int(*FIGHTER_STATUS_KIND_ESCAPE as u64), + L2CValue::new_bool(true), + ); + } + } + } + + if MENU.mash_state == Mash::Attack { + if MENU.mash_attack_state == Attack::UpB { + if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE { + if WorkModule::is_enable_transition_term( + module_accessor, + *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_JUMP_SQUAT_BUTTON, + ) { + fighter.fighter_base.change_status( + L2CValue::new_int(*FIGHTER_STATUS_KIND_SPECIAL_HI as u64), + L2CValue::new_bool(false), + ); + } + } + } + if MENU.mash_attack_state == Attack::UpSmash { + if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE { + if WorkModule::is_enable_transition_term( + module_accessor, + *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_JUMP_SQUAT_BUTTON, + ) { + fighter.fighter_base.change_status( + L2CValue::new_int(*FIGHTER_STATUS_KIND_ATTACK_HI4_START as u64), + L2CValue::new_bool(false), + ); + } + } + } + } + } + + original!()(fighter) +} + pub unsafe fn check_button_on( module_accessor: &mut app::BattleObjectModuleAccessor, button: i32,