1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2025-02-17 14:40:31 +00:00

Clippy Linter Fixes (#323)

* initial

* small fix

* Update rust.yml

* Update lib.rs

* Format Rust code using rustfmt

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
jugeeya 2022-03-24 23:48:50 -07:00 committed by GitHub
parent 3a543581da
commit 6da6aa41b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 1079 additions and 644 deletions

View file

@ -116,20 +116,20 @@ jobs:
Install the same way you would install a full release. Install the same way you would install a full release.
## Installing on Ryujinx \n ## Installing on Ryujinx
Instructions to get the beta working on Ryujinx.\n Instructions to get the beta working on Ryujinx.
1. Download a Skyline-tolerant build of Ryujinx, which can be found here: https://github.com/Ryujinx/Ryujinx/pull/2966#issuecomment-1003648371 \n 1. Download a Skyline-tolerant build of Ryujinx, which can be found here: https://github.com/Ryujinx/Ryujinx/pull/2966#issuecomment-1003648371
2. Download the beta. https://github.com/jugeeya/UltimateTrainingModpack/releases/tag/beta \n 2. Download the beta. https://github.com/jugeeya/UltimateTrainingModpack/releases/tag/beta
3. The atmosphere folder from the beta zip is everything that should be in Ryujinx's mod folder. This means `%AppData%/Ryujinx/mods/contents/01006a800016e000` should have what `atmosphere/contents/01006a800016e000` has. \n 3. The atmosphere folder from the beta zip is everything that should be in Ryujinx's mod folder. This means `%AppData%/Ryujinx/mods/contents/01006a800016e000` should have what `atmosphere/contents/01006a800016e000` has.
4. You should be good to go after this. When in training mode, use Special+Uptaunt to bring up the menu. \n 4. You should be good to go after this. When in training mode, use Special+Uptaunt to bring up the menu.
files: > files: >
training_modpack_beta.zip training_modpack_beta.zip
- name: Upload zip as artifact - name: Upload zip as artifact

View file

@ -1,256 +1,290 @@
use crate::common::*; use crate::common::consts::get_menu_from_url;
use crate::events::{Event, EVENT_QUEUE}; use crate::common::*;
use crate::training::frame_counter; use crate::events::{Event, EVENT_QUEUE};
use crate::common::consts::get_menu_from_url; use crate::mkdir;
use ramhorns::Template; use crate::training::frame_counter;
use skyline::info::get_program_id; use ramhorns::Template;
use skyline_web::{Background, BootDisplay, Webpage}; use skyline::info::get_program_id;
use smash::lib::lua_const::*; use skyline_web::{Background, BootDisplay, Webpage};
use std::fs; use smash::lib::lua_const::*;
use std::path::Path; use std::fs;
use crate::mkdir; use std::path::Path;
static mut FRAME_COUNTER_INDEX: usize = 0; static mut FRAME_COUNTER_INDEX: usize = 0;
const MENU_LOCKOUT_FRAMES: u32 = 15; const MENU_LOCKOUT_FRAMES: u32 = 15;
pub static mut QUICK_MENU_ACTIVE: bool = false; pub static mut QUICK_MENU_ACTIVE: bool = false;
pub fn init() { pub fn init() {
unsafe { unsafe {
FRAME_COUNTER_INDEX = frame_counter::register_counter(); FRAME_COUNTER_INDEX = frame_counter::register_counter();
write_menu(); write_menu();
} }
} }
pub unsafe fn menu_condition(module_accessor: &mut smash::app::BattleObjectModuleAccessor) -> bool { pub unsafe fn menu_condition(module_accessor: &mut smash::app::BattleObjectModuleAccessor) -> bool {
// Only check for button combination if the counter is 0 (not locked out) // Only check for button combination if the counter is 0 (not locked out)
match frame_counter::get_frame_count(FRAME_COUNTER_INDEX) { match frame_counter::get_frame_count(FRAME_COUNTER_INDEX) {
0 => { 0 => {
ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_SPECIAL) ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_SPECIAL)
&& ControlModule::check_button_on_trriger( && ControlModule::check_button_on_trriger(
module_accessor, module_accessor,
*CONTROL_PAD_BUTTON_APPEAL_HI, *CONTROL_PAD_BUTTON_APPEAL_HI,
) )
} }
1..MENU_LOCKOUT_FRAMES => false, 1..MENU_LOCKOUT_FRAMES => false,
_ => { _ => {
// Waited longer than the lockout time, reset the counter so the menu can be opened again // Waited longer than the lockout time, reset the counter so the menu can be opened again
frame_counter::full_reset(FRAME_COUNTER_INDEX); frame_counter::full_reset(FRAME_COUNTER_INDEX);
false false
} }
} }
} }
pub unsafe fn write_menu() { pub unsafe fn write_menu() {
let tpl = Template::new(include_str!("../templates/menu.html")).unwrap(); let tpl = Template::new(include_str!("../templates/menu.html")).unwrap();
let overall_menu = get_menu(); let overall_menu = get_menu();
let data = tpl.render(&overall_menu); let data = tpl.render(&overall_menu);
// Now that we have the html, write it to file // Now that we have the html, write it to file
// From skyline-web // From skyline-web
let program_id = get_program_id(); let program_id = get_program_id();
let htdocs_dir = "training_modpack"; let htdocs_dir = "training_modpack";
let menu_dir_path = Path::new("sd:/atmosphere/contents") let menu_dir_path = Path::new("sd:/atmosphere/contents")
.join(&format!("{:016X}", program_id)) .join(&format!("{:016X}", program_id))
.join(&format!("manual_html/html-document/{}.htdocs/", htdocs_dir)); .join(&format!("manual_html/html-document/{}.htdocs/", htdocs_dir));
let menu_html_path = menu_dir_path let menu_html_path = menu_dir_path.join("training_menu.html");
.join("training_menu.html");
mkdir(menu_dir_path.to_str().unwrap().as_bytes().as_ptr(), 777);
mkdir(menu_dir_path.to_str().unwrap().as_bytes().as_ptr(), 777); let write_resp = fs::write(menu_html_path, data);
let write_resp = fs::write(menu_html_path, data); if write_resp.is_err() {
if write_resp.is_err() { println!("Error!: {}", write_resp.err().unwrap());
println!("Error!: {}", write_resp.err().unwrap()); }
} }
}
const MENU_CONF_PATH: &str = "sd:/TrainingModpack/training_modpack_menu.conf";
const MENU_CONF_PATH: &str = "sd:/TrainingModpack/training_modpack_menu.conf";
pub fn set_menu_from_url(orig_last_url: &str) {
pub fn set_menu_from_url(orig_last_url: &str) { let last_url = &orig_last_url.replace("&save_defaults=1", "");
let last_url = &orig_last_url.replace("&save_defaults=1", ""); unsafe {
unsafe { MENU = get_menu_from_url(MENU, last_url);
MENU = get_menu_from_url(MENU, last_url);
if MENU.quick_menu == OnOff::Off {
if MENU.quick_menu == OnOff::Off { if is_emulator() {
if is_emulator() { skyline::error::show_error(
skyline::error::show_error( 0x69,
0x69, "Cannot use web menu on emulator.\n\0",
"Cannot use web menu on emulator.\n\0", "Only the quick menu is runnable via emulator currently.\n\0",
"Only the quick menu is runnable via emulator currently.\n\0", );
); MENU.quick_menu = OnOff::On;
MENU.quick_menu = OnOff::On; }
} }
} }
}
if last_url.len() != orig_last_url.len() {
if last_url.len() != orig_last_url.len() { // Save as default
// Save as default unsafe {
unsafe { DEFAULT_MENU = MENU;
DEFAULT_MENU = MENU; write_menu();
write_menu(); }
} let menu_defaults_conf_path = "sd:/TrainingModpack/training_modpack_menu_defaults.conf";
let menu_defaults_conf_path = "sd:/TrainingModpack/training_modpack_menu_defaults.conf"; std::fs::write(menu_defaults_conf_path, last_url)
std::fs::write(menu_defaults_conf_path, last_url) .expect("Failed to write default menu conf file");
.expect("Failed to write default menu conf file"); }
}
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 {
unsafe { EVENT_QUEUE.push(Event::menu_open(last_url.to_string()));
EVENT_QUEUE.push(Event::menu_open(last_url.to_string())); }
} }
}
pub fn spawn_menu() {
pub fn spawn_menu() { unsafe {
unsafe { frame_counter::reset_frame_count(FRAME_COUNTER_INDEX);
frame_counter::reset_frame_count(FRAME_COUNTER_INDEX); frame_counter::start_counting(FRAME_COUNTER_INDEX);
frame_counter::start_counting(FRAME_COUNTER_INDEX); }
}
let mut quick_menu = false;
let mut quick_menu = false; unsafe {
unsafe { if MENU.quick_menu == OnOff::On {
if MENU.quick_menu == OnOff::On { quick_menu = true;
quick_menu = true; }
} }
}
if !quick_menu {
if !quick_menu { let fname = "training_menu.html";
let fname = "training_menu.html"; let params = unsafe { MENU.to_url_params() };
let params = unsafe { MENU.to_url_params() }; let page_response = Webpage::new()
let page_response = Webpage::new() .background(Background::BlurredScreenshot)
.background(Background::BlurredScreenshot) .htdocs_dir("training_modpack")
.htdocs_dir("training_modpack") .boot_display(BootDisplay::BlurredScreenshot)
.boot_display(BootDisplay::BlurredScreenshot) .boot_icon(true)
.boot_icon(true) .start_page(&format!("{}{}", fname, params))
.start_page(&format!("{}{}", fname, params)) .open()
.open() .unwrap();
.unwrap();
let orig_last_url = page_response.get_last_url().unwrap();
let orig_last_url = page_response.get_last_url().unwrap();
set_menu_from_url(orig_last_url);
set_menu_from_url(orig_last_url); } else {
} else { unsafe {
unsafe { QUICK_MENU_ACTIVE = true;
QUICK_MENU_ACTIVE = true; }
} }
} }
}
use skyline::nn::hid::NpadGcState;
use skyline::nn::hid::NpadGcState;
pub struct ButtonPresses {
pub struct ButtonPresses { pub a: ButtonPress,
pub a: ButtonPress, pub b: ButtonPress,
pub b: ButtonPress, pub zr: ButtonPress,
pub zr: ButtonPress, pub zl: ButtonPress,
pub zl: ButtonPress, pub left: ButtonPress,
pub left: ButtonPress, pub right: ButtonPress,
pub right: ButtonPress, pub up: ButtonPress,
pub up: ButtonPress, pub down: ButtonPress,
pub down: ButtonPress }
}
pub struct ButtonPress {
pub struct ButtonPress { pub prev_frame_is_pressed: bool,
pub is_pressed: bool, pub is_pressed: bool,
pub lockout_frames: usize pub lockout_frames: usize,
} }
impl ButtonPress { impl ButtonPress {
pub fn default() -> ButtonPress { pub fn default() -> ButtonPress {
ButtonPress{ ButtonPress {
is_pressed: false, prev_frame_is_pressed: false,
lockout_frames: 0 is_pressed: false,
} lockout_frames: 0,
} }
}
pub fn read_press(&mut self) -> bool {
if self.is_pressed { pub fn read_press(&mut self) -> bool {
self.is_pressed = false; if self.is_pressed {
if self.lockout_frames == 0 { self.is_pressed = false;
self.lockout_frames = 15; if !self.prev_frame_is_pressed && self.lockout_frames == 0 {
return true; self.lockout_frames = 10;
} self.prev_frame_is_pressed = true;
} return true;
}
if self.lockout_frames > 0 { }
self.lockout_frames -= 1;
} if self.lockout_frames > 0 {
self.lockout_frames -= 1;
false }
}
} self.prev_frame_is_pressed = self.is_pressed;
false
impl ButtonPresses { }
pub fn default() -> ButtonPresses { }
ButtonPresses{
a: ButtonPress::default(), impl ButtonPresses {
b: ButtonPress::default(), pub fn default() -> ButtonPresses {
zr: ButtonPress::default(), ButtonPresses {
zl: ButtonPress::default(), a: ButtonPress::default(),
left: ButtonPress::default(), b: ButtonPress::default(),
right: ButtonPress::default(), zr: ButtonPress::default(),
up: ButtonPress::default(), zl: ButtonPress::default(),
down: ButtonPress::default() left: ButtonPress::default(),
} right: ButtonPress::default(),
} up: ButtonPress::default(),
} down: ButtonPress::default(),
}
pub static mut BUTTON_PRESSES : ButtonPresses = ButtonPresses{ }
a: ButtonPress{is_pressed: false, lockout_frames: 0}, }
b: ButtonPress{is_pressed: false, lockout_frames: 0},
zr: ButtonPress{is_pressed: false, lockout_frames: 0}, pub static mut BUTTON_PRESSES: ButtonPresses = ButtonPresses {
zl: ButtonPress{is_pressed: false, lockout_frames: 0}, a: ButtonPress {
left: ButtonPress{is_pressed: false, lockout_frames: 0}, prev_frame_is_pressed: false,
right: ButtonPress{is_pressed: false, lockout_frames: 0}, is_pressed: false,
up: ButtonPress{is_pressed: false, lockout_frames: 0}, lockout_frames: 0,
down: ButtonPress{is_pressed: false, lockout_frames: 0}, },
}; b: ButtonPress {
prev_frame_is_pressed: false,
pub fn handle_get_npad_state(state: *mut NpadGcState, _controller_id: *const u32) { is_pressed: false,
unsafe { lockout_frames: 0,
if menu::QUICK_MENU_ACTIVE { },
// TODO: This should make more sense, look into. zr: ButtonPress {
// BUTTON_PRESSES.a.is_pressed = (*state).Buttons & (1 << 0) > 0; prev_frame_is_pressed: false,
// BUTTON_PRESSES.b.is_pressed = (*state).Buttons & (1 << 1) > 0; is_pressed: false,
// BUTTON_PRESSES.zl.is_pressed = (*state).Buttons & (1 << 8) > 0; lockout_frames: 0,
// BUTTON_PRESSES.zr.is_pressed = (*state).Buttons & (1 << 9) > 0; },
// BUTTON_PRESSES.left.is_pressed = (*state).Buttons & ((1 << 12) | (1 << 16)) > 0; zl: ButtonPress {
// BUTTON_PRESSES.right.is_pressed = (*state).Buttons & ((1 << 14) | (1 << 18)) > 0; prev_frame_is_pressed: false,
// BUTTON_PRESSES.down.is_pressed = (*state).Buttons & ((1 << 15) | (1 << 19)) > 0; is_pressed: false,
// BUTTON_PRESSES.up.is_pressed = (*state).Buttons & ((1 << 13) | (1 << 17)) > 0; lockout_frames: 0,
},
if frame_counter::get_frame_count(FRAME_COUNTER_INDEX) != 0 { left: ButtonPress {
return; prev_frame_is_pressed: false,
} is_pressed: false,
lockout_frames: 0,
if (*state).Buttons & (1 << 0) > 0 { },
BUTTON_PRESSES.a.is_pressed = true; right: ButtonPress {
} prev_frame_is_pressed: false,
if (*state).Buttons & (1 << 1) > 0 { is_pressed: false,
BUTTON_PRESSES.b.is_pressed = true; lockout_frames: 0,
} },
if (*state).Buttons & (1 << 8) > 0 { up: ButtonPress {
BUTTON_PRESSES.zl.is_pressed = true; prev_frame_is_pressed: false,
} is_pressed: false,
if (*state).Buttons & (1 << 9) > 0 { lockout_frames: 0,
BUTTON_PRESSES.zr.is_pressed = true; },
} down: ButtonPress {
if (*state).Buttons & ((1 << 12) | (1 << 16)) > 0 { prev_frame_is_pressed: false,
BUTTON_PRESSES.left.is_pressed = true; is_pressed: false,
} lockout_frames: 0,
if (*state).Buttons & ((1 << 14) | (1 << 18)) > 0 { },
BUTTON_PRESSES.right.is_pressed = true; };
}
if (*state).Buttons & ((1 << 15) | (1 << 19)) > 0 { pub fn handle_get_npad_state(state: *mut NpadGcState, _controller_id: *const u32) {
BUTTON_PRESSES.down.is_pressed = true; unsafe {
} if menu::QUICK_MENU_ACTIVE {
if (*state).Buttons & ((1 << 13) | (1 << 17)) > 0 { // TODO: This should make more sense, look into.
BUTTON_PRESSES.up.is_pressed = true; // BUTTON_PRESSES.a.is_pressed = (*state).Buttons & (1 << 0) > 0;
} // BUTTON_PRESSES.b.is_pressed = (*state).Buttons & (1 << 1) > 0;
// BUTTON_PRESSES.zl.is_pressed = (*state).Buttons & (1 << 8) > 0;
// If we're here, remove all other Npad presses... // BUTTON_PRESSES.zr.is_pressed = (*state).Buttons & (1 << 9) > 0;
// Should we exclude the home button? // BUTTON_PRESSES.left.is_pressed = (*state).Buttons & ((1 << 12) | (1 << 16)) > 0;
(*state) = NpadGcState::default(); // BUTTON_PRESSES.right.is_pressed = (*state).Buttons & ((1 << 14) | (1 << 18)) > 0;
} // BUTTON_PRESSES.down.is_pressed = (*state).Buttons & ((1 << 15) | (1 << 19)) > 0;
} // BUTTON_PRESSES.up.is_pressed = (*state).Buttons & ((1 << 13) | (1 << 17)) > 0;
}
if frame_counter::get_frame_count(FRAME_COUNTER_INDEX) != 0 {
return;
}
if (*state).Buttons & (1 << 0) > 0 {
BUTTON_PRESSES.a.is_pressed = true;
}
if (*state).Buttons & (1 << 1) > 0 {
BUTTON_PRESSES.b.is_pressed = true;
}
if (*state).Buttons & (1 << 8) > 0 {
BUTTON_PRESSES.zl.is_pressed = true;
}
if (*state).Buttons & (1 << 9) > 0 {
BUTTON_PRESSES.zr.is_pressed = true;
}
if (*state).Buttons & ((1 << 12) | (1 << 16)) > 0 {
BUTTON_PRESSES.left.is_pressed = true;
}
if (*state).Buttons & ((1 << 14) | (1 << 18)) > 0 {
BUTTON_PRESSES.right.is_pressed = true;
}
if (*state).Buttons & ((1 << 15) | (1 << 19)) > 0 {
BUTTON_PRESSES.down.is_pressed = true;
}
if (*state).Buttons & ((1 << 13) | (1 << 17)) > 0 {
BUTTON_PRESSES.up.is_pressed = true;
}
// If we're here, remove all other Npad presses...
// Should we exclude the home button?
(*state) = NpadGcState::default();
}
}
}

