1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-20 00:46:34 +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:
GradualSyrup 2023-09-01 13:10:03 -05:00 committed by GitHub
parent c6352651a1
commit ebe6393143
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 112 additions and 1 deletions

View file

@ -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,
) {
}

View file

@ -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)
}