mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-30 22:00:16 +00:00
Add Miss Tech Options; Save States Control bug
This commit is contained in:
parent
4753258874
commit
02f4095c37
9 changed files with 185 additions and 115 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "training_modpack"
|
||||
version = "2.5.0"
|
||||
version = "2.5.3"
|
||||
authors = ["jugeeya <jugeeya@live.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ include $(DEVKITPRO)/libnx/switch_rules
|
|||
# NACP building is skipped as well.
|
||||
#---------------------------------------------------------------------------------
|
||||
APP_TITLE := Training Modpack
|
||||
APP_VERSION := 2.5.2Beta
|
||||
APP_VERSION := 2.5.3Beta
|
||||
|
||||
TARGET := ovlTrainingModpack
|
||||
BUILD := build
|
||||
|
|
61
TrainingModpackOverlay/include/ini_settings.hpp
Normal file
61
TrainingModpackOverlay/include/ini_settings.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include <tesla.hpp>
|
||||
|
||||
static const char* SYSTEM_SETTINGS_FILE = "/atmosphere/config/system_settings.ini";
|
||||
|
||||
static tsl::hlp::ini::IniData readSettings()
|
||||
{
|
||||
/* Open Sd card filesystem. */
|
||||
FsFileSystem fsSdmc;
|
||||
if(R_FAILED(fsOpenSdCardFileSystem(&fsSdmc))) return {};
|
||||
tsl::hlp::ScopeGuard fsGuard([&] { fsFsClose(&fsSdmc); });
|
||||
|
||||
/* Open config file. */
|
||||
FsFile fileConfig;
|
||||
if(R_FAILED(fsFsOpenFile(&fsSdmc, SYSTEM_SETTINGS_FILE, FsOpenMode_Read, &fileConfig))) return {};
|
||||
tsl::hlp::ScopeGuard fileGuard([&] { fsFileClose(&fileConfig); });
|
||||
|
||||
/* Get config file size. */
|
||||
s64 configFileSize;
|
||||
if(R_FAILED(fsFileGetSize(&fileConfig, &configFileSize))) return {};
|
||||
|
||||
/* Read and parse config file. */
|
||||
std::string configFileData(configFileSize, '\0');
|
||||
u64 readSize;
|
||||
Result rc = fsFileRead(&fileConfig, 0, configFileData.data(), configFileSize, FsReadOption_None, &readSize);
|
||||
if(R_FAILED(rc) || readSize != static_cast<u64>(configFileSize)) return {};
|
||||
|
||||
return tsl::hlp::ini::parseIni(configFileData);
|
||||
}
|
||||
|
||||
static void writeSettings(tsl::hlp::ini::IniData const& iniData)
|
||||
{
|
||||
/* Open Sd card filesystem. */
|
||||
FsFileSystem fsSdmc;
|
||||
if(R_FAILED(fsOpenSdCardFileSystem(&fsSdmc))) return;
|
||||
tsl::hlp::ScopeGuard fsGuard([&] { fsFsClose(&fsSdmc); });
|
||||
|
||||
std::string iniString = tsl::hlp::ini::unparseIni(iniData);
|
||||
|
||||
fsFsDeleteFile(&fsSdmc, SYSTEM_SETTINGS_FILE);
|
||||
fsFsCreateFile(&fsSdmc, SYSTEM_SETTINGS_FILE, iniString.length(), 0);
|
||||
|
||||
/* Open config file. */
|
||||
FsFile fileConfig;
|
||||
if(R_FAILED(fsFsOpenFile(&fsSdmc, SYSTEM_SETTINGS_FILE, FsOpenMode_Write, &fileConfig))) return;
|
||||
tsl::hlp::ScopeGuard fileGuard([&] { fsFileClose(&fileConfig); });
|
||||
|
||||
fsFileWrite(&fileConfig, 0, iniString.c_str(), iniString.length(), FsWriteOption_Flush);
|
||||
}
|
||||
|
||||
static void updateSettings(tsl::hlp::ini::IniData const& changes)
|
||||
{
|
||||
tsl::hlp::ini::IniData iniData = readSettings();
|
||||
for(auto& section : changes)
|
||||
{
|
||||
for(auto& keyValue : section.second)
|
||||
{
|
||||
iniData[section.first][keyValue.first] = keyValue.second;
|
||||
}
|
||||
}
|
||||
writeSettings(iniData);
|
||||
}
|
|
@ -114,6 +114,26 @@ options.
|
|||
CPUs will also perform a defensive
|
||||
option after getting up.)"""";
|
||||
|
||||
// Missed Tech Option
|
||||
|
||||
// clang-format off
|
||||
#define ENUM_CLASS_MissTechFlag(type,x) \
|
||||
x(type,Getup,"Normal Getup") \
|
||||
x(type,Attack,"Getup Attack") \
|
||||
x(type,RollF,"RollF") \
|
||||
x(type,RollB,"RollB")
|
||||
|
||||
// clang-format on
|
||||
DEFINE_ENUM_CLASS(MissTechFlag);
|
||||
|
||||
constexpr const char* const miss_tech_help = R""""(
|
||||
CPUs will perform a random
|
||||
option after missing a tech
|
||||
among the selected options.
|
||||
|
||||
CPUs will also perform a defensive
|
||||
option after getting up.)"""";
|
||||
|
||||
// Defensive States
|
||||
|
||||
// clang-format off
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "overlay_frame_with_help.hpp"
|
||||
#include "value_list_item.hpp"
|
||||
#include "clickable_list_item.hpp"
|
||||
#include "ini_settings.hpp"
|
||||
#include "taunt_toggles.hpp"
|
||||
|
||||
static struct TrainingModpackMenu
|
||||
|
@ -18,6 +19,7 @@ static struct TrainingModpackMenu
|
|||
LedgeFlags LEDGE_STATE = LedgeFlags::All;
|
||||
DelayFlags LEDGE_DELAY = DelayFlags::All;
|
||||
TechFlags TECH_STATE = TechFlags::All;
|
||||
MissTechFlags MISS_TECH_STATE = MissTechFlags::All;
|
||||
int SHIELD_STATE = NONE;
|
||||
DefensiveFlags DEFENSIVE_STATE = DefensiveFlags::All;
|
||||
DelayFlags OOS_OFFSET = DelayFlags::None;
|
||||
|
@ -36,69 +38,10 @@ static struct TrainingModpackMenu defaultMenu = menu;
|
|||
static int FRAME_ADVANTAGE = 0;
|
||||
|
||||
u64 pidSmash = 0;
|
||||
static const char* SYSTEM_SETTINGS_FILE = "/atmosphere/config/system_settings.ini";
|
||||
static const char* TRAINING_MOD_LOG = "/TrainingModpack/training_modpack.log";
|
||||
static const char* TRAINING_MOD_FRAME_ADV_LOG = "/TrainingModpack/training_modpack_frame_adv.log";
|
||||
static const char* TRAINING_MOD_CONF = "/TrainingModpack/training_modpack_menu.conf";
|
||||
|
||||
static tsl::hlp::ini::IniData readSettings()
|
||||
{
|
||||
/* Open Sd card filesystem. */
|
||||
FsFileSystem fsSdmc;
|
||||
if(R_FAILED(fsOpenSdCardFileSystem(&fsSdmc))) return {};
|
||||
tsl::hlp::ScopeGuard fsGuard([&] { fsFsClose(&fsSdmc); });
|
||||
|
||||
/* Open config file. */
|
||||
FsFile fileConfig;
|
||||
if(R_FAILED(fsFsOpenFile(&fsSdmc, SYSTEM_SETTINGS_FILE, FsOpenMode_Read, &fileConfig))) return {};
|
||||
tsl::hlp::ScopeGuard fileGuard([&] { fsFileClose(&fileConfig); });
|
||||
|
||||
/* Get config file size. */
|
||||
s64 configFileSize;
|
||||
if(R_FAILED(fsFileGetSize(&fileConfig, &configFileSize))) return {};
|
||||
|
||||
/* Read and parse config file. */
|
||||
std::string configFileData(configFileSize, '\0');
|
||||
u64 readSize;
|
||||
Result rc = fsFileRead(&fileConfig, 0, configFileData.data(), configFileSize, FsReadOption_None, &readSize);
|
||||
if(R_FAILED(rc) || readSize != static_cast<u64>(configFileSize)) return {};
|
||||
|
||||
return tsl::hlp::ini::parseIni(configFileData);
|
||||
}
|
||||
|
||||
static void writeSettings(tsl::hlp::ini::IniData const& iniData)
|
||||
{
|
||||
/* Open Sd card filesystem. */
|
||||
FsFileSystem fsSdmc;
|
||||
if(R_FAILED(fsOpenSdCardFileSystem(&fsSdmc))) return;
|
||||
tsl::hlp::ScopeGuard fsGuard([&] { fsFsClose(&fsSdmc); });
|
||||
|
||||
std::string iniString = tsl::hlp::ini::unparseIni(iniData);
|
||||
|
||||
fsFsDeleteFile(&fsSdmc, SYSTEM_SETTINGS_FILE);
|
||||
fsFsCreateFile(&fsSdmc, SYSTEM_SETTINGS_FILE, iniString.length(), 0);
|
||||
|
||||
/* Open config file. */
|
||||
FsFile fileConfig;
|
||||
if(R_FAILED(fsFsOpenFile(&fsSdmc, SYSTEM_SETTINGS_FILE, FsOpenMode_Write, &fileConfig))) return;
|
||||
tsl::hlp::ScopeGuard fileGuard([&] { fsFileClose(&fileConfig); });
|
||||
|
||||
fsFileWrite(&fileConfig, 0, iniString.c_str(), iniString.length(), FsWriteOption_Flush);
|
||||
}
|
||||
|
||||
static void updateSettings(tsl::hlp::ini::IniData const& changes)
|
||||
{
|
||||
tsl::hlp::ini::IniData iniData = readSettings();
|
||||
for(auto& section : changes)
|
||||
{
|
||||
for(auto& keyValue : section.second)
|
||||
{
|
||||
iniData[section.first][keyValue.first] = keyValue.second;
|
||||
}
|
||||
}
|
||||
writeSettings(iniData);
|
||||
}
|
||||
|
||||
GuiMain::GuiMain()
|
||||
{
|
||||
smInitialize();
|
||||
|
@ -424,6 +367,7 @@ tsl::elm::Element* GuiMain::createUI()
|
|||
list->addItem(createBitFlagOption(&menu.LEDGE_STATE, "Ledge Options", ledge_help, this));
|
||||
list->addItem(createBitFlagOption(&menu.LEDGE_DELAY, "Ledge Delay", ledge_delay_help, this));
|
||||
list->addItem(createBitFlagOption(&menu.TECH_STATE, "Tech Options", tech_help, this));
|
||||
list->addItem(createBitFlagOption(&menu.MISS_TECH_STATE, "Missed Tech Options", miss_tech_help, this));
|
||||
list->addItem(createBitFlagOption(&menu.DEFENSIVE_STATE, "Defensive Options", defensive_help, this));
|
||||
|
||||
list->addItem(new tsl::elm::CategoryHeader("Aerials", true));
|
||||
|
|
|
@ -35,7 +35,7 @@ macro_rules! to_index_impl {
|
|||
|
||||
return self.bits.trailing_zeros();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn random_option<T>(arg: &Vec<T>) -> &T {
|
||||
|
@ -152,6 +152,21 @@ impl TechFlags {
|
|||
get_random_impl! {TechFlags}
|
||||
}
|
||||
|
||||
// Missed Tech Options
|
||||
bitflags! {
|
||||
pub struct MissTechFlags : u32 {
|
||||
const GETUP = 0x1;
|
||||
const ATTACK = 0x2;
|
||||
const ROLL_F = 0x4;
|
||||
const ROLL_B = 0x8;
|
||||
}
|
||||
}
|
||||
|
||||
impl MissTechFlags {
|
||||
to_vec_impl! {MissTechFlags}
|
||||
get_random_impl! {MissTechFlags}
|
||||
}
|
||||
|
||||
/// Shield States
|
||||
#[repr(i32)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
@ -287,7 +302,7 @@ impl BoolFlag {
|
|||
return match *self {
|
||||
BoolFlag::TRUE => true,
|
||||
_ => false,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,6 +317,7 @@ pub struct TrainingModpackMenu {
|
|||
pub ledge_state: LedgeOption,
|
||||
pub ledge_delay: Delay,
|
||||
pub tech_state: TechFlags,
|
||||
pub miss_tech_state: MissTechFlags,
|
||||
pub shield_state: Shield,
|
||||
pub defensive_state: Defensive,
|
||||
pub oos_offset: Delay,
|
||||
|
@ -317,7 +333,7 @@ pub struct TrainingModpackMenu {
|
|||
|
||||
// Fighter Ids
|
||||
#[repr(i32)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FighterId {
|
||||
Player = 0,
|
||||
CPU = 1,
|
||||
|
|
|
@ -15,6 +15,7 @@ pub static mut MENU_STRUCT: consts::TrainingModpackMenu = consts::TrainingModpac
|
|||
ledge_state: LedgeOption::all(),
|
||||
ledge_delay: Delay::empty(),
|
||||
tech_state: TechFlags::all(),
|
||||
miss_tech_state: MissTechFlags::all(),
|
||||
shield_state: Shield::None,
|
||||
defensive_state: Defensive::all(),
|
||||
oos_offset: Delay::empty(),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::common::*;
|
||||
use crate::common::consts::FighterId;
|
||||
use crate::training::reset;
|
||||
use smash::app::{self, lua_bind::*};
|
||||
use smash::hash40;
|
||||
|
@ -19,7 +19,7 @@ struct SavedState {
|
|||
percent: f32,
|
||||
lr: f32,
|
||||
situation_kind: i32,
|
||||
state: SaveState
|
||||
state: SaveState,
|
||||
}
|
||||
|
||||
macro_rules! default_save_state {
|
||||
|
@ -30,9 +30,9 @@ macro_rules! default_save_state {
|
|||
percent: 0.0,
|
||||
lr: 1.0,
|
||||
situation_kind: 0,
|
||||
state: NoAction
|
||||
}
|
||||
state: NoAction,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
use SaveState::*;
|
||||
|
@ -69,7 +69,9 @@ pub unsafe fn get_param_int(
|
|||
pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
let save_state: &mut SavedState;
|
||||
if is_operation_cpu(module_accessor) {
|
||||
if WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID)
|
||||
== FighterId::CPU as i32
|
||||
{
|
||||
save_state = &mut SAVE_STATE_CPU;
|
||||
} else {
|
||||
save_state = &mut SAVE_STATE_PLAYER;
|
||||
|
@ -107,7 +109,11 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
ControlModule::stop_rumble(module_accessor, true);
|
||||
SoundModule::stop_all_sound(module_accessor);
|
||||
|
||||
StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_DEAD, false);
|
||||
StatusModule::change_status_request(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_DEAD,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,12 +148,18 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
}
|
||||
} else if save_state.situation_kind == SITUATION_KIND_AIR {
|
||||
if status != FIGHTER_STATUS_KIND_FALL {
|
||||
StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_FALL, false);
|
||||
StatusModule::change_status_request(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_FALL,
|
||||
false,
|
||||
);
|
||||
} else {
|
||||
save_state.state = NoAction;
|
||||
}
|
||||
} else if save_state.situation_kind == SITUATION_KIND_CLIFF {
|
||||
if status != FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE && status != FIGHTER_STATUS_KIND_CLIFF_CATCH {
|
||||
if status != FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE
|
||||
&& status != FIGHTER_STATUS_KIND_CLIFF_CATCH
|
||||
{
|
||||
StatusModule::change_status_request(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE,
|
||||
|
|
|
@ -8,7 +8,8 @@ use smash::lib::lua_const::*;
|
|||
use smash::lib::L2CValue;
|
||||
use smash::lua2cpp::L2CFighterBase;
|
||||
|
||||
static mut ROLL_DIRECTION: Direction = Direction::empty();
|
||||
static mut TECH_ROLL_DIRECTION: Direction = Direction::empty();
|
||||
static mut MISS_TECH_ROLL_DIRECTION: Direction = Direction::empty();
|
||||
|
||||
#[skyline::hook(replace = smash::lua2cpp::L2CFighterBase_change_status)]
|
||||
pub unsafe fn handle_change_status(
|
||||
|
@ -45,32 +46,42 @@ unsafe fn mod_handle_change_status(
|
|||
{
|
||||
let state: TechFlags = MENU.tech_state.get_random();
|
||||
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_PASSIVE,
|
||||
) {
|
||||
match state {
|
||||
TechFlags::IN_PLACE => {
|
||||
*status_kind = FIGHTER_STATUS_KIND_PASSIVE.as_lua_int();
|
||||
*unk = LUA_TRUE;
|
||||
mash::perform_defensive_option();
|
||||
}
|
||||
TechFlags::ROLL_F => {
|
||||
*status_kind = FIGHTER_STATUS_KIND_PASSIVE_FB.as_lua_int();
|
||||
*unk = LUA_TRUE;
|
||||
ROLL_DIRECTION = Direction::IN; // = In
|
||||
TECH_ROLL_DIRECTION = Direction::IN; // = In
|
||||
mash::perform_defensive_option();
|
||||
}
|
||||
TechFlags::ROLL_B => {
|
||||
*status_kind = FIGHTER_STATUS_KIND_PASSIVE_FB.as_lua_int();
|
||||
*unk = LUA_TRUE;
|
||||
ROLL_DIRECTION = Direction::OUT; // = Away
|
||||
TECH_ROLL_DIRECTION = Direction::OUT; // = Away
|
||||
mash::perform_defensive_option();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
mash::perform_defensive_option();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Wall Tech
|
||||
if status_kind_int == *FIGHTER_STATUS_KIND_STOP_WALL
|
||||
|| status_kind_int == *FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_LR
|
||||
if (status_kind_int == *FIGHTER_STATUS_KIND_STOP_WALL
|
||||
|| status_kind_int == *FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_LR)
|
||||
&& WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_PASSIVE_CEIL,
|
||||
)
|
||||
{
|
||||
*status_kind = FIGHTER_STATUS_KIND_PASSIVE_WALL.as_lua_int();
|
||||
*unk = LUA_TRUE;
|
||||
|
@ -78,8 +89,12 @@ unsafe fn mod_handle_change_status(
|
|||
}
|
||||
|
||||
// Ceiling Tech
|
||||
if status_kind_int == *FIGHTER_STATUS_KIND_STOP_CEIL
|
||||
|| status_kind_int == *FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_U
|
||||
if (status_kind_int == *FIGHTER_STATUS_KIND_STOP_CEIL
|
||||
|| status_kind_int == *FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_U)
|
||||
&& WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_PASSIVE_WALL,
|
||||
)
|
||||
{
|
||||
*status_kind = FIGHTER_STATUS_KIND_PASSIVE_CEIL.as_lua_int();
|
||||
*unk = LUA_TRUE;
|
||||
|
@ -87,9 +102,7 @@ unsafe fn mod_handle_change_status(
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) {
|
||||
pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
@ -106,18 +119,23 @@ pub unsafe fn get_command_flag_cat(
|
|||
]
|
||||
.contains(&status)
|
||||
{
|
||||
let random_statuses = vec![
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND, // Normal Getup
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_FB, // Getup Roll
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK, // Getup Attack
|
||||
];
|
||||
let status = match MENU.miss_tech_state.get_random() {
|
||||
MissTechFlags::GETUP => *FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
MissTechFlags::ATTACK => *FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK,
|
||||
MissTechFlags::ROLL_F => {
|
||||
MISS_TECH_ROLL_DIRECTION = Direction::IN; // = In
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_FB
|
||||
}
|
||||
MissTechFlags::ROLL_B => {
|
||||
MISS_TECH_ROLL_DIRECTION = Direction::OUT; // = Away
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_FB
|
||||
}
|
||||
_ => *FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
};
|
||||
|
||||
let random_status_index = get_random_int(random_statuses.len() as i32) as usize;
|
||||
StatusModule::change_status_request_from_script(
|
||||
module_accessor,
|
||||
random_statuses[random_status_index],
|
||||
false,
|
||||
);
|
||||
StatusModule::change_status_request_from_script(module_accessor, status, false);
|
||||
|
||||
mash::perform_defensive_option();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -134,22 +152,20 @@ pub unsafe fn change_motion(
|
|||
return None;
|
||||
}
|
||||
|
||||
let random_roll = get_random_int(2);
|
||||
|
||||
if [hash40("passive_stand_f"), hash40("passive_stand_b")].contains(&motion_kind) {
|
||||
if ROLL_DIRECTION == Direction::IN {
|
||||
if TECH_ROLL_DIRECTION == Direction::IN {
|
||||
return Some(hash40("passive_stand_f"));
|
||||
} else {
|
||||
return Some(hash40("passive_stand_b"));
|
||||
}
|
||||
} else if [hash40("down_forward_u"), hash40("down_back_u")].contains(&motion_kind) {
|
||||
if random_roll != 0 {
|
||||
if MISS_TECH_ROLL_DIRECTION == Direction::IN {
|
||||
return Some(hash40("down_forward_u"));
|
||||
} else {
|
||||
return Some(hash40("down_back_u"));
|
||||
}
|
||||
} else if [hash40("down_forward_d"), hash40("down_back_d")].contains(&motion_kind) {
|
||||
if random_roll != 0 {
|
||||
if MISS_TECH_ROLL_DIRECTION == Direction::IN {
|
||||
return Some(hash40("down_forward_d"));
|
||||
} else {
|
||||
return Some(hash40("down_back_d"));
|
||||
|
|
Loading…
Reference in a new issue