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:
parent
f41065a7f5
commit
bc3d2d8df5
24 changed files with 748 additions and 456 deletions
3
.github/workflows/rust.yml
vendored
3
.github/workflows/rust.yml
vendored
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
41
src/lib.rs
41
src/lib.rs
|
@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
63
src/test.rs
63
src/test.rs
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue