1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-20 00:46:34 +00:00

Bit Flag Refactors: Delay, Direction (#137)

* Cleanup

* Add Bit Flag

Directions

* Apply Bit Flag

Delay options

* Version +
This commit is contained in:
sidschingis 2020-08-15 17:52:29 +02:00 committed by GitHub
parent c46e1642d5
commit da66544104
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 178 additions and 215 deletions

View file

@ -38,7 +38,7 @@ include $(DEVKITPRO)/libnx/switch_rules
# NACP building is skipped as well.
#---------------------------------------------------------------------------------
APP_TITLE := Training Modpack
APP_VERSION := 2.5beta
APP_VERSION := 2.6beta
TARGET := ovlTrainingModpack
BUILD := build

View file

@ -22,16 +22,25 @@ TODO)"""";
*/
/* DI */
#define DI_RANDOM_IN_AWAY 9
const std::vector<std::string> di_items{"None", "Out", "Up Out", "Up", "Up In", "In", "Down In", "Down", "Down Out", "Random"};
// clang-format off
#define ENUM_CLASS_Direction(type,x) \
x(type,Out,"Out") \
x(type,UpOut,"Up Out") \
x(type,Up,"Up") \
x(type,UpIn,"Up In") \
x(type,In,"In") \
x(type,DownIn,"Down In") \
x(type,Down,"Down") \
x(type,DownOut,"Down Out")\
x(type,Nothing,"Neutral")
DEFINE_ENUM_CLASS(Direction);
const std::string di_help = R""""(
Specified Direction
CPUs DI in the direction specified
(relative to the player's facing
position).
Random Direction
CPUs DI randomly in or away.)"""";
)"""";
// Left Stick
const std::string left_stick_help = R""""(
@ -46,41 +55,6 @@ Currently only used for
)"""";
// Attack Option
#define MASH_NAIR 0
#define MASH_FAIR 1
#define MASH_BAIR 2
#define MASH_UPAIR 3
#define MASH_DAIR 4
#define MASH_NEUTRAL_B 5
#define MASH_SIDE_B 6
#define MASH_UP_B 7
#define MASH_DOWN_B 8
#define MASH_U_SMASH 9
#define MASH_GRAB 10
const std::vector<std::string> attack_items{"Neutral Air",
"Forward Air",
"Back Air",
"Up Air",
"Down Air",
"Neutral B",
"Side B",
"Up B",
"Down B",
"Up Smash",
"F Smash",
"D Smash",
"Grab",
"Jab",
"Ftilt",
"Utilt",
"Dtilt",
"Dash Attack"};
const std::string attack_help = R""""(
Only active when Mash Toggle is
set to Attack.
)"""";
// Ledge Option
// clang-format off
#define ENUM_CLASS_LedgeFlag(type,x) \
@ -148,14 +122,6 @@ Specific options include:
)"""";
// Mash States
#define MASH_AIRDODGE 1
#define MASH_JUMP 2
#define MASH_ATTACK 3
#define MASH_SPOTDODGE 4
#define MASH_ROLL_F 5
#define MASH_ROLL_B 6
#define MASH_RANDOM 7
const std::vector<std::string> mash_items{"None", "Airdodge", "Jump", "Attack", "Spotdodge", "Roll F", "Roll B", "Random"};
const std::string mash_help = R""""(
Use this toggle along with the Shield
Options toggle to practice moves on
@ -169,17 +135,7 @@ Airdodge
CPUs will also shield quickly if they
are hit and remain grounded.
Jump
- Hitstun, shieldstun
Attack
- Hitstun, shieldstun, landing.
Spotdodge
- Hitstun, shieldstun, landing.
Random
- Hitstun, shieldstun, landing.)"""";
)"""";
// Action items (Follow Up only atm)
@ -246,18 +202,6 @@ are saved:
- Facing direction)"""";
// OOS
const std::vector<std::string> number_list{
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
};
const std::string oos_help = R""""(
Option to delay oos options
until a certain number of hits
@ -280,7 +224,12 @@ Force mash options to
always occur, not just
out of specific states.)"""";
const std::vector<std::string> number_list_big{
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
"15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
};
#define ENUM_CLASS_DelayFlag(type,x) \
x(type,D0,"0") \
x(type,D1,"1") x(type,D2,"2") x(type,D3,"3") x(type,D4,"4") x(type,D5,"5") \
x(type,D6,"6") x(type,D7,"7") x(type,D8,"8") x(type,D9,"9") x(type,D10,"10") \
x(type,D11,"11") x(type,D12,"12") x(type,D13,"13") x(type,D14,"14") x(type,D15,"15") \
x(type,D16,"16") x(type,D17,"17") x(type,D18,"18") x(type,D19,"19") x(type,D20,"20")
// clang-format on
DEFINE_ENUM_CLASS(DelayFlag);

View file

@ -8,19 +8,19 @@
static struct TrainingModpackMenu
{
int HITBOX_VIS = true;
int DI_STATE = NONE;
int LEFT_STICK = NONE;
Directions DI_STATE = Directions::None;
Directions LEFT_STICK = Directions::None;
ActionFlags MASH_STATE = ActionFlags::None;
ActionFlags FOLLOW_UP = ActionFlags::None;
LedgeFlags LEDGE_STATE = LedgeFlags::All;
TechFlags TECH_STATE = TechFlags::All;
int SHIELD_STATE = NONE;
DefensiveFlags DEFENSIVE_STATE = DefensiveFlags::All;
int OOS_OFFSET = 0;
int REACTION_TIME = 0;
DelayFlags OOS_OFFSET = DelayFlags::None;
DelayFlags REACTION_TIME = DelayFlags::None;
int MASH_IN_NEUTRAL = false;
int FAST_FALL = false;
int FAST_FALL_DELAY = 0;
DelayFlags FAST_FALL_DELAY = DelayFlags::None;
int FALLING_AERIALS = false;
int FULL_HOP = false;
} menu;
@ -404,32 +404,19 @@ tsl::elm::Element* GuiMain::createUI()
list->addItem(createBitFlagOption(&menu.DEFENSIVE_STATE, "Defensive Options", defensive_help));
ValueListItem* diItem = new ValueListItem("Set DI", di_items, &menu.DI_STATE, "di", di_help);
list->addItem(diItem);
valueListItems.push_back(diItem);
list->addItem(createBitFlagOption(&menu.DI_STATE, "Set DI", di_help));
ValueListItem* leftStickItem =
new ValueListItem("Left Stick", di_items, &menu.LEFT_STICK, "leftStick", left_stick_help);
list->addItem(leftStickItem);
valueListItems.push_back(leftStickItem);
list->addItem(createBitFlagOption(&menu.LEFT_STICK, "Left Stick", left_stick_help));
ValueListItem* oosOffsetItem = new ValueListItem("OOS Offset", number_list, &menu.OOS_OFFSET, "oos", oos_help);
list->addItem(oosOffsetItem);
valueListItems.push_back(oosOffsetItem);
list->addItem(createBitFlagOption(&menu.OOS_OFFSET, "OOS Offset", oos_help));
ValueListItem* reactionTime =
new ValueListItem("Reaction Time", number_list_big, &menu.REACTION_TIME, "reaction_time", reaction_time_help);
list->addItem(reactionTime);
valueListItems.push_back(reactionTime);
list->addItem(createBitFlagOption(&menu.REACTION_TIME, "Reaction Time", reaction_time_help));
ValueListItem* fastFallItem = new ValueListItem("Fast Fall", on_off, &menu.FAST_FALL, "fast_fall", "");
list->addItem(fastFallItem);
valueListItems.push_back(fastFallItem);
ValueListItem* fastFallDelay =
new ValueListItem("Fast Fall Delay", number_list_big, &menu.FAST_FALL_DELAY, "fast_fall", "In Frames");
list->addItem(fastFallDelay);
valueListItems.push_back(fastFallDelay);
list->addItem(createBitFlagOption(&menu.FAST_FALL_DELAY, "Fast Fall Delay", "In Frames"));
ValueListItem* fallingAerialsItem =
new ValueListItem("Falling Aerials", on_off, &menu.FALLING_AERIALS, "falling_aerials", "");

View file

@ -10,56 +10,6 @@ pub enum HitboxVisualization {
On = 1,
}
// DI
/*
0, 0.785398, 1.570796, 2.356194, -3.14159, -2.356194, -1.570796, -0.785398
0, pi/4, pi/2, 3pi/4, pi, 5pi/4, 3pi/2, 7pi/4
*/
/// DI
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Direction {
None = 0,
Right = 1,
UpRight = 2,
Up = 3,
UpLeft = 4,
Left = 5,
DownLeft = 6,
Down = 7,
DownRight = 8,
// lol what goes here jug smh my head
Random = 9,
}
impl From<i32> for Direction {
fn from(x: i32) -> Self {
match x {
0 => Direction::None,
1 => Direction::Right,
2 => Direction::UpRight,
3 => Direction::Up,
4 => Direction::UpLeft,
5 => Direction::Left,
6 => Direction::DownLeft,
7 => Direction::Down,
8 => Direction::DownRight,
9 => Direction::Random,
_ => panic!("Invalid direction {}", x),
}
}
}
pub static ANGLE_NONE: f64 = -69.0;
pub fn direction_to_angle(direction: Direction) -> f64 {
match direction {
Direction::None => ANGLE_NONE,
Direction::Random => ANGLE_NONE, // Random Direction should be handled by the calling context
_ => (direction as i32 - 1) as f64 * PI / 4.0,
}
}
// bitflag helper function macro
macro_rules! to_vec_impl {
($e:ty) => {
@ -76,6 +26,22 @@ macro_rules! to_vec_impl {
}
}
macro_rules! to_index_impl {
($e:ty) => {
pub fn to_index(&self) -> u32 {
if self.bits == 0 {
return 0;
}
return self.bits.trailing_zeros();
}
}
}
pub fn random_option<T>(arg: &Vec<T>) -> &T {
return &arg[get_random_int(arg.len() as i32) as usize];
}
macro_rules! get_random_impl {
($e:ty) => {
pub fn get_random(&self) -> $e {
@ -92,9 +58,60 @@ macro_rules! get_random_impl {
}
}
}
};
}
// DI
/*
0, 0.785398, 1.570796, 2.356194, -3.14159, -2.356194, -1.570796, -0.785398
0, pi/4, pi/2, 3pi/4, pi, 5pi/4, 3pi/2, 7pi/4
*/
// DI / Left stick
bitflags! {
pub struct Direction : u32
{
const OUT = 0x1;
const UP_OUT = 0x2;
const UP = 0x4;
const UP_IN = 0x8;
const IN = 0x10;
const DOWN_IN = 0x20;
const DOWN = 0x40;
const DOWN_OUT = 0x80;
const NEUTRAL = 0x100;
}
}
impl Direction {
pub fn into_angle(&self) -> f64 {
let index = self.into_index();
if index == 0 {
return ANGLE_NONE;
}
(index as i32 - 1) as f64 * PI / 4.0
}
fn into_index(&self) -> i32 {
return match *self {
Direction::OUT => 1,
Direction::UP_OUT => 2,
Direction::UP => 3,
Direction::UP_IN => 4,
Direction::IN => 5,
Direction::DOWN_IN => 6,
Direction::DOWN => 7,
Direction::DOWN_OUT => 8,
__ => 0,
};
}
to_vec_impl! {Direction}
get_random_impl! {Direction}
}
pub static ANGLE_NONE: f64 = -69.0;
// Ledge Option
bitflags! {
pub struct LedgeOption : u32
@ -106,10 +123,6 @@ bitflags! {
}
}
pub fn random_option<T>(arg: &Vec<T>) -> &T {
return &arg[get_random_int(arg.len() as i32) as usize];
}
impl LedgeOption {
pub fn into_status(&self) -> Option<i32> {
Some(match *self {
@ -215,6 +228,40 @@ impl Action {
get_random_impl! {Action}
}
bitflags! {
pub struct Delay : u32 {
const D0 = 0x1;
const D1 = 0x2;
const D2 = 0x4;
const D3 = 0x8;
const D4 = 0x10;
const D5 = 0x20;
const D6 = 0x40;
const D7 = 0x80;
const D8 = 0x100;
const D9 = 0x200;
const D10 = 0x400;
const D11 = 0x800;
const D12 = 0x1000;
const D13 = 0x2000;
const D14 = 0x4000;
const D15 = 0x8000;
const D16 = 0x10000;
const D17 = 0x20000;
const D18 = 0x40000;
const D19 = 0x80000;
const D20 = 0x100000;
}
}
// https://stackoverflow.com/a/757266
impl Delay {
to_vec_impl! {Delay}
get_random_impl! {Delay}
to_index_impl! {Delay}
}
#[repr(C)]
pub struct TrainingModpackMenu {
pub hitbox_vis: HitboxVisualization,
@ -226,11 +273,11 @@ pub struct TrainingModpackMenu {
pub tech_state: TechFlags,
pub shield_state: Shield,
pub defensive_state: Defensive,
pub oos_offset: u32,
pub reaction_time: u32,
pub oos_offset: Delay,
pub reaction_time: Delay,
pub mash_in_neutral: OnOff,
pub fast_fall: OnOff,
pub fast_fall_delay: u32,
pub fast_fall_delay: Delay,
pub falling_aerials: OnOff,
pub full_hop: OnOff,
}

View file

@ -7,19 +7,19 @@ use smash::lib::lua_const::*;
pub static mut MENU_STRUCT: consts::TrainingModpackMenu = consts::TrainingModpackMenu {
hitbox_vis: HitboxVisualization::On,
di_state: Direction::None,
left_stick: Direction::None,
di_state: Direction::empty(),
left_stick: Direction::empty(),
mash_state: Action::empty(),
follow_up: Action::empty(),
ledge_state: LedgeOption::all(),
tech_state: TechFlags::all(),
shield_state: Shield::None,
defensive_state: Defensive::all(),
oos_offset: 0,
reaction_time: 0,
oos_offset: Delay::empty(),
reaction_time: Delay::empty(),
mash_in_neutral: OnOff::Off,
fast_fall: OnOff::Off,
fast_fall_delay: 0,
fast_fall_delay: Delay::empty(),
falling_aerials: OnOff::Off,
full_hop: OnOff::Off,
};

View file

@ -20,7 +20,7 @@ unsafe fn mod_handle_di(fighter: &mut L2CFighterCommon, _arg1: L2CValue) {
return;
}
if MENU.di_state == Direction::None {
if MENU.di_state == Direction::empty() {
return;
}
@ -30,7 +30,7 @@ unsafe fn mod_handle_di(fighter: &mut L2CFighterCommon, _arg1: L2CValue) {
}
// Either left, right, or none
let mut angle = get_angle(MENU.di_state);
let mut angle = MENU.di_state.get_random().into_angle();
// Nothing to do on no DI
if angle == ANGLE_NONE {
return;
@ -53,23 +53,3 @@ unsafe fn mod_handle_di(fighter: &mut L2CFighterCommon, _arg1: L2CValue) {
);
}
unsafe fn get_angle(direction: Direction) -> f64 {
if direction == Direction::Random {
let rand_direction = get_random_direction();
return direction_to_angle(rand_direction);
}
direction_to_angle(direction)
}
unsafe fn get_random_direction() -> Direction {
// Choose Left/Right/None
let rand = get_random_int(3);
if rand == 0 {
Direction::Left
} else if rand == 1 {
Direction::Right
} else {
Direction::None
}
}

View file

@ -7,6 +7,9 @@ use smash::phx::{Hash40, Vector3f};
static mut FRAME_COUNTER: usize = 0;
// The current fastfall delay
static mut DELAY: u32 = 0;
pub fn init() {
unsafe {
FRAME_COUNTER = frame_counter::register_counter();
@ -40,6 +43,8 @@ pub unsafe fn get_command_flag_cat(
// Need to be falling
if !is_falling(module_accessor) {
// Roll FF delay
DELAY = MENU.fast_fall_delay.get_random().to_index();
frame_counter::full_reset(FRAME_COUNTER);
return;
}
@ -54,7 +59,7 @@ pub unsafe fn get_command_flag_cat(
}
// Check delay
if frame_counter::should_delay(MENU.fast_fall_delay, FRAME_COUNTER) {
if frame_counter::should_delay(DELAY, FRAME_COUNTER) {
return;
}

View file

@ -4,7 +4,7 @@ use core::f64::consts::PI;
use smash::app::{self, lua_bind::*};
use smash::lib::lua_const::*;
static mut STICK_DIRECTION: Direction = Direction::None;
static mut STICK_DIRECTION: Direction = Direction::empty();
pub unsafe fn mod_get_stick_x(
module_accessor: &mut app::BattleObjectModuleAccessor,
@ -44,8 +44,8 @@ unsafe fn get_angle(module_accessor: &mut app::BattleObjectModuleAccessor) -> f6
return ANGLE_NONE;
}
STICK_DIRECTION = MENU.left_stick;
let mut angle: f64 = pick_angle(STICK_DIRECTION);
STICK_DIRECTION = MENU.left_stick.get_random();
let mut angle: f64 = STICK_DIRECTION.into_angle();
if angle == ANGLE_NONE {
return ANGLE_NONE;
@ -74,18 +74,4 @@ fn is_correct_status(module_accessor: &mut app::BattleObjectModuleAccessor) -> b
}
return false;
}
fn pick_angle(direction: Direction) -> f64 {
if direction == Direction::Random {
let rand_direction = get_random_direction();
return direction_to_angle(rand_direction);
}
direction_to_angle(direction)
}
fn get_random_direction() -> Direction {
let rand = get_random_int(8);
Direction::from(rand)
}
}

View file

@ -11,7 +11,11 @@ use smash::lib::L2CValue;
use smash::lua2cpp::L2CFighterCommon;
// How many hits to hold shield until picking an Out Of Shield option
static mut MULTI_HIT_OFFSET: u32 = unsafe { MENU.oos_offset };
static mut MULTI_HIT_OFFSET: u32 = 0;
// The current set delay
static mut SHIELD_DELAY: u32 = 0;
// Used to only decrease once per shieldstun change
static mut WAS_IN_SHIELDSTUN: bool = false;
@ -37,12 +41,14 @@ unsafe fn should_pause_shield_decay() -> bool {
!SHIELD_DECAY
}
unsafe fn reset_oos_offset() {
/*
* Need to offset by 1, since we decrease as soon as shield gets hit
* but only check later if we can OOS
*/
MULTI_HIT_OFFSET = MENU.oos_offset + 1;
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
*/
MULTI_HIT_OFFSET = MENU.oos_offset.get_random().to_index() + 1;
}
}
unsafe fn handle_oos_offset(module_accessor: &mut app::BattleObjectModuleAccessor) {
@ -58,6 +64,9 @@ unsafe fn handle_oos_offset(module_accessor: &mut app::BattleObjectModuleAccesso
return;
}
// Roll shield delay
SHIELD_DELAY = MENU.reaction_time.get_random().to_index();
// Decrease offset once if needed
if MULTI_HIT_OFFSET > 0 {
MULTI_HIT_OFFSET -= 1;
@ -178,7 +187,7 @@ unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) {
return;
}
if frame_counter::should_delay(MENU.reaction_time, REACTION_INDEX) {
if frame_counter::should_delay(SHIELD_DELAY, REACTION_INDEX) {
return;
}
@ -305,7 +314,7 @@ pub fn suspend_shield(action: Action) {
}
fn need_suspend_shield(action: Action) -> bool {
if action == Action::empty(){
if action == Action::empty() {
return false;
}

View file

@ -8,7 +8,7 @@ use smash::lib::lua_const::*;
use smash::lib::L2CValue;
use smash::lua2cpp::L2CFighterBase;
static mut ROLL_DIRECTION: Direction = Direction::None;
static mut ROLL_DIRECTION: Direction = Direction::empty();
#[skyline::hook(replace = smash::lua2cpp::L2CFighterBase_change_status)]
pub unsafe fn handle_change_status(
@ -55,12 +55,12 @@ unsafe fn mod_handle_change_status(
TechFlags::ROLL_F => {
*status_kind = FIGHTER_STATUS_KIND_PASSIVE_FB.as_lua_int();
*unk = LUA_TRUE;
ROLL_DIRECTION = Direction::Left; // = In
ROLL_DIRECTION = Direction::IN; // = In
}
TechFlags::ROLL_B => {
*status_kind = FIGHTER_STATUS_KIND_PASSIVE_FB.as_lua_int();
*unk = LUA_TRUE;
ROLL_DIRECTION = Direction::Right; // = Away
ROLL_DIRECTION = Direction::OUT; // = Away
}
_ => (),
}
@ -148,7 +148,7 @@ pub unsafe fn change_motion(
let random_roll = get_random_int(2);
if [hash40("passive_stand_f"), hash40("passive_stand_b")].contains(&motion_kind) {
if ROLL_DIRECTION == Direction::Left {
if ROLL_DIRECTION == Direction::IN {
return Some(hash40("passive_stand_f"));
} else {
return Some(hash40("passive_stand_b"));