View file

@ -1,139 +1,138 @@
pub mod consts; pub mod consts;
pub mod events; pub mod events;
pub mod menu; pub mod menu;
pub mod raygun_printer; pub mod raygun_printer;
pub mod release; pub mod release;
use crate::common::consts::*; use crate::common::consts::*;
use smash::app::{self, lua_bind::*}; use smash::app::{self, lua_bind::*};
use smash::lib::lua_const::*; use smash::lib::lua_const::*;
pub use crate::common::consts::MENU; pub use crate::common::consts::MENU;
pub static mut DEFAULT_MENU: TrainingModpackMenu = crate::common::consts::DEFAULT_MENU; pub static mut DEFAULT_MENU: TrainingModpackMenu = crate::common::consts::DEFAULT_MENU;
pub static mut BASE_MENU: TrainingModpackMenu = unsafe { DEFAULT_MENU }; pub static mut BASE_MENU: TrainingModpackMenu = unsafe { DEFAULT_MENU };
pub static mut FIGHTER_MANAGER_ADDR: usize = 0; pub static mut FIGHTER_MANAGER_ADDR: usize = 0;
pub static mut STAGE_MANAGER_ADDR: usize = 0; pub static mut STAGE_MANAGER_ADDR: usize = 0;
#[cfg(not(feature = "outside_training_mode"))] #[cfg(not(feature = "outside_training_mode"))]
extern "C" { extern "C" {
#[link_name = "\u{1}_ZN3app9smashball16is_training_modeEv"] #[link_name = "\u{1}_ZN3app9smashball16is_training_modeEv"]
pub fn is_training_mode() -> bool; pub fn is_training_mode() -> bool;
} }
#[cfg(feature = "outside_training_mode")] #[cfg(feature = "outside_training_mode")]
pub fn is_training_mode() -> bool { pub fn is_training_mode() -> bool {
return true; return true;
} }
pub fn get_category(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 { pub fn get_category(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 {
(module_accessor.info >> 28) as u8 as i32 (module_accessor.info >> 28) as u8 as i32
} }
pub fn is_emulator() -> bool { pub fn is_emulator() -> bool {
unsafe { skyline::hooks::getRegionAddress(skyline::hooks::Region::Text) as u64 == 0x8004000 } unsafe { skyline::hooks::getRegionAddress(skyline::hooks::Region::Text) as u64 == 0x8004000 }
} }
pub fn get_module_accessor(fighter_id: FighterId) -> *mut app::BattleObjectModuleAccessor {
pub fn get_module_accessor(fighter_id: FighterId) -> *mut app::BattleObjectModuleAccessor { let entry_id_int = fighter_id as i32;
let entry_id_int = fighter_id as i32; let entry_id = app::FighterEntryID(entry_id_int);
let entry_id = app::FighterEntryID(entry_id_int); unsafe {
unsafe { let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager);
let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager); let fighter_entry =
let fighter_entry = FighterManager::get_fighter_entry(mgr, entry_id) as *mut app::FighterEntry;
FighterManager::get_fighter_entry(mgr, entry_id) as *mut app::FighterEntry; let current_fighter_id = FighterEntry::current_fighter_id(fighter_entry);
let current_fighter_id = FighterEntry::current_fighter_id(fighter_entry); app::sv_battle_object::module_accessor(current_fighter_id as u32)
app::sv_battle_object::module_accessor(current_fighter_id as u32) }
} }
}
pub fn is_fighter(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_fighter(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { get_category(module_accessor) == BATTLE_OBJECT_CATEGORY_FIGHTER
get_category(module_accessor) == BATTLE_OBJECT_CATEGORY_FIGHTER }
}
pub fn is_operation_cpu(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_operation_cpu(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { unsafe {
unsafe { if !is_fighter(module_accessor) {
if !is_fighter(module_accessor) { return false;
return false; }
}
let entry_id_int =
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 {
if entry_id_int == 0 { return false;
return false; }
}
let entry_id = app::FighterEntryID(entry_id_int);
let entry_id = app::FighterEntryID(entry_id_int); let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager);
let mgr = *(FIGHTER_MANAGER_ADDR as *mut *mut app::FighterManager); let fighter_information =
let fighter_information = FighterManager::get_fighter_information(mgr, entry_id) as *mut app::FighterInformation;
FighterManager::get_fighter_information(mgr, entry_id) as *mut app::FighterInformation;
FighterInformation::is_operation_cpu(fighter_information)
FighterInformation::is_operation_cpu(fighter_information) }
} }
}
pub fn is_grounded(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_grounded(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { let situation_kind = unsafe { StatusModule::situation_kind(module_accessor) as i32 };
let situation_kind = unsafe { StatusModule::situation_kind(module_accessor) as i32 };
situation_kind == SITUATION_KIND_GROUND
situation_kind == SITUATION_KIND_GROUND }
}
pub fn is_airborne(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_airborne(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { let situation_kind = unsafe { StatusModule::situation_kind(module_accessor) as i32 };
let situation_kind = unsafe { StatusModule::situation_kind(module_accessor) as i32 };
situation_kind == SITUATION_KIND_AIR
situation_kind == SITUATION_KIND_AIR }
}
pub fn is_idle(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_idle(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { let status_kind = unsafe { StatusModule::status_kind(module_accessor) };
let status_kind = unsafe { StatusModule::status_kind(module_accessor) };
status_kind == FIGHTER_STATUS_KIND_WAIT
status_kind == FIGHTER_STATUS_KIND_WAIT }
}
pub fn is_in_hitstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_in_hitstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { let status_kind = unsafe { StatusModule::status_kind(module_accessor) };
let status_kind = unsafe { StatusModule::status_kind(module_accessor) };
(*FIGHTER_STATUS_KIND_DAMAGE..*FIGHTER_STATUS_KIND_DAMAGE_FALL).contains(&status_kind)
(*FIGHTER_STATUS_KIND_DAMAGE..*FIGHTER_STATUS_KIND_DAMAGE_FALL).contains(&status_kind) }
} pub fn is_in_footstool(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_in_footstool(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { let status_kind = unsafe { StatusModule::status_kind(module_accessor) };
let status_kind = unsafe { StatusModule::status_kind(module_accessor) };
(*FIGHTER_STATUS_KIND_TREAD_DAMAGE..=*FIGHTER_STATUS_KIND_TREAD_FALL).contains(&status_kind)
(*FIGHTER_STATUS_KIND_TREAD_DAMAGE..=*FIGHTER_STATUS_KIND_TREAD_FALL).contains(&status_kind) }
}
pub fn is_shielding(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_shielding(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool { let status_kind = unsafe { StatusModule::status_kind(module_accessor) as i32 };
let status_kind = unsafe { StatusModule::status_kind(module_accessor) as i32 };
(*FIGHTER_STATUS_KIND_GUARD_ON..=*FIGHTER_STATUS_KIND_GUARD_DAMAGE).contains(&status_kind)
(*FIGHTER_STATUS_KIND_GUARD_ON..=*FIGHTER_STATUS_KIND_GUARD_DAMAGE).contains(&status_kind) }
}
pub fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { let status_kind = unsafe { StatusModule::status_kind(module_accessor) };
let status_kind = unsafe { StatusModule::status_kind(module_accessor) }; let prev_status = unsafe { StatusModule::prev_status_kind(module_accessor, 0) };
let prev_status = unsafe { StatusModule::prev_status_kind(module_accessor, 0) };
// If we are taking shield damage or we are droping shield from taking shield damage we are in hitstun
// If we are taking shield damage or we are droping shield from taking shield damage we are in hitstun status_kind == FIGHTER_STATUS_KIND_GUARD_DAMAGE
status_kind == FIGHTER_STATUS_KIND_GUARD_DAMAGE || (prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|| (prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE && status_kind == FIGHTER_STATUS_KIND_GUARD_OFF)
&& status_kind == FIGHTER_STATUS_KIND_GUARD_OFF) }
}
pub unsafe fn is_dead(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
pub unsafe fn is_dead(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { let fighter_kind = app::utility::get_kind(module_accessor);
let fighter_kind = app::utility::get_kind(module_accessor); let fighter_is_ptrainer = [
let fighter_is_ptrainer = [ *FIGHTER_KIND_PZENIGAME,
*FIGHTER_KIND_PZENIGAME, *FIGHTER_KIND_PFUSHIGISOU,
*FIGHTER_KIND_PFUSHIGISOU, *FIGHTER_KIND_PLIZARDON,
*FIGHTER_KIND_PLIZARDON, ]
] .contains(&fighter_kind);
.contains(&fighter_kind); let status_kind = StatusModule::status_kind(module_accessor) as i32;
let status_kind = StatusModule::status_kind(module_accessor) as i32; let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0);
let prev_status_kind = StatusModule::prev_status_kind(module_accessor, 0); // Pokemon trainer enters FIGHTER_STATUS_KIND_WAIT for one frame during their respawn animation
// Pokemon trainer enters FIGHTER_STATUS_KIND_WAIT for one frame during their respawn animation // And the previous status is FIGHTER_STATUS_NONE
// And the previous status is FIGHTER_STATUS_NONE if fighter_is_ptrainer {
if fighter_is_ptrainer { [*FIGHTER_STATUS_KIND_DEAD, *FIGHTER_STATUS_KIND_STANDBY].contains(&status_kind)
[*FIGHTER_STATUS_KIND_DEAD, *FIGHTER_STATUS_KIND_STANDBY].contains(&status_kind) || (status_kind == FIGHTER_STATUS_KIND_WAIT
|| (status_kind == FIGHTER_STATUS_KIND_WAIT && prev_status_kind == FIGHTER_STATUS_KIND_NONE)
&& prev_status_kind == FIGHTER_STATUS_KIND_NONE) } else {
} else { [*FIGHTER_STATUS_KIND_DEAD, *FIGHTER_STATUS_KIND_STANDBY].contains(&status_kind)
[*FIGHTER_STATUS_KIND_DEAD, *FIGHTER_STATUS_KIND_STANDBY].contains(&status_kind) }
} }
}

View file

@ -7,7 +7,9 @@
clippy::borrow_interior_mutable_const, clippy::borrow_interior_mutable_const,
clippy::not_unsafe_ptr_arg_deref, clippy::not_unsafe_ptr_arg_deref,
clippy::missing_safety_doc, clippy::missing_safety_doc,
clippy::wrong_self_convention clippy::wrong_self_convention,
clippy::option_map_unit_fn,
clippy::float_cmp
)] )]
pub mod common; pub mod common;
@ -18,9 +20,9 @@ mod training;
#[cfg(test)] #[cfg(test)]
mod test; mod test;
use crate::common::consts::get_menu_from_url;
use crate::common::*; use crate::common::*;
use crate::events::{Event, EVENT_QUEUE}; use crate::events::{Event, EVENT_QUEUE};
use crate::common::consts::get_menu_from_url;
use skyline::libc::{c_char, mkdir}; use skyline::libc::{c_char, mkdir};
use skyline::nro::{self, NroInfo}; use skyline::nro::{self, NroInfo};
@ -69,8 +71,7 @@ pub fn render_text_to_screen(s: &str) {
pub fn main() { pub fn main() {
macro_rules! log { macro_rules! log {
($($arg:tt)*) => { ($($arg:tt)*) => {
print!("{}", "[Training Modpack] ".green()); print!("{}{}", "[Training Modpack] ".green(), format!($($arg)*));
println!($($arg)*);
}; };
} }
@ -84,7 +85,6 @@ pub fn main() {
training::training_mods(); training::training_mods();
nro::add_hook(nro_main).unwrap(); nro::add_hook(nro_main).unwrap();
unsafe { unsafe {
mkdir(c_str!("sd:/TrainingModpack/"), 777); mkdir(c_str!("sd:/TrainingModpack/"), 777);
} }
@ -141,7 +141,9 @@ pub fn main() {
} }
if is_emulator() { if is_emulator() {
unsafe { MENU.quick_menu = OnOff::On; } unsafe {
MENU.quick_menu = OnOff::On;
}
} }
std::thread::spawn(|| loop { std::thread::spawn(|| loop {
@ -179,34 +181,60 @@ pub fn main() {
let button_presses = &mut common::menu::BUTTON_PRESSES; let button_presses = &mut common::menu::BUTTON_PRESSES;
let mut received_input = true; let mut received_input = true;
loop { loop {
button_presses.a.read_press().then(|| { app.on_a(); received_input = true; }); button_presses.a.read_press().then(|| {
app.on_a();
received_input = true;
});
let b_press = &mut button_presses.b; let b_press = &mut button_presses.b;
let b_prev_press = b_press.prev_frame_is_pressed;
b_press.read_press().then(|| { b_press.read_press().then(|| {
received_input = true; received_input = true;
if !app.outer_list { if !app.outer_list {
app.on_b() app.on_b()
} else { } else if !b_prev_press {
// Leave menu. // Leave menu.
menu::QUICK_MENU_ACTIVE = false; menu::QUICK_MENU_ACTIVE = false;
crate::menu::set_menu_from_url(url.as_str()); crate::menu::set_menu_from_url(url.as_str());
} }
}); });
button_presses.zl.read_press().then(|| { app.on_l(); received_input = true; }); button_presses.zl.read_press().then(|| {
button_presses.zr.read_press().then(|| { app.on_r(); received_input = true; }); app.on_l();
button_presses.left.read_press().then(|| { app.on_left(); received_input = true; }); received_input = true;
button_presses.right.read_press().then(|| { app.on_right(); received_input = true; }); });
button_presses.up.read_press().then(|| { app.on_up(); received_input = true; }); button_presses.zr.read_press().then(|| {
button_presses.down.read_press().then(|| { app.on_down(); received_input = true; }); app.on_r();
received_input = true;
});
button_presses.left.read_press().then(|| {
app.on_left();
received_input = true;
});
button_presses.right.read_press().then(|| {
app.on_right();
received_input = true;
});
button_presses.up.read_press().then(|| {
app.on_up();
received_input = true;
});
button_presses.down.read_press().then(|| {
app.on_down();
received_input = true;
});
std::thread::sleep(std::time::Duration::from_millis(16)); std::thread::sleep(std::time::Duration::from_millis(16));
has_slept_millis += 16; has_slept_millis += 16;
if has_slept_millis < 16 * render_frames { continue; } if has_slept_millis < 16 * render_frames {
continue;
}
has_slept_millis = 16; has_slept_millis = 16;
if !menu::QUICK_MENU_ACTIVE { if !menu::QUICK_MENU_ACTIVE {
set_should_display_text_to_screen(false); set_should_display_text_to_screen(false);
continue; continue;
} }
if !received_input { continue; } if !received_input {
continue;
}
let mut view = String::new(); let mut view = String::new();
let frame_res = terminal let frame_res = terminal
@ -228,9 +256,12 @@ pub fn main() {
Color::Yellow => write!(&mut view, "{}", &cell.symbol.yellow()), Color::Yellow => write!(&mut view, "{}", &cell.symbol.yellow()),
Color::LightYellow => write!(&mut view, "{}", &cell.symbol.bright_yellow()), Color::LightYellow => write!(&mut view, "{}", &cell.symbol.bright_yellow()),
Color::Magenta => write!(&mut view, "{}", &cell.symbol.magenta()), Color::Magenta => write!(&mut view, "{}", &cell.symbol.magenta()),
Color::LightMagenta => write!(&mut view, "{}", &cell.symbol.bright_magenta()), Color::LightMagenta => {
_ => write!(&mut view, "{}", &cell.symbol), write!(&mut view, "{}", &cell.symbol.bright_magenta())
}.unwrap(); }
_ => write!(&mut view, "{}", &cell.symbol),
}
.unwrap();
if i % frame_res.area.width as usize == frame_res.area.width as usize - 1 { if i % frame_res.area.width as usize == frame_res.area.width as usize - 1 {
writeln!(&mut view).unwrap(); writeln!(&mut view).unwrap();
} }

View file

@ -39,7 +39,7 @@ pub unsafe fn is_buffing(module_accessor: &mut app::BattleObjectModuleAccessor)
if is_operation_cpu(module_accessor) { if is_operation_cpu(module_accessor) {
return IS_BUFFING_CPU; return IS_BUFFING_CPU;
} }
return IS_BUFFING_PLAYER; IS_BUFFING_PLAYER
} }
pub unsafe fn set_buff_rem(module_accessor: &mut app::BattleObjectModuleAccessor, new_value: i32) { pub unsafe fn set_buff_rem(module_accessor: &mut app::BattleObjectModuleAccessor, new_value: i32) {
@ -54,7 +54,7 @@ pub unsafe fn get_buff_rem(module_accessor: &mut app::BattleObjectModuleAccessor
if is_operation_cpu(module_accessor) { if is_operation_cpu(module_accessor) {
return BUFF_REMAINING_CPU; return BUFF_REMAINING_CPU;
} }
return BUFF_REMAINING_PLAYER; BUFF_REMAINING_PLAYER
} }
fn get_spell_vec() -> Vec<BuffOption> { fn get_spell_vec() -> Vec<BuffOption> {
@ -68,7 +68,7 @@ fn get_spell_vec() -> Vec<BuffOption> {
spell_buff.push(*buff); spell_buff.push(*buff);
} }
} }
return spell_buff; spell_buff
} }
} }
@ -99,7 +99,7 @@ pub unsafe fn handle_buffs(
return buff_sepiroth(module_accessor, percent); return buff_sepiroth(module_accessor, percent);
} }
return true; true
} }
unsafe fn buff_hero(module_accessor: &mut app::BattleObjectModuleAccessor, status: i32) -> bool { unsafe fn buff_hero(module_accessor: &mut app::BattleObjectModuleAccessor, status: i32) -> bool {
@ -115,7 +115,7 @@ unsafe fn buff_hero(module_accessor: &mut app::BattleObjectModuleAccessor, statu
return true; return true;
} }
buff_hero_single(module_accessor, status, buff_vec); buff_hero_single(module_accessor, status, buff_vec);
return false; false
} }
unsafe fn buff_hero_single( unsafe fn buff_hero_single(
@ -161,11 +161,11 @@ unsafe fn buff_cloud(module_accessor: &mut app::BattleObjectModuleAccessor) -> b
start_buff(module_accessor); start_buff(module_accessor);
handle_add_limit(100.0, module_accessor, 0); handle_add_limit(100.0, module_accessor, 0);
} }
if frame_counter::should_delay(2 as u32, BUFF_DELAY_COUNTER) { if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) {
// Need to wait 2 frames to make sure we stop the limit SFX, since it's a bit delayed // Need to wait 2 frames to make sure we stop the limit SFX, since it's a bit delayed
return false; return false;
} }
return true; true
} }
unsafe fn buff_joker(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { unsafe fn buff_joker(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
@ -176,11 +176,11 @@ unsafe fn buff_joker(module_accessor: &mut app::BattleObjectModuleAccessor) -> b
// Strangely, this doesn't actually matter and works for both fighters // Strangely, this doesn't actually matter and works for both fighters
app::FighterSpecializer_Jack::add_rebel_gauge(module_accessor, entry_id, 120.0); app::FighterSpecializer_Jack::add_rebel_gauge(module_accessor, entry_id, 120.0);
} }
if frame_counter::should_delay(2 as u32, BUFF_DELAY_COUNTER) { if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) {
// Need to wait 2 frames to make sure we stop the voice call, since it's a bit delayed // Need to wait 2 frames to make sure we stop the voice call, since it's a bit delayed
return false; return false;
} }
return true; true
} }
unsafe fn buff_mac(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool { unsafe fn buff_mac(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
@ -192,7 +192,7 @@ unsafe fn buff_mac(module_accessor: &mut app::BattleObjectModuleAccessor) -> boo
// Trying to stop KO Punch from playing seems to make it play multiple times in rapid succession // Trying to stop KO Punch from playing seems to make it play multiple times in rapid succession
// Look at 0x7100c44b60 for the func that handles this // Look at 0x7100c44b60 for the func that handles this
// Need to figure out how to update the KO meter if this is fixed // Need to figure out how to update the KO meter if this is fixed
return true; true
} }
unsafe fn buff_sepiroth( unsafe fn buff_sepiroth(
@ -217,12 +217,12 @@ unsafe fn buff_sepiroth(
// if we're not in wing, add damage // if we're not in wing, add damage
DamageModule::add_damage(module_accessor, 1000.0, 0); DamageModule::add_damage(module_accessor, 1000.0, 0);
} }
return false; false
} }
unsafe fn buff_wiifit(module_accessor: &mut app::BattleObjectModuleAccessor, status: i32) -> bool { unsafe fn buff_wiifit(module_accessor: &mut app::BattleObjectModuleAccessor, status: i32) -> bool {
if is_buffing(module_accessor) { if is_buffing(module_accessor) {
if frame_counter::should_delay(2 as u32, BUFF_DELAY_COUNTER) { if frame_counter::should_delay(2_u32, BUFF_DELAY_COUNTER) {
// Need to wait 2 frames to make sure we stop breathing SFX // Need to wait 2 frames to make sure we stop breathing SFX
return false; return false;
} }
@ -242,5 +242,5 @@ unsafe fn buff_wiifit(module_accessor: &mut app::BattleObjectModuleAccessor, sta
} else { } else {
MotionModule::set_rate(module_accessor, 40.0); MotionModule::set_rate(module_accessor, 40.0);
} }
return false; false
} }

View file

@ -16,4 +16,4 @@ pub fn check_status(
} }
false false
} }

