diff --git a/Cargo.toml b/Cargo.toml index c37ba55..1fb0b35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "training_modpack" -version = "2.5.0" +version = "2.5.3" authors = ["jugeeya "] edition = "2018" diff --git a/TrainingModpackOverlay/Makefile b/TrainingModpackOverlay/Makefile index 1c39fd0..53f34e5 100644 --- a/TrainingModpackOverlay/Makefile +++ b/TrainingModpackOverlay/Makefile @@ -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 diff --git a/TrainingModpackOverlay/include/ini_settings.hpp b/TrainingModpackOverlay/include/ini_settings.hpp new file mode 100644 index 0000000..54c827a --- /dev/null +++ b/TrainingModpackOverlay/include/ini_settings.hpp @@ -0,0 +1,61 @@ +#include + +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(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); +} \ No newline at end of file diff --git a/TrainingModpackOverlay/include/taunt_toggles.hpp b/TrainingModpackOverlay/include/taunt_toggles.hpp index 76b25d7..92aa7ee 100644 --- a/TrainingModpackOverlay/include/taunt_toggles.hpp +++ b/TrainingModpackOverlay/include/taunt_toggles.hpp @@ -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 @@ -200,7 +220,7 @@ are saved: - Position - Facing direction)""""; -const std::string reset_menu_help = R""""( +const std::string reset_menu_help = R""""( Reset menu to default configuration. Please also use on the first boot after @@ -243,7 +263,7 @@ in frames. Used to delay OOS Options.)""""; -const std::string shield_tilt_help = R""""( +const std::string shield_tilt_help = R""""( Shield Tilt Direction )""""; diff --git a/TrainingModpackOverlay/source/gui_main.cpp b/TrainingModpackOverlay/source/gui_main.cpp index 8e552ce..96ee1e7 100644 --- a/TrainingModpackOverlay/source/gui_main.cpp +++ b/TrainingModpackOverlay/source/gui_main.cpp @@ -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(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)); diff --git a/src/common/consts.rs b/src/common/consts.rs index f1bbc4a..b3c587b 100644 --- a/src/common/consts.rs +++ b/src/common/consts.rs @@ -35,7 +35,7 @@ macro_rules! to_index_impl { return self.bits.trailing_zeros(); } - } + }; } pub fn random_option(arg: &Vec) -> &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, diff --git a/src/common/mod.rs b/src/common/mod.rs index a18d7da..e655268 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -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(), diff --git a/src/training/save_states.rs b/src/training/save_states.rs index c407c16..30526d6 100644 --- a/src/training/save_states.rs +++ b/src/training/save_states.rs @@ -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, diff --git a/src/training/tech.rs b/src/training/tech.rs index 7b9f9a3..2117f2c 100644 --- a/src/training/tech.rs +++ b/src/training/tech.rs @@ -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(); - match state { - TechFlags::IN_PLACE => { - *status_kind = FIGHTER_STATUS_KIND_PASSIVE.as_lua_int(); - *unk = LUA_TRUE; + 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; + 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; + TECH_ROLL_DIRECTION = Direction::OUT; // = Away + 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 - } - TechFlags::ROLL_B => { - *status_kind = FIGHTER_STATUS_KIND_PASSIVE_FB.as_lua_int(); - *unk = LUA_TRUE; - ROLL_DIRECTION = Direction::OUT; // = Away - } - _ => (), } - 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"));