mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-27 20:34:03 +00:00
Mash Overrides (#533)
* Merge from CookieScythe branch * Rename block to shieldstun, add icons to layout.arc, add new options to ui_menu * Address clippy warnings and reformat * Add fn_null_check back to whitelist * Pray to clippy gods
This commit is contained in:
parent
e0ef313297
commit
7eec409086
15 changed files with 322 additions and 60 deletions
|
@ -116,12 +116,20 @@ pub fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -
|
|||
let status_kind = unsafe { StatusModule::status_kind(module_accessor) };
|
||||
let prev_status = unsafe { StatusModule::prev_status_kind(module_accessor, 0) };
|
||||
|
||||
// If we are taking shield damage or we are droping shield from taking shield damage we are in hitstun
|
||||
// If we are taking shield damage or we are dropping shield from taking shield damage we are in hitstun
|
||||
// check if we're in first frames of guard off; don't try to mash in parryable frames - is this a problem for jump/grab OoS?
|
||||
status_kind == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
|| (prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
&& status_kind == FIGHTER_STATUS_KIND_GUARD_OFF)
|
||||
}
|
||||
|
||||
pub unsafe fn is_in_tech(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
let status_kind = StatusModule::status_kind(module_accessor);
|
||||
(*FIGHTER_STATUS_KIND_DOWN_STAND..=*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK)
|
||||
.contains(&status_kind)
|
||||
|| (*FIGHTER_STATUS_KIND_PASSIVE..=*FIGHTER_STATUS_KIND_PASSIVE_CEIL).contains(&status_kind)
|
||||
}
|
||||
|
||||
pub unsafe fn is_ptrainer(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
[
|
||||
*FIGHTER_KIND_PZENIGAME,
|
||||
|
@ -216,7 +224,8 @@ pub unsafe fn is_in_tumble(module_accessor: &mut app::BattleObjectModuleAccessor
|
|||
pub unsafe fn is_in_landing(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
let status_kind = StatusModule::status_kind(module_accessor);
|
||||
|
||||
(*FIGHTER_STATUS_KIND_LANDING..=*FIGHTER_STATUS_KIND_LANDING_LIGHT).contains(&status_kind)
|
||||
(*FIGHTER_STATUS_KIND_LANDING..=*FIGHTER_STATUS_KIND_LANDING_DAMAGE_LIGHT)
|
||||
.contains(&status_kind)
|
||||
}
|
||||
|
||||
// Returns true if a match is currently active
|
||||
|
@ -225,7 +234,6 @@ pub unsafe fn is_ready_go() -> bool {
|
|||
FighterManager::is_ready_go(fighter_manager)
|
||||
}
|
||||
|
||||
// Returns true if a match is currently active
|
||||
pub unsafe fn entry_count() -> i32 {
|
||||
let fighter_manager = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager);
|
||||
FighterManager::entry_count(fighter_manager)
|
||||
|
|
|
@ -22,7 +22,7 @@ fn is_current_version(fpath: &str) -> VersionCheck {
|
|||
return VersionCheck::NoFile;
|
||||
}
|
||||
|
||||
if fs::read_to_string(fpath).unwrap_or("".to_string()) == CURRENT_VERSION {
|
||||
if fs::read_to_string(fpath).unwrap_or_else(|_| "".to_string()) == CURRENT_VERSION {
|
||||
VersionCheck::Current
|
||||
} else {
|
||||
VersionCheck::Update
|
||||
|
|
|
@ -75,11 +75,7 @@ pub unsafe fn generate_hitbox_effects(
|
|||
let dist_sq: f32 = x_dist * x_dist + y_dist * y_dist + z_dist * z_dist;
|
||||
let dist = dist_sq.sqrt();
|
||||
n_effects = ((dist / (size * 1.75)) + 1.0).ceil() as i32; // just enough effects to form a continuous line
|
||||
if n_effects < 2 {
|
||||
n_effects = 2;
|
||||
} else if n_effects > MAX_EFFECTS_PER_HITBOX {
|
||||
n_effects = MAX_EFFECTS_PER_HITBOX;
|
||||
}
|
||||
n_effects = n_effects.clamp(2, MAX_EFFECTS_PER_HITBOX);
|
||||
} else {
|
||||
x_dist = 0.0;
|
||||
y_dist = 0.0;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
clippy::missing_safety_doc,
|
||||
clippy::wrong_self_convention,
|
||||
clippy::option_map_unit_fn,
|
||||
clippy::fn_null_check,
|
||||
clippy::incorrect_fn_null_checks,
|
||||
clippy::transmute_num_to_bytes
|
||||
)]
|
||||
|
||||
|
|
Binary file not shown.
|
@ -3,7 +3,7 @@ use smash::app::{self};
|
|||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
|
||||
static mut DIRECTION: AttackAngle = AttackAngle::UP;
|
||||
static mut DIRECTION: AttackAngle = AttackAngle::NEUTRAL;
|
||||
|
||||
pub fn roll_direction() {
|
||||
unsafe {
|
||||
|
|
|
@ -5,10 +5,8 @@ use smash::phx::{Hash40, Vector3f};
|
|||
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use crate::training::mash;
|
||||
|
||||
static mut COUNTER: u32 = 0;
|
||||
static mut WAS_IN_CLATTER_FLAG: bool = false;
|
||||
static mut CLATTER_STEP: f32 = 8.0;
|
||||
|
||||
unsafe fn do_clatter_input(module_accessor: &mut BattleObjectModuleAccessor) {
|
||||
|
@ -44,13 +42,9 @@ pub unsafe fn handle_clatter(module_accessor: &mut BattleObjectModuleAccessor) {
|
|||
return;
|
||||
}
|
||||
if !is_in_clatter(module_accessor) {
|
||||
if WAS_IN_CLATTER_FLAG && MENU.mash_triggers.contains(MashTrigger::CLATTER) {
|
||||
mash::buffer_menu_mash();
|
||||
}
|
||||
WAS_IN_CLATTER_FLAG = false;
|
||||
// Don't do clatter inputs if we're not in clatter
|
||||
return;
|
||||
}
|
||||
WAS_IN_CLATTER_FLAG = true;
|
||||
let repeat = MENU.clatter_strength.into_u32();
|
||||
|
||||
COUNTER = (COUNTER + 1) % repeat;
|
||||
|
|
|
@ -102,7 +102,18 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor
|
|||
StatusModule::change_status_request_from_script(module_accessor, status, true);
|
||||
|
||||
if MENU.mash_triggers.contains(MashTrigger::LEDGE) {
|
||||
mash::buffer_menu_mash();
|
||||
if LEDGE_CASE == LedgeOption::NEUTRAL && MENU.ledge_neutral_override != Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.ledge_neutral_override.get_random());
|
||||
} else if LEDGE_CASE == LedgeOption::ROLL && MENU.ledge_roll_override != Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.ledge_roll_override.get_random());
|
||||
} else if LEDGE_CASE == LedgeOption::JUMP && MENU.ledge_jump_override != Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.ledge_jump_override.get_random());
|
||||
} else if LEDGE_CASE == LedgeOption::ATTACK && MENU.ledge_attack_override != Action::empty()
|
||||
{
|
||||
mash::external_buffer_menu_mash(MENU.ledge_attack_override.get_random());
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,46 +131,127 @@ pub unsafe fn get_command_flag_cat(
|
|||
}
|
||||
|
||||
unsafe fn check_buffer(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
if !QUEUE.is_empty() {
|
||||
return;
|
||||
// Different situations mean we want to change our buffered option, so we check what to buffer every frame
|
||||
let buffered_action = get_buffered_action(module_accessor);
|
||||
if let Some(action) = buffered_action {
|
||||
full_reset();
|
||||
// we need to clear the queue when adding a mash to the queue, but not necessarily a follow-up.
|
||||
// We need to clear the queue since it'll be trying to buffer that action until it's completed, but now we want
|
||||
// different things to happen.
|
||||
buffer_menu_mash(action);
|
||||
}
|
||||
|
||||
if !should_buffer(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_menu_mash();
|
||||
}
|
||||
|
||||
unsafe fn should_buffer(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
unsafe fn get_buffered_action(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) -> Option<Action> {
|
||||
// TODO: refactor this so it is less repetitive. Maybe a macro is the right tool for this
|
||||
if save_states::is_loading() {
|
||||
return false;
|
||||
return None;
|
||||
}
|
||||
|
||||
let fighter_distance = get_fighter_distance();
|
||||
MENU.mash_triggers.contains(MashTrigger::ALWAYS)
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::HIT) && is_in_hitstun(module_accessor))
|
||||
// BLOCK handled in shield.rs
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::PARRY) && is_in_parry(module_accessor))
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::TUMBLE) && is_in_tumble(module_accessor))
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::LANDING) && is_in_landing(module_accessor))
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::TRUMP) && is_in_ledgetrump(module_accessor))
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::FOOTSTOOL) && is_in_footstool(module_accessor))
|
||||
// CLATTER handled in clatter.rs
|
||||
// LEDGE handled in ledge.rs
|
||||
// TECH handled in tech.rs
|
||||
// MISTECH handled in tech.rs
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::GROUNDED) && is_grounded(module_accessor))
|
||||
if is_in_tech(module_accessor) {
|
||||
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 {
|
||||
None
|
||||
}
|
||||
} else if is_in_clatter(module_accessor) {
|
||||
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 {
|
||||
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();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} 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();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} 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();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(MashTrigger::PARRY) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_shieldstun(module_accessor) {
|
||||
let action = MENU.shieldstun_override.get_random();
|
||||
if action != Action::empty() {
|
||||
Some(action)
|
||||
} else if MENU.mash_triggers.contains(MashTrigger::SHIELDSTUN) {
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if is_in_footstool(module_accessor) {
|
||||
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 {
|
||||
None
|
||||
}
|
||||
} else if is_in_ledgetrump(module_accessor) {
|
||||
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 {
|
||||
None
|
||||
}
|
||||
} else if is_in_landing(module_accessor) {
|
||||
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 {
|
||||
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) && fighter_distance < DISTANCE_CLOSE_THRESHOLD)
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::DISTANCE_MID) && fighter_distance < DISTANCE_MID_THRESHOLD)
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::DISTANCE_FAR) && fighter_distance < DISTANCE_FAR_THRESHOLD)
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::DISTANCE_CLOSE)
|
||||
&& fighter_distance < DISTANCE_CLOSE_THRESHOLD)
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::DISTANCE_MID)
|
||||
&& fighter_distance < DISTANCE_MID_THRESHOLD)
|
||||
|| (MENU.mash_triggers.contains(MashTrigger::DISTANCE_FAR)
|
||||
&& fighter_distance < DISTANCE_FAR_THRESHOLD)
|
||||
|| MENU.mash_triggers.contains(MashTrigger::ALWAYS)
|
||||
{
|
||||
Some(MENU.mash_state.get_random())
|
||||
} else {
|
||||
// LEDGE handled in ledge.rs
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Temp Translation
|
||||
pub fn buffer_menu_mash() {
|
||||
fn buffer_menu_mash(action: Action) {
|
||||
unsafe {
|
||||
let action = MENU.mash_state.get_random();
|
||||
buffer_action(action);
|
||||
full_hop::roll_full_hop();
|
||||
fast_fall::roll_fast_fall();
|
||||
|
@ -178,6 +259,11 @@ pub fn buffer_menu_mash() {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn external_buffer_menu_mash(action: Action) {
|
||||
full_reset();
|
||||
buffer_menu_mash(action);
|
||||
}
|
||||
|
||||
unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 {
|
||||
let action = get_current_buffer();
|
||||
match action {
|
||||
|
|
|
@ -238,8 +238,12 @@ unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) {
|
|||
return;
|
||||
}
|
||||
|
||||
if MENU.mash_triggers.contains(MashTrigger::BLOCK) {
|
||||
mash::buffer_menu_mash();
|
||||
if MENU.mash_triggers.contains(MashTrigger::SHIELDSTUN) {
|
||||
if MENU.shieldstun_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.shieldstun_override.get_random())
|
||||
}
|
||||
}
|
||||
let action = mash::get_current_buffer();
|
||||
|
||||
|
@ -341,7 +345,30 @@ fn needs_oos_handling_drop_shield() -> bool {
|
|||
if action == Action::U_SMASH {
|
||||
return true;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if action == Action::SHIELD {
|
||||
let shield_state;
|
||||
unsafe {
|
||||
shield_state = &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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,11 @@ unsafe fn handle_grnd_tech(
|
|||
_ => false,
|
||||
};
|
||||
if do_tech && MENU.mash_triggers.contains(MashTrigger::TECH) {
|
||||
mash::buffer_menu_mash();
|
||||
if MENU.tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.tech_action_override.get_random())
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
|
@ -159,7 +163,11 @@ unsafe fn handle_wall_tech(
|
|||
_ => false,
|
||||
};
|
||||
if do_tech && MENU.mash_triggers.contains(MashTrigger::TECH) {
|
||||
mash::buffer_menu_mash();
|
||||
if MENU.tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.tech_action_override.get_random())
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
@ -190,7 +198,11 @@ 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) {
|
||||
mash::buffer_menu_mash();
|
||||
if MENU.tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.tech_action_override.get_random())
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
@ -258,7 +270,11 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces
|
|||
if requested_status != 0 {
|
||||
StatusModule::change_status_request_from_script(module_accessor, requested_status, false);
|
||||
if MENU.mash_triggers.contains(MashTrigger::MISTECH) {
|
||||
mash::buffer_menu_mash();
|
||||
if MENU.tech_action_override == Action::empty() {
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random())
|
||||
} else {
|
||||
mash::external_buffer_menu_mash(MENU.tech_action_override.get_random())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ pub unsafe fn get_command_flag_throw_direction(
|
|||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_THROW_HI,
|
||||
) {
|
||||
let cmd = THROW_CASE.into_cmd().unwrap_or(0);
|
||||
mash::buffer_menu_mash();
|
||||
mash::external_buffer_menu_mash(MENU.mash_state.get_random());
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ pub unsafe fn parse_anim_transform(anim_transform: &mut AnimTransform, layout_na
|
|||
as *const ResAnimationContent;
|
||||
|
||||
let name = skyline::try_from_c_str((*res_animation_cont).name.as_ptr())
|
||||
.unwrap_or("UNKNOWN".to_string());
|
||||
.unwrap_or_else(|_| "UNKNOWN".to_string());
|
||||
let anim_type = (*res_animation_cont).anim_content_type;
|
||||
|
||||
// AnimContentType 1 == MATERIAL
|
||||
|
|
|
@ -59,6 +59,19 @@ pub struct TrainingModpackMenu {
|
|||
pub tech_state: TechFlags,
|
||||
pub throw_delay: MedDelay,
|
||||
pub throw_state: ThrowOption,
|
||||
pub ledge_neutral_override: Action,
|
||||
pub ledge_roll_override: Action,
|
||||
pub ledge_jump_override: Action,
|
||||
pub ledge_attack_override: Action,
|
||||
pub tech_action_override: Action,
|
||||
pub clatter_override: Action,
|
||||
pub tumble_override: Action,
|
||||
pub hitstun_override: Action,
|
||||
pub parry_override: Action,
|
||||
pub shieldstun_override: Action,
|
||||
pub footstool_override: Action,
|
||||
pub landing_override: Action,
|
||||
pub trump_override: Action,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -136,6 +149,19 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu {
|
|||
tech_state: TechFlags::all(),
|
||||
throw_delay: MedDelay::empty(),
|
||||
throw_state: ThrowOption::NONE,
|
||||
ledge_neutral_override: Action::empty(),
|
||||
ledge_roll_override: Action::empty(),
|
||||
ledge_jump_override: Action::empty(),
|
||||
ledge_attack_override: Action::empty(),
|
||||
tech_action_override: Action::empty(),
|
||||
clatter_override: Action::empty(),
|
||||
tumble_override: Action::empty(),
|
||||
hitstun_override: Action::empty(),
|
||||
parry_override: Action::empty(),
|
||||
shieldstun_override: Action::empty(),
|
||||
footstool_override: Action::empty(),
|
||||
landing_override: Action::empty(),
|
||||
trump_override: Action::empty(),
|
||||
};
|
||||
|
||||
pub static mut MENU: TrainingModpackMenu = DEFAULTS_MENU;
|
||||
|
@ -385,6 +411,104 @@ pub unsafe fn ui_menu(menu: TrainingModpackMenu) -> UiMenu<'static> {
|
|||
);
|
||||
overall_menu.tabs.push(mash_tab);
|
||||
|
||||
let mut override_tab = Tab {
|
||||
tab_id: "override",
|
||||
tab_title: "Override Settings",
|
||||
tab_submenus: Vec::new(),
|
||||
};
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Ledge Neutral Getup",
|
||||
"ledge_neutral_override",
|
||||
"Neutral Getup Override: Mash Actions to be performed after a Neutral Getup from ledge",
|
||||
false,
|
||||
&(menu.ledge_neutral_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Ledge Roll",
|
||||
"ledge_roll_override",
|
||||
"Ledge Roll Override: Mash Actions to be performed after a Roll Getup from ledge",
|
||||
false,
|
||||
&(menu.ledge_roll_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Ledge Jump",
|
||||
"ledge_jump_override",
|
||||
"Ledge Jump Override: Mash Actions to be performed after a Jump Getup from ledge",
|
||||
false,
|
||||
&(menu.ledge_jump_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Ledge Attack",
|
||||
"ledge_attack_override",
|
||||
"Ledge Attack Override: Mash Actions to be performed after a Getup Attack from ledge",
|
||||
false,
|
||||
&(menu.ledge_attack_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Tech Action",
|
||||
"tech_action_override",
|
||||
"Tech Action Override: Mash Actions to be performed after any tech action",
|
||||
false,
|
||||
&(menu.tech_action_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Clatter",
|
||||
"clatter_override",
|
||||
"Clatter Override: Mash Actions to be performed after leaving a clatter situation (grab, bury, etc)",
|
||||
false,
|
||||
&(menu.clatter_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Tumble",
|
||||
"tumble_override",
|
||||
"Tumble Override: Mash Actions to be performed after exiting a tumble state",
|
||||
false,
|
||||
&(menu.tumble_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Hitstun",
|
||||
"hitstun_override",
|
||||
"Hitstun Override: Mash Actions to be performed after exiting a hitstun state",
|
||||
false,
|
||||
&(menu.hitstun_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Parry",
|
||||
"parry_override",
|
||||
"Parry Override: Mash Actions to be performed after a parry",
|
||||
false,
|
||||
&(menu.parry_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Shieldstun",
|
||||
"shieldstun_override",
|
||||
"Shieldstun Override: Mash Actions to be performed after exiting a shieldstun state",
|
||||
false,
|
||||
&(menu.shieldstun_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Footstool",
|
||||
"footstool_override",
|
||||
"Footstool Override: Mash Actions to be performed after exiting a footstool state",
|
||||
false,
|
||||
&(menu.footstool_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Landing",
|
||||
"landing_override",
|
||||
"Landing Override: Mash Actions to be performed after landing on the ground",
|
||||
false,
|
||||
&(menu.landing_override.bits()),
|
||||
);
|
||||
override_tab.add_submenu_with_toggles::<Action>(
|
||||
"Ledge Trump",
|
||||
"trump_override",
|
||||
"Ledge Trump Override: Mash Actions to be performed after leaving a ledgetrump state",
|
||||
false,
|
||||
&(menu.trump_override.bits()),
|
||||
);
|
||||
overall_menu.tabs.push(override_tab);
|
||||
|
||||
let mut defensive_tab = Tab {
|
||||
tab_id: "defensive",
|
||||
tab_title: "Defensive Settings",
|
||||
|
|
|
@ -1014,7 +1014,7 @@ impl ToggleTrait for CharacterItem {
|
|||
bitflags! {
|
||||
pub struct MashTrigger : u32 {
|
||||
const HIT = 0b0000_0000_0000_0000_0001;
|
||||
const BLOCK = 0b0000_0000_0000_0000_0010;
|
||||
const SHIELDSTUN = 0b0000_0000_0000_0000_0010;
|
||||
const PARRY = 0b0000_0000_0000_0000_0100;
|
||||
const TUMBLE = 0b0000_0000_0000_0000_1000;
|
||||
const LANDING = 0b0000_0000_0000_0001_0000;
|
||||
|
@ -1037,7 +1037,7 @@ impl MashTrigger {
|
|||
pub fn as_str(self) -> Option<&'static str> {
|
||||
Some(match self {
|
||||
MashTrigger::HIT => "Hitstun",
|
||||
MashTrigger::BLOCK => "Shieldstun",
|
||||
MashTrigger::SHIELDSTUN => "Shieldstun",
|
||||
MashTrigger::PARRY => "Parry",
|
||||
MashTrigger::TUMBLE => "Tumble",
|
||||
MashTrigger::LANDING => "Landing",
|
||||
|
@ -1060,7 +1060,7 @@ impl MashTrigger {
|
|||
pub const fn default() -> MashTrigger {
|
||||
// Hit, block, clatter
|
||||
MashTrigger::HIT
|
||||
.union(MashTrigger::BLOCK)
|
||||
.union(MashTrigger::SHIELDSTUN)
|
||||
.union(MashTrigger::CLATTER)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue