mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-19 16:36:35 +00:00
Add Kirby Hats to Save States (#615)
* Add reusable print_fighter_info() * rustfmt * Clippy * starting charge * Working Pikmin Save States, motion not working, order can be messed up by loading during an aerial, if you save too quickly you lose pikmin in the state * often failing boid read * notes * Prevent Pikmin from being cleaned up by the regular cleanup process * migration progress * skyline-smash branch, more pikmin work * Using buff to spawn pikmin, character specific file for cleanliness * failed reordering attempt * more failed ordering * almost kind of works but out of order * failed all, need to try individual hold and status change * hard reorder crash * battleobject not boma * comment clarification * messing around with printing * printing, about to try to find where autonomy is being set * solution found, going to hook backshield to find where autonomy is being set to true * found where to hook, will start hooking * switched to charge, issues with inline hook * need to only have autonomy ignored on save state load * distance and status controls (doesn't work perfectly) * Christmas Miracle * Working w/ Cleanup * training mode check, improved owner check * Debug for hooking, Working Implementation (No Transform, No Charge) * Working for Aegis, PT having issues (LRA into state load works, but not regular state load) * Working ptrainer hats * fmt fmt fmt
This commit is contained in:
parent
c6352651a1
commit
ebe6393143
2 changed files with 112 additions and 1 deletions
|
@ -1,8 +1,20 @@
|
|||
use crate::common::consts::FighterId;
|
||||
use crate::common::get_module_accessor;
|
||||
use crate::training::character_specific::pikmin;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use smash::app::{self, lua_bind::*, ArticleOperationTarget, FighterFacial, FighterUtil};
|
||||
use smash::lib::lua_const::*;
|
||||
use smash::phx::{Hash40, Vector3f};
|
||||
use std::ptr;
|
||||
|
||||
#[skyline::from_offset(0xba0e60)]
|
||||
fn copy_setup(
|
||||
module_accessor: *mut app::BattleObjectModuleAccessor,
|
||||
int: i32,
|
||||
fighter_kind: i32,
|
||||
bool_1: bool,
|
||||
bool_2: bool,
|
||||
);
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Copy, Clone, Debug)]
|
||||
pub struct ChargeState {
|
||||
|
@ -88,6 +100,16 @@ pub unsafe fn get_charge(
|
|||
);
|
||||
charge_state.int_x(my_charge)
|
||||
}
|
||||
// Kirby Copy Abilities
|
||||
else if fighter_kind == FIGHTER_KIND_KIRBY {
|
||||
let hat_have =
|
||||
WorkModule::is_flag(module_accessor, *FIGHTER_KIRBY_INSTANCE_WORK_ID_FLAG_COPY);
|
||||
let chara_kind = WorkModule::get_int(
|
||||
module_accessor,
|
||||
*FIGHTER_KIRBY_INSTANCE_WORK_ID_INT_COPY_CHARA,
|
||||
);
|
||||
charge_state.has_charge(hat_have).int_x(chara_kind)
|
||||
}
|
||||
// Sheik Needles
|
||||
else if fighter_kind == FIGHTER_KIND_SHEIK {
|
||||
let my_charge = WorkModule::get_int(
|
||||
|
@ -335,6 +357,25 @@ pub unsafe fn handle_charge(
|
|||
}
|
||||
});
|
||||
}
|
||||
// Kirby Copy Abilities
|
||||
else if fighter_kind == FIGHTER_KIND_KIRBY {
|
||||
charge.has_charge.map(|_has_copy_ability| {
|
||||
let cpu_module_accessor = &mut *get_module_accessor(FighterId::CPU);
|
||||
let player_module_accessor = &mut *get_module_accessor(FighterId::Player);
|
||||
let opponent_module_accessor: &mut app::BattleObjectModuleAccessor =
|
||||
if ptr::eq(module_accessor, player_module_accessor) {
|
||||
cpu_module_accessor
|
||||
} else {
|
||||
player_module_accessor
|
||||
};
|
||||
// Only try to set up Copy Ability when the current opponent matches the type of fighter from the save state
|
||||
let opponent_matches_fighter =
|
||||
is_kirby_hat_okay(opponent_module_accessor, charge.int_x);
|
||||
if opponent_matches_fighter == Some(true) {
|
||||
copy_setup(module_accessor, 1, charge.int_x.unwrap(), true, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Sheik Needles - 0 to 6
|
||||
else if fighter_kind == FIGHTER_KIND_SHEIK {
|
||||
charge.int_x.map(|needle_charge| {
|
||||
|
@ -885,3 +926,50 @@ pub unsafe fn handle_charge(
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn is_kirby_hat_okay(
|
||||
opponent_module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
save_state_fighter_option: Option<i32>,
|
||||
) -> Option<bool> {
|
||||
let mut opponent_fighter_kind = app::utility::get_kind(opponent_module_accessor);
|
||||
let save_state_fighter_kind = save_state_fighter_option?;
|
||||
if opponent_fighter_kind == save_state_fighter_kind {
|
||||
return Some(true);
|
||||
}
|
||||
// We have a fighter but they don't match - see if it's an accepted transformation
|
||||
let trainer_kinds = [
|
||||
*FIGHTER_KIND_PZENIGAME,
|
||||
*FIGHTER_KIND_PFUSHIGISOU,
|
||||
*FIGHTER_KIND_PLIZARDON,
|
||||
-1, // Fighter Kind while switching pokemon
|
||||
];
|
||||
let element_kinds = [*FIGHTER_KIND_EFLAME, *FIGHTER_KIND_ELIGHT];
|
||||
if opponent_fighter_kind == -1 {
|
||||
let trainer_boid = LinkModule::get_parent_object_id(
|
||||
opponent_module_accessor,
|
||||
*FIGHTER_POKEMON_LINK_NO_PTRAINER,
|
||||
) as u32;
|
||||
if trainer_boid != *BATTLE_OBJECT_ID_INVALID as u32
|
||||
&& app::sv_battle_object::is_active(trainer_boid)
|
||||
{
|
||||
opponent_fighter_kind = *FIGHTER_KIND_PZENIGAME; // ptrainer is in the match, so assume we have a ptrainer fighter
|
||||
}
|
||||
}
|
||||
let both_trainer = trainer_kinds.contains(&opponent_fighter_kind)
|
||||
&& trainer_kinds.contains(&save_state_fighter_kind);
|
||||
let both_element = element_kinds.contains(&opponent_fighter_kind)
|
||||
&& element_kinds.contains(&save_state_fighter_kind);
|
||||
Some(both_trainer || both_element)
|
||||
}
|
||||
|
||||
pub unsafe fn _get_kirby_hat_charge(
|
||||
_module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
_opponent_fighter_kind: i32,
|
||||
) {
|
||||
}
|
||||
|
||||
pub unsafe fn _handle_kirby_hat_charge(
|
||||
_module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
_opponent_fighter_kind: i32,
|
||||
) {
|
||||
}
|
||||
|
|
|
@ -482,11 +482,17 @@ pub unsafe fn handle_se(
|
|||
)
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FighterSoundModule {
|
||||
vtable: u64,
|
||||
owner: *mut app::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)]
|
||||
pub unsafe fn handle_fighter_play_se(
|
||||
sound_module: u64, // pointer to fighter's SoundModule
|
||||
sound_module: *mut FighterSoundModule, // pointer to fighter's SoundModule
|
||||
my_hash: Hash40,
|
||||
bool1: bool,
|
||||
bool2: bool,
|
||||
|
@ -511,6 +517,23 @@ pub unsafe fn handle_fighter_play_se(
|
|||
se_type,
|
||||
);
|
||||
}
|
||||
|
||||
// Supress Kirby Copy Ability SFX when loading Save State
|
||||
if my_hash.hash == 0x1453dd86e4 || my_hash.hash == 0x14bdd3e7c8 {
|
||||
let module_accessor = (*sound_module).owner;
|
||||
if StatusModule::status_kind(module_accessor) != FIGHTER_KIRBY_STATUS_KIND_SPECIAL_N_DRINK {
|
||||
let silent_hash = Hash40::new("se_silent");
|
||||
return original!()(
|
||||
sound_module,
|
||||
silent_hash,
|
||||
bool1,
|
||||
bool2,
|
||||
bool3,
|
||||
bool4,
|
||||
se_type,
|
||||
);
|
||||
}
|
||||
}
|
||||
original!()(sound_module, my_hash, bool1, bool2, bool3, bool4, se_type)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue