1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2025-03-05 14:22:19 +00:00

Apply Bit Flags to Mash/Defensive Options (#136)

* Apply Bit Flag

Defensive Options

* Apply Bit Flag

Followups

* Apply Bit Flag

Mash options

* Update Version String
This commit is contained in:
sidschingis 2020-08-14 21:12:50 +02:00 committed by GitHub
parent 12807258be
commit 7ff8185a65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 175 additions and 390 deletions
TrainingModpackOverlay
src

View file

@ -38,7 +38,7 @@ include $(DEVKITPRO)/libnx/switch_rules
# NACP building is skipped as well. # NACP building is skipped as well.
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
APP_TITLE := Training Modpack APP_TITLE := Training Modpack
APP_VERSION := 2.05 APP_VERSION := 2.1 Beta
TARGET := ovlTrainingModpack TARGET := ovlTrainingModpack
BUILD := build BUILD := build
@ -189,7 +189,7 @@ DEPENDS := $(OFILES:.o=.d)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
all : $(OUTPUT).ovl all : $(OUTPUT).ovl
$(OUTPUT).ovl : $(OUTPUT).elf $(OUTPUT).nacp $(OUTPUT).ovl : $(OUTPUT).elf $(OUTPUT).nacp
@elf2nro $< $@ $(NROFLAGS) @elf2nro $< $@ $(NROFLAGS)
@echo "built ... $(notdir $(OUTPUT).ovl)" @echo "built ... $(notdir $(OUTPUT).ovl)"

View file

@ -56,7 +56,7 @@ Currently only used for
#define MASH_SIDE_B 6 #define MASH_SIDE_B 6
#define MASH_UP_B 7 #define MASH_UP_B 7
#define MASH_DOWN_B 8 #define MASH_DOWN_B 8
#define MASH_UP_SMASH 9 #define MASH_U_SMASH 9
#define MASH_GRAB 10 #define MASH_GRAB 10
const std::vector<std::string> attack_items{"Neutral Air", const std::vector<std::string> attack_items{"Neutral Air",
"Forward Air", "Forward Air",
@ -125,6 +125,28 @@ Specific tech options can be chosen and include:
CPUs will also perform a defensive CPUs will also perform a defensive
option after getting up.)""""; option after getting up.)"""";
// Defensive States
// clang-format off
#define ENUM_CLASS_DefensiveFlag(type,x) \
x(type,SpotDodge,"Spotdodge") \
x(type,RollF,"RollF") \
x(type,RollB,"RollB") \
x(type,Jab,"Jab")\
x(type,Shield,"Shield")
// clang-format on
DEFINE_ENUM_CLASS(DefensiveFlag);
const std::string defensive_help = R""""(
Choose the defensive option a CPU
will perform after teching or
getting up from the ledge.
Specific options include:
Flash shield, spotdodge, and jab
)"""";
// Mash States // Mash States
#define MASH_AIRDODGE 1 #define MASH_AIRDODGE 1
#define MASH_JUMP 2 #define MASH_JUMP 2
@ -160,10 +182,19 @@ Random
- Hitstun, shieldstun, landing.)""""; - Hitstun, shieldstun, landing.)"""";
// Action items (Follow Up only atm) // Action items (Follow Up only atm)
const std::vector<std::string> action_items{"None", "Airdodge", "Jump", "Spotdodge", "Roll F", "Roll B",
"Neutral Air", "Forward Air", "Back Air", "Up Air", "Down Air", "Neutral B", // clang-format off
"Side B", "Up B", "Down B", "Up Smash", "F Smash", "D Smash", #define ENUM_CLASS_ActionFlag(type,x) \
"Grab", "Jab", "Filt", "Utilt", "Dtilt", "Dash Attack"}; x(type,Airdodge,"Airdodge") x(type,Jump,"Jump") x(type,Shield,"Shield") x(type,Spotdodge,"Spotdodge") x(type,RollF,"Roll F") x(type,RollB,"Roll B") \
x(type,Nair,"Neutral Air") x(type,Fair,"Forward Air") x(type,Bair,"Back Air") x(type,Uair,"Up Air") x(type,Dair,"Down Air") \
x(type,NeutralB,"Neutral B") x(type,SideB,"Side B") x(type,UpB,"Up B") x(type,DownB,"Down B") \
x(type,FSmash,"Forward Smash") x(type,USmash,"Up Smash") x(type,DSmash,"Down Smash") \
x(type,Jab,"Jab") x(type,FTilt,"Filt") x(type,UTilt,"Utilt") x(type,Dtilt,"Dtilt") \
x(type,DashAttack,"Dash Attack") x(type,Grab,"Grab")
// clang-format on
DEFINE_ENUM_CLASS(ActionFlag);
const std::string follow_up_help = R""""( const std::string follow_up_help = R""""(
Action to buffer Action to buffer
after the first mash option after the first mash option
@ -186,22 +217,6 @@ by damage.
Hold Hold
CPUs will hold a normal shield.)""""; CPUs will hold a normal shield.)"""";
// Defensive States
#define RANDOM_DEFENSIVE 1
#define DEFENSIVE_SPOTDODGE 2
#define DEFENSIVE_ROLL 3
#define DEFENSIVE_JAB 4
#define DEFENSIVE_SHIELD 5
const std::vector<std::string> defensive_items{"None", "Random", "Spotdodge", "Roll", "Jab", "Flash Shield"};
const std::string defensive_help = R""""(
Choose the defensive option a CPU
will perform after teching or
getting up from the ledge.
Specific options include:
Flash shield, spotdodge, and jab
)"""";
// Hitbox visualization // Hitbox visualization
const std::string hitbox_help = R""""( const std::string hitbox_help = R""""(
Currently, hitboxes and Currently, hitboxes and

