mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-30 22:00:16 +00:00
Fully Match Input Recording Notifications with the Current state (#577)
* Fully Match Input Recording Notifications with the current state * Switch final record frame variable * Use new hook for notifications, realign playback notif * fmt * Prioritize Frame Advantage * clippy fmt
This commit is contained in:
parent
8abc20812e
commit
acd6c55f48
7 changed files with 57 additions and 38 deletions
|
@ -66,6 +66,7 @@ pub unsafe fn handle_buffs(
|
||||||
// Future Enhancements:
|
// Future Enhancements:
|
||||||
// - Remove startup effects on buffs (Flash of Limit, Wii Fit's flash, Shulk's occasional Jump Art smoke, etc.)
|
// - 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
|
// - Ensure IS_BUFFING_CPU && IS_BUFFING_PLAYER are set to false on leaving training mode
|
||||||
|
// - Deal With Arsene!/Shulk Art SFX with a different function than below to keep the reset SFX on state load
|
||||||
SoundModule::stop_all_sound(module_accessor); // silences buff sfx other than KO Punch
|
SoundModule::stop_all_sound(module_accessor); // silences buff sfx other than KO Punch
|
||||||
ControlModule::stop_rumble(module_accessor, false);
|
ControlModule::stop_rumble(module_accessor, false);
|
||||||
MotionAnimcmdModule::set_sleep(module_accessor, false);
|
MotionAnimcmdModule::set_sleep(module_accessor, false);
|
||||||
|
|
|
@ -51,6 +51,8 @@ fn update_frame_advantage(new_frame_adv: i32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
FRAME_ADVANTAGE = new_frame_adv;
|
FRAME_ADVANTAGE = new_frame_adv;
|
||||||
if MENU.frame_advantage == OnOff::On {
|
if MENU.frame_advantage == OnOff::On {
|
||||||
|
// Prioritize Frame Advantage over Input Recording Playback
|
||||||
|
ui::notifications::clear_notifications("Input Recording");
|
||||||
ui::notifications::clear_notifications("Frame Advantage");
|
ui::notifications::clear_notifications("Frame Advantage");
|
||||||
ui::notifications::color_notification(
|
ui::notifications::color_notification(
|
||||||
"Frame Advantage".to_string(),
|
"Frame Advantage".to_string(),
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
use crate::common::*;
|
|
||||||
use crate::training::*;
|
|
||||||
|
|
||||||
static mut SHOULD_COUNT: Vec<bool> = vec![];
|
static mut SHOULD_COUNT: Vec<bool> = vec![];
|
||||||
static mut COUNTERS: Vec<u32> = vec![];
|
static mut COUNTERS: Vec<u32> = vec![];
|
||||||
|
|
||||||
|
@ -70,7 +67,7 @@ pub fn tick_idx(index: usize) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick() {
|
pub fn tick() {
|
||||||
unsafe {
|
unsafe {
|
||||||
for (index, _frame) in COUNTERS.iter().enumerate() {
|
for (index, _frame) in COUNTERS.iter().enumerate() {
|
||||||
if !SHOULD_COUNT[index] {
|
if !SHOULD_COUNT[index] {
|
||||||
|
@ -88,11 +85,3 @@ pub fn reset_all() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
|
||||||
if !is_operation_cpu(module_accessor) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tick();
|
|
||||||
}
|
|
||||||
|
|
|
@ -187,7 +187,9 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
||||||
{
|
{
|
||||||
lockout_record();
|
lockout_record();
|
||||||
}
|
}
|
||||||
|
if INPUT_RECORD == None {
|
||||||
|
clear_notifications("Input Recording");
|
||||||
|
}
|
||||||
// may need to move this to another func
|
// may need to move this to another func
|
||||||
if (INPUT_RECORD == Record || INPUT_RECORD == Playback)
|
if (INPUT_RECORD == Record || INPUT_RECORD == Playback)
|
||||||
&& INPUT_RECORD_FRAME >= CURRENT_FRAME_LENGTH - 1
|
&& INPUT_RECORD_FRAME >= CURRENT_FRAME_LENGTH - 1
|
||||||
|
@ -212,9 +214,9 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
||||||
"Lockout".to_owned(),
|
"Lockout".to_owned(),
|
||||||
60,
|
60,
|
||||||
ResColor {
|
ResColor {
|
||||||
r: 200,
|
r: 8,
|
||||||
g: 8,
|
g: 8,
|
||||||
b: 8,
|
b: 200,
|
||||||
a: 255,
|
a: 255,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -265,6 +267,23 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
||||||
0.0,
|
0.0,
|
||||||
*MODEL_COLOR_TYPE_COLOR_BLEND,
|
*MODEL_COLOR_TYPE_COLOR_BLEND,
|
||||||
);
|
);
|
||||||
|
} else if entry_id_int == 1 && POSSESSION == Player && INPUT_RECORD == Playback {
|
||||||
|
// Displays if the inputs from the current frame were a result of playback
|
||||||
|
if INPUT_RECORD_FRAME == 0 || INPUT_RECORD_FRAME == 1 {
|
||||||
|
// can be either, seems like a thread issue
|
||||||
|
clear_notifications("Input Recording");
|
||||||
|
color_notification(
|
||||||
|
"Input Recording".to_string(),
|
||||||
|
"Playback".to_owned(),
|
||||||
|
CURRENT_FRAME_LENGTH as u32,
|
||||||
|
ResColor {
|
||||||
|
r: 0,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
a: 255,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,19 +318,6 @@ pub unsafe fn playback(slot: Option<usize>) -> bool {
|
||||||
}
|
}
|
||||||
let slot = slot.unwrap();
|
let slot = slot.unwrap();
|
||||||
|
|
||||||
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_PLAYBACK_SLOT = slot;
|
||||||
CURRENT_FRAME_LENGTH = P1_FRAME_LENGTH_MAPPING.lock()[CURRENT_PLAYBACK_SLOT];
|
CURRENT_FRAME_LENGTH = P1_FRAME_LENGTH_MAPPING.lock()[CURRENT_PLAYBACK_SLOT];
|
||||||
INPUT_RECORD = Playback;
|
INPUT_RECORD = Playback;
|
||||||
|
@ -389,7 +395,8 @@ pub unsafe fn handle_final_input_mapping(player_idx: i32, out: *mut MappedInputs
|
||||||
|
|
||||||
P1_FINAL_MAPPING.lock()[CURRENT_RECORD_SLOT][INPUT_RECORD_FRAME] = *out;
|
P1_FINAL_MAPPING.lock()[CURRENT_RECORD_SLOT][INPUT_RECORD_FRAME] = *out;
|
||||||
*out = MappedInputs::empty(); // don't control player while recording
|
*out = MappedInputs::empty(); // don't control player while recording
|
||||||
println!("Stored Player Input! Frame: {}", INPUT_RECORD_FRAME);
|
|
||||||
|
//println!("Stored Player Input! Frame: {}", INPUT_RECORD_FRAME);
|
||||||
}
|
}
|
||||||
// Don't allow for player input during Lockout
|
// Don't allow for player input during Lockout
|
||||||
if POSSESSION == Lockout {
|
if POSSESSION == Lockout {
|
||||||
|
@ -402,7 +409,7 @@ pub unsafe fn handle_final_input_mapping(player_idx: i32, out: *mut MappedInputs
|
||||||
unsafe fn set_cpu_controls(p_data: *mut *mut u8) {
|
unsafe fn set_cpu_controls(p_data: *mut *mut u8) {
|
||||||
call_original!(p_data);
|
call_original!(p_data);
|
||||||
let controller_data = *p_data.add(1) as *mut ControlModuleInternal;
|
let controller_data = *p_data.add(1) as *mut ControlModuleInternal;
|
||||||
let controller_no = (*controller_data).controller_index;
|
let _controller_no = (*controller_data).controller_index;
|
||||||
|
|
||||||
// Check if we need to begin playback this frame due to a mash toggle
|
// Check if we need to begin playback this frame due to a mash toggle
|
||||||
// TODO: Setup STARTING_STATUS based on current playback slot here
|
// TODO: Setup STARTING_STATUS based on current playback slot here
|
||||||
|
@ -425,7 +432,8 @@ unsafe fn set_cpu_controls(p_data: *mut *mut u8) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if INPUT_RECORD == Record || INPUT_RECORD == Playback {
|
if INPUT_RECORD == Record || INPUT_RECORD == Playback {
|
||||||
let mut x_input_multiplier = RECORDED_LR * CURRENT_LR; // if we aren't facing the way we were when we initially recorded, we reverse horizontal inputs
|
// if we aren't facing the way we were when we initially recorded, we reverse horizontal inputs
|
||||||
|
let mut x_input_multiplier = RECORDED_LR * CURRENT_LR;
|
||||||
// Don't flip Shulk's dial inputs
|
// Don't flip Shulk's dial inputs
|
||||||
let fighter_kind = utility::get_kind(&mut *cpu_module_accessor);
|
let fighter_kind = utility::get_kind(&mut *cpu_module_accessor);
|
||||||
if fighter_kind == *FIGHTER_KIND_SHULK {
|
if fighter_kind == *FIGHTER_KIND_SHULK {
|
||||||
|
@ -440,7 +448,6 @@ unsafe fn set_cpu_controls(p_data: *mut *mut u8) {
|
||||||
// If we have issues with the frame after the dial comes out, change condition to
|
// If we have issues with the frame after the dial comes out, change condition to
|
||||||
// circle_menu_flag && FIGHTER_SHULK_INSTANCE_WORK_ID_INT_SPECIAL_N_DECIDE_INTERVAL_FRAME > 1
|
// circle_menu_flag && FIGHTER_SHULK_INSTANCE_WORK_ID_INT_SPECIAL_N_DECIDE_INTERVAL_FRAME > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent us from falling off of the ledge in standby
|
// Prevent us from falling off of the ledge in standby
|
||||||
if StatusModule::status_kind(cpu_module_accessor) == *FIGHTER_STATUS_KIND_CLIFF_WAIT
|
if StatusModule::status_kind(cpu_module_accessor) == *FIGHTER_STATUS_KIND_CLIFF_WAIT
|
||||||
&& is_standby()
|
&& is_standby()
|
||||||
|
@ -456,7 +463,7 @@ unsafe fn set_cpu_controls(p_data: *mut *mut u8) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Overriding Cpu Player: {}, Frame: {}, BUFFER_FRAME: {}, STARTING_STATUS: {}, INPUT_RECORD: {:#?}, POSSESSION: {:#?}", controller_no, INPUT_RECORD_FRAME, BUFFER_FRAME, STARTING_STATUS, INPUT_RECORD, POSSESSION);
|
//println!("Overriding Cpu Player: {}, Frame: {}, BUFFER_FRAME: {}, STARTING_STATUS: {}, INPUT_RECORD: {:#?}, POSSESSION: {:#?}", controller_no, INPUT_RECORD_FRAME, BUFFER_FRAME, STARTING_STATUS, INPUT_RECORD, POSSESSION);
|
||||||
|
|
||||||
let mut saved_mapped_inputs = P1_FINAL_MAPPING.lock()[if INPUT_RECORD == Record {
|
let mut saved_mapped_inputs = P1_FINAL_MAPPING.lock()[if INPUT_RECORD == Record {
|
||||||
CURRENT_RECORD_SLOT
|
CURRENT_RECORD_SLOT
|
||||||
|
|
|
@ -133,7 +133,6 @@ fn once_per_frame_per_fighter(
|
||||||
}
|
}
|
||||||
|
|
||||||
fast_fall::get_command_flag_cat(module_accessor);
|
fast_fall::get_command_flag_cat(module_accessor);
|
||||||
frame_counter::get_command_flag_cat(module_accessor);
|
|
||||||
ledge::get_command_flag_cat(module_accessor);
|
ledge::get_command_flag_cat(module_accessor);
|
||||||
shield::get_command_flag_cat(module_accessor);
|
shield::get_command_flag_cat(module_accessor);
|
||||||
directional_influence::get_command_flag_cat(module_accessor);
|
directional_influence::get_command_flag_cat(module_accessor);
|
||||||
|
@ -614,6 +613,22 @@ pub unsafe fn handle_reused_ui(
|
||||||
original!()(fighter_data, param_2)
|
original!()(fighter_data, param_2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Instruction run on the completion of the CPU Control function
|
||||||
|
static OPCF_OFFSET: usize = 0x06b7fdc;
|
||||||
|
|
||||||
|
// One instruction after the CPU Control function completes
|
||||||
|
#[skyline::hook(offset = OPCF_OFFSET, inline)]
|
||||||
|
unsafe fn handle_once_per_cpu_frame(_ctx: &mut InlineCtx) {
|
||||||
|
frame_counter::tick();
|
||||||
|
// Tick notifications
|
||||||
|
let queue = &mut ui::notifications::QUEUE;
|
||||||
|
let notification = queue.first();
|
||||||
|
if notification.is_some() {
|
||||||
|
let notification = queue.first_mut().unwrap();
|
||||||
|
notification.tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static FIM_OFFSET: usize = 0x17504a0;
|
static FIM_OFFSET: usize = 0x17504a0;
|
||||||
// TODO: Should we define all of our offsets in one file? Should at least be a good start for changing to be based on ASM instructions
|
// TODO: Should we define all of our offsets in one file? Should at least be a good start for changing to be based on ASM instructions
|
||||||
#[skyline::hook(offset = FIM_OFFSET)]
|
#[skyline::hook(offset = FIM_OFFSET)]
|
||||||
|
@ -710,6 +725,8 @@ pub fn training_mods() {
|
||||||
handle_star_ko,
|
handle_star_ko,
|
||||||
// Clatter
|
// Clatter
|
||||||
clatter::hook_start_clatter,
|
clatter::hook_start_clatter,
|
||||||
|
// Notifications
|
||||||
|
handle_once_per_cpu_frame,
|
||||||
// Input
|
// Input
|
||||||
handle_final_input_mapping
|
handle_final_input_mapping
|
||||||
);
|
);
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub unsafe fn draw(root_pane: &Pane) {
|
||||||
text.set_color(color.r, color.g, color.b, color.a);
|
text.set_color(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
let notification = queue.first_mut().unwrap();
|
let notification = queue.first_mut().unwrap();
|
||||||
let has_completed = notification.tick();
|
let has_completed = notification.check_completed();
|
||||||
if has_completed {
|
if has_completed {
|
||||||
queue.remove(0);
|
queue.remove(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,15 @@ impl Notification {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tick(&mut self) {
|
||||||
|
self.length -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns: has_completed
|
// Returns: has_completed
|
||||||
pub fn tick(&mut self) -> bool {
|
pub fn check_completed(&mut self) -> bool {
|
||||||
if self.length <= 1 {
|
if self.length <= 1 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
self.length -= 1;
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue