mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2025-01-19 08:50:14 +00:00
reformatting
This commit is contained in:
parent
329f0cd3f0
commit
6cf353faec
11 changed files with 738 additions and 514 deletions
|
@ -1,4 +1,4 @@
|
|||
pub const NONE : i32 = 0;
|
||||
pub const NONE: i32 = 0;
|
||||
|
||||
// Side Taunt
|
||||
|
||||
|
@ -9,69 +9,68 @@ pub const NONE : i32 = 0;
|
|||
*/
|
||||
|
||||
/* DI */
|
||||
pub static mut DI_STATE : i32 = NONE;
|
||||
pub const DI_RANDOM_IN_AWAY : i32 = 9;
|
||||
pub static mut DI_STATE: i32 = NONE;
|
||||
pub const DI_RANDOM_IN_AWAY: i32 = 9;
|
||||
// const std::vector<std::string> di_items{"None", "Out", "Up Out", "Up", "Up In", "In", "Down In", "Down", "Down Out", "Random"};
|
||||
|
||||
// Attack Option
|
||||
pub const MASH_NAIR : i32 = 0;
|
||||
pub const MASH_FAIR : i32 = 1;
|
||||
pub const MASH_BAIR : i32 = 2;
|
||||
pub const MASH_UPAIR : i32 = 3;
|
||||
pub const MASH_DAIR : i32 = 4;
|
||||
pub const MASH_NEUTRAL_B : i32 = 5;
|
||||
pub const MASH_SIDE_B : i32 = 6;
|
||||
pub const MASH_UP_B : i32 = 7;
|
||||
pub const MASH_DOWN_B : i32 = 8;
|
||||
pub const MASH_UP_SMASH : i32 = 9;
|
||||
pub const MASH_GRAB : i32 = 10;
|
||||
pub const MASH_NAIR: i32 = 0;
|
||||
pub const MASH_FAIR: i32 = 1;
|
||||
pub const MASH_BAIR: i32 = 2;
|
||||
pub const MASH_UPAIR: i32 = 3;
|
||||
pub const MASH_DAIR: i32 = 4;
|
||||
pub const MASH_NEUTRAL_B: i32 = 5;
|
||||
pub const MASH_SIDE_B: i32 = 6;
|
||||
pub const MASH_UP_B: i32 = 7;
|
||||
pub const MASH_DOWN_B: i32 = 8;
|
||||
pub const MASH_UP_SMASH: i32 = 9;
|
||||
pub const MASH_GRAB: i32 = 10;
|
||||
// pub const std::vector<std::string> attack_items{"Neutral Air", "Forward Air", "Back Air", "Up Air", "Down Air", "Neutral B", "Side B", "Up B", "Down B", "Up Smash", "Grab"};
|
||||
|
||||
// Ledge Option
|
||||
pub const RANDOM_LEDGE : i32 = 1;
|
||||
pub const NEUTRAL_LEDGE : i32 = 2;
|
||||
pub const ROLL_LEDGE : i32 = 3;
|
||||
pub const JUMP_LEDGE : i32 = 4;
|
||||
pub const ATTACK_LEDGE : i32 = 5;
|
||||
pub const RANDOM_LEDGE: i32 = 1;
|
||||
pub const NEUTRAL_LEDGE: i32 = 2;
|
||||
pub const ROLL_LEDGE: i32 = 3;
|
||||
pub const JUMP_LEDGE: i32 = 4;
|
||||
pub const ATTACK_LEDGE: i32 = 5;
|
||||
// pub const std::vector<std::string> ledge_items{"None", "Random", "Ntrl. Getup", "Roll", "Jump", "Attack"};
|
||||
|
||||
// Tech Option
|
||||
pub const RANDOM_TECH : i32 = 1;
|
||||
pub const TECH_IN_PLACE : i32 = 2;
|
||||
pub const TECH_ROLL : i32 = 3;
|
||||
pub const TECH_MISS : i32 = 4;
|
||||
pub const RANDOM_TECH: i32 = 1;
|
||||
pub const TECH_IN_PLACE: i32 = 2;
|
||||
pub const TECH_ROLL: i32 = 3;
|
||||
pub const TECH_MISS: i32 = 4;
|
||||
// pub const std::vector<std::string> tech_items{"None", "Random", "In-Place", "Roll", "Miss Tech"};
|
||||
|
||||
// Mash States
|
||||
pub const MASH_AIRDODGE : i32 = 1;
|
||||
pub const MASH_JUMP : i32 = 2;
|
||||
pub const MASH_ATTACK : i32 = 3;
|
||||
pub const MASH_SPOTDODGE : i32 = 4;
|
||||
pub const MASH_RANDOM : i32 = 5;
|
||||
pub const MASH_AIRDODGE: i32 = 1;
|
||||
pub const MASH_JUMP: i32 = 2;
|
||||
pub const MASH_ATTACK: i32 = 3;
|
||||
pub const MASH_SPOTDODGE: i32 = 4;
|
||||
pub const MASH_RANDOM: i32 = 5;
|
||||
// pub const std::vector<std::string> mash_items{"None", "Airdodge", "Jump", "Attack", "Spotdodge", "Random"};
|
||||
|
||||
// Shield States
|
||||
pub const SHIELD_INFINITE : i32 = 1;
|
||||
pub const SHIELD_HOLD : i32 = 2;
|
||||
pub const SHIELD_INFINITE: i32 = 1;
|
||||
pub const SHIELD_HOLD: i32 = 2;
|
||||
// pub const std::vector<std::string> shield_items{"None", "Infinite", "Hold"};
|
||||
|
||||
// Defensive States
|
||||
pub const RANDOM_DEFENSIVE : i32 = 1;
|
||||
pub const DEFENSIVE_SPOTDODGE : i32 = 2;
|
||||
pub const DEFENSIVE_ROLL : i32 = 3;
|
||||
pub const DEFENSIVE_JAB : i32 = 4;
|
||||
pub const DEFENSIVE_SHIELD : i32 = 5;
|
||||
pub const RANDOM_DEFENSIVE: i32 = 1;
|
||||
pub const DEFENSIVE_SPOTDODGE: i32 = 2;
|
||||
pub const DEFENSIVE_ROLL: i32 = 3;
|
||||
pub const DEFENSIVE_JAB: i32 = 4;
|
||||
pub const DEFENSIVE_SHIELD: i32 = 5;
|
||||
// pub const std::vector<std::string> defensive_items{"None", "Random", "Spotdodge", "Roll", "Jab", "Flash Shield"};
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TrainingModpackMenu
|
||||
{
|
||||
pub HITBOX_VIS : bool,
|
||||
pub DI_STATE : i32,
|
||||
pub ATTACK_STATE : i32,
|
||||
pub LEDGE_STATE : i32,
|
||||
pub TECH_STATE : i32,
|
||||
pub MASH_STATE : i32,
|
||||
pub SHIELD_STATE : i32,
|
||||
pub DEFENSIVE_STATE : i32,
|
||||
}
|
||||
pub struct TrainingModpackMenu {
|
||||
pub HITBOX_VIS: bool,
|
||||
pub DI_STATE: i32,
|
||||
pub ATTACK_STATE: i32,
|
||||
pub LEDGE_STATE: i32,
|
||||
pub TECH_STATE: i32,
|
||||
pub MASH_STATE: i32,
|
||||
pub SHIELD_STATE: i32,
|
||||
pub DEFENSIVE_STATE: i32,
|
||||
}
|
||||
|
|
|
@ -1,46 +1,43 @@
|
|||
pub mod consts;
|
||||
|
||||
use smash::lib::lua_const::{*};
|
||||
use crate::common::consts::*;
|
||||
use smash::app::{self};
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::{self};
|
||||
use smash::lib::lua_const::*;
|
||||
// use smash::app::{FighterManager, FighterInformation};
|
||||
use smash::hash40;
|
||||
|
||||
pub static mut menu_struct : consts::TrainingModpackMenu = consts::TrainingModpackMenu{
|
||||
HITBOX_VIS : true,
|
||||
DI_STATE : NONE,
|
||||
ATTACK_STATE : MASH_NAIR,
|
||||
LEDGE_STATE : RANDOM_LEDGE,
|
||||
TECH_STATE : RANDOM_TECH,
|
||||
MASH_STATE : NONE,
|
||||
SHIELD_STATE : NONE,
|
||||
DEFENSIVE_STATE : RANDOM_DEFENSIVE,
|
||||
pub static mut menu_struct: consts::TrainingModpackMenu = consts::TrainingModpackMenu {
|
||||
HITBOX_VIS: true,
|
||||
DI_STATE: NONE,
|
||||
ATTACK_STATE: MASH_NAIR,
|
||||
LEDGE_STATE: RANDOM_LEDGE,
|
||||
TECH_STATE: RANDOM_TECH,
|
||||
MASH_STATE: NONE,
|
||||
SHIELD_STATE: NONE,
|
||||
DEFENSIVE_STATE: RANDOM_DEFENSIVE,
|
||||
};
|
||||
|
||||
pub static mut menu : *mut consts::TrainingModpackMenu = 0 as *mut consts::TrainingModpackMenu;
|
||||
pub static mut menu: *mut consts::TrainingModpackMenu = 0 as *mut consts::TrainingModpackMenu;
|
||||
|
||||
pub static mut fighter_manager_addr : usize = 0;
|
||||
pub static mut fighter_manager_addr: usize = 0;
|
||||
|
||||
extern "C" {
|
||||
#[link_name = "\u{1}_ZN3app9smashball16is_training_modeEv"]
|
||||
pub fn is_training_mode() -> bool;
|
||||
}
|
||||
|
||||
pub fn get_category(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor) -> i32
|
||||
{
|
||||
return (module_accessor.info >> 28) as u8 as i32;
|
||||
pub fn get_category(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 {
|
||||
return (module_accessor.info >> 28) as u8 as i32;
|
||||
}
|
||||
|
||||
pub unsafe fn is_operation_cpu(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
|
||||
{
|
||||
pub unsafe fn is_operation_cpu(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
if get_category(module_accessor) as i32 != BATTLE_OBJECT_CATEGORY_FIGHTER {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
let entry_id_int = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32;
|
||||
let entry_id_int =
|
||||
WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as i32;
|
||||
let entry_id = app::FighterEntryID(entry_id_int);
|
||||
// let mut mgr = FighterManager{_address : fighter_manager_addr as u64};
|
||||
// let fighter_information = lua_bind::FighterManager::get_fighter_information(&mut mgr, entry_id) as *mut FighterInformation;
|
||||
|
@ -50,64 +47,56 @@ pub unsafe fn is_operation_cpu(
|
|||
entry_id_int > 0
|
||||
}
|
||||
|
||||
pub unsafe fn is_in_hitstun(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
|
||||
{
|
||||
pub unsafe fn is_in_hitstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
||||
(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 unsafe fn is_in_shieldstun(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
|
||||
{
|
||||
pub unsafe fn is_in_shieldstun(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
// If we are taking shield damage or we are droping shield from taking shield damage we are in hitstun
|
||||
if status_kind == FIGHTER_STATUS_KIND_GUARD_DAMAGE ||
|
||||
(prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE && status_kind == FIGHTER_STATUS_KIND_GUARD_OFF) {
|
||||
return true
|
||||
if status_kind == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
|| (prev_status == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
&& status_kind == FIGHTER_STATUS_KIND_GUARD_OFF)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
|
||||
pub unsafe fn is_in_landing(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor) -> bool
|
||||
{
|
||||
pub unsafe fn is_in_landing(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
||||
(FIGHTER_STATUS_KIND_LANDING..=FIGHTER_STATUS_KIND_LANDING_DAMAGE_LIGHT)
|
||||
.contains(&status_kind)
|
||||
(FIGHTER_STATUS_KIND_LANDING..=FIGHTER_STATUS_KIND_LANDING_DAMAGE_LIGHT).contains(&status_kind)
|
||||
}
|
||||
|
||||
|
||||
pub unsafe fn perform_defensive_option(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
flag: &mut i32)
|
||||
{
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
flag: &mut i32,
|
||||
) {
|
||||
match (*menu).DEFENSIVE_STATE {
|
||||
RANDOM_DEFENSIVE => {
|
||||
let random_cmds = vec![
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
];
|
||||
|
||||
let random_cmd_index = app::sv_math::rand(
|
||||
hash40("fighter"), random_cmds.len() as i32) as usize;
|
||||
|
||||
let random_cmd_index =
|
||||
app::sv_math::rand(hash40("fighter"), random_cmds.len() as i32) as usize;
|
||||
*flag |= random_cmds[random_cmd_index];
|
||||
},
|
||||
}
|
||||
DEFENSIVE_ROLL => {
|
||||
if app::sv_math::rand(hash40("fighter"), 2) == 0 {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F;
|
||||
} else {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B;
|
||||
}
|
||||
},
|
||||
}
|
||||
DEFENSIVE_SPOTDODGE => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
|
||||
DEFENSIVE_JAB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,87 +1,145 @@
|
|||
use smash::hash40;
|
||||
use smash::app::{self};
|
||||
use crate::common::*;
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::sv_animcmd::{self};
|
||||
use smash::app::sv_system::{self};
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::{self};
|
||||
use smash::hash40;
|
||||
use smash::lib::lua_const::*;
|
||||
use smash::lib::{L2CAgent, L2CValue};
|
||||
use smash::phx::{Hash40, Vector3f};
|
||||
use crate::common::*;
|
||||
|
||||
/**
|
||||
* Rounds a number to the nearest multiple of another number.
|
||||
*/
|
||||
pub fn round_to(val: f32, align: f32) -> f32 { (val / align).round() * align }
|
||||
pub fn round_to(val: f32, align: f32) -> f32 {
|
||||
(val / align).round() * align
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two numbers, without bounds checking.
|
||||
*/
|
||||
pub fn lerp(min: f32, max: f32, t: f32) -> f32 { min + (max - min) * t }
|
||||
|
||||
pub fn unlerp(min: f32, max: f32, val: f32) -> f32 { (val - min) / (max - min) }
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two numbers, with bounds checking.
|
||||
*/
|
||||
/**
|
||||
* Linearly interpolates between two numbers, without bounds checking.
|
||||
*/
|
||||
pub fn lerp(min: f32, max: f32, t: f32) -> f32 {
|
||||
min + (max - min) * t
|
||||
}
|
||||
|
||||
pub fn unlerp(min: f32, max: f32, val: f32) -> f32 {
|
||||
(val - min) / (max - min)
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two numbers, with bounds checking.
|
||||
*/
|
||||
pub fn lerp_bounded(min: f32, max: f32, t: f32) -> f32 {
|
||||
if t <= 0.0 { min } else { if t >= 1.0 { max } else { lerp(min, max, t) } }
|
||||
if t <= 0.0 {
|
||||
min
|
||||
} else {
|
||||
if t >= 1.0 {
|
||||
max
|
||||
} else {
|
||||
lerp(min, max, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unlerp_bounded(min: f32, max: f32, val: f32) -> f32 {
|
||||
if val <= min { 0.0 } else { if val >= max { 1.0 } else { unlerp(min, max, val)} }
|
||||
if val <= min {
|
||||
0.0
|
||||
} else {
|
||||
if val >= max {
|
||||
1.0
|
||||
} else {
|
||||
unlerp(min, max, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two colors, with bounds checking, accounting for
|
||||
* gamma. arguments:
|
||||
* - min_color (Vector3f) -- xyz maps to rgb, components are usually in the
|
||||
* range [0.0f, 1.0f] but can go beyond to account for super-bright or
|
||||
* super-dark colors
|
||||
* - max_Color (Vector3f) -- same as minColor
|
||||
* - t (float) -- how far to interpolate between the colors
|
||||
* - gamma (float = 2.0f) -- used for color correction, helps avoid ugly dark
|
||||
* colors when interpolating b/t bright colors
|
||||
*/
|
||||
|
||||
pub fn color_lerp(min_color: Vector3f, max_color: Vector3f, t: f32,
|
||||
gamma: f32) -> Vector3f {
|
||||
let gamma_inv = 1.0 / gamma;
|
||||
let align =
|
||||
1.0 / 255.0; // color components must be a multiple of 1/255
|
||||
Vector3f{x: round_to(lerp_bounded(min_color.x.powf(gamma),
|
||||
max_color.x.powf(gamma), t).powf(
|
||||
gamma_inv),
|
||||
align),
|
||||
y: round_to(lerp_bounded(min_color.y.powf(gamma),
|
||||
max_color.y.powf(gamma), t).powf(
|
||||
gamma_inv),
|
||||
align),
|
||||
z: round_to(lerp_bounded(min_color.z.powf(gamma),
|
||||
max_color.z.powf(gamma), t).powf(
|
||||
gamma_inv),
|
||||
align)}
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two colors, with bounds checking, accounting for
|
||||
* gamma. arguments:
|
||||
* - min_color (Vector3f) -- xyz maps to rgb, components are usually in the
|
||||
* range [0.0f, 1.0f] but can go beyond to account for super-bright or
|
||||
* super-dark colors
|
||||
* - max_Color (Vector3f) -- same as minColor
|
||||
* - t (float) -- how far to interpolate between the colors
|
||||
* - gamma (float = 2.0f) -- used for color correction, helps avoid ugly dark
|
||||
* colors when interpolating b/t bright colors
|
||||
*/
|
||||
|
||||
pub fn color_lerp(min_color: Vector3f, max_color: Vector3f, t: f32, gamma: f32) -> Vector3f {
|
||||
let gamma_inv = 1.0 / gamma;
|
||||
let align = 1.0 / 255.0; // color components must be a multiple of 1/255
|
||||
Vector3f {
|
||||
x: round_to(
|
||||
lerp_bounded(min_color.x.powf(gamma), max_color.x.powf(gamma), t).powf(gamma_inv),
|
||||
align,
|
||||
),
|
||||
y: round_to(
|
||||
lerp_bounded(min_color.y.powf(gamma), max_color.y.powf(gamma), t).powf(gamma_inv),
|
||||
align,
|
||||
),
|
||||
z: round_to(
|
||||
lerp_bounded(min_color.z.powf(gamma), max_color.z.powf(gamma), t).powf(gamma_inv),
|
||||
align,
|
||||
),
|
||||
}
|
||||
}
|
||||
pub const ID_COLORS: &[Vector3f] = &[
|
||||
// used to tint the hitbox effects -- make sure that at least one component
|
||||
// is equal to 1.0
|
||||
Vector3f{x: 1.0, y: 0.0, z: 0.0}, // #ff0000 (red)
|
||||
Vector3f{x: 1.0, y: 0.4, z: 0.0}, // #ff9900 (orange)
|
||||
Vector3f{x: 0.8, y: 1.0, z: 0.0}, // #ccff00 (yellow)
|
||||
Vector3f{x: 0.2, y: 1.0, z: 0.2}, // #00ff33 (green)
|
||||
Vector3f{x: 0.0, y: 0.8, z: 1.0}, // #00ccff (sky blue)
|
||||
Vector3f{x: 0.4, y: 0.4, z: 1.0}, // #6666ff (blue)
|
||||
Vector3f{x: 0.8, y: 0.0, z: 1.0}, // #cc00ff (purple)
|
||||
Vector3f{x: 1.0, y: 0.2, z: 0.8}, // #ff33cc (pink)
|
||||
Vector3f {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
}, // #ff0000 (red)
|
||||
Vector3f {
|
||||
x: 1.0,
|
||||
y: 0.4,
|
||||
z: 0.0,
|
||||
}, // #ff9900 (orange)
|
||||
Vector3f {
|
||||
x: 0.8,
|
||||
y: 1.0,
|
||||
z: 0.0,
|
||||
}, // #ccff00 (yellow)
|
||||
Vector3f {
|
||||
x: 0.2,
|
||||
y: 1.0,
|
||||
z: 0.2,
|
||||
}, // #00ff33 (green)
|
||||
Vector3f {
|
||||
x: 0.0,
|
||||
y: 0.8,
|
||||
z: 1.0,
|
||||
}, // #00ccff (sky blue)
|
||||
Vector3f {
|
||||
x: 0.4,
|
||||
y: 0.4,
|
||||
z: 1.0,
|
||||
}, // #6666ff (blue)
|
||||
Vector3f {
|
||||
x: 0.8,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
}, // #cc00ff (purple)
|
||||
Vector3f {
|
||||
x: 1.0,
|
||||
y: 0.2,
|
||||
z: 0.8,
|
||||
}, // #ff33cc (pink)
|
||||
];
|
||||
const MAX_EFFECTS_PER_HITBOX: i32 = 16; // max # of circles drawn for an extended hitbox
|
||||
|
||||
pub unsafe fn generate_hitbox_effects(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
bone: u64,
|
||||
size: f32, x: f32, y: f32,
|
||||
z: f32, x2: Option<f32>, y2: Option<f32>,
|
||||
z2: Option<f32>, color: Vector3f) {
|
||||
size: f32,
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
x2: Option<f32>,
|
||||
y2: Option<f32>,
|
||||
z2: Option<f32>,
|
||||
color: Vector3f,
|
||||
) {
|
||||
let red = L2CValue::new_num(color.x);
|
||||
let green = L2CValue::new_num(color.y);
|
||||
let blue = L2CValue::new_num(color.z);
|
||||
|
@ -95,21 +153,24 @@ pub unsafe fn generate_hitbox_effects(
|
|||
|
||||
let rate = L2CValue::new_num(8.0);
|
||||
|
||||
let x_dist : f32;
|
||||
let y_dist : f32;
|
||||
let z_dist : f32;
|
||||
let mut n_effects : i32;
|
||||
if x2 == None { // && let lib::L2CValueType::Void = y2.val_type && let lib::L2CValueType::Void = z2.val_type { // extended hitbox
|
||||
x_dist = 0.0; y_dist = 0.0; z_dist = 0.0;
|
||||
let x_dist: f32;
|
||||
let y_dist: f32;
|
||||
let z_dist: f32;
|
||||
let mut n_effects: i32;
|
||||
if x2 == None {
|
||||
// && let lib::L2CValueType::Void = y2.val_type && let lib::L2CValueType::Void = z2.val_type { // extended hitbox
|
||||
x_dist = 0.0;
|
||||
y_dist = 0.0;
|
||||
z_dist = 0.0;
|
||||
n_effects = 1;
|
||||
}
|
||||
else { // non-extended hitbox
|
||||
} else {
|
||||
// non-extended hitbox
|
||||
x_dist = x2.unwrap() - x;
|
||||
y_dist = y2.unwrap() - y;
|
||||
z_dist = z2.unwrap() - z;
|
||||
let dist_sq : f32 = x_dist * x_dist + y_dist * y_dist + z_dist * z_dist;
|
||||
let dist_sq: f32 = x_dist * x_dist + y_dist * y_dist + z_dist * z_dist;
|
||||
let dist = dist_sq.sqrt();
|
||||
n_effects = ((dist / (size * 1.75)) + 1.0).ceil() as i32; // just enough effects to form a continuous line
|
||||
n_effects = ((dist / (size * 1.75)) + 1.0).ceil() as i32; // just enough effects to form a continuous line
|
||||
if n_effects < 2 {
|
||||
n_effects = 2;
|
||||
} else if n_effects > MAX_EFFECTS_PER_HITBOX {
|
||||
|
@ -117,7 +178,7 @@ pub unsafe fn generate_hitbox_effects(
|
|||
}
|
||||
}
|
||||
|
||||
for i in 0..n_effects {
|
||||
for i in 0..n_effects {
|
||||
let mut t = 0.0;
|
||||
if n_effects > 1 {
|
||||
t = (i as f32) / ((n_effects - 1) as f32);
|
||||
|
@ -126,23 +187,38 @@ pub unsafe fn generate_hitbox_effects(
|
|||
let y_curr = y + y_dist * t;
|
||||
let z_curr = z + z_dist * t;
|
||||
|
||||
let pos = Vector3f{x : x_curr, y : y_curr, z : z_curr};
|
||||
let zeros = Vector3f{x : 0.0, y : 0.0, z : 0.0};
|
||||
|
||||
EffectModule::req_on_joint(module_accessor,
|
||||
Hash40{hash: hash40("sys_shield")}, Hash40{hash: bone},
|
||||
&pos, &zeros, size * size_mult, &zeros, &zeros,
|
||||
true,
|
||||
*EFFECT_SUB_ATTRIBUTE_NO_JOINT_SCALE as u32 |
|
||||
*EFFECT_SUB_ATTRIBUTE_FOLLOW as u32 |
|
||||
*EFFECT_SUB_ATTRIBUTE_CONCLUDE_STATUS as u32,
|
||||
0, 0);
|
||||
let pos = Vector3f {
|
||||
x: x_curr,
|
||||
y: y_curr,
|
||||
z: z_curr,
|
||||
};
|
||||
let zeros = Vector3f {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
};
|
||||
|
||||
EffectModule::req_on_joint(
|
||||
module_accessor,
|
||||
Hash40 {
|
||||
hash: hash40("sys_shield"),
|
||||
},
|
||||
Hash40 { hash: bone },
|
||||
&pos,
|
||||
&zeros,
|
||||
size * size_mult,
|
||||
&zeros,
|
||||
&zeros,
|
||||
true,
|
||||
*EFFECT_SUB_ATTRIBUTE_NO_JOINT_SCALE as u32
|
||||
| *EFFECT_SUB_ATTRIBUTE_FOLLOW as u32
|
||||
| *EFFECT_SUB_ATTRIBUTE_CONCLUDE_STATUS as u32,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
|
||||
// set to hitbox ID color
|
||||
EffectModule::set_rgb_partial_last(
|
||||
module_accessor, color.x, color.y, color.z
|
||||
);
|
||||
EffectModule::set_rgb_partial_last(module_accessor, color.x, color.y, color.z);
|
||||
|
||||
// speed up animation by rate to remove pulsing effect
|
||||
EffectModule::set_rate_last(module_accessor, 8.0);
|
||||
|
@ -151,23 +227,41 @@ pub unsafe fn generate_hitbox_effects(
|
|||
|
||||
pub unsafe fn get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32)
|
||||
{
|
||||
category: i32,
|
||||
) {
|
||||
// apply only once per frame
|
||||
if category == 0 && is_training_mode() && (*menu).HITBOX_VIS {
|
||||
// Pause Effect AnimCMD if hitbox visualization is active
|
||||
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
||||
MotionAnimcmdModule::set_sleep_effect(module_accessor,
|
||||
!((*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_TREAD_FALL).contains(&status_kind) ||
|
||||
(*FIGHTER_STATUS_KIND_WAIT..=*FIGHTER_STATUS_KIND_REBOUND_JUMP).contains(&status_kind)));
|
||||
MotionAnimcmdModule::set_sleep_effect(
|
||||
module_accessor,
|
||||
!((*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_TREAD_FALL)
|
||||
.contains(&status_kind)
|
||||
|| (*FIGHTER_STATUS_KIND_WAIT..=*FIGHTER_STATUS_KIND_REBOUND_JUMP)
|
||||
.contains(&status_kind)),
|
||||
);
|
||||
|
||||
if !(*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_CATCH_TURN).contains(&status_kind) {
|
||||
EffectModule::set_visible_kind(module_accessor, Hash40{hash: hash40("sys_shield")}, false);
|
||||
EffectModule::kill_kind(module_accessor, Hash40{hash: hash40("sys_shield")}, false, true);
|
||||
EffectModule::set_visible_kind(
|
||||
module_accessor,
|
||||
Hash40 {
|
||||
hash: hash40("sys_shield"),
|
||||
},
|
||||
false,
|
||||
);
|
||||
EffectModule::kill_kind(
|
||||
module_accessor,
|
||||
Hash40 {
|
||||
hash: hash40("sys_shield"),
|
||||
},
|
||||
false,
|
||||
true,
|
||||
);
|
||||
for i in 0..8 {
|
||||
if AttackModule::is_attack(module_accessor, i, false) {
|
||||
let attack_data = *AttackModule::attack_data(module_accessor, i, false);
|
||||
let is_capsule = attack_data.x2 != 0.0 || attack_data.y2 != 0.0 || attack_data.z2 != 0.0;
|
||||
let is_capsule =
|
||||
attack_data.x2 != 0.0 || attack_data.y2 != 0.0 || attack_data.z2 != 0.0;
|
||||
let mut x2 = None;
|
||||
let mut y2 = None;
|
||||
let mut z2 = None;
|
||||
|
@ -177,12 +271,17 @@ pub unsafe fn get_command_flag_cat(
|
|||
z2 = Some(attack_data.z2);
|
||||
}
|
||||
generate_hitbox_effects(
|
||||
module_accessor,
|
||||
attack_data.node, // joint
|
||||
attack_data.size,
|
||||
attack_data.x, attack_data.y, attack_data.z,
|
||||
x2, y2, z2,
|
||||
ID_COLORS[(i % 8) as usize]);
|
||||
module_accessor,
|
||||
attack_data.node, // joint
|
||||
attack_data.size,
|
||||
attack_data.x,
|
||||
attack_data.y,
|
||||
attack_data.z,
|
||||
x2,
|
||||
y2,
|
||||
z2,
|
||||
ID_COLORS[(i % 8) as usize],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,26 +294,31 @@ unsafe fn handle_catch(lua_state: u64) {
|
|||
let mut l2c_agent = L2CAgent::new(lua_state);
|
||||
|
||||
// get all necessary grabbox params
|
||||
let id = l2c_agent.pop_lua_stack(1); // int
|
||||
let joint = l2c_agent.pop_lua_stack(2); // hash40
|
||||
let size = l2c_agent.pop_lua_stack(3); // float
|
||||
let x = l2c_agent.pop_lua_stack(4); // float
|
||||
let y = l2c_agent.pop_lua_stack(5); // float
|
||||
let z = l2c_agent.pop_lua_stack(6); // float
|
||||
let x2 = l2c_agent.pop_lua_stack(7); // float or void
|
||||
let y2 = l2c_agent.pop_lua_stack(8); // float or void
|
||||
let z2 = l2c_agent.pop_lua_stack(9); // float or void
|
||||
let id = l2c_agent.pop_lua_stack(1); // int
|
||||
let joint = l2c_agent.pop_lua_stack(2); // hash40
|
||||
let size = l2c_agent.pop_lua_stack(3); // float
|
||||
let x = l2c_agent.pop_lua_stack(4); // float
|
||||
let y = l2c_agent.pop_lua_stack(5); // float
|
||||
let z = l2c_agent.pop_lua_stack(6); // float
|
||||
let x2 = l2c_agent.pop_lua_stack(7); // float or void
|
||||
let y2 = l2c_agent.pop_lua_stack(8); // float or void
|
||||
let z2 = l2c_agent.pop_lua_stack(9); // float or void
|
||||
|
||||
original!()(lua_state);
|
||||
|
||||
if (*menu).HITBOX_VIS && is_training_mode() {
|
||||
generate_hitbox_effects(
|
||||
sv_system::battle_object_module_accessor(lua_state),
|
||||
joint.get_int(),
|
||||
size.get_num(),
|
||||
x.get_num(), y.get_num(), z.get_num(),
|
||||
x2.try_get_num(), y2.try_get_num(), z2.try_get_num(),
|
||||
ID_COLORS[(id.get_int() + 3 % 8) as usize]);
|
||||
joint.get_int(),
|
||||
size.get_num(),
|
||||
x.get_num(),
|
||||
y.get_num(),
|
||||
z.get_num(),
|
||||
x2.try_get_num(),
|
||||
y2.try_get_num(),
|
||||
z2.try_get_num(),
|
||||
ID_COLORS[(id.get_int() + 3 % 8) as usize],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,12 +329,28 @@ pub unsafe fn is_shielding(module_accessor: *mut app::BattleObjectModuleAccessor
|
|||
|
||||
#[allow(unused_unsafe)]
|
||||
#[skyline::hook(replace = GrabModule::set_rebound)]
|
||||
pub unsafe fn handle_set_rebound(module_accessor: *mut app::BattleObjectModuleAccessor, rebound: bool) {
|
||||
pub unsafe fn handle_set_rebound(
|
||||
module_accessor: *mut app::BattleObjectModuleAccessor,
|
||||
rebound: bool,
|
||||
) {
|
||||
if is_training_mode() && rebound == false {
|
||||
// only if we're not shielding
|
||||
if !is_shielding(module_accessor) {
|
||||
EffectModule::set_visible_kind(module_accessor, Hash40{hash: hash40("sys_shield")}, false);
|
||||
EffectModule::kill_kind(module_accessor, Hash40{hash: hash40("sys_shield")}, false, true);
|
||||
EffectModule::set_visible_kind(
|
||||
module_accessor,
|
||||
Hash40 {
|
||||
hash: hash40("sys_shield"),
|
||||
},
|
||||
false,
|
||||
);
|
||||
EffectModule::kill_kind(
|
||||
module_accessor,
|
||||
Hash40 {
|
||||
hash: hash40("sys_shield"),
|
||||
},
|
||||
false,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
50
src/lib.rs
50
src/lib.rs
|
@ -5,21 +5,21 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
#![feature(with_options)]
|
||||
|
||||
mod common;
|
||||
mod hitbox_visualizer;
|
||||
mod training;
|
||||
mod common;
|
||||
|
||||
use crate::common::*;
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
|
||||
use smash::lib::lua_const::{*};
|
||||
use smash::lib::L2CValue;
|
||||
use smash::app::lua_bind::{*};
|
||||
use smash::app::sv_system::{self};
|
||||
use smash::lua2cpp::L2CFighterCommon;
|
||||
use skyline::libc::{c_void, fopen, fwrite, fclose};
|
||||
use skyline::{c_str};
|
||||
use skyline::c_str;
|
||||
use skyline::libc::{c_void, fclose, fopen, fwrite};
|
||||
use skyline::nro::{self, NroInfo};
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::sv_system::{self};
|
||||
use smash::lib::lua_const::*;
|
||||
use smash::lib::L2CValue;
|
||||
use smash::lua2cpp::L2CFighterCommon;
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
#[skyline::hook(replace = smash::lua2cpp::L2CFighterCommon_sub_guard_cont)]
|
||||
|
@ -27,9 +27,19 @@ pub unsafe fn handle_sub_guard_cont(fighter: &mut L2CFighterCommon) -> L2CValue
|
|||
let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent);
|
||||
if (*menu).MASH_STATE == MASH_ATTACK && (*menu).ATTACK_STATE == MASH_GRAB {
|
||||
if StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE {
|
||||
if WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_INVALID_CATCH_FRAME) == 0 {
|
||||
if WorkModule::is_enable_transition_term(module_accessor, *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CATCH) {
|
||||
fighter.fighter_base.change_status(L2CValue::new_int(*FIGHTER_STATUS_KIND_CATCH as u64), L2CValue::new_bool(true));
|
||||
if WorkModule::get_int(
|
||||
module_accessor,
|
||||
*FIGHTER_INSTANCE_WORK_ID_INT_INVALID_CATCH_FRAME,
|
||||
) == 0
|
||||
{
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CATCH,
|
||||
) {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_CATCH as u64),
|
||||
L2CValue::new_bool(true),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +49,11 @@ pub unsafe fn handle_sub_guard_cont(fighter: &mut L2CFighterCommon) -> L2CValue
|
|||
|
||||
fn nro_main(nro: &NroInfo) {
|
||||
match nro.name {
|
||||
"common" =>
|
||||
{
|
||||
println!("Loaded common NRO!");
|
||||
skyline::install_hook!(handle_sub_guard_cont);
|
||||
},
|
||||
_ => ()
|
||||
"common" => {
|
||||
println!("Loaded common NRO!");
|
||||
skyline::install_hook!(handle_sub_guard_cont);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +68,10 @@ pub fn main() {
|
|||
common::menu = &mut common::menu_struct;
|
||||
let buffer = format!("{:x}", common::menu as u64);
|
||||
println!("Writing training_modpack.log with {}...\n", buffer);
|
||||
let f = fopen("sd:/SaltySD/training_modpack.log\u{0}".as_bytes().as_ptr(), "w\u{0}".as_bytes().as_ptr());
|
||||
let f = fopen(
|
||||
"sd:/SaltySD/training_modpack.log\u{0}".as_bytes().as_ptr(),
|
||||
"w\u{0}".as_bytes().as_ptr(),
|
||||
);
|
||||
|
||||
println!("File pointer: {:#?}", f);
|
||||
if !f.is_null() {
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
use smash::hash40;
|
||||
use smash::app::{self};
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::lib::lua_const::*;
|
||||
use crate::common::*;
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use core::f64::consts::PI;
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::{self};
|
||||
use smash::hash40;
|
||||
use smash::lib::lua_const::*;
|
||||
|
||||
|
||||
pub unsafe fn get_float(module_accessor: &mut app::BattleObjectModuleAccessor, var: i32) -> Option<f32> {
|
||||
if var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X ||
|
||||
var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y {
|
||||
if is_training_mode() &&
|
||||
is_operation_cpu(module_accessor) &&
|
||||
is_in_hitstun(module_accessor) {
|
||||
pub unsafe fn get_float(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
var: i32,
|
||||
) -> Option<f32> {
|
||||
if var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X
|
||||
|| var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y
|
||||
{
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) && is_in_hitstun(module_accessor)
|
||||
{
|
||||
if (*menu).DI_STATE != NONE {
|
||||
let mut angle = ((*menu).DI_STATE - 1) as f64 * PI / 4.0;
|
||||
|
||||
|
@ -26,15 +28,15 @@ pub unsafe fn get_float(module_accessor: &mut app::BattleObjectModuleAccessor, v
|
|||
}
|
||||
|
||||
if var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X {
|
||||
return Some(angle.cos() as f32)
|
||||
return Some(angle.cos() as f32);
|
||||
}
|
||||
|
||||
if var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y {
|
||||
return Some(angle.sin() as f32)
|
||||
return Some(angle.sin() as f32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
use smash::hash40;
|
||||
use smash::app::{self};
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::lib::lua_const::*;
|
||||
use crate::common::*;
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::{self};
|
||||
use smash::hash40;
|
||||
use smash::lib::lua_const::*;
|
||||
|
||||
pub unsafe fn force_option(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor)
|
||||
{
|
||||
pub unsafe fn force_option(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
if StatusModule::status_kind(module_accessor) as i32 == *FIGHTER_STATUS_KIND_CLIFF_WAIT {
|
||||
if WorkModule::is_enable_transition_term(module_accessor, *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB) {
|
||||
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB,
|
||||
) {
|
||||
let random_frame = app::sv_math::rand(
|
||||
hash40("fighter"),
|
||||
MotionModule::end_frame(module_accessor) as i32) as f32;
|
||||
hash40("fighter"),
|
||||
MotionModule::end_frame(module_accessor) as i32,
|
||||
) as f32;
|
||||
|
||||
let frame = MotionModule::frame(module_accessor) as f32;
|
||||
|
||||
if frame == random_frame || frame > 30.0 {
|
||||
let mut status = 0;
|
||||
let ledge_case : i32;
|
||||
let ledge_case: i32;
|
||||
|
||||
if (*menu).LEDGE_STATE == RANDOM_LEDGE {
|
||||
ledge_case = app::sv_math::rand(hash40("fighter"), 4) + 2;
|
||||
|
@ -32,7 +32,7 @@ pub unsafe fn force_option(
|
|||
ROLL_LEDGE => status = *FIGHTER_STATUS_KIND_CLIFF_ESCAPE,
|
||||
JUMP_LEDGE => status = *FIGHTER_STATUS_KIND_CLIFF_JUMP1,
|
||||
ATTACK_LEDGE => status = *FIGHTER_STATUS_KIND_CLIFF_ATTACK,
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
|
||||
StatusModule::change_status_request_from_script(module_accessor, status, true);
|
||||
|
@ -44,31 +44,35 @@ pub unsafe fn force_option(
|
|||
pub unsafe fn should_perform_defensive_option(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
prev_status: i32,
|
||||
status: i32) -> bool
|
||||
{
|
||||
([*FIGHTER_STATUS_KIND_CLIFF_CLIMB,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_ATTACK,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_ESCAPE]
|
||||
.iter()
|
||||
.any(|i| i == &status || i == &prev_status)
|
||||
)
|
||||
&&
|
||||
(
|
||||
WorkModule::is_enable_transition_term(module_accessor, *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE) ||
|
||||
CancelModule::is_enable_cancel(module_accessor)
|
||||
)
|
||||
status: i32,
|
||||
) -> bool {
|
||||
([
|
||||
*FIGHTER_STATUS_KIND_CLIFF_CLIMB,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_ATTACK,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_ESCAPE,
|
||||
]
|
||||
.iter()
|
||||
.any(|i| i == &status || i == &prev_status))
|
||||
&& (WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE,
|
||||
) || CancelModule::is_enable_cancel(module_accessor))
|
||||
}
|
||||
|
||||
pub unsafe fn defensive_option(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32,
|
||||
flag: &mut i32)
|
||||
{
|
||||
flag: &mut i32,
|
||||
) {
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
if [*FIGHTER_STATUS_KIND_CLIFF_JUMP3,
|
||||
if [
|
||||
*FIGHTER_STATUS_KIND_CLIFF_JUMP3,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_JUMP2,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_JUMP1].contains(&status) {
|
||||
*FIGHTER_STATUS_KIND_CLIFF_JUMP1,
|
||||
]
|
||||
.contains(&status)
|
||||
{
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
|
||||
}
|
||||
|
||||
|
@ -79,16 +83,16 @@ pub unsafe fn defensive_option(
|
|||
|
||||
pub unsafe fn check_button_on(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
button: i32) -> Option<bool>
|
||||
{
|
||||
button: i32,
|
||||
) -> Option<bool> {
|
||||
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
if (*menu).DEFENSIVE_STATE == DEFENSIVE_SHIELD &&
|
||||
should_perform_defensive_option(
|
||||
module_accessor, prev_status, status) {
|
||||
return Some(true)
|
||||
if (*menu).DEFENSIVE_STATE == DEFENSIVE_SHIELD
|
||||
&& should_perform_defensive_option(module_accessor, prev_status, status)
|
||||
{
|
||||
return Some(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,10 +103,10 @@ pub unsafe fn check_button_on(
|
|||
pub unsafe fn get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32,
|
||||
flag: &mut i32)
|
||||
{
|
||||
flag: &mut i32,
|
||||
) {
|
||||
if (*menu).LEDGE_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
force_option(module_accessor);
|
||||
defensive_option(module_accessor, category, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use smash::hash40;
|
||||
use smash::app::{self};
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::lib::lua_const::*;
|
||||
use crate::common::*;
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::{self};
|
||||
use smash::hash40;
|
||||
use smash::lib::lua_const::*;
|
||||
|
||||
pub unsafe fn get_attack_air_kind(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor) -> Option<i32>
|
||||
{
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) -> Option<i32> {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if (*menu).MASH_STATE == MASH_ATTACK {
|
||||
match (*menu).ATTACK_STATE {
|
||||
|
@ -16,7 +16,7 @@ pub unsafe fn get_attack_air_kind(
|
|||
MASH_BAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_B),
|
||||
MASH_UPAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_HI),
|
||||
MASH_DAIR => return Some(*FIGHTER_COMMAND_ATTACK_AIR_KIND_LW),
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,52 +31,54 @@ pub unsafe fn get_attack_air_kind(
|
|||
pub unsafe fn get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32,
|
||||
flag: &mut i32)
|
||||
{
|
||||
flag: &mut i32,
|
||||
) {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if is_in_hitstun(module_accessor) || is_in_landing(module_accessor) || is_in_shieldstun(module_accessor) {
|
||||
if is_in_hitstun(module_accessor)
|
||||
|| is_in_landing(module_accessor)
|
||||
|| is_in_shieldstun(module_accessor)
|
||||
{
|
||||
match (*menu).MASH_STATE {
|
||||
MASH_AIRDODGE => {
|
||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
|
||||
}
|
||||
},
|
||||
MASH_JUMP => {
|
||||
if !is_in_landing(module_accessor) && category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
}
|
||||
MASH_JUMP => {
|
||||
if !is_in_landing(module_accessor) && category == FIGHTER_PAD_COMMAND_CATEGORY1
|
||||
{
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;
|
||||
}
|
||||
},
|
||||
}
|
||||
MASH_SPOTDODGE => {
|
||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE;
|
||||
}
|
||||
},
|
||||
}
|
||||
MASH_ATTACK => {
|
||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
match (*menu).ATTACK_STATE {
|
||||
MASH_NAIR |
|
||||
MASH_FAIR |
|
||||
MASH_BAIR |
|
||||
MASH_UPAIR |
|
||||
MASH_DAIR => {
|
||||
MASH_NAIR | MASH_FAIR | MASH_BAIR | MASH_UPAIR | MASH_DAIR => {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N;
|
||||
// If we are performing the attack OOS we also need to jump
|
||||
if is_in_shieldstun(module_accessor) {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;
|
||||
}
|
||||
},
|
||||
}
|
||||
MASH_NEUTRAL_B => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
|
||||
MASH_SIDE_B => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
MASH_UP_B => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
MASH_DOWN_B => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
MASH_UP_SMASH => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4,
|
||||
MASH_GRAB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH,
|
||||
_ => ()
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
} else if category == 1 {
|
||||
if (*menu).ATTACK_STATE == MASH_GRAB { *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH; }
|
||||
if (*menu).ATTACK_STATE == MASH_GRAB {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
MASH_RANDOM => {
|
||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
let situation_kind = StatusModule::situation_kind(module_accessor) as i32;
|
||||
|
@ -97,8 +99,9 @@ pub unsafe fn get_command_flag_cat(
|
|||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
];
|
||||
|
||||
let random_cmd_index = app::sv_math::rand(
|
||||
hash40("fighter"), random_commands.len() as i32) as usize;
|
||||
let random_cmd_index =
|
||||
app::sv_math::rand(hash40("fighter"), random_commands.len() as i32)
|
||||
as usize;
|
||||
|
||||
*flag |= random_commands[random_cmd_index];
|
||||
} else if situation_kind == SITUATION_KIND_GROUND {
|
||||
|
@ -121,14 +124,15 @@ pub unsafe fn get_command_flag_cat(
|
|||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
|
||||
];
|
||||
|
||||
let random_cmd_index = app::sv_math::rand(
|
||||
hash40("fighter"), random_commands.len() as i32) as usize;
|
||||
let random_cmd_index =
|
||||
app::sv_math::rand(hash40("fighter"), random_commands.len() as i32)
|
||||
as usize;
|
||||
|
||||
*flag |= random_commands[random_cmd_index];
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,23 +140,28 @@ pub unsafe fn get_command_flag_cat(
|
|||
|
||||
pub unsafe fn check_button_on(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
button: i32) -> Option<bool>
|
||||
{
|
||||
button: i32,
|
||||
) -> Option<bool> {
|
||||
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if (*menu).MASH_STATE == MASH_AIRDODGE && (is_in_hitstun(module_accessor) || is_in_landing(module_accessor)) {
|
||||
return Some(true)
|
||||
if (*menu).MASH_STATE == MASH_AIRDODGE
|
||||
&& (is_in_hitstun(module_accessor) || is_in_landing(module_accessor))
|
||||
{
|
||||
return Some(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if [*CONTROL_PAD_BUTTON_ATTACK, *CONTROL_PAD_BUTTON_CATCH].contains(&button) {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if (*menu).MASH_STATE == MASH_ATTACK && (*menu).ATTACK_STATE == MASH_GRAB && is_in_shieldstun(module_accessor) {
|
||||
return Some(true)
|
||||
if (*menu).MASH_STATE == MASH_ATTACK
|
||||
&& (*menu).ATTACK_STATE == MASH_GRAB
|
||||
&& is_in_shieldstun(module_accessor)
|
||||
{
|
||||
return Some(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use smash::{phx::Vector3f};
|
||||
use smash::app::{self};
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::lib::lua_const::*;
|
||||
use crate::common::*;
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::{self};
|
||||
use smash::lib::lua_const::*;
|
||||
use smash::phx::Vector3f;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum SaveState {
|
||||
|
@ -14,31 +14,31 @@ enum SaveState {
|
|||
|
||||
use crate::training::SaveStates::SaveState::*;
|
||||
|
||||
static mut save_state_player_state : SaveState = NoAction;
|
||||
static mut save_state_cpu_state : SaveState = NoAction;
|
||||
static mut save_state_move_alert : bool = false;
|
||||
static mut save_state_player_state: SaveState = NoAction;
|
||||
static mut save_state_cpu_state: SaveState = NoAction;
|
||||
static mut save_state_move_alert: bool = false;
|
||||
|
||||
static mut save_state_x_player : f32 = 0.0;
|
||||
static mut save_state_y_player : f32 = 0.0;
|
||||
static mut save_state_percent_player : f32 = 0.0;
|
||||
static mut save_state_lr_player : f32 = 1.0;
|
||||
static mut save_state_situation_kind_player : i32 = 0 as i32;
|
||||
static mut save_state_x_player: f32 = 0.0;
|
||||
static mut save_state_y_player: f32 = 0.0;
|
||||
static mut save_state_percent_player: f32 = 0.0;
|
||||
static mut save_state_lr_player: f32 = 1.0;
|
||||
static mut save_state_situation_kind_player: i32 = 0 as i32;
|
||||
|
||||
static mut save_state_x_cpu : f32 = 0.0;
|
||||
static mut save_state_y_cpu : f32 = 0.0;
|
||||
static mut save_state_percent_cpu : f32 = 0.0;
|
||||
static mut save_state_lr_cpu : f32 = 1.0;
|
||||
static mut save_state_situation_kind_cpu : i32 = 0 as i32;
|
||||
static mut save_state_x_cpu: f32 = 0.0;
|
||||
static mut save_state_y_cpu: f32 = 0.0;
|
||||
static mut save_state_percent_cpu: f32 = 0.0;
|
||||
static mut save_state_lr_cpu: f32 = 1.0;
|
||||
static mut save_state_situation_kind_cpu: i32 = 0 as i32;
|
||||
|
||||
pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
if is_training_mode() {
|
||||
let save_state_x : *mut f32;
|
||||
let save_state_y : *mut f32;
|
||||
let save_state_percent : *mut f32;
|
||||
let save_state_lr : *mut f32;
|
||||
let save_state_situation_kind : *mut i32;
|
||||
let save_state : *mut SaveState;
|
||||
let save_state_x: *mut f32;
|
||||
let save_state_y: *mut f32;
|
||||
let save_state_percent: *mut f32;
|
||||
let save_state_lr: *mut f32;
|
||||
let save_state_situation_kind: *mut i32;
|
||||
let save_state: *mut SaveState;
|
||||
if is_operation_cpu(module_accessor) {
|
||||
save_state_x = &mut save_state_x_cpu;
|
||||
save_state_y = &mut save_state_y_cpu;
|
||||
|
@ -56,8 +56,10 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
}
|
||||
|
||||
// Grab + Dpad up: reset state
|
||||
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH) != 0 &&
|
||||
ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI) != 0 {
|
||||
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH) != 0
|
||||
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI)
|
||||
!= 0
|
||||
{
|
||||
if *save_state == NoAction {
|
||||
save_state_player_state = CameraMove;
|
||||
save_state_cpu_state = CameraMove;
|
||||
|
@ -68,44 +70,76 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
if *save_state == CameraMove {
|
||||
*save_state = PosMove;
|
||||
|
||||
let left_right = (*save_state_x > 0.0) as i32 as f32 - (*save_state_x < 0.0) as i32 as f32;
|
||||
let left_right =
|
||||
(*save_state_x > 0.0) as i32 as f32 - (*save_state_x < 0.0) as i32 as f32;
|
||||
let mut y_pos = 0.0;
|
||||
if *save_state_situation_kind == SITUATION_KIND_GROUND {
|
||||
y_pos = -50.0;
|
||||
}
|
||||
|
||||
let pos = Vector3f{x : left_right * 50.0, y : y_pos, z : 0.0};
|
||||
let pos = Vector3f {
|
||||
x: left_right * 50.0,
|
||||
y: y_pos,
|
||||
z: 0.0,
|
||||
};
|
||||
PostureModule::set_pos(module_accessor, &pos);
|
||||
StatusModule::set_situation_kind(module_accessor, app::SituationKind{situation_kind: *SITUATION_KIND_AIR}, false);
|
||||
StatusModule::set_situation_kind(
|
||||
module_accessor,
|
||||
app::SituationKind {
|
||||
situation_kind: *SITUATION_KIND_AIR,
|
||||
},
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
// move to correct pos
|
||||
if *save_state == PosMove {
|
||||
let pos = Vector3f{x : *save_state_x, y : *save_state_y, z : 0.0};
|
||||
let pos = Vector3f {
|
||||
x: *save_state_x,
|
||||
y: *save_state_y,
|
||||
z: 0.0,
|
||||
};
|
||||
PostureModule::set_pos(module_accessor, &pos);
|
||||
PostureModule::set_lr(module_accessor, *save_state_lr);
|
||||
DamageModule::heal(module_accessor, -1.0 * DamageModule::damage(module_accessor, 0), 0);
|
||||
DamageModule::heal(
|
||||
module_accessor,
|
||||
-1.0 * DamageModule::damage(module_accessor, 0),
|
||||
0,
|
||||
);
|
||||
DamageModule::add_damage(module_accessor, *save_state_percent, 0);
|
||||
|
||||
StatusModule::set_situation_kind(module_accessor, app::SituationKind{situation_kind: *save_state_situation_kind}, false);
|
||||
StatusModule::set_situation_kind(
|
||||
module_accessor,
|
||||
app::SituationKind {
|
||||
situation_kind: *save_state_situation_kind,
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
// Doesn't work, and I don't know why yet.
|
||||
// if *save_state_situation_kind == SITUATION_KIND_GROUND && status != FIGHTER_STATUS_KIND_WAIT {
|
||||
// StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_WAIT, false);
|
||||
// StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_WAIT, false);
|
||||
// }
|
||||
// else if (*save_state_situation_kind == SITUATION_KIND_AIR && status != FIGHTER_STATUS_KIND_FALL)
|
||||
// StatusModule::change_status_request(module_accessor, FIGHTER_STATUS_KIND_FALL, 0);
|
||||
if *save_state_situation_kind == SITUATION_KIND_CLIFF && status != FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE
|
||||
&& status != FIGHTER_STATUS_KIND_CLIFF_CATCH {
|
||||
StatusModule::change_status_request(module_accessor, *FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE, false);
|
||||
// StatusModule::change_status_request(module_accessor, FIGHTER_STATUS_KIND_FALL, 0);
|
||||
if *save_state_situation_kind == SITUATION_KIND_CLIFF
|
||||
&& status != FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE
|
||||
&& status != FIGHTER_STATUS_KIND_CLIFF_CATCH
|
||||
{
|
||||
StatusModule::change_status_request(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_CATCH_MOVE,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
*save_state = NoAction;
|
||||
}
|
||||
|
||||
// Grab + Dpad down: Save state
|
||||
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH) != 0 &&
|
||||
ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_LW) != 0 {
|
||||
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH) != 0
|
||||
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_LW)
|
||||
!= 0
|
||||
{
|
||||
save_state_player_state = Save;
|
||||
save_state_cpu_state = Save;
|
||||
}
|
||||
|
@ -120,4 +154,4 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor)
|
|||
*save_state_situation_kind = StatusModule::situation_kind(module_accessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
|
||||
use smash::hash40;
|
||||
use smash::app::{self};
|
||||
use smash::lib::lua_const::*;
|
||||
use crate::common::*;
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use smash::app::{self};
|
||||
use smash::hash40;
|
||||
use smash::lib::lua_const::*;
|
||||
|
||||
pub unsafe fn get_param_float(module_accessor: &mut app::BattleObjectModuleAccessor, param_type: u64, param_hash: u64) -> Option<f32> {
|
||||
pub unsafe fn get_param_float(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
param_type: u64,
|
||||
param_hash: u64,
|
||||
) -> Option<f32> {
|
||||
if is_training_mode() {
|
||||
if (*menu).SHIELD_STATE == SHIELD_INFINITE {
|
||||
if param_type == hash40("common") {
|
||||
if param_hash == hash40("shield_dec1") {
|
||||
return Some(0.0)
|
||||
return Some(0.0);
|
||||
}
|
||||
if param_hash == hash40("shield_recovery1") {
|
||||
return Some(999.0)
|
||||
return Some(999.0);
|
||||
}
|
||||
// doesn't work, somehow. This parameter isn't checked?
|
||||
if param_hash == hash40("shield_damage_mul") {
|
||||
return Some(0.0)
|
||||
return Some(0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,17 +34,17 @@ pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAc
|
|||
if [SHIELD_HOLD, SHIELD_INFINITE].contains(&(*menu).SHIELD_STATE) {
|
||||
// If we are not mashing then we will always hold shield
|
||||
if (*menu).MASH_STATE == NONE {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
if !is_in_shieldstun(module_accessor) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
// We will only drop shield if we are in shieldstun and our attack can be performed OOS
|
||||
if (*menu).MASH_STATE == MASH_ATTACK {
|
||||
if [MASH_NEUTRAL_B, MASH_SIDE_B, MASH_DOWN_B].contains(&(*menu).ATTACK_STATE) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,11 +52,14 @@ pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAc
|
|||
false
|
||||
}
|
||||
|
||||
pub unsafe fn check_button_on(module_accessor: &mut app::BattleObjectModuleAccessor, button: i32) -> Option<bool> {
|
||||
pub unsafe fn check_button_on(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
button: i32,
|
||||
) -> Option<bool> {
|
||||
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if should_hold_shield(module_accessor) {
|
||||
return Some(true)
|
||||
return Some(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,14 +67,17 @@ pub unsafe fn check_button_on(module_accessor: &mut app::BattleObjectModuleAcces
|
|||
None
|
||||
}
|
||||
|
||||
pub unsafe fn check_button_off(module_accessor: &mut app::BattleObjectModuleAccessor, button: i32) -> Option<bool> {
|
||||
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
pub unsafe fn check_button_off(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
button: i32,
|
||||
) -> Option<bool> {
|
||||
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if should_hold_shield(module_accessor) {
|
||||
return Some(false)
|
||||
return Some(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use smash::hash40;
|
||||
use smash::app::{self};
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::lib::lua_const::*;
|
||||
use crate::common::*;
|
||||
use crate::common::consts::*;
|
||||
use crate::common::*;
|
||||
use smash::app::lua_bind::*;
|
||||
use smash::app::{self};
|
||||
use smash::hash40;
|
||||
use smash::lib::lua_const::*;
|
||||
|
||||
pub unsafe fn init_settings(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
status_kind: i32) -> Option<()>
|
||||
{
|
||||
status_kind: i32,
|
||||
) -> Option<()> {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if status_kind == FIGHTER_STATUS_KIND_DOWN {
|
||||
match (*menu).TECH_STATE {
|
||||
|
@ -16,33 +16,38 @@ pub unsafe fn init_settings(
|
|||
let random_statuses = vec![
|
||||
*FIGHTER_STATUS_KIND_DOWN,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE_FB
|
||||
*FIGHTER_STATUS_KIND_PASSIVE_FB,
|
||||
];
|
||||
|
||||
let random_status_index = app::sv_math::rand(hash40("fighter"), random_statuses.len() as i32) as usize;
|
||||
let random_status_index =
|
||||
app::sv_math::rand(hash40("fighter"), random_statuses.len() as i32)
|
||||
as usize;
|
||||
if random_statuses[random_status_index] != FIGHTER_STATUS_KIND_DOWN {
|
||||
StatusModule::change_status_request_from_script(
|
||||
module_accessor,
|
||||
random_statuses[random_status_index],
|
||||
true);
|
||||
return Some(())
|
||||
module_accessor,
|
||||
random_statuses[random_status_index],
|
||||
true,
|
||||
);
|
||||
return Some(());
|
||||
}
|
||||
},
|
||||
}
|
||||
TECH_IN_PLACE => {
|
||||
StatusModule::change_status_request_from_script(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE,
|
||||
true);
|
||||
return Some(())
|
||||
},
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE,
|
||||
true,
|
||||
);
|
||||
return Some(());
|
||||
}
|
||||
TECH_ROLL => {
|
||||
StatusModule::change_status_request_from_script(
|
||||
module_accessor,
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE_FB,
|
||||
true);
|
||||
return Some(())
|
||||
},
|
||||
_ => ()
|
||||
true,
|
||||
);
|
||||
return Some(());
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,46 +56,61 @@ pub unsafe fn init_settings(
|
|||
}
|
||||
|
||||
pub unsafe fn should_perform_defensive_option(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
prev_status: i32,
|
||||
status: i32) -> bool
|
||||
{
|
||||
(
|
||||
[*FIGHTER_STATUS_KIND_PASSIVE,
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
prev_status: i32,
|
||||
status: i32,
|
||||
) -> bool {
|
||||
([
|
||||
*FIGHTER_STATUS_KIND_PASSIVE,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE_FB,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_FB,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK].contains(&prev_status) ||
|
||||
|
||||
[*FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_FB,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK].contains(&status)
|
||||
)
|
||||
&&
|
||||
(
|
||||
WorkModule::is_enable_transition_term(module_accessor, *FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_GUARD_ON)
|
||||
// ||
|
||||
// CancelModule::is_enable_cancel(module_accessor)
|
||||
)
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK,
|
||||
]
|
||||
.contains(&prev_status)
|
||||
|| [
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_FB,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK,
|
||||
]
|
||||
.contains(&status))
|
||||
&& (
|
||||
WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_GUARD_ON,
|
||||
)
|
||||
// ||
|
||||
// CancelModule::is_enable_cancel(module_accessor)
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32,
|
||||
flag: &mut i32)
|
||||
{
|
||||
flag: &mut i32,
|
||||
) {
|
||||
if (*menu).TECH_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
if [*FIGHTER_STATUS_KIND_DOWN_WAIT, *FIGHTER_STATUS_KIND_DOWN_WAIT_CONTINUE].contains(&status) {
|
||||
if [
|
||||
*FIGHTER_STATUS_KIND_DOWN_WAIT,
|
||||
*FIGHTER_STATUS_KIND_DOWN_WAIT_CONTINUE,
|
||||
]
|
||||
.contains(&status)
|
||||
{
|
||||
let random_statuses = vec![
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_FB,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK,
|
||||
];
|
||||
|
||||
let random_status_index = app::sv_math::rand(hash40("fighter"), random_statuses.len() as i32) as usize;
|
||||
StatusModule::change_status_request_from_script(module_accessor, random_statuses[random_status_index], true);
|
||||
let random_status_index =
|
||||
app::sv_math::rand(hash40("fighter"), random_statuses.len() as i32) as usize;
|
||||
StatusModule::change_status_request_from_script(
|
||||
module_accessor,
|
||||
random_statuses[random_status_index],
|
||||
true,
|
||||
);
|
||||
} else if should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||
perform_defensive_option(module_accessor, flag);
|
||||
}
|
||||
|
@ -99,15 +119,16 @@ pub unsafe fn get_command_flag_cat(
|
|||
|
||||
pub unsafe fn check_button_on(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
button: i32) -> Option<bool>
|
||||
{
|
||||
button: i32,
|
||||
) -> Option<bool> {
|
||||
if [*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
if (*menu).DEFENSIVE_STATE == DEFENSIVE_SHIELD &&
|
||||
should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||
return Some(true)
|
||||
if (*menu).DEFENSIVE_STATE == DEFENSIVE_SHIELD
|
||||
&& should_perform_defensive_option(module_accessor, prev_status, status)
|
||||
{
|
||||
return Some(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,29 +138,29 @@ pub unsafe fn check_button_on(
|
|||
|
||||
pub unsafe fn change_motion(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
motion_kind: u64) -> Option<u64>
|
||||
{
|
||||
motion_kind: u64,
|
||||
) -> Option<u64> {
|
||||
if (*menu).TECH_STATE != NONE && is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if [hash40("passive_stand_f"), hash40("passive_stand_b")].contains(&motion_kind) {
|
||||
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
|
||||
return Some(hash40("passive_stand_f"))
|
||||
} else {
|
||||
return Some(hash40("passive_stand_b"))
|
||||
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
|
||||
return Some(hash40("passive_stand_f"));
|
||||
} else {
|
||||
return Some(hash40("passive_stand_b"));
|
||||
}
|
||||
} else if [hash40("down_forward_u"), hash40("down_back_u")].contains(&motion_kind) {
|
||||
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
|
||||
return Some(hash40("down_forward_u"))
|
||||
} else {
|
||||
return Some(hash40("down_back_u"))
|
||||
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
|
||||
return Some(hash40("down_forward_u"));
|
||||
} else {
|
||||
return Some(hash40("down_back_u"));
|
||||
}
|
||||
} else if [hash40("down_forward_d"), hash40("down_back_d")].contains(&motion_kind) {
|
||||
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
|
||||
return Some(hash40("down_forward_d"))
|
||||
} else {
|
||||
return Some(hash40("down_back_d"))
|
||||
if app::sv_math::rand(hash40("fighter"), 2) != 0 {
|
||||
return Some(hash40("down_forward_d"));
|
||||
} else {
|
||||
return Some(hash40("down_back_d"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,52 +1,57 @@
|
|||
use smash::app::{self, sv_animcmd, lua_bind::*};
|
||||
use smash::lib::{L2CAgent, L2CValue};
|
||||
use skyline::{c_str, nn::ro::LookupSymbol};
|
||||
use crate::common::consts::*;
|
||||
use crate::common::fighter_manager_addr;
|
||||
use crate::common::*;
|
||||
use crate::common::consts::*;
|
||||
use crate::hitbox_visualizer;
|
||||
use skyline::{c_str, nn::ro::LookupSymbol};
|
||||
use smash::app::{self, lua_bind::*, sv_animcmd};
|
||||
use smash::lib::{L2CAgent, L2CValue};
|
||||
|
||||
mod DirectionalInfluence;
|
||||
mod Ledge;
|
||||
mod Mash;
|
||||
mod SaveStates;
|
||||
mod Shield;
|
||||
mod Tech;
|
||||
mod Mash;
|
||||
mod Ledge;
|
||||
mod SaveStates;
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
#[skyline::hook(replace = WorkModule::get_float)]
|
||||
pub unsafe fn handle_get_float(module_accessor: &mut app::BattleObjectModuleAccessor, var: i32) -> f32 {
|
||||
DirectionalInfluence::get_float(module_accessor, var).unwrap_or_else( || {
|
||||
original!()(module_accessor, var)
|
||||
})
|
||||
pub unsafe fn handle_get_float(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
var: i32,
|
||||
) -> f32 {
|
||||
DirectionalInfluence::get_float(module_accessor, var)
|
||||
.unwrap_or_else(|| original!()(module_accessor, var))
|
||||
}
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
#[skyline::hook(replace = WorkModule::get_param_float)]
|
||||
pub unsafe fn handle_get_param_float(module_accessor: &mut app::BattleObjectModuleAccessor, param_type: u64, param_hash: u64) -> f32 {
|
||||
Shield::get_param_float(module_accessor, param_type, param_hash).unwrap_or_else( || {
|
||||
original!()(module_accessor, param_type, param_hash)
|
||||
})
|
||||
pub unsafe fn handle_get_param_float(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
param_type: u64,
|
||||
param_hash: u64,
|
||||
) -> f32 {
|
||||
Shield::get_param_float(module_accessor, param_type, param_hash)
|
||||
.unwrap_or_else(|| original!()(module_accessor, param_type, param_hash))
|
||||
}
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
#[skyline::hook(replace = ControlModule::get_attack_air_kind)]
|
||||
pub unsafe fn handle_get_attack_air_kind(module_accessor: &mut app::BattleObjectModuleAccessor) -> i32 {
|
||||
pub unsafe fn handle_get_attack_air_kind(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) -> i32 {
|
||||
// bool replace;
|
||||
// int kind = InputRecorder::get_attack_air_kind(module_accessor, replace);
|
||||
// if (replace) return kind;
|
||||
|
||||
Mash::get_attack_air_kind(module_accessor).unwrap_or_else( || {
|
||||
original!()(module_accessor)
|
||||
})
|
||||
Mash::get_attack_air_kind(module_accessor).unwrap_or_else(|| original!()(module_accessor))
|
||||
}
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
#[skyline::hook(replace = ControlModule::get_command_flag_cat)]
|
||||
pub unsafe fn handle_get_command_flag_cat(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32) -> i32
|
||||
{
|
||||
category: i32,
|
||||
) -> i32 {
|
||||
SaveStates::save_states(module_accessor);
|
||||
|
||||
let mut flag = original!()(module_accessor, category);
|
||||
|
@ -103,14 +108,13 @@ pub unsafe fn handle_get_command_flag_cat(
|
|||
#[skyline::hook(replace = ControlModule::check_button_on)]
|
||||
pub unsafe fn handle_check_button_on(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
button: i32) -> bool
|
||||
{
|
||||
Shield::check_button_on(module_accessor, button).unwrap_or_else( || {
|
||||
Mash::check_button_on(module_accessor, button).unwrap_or_else( || {
|
||||
Tech::check_button_on(module_accessor, button).unwrap_or_else( || {
|
||||
Ledge::check_button_on(module_accessor, button).unwrap_or_else( || {
|
||||
original!()(module_accessor, button)
|
||||
})
|
||||
button: i32,
|
||||
) -> bool {
|
||||
Shield::check_button_on(module_accessor, button).unwrap_or_else(|| {
|
||||
Mash::check_button_on(module_accessor, button).unwrap_or_else(|| {
|
||||
Tech::check_button_on(module_accessor, button).unwrap_or_else(|| {
|
||||
Ledge::check_button_on(module_accessor, button)
|
||||
.unwrap_or_else(|| original!()(module_accessor, button))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -120,30 +124,40 @@ pub unsafe fn handle_check_button_on(
|
|||
#[skyline::hook(replace = ControlModule::check_button_off)]
|
||||
pub unsafe fn handle_check_button_off(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
button: i32) -> bool
|
||||
{
|
||||
Shield::check_button_off(module_accessor, button).unwrap_or_else( || {
|
||||
original!()(module_accessor, button)
|
||||
})
|
||||
button: i32,
|
||||
) -> bool {
|
||||
Shield::check_button_off(module_accessor, button)
|
||||
.unwrap_or_else(|| original!()(module_accessor, button))
|
||||
}
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
#[skyline::hook(replace = StatusModule::init_settings)]
|
||||
pub unsafe fn handle_init_settings(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
situationKind: i32,
|
||||
unk1: i32,
|
||||
unk2: u32,
|
||||
situationKind: i32,
|
||||
unk1: i32,
|
||||
unk2: u32,
|
||||
groundCliffCheckKind: i32,
|
||||
unk3: bool,
|
||||
unk4: i32,
|
||||
unk5: i32,
|
||||
unk6: i32,
|
||||
unk7: i32)
|
||||
{
|
||||
unk3: bool,
|
||||
unk4: i32,
|
||||
unk5: i32,
|
||||
unk6: i32,
|
||||
unk7: i32,
|
||||
) {
|
||||
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
||||
Tech::init_settings(module_accessor, status_kind).unwrap_or_else( || {
|
||||
original!()(module_accessor, situationKind, unk1, unk2, groundCliffCheckKind, unk3, unk4, unk5, unk6, unk7)
|
||||
Tech::init_settings(module_accessor, status_kind).unwrap_or_else(|| {
|
||||
original!()(
|
||||
module_accessor,
|
||||
situationKind,
|
||||
unk1,
|
||||
unk2,
|
||||
groundCliffCheckKind,
|
||||
unk3,
|
||||
unk4,
|
||||
unk5,
|
||||
unk6,
|
||||
unk7,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -151,16 +165,25 @@ pub unsafe fn handle_init_settings(
|
|||
#[skyline::hook(replace = MotionModule::change_motion)]
|
||||
pub unsafe fn handle_change_motion(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
motion_kind: u64,
|
||||
unk1: f32,
|
||||
unk2: f32,
|
||||
unk3: bool,
|
||||
unk4: f32,
|
||||
unk5: bool,
|
||||
unk6: bool) -> u64
|
||||
{
|
||||
Tech::change_motion(module_accessor, motion_kind).unwrap_or_else( || {
|
||||
original!()(module_accessor, motion_kind, unk1, unk2, unk3, unk4, unk5, unk6)
|
||||
motion_kind: u64,
|
||||
unk1: f32,
|
||||
unk2: f32,
|
||||
unk3: bool,
|
||||
unk4: f32,
|
||||
unk5: bool,
|
||||
unk6: bool,
|
||||
) -> u64 {
|
||||
Tech::change_motion(module_accessor, motion_kind).unwrap_or_else(|| {
|
||||
original!()(
|
||||
module_accessor,
|
||||
motion_kind,
|
||||
unk1,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
unk5,
|
||||
unk6,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -170,11 +193,12 @@ pub unsafe fn handle_attack(lua_state: u64) {
|
|||
let mut l2c_agent = L2CAgent::new(lua_state);
|
||||
|
||||
// get all necessary grabbox params
|
||||
let id = l2c_agent.pop_lua_stack(1); // int
|
||||
let id = l2c_agent.pop_lua_stack(1); // int
|
||||
|
||||
// hacky way of forcing no shield damage on all hitboxes
|
||||
if is_training_mode() && (*menu).SHIELD_STATE == SHIELD_INFINITE {
|
||||
let hitbox_params : Vec<L2CValue> = (0..36).map(|i| l2c_agent.pop_lua_stack(i+1)).collect();
|
||||
let hitbox_params: Vec<L2CValue> =
|
||||
(0..36).map(|i| l2c_agent.pop_lua_stack(i + 1)).collect();
|
||||
l2c_agent.clear_lua_stack();
|
||||
for i in 0..36 {
|
||||
let mut x = hitbox_params[i];
|
||||
|
@ -186,15 +210,16 @@ pub unsafe fn handle_attack(lua_state: u64) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
original!()(lua_state);
|
||||
}
|
||||
|
||||
|
||||
pub fn training_mods() {
|
||||
println!("Applying training mods.");
|
||||
unsafe {
|
||||
LookupSymbol(&mut fighter_manager_addr, c_str("_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E"));
|
||||
LookupSymbol(
|
||||
&mut fighter_manager_addr,
|
||||
c_str("_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E"),
|
||||
);
|
||||
println!("Lookup symbol output: {:#?}", fighter_manager_addr);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue