1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-27 20:34:03 +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::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::training::input_recording::structures::*;
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?
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,
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
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() {
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;
}
pub unsafe fn playback(slot: usize) {
// Returns whether we did playback
pub unsafe fn playback(slot: Option<usize>) -> bool {
if INPUT_RECORD == Pause {
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!");
return;
return false;
}
let slot = slot.unwrap();
clear_notifications("Input Recording");
color_notification(
@ -321,46 +326,22 @@ pub unsafe fn playback(slot: usize) {
BUFFER_FRAME = 0;
let cpu_module_accessor = get_module_accessor(FighterId::CPU);
CURRENT_LR = PostureModule::lr(cpu_module_accessor);
true
}
pub unsafe fn playback_ledge(slot: usize) {
if INPUT_RECORD == Pause {
println!("Tried to playback during lockout!");
return;
pub unsafe fn playback_ledge(slot: Option<usize>) {
let did_playback = playback(slot);
if did_playback {
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
// Need to buffer 1 less frame for non-lassos
let cpu_module_accessor = get_module_accessor(FighterId::CPU);
let status_kind = StatusModule::status_kind(cpu_module_accessor) as i32;
if status_kind == *FIGHTER_STATUS_KIND_CLIFF_CATCH {
BUFFER_FRAME -= 1;
}
}
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
// 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
let cpu_module_accessor = get_module_accessor(FighterId::CPU);
let status_kind = StatusModule::status_kind(cpu_module_accessor) as i32;
if status_kind == *FIGHTER_STATUS_KIND_CLIFF_CATCH {
BUFFER_FRAME -= 1;
}
CURRENT_LR = PostureModule::lr(cpu_module_accessor);
}
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();
}
// otherwise, begin input recording playback if selected
else if MENU.save_state_playback == OnOff::On {
input_record::playback(MENU.playback_slot.get_random().into_idx().unwrap_or(0));
else if !MENU.save_state_playback.is_empty() {
input_record::playback(MENU.save_state_playback.get_random().into_idx());
}
return;

View file

@ -51,6 +51,7 @@ pub struct TrainingModpackMenu {
pub save_state_slot: SaveStateSlot,
pub randomize_slots: OnOff,
pub save_state_mirroring: SaveStateMirroring,
pub save_state_playback: PlaybackSlot,
pub sdi_state: Direction,
pub sdi_strength: SdiFrequency,
pub shield_state: Shield,
@ -72,13 +73,13 @@ pub struct TrainingModpackMenu {
pub footstool_override: Action,
pub landing_override: Action,
pub trump_override: Action,
pub save_state_playback: OnOff,
pub recording_slot: RecordSlot,
pub playback_slot: PlaybackSlot,
pub playback_mash: OnOff,
pub record_trigger: RecordTrigger,
pub recording_frames: RecordingFrames,
pub playback_button_combination: PlaybackSlot,
pub hitstun_playback: HitstunPlayback,
pub playback_mash: OnOff,
pub playback_loop: OnOff,
}
#[repr(C)]
@ -148,6 +149,7 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu {
save_state_slot: SaveStateSlot::One,
randomize_slots: OnOff::Off,
save_state_mirroring: SaveStateMirroring::None,
save_state_playback: PlaybackSlot::S1,
sdi_state: Direction::empty(),
sdi_strength: SdiFrequency::None,
shield_state: Shield::None,
@ -169,14 +171,13 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu {
footstool_override: Action::empty(),
landing_override: Action::empty(),
trump_override: Action::empty(),
save_state_playback: OnOff::Off,
recording_slot: RecordSlot::S1,
playback_slot: PlaybackSlot::S1,
playback_mash: OnOff::On,
record_trigger: RecordTrigger::None, //Command?
recording_frames: RecordingFrames::F150,
record_trigger: RecordTrigger::None,
playback_button_combination: PlaybackSlot::S1,
hitstun_playback: HitstunPlayback::Hitstun,
// TODO: alphabetize
playback_mash: OnOff::On,
playback_loop: OnOff::Off,
};
pub static mut MENU: TrainingModpackMenu = DEFAULTS_MENU;
@ -698,6 +699,13 @@ pub unsafe fn ui_menu(menu: TrainingModpackMenu) -> UiMenu<'static> {
false,
&(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);
let mut misc_tab = Tab {
@ -768,34 +776,34 @@ pub unsafe fn ui_menu(menu: TrainingModpackMenu) -> UiMenu<'static> {
true,
&(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>(
"Playback Slots",
"playback_slot",
"Playback Slots: Choose which slots to choose between for playback when this action is triggered",
"Playback Button Combination",
"playback_button_combination",
"Playback Button Combination: Choose which slots to playback input recording upon pressing button combination (Default: Attack+Right Taunt)",
false,
&(menu.playback_slot.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),
&(menu.playback_button_combination.bits() as u32),
);
input_tab.add_submenu_with_toggles::<HitstunPlayback>(
"Playback Hitstun Timing",
"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,
&(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

View file

@ -250,18 +250,15 @@ impl LedgeOption {
}
}
pub fn playback_slot(self) -> usize {
match self {
pub fn playback_slot(self) -> Option<usize> {
Some(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()
),
}
_ => return None,
})
}
pub const fn default() -> LedgeOption {