HDR-Development / smashline

31 stars 7 forks source link

Crash regarding changing to the Throw Status during the CATCH_PULL status #14

Closed Armasher5872 closed 9 months ago

Armasher5872 commented 10 months ago

Certain code used to imitate the functionality of command grabs that was utilized in Smashline 1 now immediately crash upon attempting to change status. Said code looks like this:

unsafe extern "C" fn luigi_catch_pull_main_status(fighter: &mut L2CFighterCommon) -> L2CValue {
    if WorkModule::is_flag(fighter.module_accessor, FIGHTER_INSTANCE_WORK_ID_FLAG_HAS_CATCH) {
        let throw_f_status_kind = fighter.global_table[THROW_F_STATUS_KIND].get_i32();
        fighter.change_status(throw_f_status_kind.into(), false.into());
        0.into()
    }
    else {
        fighter.status_CatchPull()
    }
}

The FIGHTER_INSTANCE_WORK_ID_FLAG_HAS_CATCH is a custom lua_const, although this issue also happens if using a mutable instance variable (like HAS_CATCH[entry_id]). Said flag gets enabled during the catch status if the previous status kind was Down Special, which can be seen here:

unsafe extern "C" fn luigi_catch_pre_status(fighter: &mut L2CFighterCommon) -> L2CValue {
    if fighter.global_table[PREV_STATUS_KIND].get_i32() == FIGHTER_STATUS_KIND_SPECIAL_LW {
        WorkModule::set_flag(fighter.module_accessor, true, FIGHTER_INSTANCE_WORK_ID_FLAG_HAS_CATCH);
        StatusModule::init_settings(fighter.module_accessor, smash::app::SituationKind(*SITUATION_KIND_NONE), *FIGHTER_KINETIC_TYPE_UNIQ, *GROUND_CORRECT_KIND_KEEP as u32, smash::app::GroundCliffCheckKind(*GROUND_CLIFF_CHECK_KIND_NONE), true, *FIGHTER_STATUS_WORK_KEEP_FLAG_NONE_FLAG, *FIGHTER_STATUS_WORK_KEEP_FLAG_NONE_INT, *FIGHTER_STATUS_WORK_KEEP_FLAG_NONE_FLOAT, 0);
        FighterStatusModuleImpl::set_fighter_status_data(fighter.module_accessor, false, *FIGHTER_TREADED_KIND_NO_REAC, false, false, false, (*FIGHTER_LOG_MASK_FLAG_ATTACK_KIND_SPECIAL_LW | *FIGHTER_LOG_MASK_FLAG_ACTION_CATEGORY_ATTACK | *FIGHTER_LOG_MASK_FLAG_ACTION_TRIGGER_ON) as u64, 0, *FIGHTER_POWER_UP_ATTACK_BIT_SPECIAL_LW as u32, 0);
        0.into()
    }
    else {
        original_status(Pre, fighter, *FIGHTER_STATUS_KIND_CATCH)(fighter)
    }
}

I cannot say if it's due to my implementation, or if it's a Smashline 2 specific issue.

Here's the crash log: 01706216210_01006a800016e000.log

The game seems to be crashing on the pre status script of the move, which looks like this:

unsafe extern "C" fn luigi_catch_pull_pre_status(fighter: &mut L2CFighterCommon) -> L2CValue {
    if WorkModule::is_flag(fighter.module_accessor, FIGHTER_INSTANCE_WORK_ID_FLAG_HAS_CATCH) {
        StatusModule::init_settings(fighter.module_accessor, smash::app::SituationKind(*SITUATION_KIND_NONE), *FIGHTER_KINETIC_TYPE_MOTION, *GROUND_CORRECT_KIND_KEEP as u32, smash::app::GroundCliffCheckKind(*GROUND_CLIFF_CHECK_KIND_NONE), true, *FIGHTER_STATUS_WORK_KEEP_FLAG_ALL_FLAG, *FIGHTER_STATUS_WORK_KEEP_FLAG_ALL_INT, *FIGHTER_STATUS_WORK_KEEP_FLAG_ALL_FLOAT, 0);
        FighterStatusModuleImpl::set_fighter_status_data(fighter.module_accessor, false, *FIGHTER_TREADED_KIND_ENABLE, false, true, false, 0, (*FIGHTER_STATUS_ATTR_DISABLE_JUMP_BOARD_EFFECT | *FIGHTER_STATUS_ATTR_DISABLE_TURN_DAMAGE | 0) as u32, 0, 0);
        0.into()
    }
    else {
        StatusModule::init_settings(fighter.module_accessor, smash::app::SituationKind(*SITUATION_KIND_NONE), *FIGHTER_KINETIC_TYPE_MOTION, *GROUND_CORRECT_KIND_GROUND_CLIFF_STOP as u32, smash::app::GroundCliffCheckKind(*GROUND_CLIFF_CHECK_KIND_NONE), true, *FIGHTER_STATUS_WORK_KEEP_FLAG_NONE_FLAG, *FIGHTER_STATUS_WORK_KEEP_FLAG_NONE_INT, *FIGHTER_STATUS_WORK_KEEP_FLAG_NONE_FLOAT, 0);
        FighterStatusModuleImpl::set_fighter_status_data(fighter.module_accessor, false, *FIGHTER_TREADED_KIND_ENABLE, false, true, false, 0, (*FIGHTER_STATUS_ATTR_DISABLE_JUMP_BOARD_EFFECT | *FIGHTER_STATUS_ATTR_DISABLE_TURN_DAMAGE | 0) as u32, 0, 0);
        0.into()
    }
}

Here's where the PC linked to in main:

71004816a4 08 05 40 f9     ldr        x8,[x8, #0x8] (**(code **)(**(long **)(*(long *)(*(long *)(lVar4 + lVar3 * 0x68 + 0x58) + 8) + 0x38) + 0xb0))();

From my understanding, it's an issue regarding LinkModule::get_parent_lr, and could possibly be crashing because the game doesn't have a reference on what value it's supposed to put in the function (If this assumption is incorrect let me know).

I will need to perform further testing to determine if it's only the throw status that causes a crash, or if attempting to transition into any other status kind causes a crash.

If I manage to solve this issue, I will mention it in a followup on what solved it.

Armasher5872 commented 10 months ago

Followup note:

While I have not solved the issue entirely, I have found that so far, only the throw status kinds cause a crash when attempting to directly transition into them. Additionally, this still happens even if attempting it via a vtable hook.

Armasher5872 commented 9 months ago

Figured out what seemingly fixed it:

For Luigi, it was reimplementing all of his vanilla grab statuses to permit him to grab properly.