From 8feab4cf17767fbb82f18e2b99bec17137701152 Mon Sep 17 00:00:00 2001 From: sidschingis Date: Thu, 13 Aug 2020 23:20:56 +0200 Subject: [PATCH] Shield Flash Workaround (#134) * Fix Shield Buffer Shield doesn't work with cat_flags * Move unsafe declaration inwards --- src/common/mod.rs | 67 ++++++++++++++++++++++++-------------- src/training/left_stick.rs | 10 +++--- src/training/mash.rs | 46 ++++++++++++++++---------- src/training/shield.rs | 6 ++-- 4 files changed, 78 insertions(+), 51 deletions(-) diff --git a/src/common/mod.rs b/src/common/mod.rs index 775f312..b5260fc 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -42,41 +42,52 @@ pub fn get_category(module_accessor: &mut app::BattleObjectModuleAccessor) -> i3 return (module_accessor.info >> 28) as u8 as i32; } -pub unsafe fn get_module_accessor(fighter_id: FighterId) -> *mut app::BattleObjectModuleAccessor { +pub fn get_module_accessor(fighter_id: FighterId) -> *mut app::BattleObjectModuleAccessor { let entry_id_int = fighter_id as i32; let entry_id = app::FighterEntryID(entry_id_int); - let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager); - let fighter_entry = FighterManager::get_fighter_entry(mgr, entry_id) as *mut app::FighterEntry; - let current_fighter_id = FighterEntry::current_fighter_id(fighter_entry); - app::sv_battle_object::module_accessor(current_fighter_id as u32) + unsafe { + let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager); + let fighter_entry = + FighterManager::get_fighter_entry(mgr, entry_id) as *mut app::FighterEntry; + let current_fighter_id = FighterEntry::current_fighter_id(fighter_entry); + app::sv_battle_object::module_accessor(current_fighter_id as u32) + } } -pub unsafe fn is_fighter(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { +pub fn is_fighter(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { get_category(module_accessor) == BATTLE_OBJECT_CATEGORY_FIGHTER } -pub unsafe fn is_operation_cpu(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { - if !is_fighter(module_accessor) { - return false; +pub fn is_operation_cpu(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { + unsafe { + if !is_fighter(module_accessor) { + return false; + } + + let entry_id_int = + WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32; + let entry_id = app::FighterEntryID(entry_id_int); + let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager); + let fighter_information = + FighterManager::get_fighter_information(mgr, entry_id) as *mut app::FighterInformation; + + FighterInformation::is_operation_cpu(fighter_information) } - - let entry_id_int = - WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32; - let entry_id = app::FighterEntryID(entry_id_int); - let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager); - let fighter_information = - FighterManager::get_fighter_information(mgr, entry_id) as *mut app::FighterInformation; - - FighterInformation::is_operation_cpu(fighter_information) } -pub unsafe fn is_grounded(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { - let situation_kind = StatusModule::situation_kind(module_accessor) as i32; +pub fn is_grounded(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { + let situation_kind; + unsafe { + situation_kind = StatusModule::situation_kind(module_accessor) as i32; + } situation_kind == SITUATION_KIND_GROUND } -pub unsafe fn is_airborne(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { - let situation_kind = StatusModule::situation_kind(module_accessor) as i32; +pub fn is_airborne(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { + let situation_kind; + unsafe { + situation_kind = StatusModule::situation_kind(module_accessor) as i32; + } situation_kind == SITUATION_KIND_AIR } @@ -110,9 +121,15 @@ pub fn is_shielding(module_accessor: *mut app::BattleObjectModuleAccessor) -> bo } } -pub unsafe fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { - let status_kind = StatusModule::status_kind(module_accessor); - let prev_status = StatusModule::prev_status_kind(module_accessor, 0); +pub fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { + let status_kind; + let prev_status; + + unsafe { + status_kind = StatusModule::status_kind(module_accessor); + prev_status = StatusModule::prev_status_kind(module_accessor, 0); + } + // If we are taking shield damage or we are droping shield from taking shield damage we are in hitstun status_kind == FIGHTER_STATUS_KIND_GUARD_DAMAGE || (prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE diff --git a/src/training/left_stick.rs b/src/training/left_stick.rs index 2232abb..b51d356 100644 --- a/src/training/left_stick.rs +++ b/src/training/left_stick.rs @@ -67,10 +67,8 @@ unsafe fn get_angle(module_accessor: &mut app::BattleObjectModuleAccessor) -> f6 } fn is_correct_status(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { - let air_dodge_condition; - unsafe { - air_dodge_condition = is_airborne(module_accessor) && is_in_hitstun(module_accessor); - } + let air_dodge_condition= is_airborne(module_accessor) && is_in_hitstun(module_accessor); + if air_dodge_condition { return true; } @@ -78,7 +76,7 @@ fn is_correct_status(module_accessor: &mut app::BattleObjectModuleAccessor) -> b return false; } -unsafe fn pick_angle(direction: Direction) -> f64 { +fn pick_angle(direction: Direction) -> f64 { if direction == Direction::Random { let rand_direction = get_random_direction(); return direction_to_angle(rand_direction); @@ -87,7 +85,7 @@ unsafe fn pick_angle(direction: Direction) -> f64 { direction_to_angle(direction) } -unsafe fn get_random_direction() -> Direction { +fn get_random_direction() -> Direction { let rand = get_random_int(8); Direction::from(rand) } diff --git a/src/training/mash.rs b/src/training/mash.rs index 6cc8c73..94baf5b 100644 --- a/src/training/mash.rs +++ b/src/training/mash.rs @@ -195,21 +195,19 @@ pub fn mash_to_action(mash: Mash) -> Action { fn get_random_action(module_accessor: &mut app::BattleObjectModuleAccessor) -> Action { let mut random_cmds = vec![Mash::Jump, Mash::Attack]; - unsafe { - if is_airborne(module_accessor) { - random_cmds.push(Mash::Airdodge); - } - - if is_grounded(module_accessor) { - random_cmds.push(Mash::RollBack); - random_cmds.push(Mash::RollForward); - random_cmds.push(Mash::Spotdodge); - } - - let random_cmd_index = get_random_int(random_cmds.len() as i32) as usize; - - mash_to_action(random_cmds[random_cmd_index]) + if is_airborne(module_accessor) { + random_cmds.push(Mash::Airdodge); } + + if is_grounded(module_accessor) { + random_cmds.push(Mash::RollBack); + random_cmds.push(Mash::RollForward); + random_cmds.push(Mash::Spotdodge); + } + + let random_cmd_index = get_random_int(random_cmds.len() as i32) as usize; + + mash_to_action(random_cmds[random_cmd_index]) } fn attack_to_action(attack: Attack) -> Action { @@ -248,6 +246,10 @@ unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor) let command_flag; // Shield if grounded instead if is_grounded(module_accessor) { + /* + Doesn't actually cause the shield, but will clear the buffer once shield is possible. + Shield hold is performed through shield::should_hold_shield and request_shield + */ expected_status = *FIGHTER_STATUS_KIND_GUARD_ON; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE; } else { @@ -284,7 +286,7 @@ unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor) Shield => { /* Doesn't actually cause the shield, but will clear the buffer once shield is possible. - Shield hold is performed through shield::should_hold_shield + Shield hold is performed through shield::should_hold_shield and request_shield */ return get_flag( module_accessor, @@ -296,6 +298,16 @@ unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor) } } +pub fn request_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { + match get_current_buffer() { + Action::Shield => return true, + Action::Airdodge => return is_grounded(module_accessor), + _ => {} + } + + return false; +} + unsafe fn update_jump_flag(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 { let check_flag = if is_grounded(module_accessor) { *FIGHTER_STATUS_KIND_JUMP_SQUAT @@ -438,9 +450,9 @@ unsafe fn get_aerial_flag( * We always trigger attack and change it later into the correct aerial * @see get_attack_air_kind() */ - let command_flag: i32 = match action { + let command_flag: i32 = match action { Nair | Fair | Bair | UpAir | Dair => *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N, - _ => 0 + _ => 0, }; set_aerial(action); diff --git a/src/training/shield.rs b/src/training/shield.rs index 5969aa3..59d0e03 100644 --- a/src/training/shield.rs +++ b/src/training/shield.rs @@ -130,9 +130,9 @@ pub unsafe fn get_param_float( None } -pub fn should_hold_shield() -> bool { +pub fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { // Mash shield - if mash::get_current_buffer() == Action::Shield { + if mash::request_shield(module_accessor) { return true; } @@ -343,7 +343,7 @@ unsafe fn should_return_none_in_check_button( return true; } - if !should_hold_shield() { + if !should_hold_shield(module_accessor) { return true; }