1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2025-03-16 11:26:11 +00:00

random DI; mash jump; cleanup on aisle EVERYWHERE

This commit is contained in:
jugeeya 2019-05-20 16:07:01 -07:00
parent b7c26e7c12
commit 09a50060ba
6 changed files with 156 additions and 158 deletions

View file

@ -8,18 +8,17 @@
#include "lua_helper.hpp"
#include <initializer_list>
#include <vector>
using namespace lib;
struct ACMDReplacement {
void* func;
int battle_object_category;
int battle_object_kind;
const char* acmd_script;
};
u64 load_module(u64 module_accessor, u64 module_offset) {
return LOAD64(module_accessor + module_offset);
}
std::vector<ACMDReplacement> acmd_replacements;
void* load_module_impl(u64 module, u64 function_offset) {
u64 function_impl = LOAD64(module) + function_offset;
return (void*) LOAD64(function_impl);
}
namespace app::sv_system
{

View file

@ -17,39 +17,23 @@ Vector3f id_colors[8] = {
{0.7843f, 0.0f, 1.0f}, {0.3765f, 0.2863f, 0.5294f},
};
void app_sv_animcmd_ATTACK_replace(u64 a1);
void AttackModule_clear_all_replace(u64 module_accessor);
void AttackModule_clear_replace(u64 module_accessor, int id, bool unk);
void hitbox_vis_main() {
AttackModule_set_attack_lua_state =
(void (*)(u64, u64))SaltySDCore_FindSymbol("_ZN3app10sv_animcmd6ATTACKEP9lua_State") + 0xD0 - 0x70;
SaltySD_function_replace_sym(
"_ZN3app10sv_animcmd6ATTACKEP9lua_State",
(u64)&app_sv_animcmd_ATTACK_replace);
SaltySD_function_replace_sym(
"_ZN3app8lua_bind28AttackModule__clear_all_implEPNS_26BattleObjectModuleAccessorE",
(u64)&AttackModule_clear_all_replace);
}
void AttackModule_clear_all_replace(u64 module_accessor) {
u64 attack_module = LOAD64(module_accessor + 0xA0);
u64 attack_module_clear_all = LOAD64(attack_module) + 0x50LL;
u64 (*attack_module_clear_all_impl)(u64) =
(u64(*)(u64))(LOAD64(attack_module_clear_all));
attack_module_clear_all_impl(attack_module);
if (is_training_mode()) {
// Clear graphics every time we clear all hitboxes.
// Only if we're not shielding.
int status_kind = StatusModule::status_kind(module_accessor);
if (!(status_kind >= 0x1b && status_kind <= 0x1d)) {
Hash40 shieldEffectHash = {.hash = 0xAFAE75F05LL};
EffectModule::kill_kind(module_accessor, shieldEffectHash.hash, 0, 1);
namespace app::lua_bind::AttackModule {
// Clear graphics every time we clear all hitboxes
void clear_all_replace(u64 module_accessor) {
if (is_training_mode()) {
// Only if we're not shielding
int status_kind = StatusModule::status_kind(module_accessor);
if (!(status_kind >= FIGHTER_STATUS_KIND_GUARD_ON && status_kind <= FIGHTER_STATUS_KIND_GUARD_OFF)) {
Hash40 shieldEffectHash = {.hash = 0xAFAE75F05LL};
EffectModule::kill_kind(module_accessor, shieldEffectHash.hash, 0, 1);
}
}
// call original AttackModule::clear_all_impl
u64 attack_module = load_module(module_accessor, 0xA0);
void (*clear_all)(u64) = (void(*)(u64))(load_module_impl(attack_module, 0x50));
return clear_all(attack_module);
}
}
@ -105,44 +89,59 @@ void generate_hitbox_effects(L2CAgent *l2c_agent, L2CValue *id, L2CValue *bone,
}
}
void app_sv_animcmd_ATTACK_replace(u64 a1) {
// Instantiate our own L2CAgent with the given lua_State
L2CAgent l2c_agent;
l2c_agent.L2CAgent_constr(a1);
namespace app::sv_animcmd {
void ATTACK_replace(u64 a1) {
// Instantiate our own L2CAgent with the given lua_State
L2CAgent l2c_agent;
l2c_agent.L2CAgent_constr(a1);
// Get all necessary hitbox params
L2CValue id, bone, damage, angle, kbg, wkb, bkb, size, x, y, z, x2, y2, z2;
l2c_agent.get_lua_stack(1, &id);
l2c_agent.get_lua_stack(3, &bone);
l2c_agent.get_lua_stack(4, &damage);
l2c_agent.get_lua_stack(5, &angle);
l2c_agent.get_lua_stack(6, &kbg);
l2c_agent.get_lua_stack(7, &wkb);
l2c_agent.get_lua_stack(8, &bkb);
l2c_agent.get_lua_stack(9, &size);
l2c_agent.get_lua_stack(10, &x);
l2c_agent.get_lua_stack(11, &y);
l2c_agent.get_lua_stack(12, &z);
l2c_agent.get_lua_stack(13, &x2);
l2c_agent.get_lua_stack(14, &y2);
l2c_agent.get_lua_stack(15, &z2);
// Get all necessary hitbox params
L2CValue id, bone, damage, angle, kbg, wkb, bkb, size, x, y, z, x2, y2, z2;
l2c_agent.get_lua_stack(1, &id);
l2c_agent.get_lua_stack(3, &bone);
l2c_agent.get_lua_stack(4, &damage);
l2c_agent.get_lua_stack(5, &angle);
l2c_agent.get_lua_stack(6, &kbg);
l2c_agent.get_lua_stack(7, &wkb);
l2c_agent.get_lua_stack(8, &bkb);
l2c_agent.get_lua_stack(9, &size);
l2c_agent.get_lua_stack(10, &x);
l2c_agent.get_lua_stack(11, &y);
l2c_agent.get_lua_stack(12, &z);
l2c_agent.get_lua_stack(13, &x2);
l2c_agent.get_lua_stack(14, &y2);
l2c_agent.get_lua_stack(15, &z2);
// original code: parse lua stack and call AttackModule::set_attack()
AttackModule_set_attack_lua_state(LOAD64(LOAD64(a1 - 8) + 416LL), a1);
// original code: parse lua stack and call AttackModule::set_attack()
AttackModule_set_attack_lua_state(LOAD64(LOAD64(a1 - 8) + 416LL), a1);
if (HITBOX_VIS && is_training_mode()) {
// Generate hitbox effect(s)
generate_hitbox_effects(&l2c_agent, &id, &bone, &size, &x, &y, &z, &x2, &y2, &z2);
if (HITBOX_VIS && is_training_mode()) {
// Generate hitbox effect(s)
generate_hitbox_effects(&l2c_agent, &id, &bone, &size, &x, &y, &z, &x2, &y2, &z2);
}
u64 v1, v2, i;
v1 = a1;
// original code: clear_lua_stack section
v2 = LOAD64(v1 + 16);
for (i = **(u64 **)(v1 + 32) + 16LL; v2 < i; v2 = LOAD64(v1 + 16)) {
LOAD64(v1 + 16) = v2 + 16;
*(__int32_t *)(v2 + 8) = 0;
}
LOAD64(v1 + 16) = i;
}
}
u64 v1, v2, i;
v1 = a1;
void hitbox_vis_main() {
AttackModule_set_attack_lua_state =
(void (*)(u64, u64))SaltySDCore_FindSymbol("_ZN3app10sv_animcmd6ATTACKEP9lua_State") + 0xD0 - 0x70;
// original code: clear_lua_stack section
v2 = LOAD64(v1 + 16);
for (i = **(u64 **)(v1 + 32) + 16LL; v2 < i; v2 = LOAD64(v1 + 16)) {
LOAD64(v1 + 16) = v2 + 16;
*(__int32_t *)(v2 + 8) = 0;
}
LOAD64(v1 + 16) = i;
SaltySD_function_replace_sym(
"_ZN3app10sv_animcmd6ATTACKEP9lua_State",
(u64)&ATTACK_replace);
SaltySD_function_replace_sym(
"_ZN3app8lua_bind28AttackModule__clear_all_implEPNS_26BattleObjectModuleAccessorE",
(u64)&AttackModule::clear_all_replace);
}

View file

@ -5,6 +5,8 @@
#include "l2c.hpp"
#include "lua_bind_hash.hpp"
#define LOAD64 *(u64 *)
u64 is_training_mode(void) asm("_ZN3app9smashball16is_training_modeEv") LINKABLE;
namespace lib

View file

@ -16,12 +16,9 @@
#include <vector>
#define LOAD64 *(u64 *)
using namespace lib;
using namespace app::lua_bind;
u64 shine_replace(L2CAgent* l2c_agent, void* variadic);
u64 appeal_lw_replace(L2CAgent* l2c_agent, void* variadic);
u64 appeal_hi_replace(L2CAgent* l2c_agent, void* variadic);
u64 appeal_s_replace(L2CAgent* l2c_agent, void* variadic);
@ -44,8 +41,10 @@ u64 appeal_lw_replace(L2CAgent* l2c_agent, void* variadic) {
acmd.frame(1);
if (acmd.is_excute()) {
TOGGLE_STATE = (TOGGLE_STATE + 1) % NUM_TOGGLE_STATES;
if (TOGGLE_STATE)
if (TOGGLE_STATE == MASH_AIRDODGE)
print_string(acmd.module_accessor, "MASH\nAIRDODGE");
else if (TOGGLE_STATE == MASH_JUMP)
print_string(acmd.module_accessor, "MASH\nJUMP");
else
print_string(acmd.module_accessor, "NONE");
}
@ -75,7 +74,7 @@ u64 appeal_s_replace(L2CAgent* l2c_agent, void* variadic) {
if (acmd.is_excute()) {
DI_STATE = (DI_STATE + 1) % NUM_DI_STATES;
const char* DI_strings[NUM_DI_STATES] = {"NONE", "AWAY", "DOWN AWAY", "DOWN", "DOWN IN",
"IN", "UP IN", "UP", "UP AWAY"};
"IN", "UP IN", "UP", "UP AWAY", "RANDOM\nIN AWAY"};
print_string(acmd.module_accessor, DI_strings[DI_STATE]);
}

View file

@ -11,12 +11,14 @@ bool HITBOX_VIS = 1;
// 0, pi/4, pi/2, 3pi/4, pi, 5pi/4, 3pi/2, 7pi/4
int DI_STATE = 0;
#define NUM_DI_STATES 9
#define DI_RANDOM_IN_AWAY 9
#define NUM_DI_STATES 10
// Down Taunt
#define MASH_AIRDODGE 1
#define MASH_JUMP 2
int TOGGLE_STATE = 1;
#define NUM_TOGGLE_STATES 2
int TOGGLE_STATE = 0;
#define NUM_TOGGLE_STATES 3
#endif // TAUNT_TOGGLES_H

View file

@ -11,89 +11,86 @@ using namespace app::sv_animcmd;
u64 fighter_manager_addr;
u64 WorkModule_enable_transition_term_group_replace(u64 module_accessor, u64 transition_group);
float WorkModule_get_float_replace(u64 module_accessor, int var);
void MotionModule_change_motion_replace(u64 module_accessor, u64 hash,
float start_frame,
float frame_speed_mult, bool unk1,
float unk2, bool unk3, bool unk4);
bool is_operation_cpu(u64 module_accessor) {
int entry_id = WorkModule::get_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID);
u64 fighter_information = FighterManager::get_fighter_information(LOAD64(fighter_manager_addr), entry_id);
return FighterInformation::is_operation_cpu(fighter_information);
}
bool is_in_hitstun(u64 module_accessor) {
int status_kind = StatusModule::status_kind(module_accessor);
return status_kind >= FIGHTER_STATUS_KIND_DAMAGE && status_kind <= FIGHTER_STATUS_KIND_DAMAGE_FALL;
}
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)) {
// Airdodge
if (TOGGLE_STATE == MASH_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);
}
// Jump
else if (TOGGLE_STATE == MASH_JUMP) {
if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_JUMP_AERIAL)
StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_JUMP_AERIAL, 1);
else if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_GROUND_JUMP)
StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_JUMP_SQUAT, 1);
}
}
}
// 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 = (rand() % 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);
}
}
void training_mods_main() {
fighter_manager_addr = SaltySDCore_FindSymbol("_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E");
SaltySD_function_replace_sym(
"_ZN3app8lua_bind45WorkModule__enable_transition_term_group_implEPNS_26BattleObjectModuleAccessorEi",
(u64)&WorkModule_enable_transition_term_group_replace);
(u64)&WorkModule::enable_transition_term_group_replace);
SaltySD_function_replace_sym(
"_ZN3app8lua_bind26WorkModule__get_float_implEPNS_26BattleObjectModuleAccessorEi",
(u64)&WorkModule_get_float_replace);
}
bool is_operation_cpu(u64 module_accessor) {
int entry_id = WorkModule::get_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID);
u64 fighter_information = FighterManager::get_fighter_information(
LOAD64(fighter_manager_addr), entry_id);
return FighterInformation::is_operation_cpu(fighter_information);
}
// Force airdodge
u64 WorkModule_enable_transition_term_group_replace(u64 module_accessor,
u64 transition_group) {
if (TOGGLE_STATE == MASH_AIRDODGE && is_training_mode()) {
// 0x1F00000D for airdodge
if (transition_group == 0x1F00000D) {
if (is_operation_cpu(module_accessor)) {
int status_kind = StatusModule::status_kind(module_accessor);
// Damage -> DamageFall
if (status_kind >= 0x48 && status_kind <= 0x50) {
StatusModule::change_status_request_from_script(module_accessor, 0x22, 1);
}
}
}
}
// call original WorkModule::enable_transition_term_group_impl
u64 work_module = LOAD64(module_accessor + 0x50);
u64 enable_transition_term_group_impl = LOAD64(work_module) + 0x140LL;
u64 (*work_module_enable_transition_term_group_impl)(u64, u64) =
(u64(*)(u64, u64))(LOAD64(enable_transition_term_group_impl));
return work_module_enable_transition_term_group_impl(work_module,
transition_group);
}
// Force DI
float WorkModule_get_float_replace(u64 module_accessor, int var) {
if (is_training_mode() && DI_STATE != NONE) {
if (is_operation_cpu(module_accessor)) {
int status_kind = StatusModule::status_kind(module_accessor);
// Damage -> DamageFall
if (status_kind >= 0x48 && status_kind <= 0x50) {
float angle = (DI_STATE - 1) * M_PI / 4.0;
// 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 = LOAD64(module_accessor + 0x50);
u64 get_float_impl = LOAD64(work_module) + 0x58LL;
float (*work_module_get_float_impl)(u64, int) =
(float (*)(u64, int))(LOAD64(get_float_impl));
return work_module_get_float_impl(work_module, var);
(u64)&WorkModule::get_float_replace);
}