View file

@ -7,23 +7,22 @@
static struct TrainingModpackMenu static struct TrainingModpackMenu
{ {
int HITBOX_VIS = true; int HITBOX_VIS = true;
int DI_STATE = NONE; int DI_STATE = NONE;
int LEFT_STICK = NONE; int LEFT_STICK = NONE;
int ATTACK_STATE = MASH_NAIR; ActionFlags MASH_STATE = ActionFlags::None;
int FOLLOW_UP = 0; ActionFlags FOLLOW_UP = ActionFlags::None;
LedgeFlags LEDGE_STATE = LedgeFlags::All; LedgeFlags LEDGE_STATE = LedgeFlags::All;
TechFlags TECH_STATE = TechFlags::All; TechFlags TECH_STATE = TechFlags::All;
int MASH_STATE = NONE; int SHIELD_STATE = NONE;
int SHIELD_STATE = NONE; DefensiveFlags DEFENSIVE_STATE = DefensiveFlags::All;
int DEFENSIVE_STATE = RANDOM_DEFENSIVE; int OOS_OFFSET = 0;
int OOS_OFFSET = 0; int REACTION_TIME = 0;
int REACTION_TIME = 0; int MASH_IN_NEUTRAL = false;
int MASH_IN_NEUTRAL = false; int FAST_FALL = false;
int FAST_FALL = false; int FAST_FALL_DELAY = 0;
int FAST_FALL_DELAY = 0; int FALLING_AERIALS = false;
int FALLING_AERIALS = false; int FULL_HOP = false;
int FULL_HOP = false;
} menu; } menu;
static int FRAME_ADVANTAGE = 0; static int FRAME_ADVANTAGE = 0;
@ -390,19 +389,9 @@ tsl::elm::Element* GuiMain::createUI()
list->addItem(shieldItem); list->addItem(shieldItem);
valueListItems.push_back(shieldItem); valueListItems.push_back(shieldItem);
ValueListItem* mashItem = new ValueListItem("Mash Toggles", mash_items, &menu.MASH_STATE, "mash", mash_help); list->addItem(createBitFlagOption(&menu.MASH_STATE, "Mash Toggles", mash_help));
list->addItem(mashItem);
valueListItems.push_back(mashItem);
ValueListItem* attackItem = list->addItem(createBitFlagOption(&menu.FOLLOW_UP, "Followup Toggles", follow_up_help));
new ValueListItem("Attack Toggles", attack_items, &menu.ATTACK_STATE, "attack", attack_help);
list->addItem(attackItem);
valueListItems.push_back(attackItem);
ValueListItem* followUp =
new ValueListItem("Followup Toggles", action_items, &menu.FOLLOW_UP, "followUp", follow_up_help);
list->addItem(followUp);
valueListItems.push_back(followUp);
ValueListItem* mashNeutralItem = ValueListItem* mashNeutralItem =
new ValueListItem("Mash In Neutral", on_off, &menu.MASH_IN_NEUTRAL, "mash_neutral", mash_neutral_help); new ValueListItem("Mash In Neutral", on_off, &menu.MASH_IN_NEUTRAL, "mash_neutral", mash_neutral_help);
@ -410,12 +399,10 @@ tsl::elm::Element* GuiMain::createUI()
valueListItems.push_back(mashNeutralItem); valueListItems.push_back(mashNeutralItem);
list->addItem(createBitFlagOption(&menu.LEDGE_STATE, "Ledge Options", ledge_help)); list->addItem(createBitFlagOption(&menu.LEDGE_STATE, "Ledge Options", ledge_help));
list->addItem(createBitFlagOption(&menu.TECH_STATE, "Tech Options", tech_help)); list->addItem(createBitFlagOption(&menu.TECH_STATE, "Tech Options", tech_help));
ValueListItem* defensiveItem = list->addItem(createBitFlagOption(&menu.DEFENSIVE_STATE, "Defensive Options", defensive_help));
new ValueListItem("Defensive Options", defensive_items, &menu.DEFENSIVE_STATE, "defensive", defensive_help);
list->addItem(defensiveItem);
valueListItems.push_back(defensiveItem);
ValueListItem* diItem = new ValueListItem("Set DI", di_items, &menu.DI_STATE, "di", di_help); ValueListItem* diItem = new ValueListItem("Set DI", di_items, &menu.DI_STATE, "di", di_help);
list->addItem(diItem); list->addItem(diItem);