View file

@ -29,10 +29,12 @@ fn is_steve(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
fighter_id == *FIGHTER_KIND_PICKEL fighter_id == *FIGHTER_KIND_PICKEL
} }
pub fn save_steve_state(module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<SteveState> { pub fn save_steve_state(
module_accessor: &mut app::BattleObjectModuleAccessor,
) -> Option<SteveState> {
// Returns None if not Steve, a SteveState if it is // Returns None if not Steve, a SteveState if it is
if !is_steve(module_accessor) { if !is_steve(module_accessor) {
return None; None
} else { } else {
unsafe { unsafe {
Some(save(module_accessor)) // should return the SteveState Some(save(module_accessor)) // should return the SteveState
@ -40,36 +42,69 @@ pub fn save_steve_state(module_accessor: &mut app::BattleObjectModuleAccessor) -
} }
} }
pub fn load_steve_state(module_accessor: &mut app::BattleObjectModuleAccessor, steve_state: SteveState) -> bool { pub fn load_steve_state(
module_accessor: &mut app::BattleObjectModuleAccessor,
steve_state: SteveState,
) -> bool {
// Returns false if not Steve, true if it is and we've set the variables // Returns false if not Steve, true if it is and we've set the variables
if !is_steve(module_accessor) { if !is_steve(module_accessor) {
return false; false
} else { } else {
unsafe { unsafe { load(module_accessor, steve_state) }
load(module_accessor, steve_state) true
}
return true;
} }
} }
unsafe fn save(module_accessor: &mut app::BattleObjectModuleAccessor) -> SteveState { unsafe fn save(module_accessor: &mut app::BattleObjectModuleAccessor) -> SteveState {
let mat_g1 = WorkModule::get_int(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_GRADE_1); let mat_g1 = WorkModule::get_int(
let mat_wood = WorkModule::get_int(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_WOOD); module_accessor,
let mat_stone = WorkModule::get_int(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_STONE); *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_GRADE_1,
let mat_iron = WorkModule::get_int(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_IRON); );
let mat_gold = WorkModule::get_int(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_GOLD); let mat_wood = WorkModule::get_int(
let mat_redstone = WorkModule::get_int(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_RED_STONE); module_accessor,
let mat_diamond = WorkModule::get_int(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_DIAMOND); *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_WOOD,
let extend_buffer_address = WorkModule::get_int64(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_EXTEND_BUFFER); );
let sword_mat = *((extend_buffer_address + (0xC * 0)) as *const char); let mat_stone = WorkModule::get_int(
let sword_durability = *(((extend_buffer_address + ((0xC * 0) + 4))) as *const f32); module_accessor,
let axe_mat = *((extend_buffer_address + (0xC * 1)) as *const char); *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_STONE,
let axe_durability = *(((extend_buffer_address + ((0xC * 1) + 4))) as *const f32); );
let pick_mat = *((extend_buffer_address + (0xC * 2)) as *const char); let mat_iron = WorkModule::get_int(
let pick_durability = *(((extend_buffer_address + ((0xC * 2) + 4))) as *const f32); module_accessor,
let shovel_mat = *((extend_buffer_address + (0xC * 3)) as *const char); *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_IRON,
let shovel_durability = *(((extend_buffer_address + ((0xC * 3) + 4))) as *const f32); );
let mat_gold = WorkModule::get_int(
module_accessor,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_GOLD,
);
let mat_redstone = WorkModule::get_int(
module_accessor,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_RED_STONE,
);
let mat_diamond = WorkModule::get_int(
module_accessor,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_DIAMOND,
);
let extend_buffer_address = WorkModule::get_int64(
module_accessor,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_EXTEND_BUFFER,
);
let mut extend_buffer_offset = 0;
let sword_mat = *((extend_buffer_address + (0xC * extend_buffer_offset)) as *const char);
let sword_durability =
*((extend_buffer_address + ((0xC * extend_buffer_offset) + 4)) as *const f32);
extend_buffer_offset += 1;
let axe_mat = *((extend_buffer_address + (0xC * extend_buffer_offset)) as *const char);
let axe_durability =
*((extend_buffer_address + ((0xC * extend_buffer_offset) + 4)) as *const f32);
extend_buffer_offset += 1;
let pick_mat = *((extend_buffer_address + (0xC * extend_buffer_offset)) as *const char);
let pick_durability =
*((extend_buffer_address + ((0xC * extend_buffer_offset) + 4)) as *const f32);
extend_buffer_offset += 1;
let shovel_mat = *((extend_buffer_address + (0xC * extend_buffer_offset)) as *const char);
let shovel_durability =
*((extend_buffer_address + ((0xC * extend_buffer_offset) + 4)) as *const f32);
SteveState { SteveState {
mat_g1, mat_g1,
mat_wood, mat_wood,
@ -90,35 +125,78 @@ unsafe fn save(module_accessor: &mut app::BattleObjectModuleAccessor) -> SteveSt
} }
unsafe fn load(module_accessor: &mut app::BattleObjectModuleAccessor, steve_state: SteveState) { unsafe fn load(module_accessor: &mut app::BattleObjectModuleAccessor, steve_state: SteveState) {
WorkModule::set_int(module_accessor, steve_state.mat_g1, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_GRADE_1); WorkModule::set_int(
WorkModule::set_int(module_accessor, steve_state.mat_wood, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_WOOD); module_accessor,
WorkModule::set_int(module_accessor, steve_state.mat_stone, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_STONE); steve_state.mat_g1,
WorkModule::set_int(module_accessor, steve_state.mat_iron, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_IRON); *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_GRADE_1,
WorkModule::set_int(module_accessor, steve_state.mat_gold, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_GOLD); );
WorkModule::set_int(module_accessor, steve_state.mat_redstone, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_RED_STONE); WorkModule::set_int(
WorkModule::set_int(module_accessor, steve_state.mat_diamond, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_DIAMOND); module_accessor,
steve_state.mat_wood,
let extend_buffer_address = WorkModule::get_int64(module_accessor, *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_EXTEND_BUFFER); *FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_WOOD,
);
WorkModule::set_int(
module_accessor,
steve_state.mat_stone,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_STONE,
);
WorkModule::set_int(
module_accessor,
steve_state.mat_iron,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_IRON,
);
WorkModule::set_int(
module_accessor,
steve_state.mat_gold,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_GOLD,
);
WorkModule::set_int(
module_accessor,
steve_state.mat_redstone,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_RED_STONE,
);
WorkModule::set_int(
module_accessor,
steve_state.mat_diamond,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_MATERIAL_NUM_DIAMOND,
);
let extend_buffer_address = WorkModule::get_int64(
module_accessor,
*FIGHTER_PICKEL_INSTANCE_WORK_ID_INT_EXTEND_BUFFER,
);
// We have to grab the address every time instead of saving it, because loading // We have to grab the address every time instead of saving it, because loading
// a state from a separate training mode instance would cause a crash // a state from a separate training mode instance would cause a crash
*((extend_buffer_address + (0xC * 0)) as *mut char) = steve_state.sword_mat; let mut extend_buffer_offset = 0;
*((extend_buffer_address + (0xC * 1)) as *mut char) = steve_state.axe_mat; *((extend_buffer_address + (0xC * extend_buffer_offset)) as *mut char) = steve_state.sword_mat;
*((extend_buffer_address + (0xC * 2)) as *mut char) = steve_state.pick_mat; extend_buffer_offset += 1;
*((extend_buffer_address + (0xC * 3)) as *mut char) = steve_state.shovel_mat; *((extend_buffer_address + (0xC * extend_buffer_offset)) as *mut char) = steve_state.axe_mat;
extend_buffer_offset += 1;
*((extend_buffer_address + (0xC * extend_buffer_offset)) as *mut char) = steve_state.pick_mat;
extend_buffer_offset += 1;
*((extend_buffer_address + (0xC * extend_buffer_offset)) as *mut char) = steve_state.shovel_mat;
// Update durability // Update durability
*((extend_buffer_address + (0xC * 0) + 4) as *mut f32) = steve_state.sword_durability; extend_buffer_offset = 0;
*((extend_buffer_address + (0xC * 1) + 4) as *mut f32) = steve_state.axe_durability; *((extend_buffer_address + (0xC * extend_buffer_offset) + 4) as *mut f32) =
*((extend_buffer_address + (0xC * 2) + 4) as *mut f32) = steve_state.pick_durability; steve_state.sword_durability;
*((extend_buffer_address + (0xC * 3) + 4) as *mut f32) = steve_state.shovel_durability; extend_buffer_offset += 1;
*((extend_buffer_address + (0xC * extend_buffer_offset) + 4) as *mut f32) =
steve_state.axe_durability;
extend_buffer_offset += 1;
*((extend_buffer_address + (0xC * extend_buffer_offset) + 4) as *mut f32) =
steve_state.pick_durability;
extend_buffer_offset += 1;
*((extend_buffer_address + (0xC * extend_buffer_offset) + 4) as *mut f32) =
steve_state.shovel_durability;
// Update UI meter at the bottom by subtracting the materials by 0 after setting them // Update UI meter at the bottom by subtracting the materials by 0 after setting them
let mut curr_material = 0; let mut curr_material = 0;
while curr_material < 7 { while curr_material < 7 {
app::FighterSpecializer_Pickel::sub_material_num(module_accessor,curr_material,0); app::FighterSpecializer_Pickel::sub_material_num(module_accessor, curr_material, 0);
curr_material += 1; curr_material += 1;
} }
} }

View file

@ -1,4 +1,4 @@
use smash::app::{self, lua_bind::*, ArticleOperationTarget, FighterUtil, FighterFacial}; use smash::app::{self, lua_bind::*, ArticleOperationTarget, FighterFacial, FighterUtil};
use smash::lib::lua_const::*; use smash::lib::lua_const::*;
use smash::phx::{Hash40, Vector3f}; use smash::phx::{Hash40, Vector3f};
@ -9,7 +9,7 @@ pub struct ChargeState {
pub float_x: Option<f32>, pub float_x: Option<f32>,
pub float_y: Option<f32>, pub float_y: Option<f32>,
pub float_z: Option<f32>, pub float_z: Option<f32>,
pub has_charge: Option<bool> pub has_charge: Option<bool>,
} }
impl ChargeState { impl ChargeState {
@ -42,7 +42,6 @@ impl ChargeState {
self.has_charge = Some(has_charge); self.has_charge = Some(has_charge);
self self
} }
} }
impl Default for ChargeState { impl Default for ChargeState {
@ -53,151 +52,234 @@ impl Default for ChargeState {
float_x: None, float_x: None,
float_y: None, float_y: None,
float_z: None, float_z: None,
has_charge: None has_charge: None,
} }
} }
} }
pub unsafe fn get_charge(module_accessor: &mut app::BattleObjectModuleAccessor, fighter_kind: i32) -> ChargeState { pub unsafe fn get_charge(
module_accessor: &mut app::BattleObjectModuleAccessor,
fighter_kind: i32,
) -> ChargeState {
let charge_state = ChargeState::default(); let charge_state = ChargeState::default();
// Mario FLUDD // Mario FLUDD
if fighter_kind == FIGHTER_KIND_MARIO { if fighter_kind == FIGHTER_KIND_MARIO {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_MARIO_INSTANCE_WORK_ID_INT_SPECIAL_LW_CHARGE); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_MARIO_INSTANCE_WORK_ID_INT_SPECIAL_LW_CHARGE,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Donkey Kong Giant Punch // Donkey Kong Giant Punch
else if fighter_kind == FIGHTER_KIND_DONKEY { else if fighter_kind == FIGHTER_KIND_DONKEY {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_DONKEY_INSTANCE_WORK_ID_INT_SPECIAL_N_COUNT); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_DONKEY_INSTANCE_WORK_ID_INT_SPECIAL_N_COUNT,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Samus/Dark Samus Charge Shot // Samus/Dark Samus Charge Shot
else if fighter_kind == FIGHTER_KIND_SAMUS || fighter_kind == FIGHTER_KIND_SAMUSD { else if fighter_kind == FIGHTER_KIND_SAMUS || fighter_kind == FIGHTER_KIND_SAMUSD {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_SAMUS_INSTANCE_WORK_ID_INT_SPECIAL_N_COUNT); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_SAMUS_INSTANCE_WORK_ID_INT_SPECIAL_N_COUNT,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Sheik Needles // Sheik Needles
else if fighter_kind == FIGHTER_KIND_SHEIK { else if fighter_kind == FIGHTER_KIND_SHEIK {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_SHEIK_INSTANCE_WORK_ID_INT_NEEDLE_COUNT); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_SHEIK_INSTANCE_WORK_ID_INT_NEEDLE_COUNT,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Mewtwo Shadowball // Mewtwo Shadowball
else if fighter_kind == FIGHTER_KIND_MEWTWO { else if fighter_kind == FIGHTER_KIND_MEWTWO {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_SHADOWBALL_CHARGE_FRAME); let my_charge = WorkModule::get_int(
let prev_frame = WorkModule::get_int(module_accessor, *FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_PREV_SHADOWBALL_CHARGE_FRAME); module_accessor,
let ball_had = WorkModule::is_flag(module_accessor, *FIGHTER_MEWTWO_INSTANCE_WORK_ID_FLAG_SHADOWBALL_HAD); *FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_SHADOWBALL_CHARGE_FRAME,
charge_state.int_x(my_charge).int_y(prev_frame).has_charge(ball_had) );
let prev_frame = WorkModule::get_int(
module_accessor,
*FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_PREV_SHADOWBALL_CHARGE_FRAME,
);
let ball_had = WorkModule::is_flag(
module_accessor,
*FIGHTER_MEWTWO_INSTANCE_WORK_ID_FLAG_SHADOWBALL_HAD,
);
charge_state
.int_x(my_charge)
.int_y(prev_frame)
.has_charge(ball_had)
} }
// Game and Watch Bucket // Game and Watch Bucket
else if fighter_kind == FIGHTER_KIND_GAMEWATCH { else if fighter_kind == FIGHTER_KIND_GAMEWATCH {
let my_charge = WorkModule::get_float(module_accessor, *FIGHTER_GAMEWATCH_INSTANCE_WORK_ID_FLOAT_SPECIAL_LW_GAUGE); let my_charge = WorkModule::get_float(
let my_attack = WorkModule::get_float(module_accessor, *FIGHTER_GAMEWATCH_INSTANCE_WORK_ID_FLOAT_SPECIAL_LW_ATTACK); module_accessor,
*FIGHTER_GAMEWATCH_INSTANCE_WORK_ID_FLOAT_SPECIAL_LW_GAUGE,
);
let my_attack = WorkModule::get_float(
module_accessor,
*FIGHTER_GAMEWATCH_INSTANCE_WORK_ID_FLOAT_SPECIAL_LW_ATTACK,
);
charge_state.float_x(my_charge).float_y(my_attack) charge_state.float_x(my_charge).float_y(my_attack)
} }
// Wario Waft // Wario Waft
else if fighter_kind == FIGHTER_KIND_WARIO { else if fighter_kind == FIGHTER_KIND_WARIO {
let my_charge = WorkModule::get_int(module_accessor, 0x100000BF); // FIGHTER_WARIO_INSTANCE_WORK_ID_INT_GASS_COUNT let my_charge = WorkModule::get_int(module_accessor, 0x100000BF); // FIGHTER_WARIO_INSTANCE_WORK_ID_INT_GASS_COUNT
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Squirtle Water Gun // Squirtle Water Gun
else if fighter_kind == FIGHTER_KIND_PZENIGAME { else if fighter_kind == FIGHTER_KIND_PZENIGAME {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_PZENIGAME_INSTANCE_WORK_ID_INT_SPECIAL_N_CHARGE); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_PZENIGAME_INSTANCE_WORK_ID_INT_SPECIAL_N_CHARGE,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Lucario Aura Sphere // Lucario Aura Sphere
else if fighter_kind == FIGHTER_KIND_LUCARIO { else if fighter_kind == FIGHTER_KIND_LUCARIO {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_AURABALL_CHARGE_FRAME); let my_charge = WorkModule::get_int(
let prev_frame = WorkModule::get_int(module_accessor, *FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_PREV_AURABALL_CHARGE_FRAME); module_accessor,
let ball_had = WorkModule::is_flag(module_accessor, *FIGHTER_LUCARIO_INSTANCE_WORK_ID_FLAG_AURABALL_HAD); *FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_AURABALL_CHARGE_FRAME,
charge_state.int_x(my_charge).int_y(prev_frame).has_charge(ball_had) );
let prev_frame = WorkModule::get_int(
module_accessor,
*FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_PREV_AURABALL_CHARGE_FRAME,
);
let ball_had = WorkModule::is_flag(
module_accessor,
*FIGHTER_LUCARIO_INSTANCE_WORK_ID_FLAG_AURABALL_HAD,
);
charge_state
.int_x(my_charge)
.int_y(prev_frame)
.has_charge(ball_had)
} }
// ROB Gyro/Laser/Fuel // ROB Gyro/Laser/Fuel
else if fighter_kind == FIGHTER_KIND_ROBOT { else if fighter_kind == FIGHTER_KIND_ROBOT {
let laser_charge = WorkModule::get_float(module_accessor, *FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_BEAM_ENERGY_VALUE); let laser_charge = WorkModule::get_float(
let gyro_charge = WorkModule::get_float(module_accessor, *FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_GYRO_CHARGE_VALUE); module_accessor,
let fuel_charge = WorkModule::get_float(module_accessor, *FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_BURNER_ENERGY_VALUE); *FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_BEAM_ENERGY_VALUE,
charge_state.float_x(laser_charge).float_y(gyro_charge).float_z(fuel_charge) );
let gyro_charge = WorkModule::get_float(
module_accessor,
*FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_GYRO_CHARGE_VALUE,
);
let fuel_charge = WorkModule::get_float(
module_accessor,
*FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_BURNER_ENERGY_VALUE,
);
charge_state
.float_x(laser_charge)
.float_y(gyro_charge)
.float_z(fuel_charge)
} }
// Wii Fit Sun Salutation // Wii Fit Sun Salutation
else if fighter_kind == FIGHTER_KIND_WIIFIT { else if fighter_kind == FIGHTER_KIND_WIIFIT {
let my_charge = WorkModule::get_float(module_accessor, *FIGHTER_WIIFIT_INSTANCE_WORK_ID_FLOAT_SPECIAL_N_CHARGE_LEVEL_RATIO); let my_charge = WorkModule::get_float(
module_accessor,
*FIGHTER_WIIFIT_INSTANCE_WORK_ID_FLOAT_SPECIAL_N_CHARGE_LEVEL_RATIO,
);
charge_state.float_x(my_charge) charge_state.float_x(my_charge)
} }
// Pac-Man Bonus Fruit // Pac-Man Bonus Fruit
else if fighter_kind == FIGHTER_KIND_PACMAN { else if fighter_kind == FIGHTER_KIND_PACMAN {
let my_charge = WorkModule::get_int(module_accessor, 0x100000C1); // FIGHTER_PACMAN_INSTANCE_WORK_ID_INT_SPECIAL_N_CHARGE_RANK let my_charge = WorkModule::get_int(module_accessor, 0x100000C1); // FIGHTER_PACMAN_INSTANCE_WORK_ID_INT_SPECIAL_N_CHARGE_RANK
let max_have = WorkModule::is_flag(module_accessor, *FIGHTER_PACMAN_INSTANCE_WORK_ID_FLAG_SPECIAL_N_MAX_HAVE_ITEM); let max_have = WorkModule::is_flag(
module_accessor,
*FIGHTER_PACMAN_INSTANCE_WORK_ID_FLAG_SPECIAL_N_MAX_HAVE_ITEM,
);
charge_state.int_x(my_charge).has_charge(max_have) charge_state.int_x(my_charge).has_charge(max_have)
} }
// Robin Thunder Tome Spells // Robin Thunder Tome Spells
else if fighter_kind == FIGHTER_KIND_REFLET { else if fighter_kind == FIGHTER_KIND_REFLET {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_REFLET_INSTANCE_WORK_ID_INT_SPECIAL_N_THUNDER_KIND); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_REFLET_INSTANCE_WORK_ID_INT_SPECIAL_N_THUNDER_KIND,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Plant Poison Breath // Plant Poison Breath
else if fighter_kind == FIGHTER_KIND_PACKUN { else if fighter_kind == FIGHTER_KIND_PACKUN {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_PACKUN_INSTANCE_WORK_ID_INT_SPECIAL_S_COUNT); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_PACKUN_INSTANCE_WORK_ID_INT_SPECIAL_S_COUNT,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Hero (Ka)frizz(le) // Hero (Ka)frizz(le)
else if fighter_kind == FIGHTER_KIND_BRAVE { else if fighter_kind == FIGHTER_KIND_BRAVE {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_BRAVE_INSTANCE_WORK_ID_INT_SPECIAL_N_HOLD_FRAME); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_BRAVE_INSTANCE_WORK_ID_INT_SPECIAL_N_HOLD_FRAME,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Banjo Wonderwing // Banjo Wonderwing
else if fighter_kind == FIGHTER_KIND_BUDDY { else if fighter_kind == FIGHTER_KIND_BUDDY {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_BUDDY_INSTANCE_WORK_ID_INT_SPECIAL_S_REMAIN); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_BUDDY_INSTANCE_WORK_ID_INT_SPECIAL_S_REMAIN,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} }
// Mii Gunner Charge Blast // Mii Gunner Charge Blast
else if fighter_kind == FIGHTER_KIND_MIIGUNNER { else if fighter_kind == FIGHTER_KIND_MIIGUNNER {
let my_charge = WorkModule::get_int(module_accessor, *FIGHTER_MIIGUNNER_INSTANCE_WORK_ID_INT_GUNNER_CHARGE_COUNT); let my_charge = WorkModule::get_int(
module_accessor,
*FIGHTER_MIIGUNNER_INSTANCE_WORK_ID_INT_GUNNER_CHARGE_COUNT,
);
charge_state.int_x(my_charge) charge_state.int_x(my_charge)
} else { } else {
charge_state charge_state
} }
} }
pub unsafe fn handle_charge(module_accessor: &mut app::BattleObjectModuleAccessor, fighter_kind: i32, charge: ChargeState) { pub unsafe fn handle_charge(
module_accessor: &mut app::BattleObjectModuleAccessor,
fighter_kind: i32,
charge: ChargeState,
) {
// Mario Fludd - 0 to 80 // Mario Fludd - 0 to 80
if fighter_kind == FIGHTER_KIND_MARIO { if fighter_kind == FIGHTER_KIND_MARIO {
charge.int_x.map(|fludd_charge| { charge.int_x.map(|fludd_charge| {
WorkModule::set_int(module_accessor, fludd_charge, *FIGHTER_MARIO_INSTANCE_WORK_ID_INT_SPECIAL_LW_CHARGE); WorkModule::set_int(
module_accessor,
fludd_charge,
*FIGHTER_MARIO_INSTANCE_WORK_ID_INT_SPECIAL_LW_CHARGE,
);
if fludd_charge == 80 { if fludd_charge == 80 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
} }
}); });
} }
// DK Punch - 0 to 110 // DK Punch - 0 to 110
else if fighter_kind == FIGHTER_KIND_DONKEY { else if fighter_kind == FIGHTER_KIND_DONKEY {
charge.int_x.map(|punch_charge| { charge.int_x.map(|punch_charge| {
WorkModule::set_int(module_accessor, punch_charge, *FIGHTER_DONKEY_INSTANCE_WORK_ID_INT_SPECIAL_N_COUNT); WorkModule::set_int(
module_accessor,
punch_charge,
*FIGHTER_DONKEY_INSTANCE_WORK_ID_INT_SPECIAL_N_COUNT,
);
if punch_charge == 110 { if punch_charge == 110 {
FighterUtil::set_face_motion_by_priority(module_accessor,FighterFacial(*FIGHTER_FACIAL_SPECIAL), Hash40::new("special_n_max_face")); FighterUtil::set_face_motion_by_priority(
module_accessor,
FighterFacial(*FIGHTER_FACIAL_SPECIAL),
Hash40::new("special_n_max_face"),
);
} }
}); });
} }
// Samus/Dark Samus Charge Shot - 0 to 112 // Samus/Dark Samus Charge Shot - 0 to 112
else if fighter_kind == FIGHTER_KIND_SAMUS || fighter_kind == FIGHTER_KIND_SAMUSD { else if fighter_kind == FIGHTER_KIND_SAMUS || fighter_kind == FIGHTER_KIND_SAMUSD {
charge.int_x.map(|shot_charge| { charge.int_x.map(|shot_charge| {
WorkModule::set_int(module_accessor, shot_charge, *FIGHTER_SAMUS_INSTANCE_WORK_ID_INT_SPECIAL_N_COUNT); WorkModule::set_int(
module_accessor,
shot_charge,
*FIGHTER_SAMUS_INSTANCE_WORK_ID_INT_SPECIAL_N_COUNT,
);
if shot_charge == 112 { if shot_charge == 112 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
let samus_cshot_hash; let samus_cshot_hash;
@ -218,65 +300,127 @@ pub unsafe fn handle_charge(module_accessor: &mut app::BattleObjectModuleAccesso
z: 176.373, z: 176.373,
}; };
let efh = EffectModule::req_follow( let efh = EffectModule::req_follow(
module_accessor, samus_cshot_hash, module_accessor,
joint_hash, &pos, &rot, 1.0, false, samus_cshot_hash,
0, 0, 0, 0, 0, joint_hash,
false, false &pos,
&rot,
1.0,
false,
0,
0,
0,
0,
0,
false,
false,
);
WorkModule::set_int(
module_accessor,
efh as i32,
*FIGHTER_SAMUS_INSTANCE_WORK_ID_INT_EFH_CHARGE_MAX,
); );
WorkModule::set_int(module_accessor, efh as i32, *FIGHTER_SAMUS_INSTANCE_WORK_ID_INT_EFH_CHARGE_MAX);
} }
}); });
} }
// Sheik Needles - 0 to 6 // Sheik Needles - 0 to 6
else if fighter_kind == FIGHTER_KIND_SHEIK { else if fighter_kind == FIGHTER_KIND_SHEIK {
charge.int_x.map(|needle_charge| { charge.int_x.map(|needle_charge| {
WorkModule::set_int(module_accessor, needle_charge, *FIGHTER_SHEIK_INSTANCE_WORK_ID_INT_NEEDLE_COUNT); WorkModule::set_int(
ArticleModule::generate_article_enable(module_accessor,*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE, false, -1); module_accessor,
needle_charge,
*FIGHTER_SHEIK_INSTANCE_WORK_ID_INT_NEEDLE_COUNT,
);
ArticleModule::generate_article_enable(
module_accessor,
*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE,
false,
-1,
);
let hash_main = Hash40::new("set_main"); let hash_main = Hash40::new("set_main");
match needle_charge { match needle_charge {
6 => { 6 => {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
ArticleModule::set_visibility(module_accessor,*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE, ArticleModule::set_visibility(
hash_main, Hash40::new("group_main_default"),ArticleOperationTarget(0)); module_accessor,
*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE,
hash_main,
Hash40::new("group_main_default"),
ArticleOperationTarget(0),
);
} }
5 => { 5 => {
ArticleModule::set_visibility(module_accessor,*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE, ArticleModule::set_visibility(
hash_main, Hash40::new("group_main_5"),ArticleOperationTarget(0)); module_accessor,
*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE,
hash_main,
Hash40::new("group_main_5"),
ArticleOperationTarget(0),
);
} }
4 => { 4 => {
ArticleModule::set_visibility(module_accessor,*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE, ArticleModule::set_visibility(
hash_main, Hash40::new("group_main_4"),ArticleOperationTarget(0)); module_accessor,
*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE,
hash_main,
Hash40::new("group_main_4"),
ArticleOperationTarget(0),
);
} }
3 => { 3 => {
ArticleModule::set_visibility(module_accessor,*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE, ArticleModule::set_visibility(
hash_main, Hash40::new("group_main_3"),ArticleOperationTarget(0)); module_accessor,
*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE,
hash_main,
Hash40::new("group_main_3"),
ArticleOperationTarget(0),
);
} }
2 => { 2 => {
ArticleModule::set_visibility(module_accessor,*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE, ArticleModule::set_visibility(
hash_main, Hash40::new("group_main_2"),ArticleOperationTarget(0)); module_accessor,
*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE,
hash_main,
Hash40::new("group_main_2"),
ArticleOperationTarget(0),
);
} }
1 => { 1 => {
ArticleModule::set_visibility(module_accessor,*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE, ArticleModule::set_visibility(
hash_main, Hash40::new("group_main_1"),ArticleOperationTarget(0)); module_accessor,
*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE,
hash_main,
Hash40::new("group_main_1"),
ArticleOperationTarget(0),
);
} }
_ => { _ => {
ArticleModule::set_visibility(module_accessor,*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE, ArticleModule::set_visibility(
hash_main, Hash40::new("group_main_0"),ArticleOperationTarget(0)); module_accessor,
*FIGHTER_SHEIK_GENERATE_ARTICLE_NEEDLEHAVE,
hash_main,
Hash40::new("group_main_0"),
ArticleOperationTarget(0),
);
} }
} }
}); });
} }
// Mewtwo Shadowball - 0 to 120, Boolean // Mewtwo Shadowball - 0 to 120, Boolean
else if fighter_kind == FIGHTER_KIND_MEWTWO { else if fighter_kind == FIGHTER_KIND_MEWTWO {
charge.int_x.map(|charge_frame| { charge.int_x.map(|charge_frame| {
WorkModule::set_int(module_accessor, charge_frame, *FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_SHADOWBALL_CHARGE_FRAME); WorkModule::set_int(
module_accessor,
charge_frame,
*FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_SHADOWBALL_CHARGE_FRAME,
);
}); });
charge.int_y.map(|prev_frame| { charge.int_y.map(|prev_frame| {
WorkModule::set_int(module_accessor, prev_frame, *FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_PREV_SHADOWBALL_CHARGE_FRAME); WorkModule::set_int(
module_accessor,
prev_frame,
*FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_PREV_SHADOWBALL_CHARGE_FRAME,
);
if prev_frame == 120 { if prev_frame == 120 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
let effect_hash = Hash40::new("mewtwo_shadowball_max_hand"); let effect_hash = Hash40::new("mewtwo_shadowball_max_hand");
@ -293,30 +437,65 @@ pub unsafe fn handle_charge(module_accessor: &mut app::BattleObjectModuleAccesso
z: 0.0, z: 0.0,
}; };
let efh_1 = EffectModule::req_follow( let efh_1 = EffectModule::req_follow(
module_accessor, effect_hash, module_accessor,
joint_hash_1, &pos, &rot, 1.0, false, effect_hash,
0, 0, -1, 0, 0, joint_hash_1,
false, false &pos,
&rot,
1.0,
false,
0,
0,
-1,
0,
0,
false,
false,
); );
let efh_2 = EffectModule::req_follow( let efh_2 = EffectModule::req_follow(
module_accessor, effect_hash, module_accessor,
joint_hash_2, &pos, &rot, 1.0, false, effect_hash,
0, 0, -1, 0, 0, joint_hash_2,
false, false &pos,
&rot,
1.0,
false,
0,
0,
-1,
0,
0,
false,
false,
);
WorkModule::set_int(
module_accessor,
efh_1 as i32,
*FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_EF_ID_SHADOWBALL_MAX_L,
);
WorkModule::set_int(
module_accessor,
efh_2 as i32,
*FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_EF_ID_SHADOWBALL_MAX_R,
); );
WorkModule::set_int(module_accessor, efh_1 as i32, *FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_EF_ID_SHADOWBALL_MAX_L);
WorkModule::set_int(module_accessor, efh_2 as i32, *FIGHTER_MEWTWO_INSTANCE_WORK_ID_INT_EF_ID_SHADOWBALL_MAX_R);
} }
}); });
charge.has_charge.map(|has_shadowball| { charge.has_charge.map(|has_shadowball| {
WorkModule::set_flag(module_accessor, has_shadowball, *FIGHTER_MEWTWO_INSTANCE_WORK_ID_FLAG_SHADOWBALL_HAD); WorkModule::set_flag(
module_accessor,
has_shadowball,
*FIGHTER_MEWTWO_INSTANCE_WORK_ID_FLAG_SHADOWBALL_HAD,
);
}); });
} }
// GnW Bucket - 0 to 3, Attack not tested // GnW Bucket - 0 to 3, Attack not tested
else if fighter_kind == FIGHTER_KIND_GAMEWATCH { else if fighter_kind == FIGHTER_KIND_GAMEWATCH {
charge.float_x.map(|bucket_level| { charge.float_x.map(|bucket_level| {
WorkModule::set_float(module_accessor, bucket_level, *FIGHTER_GAMEWATCH_INSTANCE_WORK_ID_FLOAT_SPECIAL_LW_GAUGE); WorkModule::set_float(
module_accessor,
bucket_level,
*FIGHTER_GAMEWATCH_INSTANCE_WORK_ID_FLOAT_SPECIAL_LW_GAUGE,
);
if bucket_level == 3.0 { if bucket_level == 3.0 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
} else { } else {
@ -325,34 +504,47 @@ pub unsafe fn handle_charge(module_accessor: &mut app::BattleObjectModuleAccesso
} }
}); });
charge.float_y.map(|bucket_attack| { charge.float_y.map(|bucket_attack| {
WorkModule::set_float(module_accessor, bucket_attack, *FIGHTER_GAMEWATCH_INSTANCE_WORK_ID_FLOAT_SPECIAL_LW_ATTACK); WorkModule::set_float(
module_accessor,
bucket_attack,
*FIGHTER_GAMEWATCH_INSTANCE_WORK_ID_FLOAT_SPECIAL_LW_ATTACK,
);
}); });
} }
// Wario Waft - 0 to 6000 // Wario Waft - 0 to 6000
else if fighter_kind == FIGHTER_KIND_WARIO { else if fighter_kind == FIGHTER_KIND_WARIO {
charge.int_x.map(|waft_count| { charge.int_x.map(|waft_count| {
WorkModule::set_int(module_accessor, waft_count, 0x100000BF); // FIGHTER_WARIO_INSTANCE_WORK_ID_INT_GASS_COUNT WorkModule::set_int(module_accessor, waft_count, 0x100000BF); // FIGHTER_WARIO_INSTANCE_WORK_ID_INT_GASS_COUNT
}); });
} }
// Squirtle Water Gun - 0 to 45 // Squirtle Water Gun - 0 to 45
else if fighter_kind == FIGHTER_KIND_PZENIGAME { else if fighter_kind == FIGHTER_KIND_PZENIGAME {
charge.int_x.map(|water_charge| { charge.int_x.map(|water_charge| {
WorkModule::set_int(module_accessor, water_charge, *FIGHTER_PZENIGAME_INSTANCE_WORK_ID_INT_SPECIAL_N_CHARGE); WorkModule::set_int(
module_accessor,
water_charge,
*FIGHTER_PZENIGAME_INSTANCE_WORK_ID_INT_SPECIAL_N_CHARGE,
);
if water_charge == 45 { if water_charge == 45 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
} }
}); });
} }
// Lucario Aura Sphere - 0 to 90, Boolean // Lucario Aura Sphere - 0 to 90, Boolean
else if fighter_kind == FIGHTER_KIND_LUCARIO { else if fighter_kind == FIGHTER_KIND_LUCARIO {
charge.int_x.map(|charge_frame| { charge.int_x.map(|charge_frame| {
WorkModule::set_int(module_accessor, charge_frame, *FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_AURABALL_CHARGE_FRAME); WorkModule::set_int(
module_accessor,
charge_frame,
*FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_AURABALL_CHARGE_FRAME,
);
}); });
charge.int_y.map(|prev_frame| { charge.int_y.map(|prev_frame| {
WorkModule::set_int(module_accessor, prev_frame, *FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_PREV_AURABALL_CHARGE_FRAME); WorkModule::set_int(
module_accessor,
prev_frame,
*FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_PREV_AURABALL_CHARGE_FRAME,
);
if prev_frame == 90 { if prev_frame == 90 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
let effect_hash_1 = Hash40::new("lucario_hadoudan_max_l"); let effect_hash_1 = Hash40::new("lucario_hadoudan_max_l");
@ -370,70 +562,122 @@ pub unsafe fn handle_charge(module_accessor: &mut app::BattleObjectModuleAccesso
z: 0.0, z: 0.0,
}; };
let efh_1 = EffectModule::req_follow( let efh_1 = EffectModule::req_follow(
module_accessor, effect_hash_1, module_accessor,
joint_hash_1, &pos, &rot, 1.0, false, effect_hash_1,
0, 0, -1, 0, 0, joint_hash_1,
false, false &pos,
&rot,
1.0,
false,
0,
0,
-1,
0,
0,
false,
false,
); );
let efh_2 = EffectModule::req_follow( let efh_2 = EffectModule::req_follow(
module_accessor, effect_hash_2, module_accessor,
joint_hash_2, &pos, &rot, 1.0, false, effect_hash_2,
0, 0, -1, 0, 0, joint_hash_2,
false, false &pos,
&rot,
1.0,
false,
0,
0,
-1,
0,
0,
false,
false,
);
WorkModule::set_int(
module_accessor,
efh_1 as i32,
*FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_EF_ID_AURABALL_MAX_L,
);
WorkModule::set_int(
module_accessor,
efh_2 as i32,
*FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_EF_ID_AURABALL_MAX_R,
); );
WorkModule::set_int(module_accessor, efh_1 as i32, *FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_EF_ID_AURABALL_MAX_L);
WorkModule::set_int(module_accessor, efh_2 as i32, *FIGHTER_LUCARIO_INSTANCE_WORK_ID_INT_EF_ID_AURABALL_MAX_R);
} }
}); });
charge.has_charge.map(|has_aurasphere| { charge.has_charge.map(|has_aurasphere| {
WorkModule::set_flag(module_accessor, has_aurasphere, *FIGHTER_LUCARIO_INSTANCE_WORK_ID_FLAG_AURABALL_HAD); WorkModule::set_flag(
module_accessor,
has_aurasphere,
*FIGHTER_LUCARIO_INSTANCE_WORK_ID_FLAG_AURABALL_HAD,
);
}); });
} }
// ROB Gyro/Laser/Fuel - Gyro from 0 to 90, rest unchecked // ROB Gyro/Laser/Fuel - Gyro from 0 to 90, rest unchecked
else if fighter_kind == FIGHTER_KIND_ROBOT { else if fighter_kind == FIGHTER_KIND_ROBOT {
charge.float_x.map(|beam_energy| { charge.float_x.map(|beam_energy| {
WorkModule::set_float(module_accessor, beam_energy, *FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_BEAM_ENERGY_VALUE); WorkModule::set_float(
module_accessor,
beam_energy,
*FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_BEAM_ENERGY_VALUE,
);
}); });
charge.float_y.map(|gyro_charge| { charge.float_y.map(|gyro_charge| {
WorkModule::set_float(module_accessor, gyro_charge, *FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_GYRO_CHARGE_VALUE); WorkModule::set_float(
module_accessor,
gyro_charge,
*FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_GYRO_CHARGE_VALUE,
);
if gyro_charge == 90.0 { if gyro_charge == 90.0 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
} }
}); });
charge.float_z.map(|burner_energy| { charge.float_z.map(|burner_energy| {
WorkModule::set_float(module_accessor, burner_energy, *FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_BURNER_ENERGY_VALUE); WorkModule::set_float(
module_accessor,
burner_energy,
*FIGHTER_ROBOT_INSTANCE_WORK_ID_FLOAT_BURNER_ENERGY_VALUE,
);
}); });
} }
// Wii Fit Sun Salutation - 0 to 1 // Wii Fit Sun Salutation - 0 to 1
else if fighter_kind == FIGHTER_KIND_WIIFIT { else if fighter_kind == FIGHTER_KIND_WIIFIT {
charge.float_x.map(|sun_ratio| { charge.float_x.map(|sun_ratio| {
WorkModule::set_float(module_accessor, sun_ratio, *FIGHTER_WIIFIT_INSTANCE_WORK_ID_FLOAT_SPECIAL_N_CHARGE_LEVEL_RATIO) WorkModule::set_float(
module_accessor,
sun_ratio,
*FIGHTER_WIIFIT_INSTANCE_WORK_ID_FLOAT_SPECIAL_N_CHARGE_LEVEL_RATIO,
)
}); });
} }
// Pac-Man Bonus Fruit - 0 to 12 // Pac-Man Bonus Fruit - 0 to 12
else if fighter_kind == FIGHTER_KIND_PACMAN { else if fighter_kind == FIGHTER_KIND_PACMAN {
charge.int_x.map(|charge_rank| { charge.int_x.map(|charge_rank| {
WorkModule::set_int(module_accessor, charge_rank, 0x100000C1); // FIGHTER_PACMAN_INSTANCE_WORK_ID_INT_SPECIAL_N_CHARGE_RANK WorkModule::set_int(module_accessor, charge_rank, 0x100000C1); // FIGHTER_PACMAN_INSTANCE_WORK_ID_INT_SPECIAL_N_CHARGE_RANK
if charge_rank == 12 { if charge_rank == 12 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
} }
}); });
charge.has_charge.map(|has_fruit| { charge.has_charge.map(|has_fruit| {
WorkModule::set_flag(module_accessor, has_fruit, *FIGHTER_PACMAN_INSTANCE_WORK_ID_FLAG_SPECIAL_N_MAX_HAVE_ITEM); WorkModule::set_flag(
module_accessor,
has_fruit,
*FIGHTER_PACMAN_INSTANCE_WORK_ID_FLAG_SPECIAL_N_MAX_HAVE_ITEM,
);
}); });
} }
// Robin Thunder Tome Spells - 0 to 3 // Robin Thunder Tome Spells - 0 to 3
else if fighter_kind == FIGHTER_KIND_REFLET { else if fighter_kind == FIGHTER_KIND_REFLET {
charge.int_x.map(|thunder_kind| { charge.int_x.map(|thunder_kind| {
WorkModule::set_int(module_accessor, thunder_kind, *FIGHTER_REFLET_INSTANCE_WORK_ID_INT_SPECIAL_N_THUNDER_KIND); WorkModule::set_int(
if thunder_kind == 3 { module_accessor,
thunder_kind,
*FIGHTER_REFLET_INSTANCE_WORK_ID_INT_SPECIAL_N_THUNDER_KIND,
);
if thunder_kind == 3 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
let reflet_hash = Hash40::new("reflet_thunder_max"); let reflet_hash = Hash40::new("reflet_thunder_max");
let joint_hash = Hash40::new("handl"); let joint_hash = Hash40::new("handl");
let pos = Vector3f { let pos = Vector3f {
x: 1.0, x: 1.0,
@ -446,19 +690,32 @@ pub unsafe fn handle_charge(module_accessor: &mut app::BattleObjectModuleAccesso
z: 0.0, z: 0.0,
}; };
EffectModule::req_follow( EffectModule::req_follow(
module_accessor, reflet_hash, module_accessor,
joint_hash, &pos, &rot, 1.0, false, reflet_hash,
0, 0, -1, 0, 0, joint_hash,
false, false &pos,
&rot,
1.0,
false,
0,
0,
-1,
0,
0,
false,
false,
); );
} }
}); });
} }
// Mii Gunner Charge Blast - 0 to 120 // Mii Gunner Charge Blast - 0 to 120
else if fighter_kind == FIGHTER_KIND_MIIGUNNER { else if fighter_kind == FIGHTER_KIND_MIIGUNNER {
charge.int_x.map(|blast_charge| { charge.int_x.map(|blast_charge| {
WorkModule::set_int(module_accessor, blast_charge, *FIGHTER_MIIGUNNER_INSTANCE_WORK_ID_INT_GUNNER_CHARGE_COUNT); WorkModule::set_int(
module_accessor,
blast_charge,
*FIGHTER_MIIGUNNER_INSTANCE_WORK_ID_INT_GUNNER_CHARGE_COUNT,
);
if blast_charge == 120 { if blast_charge == 120 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
let gunner_hash = Hash40::new("miigunner_cshot_max"); let gunner_hash = Hash40::new("miigunner_cshot_max");
@ -474,23 +731,40 @@ pub unsafe fn handle_charge(module_accessor: &mut app::BattleObjectModuleAccesso
z: 0.0, z: 0.0,
}; };
let efh = EffectModule::req_follow( let efh = EffectModule::req_follow(
module_accessor, gunner_hash, module_accessor,
joint_hash, &pos, &rot, 1.0, false, gunner_hash,
0, 0, 0, 0, 0, joint_hash,
false, false &pos,
&rot,
1.0,
false,
0,
0,
0,
0,
0,
false,
false,
);
WorkModule::set_int(
module_accessor,
efh as i32,
*FIGHTER_MIIGUNNER_INSTANCE_WORK_ID_INT_EFH_CHARGE_MAX,
); );
WorkModule::set_int(module_accessor, efh as i32, *FIGHTER_MIIGUNNER_INSTANCE_WORK_ID_INT_EFH_CHARGE_MAX);
} }
}); });
} }
// Plant Poison - 0 to 75 // Plant Poison - 0 to 75
else if fighter_kind == FIGHTER_KIND_PACKUN { else if fighter_kind == FIGHTER_KIND_PACKUN {
charge.int_x.map(|poison_count| { charge.int_x.map(|poison_count| {
WorkModule::set_int(module_accessor, poison_count, *FIGHTER_PACKUN_INSTANCE_WORK_ID_INT_SPECIAL_S_COUNT); WorkModule::set_int(
if poison_count == 75 { module_accessor,
poison_count,
*FIGHTER_PACKUN_INSTANCE_WORK_ID_INT_SPECIAL_S_COUNT,
);
if poison_count == 75 {
EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0); EffectModule::req_common(module_accessor, Hash40::new("charge_max"), 0.0);
let plant_hash = Hash40::new("packun_poison_max_smoke"); let plant_hash = Hash40::new("packun_poison_max_smoke");
let joint_hash = Hash40::new("hip"); let joint_hash = Hash40::new("hip");
let pos = Vector3f { let pos = Vector3f {
x: 0.0, x: 0.0,
@ -503,31 +777,49 @@ pub unsafe fn handle_charge(module_accessor: &mut app::BattleObjectModuleAccesso
z: 0.0, z: 0.0,
}; };
let efh = EffectModule::req_follow( let efh = EffectModule::req_follow(
module_accessor, plant_hash, module_accessor,
joint_hash, &pos, &rot, 1.0, false, plant_hash,
32768, 0, -1, 0, 0, joint_hash,
false, false &pos,
&rot,
1.0,
false,
32768,
0,
-1,
0,
0,
false,
false,
);
WorkModule::set_int(
module_accessor,
efh as i32,
*FIGHTER_PACKUN_INSTANCE_WORK_ID_INT_SPECIAL_S_CHARGE_MAX_EFFECT_HANDLE,
); );
WorkModule::set_int(module_accessor, efh as i32, *FIGHTER_PACKUN_INSTANCE_WORK_ID_INT_SPECIAL_S_CHARGE_MAX_EFFECT_HANDLE);
} }
}); });
} }
// Hero (Ka)frizz(le) - 0 to 81 // Hero (Ka)frizz(le) - 0 to 81
else if fighter_kind == FIGHTER_KIND_BRAVE { else if fighter_kind == FIGHTER_KIND_BRAVE {
EffectModule::remove_common(module_accessor, Hash40::new("charge_max")); EffectModule::remove_common(module_accessor, Hash40::new("charge_max"));
WorkModule::off_flag(module_accessor, 0x200000E8); // FIGHTER_BRAVE_INSTANCE_WORK_ID_FLAG_SPECIAL_N_MAX_EFFECT WorkModule::off_flag(module_accessor, 0x200000E8); // FIGHTER_BRAVE_INSTANCE_WORK_ID_FLAG_SPECIAL_N_MAX_EFFECT
charge.int_x.map(|frizz_charge| { charge.int_x.map(|frizz_charge| {
WorkModule::set_int(module_accessor, frizz_charge, *FIGHTER_BRAVE_INSTANCE_WORK_ID_INT_SPECIAL_N_HOLD_FRAME); WorkModule::set_int(
module_accessor,
frizz_charge,
*FIGHTER_BRAVE_INSTANCE_WORK_ID_INT_SPECIAL_N_HOLD_FRAME,
);
}); });
} }
// Banjo Wonderwing - 0 to 5 // Banjo Wonderwing - 0 to 5
else if fighter_kind == FIGHTER_KIND_BUDDY { else if fighter_kind == FIGHTER_KIND_BUDDY {
charge.int_x.map(|wing_remain| { charge.int_x.map(|wing_remain| {
WorkModule::set_int(module_accessor, wing_remain, *FIGHTER_BUDDY_INSTANCE_WORK_ID_INT_SPECIAL_S_REMAIN); WorkModule::set_int(
module_accessor,
wing_remain,
*FIGHTER_BUDDY_INSTANCE_WORK_ID_INT_SPECIAL_S_REMAIN,
);
}); });
} }
return;
} }

