mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-20 08:54:15 +00:00
huge migration, get menu working, OoS grab
This commit is contained in:
parent
7a57b8e247
commit
548b306645
10 changed files with 248 additions and 208 deletions
|
@ -7,7 +7,7 @@ use smash::app::lua_bind::{self, *};
|
||||||
use smash::app::{FighterManager, FighterInformation};
|
use smash::app::{FighterManager, FighterInformation};
|
||||||
use smash::hash40;
|
use smash::hash40;
|
||||||
|
|
||||||
pub static menu : consts::TrainingModpackMenu = consts::TrainingModpackMenu{
|
pub static mut menu_struct : consts::TrainingModpackMenu = consts::TrainingModpackMenu{
|
||||||
HITBOX_VIS : true,
|
HITBOX_VIS : true,
|
||||||
DI_STATE : NONE,
|
DI_STATE : NONE,
|
||||||
ATTACK_STATE : MASH_NAIR,
|
ATTACK_STATE : MASH_NAIR,
|
||||||
|
@ -18,6 +18,8 @@ pub static menu : consts::TrainingModpackMenu = consts::TrainingModpackMenu{
|
||||||
DEFENSIVE_STATE : RANDOM_DEFENSIVE,
|
DEFENSIVE_STATE : RANDOM_DEFENSIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub static mut menu : *mut consts::TrainingModpackMenu = 0 as *mut consts::TrainingModpackMenu;
|
||||||
|
|
||||||
pub static mut fighter_manager_addr : usize = 0;
|
pub static mut fighter_manager_addr : usize = 0;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -84,7 +86,7 @@ pub unsafe fn perform_defensive_option(
|
||||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||||
flag: &mut i32)
|
flag: &mut i32)
|
||||||
{
|
{
|
||||||
match menu.DEFENSIVE_STATE {
|
match (*menu).DEFENSIVE_STATE {
|
||||||
RANDOM_DEFENSIVE => {
|
RANDOM_DEFENSIVE => {
|
||||||
let random_cmds = vec![
|
let random_cmds = vec![
|
||||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
|
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
|
||||||
|
|
|
@ -130,15 +130,6 @@ pub unsafe fn generate_hitbox_effects(
|
||||||
let pos = Vector3f{x : x_curr, y : y_curr, z : z_curr};
|
let pos = Vector3f{x : x_curr, y : y_curr, z : z_curr};
|
||||||
let zeros = Vector3f{x : 0.0, y : 0.0, z : 0.0};
|
let zeros = Vector3f{x : 0.0, y : 0.0, z : 0.0};
|
||||||
|
|
||||||
// EffectModule::req_follow(module_accessor,
|
|
||||||
// Hash40{hash: hash40("sys_shield")}, Hash40{hash: bone},
|
|
||||||
// &pos, &zeros, size * size_mult,
|
|
||||||
// true,
|
|
||||||
// *EFFECT_SUB_ATTRIBUTE_NO_JOINT_SCALE as u32 |
|
|
||||||
// *EFFECT_SUB_ATTRIBUTE_FOLLOW as u32 |
|
|
||||||
// *EFFECT_SUB_ATTRIBUTE_CONCLUDE_STATUS as u32,
|
|
||||||
// 0, 0, 0, 0, true, true);
|
|
||||||
|
|
||||||
EffectModule::req_on_joint(module_accessor,
|
EffectModule::req_on_joint(module_accessor,
|
||||||
Hash40{hash: hash40("sys_shield")}, Hash40{hash: bone},
|
Hash40{hash: hash40("sys_shield")}, Hash40{hash: bone},
|
||||||
&pos, &zeros, size * size_mult, &zeros, &zeros,
|
&pos, &zeros, size * size_mult, &zeros, &zeros,
|
||||||
|
@ -159,7 +150,7 @@ pub unsafe fn generate_hitbox_effects(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if menu.HITBOX_VIS && is_training_mode() { // generate hitbox effect(s)
|
// if (*menu).HITBOX_VIS && is_training_mode() { // generate hitbox effect(s)
|
||||||
// let color_scale: f32;
|
// let color_scale: f32;
|
||||||
// if true { // color intensity scales with damage
|
// if true { // color intensity scales with damage
|
||||||
// color_scale = unlerp_bounded(1.0, 18.0, damage.get_num());
|
// color_scale = unlerp_bounded(1.0, 18.0, damage.get_num());
|
||||||
|
@ -198,6 +189,46 @@ pub unsafe fn generate_hitbox_effects(
|
||||||
// color);
|
// color);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
pub unsafe fn get_command_flag_cat(
|
||||||
|
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||||
|
category: i32)
|
||||||
|
{
|
||||||
|
// apply only once per frame
|
||||||
|
if category == 0 && is_training_mode() && (*menu).HITBOX_VIS {
|
||||||
|
// Pause Effect AnimCMD if hitbox visualization is active
|
||||||
|
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
||||||
|
MotionAnimcmdModule::set_sleep_effect(module_accessor,
|
||||||
|
!((*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_TREAD_FALL).contains(&status_kind) ||
|
||||||
|
(*FIGHTER_STATUS_KIND_WAIT..=*FIGHTER_STATUS_KIND_REBOUND_JUMP).contains(&status_kind)));
|
||||||
|
|
||||||
|
if !(*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_CATCH_TURN).contains(&status_kind) {
|
||||||
|
EffectModule::set_visible_kind(module_accessor, Hash40{hash: hash40("sys_shield")}, false);
|
||||||
|
EffectModule::kill_kind(module_accessor, Hash40{hash: hash40("sys_shield")}, false, true);
|
||||||
|
for i in 0..8 {
|
||||||
|
if AttackModule::is_attack(module_accessor, i, false) {
|
||||||
|
let attack_data = *AttackModule::attack_data(module_accessor, i, false);
|
||||||
|
let is_capsule = attack_data.x2 != 0.0 || attack_data.y2 != 0.0 || attack_data.z2 != 0.0;
|
||||||
|
let mut x2 = None;
|
||||||
|
let mut y2 = None;
|
||||||
|
let mut z2 = None;
|
||||||
|
if is_capsule {
|
||||||
|
x2 = Some(attack_data.x2);
|
||||||
|
y2 = Some(attack_data.y2);
|
||||||
|
z2 = Some(attack_data.z2);
|
||||||
|
}
|
||||||
|
generate_hitbox_effects(
|
||||||
|
module_accessor,
|
||||||
|
attack_data.node, // joint
|
||||||
|
attack_data.size,
|
||||||
|
attack_data.x, attack_data.y, attack_data.z,
|
||||||
|
x2, y2, z2,
|
||||||
|
ID_COLORS[(i % 8) as usize]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
#[skyline::hook(replace = sv_animcmd::CATCH)]
|
#[skyline::hook(replace = sv_animcmd::CATCH)]
|
||||||
unsafe fn handle_catch(lua_state: u64) {
|
unsafe fn handle_catch(lua_state: u64) {
|
||||||
|
@ -216,7 +247,7 @@ unsafe fn handle_catch(lua_state: u64) {
|
||||||
|
|
||||||
original!()(lua_state);
|
original!()(lua_state);
|
||||||
|
|
||||||
if menu.HITBOX_VIS && is_training_mode() {
|
if (*menu).HITBOX_VIS && is_training_mode() {
|
||||||
generate_hitbox_effects(
|
generate_hitbox_effects(
|
||||||
sv_system::battle_object_module_accessor(lua_state),
|
sv_system::battle_object_module_accessor(lua_state),
|
||||||
joint.get_int(),
|
joint.get_int(),
|
||||||
|
|
156
src/lib.rs
156
src/lib.rs
|
@ -5,6 +5,7 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
#![feature(with_options)]
|
#![feature(with_options)]
|
||||||
|
#![feature(asm)]
|
||||||
|
|
||||||
mod hitbox_visualizer;
|
mod hitbox_visualizer;
|
||||||
mod training;
|
mod training;
|
||||||
|
@ -17,36 +18,29 @@ use smash::app::{self};
|
||||||
use smash::app::lua_bind::{*};
|
use smash::app::lua_bind::{*};
|
||||||
use smash::app::sv_animcmd::{self};
|
use smash::app::sv_animcmd::{self};
|
||||||
use smash::app::sv_system::{self};
|
use smash::app::sv_system::{self};
|
||||||
|
use smash::lua2cpp::L2CFighterCommon;
|
||||||
use skyline::libc::{size_t, c_int, c_void, strlen, fopen, fwrite, fclose};
|
use skyline::libc::{size_t, c_int, c_void, strlen, fopen, fwrite, fclose};
|
||||||
use smash::Result;
|
use smash::Result;
|
||||||
use skyline::nn;
|
use skyline::nn;
|
||||||
use skyline::patching::patch_data_from_text;
|
use skyline::patching::patch_data_from_text;
|
||||||
use skyline::{from_c_str, c_str, hooks::A64HookFunction, logging::hex_dump_ptr};
|
use skyline::{from_c_str, c_str, hooks::A64HookFunction, logging::hex_dump_ptr, logging::HexDump};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use skyline::nro::{self, NroInfo};
|
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)]
|
#[allow(unused_unsafe)]
|
||||||
#[skyline::hook(replace = status_AttackAirMain_common)]
|
#[skyline::hook(replace = smash::lua2cpp::L2CFighterCommon_sub_guard_cont)]
|
||||||
pub unsafe fn handle_AttackAirMain(fighter: *mut L2CAgent) {
|
pub unsafe fn handle_sub_guard_cont(fighter: &mut L2CFighterCommon) -> L2CValue {
|
||||||
CancelModule::enable_cancel(sv_system::battle_object_module_accessor((*fighter).lua_state_agent));
|
let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent);
|
||||||
original!()(fighter);
|
if (*menu).MASH_STATE == MASH_ATTACK && (*menu).ATTACK_STATE == MASH_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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
original!()(fighter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nro_main(nro: &NroInfo) {
|
fn nro_main(nro: &NroInfo) {
|
||||||
|
@ -54,27 +48,8 @@ fn nro_main(nro: &NroInfo) {
|
||||||
"common" =>
|
"common" =>
|
||||||
{
|
{
|
||||||
println!("Loaded common NRO!");
|
println!("Loaded common NRO!");
|
||||||
unsafe {
|
skyline::install_hook!(handle_sub_guard_cont);
|
||||||
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);
|
|
||||||
println!("Hooked!");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"item" => println!("Loaded item NRO!"),
|
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,14 +57,14 @@ fn nro_main(nro: &NroInfo) {
|
||||||
#[skyline::main(name = "test")]
|
#[skyline::main(name = "test")]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
println!("Training modpack initialized.");
|
println!("Training modpack initialized.");
|
||||||
// hitbox_visualizer::hitbox_visualization();
|
hitbox_visualizer::hitbox_visualization();
|
||||||
training::training_mods();
|
training::training_mods();
|
||||||
nro::add_hook(nro_main).unwrap();
|
nro::add_hook(nro_main).unwrap();
|
||||||
|
|
||||||
let buffer = format!("{:x}", &common::menu as *const _ as u64);
|
|
||||||
println!("Writing training_modpack.log with {}...\n", buffer);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// let f = fopen(c_str("sd:/test.log"), c_str("w"));
|
common::menu = &mut common::menu_struct;
|
||||||
|
let buffer = format!("{:x}", common::menu as u64);
|
||||||
|
println!("Writing training_modpack.log with {}...\n", buffer);
|
||||||
let f = fopen("sd:/SaltySD/training_modpack.log\u{0}".as_bytes().as_ptr(), "w\u{0}".as_bytes().as_ptr());
|
let f = fopen("sd:/SaltySD/training_modpack.log\u{0}".as_bytes().as_ptr(), "w\u{0}".as_bytes().as_ptr());
|
||||||
|
|
||||||
println!("File pointer: {:#?}", f);
|
println!("File pointer: {:#?}", f);
|
||||||
|
@ -98,93 +73,4 @@ pub fn main() {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fs::File::create("sd:/test.log").unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #![feature(proc_macro_hygiene)]
|
|
||||||
|
|
||||||
// use smash::hash40;
|
|
||||||
// use smash::lib::lua_const::{*};
|
|
||||||
// use smash::lib::{self, L2CAgent, L2CValue};
|
|
||||||
// use smash::app;
|
|
||||||
// use smash::app::{lua_bind::*, sv_animcmd, sv_system};
|
|
||||||
// use skyline::libc::{size_t, c_int, c_void, strlen};
|
|
||||||
// use smash::Result;
|
|
||||||
// use skyline::nro::{self, NroInfo};
|
|
||||||
// use skyline::logging::HexDump;
|
|
||||||
|
|
||||||
// extern "C" {
|
|
||||||
// #[link_name = "\u{1}_ZN7lua2cpp16L2CFighterCommon17status_Catch_MainEv"]
|
|
||||||
// pub fn status_Catch_Main(
|
|
||||||
// arg1: *mut L2CAgent
|
|
||||||
// ) -> u64;
|
|
||||||
|
|
||||||
// #[link_name = "\u{1}_ZN7lua2cpp16L2CFighterCommon28sub_wait_ground_check_commonEN3lib8L2CValueE"]
|
|
||||||
// pub fn sub_wait_ground_check_common(
|
|
||||||
// arg1: *mut L2CAgent,
|
|
||||||
// arg2: L2CValue
|
|
||||||
// ) -> L2CValue;
|
|
||||||
|
|
||||||
// #[link_name = "\u{1}_ZN7lua2cpp16L2CFighterCommon25sub_air_check_fall_commonEv"]
|
|
||||||
// pub fn sub_air_check_fall_common(
|
|
||||||
// arg1: *mut L2CAgent
|
|
||||||
// ) -> L2CValue;
|
|
||||||
|
|
||||||
// #[link_name = "\u{1}_ZN7lua2cpp14L2CFighterBase13change_statusEN3lib8L2CValueES2_"]
|
|
||||||
// pub fn change_status(
|
|
||||||
// arg1: *mut L2CAgent,
|
|
||||||
// arg2: L2CValue,
|
|
||||||
// arg3: L2CValue
|
|
||||||
// ) -> u64;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[allow(unused_unsafe)]
|
|
||||||
// #[skyline::hook(replace = status_Catch_Main)]
|
|
||||||
// pub unsafe fn handle_status_Catch_Main(fighter: *mut L2CAgent) {
|
|
||||||
// let module_accessor = sv_system::battle_object_module_accessor((*fighter).lua_state_agent);
|
|
||||||
// // if CancelModule::is_enable_cancel(module_accessor) {
|
|
||||||
// // let ret = sub_wait_ground_check_common(fighter, L2CValue::new_bool(false));
|
|
||||||
// // println!("{}", HexDump(&ret));
|
|
||||||
// // // sub_air_check_fall_common(fighter);
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// let situation_kind = StatusModule::situation_kind(module_accessor) as i32;
|
|
||||||
// if situation_kind == SITUATION_KIND_AIR {
|
|
||||||
// // change_status(fighter,L2CValue::new_int(*FIGHTER_STATUS_KIND_FALL as u64), L2CValue::new_bool(false));
|
|
||||||
// StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_FALL, false);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if WorkModule::is_enable_transition_term(module_accessor,*FIGHTER_STATUS_TRANSITION_TERM_ID_WAIT) {
|
|
||||||
// if MotionModule::is_end(module_accessor) {
|
|
||||||
// if situation_kind != SITUATION_KIND_GROUND {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// // change_status(fighter,L2CValue::new_int(*FIGHTER_STATUS_KIND_WAIT as u64), L2CValue::new_bool(false));
|
|
||||||
// StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_WAIT, false);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // original!()(fighter); // to call original
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn nro_main(nro: &NroInfo) {
|
|
||||||
// match nro.name {
|
|
||||||
// "common" =>
|
|
||||||
// {
|
|
||||||
// println!("Loaded common NRO!");
|
|
||||||
// skyline::install_hook!(handle_status_Catch_Main);
|
|
||||||
// println!("change_status: {:p}", change_status as *const());
|
|
||||||
// println!("sub_air_check_fall_common: {:p}", sub_air_check_fall_common as *const());
|
|
||||||
// println!("sub_wait_ground_check_common: {:p}", sub_wait_ground_check_common as *const());
|
|
||||||
// },
|
|
||||||
// _ => ()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[skyline::main(name = "test")]
|
|
||||||
// pub fn main() {
|
|
||||||
// println!("Hello from Skyline plugin!");
|
|
||||||
// nro::add_hook(nro_main).unwrap();
|
|
||||||
// }
|
|
||||||
|
|
|
@ -13,11 +13,11 @@ pub unsafe fn get_float(module_accessor: &mut app::BattleObjectModuleAccessor, v
|
||||||
if is_training_mode() &&
|
if is_training_mode() &&
|
||||||
is_operation_cpu(module_accessor) &&
|
is_operation_cpu(module_accessor) &&
|
||||||
is_in_hitstun(module_accessor) {
|
is_in_hitstun(module_accessor) {
|
||||||
if menu.DI_STATE != NONE {
|
if (*menu).DI_STATE != NONE {
|
||||||
let mut angle = (menu.DI_STATE - 1) as f64 * PI / 4.0;
|
let mut angle = ((*menu).DI_STATE - 1) as f64 * PI / 4.0;
|
||||||
|
|
||||||
// Either 0 (right) or PI (left)
|
// Either 0 (right) or PI (left)
|
||||||
if menu.DI_STATE == DI_RANDOM_IN_AWAY {
|
if (*menu).DI_STATE == DI_RANDOM_IN_AWAY {
|
||||||
angle = app::sv_math::rand(hash40("fighter"), 2) as f64 * PI;
|
angle = app::sv_math::rand(hash40("fighter"), 2) as f64 * PI;
|
||||||
}
|
}
|
||||||
// If facing left, reverse angle
|
// If facing left, reverse angle
|
||||||
|
|
|
@ -21,10 +21,10 @@ pub unsafe fn force_option(
|
||||||
let mut status = 0;
|
let mut status = 0;
|
||||||
let ledge_case : i32;
|
let ledge_case : i32;
|
||||||
|
|
||||||
if menu.LEDGE_STATE == RANDOM_LEDGE {
|
if (*menu).LEDGE_STATE == RANDOM_LEDGE {
|
||||||
ledge_case = app::sv_math::rand(hash40("fighter"), 4) + 2;
|
ledge_case = app::sv_math::rand(hash40("fighter"), 4) + 2;
|
||||||
} else {
|
} else {
|
||||||
ledge_case = menu.LEDGE_STATE;
|
ledge_case = (*menu).LEDGE_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
match ledge_case {
|
match ledge_case {
|
||||||
|
@ -85,7 +85,7 @@ pub unsafe fn check_button_on(
|
||||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||||
if menu.DEFENSIVE_STATE == DEFENSIVE_SHIELD &&
|
if (*menu).DEFENSIVE_STATE == DEFENSIVE_SHIELD &&
|
||||||
should_perform_defensive_option(
|
should_perform_defensive_option(
|
||||||
module_accessor, prev_status, status) {
|
module_accessor, prev_status, status) {
|
||||||
return Some(true)
|
return Some(true)
|
||||||
|
@ -101,7 +101,7 @@ pub unsafe fn get_command_flag_cat(
|
||||||
category: i32,
|
category: i32,
|
||||||
flag: &mut i32)
|
flag: &mut i32)
|
||||||
{
|
{
|
||||||
if menu.LEDGE_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
|
if (*menu).LEDGE_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
|
||||||
force_option(module_accessor);
|
force_option(module_accessor);
|
||||||
defensive_option(module_accessor, category, flag);
|
defensive_option(module_accessor, category, flag);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ pub unsafe fn get_attack_air_kind(
|
||||||
module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<i32>
|
module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<i32>
|
||||||
{
|
{
|
||||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||||
if menu.MASH_STATE == MASH_ATTACK {
|
if (*menu).MASH_STATE == MASH_ATTACK {
|
||||||
match menu.ATTACK_STATE {
|
match (*menu).ATTACK_STATE {
|
||||||
MASH_NAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_N),
|
MASH_NAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_N),
|
||||||
MASH_FAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_F),
|
MASH_FAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_F),
|
||||||
MASH_BAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_B),
|
MASH_BAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_B),
|
||||||
|
@ -20,7 +20,7 @@ pub unsafe fn get_attack_air_kind(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu.MASH_STATE == MASH_RANDOM {
|
if (*menu).MASH_STATE == MASH_RANDOM {
|
||||||
return Some(app::sv_math::rand(hash40("fighter"), 5) + 1);
|
return Some(app::sv_math::rand(hash40("fighter"), 5) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ pub unsafe fn get_command_flag_cat(
|
||||||
{
|
{
|
||||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
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) {
|
if is_in_hitstun(module_accessor) || is_in_landing(module_accessor) || is_in_shieldstun(module_accessor) {
|
||||||
match menu.MASH_STATE {
|
match (*menu).MASH_STATE {
|
||||||
MASH_AIRDODGE => {
|
MASH_AIRDODGE => {
|
||||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
|
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
|
||||||
|
@ -53,7 +53,7 @@ pub unsafe fn get_command_flag_cat(
|
||||||
},
|
},
|
||||||
MASH_ATTACK => {
|
MASH_ATTACK => {
|
||||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||||
match menu.ATTACK_STATE {
|
match (*menu).ATTACK_STATE {
|
||||||
MASH_NAIR |
|
MASH_NAIR |
|
||||||
MASH_FAIR |
|
MASH_FAIR |
|
||||||
MASH_BAIR |
|
MASH_BAIR |
|
||||||
|
@ -74,7 +74,7 @@ pub unsafe fn get_command_flag_cat(
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
} else if category == 1 {
|
} else if category == 1 {
|
||||||
if menu.ATTACK_STATE == MASH_GRAB { *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH; }
|
if (*menu).ATTACK_STATE == MASH_GRAB { *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH; }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MASH_RANDOM => {
|
MASH_RANDOM => {
|
||||||
|
@ -140,7 +140,7 @@ pub unsafe fn check_button_on(
|
||||||
{
|
{
|
||||||
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
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)) {
|
if (*menu).MASH_STATE == MASH_AIRDODGE && (is_in_hitstun(module_accessor) || is_in_landing(module_accessor)) {
|
||||||
return Some(true)
|
return Some(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ pub unsafe fn check_button_on(
|
||||||
|
|
||||||
if [*CONTROL_PAD_BUTTON_ATTACK, *CONTROL_PAD_BUTTON_CATCH].contains(&button) {
|
if [*CONTROL_PAD_BUTTON_ATTACK, *CONTROL_PAD_BUTTON_CATCH].contains(&button) {
|
||||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
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) {
|
if (*menu).MASH_STATE == MASH_ATTACK && (*menu).ATTACK_STATE == MASH_GRAB && is_in_shieldstun(module_accessor) {
|
||||||
return Some(true)
|
return Some(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
127
src/training/SaveStates.rs
Normal file
127
src/training/SaveStates.rs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
use smash::{hash40, phx::Hash40, phx::Vector3f};
|
||||||
|
use smash::app::{self};
|
||||||
|
use smash::app::lua_bind::*;
|
||||||
|
use smash::lib::lua_const::*;
|
||||||
|
use crate::common::*;
|
||||||
|
use crate::common::consts::*;
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
enum SaveState {
|
||||||
|
Save,
|
||||||
|
NoAction,
|
||||||
|
CameraMove,
|
||||||
|
PosMove,
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::training::SaveStates::SaveState::*;
|
||||||
|
|
||||||
|
static mut save_state_player_state : SaveState = NoAction;
|
||||||
|
static mut save_state_cpu_state : SaveState = NoAction;
|
||||||
|
static mut save_state_move_alert : bool = false;
|
||||||
|
|
||||||
|
static mut save_state_x_player : f32 = 0.0;
|
||||||
|
static mut save_state_y_player : f32 = 0.0;
|
||||||
|
static mut save_state_percent_player : f32 = 0.0;
|
||||||
|
static mut save_state_lr_player : f32 = 1.0;
|
||||||
|
static mut save_state_situation_kind_player : i32 = 0 as i32;
|
||||||
|
|
||||||
|
static mut save_state_x_cpu : f32 = 0.0;
|
||||||
|
static mut save_state_y_cpu : f32 = 0.0;
|
||||||
|
static mut save_state_percent_cpu : f32 = 0.0;
|
||||||
|
static mut save_state_lr_cpu : f32 = 1.0;
|
||||||
|
static mut save_state_situation_kind_cpu : i32 = 0 as i32;
|
||||||
|
|
||||||
|
pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||||
|
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||||
|
if is_training_mode() {
|
||||||
|
let save_state_x : *mut f32;
|
||||||
|
let save_state_y : *mut f32;
|
||||||
|
let save_state_percent : *mut f32;
|
||||||
|
let save_state_lr : *mut f32;
|
||||||
|
let save_state_situation_kind : *mut i32;
|
||||||
|
let save_state : *mut SaveState;
|
||||||
|
if is_operation_cpu(module_accessor) {
|
||||||
|
save_state_x = &mut save_state_x_cpu;
|
||||||
|
save_state_y = &mut save_state_y_cpu;
|
||||||
|
save_state_percent = &mut save_state_percent_cpu;
|
||||||
|
save_state_lr = &mut save_state_lr_cpu;
|
||||||
|
save_state_situation_kind = &mut save_state_situation_kind_cpu;
|
||||||
|
save_state = &mut save_state_cpu_state;
|
||||||
|
} else {
|
||||||
|
save_state_x = &mut save_state_x_player;
|
||||||
|
save_state_y = &mut save_state_y_player;
|
||||||
|
save_state_percent = &mut save_state_percent_player;
|
||||||
|
save_state_lr = &mut save_state_lr_player;
|
||||||
|
save_state_situation_kind = &mut save_state_situation_kind_player;
|
||||||
|
save_state = &mut save_state_player_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab + Dpad up: reset state
|
||||||
|
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH) != 0 &&
|
||||||
|
ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI) != 0 {
|
||||||
|
if *save_state == NoAction {
|
||||||
|
save_state_player_state = CameraMove;
|
||||||
|
save_state_cpu_state = CameraMove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to camera bounds
|
||||||
|
if *save_state == CameraMove {
|
||||||
|
*save_state = PosMove;
|
||||||
|
|
||||||
|
let left_right = (*save_state_x > 0.0) as i32 as f32 - (*save_state_x < 0.0) as i32 as f32;
|
||||||
|
let mut y_pos = 0.0;
|
||||||
|
if *save_state_situation_kind == SITUATION_KIND_GROUND {
|
||||||
|
y_pos = -50.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos = Vector3f{x : left_right * 50.0, y : y_pos, z : 0.0};
|
||||||
|
PostureModule::set_pos(module_accessor, &pos);
|
||||||
|
StatusModule::set_situation_kind(module_accessor, app::SituationKind{situation_kind: *SITUATION_KIND_AIR}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to correct pos
|
||||||
|
if *save_state == PosMove {
|
||||||
|
let pos = Vector3f{x : *save_state_x, y : *save_state_y, z : 0.0};
|
||||||
|
PostureModule::set_pos(module_accessor, &pos);
|
||||||
|
PostureModule::set_lr(module_accessor, *save_state_lr);
|
||||||
|
// DamageModule::add_damage(
|
||||||
|
// module_accessor,
|
||||||
|
// -1.0 * DamageModule::damage(module_accessor, 0), 0);
|
||||||
|
DamageModule::heal(module_accessor, -1.0 * DamageModule::damage(module_accessor, 0), 0);
|
||||||
|
DamageModule::add_damage(module_accessor, *save_state_percent, 0);
|
||||||
|
|
||||||
|
StatusModule::set_situation_kind(module_accessor, app::SituationKind{situation_kind: *save_state_situation_kind}, false);
|
||||||
|
|
||||||
|
// Doesn't work, and I don't know why yet.
|
||||||
|
// if *save_state_situation_kind == SITUATION_KIND_GROUND && status != FIGHTER_STATUS_KIND_WAIT {
|
||||||
|
// StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_WAIT, false);
|
||||||
|
// }
|
||||||
|
// else if (*save_state_situation_kind == SITUATION_KIND_AIR && status != FIGHTER_STATUS_KIND_FALL)
|
||||||
|
// StatusModule::change_status_request(module_accessor, FIGHTER_STATUS_KIND_FALL, 0);
|
||||||
|
if *save_state_situation_kind == SITUATION_KIND_CLIFF && status != FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE
|
||||||
|
&& status != FIGHTER_STATUS_KIND_CLIFF_CATCH {
|
||||||
|
StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
*save_state = NoAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab + Dpad down: Save state
|
||||||
|
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH) != 0 &&
|
||||||
|
ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_LW) != 0 {
|
||||||
|
save_state_player_state = Save;
|
||||||
|
save_state_cpu_state = Save;
|
||||||
|
}
|
||||||
|
|
||||||
|
if *save_state == Save {
|
||||||
|
*save_state = NoAction;
|
||||||
|
|
||||||
|
*save_state_x = PostureModule::pos_x(module_accessor);
|
||||||
|
*save_state_y = PostureModule::pos_y(module_accessor);
|
||||||
|
*save_state_lr = PostureModule::lr(module_accessor);
|
||||||
|
*save_state_percent = DamageModule::damage(module_accessor, 0);
|
||||||
|
*save_state_situation_kind = StatusModule::situation_kind(module_accessor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ use crate::common::consts::*;
|
||||||
|
|
||||||
pub unsafe fn get_param_float(module_accessor: &mut app::BattleObjectModuleAccessor, param_type: u64, param_hash: u64) -> Option<f32> {
|
pub unsafe fn get_param_float(module_accessor: &mut app::BattleObjectModuleAccessor, param_type: u64, param_hash: u64) -> Option<f32> {
|
||||||
if is_training_mode() {
|
if is_training_mode() {
|
||||||
if menu.SHIELD_STATE == SHIELD_INFINITE {
|
if (*menu).SHIELD_STATE == SHIELD_INFINITE {
|
||||||
if param_type == hash40("common") {
|
if param_type == hash40("common") {
|
||||||
if param_hash == hash40("shield_dec1") {
|
if param_hash == hash40("shield_dec1") {
|
||||||
return Some(0.0)
|
return Some(0.0)
|
||||||
|
@ -29,9 +29,9 @@ pub unsafe fn get_param_float(module_accessor: &mut app::BattleObjectModuleAcces
|
||||||
|
|
||||||
pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||||
// We should hold shield if the state requires it
|
// We should hold shield if the state requires it
|
||||||
if [SHIELD_HOLD, SHIELD_INFINITE].contains(&menu.SHIELD_STATE) {
|
if [SHIELD_HOLD, SHIELD_INFINITE].contains(&(*menu).SHIELD_STATE) {
|
||||||
// If we are not mashing then we will always hold shield
|
// If we are not mashing then we will always hold shield
|
||||||
if menu.MASH_STATE == NONE {
|
if (*menu).MASH_STATE == NONE {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAc
|
||||||
}
|
}
|
||||||
|
|
||||||
// We will only drop shield if we are in shieldstun and our attack can be performed OOS
|
// We will only drop shield if we are in shieldstun and our attack can be performed OOS
|
||||||
if menu.MASH_STATE == MASH_ATTACK {
|
if (*menu).MASH_STATE == MASH_ATTACK {
|
||||||
if [MASH_NEUTRAL_B, MASH_SIDE_B, MASH_DOWN_B].contains(&menu.ATTACK_STATE) {
|
if [MASH_NEUTRAL_B, MASH_SIDE_B, MASH_DOWN_B].contains(&(*menu).ATTACK_STATE) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub unsafe fn init_settings(
|
||||||
{
|
{
|
||||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||||
if status_kind == FIGHTER_STATUS_KIND_DOWN {
|
if status_kind == FIGHTER_STATUS_KIND_DOWN {
|
||||||
match menu.TECH_STATE {
|
match (*menu).TECH_STATE {
|
||||||
RANDOM_TECH => {
|
RANDOM_TECH => {
|
||||||
let random_statuses = vec![
|
let random_statuses = vec![
|
||||||
*FIGHTER_STATUS_KIND_DOWN,
|
*FIGHTER_STATUS_KIND_DOWN,
|
||||||
|
@ -79,7 +79,7 @@ pub unsafe fn get_command_flag_cat(
|
||||||
category: i32,
|
category: i32,
|
||||||
flag: &mut i32)
|
flag: &mut i32)
|
||||||
{
|
{
|
||||||
if menu.TECH_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
|
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 prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||||
let status = StatusModule::status_kind(module_accessor) 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) {
|
if [*FIGHTER_STATUS_KIND_DOWN_WAIT, *FIGHTER_STATUS_KIND_DOWN_WAIT_CONTINUE].contains(&status) {
|
||||||
|
@ -105,7 +105,7 @@ pub unsafe fn check_button_on(
|
||||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||||
if menu.DEFENSIVE_STATE == DEFENSIVE_SHIELD &&
|
if (*menu).DEFENSIVE_STATE == DEFENSIVE_SHIELD &&
|
||||||
should_perform_defensive_option(module_accessor, prev_status, status) {
|
should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||||
return Some(true)
|
return Some(true)
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ pub unsafe fn change_motion(
|
||||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||||
motion_kind: u64) -> Option<u64>
|
motion_kind: u64) -> Option<u64>
|
||||||
{
|
{
|
||||||
if menu.TECH_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
|
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 [hash40("passive_stand_f"), hash40("passive_stand_b")].contains(&motion_kind) {
|
||||||
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
|
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
|
||||||
return Some(hash40("passive_stand_f"))
|
return Some(hash40("passive_stand_f"))
|
||||||
|
|
|
@ -13,6 +13,7 @@ mod Shield;
|
||||||
mod Tech;
|
mod Tech;
|
||||||
mod Mash;
|
mod Mash;
|
||||||
mod Ledge;
|
mod Ledge;
|
||||||
|
mod SaveStates;
|
||||||
|
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
#[skyline::hook(replace = WorkModule::get_float)]
|
#[skyline::hook(replace = WorkModule::get_float)]
|
||||||
|
@ -48,42 +49,7 @@ pub unsafe fn handle_get_command_flag_cat(
|
||||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||||
category: i32) -> i32
|
category: i32) -> i32
|
||||||
{
|
{
|
||||||
//save_states(module_accessor);
|
SaveStates::save_states(module_accessor);
|
||||||
|
|
||||||
// apply only once per frame
|
|
||||||
if category == 0 && is_training_mode() && menu.HITBOX_VIS {
|
|
||||||
// Pause Effect AnimCMD if hitbox visualization is active
|
|
||||||
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
|
||||||
MotionAnimcmdModule::set_sleep_effect(module_accessor,
|
|
||||||
!((*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_TREAD_FALL).contains(&status_kind) ||
|
|
||||||
(*FIGHTER_STATUS_KIND_WAIT..=*FIGHTER_STATUS_KIND_REBOUND_JUMP).contains(&status_kind)));
|
|
||||||
|
|
||||||
if !(*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_CATCH_TURN).contains(&status_kind) {
|
|
||||||
EffectModule::set_visible_kind(module_accessor, Hash40{hash: hash40("sys_shield")}, false);
|
|
||||||
EffectModule::kill_kind(module_accessor, Hash40{hash: hash40("sys_shield")}, false, true);
|
|
||||||
for i in 0..8 {
|
|
||||||
if AttackModule::is_attack(module_accessor, i, false) {
|
|
||||||
let attack_data = *AttackModule::attack_data(module_accessor, i, false);
|
|
||||||
let is_capsule = attack_data.x2 != 0.0 || attack_data.y2 != 0.0 || attack_data.z2 != 0.0;
|
|
||||||
let mut x2 = None;
|
|
||||||
let mut y2 = None;
|
|
||||||
let mut z2 = None;
|
|
||||||
if is_capsule {
|
|
||||||
x2 = Some(attack_data.x2);
|
|
||||||
y2 = Some(attack_data.y2);
|
|
||||||
z2 = Some(attack_data.z2);
|
|
||||||
}
|
|
||||||
hitbox_visualizer::generate_hitbox_effects(
|
|
||||||
module_accessor,
|
|
||||||
attack_data.node_, // joint
|
|
||||||
attack_data.size_,
|
|
||||||
attack_data.x, attack_data.y, attack_data.z,
|
|
||||||
x2, y2, z2,
|
|
||||||
hitbox_visualizer::ID_COLORS[(i % 8) as usize]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut flag = original!()(module_accessor, category);
|
let mut flag = original!()(module_accessor, category);
|
||||||
|
|
||||||
|
@ -94,6 +60,7 @@ pub unsafe fn handle_get_command_flag_cat(
|
||||||
Mash::get_command_flag_cat(module_accessor, category, &mut flag);
|
Mash::get_command_flag_cat(module_accessor, category, &mut flag);
|
||||||
Ledge::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);
|
Tech::get_command_flag_cat(module_accessor, category, &mut flag);
|
||||||
|
hitbox_visualizer::get_command_flag_cat(module_accessor, category);
|
||||||
|
|
||||||
flag
|
flag
|
||||||
}
|
}
|
||||||
|
@ -199,6 +166,32 @@ pub unsafe fn handle_change_motion(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
|
#[skyline::hook(replace = sv_animcmd::ATTACK)]
|
||||||
|
pub unsafe fn handle_attack(lua_state: u64) {
|
||||||
|
let mut l2c_agent = L2CAgent::new(lua_state);
|
||||||
|
|
||||||
|
// get all necessary grabbox params
|
||||||
|
let id = l2c_agent.pop_lua_stack(1); // int
|
||||||
|
|
||||||
|
// hacky way of forcing no shield damage on all hitboxes
|
||||||
|
if is_training_mode() && (*menu).SHIELD_STATE == SHIELD_INFINITE {
|
||||||
|
let hitbox_params : Vec<L2CValue> = (0..36).map(|i| l2c_agent.pop_lua_stack(i+1)).collect();
|
||||||
|
l2c_agent.clear_lua_stack();
|
||||||
|
for i in 0..36 {
|
||||||
|
let mut x = hitbox_params[i];
|
||||||
|
if i == 20 {
|
||||||
|
l2c_agent.push_lua_stack(&mut L2CValue::new_num(-999.0));
|
||||||
|
} else {
|
||||||
|
l2c_agent.push_lua_stack(&mut x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
original!()(lua_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn training_mods() {
|
pub fn training_mods() {
|
||||||
println!("Applying training mods.");
|
println!("Applying training mods.");
|
||||||
|
@ -216,6 +209,7 @@ pub fn training_mods() {
|
||||||
// Hold/Infinite shield
|
// Hold/Infinite shield
|
||||||
skyline::install_hook!(handle_check_button_on);
|
skyline::install_hook!(handle_check_button_on);
|
||||||
skyline::install_hook!(handle_check_button_off);
|
skyline::install_hook!(handle_check_button_off);
|
||||||
|
skyline::install_hook!(handle_attack);
|
||||||
|
|
||||||
skyline::install_hook!(handle_get_param_float);
|
skyline::install_hook!(handle_get_param_float);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue