1
0
Fork 0
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:
jugeeya 2019-06-02 18:41:40 -07:00
parent 97c889345d
commit 762cfaaf7d
4 changed files with 163 additions and 77 deletions

View file

@ -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()) {

View file

@ -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");
}

View file

@ -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

View file

@ -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);
}