View file

@ -64,13 +64,14 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor
reset_ledge_delay(); reset_ledge_delay();
return; return;
} }
// Need to roll ledge delay so we know if getup needs to be buffered // Need to roll ledge delay so we know if getup needs to be buffered
roll_ledge_delay(); roll_ledge_delay();
roll_ledge_case(); roll_ledge_case();
// This flag is false when needing to buffer, and true when getting up // This flag is false when needing to buffer, and true when getting up
let flag_cliff = WorkModule::is_flag(module_accessor,*FIGHTER_INSTANCE_WORK_ID_FLAG_CATCH_CLIFF); let flag_cliff =
WorkModule::is_flag(module_accessor, *FIGHTER_INSTANCE_WORK_ID_FLAG_CATCH_CLIFF);
let current_frame = MotionModule::frame(module_accessor) as i32; let current_frame = MotionModule::frame(module_accessor) as i32;
let should_buffer = (LEDGE_DELAY == 0) && (current_frame == 19) && (!flag_cliff); let should_buffer = (LEDGE_DELAY == 0) && (current_frame == 19) && (!flag_cliff);
@ -105,7 +106,6 @@ pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor
} }
_ => mash::perform_defensive_option(), _ => mash::perform_defensive_option(),
} }
} }
pub unsafe fn is_enable_transition_term( pub unsafe fn is_enable_transition_term(

View file

@ -9,6 +9,7 @@ use smash::params::*;
use smash::phx::{Hash40, Vector3f}; use smash::phx::{Hash40, Vector3f};
pub mod buff; pub mod buff;
pub mod charge;
pub mod combo; pub mod combo;
pub mod directional_influence; pub mod directional_influence;
pub mod frame_counter; pub mod frame_counter;
@ -17,7 +18,6 @@ pub mod sdi;
pub mod shield; pub mod shield;
pub mod tech; pub mod tech;
pub mod throw; pub mod throw;
pub mod charge;
mod air_dodge_direction; mod air_dodge_direction;
mod attack_angle; mod attack_angle;
@ -354,7 +354,7 @@ pub unsafe fn handle_check_doyle_summon_dispatch(
return 4294967295; return 4294967295;
} }
} }
return ori; ori
} }
// Set Stale Moves to On // Set Stale Moves to On
@ -373,7 +373,7 @@ static STALE_MENU_OFFSET: usize = 0x013e88a0;
#[skyline::hook(offset=STALE_MENU_OFFSET, inline)] #[skyline::hook(offset=STALE_MENU_OFFSET, inline)]
unsafe fn stale_menu_handle(ctx: &mut InlineCtx) { unsafe fn stale_menu_handle(ctx: &mut InlineCtx) {
// Set the text pointer to where "mel_training_on" is located // Set the text pointer to where "mel_training_on" is located
let on_text_ptr = ((getRegionAddress(Region::Text) as u64) + (0x42b215e as u64)) as u64; let on_text_ptr = ((getRegionAddress(Region::Text) as u64) + (0x42b215e)) as u64;
let x1 = ctx.registers[1].x.as_mut(); let x1 = ctx.registers[1].x.as_mut();
*x1 = on_text_ptr; *x1 = on_text_ptr;
} }

