1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-20 00:46:34 +00:00

finish porting non-beta features

This commit is contained in:
jugeeya 2020-05-04 18:55:19 -07:00
parent fb466cb3fe
commit a5fc17904f
9 changed files with 799 additions and 215 deletions

View file

@ -18,35 +18,47 @@ pub static menu : consts::TrainingModpackMenu = consts::TrainingModpackMenu{
DEFENSIVE_STATE : RANDOM_DEFENSIVE,
};
static mut fighter_manager: FighterManager = FighterManager{ _address: 0 };
pub static mut fighter_manager_addr : usize = 0;
extern "C" {
#[link_name = "\u{1}_ZN3app9smashball16is_training_modeEv"]
pub fn is_training_mode() -> bool;
}
pub fn get_category(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 {
pub fn get_category(
module_accessor: &mut app::BattleObjectModuleAccessor) -> i32
{
return (module_accessor.info >> 28) as u8 as i32;
}
pub unsafe fn is_operation_cpu(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub unsafe fn is_operation_cpu(
module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
{
if get_category(module_accessor) as i32 != BATTLE_OBJECT_CATEGORY_FIGHTER {
return false
}
let entry_id = app::FighterEntryID(WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32);
let fighter_information = lua_bind::FighterManager::get_fighter_information(&mut fighter_manager, entry_id) as *mut FighterInformation;
let entry_id_int = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32;
let entry_id = app::FighterEntryID(entry_id_int);
// let mut mgr = FighterManager{_address : fighter_manager_addr as u64};
// let fighter_information = lua_bind::FighterManager::get_fighter_information(&mut mgr, entry_id) as *mut FighterInformation;
// println!("FighterInformation: {:#?}", fighter_information);
lua_bind::FighterInformation::is_operation_cpu(fighter_information)
// lua_bind::FighterInformation::is_operation_cpu(fighter_information)
entry_id_int > 0
}
pub unsafe fn is_in_hitstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub unsafe fn is_in_hitstun(
module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
{
let status_kind = StatusModule::status_kind(module_accessor) as i32;
(FIGHTER_STATUS_KIND_DAMAGE..=FIGHTER_STATUS_KIND_DAMAGE_FALL)
.contains(&status_kind)
}
pub unsafe fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub unsafe fn is_in_shieldstun(
module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
{
let status_kind = StatusModule::status_kind(module_accessor) as i32;
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
// If we are taking shield damage or we are droping shield from taking shield damage we are in hitstun
@ -59,33 +71,41 @@ pub unsafe fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAcce
}
pub unsafe fn is_in_landing(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub unsafe fn is_in_landing(
module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
{
let status_kind = StatusModule::status_kind(module_accessor) as i32;
(FIGHTER_STATUS_KIND_LANDING..=FIGHTER_STATUS_KIND_LANDING_DAMAGE_LIGHT)
.contains(&status_kind)
}
pub unsafe fn perform_defensive_option(module_accessor: &mut app::BattleObjectModuleAccessor, flag: &mut i32) {
if menu.DEFENSIVE_STATE == RANDOM_DEFENSIVE {
let random_cmds = vec![
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N
];
let random_cmd_index = app::sv_math::rand(hash40("fighter"), random_cmds.len() as i32) as usize;
*flag |= random_cmds[random_cmd_index];
} else if menu.DEFENSIVE_STATE == DEFENSIVE_ROLL {
if app::sv_math::rand(hash40("fighter"), 2) == 0 {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F;
} else {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B;
}
} else if menu.DEFENSIVE_STATE == DEFENSIVE_SPOTDODGE {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE;
} else if menu.DEFENSIVE_STATE == DEFENSIVE_JAB {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N;
pub unsafe fn perform_defensive_option(
module_accessor: &mut app::BattleObjectModuleAccessor,
flag: &mut i32)
{
match menu.DEFENSIVE_STATE {
RANDOM_DEFENSIVE => {
let random_cmds = vec![
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N
];
let random_cmd_index = app::sv_math::rand(
hash40("fighter"), random_cmds.len() as i32) as usize;
*flag |= random_cmds[random_cmd_index];
},
DEFENSIVE_ROLL => {
if app::sv_math::rand(hash40("fighter"), 2) == 0 {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F;
} else {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B;
}
},
DEFENSIVE_SPOTDODGE => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
DEFENSIVE_JAB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
_ => ()
}
}

View file

@ -1,13 +1,12 @@
use smash::hash40;
use smash::app::BattleObjectModuleAccessor;
use smash::app::sv_animcmd::{self};
use smash::app::lua_bind::*;
use smash::lib::{self, L2CAgent, L2CValue};
use smash::phx::{Hash40, Vector3f};
use smash::lib::lua_const::{*};
use smash::app::sv_system::{self};
use smash::app::{self};
use skyline::logging::hex_dump_ptr;
use smash::app::sv_animcmd::{self};
use smash::app::sv_system::{self};
use smash::app::lua_bind::*;
use smash::lib::lua_const::*;
use smash::lib::{L2CAgent, L2CValue, L2CValueType};
use smash::phx::{Hash40, Vector3f};
use skyline::{logging::HexDump};
use crate::common::*;
/**
@ -108,7 +107,7 @@ pub unsafe fn generate_hitbox_effects(l2c_agent: &mut L2CAgent, bone: L2CValue,
let y_dist : f32;
let z_dist : f32;
let mut n_effects : i32;
if let lib::L2CValueType::Void = x2.val_type{ // && let lib::L2CValueType::Void = y2.val_type && let lib::L2CValueType::Void = z2.val_type { // extended hitbox
if let L2CValueType::Void = x2.val_type { // && let lib::L2CValueType::Void = y2.val_type && let lib::L2CValueType::Void = z2.val_type { // extended hitbox
x_dist = 0.0; y_dist = 0.0; z_dist = 0.0;
n_effects = 1;
}
@ -177,7 +176,7 @@ unsafe fn handle_attack(lua_state: u64) {
if menu.HITBOX_VIS && is_training_mode() { // generate hitbox effect(s)
let color_scale: f32;
if false { // color intensity scales with damage
if true { // color intensity scales with damage
color_scale = unlerp_bounded(1.0, 18.0, damage.get_num());
} else { // color intensity scales with total KB
// calculate the expected KB a character with 95 weight will receive
@ -232,14 +231,14 @@ unsafe fn handle_catch(lua_state: u64) {
}
}
pub unsafe fn is_shielding(module_accessor: *mut BattleObjectModuleAccessor) -> bool {
pub unsafe fn is_shielding(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
let status_kind = StatusModule::status_kind(module_accessor) as i32;
(FIGHTER_STATUS_KIND_GUARD_ON..=FIGHTER_STATUS_KIND_GUARD_OFF).contains(&status_kind)
}
#[allow(unused_unsafe)]
#[skyline::hook(replace = AttackModule::clear_all)]
pub unsafe fn handle_clear_all(module_accessor: *mut BattleObjectModuleAccessor) {
pub unsafe fn handle_clear_all(module_accessor: *mut app::BattleObjectModuleAccessor) {
if is_training_mode() {
// only if we're not shielding
if !is_shielding(module_accessor) {
@ -252,7 +251,7 @@ pub unsafe fn handle_clear_all(module_accessor: *mut BattleObjectModuleAccessor)
#[allow(unused_unsafe)]
#[skyline::hook(replace = GrabModule::set_rebound)]
pub unsafe fn handle_set_rebound(module_accessor: *mut BattleObjectModuleAccessor, rebound: bool) {
pub unsafe fn handle_set_rebound(module_accessor: *mut app::BattleObjectModuleAccessor, rebound: bool) {
if is_training_mode() && rebound == false {
// only if we're not shielding
if !is_shielding(module_accessor) {

View file

@ -21,37 +21,87 @@ use skyline::libc::{size_t, c_int, c_void, strlen};
use smash::Result;
use skyline::nn;
use skyline::patching::patch_data_from_text;
use skyline::{from_c_str, c_str};
use skyline::{from_c_str, c_str, hooks::A64HookFunction};
use std::fs;
use skyline::nro::{self, NroInfo};
extern "C" {
#[link_name = "\u{1}_ZN7lua2cpp16L2CFighterCommon28status_AttackAir_Main_commonEv"]
pub fn status_AttackAirMain_common(
arg1: *mut L2CAgent
) -> u64;
#[link_name = "\u{1}_ZN7lua2cpp27L2CFighterAnimcmdGameCommon21game_BatSwing4Common1Ev"]
pub fn game_BatSwing4Common1(
arg1: *mut L2CAgent
) -> u64;
#[link_name = "\u{1}_ZN7lua2cpp27L2CFighterAnimcmdGameCommon21game_BatSwing4Common2Ev"]
pub fn game_BatSwing4Common2(
arg1: *mut L2CAgent
) -> u64;
}
#[allow(unused_unsafe)]
#[skyline::hook(replace = nn::ro::LoadModule)]
pub unsafe fn handle_load_module(
p_out_module: *mut skyline::nn::ro::Module,
p_image: *const c_void,
buffer: *mut c_void,
buffer_size: size_t,
flag: c_int) -> Result {
#[skyline::hook(replace = status_AttackAirMain_common)]
pub unsafe fn handle_AttackAirMain(fighter: *mut L2CAgent) {
CancelModule::enable_cancel(sv_system::battle_object_module_accessor((*fighter).lua_state_agent));
original!()(fighter);
}
let ret = original!()(p_out_module, p_image, buffer, buffer_size, flag);
#[allow(unused_unsafe)]
#[skyline::hook(replace = game_BatSwing4Common1)]
pub unsafe fn handle_game_BatSwing4Common1(fighter: *mut L2CAgent) {
println!("[handle_game_BatSwing4Common1]");
original!()(fighter);
}
let name = from_c_str(&(*p_out_module).Name as *const u8);
println!("[handleLoadModule] NRO name: {}\n", name);
let text_start = (*(*p_out_module).ModuleObject).module_base;
println!("Module base: {}\n", text_start);
if name.starts_with("common") {
println!("Is common!");
// raw const_value_table is at : 0x635b70
let fighter_status_kind_fall : u64 = 0x8ee6c39e9be4f0b5;
let res = match patch_data_from_text(text_start as *const u8, 0x6362b8, &fighter_status_kind_fall) {
Ok(v) => format!("Patched!"),
Err(e) => format!("Error patching with e: {}", e)
};
println!("{}", res);
#[allow(unused_unsafe)]
#[skyline::hook(replace = game_BatSwing4Common2)]
pub unsafe fn handle_game_BatSwing4Common2(fighter: *mut L2CAgent) {
println!("[handle_game_BatSwing4Common2]");
sv_animcmd::frame((*fighter).lua_state_agent, 0x30 as f32);
if sv_animcmd::is_excute((*fighter).lua_state_agent) {
hitbox_visualizer::wrap(sv_animcmd::EFFECT_FOLLOW_NO_SCALE,
&mut (*fighter),
&mut [
L2CValue::new_int(hash40("sys_shield")), L2CValue::new_int(hash40("top")),
L2CValue::new_num(0.0), L2CValue::new_num(0.0), L2CValue::new_num(0.0), L2CValue::new_num(0.0), L2CValue::new_num(0.0), L2CValue::new_num(0.0),
L2CValue::new_num(1.0), L2CValue::new_bool(false)].to_vec());
}
original!()(fighter);
}
ret
fn nro_main(nro: &NroInfo) {
match nro.name {
"common" =>
{
println!("Loaded common NRO!");
unsafe {
let text_start = (*(*nro.module).ModuleObject).module_base;
println!("Common Text Start: {:x}", text_start);
// raw const_value_table is at : 0x635b70
let fighter_status_kind_fall : u64 = 0x8ee6c39e9be4f0b5;
// let res = match patch_data_from_text(text_start as *const u8, 0x6362b8, &fighter_status_kind_fall) {
// Ok(v) => format!("Patched!"),
// Err(e) => format!("Error patching with e: {}", e)
// };
let fighter_kind_popo : u64 = 0x04aa7a0e945950d5;
let res = match patch_data_from_text(text_start as *const u8, 0x638d78, &fighter_kind_popo) {
Ok(v) => format!("Patched!"),
Err(e) => format!("Error patching with e: {}", e)
};
println!("Result: {}", res);
// skyline::install_hook!(handle_AttackAirMain);
// skyline::install_hook!(handle_game_BatSwing4Common1);
// skyline::install_hook!(handle_game_BatSwing4Common2);
println!("Hooked!");
}
},
"item" => println!("Loaded item NRO!"),
_ => ()
}
}
#[skyline::main(name = "test")]
@ -59,10 +109,11 @@ pub fn main() {
println!("Training modpack initialized.");
hitbox_visualizer::hitbox_visualization();
training::training_mods();
nro::add_hook(nro_main).unwrap();
println!("OpenMode_Write: {} {}", nn::fs::OpenMode_OpenMode_Write, nn::fs::OpenMode_OpenMode_Write as i32);
let buffer = format!("{:x}", &common::menu as *const _ as u64);
println!("Writing training_modpack.log with {}...\n", buffer);
// println!("OpenMode_Write: {} {}", nn::fs::OpenMode_OpenMode_Write, nn::fs::OpenMode_OpenMode_Write as i32);
// let buffer = format!("{:x}", &common::menu as *const _ as u64);
// println!("Writing training_modpack.log with {}...\n", buffer);
// skyline::install_hook!(handle_load_module);
// fs::File::create("sd:/test.log").unwrap();
}

View file

@ -0,0 +1,40 @@
use smash::hash40;
use smash::app::{self};
use smash::app::lua_bind::*;
use smash::lib::lua_const::*;
use crate::common::*;
use crate::common::consts::*;
use core::f64::consts::PI;
pub unsafe fn get_float(module_accessor: &mut app::BattleObjectModuleAccessor, var: i32) -> Option<f32> {
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 != NONE {
let mut angle = (menu.DI_STATE - 1) as f64 * PI / 4.0;
// Either 0 (right) or PI (left)
if menu.DI_STATE == DI_RANDOM_IN_AWAY {
angle = app::sv_math::rand(hash40("fighter"), 2) as f64 * 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)
}
}
}
}
None
}

108
src/training/Ledge.rs Normal file
View file

@ -0,0 +1,108 @@
use smash::{hash40, phx::Hash40};
use smash::app::{self};
use smash::app::lua_bind::*;
use smash::lib::lua_const::*;
use crate::common::*;
use crate::common::consts::*;
pub unsafe fn force_option(
module_accessor: &mut app::BattleObjectModuleAccessor)
{
if StatusModule::status_kind(module_accessor) as i32 == *FIGHTER_STATUS_KIND_CLIFF_WAIT {
if WorkModule::is_enable_transition_term(module_accessor, *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB) {
let random_frame = app::sv_math::rand(
hash40("fighter"),
MotionModule::end_frame(module_accessor) as i32) as f32;
let frame = MotionModule::frame(module_accessor) as f32;
if frame == random_frame || frame > 30.0 {
let mut status = 0;
let ledge_case : i32;
if menu.LEDGE_STATE == RANDOM_LEDGE {
ledge_case = app::sv_math::rand(hash40("fighter"), 4) + 2;
} else {
ledge_case = menu.LEDGE_STATE;
}
match ledge_case {
NEUTRAL_LEDGE => status = *FIGHTER_STATUS_KIND_CLIFF_CLIMB,
ROLL_LEDGE => status = *FIGHTER_STATUS_KIND_CLIFF_ESCAPE,
JUMP_LEDGE => status = *FIGHTER_STATUS_KIND_CLIFF_JUMP1,
ATTACK_LEDGE => status = *FIGHTER_STATUS_KIND_CLIFF_ATTACK,
_ => ()
}
StatusModule::change_status_request_from_script(module_accessor, status, true);
}
}
}
}
pub unsafe fn should_perform_defensive_option(
module_accessor: &mut app::BattleObjectModuleAccessor,
prev_status: i32,
status: i32) -> bool
{
([*FIGHTER_STATUS_KIND_CLIFF_CLIMB,
*FIGHTER_STATUS_KIND_CLIFF_ATTACK,
*FIGHTER_STATUS_KIND_CLIFF_ESCAPE]
.iter()
.any(|i| i == &status || i == &prev_status)
)
&&
(
WorkModule::is_enable_transition_term(module_accessor, *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE) ||
CancelModule::is_enable_cancel(module_accessor)
)
}
pub unsafe fn defensive_option(
module_accessor: &mut app::BattleObjectModuleAccessor,
category: i32,
flag: &mut i32)
{
let status = StatusModule::status_kind(module_accessor) as i32;
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
if [*FIGHTER_STATUS_KIND_CLIFF_JUMP3,
*FIGHTER_STATUS_KIND_CLIFF_JUMP2,
*FIGHTER_STATUS_KIND_CLIFF_JUMP1].contains(&status) {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
}
if should_perform_defensive_option(module_accessor, prev_status, status) {
perform_defensive_option(module_accessor, flag);
}
}
pub unsafe fn check_button_on(
module_accessor: &mut app::BattleObjectModuleAccessor,
button: i32) -> Option<bool>
{
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
if is_training_mode() && is_operation_cpu(module_accessor) {
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
let status = StatusModule::status_kind(module_accessor) as i32;
if menu.DEFENSIVE_STATE == DEFENSIVE_SHIELD &&
should_perform_defensive_option(
module_accessor, prev_status, status) {
return Some(true)
}
}
}
None
}
pub unsafe fn get_command_flag_cat(
module_accessor: &mut app::BattleObjectModuleAccessor,
category: i32,
flag: &mut i32)
{
if menu.LEDGE_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
force_option(module_accessor);
defensive_option(module_accessor, category, flag);
}
}

158
src/training/Mash.rs Normal file
View file

@ -0,0 +1,158 @@
use smash::{hash40, phx::Hash40};
use smash::app::{self};
use smash::app::lua_bind::*;
use smash::lib::lua_const::*;
use crate::common::*;
use crate::common::consts::*;
pub unsafe fn get_attack_air_kind(
module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<i32>
{
if is_training_mode() && is_operation_cpu(module_accessor) {
if menu.MASH_STATE == MASH_ATTACK {
match menu.ATTACK_STATE {
MASH_NAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_N),
MASH_FAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_F),
MASH_BAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_B),
MASH_UPAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_HI),
MASH_DAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_LW),
_ => ()
}
}
if menu.MASH_STATE == MASH_RANDOM {
return Some(app::sv_math::rand(hash40("fighter"), 5) + 1);
}
}
None
}
pub unsafe fn get_command_flag_cat(
module_accessor: &mut app::BattleObjectModuleAccessor,
category: i32,
flag: &mut i32)
{
if is_training_mode() && is_operation_cpu(module_accessor) {
if is_in_hitstun(module_accessor) || is_in_landing(module_accessor) || is_in_shieldstun(module_accessor) {
match menu.MASH_STATE {
MASH_AIRDODGE => {
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
}
},
MASH_JUMP => {
if !is_in_landing(module_accessor) && category == FIGHTER_PAD_COMMAND_CATEGORY1 {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;
}
},
MASH_SPOTDODGE => {
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE;
}
},
MASH_ATTACK => {
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
match menu.ATTACK_STATE {
MASH_NAIR |
MASH_FAIR |
MASH_BAIR |
MASH_UPAIR |
MASH_DAIR => {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N;
// If we are performing the attack OOS we also need to jump
if is_in_shieldstun(module_accessor) {
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;
}
},
MASH_NEUTRAL_B => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
MASH_SIDE_B => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
MASH_UP_B => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
MASH_DOWN_B => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
MASH_UP_SMASH => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4,
MASH_GRAB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH,
_ => ()
}
} else if category == 1 {
if menu.ATTACK_STATE == MASH_GRAB { *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH; }
}
},
MASH_RANDOM => {
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
let situation_kind = StatusModule::situation_kind(module_accessor) as i32;
if situation_kind == SITUATION_KIND_AIR {
let random_commands = vec![
*FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE,
*FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
// one for each aerial
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
];
let random_cmd_index = app::sv_math::rand(
hash40("fighter"), random_commands.len() as i32) as usize;
*flag |= random_commands[random_cmd_index];
} else if situation_kind == SITUATION_KIND_GROUND {
let random_commands = vec![
*FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S3,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI3,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW3,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S4,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4,
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW4,
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
*FIGHTER_PAD_CMD_CAT1_FLAG_CATCH,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
];
let random_cmd_index = app::sv_math::rand(
hash40("fighter"), random_commands.len() as i32) as usize;
*flag |= random_commands[random_cmd_index];
}
}
},
_ => ()
}
}
}
}
pub unsafe fn check_button_on(
module_accessor: &mut app::BattleObjectModuleAccessor,
button: i32) -> Option<bool>
{
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
if is_training_mode() && is_operation_cpu(module_accessor) {
if menu.MASH_STATE == MASH_AIRDODGE && (is_in_hitstun(module_accessor) || is_in_landing(module_accessor)) {
return Some(true)
}
}
}
if [*CONTROL_PAD_BUTTON_ATTACK, *CONTROL_PAD_BUTTON_CATCH].contains(&button) {
if is_training_mode() && is_operation_cpu(module_accessor) {
if menu.MASH_STATE == MASH_ATTACK && menu.ATTACK_STATE == MASH_GRAB && is_in_shieldstun(module_accessor) {
return Some(true)
}
}
}
None
}

75
src/training/Shield.rs Normal file
View file

@ -0,0 +1,75 @@
use smash::hash40;
use smash::app::{self};
use smash::app::lua_bind::*;
use smash::lib::lua_const::*;
use crate::common::*;
use crate::common::consts::*;
pub unsafe fn get_param_float(module_accessor: &mut app::BattleObjectModuleAccessor, param_type: u64, param_hash: u64) -> Option<f32> {
if is_training_mode() {
if menu.SHIELD_STATE == SHIELD_INFINITE {
if param_type == hash40("common") {
if param_hash == hash40("shield_dec1") {
return Some(0.0)
}
if param_hash == hash40("shield_recovery1") {
return Some(999.0)
}
// doesn't work, somehow. This parameter isn't checked?
if param_hash == hash40("shield_damage_mul") {
return Some(0.0)
}
}
}
}
None
}
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 == NONE {
return true
}
if !is_in_shieldstun(module_accessor) {
return true
}
// We will only drop shield if we are in shieldstun and our attack can be performed OOS
if menu.MASH_STATE == MASH_ATTACK {
if [MASH_NEUTRAL_B, MASH_SIDE_B, MASH_DOWN_B].contains(&menu.ATTACK_STATE) {
return true
}
}
}
false
}
pub unsafe fn check_button_on(module_accessor: &mut app::BattleObjectModuleAccessor, button: i32) -> Option<bool> {
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
if is_training_mode() && is_operation_cpu(module_accessor) {
if should_hold_shield(module_accessor) {
return Some(true)
}
}
}
None
}
pub unsafe fn check_button_off(module_accessor: &mut app::BattleObjectModuleAccessor, button: i32) -> Option<bool> {
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
if is_training_mode() && is_operation_cpu(module_accessor) {
if should_hold_shield(module_accessor) {
return Some(false)
}
}
}
None
}

144
src/training/Tech.rs Normal file
View file

@ -0,0 +1,144 @@
use smash::{hash40, phx::Hash40};
use smash::app::{self};
use smash::app::lua_bind::*;
use smash::lib::lua_const::*;
use crate::common::*;
use crate::common::consts::*;
pub unsafe fn init_settings(
module_accessor: &mut app::BattleObjectModuleAccessor,
status_kind: i32) -> Option<()>
{
if is_training_mode() && is_operation_cpu(module_accessor) {
if status_kind == FIGHTER_STATUS_KIND_DOWN {
match menu.TECH_STATE {
RANDOM_TECH => {
let random_statuses = vec![
*FIGHTER_STATUS_KIND_DOWN,
*FIGHTER_STATUS_KIND_PASSIVE,
*FIGHTER_STATUS_KIND_PASSIVE_FB
];
let random_status_index = app::sv_math::rand(hash40("fighter"), random_statuses.len() as i32) as usize;
if random_statuses[random_status_index] != FIGHTER_STATUS_KIND_DOWN {
StatusModule::change_status_request_from_script(
module_accessor,
random_statuses[random_status_index],
true);
return Some(())
}
},
TECH_IN_PLACE => {
StatusModule::change_status_request_from_script(
module_accessor,
*FIGHTER_STATUS_KIND_PASSIVE,
true);
return Some(())
},
TECH_ROLL => {
StatusModule::change_status_request_from_script(
module_accessor,
*FIGHTER_STATUS_KIND_PASSIVE_FB,
true);
return Some(())
},
_ => ()
}
}
}
None
}
pub unsafe fn should_perform_defensive_option(
module_accessor: &mut app::BattleObjectModuleAccessor,
prev_status: i32,
status: i32) -> bool
{
(
[*FIGHTER_STATUS_KIND_PASSIVE,
*FIGHTER_STATUS_KIND_PASSIVE_FB,
*FIGHTER_STATUS_KIND_DOWN_STAND,
*FIGHTER_STATUS_KIND_DOWN_STAND_FB,
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK].contains(&prev_status) ||
[*FIGHTER_STATUS_KIND_DOWN_STAND,
*FIGHTER_STATUS_KIND_DOWN_STAND_FB,
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK].contains(&status)
)
&&
(
WorkModule::is_enable_transition_term(module_accessor, *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_GUARD_ON) ||
CancelModule::is_enable_cancel(module_accessor)
)
}
pub unsafe fn get_command_flag_cat(
module_accessor: &mut app::BattleObjectModuleAccessor,
category: i32,
flag: &mut i32)
{
if menu.TECH_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
let status = StatusModule::status_kind(module_accessor) as i32;
if [*FIGHTER_STATUS_KIND_DOWN_WAIT, *FIGHTER_STATUS_KIND_DOWN_WAIT_CONTINUE].contains(&status) {
let random_statuses = vec![
*FIGHTER_STATUS_KIND_DOWN_STAND,
*FIGHTER_STATUS_KIND_DOWN_STAND_FB,
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK
];
let random_status_index = app::sv_math::rand(hash40("fighter"), random_statuses.len() as i32) as usize;
StatusModule::change_status_request_from_script(module_accessor, random_statuses[random_status_index], true);
} else if should_perform_defensive_option(module_accessor, prev_status, status) {
perform_defensive_option(module_accessor, flag);
}
}
}
pub unsafe fn check_button_on(
module_accessor: &mut app::BattleObjectModuleAccessor,
button: i32) -> Option<bool>
{
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
if is_training_mode() && is_operation_cpu(module_accessor) {
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
let status = StatusModule::status_kind(module_accessor) as i32;
if menu.DEFENSIVE_STATE == DEFENSIVE_SHIELD &&
should_perform_defensive_option(module_accessor, prev_status, status) {
return Some(true)
}
}
}
None
}
pub unsafe fn change_motion(
module_accessor: &mut app::BattleObjectModuleAccessor,
motion_kind: u64) -> Option<u64>
{
if menu.TECH_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
if [hash40("passive_stand_f"), hash40("passive_stand_b")].contains(&motion_kind) {
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
return Some(hash40("passive_stand_f"))
} else {
return Some(hash40("passive_stand_b"))
}
} else if [hash40("down_forward_u") | hash40("down_back_u")].contains(&motion_kind) {
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
return Some(hash40("down_forward_u"))
} else {
return Some(hash40("down_back_u"))
}
} else if [hash40("down_forward_d") | hash40("down_back_d")].contains(&motion_kind) {
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
return Some(hash40("down_forward_d"))
} else {
return Some(hash40("down_back_d"))
}
}
}
None
}

View file

@ -1,78 +1,74 @@
use smash::hash40;
use smash::app::BattleObjectModuleAccessor;
use smash::app::sv_animcmd::{self};
use smash::app::lua_bind::*;
use smash::lib::{self, L2CAgent, L2CValue};
use smash::app::{self, sv_system, sv_animcmd, lua_bind::*, FighterManager};
use smash::lib::{self, L2CAgent, L2CValue, lua_const::*};
use smash::phx::{Hash40, Vector3f};
use smash::lib::lua_const::{*};
use smash::app::sv_system::{self};
use smash::app::{self};
use skyline::logging::hex_dump_ptr;
use smash::hash40;
use skyline::{c_str, nn::ro::LookupSymbol, logging::hex_dump_ptr};
use crate::common::fighter_manager_addr;
use crate::common::*;
use crate::common::consts::*;
mod DirectionalInfluence;
mod Shield;
mod Tech;
mod Mash;
mod Ledge;
#[allow(unused_unsafe)]
#[skyline::hook(replace = WorkModule::get_float)]
pub unsafe fn handle_get_float(module_accessor: *mut BattleObjectModuleAccessor, var: i32) -> f32 {
let mut replace = false;
//float ret = DirectionalInfluence::get_float(module_accessor, var, replace);
//if (replace) return ret;
original!()(module_accessor, var)
pub unsafe fn handle_get_float(module_accessor: &mut app::BattleObjectModuleAccessor, var: i32) -> f32 {
DirectionalInfluence::get_float(module_accessor, var).unwrap_or_else( || {
original!()(module_accessor, var)
})
}
// float get_param_float_replace(u64 module_accessor, u64 param_type, u64 param_hash) {
// bool replace;
// float ret = Shield::get_param_float(module_accessor, param_type, param_hash, replace);
// if (replace) return ret;
#[allow(unused_unsafe)]
#[skyline::hook(replace = WorkModule::get_param_float)]
pub unsafe fn handle_get_param_float(module_accessor: &mut app::BattleObjectModuleAccessor, param_type: u64, param_hash: u64) -> f32 {
Shield::get_param_float(module_accessor, param_type, param_hash).unwrap_or_else( || {
original!()(module_accessor, param_type, param_hash)
})
}
// u64 work_module = load_module(module_accessor, 0x50);
// float (*get_param_float)(u64, u64, u64) = (float (*)(u64, u64, u64)) load_module_impl(work_module, 0x240);
// return get_param_float(work_module, param_type, param_hash);
// }
// } // namespace WorkModule
#[allow(unused_unsafe)]
#[skyline::hook(replace = ControlModule::get_attack_air_kind)]
pub unsafe fn handle_get_attack_air_kind(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 {
// bool replace;
// int kind = InputRecorder::get_attack_air_kind(module_accessor, replace);
// if (replace) return kind;
// namespace ControlModule {
// int get_attack_air_kind_replace(u64 module_accessor) {
// bool replace;
// int kind = InputRecorder::get_attack_air_kind(module_accessor, replace);
// if (replace) return kind;
Mash::get_attack_air_kind(module_accessor).unwrap_or_else( || {
original!()(module_accessor)
})
}
// kind = Mash::get_attack_air_kind(module_accessor, replace);
// if (replace) return kind;
#[allow(unused_unsafe)]
#[skyline::hook(replace = ControlModule::get_command_flag_cat)]
pub unsafe fn handle_get_command_flag_cat(
module_accessor: &mut app::BattleObjectModuleAccessor,
category: i32) -> i32
{
//save_states(module_accessor);
// u64 control_module = load_module(module_accessor, 0x48);
// int (*get_attack_air_kind)(u64) = (int (*)(u64)) load_module_impl(control_module, 0x3B0);
// return get_attack_air_kind(control_module);
// }
// Pause Effect AnimCMD if hitbox visualization is active
let status_kind = StatusModule::status_kind(module_accessor) as i32;
MotionAnimcmdModule::set_sleep_effect(module_accessor,
is_training_mode() &&
menu.HITBOX_VIS &&
!((*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_TREAD_FALL).contains(&status_kind) ||
(*FIGHTER_STATUS_KIND_WAIT..=*FIGHTER_STATUS_KIND_REBOUND_JUMP).contains(&status_kind)));
// int get_command_flag_cat_replace(u64 module_accessor, int category) {
// int (*prev_replace)(u64, int) = (int (*)(u64, int)) prev_get_command_flag_cat;
// if (prev_replace)
// prev_replace(module_accessor, category);
// //save_states(module_accessor);
let mut flag = original!()(module_accessor, category);
// // Pause Effect AnimCMD if hitbox visualization is active
// int status_kind = StatusModule::status_kind(module_accessor);
// MotionAnimcmdModule::set_sleep_effect(module_accessor,
// is_training_mode() &&
// menu.HITBOX_VIS &&
// !((status_kind >= FIGHTER_STATUS_KIND_CATCH && status_kind <= FIGHTER_STATUS_KIND_TREAD_FALL) ||
// (status_kind >= FIGHTER_STATUS_KIND_WAIT && status_kind <= FIGHTER_STATUS_KIND_REBOUND_JUMP)));
// bool replace;
// int ret = InputRecorder::get_command_flag_cat(module_accessor, category, flag, replace);
// if (replace) return ret;
// u64 control_module = load_module(module_accessor, 0x48);
// int (*get_command_flag_cat)(u64, int) = (int (*)(u64, int)) load_module_impl(control_module, 0x350);
// int flag = get_command_flag_cat(control_module, category);
Mash::get_command_flag_cat(module_accessor, category, &mut flag);
Ledge::get_command_flag_cat(module_accessor, category, &mut flag);
Tech::get_command_flag_cat(module_accessor, category, &mut flag);
// // bool replace;
// // int ret = InputRecorder::get_command_flag_cat(module_accessor, category, flag, replace);
// // if (replace) return ret;
// Mash::get_command_flag_cat(module_accessor, category, flag);
// Ledge::get_command_flag_cat(module_accessor, category, flag);
// Tech::get_command_flag_cat(module_accessor, category, flag);
// return flag;
// }
flag
}
// int get_pad_flag(u64 module_accessor) {
// u64 control_module = load_module(module_accessor, 0x48);
@ -110,96 +106,93 @@ pub unsafe fn handle_get_float(module_accessor: *mut BattleObjectModuleAccessor,
// return stick_y;
// }
// bool check_button_on_replace(u64 module_accessor, int button) {
// bool replace;
// bool ret = Shield::check_button_on(module_accessor, button, replace);
// if (replace) return ret;
// ret = Mash::check_button_on(module_accessor, button, replace);
// if (replace) return ret;
// ret = Tech::check_button_on(module_accessor, button, replace);
// if (replace) return ret;
// ret = Ledge::check_button_on(module_accessor, button, replace);
// if (replace) return ret;
#[allow(unused_unsafe)]
#[skyline::hook(replace = ControlModule::check_button_on)]
pub unsafe fn handle_check_button_on(
module_accessor: &mut app::BattleObjectModuleAccessor,
button: i32) -> bool
{
Shield::check_button_on(module_accessor, button).unwrap_or_else( || {
Mash::check_button_on(module_accessor, button).unwrap_or_else( || {
Tech::check_button_on(module_accessor, button).unwrap_or_else( || {
Ledge::check_button_on(module_accessor, button).unwrap_or_else( || {
original!()(module_accessor, button)
})
})
})
})
}
// u64 control_module = load_module(module_accessor, 0x48);
// bool (*check_button_on)(u64, int) = (bool (*)(u64, int)) load_module_impl(control_module, 0x260);
// return check_button_on(control_module, button);
// }
#[allow(unused_unsafe)]
#[skyline::hook(replace = ControlModule::check_button_off)]
pub unsafe fn handle_check_button_off(
module_accessor: &mut app::BattleObjectModuleAccessor,
button: i32) -> bool
{
Shield::check_button_off(module_accessor, button).unwrap_or_else( || {
original!()(module_accessor, button)
})
}
// bool check_button_off_replace(u64 module_accessor, int button) {
// bool replace;
// bool ret = Shield::check_button_off(module_accessor, button, replace);
// if (replace) return ret;
#[allow(unused_unsafe)]
#[skyline::hook(replace = StatusModule::init_settings)]
pub unsafe fn handle_init_settings(
module_accessor: &mut app::BattleObjectModuleAccessor,
situationKind: i32,
unk1: i32,
unk2: u32,
groundCliffCheckKind: i32,
unk3: bool,
unk4: i32,
unk5: i32,
unk6: i32,
unk7: i32)
{
let status_kind = StatusModule::status_kind(module_accessor) as i32;
Tech::init_settings(module_accessor, status_kind).unwrap_or_else( || {
original!()(module_accessor, situationKind, unk1, unk2, groundCliffCheckKind, unk3, unk4, unk5, unk6, unk7)
})
}
// u64 control_module = load_module(module_accessor, 0x48);
// bool (*check_button_off)(u64, int) = (bool (*)(u64, int)) load_module_impl(control_module, 0x268);
// return check_button_off(control_module, button);
// }
// } // namespace ControlModule
// namespace StatusModule {
// void init_settings_replace(u64 module_accessor, int situationKind, int unk1, uint unk2, int groundCliffCheckKind, bool unk3, int unk4, int unk5, int unk6, int unk7) {
// bool replace;
// Tech::init_settings(module_accessor, StatusModule::status_kind(module_accessor), replace);
// if (replace) return;
// u64 status_module = load_module(module_accessor, 0x40);
// void (*init_settings)(u64,int,int,uint,int,bool,int,int,int,int) =
// (void (*)(u64,int,int,uint,int,bool,int,int,int,int)) load_module_impl(status_module, 0x1C8);
// init_settings(status_module, situationKind, unk1, unk2, groundCliffCheckKind, unk3, unk4, unk5, unk6, unk7);
// }
// } // namespace StatusModule
// namespace MotionModule {
// u64 change_motion_replace(u64 module_accessor, u64 motion_kind, float unk1, float unk2, bool unk3, float unk4, bool unk5, bool unk6) {
// bool replace;
// u64 motion_kind_ret = Tech::change_motion(module_accessor, motion_kind, replace);
// if (replace) motion_kind = motion_kind_ret;
// u64 motion_module = load_module(module_accessor, 0x88);
// u64 change_motion_offset = 0;
// if (major < 4) change_motion_offset = 0xD8;
// else change_motion_offset = 0xE0;
// u64 (*change_motion)(u64,u64,float,float,bool,float,bool,bool) =
// (u64 (*)(u64,u64,float,float,bool,float,bool,bool)) load_module_impl(motion_module, change_motion_offset);
// return change_motion(motion_module, motion_kind, unk1, unk2, unk3, unk4, unk5, unk6);
// }
// } // namespace MotionModule
// } // namespace app::lua_bind
#[allow(unused_unsafe)]
#[skyline::hook(replace = MotionModule::change_motion)]
pub unsafe fn handle_change_motion(
module_accessor: &mut app::BattleObjectModuleAccessor,
motion_kind: u64,
unk1: f32,
unk2: f32,
unk3: bool,
unk4: f32,
unk5: bool,
unk6: bool) -> u64
{
Tech::change_motion(module_accessor, motion_kind).unwrap_or_else( || {
original!()(module_accessor, motion_kind, unk1, unk2, unk3, unk4, unk5, unk6)
})
}
pub fn training_mods() {
println!("Applying hitbox visualization mods.");
// fighter_manager_addr = SaltySDCore_FindSymbol(
// "_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E");
println!("Applying training mods.");
unsafe {
LookupSymbol(&mut fighter_manager_addr, c_str("_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E"));
println!("Lookup symbol output: {:#?}", fighter_manager_addr);
}
// // Mash airdodge/jump
// SaltySD_function_replace_sym_check_prev(
// "_ZN3app8lua_bind40ControlModule__get_command_flag_cat_implEPNS_26BattleObjectModuleAccessorEi",
// (u64)&ControlModule::get_command_flag_cat_replace,
// prev_get_command_flag_cat);
// Mash airdodge/jump
skyline::install_hook!(handle_get_command_flag_cat);
// Set DI
skyline::install_hook!(handle_get_float);
// Hold/Infinite shield
// SaltySD_function_replace_sym(
// "_ZN3app8lua_bind35ControlModule__check_button_on_implEPNS_26BattleObjectModuleAccessorEi",
// (u64)&ControlModule::check_button_on_replace);
// SaltySD_function_replace_sym(
// "_ZN3app8lua_bind36ControlModule__check_button_off_implEPNS_26BattleObjectModuleAccessorEi",
// (u64)&ControlModule::check_button_off_replace);
// SaltySD_function_replace_sym(
// "_ZN3app8lua_bind32WorkModule__get_param_float_implEPNS_26BattleObjectModuleAccessorEmm",
// (u64)&WorkModule::get_param_float_replace);
skyline::install_hook!(handle_check_button_on);
skyline::install_hook!(handle_check_button_off);
// // Mash attack
// SaltySD_function_replace_sym(
// "_ZN3app8lua_bind39ControlModule__get_attack_air_kind_implEPNS_26BattleObjectModuleAccessorE",
// (u64)&ControlModule::get_attack_air_kind_replace);
skyline::install_hook!(handle_get_param_float);
// Mash attack
skyline::install_hook!(handle_get_attack_air_kind);
// // Input recorder
// SaltySD_function_replace_sym(
@ -209,11 +202,7 @@ pub fn training_mods() {
// "_ZN3app8lua_bind31ControlModule__get_stick_y_implEPNS_26BattleObjectModuleAccessorE",
// (u64)&ControlModule::get_stick_y_replace);
// // Tech options
// SaltySD_function_replace_sym(
// "_ZN3app8lua_bind32StatusModule__init_settings_implEPNS_26BattleObjectModuleAccessorENS_13SituationKindEijNS_20GroundCliffCheckKindEbiiii",
// (u64)&StatusModule::init_settings_replace);
// SaltySD_function_replace_sym(
// "_ZN3app8lua_bind32MotionModule__change_motion_implEPNS_26BattleObjectModuleAccessorEN3phx6Hash40Effbfbb",
// (u64)&MotionModule::change_motion_replace);
// Tech options
skyline::install_hook!(handle_init_settings);
skyline::install_hook!(handle_change_motion);
}