From 4a634b31a573ed7fed367b45ddc18425c7076c10 Mon Sep 17 00:00:00 2001 From: jugeeya Date: Fri, 4 Aug 2023 15:34:44 -0700 Subject: [PATCH] Playback Slots for Actions and Ledge Options --- src/training/input_record.rs | 12 ++--- src/training/ledge.rs | 8 +-- src/training/mash.rs | 14 ++++-- src/training/save_states.rs | 2 +- training_mod_consts/src/lib.rs | 2 +- training_mod_consts/src/options.rs | 79 ++++++++++++++++++++++++++++-- 6 files changed, 97 insertions(+), 20 deletions(-) diff --git a/src/training/input_record.rs b/src/training/input_record.rs index 18b2d05..82ace20 100644 --- a/src/training/input_record.rs +++ b/src/training/input_record.rs @@ -123,7 +123,7 @@ unsafe fn should_mash_playback() { // probably need a separate standby setting for grounded, aerial, shield, where shield starts once you let go of shield, and aerial keeps you in the air? if should_playback { - playback(); + playback(mash::queued_playback_slot()); } } @@ -183,7 +183,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces button_config::ButtonCombo::InputPlayback, ) { //crate::common::raygun_printer::print_string(&mut *module_accessor, "PLAYBACK"); - playback(); + playback(MENU.playback_slot.get_random().into_idx().unwrap_or(0)); println!("Playback Command Received!"); //debug } // Attack + Dpad Left: Record @@ -304,7 +304,7 @@ pub unsafe fn _record() { BUFFER_FRAME = 0; } -pub unsafe fn playback() { +pub unsafe fn playback(slot: usize) { if INPUT_RECORD == Pause { println!("Tried to playback during lockout!"); return; @@ -327,7 +327,7 @@ pub unsafe fn playback() { }, ); - CURRENT_PLAYBACK_SLOT = MENU.playback_slot.get_random().into_idx().unwrap_or(0); + CURRENT_PLAYBACK_SLOT = slot; INPUT_RECORD = Playback; POSSESSION = Player; INPUT_RECORD_FRAME = 0; @@ -336,7 +336,7 @@ pub unsafe fn playback() { CURRENT_LR = PostureModule::lr(cpu_module_accessor); } -pub unsafe fn playback_ledge() { +pub unsafe fn playback_ledge(slot: usize) { if INPUT_RECORD == Pause { println!("Tried to playback during lockout!"); return; @@ -359,7 +359,7 @@ pub unsafe fn playback_ledge() { }, ); - CURRENT_PLAYBACK_SLOT = MENU.playback_slot.get_random().into_idx().unwrap_or(0); + CURRENT_PLAYBACK_SLOT = slot; INPUT_RECORD = Playback; POSSESSION = Player; diff --git a/src/training/ledge.rs b/src/training/ledge.rs index 39e1dd6..6af0312 100644 --- a/src/training/ledge.rs +++ b/src/training/ledge.rs @@ -138,11 +138,11 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor // Not able to take any action yet // We buffer playback on frame 18 because we don't change status this frame from inputting on next frame; do we need to do one earlier for lasso? if should_buffer_playback - && LEDGE_CASE == LedgeOption::PLAYBACK + && LEDGE_CASE.is_playback() && MENU.record_trigger != RecordTrigger::Ledge && MENU.ledge_delay != LongDelay::empty() { - input_record::playback_ledge(); + input_record::playback_ledge(LEDGE_CASE.playback_slot()); return; } // This check isn't reliable for buffered options in time, so don't return if we need to buffer an option this frame @@ -163,9 +163,9 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor let status = LEDGE_CASE.into_status().unwrap_or(0); - if LEDGE_CASE == LedgeOption::PLAYBACK { + if LEDGE_CASE.is_playback() { if MENU.record_trigger != RecordTrigger::Ledge { - input_record::playback(); + input_record::playback(LEDGE_CASE.playback_slot()); } } else { StatusModule::change_status_request_from_script(module_accessor, status, true); diff --git a/src/training/mash.rs b/src/training/mash.rs index 12073cd..fb04123 100644 --- a/src/training/mash.rs +++ b/src/training/mash.rs @@ -44,7 +44,11 @@ unsafe fn dash_transition_check(module_accessor: &mut app::BattleObjectModuleAcc } pub fn is_playback_queued() -> bool { - get_current_buffer() == Action::PLAYBACK + get_current_buffer().is_playback() +} + +pub fn queued_playback_slot() -> usize { + get_current_buffer().playback_slot() } pub unsafe fn is_dashing_for_dash_attack( @@ -77,7 +81,7 @@ pub fn buffer_action(action: Action) { && !input_record::is_recording() && !input_record::is_standby() && !is_playback_queued() - && action != Action::PLAYBACK + && !action.is_playback() { //println!("Stopping mash playback for menu option!"); // if we don't want to leave playback on mash actions, then don't perform the mash @@ -383,7 +387,11 @@ unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor) get_flag(module_accessor, *FIGHTER_STATUS_KIND_DASH, 0) } - Action::PLAYBACK => { + Action::PLAYBACK_1 + | Action::PLAYBACK_2 + | Action::PLAYBACK_3 + | Action::PLAYBACK_4 + | Action::PLAYBACK_5 => { // Because these status changes take place after we would receive input from the controller, we need to queue input playback 1 frame before we can act 0 // We don't ever want to explicitly provide any command flags here; if we're trying to do input recording, the playback handles it all } diff --git a/src/training/save_states.rs b/src/training/save_states.rs index 64dca44..488c558 100644 --- a/src/training/save_states.rs +++ b/src/training/save_states.rs @@ -613,7 +613,7 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) } // otherwise, begin input recording playback if selected else if MENU.save_state_playback == OnOff::On { - input_record::playback(); + input_record::playback(MENU.playback_slot.get_random().into_idx().unwrap_or(0)); } return; diff --git a/training_mod_consts/src/lib.rs b/training_mod_consts/src/lib.rs index aada46b..3717258 100644 --- a/training_mod_consts/src/lib.rs +++ b/training_mod_consts/src/lib.rs @@ -766,7 +766,7 @@ pub unsafe fn ui_menu(menu: TrainingModpackMenu) -> UiMenu<'static> { true, &(menu.save_state_playback as u32), ); - input_tab.add_submenu_with_toggles::( // TODO: This menu should really be a submenu inside Action menus, probably want to be able to customize for each action + input_tab.add_submenu_with_toggles::( "Playback Slots", "playback_slot", "Playback Slots: Choose which slots to choose between for playback when this action is triggered", diff --git a/training_mod_consts/src/options.rs b/training_mod_consts/src/options.rs index 832fe38..26c979c 100644 --- a/training_mod_consts/src/options.rs +++ b/training_mod_consts/src/options.rs @@ -191,7 +191,11 @@ bitflags! { const JUMP = 0x4; const ATTACK = 0x8; const WAIT = 0x10; - const PLAYBACK = 0x20; + const PLAYBACK_1 = 0x20; + const PLAYBACK_2 = 0x40; + const PLAYBACK_3 = 0x80; + const PLAYBACK_4 = 0x100; + const PLAYBACK_5 = 0x200; } } @@ -205,7 +209,11 @@ impl LedgeOption { LedgeOption::JUMP => *FIGHTER_STATUS_KIND_CLIFF_JUMP1, LedgeOption::ATTACK => *FIGHTER_STATUS_KIND_CLIFF_ATTACK, LedgeOption::WAIT => *FIGHTER_STATUS_KIND_CLIFF_WAIT, - LedgeOption::PLAYBACK => *FIGHTER_STATUS_KIND_NONE, + LedgeOption::PLAYBACK_1 + | LedgeOption::PLAYBACK_2 + | LedgeOption::PLAYBACK_3 + | LedgeOption::PLAYBACK_4 + | LedgeOption::PLAYBACK_5 => *FIGHTER_STATUS_KIND_NONE, _ => return None, }) } @@ -221,10 +229,41 @@ impl LedgeOption { LedgeOption::JUMP => "Jump", LedgeOption::ATTACK => "Getup Attack", LedgeOption::WAIT => "Wait", - LedgeOption::PLAYBACK => "Input Playback", + LedgeOption::PLAYBACK_1 => "Playback Slot 1", + LedgeOption::PLAYBACK_2 => "Playback Slot 2", + LedgeOption::PLAYBACK_3 => "Playback Slot 3", + LedgeOption::PLAYBACK_4 => "Playback Slot 4", + LedgeOption::PLAYBACK_5 => "Playback Slot 5", + _ => return None, }) } + + pub fn is_playback(self) -> bool { + match self { + LedgeOption::PLAYBACK_1 + | LedgeOption::PLAYBACK_2 + | LedgeOption::PLAYBACK_3 + | LedgeOption::PLAYBACK_4 + | LedgeOption::PLAYBACK_5 => true, + _ => false, + } + } + + pub fn playback_slot(self) -> usize { + match self { + LedgeOption::PLAYBACK_1 => 0, + LedgeOption::PLAYBACK_2 => 1, + LedgeOption::PLAYBACK_3 => 2, + LedgeOption::PLAYBACK_4 => 3, + LedgeOption::PLAYBACK_5 => 4, + _ => panic!( + "Invalid LedgeOption playback slot: {}", + self.as_str().unwrap() + ), + } + } + pub const fn default() -> LedgeOption { // Neutral,Roll,Jump,Attack (everything except wait) LedgeOption::NEUTRAL @@ -414,7 +453,11 @@ bitflags! { // TODO: Make work const DASH = 0x0080_0000; const DASH_ATTACK = 0x0100_0000; - const PLAYBACK = 0x0200_0000; + const PLAYBACK_1 = 0x0200_0000; + const PLAYBACK_2 = 0x0400_0000; + const PLAYBACK_3 = 0x0800_0000; + const PLAYBACK_4 = 0x1000_0000; + const PLAYBACK_5 = 0x2000_0000; } } @@ -463,10 +506,36 @@ impl Action { Action::GRAB => "Grab", Action::DASH => "Dash", Action::DASH_ATTACK => "Dash Attack", - Action::PLAYBACK => "Input Playback", + Action::PLAYBACK_1 => "Playback Slot 1", + Action::PLAYBACK_2 => "Playback Slot 2", + Action::PLAYBACK_3 => "Playback Slot 3", + Action::PLAYBACK_4 => "Playback Slot 4", + Action::PLAYBACK_5 => "Playback Slot 5", _ => return None, }) } + + pub fn is_playback(self) -> bool { + match self { + Action::PLAYBACK_1 + | Action::PLAYBACK_2 + | Action::PLAYBACK_3 + | Action::PLAYBACK_4 + | Action::PLAYBACK_5 => true, + _ => false, + } + } + + pub fn playback_slot(self) -> usize { + match self { + Action::PLAYBACK_1 => 0, + Action::PLAYBACK_2 => 1, + Action::PLAYBACK_3 => 2, + Action::PLAYBACK_4 => 3, + Action::PLAYBACK_5 => 4, + _ => panic!("Invalid Action playback slot: {}", self.as_str().unwrap()), + } + } } extra_bitflag_impls! {Action}