mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-20 00:46:34 +00:00
Increase Resilience to Game Updates by Dynamically Finding Offsets (#661)
* Search for offsets instead of using static offsets * Collect the rest of the offsets, still need to convert into needle searches * Finish writing offset search code * Run rustfmt * Fix build error * Fix clippy warnings * Add additional bytes and use symbols to prevent false-positives * Replace additional offsets with symbols * Change add_damage from symbol back to offset
This commit is contained in:
parent
b2ef9b85a7
commit
bf94573193
14 changed files with 497 additions and 166 deletions
|
@ -5,6 +5,7 @@ use smash::lua2cpp::L2CFighterCommon;
|
|||
|
||||
pub use crate::common::consts::MENU;
|
||||
use crate::common::consts::*;
|
||||
use crate::common::offsets::OFFSET_GET_BATTLE_OBJECT_FROM_ID;
|
||||
use crate::training::character_specific::ptrainer;
|
||||
|
||||
pub mod button_config;
|
||||
|
@ -14,6 +15,7 @@ pub mod dialog;
|
|||
pub mod events;
|
||||
pub mod input;
|
||||
pub mod menu;
|
||||
pub mod offsets;
|
||||
pub mod raygun_printer;
|
||||
pub mod release;
|
||||
|
||||
|
@ -34,7 +36,7 @@ pub fn is_training_mode() -> bool {
|
|||
true
|
||||
}
|
||||
|
||||
#[skyline::from_offset(0x3ac540)]
|
||||
#[skyline::from_offset(*OFFSET_GET_BATTLE_OBJECT_FROM_ID as isize)]
|
||||
pub fn get_battle_object_from_id(battle_object_id: u32) -> *mut app::BattleObject;
|
||||
|
||||
pub fn get_category(module_accessor: &app::BattleObjectModuleAccessor) -> i32 {
|
||||
|
|
347
src/common/offsets.rs
Normal file
347
src/common/offsets.rs
Normal file
|
@ -0,0 +1,347 @@
|
|||
// TODO!(Do all these need to be referenced by offset? Or do some of them have symbols?)
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)] // We want the assembly needles to stay in lines of four bytes each
|
||||
use crate::logging::*;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
// Stolen from HDR who stole it from Arcropolis
|
||||
// https://github.com/HDR-Development/HewDraw-Remix/blob/dev/dynamic/src/util.rs
|
||||
pub fn byte_search<T: Eq>(needle: &[T]) -> Option<usize> {
|
||||
let text = unsafe {
|
||||
let start = skyline::hooks::getRegionAddress(skyline::hooks::Region::Text) as *const T;
|
||||
let end = skyline::hooks::getRegionAddress(skyline::hooks::Region::Rodata) as *const T;
|
||||
let length = end.offset_from(start) as usize;
|
||||
std::slice::from_raw_parts(start, length)
|
||||
};
|
||||
|
||||
text.windows(needle.len())
|
||||
.position(|window| window == needle)
|
||||
}
|
||||
|
||||
// Wrapper around byte_search() with some additional logging
|
||||
fn find_offset(name: &str, needle: &[u8]) -> Option<usize> {
|
||||
info!("Searching for {}", name);
|
||||
let offset_opt = byte_search(needle);
|
||||
match offset_opt {
|
||||
Some(offset) => {
|
||||
info!("Found offset for {} at {:#x}", name, offset);
|
||||
Some(offset)
|
||||
}
|
||||
None => {
|
||||
error!("Cound not find offset for {}", name);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_offset {
|
||||
($fn_name:ident) => {
|
||||
paste::paste! {
|
||||
lazy_static! {
|
||||
pub static ref [<OFFSET_ $fn_name>]: usize = find_offset(stringify!($fn_name), [<NEEDLE_ $fn_name>]).expect(stringify!(Failed to find offset for $fn_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// To add a new offset, you need to define a NEEDLE_ static first with the
|
||||
// bytecode at that offset.
|
||||
//
|
||||
// Example:
|
||||
// OFFSET_GET_BATTLE_OBJECT_FROM_ID gets defined by the NEEDLE_GET_BATTLE_OBJECT_FROM_ID
|
||||
// bytecode and the impl_offset! macro with the argument GET_BATTLE_OBJECT_FROM_ID
|
||||
//
|
||||
// Recommended to use the first 8 instructions (32 bytes), unless the function is shorter
|
||||
|
||||
// OFFSET_GET_BATTLE_OBJECT_FROM_ID = 0x3ac540
|
||||
static NEEDLE_GET_BATTLE_OBJECT_FROM_ID: &[u8] = &[
|
||||
0xff, 0x03, 0x06, 0xd1,
|
||||
0xee, 0x73, 0x00, 0xfd,
|
||||
0xed, 0x33, 0x0f, 0x6d,
|
||||
0xeb, 0x2b, 0x10, 0x6d,
|
||||
0xe9, 0x23, 0x11, 0x6d,
|
||||
0xfc, 0x6f, 0x12, 0xa9,
|
||||
0xfa, 0x67, 0x13, 0xa9,
|
||||
0xf8, 0x5f, 0x14, 0xa9,
|
||||
];
|
||||
impl_offset!(GET_BATTLE_OBJECT_FROM_ID);
|
||||
|
||||
// OFFSET_COPY_SETUP = 0xba0e60
|
||||
static NEEDLE_COPY_SETUP: &[u8] = &[
|
||||
0xe8, 0x0f, 0x19, 0xfc,
|
||||
0xfc, 0x6f, 0x01, 0xa9,
|
||||
0xfa, 0x67, 0x02, 0xa9,
|
||||
0xf8, 0x5f, 0x03, 0xa9,
|
||||
0xf6, 0x57, 0x04, 0xa9,
|
||||
0xf4, 0x4f, 0x05, 0xa9,
|
||||
0xfd, 0x7b, 0x06, 0xa9,
|
||||
0xfd, 0x83, 0x01, 0x91,
|
||||
];
|
||||
impl_offset!(COPY_SETUP);
|
||||
|
||||
// OFFSET_IS_VISIBLE_BACKSHIELD = 0x1655400
|
||||
static NEEDLE_IS_VISIBLE_BACKSHIELD: &[u8] = &[
|
||||
0xfd, 0x7b, 0xbf, 0xa9,
|
||||
0xfd, 0x03, 0x00, 0x91,
|
||||
0x00, 0x28, 0x40, 0xf9,
|
||||
0x08, 0x00, 0x40, 0xf9,
|
||||
0x08, 0x85, 0x40, 0xf9,
|
||||
0xa1, 0x0f, 0x80, 0x52,
|
||||
0x01, 0x00, 0xa4, 0x72,
|
||||
0x00, 0x01, 0x3f, 0xd6,
|
||||
];
|
||||
impl_offset!(IS_VISIBLE_BACKSHIELD);
|
||||
|
||||
// OFFSET_SET_CPU_CONTROLS = 0x2da180
|
||||
static NEEDLE_SET_CPU_CONTROLS: &[u8] = &[
|
||||
0xff, 0x03, 0x06, 0xd1,
|
||||
0xee, 0x73, 0x00, 0xfd,
|
||||
0xed, 0x33, 0x0f, 0x6d,
|
||||
0xeb, 0x2b, 0x10, 0x6d,
|
||||
0xe9, 0x23, 0x11, 0x6d,
|
||||
0xfc, 0x6f, 0x12, 0xa9,
|
||||
0xfa, 0x67, 0x13, 0xa9,
|
||||
0xf8, 0x5f, 0x14, 0xa9,
|
||||
];
|
||||
impl_offset!(SET_CPU_CONTROLS);
|
||||
|
||||
// OFFSET_ADD_DAMAGE = 0x3ff9a0
|
||||
static NEEDLE_ADD_DAMAGE: &[u8] = &[
|
||||
0x08, 0x20, 0x20, 0x1e,
|
||||
0x8d, 0x00, 0x00, 0x54,
|
||||
0x08, 0x14, 0x4e, 0x39,
|
||||
0x48, 0x00, 0x00, 0x34,
|
||||
0xc0, 0x03, 0x5f, 0xd6,
|
||||
];
|
||||
impl_offset!(ADD_DAMAGE);
|
||||
|
||||
// OFFSET_CHANGE_ACTIVE_CAMERA = 0x4ee460
|
||||
static NEEDLE_CHANGE_ACTIVE_CAMERA: &[u8] = &[
|
||||
0xff, 0x03, 0x02, 0xd1,
|
||||
0xf8, 0x5f, 0x04, 0xa9,
|
||||
0xf6, 0x57, 0x05, 0xa9,
|
||||
0xf4, 0x4f, 0x06, 0xa9,
|
||||
0xfd, 0x7b, 0x07, 0xa9,
|
||||
0xfd, 0xc3, 0x01, 0x91,
|
||||
0x08, 0x04, 0x40, 0xb9,
|
||||
0x1f, 0x01, 0x01, 0x6b,
|
||||
];
|
||||
impl_offset!(CHANGE_ACTIVE_CAMERA);
|
||||
|
||||
// OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES = 0x3157bb0
|
||||
static NEEDLE_SET_TRAINING_FIXED_CAMERA_VALUES: &[u8] = &[
|
||||
0x01, 0xe4, 0x00, 0x2f,
|
||||
0x20, 0x00, 0xc0, 0x3d,
|
||||
0x22, 0x1c, 0xa1, 0x4e,
|
||||
0x02, 0x44, 0x04, 0x6e,
|
||||
0xe8, 0x0a, 0x01, 0xf0,
|
||||
0x08, 0x81, 0x47, 0xf9,
|
||||
0x08, 0x01, 0x40, 0xf9,
|
||||
0x40, 0x04, 0x18, 0x6e,
|
||||
0x00, 0xf5, 0x82, 0x3d,
|
||||
];
|
||||
impl_offset!(SET_TRAINING_FIXED_CAMERA_VALUES);
|
||||
|
||||
// OFFSET_DRAW = 0x4b620
|
||||
static NEEDLE_DRAW: &[u8] = &[
|
||||
0x08, 0x0c, 0x40, 0xf9,
|
||||
0xc8, 0x03, 0x00, 0xb4,
|
||||
0xff, 0x83, 0x01, 0xd1,
|
||||
0xf5, 0x1b, 0x00, 0xf9,
|
||||
0xf4, 0x4f, 0x04, 0xa9,
|
||||
0xfd, 0x7b, 0x05, 0xa9,
|
||||
0xfd, 0x43, 0x01, 0x91,
|
||||
0xf4, 0x03, 0x00, 0xaa,
|
||||
];
|
||||
impl_offset!(DRAW);
|
||||
|
||||
// OFFSET_CLOUD_ADD_LIMIT = 0x8dc140
|
||||
static NEEDLE_CLOUD_ADD_LIMIT: &[u8] = &[
|
||||
0xff, 0x03, 0x03, 0xd1,
|
||||
0xe9, 0x23, 0x05, 0x6d,
|
||||
0xfc, 0x6f, 0x06, 0xa9,
|
||||
0xfa, 0x67, 0x07, 0xa9,
|
||||
0xf8, 0x5f, 0x08, 0xa9,
|
||||
0xf6, 0x57, 0x09, 0xa9,
|
||||
0xf4, 0x4f, 0x0a, 0xa9,
|
||||
0xfd, 0x7b, 0x0b, 0xa9,
|
||||
0xfd, 0xc3, 0x02, 0x91,
|
||||
0x13, 0x28, 0x40, 0xf9,
|
||||
0x68, 0x02, 0x40, 0xf9,
|
||||
0x08, 0x85, 0x40, 0xf9,
|
||||
];
|
||||
impl_offset!(CLOUD_ADD_LIMIT);
|
||||
|
||||
// IMPORTANT! Because this offset is so close to OFFSET_STALE and
|
||||
// because we are modifying inline instead of hooking the whole function,
|
||||
// this hook has to be initialized first! Otherwise the search will fail.
|
||||
// OFFSET_STALE_MENU = 0x13e88a0
|
||||
static NEEDLE_STALE_MENU: &[u8] = &[
|
||||
0xdf, 0x82, 0x2d, 0x39,
|
||||
0x93, 0x40, 0x8e, 0x94,
|
||||
0x00, 0x1d, 0xa8, 0x4e,
|
||||
0xc0, 0xa2, 0x06, 0x91,
|
||||
0xdf, 0x22, 0x2f, 0x39,
|
||||
0xff, 0x43, 0x8e, 0x94,
|
||||
0xca, 0x82, 0x6d, 0x39,
|
||||
0xe8, 0x77, 0x01, 0x90,
|
||||
0x08, 0x6d, 0x3c, 0x91,
|
||||
];
|
||||
impl_offset!(STALE_MENU);
|
||||
|
||||
// IMPORTANT! See above comment for STALE_MENU
|
||||
// OFFSET_STALE = 0x13e88a4
|
||||
static NEEDLE_STALE: &[u8] = &[
|
||||
0x93, 0x40, 0x8e, 0x94,
|
||||
0x00, 0x1d, 0xa8, 0x4e,
|
||||
0xc0, 0xa2, 0x06, 0x91,
|
||||
0xdf, 0x22, 0x2f, 0x39,
|
||||
];
|
||||
impl_offset!(STALE);
|
||||
|
||||
// todo!(Can we remove this and replace with SoundModule::play_se()?)
|
||||
// OFFSET_PLAY_SE = 0x4cf6a0
|
||||
static NEEDLE_PLAY_SE: &[u8] = &[
|
||||
0xa8, 0x00, 0x00, 0x12,
|
||||
0x9f, 0x00, 0x00, 0x72,
|
||||
0xe9, 0x03, 0x1e, 0x32,
|
||||
0x24, 0x11, 0x88, 0x1a,
|
||||
0x42, 0x00, 0x00, 0x12,
|
||||
0x63, 0x00, 0x00, 0x12,
|
||||
0xe5, 0x03, 0x06, 0x2a,
|
||||
];
|
||||
impl_offset!(PLAY_SE);
|
||||
|
||||
// OFFSET_CAN_FUTTOBI_BACK = 0x260f950
|
||||
static NEEDLE_CAN_FUTTOBI_BACK: &[u8] = &[
|
||||
0x00, 0x07, 0x00, 0xb4,
|
||||
0x09, 0x04, 0x40, 0xf9,
|
||||
0x28, 0x01, 0x40, 0x39,
|
||||
0x1f, 0x31, 0x00, 0x71,
|
||||
0x41, 0x04, 0x00, 0x54,
|
||||
0x28, 0x11, 0x40, 0xb8,
|
||||
0x0a, 0x05, 0x00, 0x71,
|
||||
0xeb, 0x03, 0x00, 0x54,
|
||||
0x0d, 0x00, 0x40, 0xf9,
|
||||
0x28, 0x51, 0x80, 0xb8,
|
||||
0x8e, 0x7b, 0x94, 0xd2,
|
||||
0x8e, 0x0d, 0xb7, 0xf2,
|
||||
];
|
||||
impl_offset!(CAN_FUTTOBI_BACK);
|
||||
|
||||
// OFFSET_REUSED_UI = 0x68cd80
|
||||
static NEEDLE_REUSED_UI: &[u8] = &[
|
||||
0xff, 0x43, 0x01, 0xd1,
|
||||
0xf5, 0x13, 0x00, 0xf9,
|
||||
0xf4, 0x4f, 0x03, 0xa9,
|
||||
0xfd, 0x7b, 0x04, 0xa9,
|
||||
0xfd, 0x03, 0x01, 0x91,
|
||||
0x08, 0x00, 0x40, 0xb9,
|
||||
0x1f, 0x21, 0x00, 0x71,
|
||||
0x62, 0x06, 0x00, 0x54,
|
||||
];
|
||||
impl_offset!(REUSED_UI);
|
||||
|
||||
|
||||
// OFFSET_OPCF = 0x6b7fdc
|
||||
static NEEDLE_OPCF: &[u8] = &[
|
||||
0x68, 0xb6, 0x40, 0xf9,
|
||||
0x09, 0x81, 0x49, 0x39,
|
||||
0x69, 0xe1, 0xff, 0x35,
|
||||
0x08, 0x55, 0x41, 0x39,
|
||||
0x28, 0xe1, 0x1f, 0x37,
|
||||
0xe0, 0x03, 0x13, 0xaa,
|
||||
0x63, 0x88, 0xf0, 0x97,
|
||||
0xe9, 0x23, 0x43, 0x6d,
|
||||
];
|
||||
impl_offset!(OPCF);
|
||||
|
||||
// OFFSET_FIM = 0x17504a0
|
||||
static NEEDLE_FIM: &[u8] = &[
|
||||
0xff, 0x03, 0x02, 0xd1,
|
||||
0xf7, 0x23, 0x00, 0xf9,
|
||||
0xf6, 0x57, 0x05, 0xa9,
|
||||
0xf4, 0x4f, 0x06, 0xa9,
|
||||
0xfd, 0x7b, 0x07, 0xa9,
|
||||
0xfd, 0xc3, 0x01, 0x91,
|
||||
0x3f, 0x04, 0x00, 0x31,
|
||||
0xe0, 0x77, 0x00, 0x54,
|
||||
];
|
||||
impl_offset!(FIM);
|
||||
|
||||
// OFFSET_SSS_TRAINING = 0x184d1d8
|
||||
static NEEDLE_SSS_TRAINING: &[u8] = &[
|
||||
0x9f, 0xe3, 0x0b, 0x39,
|
||||
0x88, 0xbf, 0x0b, 0x39,
|
||||
0x56, 0x02, 0x00, 0x14,
|
||||
0x00, 0x01, 0x00, 0xf9,
|
||||
0xe8, 0x03, 0x00, 0x32,
|
||||
|
||||
];
|
||||
impl_offset!(SSS_TRAINING);
|
||||
|
||||
// OFFSET_GENERATE_ARTICLE_FOR_TARGET = 0x3d40a0
|
||||
static NEEDLE_GENERATE_ARTICLE_FOR_TARGET: &[u8] = &[
|
||||
0xf4, 0x4f, 0xbe, 0xa9,
|
||||
0xfd, 0x7b, 0x01, 0xa9,
|
||||
0xfd, 0x43, 0x00, 0x91,
|
||||
0xf3, 0x03, 0x03, 0x2a,
|
||||
0x42, 0x00, 0x00, 0xb5,
|
||||
0x02, 0x04, 0x40, 0xf9,
|
||||
];
|
||||
impl_offset!(GENERATE_ARTICLE_FOR_TARGET);
|
||||
|
||||
// OFFSET_KIRBY_OPFF = 0xb971b0
|
||||
static NEEDLE_KIRBY_OPFF: &[u8] = &[
|
||||
0xff, 0x43, 0x02, 0xd1,
|
||||
0xfc, 0x6f, 0x03, 0xa9,
|
||||
0xfa, 0x67, 0x04, 0xa9,
|
||||
0xf8, 0x5f, 0x05, 0xa9,
|
||||
0xf6, 0x57, 0x06, 0xa9,
|
||||
0xf4, 0x4f, 0x07, 0xa9,
|
||||
0xfd, 0x7b, 0x08, 0xa9,
|
||||
0xfd, 0x03, 0x02, 0x91,
|
||||
0x3a, 0x10, 0x40, 0xf9,
|
||||
0x54, 0x2b, 0x40, 0xf9,
|
||||
0x88, 0x02, 0x40, 0xf9,
|
||||
0x08, 0x59, 0x40, 0xf9,
|
||||
];
|
||||
impl_offset!(KIRBY_OPFF);
|
||||
|
||||
// OFFSET_ACTIVATE_AUTONOMY = 0x34b5cf0
|
||||
static NEEDLE_ACTIVATE_AUTONOMY: &[u8] = &[
|
||||
0xf6, 0x57, 0xbd, 0xa9,
|
||||
0xf4, 0x4f, 0x01, 0xa9,
|
||||
0xfd, 0x7b, 0x02, 0xa9,
|
||||
0xfd, 0x83, 0x00, 0x91,
|
||||
0x28, 0x00, 0x40, 0xf9,
|
||||
0x08, 0x89, 0x40, 0xf9,
|
||||
0xd5, 0x00, 0x80, 0x52,
|
||||
0x15, 0x00, 0xa4, 0x72,
|
||||
];
|
||||
impl_offset!(ACTIVATE_AUTONOMY);
|
||||
|
||||
// OFFSET_POKEMON_DECIDE = 0x34cdc64
|
||||
static NEEDLE_POKEMON_DECIDE: &[u8] = &[
|
||||
0x28, 0x69, 0x2b, 0x38,
|
||||
0x48, 0x26, 0x8b, 0x52,
|
||||
0x2a, 0x69, 0x28, 0x38,
|
||||
0x88, 0x12, 0x40, 0xf9,
|
||||
0x49, 0x01, 0x80, 0x52,
|
||||
0x14, 0x29, 0x40, 0xf9,
|
||||
0xe9, 0x0b, 0x00, 0xb9,
|
||||
0x29, 0xdf, 0x00, 0xb0,
|
||||
];
|
||||
impl_offset!(POKEMON_DECIDE);
|
||||
|
||||
// OFFSET_LAYOUT_ARC_MALLOC = 0x37730d4
|
||||
static NEEDLE_LAYOUT_ARC_MALLOC: &[u8] = &[
|
||||
0xe3, 0xe6, 0x06, 0x94,
|
||||
0xa0, 0x05, 0x00, 0xb4,
|
||||
0xe1, 0x03, 0x15, 0xaa,
|
||||
0xe2, 0x03, 0x17, 0xaa,
|
||||
0xc0, 0xb6, 0x00, 0xf9,
|
||||
0x72, 0x2e, 0x09, 0x94,
|
||||
0xc1, 0xb6, 0x40, 0xf9,
|
||||
0xc2, 0x57, 0x00, 0xb0,
|
||||
];
|
||||
impl_offset!(LAYOUT_ARC_MALLOC);
|
|
@ -7,6 +7,7 @@ use smash::lib::lua_const::*;
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use crate::offsets::OFFSET_GENERATE_ARTICLE_FOR_TARGET;
|
||||
use crate::training::mash;
|
||||
|
||||
pub struct CharItem {
|
||||
|
@ -509,9 +510,7 @@ daikon_replace!(DAISY, daisy, 2);
|
|||
daikon_replace!(DAISY, daisy, 1);
|
||||
|
||||
// GenerateArticleForTarget for Peach/Diddy(/Link?) item creation
|
||||
static GAFT_OFFSET: usize = 0x03d40a0;
|
||||
|
||||
#[skyline::hook(offset = GAFT_OFFSET)]
|
||||
#[skyline::hook(offset = *OFFSET_GENERATE_ARTICLE_FOR_TARGET)]
|
||||
pub unsafe fn handle_generate_article_for_target(
|
||||
article_module_accessor: *mut BattleObjectModuleAccessor,
|
||||
int_1: i32,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::common::try_get_battle_object;
|
||||
use crate::offsets::OFFSET_KIRBY_OPFF;
|
||||
use crate::training::charge::ChargeState;
|
||||
use crate::training::save_states;
|
||||
use smash::app::{self, lua_bind::*, smashball::is_training_mode};
|
||||
|
@ -13,8 +14,7 @@ pub struct CopyModule {
|
|||
}
|
||||
|
||||
// Wait to set up copy ability variables until after CopyStart runs;
|
||||
static KIRBY_OPFF_OFFSET: usize = 0xb971b0;
|
||||
#[skyline::hook(offset = KIRBY_OPFF_OFFSET)]
|
||||
#[skyline::hook(offset = *OFFSET_KIRBY_OPFF)]
|
||||
pub unsafe fn handle_copy_start(param1: u64, kirby_fighter: *mut app::Fighter) -> u64 {
|
||||
if !is_training_mode() || !save_states::is_loading() {
|
||||
return original!()(param1, kirby_fighter);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::info;
|
||||
use crate::offsets::OFFSET_ACTIVATE_AUTONOMY;
|
||||
use smash::app::{self, lua_bind::*, smashball::is_training_mode};
|
||||
use smash::lib::lua_const::*;
|
||||
|
||||
|
@ -30,8 +31,7 @@ pub struct WeaponWorkModule {
|
|||
}
|
||||
|
||||
// Prevent Order Loss
|
||||
static ACTIVATE_AUTONOMY_OFFSET: usize = 0x034b5cf0;
|
||||
#[skyline::hook(offset = ACTIVATE_AUTONOMY_OFFSET)]
|
||||
#[skyline::hook(offset = *OFFSET_ACTIVATE_AUTONOMY)]
|
||||
pub unsafe fn autonomy_handle(weapon: *mut app::Weapon, work_module: *mut WeaponWorkModule) {
|
||||
if !is_training_mode() {
|
||||
return original!()(weapon, work_module);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::offsets::OFFSET_POKEMON_DECIDE;
|
||||
use crate::training::frame_counter;
|
||||
use crate::training::save_states;
|
||||
use once_cell::sync::Lazy;
|
||||
|
@ -138,9 +139,7 @@ pub unsafe fn handle_pokemon_sound_effect(hash: Hash40) -> Hash40 {
|
|||
}
|
||||
|
||||
// Choose which pokemon to switch to!
|
||||
static POKEMON_DECIDE_OFFSET: usize = 0x34cdc64;
|
||||
|
||||
#[skyline::hook(offset = POKEMON_DECIDE_OFFSET, inline)]
|
||||
#[skyline::hook(offset = *OFFSET_POKEMON_DECIDE, inline)]
|
||||
unsafe fn handle_pokemon_decide(ctx: &mut InlineCtx) {
|
||||
if !is_training_mode() || !save_states::is_loading() {
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::common::consts::FighterId;
|
||||
use crate::common::offsets::OFFSET_COPY_SETUP;
|
||||
use crate::common::{get_module_accessor, try_get_battle_object};
|
||||
use crate::training::character_specific::{kirby, pikmin};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -7,7 +8,7 @@ use smash::lib::lua_const::*;
|
|||
use smash::phx::{Hash40, Vector3f};
|
||||
use std::ptr;
|
||||
|
||||
#[skyline::from_offset(0xba0e60)]
|
||||
#[skyline::from_offset(*OFFSET_COPY_SETUP as isize)]
|
||||
fn copy_setup(
|
||||
module_accessor: *mut app::BattleObjectModuleAccessor,
|
||||
int: i32,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use skyline::nn::ui2d::ResColor;
|
||||
use smash::app::BattleObjectModuleAccessor;
|
||||
use training_mod_consts::OnOff;
|
||||
|
||||
use crate::common::consts::FighterId;
|
||||
|
@ -17,12 +18,12 @@ static mut FRAME_ADVANTAGE_CHECK: bool = false;
|
|||
static FRAME_COUNTER_INDEX: Lazy<usize> =
|
||||
Lazy::new(|| frame_counter::register_counter(frame_counter::FrameCounterType::InGame));
|
||||
|
||||
unsafe fn _was_in_hitstun(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||
unsafe fn _was_in_hitstun(module_accessor: *mut BattleObjectModuleAccessor) -> bool {
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0);
|
||||
(*FIGHTER_STATUS_KIND_DAMAGE..*FIGHTER_STATUS_KIND_DAMAGE_FALL).contains(&prev_status)
|
||||
}
|
||||
|
||||
unsafe fn was_in_shieldstun(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||
unsafe fn was_in_shieldstun(module_accessor: *mut BattleObjectModuleAccessor) -> bool {
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0);
|
||||
prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
}
|
||||
|
@ -38,7 +39,7 @@ macro_rules! actionable_statuses {
|
|||
};
|
||||
}
|
||||
|
||||
unsafe fn is_actionable(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||
unsafe fn is_actionable(module_accessor: *mut BattleObjectModuleAccessor) -> bool {
|
||||
actionable_statuses!().iter().any(|actionable_transition| {
|
||||
WorkModule::is_enable_transition_term(module_accessor, **actionable_transition)
|
||||
}) || CancelModule::is_enable_cancel(module_accessor)
|
||||
|
@ -81,7 +82,7 @@ fn update_frame_advantage(new_frame_adv: i32) {
|
|||
}
|
||||
|
||||
pub unsafe fn is_enable_transition_term(
|
||||
module_accessor: *mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: *mut BattleObjectModuleAccessor,
|
||||
transition_term: i32,
|
||||
is: bool,
|
||||
) {
|
||||
|
@ -120,7 +121,7 @@ pub unsafe fn is_enable_transition_term(
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAccessor) {
|
||||
let entry_id_int = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID);
|
||||
// do only once.
|
||||
if entry_id_int != (FighterId::Player as i32) {
|
||||
|
|
|
@ -2,88 +2,98 @@
|
|||
#![allow(unused_imports)]
|
||||
#![cfg(debug_assertions)]
|
||||
use crate::common::is_operation_cpu;
|
||||
use smash::app::{self, lua_bind::*, smashball::is_training_mode, utility};
|
||||
use crate::common::offsets::OFFSET_IS_VISIBLE_BACKSHIELD;
|
||||
use smash::app::{lua_bind::*, smashball::is_training_mode, utility, BattleObjectModuleAccessor};
|
||||
use smash::lib::lua_const::*;
|
||||
|
||||
#[skyline::from_offset(0x1655400)]
|
||||
fn is_visible_backshield(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool;
|
||||
#[skyline::from_offset(*OFFSET_IS_VISIBLE_BACKSHIELD as isize)]
|
||||
fn is_visible_backshield(module_accessor: *mut BattleObjectModuleAccessor) -> bool;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WorkModule2 {
|
||||
vtable: u64,
|
||||
owner: &'static mut app::BattleObjectModuleAccessor,
|
||||
owner: &'static mut BattleObjectModuleAccessor,
|
||||
}
|
||||
|
||||
static ON_FLAG_OFFSET: usize = 0x4e4910;
|
||||
#[skyline::hook(offset = ON_FLAG_OFFSET)]
|
||||
pub unsafe fn handle_on_flag(work_module: &mut WorkModule2, address: i32) {
|
||||
#[skyline::hook(replace = WorkModule::on_flag)]
|
||||
pub unsafe fn handle_on_flag(module_accessor: &mut BattleObjectModuleAccessor, address: i32) {
|
||||
if address == *WEAPON_PTRAINER_PTRAINER_INSTANCE_WORK_ID_FLAG_OUTFIELD_INVISIBLE
|
||||
&& app::utility::get_kind(work_module.owner) != *FIGHTER_KIND_SHEIK
|
||||
&& utility::get_kind(module_accessor) != *FIGHTER_KIND_SHEIK
|
||||
{
|
||||
is_visible_backshield(work_module.owner);
|
||||
is_visible_backshield(module_accessor);
|
||||
}
|
||||
original!()(work_module, address);
|
||||
original!()(module_accessor, address);
|
||||
}
|
||||
|
||||
static SET_INT_OFFSET: usize = 0x4e4600;
|
||||
#[skyline::hook(offset = SET_INT_OFFSET)]
|
||||
pub unsafe fn handle_set_int(work_module: &mut WorkModule2, value: u32, address: i32) {
|
||||
#[skyline::hook(replace = WorkModule::set_int)]
|
||||
pub unsafe fn handle_set_int(
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
value: u32,
|
||||
address: i32,
|
||||
) {
|
||||
if !is_training_mode() {
|
||||
original!()(work_module, value, address);
|
||||
original!()(module_accessor, value, address);
|
||||
}
|
||||
if address == *WEAPON_PTRAINER_MBALL_INSTANCE_WORK_ID_INT_PLATE_EFF_ID
|
||||
&& app::utility::get_kind(work_module.owner) == *WEAPON_KIND_PTRAINER_MBALL
|
||||
&& utility::get_kind(module_accessor) == *WEAPON_KIND_PTRAINER_MBALL
|
||||
{
|
||||
is_visible_backshield(work_module.owner);
|
||||
is_visible_backshield(module_accessor);
|
||||
}
|
||||
original!()(work_module, value, address);
|
||||
original!()(module_accessor, value, address);
|
||||
}
|
||||
|
||||
static SET_INT64_OFFSET: usize = 0x4e4680;
|
||||
#[skyline::hook(offset = SET_INT64_OFFSET)]
|
||||
pub unsafe fn handle_set_int_64(work_module: &mut WorkModule2, value: u64, address: i32) {
|
||||
#[skyline::hook(replace = WorkModule::set_int64)]
|
||||
pub unsafe fn handle_set_int_64(
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
value: u64,
|
||||
address: i32,
|
||||
) {
|
||||
if !is_training_mode() {
|
||||
original!()(work_module, value, address);
|
||||
original!()(module_accessor, value, address);
|
||||
}
|
||||
original!()(work_module, value, address);
|
||||
original!()(module_accessor, value, address);
|
||||
}
|
||||
|
||||
static SET_FLOAT_OFFSET: usize = 0x4e4420;
|
||||
#[skyline::hook(offset = SET_FLOAT_OFFSET)]
|
||||
pub unsafe fn handle_set_float(work_module: &mut WorkModule2, value: f32, address: i32) {
|
||||
#[skyline::hook(replace = WorkModule::set_float)]
|
||||
pub unsafe fn handle_set_float(
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
value: f32,
|
||||
address: i32,
|
||||
) {
|
||||
if !is_training_mode() {
|
||||
original!()(work_module, value, address);
|
||||
original!()(module_accessor, value, address);
|
||||
}
|
||||
if address == *FIGHTER_WIIFIT_INSTANCE_WORK_ID_FLOAT_SPECIAL_N_CHARGE_LEVEL_RATIO //*FIGHTER_KIRBY_INSTANCE_WORK_ID_FLAG_COPY_ON_START
|
||||
&& app::utility::get_kind(work_module.owner) == FIGHTER_KIND_KIRBY
|
||||
&& utility::get_kind(module_accessor) == FIGHTER_KIND_KIRBY
|
||||
{
|
||||
is_visible_backshield(work_module.owner);
|
||||
is_visible_backshield(module_accessor);
|
||||
}
|
||||
original!()(work_module, value, address);
|
||||
original!()(module_accessor, value, address);
|
||||
}
|
||||
|
||||
static IS_FLAG_OFFSET: usize = 0x4e48e0;
|
||||
#[skyline::hook(offset = IS_FLAG_OFFSET)]
|
||||
pub unsafe fn handle_is_flag(work_module: &mut WorkModule2, address: i32) -> bool {
|
||||
#[skyline::hook(replace = WorkModule::is_flag)]
|
||||
pub unsafe fn handle_is_flag(
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
address: i32,
|
||||
) -> bool {
|
||||
if !is_training_mode() {
|
||||
original!()(work_module, address);
|
||||
original!()(module_accessor, address);
|
||||
}
|
||||
if address == *WEAPON_PTRAINER_PTRAINER_INSTANCE_WORK_ID_FLAG_ENABLE_CHANGE_POKEMON //*FIGHTER_KIRBY_INSTANCE_WORK_ID_FLAG_COPY_ON_START
|
||||
&& app::utility::get_kind(work_module.owner) != *FIGHTER_KIND_SHEIK
|
||||
&& original!()(work_module, address)
|
||||
&& utility::get_kind(module_accessor) != *FIGHTER_KIND_SHEIK
|
||||
&& original!()(module_accessor, address)
|
||||
{
|
||||
is_visible_backshield(work_module.owner);
|
||||
is_visible_backshield(module_accessor);
|
||||
}
|
||||
original!()(work_module, address)
|
||||
original!()(module_accessor, address)
|
||||
}
|
||||
|
||||
static GET_INT_OFFSET: usize = 0x4e45e0;
|
||||
#[skyline::hook(offset = GET_INT_OFFSET)]
|
||||
pub unsafe fn handle_get_int(work_module: &mut WorkModule2, address: i32) {
|
||||
#[skyline::hook(replace = WorkModule::get_int)]
|
||||
pub unsafe fn handle_get_int(module_accessor: &mut BattleObjectModuleAccessor, address: i32) {
|
||||
if !is_training_mode() {
|
||||
original!()(work_module, address);
|
||||
original!()(module_accessor, address);
|
||||
}
|
||||
original!()(work_module, address);
|
||||
original!()(module_accessor, address);
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
|
@ -116,7 +126,7 @@ pub fn init() {
|
|||
// );
|
||||
#[allow(clippy::too_many_arguments)] // This function has so many arguments so it's easy to quickly fill them in when debugging with the analyzer
|
||||
pub fn print_fighter_info(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
title: &str,
|
||||
player_only: bool,
|
||||
cpu_only: bool,
|
||||
|
|
|
@ -11,6 +11,7 @@ use PossessionState::*;
|
|||
|
||||
use crate::common::consts::{FighterId, HitstunPlayback, OnOff, RecordTrigger};
|
||||
use crate::common::input::*;
|
||||
use crate::common::offsets::OFFSET_SET_CPU_CONTROLS;
|
||||
use crate::common::{button_config, is_training_mode};
|
||||
use crate::common::{
|
||||
get_module_accessor, is_in_hitstun, is_in_shieldstun, try_get_module_accessor, MENU,
|
||||
|
@ -434,7 +435,7 @@ pub unsafe fn handle_final_input_mapping(player_idx: i32, out: *mut MappedInputs
|
|||
}
|
||||
}
|
||||
|
||||
#[skyline::hook(offset = 0x2da180)] // After cpu controls are assigned from ai calls
|
||||
#[skyline::hook(offset = *OFFSET_SET_CPU_CONTROLS)] // After cpu controls are assigned from ai calls
|
||||
unsafe fn set_cpu_controls(p_data: *mut *mut u8) {
|
||||
call_original!(p_data);
|
||||
if !is_training_mode() {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::common::button_config;
|
||||
use crate::common::consts::{BuffOption, FighterId, MENU};
|
||||
use crate::common::offsets::*;
|
||||
use crate::common::{
|
||||
consts::BuffOption, consts::FighterId, consts::MENU, dev_config, get_module_accessor,
|
||||
is_operation_cpu, is_training_mode, menu, FIGHTER_MANAGER_ADDR, ITEM_MANAGER_ADDR,
|
||||
STAGE_MANAGER_ADDR,
|
||||
dev_config, get_module_accessor, is_operation_cpu, is_training_mode, menu,
|
||||
FIGHTER_MANAGER_ADDR, ITEM_MANAGER_ADDR, STAGE_MANAGER_ADDR,
|
||||
};
|
||||
use crate::hitbox_visualizer;
|
||||
use crate::input::*;
|
||||
|
@ -10,7 +11,9 @@ use crate::logging::*;
|
|||
use crate::training::character_specific::{items, kirby, pikmin, ptrainer};
|
||||
use skyline::hooks::{getRegionAddress, InlineCtx, Region};
|
||||
use skyline::nn::ro::LookupSymbol;
|
||||
use smash::app::{self, enSEType, lua_bind::*, utility};
|
||||
use smash::app::{
|
||||
enSEType, lua_bind::*, utility, BattleObjectModuleAccessor, FighterSpecializer_Jack,
|
||||
};
|
||||
use smash::lib::lua_const::*;
|
||||
use smash::params::*;
|
||||
use smash::phx::{Hash40, Vector3f};
|
||||
|
@ -47,7 +50,7 @@ mod debug;
|
|||
|
||||
#[skyline::hook(replace = WorkModule::get_param_float)]
|
||||
pub unsafe fn handle_get_param_float(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
param_type: u64,
|
||||
param_hash: u64,
|
||||
) -> f32 {
|
||||
|
@ -61,7 +64,7 @@ pub unsafe fn handle_get_param_float(
|
|||
|
||||
#[skyline::hook(replace = WorkModule::get_param_int)]
|
||||
pub unsafe fn handle_get_param_int(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
param_type: u64,
|
||||
param_hash: u64,
|
||||
) -> i32 {
|
||||
|
@ -75,9 +78,7 @@ pub unsafe fn handle_get_param_int(
|
|||
}
|
||||
|
||||
#[skyline::hook(replace = ControlModule::get_attack_air_kind)]
|
||||
pub unsafe fn handle_get_attack_air_kind(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) -> i32 {
|
||||
pub unsafe fn handle_get_attack_air_kind(module_accessor: &mut BattleObjectModuleAccessor) -> i32 {
|
||||
let ori = original!()(module_accessor);
|
||||
if !is_training_mode() {
|
||||
return ori;
|
||||
|
@ -91,7 +92,7 @@ pub unsafe fn handle_get_attack_air_kind(
|
|||
|
||||
#[skyline::hook(replace = ControlModule::get_command_flag_cat)]
|
||||
pub unsafe fn handle_get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
category: i32,
|
||||
) -> i32 {
|
||||
let mut flag = original!()(module_accessor, category);
|
||||
|
@ -116,10 +117,7 @@ pub unsafe fn handle_get_command_flag_cat(
|
|||
flag
|
||||
}
|
||||
|
||||
fn once_per_frame_per_fighter(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32,
|
||||
) {
|
||||
fn once_per_frame_per_fighter(module_accessor: &mut BattleObjectModuleAccessor, category: i32) {
|
||||
if category != FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
return;
|
||||
}
|
||||
|
@ -158,7 +156,7 @@ fn once_per_frame_per_fighter(
|
|||
* 1 is fully right, -1 is fully left
|
||||
*/
|
||||
#[skyline::hook(replace = ControlModule::get_stick_x_no_clamp)]
|
||||
pub unsafe fn get_stick_x_no_clamp(module_accessor: &mut app::BattleObjectModuleAccessor) -> f32 {
|
||||
pub unsafe fn get_stick_x_no_clamp(module_accessor: &mut BattleObjectModuleAccessor) -> f32 {
|
||||
let ori = original!()(module_accessor);
|
||||
if !is_training_mode() {
|
||||
return ori;
|
||||
|
@ -173,7 +171,7 @@ pub unsafe fn get_stick_x_no_clamp(module_accessor: &mut app::BattleObjectModule
|
|||
* 1 is fully up, -1 is fully down
|
||||
*/
|
||||
#[skyline::hook(replace = ControlModule::get_stick_y_no_clamp)]
|
||||
pub unsafe fn get_stick_y_no_clamp(module_accessor: &mut app::BattleObjectModuleAccessor) -> f32 {
|
||||
pub unsafe fn get_stick_y_no_clamp(module_accessor: &mut BattleObjectModuleAccessor) -> f32 {
|
||||
let ori = original!()(module_accessor);
|
||||
if !is_training_mode() {
|
||||
return ori;
|
||||
|
@ -188,7 +186,7 @@ pub unsafe fn get_stick_y_no_clamp(module_accessor: &mut app::BattleObjectModule
|
|||
* Air Dodging
|
||||
*/
|
||||
#[skyline::hook(replace = ControlModule::get_stick_x)]
|
||||
pub unsafe fn get_stick_x(module_accessor: &mut app::BattleObjectModuleAccessor) -> f32 {
|
||||
pub unsafe fn get_stick_x(module_accessor: &mut BattleObjectModuleAccessor) -> f32 {
|
||||
let ori = original!()(module_accessor);
|
||||
if !is_training_mode() {
|
||||
return ori;
|
||||
|
@ -202,7 +200,7 @@ pub unsafe fn get_stick_x(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
* angled ftilt/fsmash
|
||||
*/
|
||||
#[skyline::hook(replace = ControlModule::get_stick_dir)]
|
||||
pub unsafe fn get_stick_dir(module_accessor: &mut app::BattleObjectModuleAccessor) -> f32 {
|
||||
pub unsafe fn get_stick_dir(module_accessor: &mut BattleObjectModuleAccessor) -> f32 {
|
||||
let ori = original!()(module_accessor);
|
||||
if !is_training_mode() {
|
||||
return ori;
|
||||
|
@ -226,7 +224,7 @@ pub unsafe fn get_stick_dir(module_accessor: &mut app::BattleObjectModuleAccesso
|
|||
* Crouching
|
||||
*/
|
||||
#[skyline::hook(replace = ControlModule::get_stick_y)]
|
||||
pub unsafe fn get_stick_y(module_accessor: &mut app::BattleObjectModuleAccessor) -> f32 {
|
||||
pub unsafe fn get_stick_y(module_accessor: &mut BattleObjectModuleAccessor) -> f32 {
|
||||
let ori = original!()(module_accessor);
|
||||
if !is_training_mode() {
|
||||
return ori;
|
||||
|
@ -238,7 +236,7 @@ pub unsafe fn get_stick_y(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
|
||||
#[skyline::hook(replace = ControlModule::check_button_on)]
|
||||
pub unsafe fn handle_check_button_on(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
button: i32,
|
||||
) -> bool {
|
||||
let ori = original!()(module_accessor, button);
|
||||
|
@ -252,7 +250,7 @@ pub unsafe fn handle_check_button_on(
|
|||
|
||||
#[skyline::hook(replace = ControlModule::check_button_off)]
|
||||
pub unsafe fn handle_check_button_off(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
button: i32,
|
||||
) -> bool {
|
||||
let ori = original!()(module_accessor, button);
|
||||
|
@ -266,7 +264,7 @@ pub unsafe fn handle_check_button_off(
|
|||
|
||||
#[skyline::hook(replace = MotionModule::change_motion)]
|
||||
pub unsafe fn handle_change_motion(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
motion_kind: u64,
|
||||
unk1: f32,
|
||||
unk2: f32,
|
||||
|
@ -300,7 +298,7 @@ pub unsafe fn handle_change_motion(
|
|||
|
||||
#[skyline::hook(replace = WorkModule::is_enable_transition_term)]
|
||||
pub unsafe fn handle_is_enable_transition_term(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
transition_term: i32,
|
||||
) -> bool {
|
||||
let ori = original!()(module_accessor, transition_term);
|
||||
|
@ -332,7 +330,7 @@ pub unsafe fn handle_set_dead_rumble(lua_state: u64) -> u64 {
|
|||
|
||||
#[skyline::hook(replace = CameraModule::req_quake)]
|
||||
pub unsafe fn handle_req_quake(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
my_int: i32,
|
||||
) -> u64 {
|
||||
if !is_training_mode() {
|
||||
|
@ -354,13 +352,11 @@ fn params_main(params_info: &ParamsInfo<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
static CLOUD_ADD_LIMIT_OFFSET: usize = 0x008dc140;
|
||||
|
||||
// this function is used to add limit to Cloud's limit gauge. Hooking it here so we can call it in buff.rs
|
||||
#[skyline::hook(offset = CLOUD_ADD_LIMIT_OFFSET)]
|
||||
#[skyline::hook(offset = *OFFSET_CLOUD_ADD_LIMIT)]
|
||||
pub unsafe fn handle_add_limit(
|
||||
add_limit: f32,
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
is_special_lw: u64,
|
||||
) {
|
||||
original!()(add_limit, module_accessor, is_special_lw)
|
||||
|
@ -368,7 +364,7 @@ pub unsafe fn handle_add_limit(
|
|||
|
||||
#[skyline::hook(replace = EffectModule::req_screen)] // hooked to prevent the screen from darkening when loading a save state with One-Winged Angel
|
||||
pub unsafe fn handle_req_screen(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
my_hash: Hash40,
|
||||
bool_1: bool,
|
||||
bool_2: bool,
|
||||
|
@ -386,9 +382,9 @@ pub unsafe fn handle_req_screen(
|
|||
original!()(module_accessor, my_hash, bool_1, bool_2, bool_3)
|
||||
}
|
||||
|
||||
#[skyline::hook(replace = app::FighterSpecializer_Jack::check_doyle_summon_dispatch)] // returns status of summon dispatch if triggered, -1 as u64 otherwise
|
||||
#[skyline::hook(replace = FighterSpecializer_Jack::check_doyle_summon_dispatch)] // returns status of summon dispatch if triggered, -1 as u64 otherwise
|
||||
pub unsafe fn handle_check_doyle_summon_dispatch(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
bool_1: bool,
|
||||
bool_2: bool,
|
||||
) -> u64 {
|
||||
|
@ -402,7 +398,7 @@ pub unsafe fn handle_check_doyle_summon_dispatch(
|
|||
ori
|
||||
}
|
||||
|
||||
#[skyline::hook(offset = 0x03ff9a0)]
|
||||
#[skyline::hook(offset = *OFFSET_ADD_DAMAGE)]
|
||||
pub unsafe fn handle_add_damage(
|
||||
damage_module: *mut u64, // DamageModule
|
||||
mut damage_to_add: f32,
|
||||
|
@ -412,7 +408,7 @@ pub unsafe fn handle_add_damage(
|
|||
return original!()(damage_module, damage_to_add, param_2);
|
||||
}
|
||||
let module_accessor =
|
||||
&mut **(damage_module.byte_add(0x8) as *mut *mut app::BattleObjectModuleAccessor);
|
||||
&mut **(damage_module.byte_add(0x8) as *mut *mut BattleObjectModuleAccessor);
|
||||
// Prevent Wii Fit Deep Breathing from Healing on Save State Load
|
||||
if utility::get_kind(module_accessor) == *FIGHTER_KIND_WIIFIT
|
||||
&& buff::is_buffing(module_accessor)
|
||||
|
@ -423,10 +419,8 @@ pub unsafe fn handle_add_damage(
|
|||
}
|
||||
|
||||
// Set Stale Moves to On
|
||||
static STALE_OFFSET: usize = 0x013e88a4;
|
||||
|
||||
// One instruction after stale moves toggle register is set to 0
|
||||
#[skyline::hook(offset = STALE_OFFSET, inline)]
|
||||
#[skyline::hook(offset = *OFFSET_STALE, inline)]
|
||||
unsafe fn stale_handle(ctx: &mut InlineCtx) {
|
||||
let x22 = ctx.registers[22].x.as_mut();
|
||||
let training_structure_address = (*x22 + 0xb60) as *mut u8;
|
||||
|
@ -434,10 +428,8 @@ unsafe fn stale_handle(ctx: &mut InlineCtx) {
|
|||
}
|
||||
|
||||
// Set Stale Moves to On in the menu text
|
||||
static STALE_MENU_OFFSET: usize = 0x013e88a0;
|
||||
|
||||
// One instruction after menu text register is set to off
|
||||
#[skyline::hook(offset = STALE_MENU_OFFSET, inline)]
|
||||
#[skyline::hook(offset = *OFFSET_STALE_MENU, inline)]
|
||||
unsafe fn stale_menu_handle(ctx: &mut InlineCtx) {
|
||||
// Set the text pointer to where "mel_training_on" is located
|
||||
let on_text_ptr = (getRegionAddress(Region::Text) as u64) + 0x42b215e;
|
||||
|
@ -447,7 +439,7 @@ unsafe fn stale_menu_handle(ctx: &mut InlineCtx) {
|
|||
|
||||
#[skyline::hook(replace = SoundModule::play_se)] // hooked to prevent death sfx from playing when loading save states
|
||||
pub unsafe fn handle_se(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
my_hash: Hash40,
|
||||
bool1: bool,
|
||||
bool2: bool,
|
||||
|
@ -493,12 +485,11 @@ pub unsafe fn handle_se(
|
|||
#[repr(C)]
|
||||
pub struct FighterSoundModule {
|
||||
vtable: u64,
|
||||
owner: *mut app::BattleObjectModuleAccessor,
|
||||
owner: *mut BattleObjectModuleAccessor,
|
||||
}
|
||||
|
||||
static PLAY_SE_OFFSET: usize = 0x04cf6a0;
|
||||
// fighters don't use the symbol and go straight through their vtable to this function
|
||||
#[skyline::hook(offset = PLAY_SE_OFFSET)]
|
||||
#[skyline::hook(offset = *OFFSET_PLAY_SE)]
|
||||
pub unsafe fn handle_fighter_play_se(
|
||||
sound_module: *mut FighterSoundModule, // pointer to fighter's SoundModule
|
||||
mut my_hash: Hash40,
|
||||
|
@ -534,15 +525,10 @@ pub unsafe fn handle_fighter_play_se(
|
|||
original!()(sound_module, my_hash, bool1, bool2, bool3, bool4, se_type)
|
||||
}
|
||||
|
||||
pub struct FighterEffectModule {
|
||||
_vtable: u64,
|
||||
owner: *mut app::BattleObjectModuleAccessor,
|
||||
}
|
||||
|
||||
static FOLLOW_REQ_OFFSET: usize = 0x044f860;
|
||||
#[skyline::hook(offset = FOLLOW_REQ_OFFSET)] // hooked to prevent score gfx from playing when loading save states
|
||||
// hooked to prevent score gfx from playing when loading save states
|
||||
#[skyline::hook(replace = EffectModule::req_follow)]
|
||||
pub unsafe fn handle_effect_follow(
|
||||
effect_module: &mut FighterEffectModule,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
eff_hash: Hash40,
|
||||
joint_hash: Hash40,
|
||||
pos: *const Vector3f,
|
||||
|
@ -559,7 +545,7 @@ pub unsafe fn handle_effect_follow(
|
|||
) -> u64 {
|
||||
if !is_training_mode() {
|
||||
return original!()(
|
||||
effect_module,
|
||||
module_accessor,
|
||||
eff_hash,
|
||||
joint_hash,
|
||||
pos,
|
||||
|
@ -580,7 +566,7 @@ pub unsafe fn handle_effect_follow(
|
|||
size = 0.0
|
||||
}
|
||||
original!()(
|
||||
effect_module,
|
||||
module_accessor,
|
||||
eff_hash,
|
||||
joint_hash,
|
||||
pos,
|
||||
|
@ -597,10 +583,9 @@ pub unsafe fn handle_effect_follow(
|
|||
)
|
||||
}
|
||||
|
||||
static EFFECT_REQ_OFFSET: usize = 0x44de50;
|
||||
#[skyline::hook(offset = EFFECT_REQ_OFFSET)] // hooked to prevent death gfx from playing when loading save states
|
||||
#[skyline::hook(replace = EffectModule::req)] // hooked to prevent death gfx from playing when loading save states
|
||||
pub unsafe fn handle_fighter_effect(
|
||||
effect_module: *mut FighterEffectModule, // pointer to effect module
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
eff_hash: Hash40,
|
||||
pos: *const Vector3f,
|
||||
rot: *const Vector3f,
|
||||
|
@ -612,7 +597,7 @@ pub unsafe fn handle_fighter_effect(
|
|||
) -> u64 {
|
||||
if !is_training_mode() {
|
||||
return original!()(
|
||||
effect_module,
|
||||
module_accessor,
|
||||
eff_hash,
|
||||
pos,
|
||||
rot,
|
||||
|
@ -623,9 +608,9 @@ pub unsafe fn handle_fighter_effect(
|
|||
arg9,
|
||||
);
|
||||
}
|
||||
size = ptrainer::handle_pokemon_effect(&mut *(*effect_module).owner, eff_hash, size);
|
||||
size = ptrainer::handle_pokemon_effect(module_accessor, eff_hash, size);
|
||||
original!()(
|
||||
effect_module,
|
||||
module_accessor,
|
||||
eff_hash,
|
||||
pos,
|
||||
rot,
|
||||
|
@ -637,10 +622,9 @@ pub unsafe fn handle_fighter_effect(
|
|||
)
|
||||
}
|
||||
|
||||
static JOINT_EFFECT_REQ_OFFSET: usize = 0x44e1e0;
|
||||
#[skyline::hook(offset = JOINT_EFFECT_REQ_OFFSET)] // hooked to prevent death gfx from playing when loading save states
|
||||
#[skyline::hook(replace = EffectModule::req_on_joint)] // hooked to prevent death gfx from playing when loading save states
|
||||
pub unsafe fn handle_fighter_joint_effect(
|
||||
effect_module: *mut FighterEffectModule, // pointer to effect module
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
eff_hash: Hash40,
|
||||
joint_hash: Hash40,
|
||||
pos: *const Vector3f,
|
||||
|
@ -655,7 +639,7 @@ pub unsafe fn handle_fighter_joint_effect(
|
|||
) -> u64 {
|
||||
if !is_training_mode() {
|
||||
return original!()(
|
||||
effect_module,
|
||||
module_accessor,
|
||||
eff_hash,
|
||||
joint_hash,
|
||||
pos,
|
||||
|
@ -669,9 +653,9 @@ pub unsafe fn handle_fighter_joint_effect(
|
|||
arg9,
|
||||
);
|
||||
}
|
||||
size = ptrainer::handle_pokemon_effect(&mut *(*effect_module).owner, eff_hash, size);
|
||||
size = ptrainer::handle_pokemon_effect(module_accessor, eff_hash, size);
|
||||
original!()(
|
||||
effect_module,
|
||||
module_accessor,
|
||||
eff_hash,
|
||||
joint_hash,
|
||||
pos,
|
||||
|
@ -688,7 +672,7 @@ pub unsafe fn handle_fighter_joint_effect(
|
|||
|
||||
#[skyline::hook(replace = EffectModule::req)] // hooked to prevent death gfx from playing when loading save states
|
||||
pub unsafe fn handle_effect(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
eff_hash: Hash40,
|
||||
pos: *const Vector3f,
|
||||
rot: *const Vector3f,
|
||||
|
@ -738,10 +722,8 @@ pub unsafe fn handle_effect(
|
|||
)
|
||||
}
|
||||
|
||||
static CAN_FUTTOBI_BACK_OFFSET: usize = 0x0260f950;
|
||||
|
||||
// can_futtobi_back, checks if stage allows for star KOs
|
||||
#[skyline::hook(offset = CAN_FUTTOBI_BACK_OFFSET)]
|
||||
#[skyline::hook(offset = *OFFSET_CAN_FUTTOBI_BACK)]
|
||||
pub unsafe fn handle_star_ko(my_long_ptr: &mut u64) -> bool {
|
||||
let ori = original!()(my_long_ptr);
|
||||
if !is_training_mode() {
|
||||
|
@ -751,9 +733,8 @@ pub unsafe fn handle_star_ko(my_long_ptr: &mut u64) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
static REUSED_UI_OFFSET: usize = 0x068cd80;
|
||||
// A function reused by many functions to update UI. Called to update at least Little Mac's meter.
|
||||
#[skyline::hook(offset = REUSED_UI_OFFSET)]
|
||||
#[skyline::hook(offset = *OFFSET_REUSED_UI)]
|
||||
pub unsafe fn handle_reused_ui(
|
||||
fighter_data: *mut u32, // a pointer to length 4 data in the Fighter's FighterEntry in the FighterManager
|
||||
mut param_2: u32, // In Little Mac's case, the meter value as an integer
|
||||
|
@ -779,22 +760,18 @@ pub unsafe fn handle_reused_ui(
|
|||
original!()(fighter_data, param_2)
|
||||
}
|
||||
|
||||
static ARTICLE_GET_INT_OFFSET: usize = 0x3d5920;
|
||||
|
||||
#[skyline::hook(offset = ARTICLE_GET_INT_OFFSET)]
|
||||
#[skyline::hook(replace = ArticleModule::get_int)]
|
||||
pub unsafe fn handle_article_get_int(
|
||||
article_module: *mut app::BattleObjectModuleAccessor, // *mut ArticleModule
|
||||
module_accessor: *mut BattleObjectModuleAccessor,
|
||||
generate_article: i32,
|
||||
address: i32,
|
||||
) -> i32 {
|
||||
original!()(article_module, generate_article, address)
|
||||
original!()(module_accessor, generate_article, address)
|
||||
}
|
||||
|
||||
// Instruction run on the completion of the CPU Control function
|
||||
static OPCF_OFFSET: usize = 0x06b7fdc;
|
||||
|
||||
// One instruction after the CPU Control function completes
|
||||
#[skyline::hook(offset = OPCF_OFFSET, inline)]
|
||||
#[skyline::hook(offset = *OFFSET_OPCF, inline)]
|
||||
unsafe fn handle_once_per_cpu_frame(_ctx: &mut InlineCtx) {
|
||||
input_record::handle_recording();
|
||||
frame_counter::tick_ingame();
|
||||
|
@ -808,9 +785,7 @@ unsafe fn handle_once_per_cpu_frame(_ctx: &mut InlineCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
static FIM_OFFSET: usize = 0x17504a0;
|
||||
// TODO: Should we define all of our offsets in one file? Should at least be a good start for changing to be based on ASM instructions
|
||||
#[skyline::hook(offset = FIM_OFFSET)]
|
||||
#[skyline::hook(offset = *OFFSET_FIM)]
|
||||
unsafe fn handle_final_input_mapping(
|
||||
mappings: *mut ControllerMapping,
|
||||
player_idx: i32, // Is this the player index, or plugged in controller index? Need to check, assuming player for now - is this 0 indexed or 1?
|
||||
|
@ -881,8 +856,7 @@ pub fn training_mods() {
|
|||
// Enable Custom Stages for Training Mode
|
||||
// Specifically, we prevent a field in StageSelectInfo of the Scene that controls if the Custom Stage tab is loaded
|
||||
// from being set to false when we load the SSS in Training Mode
|
||||
static SSS_TRAINING_OFFSET: usize = 0x184d1d8;
|
||||
skyline::patching::Patch::in_text(SSS_TRAINING_OFFSET)
|
||||
skyline::patching::Patch::in_text(*OFFSET_SSS_TRAINING)
|
||||
.nop()
|
||||
.unwrap();
|
||||
|
||||
|
@ -922,8 +896,8 @@ pub fn training_mods() {
|
|||
// Buff SFX
|
||||
handle_fighter_play_se,
|
||||
// Stale Moves
|
||||
stale_menu_handle, // This has to be initialized before stale_handle otherwise the offset search fails
|
||||
stale_handle,
|
||||
stale_menu_handle,
|
||||
// Death SFX
|
||||
handle_se,
|
||||
// Death GFX
|
||||
|
|
|
@ -6,6 +6,9 @@ use smash::lua2cpp::L2CFighterBase;
|
|||
use smash::phx::{Hash40, Vector3f};
|
||||
|
||||
use crate::common::consts::*;
|
||||
use crate::common::offsets::OFFSET_CHANGE_ACTIVE_CAMERA;
|
||||
|
||||
use crate::common::offsets::OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES;
|
||||
use crate::common::*;
|
||||
use crate::training::{frame_counter, mash, save_states};
|
||||
|
||||
|
@ -393,31 +396,25 @@ pub unsafe fn hide_tech() {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct FighterCameraModule {
|
||||
_vtable: u64,
|
||||
owner: *mut BattleObjectModuleAccessor,
|
||||
}
|
||||
|
||||
// Prevent Mistech Quake
|
||||
#[skyline::hook(offset = 0x3ec820)]
|
||||
#[skyline::hook(replace = CameraModule::req_quake_pos)]
|
||||
pub unsafe fn handle_fighter_req_quake_pos(
|
||||
camera_module: &mut FighterCameraModule,
|
||||
module_accessor: &mut BattleObjectModuleAccessor,
|
||||
quake_kind: i32,
|
||||
) -> u64 {
|
||||
let module_accessor = camera_module.owner;
|
||||
if !is_training_mode() || !is_operation_cpu(&mut *module_accessor) {
|
||||
return original!()(camera_module, quake_kind);
|
||||
return original!()(module_accessor, quake_kind);
|
||||
}
|
||||
let status = StatusModule::status_kind(module_accessor);
|
||||
if status == FIGHTER_STATUS_KIND_DOWN && MENU.tech_hide == OnOff::ON {
|
||||
// We're hiding techs, prevent mistech quake from giving away missed tech
|
||||
return original!()(camera_module, *CAMERA_QUAKE_KIND_NONE);
|
||||
return original!()(module_accessor, *CAMERA_QUAKE_KIND_NONE);
|
||||
}
|
||||
original!()(camera_module, quake_kind)
|
||||
original!()(module_accessor, quake_kind)
|
||||
}
|
||||
|
||||
// Zoom in the Fixed Camera view while this is on to set up a good situation for practice
|
||||
#[skyline::hook(offset = 0x4ee460)]
|
||||
#[skyline::hook(offset = *OFFSET_CHANGE_ACTIVE_CAMERA)]
|
||||
pub unsafe fn handle_change_active_camera(
|
||||
camera_manager: *mut u64,
|
||||
camera_mode: i32,
|
||||
|
@ -733,7 +730,7 @@ fn get_stage_camera_values(stage_id: i32) -> Option<Vector3f> {
|
|||
}
|
||||
|
||||
// We hook where the training fixed camera fields are initially set, so we can change them later if necessary
|
||||
#[skyline::hook(offset = 0x3157bb0)]
|
||||
#[skyline::hook(offset = *OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES)]
|
||||
pub unsafe fn handle_set_training_fixed_camera_values(
|
||||
camera_manager: *mut u64, // not actually camera manager - is this even used?????
|
||||
fixed_camera_values: &mut CameraValuesForTraining,
|
||||
|
|
|
@ -5,12 +5,12 @@ use skyline::nn::ui2d::*;
|
|||
use smash::ui2d::SmashTextBox;
|
||||
use training_mod_consts::{OnOff, MENU};
|
||||
|
||||
use crate::common::menu::QUICK_MENU_ACTIVE;
|
||||
use crate::common::offsets::{OFFSET_DRAW, OFFSET_LAYOUT_ARC_MALLOC};
|
||||
use crate::common::{is_ready_go, is_training_mode};
|
||||
#[cfg(feature = "layout_arc_from_file")]
|
||||
use crate::consts::LAYOUT_ARC_PATH;
|
||||
use crate::{
|
||||
common::{is_ready_go, is_training_mode, menu::QUICK_MENU_ACTIVE},
|
||||
training::frame_counter,
|
||||
};
|
||||
use crate::training::frame_counter;
|
||||
|
||||
mod damage;
|
||||
mod display;
|
||||
|
@ -52,7 +52,7 @@ pub fn fade_out(pane: &mut Pane, current_frame: u32, total_frames: u32) {
|
|||
}
|
||||
}
|
||||
|
||||
#[skyline::hook(offset = 0x4b620)]
|
||||
#[skyline::hook(offset = *OFFSET_DRAW)]
|
||||
pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64) {
|
||||
let layout_name = skyline::from_c_str((*layout).layout_name);
|
||||
let root_pane = &mut *(*layout).root_pane;
|
||||
|
@ -128,7 +128,7 @@ static mut LAYOUT_ARC: &mut [u8; LAYOUT_ARC_SIZE] = &mut [0u8; LAYOUT_ARC_SIZE];
|
|||
/// label_material.set_white_res_color(LABEL_WHITE_SELECTED_COLOR);
|
||||
/// label_material.set_black_res_color(LABEL_BLACK_SELECTED_COLOR);
|
||||
/// ```
|
||||
#[skyline::hook(offset = 0x37730d4, inline)]
|
||||
#[skyline::hook(offset = *OFFSET_LAYOUT_ARC_MALLOC, inline)]
|
||||
unsafe fn handle_layout_arc_malloc(ctx: &mut skyline::hooks::InlineCtx) {
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue