mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2025-03-14 02:16:10 +00:00
add hold/infinite shield; shield damage is still wrongly applied
This commit is contained in:
parent
97c889345d
commit
762cfaaf7d
4 changed files with 163 additions and 77 deletions
|
@ -113,7 +113,7 @@ void generate_hitbox_effects(L2CAgent *l2c_agent, L2CValue *bone, L2CValue *size
|
|||
|
||||
ACMD acmd(l2c_agent);
|
||||
acmd.wrap(EFFECT_FOLLOW_NO_SCALE, { shieldEffect, *bone, x_curr, y_curr, z_curr, x_rot, y_rot, z_rot, effect_size, terminate });
|
||||
|
||||
|
||||
// set to hitbox ID color
|
||||
acmd.wrap(LAST_EFFECT_SET_COLOR, { red, green, blue });
|
||||
|
||||
|
@ -199,13 +199,25 @@ namespace app::sv_animcmd {
|
|||
l2c_agent.get_lua_stack(8, &y2); // float or void
|
||||
l2c_agent.get_lua_stack(9, &z2); // float or void
|
||||
|
||||
// SaltySD_function_replace_sym works by replacing the
|
||||
// first four instructions of a function with instructions
|
||||
// to jump to a replacement function like CATCH_replace.
|
||||
// if we want to jump back, we just need to reimplement the
|
||||
// first four instructions and jump back to the original address
|
||||
// + the length of 4 instructions
|
||||
|
||||
// load address, along with lua_state as first arg
|
||||
asm("MOV X9, %x0" : : "r"(Catch_jumpback));
|
||||
asm("MOV X0, %x0" : : "r"(l2c_agent.lua_state_agent));
|
||||
|
||||
// the first four instructions: they will usually be
|
||||
// setting up the stack for local variables
|
||||
asm("SUB SP, SP, #0xC0");
|
||||
asm("STR X25, [SP, #0x70]");
|
||||
asm("STP X24, X23, [SP, #0x80]");
|
||||
asm("STP X22, X21, [SP, #0x90]");
|
||||
|
||||
// jump to Catch_jumpback
|
||||
asm("BLR X9");
|
||||
|
||||
if (HITBOX_VIS && is_training_mode()) {
|
||||
|
|
|
@ -45,6 +45,10 @@ u64 appeal_lw_replace(L2CAgent* l2c_agent, void* variadic) {
|
|||
print_string(acmd.module_accessor, "MASH\nAIRDODGE");
|
||||
else if (TOGGLE_STATE == MASH_JUMP)
|
||||
print_string(acmd.module_accessor, "MASH\nJUMP");
|
||||
else if (TOGGLE_STATE == HOLD_SHIELD)
|
||||
print_string(acmd.module_accessor, "HOLD\nSHIELD");
|
||||
else if (TOGGLE_STATE == INFINITE_SHIELD)
|
||||
print_string(acmd.module_accessor, "INFINITE\nSHIELD");
|
||||
else
|
||||
print_string(acmd.module_accessor, "NONE");
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@ int DI_STATE = 0;
|
|||
// Down Taunt
|
||||
#define MASH_AIRDODGE 1
|
||||
#define MASH_JUMP 2
|
||||
#define INFINITE_SHIELD 3
|
||||
#define HOLD_SHIELD 4
|
||||
|
||||
int TOGGLE_STATE = 0;
|
||||
#define NUM_TOGGLE_STATES 3
|
||||
#define NUM_TOGGLE_STATES 5
|
||||
|
||||
#endif // TAUNT_TOGGLES_H
|
||||
|
|
|
@ -39,95 +39,163 @@ void perform_jump(u64 module_accessor) {
|
|||
}
|
||||
}
|
||||
|
||||
namespace app::lua_bind::WorkModule {
|
||||
// Force option out of hitstun
|
||||
u64 enable_transition_term_group_replace(u64 module_accessor, int transition_group) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (is_in_hitstun(module_accessor)) {
|
||||
if (TOGGLE_STATE == MASH_AIRDODGE) { // airdodge
|
||||
if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_ESCAPE)
|
||||
StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_ESCAPE_AIR, 1);
|
||||
} else if (TOGGLE_STATE == MASH_JUMP) { // jump
|
||||
if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_JUMP_AERIAL)
|
||||
perform_jump(module_accessor);
|
||||
else if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_GROUND_JUMP)
|
||||
perform_jump(module_accessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call original WorkModule::enable_transition_term_group_impl
|
||||
u64 work_module = load_module(module_accessor, 0x50);
|
||||
u64 (*enable_transition_term_group)(u64, u64) = (u64(*)(u64, u64))(load_module_impl(work_module, 0x140));
|
||||
|
||||
return enable_transition_term_group(work_module, transition_group);
|
||||
}
|
||||
|
||||
// Force DI
|
||||
float get_float_replace(u64 module_accessor, int var) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (is_in_hitstun(module_accessor)) {
|
||||
if (DI_STATE != NONE) {
|
||||
float angle = (DI_STATE - 1) * M_PI / 4.0;
|
||||
|
||||
// Either 0 (right) or PI (left)
|
||||
if (DI_STATE == DI_RANDOM_IN_AWAY) {
|
||||
angle = app::sv_math::rand(hash40("fighter"), 2) * M_PI;
|
||||
}
|
||||
|
||||
// If facing left, reverse angle
|
||||
if (PostureModule::lr(module_accessor) != -1.0)
|
||||
angle -= M_PI;
|
||||
|
||||
if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X)
|
||||
return cos(angle);
|
||||
|
||||
if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y)
|
||||
return sin(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call original WorkModule::get_float_impl
|
||||
u64 work_module = load_module(module_accessor, 0x50);
|
||||
float (*get_float)(u64, int) = (float (*)(u64, int))(load_module_impl(work_module, 0x58));
|
||||
|
||||
return get_float(work_module, var);
|
||||
}
|
||||
}
|
||||
|
||||
namespace app::lua_bind::MotionModule {
|
||||
void change_motion_replace(u64 module_accessor, u64 motion_kind, float start_frame, float frame_speed_mult, bool unk1, float unk2, bool unk3, bool unk4) {
|
||||
u64 curr_motion_kind = MotionModule::motion_kind(module_accessor);
|
||||
if ((curr_motion_kind == hash40("damage_air_1") ||
|
||||
curr_motion_kind == hash40("damage_air_2") ||
|
||||
curr_motion_kind == hash40("damage_air_3")) && motion_kind == hash40("fall")) {
|
||||
namespace app::lua_bind {
|
||||
namespace WorkModule {
|
||||
// Force option out of hitstun
|
||||
u64 enable_transition_term_group_replace(u64 module_accessor, int transition_group) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (TOGGLE_STATE == MASH_AIRDODGE) // airdodge
|
||||
StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_ESCAPE_AIR, 1);
|
||||
else if (TOGGLE_STATE == MASH_JUMP) // jump
|
||||
perform_jump(module_accessor);
|
||||
if (is_in_hitstun(module_accessor)) {
|
||||
if (TOGGLE_STATE == MASH_AIRDODGE) { // airdodge
|
||||
if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_ESCAPE)
|
||||
StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_ESCAPE_AIR, 1);
|
||||
} else if (TOGGLE_STATE == MASH_JUMP) { // jump
|
||||
if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_JUMP_AERIAL)
|
||||
perform_jump(module_accessor);
|
||||
else if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_GROUND_JUMP)
|
||||
perform_jump(module_accessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call original WorkModule::enable_transition_term_group_impl
|
||||
u64 work_module = load_module(module_accessor, 0x50);
|
||||
u64 (*enable_transition_term_group)(u64, u64) = (u64(*)(u64, u64))(load_module_impl(work_module, 0x140));
|
||||
|
||||
return enable_transition_term_group(work_module, transition_group);
|
||||
}
|
||||
|
||||
// Force DI
|
||||
float get_float_replace(u64 module_accessor, int var) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (is_in_hitstun(module_accessor)) {
|
||||
if (DI_STATE != NONE) {
|
||||
float angle = (DI_STATE - 1) * M_PI / 4.0;
|
||||
|
||||
// Either 0 (right) or PI (left)
|
||||
if (DI_STATE == DI_RANDOM_IN_AWAY) {
|
||||
angle = app::sv_math::rand(hash40("fighter"), 2) * M_PI;
|
||||
}
|
||||
|
||||
// If facing left, reverse angle
|
||||
if (PostureModule::lr(module_accessor) != -1.0)
|
||||
angle -= M_PI;
|
||||
|
||||
if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X)
|
||||
return cos(angle);
|
||||
|
||||
if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y)
|
||||
return sin(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call original WorkModule::get_float_impl
|
||||
u64 work_module = load_module(module_accessor, 0x50);
|
||||
float (*get_float)(u64, int) = (float (*)(u64, int))(load_module_impl(work_module, 0x58));
|
||||
|
||||
return get_float(work_module, var);
|
||||
}
|
||||
|
||||
// call original
|
||||
u64 motion_module = load_module(module_accessor, 0x88);
|
||||
void (*change_motion)(u64, u64, float, float, bool, float, bool, bool) =
|
||||
(void (*)(u64, u64, float, float, bool, float, bool, bool)) load_module_impl(motion_module, 0xD8);
|
||||
float get_param_float_replace(u64 module_accessor, u64 param_type, u64 param_hash) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (TOGGLE_STATE == INFINITE_SHIELD) {
|
||||
if (param_type == hash40("common")) {
|
||||
if (param_hash == hash40("shield_dec1"))
|
||||
return 0.0;
|
||||
if (param_hash == hash40("shield_recovery1"))
|
||||
return 0.0;
|
||||
// doesn't work, somehow. This parameter isn't checked?
|
||||
if (param_hash == hash40("shield_damage_mul"))
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
change_motion(motion_module, motion_kind, start_frame, frame_speed_mult, unk1, unk2, unk3, unk4);
|
||||
// call original
|
||||
u64 work_module = load_module(module_accessor, 0x50);
|
||||
float (*get_param_float)(u64, u64, u64) = (float (*)(u64, u64, u64))(load_module_impl(work_module, 0x240));
|
||||
|
||||
return get_param_float(work_module, param_type, param_hash);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MotionModule {
|
||||
void change_motion_replace(u64 module_accessor, u64 motion_kind, float start_frame, float frame_speed_mult, bool unk1, float unk2, bool unk3, bool unk4) {
|
||||
u64 curr_motion_kind = MotionModule::motion_kind(module_accessor);
|
||||
if ((curr_motion_kind == hash40("damage_air_1") ||
|
||||
curr_motion_kind == hash40("damage_air_2") ||
|
||||
curr_motion_kind == hash40("damage_air_3")) && motion_kind == hash40("fall")) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (TOGGLE_STATE == MASH_AIRDODGE) // airdodge
|
||||
StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_ESCAPE_AIR, 1);
|
||||
else if (TOGGLE_STATE == MASH_JUMP) // jump
|
||||
perform_jump(module_accessor);
|
||||
}
|
||||
}
|
||||
|
||||
// call original
|
||||
u64 motion_module = load_module(module_accessor, 0x88);
|
||||
void (*change_motion)(u64, u64, float, float, bool, float, bool, bool) =
|
||||
(void (*)(u64, u64, float, float, bool, float, bool, bool)) load_module_impl(motion_module, 0xD8);
|
||||
|
||||
change_motion(motion_module, motion_kind, start_frame, frame_speed_mult, unk1, unk2, unk3, unk4);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ControlModule {
|
||||
bool check_button_on_replace(u64 module_accessor, int button) {
|
||||
if (button == CONTROL_PAD_BUTTON_GUARD_HOLD || button == CONTROL_PAD_BUTTON_GUARD) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (TOGGLE_STATE == HOLD_SHIELD || TOGGLE_STATE == INFINITE_SHIELD)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// call original
|
||||
u64 control_module = load_module(module_accessor, 0x48);
|
||||
bool (*check_button_on)(u64, int) = (bool (*)(u64, int))load_module_impl(control_module, 0x260);
|
||||
return check_button_on(control_module, button);
|
||||
}
|
||||
|
||||
bool check_button_off_replace(u64 module_accessor, int button) {
|
||||
if (button == CONTROL_PAD_BUTTON_GUARD_HOLD || button == CONTROL_PAD_BUTTON_GUARD) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (TOGGLE_STATE == HOLD_SHIELD || TOGGLE_STATE == INFINITE_SHIELD)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// call original
|
||||
u64 control_module = load_module(module_accessor, 0x48);
|
||||
bool (*check_button_off)(u64, int) = (bool (*)(u64, int))load_module_impl(control_module, 0x268);
|
||||
return check_button_off(control_module, button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void training_mods_main() {
|
||||
fighter_manager_addr = SaltySDCore_FindSymbol("_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E");
|
||||
// Mash airdodge/jump
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind45WorkModule__enable_transition_term_group_implEPNS_26BattleObjectModuleAccessorEi",
|
||||
(u64)&WorkModule::enable_transition_term_group_replace);
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind26WorkModule__get_float_implEPNS_26BattleObjectModuleAccessorEi",
|
||||
(u64)&WorkModule::get_float_replace);
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind32MotionModule__change_motion_implEPNS_26BattleObjectModuleAccessorEN3phx6Hash40Effbfbb",
|
||||
(u64)&MotionModule::change_motion_replace);
|
||||
|
||||
// Set DI
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind26WorkModule__get_float_implEPNS_26BattleObjectModuleAccessorEi",
|
||||
(u64)&WorkModule::get_float_replace);
|
||||
|
||||
// Hold/Infinite shield
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind35ControlModule__check_button_on_implEPNS_26BattleObjectModuleAccessorEi",
|
||||
(u64)&ControlModule::check_button_on_replace);
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind36ControlModule__check_button_off_implEPNS_26BattleObjectModuleAccessorEi",
|
||||
(u64)&ControlModule::check_button_off_replace);
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind32WorkModule__get_param_float_implEPNS_26BattleObjectModuleAccessorEmm",
|
||||
(u64)&WorkModule::get_param_float_replace);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue