mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-27 20:34:03 +00:00
13.0.2 Support - With ui2d update; fix notification ticking (#667)
* Correct bytecode for most of the offset searches * Fix Offset for GET_BATTLE_OBJECT_FROM_ID * Revert to make it crash on MALLOC * MALLOC crashing so TODOing it, up to crash on fixed_camera * attempt to hardcode SET_TRAINING_FIXED_CAMERA_VALUES, which causes the crash whether hardcoded or replaced, maybe due to next hook failing? * initial * Small changes to fix notification ticks --------- Co-authored-by: asimon-1 <40246417+asimon-1@users.noreply.github.com> Co-authored-by: GradualSyrup <68757075+GradualSyrup@users.noreply.github.com>
This commit is contained in:
parent
6862c235fe
commit
7dd05f1afd
8 changed files with 60 additions and 94 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "training_modpack"
|
name = "training_modpack"
|
||||||
version = "6.0.1"
|
version = "6.1.0"
|
||||||
authors = ["jugeeya <jugeeya@live.com>"]
|
authors = ["jugeeya <jugeeya@live.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" }
|
skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" }
|
||||||
skyline_smash = { git = "https://github.com/GradualSyrup/skyline-smash.git", branch = "training-modpack-updates" }
|
skyline_smash = { git = "https://github.com/jugeeya/skyline-smash.git", branch = "patch-2" }
|
||||||
skyline-web = { git = "https://github.com/skyline-rs/skyline-web.git" }
|
skyline-web = { git = "https://github.com/skyline-rs/skyline-web.git" }
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
parking_lot = { version = "0.12.0", features = ["nightly"] }
|
parking_lot = { version = "0.12.0", features = ["nightly"] }
|
||||||
|
|
|
@ -52,16 +52,16 @@ macro_rules! impl_offset {
|
||||||
//
|
//
|
||||||
// Recommended to use the first 8 instructions (32 bytes), unless the function is shorter
|
// Recommended to use the first 8 instructions (32 bytes), unless the function is shorter
|
||||||
|
|
||||||
// OFFSET_GET_BATTLE_OBJECT_FROM_ID = 0x3ac540
|
// OFFSET_GET_BATTLE_OBJECT_FROM_ID = 0x3ac560
|
||||||
static NEEDLE_GET_BATTLE_OBJECT_FROM_ID: &[u8] = &[
|
static NEEDLE_GET_BATTLE_OBJECT_FROM_ID: &[u8] = &[
|
||||||
0xff, 0x03, 0x06, 0xd1,
|
0x08, 0x7c, 0x1c, 0x53,
|
||||||
0xee, 0x73, 0x00, 0xfd,
|
0x1f, 0x11, 0x00, 0x71,
|
||||||
0xed, 0x33, 0x0f, 0x6d,
|
0x68, 0x07, 0x00, 0x54,
|
||||||
0xeb, 0x2b, 0x10, 0x6d,
|
0x49, 0x08, 0x02, 0xf0,
|
||||||
0xe9, 0x23, 0x11, 0x6d,
|
0x29, 0xd1, 0x07, 0x91,
|
||||||
0xfc, 0x6f, 0x12, 0xa9,
|
0x28, 0x79, 0xa8, 0xb8,
|
||||||
0xfa, 0x67, 0x13, 0xa9,
|
0x08, 0x01, 0x09, 0x8b,
|
||||||
0xf8, 0x5f, 0x14, 0xa9,
|
0x00, 0x01, 0x1f, 0xd6,
|
||||||
];
|
];
|
||||||
impl_offset!(GET_BATTLE_OBJECT_FROM_ID);
|
impl_offset!(GET_BATTLE_OBJECT_FROM_ID);
|
||||||
|
|
||||||
|
@ -127,19 +127,15 @@ static NEEDLE_CHANGE_ACTIVE_CAMERA: &[u8] = &[
|
||||||
];
|
];
|
||||||
impl_offset!(CHANGE_ACTIVE_CAMERA);
|
impl_offset!(CHANGE_ACTIVE_CAMERA);
|
||||||
|
|
||||||
// OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES = 0x3157bb0
|
// OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES = 0x3158830 (old: 0x3157bb0)
|
||||||
static NEEDLE_SET_TRAINING_FIXED_CAMERA_VALUES: &[u8] = &[
|
|
||||||
0x01, 0xe4, 0x00, 0x2f,
|
// static NEEDLE_SET_TRAINING_FIXED_CAMERA_VALUES: &[u8] = &[
|
||||||
0x20, 0x00, 0xc0, 0x3d,
|
// 0x01, 0xe4, 0x00, 0x2f,
|
||||||
0x22, 0x1c, 0xa1, 0x4e,
|
// 0x20, 0x00, 0xc0, 0x3d,
|
||||||
0x02, 0x44, 0x04, 0x6e,
|
// 0x22, 0x1c, 0xa1, 0x4e,
|
||||||
0xe8, 0x0a, 0x01, 0xf0,
|
// 0x02, 0x44, 0x04, 0x6e,
|
||||||
0x08, 0x81, 0x47, 0xf9,
|
// ];
|
||||||
0x08, 0x01, 0x40, 0xf9,
|
// impl_offset!(SET_TRAINING_FIXED_CAMERA_VALUES);
|
||||||
0x40, 0x04, 0x18, 0x6e,
|
|
||||||
0x00, 0xf5, 0x82, 0x3d,
|
|
||||||
];
|
|
||||||
impl_offset!(SET_TRAINING_FIXED_CAMERA_VALUES);
|
|
||||||
|
|
||||||
// OFFSET_DRAW = 0x4b620
|
// OFFSET_DRAW = 0x4b620
|
||||||
static NEEDLE_DRAW: &[u8] = &[
|
static NEEDLE_DRAW: &[u8] = &[
|
||||||
|
@ -174,24 +170,19 @@ impl_offset!(CLOUD_ADD_LIMIT);
|
||||||
// IMPORTANT! Because this offset is so close to OFFSET_STALE and
|
// IMPORTANT! Because this offset is so close to OFFSET_STALE and
|
||||||
// because we are modifying inline instead of hooking the whole function,
|
// because we are modifying inline instead of hooking the whole function,
|
||||||
// this hook has to be initialized first! Otherwise the search will fail.
|
// this hook has to be initialized first! Otherwise the search will fail.
|
||||||
// OFFSET_STALE_MENU = 0x13e88a0
|
// OFFSET_STALE_MENU = 0x13e88c0
|
||||||
static NEEDLE_STALE_MENU: &[u8] = &[
|
static NEEDLE_STALE_MENU: &[u8] = &[
|
||||||
0xdf, 0x82, 0x2d, 0x39,
|
0xdf, 0x82, 0x2d, 0x39,
|
||||||
0x93, 0x40, 0x8e, 0x94,
|
0xab, 0x43, 0x8e, 0x94,
|
||||||
0x00, 0x1d, 0xa8, 0x4e,
|
0x00, 0x1d, 0xa8, 0x4e,
|
||||||
0xc0, 0xa2, 0x06, 0x91,
|
0xc0, 0xa2, 0x06, 0x91,
|
||||||
0xdf, 0x22, 0x2f, 0x39,
|
|
||||||
0xff, 0x43, 0x8e, 0x94,
|
|
||||||
0xca, 0x82, 0x6d, 0x39,
|
|
||||||
0xe8, 0x77, 0x01, 0x90,
|
|
||||||
0x08, 0x6d, 0x3c, 0x91,
|
|
||||||
];
|
];
|
||||||
impl_offset!(STALE_MENU);
|
impl_offset!(STALE_MENU);
|
||||||
|
|
||||||
// IMPORTANT! See above comment for STALE_MENU
|
// IMPORTANT! See above comment for STALE_MENU
|
||||||
// OFFSET_STALE = 0x13e88a4
|
// OFFSET_STALE = 0x13e88c4
|
||||||
static NEEDLE_STALE: &[u8] = &[
|
static NEEDLE_STALE: &[u8] = &[
|
||||||
0x93, 0x40, 0x8e, 0x94,
|
0xab, 0x43, 0x8e, 0x94,
|
||||||
0x00, 0x1d, 0xa8, 0x4e,
|
0x00, 0x1d, 0xa8, 0x4e,
|
||||||
0xc0, 0xa2, 0x06, 0x91,
|
0xc0, 0xa2, 0x06, 0x91,
|
||||||
0xdf, 0x22, 0x2f, 0x39,
|
0xdf, 0x22, 0x2f, 0x39,
|
||||||
|
@ -242,18 +233,18 @@ static NEEDLE_REUSED_UI: &[u8] = &[
|
||||||
impl_offset!(REUSED_UI);
|
impl_offset!(REUSED_UI);
|
||||||
|
|
||||||
|
|
||||||
// OFFSET_OPCF = 0x6b7fdc
|
// // OFFSET_OPCF = 0x6b7ffc (old: 0x6b7fdc)
|
||||||
static NEEDLE_OPCF: &[u8] = &[
|
// static NEEDLE_OPCF: &[u8] = &[
|
||||||
0x68, 0xb6, 0x40, 0xf9,
|
// 0x68, 0xb6, 0x40, 0xf9,
|
||||||
0x09, 0x81, 0x49, 0x39,
|
// 0x09, 0x81, 0x49, 0x39,
|
||||||
0x69, 0xe1, 0xff, 0x35,
|
// 0x69, 0xe1, 0xff, 0x35,
|
||||||
0x08, 0x55, 0x41, 0x39,
|
// 0x08, 0x55, 0x41, 0x39,
|
||||||
0x28, 0xe1, 0x1f, 0x37,
|
// 0x28, 0xe1, 0x1f, 0x37,
|
||||||
0xe0, 0x03, 0x13, 0xaa,
|
// 0xe0, 0x03, 0x13, 0xaa,
|
||||||
0x63, 0x88, 0xf0, 0x97,
|
// 0x5b, 0x88, 0xf0, 0x97,
|
||||||
0xe9, 0x23, 0x43, 0x6d,
|
// 0xe9, 0x23, 0x43, 0x6d,
|
||||||
];
|
// ];
|
||||||
impl_offset!(OPCF);
|
// impl_offset!(OPCF);
|
||||||
|
|
||||||
// OFFSET_FIM = 0x17504a0
|
// OFFSET_FIM = 0x17504a0
|
||||||
static NEEDLE_FIM: &[u8] = &[
|
static NEEDLE_FIM: &[u8] = &[
|
||||||
|
@ -320,37 +311,30 @@ static NEEDLE_ACTIVATE_AUTONOMY: &[u8] = &[
|
||||||
];
|
];
|
||||||
impl_offset!(ACTIVATE_AUTONOMY);
|
impl_offset!(ACTIVATE_AUTONOMY);
|
||||||
|
|
||||||
// OFFSET_POKEMON_DECIDE = 0x34cdc64
|
// OFFSET_POKEMON_DECIDE = 0x34ce8e4
|
||||||
static NEEDLE_POKEMON_DECIDE: &[u8] = &[
|
static NEEDLE_POKEMON_DECIDE: &[u8] = &[
|
||||||
0x28, 0x69, 0x2b, 0x38,
|
0x28, 0x69, 0x2b, 0x38,
|
||||||
0x48, 0x26, 0x8b, 0x52,
|
0x48, 0x26, 0x8b, 0x52,
|
||||||
0x2a, 0x69, 0x28, 0x38,
|
0x2a, 0x69, 0x28, 0x38,
|
||||||
0x88, 0x12, 0x40, 0xf9,
|
0x88, 0x12, 0x40, 0xf9,
|
||||||
0x49, 0x01, 0x80, 0x52,
|
|
||||||
0x14, 0x29, 0x40, 0xf9,
|
|
||||||
0xe9, 0x0b, 0x00, 0xb9,
|
|
||||||
0x29, 0xdf, 0x00, 0xb0,
|
|
||||||
];
|
];
|
||||||
impl_offset!(POKEMON_DECIDE);
|
impl_offset!(POKEMON_DECIDE);
|
||||||
|
|
||||||
// OFFSET_LAYOUT_ARC_MALLOC = 0x37730d4
|
// // OFFSET_LAYOUT_ARC_MALLOC = 0x3773d54 (old: 0x37730d4)
|
||||||
static NEEDLE_LAYOUT_ARC_MALLOC: &[u8] = &[
|
|
||||||
0xe3, 0xe6, 0x06, 0x94,
|
|
||||||
0xa0, 0x05, 0x00, 0xb4,
|
|
||||||
0xe1, 0x03, 0x15, 0xaa,
|
|
||||||
0xe2, 0x03, 0x17, 0xaa,
|
|
||||||
0xc0, 0xb6, 0x00, 0xf9,
|
|
||||||
0x72, 0x2e, 0x09, 0x94,
|
|
||||||
0xc1, 0xb6, 0x40, 0xf9,
|
|
||||||
0xc2, 0x57, 0x00, 0xb0,
|
|
||||||
];
|
|
||||||
impl_offset!(LAYOUT_ARC_MALLOC);
|
|
||||||
|
|
||||||
// OFFSET_TRAINING_RESET_CHECK = 0x1378e30
|
// static NEEDLE_LAYOUT_ARC_MALLOC: &[u8] = &[
|
||||||
|
// 0xe3, 0xe6, 0x06, 0x94,
|
||||||
|
// 0xa0, 0x05, 0x00, 0xb4,
|
||||||
|
// 0xe1, 0x03, 0x15, 0xaa,
|
||||||
|
// 0xe2, 0x03, 0x17, 0xaa,
|
||||||
|
// ];
|
||||||
|
// impl_offset!(LAYOUT_ARC_MALLOC);
|
||||||
|
|
||||||
|
// OFFSET_TRAINING_RESET_CHECK = 0x1378e50
|
||||||
static NEEDLE_TRAINING_RESET_CHECK: &[u8] = &[
|
static NEEDLE_TRAINING_RESET_CHECK: &[u8] = &[
|
||||||
0x1f, 0x09, 0x00, 0x71,
|
0x1f, 0x09, 0x00, 0x71,
|
||||||
0x41, 0x1c, 0x00, 0x54,
|
0x41, 0x1c, 0x00, 0x54,
|
||||||
0xe8, 0xf9, 0x01, 0xf0,
|
0x08, 0xfa, 0x01, 0xb0,
|
||||||
0x08, 0x7d, 0x42, 0xf9,
|
0x08, 0x7d, 0x42, 0xf9,
|
||||||
0x08, 0x01, 0x40, 0xf9,
|
0x08, 0x01, 0x40, 0xf9,
|
||||||
0x09, 0xa1, 0x40, 0xb9,
|
0x09, 0xa1, 0x40, 0xb9,
|
||||||
|
|
|
@ -781,18 +781,11 @@ pub unsafe fn handle_article_get_int(
|
||||||
|
|
||||||
// Instruction run on the completion of the CPU Control function
|
// Instruction run on the completion of the CPU Control function
|
||||||
// One instruction after the CPU Control function completes
|
// One instruction after the CPU Control function completes
|
||||||
#[skyline::hook(offset = *OFFSET_OPCF, inline)]
|
#[skyline::hook(offset = 0x6b7fdc, inline)]
|
||||||
unsafe fn handle_once_per_cpu_frame(_ctx: &mut InlineCtx) {
|
unsafe fn handle_once_per_cpu_frame(_ctx: &mut InlineCtx) {
|
||||||
input_record::handle_recording();
|
input_record::handle_recording();
|
||||||
frame_counter::tick_ingame();
|
frame_counter::tick_ingame();
|
||||||
tech::hide_tech();
|
tech::hide_tech();
|
||||||
// Tick notifications
|
|
||||||
let queue = &mut ui::notifications::QUEUE;
|
|
||||||
let notification = queue.first();
|
|
||||||
if notification.is_some() {
|
|
||||||
let notification = queue.first_mut().unwrap();
|
|
||||||
notification.tick();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skyline::hook(offset = *OFFSET_FIM)]
|
#[skyline::hook(offset = *OFFSET_FIM)]
|
||||||
|
|
|
@ -8,7 +8,7 @@ use smash::phx::{Hash40, Vector3f};
|
||||||
use crate::common::consts::*;
|
use crate::common::consts::*;
|
||||||
use crate::common::offsets::OFFSET_CHANGE_ACTIVE_CAMERA;
|
use crate::common::offsets::OFFSET_CHANGE_ACTIVE_CAMERA;
|
||||||
|
|
||||||
use crate::common::offsets::OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES;
|
//use crate::common::offsets::OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES;
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use crate::training::{frame_counter, mash, save_states};
|
use crate::training::{frame_counter, mash, save_states};
|
||||||
|
|
||||||
|
@ -730,7 +730,7 @@ fn get_stage_camera_values(stage_id: i32) -> Option<Vector3f> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We hook where the training fixed camera fields are initially set, so we can change them later if necessary
|
// We hook where the training fixed camera fields are initially set, so we can change them later if necessary
|
||||||
#[skyline::hook(offset = *OFFSET_SET_TRAINING_FIXED_CAMERA_VALUES)]
|
#[skyline::hook(offset = 0x3157bb0)] // TODO: Fix for 13.0.2
|
||||||
pub unsafe fn handle_set_training_fixed_camera_values(
|
pub unsafe fn handle_set_training_fixed_camera_values(
|
||||||
camera_manager: *mut u64, // not actually camera manager - is this even used?????
|
camera_manager: *mut u64, // not actually camera manager - is this even used?????
|
||||||
fixed_camera_values: &mut CameraValuesForTraining,
|
fixed_camera_values: &mut CameraValuesForTraining,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use skyline::nn::ui2d::*;
|
use skyline::nn::ui2d::*;
|
||||||
use smash::ui2d::{SmashPane, SmashTextBox};
|
use smash::ui2d::{SmashPane, SmashTextBox};
|
||||||
|
|
||||||
use crate::common::{menu::QUICK_MENU_ACTIVE, TRAINING_MENU_ADDR};
|
use crate::common::menu::QUICK_MENU_ACTIVE;
|
||||||
use crate::training::ui;
|
use crate::training::ui;
|
||||||
macro_rules! display_parent_fmt {
|
macro_rules! display_parent_fmt {
|
||||||
($x:ident) => {
|
($x:ident) => {
|
||||||
|
@ -22,8 +22,6 @@ macro_rules! display_txt_fmt {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn draw(root_pane: &Pane) {
|
pub unsafe fn draw(root_pane: &Pane) {
|
||||||
// Make sure the combo counter is being displayed before we draw
|
|
||||||
let cc_displayed = (*TRAINING_MENU_ADDR).combo_display_toggle != 0;
|
|
||||||
let notification_idx = 0;
|
let notification_idx = 0;
|
||||||
|
|
||||||
let queue = &mut ui::notifications::QUEUE;
|
let queue = &mut ui::notifications::QUEUE;
|
||||||
|
@ -32,20 +30,15 @@ pub unsafe fn draw(root_pane: &Pane) {
|
||||||
root_pane
|
root_pane
|
||||||
.find_pane_by_name_recursive(display_parent_fmt!(notification_idx))
|
.find_pane_by_name_recursive(display_parent_fmt!(notification_idx))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_visible(notification.is_some() && !QUICK_MENU_ACTIVE && cc_displayed);
|
.set_visible(notification.is_some() && !QUICK_MENU_ACTIVE);
|
||||||
if notification.is_none() {
|
if notification.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let notification = notification.unwrap();
|
let notification = notification.unwrap();
|
||||||
|
notification.tick();
|
||||||
let color = notification.color;
|
let color = notification.color;
|
||||||
|
|
||||||
if !cc_displayed {
|
|
||||||
// Set the notification to drawn so we don't draw it
|
|
||||||
notification.set_drawn();
|
|
||||||
notification.force_complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
if !notification.has_drawn() {
|
if !notification.has_drawn() {
|
||||||
notification.set_drawn();
|
notification.set_drawn();
|
||||||
root_pane
|
root_pane
|
||||||
|
|
|
@ -6,7 +6,8 @@ use smash::ui2d::SmashTextBox;
|
||||||
use training_mod_consts::{OnOff, MENU};
|
use training_mod_consts::{OnOff, MENU};
|
||||||
|
|
||||||
use crate::common::menu::QUICK_MENU_ACTIVE;
|
use crate::common::menu::QUICK_MENU_ACTIVE;
|
||||||
use crate::common::offsets::{OFFSET_DRAW, OFFSET_LAYOUT_ARC_MALLOC};
|
//use crate::common::offsets::{OFFSET_DRAW, OFFSET_LAYOUT_ARC_MALLOC};
|
||||||
|
use crate::common::offsets::OFFSET_DRAW;
|
||||||
use crate::common::{is_ready_go, is_training_mode};
|
use crate::common::{is_ready_go, is_training_mode};
|
||||||
#[cfg(feature = "layout_arc_from_file")]
|
#[cfg(feature = "layout_arc_from_file")]
|
||||||
use crate::consts::LAYOUT_ARC_PATH;
|
use crate::consts::LAYOUT_ARC_PATH;
|
||||||
|
@ -90,7 +91,7 @@ pub unsafe fn handle_draw(layout: *mut Layout, draw_info: u64, cmd_buffer: u64)
|
||||||
// in order for us to be able to swap the 'layout.arc' with the current
|
// in order for us to be able to swap the 'layout.arc' with the current
|
||||||
// version of the file in between loads of training mode.
|
// version of the file in between loads of training mode.
|
||||||
#[cfg(feature = "layout_arc_from_file")]
|
#[cfg(feature = "layout_arc_from_file")]
|
||||||
const LAYOUT_ARC_SIZE: usize = (4 * MEBIBYTE) as usize;
|
const LAYOUT_ARC_SIZE: usize = (5 * MEBIBYTE) as usize;
|
||||||
#[cfg(feature = "layout_arc_from_file")]
|
#[cfg(feature = "layout_arc_from_file")]
|
||||||
static mut LAYOUT_ARC: &mut [u8; LAYOUT_ARC_SIZE] = &mut [0u8; LAYOUT_ARC_SIZE];
|
static mut LAYOUT_ARC: &mut [u8; LAYOUT_ARC_SIZE] = &mut [0u8; LAYOUT_ARC_SIZE];
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ static mut LAYOUT_ARC: &mut [u8; LAYOUT_ARC_SIZE] = &mut [0u8; LAYOUT_ARC_SIZE];
|
||||||
/// label_material.set_white_res_color(LABEL_WHITE_SELECTED_COLOR);
|
/// label_material.set_white_res_color(LABEL_WHITE_SELECTED_COLOR);
|
||||||
/// label_material.set_black_res_color(LABEL_BLACK_SELECTED_COLOR);
|
/// label_material.set_black_res_color(LABEL_BLACK_SELECTED_COLOR);
|
||||||
/// ```
|
/// ```
|
||||||
#[skyline::hook(offset = *OFFSET_LAYOUT_ARC_MALLOC, inline)]
|
#[skyline::hook(offset = 0x3773d54, inline)] // TODO: Fix for 13.0.2
|
||||||
unsafe fn handle_layout_arc_malloc(ctx: &mut skyline::hooks::InlineCtx) {
|
unsafe fn handle_layout_arc_malloc(ctx: &mut skyline::hooks::InlineCtx) {
|
||||||
if !is_training_mode() {
|
if !is_training_mode() {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -34,11 +34,6 @@ impl Notification {
|
||||||
self.length -= 1;
|
self.length -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to force the notification to be removed from queue
|
|
||||||
pub fn force_complete(&mut self) {
|
|
||||||
self.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns: has_completed
|
// Returns: has_completed
|
||||||
pub fn check_completed(&mut self) -> bool {
|
pub fn check_completed(&mut self) -> bool {
|
||||||
if self.length <= 1 {
|
if self.length <= 1 {
|
||||||
|
|
|
@ -671,7 +671,7 @@ impl_toggletrait! {
|
||||||
OnOff,
|
OnOff,
|
||||||
"Frame Advantage",
|
"Frame Advantage",
|
||||||
"frame_advantage",
|
"frame_advantage",
|
||||||
"Frame Advantage: Display the time difference between when the player is actionable and the CPU is actionable",
|
"Frame Advantage: Display the time difference between when the player is actionable and the CPU is actionable\nNote that the CPU must not be mashing any options.",
|
||||||
true,
|
true,
|
||||||
1,
|
1,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue