mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2025-03-30 02:02:43 +00:00
Update MENU
This commit is contained in:
parent
8c78561cc7
commit
76b38f575e
32 changed files with 369 additions and 372 deletions
|
@ -3,11 +3,11 @@ use std::collections::HashMap;
|
|||
use crate::common::menu::{MENU_CLOSE_FRAME_COUNTER, QUICK_MENU_ACTIVE};
|
||||
use crate::common::ButtonConfig;
|
||||
use crate::input::{ControllerStyle::*, *};
|
||||
use training_mod_sync::*;
|
||||
use crate::training::frame_counter;
|
||||
use crate::training::ui::menu::VANILLA_MENU_ACTIVE;
|
||||
|
||||
use training_mod_consts::{OnOff, MENU};
|
||||
use training_mod_sync::*;
|
||||
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
|
@ -176,10 +176,10 @@ unsafe fn get_combo_keys(combo: ButtonCombo) -> ButtonConfig {
|
|||
match combo {
|
||||
// For OpenMenu, have a default in addition to accepting start press
|
||||
ButtonCombo::OpenMenu => DEFAULT_OPEN_MENU_CONFIG,
|
||||
ButtonCombo::SaveState => MENU.save_state_save,
|
||||
ButtonCombo::LoadState => MENU.save_state_load,
|
||||
ButtonCombo::InputRecord => MENU.input_record,
|
||||
ButtonCombo::InputPlayback => MENU.input_playback,
|
||||
ButtonCombo::SaveState => get(&MENU).save_state_save,
|
||||
ButtonCombo::LoadState => get(&MENU).save_state_load,
|
||||
ButtonCombo::InputRecord => get(&MENU).input_record,
|
||||
ButtonCombo::InputPlayback => get(&MENU).input_playback,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ pub fn handle_final_input_mapping(player_idx: i32, controller_struct: &mut SomeC
|
|||
let mut start_menu_request = false;
|
||||
|
||||
let menu_close_wait_frame = frame_counter::get_frame_count(*MENU_CLOSE_FRAME_COUNTER);
|
||||
if unsafe { MENU.menu_open_start_press == OnOff::ON } {
|
||||
if get(&MENU).menu_open_start_press == OnOff::ON {
|
||||
let mut start_hold_frames = read_rwlock(&START_HOLD_FRAMES);
|
||||
if p1_controller.current_buttons.plus() {
|
||||
start_hold_frames += 1;
|
||||
|
|
|
@ -37,7 +37,7 @@ pub fn load_from_file() {
|
|||
if let Ok(menu_conf_json) = serde_json::from_reader::<BufReader<_>, MenuJsonStruct>(reader)
|
||||
{
|
||||
unsafe {
|
||||
MENU = menu_conf_json.menu;
|
||||
assign_rwlock(&MENU, menu_conf_json.menu);
|
||||
DEFAULTS_MENU = menu_conf_json.defaults_menu;
|
||||
info!("Previous menu found. Loading...");
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ pub unsafe fn set_menu_from_json(message: &str) {
|
|||
info!("Received menu message: {message}");
|
||||
if let Ok(message_json) = response {
|
||||
// Includes both MENU and DEFAULTS_MENU
|
||||
MENU = message_json.menu;
|
||||
assign_rwlock(&MENU, message_json.menu);
|
||||
DEFAULTS_MENU = message_json.defaults_menu;
|
||||
fs::write(
|
||||
MENU_OPTIONS_PATH,
|
||||
|
|
|
@ -5,7 +5,8 @@ use zip::ZipArchive;
|
|||
use crate::common::dialog;
|
||||
use crate::consts::*;
|
||||
use crate::logging::*;
|
||||
use training_mod_sync::LazyLock;
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
pub static CURRENT_VERSION: LazyLock<String> = LazyLock::new(|| {
|
||||
info!("Initialized lazy static value: CURRENT_VERSION");
|
||||
|
@ -74,7 +75,7 @@ impl Release {
|
|||
}
|
||||
|
||||
fn get_update_policy() -> UpdatePolicy {
|
||||
unsafe { MENU.update_policy }
|
||||
get(&MENU).update_policy
|
||||
}
|
||||
|
||||
fn get_release(beta: bool) -> Result<Release> {
|
||||
|
|
|
@ -6,7 +6,8 @@ use smash::app::smashball::is_training_mode;
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::logging::*;
|
||||
use training_mod_sync::LazyLock;
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
use HazardState::*;
|
||||
use HookState::*;
|
||||
|
@ -93,7 +94,7 @@ fn hazard_intercept(_ctx: &skyline::hooks::InlineCtx) {
|
|||
fn mod_handle_hazards() {
|
||||
unsafe {
|
||||
let address = *HAZARD_FLAG_ADDRESS as *mut u8;
|
||||
*address = (MENU.stage_hazards == OnOff::ON) as u8;
|
||||
*address = (get(&MENU).stage_hazards == OnOff::ON) as u8;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ use smash::phx::{Hash40, Vector3f};
|
|||
use crate::common::{consts::*, *};
|
||||
use crate::logging::*;
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
pub const ID_COLORS: &[Vector3f] = &[
|
||||
// used to tint the hitbox effects -- make sure that at least one component
|
||||
// is equal to 1.0
|
||||
|
@ -135,7 +137,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
|
|||
// Resume Effect AnimCMD incase we don't display hitboxes
|
||||
MotionAnimcmdModule::set_sleep_effect(module_accessor, false);
|
||||
|
||||
if MENU.hitbox_vis == OnOff::OFF {
|
||||
if get(&MENU).hitbox_vis == OnOff::OFF {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -205,7 +207,7 @@ unsafe fn mod_handle_attack(lua_state: u64) {
|
|||
|
||||
// necessary if param object fails
|
||||
// hacky way of forcing no shield damage on all hitboxes
|
||||
if MENU.shield_state == Shield::INFINITE {
|
||||
if get(&MENU).shield_state == Shield::INFINITE {
|
||||
let mut hitbox_params: Vec<L2CValue> =
|
||||
(0..36).map(|i| l2c_agent.pop_lua_stack(i + 1)).collect();
|
||||
l2c_agent.clear_lua_stack();
|
||||
|
@ -219,7 +221,7 @@ unsafe fn mod_handle_attack(lua_state: u64) {
|
|||
}
|
||||
|
||||
// Hitbox Visualization
|
||||
if MENU.hitbox_vis == OnOff::ON {
|
||||
if get(&MENU).hitbox_vis == OnOff::ON {
|
||||
// get all necessary grabbox params
|
||||
let id = l2c_agent.pop_lua_stack(1); // int
|
||||
let joint = l2c_agent.pop_lua_stack(3); // hash40
|
||||
|
@ -274,7 +276,7 @@ unsafe fn handle_catch(lua_state: u64) {
|
|||
}
|
||||
|
||||
unsafe fn mod_handle_catch(lua_state: u64) {
|
||||
if MENU.hitbox_vis == OnOff::OFF {
|
||||
if get(&MENU).hitbox_vis == OnOff::OFF {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
62
src/lib.rs
62
src/lib.rs
|
@ -126,38 +126,36 @@ pub fn main() {
|
|||
info!("Skipping version check because we are using an emulator");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
notification("Training Modpack".to_string(), "Welcome!".to_string(), 60);
|
||||
notification(
|
||||
"Open Menu".to_string(),
|
||||
if MENU.menu_open_start_press == OnOff::ON {
|
||||
"Hold Start".to_string()
|
||||
} else {
|
||||
DEFAULT_OPEN_MENU_CONFIG.to_string()
|
||||
},
|
||||
120,
|
||||
);
|
||||
notification(
|
||||
"Save State".to_string(),
|
||||
MENU.save_state_save.to_string(),
|
||||
120,
|
||||
);
|
||||
notification(
|
||||
"Load State".to_string(),
|
||||
MENU.save_state_load.to_string(),
|
||||
120,
|
||||
);
|
||||
notification(
|
||||
"Input Record".to_string(),
|
||||
MENU.input_record.to_string(),
|
||||
120,
|
||||
);
|
||||
notification(
|
||||
"Input Playback".to_string(),
|
||||
MENU.input_playback.to_string(),
|
||||
120,
|
||||
);
|
||||
}
|
||||
notification("Training Modpack".to_string(), "Welcome!".to_string(), 60);
|
||||
notification(
|
||||
"Open Menu".to_string(),
|
||||
if get(&MENU).menu_open_start_press == OnOff::ON {
|
||||
"Hold Start".to_string()
|
||||
} else {
|
||||
DEFAULT_OPEN_MENU_CONFIG.to_string()
|
||||
},
|
||||
120,
|
||||
);
|
||||
notification(
|
||||
"Save State".to_string(),
|
||||
get(&MENU).save_state_save.to_string(),
|
||||
120,
|
||||
);
|
||||
notification(
|
||||
"Load State".to_string(),
|
||||
get(&MENU).save_state_load.to_string(),
|
||||
120,
|
||||
);
|
||||
notification(
|
||||
"Input Record".to_string(),
|
||||
get(&MENU).input_record.to_string(),
|
||||
120,
|
||||
);
|
||||
notification(
|
||||
"Input Playback".to_string(),
|
||||
get(&MENU).input_playback.to_string(),
|
||||
120,
|
||||
);
|
||||
|
||||
std::thread::spawn(events_loop);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ use smash::lib::lua_const::*;
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::directional_influence::should_reverse_angle;
|
||||
use training_mod_sync::*;
|
||||
|
||||
static AIRDODGE_STICK_DIRECTION: RwLock<Direction> = RwLock::new(Direction::empty());
|
||||
|
||||
|
@ -32,7 +32,10 @@ unsafe fn get_angle(module_accessor: &mut app::BattleObjectModuleAccessor) -> Op
|
|||
return None;
|
||||
}
|
||||
|
||||
assign_rwlock(&AIRDODGE_STICK_DIRECTION, MENU.air_dodge_dir.get_random());
|
||||
assign_rwlock(
|
||||
&AIRDODGE_STICK_DIRECTION,
|
||||
get(&MENU).air_dodge_dir.get_random(),
|
||||
);
|
||||
let direction = read_rwlock(&AIRDODGE_STICK_DIRECTION);
|
||||
direction.into_angle().map(|angle| {
|
||||
if !should_reverse_angle(direction) {
|
||||
|
|
|
@ -7,9 +7,10 @@ use training_mod_sync::*;
|
|||
static ATTACK_ANGLE_DIRECTION: RwLock<AttackAngle> = RwLock::new(AttackAngle::NEUTRAL);
|
||||
|
||||
pub fn roll_direction() {
|
||||
unsafe {
|
||||
assign_rwlock(&ATTACK_ANGLE_DIRECTION, MENU.attack_angle.get_random());
|
||||
}
|
||||
assign_rwlock(
|
||||
&ATTACK_ANGLE_DIRECTION,
|
||||
get(&MENU).attack_angle.get_random(),
|
||||
);
|
||||
}
|
||||
|
||||
pub unsafe fn mod_get_stick_dir(
|
||||
|
|
|
@ -5,10 +5,11 @@ use smash::phx::{Hash40, Vector3f};
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::is_operation_cpu;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::frame_counter;
|
||||
use crate::training::handle_add_limit;
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
static BUFF_REMAINING_PLAYER: RwLock<usize> = RwLock::new(0);
|
||||
static BUFF_REMAINING_CPU: RwLock<usize> = RwLock::new(0);
|
||||
|
||||
|
@ -77,7 +78,7 @@ pub unsafe fn handle_buffs(
|
|||
CameraModule::stop_quake(module_accessor, *CAMERA_QUAKE_KIND_M); // stops Psyche-Up quake
|
||||
CameraModule::stop_quake(module_accessor, *CAMERA_QUAKE_KIND_S); // stops Monado Art quake
|
||||
|
||||
let menu_vec = MENU.buff_state;
|
||||
let menu_vec = get(&MENU).buff_state;
|
||||
|
||||
if fighter_kind == *FIGHTER_KIND_BRAVE {
|
||||
return buff_hero(module_accessor, status);
|
||||
|
@ -102,7 +103,7 @@ pub unsafe fn handle_buffs(
|
|||
}
|
||||
|
||||
unsafe fn buff_hero(module_accessor: &mut app::BattleObjectModuleAccessor, status: i32) -> bool {
|
||||
let buff_vec: Vec<BuffOption> = MENU.buff_state.hero_buffs().to_vec();
|
||||
let buff_vec: Vec<BuffOption> = get(&MENU).buff_state.hero_buffs().to_vec();
|
||||
if !is_buffing(module_accessor) {
|
||||
// Initial set up for spells
|
||||
start_buff(module_accessor);
|
||||
|
@ -239,7 +240,7 @@ unsafe fn buff_sepiroth(module_accessor: &mut app::BattleObjectModuleAccessor) -
|
|||
|
||||
unsafe fn buff_wario(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
if !is_buffing(module_accessor) {
|
||||
let waft_level: BuffOption = MENU.buff_state.wario_buffs().get_random();
|
||||
let waft_level: BuffOption = get(&MENU).buff_state.wario_buffs().get_random();
|
||||
let waft_count_secs = match waft_level {
|
||||
BuffOption::WAFT_MINI => WorkModule::get_param_float(
|
||||
module_accessor,
|
||||
|
@ -275,7 +276,7 @@ unsafe fn buff_wario(module_accessor: &mut app::BattleObjectModuleAccessor) -> b
|
|||
}
|
||||
|
||||
unsafe fn buff_shulk(module_accessor: &mut app::BattleObjectModuleAccessor, status: i32) -> bool {
|
||||
let current_art = MENU.buff_state.shulk_buffs().get_random();
|
||||
let current_art = get(&MENU).buff_state.shulk_buffs().get_random();
|
||||
if current_art == BuffOption::empty() {
|
||||
// No Monado Arts selected in the buff menu, so we don't need to buff
|
||||
return true;
|
||||
|
|
|
@ -47,7 +47,7 @@ pub unsafe fn handle_clatter(module_accessor: &mut BattleObjectModuleAccessor) {
|
|||
// Don't do clatter inputs if we're not in clatter
|
||||
return;
|
||||
}
|
||||
let repeat = MENU.clatter_strength.into_u32();
|
||||
let repeat = get(&MENU).clatter_strength.into_u32();
|
||||
|
||||
let mut counter_guard = lock_write_rwlock(&COUNTER);
|
||||
*counter_guard = ((*counter_guard) + 1) % repeat;
|
||||
|
|
|
@ -3,10 +3,11 @@ use training_mod_consts::OnOff;
|
|||
|
||||
use crate::common::*;
|
||||
use crate::consts::Action;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::ui::notifications;
|
||||
use crate::training::*;
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
static PLAYER_WAS_ACTIONABLE: RwLock<bool> = RwLock::new(false);
|
||||
static CPU_WAS_ACTIONABLE: RwLock<bool> = RwLock::new(false);
|
||||
|
||||
|
@ -49,37 +50,35 @@ unsafe fn is_actionable(module_accessor: *mut BattleObjectModuleAccessor) -> boo
|
|||
}
|
||||
|
||||
fn update_frame_advantage(frame_advantage: i32) {
|
||||
unsafe {
|
||||
if MENU.frame_advantage == OnOff::ON {
|
||||
// Prioritize Frame Advantage over Input Recording Playback
|
||||
notifications::clear_notifications_except("Input Recording");
|
||||
notifications::clear_notifications_except("Frame Advantage");
|
||||
notifications::color_notification(
|
||||
"Frame Advantage".to_string(),
|
||||
format!("{frame_advantage}"),
|
||||
60,
|
||||
match frame_advantage {
|
||||
x if x < 0 => ResColor {
|
||||
r: 200,
|
||||
g: 8,
|
||||
b: 8,
|
||||
a: 255,
|
||||
},
|
||||
0 => ResColor {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: 255,
|
||||
},
|
||||
_ => ResColor {
|
||||
r: 31,
|
||||
g: 198,
|
||||
b: 0,
|
||||
a: 255,
|
||||
},
|
||||
if get(&MENU).frame_advantage == OnOff::ON {
|
||||
// Prioritize Frame Advantage over Input Recording Playback
|
||||
notifications::clear_notifications_except("Input Recording");
|
||||
notifications::clear_notifications_except("Frame Advantage");
|
||||
notifications::color_notification(
|
||||
"Frame Advantage".to_string(),
|
||||
format!("{frame_advantage}"),
|
||||
60,
|
||||
match frame_advantage {
|
||||
x if x < 0 => ResColor {
|
||||
r: 200,
|
||||
g: 8,
|
||||
b: 8,
|
||||
a: 255,
|
||||
},
|
||||
);
|
||||
}
|
||||
0 => ResColor {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: 255,
|
||||
},
|
||||
_ => ResColor {
|
||||
r: 31,
|
||||
g: 198,
|
||||
b: 0,
|
||||
a: 255,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +100,7 @@ pub unsafe fn once_per_frame(module_accessor: &mut BattleObjectModuleAccessor) {
|
|||
|| frame_counter::is_counting(*CPU_FRAME_COUNTER_INDEX);
|
||||
|
||||
if !is_counting {
|
||||
if MENU.mash_state == Action::empty()
|
||||
if get(&MENU).mash_state == Action::empty()
|
||||
&& !player_is_actionable
|
||||
&& !cpu_is_actionable
|
||||
&& (!was_in_shieldstun(cpu_module_accessor) && is_in_shieldstun(cpu_module_accessor)
|
||||
|
|
|
@ -4,13 +4,15 @@ use smash::lib::lua_const::*;
|
|||
use crate::common::consts::OnOff;
|
||||
use crate::common::*;
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
pub unsafe fn mod_get_stick_y(module_accessor: &mut BattleObjectModuleAccessor) -> Option<f32> {
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return None;
|
||||
}
|
||||
let fighter_status_kind = StatusModule::status_kind(module_accessor);
|
||||
|
||||
if MENU.crouch == OnOff::ON
|
||||
if get(&MENU).crouch == OnOff::ON
|
||||
&& [
|
||||
*FIGHTER_STATUS_KIND_WAIT,
|
||||
*FIGHTER_STATUS_KIND_SQUAT,
|
||||
|
|
|
@ -12,15 +12,12 @@ use training_mod_sync::*;
|
|||
static DI_CASE: RwLock<Direction> = RwLock::new(Direction::empty());
|
||||
|
||||
pub fn roll_di_case() {
|
||||
unsafe {
|
||||
let mut di_case_guard = lock_write_rwlock(&DI_CASE);
|
||||
if *di_case_guard != Direction::empty() {
|
||||
// DI direction already selected, don't pick a new one
|
||||
return;
|
||||
}
|
||||
|
||||
*di_case_guard = MENU.di_state.get_random();
|
||||
let mut di_case_guard = lock_write_rwlock(&DI_CASE);
|
||||
if *di_case_guard != Direction::empty() {
|
||||
// DI direction already selected, don't pick a new one
|
||||
return;
|
||||
}
|
||||
*di_case_guard = get(&MENU).di_state.get_random();
|
||||
}
|
||||
|
||||
pub fn reset_di_case(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
|
@ -47,7 +44,7 @@ pub unsafe fn handle_correct_damage_vector_common(
|
|||
}
|
||||
|
||||
unsafe fn mod_handle_di(fighter: &L2CFighterCommon, _arg1: L2CValue) {
|
||||
if MENU.di_state == Direction::empty() {
|
||||
if get(&MENU).di_state == Direction::empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@ use smash::lib::lua_const::*;
|
|||
use smash::phx::{Hash40, Vector3f};
|
||||
|
||||
use crate::common::*;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::{frame_counter, input_record};
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
static DELAY: RwLock<u32> = RwLock::new(0);
|
||||
static FAST_FALL: RwLock<bool> = RwLock::new(false);
|
||||
static FRAME_COUNTER_INDEX: LazyLock<usize> =
|
||||
|
@ -16,9 +17,7 @@ fn should_fast_fall() -> bool {
|
|||
}
|
||||
|
||||
pub fn roll_fast_fall() {
|
||||
unsafe {
|
||||
assign_rwlock(&FAST_FALL, MENU.fast_fall.get_random().into_bool());
|
||||
}
|
||||
assign_rwlock(&FAST_FALL, get(&MENU).fast_fall.get_random().into_bool());
|
||||
}
|
||||
|
||||
pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
|
@ -38,7 +37,7 @@ pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccesso
|
|||
unsafe {
|
||||
if !is_falling(module_accessor) {
|
||||
// Roll FF delay
|
||||
assign_rwlock(&DELAY, MENU.fast_fall_delay.get_random().into_delay());
|
||||
assign_rwlock(&DELAY, get(&MENU).fast_fall_delay.get_random().into_delay());
|
||||
frame_counter::full_reset(*FRAME_COUNTER_INDEX);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,9 +13,7 @@ pub fn should_full_hop() -> bool {
|
|||
}
|
||||
|
||||
pub fn roll_full_hop() {
|
||||
unsafe {
|
||||
assign_rwlock(&FULL_HOP, MENU.full_hop.get_random().into_bool());
|
||||
}
|
||||
assign_rwlock(&FULL_HOP, get(&MENU).full_hop.get_random().into_bool());
|
||||
}
|
||||
|
||||
pub unsafe fn check_button_on(
|
||||
|
|
|
@ -4,6 +4,8 @@ use crate::common::input::*;
|
|||
use lazy_static::lazy_static;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
use crate::common::MENU;
|
||||
|
||||
lazy_static! {
|
||||
|
@ -17,14 +19,14 @@ pub fn handle_final_input_mapping(player_idx: i32, out: *mut MappedInputs) {
|
|||
let mut delayed_mappings = P1_DELAYED_INPUT_MAPPINGS.lock();
|
||||
let actual_mapping = *out;
|
||||
|
||||
if delayed_mappings.len() < MENU.input_delay.into_delay() as usize {
|
||||
if delayed_mappings.len() < get(&MENU).input_delay.into_delay() as usize {
|
||||
*out = MappedInputs::empty();
|
||||
} else if let Some(delayed_mapping) = delayed_mappings.back() {
|
||||
*out = *delayed_mapping;
|
||||
}
|
||||
|
||||
delayed_mappings.push_front(actual_mapping);
|
||||
delayed_mappings.truncate(MENU.input_delay.into_delay() as usize);
|
||||
delayed_mappings.truncate(get(&MENU).input_delay.into_delay() as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@ use std::collections::VecDeque;
|
|||
|
||||
use crate::common::input::*;
|
||||
use crate::menu::QUICK_MENU_ACTIVE;
|
||||
use training_mod_sync::*;
|
||||
use crate::try_get_module_accessor;
|
||||
use skyline::nn::ui2d::ResColor;
|
||||
use smash::app::{lua_bind::*, utility};
|
||||
use training_mod_consts::{FighterId, InputDisplay, MENU};
|
||||
use training_mod_sync::*;
|
||||
|
||||
use super::{frame_counter, input_record::STICK_CLAMP_MULTIPLIER};
|
||||
|
||||
|
@ -136,50 +136,51 @@ fn bin_stick_values(x: i8, y: i8) -> (DirectionStrength, f32) {
|
|||
|
||||
impl InputLog {
|
||||
pub fn is_different(&self, other: &InputLog) -> bool {
|
||||
unsafe {
|
||||
match MENU.input_display {
|
||||
InputDisplay::SMASH => self.is_smash_different(other),
|
||||
InputDisplay::RAW => self.is_raw_different(other),
|
||||
InputDisplay::STATUS => self.is_status_different(other),
|
||||
InputDisplay::NONE => false,
|
||||
_ => panic!("Invalid value in is_different: {}", MENU.input_display),
|
||||
}
|
||||
match get(&MENU).input_display {
|
||||
InputDisplay::SMASH => self.is_smash_different(other),
|
||||
InputDisplay::RAW => self.is_raw_different(other),
|
||||
InputDisplay::STATUS => self.is_status_different(other),
|
||||
InputDisplay::NONE => false,
|
||||
_ => panic!(
|
||||
"Invalid value in is_different: {}",
|
||||
get(&MENU).input_display
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn binned_lstick(&self) -> (DirectionStrength, f32) {
|
||||
unsafe {
|
||||
match MENU.input_display {
|
||||
InputDisplay::SMASH => self.smash_binned_lstick(),
|
||||
InputDisplay::RAW => self.raw_binned_lstick(),
|
||||
InputDisplay::STATUS => (DirectionStrength::None, 0.0),
|
||||
InputDisplay::NONE => panic!("Invalid input display to log"),
|
||||
_ => panic!("Invalid value in binned_lstick: {}", MENU.input_display),
|
||||
}
|
||||
match get(&MENU).input_display {
|
||||
InputDisplay::SMASH => self.smash_binned_lstick(),
|
||||
InputDisplay::RAW => self.raw_binned_lstick(),
|
||||
InputDisplay::STATUS => (DirectionStrength::None, 0.0),
|
||||
InputDisplay::NONE => panic!("Invalid input display to log"),
|
||||
_ => panic!(
|
||||
"Invalid value in binned_lstick: {}",
|
||||
get(&MENU).input_display
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn binned_rstick(&self) -> (DirectionStrength, f32) {
|
||||
unsafe {
|
||||
match MENU.input_display {
|
||||
InputDisplay::SMASH => self.smash_binned_rstick(),
|
||||
InputDisplay::RAW => self.raw_binned_rstick(),
|
||||
InputDisplay::STATUS => (DirectionStrength::None, 0.0),
|
||||
InputDisplay::NONE => panic!("Invalid input display to log"),
|
||||
_ => panic!("Invalid value in binned_rstick: {}", MENU.input_display),
|
||||
}
|
||||
match get(&MENU).input_display {
|
||||
InputDisplay::SMASH => self.smash_binned_rstick(),
|
||||
InputDisplay::RAW => self.raw_binned_rstick(),
|
||||
InputDisplay::STATUS => (DirectionStrength::None, 0.0),
|
||||
InputDisplay::NONE => panic!("Invalid input display to log"),
|
||||
_ => panic!(
|
||||
"Invalid value in binned_rstick: {}",
|
||||
get(&MENU).input_display
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn button_icons(&self) -> VecDeque<(&str, ResColor)> {
|
||||
unsafe {
|
||||
match MENU.input_display {
|
||||
InputDisplay::SMASH => self.smash_button_icons(),
|
||||
InputDisplay::RAW => self.raw_button_icons(),
|
||||
InputDisplay::STATUS => VecDeque::new(),
|
||||
InputDisplay::NONE => panic!("Invalid input display to log"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
match get(&MENU).input_display {
|
||||
InputDisplay::SMASH => self.smash_button_icons(),
|
||||
InputDisplay::RAW => self.raw_button_icons(),
|
||||
InputDisplay::STATUS => VecDeque::new(),
|
||||
InputDisplay::NONE => panic!("Invalid input display to log"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,14 +261,12 @@ impl InputLog {
|
|||
self.smash_inputs.buttons != other.smash_inputs.buttons
|
||||
|| self.smash_binned_lstick() != other.smash_binned_lstick()
|
||||
|| self.smash_binned_rstick() != other.smash_binned_rstick()
|
||||
|| (unsafe { MENU.input_display_status.as_bool() } && self.status != other.status)
|
||||
|| (get(&MENU).input_display_status.as_bool() && self.status != other.status)
|
||||
}
|
||||
|
||||
fn is_status_different(&self, other: &InputLog) -> bool {
|
||||
unsafe {
|
||||
let input_display_status = MENU.input_display_status.as_bool();
|
||||
input_display_status && (self.status != other.status)
|
||||
}
|
||||
let input_display_status = get(&MENU).input_display_status.as_bool();
|
||||
input_display_status && (self.status != other.status)
|
||||
}
|
||||
|
||||
fn smash_binned_lstick(&self) -> (DirectionStrength, f32) {
|
||||
|
@ -282,7 +281,7 @@ impl InputLog {
|
|||
self.raw_inputs.current_buttons != other.raw_inputs.current_buttons
|
||||
|| self.raw_binned_lstick() != other.raw_binned_lstick()
|
||||
|| self.raw_binned_rstick() != other.raw_binned_rstick()
|
||||
|| (unsafe { MENU.input_display_status.as_bool() } && self.status != other.status)
|
||||
|| (get(&MENU).input_display_status.as_bool() && self.status != other.status)
|
||||
}
|
||||
|
||||
fn raw_binned_lstick(&self) -> (DirectionStrength, f32) {
|
||||
|
@ -316,7 +315,7 @@ pub fn handle_final_input_mapping(
|
|||
out: *mut MappedInputs,
|
||||
) {
|
||||
unsafe {
|
||||
if MENU.input_display == InputDisplay::NONE {
|
||||
if get(&MENU).input_display == InputDisplay::NONE {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ use crate::training::mash;
|
|||
use crate::training::ui::notifications::{clear_notifications_except, color_notification};
|
||||
use crate::{error, warn};
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum InputRecordState {
|
||||
None,
|
||||
|
@ -104,17 +106,18 @@ unsafe fn should_mash_playback() {
|
|||
|
||||
if is_in_hitstun(&mut *cpu_module_accessor) {
|
||||
// if we're in hitstun and want to enter the frame we start hitstop for SDI, start if we're in any damage status instantly
|
||||
if MENU.hitstun_playback == HitstunPlayback::INSTANT {
|
||||
if get(&MENU).hitstun_playback == HitstunPlayback::INSTANT {
|
||||
should_playback = true;
|
||||
}
|
||||
// if we want to wait until we exit hitstop and begin flying away for shield art etc, start if we're not in hitstop
|
||||
if MENU.hitstun_playback == HitstunPlayback::HITSTOP
|
||||
if get(&MENU).hitstun_playback == HitstunPlayback::HITSTOP
|
||||
&& !StopModule::is_stop(cpu_module_accessor)
|
||||
{
|
||||
should_playback = true;
|
||||
}
|
||||
// if we're in hitstun and want to wait till FAF to act, then we want to match our starting status to the correct transition term to see if we can hitstun cancel
|
||||
if MENU.hitstun_playback == HitstunPlayback::HITSTUN && can_transition(cpu_module_accessor)
|
||||
if get(&MENU).hitstun_playback == HitstunPlayback::HITSTUN
|
||||
&& can_transition(cpu_module_accessor)
|
||||
{
|
||||
should_playback = true;
|
||||
}
|
||||
|
@ -193,12 +196,12 @@ unsafe fn handle_recording_for_fighter(module_accessor: &mut BattleObjectModuleA
|
|||
let fighter_kind = utility::get_kind(module_accessor);
|
||||
let fighter_is_nana = fighter_kind == *FIGHTER_KIND_NANA;
|
||||
|
||||
CURRENT_RECORD_SLOT = MENU.recording_slot.into_idx().unwrap_or(0);
|
||||
CURRENT_RECORD_SLOT = get(&MENU).recording_slot.into_idx().unwrap_or(0);
|
||||
|
||||
if entry_id_int == 0 && !fighter_is_nana {
|
||||
if button_config::combo_passes(button_config::ButtonCombo::InputPlayback) {
|
||||
playback(MENU.playback_button_slots.get_random().into_idx());
|
||||
} else if MENU.record_trigger.contains(&RecordTrigger::COMMAND)
|
||||
playback(get(&MENU).playback_button_slots.get_random().into_idx());
|
||||
} else if get(&MENU).record_trigger.contains(&RecordTrigger::COMMAND)
|
||||
&& button_config::combo_passes(button_config::ButtonCombo::InputRecord)
|
||||
{
|
||||
lockout_record();
|
||||
|
@ -217,7 +220,9 @@ unsafe fn handle_recording_for_fighter(module_accessor: &mut BattleObjectModuleA
|
|||
|
||||
// If we need to crop the recording for neutral input
|
||||
// INPUT_RECORD_FRAME must be > 0 to prevent bounding errors
|
||||
if INPUT_RECORD == Record && MENU.recording_crop == OnOff::ON && INPUT_RECORD_FRAME > 0
|
||||
if INPUT_RECORD == Record
|
||||
&& get(&MENU).recording_crop == OnOff::ON
|
||||
&& INPUT_RECORD_FRAME > 0
|
||||
{
|
||||
while INPUT_RECORD_FRAME > 0 && is_input_neutral(INPUT_RECORD_FRAME - 1) {
|
||||
// Discard frames at the end of the recording until the last frame with input
|
||||
|
@ -229,7 +234,7 @@ unsafe fn handle_recording_for_fighter(module_accessor: &mut BattleObjectModuleA
|
|||
|
||||
INPUT_RECORD_FRAME = 0;
|
||||
|
||||
if MENU.playback_loop == OnOff::ON && INPUT_RECORD == Playback {
|
||||
if get(&MENU).playback_loop == OnOff::ON && INPUT_RECORD == Playback {
|
||||
playback(Some(CURRENT_PLAYBACK_SLOT));
|
||||
} else {
|
||||
INPUT_RECORD = None;
|
||||
|
@ -327,7 +332,7 @@ pub unsafe fn lockout_record() {
|
|||
.for_each(|mapped_input| {
|
||||
*mapped_input = MappedInputs::empty();
|
||||
});
|
||||
CURRENT_FRAME_LENGTH = MENU.recording_duration.into_frames();
|
||||
CURRENT_FRAME_LENGTH = get(&MENU).recording_duration.into_frames();
|
||||
P1_FRAME_LENGTH_MAPPING.lock()[CURRENT_RECORD_SLOT] = CURRENT_FRAME_LENGTH;
|
||||
LOCKOUT_FRAME = 30; // This needs to be this high or issues occur dropping shield - but does this cause problems when trying to record ledge?
|
||||
BUFFER_FRAME = 0;
|
||||
|
|
|
@ -3,9 +3,10 @@ use smash::lib::lua_const::*;
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::{frame_counter, input_record, mash};
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
const NOT_SET: u32 = 9001;
|
||||
static LEDGE_DELAY: RwLock<u32> = RwLock::new(NOT_SET);
|
||||
static LEDGE_CASE: RwLock<LedgeOption> = RwLock::new(LedgeOption::empty());
|
||||
|
@ -35,10 +36,7 @@ fn roll_ledge_delay() {
|
|||
// Don't roll another ledge delay if one is already selected
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
*ledge_delay_guard = MENU.ledge_delay.get_random().into_longdelay();
|
||||
}
|
||||
*ledge_delay_guard = get(&MENU).ledge_delay.get_random().into_longdelay();
|
||||
}
|
||||
|
||||
fn roll_ledge_case() {
|
||||
|
@ -48,48 +46,43 @@ fn roll_ledge_case() {
|
|||
if *ledge_case_guard != LedgeOption::empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
*ledge_case_guard = MENU.ledge_state.get_random();
|
||||
}
|
||||
*ledge_case_guard = get(&MENU).ledge_state.get_random();
|
||||
}
|
||||
|
||||
fn get_ledge_option() -> Option<Action> {
|
||||
unsafe {
|
||||
let mut override_action: Option<Action> = None;
|
||||
let regular_action = if MENU.mash_triggers.contains(&MashTrigger::LEDGE) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let mut override_action: Option<Action> = None;
|
||||
let regular_action = if get(&MENU).mash_triggers.contains(&MashTrigger::LEDGE) {
|
||||
Some(get(&MENU).mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
match read_rwlock(&LEDGE_CASE) {
|
||||
LedgeOption::NEUTRAL => {
|
||||
if MENU.ledge_neutral_override != Action::empty() {
|
||||
override_action = Some(MENU.ledge_neutral_override.get_random());
|
||||
}
|
||||
}
|
||||
LedgeOption::ROLL => {
|
||||
if MENU.ledge_roll_override != Action::empty() {
|
||||
override_action = Some(MENU.ledge_roll_override.get_random());
|
||||
}
|
||||
}
|
||||
LedgeOption::JUMP => {
|
||||
if MENU.ledge_jump_override != Action::empty() {
|
||||
override_action = Some(MENU.ledge_jump_override.get_random());
|
||||
}
|
||||
}
|
||||
LedgeOption::ATTACK => {
|
||||
if MENU.ledge_attack_override != Action::empty() {
|
||||
override_action = Some(MENU.ledge_attack_override.get_random());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
override_action = None;
|
||||
match read_rwlock(&LEDGE_CASE) {
|
||||
LedgeOption::NEUTRAL => {
|
||||
if get(&MENU).ledge_neutral_override != Action::empty() {
|
||||
override_action = Some(get(&MENU).ledge_neutral_override.get_random());
|
||||
}
|
||||
}
|
||||
override_action.or(regular_action)
|
||||
LedgeOption::ROLL => {
|
||||
if get(&MENU).ledge_roll_override != Action::empty() {
|
||||
override_action = Some(get(&MENU).ledge_roll_override.get_random());
|
||||
}
|
||||
}
|
||||
LedgeOption::JUMP => {
|
||||
if get(&MENU).ledge_jump_override != Action::empty() {
|
||||
override_action = Some(get(&MENU).ledge_jump_override.get_random());
|
||||
}
|
||||
}
|
||||
LedgeOption::ATTACK => {
|
||||
if get(&MENU).ledge_attack_override != Action::empty() {
|
||||
override_action = Some(get(&MENU).ledge_attack_override.get_random());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
override_action = None;
|
||||
}
|
||||
}
|
||||
override_action.or(regular_action)
|
||||
}
|
||||
|
||||
pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
|
@ -137,7 +130,7 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor
|
|||
// 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.is_playback()
|
||||
&& MENU.ledge_delay != LongDelay::empty()
|
||||
&& get(&MENU).ledge_delay != LongDelay::empty()
|
||||
{
|
||||
input_record::playback_ledge(ledge_case.playback_slot());
|
||||
return;
|
||||
|
@ -180,7 +173,7 @@ pub unsafe fn is_enable_transition_term(
|
|||
|
||||
// Only handle ledge scenarios from menu
|
||||
if StatusModule::status_kind(_module_accessor) != *FIGHTER_STATUS_KIND_CLIFF_WAIT
|
||||
|| MENU.ledge_state == LedgeOption::empty()
|
||||
|| get(&MENU).ledge_state == LedgeOption::empty()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
@ -210,7 +203,7 @@ pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccesso
|
|||
return;
|
||||
}
|
||||
|
||||
if MENU.ledge_state == LedgeOption::empty() {
|
||||
if get(&MENU).ledge_state == LedgeOption::empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ use crate::training::input_record;
|
|||
use crate::training::shield;
|
||||
use crate::training::{attack_angle, save_states};
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
const DISTANCE_CLOSE_THRESHOLD: f32 = 16.0;
|
||||
|
@ -80,7 +82,7 @@ pub fn buffer_action(action: Action) {
|
|||
unsafe {
|
||||
// exit playback if we want to perform mash actions out of it
|
||||
// TODO: Figure out some way to deal with trying to playback into another playback
|
||||
if MENU.playback_mash == OnOff::ON
|
||||
if get(&MENU).playback_mash == OnOff::ON
|
||||
&& input_record::is_playback()
|
||||
&& !input_record::is_recording()
|
||||
&& !input_record::is_standby()
|
||||
|
@ -108,9 +110,7 @@ pub fn buffer_action(action: Action) {
|
|||
pub fn buffer_follow_up() {
|
||||
let action;
|
||||
|
||||
unsafe {
|
||||
action = MENU.follow_up.get_random();
|
||||
}
|
||||
action = get(&MENU).follow_up.get_random();
|
||||
|
||||
if action == Action::empty() {
|
||||
return;
|
||||
|
@ -216,91 +216,100 @@ unsafe fn get_buffered_action(
|
|||
return None;
|
||||
}
|
||||
let fighter_distance = get_fighter_distance();
|
||||
let menu = get(&MENU);
|
||||
if is_in_tech(module_accessor) {
|
||||
let action = MENU.tech_action_override.get_random();
|
||||
let action = menu.tech_action_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(&MashTrigger::TECH) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else if menu.mash_triggers.contains(&MashTrigger::TECH) {
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_clatter(module_accessor) {
|
||||
let action = MENU.clatter_override.get_random();
|
||||
let action = menu.clatter_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(&MashTrigger::CLATTER) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else if menu.mash_triggers.contains(&MashTrigger::CLATTER) {
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_tumble(module_accessor) {
|
||||
// Note that the tumble check needs to come before hitstun,
|
||||
// otherwise the hitstun check will always return first
|
||||
let action = MENU.tumble_override.get_random();
|
||||
let action = menu.tumble_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(&MashTrigger::TUMBLE) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else if menu.mash_triggers.contains(&MashTrigger::TUMBLE) {
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_hitstun(module_accessor) {
|
||||
let action = MENU.hitstun_override.get_random();
|
||||
let action = menu.hitstun_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(&MashTrigger::HIT) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else if menu.mash_triggers.contains(&MashTrigger::HIT) {
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_parry(module_accessor) {
|
||||
let action = MENU.parry_override.get_random();
|
||||
let action = menu.parry_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(&MashTrigger::PARRY) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else if menu.mash_triggers.contains(&MashTrigger::PARRY) {
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_footstool(module_accessor) {
|
||||
let action = MENU.footstool_override.get_random();
|
||||
let action = menu.footstool_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(&MashTrigger::FOOTSTOOL) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else if menu.mash_triggers.contains(&MashTrigger::FOOTSTOOL) {
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_ledgetrump(module_accessor) {
|
||||
let action = MENU.trump_override.get_random();
|
||||
let action = menu.trump_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(&MashTrigger::TRUMP) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else if menu.mash_triggers.contains(&MashTrigger::TRUMP) {
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_landing(module_accessor) {
|
||||
let action = MENU.landing_override.get_random();
|
||||
let action = menu.landing_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(&MashTrigger::LANDING) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else if menu.mash_triggers.contains(&MashTrigger::LANDING) {
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if (MENU.mash_triggers.contains(&MashTrigger::GROUNDED) && is_grounded(module_accessor))
|
||||
|| (MENU.mash_triggers.contains(&MashTrigger::AIRBORNE) && is_airborne(module_accessor))
|
||||
|| (MENU.mash_triggers.contains(&MashTrigger::DISTANCE_CLOSE)
|
||||
} else if (menu.mash_triggers.contains(&MashTrigger::GROUNDED)
|
||||
&& is_grounded(module_accessor))
|
||||
|| (menu.mash_triggers.contains(&MashTrigger::AIRBORNE)
|
||||
&& is_airborne(module_accessor))
|
||||
|| (menu
|
||||
.mash_triggers
|
||||
.contains(&MashTrigger::DISTANCE_CLOSE)
|
||||
&& fighter_distance < DISTANCE_CLOSE_THRESHOLD)
|
||||
|| (MENU.mash_triggers.contains(&MashTrigger::DISTANCE_MID)
|
||||
|| (menu
|
||||
.mash_triggers
|
||||
.contains(&MashTrigger::DISTANCE_MID)
|
||||
&& fighter_distance < DISTANCE_MID_THRESHOLD)
|
||||
|| (MENU.mash_triggers.contains(&MashTrigger::DISTANCE_FAR)
|
||||
|| (menu
|
||||
.mash_triggers
|
||||
.contains(&MashTrigger::DISTANCE_FAR)
|
||||
&& fighter_distance < DISTANCE_FAR_THRESHOLD)
|
||||
|| MENU.mash_triggers.contains(&MashTrigger::ALWAYS)
|
||||
|| menu.mash_triggers.contains(&MashTrigger::ALWAYS)
|
||||
{
|
||||
Some(MENU.mash_state.get_random())
|
||||
Some(menu.mash_state.get_random())
|
||||
} else {
|
||||
// SHIELD handled in shield.rs
|
||||
// LEDGE handled in ledge.rs
|
||||
|
@ -313,7 +322,7 @@ fn buffer_menu_mash(action: Action) {
|
|||
buffer_action(action);
|
||||
full_hop::roll_full_hop();
|
||||
fast_fall::roll_fast_fall();
|
||||
FALLING_AERIAL = MENU.falling_aerials.get_random().into_bool();
|
||||
FALLING_AERIAL = get(&MENU).falling_aerials.get_random().into_bool();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,7 +586,7 @@ fn roll_aerial_delay(action: Action) {
|
|||
return;
|
||||
}
|
||||
unsafe {
|
||||
AERIAL_DELAY = MENU.aerial_delay.get_random().into_delay();
|
||||
AERIAL_DELAY = get(&MENU).aerial_delay.get_random().into_delay();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ use crate::common::{
|
|||
use crate::hitbox_visualizer;
|
||||
use crate::input::*;
|
||||
use crate::logging::*;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::character_specific::{items, kirby, pikmin, ptrainer};
|
||||
use skyline::hooks::{getRegionAddress, InlineCtx, Region};
|
||||
use skyline::nn::ro::LookupSymbol;
|
||||
|
@ -20,6 +19,7 @@ use smash::app::{
|
|||
use smash::lib::lua_const::*;
|
||||
use smash::params::*;
|
||||
use smash::phx::{Hash40, Vector3f};
|
||||
use training_mod_sync::*;
|
||||
|
||||
pub mod buff;
|
||||
pub mod charge;
|
||||
|
@ -134,7 +134,7 @@ fn once_per_frame_per_fighter(module_accessor: &mut BattleObjectModuleAccessor,
|
|||
// Handle dodge staling here b/c input recording or mash can cause dodging
|
||||
WorkModule::set_flag(
|
||||
module_accessor,
|
||||
!(MENU.stale_dodges.as_bool()),
|
||||
!(get(&MENU).stale_dodges.as_bool()),
|
||||
*FIGHTER_INSTANCE_WORK_ID_FLAG_DISABLE_ESCAPE_PENALTY,
|
||||
);
|
||||
input_record::handle_recording();
|
||||
|
@ -428,7 +428,7 @@ pub unsafe fn handle_add_damage(
|
|||
#[skyline::hook(offset = *OFFSET_TRAINING_RESET_CHECK, inline)]
|
||||
unsafe fn lra_handle(ctx: &mut InlineCtx) {
|
||||
let x8 = ctx.registers[8].x.as_mut();
|
||||
if !(MENU.lra_reset.as_bool()) {
|
||||
if !(get(&MENU).lra_reset.as_bool()) {
|
||||
*x8 = 0;
|
||||
}
|
||||
}
|
||||
|
@ -766,7 +766,7 @@ pub unsafe fn handle_reused_ui(
|
|||
// If Little Mac is in the game and we're buffing him, set the meter to 100
|
||||
if (player_fighter_kind == *FIGHTER_KIND_LITTLEMAC
|
||||
|| cpu_fighter_kind == *FIGHTER_KIND_LITTLEMAC)
|
||||
&& MENU.buff_state.contains(&BuffOption::KO)
|
||||
&& get(&MENU).buff_state.contains(&BuffOption::KO)
|
||||
{
|
||||
param_2 = 100;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ use crate::common::get_module_accessor;
|
|||
use crate::common::is_dead;
|
||||
use crate::common::MENU;
|
||||
use crate::is_operation_cpu;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::buff;
|
||||
use crate::training::character_specific::{ptrainer, steve};
|
||||
use crate::training::charge::{self, ChargeState};
|
||||
|
@ -36,6 +35,7 @@ use crate::training::items::apply_item;
|
|||
use crate::training::reset;
|
||||
use crate::training::ui::notifications;
|
||||
use crate::{is_ptrainer, ITEM_MANAGER_ADDR};
|
||||
use training_mod_sync::*;
|
||||
|
||||
// Don't remove Mii hats, Pikmin, Luma, or crafting table
|
||||
const ARTICLE_ALLOWLIST: [(LuaConst, LuaConst); 9] = [
|
||||
|
@ -233,11 +233,11 @@ static mut MIRROR_STATE: f32 = 1.0;
|
|||
static mut RANDOM_SLOT: usize = 0;
|
||||
|
||||
unsafe fn get_slot() -> usize {
|
||||
let random_slot = MENU.randomize_slots.get_random();
|
||||
let random_slot = get(&MENU).randomize_slots.get_random();
|
||||
if random_slot != SaveStateSlot::empty() {
|
||||
RANDOM_SLOT
|
||||
} else {
|
||||
MENU.save_state_slot.into_idx().unwrap_or(0)
|
||||
get(&MENU).save_state_slot.into_idx().unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,13 +256,13 @@ pub unsafe fn is_loading() -> bool {
|
|||
}
|
||||
|
||||
pub unsafe fn should_mirror() -> f32 {
|
||||
match MENU.save_state_mirroring {
|
||||
match get(&MENU).save_state_mirroring {
|
||||
SaveStateMirroring::NONE => 1.0,
|
||||
SaveStateMirroring::ALTERNATE => -1.0 * MIRROR_STATE,
|
||||
SaveStateMirroring::RANDOM => ([-1.0, 1.0])[get_random_int(2) as usize],
|
||||
_ => panic!(
|
||||
"Invalid value in should_mirror: {}",
|
||||
MENU.save_state_mirroring
|
||||
get(&MENU).save_state_mirroring
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ pub unsafe fn on_death(fighter_kind: i32, module_accessor: &mut app::BattleObjec
|
|||
}
|
||||
|
||||
pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
if MENU.save_state_enable == OnOff::OFF {
|
||||
if get(&MENU).save_state_enable == OnOff::OFF {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -449,7 +449,7 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
.contains(&fighter_kind);
|
||||
|
||||
// Reset state
|
||||
let autoload_reset = MENU.save_state_autoload == OnOff::ON
|
||||
let autoload_reset = get(&MENU).save_state_autoload == OnOff::ON
|
||||
&& save_state.state == NoAction
|
||||
&& is_dead(module_accessor);
|
||||
let mut triggered_reset: bool = false;
|
||||
|
@ -458,7 +458,7 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
}
|
||||
if (autoload_reset || triggered_reset) && !fighter_is_nana {
|
||||
if save_state.state == NoAction {
|
||||
let random_slot = MENU.randomize_slots.get_random();
|
||||
let random_slot = get(&MENU).randomize_slots.get_random();
|
||||
let slot = if random_slot != SaveStateSlot::empty() {
|
||||
RANDOM_SLOT = random_slot.into_idx().unwrap_or(0);
|
||||
RANDOM_SLOT
|
||||
|
@ -573,48 +573,48 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
if save_state.state == NoAction {
|
||||
// Set damage of the save state
|
||||
if !is_cpu {
|
||||
match MENU.save_damage_player {
|
||||
match get(&MENU).save_damage_player {
|
||||
SaveDamage::SAVED => {
|
||||
set_damage(module_accessor, save_state.percent);
|
||||
}
|
||||
SaveDamage::RANDOM => {
|
||||
// Gen random value
|
||||
let pct: f32 = get_random_float(
|
||||
MENU.save_damage_limits_player.0 as f32,
|
||||
MENU.save_damage_limits_player.1 as f32,
|
||||
get(&MENU).save_damage_limits_player.0 as f32,
|
||||
get(&MENU).save_damage_limits_player.1 as f32,
|
||||
);
|
||||
set_damage(module_accessor, pct);
|
||||
}
|
||||
SaveDamage::DEFAULT => {}
|
||||
_ => panic!(
|
||||
"Invalid value in save_states()::save_damage_player: {}",
|
||||
MENU.save_damage_player
|
||||
get(&MENU).save_damage_player
|
||||
),
|
||||
}
|
||||
} else {
|
||||
match MENU.save_damage_cpu {
|
||||
match get(&MENU).save_damage_cpu {
|
||||
SaveDamage::SAVED => {
|
||||
set_damage(module_accessor, save_state.percent);
|
||||
}
|
||||
SaveDamage::RANDOM => {
|
||||
// Gen random value
|
||||
let pct: f32 = get_random_float(
|
||||
MENU.save_damage_limits_cpu.0 as f32,
|
||||
MENU.save_damage_limits_cpu.1 as f32,
|
||||
get(&MENU).save_damage_limits_cpu.0 as f32,
|
||||
get(&MENU).save_damage_limits_cpu.1 as f32,
|
||||
);
|
||||
set_damage(module_accessor, pct);
|
||||
}
|
||||
SaveDamage::DEFAULT => {}
|
||||
_ => panic!(
|
||||
"Invalid value in save_states()::save_damage_cpu: {}",
|
||||
MENU.save_damage_cpu
|
||||
get(&MENU).save_damage_cpu
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// Set to held item
|
||||
if !is_cpu && !fighter_is_nana && MENU.character_item != CharacterItem::NONE {
|
||||
apply_item(MENU.character_item);
|
||||
if !is_cpu && !fighter_is_nana && get(&MENU).character_item != CharacterItem::NONE {
|
||||
apply_item(get(&MENU).character_item);
|
||||
}
|
||||
|
||||
// Set the charge of special moves if the fighter matches the kind in the save state
|
||||
|
@ -662,17 +662,20 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
}
|
||||
|
||||
// if we're recording on state load, record
|
||||
if MENU.record_trigger.contains(&RecordTrigger::SAVESTATE) {
|
||||
if get(&MENU)
|
||||
.record_trigger
|
||||
.contains(&RecordTrigger::SAVESTATE)
|
||||
{
|
||||
input_record::lockout_record();
|
||||
return;
|
||||
}
|
||||
// otherwise, begin input recording playback if selected
|
||||
// for ledge, don't do this - if you want playback on a ledge, you have to set it as a ledge option,
|
||||
// otherwise there too many edge cases here
|
||||
else if MENU.save_state_playback.get_random() != PlaybackSlot::empty()
|
||||
else if get(&MENU).save_state_playback.get_random() != PlaybackSlot::empty()
|
||||
&& save_state.situation_kind != SITUATION_KIND_CLIFF
|
||||
{
|
||||
input_record::playback(MENU.save_state_playback.get_random().into_idx());
|
||||
input_record::playback(get(&MENU).save_state_playback.get_random().into_idx());
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -707,12 +710,12 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
if button_config::combo_passes(button_config::ButtonCombo::SaveState) {
|
||||
// Don't begin saving state if Nana's delayed input is captured
|
||||
MIRROR_STATE = 1.0;
|
||||
save_state_player(MENU.save_state_slot.into_idx().unwrap_or(0)).state = Save;
|
||||
save_state_cpu(MENU.save_state_slot.into_idx().unwrap_or(0)).state = Save;
|
||||
save_state_player(get(&MENU).save_state_slot.into_idx().unwrap_or(0)).state = Save;
|
||||
save_state_cpu(get(&MENU).save_state_slot.into_idx().unwrap_or(0)).state = Save;
|
||||
notifications::clear_notifications_except("Save State");
|
||||
notifications::notification(
|
||||
"Save State".to_string(),
|
||||
format!("Saved Slot {}", MENU.save_state_slot),
|
||||
format!("Saved Slot {}", get(&MENU).save_state_slot),
|
||||
120,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ use smash::Vector2f;
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::directional_influence;
|
||||
use training_mod_sync::*;
|
||||
|
||||
static COUNTER: RwLock<u32> = RwLock::new(0);
|
||||
static DIRECTION: RwLock<Direction> = RwLock::new(Direction::NEUTRAL);
|
||||
|
@ -14,9 +14,7 @@ static DIRECTION: RwLock<Direction> = RwLock::new(Direction::NEUTRAL);
|
|||
// TODO! Bug - we only roll a new direction when loading a save state or on LRA reset
|
||||
pub fn roll_direction() {
|
||||
assign_rwlock(&COUNTER, 0);
|
||||
unsafe {
|
||||
assign_rwlock(&DIRECTION, MENU.sdi_state.get_random());
|
||||
}
|
||||
assign_rwlock(&DIRECTION, get(&MENU).sdi_state.get_random());
|
||||
}
|
||||
|
||||
unsafe fn get_sdi_direction() -> Option<f64> {
|
||||
|
@ -40,7 +38,7 @@ pub unsafe fn check_hit_stop_delay_command(
|
|||
if !is_training_mode() || !is_operation_cpu(module_accessor) {
|
||||
return original!()(module_accessor, sdi_direction);
|
||||
}
|
||||
let repeat = MENU.sdi_strength.into_u32();
|
||||
let repeat = get(&MENU).sdi_strength.into_u32();
|
||||
let mut counter_guard = lock_write_rwlock(&COUNTER);
|
||||
*counter_guard = (*counter_guard + 1) % repeat;
|
||||
if *counter_guard == repeat - 1 {
|
||||
|
|
|
@ -8,9 +8,10 @@ use smash::lua2cpp::L2CFighterCommon;
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::{frame_counter, input_record, mash, save_states};
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
// TODO!() We only reset this on save state load or LRA reset
|
||||
// How many hits to hold shield until picking an Out Of Shield option
|
||||
static MULTI_HIT_OFFSET: RwLock<u32> = RwLock::new(0);
|
||||
|
@ -43,16 +44,14 @@ fn should_pause_shield_decay() -> bool {
|
|||
}
|
||||
|
||||
fn reset_oos_offset() {
|
||||
unsafe {
|
||||
/*
|
||||
* Need to offset by 1, since we decrease as soon as shield gets hit
|
||||
* but only check later if we can OOS
|
||||
*/
|
||||
assign_rwlock(
|
||||
&MULTI_HIT_OFFSET,
|
||||
MENU.oos_offset.get_random().into_delay() + 1,
|
||||
);
|
||||
}
|
||||
/*
|
||||
* Need to offset by 1, since we decrease as soon as shield gets hit
|
||||
* but only check later if we can OOS
|
||||
*/
|
||||
assign_rwlock(
|
||||
&MULTI_HIT_OFFSET,
|
||||
get(&MENU).oos_offset.get_random().into_delay() + 1,
|
||||
);
|
||||
}
|
||||
|
||||
fn handle_oos_offset(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
|
@ -70,9 +69,10 @@ fn handle_oos_offset(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
|||
}
|
||||
|
||||
// Roll shield delay
|
||||
unsafe {
|
||||
assign_rwlock(&SHIELD_DELAY, MENU.reaction_time.get_random().into_delay());
|
||||
}
|
||||
assign_rwlock(
|
||||
&SHIELD_DELAY,
|
||||
get(&MENU).reaction_time.get_random().into_delay(),
|
||||
);
|
||||
|
||||
// Decrease offset once if needed
|
||||
let mut multi_hit_offset_guard = lock_write_rwlock(&MULTI_HIT_OFFSET);
|
||||
|
@ -116,7 +116,7 @@ pub unsafe fn get_param_float(
|
|||
return None;
|
||||
}
|
||||
|
||||
if MENU.shield_state != Shield::NONE {
|
||||
if get(&MENU).shield_state != Shield::NONE {
|
||||
handle_oos_offset(module_accessor);
|
||||
}
|
||||
|
||||
|
@ -125,10 +125,7 @@ pub unsafe fn get_param_float(
|
|||
|
||||
// Shield Decay//Recovery
|
||||
fn handle_shield_decay(param_type: u64, param_hash: u64) -> Option<f32> {
|
||||
let menu_state;
|
||||
unsafe {
|
||||
menu_state = MENU.shield_state;
|
||||
}
|
||||
let menu_state = get(&MENU).shield_state;
|
||||
|
||||
if menu_state != Shield::INFINITE
|
||||
&& menu_state != Shield::CONSTANT
|
||||
|
@ -166,7 +163,7 @@ pub unsafe fn param_installer() {
|
|||
*cached_shield_damage_mul_guard = Some(common_params.shield_damage_mul);
|
||||
}
|
||||
|
||||
if is_training_mode() && (MENU.shield_state == Shield::INFINITE) {
|
||||
if is_training_mode() && (get(&MENU).shield_state == Shield::INFINITE) {
|
||||
// if you are in training mode and have infinite shield enabled,
|
||||
// set the game's shield_damage_mul to 0.0
|
||||
common_params.shield_damage_mul = 0.0;
|
||||
|
@ -190,10 +187,7 @@ pub fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
return true;
|
||||
}
|
||||
|
||||
let shield_state;
|
||||
unsafe {
|
||||
shield_state = &MENU.shield_state;
|
||||
}
|
||||
let shield_state = &get(&MENU).shield_state;
|
||||
|
||||
// We should hold shield if the state requires it
|
||||
if unsafe { save_states::is_loading() }
|
||||
|
@ -228,7 +222,7 @@ unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) {
|
|||
}
|
||||
|
||||
// Enable shield decay
|
||||
if MENU.shield_state == Shield::HOLD {
|
||||
if get(&MENU).shield_state == Shield::HOLD {
|
||||
set_shield_decay(true);
|
||||
}
|
||||
|
||||
|
@ -250,11 +244,11 @@ unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) {
|
|||
return;
|
||||
}
|
||||
|
||||
if MENU.mash_triggers.contains(&MashTrigger::SHIELDSTUN) {
|
||||
if MENU.shieldstun_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
if get(&MENU).mash_triggers.contains(&MashTrigger::SHIELDSTUN) {
|
||||
if get(&MENU).shieldstun_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(get(&MENU).mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.shieldstun_override.get_random())
|
||||
mash::external_buffer_menu_mash(get(&MENU).shieldstun_override.get_random())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,10 +354,7 @@ fn needs_oos_handling_drop_shield() -> bool {
|
|||
}
|
||||
// Make sure we only flicker shield when Airdodge and Shield mash options are selected
|
||||
if action == Action::AIR_DODGE {
|
||||
let shield_state;
|
||||
unsafe {
|
||||
shield_state = &MENU.shield_state;
|
||||
}
|
||||
let shield_state = &get(&MENU).shield_state;
|
||||
// If we're supposed to be holding shield, let airdodge make us drop shield
|
||||
if [Shield::HOLD, Shield::INFINITE, Shield::CONSTANT].contains(shield_state) {
|
||||
suspend_shield(Action::AIR_DODGE);
|
||||
|
@ -373,10 +364,7 @@ fn needs_oos_handling_drop_shield() -> bool {
|
|||
|
||||
// Make sure we only flicker shield when Airdodge and Shield mash options are selected
|
||||
if action == Action::AIR_DODGE {
|
||||
let shield_state;
|
||||
unsafe {
|
||||
shield_state = &MENU.shield_state;
|
||||
}
|
||||
let shield_state = &get(&MENU).shield_state;
|
||||
// If we're supposed to be holding shield, let airdodge make us drop shield
|
||||
if [Shield::HOLD, Shield::INFINITE, Shield::CONSTANT].contains(shield_state) {
|
||||
suspend_shield(Action::AIR_DODGE);
|
||||
|
@ -385,10 +373,7 @@ fn needs_oos_handling_drop_shield() -> bool {
|
|||
}
|
||||
|
||||
if action == Action::SHIELD {
|
||||
let shield_state;
|
||||
unsafe {
|
||||
shield_state = &MENU.shield_state;
|
||||
}
|
||||
let shield_state = &get(&MENU).shield_state;
|
||||
// Don't drop shield on shield hit if we're supposed to be holding shield
|
||||
if [Shield::HOLD, Shield::INFINITE, Shield::CONSTANT].contains(shield_state) {
|
||||
return false;
|
||||
|
|
|
@ -7,24 +7,18 @@ use training_mod_sync::*;
|
|||
static SHIELD_STICK_DIRECTION: RwLock<Direction> = RwLock::new(Direction::OUT);
|
||||
|
||||
pub fn roll_direction() {
|
||||
unsafe {
|
||||
assign_rwlock(&SHIELD_STICK_DIRECTION, MENU.shield_tilt.get_random());
|
||||
}
|
||||
assign_rwlock(&SHIELD_STICK_DIRECTION, get(&MENU).shield_tilt.get_random());
|
||||
}
|
||||
|
||||
pub unsafe fn mod_get_stick_x(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) -> Option<f32> {
|
||||
pub fn mod_get_stick_x(module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<f32> {
|
||||
get_angle(module_accessor).map(|a| a.cos() as f32)
|
||||
}
|
||||
|
||||
pub unsafe fn mod_get_stick_y(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) -> Option<f32> {
|
||||
pub fn mod_get_stick_y(module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<f32> {
|
||||
get_angle(module_accessor).map(|a| a.sin() as f32)
|
||||
}
|
||||
|
||||
unsafe fn get_angle(module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<f64> {
|
||||
fn get_angle(module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<f64> {
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ use crate::common::offsets::{
|
|||
OFFSET_CHANGE_ACTIVE_CAMERA, OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES,
|
||||
};
|
||||
use crate::common::*;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::{frame_counter, mash, save_states};
|
||||
use training_mod_sync::*;
|
||||
|
||||
static TECH_ROLL_DIRECTION: RwLock<Direction> = RwLock::new(Direction::empty());
|
||||
static MISS_TECH_ROLL_DIRECTION: RwLock<Direction> = RwLock::new(Direction::empty());
|
||||
|
@ -63,7 +63,7 @@ unsafe fn mod_handle_change_status(
|
|||
.try_get_int()
|
||||
.unwrap_or(*FIGHTER_STATUS_KIND_WAIT as u64) as i32;
|
||||
|
||||
let state: TechFlags = MENU.tech_state.get_random();
|
||||
let state: TechFlags = get(&MENU).tech_state.get_random();
|
||||
|
||||
if handle_grnd_tech(module_accessor, status_kind, unk, status_kind_int, state) {
|
||||
return;
|
||||
|
@ -125,11 +125,11 @@ unsafe fn handle_grnd_tech(
|
|||
}
|
||||
_ => false,
|
||||
};
|
||||
if do_tech && MENU.mash_triggers.contains(&MashTrigger::TECH) {
|
||||
if MENU.tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
if do_tech && get(&MENU).mash_triggers.contains(&MashTrigger::TECH) {
|
||||
if get(&MENU).tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(get(&MENU).mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.tech_action_override.get_random())
|
||||
mash::external_buffer_menu_mash(get(&MENU).tech_action_override.get_random())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,11 +172,11 @@ unsafe fn handle_wall_tech(
|
|||
}
|
||||
_ => false,
|
||||
};
|
||||
if do_tech && MENU.mash_triggers.contains(&MashTrigger::TECH) {
|
||||
if MENU.tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
if do_tech && get(&MENU).mash_triggers.contains(&MashTrigger::TECH) {
|
||||
if get(&MENU).tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(get(&MENU).mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.tech_action_override.get_random())
|
||||
mash::external_buffer_menu_mash(get(&MENU).tech_action_override.get_random())
|
||||
}
|
||||
}
|
||||
true
|
||||
|
@ -207,18 +207,18 @@ unsafe fn handle_ceil_tech(
|
|||
|
||||
*status_kind = FIGHTER_STATUS_KIND_PASSIVE_CEIL.as_lua_int();
|
||||
*unk = LUA_TRUE;
|
||||
if MENU.mash_triggers.contains(&MashTrigger::TECH) {
|
||||
if MENU.tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
if get(&MENU).mash_triggers.contains(&MashTrigger::TECH) {
|
||||
if get(&MENU).tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(get(&MENU).mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.tech_action_override.get_random())
|
||||
mash::external_buffer_menu_mash(get(&MENU).tech_action_override.get_random())
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAccessor) {
|
||||
if !is_operation_cpu(module_accessor) || MENU.tech_state == TechFlags::empty() {
|
||||
if !is_operation_cpu(module_accessor) || get(&MENU).tech_state == TechFlags::empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
|||
.contains(&status)
|
||||
{
|
||||
// Mistech
|
||||
requested_status = match MENU.miss_tech_state.get_random() {
|
||||
requested_status = match get(&MENU).miss_tech_state.get_random() {
|
||||
MissTechFlags::GETUP => *FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
MissTechFlags::ATTACK => *FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK,
|
||||
MissTechFlags::ROLL_F => {
|
||||
|
@ -250,7 +250,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
|||
if frame_counter::should_delay(lockout_time, *FRAME_COUNTER) {
|
||||
return;
|
||||
};
|
||||
requested_status = match MENU.miss_tech_state.get_random() {
|
||||
requested_status = match get(&MENU).miss_tech_state.get_random() {
|
||||
MissTechFlags::GETUP => *FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
MissTechFlags::ATTACK => *FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK,
|
||||
MissTechFlags::ROLL_F => {
|
||||
|
@ -265,7 +265,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
|||
};
|
||||
} else if status == *FIGHTER_STATUS_KIND_SLIP_WAIT {
|
||||
// Handle slips (like Diddy banana)
|
||||
requested_status = match MENU.miss_tech_state.get_random() {
|
||||
requested_status = match get(&MENU).miss_tech_state.get_random() {
|
||||
MissTechFlags::GETUP => *FIGHTER_STATUS_KIND_SLIP_STAND,
|
||||
MissTechFlags::ATTACK => *FIGHTER_STATUS_KIND_SLIP_STAND_ATTACK,
|
||||
MissTechFlags::ROLL_F => *FIGHTER_STATUS_KIND_SLIP_STAND_F,
|
||||
|
@ -279,11 +279,11 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
|||
|
||||
if requested_status != 0 {
|
||||
StatusModule::change_status_force(module_accessor, requested_status, true);
|
||||
if MENU.mash_triggers.contains(&MashTrigger::MISTECH) {
|
||||
if MENU.tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
if get(&MENU).mash_triggers.contains(&MashTrigger::MISTECH) {
|
||||
if get(&MENU).tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(get(&MENU).mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.tech_action_override.get_random())
|
||||
mash::external_buffer_menu_mash(get(&MENU).tech_action_override.get_random())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ pub unsafe fn change_motion(
|
|||
return None;
|
||||
}
|
||||
|
||||
if MENU.tech_state == TechFlags::empty() {
|
||||
if get(&MENU).tech_state == TechFlags::empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ unsafe fn get_snake_laydown_lockout_time(module_accessor: &mut BattleObjectModul
|
|||
}
|
||||
|
||||
pub unsafe fn hide_tech() {
|
||||
if !is_training_mode() || MENU.tech_hide == OnOff::OFF {
|
||||
if !is_training_mode() || get(&MENU).tech_hide == OnOff::OFF {
|
||||
return;
|
||||
}
|
||||
let module_accessor = get_module_accessor(FighterId::CPU);
|
||||
|
@ -407,7 +407,7 @@ pub unsafe fn handle_fighter_req_quake_pos(
|
|||
return original!()(module_accessor, quake_kind);
|
||||
}
|
||||
let status = StatusModule::status_kind(module_accessor);
|
||||
if status == FIGHTER_STATUS_KIND_DOWN && MENU.tech_hide == OnOff::ON {
|
||||
if status == FIGHTER_STATUS_KIND_DOWN && get(&MENU).tech_hide == OnOff::ON {
|
||||
// We're hiding techs, prevent mistech quake from giving away missed tech
|
||||
return original!()(module_accessor, *CAMERA_QUAKE_KIND_NONE);
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ pub struct CameraManager {
|
|||
|
||||
unsafe fn set_fixed_camera_values() {
|
||||
let camera_manager = get_camera_manager();
|
||||
if MENU.tech_hide == OnOff::OFF {
|
||||
if get(&MENU).tech_hide == OnOff::OFF {
|
||||
// Use Stage's Default Values for fixed Camera
|
||||
camera_manager.fixed_camera_center = read_rwlock(&DEFAULT_FIXED_CAM_CENTER);
|
||||
} else {
|
||||
|
|
|
@ -3,10 +3,9 @@ use smash::lib::lua_const::*;
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::frame_counter;
|
||||
use crate::training::mash;
|
||||
|
||||
use training_mod_sync::*;
|
||||
|
||||
const NOT_SET: u32 = 9001;
|
||||
static THROW_DELAY: RwLock<u32> = RwLock::new(NOT_SET);
|
||||
|
@ -44,27 +43,27 @@ pub fn reset_throw_case() {
|
|||
fn roll_throw_delay() {
|
||||
if read_rwlock(&THROW_DELAY) == NOT_SET {
|
||||
// Only roll another throw delay if one is not already selected
|
||||
unsafe {
|
||||
assign_rwlock(&THROW_DELAY, MENU.throw_delay.get_random().into_meddelay());
|
||||
}
|
||||
assign_rwlock(
|
||||
&THROW_DELAY,
|
||||
get(&MENU).throw_delay.get_random().into_meddelay(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn roll_pummel_delay() {
|
||||
if read_rwlock(&PUMMEL_DELAY) == NOT_SET {
|
||||
// Don't roll another pummel delay if one is already selected
|
||||
unsafe {
|
||||
assign_rwlock(&PUMMEL_DELAY, MENU.pummel_delay.get_random().into_meddelay());
|
||||
}
|
||||
assign_rwlock(
|
||||
&PUMMEL_DELAY,
|
||||
get(&MENU).pummel_delay.get_random().into_meddelay(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn roll_throw_case() {
|
||||
if read_rwlock(&THROW_CASE) == ThrowOption::empty() {
|
||||
// Only re-roll if there is not already a throw option selected
|
||||
unsafe {
|
||||
assign_rwlock(&THROW_CASE, MENU.throw_state.get_random());
|
||||
}
|
||||
assign_rwlock(&THROW_CASE, get(&MENU).throw_state.get_random());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +112,7 @@ pub unsafe fn get_command_flag_throw_direction(
|
|||
}
|
||||
|
||||
// If no pummel delay is selected (default), then don't pummel
|
||||
if MENU.pummel_delay == MedDelay::empty() {
|
||||
if get(&MENU).pummel_delay == MedDelay::empty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -132,7 +131,7 @@ pub unsafe fn get_command_flag_throw_direction(
|
|||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_THROW_HI,
|
||||
) {
|
||||
let cmd = read_rwlock(&THROW_CASE).into_cmd().unwrap_or(0);
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random());
|
||||
mash::external_buffer_menu_mash(get(&MENU).mash_state.get_random());
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@ use training_mod_consts::{InputDisplay, MENU};
|
|||
|
||||
use crate::common::consts::status_display_name;
|
||||
use crate::menu::QUICK_MENU_ACTIVE;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::input_log::{
|
||||
DirectionStrength, InputLog, DRAW_LOG_BASE_IDX, NUM_LOGS, P1_INPUT_LOGS, WHITE, YELLOW,
|
||||
};
|
||||
use crate::training::ui::fade_out;
|
||||
use crate::training::ui::menu::VANILLA_MENU_ACTIVE;
|
||||
use training_mod_sync::*;
|
||||
|
||||
macro_rules! log_parent_fmt {
|
||||
($x:ident) => {
|
||||
|
@ -176,7 +176,7 @@ unsafe fn draw_log(root_pane: &Pane, log_idx: usize, log: &InputLog) {
|
|||
.as_textbox()
|
||||
.set_text_string(frame_text.as_str());
|
||||
|
||||
let status_text = if MENU.input_display_status.as_bool() {
|
||||
let status_text = if get(&MENU).input_display_status.as_bool() {
|
||||
status_display_name(log.fighter_kind, log.status)
|
||||
} else {
|
||||
"".to_string()
|
||||
|
@ -195,9 +195,9 @@ pub unsafe fn draw(root_pane: &Pane) {
|
|||
logs_pane.set_visible(
|
||||
!read_rwlock(&QUICK_MENU_ACTIVE)
|
||||
&& !read_rwlock(&VANILLA_MENU_ACTIVE)
|
||||
&& MENU.input_display != InputDisplay::NONE,
|
||||
&& get(&MENU).input_display != InputDisplay::NONE,
|
||||
);
|
||||
if MENU.input_display == InputDisplay::NONE {
|
||||
if get(&MENU).input_display == InputDisplay::NONE {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ use crate::common::offsets::{OFFSET_DRAW, OFFSET_LAYOUT_ARC_MALLOC};
|
|||
use crate::common::{is_ready_go, is_training_mode};
|
||||
#[cfg(feature = "layout_arc_from_file")]
|
||||
use crate::consts::LAYOUT_ARC_PATH;
|
||||
use training_mod_sync::*;
|
||||
use crate::training::frame_counter;
|
||||
use training_mod_sync::*;
|
||||
|
||||
mod damage;
|
||||
mod display;
|
||||
|
@ -72,7 +72,7 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
|
|||
{
|
||||
// InfluencedAlpha means "Should my children panes' alpha be influenced by mine, as the parent?"
|
||||
root_pane.flags |= 1 << PaneFlag::InfluencedAlpha as u8;
|
||||
root_pane.set_visible(MENU.hud == OnOff::ON && !read_rwlock(&QUICK_MENU_ACTIVE));
|
||||
root_pane.set_visible(get(&MENU).hud == OnOff::ON && !read_rwlock(&QUICK_MENU_ACTIVE));
|
||||
}
|
||||
|
||||
damage::draw(root_pane, &layout_name);
|
||||
|
|
|
@ -17,7 +17,8 @@ skyline_smash = { git = "https://github.com/ultimate-research/skyline-smash.git"
|
|||
toml = "0.5.9"
|
||||
anyhow = "1.0.72"
|
||||
rand = { git = "https://github.com/skyline-rs/rand" }
|
||||
training_mod_tui = { path = "../training_mod_tui"}
|
||||
training_mod_sync = { path = "../training_mod_sync" }
|
||||
training_mod_tui = { path = "../training_mod_tui" }
|
||||
|
||||
[features]
|
||||
default = ["smash"]
|
||||
|
|
|
@ -12,6 +12,8 @@ pub mod config;
|
|||
pub use config::*;
|
||||
|
||||
use paste::paste;
|
||||
|
||||
use training_mod_sync::*;
|
||||
pub use training_mod_tui::*;
|
||||
|
||||
pub const TOGGLE_MAX: u8 = 5;
|
||||
|
@ -204,7 +206,7 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu {
|
|||
lra_reset: OnOff::ON,
|
||||
};
|
||||
|
||||
pub static mut MENU: TrainingModpackMenu = DEFAULTS_MENU;
|
||||
pub static MENU: RwLock<TrainingModpackMenu> = RwLock::new(DEFAULTS_MENU);
|
||||
|
||||
impl_toggletrait! {
|
||||
OnOff,
|
||||
|
|
|
@ -33,4 +33,9 @@ pub fn lock_write_rwlock<T>(rwlock: &RwLock<T>) -> RwLockWriteGuard<T> {
|
|||
/// Don't forget to drop the guard as soon as you're finished with it
|
||||
pub fn lock_read_rwlock<T>(rwlock: &RwLock<T>) -> RwLockReadGuard<T> {
|
||||
rwlock.read().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Shorthand for read_rwlock
|
||||
pub fn get<T: Copy>(rwlock: &RwLock<T>) -> T {
|
||||
read_rwlock(rwlock)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue