1
0
Fork 0
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:
jugeeya 2020-08-29 11:03:33 -07:00
parent 4753258874
commit 02f4095c37
9 changed files with 185 additions and 115 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "training_modpack"
version = "2.5.0"
version = "2.5.3"
authors = ["jugeeya <jugeeya@live.com>"]
edition = "2018"

View file

@ -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

View 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);
}

View file

@ -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

View file

@ -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));

View file

@ -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,

View file

@ -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(),

View file

@ -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,

View file

@ -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"));