From e74ee787f32867f949c17ccf007cd4af88b7c8f4 Mon Sep 17 00:00:00 2001 From: jugeeya Date: Tue, 8 Sep 2020 21:10:27 -0700 Subject: [PATCH] Fix infinite shield with projectiles --- Cargo.toml | 2 +- src/hitbox_visualizer/mod.rs | 17 +------------- src/lib.rs | 8 +++---- src/training/mod.rs | 43 ++++++++++++++++++++++++++++++++++++ src/training/shield.rs | 18 +++++++++++---- 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1fb0b35..ffeaa41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib"] [dependencies] skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" } skyline_smash = { git = "https://github.com/ultimate-research/skyline-smash.git" } -bitflags = "1.0" +bitflags = "1.2.1" # skyline = { path = "../../../../src/skyline-rs" } # skyline_smash = { path = "../../../../src/skyline-smash" } diff --git a/src/hitbox_visualizer/mod.rs b/src/hitbox_visualizer/mod.rs index 81a74aa..11fe1af 100644 --- a/src/hitbox_visualizer/mod.rs +++ b/src/hitbox_visualizer/mod.rs @@ -1,6 +1,6 @@ use crate::common::{consts::*, *}; use smash::app::{self, lua_bind::*, sv_animcmd, sv_system}; -use smash::lib::{lua_const::*, L2CAgent, L2CValue}; +use smash::lib::{lua_const::*, L2CAgent}; use smash::phx::{Hash40, Vector3f}; pub const ID_COLORS: &[Vector3f] = &[ @@ -221,21 +221,6 @@ unsafe fn handle_attack(lua_state: u64) { unsafe fn mod_handle_attack(lua_state: u64) { let mut l2c_agent = L2CAgent::new(lua_state); - // hacky way of forcing no shield damage on all hitboxes - if MENU.shield_state == Shield::Infinite { - let hitbox_params: Vec = - (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); - } - } - } - // Hitbox Visualization if MENU.hitbox_vis == HitboxVisualization::On { // get all necessary grabbox params diff --git a/src/lib.rs b/src/lib.rs index 7257322..1792183 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,8 @@ #![feature(const_mut_refs)] mod common; -mod hitbox_visualizer; mod hazard_manager; +mod hitbox_visualizer; mod training; #[macro_use] @@ -31,9 +31,9 @@ fn nro_main(nro: &NroInfo<'_>) { } macro_rules! c_str { - ($l:tt) => { [$l.as_bytes(), "\u{0}".as_bytes()] - .concat() - .as_ptr(); } + ($l:tt) => { + [$l.as_bytes(), "\u{0}".as_bytes()].concat().as_ptr(); + }; } #[skyline::main(name = "training_modpack")] diff --git a/src/training/mod.rs b/src/training/mod.rs index 00dc0d5..2aad151 100644 --- a/src/training/mod.rs +++ b/src/training/mod.rs @@ -73,6 +73,8 @@ pub unsafe fn handle_get_command_flag_cat( ) -> i32 { let mut flag = original!()(module_accessor, category); + shield::param_installer(); + if !is_training_mode() { return flag; } @@ -292,6 +294,34 @@ pub unsafe fn handle_set_dead_rumble(lua_state: u64) -> u64 { original!()(lua_state) } +pub static mut COMMON_OBJ: u64 = 0; +// 8.1.0 Offset +static mut LOAD_PRC_FILE_OFFSET: usize = 0x34369d0; + +static LOAD_PRC_FILE_SEARCH_CODE: &[u8] = &[ + 0xff, 0xc3, 0x01, 0xd1, 0xff, 0xdf, 0x02, 0xa9, 0xf6, 0x57, 0x04, 0xa9, 0xf4, 0x4f, 0x05, 0xa9, + 0xfd, 0x7b, 0x06, 0xa9, 0xfd, 0x83, 0x01, 0x91, 0xf6, 0x5f, 0x00, 0x32, 0x88, 0x79, 0x00, 0xb0, + 0x08, 0xed, 0x0f, 0x91, 0xf3, 0x03, 0x00, 0xaa, 0xe8, 0x07, 0x00, 0xf9, 0xe8, 0x03, 0x00, 0x91, + 0x3f, 0x00, 0x16, 0x6b, +]; + +#[skyline::hook(offset = LOAD_PRC_FILE_OFFSET)] +unsafe fn load_once_common_params(common_obj: u64, table1_idx: u32) { + let loaded_tables = smash::resource::LoadedTables::get_instance(); + let hash = loaded_tables.get_hash_from_t1_index(table1_idx).as_u64(); + + if hash == smash::phx::Hash40::new("fighter/common/param/common.prc").hash { + COMMON_OBJ = common_obj; + } + original!()(common_obj, table1_idx) +} + +fn find_subsequence(haystack: &[u8], needle: &[u8]) -> Option { + haystack + .windows(needle.len()) + .position(|window| window == needle) +} + pub fn training_mods() { println!("[Training Modpack] Applying training mods."); unsafe { @@ -308,6 +338,17 @@ pub fn training_mods() { .as_bytes() .as_ptr(), ); + + use skyline::hooks::{getRegionAddress, Region}; + + let text_ptr = getRegionAddress(Region::Text) as *const u8; + let text_size = (getRegionAddress(Region::Rodata) as usize) - (text_ptr as usize); + let text = std::slice::from_raw_parts(text_ptr, text_size); + if let Some(offset) = find_subsequence(text, LOAD_PRC_FILE_SEARCH_CODE) { + LOAD_PRC_FILE_OFFSET = offset; + } else { + println!("Error: no offset found for function 'load_prc_file'. Defaulting to 8.1.0 offset. This likely won't work."); + } } skyline::install_hooks!( @@ -334,6 +375,8 @@ pub fn training_mods() { handle_is_enable_transition_term, // SDI crate::training::sdi::check_hit_stop_delay_command, + // Generic params + load_once_common_params ); combo::init(); diff --git a/src/training/shield.rs b/src/training/shield.rs index 4b90842..689d8d3 100644 --- a/src/training/shield.rs +++ b/src/training/shield.rs @@ -124,15 +124,25 @@ pub unsafe fn get_param_float( 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 param_installer() { + if crate::training::COMMON_OBJ != 0 { + if is_training_mode() + && (MENU.shield_state == Shield::Infinite || should_pause_shield_decay()) + { + // Set "shield_damage_mul" to 0.0f + *((crate::training::COMMON_OBJ + 0x16c) as *mut f32) = 0x0 as f32; + } else { + // Set "shield_damage_mul" to 1.19f + *((crate::training::COMMON_OBJ + 0x16c) as *mut f32) = 1.19 as f32; + } + } +} + pub fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { // Mash shield if mash::request_shield(module_accessor) {