mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2025-01-19 08:50:14 +00:00
Buff Health Fixes (#571)
* Hooked AddDamage, pointer manipulation trouble * Working Wii Fit Fix * Inline Hook Setup for Sephiroth Wing (crashes) * Revert Broken Wing Chanes * Further revert * Fix Sephiroth Buff Percentage glitches
This commit is contained in:
parent
60f8ffc410
commit
fe8ae6f39f
5 changed files with 61 additions and 69 deletions
|
@ -2,6 +2,7 @@
|
|||
#![feature(const_mut_refs)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
#![feature(c_variadic)]
|
||||
#![feature(pointer_byte_offsets)]
|
||||
#![allow(
|
||||
clippy::borrow_interior_mutable_const,
|
||||
clippy::declare_interior_mutable_const,
|
||||
|
|
|
@ -62,9 +62,10 @@ pub unsafe fn handle_buffs(
|
|||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
fighter_kind: i32,
|
||||
status: i32,
|
||||
percent: f32,
|
||||
) -> bool {
|
||||
// Future Enhancement - Remove startup effects on buffs (Flash of Limit, Wii Fit's flash, Shulk's occasional Jump Art smoke, etc.)
|
||||
// Future Enhancements:
|
||||
// - Remove startup effects on buffs (Flash of Limit, Wii Fit's flash, Shulk's occasional Jump Art smoke, etc.)
|
||||
// - Ensure IS_BUFFING_CPU && IS_BUFFING_PLAYER are set to false on leaving training mode
|
||||
SoundModule::stop_all_sound(module_accessor); // silences buff sfx other than KO Punch
|
||||
ControlModule::stop_rumble(module_accessor, false);
|
||||
MotionAnimcmdModule::set_sleep(module_accessor, false);
|
||||
|
@ -78,13 +79,13 @@ pub unsafe fn handle_buffs(
|
|||
} else if fighter_kind == *FIGHTER_KIND_JACK && menu_vec.contains(&BuffOption::ARSENE) {
|
||||
return buff_joker(module_accessor);
|
||||
} else if fighter_kind == *FIGHTER_KIND_WIIFIT && menu_vec.contains(&BuffOption::BREATHING) {
|
||||
return buff_wiifit(module_accessor, status, percent);
|
||||
return buff_wiifit(module_accessor, status);
|
||||
} else if fighter_kind == *FIGHTER_KIND_CLOUD && menu_vec.contains(&BuffOption::LIMIT) {
|
||||
return buff_cloud(module_accessor);
|
||||
} else if fighter_kind == *FIGHTER_KIND_LITTLEMAC && menu_vec.contains(&BuffOption::KO) {
|
||||
return buff_mac(module_accessor);
|
||||
} else if fighter_kind == *FIGHTER_KIND_EDGE && menu_vec.contains(&BuffOption::WING) {
|
||||
return buff_sepiroth(module_accessor, percent);
|
||||
return buff_sepiroth(module_accessor);
|
||||
} else if fighter_kind == *FIGHTER_KIND_SHULK {
|
||||
return buff_shulk(module_accessor, status);
|
||||
}
|
||||
|
@ -193,27 +194,36 @@ unsafe fn buff_mac(module_accessor: &mut app::BattleObjectModuleAccessor) -> boo
|
|||
true
|
||||
}
|
||||
|
||||
unsafe fn buff_sepiroth(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
percent: f32,
|
||||
) -> bool {
|
||||
start_buff(module_accessor);
|
||||
if WorkModule::get_int(
|
||||
module_accessor,
|
||||
*FIGHTER_EDGE_INSTANCE_WORK_ID_INT_ONE_WINGED_WING_STATE,
|
||||
) == 1
|
||||
{
|
||||
// Once we're in wing, heal to correct damage
|
||||
DamageModule::heal(
|
||||
unsafe fn buff_sepiroth(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
if !is_buffing(module_accessor) {
|
||||
// To ensure Sephiroth gains Wing, we set flags for Sephiroth being in a Stamina Mode Sudden Death match.
|
||||
// The function that checks whether to start giving Sephiroth Wing every frame also checks for this exact
|
||||
// scenario. We do this because inline hooking it with the current version of skyline crashes the game,
|
||||
// likely due to the hook clobbering some of the floating point registers that we need for later.
|
||||
WorkModule::on_flag(
|
||||
module_accessor,
|
||||
-1.0 * DamageModule::damage(module_accessor, 0),
|
||||
0,
|
||||
*FIGHTER_EDGE_INSTANCE_WORK_ID_FLAG_IS_RULE_HP,
|
||||
);
|
||||
WorkModule::on_flag(
|
||||
module_accessor,
|
||||
*FIGHTER_EDGE_INSTANCE_WORK_ID_FLAG_SUDDEN_DEATH,
|
||||
);
|
||||
}
|
||||
start_buff(module_accessor);
|
||||
if WorkModule::is_flag(
|
||||
module_accessor,
|
||||
*FIGHTER_EDGE_INSTANCE_WORK_ID_FLAG_ONE_WINGED_ACTIVATED,
|
||||
) {
|
||||
// Wing is activated, so we turn off these flags so future deaths don't spawn Sephiroth in with Wing
|
||||
WorkModule::off_flag(
|
||||
module_accessor,
|
||||
*FIGHTER_EDGE_INSTANCE_WORK_ID_FLAG_IS_RULE_HP,
|
||||
);
|
||||
WorkModule::off_flag(
|
||||
module_accessor,
|
||||
*FIGHTER_EDGE_INSTANCE_WORK_ID_FLAG_SUDDEN_DEATH,
|
||||
);
|
||||
DamageModule::add_damage(module_accessor, percent, 0);
|
||||
return true;
|
||||
} else {
|
||||
// if we're not in wing, add damage
|
||||
DamageModule::add_damage(module_accessor, 1000.0, 0);
|
||||
}
|
||||
false
|
||||
}
|
||||
|
@ -259,29 +269,13 @@ unsafe fn buff_shulk(module_accessor: &mut app::BattleObjectModuleAccessor, stat
|
|||
false
|
||||
}
|
||||
|
||||
unsafe fn buff_wiifit(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
status: i32,
|
||||
percent: f32,
|
||||
) -> bool {
|
||||
if is_buffing(module_accessor) {
|
||||
if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) {
|
||||
// Need to wait 2 frames to make sure we stop breathing SFX
|
||||
return false;
|
||||
}
|
||||
// Deep Breathing can heal, so we need to reset the damage
|
||||
DamageModule::heal(
|
||||
module_accessor,
|
||||
-1.0 * DamageModule::damage(module_accessor, 0),
|
||||
0,
|
||||
);
|
||||
DamageModule::add_damage(module_accessor, percent, 0);
|
||||
return true;
|
||||
unsafe fn buff_wiifit(module_accessor: &mut app::BattleObjectModuleAccessor, status: i32) -> bool {
|
||||
if !is_buffing(module_accessor) {
|
||||
start_buff(module_accessor);
|
||||
}
|
||||
let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0);
|
||||
if prev_status_kind == FIGHTER_WIIFIT_STATUS_KIND_SPECIAL_LW_SUCCESS {
|
||||
start_buff(module_accessor);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if status != FIGHTER_WIIFIT_STATUS_KIND_SPECIAL_LW_SUCCESS {
|
||||
StatusModule::change_status_force(
|
||||
|
|
|
@ -622,10 +622,6 @@ unsafe fn get_flag(
|
|||
) -> i32 {
|
||||
// let current_status = StatusModule::prev_status_kind(module_accessor,0);
|
||||
let current_status = StatusModule::status_kind(module_accessor);
|
||||
println!(
|
||||
"Current Status: {}, Expected Status: {}",
|
||||
current_status, expected_status
|
||||
);
|
||||
if current_status == expected_status {
|
||||
// Reset Buffer
|
||||
reset();
|
||||
|
|
|
@ -120,26 +120,6 @@ fn once_per_frame_per_fighter(
|
|||
return;
|
||||
}
|
||||
|
||||
/*unsafe {
|
||||
let fighter_kind = app::utility::get_kind(module_accessor);
|
||||
if fighter_kind == *FIGHTER_KIND_LITTLEMAC {
|
||||
let status = StatusModule::status_kind(module_accessor);
|
||||
let gage_max_keep = WorkModule::get_int(module_accessor, *FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_INT_KO_GAGE_MAX_KEEP_FRAME);
|
||||
let select_timer = WorkModule::get_int(module_accessor, *FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_INT_SPECIAL_N2_HIT_FRAME);
|
||||
|
||||
let max_effect_flag = WorkModule::is_flag(module_accessor, *FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_FLAG_REQUEST_KO_GAUGE_MAX_EFFECT);
|
||||
let mesh_flag = WorkModule::is_flag(module_accessor, *FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_FLAG_DAMAGE_MESH);
|
||||
|
||||
let gage_max_keep = WorkModule::get_float(module_accessor, *FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_INT_KO_GAGE_MAX_KEEP_FRAME);
|
||||
let select_timer = WorkModule::get_float(module_accessor, *FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_INT_SPECIAL_N2_HIT_FRAME);
|
||||
|
||||
// may need to check out his status flags and not just work insts
|
||||
println!("Status: {:x}, Counter: {}, Select_Timer: {}, Decide_Interval_Frame: {}, SNType: {}, SNTypeSelect: {}, Sel_F: {}, Active_F: {}, SelButton: {}, Circ Menu: {}",
|
||||
status, counter, select_timer, decide_interval_frame, special_n_type, special_n_type_select, select_flag, active_flag, select_button_push_flag, circle_menu_flag
|
||||
);
|
||||
}
|
||||
}*/
|
||||
|
||||
unsafe {
|
||||
if menu::menu_condition(module_accessor) {
|
||||
menu::spawn_menu();
|
||||
|
@ -406,6 +386,26 @@ pub unsafe fn handle_check_doyle_summon_dispatch(
|
|||
ori
|
||||
}
|
||||
|
||||
#[skyline::hook(offset = 0x03ff9a0)]
|
||||
pub unsafe fn handle_add_damage(
|
||||
damage_module: *mut u64, // DamageModule
|
||||
mut damage_to_add: f32,
|
||||
param_2: i32,
|
||||
) -> u64 {
|
||||
if !is_training_mode() {
|
||||
return original!()(damage_module, damage_to_add, param_2);
|
||||
}
|
||||
let module_accessor =
|
||||
&mut **(damage_module.byte_add(0x8) as *mut *mut app::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)
|
||||
{
|
||||
damage_to_add = 0.0;
|
||||
}
|
||||
original!()(damage_module, damage_to_add, param_2)
|
||||
}
|
||||
|
||||
// Set Stale Moves to On
|
||||
static STALE_OFFSET: usize = 0x013e88a4;
|
||||
|
||||
|
@ -691,6 +691,9 @@ pub fn training_mods() {
|
|||
handle_check_doyle_summon_dispatch,
|
||||
handle_reused_ui,
|
||||
handle_req_screen,
|
||||
handle_add_damage,
|
||||
// Buff SFX
|
||||
handle_fighter_play_se,
|
||||
// Stale Moves
|
||||
stale_handle,
|
||||
stale_menu_handle,
|
||||
|
@ -702,8 +705,6 @@ pub fn training_mods() {
|
|||
handle_star_ko,
|
||||
// Clatter
|
||||
clatter::hook_start_clatter,
|
||||
// Buff SFX
|
||||
handle_fighter_play_se,
|
||||
);
|
||||
|
||||
combo::init();
|
||||
|
|
|
@ -621,7 +621,7 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
|
||||
if save_state.state == ApplyBuff {
|
||||
// needs its own save_state.state since this may take multiple frames, want it to loop
|
||||
if buff::handle_buffs(module_accessor, fighter_kind, status, save_state.percent) {
|
||||
if buff::handle_buffs(module_accessor, fighter_kind, status) {
|
||||
// returns true when done buffing fighter
|
||||
buff::restart_buff(module_accessor);
|
||||
// set is_buffing back to false when done
|
||||
|
|
Loading…
Reference in a new issue