mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2024-11-20 08:54:15 +00:00
Code Refactoring (#83)
* Update TrainingModpackOverlay * Apply Auto Formatter * Auto Format * Extract Modding Behaviour Moved to separate function * Guard Clause * Guard Clause * Use Match Clause * Fix Comment * Extract Shared Condition * Extract Modding Function * Guard Clause * Guard Clause * Guard Clause * Guard Clause * Guard Clause * Extract Shared Code * Fix Variable Reference Properly borrow the variables * Fix Missed Tech Buffering * Move Training Mode Check To Start * Guard Clause * Guard Clause * Extract Modding Behaviour * Extract Function For randomizing the di angle * Guard Clause * Guard Clause * Simplify Loop Separate condition from behaviour * Extract Modding Behaviour * Extract Modding Behaviour * Formatting * Fix Typos * Fix Typos * Fix Mash Toggle ! was binding stronger than == * Move Negation Inwards * Reduce Nesting * Extract Shared Condition * Extract Method Moved random command list definition to separate function
This commit is contained in:
parent
e5ff95ce61
commit
e67c69ed63
7 changed files with 882 additions and 721 deletions
|
@ -158,78 +158,82 @@ pub unsafe fn get_command_flag_cat(
|
|||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
category: i32,
|
||||
) {
|
||||
if is_training_mode() {
|
||||
// Pause Effect AnimCMD if hitbox visualization is active
|
||||
MotionAnimcmdModule::set_sleep_effect(
|
||||
module_accessor,
|
||||
MENU.hitbox_vis
|
||||
&& !((*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_TREAD_FALL)
|
||||
.contains(&StatusModule::status_kind(module_accessor))),
|
||||
);
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
// apply only once per frame
|
||||
if category == 0 && is_training_mode() && MENU.hitbox_vis {
|
||||
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
||||
if !(*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_CATCH_TURN).contains(&status_kind)
|
||||
&& !is_shielding(module_accessor)
|
||||
{
|
||||
EffectModule::set_visible_kind(module_accessor, Hash40::new("sys_shield"), false);
|
||||
EffectModule::kill_kind(module_accessor, Hash40::new("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 mut x2 = None;
|
||||
let mut y2 = None;
|
||||
let mut z2 = None;
|
||||
if is_capsule {
|
||||
x2 = Some(attack_data.x2);
|
||||
y2 = Some(attack_data.y2);
|
||||
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],
|
||||
);
|
||||
}
|
||||
}
|
||||
if category != 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// Resume Effect AnimCMD incase we don't display hitboxes
|
||||
MotionAnimcmdModule::set_sleep_effect(module_accessor, false);
|
||||
|
||||
if !MENU.hitbox_vis {
|
||||
return;
|
||||
}
|
||||
|
||||
let status_kind = StatusModule::status_kind(module_accessor) as i32;
|
||||
if (*FIGHTER_STATUS_KIND_CATCH..=*FIGHTER_STATUS_KIND_CATCH_TURN).contains(&status_kind) {
|
||||
return;
|
||||
}
|
||||
|
||||
if is_shielding(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pause Effect AnimCMD if hitbox visualization is active
|
||||
MotionAnimcmdModule::set_sleep_effect(module_accessor, true);
|
||||
|
||||
EffectModule::set_visible_kind(module_accessor, Hash40::new("sys_shield"), false);
|
||||
EffectModule::kill_kind(module_accessor, Hash40::new("sys_shield"), false, true);
|
||||
for i in 0..8 {
|
||||
if !AttackModule::is_attack(module_accessor, i, false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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 mut x2 = None;
|
||||
let mut y2 = None;
|
||||
let mut z2 = None;
|
||||
if is_capsule {
|
||||
x2 = Some(attack_data.x2);
|
||||
y2 = Some(attack_data.y2);
|
||||
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],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Necessary to ensure we visualize on the first frame of the hitbox
|
||||
#[skyline::hook(replace = sv_animcmd::ATTACK)]
|
||||
unsafe fn handle_attack(lua_state: u64) {
|
||||
mod_handle_attack(lua_state);
|
||||
original!()(lua_state);
|
||||
}
|
||||
|
||||
unsafe fn mod_handle_attack(lua_state: u64) {
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
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(3); // hash40
|
||||
let _damage = l2c_agent.pop_lua_stack(4); // float
|
||||
let _angle = l2c_agent.pop_lua_stack(5); // int
|
||||
let _kbg = l2c_agent.pop_lua_stack(6); // int
|
||||
let _fkb = l2c_agent.pop_lua_stack(7); // int
|
||||
let _bkb = l2c_agent.pop_lua_stack(8); // int
|
||||
let size = l2c_agent.pop_lua_stack(9); // float
|
||||
let x = l2c_agent.pop_lua_stack(10); // float
|
||||
let y = l2c_agent.pop_lua_stack(11); // float
|
||||
let z = l2c_agent.pop_lua_stack(12); // float
|
||||
let x2 = l2c_agent.pop_lua_stack(13); // float or void
|
||||
let y2 = l2c_agent.pop_lua_stack(14); // float or void
|
||||
let z2 = l2c_agent.pop_lua_stack(15); // float or void
|
||||
|
||||
// hacky way of forcing no shield damage on all hitboxes
|
||||
if is_training_mode() && MENU.shield_state == Shield::Infinite {
|
||||
if MENU.shield_state == Shield::Infinite {
|
||||
let hitbox_params: Vec<L2CValue> =
|
||||
(0..36).map(|i| l2c_agent.pop_lua_stack(i + 1)).collect();
|
||||
l2c_agent.clear_lua_stack();
|
||||
|
@ -243,9 +247,24 @@ unsafe fn handle_attack(lua_state: u64) {
|
|||
}
|
||||
}
|
||||
|
||||
original!()(lua_state);
|
||||
// Hitbox Visualization
|
||||
if MENU.hitbox_vis {
|
||||
// get all necessary grabbox params
|
||||
let id = l2c_agent.pop_lua_stack(1); // int
|
||||
let joint = l2c_agent.pop_lua_stack(3); // hash40
|
||||
let _damage = l2c_agent.pop_lua_stack(4); // float
|
||||
let _angle = l2c_agent.pop_lua_stack(5); // int
|
||||
let _kbg = l2c_agent.pop_lua_stack(6); // int
|
||||
let _fkb = l2c_agent.pop_lua_stack(7); // int
|
||||
let _bkb = l2c_agent.pop_lua_stack(8); // int
|
||||
let size = l2c_agent.pop_lua_stack(9); // float
|
||||
let x = l2c_agent.pop_lua_stack(10); // float
|
||||
let y = l2c_agent.pop_lua_stack(11); // float
|
||||
let z = l2c_agent.pop_lua_stack(12); // float
|
||||
let x2 = l2c_agent.pop_lua_stack(13); // float or void
|
||||
let y2 = l2c_agent.pop_lua_stack(14); // float or void
|
||||
let z2 = l2c_agent.pop_lua_stack(15); // float or void
|
||||
|
||||
if MENU.hitbox_vis && is_training_mode() {
|
||||
generate_hitbox_effects(
|
||||
sv_system::battle_object_module_accessor(lua_state),
|
||||
joint.get_int(),
|
||||
|
@ -263,9 +282,21 @@ unsafe fn handle_attack(lua_state: u64) {
|
|||
|
||||
#[skyline::hook(replace = sv_animcmd::CATCH)]
|
||||
unsafe fn handle_catch(lua_state: u64) {
|
||||
let mut l2c_agent = L2CAgent::new(lua_state);
|
||||
mod_handle_catch(lua_state);
|
||||
original!()(lua_state);
|
||||
}
|
||||
|
||||
unsafe fn mod_handle_catch(lua_state: u64) {
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
if !MENU.hitbox_vis {
|
||||
return;
|
||||
}
|
||||
|
||||
// get all necessary grabbox params
|
||||
let mut l2c_agent = L2CAgent::new(lua_state);
|
||||
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
|
||||
|
@ -276,22 +307,18 @@ unsafe fn handle_catch(lua_state: u64) {
|
|||
let y2 = l2c_agent.pop_lua_stack(8); // float or void
|
||||
let z2 = l2c_agent.pop_lua_stack(9); // float or void
|
||||
|
||||
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],
|
||||
);
|
||||
}
|
||||
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],
|
||||
);
|
||||
}
|
||||
|
||||
pub unsafe fn is_shielding(module_accessor: *mut app::BattleObjectModuleAccessor) -> bool {
|
||||
|
@ -304,15 +331,26 @@ 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::new("sys_shield"), false);
|
||||
EffectModule::kill_kind(module_accessor, Hash40::new("sys_shield"), false, true);
|
||||
}
|
||||
mod_handle_handle_set_rebound(module_accessor, rebound);
|
||||
original!()(module_accessor, rebound);
|
||||
}
|
||||
|
||||
unsafe fn mod_handle_handle_set_rebound(module_accessor: *mut app::BattleObjectModuleAccessor, rebound: bool) {
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
original!()(module_accessor, rebound);
|
||||
if rebound != false {
|
||||
return;
|
||||
}
|
||||
|
||||
// only if we're not shielding
|
||||
if is_shielding(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
EffectModule::set_visible_kind(module_accessor, Hash40::new("sys_shield"), false);
|
||||
EffectModule::kill_kind(module_accessor, Hash40::new("sys_shield"), false, true);
|
||||
}
|
||||
|
||||
pub fn hitbox_visualization() {
|
||||
|
|
|
@ -15,40 +15,59 @@ pub unsafe fn handle_correct_damage_vector_common(
|
|||
fighter: &mut L2CFighterCommon,
|
||||
arg1: L2CValue,
|
||||
) -> L2CValue {
|
||||
let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent);
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if MENU.di_state != DirectionalInfluence::None {
|
||||
DI_ANGLE = (MENU.di_state as i32 - 1) as f64 * PI / 4.0;
|
||||
|
||||
// Either left, right, or none
|
||||
if MENU.di_state == DirectionalInfluence::RandomInAway {
|
||||
let rand = app::sv_math::rand(hash40("fighter"), 3);
|
||||
// Either 0 (right) or PI (left)
|
||||
if [0, 1].contains(&rand) {
|
||||
DI_ANGLE = rand as f64 * PI;
|
||||
} else {
|
||||
DI_ANGLE = NO_DI;
|
||||
}
|
||||
}
|
||||
// If facing left, reverse angle
|
||||
if DI_ANGLE != NO_DI && PostureModule::lr(module_accessor) != -1.0 {
|
||||
DI_ANGLE -= PI;
|
||||
}
|
||||
|
||||
if DI_ANGLE != NO_DI {
|
||||
WorkModule::set_float(
|
||||
module_accessor,
|
||||
DI_ANGLE.cos() as f32,
|
||||
*FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X,
|
||||
);
|
||||
WorkModule::set_float(
|
||||
module_accessor,
|
||||
DI_ANGLE.sin() as f32,
|
||||
*FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod_handle_di(fighter, arg1);
|
||||
original!()(fighter, arg1)
|
||||
}
|
||||
|
||||
unsafe fn mod_handle_di(fighter: &mut L2CFighterCommon, _arg1: L2CValue) {
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
if MENU.di_state == DirectionalInfluence::None {
|
||||
return;
|
||||
}
|
||||
|
||||
let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent);
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Either left, right, or none
|
||||
if MENU.di_state == DirectionalInfluence::RandomInAway {
|
||||
DI_ANGLE = get_random_di();
|
||||
} else {
|
||||
DI_ANGLE = (MENU.di_state as i32 - 1) as f64 * PI / 4.0;
|
||||
}
|
||||
|
||||
// If facing left, reverse angle
|
||||
if DI_ANGLE != NO_DI && PostureModule::lr(module_accessor) != -1.0 {
|
||||
DI_ANGLE -= PI;
|
||||
}
|
||||
|
||||
// Nothig to do on no DI
|
||||
if DI_ANGLE == NO_DI {
|
||||
return;
|
||||
}
|
||||
|
||||
WorkModule::set_float(
|
||||
module_accessor,
|
||||
DI_ANGLE.cos() as f32,
|
||||
*FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X,
|
||||
);
|
||||
WorkModule::set_float(
|
||||
module_accessor,
|
||||
DI_ANGLE.sin() as f32,
|
||||
*FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y,
|
||||
);
|
||||
}
|
||||
|
||||
unsafe fn get_random_di() -> f64 {
|
||||
let rand = app::sv_math::rand(hash40("fighter"), 3);
|
||||
if [0, 1].contains(&rand) {
|
||||
// Either 0 (right) or PI (left)
|
||||
rand as f64 * PI
|
||||
} else {
|
||||
NO_DI
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,35 +5,41 @@ use smash::hash40;
|
|||
use smash::lib::lua_const::*;
|
||||
|
||||
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,
|
||||
) {
|
||||
let random_frame = app::sv_math::rand(
|
||||
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: LedgeOption;
|
||||
|
||||
if MENU.ledge_state == LedgeOption::Random {
|
||||
ledge_case = (app::sv_math::rand(hash40("fighter"), 4) + 2).into();
|
||||
} else {
|
||||
ledge_case = MENU.ledge_state;
|
||||
}
|
||||
|
||||
if let Some(new_status) = ledge_case.into_status() {
|
||||
status = new_status;
|
||||
}
|
||||
|
||||
StatusModule::change_status_request_from_script(module_accessor, status, true);
|
||||
}
|
||||
}
|
||||
if StatusModule::status_kind(module_accessor) as i32 != *FIGHTER_STATUS_KIND_CLIFF_WAIT {
|
||||
return;
|
||||
}
|
||||
|
||||
if !WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
let random_frame = app::sv_math::rand(
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut status = 0;
|
||||
let ledge_case: LedgeOption;
|
||||
|
||||
if MENU.ledge_state == LedgeOption::Random {
|
||||
ledge_case = (app::sv_math::rand(hash40("fighter"), 4) + 2).into();
|
||||
} else {
|
||||
ledge_case = MENU.ledge_state;
|
||||
}
|
||||
|
||||
if let Some(new_status) = ledge_case.into_status() {
|
||||
status = new_status;
|
||||
}
|
||||
|
||||
StatusModule::change_status_request_from_script(module_accessor, status, true);
|
||||
}
|
||||
|
||||
pub unsafe fn should_perform_defensive_option(
|
||||
|
@ -62,28 +68,40 @@ pub unsafe fn defensive_option(
|
|||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
|
||||
if should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||
perform_defensive_option(module_accessor, flag);
|
||||
if !should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||
return;
|
||||
}
|
||||
|
||||
perform_defensive_option(module_accessor, flag);
|
||||
}
|
||||
|
||||
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) {
|
||||
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 !is_training_mode() {
|
||||
return None;
|
||||
}
|
||||
|
||||
None
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if ![*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if MENU.defensive_state != Defensive::Shield {
|
||||
return None;
|
||||
}
|
||||
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
if !should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(true)
|
||||
}
|
||||
|
||||
pub unsafe fn get_command_flag_cat(
|
||||
|
@ -91,11 +109,18 @@ pub unsafe fn get_command_flag_cat(
|
|||
category: i32,
|
||||
flag: &mut i32,
|
||||
) {
|
||||
if MENU.ledge_state != LedgeOption::None
|
||||
&& is_training_mode()
|
||||
&& is_operation_cpu(module_accessor)
|
||||
{
|
||||
force_option(module_accessor);
|
||||
defensive_option(module_accessor, category, flag);
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if MENU.ledge_state == LedgeOption::None {
|
||||
return;
|
||||
}
|
||||
|
||||
force_option(module_accessor);
|
||||
defensive_option(module_accessor, category, flag);
|
||||
}
|
||||
|
|
|
@ -8,16 +8,24 @@ use smash::lib::lua_const::*;
|
|||
pub unsafe fn get_attack_air_kind(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) -> Option<i32> {
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if MENU.mash_state == Mash::Attack {
|
||||
MENU.mash_attack_state.into_attack_air_kind()
|
||||
} else if MENU.mash_state == Mash::Random {
|
||||
Some(app::sv_math::rand(hash40("fighter"), 5) + 1)
|
||||
} else {
|
||||
None
|
||||
if !is_training_mode() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return None;
|
||||
}
|
||||
|
||||
match MENU.mash_state {
|
||||
Mash::Attack => {
|
||||
return MENU.mash_attack_state.into_attack_air_kind();
|
||||
}
|
||||
Mash::Random => {
|
||||
return Some(app::sv_math::rand(hash40("fighter"), 5) + 1);
|
||||
}
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,140 +34,153 @@ pub unsafe fn get_command_flag_cat(
|
|||
category: i32,
|
||||
flag: &mut i32,
|
||||
) {
|
||||
// Check for OOS delay
|
||||
if is_training_mode() && is_operation_cpu(module_accessor)
|
||||
&& is_in_shieldstun(module_accessor) && !shield::allow_oos(){
|
||||
if category != FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
|| is_in_footstool(module_accessor)
|
||||
|| StatusModule::status_kind(module_accessor) == FIGHTER_STATUS_KIND_CLIFF_ROBBED
|
||||
{
|
||||
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
|
||||
{
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for OOS delay
|
||||
if is_in_shieldstun(module_accessor) && !shield::allow_oos() {
|
||||
return;
|
||||
}
|
||||
|
||||
if !(is_in_hitstun(module_accessor)
|
||||
|| is_in_landing(module_accessor)
|
||||
|| is_in_shieldstun(module_accessor)
|
||||
|| is_in_footstool(module_accessor)
|
||||
|| StatusModule::status_kind(module_accessor) == FIGHTER_STATUS_KIND_CLIFF_ROBBED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
match MENU.mash_state {
|
||||
Mash::Airdodge => {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
|
||||
}
|
||||
Mash::Jump => {
|
||||
if !is_in_landing(module_accessor) {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;
|
||||
}
|
||||
}
|
||||
Mash::Spotdodge => {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE;
|
||||
}
|
||||
Mash::RollForward => {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F;
|
||||
}
|
||||
Mash::RollBack => {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B;
|
||||
}
|
||||
Mash::Attack => {
|
||||
use Attack::*;
|
||||
|
||||
match MENU.mash_attack_state {
|
||||
Nair | Fair | Bair | UpAir | 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::Spotdodge => {
|
||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE;
|
||||
}
|
||||
}
|
||||
Mash::RollForward => {
|
||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F;
|
||||
}
|
||||
}
|
||||
Mash::RollBack => {
|
||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
*flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B;
|
||||
}
|
||||
}
|
||||
Mash::Attack => {
|
||||
if category == FIGHTER_PAD_COMMAND_CATEGORY1 {
|
||||
use Attack::*;
|
||||
|
||||
match MENU.mash_attack_state {
|
||||
Nair | Fair | Bair | UpAir | 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;
|
||||
}
|
||||
}
|
||||
NeutralB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
|
||||
SideB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
UpB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
DownB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
UpSmash => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4,
|
||||
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;
|
||||
|
||||
if situation_kind == SITUATION_KIND_AIR {
|
||||
let random_commands = vec![
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
|
||||
// one for each aerial
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
];
|
||||
|
||||
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 {
|
||||
let random_commands = vec![
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S3,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI3,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW3,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S4,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW4,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_CATCH,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
|
||||
];
|
||||
|
||||
let random_cmd_index =
|
||||
app::sv_math::rand(hash40("fighter"), random_commands.len() as i32)
|
||||
as usize;
|
||||
|
||||
*flag |= random_commands[random_cmd_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
NeutralB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
|
||||
SideB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
UpB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
DownB => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
UpSmash => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4,
|
||||
Grab => *flag |= *FIGHTER_PAD_CMD_CAT1_FLAG_CATCH,
|
||||
}
|
||||
}
|
||||
Mash::Random => {
|
||||
let random_commands = get_random_command_list(module_accessor);
|
||||
|
||||
if random_commands.len() == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let random_cmd_index =
|
||||
app::sv_math::rand(hash40("fighter"), random_commands.len() as i32) as usize;
|
||||
|
||||
*flag |= random_commands[random_cmd_index];
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn get_random_command_list(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) -> Vec<i32> {
|
||||
let situation_kind = StatusModule::situation_kind(module_accessor) as i32;
|
||||
|
||||
if situation_kind == SITUATION_KIND_AIR {
|
||||
return vec![
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
|
||||
// one for each aerial
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
];
|
||||
}
|
||||
|
||||
if situation_kind == SITUATION_KIND_GROUND {
|
||||
return vec![
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S3,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI3,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW3,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S4,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW4,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_CATCH,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
|
||||
*FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
|
||||
];
|
||||
}
|
||||
|
||||
return vec![];
|
||||
}
|
||||
|
||||
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 MENU.mash_state == Mash::Airdodge
|
||||
&& (is_in_hitstun(module_accessor)
|
||||
|| is_in_landing(module_accessor)
|
||||
|| is_in_footstool(module_accessor))
|
||||
{
|
||||
return Some(true);
|
||||
}
|
||||
}
|
||||
if !is_training_mode() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if ![*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if MENU.mash_state == Mash::Airdodge
|
||||
&& !(is_in_hitstun(module_accessor)
|
||||
|| is_in_landing(module_accessor)
|
||||
|| is_in_footstool(module_accessor))
|
||||
{
|
||||
return Some(true);
|
||||
}
|
||||
|
||||
None
|
||||
|
|
|
@ -29,166 +29,163 @@ 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) {
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
if is_operation_cpu(module_accessor) {
|
||||
save_state_x = &mut SAVE_STATE_X_CPU;
|
||||
save_state_y = &mut SAVE_STATE_Y_CPU;
|
||||
save_state_percent = &mut SAVE_STATE_PERCENT_CPU;
|
||||
save_state_lr = &mut SAVE_STATE_LR_CPU;
|
||||
save_state_situation_kind = &mut SAVE_STATE_SITUATION_KIND_CPU;
|
||||
save_state = &mut SAVE_STATE_CPU_STATE;
|
||||
} else {
|
||||
save_state_x = &mut SAVE_STATE_X_PLAYER;
|
||||
save_state_y = &mut SAVE_STATE_Y_PLAYER;
|
||||
save_state_percent = &mut SAVE_STATE_PERCENT_PLAYER;
|
||||
save_state_lr = &mut SAVE_STATE_LR_PLAYER;
|
||||
save_state_situation_kind = &mut SAVE_STATE_SITUATION_KIND_PLAYER;
|
||||
save_state = &mut SAVE_STATE_PLAYER_STATE;
|
||||
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;
|
||||
save_state_percent = &mut SAVE_STATE_PERCENT_CPU;
|
||||
save_state_lr = &mut SAVE_STATE_LR_CPU;
|
||||
save_state_situation_kind = &mut SAVE_STATE_SITUATION_KIND_CPU;
|
||||
save_state = &mut SAVE_STATE_CPU_STATE;
|
||||
} else {
|
||||
save_state_x = &mut SAVE_STATE_X_PLAYER;
|
||||
save_state_y = &mut SAVE_STATE_Y_PLAYER;
|
||||
save_state_percent = &mut SAVE_STATE_PERCENT_PLAYER;
|
||||
save_state_lr = &mut SAVE_STATE_LR_PLAYER;
|
||||
save_state_situation_kind = &mut SAVE_STATE_SITUATION_KIND_PLAYER;
|
||||
save_state = &mut SAVE_STATE_PLAYER_STATE;
|
||||
}
|
||||
|
||||
// Grab + Dpad up: reset state
|
||||
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH)
|
||||
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI)
|
||||
{
|
||||
if *save_state == NoAction {
|
||||
SAVE_STATE_PLAYER_STATE = CameraMove;
|
||||
SAVE_STATE_CPU_STATE = CameraMove;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab + Dpad up: reset state
|
||||
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH)
|
||||
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_HI)
|
||||
{
|
||||
if *save_state == NoAction {
|
||||
SAVE_STATE_PLAYER_STATE = CameraMove;
|
||||
SAVE_STATE_CPU_STATE = CameraMove;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// move to camera bounds
|
||||
if *save_state == CameraMove {
|
||||
*save_state = PosMove;
|
||||
|
||||
// move to camera bounds
|
||||
if *save_state == CameraMove {
|
||||
*save_state = PosMove;
|
||||
let left_right = (PostureModule::pos_x(module_accessor) > 0.0) as i32 as f32
|
||||
- (PostureModule::pos_x(module_accessor) < 0.0) as i32 as f32;
|
||||
let y_pos = 20.0;
|
||||
|
||||
let left_right = (PostureModule::pos_x(module_accessor) > 0.0) as i32 as f32
|
||||
- (PostureModule::pos_x(module_accessor) < 0.0) as i32 as f32;
|
||||
let y_pos = 20.0;
|
||||
let pos = Vector3f {
|
||||
x: left_right * 50.0,
|
||||
y: y_pos,
|
||||
z: 0.0,
|
||||
};
|
||||
PostureModule::set_pos(module_accessor, &pos);
|
||||
|
||||
let pos = Vector3f {
|
||||
x: left_right * 50.0,
|
||||
y: y_pos,
|
||||
z: 0.0,
|
||||
};
|
||||
PostureModule::set_pos(module_accessor, &pos);
|
||||
|
||||
// force aerial, because from aerial state we can move anywhere
|
||||
if StatusModule::situation_kind(module_accessor) == SITUATION_KIND_GROUND {
|
||||
StatusModule::change_status_request(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_JUMP_SQUAT,
|
||||
false,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// move to correct pos
|
||||
if *save_state == PosMove {
|
||||
if StatusModule::situation_kind(module_accessor) == SITUATION_KIND_GROUND {
|
||||
return;
|
||||
}
|
||||
|
||||
KineticModule::clear_speed_all(module_accessor);
|
||||
|
||||
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(
|
||||
// force aerial, because from aerial state we can move anywhere
|
||||
if StatusModule::situation_kind(module_accessor) == SITUATION_KIND_GROUND {
|
||||
StatusModule::change_status_request(
|
||||
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,
|
||||
},
|
||||
*FIGHTER_STATUS_KIND_JUMP_SQUAT,
|
||||
false,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if *save_state_situation_kind == SITUATION_KIND_GROUND
|
||||
&& status != FIGHTER_STATUS_KIND_WAIT
|
||||
{
|
||||
StatusModule::change_status_request(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_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,
|
||||
false,
|
||||
);
|
||||
} else 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;
|
||||
// move to correct pos
|
||||
if *save_state == PosMove {
|
||||
if StatusModule::situation_kind(module_accessor) == SITUATION_KIND_GROUND {
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab + Dpad down: Save state
|
||||
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH)
|
||||
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_LW)
|
||||
KineticModule::clear_speed_all(module_accessor);
|
||||
|
||||
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::add_damage(module_accessor, *save_state_percent, 0);
|
||||
|
||||
StatusModule::set_situation_kind(
|
||||
module_accessor,
|
||||
app::SituationKind {
|
||||
situation_kind: *save_state_situation_kind,
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
if *save_state_situation_kind == SITUATION_KIND_GROUND && status != FIGHTER_STATUS_KIND_WAIT
|
||||
{
|
||||
SAVE_STATE_PLAYER_STATE = Save;
|
||||
SAVE_STATE_CPU_STATE = Save;
|
||||
}
|
||||
|
||||
if *save_state == Save {
|
||||
*save_state = NoAction;
|
||||
|
||||
*save_state_x = PostureModule::pos_x(module_accessor);
|
||||
*save_state_y = PostureModule::pos_y(module_accessor);
|
||||
*save_state_lr = PostureModule::lr(module_accessor);
|
||||
*save_state_percent = DamageModule::damage(module_accessor, 0);
|
||||
*save_state_situation_kind = StatusModule::situation_kind(module_accessor);
|
||||
|
||||
let zeros = Vector3f {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
};
|
||||
|
||||
EffectModule::req_on_joint(
|
||||
StatusModule::change_status_request(
|
||||
module_accessor,
|
||||
Hash40::new("sys_deku_flash"),
|
||||
Hash40::new("top"),
|
||||
&zeros,
|
||||
&zeros,
|
||||
0.25,
|
||||
&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,
|
||||
*FIGHTER_STATUS_KIND_CLIFF_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, false);
|
||||
} else 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;
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab + Dpad down: Save state
|
||||
if ControlModule::check_button_on(module_accessor, *CONTROL_PAD_BUTTON_CATCH)
|
||||
&& ControlModule::check_button_trigger(module_accessor, *CONTROL_PAD_BUTTON_APPEAL_LW)
|
||||
{
|
||||
SAVE_STATE_PLAYER_STATE = Save;
|
||||
SAVE_STATE_CPU_STATE = Save;
|
||||
}
|
||||
|
||||
if *save_state == Save {
|
||||
*save_state = NoAction;
|
||||
|
||||
*save_state_x = PostureModule::pos_x(module_accessor);
|
||||
*save_state_y = PostureModule::pos_y(module_accessor);
|
||||
*save_state_lr = PostureModule::lr(module_accessor);
|
||||
*save_state_percent = DamageModule::damage(module_accessor, 0);
|
||||
*save_state_situation_kind = StatusModule::situation_kind(module_accessor);
|
||||
|
||||
let zeros = Vector3f {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
z: 0.0,
|
||||
};
|
||||
|
||||
EffectModule::req_on_joint(
|
||||
module_accessor,
|
||||
Hash40::new("sys_deku_flash"),
|
||||
Hash40::new("top"),
|
||||
&zeros,
|
||||
&zeros,
|
||||
0.25,
|
||||
&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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use smash::lib::L2CValue;
|
|||
use smash::lua2cpp::L2CFighterCommon;
|
||||
|
||||
// How many hits to hold shield until picking an Out Of Shield option
|
||||
static mut MULTI_HIT_OFFSET : u8 = MENU.oos_offset;
|
||||
static mut MULTI_HIT_OFFSET: u8 = MENU.oos_offset;
|
||||
// Used to only decrease once per shieldstun change
|
||||
static mut WAS_IN_SHIELDSTUN: bool = false;
|
||||
|
||||
|
@ -24,7 +24,7 @@ unsafe fn should_pause_shield_decay() -> bool {
|
|||
!SHIELD_DECAY
|
||||
}
|
||||
|
||||
unsafe fn reset_oos_offset(){
|
||||
unsafe fn reset_oos_offset() {
|
||||
/*
|
||||
* Need to offset by 1, since we decrease as soon as shield gets hit
|
||||
* but only check later if we can OOS
|
||||
|
@ -32,8 +32,7 @@ unsafe fn reset_oos_offset(){
|
|||
MULTI_HIT_OFFSET = MENU.oos_offset + 1;
|
||||
}
|
||||
|
||||
unsafe fn handle_oos_offset(module_accessor: &mut app::BattleObjectModuleAccessor)
|
||||
{
|
||||
unsafe fn handle_oos_offset(module_accessor: &mut app::BattleObjectModuleAccessor) {
|
||||
// Check if we are currently in shield stun
|
||||
if !is_in_shieldstun(module_accessor) {
|
||||
// Make sure we don't forget and wait until we get hit on shield
|
||||
|
@ -55,7 +54,7 @@ unsafe fn handle_oos_offset(module_accessor: &mut app::BattleObjectModuleAccesso
|
|||
WAS_IN_SHIELDSTUN = true;
|
||||
}
|
||||
|
||||
pub unsafe fn allow_oos()->bool {
|
||||
pub unsafe fn allow_oos() -> bool {
|
||||
// Delay OOS until offset hits 0
|
||||
MULTI_HIT_OFFSET == 0
|
||||
}
|
||||
|
@ -70,8 +69,7 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut app::BattleObjectModule
|
|||
}
|
||||
|
||||
// Reset oos offset when standing
|
||||
if is_idle(module_accessor)
|
||||
|| is_in_hitstun(module_accessor){
|
||||
if is_idle(module_accessor) || is_in_hitstun(module_accessor) {
|
||||
reset_oos_offset();
|
||||
}
|
||||
|
||||
|
@ -87,29 +85,32 @@ pub unsafe fn get_param_float(
|
|||
param_type: u64,
|
||||
param_hash: u64,
|
||||
) -> Option<f32> {
|
||||
if !is_training_mode() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if is_training_mode() {
|
||||
if MENU.shield_state != Shield::None {
|
||||
handle_oos_offset(module_accessor);
|
||||
}
|
||||
|
||||
if MENU.shield_state != Shield::None {
|
||||
handle_oos_offset(module_accessor);
|
||||
// Shield Decay//Recovery
|
||||
if MENU.shield_state == Shield::Infinite || should_pause_shield_decay() {
|
||||
if param_type != hash40("common") {
|
||||
return None;
|
||||
}
|
||||
|
||||
if MENU.shield_state == Shield::Infinite || should_pause_shield_decay() {
|
||||
if param_type == hash40("common") {
|
||||
if param_hash == hash40("shield_dec1") {
|
||||
return Some(0.0);
|
||||
}
|
||||
if param_hash == hash40("shield_recovery1") {
|
||||
return Some(999.0);
|
||||
}
|
||||
// doesn't work, somehow. This parameter isn't checked?
|
||||
if param_hash == hash40("shield_damage_mul") {
|
||||
return Some(0.0);
|
||||
}
|
||||
}
|
||||
if param_hash == hash40("shield_dec1") {
|
||||
return Some(0.0);
|
||||
}
|
||||
if param_hash == hash40("shield_recovery1") {
|
||||
return Some(999.0);
|
||||
}
|
||||
// doesn't work, somehow. This parameter isn't checked?
|
||||
if param_hash == hash40("shield_damage_mul") {
|
||||
return Some(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,31 +119,33 @@ pub unsafe fn get_param_float(
|
|||
|
||||
pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAccessor) -> bool {
|
||||
// We should hold shield if the state requires it
|
||||
if [Shield::Hold, Shield::Infinite].contains(&MENU.shield_state) {
|
||||
// If we are not mashing attack then we will always hold shield
|
||||
if MENU.mash_state != Mash::Attack {
|
||||
return true;
|
||||
if ![Shield::Hold, Shield::Infinite].contains(&MENU.shield_state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are not mashing attack then we will always hold shield
|
||||
if MENU.mash_state != Mash::Attack {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Hold shield while OOS is not allowed
|
||||
if !allow_oos() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if !is_in_shieldstun(module_accessor) {
|
||||
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 [Attack::NeutralB, Attack::SideB, Attack::DownB].contains(&MENU.mash_attack_state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hold shield while OOS is not allowed
|
||||
if !allow_oos() {
|
||||
if MENU.mash_attack_state == Attack::Grab {
|
||||
return true;
|
||||
}
|
||||
|
||||
if !is_in_shieldstun(module_accessor) {
|
||||
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 [Attack::NeutralB, Attack::SideB, Attack::DownB].contains(&MENU.mash_attack_state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if MENU.mash_attack_state == Attack::Grab {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
|
@ -150,154 +153,153 @@ pub unsafe fn should_hold_shield(module_accessor: &mut app::BattleObjectModuleAc
|
|||
|
||||
#[skyline::hook(replace = smash::lua2cpp::L2CFighterCommon_sub_guard_cont)]
|
||||
pub unsafe fn handle_sub_guard_cont(fighter: &mut L2CFighterCommon) -> L2CValue {
|
||||
mod_handle_sub_guard_cont(fighter);
|
||||
original!()(fighter)
|
||||
}
|
||||
|
||||
unsafe fn mod_handle_sub_guard_cont(fighter: &mut L2CFighterCommon) {
|
||||
let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent);
|
||||
if !is_training_mode()
|
||||
|| !is_operation_cpu(module_accessor)
|
||||
|| StatusModule::prev_status_kind(module_accessor, 0) != FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable shield decay
|
||||
if is_training_mode()
|
||||
&& is_operation_cpu(module_accessor)
|
||||
&& StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
{
|
||||
set_shield_decay(true);
|
||||
}
|
||||
set_shield_decay(true);
|
||||
|
||||
// Check for OOS delay
|
||||
if is_training_mode()
|
||||
&& is_operation_cpu(module_accessor)
|
||||
&& StatusModule::prev_status_kind(module_accessor, 0) == FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
&& !allow_oos() {
|
||||
return original!()(fighter);
|
||||
if !allow_oos() {
|
||||
return;
|
||||
}
|
||||
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
if MENU.mash_state == Mash::Attack && MENU.mash_attack_state == Attack::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 MENU.mash_state == Mash::Spotdodge {
|
||||
if StatusModule::prev_status_kind(module_accessor, 0)
|
||||
== FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
{
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE,
|
||||
) {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_ESCAPE as u64),
|
||||
L2CValue::new_bool(true),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if MENU.mash_state == Mash::RollForward {
|
||||
if StatusModule::prev_status_kind(module_accessor, 0)
|
||||
== FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
{
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE,
|
||||
) {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_ESCAPE_F as u64),
|
||||
L2CValue::new_bool(true),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if MENU.mash_state == Mash::RollBack {
|
||||
if StatusModule::prev_status_kind(module_accessor, 0)
|
||||
== FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
{
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE,
|
||||
) {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_ESCAPE_B as u64),
|
||||
L2CValue::new_bool(true),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if MENU.mash_state == Mash::Attack {
|
||||
if MENU.mash_attack_state == Attack::UpB {
|
||||
if StatusModule::prev_status_kind(module_accessor, 0)
|
||||
== FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
{
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_JUMP_SQUAT_BUTTON,
|
||||
) {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_SPECIAL_HI as u64),
|
||||
L2CValue::new_bool(false),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if MENU.mash_attack_state == Attack::UpSmash {
|
||||
if StatusModule::prev_status_kind(module_accessor, 0)
|
||||
== FIGHTER_STATUS_KIND_GUARD_DAMAGE
|
||||
{
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_JUMP_SQUAT_BUTTON,
|
||||
) {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_ATTACK_HI4_START as u64),
|
||||
L2CValue::new_bool(false),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if MENU.mash_state == Mash::Attack {
|
||||
handle_attack_option(fighter, module_accessor);
|
||||
return;
|
||||
}
|
||||
|
||||
original!()(fighter)
|
||||
if WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_ESCAPE,
|
||||
) {
|
||||
handle_escape_option(fighter);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn handle_escape_option(fighter: &mut L2CFighterCommon) {
|
||||
match MENU.mash_state {
|
||||
Mash::Spotdodge => {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_ESCAPE as u64),
|
||||
L2CValue::new_bool(true),
|
||||
);
|
||||
}
|
||||
Mash::RollForward => {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_ESCAPE_F as u64),
|
||||
L2CValue::new_bool(true),
|
||||
);
|
||||
}
|
||||
Mash::RollBack => {
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_ESCAPE_B as u64),
|
||||
L2CValue::new_bool(true),
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn handle_attack_option(
|
||||
fighter: &mut L2CFighterCommon,
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
) {
|
||||
match MENU.mash_attack_state {
|
||||
Attack::Grab => {
|
||||
if !WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CATCH,
|
||||
) || !WorkModule::get_int(
|
||||
module_accessor,
|
||||
*FIGHTER_INSTANCE_WORK_ID_INT_INVALID_CATCH_FRAME,
|
||||
) == 0
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_CATCH as u64),
|
||||
L2CValue::new_bool(true),
|
||||
);
|
||||
}
|
||||
Attack::UpB => {
|
||||
if !WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_JUMP_SQUAT_BUTTON,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_SPECIAL_HI as u64),
|
||||
L2CValue::new_bool(false),
|
||||
);
|
||||
}
|
||||
Attack::UpSmash => {
|
||||
if !WorkModule::is_enable_transition_term(
|
||||
module_accessor,
|
||||
*FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_JUMP_SQUAT_BUTTON,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
fighter.fighter_base.change_status(
|
||||
L2CValue::new_int(*FIGHTER_STATUS_KIND_ATTACK_HI4_START as u64),
|
||||
L2CValue::new_bool(false),
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
if should_return_none_in_check_button(module_accessor, button) {
|
||||
return None;
|
||||
}
|
||||
|
||||
None
|
||||
Some(true)
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
if should_return_none_in_check_button(module_accessor, button) {
|
||||
return None;
|
||||
}
|
||||
Some(false)
|
||||
}
|
||||
|
||||
unsafe fn should_return_none_in_check_button(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
button: i32,
|
||||
) -> bool {
|
||||
if !is_training_mode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
None
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ![*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if !should_hold_shield(module_accessor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
|
|
@ -15,61 +15,89 @@ pub unsafe fn handle_change_status(
|
|||
) -> L2CValue {
|
||||
let mut status_kind = status_kind;
|
||||
let mut unk = unk;
|
||||
let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent);
|
||||
if is_training_mode() && is_operation_cpu(module_accessor) {
|
||||
let status_kind_int = status_kind
|
||||
.try_get_int()
|
||||
.unwrap_or(*FIGHTER_STATUS_KIND_WAIT as u64) as i32;
|
||||
if status_kind_int == FIGHTER_STATUS_KIND_DOWN
|
||||
|| status_kind_int == FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_D
|
||||
{
|
||||
match MENU.tech_state {
|
||||
TechOption::Random => {
|
||||
let random_statuses = vec![
|
||||
*FIGHTER_STATUS_KIND_DOWN,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE_FB,
|
||||
];
|
||||
|
||||
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 {
|
||||
status_kind =
|
||||
L2CValue::new_int(random_statuses[random_status_index] as u64);
|
||||
unk = L2CValue::new_bool(true);
|
||||
}
|
||||
}
|
||||
TechOption::InPlace => {
|
||||
status_kind = L2CValue::new_int(*FIGHTER_STATUS_KIND_PASSIVE as u64);
|
||||
unk = L2CValue::new_bool(true);
|
||||
}
|
||||
TechOption::Roll => {
|
||||
status_kind = L2CValue::new_int(*FIGHTER_STATUS_KIND_PASSIVE_FB as u64);
|
||||
unk = L2CValue::new_bool(true);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
} else if status_kind_int == FIGHTER_STATUS_KIND_STOP_WALL
|
||||
|| status_kind_int == FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_LR
|
||||
{
|
||||
if MENU.tech_state != TechOption::None && MENU.tech_state != TechOption::Miss {
|
||||
status_kind = L2CValue::new_int(*FIGHTER_STATUS_KIND_PASSIVE_WALL as u64);
|
||||
unk = L2CValue::new_bool(true);
|
||||
}
|
||||
} else if status_kind_int == FIGHTER_STATUS_KIND_STOP_CEIL
|
||||
|| status_kind_int == FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_U
|
||||
{
|
||||
if MENU.tech_state != TechOption::None && MENU.tech_state != TechOption::Miss {
|
||||
status_kind = L2CValue::new_int(*FIGHTER_STATUS_KIND_PASSIVE_CEIL as u64);
|
||||
unk = L2CValue::new_bool(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
mod_handle_change_status(fighter, &mut status_kind, &mut unk);
|
||||
|
||||
original!()(fighter, status_kind, unk)
|
||||
}
|
||||
|
||||
unsafe fn mod_handle_change_status(
|
||||
fighter: &mut L2CFighterBase,
|
||||
status_kind: &mut L2CValue,
|
||||
unk: &mut L2CValue,
|
||||
) {
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
let module_accessor = sv_system::battle_object_module_accessor(fighter.lua_state_agent);
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if MENU.tech_state == TechOption::None {
|
||||
return;
|
||||
}
|
||||
|
||||
if MENU.tech_state == TechOption::Miss {
|
||||
return;
|
||||
}
|
||||
|
||||
let status_kind_int = status_kind
|
||||
.try_get_int()
|
||||
.unwrap_or(*FIGHTER_STATUS_KIND_WAIT as u64) as i32;
|
||||
|
||||
// Ground Tech
|
||||
if status_kind_int == FIGHTER_STATUS_KIND_DOWN
|
||||
|| status_kind_int == FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_D
|
||||
{
|
||||
match MENU.tech_state {
|
||||
TechOption::Random => {
|
||||
let random_statuses = vec![
|
||||
*FIGHTER_STATUS_KIND_DOWN,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE,
|
||||
*FIGHTER_STATUS_KIND_PASSIVE_FB,
|
||||
];
|
||||
|
||||
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 {
|
||||
*status_kind = L2CValue::new_int(random_statuses[random_status_index] as u64);
|
||||
*unk = L2CValue::new_bool(true);
|
||||
}
|
||||
}
|
||||
TechOption::InPlace => {
|
||||
*status_kind = L2CValue::new_int(*FIGHTER_STATUS_KIND_PASSIVE as u64);
|
||||
*unk = L2CValue::new_bool(true);
|
||||
}
|
||||
TechOption::Roll => {
|
||||
*status_kind = L2CValue::new_int(*FIGHTER_STATUS_KIND_PASSIVE_FB as u64);
|
||||
*unk = L2CValue::new_bool(true);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Wall Tech
|
||||
if status_kind_int == FIGHTER_STATUS_KIND_STOP_WALL
|
||||
|| status_kind_int == FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_LR
|
||||
{
|
||||
*status_kind = L2CValue::new_int(*FIGHTER_STATUS_KIND_PASSIVE_WALL as u64);
|
||||
*unk = L2CValue::new_bool(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ceiling Tech
|
||||
if status_kind_int == FIGHTER_STATUS_KIND_STOP_CEIL
|
||||
|| status_kind_int == FIGHTER_STATUS_KIND_DAMAGE_FLY_REFLECT_U
|
||||
{
|
||||
*status_kind = L2CValue::new_int(*FIGHTER_STATUS_KIND_PASSIVE_CEIL as u64);
|
||||
*unk = L2CValue::new_bool(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn should_perform_defensive_option(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
prev_status: i32,
|
||||
|
@ -101,34 +129,46 @@ pub unsafe fn get_command_flag_cat(
|
|||
_category: i32,
|
||||
flag: &mut i32,
|
||||
) {
|
||||
if MENU.tech_state != TechOption::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)
|
||||
{
|
||||
let random_statuses = vec![
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_FB,
|
||||
*FIGHTER_STATUS_KIND_DOWN_STAND_ATTACK,
|
||||
];
|
||||
if !is_training_mode() {
|
||||
return;
|
||||
}
|
||||
|
||||
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],
|
||||
false,
|
||||
);
|
||||
} else if should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||
perform_defensive_option(module_accessor, flag);
|
||||
}
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if MENU.tech_state == TechOption::None {
|
||||
return;
|
||||
}
|
||||
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
|
||||
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,
|
||||
];
|
||||
|
||||
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],
|
||||
false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
|
||||
if should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||
perform_defensive_option(module_accessor, flag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,47 +176,66 @@ 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) {
|
||||
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 !is_training_mode() {
|
||||
return None;
|
||||
}
|
||||
|
||||
None
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if ![*CONTROL_PAD_BUTTON_GUARD_HOLD, *CONTROL_PAD_BUTTON_GUARD].contains(&button) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !(MENU.defensive_state == Defensive::Shield) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let prev_status = StatusModule::prev_status_kind(module_accessor, 0) as i32;
|
||||
let status = StatusModule::status_kind(module_accessor) as i32;
|
||||
if !should_perform_defensive_option(module_accessor, prev_status, status) {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(true);
|
||||
}
|
||||
|
||||
pub unsafe fn change_motion(
|
||||
module_accessor: &mut app::BattleObjectModuleAccessor,
|
||||
motion_kind: u64,
|
||||
) -> Option<u64> {
|
||||
if MENU.tech_state != TechOption::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"));
|
||||
}
|
||||
} 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"));
|
||||
}
|
||||
} 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 !is_training_mode() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !is_operation_cpu(module_accessor) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if MENU.tech_state == TechOption::None {
|
||||
return None;
|
||||
}
|
||||
|
||||
let random_roll = app::sv_math::rand(hash40("fighter"), 2);
|
||||
|
||||
if [hash40("passive_stand_f"), hash40("passive_stand_b")].contains(&motion_kind) {
|
||||
if random_roll != 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 random_roll != 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 random_roll != 0 {
|
||||
return Some(hash40("down_forward_d"));
|
||||
} else {
|
||||
return Some(hash40("down_back_d"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue