mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-20 00:46:34 +00:00
Initial
This commit is contained in:
parent
b519152ce7
commit
64041cb21e
12 changed files with 120 additions and 119 deletions
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::sync::Lazy;
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
@ -109,10 +110,12 @@ lazy_static! {
|
||||||
(RUp, 0),
|
(RUp, 0),
|
||||||
]))
|
]))
|
||||||
};
|
};
|
||||||
pub static ref VISUAL_FRAME_COUNTER: Mutex<u32> = Mutex::new(0);
|
|
||||||
pub static ref VISUAL_FRAME_COUNTER_SHOULD_COUNT: Mutex<bool> = Mutex::new(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MENU_CLOSE_FRAME_COUNTER: Lazy<u32> = Lazy::new(|| {
|
||||||
|
frame_counter::register_counter(frame_counter::FrameCounterType::Real)
|
||||||
|
});
|
||||||
|
|
||||||
pub fn handle_final_input_mapping(
|
pub fn handle_final_input_mapping(
|
||||||
player_idx: i32,
|
player_idx: i32,
|
||||||
controller_struct: &mut SomeControllerStruct,
|
controller_struct: &mut SomeControllerStruct,
|
||||||
|
@ -122,7 +125,7 @@ pub fn handle_final_input_mapping(
|
||||||
if player_idx == 0 {
|
if player_idx == 0 {
|
||||||
let p1_controller = &mut *controller_struct.controller;
|
let p1_controller = &mut *controller_struct.controller;
|
||||||
*P1_CONTROLLER_STYLE.lock() = p1_controller.style;
|
*P1_CONTROLLER_STYLE.lock() = p1_controller.style;
|
||||||
let visual_frame_count = *VISUAL_FRAME_COUNTER.data_ptr();
|
let visual_frame_count = frame_counter::get_frame_count(*MENU_CLOSE_FRAME_COUNTER);
|
||||||
if visual_frame_count > 0 && visual_frame_count < MENU_CLOSE_WAIT_FRAMES {
|
if visual_frame_count > 0 && visual_frame_count < MENU_CLOSE_WAIT_FRAMES {
|
||||||
// If we just closed the menu, kill all inputs to avoid accidental presses
|
// If we just closed the menu, kill all inputs to avoid accidental presses
|
||||||
*out = MappedInputs::empty();
|
*out = MappedInputs::empty();
|
||||||
|
@ -131,7 +134,7 @@ pub fn handle_final_input_mapping(
|
||||||
p1_controller.just_down = ButtonBitfield::default();
|
p1_controller.just_down = ButtonBitfield::default();
|
||||||
p1_controller.just_release = ButtonBitfield::default();
|
p1_controller.just_release = ButtonBitfield::default();
|
||||||
} else if visual_frame_count >= MENU_CLOSE_WAIT_FRAMES {
|
} else if visual_frame_count >= MENU_CLOSE_WAIT_FRAMES {
|
||||||
*VISUAL_FRAME_COUNTER_SHOULD_COUNT.lock() = false;
|
frame_counter::stop_counting(*MENU_CLOSE_FRAME_COUNTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if QUICK_MENU_ACTIVE {
|
if QUICK_MENU_ACTIVE {
|
||||||
|
@ -190,7 +193,7 @@ pub fn handle_final_input_mapping(
|
||||||
app.on_b()
|
app.on_b()
|
||||||
} else {
|
} else {
|
||||||
// Leave menu.
|
// Leave menu.
|
||||||
*VISUAL_FRAME_COUNTER_SHOULD_COUNT.lock() = true;
|
frame_counter::start_counting(*MENU_CLOSE_FRAME_COUNTER);
|
||||||
QUICK_MENU_ACTIVE = false;
|
QUICK_MENU_ACTIVE = false;
|
||||||
let menu_json = app.get_menu_selections();
|
let menu_json = app.get_menu_selections();
|
||||||
set_menu_from_json(&menu_json);
|
set_menu_from_json(&menu_json);
|
||||||
|
@ -202,7 +205,7 @@ pub fn handle_final_input_mapping(
|
||||||
.then(|| {
|
.then(|| {
|
||||||
received_input = true;
|
received_input = true;
|
||||||
// Leave menu.
|
// Leave menu.
|
||||||
*VISUAL_FRAME_COUNTER_SHOULD_COUNT.lock() = true;
|
frame_counter::start_counting(*MENU_CLOSE_FRAME_COUNTER);
|
||||||
QUICK_MENU_ACTIVE = false;
|
QUICK_MENU_ACTIVE = false;
|
||||||
let menu_json = app.get_menu_selections();
|
let menu_json = app.get_menu_selections();
|
||||||
set_menu_from_json(&menu_json);
|
set_menu_from_json(&menu_json);
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::is_operation_cpu;
|
||||||
use crate::training::frame_counter;
|
use crate::training::frame_counter;
|
||||||
use crate::training::handle_add_limit;
|
use crate::training::handle_add_limit;
|
||||||
|
|
||||||
static mut BUFF_DELAY_COUNTER: usize = 0;
|
use std::sync::Lazy;
|
||||||
|
|
||||||
static mut BUFF_REMAINING_PLAYER: i32 = 0;
|
static mut BUFF_REMAINING_PLAYER: i32 = 0;
|
||||||
static mut BUFF_REMAINING_CPU: i32 = 0;
|
static mut BUFF_REMAINING_CPU: i32 = 0;
|
||||||
|
@ -14,11 +14,9 @@ static mut BUFF_REMAINING_CPU: i32 = 0;
|
||||||
static mut IS_BUFFING_PLAYER: bool = false;
|
static mut IS_BUFFING_PLAYER: bool = false;
|
||||||
static mut IS_BUFFING_CPU: bool = false;
|
static mut IS_BUFFING_CPU: bool = false;
|
||||||
|
|
||||||
pub fn init() {
|
static BUFF_DELAY_COUNTER: Lazy<u32> = Lazy::new(|| {
|
||||||
unsafe {
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
BUFF_DELAY_COUNTER = frame_counter::register_counter();
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn restart_buff(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
pub unsafe fn restart_buff(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||||
if is_operation_cpu(module_accessor) {
|
if is_operation_cpu(module_accessor) {
|
||||||
|
@ -107,7 +105,7 @@ unsafe fn buff_hero(module_accessor: &mut app::BattleObjectModuleAccessor, statu
|
||||||
}
|
}
|
||||||
if get_buff_rem(module_accessor) <= 0 {
|
if get_buff_rem(module_accessor) <= 0 {
|
||||||
// If there are no buffs selected/left, we're done
|
// If there are no buffs selected/left, we're done
|
||||||
if frame_counter::should_delay(3_u32, BUFF_DELAY_COUNTER) {
|
if frame_counter::should_delay(3_u32, *BUFF_DELAY_COUNTER) {
|
||||||
// Need to wait 3 frames to make sure we stop the spell SFX, since it's a bit delayed
|
// Need to wait 3 frames to make sure we stop the spell SFX, since it's a bit delayed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +158,7 @@ unsafe fn buff_cloud(module_accessor: &mut app::BattleObjectModuleAccessor) -> b
|
||||||
start_buff(module_accessor);
|
start_buff(module_accessor);
|
||||||
handle_add_limit(100.0, module_accessor, 0);
|
handle_add_limit(100.0, module_accessor, 0);
|
||||||
}
|
}
|
||||||
if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) {
|
if frame_counter::should_delay(2_u32, *BUFF_DELAY_COUNTER) {
|
||||||
// Need to wait 2 frames to make sure we stop the limit SFX, since it's a bit delayed
|
// Need to wait 2 frames to make sure we stop the limit SFX, since it's a bit delayed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +173,7 @@ unsafe fn buff_joker(module_accessor: &mut app::BattleObjectModuleAccessor) -> b
|
||||||
// Strangely, this doesn't actually matter and works for both fighters
|
// Strangely, this doesn't actually matter and works for both fighters
|
||||||
app::FighterSpecializer_Jack::add_rebel_gauge(module_accessor, entry_id, 120.0);
|
app::FighterSpecializer_Jack::add_rebel_gauge(module_accessor, entry_id, 120.0);
|
||||||
}
|
}
|
||||||
if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) {
|
if frame_counter::should_delay(2_u32, *BUFF_DELAY_COUNTER) {
|
||||||
// Need to wait 2 frames to make sure we stop the voice call, since it's a bit delayed
|
// Need to wait 2 frames to make sure we stop the voice call, since it's a bit delayed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +190,7 @@ unsafe fn buff_mac(module_accessor: &mut app::BattleObjectModuleAccessor) -> boo
|
||||||
*FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_FLOAT_KO_GAGE,
|
*FIGHTER_LITTLEMAC_INSTANCE_WORK_ID_FLOAT_KO_GAGE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) {
|
if frame_counter::should_delay(2_u32, *BUFF_DELAY_COUNTER) {
|
||||||
// Need to wait 2 frames to make sure we stop the KO sound, since it's a bit delayed
|
// Need to wait 2 frames to make sure we stop the KO sound, since it's a bit delayed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +240,7 @@ unsafe fn buff_shulk(module_accessor: &mut app::BattleObjectModuleAccessor, stat
|
||||||
start_buff(module_accessor);
|
start_buff(module_accessor);
|
||||||
let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0);
|
let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0);
|
||||||
if prev_status_kind == FIGHTER_SHULK_STATUS_KIND_SPECIAL_N_ACTION {
|
if prev_status_kind == FIGHTER_SHULK_STATUS_KIND_SPECIAL_N_ACTION {
|
||||||
if frame_counter::should_delay(3_u32, BUFF_DELAY_COUNTER) {
|
if frame_counter::should_delay(3_u32, *BUFF_DELAY_COUNTER) {
|
||||||
// Need to continue to be buffing to make sure we stop "JUMP!" voice line
|
// Need to continue to be buffing to make sure we stop "JUMP!" voice line
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ use crate::common::consts::FighterId;
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::training::*;
|
use crate::training::*;
|
||||||
|
|
||||||
|
use std::sync::Lazy;
|
||||||
|
|
||||||
pub static mut FRAME_ADVANTAGE: i32 = 0;
|
pub static mut FRAME_ADVANTAGE: i32 = 0;
|
||||||
static mut PLAYER_ACTIONABLE: bool = false;
|
static mut PLAYER_ACTIONABLE: bool = false;
|
||||||
static mut CPU_ACTIONABLE: bool = false;
|
static mut CPU_ACTIONABLE: bool = false;
|
||||||
|
@ -12,13 +14,9 @@ static mut PLAYER_ACTIVE_FRAME: u32 = 0;
|
||||||
static mut CPU_ACTIVE_FRAME: u32 = 0;
|
static mut CPU_ACTIVE_FRAME: u32 = 0;
|
||||||
static mut FRAME_ADVANTAGE_CHECK: bool = false;
|
static mut FRAME_ADVANTAGE_CHECK: bool = false;
|
||||||
|
|
||||||
static mut FRAME_COUNTER_INDEX: usize = 0;
|
static FRAME_COUNTER_INDEX: Lazy<u32> = Lazy::new(|| {
|
||||||
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
pub fn init() {
|
});
|
||||||
unsafe {
|
|
||||||
FRAME_COUNTER_INDEX = frame_counter::register_counter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn _was_in_hitstun(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
unsafe fn _was_in_hitstun(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0);
|
let prev_status = StatusModule::prev_status_kind(module_accessor, 0);
|
||||||
|
@ -105,7 +103,7 @@ pub unsafe fn is_enable_transition_term(
|
||||||
.any(|actionable_transition| *actionable_transition == transition_term))
|
.any(|actionable_transition| *actionable_transition == transition_term))
|
||||||
|| (CancelModule::is_enable_cancel(module_accessor)))
|
|| (CancelModule::is_enable_cancel(module_accessor)))
|
||||||
{
|
{
|
||||||
PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX);
|
PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(*FRAME_COUNTER_INDEX);
|
||||||
PLAYER_ACTIONABLE = true;
|
PLAYER_ACTIONABLE = true;
|
||||||
|
|
||||||
// if both are now active
|
// if both are now active
|
||||||
|
@ -117,7 +115,7 @@ pub unsafe fn is_enable_transition_term(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_counter::stop_counting(FRAME_COUNTER_INDEX);
|
frame_counter::stop_counting(*FRAME_COUNTER_INDEX);
|
||||||
FRAME_ADVANTAGE_CHECK = false;
|
FRAME_ADVANTAGE_CHECK = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,11 +139,11 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
|
||||||
|
|
||||||
// the frame the fighter *becomes* actionable
|
// the frame the fighter *becomes* actionable
|
||||||
if !CPU_ACTIONABLE && is_actionable(cpu_module_accessor) {
|
if !CPU_ACTIONABLE && is_actionable(cpu_module_accessor) {
|
||||||
CPU_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX);
|
CPU_ACTIVE_FRAME = frame_counter::get_frame_count(*FRAME_COUNTER_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !PLAYER_ACTIONABLE && is_actionable(player_module_accessor) {
|
if !PLAYER_ACTIONABLE && is_actionable(player_module_accessor) {
|
||||||
PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX);
|
PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(*FRAME_COUNTER_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPU_ACTIONABLE = is_actionable(cpu_module_accessor);
|
CPU_ACTIONABLE = is_actionable(cpu_module_accessor);
|
||||||
|
@ -154,8 +152,8 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
|
||||||
// if neither are active
|
// if neither are active
|
||||||
if !CPU_ACTIONABLE && !PLAYER_ACTIONABLE {
|
if !CPU_ACTIONABLE && !PLAYER_ACTIONABLE {
|
||||||
if !FRAME_ADVANTAGE_CHECK {
|
if !FRAME_ADVANTAGE_CHECK {
|
||||||
frame_counter::reset_frame_count(FRAME_COUNTER_INDEX);
|
frame_counter::reset_frame_count(*FRAME_COUNTER_INDEX);
|
||||||
frame_counter::start_counting(FRAME_COUNTER_INDEX);
|
frame_counter::start_counting(*FRAME_COUNTER_INDEX);
|
||||||
}
|
}
|
||||||
FRAME_ADVANTAGE_CHECK = true;
|
FRAME_ADVANTAGE_CHECK = true;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +164,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
|
||||||
update_frame_advantage((CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32);
|
update_frame_advantage((CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_counter::stop_counting(FRAME_COUNTER_INDEX);
|
frame_counter::stop_counting(*FRAME_COUNTER_INDEX);
|
||||||
FRAME_ADVANTAGE_CHECK = false;
|
FRAME_ADVANTAGE_CHECK = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use smash::phx::{Hash40, Vector3f};
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::training::{frame_counter, input_record};
|
use crate::training::{frame_counter, input_record};
|
||||||
|
|
||||||
static mut FRAME_COUNTER: usize = 0;
|
use std::sync::Lazy;
|
||||||
|
|
||||||
// The current fastfall delay
|
// The current fastfall delay
|
||||||
static mut DELAY: u32 = 0;
|
static mut DELAY: u32 = 0;
|
||||||
|
@ -22,11 +22,9 @@ pub fn roll_fast_fall() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
static FRAME_COUNTER_INDEX: Lazy<u32> = Lazy::new(|| {
|
||||||
unsafe {
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
FRAME_COUNTER = frame_counter::register_counter();
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||||
if !should_fast_fall() {
|
if !should_fast_fall() {
|
||||||
|
@ -46,7 +44,7 @@ pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccesso
|
||||||
if !is_falling(module_accessor) {
|
if !is_falling(module_accessor) {
|
||||||
// Roll FF delay
|
// Roll FF delay
|
||||||
DELAY = MENU.fast_fall_delay.get_random().into_delay();
|
DELAY = MENU.fast_fall_delay.get_random().into_delay();
|
||||||
frame_counter::full_reset(FRAME_COUNTER);
|
frame_counter::full_reset(*FRAME_COUNTER_INDEX);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccesso
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check delay
|
// Check delay
|
||||||
if frame_counter::should_delay(DELAY, FRAME_COUNTER) {
|
if frame_counter::should_delay(DELAY, *FRAME_COUNTER_INDEX) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,48 @@
|
||||||
static mut SHOULD_COUNT: Vec<bool> = vec![];
|
pub enum FrameCounterType {
|
||||||
static mut NO_RESET: Vec<bool> = vec![];
|
InGame,
|
||||||
static mut COUNTERS: Vec<u32> = vec![];
|
// "Reset" occurs when we enter training mode and when we run L+R+A or save state load
|
||||||
|
// Some frame counters need in-game frames that do not reset when this occurs
|
||||||
|
InGameNoReset,
|
||||||
|
Real
|
||||||
|
}
|
||||||
|
|
||||||
fn _register_counter(no_reset: bool) -> usize {
|
pub struct FrameCounter {
|
||||||
|
count: u32,
|
||||||
|
should_count: bool,
|
||||||
|
counter_type: FrameCounterType,
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut COUNTERS: Vec<FrameCounter> = vec![];
|
||||||
|
|
||||||
|
pub fn register_counter(counter_type: FrameCounterType) -> usize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let index = COUNTERS.len();
|
let index = COUNTERS.len();
|
||||||
|
|
||||||
COUNTERS.push(0);
|
COUNTERS.push(FrameCounter{
|
||||||
SHOULD_COUNT.push(false);
|
count: 0,
|
||||||
NO_RESET.push(no_reset);
|
should_count: false,
|
||||||
|
counter_type: counter_type
|
||||||
|
})
|
||||||
|
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _register_counter_no_reset() -> usize {
|
|
||||||
_register_counter(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_counter() -> usize {
|
|
||||||
_register_counter(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn start_counting(index: usize) {
|
pub fn start_counting(index: usize) {
|
||||||
unsafe {
|
unsafe {
|
||||||
SHOULD_COUNT[index] = true;
|
COUNTERS[index].should_count = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop_counting(index: usize) {
|
pub fn stop_counting(index: usize) {
|
||||||
unsafe {
|
unsafe {
|
||||||
SHOULD_COUNT[index] = false;
|
COUNTERS[index].should_count = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_frame_count(index: usize) {
|
pub fn reset_frame_count(index: usize) {
|
||||||
unsafe {
|
unsafe {
|
||||||
COUNTERS[index] = 0;
|
COUNTERS[index].count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,19 +74,30 @@ pub fn should_delay(delay: u32, index: usize) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_frame_count(index: usize) -> u32 {
|
pub fn get_frame_count(index: usize) -> u32 {
|
||||||
unsafe { COUNTERS[index] }
|
unsafe { COUNTERS[index].count }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick_idx(index: usize) {
|
pub fn tick_idx(index: usize) {
|
||||||
unsafe {
|
unsafe {
|
||||||
COUNTERS[index] += 1;
|
COUNTERS[index].count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick() {
|
pub fn tick_ingame() {
|
||||||
unsafe {
|
unsafe {
|
||||||
for (index, _frame) in COUNTERS.iter().enumerate() {
|
for (index, counter) in COUNTERS.iter().enumerate() {
|
||||||
if !SHOULD_COUNT[index] {
|
if !counter.should_count || counter.counter_type == FrameCounterType::Real {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tick_idx(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick_real() {
|
||||||
|
unsafe {
|
||||||
|
for (index, counter) in COUNTERS.iter().enumerate() {
|
||||||
|
if !counter.should_count || (counter.counter_type == FrameCounterType::InGame || counter.counter_type == FrameCounterType::InGameNoReset) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tick_idx(index);
|
tick_idx(index);
|
||||||
|
@ -90,8 +107,8 @@ pub fn tick() {
|
||||||
|
|
||||||
pub fn reset_all() {
|
pub fn reset_all() {
|
||||||
unsafe {
|
unsafe {
|
||||||
for (index, _frame) in COUNTERS.iter().enumerate() {
|
for (index, counter) in COUNTERS.iter().enumerate() {
|
||||||
if NO_RESET[index] {
|
if counter.counter_type != FrameCounterType::InGame {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
full_reset(index);
|
full_reset(index);
|
||||||
|
|
|
@ -5,22 +5,23 @@ use crate::common::consts::*;
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::training::{frame_counter, input_record, mash};
|
use crate::training::{frame_counter, input_record, mash};
|
||||||
|
|
||||||
|
use std::sync::Lazy;
|
||||||
|
|
||||||
const NOT_SET: u32 = 9001;
|
const NOT_SET: u32 = 9001;
|
||||||
static mut LEDGE_DELAY: u32 = NOT_SET;
|
static mut LEDGE_DELAY: u32 = NOT_SET;
|
||||||
static mut LEDGE_DELAY_COUNTER: usize = 0;
|
static mut LEDGE_DELAY_COUNTER: usize = 0;
|
||||||
static mut LEDGE_CASE: LedgeOption = LedgeOption::empty();
|
static mut LEDGE_CASE: LedgeOption = LedgeOption::empty();
|
||||||
|
|
||||||
pub fn init() {
|
static LEDGE_DELAY_COUNTER: Lazy<u32> = Lazy::new(|| {
|
||||||
unsafe {
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
LEDGE_DELAY_COUNTER = frame_counter::register_counter();
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_ledge_delay() {
|
pub fn reset_ledge_delay() {
|
||||||
unsafe {
|
unsafe {
|
||||||
if LEDGE_DELAY != NOT_SET {
|
if LEDGE_DELAY != NOT_SET {
|
||||||
LEDGE_DELAY = NOT_SET;
|
LEDGE_DELAY = NOT_SET;
|
||||||
frame_counter::full_reset(LEDGE_DELAY_COUNTER);
|
frame_counter::full_reset(*LEDGE_DELAY_COUNTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +155,7 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if frame_counter::should_delay(LEDGE_DELAY, LEDGE_DELAY_COUNTER) {
|
if frame_counter::should_delay(LEDGE_DELAY, *LEDGE_DELAY_COUNTER) {
|
||||||
// Not yet time to perform the ledge action
|
// Not yet time to perform the ledge action
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +190,7 @@ pub unsafe fn is_enable_transition_term(
|
||||||
// Disallow the default cliff-climb if we are waiting or we didn't get up during a recording
|
// Disallow the default cliff-climb if we are waiting or we didn't get up during a recording
|
||||||
if term == *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB
|
if term == *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB
|
||||||
&& ((LEDGE_CASE == LedgeOption::WAIT
|
&& ((LEDGE_CASE == LedgeOption::WAIT
|
||||||
|| frame_counter::get_frame_count(LEDGE_DELAY_COUNTER) < LEDGE_DELAY)
|
|| frame_counter::get_frame_count(*LEDGE_DELAY_COUNTER) < LEDGE_DELAY)
|
||||||
|| (LEDGE_CASE.is_playback() && !input_record::is_playback()))
|
|| (LEDGE_CASE.is_playback() && !input_record::is_playback()))
|
||||||
{
|
{
|
||||||
return Some(false);
|
return Some(false);
|
||||||
|
|
|
@ -20,9 +20,12 @@ static mut QUEUE: Vec<Action> = vec![];
|
||||||
|
|
||||||
static mut FALLING_AERIAL: bool = false;
|
static mut FALLING_AERIAL: bool = false;
|
||||||
|
|
||||||
static mut AERIAL_DELAY_COUNTER: usize = 0;
|
|
||||||
static mut AERIAL_DELAY: u32 = 0;
|
static mut AERIAL_DELAY: u32 = 0;
|
||||||
|
|
||||||
|
static AERIAL_DELAY_COUNTER: Lazy<u32> = Lazy::new(|| {
|
||||||
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
|
});
|
||||||
|
|
||||||
// Track if we're about to do another command flag cat run in the same frame for a dash or dash attack
|
// Track if we're about to do another command flag cat run in the same frame for a dash or dash attack
|
||||||
static mut IS_TRANSITIONING_DASH: bool = false;
|
static mut IS_TRANSITIONING_DASH: bool = false;
|
||||||
|
|
||||||
|
@ -138,7 +141,7 @@ pub fn reset() {
|
||||||
shield::suspend_shield(get_current_buffer());
|
shield::suspend_shield(get_current_buffer());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
frame_counter::full_reset(AERIAL_DELAY_COUNTER);
|
frame_counter::full_reset(*AERIAL_DELAY_COUNTER);
|
||||||
AERIAL_DELAY = 0;
|
AERIAL_DELAY = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,12 +580,6 @@ unsafe fn get_aerial_flag(
|
||||||
flag
|
flag
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
unsafe {
|
|
||||||
AERIAL_DELAY_COUNTER = frame_counter::register_counter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn roll_aerial_delay(action: Action) {
|
fn roll_aerial_delay(action: Action) {
|
||||||
if !shield::is_aerial(action) {
|
if !shield::is_aerial(action) {
|
||||||
return;
|
return;
|
||||||
|
@ -609,7 +606,7 @@ fn should_delay_aerial(module_accessor: &mut app::BattleObjectModuleAccessor) ->
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_counter::should_delay(AERIAL_DELAY, AERIAL_DELAY_COUNTER)
|
frame_counter::should_delay(AERIAL_DELAY, *AERIAL_DELAY_COUNTER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ use crate::common::consts::*;
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::training::{frame_counter, input_record, mash, save_states};
|
use crate::training::{frame_counter, input_record, mash, save_states};
|
||||||
|
|
||||||
|
use std::sync::Lazy;
|
||||||
|
|
||||||
// How many hits to hold shield until picking an Out Of Shield option
|
// How many hits to hold shield until picking an Out Of Shield option
|
||||||
static mut MULTI_HIT_OFFSET: u32 = 0;
|
static mut MULTI_HIT_OFFSET: u32 = 0;
|
||||||
|
|
||||||
|
@ -19,16 +21,12 @@ static mut SHIELD_DELAY: u32 = 0;
|
||||||
// Used to only decrease once per shieldstun change
|
// Used to only decrease once per shieldstun change
|
||||||
static mut WAS_IN_SHIELDSTUN: bool = false;
|
static mut WAS_IN_SHIELDSTUN: bool = false;
|
||||||
|
|
||||||
static mut REACTION_INDEX: usize = 0;
|
|
||||||
|
|
||||||
// For how many frames should the shield hold be overwritten
|
// For how many frames should the shield hold be overwritten
|
||||||
static mut SUSPEND_SHIELD: bool = false;
|
static mut SUSPEND_SHIELD: bool = false;
|
||||||
|
|
||||||
pub fn init() {
|
static REACTION_COUNTER_INDEX: Lazy<u32> = Lazy::new(|| {
|
||||||
unsafe {
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
REACTION_INDEX = frame_counter::register_counter();
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle for shield decay
|
// Toggle for shield decay
|
||||||
static mut SHIELD_DECAY: bool = false;
|
static mut SHIELD_DECAY: bool = false;
|
||||||
|
@ -236,11 +234,11 @@ unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_shielding(module_accessor) {
|
if !is_shielding(module_accessor) {
|
||||||
frame_counter::full_reset(REACTION_INDEX);
|
frame_counter::full_reset(*REACTION_COUNTER_INDEX);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if frame_counter::should_delay(SHIELD_DELAY, REACTION_INDEX) {
|
if frame_counter::should_delay(SHIELD_DELAY, *REACTION_COUNTER_INDEX) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,14 @@ use crate::common::consts::*;
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::training::{frame_counter, mash};
|
use crate::training::{frame_counter, mash};
|
||||||
|
|
||||||
|
use std::sync::Lazy;
|
||||||
|
|
||||||
static mut TECH_ROLL_DIRECTION: Direction = Direction::empty();
|
static mut TECH_ROLL_DIRECTION: Direction = Direction::empty();
|
||||||
static mut MISS_TECH_ROLL_DIRECTION: Direction = Direction::empty();
|
static mut MISS_TECH_ROLL_DIRECTION: Direction = Direction::empty();
|
||||||
static mut FRAME_COUNTER: usize = 0;
|
|
||||||
|
|
||||||
pub fn init() {
|
static FRAME_COUNTER: Lazy<u32> = Lazy::new(|| {
|
||||||
unsafe {
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
FRAME_COUNTER = frame_counter::register_counter();
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn is_enable_passive(module_accessor: &mut BattleObjectModuleAccessor) -> bool {
|
unsafe fn is_enable_passive(module_accessor: &mut BattleObjectModuleAccessor) -> bool {
|
||||||
let fighter = get_fighter_common_from_accessor(module_accessor);
|
let fighter = get_fighter_common_from_accessor(module_accessor);
|
||||||
|
@ -237,7 +236,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
||||||
} else if status == *FIGHTER_STATUS_KIND_LAY_DOWN {
|
} else if status == *FIGHTER_STATUS_KIND_LAY_DOWN {
|
||||||
// Snake down throw
|
// Snake down throw
|
||||||
let lockout_time = get_snake_laydown_lockout_time(module_accessor);
|
let lockout_time = get_snake_laydown_lockout_time(module_accessor);
|
||||||
if frame_counter::should_delay(lockout_time, FRAME_COUNTER) {
|
if frame_counter::should_delay(lockout_time, *FRAME_COUNTER) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
requested_status = match MENU.miss_tech_state.get_random() {
|
requested_status = match MENU.miss_tech_state.get_random() {
|
||||||
|
@ -264,7 +263,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// Not in a tech situation, make sure the snake dthrow counter is fully reset.
|
// Not in a tech situation, make sure the snake dthrow counter is fully reset.
|
||||||
frame_counter::full_reset(FRAME_COUNTER);
|
frame_counter::full_reset(*FRAME_COUNTER);
|
||||||
};
|
};
|
||||||
|
|
||||||
if requested_status != 0 {
|
if requested_status != 0 {
|
||||||
|
|
|
@ -11,15 +11,12 @@ static mut THROW_DELAY: u32 = NOT_SET;
|
||||||
static mut THROW_DELAY_COUNTER: usize = 0;
|
static mut THROW_DELAY_COUNTER: usize = 0;
|
||||||
static mut THROW_CASE: ThrowOption = ThrowOption::empty();
|
static mut THROW_CASE: ThrowOption = ThrowOption::empty();
|
||||||
|
|
||||||
static mut PUMMEL_DELAY: u32 = NOT_SET;
|
static THROW_DELAY_COUNTER: Lazy<u32> = Lazy::new(|| {
|
||||||
static mut PUMMEL_DELAY_COUNTER: usize = 0;
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
|
});
|
||||||
pub fn init() {
|
static PUMMEL_DELAY_COUNTER: Lazy<u32> = Lazy::new(|| {
|
||||||
unsafe {
|
frame_counter::register_counter(frame_counter::FrameCounterType::InGame)
|
||||||
THROW_DELAY_COUNTER = frame_counter::register_counter();
|
});
|
||||||
PUMMEL_DELAY_COUNTER = frame_counter::register_counter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rolling Throw Delays and Pummel Delays separately
|
// Rolling Throw Delays and Pummel Delays separately
|
||||||
|
|
||||||
|
@ -27,7 +24,7 @@ pub fn reset_throw_delay() {
|
||||||
unsafe {
|
unsafe {
|
||||||
if THROW_DELAY != NOT_SET {
|
if THROW_DELAY != NOT_SET {
|
||||||
THROW_DELAY = NOT_SET;
|
THROW_DELAY = NOT_SET;
|
||||||
frame_counter::full_reset(THROW_DELAY_COUNTER);
|
frame_counter::full_reset(*THROW_DELAY_COUNTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +33,7 @@ pub fn reset_pummel_delay() {
|
||||||
unsafe {
|
unsafe {
|
||||||
if PUMMEL_DELAY != NOT_SET {
|
if PUMMEL_DELAY != NOT_SET {
|
||||||
PUMMEL_DELAY = NOT_SET;
|
PUMMEL_DELAY = NOT_SET;
|
||||||
frame_counter::full_reset(PUMMEL_DELAY_COUNTER);
|
frame_counter::full_reset(*PUMMEL_DELAY_COUNTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,9 +117,9 @@ pub unsafe fn get_command_flag_throw_direction(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if frame_counter::should_delay(THROW_DELAY, THROW_DELAY_COUNTER) {
|
if frame_counter::should_delay(THROW_DELAY, *THROW_DELAY_COUNTER) {
|
||||||
// Not yet time to perform the throw action
|
// Not yet time to perform the throw action
|
||||||
if frame_counter::should_delay(PUMMEL_DELAY, PUMMEL_DELAY_COUNTER) {
|
if frame_counter::should_delay(PUMMEL_DELAY, *PUMMEL_DELAY_COUNTER) {
|
||||||
// And not yet time to pummel either, so don't do anything
|
// And not yet time to pummel either, so don't do anything
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use training_mod_tui::gauge::GaugeState;
|
||||||
use training_mod_tui::{App, AppPage, NUM_LISTS};
|
use training_mod_tui::{App, AppPage, NUM_LISTS};
|
||||||
|
|
||||||
use crate::common::menu::{
|
use crate::common::menu::{
|
||||||
MENU_CLOSE_WAIT_FRAMES, VISUAL_FRAME_COUNTER, VISUAL_FRAME_COUNTER_SHOULD_COUNT,
|
MENU_CLOSE_WAIT_FRAMES, MENU_CLOSE_FRAME_COUNTER,
|
||||||
};
|
};
|
||||||
use crate::{common, common::menu::QUICK_MENU_ACTIVE, input::*};
|
use crate::{common, common::menu::QUICK_MENU_ACTIVE, input::*};
|
||||||
|
|
||||||
|
@ -353,12 +353,6 @@ unsafe fn render_slider_page(app: &App, root_pane: &Pane) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn draw(root_pane: &Pane) {
|
pub unsafe fn draw(root_pane: &Pane) {
|
||||||
if *VISUAL_FRAME_COUNTER_SHOULD_COUNT.data_ptr() {
|
|
||||||
*VISUAL_FRAME_COUNTER.lock() += 1;
|
|
||||||
} else {
|
|
||||||
*VISUAL_FRAME_COUNTER.lock() = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine if we're in the menu by seeing if the "help" footer has
|
// Determine if we're in the menu by seeing if the "help" footer has
|
||||||
// begun moving upward. It starts at -80 and moves to 0 over 10 frames
|
// begun moving upward. It starts at -80 and moves to 0 over 10 frames
|
||||||
// in info_training_in_menu.bflan
|
// in info_training_in_menu.bflan
|
||||||
|
@ -381,7 +375,7 @@ pub unsafe fn draw(root_pane: &Pane) {
|
||||||
|
|
||||||
let overall_parent_pane = root_pane.find_pane_by_name_recursive("TrModMenu").unwrap();
|
let overall_parent_pane = root_pane.find_pane_by_name_recursive("TrModMenu").unwrap();
|
||||||
overall_parent_pane.set_visible(true);
|
overall_parent_pane.set_visible(true);
|
||||||
let menu_close_wait_frame = *VISUAL_FRAME_COUNTER.data_ptr();
|
let menu_close_wait_frame = frame_counter::get_frame_count(*MENU_CLOSE_FRAME_COUNTER);
|
||||||
if QUICK_MENU_ACTIVE {
|
if QUICK_MENU_ACTIVE {
|
||||||
overall_parent_pane.alpha = 255;
|
overall_parent_pane.alpha = 255;
|
||||||
overall_parent_pane.global_alpha = 255;
|
overall_parent_pane.global_alpha = 255;
|
||||||
|
|
|
@ -56,6 +56,7 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
|
||||||
damage::draw(root_pane, &layout_name);
|
damage::draw(root_pane, &layout_name);
|
||||||
|
|
||||||
if layout_name == "info_training" {
|
if layout_name == "info_training" {
|
||||||
|
frame_counter::tick_real();
|
||||||
display::draw(root_pane);
|
display::draw(root_pane);
|
||||||
menu::draw(root_pane);
|
menu::draw(root_pane);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue