mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-24 02:44:17 +00:00
Make it more intuitive for devs to add new menu items (#709)
* Rework how we set up the menu so we only have to write the fn once * Clippy warnings
This commit is contained in:
parent
858d35142e
commit
cb6ca02f3a
5 changed files with 595 additions and 742 deletions
|
@ -139,13 +139,13 @@ fn get_release(beta: bool) -> Result<Release> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if beta && beta_release.is_some() {
|
if beta {
|
||||||
Ok(beta_release.unwrap())
|
beta_release.ok_or(anyhow!(
|
||||||
} else if !beta && stable_release.is_some() {
|
"The specified beta release was not found in the GitHub JSON response!"
|
||||||
Ok(stable_release.unwrap())
|
))
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!(
|
stable_release.ok_or(anyhow!(
|
||||||
"The specified release was not found in the GitHub JSON response!"
|
"The specified stable release was not found in the GitHub JSON response!"
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -580,8 +580,8 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
||||||
SaveDamage::RANDOM => {
|
SaveDamage::RANDOM => {
|
||||||
// Gen random value
|
// Gen random value
|
||||||
let pct: f32 = get_random_float(
|
let pct: f32 = get_random_float(
|
||||||
read(&MENU).save_damage_limits_player.0 as f32,
|
read(&MENU).save_damage_limits_player.LOWER as f32,
|
||||||
read(&MENU).save_damage_limits_player.1 as f32,
|
read(&MENU).save_damage_limits_player.UPPER as f32,
|
||||||
);
|
);
|
||||||
set_damage(module_accessor, pct);
|
set_damage(module_accessor, pct);
|
||||||
}
|
}
|
||||||
|
@ -599,8 +599,8 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
||||||
SaveDamage::RANDOM => {
|
SaveDamage::RANDOM => {
|
||||||
// Gen random value
|
// Gen random value
|
||||||
let pct: f32 = get_random_float(
|
let pct: f32 = get_random_float(
|
||||||
read(&MENU).save_damage_limits_cpu.0 as f32,
|
read(&MENU).save_damage_limits_cpu.UPPER as f32,
|
||||||
read(&MENU).save_damage_limits_cpu.1 as f32,
|
read(&MENU).save_damage_limits_cpu.LOWER as f32,
|
||||||
);
|
);
|
||||||
set_damage(module_accessor, pct);
|
set_damage(module_accessor, pct);
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,7 @@ unsafe fn handle_layout_arc_malloc(ctx: &mut skyline::hooks::InlineCtx) {
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(idx, byte)| LAYOUT_ARC[idx] = *byte);
|
.for_each(|(idx, byte)| LAYOUT_ARC[idx] = *byte);
|
||||||
|
#[allow(static_mut_refs)]
|
||||||
inject_arc = LAYOUT_ARC.as_ptr();
|
inject_arc = LAYOUT_ARC.as_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,67 +1,97 @@
|
||||||
|
use crate::TOGGLE_MAX;
|
||||||
use byteflags::*;
|
use byteflags::*;
|
||||||
use core::f64::consts::PI;
|
use core::f64::consts::PI;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
#[cfg(feature = "smash")]
|
#[cfg(feature = "smash")]
|
||||||
use smash::lib::lua_const::*;
|
use smash::lib::lua_const::*;
|
||||||
|
use training_mod_tui::{
|
||||||
|
StatefulSlider, StatefulTable, SubMenu, SubMenuType, Toggle, NX_SUBMENU_COLUMNS,
|
||||||
|
NX_SUBMENU_ROWS,
|
||||||
|
};
|
||||||
|
|
||||||
#[macro_export]
|
pub trait SubMenuTrait {
|
||||||
macro_rules! impl_toggletrait {
|
fn to_submenu<'a>(
|
||||||
(
|
title: &'a str,
|
||||||
$e:ty,
|
id: &'a str,
|
||||||
$title:literal,
|
help_text: &'a str,
|
||||||
$id:literal,
|
submenu_type: SubMenuType,
|
||||||
$help_text:literal,
|
) -> SubMenu<'a>;
|
||||||
$single:literal,
|
|
||||||
$max:expr,
|
|
||||||
) => {
|
|
||||||
paste! {
|
|
||||||
fn [<to_submenu_ $id>]<'a>() -> SubMenu<'a> {
|
|
||||||
let submenu_type = if $single { SubMenuType::ToggleSingle } else { SubMenuType::ToggleMultiple };
|
|
||||||
let value = 0;
|
|
||||||
let max: u8 = $max;
|
|
||||||
let toggles_vec: Vec<Toggle> = <$e>::ALL_NAMES
|
|
||||||
.iter()
|
|
||||||
.map(|title| Toggle { title, value, max })
|
|
||||||
.collect();
|
|
||||||
SubMenu {
|
|
||||||
title: $title,
|
|
||||||
id: $id,
|
|
||||||
help_text: $help_text,
|
|
||||||
submenu_type: submenu_type,
|
|
||||||
toggles: StatefulTable::with_items(NX_SUBMENU_ROWS, NX_SUBMENU_COLUMNS, toggles_vec),
|
|
||||||
slider: None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_slidertrait {
|
macro_rules! impl_submenutrait {
|
||||||
(
|
($e:ty) => {
|
||||||
$e:ty,
|
impl SubMenuTrait for $e {
|
||||||
$title:literal,
|
fn to_submenu<'a>(
|
||||||
$id:literal,
|
title: &'a str,
|
||||||
$help_text:literal,
|
id: &'a str,
|
||||||
) => {
|
help_text: &'a str,
|
||||||
paste! {
|
submenu_type: SubMenuType,
|
||||||
fn [<to_submenu_ $id>]<'a>() -> SubMenu<'a> {
|
) -> SubMenu<'a> {
|
||||||
let slider = StatefulSlider {
|
match submenu_type {
|
||||||
lower: 0,
|
SubMenuType::ToggleSingle => {
|
||||||
upper: 150,
|
let value = 0;
|
||||||
..StatefulSlider::new()
|
let max = 1;
|
||||||
};
|
let toggles_vec: Vec<Toggle> = Self::ALL_NAMES
|
||||||
SubMenu {
|
.iter()
|
||||||
title: $title,
|
.map(|title| Toggle { title, value, max })
|
||||||
id: $id,
|
.collect();
|
||||||
help_text: $help_text,
|
SubMenu {
|
||||||
submenu_type: SubMenuType::Slider,
|
title: title,
|
||||||
toggles: StatefulTable::with_items(NX_SUBMENU_ROWS, NX_SUBMENU_COLUMNS, Vec::new()),
|
id: id,
|
||||||
slider: Some(slider)
|
help_text: help_text,
|
||||||
|
submenu_type: submenu_type,
|
||||||
|
toggles: StatefulTable::with_items(
|
||||||
|
NX_SUBMENU_ROWS,
|
||||||
|
NX_SUBMENU_COLUMNS,
|
||||||
|
toggles_vec,
|
||||||
|
),
|
||||||
|
slider: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SubMenuType::ToggleMultiple => {
|
||||||
|
let value = 0;
|
||||||
|
let max = TOGGLE_MAX;
|
||||||
|
let toggles_vec: Vec<Toggle> = Self::ALL_NAMES
|
||||||
|
.iter()
|
||||||
|
.map(|title| Toggle { title, value, max })
|
||||||
|
.collect();
|
||||||
|
SubMenu {
|
||||||
|
title: title,
|
||||||
|
id: id,
|
||||||
|
help_text: help_text,
|
||||||
|
submenu_type: submenu_type,
|
||||||
|
toggles: StatefulTable::with_items(
|
||||||
|
NX_SUBMENU_ROWS,
|
||||||
|
NX_SUBMENU_COLUMNS,
|
||||||
|
toggles_vec,
|
||||||
|
),
|
||||||
|
slider: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SubMenuType::Slider => {
|
||||||
|
let slider = StatefulSlider {
|
||||||
|
lower: 0,
|
||||||
|
upper: 150,
|
||||||
|
..StatefulSlider::new()
|
||||||
|
};
|
||||||
|
SubMenu {
|
||||||
|
title: title,
|
||||||
|
id: id,
|
||||||
|
help_text: help_text,
|
||||||
|
submenu_type: submenu_type,
|
||||||
|
toggles: StatefulTable::with_items(
|
||||||
|
NX_SUBMENU_ROWS,
|
||||||
|
NX_SUBMENU_COLUMNS,
|
||||||
|
Vec::new(),
|
||||||
|
),
|
||||||
|
slider: Some(slider),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_random_int(_max: i32) -> i32 {
|
pub fn get_random_int(_max: i32) -> i32 {
|
||||||
|
@ -113,6 +143,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(Direction);
|
||||||
|
|
||||||
impl Direction {
|
impl Direction {
|
||||||
pub fn into_angle(self) -> Option<f64> {
|
pub fn into_angle(self) -> Option<f64> {
|
||||||
let index = self.into_index();
|
let index = self.into_index();
|
||||||
|
@ -161,6 +193,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(LedgeOption);
|
||||||
|
|
||||||
impl LedgeOption {
|
impl LedgeOption {
|
||||||
pub fn into_status(self) -> Option<i32> {
|
pub fn into_status(self) -> Option<i32> {
|
||||||
#[cfg(feature = "smash")]
|
#[cfg(feature = "smash")]
|
||||||
|
@ -228,6 +262,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(TechFlags);
|
||||||
|
|
||||||
// Missed Tech Options
|
// Missed Tech Options
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct MissTechFlags {
|
pub struct MissTechFlags {
|
||||||
|
@ -238,6 +274,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(MissTechFlags);
|
||||||
|
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct Shield {
|
pub struct Shield {
|
||||||
pub NONE = "None",
|
pub NONE = "None",
|
||||||
|
@ -247,6 +285,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(Shield);
|
||||||
|
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct SaveStateMirroring {
|
pub struct SaveStateMirroring {
|
||||||
pub NONE = "None",
|
pub NONE = "None",
|
||||||
|
@ -255,6 +295,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(SaveStateMirroring);
|
||||||
|
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct OnOff {
|
pub struct OnOff {
|
||||||
pub ON = "On",
|
pub ON = "On",
|
||||||
|
@ -262,6 +304,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(OnOff);
|
||||||
|
|
||||||
impl OnOff {
|
impl OnOff {
|
||||||
pub fn from_val(val: u32) -> Option<Self> {
|
pub fn from_val(val: u32) -> Option<Self> {
|
||||||
match val {
|
match val {
|
||||||
|
@ -315,6 +359,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(Action);
|
||||||
|
|
||||||
impl Action {
|
impl Action {
|
||||||
pub fn into_attack_air_kind(self) -> Option<i32> {
|
pub fn into_attack_air_kind(self) -> Option<i32> {
|
||||||
#[cfg(feature = "smash")]
|
#[cfg(feature = "smash")]
|
||||||
|
@ -363,6 +409,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(AttackAngle);
|
||||||
|
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct Delay {
|
pub struct Delay {
|
||||||
pub D0 = "0",
|
pub D0 = "0",
|
||||||
|
@ -399,6 +447,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(Delay);
|
||||||
|
|
||||||
impl Delay {
|
impl Delay {
|
||||||
pub fn into_delay(&self) -> u32 {
|
pub fn into_delay(&self) -> u32 {
|
||||||
if *self == Delay::empty() {
|
if *self == Delay::empty() {
|
||||||
|
@ -477,6 +527,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(MedDelay);
|
||||||
|
|
||||||
impl MedDelay {
|
impl MedDelay {
|
||||||
pub fn into_meddelay(&self) -> u32 {
|
pub fn into_meddelay(&self) -> u32 {
|
||||||
if *self == MedDelay::empty() {
|
if *self == MedDelay::empty() {
|
||||||
|
@ -555,6 +607,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(LongDelay);
|
||||||
|
|
||||||
impl LongDelay {
|
impl LongDelay {
|
||||||
pub fn into_longdelay(&self) -> u32 {
|
pub fn into_longdelay(&self) -> u32 {
|
||||||
if *self == LongDelay::empty() {
|
if *self == LongDelay::empty() {
|
||||||
|
@ -621,6 +675,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(BuffOption);
|
||||||
|
|
||||||
impl BuffOption {
|
impl BuffOption {
|
||||||
pub fn into_int(self) -> Option<i32> {
|
pub fn into_int(self) -> Option<i32> {
|
||||||
#[cfg(feature = "smash")]
|
#[cfg(feature = "smash")]
|
||||||
|
@ -690,6 +746,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(ThrowOption);
|
||||||
|
|
||||||
impl ThrowOption {
|
impl ThrowOption {
|
||||||
pub fn into_cmd(self) -> Option<i32> {
|
pub fn into_cmd(self) -> Option<i32> {
|
||||||
#[cfg(feature = "smash")]
|
#[cfg(feature = "smash")]
|
||||||
|
@ -717,6 +775,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(BoolFlag);
|
||||||
|
|
||||||
impl BoolFlag {
|
impl BoolFlag {
|
||||||
pub fn into_bool(self) -> bool {
|
pub fn into_bool(self) -> bool {
|
||||||
matches!(self, BoolFlag::TRUE)
|
matches!(self, BoolFlag::TRUE)
|
||||||
|
@ -732,6 +792,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(SdiFrequency);
|
||||||
|
|
||||||
impl SdiFrequency {
|
impl SdiFrequency {
|
||||||
pub fn into_u32(self) -> u32 {
|
pub fn into_u32(self) -> u32 {
|
||||||
match self {
|
match self {
|
||||||
|
@ -753,6 +815,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(ClatterFrequency);
|
||||||
|
|
||||||
impl ClatterFrequency {
|
impl ClatterFrequency {
|
||||||
pub fn into_u32(self) -> u32 {
|
pub fn into_u32(self) -> u32 {
|
||||||
match self {
|
match self {
|
||||||
|
@ -787,6 +851,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(CharacterItem);
|
||||||
|
|
||||||
impl CharacterItem {
|
impl CharacterItem {
|
||||||
pub fn as_idx(&self) -> usize {
|
pub fn as_idx(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -834,6 +900,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(MashTrigger);
|
||||||
|
|
||||||
impl MashTrigger {
|
impl MashTrigger {
|
||||||
pub const fn default() -> MashTrigger {
|
pub const fn default() -> MashTrigger {
|
||||||
// Hit, block, clatter
|
// Hit, block, clatter
|
||||||
|
@ -847,12 +915,21 @@ impl MashTrigger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
|
byteflags! {
|
||||||
pub struct DamagePercent(pub u32, pub u32);
|
pub struct DamagePercent {
|
||||||
|
pub LOWER = "Lower",
|
||||||
|
pub UPPER = "Upper",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(DamagePercent);
|
||||||
|
|
||||||
impl DamagePercent {
|
impl DamagePercent {
|
||||||
pub const fn default() -> DamagePercent {
|
pub const fn default() -> DamagePercent {
|
||||||
DamagePercent(0, 150)
|
DamagePercent {
|
||||||
|
LOWER: 0,
|
||||||
|
UPPER: 150,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,6 +941,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(SaveDamage);
|
||||||
|
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct SaveStateSlot
|
pub struct SaveStateSlot
|
||||||
{
|
{
|
||||||
|
@ -875,6 +954,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(SaveStateSlot);
|
||||||
|
|
||||||
impl SaveStateSlot {
|
impl SaveStateSlot {
|
||||||
pub fn into_idx(&self) -> Option<usize> {
|
pub fn into_idx(&self) -> Option<usize> {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -898,6 +979,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(RecordSlot);
|
||||||
|
|
||||||
impl RecordSlot {
|
impl RecordSlot {
|
||||||
pub fn into_idx(&self) -> Option<usize> {
|
pub fn into_idx(&self) -> Option<usize> {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -921,6 +1004,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(PlaybackSlot);
|
||||||
|
|
||||||
impl PlaybackSlot {
|
impl PlaybackSlot {
|
||||||
pub fn into_idx(&self) -> Option<usize> {
|
pub fn into_idx(&self) -> Option<usize> {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -943,6 +1028,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(HitstunPlayback);
|
||||||
|
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct RecordTrigger {
|
pub struct RecordTrigger {
|
||||||
pub COMMAND = "Button Combination",
|
pub COMMAND = "Button Combination",
|
||||||
|
@ -950,6 +1037,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(RecordTrigger);
|
||||||
|
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct RecordingDuration {
|
pub struct RecordingDuration {
|
||||||
pub F60 = "60",
|
pub F60 = "60",
|
||||||
|
@ -974,6 +1063,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(RecordingDuration);
|
||||||
|
|
||||||
impl RecordingDuration {
|
impl RecordingDuration {
|
||||||
pub fn into_frames(&self) -> usize {
|
pub fn into_frames(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -1022,6 +1113,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(ButtonConfig);
|
||||||
|
|
||||||
byteflags! {
|
byteflags! {
|
||||||
pub struct UpdatePolicy {
|
pub struct UpdatePolicy {
|
||||||
pub STABLE = "Stable",
|
pub STABLE = "Stable",
|
||||||
|
@ -1030,6 +1123,8 @@ byteflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(UpdatePolicy);
|
||||||
|
|
||||||
impl UpdatePolicy {
|
impl UpdatePolicy {
|
||||||
pub const fn default() -> UpdatePolicy {
|
pub const fn default() -> UpdatePolicy {
|
||||||
UpdatePolicy::STABLE
|
UpdatePolicy::STABLE
|
||||||
|
@ -1044,3 +1139,5 @@ byteflags! {
|
||||||
pub STATUS = "Status Only",
|
pub STATUS = "Status Only",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_submenutrait!(InputDisplay);
|
||||||
|
|
Loading…
Reference in a new issue