View file

@ -60,59 +60,6 @@ pub fn direction_to_angle(direction: Direction) -> f64 {
} }
} }
/// Mash Attack States
#[repr(i32)]
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum Attack {
Nair = 0,
Fair = 1,
Bair = 2,
UpAir = 3,
Dair = 4,
NeutralB = 5,
SideB = 6,
UpB = 7,
DownB = 8,
UpSmash = 9,
FSmash = 10,
DSmash = 11,
Grab = 12,
Jab = 13,
Ftilt = 14,
Utilt = 15,
Dtilt = 16,
DashAttack = 17,
Nothing = 9999,
}
impl From<i32> for Attack {
fn from(x: i32) -> Self {
use Attack::*;
match x {
0 => Nair,
1 => Fair,
2 => Bair,
3 => UpAir,
4 => Dair,
5 => NeutralB,
6 => SideB,
7 => UpB,
8 => DownB,
9 => UpSmash,
10 => FSmash,
11 => DSmash,
12 => Grab,
13 => Jab,
14 => Ftilt,
15 => Utilt,
16 => Dtilt,
17 => DashAttack,
_ => Nothing,
}
}
}
// bitflag helper function macro // bitflag helper function macro
macro_rules! to_vec_impl { macro_rules! to_vec_impl {
($e:ty) => { ($e:ty) => {
@ -152,10 +99,10 @@ macro_rules! get_random_impl {
bitflags! { bitflags! {
pub struct LedgeOption : u32 pub struct LedgeOption : u32
{ {
const NEUTRAL = 0b1; const NEUTRAL = 0x1;
const ROLL = 0b10; const ROLL = 0x2;
const JUMP = 0b100; const JUMP = 0x4;
const ATTACK = 0b1000; const ATTACK = 0x8;
} }
} }
@ -192,37 +139,6 @@ impl TechFlags {
get_random_impl! {TechFlags} get_random_impl! {TechFlags}
} }
/// Mash States
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Mash {
None = 0,
Airdodge = 1,
Jump = 2,
Attack = 3,
Spotdodge = 4,
RollForward = 5,
RollBack = 6,
Random = 7,
Shield = 99,
}
impl From<i32> for Mash {
fn from(x: i32) -> Self {
match x {
0 => Mash::None,
1 => Mash::Airdodge,
2 => Mash::Jump,
3 => Mash::Attack,
4 => Mash::Spotdodge,
5 => Mash::RollForward,
6 => Mash::RollBack,
7 => Mash::Random,
_ => panic!("Invalid mash state {}", x),
}
}
}
/// Shield States /// Shield States
#[repr(i32)] #[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -233,31 +149,19 @@ pub enum Shield {
} }
// Defensive States // Defensive States
#[repr(i32)] bitflags! {
#[derive(Debug, Clone, Copy, PartialEq)] pub struct Defensive : u32 {
pub enum Defensive { const SPOT_DODGE = 0x1;
None = 0, const ROLL_F = 0x2;
Random = 1, const ROLL_B = 0x4;
Spotdodge = 2, const JAB = 0x8;
Roll = 3, const SHIELD = 0x10;
Jab = 4, }
Shield = 5,
} }
impl From<i32> for Defensive { impl Defensive {
fn from(x: i32) -> Self { to_vec_impl! {Defensive}
use Defensive::*; get_random_impl! {Defensive}
match x {
0 => None,
1 => Random,
2 => Spotdodge,
3 => Roll,
4 => Jab,
5 => Shield,
_ => panic!("Invalid mash state {}", x),
}
}
} }
#[repr(i32)] #[repr(i32)]
@ -267,85 +171,48 @@ pub enum OnOff {
On = 1, On = 1,
} }
#[repr(i32)] bitflags! {
#[derive(Debug, Clone, Copy, PartialEq)] pub struct Action : u32 {
pub enum Action { const AIR_DODGE = 0x1;
Nothing = 0, const JUMP = 0x2;
Airdodge = 1, const SHIELD = 0x4;
Jump = 2, const SPOT_DODGE = 0x8;
Spotdodge = 3, const ROLL_F = 0x10;
RollForward = 4, const ROLL_B = 0x20;
RollBack = 5, const NAIR = 0x40;
Nair = 6, const FAIR = 0x80;
Fair = 7, const BAIR = 0x100;
Bair = 8, const UAIR = 0x200;
UpAir = 9, const DAIR = 0x400;
Dair = 10, const NEUTRAL_B = 0x800;
NeutralB = 11, const SIDE_B = 0x1000;
SideB = 12, const UP_B = 0x2000;
UpB = 13, const DOWN_B = 0x4000;
DownB = 14, const F_SMASH = 0x8000;
UpSmash = 15, const U_SMASH = 0x10000;
FSmash = 16, const D_SMASH = 0x20000;
DSmash = 17, const JAB = 0x40000;
Grab = 18, const F_TILT = 0x80000;
Jab = 19, const U_TILT = 0x100000;
Ftilt = 20, const D_TILT = 0x200000;
Utilt = 21, const DASH_ATTACK = 0x400000;
Dtilt = 22, const GRAB = 0x800000;
DashAttack = 23, }
Shield = 99,
} }
impl Action { impl Action {
pub fn into_attack_air_kind(&self) -> Option<i32> { pub fn into_attack_air_kind(&self) -> Option<i32> {
use Action::*; Some(match *self {
Action::NAIR => *FIGHTER_COMMAND_ATTACK_AIR_KIND_N,
Some(match self { Action::FAIR => *FIGHTER_COMMAND_ATTACK_AIR_KIND_F,
Nair => *FIGHTER_COMMAND_ATTACK_AIR_KIND_N, Action::BAIR => *FIGHTER_COMMAND_ATTACK_AIR_KIND_B,
Fair => *FIGHTER_COMMAND_ATTACK_AIR_KIND_F, Action::DAIR => *FIGHTER_COMMAND_ATTACK_AIR_KIND_LW,
Bair => *FIGHTER_COMMAND_ATTACK_AIR_KIND_B, Action::UAIR => *FIGHTER_COMMAND_ATTACK_AIR_KIND_HI,
Dair => *FIGHTER_COMMAND_ATTACK_AIR_KIND_LW,
UpAir => *FIGHTER_COMMAND_ATTACK_AIR_KIND_HI,
_ => return None, _ => return None,
}) })
} }
} to_vec_impl! {Action}
get_random_impl! {Action}
// To satisfy the unused warning
impl From<i32> for Action {
fn from(x: i32) -> Self {
use Action::*;
match x {
0 => Nothing,
1 => Airdodge,
2 => Jump,
3 => Spotdodge,
4 => RollForward,
5 => RollBack,
6 => Nair,
7 => Fair,
8 => Bair,
9 => UpAir,
10 => Dair,
11 => NeutralB,
12 => SideB,
13 => UpB,
14 => DownB,
15 => UpSmash,
16 => FSmash,
17 => DSmash,
18 => Grab,
19 => Jab,
20 => Ftilt,
21 => Utilt,
22 => Dtilt,
23 => DashAttack,
99 => Shield,
_ => Nothing,
}
}
} }
#[repr(C)] #[repr(C)]
@ -353,11 +220,10 @@ pub struct TrainingModpackMenu {
pub hitbox_vis: HitboxVisualization, pub hitbox_vis: HitboxVisualization,
pub di_state: Direction, pub di_state: Direction,
pub left_stick: Direction, // Currently only used for air dodge direction pub left_stick: Direction, // Currently only used for air dodge direction
pub mash_attack_state: Attack, pub mash_state: Action,
pub follow_up: Action, pub follow_up: Action,
pub ledge_state: LedgeOption, pub ledge_state: LedgeOption,
pub tech_state: TechFlags, pub tech_state: TechFlags,
pub mash_state: Mash,
pub shield_state: Shield, pub shield_state: Shield,
pub defensive_state: Defensive, pub defensive_state: Defensive,
pub oos_offset: u32, pub oos_offset: u32,

View file

@ -9,13 +9,12 @@ pub static mut MENU_STRUCT: consts::TrainingModpackMenu = consts::TrainingModpac
hitbox_vis: HitboxVisualization::On, hitbox_vis: HitboxVisualization::On,
di_state: Direction::None, di_state: Direction::None,
left_stick: Direction::None, left_stick: Direction::None,
mash_attack_state: Attack::Nair, mash_state: Action::empty(),
follow_up: Action::Nothing, follow_up: Action::empty(),
ledge_state: LedgeOption::all(), ledge_state: LedgeOption::all(),
tech_state: TechFlags::all(), tech_state: TechFlags::all(),
mash_state: Mash::None,
shield_state: Shield::None, shield_state: Shield::None,
defensive_state: Defensive::Random, defensive_state: Defensive::all(),
oos_offset: 0, oos_offset: 0,
reaction_time: 0, reaction_time: 0,
mash_in_neutral: OnOff::Off, mash_in_neutral: OnOff::Off,

View file

@ -32,7 +32,7 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor
match ledge_case { match ledge_case {
LedgeOption::JUMP => { LedgeOption::JUMP => {
mash::buffer_menu_mash(module_accessor); mash::buffer_menu_mash();
} }
_ => mash::perform_defensive_option(), _ => mash::perform_defensive_option(),
} }

View file

@ -6,7 +6,7 @@ use crate::training::shield;
use smash::app::{self, lua_bind::*}; use smash::app::{self, lua_bind::*};
use smash::lib::lua_const::*; use smash::lib::lua_const::*;
static mut CURRENT_AERIAL: Action = Action::Nair; static mut CURRENT_AERIAL: Action = Action::NAIR;
static mut QUEUE: Vec<Action> = vec![]; static mut QUEUE: Vec<Action> = vec![];
pub fn buffer_action(action: Action) { pub fn buffer_action(action: Action) {
@ -29,7 +29,7 @@ pub fn buffer_follow_up() {
action = MENU.follow_up; action = MENU.follow_up;
} }
if action == Action::Nothing { if action == Action::empty() {
return; return;
} }
@ -40,8 +40,11 @@ pub fn buffer_follow_up() {
pub fn get_current_buffer() -> Action { pub fn get_current_buffer() -> Action {
unsafe { unsafe {
let current = QUEUE.last().unwrap_or(&Action::Nothing); if QUEUE.len() == 0 {
*current return Action::empty();
}
return *QUEUE.last().unwrap();
} }
} }
@ -116,7 +119,7 @@ unsafe fn check_buffer(module_accessor: &mut app::BattleObjectModuleAccessor) {
return; return;
} }
buffer_menu_mash(module_accessor); buffer_menu_mash();
} }
fn should_reset(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { fn should_reset(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
@ -165,83 +168,20 @@ fn should_buffer(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
} }
// Temp Translation // Temp Translation
pub fn buffer_menu_mash(module_accessor: &mut app::BattleObjectModuleAccessor) -> Action { pub fn buffer_menu_mash() -> Action {
unsafe { unsafe {
let action; let action = MENU.mash_state.get_random();
if MENU.mash_state == Mash::Random {
action = get_random_action(module_accessor);
} else {
action = mash_to_action(MENU.mash_state);
}
buffer_action(action); buffer_action(action);
action action
} }
} }
pub fn mash_to_action(mash: Mash) -> Action {
use Action::*;
match mash {
Mash::Airdodge => Airdodge,
Mash::Jump => Jump,
Mash::Spotdodge => Spotdodge,
Mash::RollForward => RollForward,
Mash::RollBack => RollBack,
Mash::Shield => Shield,
Mash::Attack => unsafe { attack_to_action(MENU.mash_attack_state) },
_ => Nothing,
}
}
fn get_random_action(module_accessor: &mut app::BattleObjectModuleAccessor) -> Action {
let mut random_cmds = vec![Mash::Jump, Mash::Attack];
if is_airborne(module_accessor) {
random_cmds.push(Mash::Airdodge);
}
if is_grounded(module_accessor) {
random_cmds.push(Mash::RollBack);
random_cmds.push(Mash::RollForward);
random_cmds.push(Mash::Spotdodge);
}
let random_cmd_index = get_random_int(random_cmds.len() as i32) as usize;
mash_to_action(random_cmds[random_cmd_index])
}
fn attack_to_action(attack: Attack) -> Action {
use Action::*;
match attack {
Attack::Nair => Nair,
Attack::Fair => Fair,
Attack::Bair => Bair,
Attack::UpAir => UpAir,
Attack::Dair => Dair,
Attack::NeutralB => NeutralB,
Attack::SideB => SideB,
Attack::UpB => UpB,
Attack::DownB => DownB,
Attack::UpSmash => UpSmash,
Attack::FSmash => FSmash,
Attack::DSmash => DSmash,
Attack::Grab => Grab,
Attack::Jab => Jab,
Attack::Ftilt => Ftilt,
Attack::Utilt => Utilt,
Attack::Dtilt => Dtilt,
Attack::DashAttack => DashAttack,
Attack::Nothing => Nothing,
}
}
unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 { unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 {
use Action::*;
let action = get_current_buffer(); let action = get_current_buffer();
match action { match action {
Airdodge => { Action::AIR_DODGE => {
let expected_status; let expected_status;
let command_flag; let command_flag;
// Shield if grounded instead // Shield if grounded instead
@ -259,31 +199,31 @@ unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor)
return get_flag(module_accessor, expected_status, command_flag); return get_flag(module_accessor, expected_status, command_flag);
} }
Jump => { Action::JUMP => {
return update_jump_flag(module_accessor); return update_jump_flag(module_accessor);
} }
Spotdodge => { Action::SPOT_DODGE => {
return get_flag( return get_flag(
module_accessor, module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE, *FIGHTER_STATUS_KIND_ESCAPE,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE, *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
); );
} }
RollForward => { Action::ROLL_F => {
return get_flag( return get_flag(
module_accessor, module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE_F, *FIGHTER_STATUS_KIND_ESCAPE_F,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F, *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
); );
} }
RollBack => { Action::ROLL_B => {
return get_flag( return get_flag(
module_accessor, module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE_B, *FIGHTER_STATUS_KIND_ESCAPE_B,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B, *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
); );
} }
Shield => { Action::SHIELD => {
/* /*
Doesn't actually cause the shield, but will clear the buffer once shield is possible. Doesn't actually cause the shield, but will clear the buffer once shield is possible.
Shield hold is performed through shield::should_hold_shield and request_shield Shield hold is performed through shield::should_hold_shield and request_shield
@ -300,8 +240,8 @@ unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor)
pub fn request_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { pub fn request_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
match get_current_buffer() { match get_current_buffer() {
Action::Shield => return true, Action::SHIELD => return true,
Action::Airdodge => return is_grounded(module_accessor), Action::AIR_DODGE => return is_grounded(module_accessor),
_ => {} _ => {}
} }
@ -325,44 +265,42 @@ unsafe fn get_attack_flag(
module_accessor: &mut app::BattleObjectModuleAccessor, module_accessor: &mut app::BattleObjectModuleAccessor,
action: Action, action: Action,
) -> i32 { ) -> i32 {
use Action::*;
let command_flag: i32; let command_flag: i32;
let status: i32; let status: i32;
match action { match action {
Nair | Fair | Bair | UpAir | Dair => { Action::NAIR | Action::FAIR | Action::BAIR | Action::UAIR | Action::DAIR => {
return get_aerial_flag(module_accessor, action); return get_aerial_flag(module_accessor, action);
} }
NeutralB => { Action::NEUTRAL_B => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N;
status = *FIGHTER_STATUS_KIND_SPECIAL_N; status = *FIGHTER_STATUS_KIND_SPECIAL_N;
} }
SideB => { Action::SIDE_B => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S;
status = *FIGHTER_STATUS_KIND_SPECIAL_S; status = *FIGHTER_STATUS_KIND_SPECIAL_S;
} }
UpB => { Action::UP_B => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI;
status = *FIGHTER_STATUS_KIND_SPECIAL_HI; status = *FIGHTER_STATUS_KIND_SPECIAL_HI;
} }
DownB => { Action::DOWN_B => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW;
status = *FIGHTER_STATUS_KIND_SPECIAL_LW; status = *FIGHTER_STATUS_KIND_SPECIAL_LW;
} }
UpSmash => { Action::U_SMASH => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4;
status = *FIGHTER_STATUS_KIND_ATTACK_HI4_START; status = *FIGHTER_STATUS_KIND_ATTACK_HI4_START;
} }
FSmash => { Action::F_SMASH => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S4; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S4;
status = *FIGHTER_STATUS_KIND_ATTACK_S4_START; status = *FIGHTER_STATUS_KIND_ATTACK_S4_START;
} }
DSmash => { Action::D_SMASH => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW4; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW4;
status = *FIGHTER_STATUS_KIND_ATTACK_LW4_START; status = *FIGHTER_STATUS_KIND_ATTACK_LW4_START;
} }
Grab => { Action::GRAB => {
let cannot_grab = WorkModule::get_int( let cannot_grab = WorkModule::get_int(
module_accessor, module_accessor,
*FIGHTER_INSTANCE_WORK_ID_INT_INVALID_CATCH_FRAME, *FIGHTER_INSTANCE_WORK_ID_INT_INVALID_CATCH_FRAME,
@ -374,7 +312,7 @@ unsafe fn get_attack_flag(
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH;
status = *FIGHTER_STATUS_KIND_CATCH; status = *FIGHTER_STATUS_KIND_CATCH;
} }
Jab => { Action::JAB => {
// Prevent nair when airborne // Prevent nair when airborne
if !is_grounded(module_accessor) { if !is_grounded(module_accessor) {
return 0; return 0;
@ -383,19 +321,19 @@ unsafe fn get_attack_flag(
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N;
status = *FIGHTER_STATUS_KIND_ATTACK; status = *FIGHTER_STATUS_KIND_ATTACK;
} }
Ftilt => { Action::F_TILT => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S3; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S3;
status = *FIGHTER_STATUS_KIND_ATTACK_S3; status = *FIGHTER_STATUS_KIND_ATTACK_S3;
} }
Utilt => { Action::U_TILT => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI3; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI3;
status = *FIGHTER_STATUS_KIND_ATTACK_HI3; status = *FIGHTER_STATUS_KIND_ATTACK_HI3;
} }
Dtilt => { Action::D_TILT => {
command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW3; command_flag = *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW3;
status = *FIGHTER_STATUS_KIND_ATTACK_LW3; status = *FIGHTER_STATUS_KIND_ATTACK_LW3;
} }
DashAttack => { Action::DASH_ATTACK => {
let current_status = StatusModule::status_kind(module_accessor); let current_status = StatusModule::status_kind(module_accessor);
let is_dashing = current_status == *FIGHTER_STATUS_KIND_DASH; let is_dashing = current_status == *FIGHTER_STATUS_KIND_DASH;
@ -444,14 +382,14 @@ unsafe fn get_aerial_flag(
return flag; return flag;
} }
use Action::*;
/* /*
* We always trigger attack and change it later into the correct aerial * We always trigger attack and change it later into the correct aerial
* @see get_attack_air_kind() * @see get_attack_air_kind()
*/ */
let command_flag: i32 = match action { let command_flag: i32 = match action {
Nair | Fair | Bair | UpAir | Dair => *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N, Action::NAIR | Action::FAIR | Action::BAIR | Action::UAIR | Action::DAIR => {
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N
}
_ => 0, _ => 0,
}; };
@ -509,37 +447,14 @@ fn try_change_status(
pub unsafe fn perform_defensive_option() { pub unsafe fn perform_defensive_option() {
reset(); reset();
let action; let action = match MENU.defensive_state.get_random() {
Defensive::ROLL_F => Action::ROLL_F,
match MENU.defensive_state { Defensive::ROLL_B => Action::ROLL_B,
Defensive::Random => { Defensive::SPOT_DODGE => Action::SPOT_DODGE,
let random_cmds = vec![ Defensive::JAB => Action::JAB,
Mash::Spotdodge, Defensive::SHIELD => Action::SHIELD,
Mash::RollBack, _ => Action::empty(),
Mash::RollForward, };
Mash::Attack,
];
let random_cmd_index = get_random_int(random_cmds.len() as i32) as usize;
action = mash_to_action(random_cmds[random_cmd_index]);
}
Defensive::Roll => {
if get_random_int(2) == 0 {
action = Action::RollForward;
} else {
action = Action::RollBack;
}
}
Defensive::Spotdodge => action = Action::Spotdodge,
Defensive::Jab => {
action = Action::Jab;
}
Defensive::Shield => {
action = Action::Shield;
}
_ => return,
}
buffer_action(action); buffer_action(action);

View file

@ -182,7 +182,7 @@ unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) {
return; return;
} }
let action = mash::buffer_menu_mash(module_accessor); let action = mash::buffer_menu_mash();
if handle_escape_option(fighter, module_accessor) { if handle_escape_option(fighter, module_accessor) {
return; return;
@ -239,19 +239,19 @@ unsafe fn handle_escape_option(
} }
match mash::get_current_buffer() { match mash::get_current_buffer() {
Action::Spotdodge => { Action::SPOT_DODGE => {
fighter fighter
.fighter_base .fighter_base
.change_status(FIGHTER_STATUS_KIND_ESCAPE.as_lua_int(), LUA_TRUE); .change_status(FIGHTER_STATUS_KIND_ESCAPE.as_lua_int(), LUA_TRUE);
return true; return true;
} }
Action::RollForward => { Action::ROLL_F => {
fighter fighter
.fighter_base .fighter_base
.change_status(FIGHTER_STATUS_KIND_ESCAPE_F.as_lua_int(), LUA_TRUE); .change_status(FIGHTER_STATUS_KIND_ESCAPE_F.as_lua_int(), LUA_TRUE);
return true; return true;
} }
Action::RollBack => { Action::ROLL_B => {
fighter fighter
.fighter_base .fighter_base
.change_status(FIGHTER_STATUS_KIND_ESCAPE_B.as_lua_int(), LUA_TRUE); .change_status(FIGHTER_STATUS_KIND_ESCAPE_B.as_lua_int(), LUA_TRUE);
@ -267,7 +267,7 @@ unsafe fn handle_escape_option(
fn needs_oos_handling_drop_shield() -> bool { fn needs_oos_handling_drop_shield() -> bool {
let action = mash::get_current_buffer(); let action = mash::get_current_buffer();
if action == Action::Jump { if action == Action::JUMP {
return true; return true;
} }
@ -275,11 +275,11 @@ fn needs_oos_handling_drop_shield() -> bool {
return true; return true;
} }
if action == Action::UpB { if action == Action::UP_B {
return true; return true;
} }
if action == Action::UpSmash { if action == Action::U_SMASH {
return true; return true;
} }
@ -288,11 +288,11 @@ fn needs_oos_handling_drop_shield() -> bool {
pub fn is_aerial(action: Action) -> bool { pub fn is_aerial(action: Action) -> bool {
match action { match action {
Action::Nair => return true, Action::NAIR => return true,
Action::Fair => return true, Action::FAIR => return true,
Action::Bair => return true, Action::BAIR => return true,
Action::UpAir => return true, Action::UAIR => return true,
Action::Dair => return true, Action::DAIR => return true,
_ => return false, _ => return false,
} }
} }
@ -305,11 +305,14 @@ pub fn suspend_shield(action: Action) {
} }
fn need_suspend_shield(action: Action) -> bool { fn need_suspend_shield(action: Action) -> bool {
if action == Action::empty(){
return false;
}
match action { match action {
Action::UpSmash => false, Action::U_SMASH => false,
Action::Grab => false, Action::GRAB => false,
Action::Shield => false, Action::SHIELD => false,
Action::Nothing => false,
_ => { _ => {
// Force shield drop // Force shield drop
true true