1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2025-03-14 02:16:10 +00:00

Add rustfmt action (#265)

* Add rustfmt action

* Update rust.yml

* Format Rust code using rustfmt

* Update consts.rs

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
jugeeya 2021-09-14 14:05:48 -07:00 committed by GitHub
parent f41065a7f5
commit bc3d2d8df5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 748 additions and 456 deletions

View file

@ -28,6 +28,9 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
toolchain: nightly-2021-06-01
args: --all-features --target=x86_64-unknown-linux-gnu
- uses: mbrobbel/rustfmt-check@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
plugin:
runs-on: ubuntu-latest
container:

View file

@ -28,7 +28,7 @@ macro_rules! extra_bitflag_impls {
if self.bits == 0 {
return 0;
}
return self.bits.trailing_zeros();
}
@ -144,7 +144,8 @@ impl Direction {
Direction::LEFT => "Left",
Direction::RIGHT => "Right",
_ => "",
}.to_string()
}
.to_string()
}
}
@ -182,7 +183,8 @@ impl LedgeOption {
LedgeOption::ATTACK => "Getup Attack",
LedgeOption::WAIT => "Wait",
_ => "",
}.to_string()
}
.to_string()
}
}
@ -206,7 +208,8 @@ impl TechFlags {
TechFlags::ROLL_B => "Roll Backwards",
TechFlags::IN_PLACE => "Tech In Place",
_ => "",
}.to_string()
}
.to_string()
}
}
@ -230,7 +233,8 @@ impl MissTechFlags {
MissTechFlags::ROLL_F => "Roll Forwards",
MissTechFlags::ROLL_B => "Roll Backwards",
_ => "",
}.to_string()
}
.to_string()
}
}
@ -253,7 +257,8 @@ impl Shield {
Shield::Infinite => "Infinite",
Shield::Hold => "Hold",
Shield::Constant => "Constant",
}.to_string()
}
.to_string()
}
pub fn to_url_param(&self) -> String {
@ -262,7 +267,8 @@ impl Shield {
Shield::Infinite => "1",
Shield::Hold => "2",
Shield::Constant => "3",
}.to_string()
}
.to_string()
}
}
@ -281,7 +287,8 @@ impl SaveStateMirroring {
SaveStateMirroring::None => "None",
SaveStateMirroring::Alternate => "Alternate",
SaveStateMirroring::Random => "Random",
}.to_string()
}
.to_string()
}
fn to_url_param(&self) -> String {
@ -289,7 +296,8 @@ impl SaveStateMirroring {
SaveStateMirroring::None => "0",
SaveStateMirroring::Alternate => "1",
SaveStateMirroring::Random => "2",
}.to_string()
}
.to_string()
}
}
@ -313,7 +321,8 @@ impl Defensive {
Defensive::JAB => "Jab",
Defensive::SHIELD => "Shield",
_ => "",
}.to_string()
}
.to_string()
}
}
@ -331,7 +340,7 @@ impl OnOff {
match val {
1 => Some(OnOff::On),
0 => Some(OnOff::Off),
_ => None
_ => None,
}
}
@ -339,14 +348,16 @@ impl OnOff {
match self {
OnOff::Off => "Off",
OnOff::On => "On",
}.to_string()
}
.to_string()
}
pub fn to_url_param(&self) -> String {
match self {
OnOff::Off => "0",
OnOff::On => "1",
}.to_string()
}
.to_string()
}
}
@ -421,7 +432,8 @@ impl Action {
Action::DASH => "Dash",
Action::DASH_ATTACK => "Dash Attack",
_ => "",
}.to_string()
}
.to_string()
}
}
@ -441,14 +453,14 @@ impl AttackAngle {
AttackAngle::NEUTRAL => "Neutral",
AttackAngle::UP => "Up",
AttackAngle::DOWN => "Down",
_ => ""
}.to_string()
_ => "",
}
.to_string()
}
}
extra_bitflag_impls! {AttackAngle}
bitflags! {
pub struct Delay : u32 {
const D0 = 0x1;
@ -488,16 +500,16 @@ bitflags! {
impl Delay {
pub fn into_string(self) -> String {
match self {
Delay::D0 => "0",
Delay::D1 => "1",
Delay::D2 => "2",
Delay::D3 => "3",
Delay::D4 => "4",
Delay::D5 => "5",
Delay::D6 => "6",
Delay::D7 => "7",
Delay::D8 => "8",
Delay::D9 => "9",
Delay::D0 => "0",
Delay::D1 => "1",
Delay::D2 => "2",
Delay::D3 => "3",
Delay::D4 => "4",
Delay::D5 => "5",
Delay::D6 => "6",
Delay::D7 => "7",
Delay::D8 => "8",
Delay::D9 => "9",
Delay::D10 => "10",
Delay::D11 => "11",
Delay::D12 => "12",
@ -520,7 +532,8 @@ impl Delay {
Delay::D29 => "29",
Delay::D30 => "30",
_ => "",
}.to_string()
}
.to_string()
}
pub fn into_delay(&self) -> u32 {
@ -569,16 +582,16 @@ bitflags! {
impl LongDelay {
pub fn into_string(self) -> String {
match self {
LongDelay::D0 => "0",
LongDelay::D10 => "10",
LongDelay::D20 => "20",
LongDelay::D30 => "30",
LongDelay::D40 => "40",
LongDelay::D50 => "50",
LongDelay::D60 => "60",
LongDelay::D70 => "70",
LongDelay::D80 => "80",
LongDelay::D90 => "90",
LongDelay::D0 => "0",
LongDelay::D10 => "10",
LongDelay::D20 => "20",
LongDelay::D30 => "30",
LongDelay::D40 => "40",
LongDelay::D50 => "50",
LongDelay::D60 => "60",
LongDelay::D70 => "70",
LongDelay::D80 => "80",
LongDelay::D90 => "90",
LongDelay::D100 => "100",
LongDelay::D110 => "110",
LongDelay::D120 => "120",
@ -601,7 +614,8 @@ impl LongDelay {
LongDelay::D290 => "290",
LongDelay::D300 => "300",
_ => "",
}.to_string()
}
.to_string()
}
pub fn into_longdelay(&self) -> u32 {
@ -629,11 +643,11 @@ impl BoolFlag {
match self {
BoolFlag::TRUE => "True",
_ => "False",
}.to_string()
}
.to_string()
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, EnumIter)]
pub enum SdiStrength {
@ -656,7 +670,8 @@ impl SdiStrength {
SdiStrength::Normal => "Normal",
SdiStrength::Medium => "Medium",
SdiStrength::High => "High",
}.to_string()
}
.to_string()
}
pub fn to_url_param(&self) -> String {
@ -664,7 +679,8 @@ impl SdiStrength {
SdiStrength::Normal => "0",
SdiStrength::Medium => "1",
SdiStrength::High => "2",
}.to_string()
}
.to_string()
}
}
@ -743,7 +759,7 @@ url_params! {
}
macro_rules! set_by_str {
($obj:ident, $s:ident, $(($field:ident = $rhs:expr))*) => {
($obj:ident, $s:ident, $($field:ident = $rhs:expr,)*) => {
$(
if $s == stringify!($field) {
$obj.$field = $rhs.unwrap();
@ -754,36 +770,37 @@ macro_rules! set_by_str {
impl TrainingModpackMenu {
pub fn set(&mut self, s: &str, val: u32) {
set_by_str!(self, s,
(aerial_delay = Delay::from_bits(val))
(air_dodge_dir = Direction::from_bits(val))
(attack_angle = AttackAngle::from_bits(val))
(defensive_state = Defensive::from_bits(val))
(di_state = Direction::from_bits(val))
(falling_aerials = BoolFlag::from_bits(val))
(fast_fall_delay = Delay::from_bits(val))
(fast_fall = BoolFlag::from_bits(val))
(follow_up = Action::from_bits(val))
(full_hop = BoolFlag::from_bits(val))
(hitbox_vis = OnOff::from_val(val))
(input_delay = Some(val as i32))
(ledge_delay = LongDelay::from_bits(val))
(ledge_state = LedgeOption::from_bits(val))
(mash_in_neutral = OnOff::from_val(val))
(mash_state = Action::from_bits(val))
(miss_tech_state = MissTechFlags::from_bits(val))
(oos_offset = Delay::from_bits(val))
(reaction_time = Delay::from_bits(val))
(sdi_state = Direction::from_bits(val))
(sdi_strength = num::FromPrimitive::from_u32(val))
(shield_state = num::FromPrimitive::from_u32(val))
(shield_tilt = Direction::from_bits(val))
(stage_hazards = OnOff::from_val(val))
(tech_state = TechFlags::from_bits(val))
(save_damage = OnOff::from_val(val))
(frame_advantage = OnOff::from_val(val))
(save_state_mirroring = num::FromPrimitive::from_u32(val))
set_by_str!(
self,
s,
aerial_delay = Delay::from_bits(val),
air_dodge_dir = Direction::from_bits(val),
attack_angle = AttackAngle::from_bits(val),
defensive_state = Defensive::from_bits(val),
di_state = Direction::from_bits(val),
falling_aerials = BoolFlag::from_bits(val),
fast_fall_delay = Delay::from_bits(val),
fast_fall = BoolFlag::from_bits(val),
follow_up = Action::from_bits(val),
full_hop = BoolFlag::from_bits(val),
hitbox_vis = OnOff::from_val(val),
input_delay = Some(val as i32),
ledge_delay = LongDelay::from_bits(val),
ledge_state = LedgeOption::from_bits(val),
mash_in_neutral = OnOff::from_val(val),
mash_state = Action::from_bits(val),
miss_tech_state = MissTechFlags::from_bits(val),
oos_offset = Delay::from_bits(val),
reaction_time = Delay::from_bits(val),
sdi_state = Direction::from_bits(val),
sdi_strength = num::FromPrimitive::from_u32(val),
shield_state = num::FromPrimitive::from_u32(val),
shield_tilt = Direction::from_bits(val),
stage_hazards = OnOff::from_val(val),
tech_state = TechFlags::from_bits(val),
save_damage = OnOff::from_val(val),
frame_advantage = OnOff::from_val(val),
save_state_mirroring = num::FromPrimitive::from_u32(val),
);
}
}
@ -794,4 +811,4 @@ impl TrainingModpackMenu {
pub enum FighterId {
Player = 0,
CPU = 1,
}
}

View file

@ -1,9 +1,9 @@
use std::time::{SystemTime, UNIX_EPOCH};
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use skyline::libc::c_void;
use skyline::nn::{crypto, account, time, oe};
use core::lazy::OnceCell;
use serde::{Deserialize, Serialize};
use skyline::libc::c_void;
use skyline::nn::{account, crypto, oe, time};
use std::convert::TryInto;
use std::time::{SystemTime, UNIX_EPOCH};
pub static mut EVENT_QUEUE: Vec<Event> = vec![];
static mut SESSION_ID: OnceCell<String> = OnceCell::new();
@ -31,7 +31,7 @@ extern "C" {
pub struct Uuid {
Size: u32,
StringSize: u32,
data: [u8; 16]
data: [u8; 16],
}
impl Uuid {
@ -45,23 +45,21 @@ impl Uuid {
}
struct Sha256Hash {
hash: [u8; 0x20]
hash: [u8; 0x20],
}
impl Event {
pub fn new() -> Event {
let mut device_uuid = Uuid{
let mut device_uuid = Uuid {
Size: 16,
StringSize: 300,
data: [0u8; 16]
data: [0u8; 16],
};
unsafe {
GetPseudoDeviceId(&mut device_uuid as *mut Uuid);
}
let mut time = skyline::nn::time::PosixTime{
time: 0
};
let mut time = skyline::nn::time::PosixTime { time: 0 };
unsafe {
time::Initialize();
let event_time = SystemTime::now()
@ -69,8 +67,8 @@ impl Event {
.expect("Time went backwards")
.as_millis();
let mut smash_version = oe::DisplayVersion{
name: [0 as skyline::libc::c_char; 16]
let mut smash_version = oe::DisplayVersion {
name: [0 as skyline::libc::c_char; 16],
};
oe::GetDisplayVersion(&mut smash_version);
if SESSION_ID.get().is_none() {
@ -78,62 +76,70 @@ impl Event {
let mut user_uid = account::Uid::new();
account::GetLastOpenedUser(&mut user_uid);
let mut user_id_hash = Sha256Hash{
hash: [0; 0x20]
};
let mut user_id_hash = Sha256Hash { hash: [0; 0x20] };
crypto::GenerateSha256Hash(
&mut user_id_hash as *mut _ as *mut c_void,
&mut user_id_hash as *mut _ as *mut c_void,
0x20 * 8,
user_uid.id.as_ptr() as *const c_void,
16 * 8);
user_uid.id.as_ptr() as *const c_void,
16 * 8,
);
USER_ID.set(
user_uid.id
.into_iter()
.map(|i| format!("{:02x}", i))
.collect::<Vec<String>>()
.join("")
).unwrap();
USER_ID
.set(
user_uid
.id
.into_iter()
.map(|i| format!("{:02x}", i))
.collect::<Vec<String>>()
.join(""),
)
.unwrap();
let mut device_id_hash = Sha256Hash{
hash: [0; 0x20]
};
let mut device_id_hash = Sha256Hash { hash: [0; 0x20] };
crypto::GenerateSha256Hash(
&mut device_id_hash as *mut _ as *mut c_void,
&mut device_id_hash as *mut _ as *mut c_void,
0x20 * 8,
device_uuid.data.as_ptr() as *const c_void,
64 * 2);
DEVICE_ID.set(
device_uuid.data
.into_iter()
.map(|i| format!("{:02x}", i))
.collect::<Vec<String>>()
.join("")
).unwrap();
device_uuid.data.as_ptr() as *const c_void,
64 * 2,
);
DEVICE_ID
.set(
device_uuid
.data
.into_iter()
.map(|i| format!("{:02x}", i))
.collect::<Vec<String>>()
.join(""),
)
.unwrap();
let mut session_id_hash = Sha256Hash{
hash: [0; 0x20]
};
// let mut device_id_0_bytes : [u8; 8] = Default::default();
let mut session_id_hash = Sha256Hash { hash: [0; 0x20] };
// let mut device_id_0_bytes : [u8; 8] = Default::default();
// device_id_0_bytes.copy_from_slice(&device_uuid.data[0..8]);
// let mut device_id_1_bytes : [u8; 8] = Default::default();
// let mut device_id_1_bytes : [u8; 8] = Default::default();
// device_id_1_bytes.copy_from_slice(&device_uuid.data[8..16]);
let event_time_bytes : [u8; 16] = std::mem::transmute(event_time.to_be());
let session_id_bytes : [u8; 32] = [
event_time_bytes, device_uuid.data
].concat().try_into().unwrap();
let event_time_bytes: [u8; 16] = std::mem::transmute(event_time.to_be());
let session_id_bytes: [u8; 32] = [event_time_bytes, device_uuid.data]
.concat()
.try_into()
.unwrap();
crypto::GenerateSha256Hash(
&mut session_id_hash as *mut _ as *mut c_void,
&mut session_id_hash as *mut _ as *mut c_void,
0x20 * 8,
session_id_bytes.as_ptr() as *const c_void,
32 * 8);
SESSION_ID.set(session_id_hash.hash
.into_iter()
.map(|i| format!("{:02x}", i))
.collect::<Vec<String>>()
.join("")).unwrap();
session_id_bytes.as_ptr() as *const c_void,
32 * 8,
);
SESSION_ID
.set(
session_id_hash
.hash
.into_iter()
.map(|i| format!("{:02x}", i))
.collect::<Vec<String>>()
.join(""),
)
.unwrap();
}
let mut event = Event::default();
@ -142,7 +148,12 @@ impl Event {
event.event_time = event_time;
event.session_id = SESSION_ID.get().unwrap().to_string();
event.mod_version = crate::common::release::CURRENT_VERSION.to_string();
event.smash_version = std::ffi::CStr::from_ptr(smash_version.name.as_ptr() as *const i8).to_owned().to_str().unwrap().to_string();
event.smash_version =
std::ffi::CStr::from_ptr(smash_version.name.as_ptr() as *const i8)
.to_owned()
.to_str()
.unwrap()
.to_string();
event
}
}
@ -152,11 +163,11 @@ impl Event {
event.event_name = "SMASH_OPEN".to_string();
event
}
pub fn menu_open(menu_settings: String) -> Event {
let mut event = Event::new();
event.event_name = "MENU_OPEN".to_string();
event.menu_settings = menu_settings;
event
}
}
}

View file

@ -1,13 +1,13 @@
use std::fs;
use std::path::Path;
use crate::common::*;
use skyline::info::get_program_id;
use smash::lib::lua_const::*;
use skyline_web::{Background, BootDisplay, Webpage};
use ramhorns::{Template, Content};
use strum::IntoEnumIterator;
use crate::events::{Event, EVENT_QUEUE};
use crate::training::frame_counter;
use ramhorns::{Content, Template};
use skyline::info::get_program_id;
use skyline_web::{Background, BootDisplay, Webpage};
use smash::lib::lua_const::*;
use std::fs;
use std::path::Path;
use strum::IntoEnumIterator;
static mut FRAME_COUNTER_INDEX: usize = 0;
const MENU_LOCKOUT_FRAMES: u32 = 5;
@ -19,13 +19,12 @@ pub fn init() {
}
}
#[derive(Content)]
struct Slider {
min: usize,
max: usize,
index: usize,
value: usize
value: usize,
}
#[derive(Content)]
@ -61,44 +60,44 @@ impl<'a> SubMenu<'a> {
pub fn max_idx(&self) -> usize {
self.toggles
.iter()
.max_by(|t1,t2| t1.index.cmp(&t2.index))
.max_by(|t1, t2| t1.index.cmp(&t2.index))
.map(|t| t.index)
.unwrap_or(self.index)
}
pub fn add_toggle(&mut self, title: &'a str, checked: bool, value: usize, default: bool) {
self.toggles.push(Toggle{
self.toggles.push(Toggle {
title,
checked: if checked { "is-appear"} else { "is-hidden" },
checked: if checked { "is-appear" } else { "is-hidden" },
index: self.max_idx() + 1,
value,
default: if default { "is-appear"} else { "is-hidden" },
default: if default { "is-appear" } else { "is-hidden" },
});
}
pub fn add_slider(&mut self, min: usize, max: usize, value: usize) {
self.sliders.push(Slider{
self.sliders.push(Slider {
min,
max,
index: self.max_idx() + 1,
value
value,
});
}
pub fn add_onoffselector(&mut self, title: &'a str, checked: bool, default: bool) {
// TODO: Is there a more elegant way to do this?
// The HTML only supports a single onoffselector but the SubMenu stores it as a Vec
self.onoffselector.push(OnOffSelector{
self.onoffselector.push(OnOffSelector {
title,
checked: if checked { "is-appear"} else { "is-hidden" },
default: if default { "is-appear"} else { "is-hidden" },
checked: if checked { "is-appear" } else { "is-hidden" },
default: if default { "is-appear" } else { "is-hidden" },
});
}
}
#[derive(Content)]
struct Menu<'a> {
sub_menus: Vec<SubMenu<'a>>
sub_menus: Vec<SubMenu<'a>>,
}
impl<'a> Menu<'a> {
@ -110,7 +109,16 @@ impl<'a> Menu<'a> {
.unwrap_or(0)
}
pub fn add_sub_menu(&mut self, title: &'a str, id: &'a str, check_against: usize, toggles: Vec<(&'a str, usize)>, sliders: Vec<(usize,usize,usize)>, defaults: usize, help_text: &'a str) {
pub fn add_sub_menu(
&mut self,
title: &'a str,
id: &'a str,
check_against: usize,
toggles: Vec<(&'a str, usize)>,
sliders: Vec<(usize, usize, usize)>,
defaults: usize,
help_text: &'a str,
) {
let mut sub_menu = SubMenu {
title,
id,
@ -124,7 +132,12 @@ impl<'a> Menu<'a> {
};
for toggle in toggles {
sub_menu.add_toggle(toggle.0, (check_against & toggle.1) != 0, toggle.1, (defaults & toggle.1) != 0)
sub_menu.add_toggle(
toggle.0,
(check_against & toggle.1) != 0,
toggle.1,
(defaults & toggle.1) != 0,
)
}
for slider in sliders {
@ -134,7 +147,16 @@ impl<'a> Menu<'a> {
self.sub_menus.push(sub_menu);
}
pub fn add_sub_menu_sep(&mut self, title: &'a str, id: &'a str, check_against: usize, strs: Vec<&'a str>, vals: Vec<usize>, defaults: usize, help_text: &'a str) {
pub fn add_sub_menu_sep(
&mut self,
title: &'a str,
id: &'a str,
check_against: usize,
strs: Vec<&'a str>,
vals: Vec<usize>,
defaults: usize,
help_text: &'a str,
) {
let mut sub_menu = SubMenu {
title,
id,
@ -148,7 +170,12 @@ impl<'a> Menu<'a> {
};
for i in 0..strs.len() {
sub_menu.add_toggle(strs[i], (check_against & vals[i]) != 0, vals[i], (defaults & vals[i]) != 0)
sub_menu.add_toggle(
strs[i],
(check_against & vals[i]) != 0,
vals[i],
(defaults & vals[i]) != 0,
)
}
// TODO: add sliders?
@ -156,7 +183,15 @@ impl<'a> Menu<'a> {
self.sub_menus.push(sub_menu);
}
pub fn add_sub_menu_onoff(&mut self, title: &'a str, id: &'a str, check_against: usize, checked: bool, default: usize, help_text: &'a str) {
pub fn add_sub_menu_onoff(
&mut self,
title: &'a str,
id: &'a str,
check_against: usize,
checked: bool,
default: usize,
help_text: &'a str,
) {
let mut sub_menu = SubMenu {
title,
id,
@ -181,8 +216,8 @@ macro_rules! add_bitflag_submenu {
let [<$id _vals>] = <$e>::to_toggle_vals();
$menu.add_sub_menu_sep(
$title,
stringify!($id),
$title,
stringify!($id),
MENU.$id.bits() as usize,
[<$id _strs>].iter().map(|i| i.as_str()).collect(),
[<$id _vals>],
@ -202,8 +237,8 @@ macro_rules! add_single_option_submenu {
}
$menu.add_sub_menu(
$title,
stringify!($id),
$title,
stringify!($id),
MENU.$id as usize,
[<$id _toggles>].iter().map(|(x, y)| (x.as_str(), *y)).collect::<Vec<(&str, usize)>>(),
[].to_vec(),
@ -216,41 +251,48 @@ macro_rules! add_single_option_submenu {
macro_rules! add_onoff_submenu {
($menu:ident, $title:literal, $id:ident, $help_text:literal) => {
paste::paste!{
paste::paste! {
$menu.add_sub_menu_onoff(
$title,
stringify!($id),
$title,
stringify!($id),
MENU.$id as usize,
(MENU.$id as usize & OnOff::On as usize) != 0,
DEFAULT_MENU.$id as usize,
stringify!($help_text),
);
}
}
};
}
pub fn set_menu_from_url(s: &str) {
let base_url_len = "http://localhost/?".len();
let total_len = s.len();
let ss: String = s.chars().skip(base_url_len).take(total_len - base_url_len).collect();
let ss: String = s
.chars()
.skip(base_url_len)
.take(total_len - base_url_len)
.collect();
for toggle_values in ss.split('&') {
let toggle_value_split = toggle_values.split('=').collect::<Vec<&str>>();
let toggle = toggle_value_split[0];
if toggle.is_empty() { continue; }
if toggle.is_empty() {
continue;
}
let toggle_vals = toggle_value_split[1];
let mut bits = 0;
for toggle_val in toggle_vals.split(',') {
if toggle_val.is_empty() { continue; }
if toggle_val.is_empty() {
continue;
}
let val = toggle_val.parse::<u32>().unwrap();
bits |= val;
}
unsafe {
MENU.set(toggle, bits);
}
@ -261,9 +303,12 @@ pub unsafe fn menu_condition(module_accessor: &mut smash::app::BattleObjectModul
// Only check for button combination if the counter is 0 (not locked out)
match frame_counter::get_frame_count(FRAME_COUNTER_INDEX) {
0 => {
ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_SPECIAL) &&
ControlModule::check_button_on_trriger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI)
},
ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_SPECIAL)
&& ControlModule::check_button_on_trriger(
module_accessor,
*CONTROL_PAD_BUTTON_APPEAL_HI,
)
}
1..MENU_LOCKOUT_FRAMES => false,
_ => {
// Waited longer than the lockout time, reset the counter so the menu can be opened again
@ -277,56 +322,220 @@ pub unsafe fn write_menu() {
let tpl = Template::new(include_str!("../templates/menu.html")).unwrap();
let mut overall_menu = Menu {
sub_menus: Vec::new()
sub_menus: Vec::new(),
};
// Toggle/bitflag menus
add_bitflag_submenu!(overall_menu, "Mash Toggles", mash_state, Action, "Mash Toggles: Actions to be performed as soon as possible");
add_bitflag_submenu!(overall_menu, "Followup Toggles", follow_up, Action, "Followup Toggles: Actions to be performed after the Mash option");
add_bitflag_submenu!(overall_menu, "Attack Angle", attack_angle, AttackAngle, "Attack Angle: For attacks that can be angled, such as some forward tilts");
add_bitflag_submenu!(
overall_menu,
"Mash Toggles",
mash_state,
Action,
"Mash Toggles: Actions to be performed as soon as possible"
);
add_bitflag_submenu!(
overall_menu,
"Followup Toggles",
follow_up,
Action,
"Followup Toggles: Actions to be performed after the Mash option"
);
add_bitflag_submenu!(
overall_menu,
"Attack Angle",
attack_angle,
AttackAngle,
"Attack Angle: For attacks that can be angled, such as some forward tilts"
);
add_bitflag_submenu!(overall_menu, "Ledge Options", ledge_state, LedgeOption, "Ledge Options: Actions to be taken when on the ledge");
add_bitflag_submenu!(overall_menu, "Ledge Delay", ledge_delay, LongDelay, "Ledge Delay: How many frames to delay the ledge option");
add_bitflag_submenu!(overall_menu, "Tech Options", tech_state, TechFlags, "Tech Options: Actions to take when slammed into a hard surface");
add_bitflag_submenu!(overall_menu, "Miss Tech Options", miss_tech_state, MissTechFlags, "Miss Tech Options: Actions to take after missing a tech");
add_bitflag_submenu!(overall_menu, "Defensive Options", defensive_state, Defensive, "Defensive Options: Actions to take after a ledge option, tech option, or miss tech option");
add_bitflag_submenu!(
overall_menu,
"Ledge Options",
ledge_state,
LedgeOption,
"Ledge Options: Actions to be taken when on the ledge"
);
add_bitflag_submenu!(
overall_menu,
"Ledge Delay",
ledge_delay,
LongDelay,
"Ledge Delay: How many frames to delay the ledge option"
);
add_bitflag_submenu!(
overall_menu,
"Tech Options",
tech_state,
TechFlags,
"Tech Options: Actions to take when slammed into a hard surface"
);
add_bitflag_submenu!(
overall_menu,
"Miss Tech Options",
miss_tech_state,
MissTechFlags,
"Miss Tech Options: Actions to take after missing a tech"
);
add_bitflag_submenu!(
overall_menu,
"Defensive Options",
defensive_state,
Defensive,
"Defensive Options: Actions to take after a ledge option, tech option, or miss tech option"
);
add_bitflag_submenu!(overall_menu, "Aerial Delay", aerial_delay, Delay, "Aerial Delay: How long to delay a Mash aerial attack");
add_bitflag_submenu!(overall_menu, "OoS Offset", oos_offset, Delay, "OoS Offset: How many times the CPU shield can be hit before performing a Mash option");
add_bitflag_submenu!(overall_menu, "Reaction Time", reaction_time, Delay, "Reaction Time: How many frames to delay before performing an option out of shield");
add_bitflag_submenu!(
overall_menu,
"Aerial Delay",
aerial_delay,
Delay,
"Aerial Delay: How long to delay a Mash aerial attack"
);
add_bitflag_submenu!(
overall_menu,
"OoS Offset",
oos_offset,
Delay,
"OoS Offset: How many times the CPU shield can be hit before performing a Mash option"
);
add_bitflag_submenu!(
overall_menu,
"Reaction Time",
reaction_time,
Delay,
"Reaction Time: How many frames to delay before performing an option out of shield"
);
add_bitflag_submenu!(overall_menu, "Fast Fall", fast_fall, BoolFlag, "Fast Fall: Should the CPU fastfall during a jump");
add_bitflag_submenu!(overall_menu, "Fast Fall Delay", fast_fall_delay, Delay, "Fast Fall Delay: How many frames the CPU should delay their fastfall");
add_bitflag_submenu!(overall_menu, "Falling Aerials", falling_aerials, BoolFlag, "Falling Aerials: Should aerials be performed when rising or when falling");
add_bitflag_submenu!(overall_menu, "Full Hop", full_hop, BoolFlag, "Full Hop: Should the CPU perform a full hop or a short hop");
add_bitflag_submenu!(
overall_menu,
"Fast Fall",
fast_fall,
BoolFlag,
"Fast Fall: Should the CPU fastfall during a jump"
);
add_bitflag_submenu!(
overall_menu,
"Fast Fall Delay",
fast_fall_delay,
Delay,
"Fast Fall Delay: How many frames the CPU should delay their fastfall"
);
add_bitflag_submenu!(
overall_menu,
"Falling Aerials",
falling_aerials,
BoolFlag,
"Falling Aerials: Should aerials be performed when rising or when falling"
);
add_bitflag_submenu!(
overall_menu,
"Full Hop",
full_hop,
BoolFlag,
"Full Hop: Should the CPU perform a full hop or a short hop"
);
add_bitflag_submenu!(overall_menu, "Shield Tilt", shield_tilt, Direction, "Shield Tilt: Direction to tilt the shield");
add_bitflag_submenu!(overall_menu, "DI Direction", di_state, Direction, "DI Direction: Direction to angle the directional influence during hitlag");
add_bitflag_submenu!(overall_menu, "SDI Direction", sdi_state, Direction, "SDI Direction: Direction to angle the smash directional influence during hitlag");
add_bitflag_submenu!(overall_menu, "Airdodge Direction", air_dodge_dir, Direction, "Airdodge Direction: Direction to angle airdodges");
add_single_option_submenu!(overall_menu, "SDI Strength", sdi_strength, SdiStrength, "SDI Strength: Relative strength of the smash directional influence inputs");
add_single_option_submenu!(overall_menu, "Shield Toggles", shield_state, Shield, "Shield Toggles: CPU Shield Behavior");
add_single_option_submenu!(overall_menu, "Mirroring", save_state_mirroring, SaveStateMirroring, "Mirroring: Flips save states in the left-right direction across the stage center");
add_bitflag_submenu!(
overall_menu,
"Shield Tilt",
shield_tilt,
Direction,
"Shield Tilt: Direction to tilt the shield"
);
add_bitflag_submenu!(
overall_menu,
"DI Direction",
di_state,
Direction,
"DI Direction: Direction to angle the directional influence during hitlag"
);
add_bitflag_submenu!(
overall_menu,
"SDI Direction",
sdi_state,
Direction,
"SDI Direction: Direction to angle the smash directional influence during hitlag"
);
add_bitflag_submenu!(
overall_menu,
"Airdodge Direction",
air_dodge_dir,
Direction,
"Airdodge Direction: Direction to angle airdodges"
);
add_single_option_submenu!(
overall_menu,
"SDI Strength",
sdi_strength,
SdiStrength,
"SDI Strength: Relative strength of the smash directional influence inputs"
);
add_single_option_submenu!(
overall_menu,
"Shield Toggles",
shield_state,
Shield,
"Shield Toggles: CPU Shield Behavior"
);
add_single_option_submenu!(
overall_menu,
"Mirroring",
save_state_mirroring,
SaveStateMirroring,
"Mirroring: Flips save states in the left-right direction across the stage center"
);
// Slider menus
overall_menu.add_sub_menu(
"Input Delay",
"input_delay",
"Input Delay",
"input_delay",
// unnecessary for slider?
MENU.input_delay as usize,
[("0", 0),("1",1),("2",2),("3",3),("4",4),("5",5),("6",6),("7",7),("8",8),("9",9),("10",10)].to_vec(),
[
("0", 0),
("1", 1),
("2", 2),
("3", 3),
("4", 4),
("5", 5),
("6", 6),
("7", 7),
("8", 8),
("9", 9),
("10", 10),
]
.to_vec(),
[].to_vec(), //(0, 10, MENU.input_delay as usize)
DEFAULT_MENU.input_delay as usize,
stringify!("Input Delay: Frames to delay player inputs by"),
);
add_onoff_submenu!(overall_menu, "Save Damage", save_damage, "Save Damage: Should save states retain player/CPU damage");
add_onoff_submenu!(overall_menu, "Hitbox Visualization", hitbox_vis, "Hitbox Visualization: Should hitboxes be displayed, hiding other visual effects");
add_onoff_submenu!(overall_menu, "Stage Hazards", stage_hazards, "Stage Hazards: Should stage hazards be present");
add_onoff_submenu!(
overall_menu,
"Save Damage",
save_damage,
"Save Damage: Should save states retain player/CPU damage"
);
add_onoff_submenu!(
overall_menu,
"Hitbox Visualization",
hitbox_vis,
"Hitbox Visualization: Should hitboxes be displayed, hiding other visual effects"
);
add_onoff_submenu!(
overall_menu,
"Stage Hazards",
stage_hazards,
"Stage Hazards: Should stage hazards be present"
);
add_onoff_submenu!(overall_menu, "Frame Advantage", frame_advantage, "Frame Advantage: Display the time difference between when the player is actionable and the CPU is actionable");
add_onoff_submenu!(overall_menu, "Mash In Neutral", mash_in_neutral, "Mash In Neutral: Should Mash options be performed repeatedly or only when the CPU is hit");
add_onoff_submenu!(
overall_menu,
"Mash In Neutral",
mash_in_neutral,
"Mash In Neutral: Should Mash options be performed repeatedly or only when the CPU is hit"
);
let data = tpl.render(&overall_menu);
@ -355,15 +564,12 @@ pub unsafe fn spawn_menu() {
.open()
.unwrap();
let last_url = page_response
.get_last_url()
.unwrap();
let last_url = page_response.get_last_url().unwrap();
set_menu_from_url(last_url);
let menu_conf_path = "sd:/TrainingModpack/training_modpack_menu.conf";
std::fs::write(menu_conf_path, last_url)
.expect("Failed to write menu conf file");
std::fs::write(menu_conf_path, last_url).expect("Failed to write menu conf file");
unsafe {
EVENT_QUEUE.push(Event::menu_open(last_url.to_string()));
}

View file

@ -1,8 +1,8 @@
pub mod consts;
pub mod events;
pub mod menu;
pub mod release;
pub mod raygun_printer;
pub mod release;
use crate::common::consts::*;
use crate::common::events::*;
@ -38,10 +38,9 @@ pub static DEFAULT_MENU: consts::TrainingModpackMenu = consts::TrainingModpackMe
input_delay: 0,
save_damage: OnOff::On,
save_state_mirroring: SaveStateMirroring::None,
frame_advantage: OnOff::Off
frame_advantage: OnOff::Off,
};
pub static mut MENU: TrainingModpackMenu = DEFAULT_MENU;
pub static mut FIGHTER_MANAGER_ADDR: usize = 0;
pub static mut STAGE_MANAGER_ADDR: usize = 0;

View file

@ -1,9 +1,9 @@
use smash::phx::{Vector3f, Hash40};
use smash::app;
use smash::phx::{Hash40, Vector3f};
pub static RAYGUN_LENGTH : f32 = 8.0;
pub static RAYGUN_HEIGHT : f32 = 6.0;
pub static RAYGUN_HORIZ_OFFSET : f32 = 2.0;
pub static RAYGUN_LENGTH: f32 = 8.0;
pub static RAYGUN_HEIGHT: f32 = 6.0;
pub static RAYGUN_HORIZ_OFFSET: f32 = 2.0;
/*
segment data list : {Z, Y, X, ZRot, Size}
@ -14,28 +14,40 @@ pub static RAYGUN_HORIZ_OFFSET : f32 = 2.0;
*/
pub static SEGMENT_DICT: [[f32; 5]; 15] = [
[0.0, RAYGUN_HEIGHT*2.0, 0.0, 0.0, 0.25], // a
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH, 90.0, 0.25], // b
[0.0, 0.0, RAYGUN_LENGTH, 90.0, 0.25], // c
[0.0, 0.0, 0.0, 0.0, 0.25], // d
[0.0, 0.0, 0.0, 90.0, 0.25], // e
[0.0, RAYGUN_HEIGHT, 0.0, 90.0, 0.25], // f
[0.0, RAYGUN_HEIGHT, 0.0, 0.0, 0.25], // g mid
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH/2.0, 90.0, 0.25], // h
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH/2.0, 52.0, 0.2], // i
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH/2.0, -52.0, 0.2], // j
[0.0, 0.0, RAYGUN_LENGTH/2.0, 90.0, 0.25], // k
[0.0, RAYGUN_HEIGHT/2.0, RAYGUN_LENGTH*3.0/16.0, 52.0, 0.2], // l
[0.0, RAYGUN_HEIGHT*3.0/2.0, RAYGUN_LENGTH*3.0/16.0, -52.0, 0.2], // m
[0.0, RAYGUN_HEIGHT, 0.0, 0.0, 0.15], // n
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH/2.0, 0.0, 0.15], // o
];
[0.0, RAYGUN_HEIGHT * 2.0, 0.0, 0.0, 0.25], // a
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH, 90.0, 0.25], // b
[0.0, 0.0, RAYGUN_LENGTH, 90.0, 0.25], // c
[0.0, 0.0, 0.0, 0.0, 0.25], // d
[0.0, 0.0, 0.0, 90.0, 0.25], // e
[0.0, RAYGUN_HEIGHT, 0.0, 90.0, 0.25], // f
[0.0, RAYGUN_HEIGHT, 0.0, 0.0, 0.25], // g mid
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH / 2.0, 90.0, 0.25], // h
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH / 2.0, 52.0, 0.2], // i
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH / 2.0, -52.0, 0.2], // j
[0.0, 0.0, RAYGUN_LENGTH / 2.0, 90.0, 0.25], // k
[
0.0,
RAYGUN_HEIGHT / 2.0,
RAYGUN_LENGTH * 3.0 / 16.0,
52.0,
0.2,
], // l
[
0.0,
RAYGUN_HEIGHT * 3.0 / 2.0,
RAYGUN_LENGTH * 3.0 / 16.0,
-52.0,
0.2,
], // m
[0.0, RAYGUN_HEIGHT, 0.0, 0.0, 0.15], // n
[0.0, RAYGUN_HEIGHT, RAYGUN_LENGTH / 2.0, 0.0, 0.15], // o
];
/*
/*
Segments making up each character, each index corresponding to:
'A' through 'Z', '0' through '9', ' ', '-', '+', '#' (where '#' is all segments)
*/
pub static ALPHABET: [&str; 40] = [
pub static ALPHABET: [&str; 40] = [
"abcefg",
"adefijn",
"adef",
@ -80,33 +92,44 @@ pub static ALPHABET: [&str; 40] = [
// Each index is a segment's corresponding flipped segment, for when facing left
pub static SEGMENT_REV: [char; 15] = [
'a',
'f',
'e',
'd',
'c',
'b',
'g',
'h',
'm',
'l',
'k',
'j',
'i',
'o',
'n',
'a', 'f', 'e', 'd', 'c', 'b', 'g', 'h', 'm', 'l', 'k', 'j', 'i', 'o', 'n',
];
fn show_segment(module_accessor: &mut app::BattleObjectModuleAccessor, z: f32, y: f32, x: f32, zrot: f32, size: f32) {
let pos = Vector3f{x, y, z};
let rot = Vector3f{x : 0.0, y : 90.0, z : zrot};
let random = Vector3f{x : 0.0, y : 0.0, z : 0.0};
fn show_segment(
module_accessor: &mut app::BattleObjectModuleAccessor,
z: f32,
y: f32,
x: f32,
zrot: f32,
size: f32,
) {
let pos = Vector3f { x, y, z };
let rot = Vector3f {
x: 0.0,
y: 90.0,
z: zrot,
};
let random = Vector3f {
x: 0.0,
y: 0.0,
z: 0.0,
};
unsafe {
app::lua_bind::EffectModule::req_on_joint(module_accessor,
Hash40::new("sys_raygun_bullet"), Hash40::new("top"),
&pos, &rot, size, &random, &random,
false, 0, 0, 0);
app::lua_bind::EffectModule::req_on_joint(
module_accessor,
Hash40::new("sys_raygun_bullet"),
Hash40::new("top"),
&pos,
&rot,
size,
&random,
&random,
false,
0,
0,
0,
);
}
}
@ -118,16 +141,17 @@ fn alphabet_index(to_print: char) -> i32 {
'-' => 37,
'+' => 38,
'#' => 39,
_ => -1
_ => -1,
}
}
fn print_char(module_accessor: &mut app::BattleObjectModuleAccessor,
to_print: char,
line_num: i32,
fn print_char(
module_accessor: &mut app::BattleObjectModuleAccessor,
to_print: char,
line_num: i32,
horiz_offset: f32,
facing_left: i32)
{
facing_left: i32,
) {
let alph_index = alphabet_index(to_print);
if !(0..40).contains(&alph_index) {
return;
@ -136,7 +160,7 @@ fn print_char(module_accessor: &mut app::BattleObjectModuleAccessor,
let line_offset = 40.0 - ((line_num as f32) * 16.0);
for segment_char in segment_str.chars() {
for segment_char in segment_str.chars() {
let mut index = segment_char as i32 - 'a' as i32;
let segment: [f32; 5];
@ -145,7 +169,7 @@ fn print_char(module_accessor: &mut app::BattleObjectModuleAccessor,
}
segment = SEGMENT_DICT[index as usize];
let size_mult : f32 = 0.5;
let size_mult: f32 = 0.5;
let mut z = segment[0];
let mut y = segment[1] + line_offset;
@ -171,7 +195,12 @@ fn print_char(module_accessor: &mut app::BattleObjectModuleAccessor,
pub fn print_string(module_accessor: &mut app::BattleObjectModuleAccessor, to_write: &str) {
// Delete any previous strings
unsafe {
app::lua_bind::EffectModule::kill_kind(module_accessor, Hash40::new("sys_raygun_bullet"), false, true);
app::lua_bind::EffectModule::kill_kind(
module_accessor,
Hash40::new("sys_raygun_bullet"),
false,
true,
);
}
let mut line_num = 0;
@ -194,12 +223,18 @@ pub fn print_string(module_accessor: &mut app::BattleObjectModuleAccessor, to_wr
continue;
}
print_char(module_accessor, curr_char.to_uppercase().collect::<Vec<_>>()[0], line_num, horiz_offset, facing_left);
print_char(
module_accessor,
curr_char.to_uppercase().collect::<Vec<_>>()[0],
line_num,
horiz_offset,
facing_left,
);
char_num += 1;
// short characters
if curr_char == 'D' || curr_char == '1' {
horiz_offset += facing_left as f32 * (RAYGUN_LENGTH/2.0 + 3.0);
horiz_offset += facing_left as f32 * (RAYGUN_LENGTH / 2.0 + 3.0);
} else {
horiz_offset += facing_left as f32 * (RAYGUN_LENGTH + 3.0);
}

View file

@ -1,6 +1,6 @@
use skyline_web::DialogOk;
use std::fs;
use std::io::Write;
use skyline_web::DialogOk;
pub const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
const VERSION_FILE_PATH: &str = "sd:/TrainingModpack/version.txt";
@ -32,4 +32,4 @@ pub fn version_check() {
);
record_current_version(VERSION_FILE_PATH);
}
}
}

View file

@ -59,14 +59,14 @@ pub unsafe fn generate_hitbox_effects(
) {
let size_mult = 19.0 / 200.0;
let (x,y,z) = (center.x, center.y, center.z);
let (x, y, z) = (center.x, center.y, center.z);
let x_dist: f32;
let y_dist: f32;
let z_dist: f32;
let mut n_effects: i32;
if let Some(capsule_center) = capsule_center {
let (x2,y2,z2) = (capsule_center.x, capsule_center.y, capsule_center.z);
let (x2, y2, z2) = (capsule_center.x, capsule_center.y, capsule_center.z);
x_dist = x2 - x;
y_dist = y2 - y;
z_dist = z2 - z;
@ -182,10 +182,18 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
}
let attack_data = *AttackModule::attack_data(module_accessor, i, false);
let center = Vector3f{x: attack_data.x, y: attack_data.y, z: attack_data.z};
let center = Vector3f {
x: attack_data.x,
y: attack_data.y,
z: attack_data.z,
};
let is_capsule = attack_data.x2 != 0.0 || attack_data.y2 != 0.0 || attack_data.z2 != 0.0;
let capsule_center = if is_capsule {
Some(Vector3f{x: attack_data.x2, y: attack_data.y2, z: attack_data.z2})
Some(Vector3f {
x: attack_data.x2,
y: attack_data.y2,
z: attack_data.z2,
})
} else {
None
};
@ -246,10 +254,19 @@ unsafe fn mod_handle_attack(lua_state: u64) {
let y2 = l2c_agent.pop_lua_stack(14); // float or void
let z2 = l2c_agent.pop_lua_stack(15); // float or void
let center = Vector3f{x: x.get_num(), y: y.get_num(), z: z.get_num()};
let capsule_center =
if let (Some(x2), Some(y2), Some(z2)) = (x2.try_get_num(), y2.try_get_num(), z2.try_get_num()) {
Some(Vector3f{x: x2, y: y2, z: z2})
let center = Vector3f {
x: x.get_num(),
y: y.get_num(),
z: z.get_num(),
};
let capsule_center = if let (Some(x2), Some(y2), Some(z2)) =
(x2.try_get_num(), y2.try_get_num(), z2.try_get_num())
{
Some(Vector3f {
x: x2,
y: y2,
z: z2,
})
} else {
None
};
@ -291,10 +308,19 @@ unsafe fn mod_handle_catch(lua_state: u64) {
let y2 = l2c_agent.pop_lua_stack(8); // float or void
let z2 = l2c_agent.pop_lua_stack(9); // float or void
let center = Vector3f{x: x.get_num(), y: y.get_num(), z: z.get_num()};
let capsule_center =
if let (Some(x2), Some(y2), Some(z2)) = (x2.try_get_num(), y2.try_get_num(), z2.try_get_num()) {
Some(Vector3f{x: x2, y: y2, z: z2})
let center = Vector3f {
x: x.get_num(),
y: y.get_num(),
z: z.get_num(),
};
let capsule_center = if let (Some(x2), Some(y2), Some(z2)) =
(x2.try_get_num(), y2.try_get_num(), z2.try_get_num())
{
Some(Vector3f {
x: x2,
y: y2,
z: z2,
})
} else {
None
};

View file

@ -3,7 +3,12 @@
#![feature(const_mut_refs)]
#![feature(exclusive_range_pattern)]
#![feature(once_cell)]
#![allow(clippy::borrow_interior_mutable_const, clippy::not_unsafe_ptr_arg_deref, clippy::missing_safety_doc, clippy::wrong_self_convention)]
#![allow(
clippy::borrow_interior_mutable_const,
clippy::not_unsafe_ptr_arg_deref,
clippy::missing_safety_doc,
clippy::wrong_self_convention
)]
pub mod common;
mod hazard_manager;
@ -24,8 +29,8 @@ use crate::events::{Event, EVENT_QUEUE};
use crate::menu::set_menu_from_url;
use skyline::libc::mkdir;
use std::fs;
use skyline::nro::{self, NroInfo};
use std::fs;
use owo_colors::OwoColorize;
@ -68,7 +73,7 @@ pub fn main() {
hazard_manager::hazard_manager();
training::training_mods();
nro::add_hook(nro_main).unwrap();
unsafe {
mkdir(c_str!("sd:/TrainingModpack/"), 777);
}
@ -87,26 +92,22 @@ pub fn main() {
log!("Loading previous menu from training_modpack_menu.conf...");
let menu_conf = fs::read(menu_conf_path).unwrap();
if menu_conf.starts_with(b"http://localhost") {
set_menu_from_url(std::str::from_utf8(&menu_conf).unwrap());
set_menu_from_url(std::str::from_utf8(&menu_conf).unwrap());
}
}
std::thread::spawn(||{
loop {
std::thread::sleep(std::time::Duration::from_secs(5));
unsafe {
while let Some(event) = EVENT_QUEUE.pop() {
let host = "https://my-project-1511972643240-default-rtdb.firebaseio.com";
let path = format!("/event/{}/device/{}/{}.json",
event.event_name, event.device_id, event.event_time);
let url = format!("{}{}", host, path);
minreq::post(url)
.with_json(&event)
.unwrap()
.send()
.ok();
}
std::thread::spawn(|| loop {
std::thread::sleep(std::time::Duration::from_secs(5));
unsafe {
while let Some(event) = EVENT_QUEUE.pop() {
let host = "https://my-project-1511972643240-default-rtdb.firebaseio.com";
let path = format!(
"/event/{}/device/{}/{}.json",
event.event_name, event.device_id, event.event_time
);
let url = format!("{}{}", host, path);
minreq::post(url).with_json(&event).unwrap().send().ok();
}
}
});

View file

@ -1,30 +1,33 @@
/// Recommended to run with the following command:
/// `RUSTFLAGS=-Awarnings cargo test --target=x86_64-unknown-linux-gnu`
/// But you can replace the target with your PC's target.
/// This will run and render the default menu in your default HTML opening program, ideally Chrome.
#[test]
fn write_menu() {
unsafe {
use std::process::Command;
use crate::common::menu::write_menu;
let folder_path = "../contents.htdocs";
let path = "../contents.htdocs/training_menu.html";
assert!(std::path::Path::new(folder_path).exists(), "Needs required folder: ../contents.htdocs!");
std::fs::write(path, write_menu()).unwrap();
let (cmd, args) = if wsl::is_wsl() || cfg!(target_os = "windows") {
("cmd.exe", ["/C", "start", path])
} else {
("sh", ["-c", "open", path])
};
Command::new(cmd)
.args(&args)
.output()
.expect("failed to open rendered HTML file");
}
}
/// Recommended to run with the following command:
/// `RUSTFLAGS=-Awarnings cargo test --target=x86_64-unknown-linux-gnu`
/// But you can replace the target with your PC's target.
/// This will run and render the default menu in your default HTML opening program, ideally Chrome.
#[test]
fn write_menu() {
unsafe {
use crate::common::menu::write_menu;
use std::process::Command;
let folder_path = "../contents.htdocs";
let path = "../contents.htdocs/training_menu.html";
assert!(
std::path::Path::new(folder_path).exists(),
"Needs required folder: ../contents.htdocs!"
);
std::fs::write(path, write_menu()).unwrap();
let (cmd, args) = if wsl::is_wsl() || cfg!(target_os = "windows") {
("cmd.exe", ["/C", "start", path])
} else {
("sh", ["-c", "open", path])
};
Command::new(cmd)
.args(&args)
.output()
.expect("failed to open rendered HTML file");
}
}

View file

@ -38,7 +38,8 @@ unsafe fn get_angle(module_accessor: &mut app::BattleObjectModuleAccessor) -> Op
let launch_speed_x = KineticEnergy::get_speed_x(KineticModule::get_energy(
module_accessor,
*FIGHTER_KINETIC_ENERGY_ID_DAMAGE,
) as *mut smash::app::KineticEnergy);
)
as *mut smash::app::KineticEnergy);
// If we're launched left, reverse stick X
if launch_speed_x < 0.0 {
PI - angle
@ -51,4 +52,4 @@ unsafe fn get_angle(module_accessor: &mut app::BattleObjectModuleAccessor) -> Op
fn is_correct_status(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
is_airborne(module_accessor) && is_in_hitstun(module_accessor)
}
}

View file

@ -19,7 +19,7 @@ pub unsafe fn mod_get_stick_dir(
match DIRECTION {
AttackAngle::UP => Some(1.0),
AttackAngle::DOWN =>Some(-1.0),
AttackAngle::DOWN => Some(-1.0),
_ => None,
}
}
}

View file

@ -29,23 +29,25 @@ unsafe fn was_in_shieldstun(module_accessor: *mut app::BattleObjectModuleAccesso
macro_rules! actionable_statuses {
() => {
vec![
FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE_AIR,
FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ATTACK_AIR,
FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_GUARD_ON,
FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE
];
vec![
FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE_AIR,
FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ATTACK_AIR,
FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_GUARD_ON,
FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE,
];
};
}
unsafe fn is_actionable(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
actionable_statuses!().iter().any(
|actionable_transition|
WorkModule::is_enable_transition_term(module_accessor, **actionable_transition))
|| CancelModule::is_enable_cancel(module_accessor)
actionable_statuses!().iter().any(|actionable_transition| {
WorkModule::is_enable_transition_term(module_accessor, **actionable_transition)
}) || CancelModule::is_enable_cancel(module_accessor)
}
fn update_frame_advantage(module_accessor: *mut app::BattleObjectModuleAccessor, new_frame_adv: i32) {
fn update_frame_advantage(
module_accessor: *mut app::BattleObjectModuleAccessor,
new_frame_adv: i32,
) {
unsafe {
FRAME_ADVANTAGE = new_frame_adv;
if MENU.frame_advantage == consts::OnOff::On {
@ -57,7 +59,7 @@ fn update_frame_advantage(module_accessor: *mut app::BattleObjectModuleAccessor,
pub unsafe fn is_enable_transition_term(
module_accessor: *mut app::BattleObjectModuleAccessor,
transition_term: i32,
is: bool
is: bool,
) {
let entry_id_int =
WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32;
@ -70,12 +72,13 @@ pub unsafe fn is_enable_transition_term(
// This is in the case that the transition term becomes enabled after our initial check
// and the user buffers that action on that frame.
if !PLAYER_ACTIONABLE &&
(
(is && actionable_statuses!().iter().any(|actionable_transition| *actionable_transition == transition_term))
||
(CancelModule::is_enable_cancel(module_accessor))
) {
if !PLAYER_ACTIONABLE
&& ((is
&& actionable_statuses!()
.iter()
.any(|actionable_transition| *actionable_transition == transition_term))
|| (CancelModule::is_enable_cancel(module_accessor)))
{
PLAYER_ACTIVE_FRAME = frame_counter::get_frame_count(FRAME_COUNTER_INDEX);
PLAYER_ACTIONABLE = true;
@ -83,8 +86,10 @@ pub unsafe fn is_enable_transition_term(
if PLAYER_ACTIONABLE && CPU_ACTIONABLE && FRAME_ADVANTAGE_CHECK {
let cpu_module_accessor = get_module_accessor(FighterId::CPU);
if was_in_hitstun(cpu_module_accessor) || was_in_shieldstun(cpu_module_accessor) {
update_frame_advantage(module_accessor,
(CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32);
update_frame_advantage(
module_accessor,
(CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32,
);
}
frame_counter::stop_counting(FRAME_COUNTER_INDEX);
@ -93,9 +98,7 @@ pub unsafe fn is_enable_transition_term(
}
}
pub unsafe fn get_command_flag_cat(
module_accessor: &mut app::BattleObjectModuleAccessor,
) {
pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
let entry_id_int =
WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32;
// do only once.
@ -136,8 +139,10 @@ pub unsafe fn get_command_flag_cat(
// if both are now active
if PLAYER_ACTIONABLE && CPU_ACTIONABLE && FRAME_ADVANTAGE_CHECK {
if was_in_hitstun(cpu_module_accessor) || was_in_shieldstun(cpu_module_accessor) {
update_frame_advantage(player_module_accessor,
(CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32);
update_frame_advantage(
player_module_accessor,
(CPU_ACTIVE_FRAME as i64 - PLAYER_ACTIVE_FRAME as i64) as i32,
);
}
frame_counter::stop_counting(FRAME_COUNTER_INDEX);

View file

@ -55,9 +55,7 @@ unsafe fn mod_handle_di(fighter: &mut L2CFighterCommon, _arg1: L2CValue) {
roll_di_case();
let angle_tuple = DI_CASE
.into_angle()
.map_or((0.0, 0.0), |angle| {
let angle_tuple = DI_CASE.into_angle().map_or((0.0, 0.0), |angle| {
let a = if should_reverse_angle(&DI_CASE) {
PI - angle
} else {
@ -71,13 +69,11 @@ unsafe fn mod_handle_di(fighter: &mut L2CFighterCommon, _arg1: L2CValue) {
}
pub fn should_reverse_angle(direction: &Direction) -> bool {
let cpu_module_accessor = get_module_accessor(FighterId::CPU);
let player_module_accessor = get_module_accessor(FighterId::Player);
unsafe {
PostureModule::pos_x(player_module_accessor)
> PostureModule::pos_x(cpu_module_accessor)
&& ![Direction::LEFT, Direction::RIGHT].contains(&direction)
PostureModule::pos_x(player_module_accessor) > PostureModule::pos_x(cpu_module_accessor)
&& ![Direction::LEFT, Direction::RIGHT].contains(&direction)
}
}
@ -102,4 +98,4 @@ pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccesso
}
reset_di_case(module_accessor);
}
}

View file

@ -12,9 +12,7 @@ static mut DELAY: u32 = 0;
static mut FAST_FALL: bool = false;
fn should_fast_fall() -> bool {
unsafe {
FAST_FALL
}
unsafe { FAST_FALL }
}
pub fn roll_fast_fall() {

View file

@ -75,7 +75,7 @@ fn tick() {
}
}
pub fn reset_all(){
pub fn reset_all() {
unsafe {
for (index, _frame) in COUNTERS.iter().enumerate() {
full_reset(index);
@ -83,9 +83,7 @@ pub fn reset_all(){
}
}
pub fn get_command_flag_cat(
module_accessor: &mut app::BattleObjectModuleAccessor,
) {
pub fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModuleAccessor) {
if !is_operation_cpu(module_accessor) {
return;
}

View file

@ -6,9 +6,7 @@ use smash::lib::lua_const::*;
static mut FULL_HOP: bool = false;
pub fn should_full_hop() -> bool {
unsafe{
FULL_HOP
}
unsafe { FULL_HOP }
}
pub fn roll_full_hop() {

View file

@ -1,8 +1,8 @@
use crate::common::MENU;
use lazy_static::lazy_static;
use parking_lot::Mutex;
use skyline::nn::hid::{NpadHandheldState, GetNpadStyleSet};
use skyline::nn::hid::{GetNpadStyleSet, NpadHandheldState};
use std::collections::VecDeque;
use crate::common::MENU;
lazy_static! {
static ref P1_DELAYED_NPAD_STATES: Mutex<VecDeque<NpadHandheldState>> =
@ -23,10 +23,7 @@ pub unsafe fn p1_controller_id() -> u32 {
}
}
pub fn handle_get_npad_state(
state: *mut NpadHandheldState,
controller_id: *const u32,
) {
pub fn handle_get_npad_state(state: *mut NpadHandheldState, controller_id: *const u32) {
unsafe {
if crate::common::is_training_mode() {
if *controller_id == p1_controller_id() {
@ -48,4 +45,4 @@ pub fn handle_get_npad_state(
}
}
}
}
}

View file

@ -1,15 +1,13 @@
use skyline::nn::hid::NpadHandheldState;
use smash::app::{BattleObjectModuleAccessor, lua_bind::*};
use smash::lib::lua_const::*;
use crate::training::input_delay::p1_controller_id;
use lazy_static::lazy_static;
use parking_lot::Mutex;
use crate::training::input_delay::p1_controller_id;
use skyline::nn::hid::NpadHandheldState;
use smash::app::{lua_bind::*, BattleObjectModuleAccessor};
use smash::lib::lua_const::*;
lazy_static! {
static ref P1_NPAD_STATES: Mutex<[NpadHandheldState; 90]> =
Mutex::new([{
NpadHandheldState::default()
}; 90]);
Mutex::new([{ NpadHandheldState::default() }; 90]);
}
pub static mut INPUT_RECORD: InputRecordState = InputRecordState::None;
@ -26,23 +24,22 @@ use InputRecordState::*;
pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAccessor) {
let entry_id_int =
WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32;
WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32;
if entry_id_int == 0 {
// Attack + Dpad Right: Playback
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_ATTACK)
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_S_R) {
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_S_R)
{
playback();
}
// Attack + Dpad Left: Record
else if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_ATTACK)
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_S_L)
{
record();
record();
}
if INPUT_RECORD == Record || INPUT_RECORD == Playback {
if INPUT_RECORD_FRAME >= P1_NPAD_STATES.lock().len() - 1 {
if INPUT_RECORD == Record {
@ -70,10 +67,7 @@ pub unsafe fn playback() {
}
#[allow(dead_code)]
pub unsafe fn handle_get_npad_state(
state: *mut NpadHandheldState,
controller_id: *const u32,
) {
pub unsafe fn handle_get_npad_state(state: *mut NpadHandheldState, controller_id: *const u32) {
if *controller_id == p1_controller_id() {
if INPUT_RECORD == Record {
P1_NPAD_STATES.lock()[INPUT_RECORD_FRAME] = *state;

View file

@ -101,17 +101,21 @@ pub unsafe fn is_enable_transition_term(
_module_accessor: *mut app::BattleObjectModuleAccessor,
term: i32,
) -> Option<bool> {
if !is_operation_cpu(&mut*_module_accessor) {
if !is_operation_cpu(&mut *_module_accessor) {
return None;
}
// Only handle ledge scenarios from menu
if StatusModule::status_kind(_module_accessor) as i32 != *FIGHTER_STATUS_KIND_CLIFF_WAIT || MENU.ledge_state == LedgeOption::empty() {
if StatusModule::status_kind(_module_accessor) as i32 != *FIGHTER_STATUS_KIND_CLIFF_WAIT
|| MENU.ledge_state == LedgeOption::empty()
{
return None;
}
// Disallow the default cliff-climb if we are waiting
if (LEDGE_CASE == LedgeOption::WAIT || frame_counter::get_frame_count(LEDGE_DELAY_COUNTER) < LEDGE_DELAY) &&
term == *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB {
if (LEDGE_CASE == LedgeOption::WAIT
|| frame_counter::get_frame_count(LEDGE_DELAY_COUNTER) < LEDGE_DELAY)
&& term == *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB
{
return Some(false);
}
None

View file

@ -176,37 +176,35 @@ unsafe fn perform_action(module_accessor: &mut app::BattleObjectModuleAccessor)
Doesn't actually cause the shield, but will clear the buffer once shield is possible.
Shield hold is performed through shield::should_hold_shield and request_shield
*/
(*FIGHTER_STATUS_KIND_GUARD_ON, *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE)
(
*FIGHTER_STATUS_KIND_GUARD_ON,
*FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE,
)
} else {
(*FIGHTER_STATUS_KIND_ESCAPE_AIR, *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE)
(
*FIGHTER_STATUS_KIND_ESCAPE_AIR,
*FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE,
)
};
get_flag(module_accessor, expected_status, command_flag)
}
Action::JUMP => {
update_jump_flag(module_accessor)
}
Action::SPOT_DODGE => {
get_flag(
module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
)
}
Action::ROLL_F => {
get_flag(
module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE_F,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
)
}
Action::ROLL_B => {
get_flag(
module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE_B,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
)
}
Action::JUMP => update_jump_flag(module_accessor),
Action::SPOT_DODGE => get_flag(
module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
),
Action::ROLL_F => get_flag(
module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE_F,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
),
Action::ROLL_B => get_flag(
module_accessor,
*FIGHTER_STATUS_KIND_ESCAPE_B,
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
),
Action::SHIELD => {
if !is_grounded(module_accessor) {
return 0;
@ -237,7 +235,7 @@ pub fn request_shield(module_accessor: &mut app::BattleObjectModuleAccessor) ->
match get_current_buffer() {
Action::SHIELD => true,
Action::AIR_DODGE => is_grounded(module_accessor),
_ => false
_ => false,
}
}

View file

@ -1,18 +1,18 @@
use crate::common::{is_training_mode, menu, FIGHTER_MANAGER_ADDR, STAGE_MANAGER_ADDR};
use crate::hitbox_visualizer;
use skyline::nn::ro::LookupSymbol;
use skyline::nn::hid::*;
use skyline::nn::ro::LookupSymbol;
use smash::app::{self, lua_bind::*};
use smash::lib::lua_const::*;
use smash::params::*;
pub mod combo;
pub mod directional_influence;
pub mod frame_counter;
pub mod ledge;
pub mod sdi;
pub mod shield;
pub mod tech;
pub mod ledge;
pub mod frame_counter;
mod air_dodge_direction;
mod attack_angle;
@ -162,20 +162,19 @@ pub unsafe fn get_stick_x(module_accessor: &mut app::BattleObjectModuleAccessor)
air_dodge_direction::mod_get_stick_x(module_accessor).unwrap_or(ori)
}
/**
* Called when:
* angled ftilt/fsmash
*/
#[skyline::hook(replace = ControlModule::get_stick_dir)]
pub unsafe fn get_stick_dir(module_accessor: &mut app::BattleObjectModuleAccessor) -> f32 {
let ori = original!()(module_accessor);
if !is_training_mode() {
return ori;
}
#[skyline::hook(replace = ControlModule::get_stick_dir)]
pub unsafe fn get_stick_dir(module_accessor: &mut app::BattleObjectModuleAccessor) -> f32 {
let ori = original!()(module_accessor);
if !is_training_mode() {
return ori;
}
attack_angle::mod_get_stick_dir(module_accessor).unwrap_or(ori)
}
attack_angle::mod_get_stick_dir(module_accessor).unwrap_or(ori)
}
/**
*
@ -291,7 +290,7 @@ fn params_main(params_info: &ParamsInfo<'_>) {
#[allow(improper_ctypes)]
extern "C" {
fn add_nn_hid_hook(callback: fn(*mut NpadHandheldState,*const u32));
fn add_nn_hid_hook(callback: fn(*mut NpadHandheldState, *const u32));
}
pub fn training_mods() {

View file

@ -1,8 +1,8 @@
use crate::common::consts::FighterId;
use crate::common::consts::OnOff;
use crate::common::consts::SaveStateMirroring;
use crate::common::MENU;
use crate::common::get_random_int;
use crate::common::MENU;
use crate::training::reset;
use smash::app::{self, lua_bind::*};
use smash::hash40;
@ -51,7 +51,7 @@ pub unsafe fn should_mirror() -> f32 {
match MENU.save_state_mirroring {
SaveStateMirroring::None => 1.0,
SaveStateMirroring::Alternate => -1.0 * MIRROR_STATE,
SaveStateMirroring::Random => {([-1.0, 1.0])[get_random_int(2) as usize]},
SaveStateMirroring::Random => ([-1.0, 1.0])[get_random_int(2) as usize],
}
}
@ -81,7 +81,7 @@ pub unsafe fn get_param_int(
None
}
fn set_damage(module_accessor: &mut app::BattleObjectModuleAccessor, damage : f32) {
fn set_damage(module_accessor: &mut app::BattleObjectModuleAccessor, damage: f32) {
let overwrite_damage;
unsafe {

View file

@ -323,7 +323,10 @@ fn needs_oos_handling_drop_shield() -> bool {
}
pub fn is_aerial(action: Action) -> bool {
matches!(action, Action::NAIR | Action::FAIR | Action::BAIR | Action::UAIR | Action::DAIR)
matches!(
action,
Action::NAIR | Action::FAIR | Action::BAIR | Action::UAIR | Action::DAIR
)
}
// Needed for shield drop options