#ifndef ACMD_WRAPPER_H #define ACMD_WRAPPER_H #include #include "imports/app/lua_bind.hpp" #include "imports/app/sv_animcmd.hpp" #include "imports/app/sv_math.hpp" #include "imports/app/sv_system.hpp" #include "imports/lib/l2c.hpp" #include using namespace lib; u64 load_module(u64 module_accessor, u64 module_offset) { return LOAD64(module_accessor + module_offset); } void* load_module_impl(u64 module, u64 function_offset) { u64 function_impl = LOAD64(module) + function_offset; return (void*)LOAD64(function_impl); } bool is_before_frame(u64 lua_state, float f) { u64 acmd_frame_obj = LOAD64(LOAD64(lua_state - 8) + 432LL); return *(float*)((*((u32*)acmd_frame_obj + 64) + 15) & 0xFFFFFFF0) < f; } struct ACMD { L2CAgent* l2c_agent; u64 module_accessor; ACMD(L2CAgent* agent) { l2c_agent = agent; module_accessor = app::sv_system::battle_object_module_accessor( l2c_agent->lua_state_agent); } void frame(float f) { l2c_agent->clear_lua_stack(); L2CValue frame_val(f); l2c_agent->push_lua_stack(&frame_val); app::sv_animcmd::frame(l2c_agent->lua_state_agent, f); l2c_agent->clear_lua_stack(); } // attempted reimplementation of sv_animcmd::frame bool _frame(float f) { u64 acmd_obj = LOAD64(LOAD64(l2c_agent->lua_state_agent - 8) + 432); if (!is_before_frame(l2c_agent->lua_state_agent, f)) return true; *(u8*)(acmd_obj + 47) = 3; LOAD64(acmd_obj + 48) = (u64)&is_before_frame; *(float*)(acmd_obj + 56) = f; u64 acmd_obj_other = LOAD64(acmd_obj); if (*(u8*)(acmd_obj_other + 664)) { void (*some_func)(u64) = (void (*)(u64))LOAD64( LOAD64(LOAD64(acmd_obj_other + 656)) + 16); some_func(LOAD64(acmd_obj_other + 656)); return true; } bool doThing = false; if (!*(u16*)(l2c_agent->lua_state_agent + 196)) { u64 v4 = LOAD64(l2c_agent->lua_state_agent + 32); *(u8*)(l2c_agent->lua_state_agent + 12) = 1; LOAD64(v4 + 56) = LOAD64(v4) - LOAD64(l2c_agent->lua_state_agent + 56); if (*(u8*)(v4 + 66) & 2) return true; doThing = true; } if (doThing || LOAD64(LOAD64(l2c_agent->lua_state_agent + 24) + 200) == l2c_agent->lua_state_agent) { // throw u64 v4 = LOAD64(l2c_agent->lua_state_agent + 32); LOAD64(v4 + 32) = 0; LOAD64(v4) = LOAD64(l2c_agent->lua_state_agent + 16) - 16; } return false; // throw } void wait(float f) { l2c_agent->clear_lua_stack(); L2CValue frame_val(f); l2c_agent->push_lua_stack(&frame_val); app::sv_animcmd::wait(l2c_agent->lua_state_agent, f); l2c_agent->clear_lua_stack(); } bool is_excute() { l2c_agent->clear_lua_stack(); app::sv_animcmd::is_excute(l2c_agent->lua_state_agent); L2CValue is_excute; l2c_agent->get_lua_stack(1, &is_excute); bool excute = (bool)(is_excute); l2c_agent->clear_lua_stack(); return excute; } void wrap(u64 (*acmd_func)(u64), std::initializer_list list) { l2c_agent->clear_lua_stack(); for (L2CValue elem : list) l2c_agent->push_lua_stack(&elem); acmd_func(l2c_agent->lua_state_agent); l2c_agent->clear_lua_stack(); } void ATTACK(u64 i1, // ID u64 i2, // Part u64 h1, // Bone float f1, // Damage u64 i3, // Angle u64 i4, // KBG u64 i5, // FKB u64 i6, // BKB float f2, // Size float f3, // X float f4, // Y float f5, // Z // X2 // Y2 // Z2 float f6, // Hitlag float f7, // SDI u64 i7, // Clang/Rebound u64 i8, // Facing Restriction u64 i9, // Fixed Weight u64 i10, // Shield Damage float f8, // Trip Chance u64 i11, // Rehite Rate u64 i12, // Reflectable u64 i13, // Absorbable u64 i14, // Flinchless u64 i15, // Disable Hitlag u64 i16, // Direct u64 i17, // Ground/Air u64 i18, // Hit Bits u64 i19, // Collision Bits u64 i20, // Friendly Fire u64 h2, // Effect u64 i21, // SFX Level u64 i22, // SFX Type u64 i23) { // Move Type wrap(app::sv_animcmd::ATTACK, {L2CValue(i1), L2CValue(i2), L2CValue(h1), L2CValue(f1), L2CValue(i3), L2CValue(i4), L2CValue(i5), L2CValue(i6), L2CValue(f2), L2CValue(f3), L2CValue(f4), L2CValue(f5), L2CValue("void"), L2CValue("void"), L2CValue("void"), L2CValue(f6), L2CValue(f7), L2CValue(i7), L2CValue(i8), L2CValue(i9), L2CValue(i10), L2CValue(f8), L2CValue(i11), L2CValue(i12), L2CValue(i13), L2CValue(i14), L2CValue(i15), L2CValue(i16), L2CValue(i17), L2CValue(i18), L2CValue(i19), L2CValue(i20), L2CValue(h2), L2CValue(i21), L2CValue(i22), L2CValue(i23)}); } void ATTACK(u64 i1, // ID u64 i2, // Part u64 h1, // Bone float f1, // Damage u64 i3, // Angle u64 i4, // KBG u64 i5, // FKB u64 i6, // BKB float f2, // Size float f3, // X float f4, // Y float f5, // Z float fX2, // X2 float fY2, // Y2 float fZ2, // Z2 float f6, // Hitlag float f7, // SDI u64 i7, // Clang/Rebound u64 i8, // Facing Restriction u64 i9, // Fixed Weight u64 i10, // Shield Damage float f8, // Trip Chance u64 i11, // Rehite Rate u64 i12, // Reflectable u64 i13, // Absorbable u64 i14, // Flinchless u64 i15, // Disable Hitlag u64 i16, // Direct u64 i17, // Ground/Air u64 i18, // Hit Bits u64 i19, // Collision Bits u64 i20, // Friendly Fire u64 h2, // Effect u64 i21, // SFX Level u64 i22, // SFX Type u64 i23) { // Move Type wrap(app::sv_animcmd::ATTACK, {L2CValue(i1), L2CValue(i2), L2CValue(h1), L2CValue(f1), L2CValue(i3), L2CValue(i4), L2CValue(i5), L2CValue(i6), L2CValue(f2), L2CValue(f3), L2CValue(f4), L2CValue(f5), L2CValue(fX2), L2CValue(fY2), L2CValue(fZ2), L2CValue(f6), L2CValue(f7), L2CValue(i7), L2CValue(i8), L2CValue(i9), L2CValue(i10), L2CValue(f8), L2CValue(i11), L2CValue(i12), L2CValue(i13), L2CValue(i14), L2CValue(i15), L2CValue(i16), L2CValue(i17), L2CValue(i18), L2CValue(i19), L2CValue(i20), L2CValue(h2), L2CValue(i21), L2CValue(i22), L2CValue(i23)}); } }; #endif // ACMD_WRAPPER_H