1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-30 22:00:16 +00:00

Input Recording Menu Refactor (#579)

* Initial

* Formatting

* Slight name changes
This commit is contained in:
jugeeya 2023-08-07 11:59:47 -07:00 committed by GitHub
parent fea2651726
commit 85815f87ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 80 deletions

View file

@ -1,5 +1,5 @@
use crate::common::button_config; use crate::common::button_config;
use crate::common::consts::{FighterId, HitstunPlayback}; use crate::common::consts::{FighterId, HitstunPlayback, OnOff};
use crate::common::{get_module_accessor, is_in_hitstun, is_in_shieldstun, MENU}; use crate::common::{get_module_accessor, is_in_hitstun, is_in_shieldstun, MENU};
use crate::training::input_recording::structures::*; use crate::training::input_recording::structures::*;
use crate::training::mash; use crate::training::mash;
@ -125,7 +125,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? // 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 { if should_playback {
playback(mash::queued_playback_slot()); playback(Some(mash::queued_playback_slot()));
} }
} }
@ -184,7 +184,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
module_accessor, module_accessor,
button_config::ButtonCombo::InputPlayback, button_config::ButtonCombo::InputPlayback,
) { ) {
playback(MENU.playback_slot.get_random().into_idx().unwrap_or(0)); playback(MENU.playback_button_combination.get_random().into_idx());
} }
// Attack + Dpad Left: Record // Attack + Dpad Left: Record
else if button_config::combo_passes_exclusive( else if button_config::combo_passes_exclusive(
@ -204,6 +204,9 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
if mash::is_playback_queued() { if mash::is_playback_queued() {
mash::reset(); mash::reset();
} }
if MENU.playback_loop == OnOff::On {
playback(Some(CURRENT_PLAYBACK_SLOT));
}
} }
} }
@ -290,15 +293,17 @@ pub unsafe fn lockout_record() {
CURRENT_LR = RECORDED_LR; CURRENT_LR = RECORDED_LR;
} }
pub unsafe fn playback(slot: usize) { // Returns whether we did playback
pub unsafe fn playback(slot: Option<usize>) -> bool {
if INPUT_RECORD == Pause { if INPUT_RECORD == Pause {
println!("Tried to playback during lockout!"); println!("Tried to playback during lockout!");
return; return false;
} }
if MENU.playback_slot.is_empty() { if slot.is_none() {
println!("Tried to playback without a slot selected!"); println!("Tried to playback without a slot selected!");
return; return false;
} }
let slot = slot.unwrap();
clear_notifications("Input Recording"); clear_notifications("Input Recording");
color_notification( color_notification(
@ -321,37 +326,13 @@ pub unsafe fn playback(slot: usize) {
BUFFER_FRAME = 0; BUFFER_FRAME = 0;
let cpu_module_accessor = get_module_accessor(FighterId::CPU); let cpu_module_accessor = get_module_accessor(FighterId::CPU);
CURRENT_LR = PostureModule::lr(cpu_module_accessor); CURRENT_LR = PostureModule::lr(cpu_module_accessor);
true
} }
pub unsafe fn playback_ledge(slot: usize) { pub unsafe fn playback_ledge(slot: Option<usize>) {
if INPUT_RECORD == Pause { let did_playback = playback(slot);
println!("Tried to playback during lockout!"); if did_playback {
return;
}
if MENU.playback_slot.is_empty() {
println!("Tried to playback without a slot selected!");
return;
}
clear_notifications("Input Recording");
color_notification(
"Input Recording".to_string(),
"Playback".to_owned(),
60,
ResColor {
r: 0,
g: 0,
b: 0,
a: 255,
},
);
CURRENT_PLAYBACK_SLOT = slot;
CURRENT_FRAME_LENGTH = P1_FRAME_LENGTH_MAPPING.lock()[CURRENT_PLAYBACK_SLOT];
INPUT_RECORD = Playback;
POSSESSION = Player;
INPUT_RECORD_FRAME = 0;
BUFFER_FRAME = 5; // So we can make sure the option is buffered and won't get ledge trumped if delay is 0 BUFFER_FRAME = 5; // So we can make sure the option is buffered and won't get ledge trumped if delay is 0
// drop down from ledge can't be buffered on the same frame as jump/attack/roll/ngu so we have to do this // drop down from ledge can't be buffered on the same frame as jump/attack/roll/ngu so we have to do this
// Need to buffer 1 less frame for non-lassos // Need to buffer 1 less frame for non-lassos
@ -360,7 +341,7 @@ pub unsafe fn playback_ledge(slot: usize) {
if status_kind == *FIGHTER_STATUS_KIND_CLIFF_CATCH { if status_kind == *FIGHTER_STATUS_KIND_CLIFF_CATCH {
BUFFER_FRAME -= 1; BUFFER_FRAME -= 1;
} }
CURRENT_LR = PostureModule::lr(cpu_module_accessor); }
} }
pub unsafe fn stop_playback() { pub unsafe fn stop_playback() {

View file

@ -614,8 +614,8 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
input_record::lockout_record(); input_record::lockout_record();
} }
// otherwise, begin input recording playback if selected // otherwise, begin input recording playback if selected
else if MENU.save_state_playback == OnOff::On { else if !MENU.save_state_playback.is_empty() {
input_record::playback(MENU.playback_slot.get_random().into_idx().unwrap_or(0)); input_record::playback(MENU.save_state_playback.get_random().into_idx());
} }
return; return;

View file

@ -51,6 +51,7 @@ pub struct TrainingModpackMenu {
pub save_state_slot: SaveStateSlot, pub save_state_slot: SaveStateSlot,
pub randomize_slots: OnOff, pub randomize_slots: OnOff,
pub save_state_mirroring: SaveStateMirroring, pub save_state_mirroring: SaveStateMirroring,
pub save_state_playback: PlaybackSlot,
pub sdi_state: Direction, pub sdi_state: Direction,
pub sdi_strength: SdiFrequency, pub sdi_strength: SdiFrequency,
pub shield_state: Shield, pub shield_state: Shield,
@ -72,13 +73,13 @@ pub struct TrainingModpackMenu {
pub footstool_override: Action, pub footstool_override: Action,
pub landing_override: Action, pub landing_override: Action,
pub trump_override: Action, pub trump_override: Action,
pub save_state_playback: OnOff,
pub recording_slot: RecordSlot, pub recording_slot: RecordSlot,
pub playback_slot: PlaybackSlot,
pub playback_mash: OnOff,
pub record_trigger: RecordTrigger, pub record_trigger: RecordTrigger,
pub recording_frames: RecordingFrames, pub recording_frames: RecordingFrames,
pub playback_button_combination: PlaybackSlot,
pub hitstun_playback: HitstunPlayback, pub hitstun_playback: HitstunPlayback,
pub playback_mash: OnOff,
pub playback_loop: OnOff,
} }
#[repr(C)] #[repr(C)]
@ -148,6 +149,7 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu {
save_state_slot: SaveStateSlot::One, save_state_slot: SaveStateSlot::One,
randomize_slots: OnOff::Off, randomize_slots: OnOff::Off,
save_state_mirroring: SaveStateMirroring::None, save_state_mirroring: SaveStateMirroring::None,
save_state_playback: PlaybackSlot::S1,
sdi_state: Direction::empty(), sdi_state: Direction::empty(),
sdi_strength: SdiFrequency::None, sdi_strength: SdiFrequency::None,
shield_state: Shield::None, shield_state: Shield::None,
@ -169,14 +171,13 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu {
footstool_override: Action::empty(), footstool_override: Action::empty(),
landing_override: Action::empty(), landing_override: Action::empty(),
trump_override: Action::empty(), trump_override: Action::empty(),
save_state_playback: OnOff::Off,
recording_slot: RecordSlot::S1, recording_slot: RecordSlot::S1,
playback_slot: PlaybackSlot::S1,
playback_mash: OnOff::On,
record_trigger: RecordTrigger::None, //Command?
recording_frames: RecordingFrames::F150, recording_frames: RecordingFrames::F150,
record_trigger: RecordTrigger::None,
playback_button_combination: PlaybackSlot::S1,
hitstun_playback: HitstunPlayback::Hitstun, hitstun_playback: HitstunPlayback::Hitstun,
// TODO: alphabetize playback_mash: OnOff::On,
playback_loop: OnOff::Off,
}; };
pub static mut MENU: TrainingModpackMenu = DEFAULTS_MENU; pub static mut MENU: TrainingModpackMenu = DEFAULTS_MENU;
@ -698,6 +699,13 @@ pub unsafe fn ui_menu(menu: TrainingModpackMenu) -> UiMenu<'static> {
false, false,
&(menu.buff_state.bits()), &(menu.buff_state.bits()),
); );
save_state_tab.add_submenu_with_toggles::<PlaybackSlot>(
"Save State Playback",
"save_state_playback",
"Save State Playback: Choose which slots to playback input recording upon loading a save state",
false,
&(menu.save_state_playback.bits() as u32),
);
overall_menu.tabs.push(save_state_tab); overall_menu.tabs.push(save_state_tab);
let mut misc_tab = Tab { let mut misc_tab = Tab {
@ -768,34 +776,34 @@ pub unsafe fn ui_menu(menu: TrainingModpackMenu) -> UiMenu<'static> {
true, true,
&(menu.recording_frames as u32), &(menu.recording_frames as u32),
); );
input_tab.add_submenu_with_toggles::<OnOff>(
"Save State Playback",
"save_state_playback",
"Save State Playback: Begin recorded input playback upon loading a save state",
true,
&(menu.save_state_playback as u32),
);
input_tab.add_submenu_with_toggles::<PlaybackSlot>( input_tab.add_submenu_with_toggles::<PlaybackSlot>(
"Playback Slots", "Playback Button Combination",
"playback_slot", "playback_button_combination",
"Playback Slots: Choose which slots to choose between for playback when this action is triggered", "Playback Button Combination: Choose which slots to playback input recording upon pressing button combination (Default: Attack+Right Taunt)",
false, false,
&(menu.playback_slot.bits() as u32), &(menu.playback_button_combination.bits() as u32),
);
input_tab.add_submenu_with_toggles::<OnOff>(
"Mash Ends Playback",
"playback_mash",
"Mash Ends Playback: End input recording playback when a mash trigger occurs",
true,
&(menu.playback_mash as u32),
); );
input_tab.add_submenu_with_toggles::<HitstunPlayback>( input_tab.add_submenu_with_toggles::<HitstunPlayback>(
"Playback Hitstun Timing", "Playback Hitstun Timing",
"hitstun_playback", "hitstun_playback",
"Playback Hitstun Timing: When to begin playing back inputs on hitstun mash trigger", "Playback Hitstun Timing: When to begin playing back inputs when a hitstun mash trigger occurs",
true, true,
&(menu.hitstun_playback as u32), &(menu.hitstun_playback as u32),
); );
input_tab.add_submenu_with_toggles::<OnOff>(
"Playback Mash Interrupt",
"playback_mash",
"Playback Mash Interrupt: End input playback when a mash trigger occurs",
true,
&(menu.playback_mash as u32),
);
input_tab.add_submenu_with_toggles::<OnOff>(
"Playback Loop",
"playback_loop",
"Playback Loop: Repeat triggered input playbacks indefinitely",
true,
&(menu.playback_loop as u32),
);
overall_menu.tabs.push(input_tab); overall_menu.tabs.push(input_tab);
overall_menu overall_menu

View file

@ -250,18 +250,15 @@ impl LedgeOption {
} }
} }
pub fn playback_slot(self) -> usize { pub fn playback_slot(self) -> Option<usize> {
match self { Some(match self {
LedgeOption::PLAYBACK_1 => 0, LedgeOption::PLAYBACK_1 => 0,
LedgeOption::PLAYBACK_2 => 1, LedgeOption::PLAYBACK_2 => 1,
LedgeOption::PLAYBACK_3 => 2, LedgeOption::PLAYBACK_3 => 2,
LedgeOption::PLAYBACK_4 => 3, LedgeOption::PLAYBACK_4 => 3,
LedgeOption::PLAYBACK_5 => 4, LedgeOption::PLAYBACK_5 => 4,
_ => panic!( _ => return None,
"Invalid LedgeOption playback slot: {}", })
self.as_str().unwrap()
),
}
} }
pub const fn default() -> LedgeOption { pub const fn default() -> LedgeOption {