View file

@ -5,8 +5,8 @@ use crate::common::consts::SaveStateMirroring;
use crate::common::is_dead; use crate::common::is_dead;
use crate::common::MENU; use crate::common::MENU;
use crate::training::buff; use crate::training::buff;
use crate::training::reset;
use crate::training::charge::{self, ChargeState}; use crate::training::charge::{self, ChargeState};
use crate::training::reset;
use smash::app::{self, lua_bind::*}; use smash::app::{self, lua_bind::*};
use smash::hash40; use smash::hash40;
use smash::lib::lua_const::*; use smash::lib::lua_const::*;
@ -87,7 +87,7 @@ pub unsafe fn is_killing() -> bool {
if SAVE_STATE_PLAYER.state == KillPlayer || SAVE_STATE_CPU.state == KillPlayer { if SAVE_STATE_PLAYER.state == KillPlayer || SAVE_STATE_CPU.state == KillPlayer {
return true; return true;
} }
return false; false
} }
pub unsafe fn should_mirror() -> f32 { pub unsafe fn should_mirror() -> f32 {
@ -234,14 +234,14 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
CameraModule::zoom_out(module_accessor, 0); CameraModule::zoom_out(module_accessor, 0);
// Remove blue effect (but does not remove darkened screen) // Remove blue effect (but does not remove darkened screen)
EffectModule::kill_kind( EffectModule::kill_kind(
module_accessor, module_accessor,
Hash40::new("sys_bg_criticalhit"), Hash40::new("sys_bg_criticalhit"),
false, false,
false false,
); );
// Removes the darkened screen from special zooms // Removes the darkened screen from special zooms
// If there's a crit that doesn't get removed, it's likely bg_criticalhit2. // If there's a crit that doesn't get removed, it's likely bg_criticalhit2.
EffectModule::remove_screen(module_accessor,Hash40::new("bg_criticalhit"),0); EffectModule::remove_screen(module_accessor, Hash40::new("bg_criticalhit"), 0);
// Remove all quakes to prevent screen shake lingering through load. // Remove all quakes to prevent screen shake lingering through load.
for quake_kind in *CAMERA_QUAKE_KIND_NONE..=*CAMERA_QUAKE_KIND_MAX { for quake_kind in *CAMERA_QUAKE_KIND_NONE..=*CAMERA_QUAKE_KIND_MAX {
CameraModule::stop_quake(module_accessor, quake_kind); CameraModule::stop_quake(module_accessor, quake_kind);
@ -325,7 +325,7 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
} }
// Perform fighter specific loading actions // Perform fighter specific loading actions
save_state.steve_state.map(|load_steve| { save_state.steve_state.map(|load_steve| {
steve::load_steve_state(module_accessor,load_steve); steve::load_steve_state(module_accessor, load_steve);
}); });
// Play Training Reset SFX, since silence is eerie // Play Training Reset SFX, since silence is eerie
// Only play for the CPU so we don't have 2 overlapping // Only play for the CPU so we don't have 2 overlapping

View file

@ -150,5 +150,5 @@ pub unsafe fn get_command_flag_throw_direction(
return cmd; return cmd;
} }
return 0; 0
} }

View file

@ -387,6 +387,7 @@ pub fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) -> String {
f.render_stateful_widget(list, list_chunks[list_section], &mut state); f.render_stateful_widget(list, list_chunks[list_section], &mut state);
} }
// TODO: Add Save Defaults
let help_paragraph = Paragraph::new( let help_paragraph = Paragraph::new(
item_help.unwrap_or("").replace("\"", "") + item_help.unwrap_or("").replace("\"", "") +
"\nA: Enter sub-menu | B: Exit menu | ZL/ZR: Next tab" "\nA: Enter sub-menu | B: Exit menu | ZL/ZR: Next tab"