mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2025-01-31 22:47:25 +00:00
change formatting (google style, 4 tab size)
This commit is contained in:
parent
1e9762d0d8
commit
aa23f87d6b
7 changed files with 971 additions and 984 deletions
|
@ -3,10 +3,10 @@
|
|||
|
||||
#include <switch.h>
|
||||
|
||||
#include "imports/app/sv_animcmd.hpp"
|
||||
#include "imports/app/sv_system.hpp"
|
||||
#include "imports/app/sv_math.hpp"
|
||||
#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 <initializer_list>
|
||||
|
@ -14,71 +14,71 @@
|
|||
using namespace lib;
|
||||
|
||||
u64 load_module(u64 module_accessor, u64 module_offset) {
|
||||
return LOAD64(module_accessor + 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);
|
||||
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;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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();
|
||||
}
|
||||
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) {
|
||||
// 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;
|
||||
|
||||
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);
|
||||
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)) {
|
||||
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;
|
||||
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
|
||||
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;
|
||||
|
@ -86,132 +86,130 @@ struct ACMD {
|
|||
// 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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
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<L2CValue> list) {
|
||||
l2c_agent->clear_lua_stack();
|
||||
for (L2CValue elem : list)
|
||||
l2c_agent->push_lua_stack(&elem);
|
||||
void wrap(u64 (*acmd_func)(u64), std::initializer_list<L2CValue> 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();
|
||||
}
|
||||
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
|
||||
// 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)
|
||||
});
|
||||
}
|
||||
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
|
||||
#endif // ACMD_WRAPPER_H
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
#include "useful/useful.h"
|
||||
#include "useful/visual.h"
|
||||
|
||||
#include "imports/lib/l2c.hpp"
|
||||
#include "acmd_wrapper.hpp"
|
||||
#include "imports/lib/l2c.hpp"
|
||||
#include "saltysd/saltysd_helper.hpp"
|
||||
#include "useful/const_value_table.h"
|
||||
#include "taunt_toggles.h"
|
||||
#include "useful/const_value_table.h"
|
||||
|
||||
#include "useful/raygun_printer.hpp"
|
||||
|
||||
|
@ -23,273 +23,286 @@ u64 effect_manager_addr;
|
|||
void (*AttackModule_set_attack_lua_state)(u64, u64);
|
||||
u64 Catch_jumpback;
|
||||
|
||||
Vector3f ID_COLORS[8] = { // used to tint the hitbox effects -- make sure that at least one component is equal to 1.0
|
||||
{ 1.0f, 0.0f, 0.0f }, // #ff0000 (red)
|
||||
{ 1.0f, 0.4f, 0.0f }, // #ff9900 (orange)
|
||||
{ 0.8f, 1.0f, 0.0f }, // #ccff00 (yellow)
|
||||
{ 0.2f, 1.0f, 0.2f }, // #00ff33 (green)
|
||||
{ 0.0f, 0.8f, 1.0f }, // #00ccff (sky blue)
|
||||
{ 0.4f, 0.4f, 1.0f }, // #6666ff (blue)
|
||||
{ 0.8f, 0.0f, 1.0f }, // #cc00ff (purple)
|
||||
{ 1.0f, 0.2f, 0.8f }, // #ff33cc (pink)
|
||||
Vector3f ID_COLORS[8] = {
|
||||
// used to tint the hitbox effects -- make sure that at least one component
|
||||
// is equal to 1.0
|
||||
{1.0f, 0.0f, 0.0f}, // #ff0000 (red)
|
||||
{1.0f, 0.4f, 0.0f}, // #ff9900 (orange)
|
||||
{0.8f, 1.0f, 0.0f}, // #ccff00 (yellow)
|
||||
{0.2f, 1.0f, 0.2f}, // #00ff33 (green)
|
||||
{0.0f, 0.8f, 1.0f}, // #00ccff (sky blue)
|
||||
{0.4f, 0.4f, 1.0f}, // #6666ff (blue)
|
||||
{0.8f, 0.0f, 1.0f}, // #cc00ff (purple)
|
||||
{1.0f, 0.2f, 0.8f}, // #ff33cc (pink)
|
||||
};
|
||||
int MAX_EFFECTS_PER_HITBOX = 16; // max # of circles drawn for an extended hitbox
|
||||
int MAX_EFFECTS_PER_HITBOX = 16; // max # of circles drawn for an extended hitbox
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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));
|
||||
// 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);
|
||||
}
|
||||
return clear_all(attack_module);
|
||||
}
|
||||
} // namespace app::lua_bind::AttackModule
|
||||
|
||||
namespace app::lua_bind::GrabModule {
|
||||
// clear graphics every time we clear rebound
|
||||
void set_rebound_replace(u64 module_accessor, bool rebound) {
|
||||
if (is_training_mode() && rebound == false) {
|
||||
// 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 GrabModule::set_rebound_impl
|
||||
u64 grab_module = load_module(module_accessor, 0x158);
|
||||
void (*set_rebound)(u64, bool) = (void(*)(u64, bool))(load_module_impl(grab_module, 0x100));
|
||||
|
||||
return set_rebound(grab_module, rebound);
|
||||
}
|
||||
}
|
||||
|
||||
Vector3f EffectModule_last_get_scale_w(u64 effect_module)
|
||||
{
|
||||
Vector3f ret;
|
||||
uint handle = *(uint *)(effect_module + 36);
|
||||
if ( handle && (signed int)handle >= 1 )
|
||||
{
|
||||
u64 effect = LOAD64(effect_manager_addr) + 768 * (handle >> 24);
|
||||
bool is_exist_effect = effect && *(uint *)(effect + 4) == handle;
|
||||
if ( is_exist_effect )
|
||||
{
|
||||
float* scale = (float*)(effect + 256);
|
||||
ret.x = *(float *)(scale);
|
||||
ret.y = *(float *)(scale+1);
|
||||
ret.z = *(float *)(scale+2);
|
||||
// clear graphics every time we clear rebound
|
||||
void set_rebound_replace(u64 module_accessor, bool rebound) {
|
||||
if (is_training_mode() && rebound == false) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
// call original GrabModule::set_rebound_impl
|
||||
u64 grab_module = load_module(module_accessor, 0x158);
|
||||
void (*set_rebound)(u64, bool) =
|
||||
(void (*)(u64, bool))(load_module_impl(grab_module, 0x100));
|
||||
|
||||
return set_rebound(grab_module, rebound);
|
||||
}
|
||||
} // namespace app::lua_bind::GrabModule
|
||||
|
||||
Vector3f EffectModule_last_get_scale_w(u64 effect_module) {
|
||||
Vector3f ret;
|
||||
uint handle = *(uint *)(effect_module + 36);
|
||||
if (handle && (signed int)handle >= 1) {
|
||||
u64 effect = LOAD64(effect_manager_addr) + 768 * (handle >> 24);
|
||||
bool is_exist_effect = effect && *(uint *)(effect + 4) == handle;
|
||||
if (is_exist_effect) {
|
||||
float *scale = (float *)(effect + 256);
|
||||
ret.x = *(float *)(scale);
|
||||
ret.y = *(float *)(scale + 1);
|
||||
ret.z = *(float *)(scale + 2);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void generate_hitbox_effects(L2CAgent *l2c_agent, L2CValue *bone, L2CValue *size,
|
||||
L2CValue *x, L2CValue *y, L2CValue *z, L2CValue *x2, L2CValue *y2, L2CValue *z2,
|
||||
Vector3f *color) {
|
||||
L2CValue red(color->x);
|
||||
L2CValue green(color->y);
|
||||
L2CValue blue(color->z);
|
||||
void generate_hitbox_effects(L2CAgent *l2c_agent, L2CValue *bone,
|
||||
L2CValue *size, L2CValue *x, L2CValue *y,
|
||||
L2CValue *z, L2CValue *x2, L2CValue *y2,
|
||||
L2CValue *z2, Vector3f *color) {
|
||||
L2CValue red(color->x);
|
||||
L2CValue green(color->y);
|
||||
L2CValue blue(color->z);
|
||||
|
||||
float size_mult = 19.0f / 200.0f;
|
||||
Hash40 shield_effect_hash = { .hash = 0xAFAE75F05LL };
|
||||
float size_mult = 19.0f / 200.0f;
|
||||
Hash40 shield_effect_hash = {.hash = 0xAFAE75F05LL};
|
||||
|
||||
L2CValue shieldEffect(shield_effect_hash.hash);
|
||||
L2CValue x_rot(0.0f);
|
||||
L2CValue y_rot(0.0f);
|
||||
L2CValue z_rot(0.0f);
|
||||
L2CValue terminate(true);
|
||||
L2CValue effect_size((float)size->raw_float * size_mult);
|
||||
L2CValue shieldEffect(shield_effect_hash.hash);
|
||||
L2CValue x_rot(0.0f);
|
||||
L2CValue y_rot(0.0f);
|
||||
L2CValue z_rot(0.0f);
|
||||
L2CValue terminate(true);
|
||||
L2CValue effect_size((float)size->raw_float * size_mult);
|
||||
|
||||
L2CValue rate(8.0f);
|
||||
L2CValue rate(8.0f);
|
||||
|
||||
float x_dist, y_dist, z_dist;
|
||||
int n_effects;
|
||||
if (x2->type != L2C_void && y2->type != L2C_void && z2->type != L2C_void) { // extended hitbox
|
||||
x_dist = x2->raw_float - x->raw_float;
|
||||
y_dist = y2->raw_float - y->raw_float;
|
||||
z_dist = z2->raw_float - z->raw_float;
|
||||
float dist = sqrtf(x_dist * x_dist + y_dist * y_dist + z_dist * z_dist);
|
||||
n_effects = (int)ceilf(dist / (size->raw_float * 1.75f)) + 1; // just enough effects to form a continuous line
|
||||
if (n_effects < 2)
|
||||
n_effects = 2;
|
||||
if (n_effects > MAX_EFFECTS_PER_HITBOX)
|
||||
n_effects = MAX_EFFECTS_PER_HITBOX;
|
||||
} else { // non-extended hitbox
|
||||
x_dist = y_dist = z_dist = 0;
|
||||
n_effects = 1;
|
||||
}
|
||||
float x_dist, y_dist, z_dist;
|
||||
int n_effects;
|
||||
if (x2->type != L2C_void && y2->type != L2C_void &&
|
||||
z2->type != L2C_void) { // extended hitbox
|
||||
x_dist = x2->raw_float - x->raw_float;
|
||||
y_dist = y2->raw_float - y->raw_float;
|
||||
z_dist = z2->raw_float - z->raw_float;
|
||||
float dist = sqrtf(x_dist * x_dist + y_dist * y_dist + z_dist * z_dist);
|
||||
n_effects = (int)ceilf(dist / (size->raw_float * 1.75f)) + 1; // just enough effects to form a continuous line
|
||||
if (n_effects < 2) n_effects = 2;
|
||||
if (n_effects > MAX_EFFECTS_PER_HITBOX)
|
||||
n_effects = MAX_EFFECTS_PER_HITBOX;
|
||||
} else { // non-extended hitbox
|
||||
x_dist = y_dist = z_dist = 0;
|
||||
n_effects = 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_effects; i++) {
|
||||
float t = n_effects <= 1 ? 0 : (float)i / (n_effects - 1);
|
||||
L2CValue x_curr(x->raw_float + x_dist * t);
|
||||
L2CValue y_curr(y->raw_float + y_dist * t);
|
||||
L2CValue z_curr(z->raw_float + z_dist * t);
|
||||
for (int i = 0; i < n_effects; i++) {
|
||||
float t = n_effects <= 1 ? 0 : (float)i / (n_effects - 1);
|
||||
L2CValue x_curr(x->raw_float + x_dist * t);
|
||||
L2CValue y_curr(y->raw_float + y_dist * t);
|
||||
L2CValue z_curr(z->raw_float + z_dist * t);
|
||||
|
||||
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 });
|
||||
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});
|
||||
|
||||
// speed up animation by rate to remove pulsing effect
|
||||
acmd.wrap(LAST_EFFECT_SET_RATE, { rate });
|
||||
}
|
||||
// set to hitbox ID color
|
||||
acmd.wrap(LAST_EFFECT_SET_COLOR, {red, green, blue});
|
||||
|
||||
// speed up animation by rate to remove pulsing effect
|
||||
acmd.wrap(LAST_EFFECT_SET_RATE, {rate});
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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, fkb, bkb, size, x, y, z, x2, y2, z2;
|
||||
l2c_agent.get_lua_stack(1, &id); // int
|
||||
l2c_agent.get_lua_stack(3, &bone); // hash40
|
||||
l2c_agent.get_lua_stack(4, &damage); // float
|
||||
l2c_agent.get_lua_stack(5, &angle); // int
|
||||
l2c_agent.get_lua_stack(6, &kbg); // int
|
||||
l2c_agent.get_lua_stack(7, &fkb); // int
|
||||
l2c_agent.get_lua_stack(8, &bkb); // int
|
||||
l2c_agent.get_lua_stack(9, &size); // float
|
||||
l2c_agent.get_lua_stack(10, &x); // float
|
||||
l2c_agent.get_lua_stack(11, &y); // float
|
||||
l2c_agent.get_lua_stack(12, &z); // float
|
||||
l2c_agent.get_lua_stack(13, &x2); // float or void
|
||||
l2c_agent.get_lua_stack(14, &y2); // float or void
|
||||
l2c_agent.get_lua_stack(15, &z2); // float or void
|
||||
// get all necessary hitbox params
|
||||
L2CValue id, bone, damage, angle, kbg, fkb, bkb, size, x, y, z, x2, y2, z2;
|
||||
l2c_agent.get_lua_stack(1, &id); // int
|
||||
l2c_agent.get_lua_stack(3, &bone); // hash40
|
||||
l2c_agent.get_lua_stack(4, &damage); // float
|
||||
l2c_agent.get_lua_stack(5, &angle); // int
|
||||
l2c_agent.get_lua_stack(6, &kbg); // int
|
||||
l2c_agent.get_lua_stack(7, &fkb); // int
|
||||
l2c_agent.get_lua_stack(8, &bkb); // int
|
||||
l2c_agent.get_lua_stack(9, &size); // float
|
||||
l2c_agent.get_lua_stack(10, &x); // float
|
||||
l2c_agent.get_lua_stack(11, &y); // float
|
||||
l2c_agent.get_lua_stack(12, &z); // float
|
||||
l2c_agent.get_lua_stack(13, &x2); // float or void
|
||||
l2c_agent.get_lua_stack(14, &y2); // float or void
|
||||
l2c_agent.get_lua_stack(15, &z2); // float or void
|
||||
|
||||
// hacky way of forcing no shield damage on all hitboxes
|
||||
if (is_training_mode() && TOGGLE_STATE == INFINITE_SHIELD) {
|
||||
L2CValue hitbox_params[36];
|
||||
for (size_t i = 0; i < 36; i++)
|
||||
l2c_agent.get_lua_stack(i+1, &hitbox_params[i]);
|
||||
|
||||
l2c_agent.clear_lua_stack();
|
||||
// hacky way of forcing no shield damage on all hitboxes
|
||||
if (is_training_mode() && TOGGLE_STATE == INFINITE_SHIELD) {
|
||||
L2CValue hitbox_params[36];
|
||||
for (size_t i = 0; i < 36; i++)
|
||||
l2c_agent.get_lua_stack(i + 1, &hitbox_params[i]);
|
||||
|
||||
for (size_t i = 0; i < 36; i++) {
|
||||
if (i == 20) {
|
||||
L2CValue no_shield_damage(-999);
|
||||
l2c_agent.push_lua_stack(&no_shield_damage);
|
||||
}
|
||||
else
|
||||
l2c_agent.push_lua_stack(&hitbox_params[i]);
|
||||
}
|
||||
}
|
||||
l2c_agent.clear_lua_stack();
|
||||
|
||||
// original code: parse lua stack and call AttackModule::set_attack()
|
||||
AttackModule_set_attack_lua_state(LOAD64(LOAD64(a1 - 8) + 416LL), a1);
|
||||
for (size_t i = 0; i < 36; i++) {
|
||||
if (i == 20) {
|
||||
L2CValue no_shield_damage(-999);
|
||||
l2c_agent.push_lua_stack(&no_shield_damage);
|
||||
} else
|
||||
l2c_agent.push_lua_stack(&hitbox_params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (HITBOX_VIS && is_training_mode()) { // generate hitbox effect(s)
|
||||
float color_scale;
|
||||
if (false) { // color intensity scales with damage
|
||||
color_scale = unlerp_bounded(1.0f, 18.0f, damage.raw_float);
|
||||
} else { // color intensity scales with total KB
|
||||
// calculate the expected KB a character with 95 weight will receive at 80% pre-hit
|
||||
float TARGET_PERCENT = 80.0f;
|
||||
int TARGET_WEIGHT = 95;
|
||||
float percent_component;
|
||||
if (fkb.raw > 0) {
|
||||
percent_component = (10.0f + fkb.raw) * 0.1f * (1.0f + fkb.raw * 0.5f);
|
||||
} else {
|
||||
percent_component = (TARGET_PERCENT + damage.raw_float) * 0.1f * (1.0f + damage.raw_float * 0.5f);
|
||||
}
|
||||
float weight_component = 200.0f / (TARGET_WEIGHT + 100);
|
||||
float kb = (percent_component * weight_component * 1.4f + 18.0f) * (kbg.raw * 0.01f) + bkb.raw;
|
||||
color_scale = unlerp_bounded(50.0f, 200.0f, kb);
|
||||
}
|
||||
float color_t = 0.8f + 0.2f * powf(color_scale, 0.5f); // non-linear scaling to magnify differences at lower values
|
||||
Vector3f color = color_lerp({ 1.0f, 1.0f, 1.0f }, ID_COLORS[id.raw % 8], color_t);
|
||||
generate_hitbox_effects(&l2c_agent, &bone, &size, &x, &y, &z, &x2, &y2, &z2, &color);
|
||||
}
|
||||
// original code: parse lua stack and call AttackModule::set_attack()
|
||||
AttackModule_set_attack_lua_state(LOAD64(LOAD64(a1 - 8) + 416LL), a1);
|
||||
|
||||
u64 v1, v2, i;
|
||||
v1 = a1;
|
||||
if (HITBOX_VIS && is_training_mode()) { // generate hitbox effect(s)
|
||||
float color_scale;
|
||||
if (false) { // color intensity scales with damage
|
||||
color_scale = unlerp_bounded(1.0f, 18.0f, damage.raw_float);
|
||||
} else { // color intensity scales with total KB
|
||||
// calculate the expected KB a character with 95 weight will receive
|
||||
// at 80% pre-hit
|
||||
float TARGET_PERCENT = 80.0f;
|
||||
int TARGET_WEIGHT = 95;
|
||||
float percent_component;
|
||||
if (fkb.raw > 0) {
|
||||
percent_component =
|
||||
(10.0f + fkb.raw) * 0.1f * (1.0f + fkb.raw * 0.5f);
|
||||
} else {
|
||||
percent_component = (TARGET_PERCENT + damage.raw_float) * 0.1f *
|
||||
(1.0f + damage.raw_float * 0.5f);
|
||||
}
|
||||
float weight_component = 200.0f / (TARGET_WEIGHT + 100);
|
||||
float kb = (percent_component * weight_component * 1.4f + 18.0f) *
|
||||
(kbg.raw * 0.01f) +
|
||||
bkb.raw;
|
||||
color_scale = unlerp_bounded(50.0f, 200.0f, kb);
|
||||
}
|
||||
float color_t =
|
||||
0.8f +
|
||||
0.2f * powf(color_scale, 0.5f); // non-linear scaling to magnify
|
||||
// differences at lower values
|
||||
Vector3f color = color_lerp({1.0f, 1.0f, 1.0f}, ID_COLORS[id.raw % 8], color_t);
|
||||
generate_hitbox_effects(&l2c_agent, &bone, &size, &x, &y, &z, &x2, &y2, &z2, &color);
|
||||
}
|
||||
|
||||
// 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 CATCH_replace(u64 a1) {
|
||||
L2CAgent l2c_agent;
|
||||
l2c_agent.L2CAgent_constr(a1);
|
||||
|
||||
// get all necessary grabbox params
|
||||
L2CValue id, joint, size, x, y, z, x2, y2, z2;
|
||||
l2c_agent.get_lua_stack(1, &id); // int
|
||||
l2c_agent.get_lua_stack(2, &joint); // hash40
|
||||
l2c_agent.get_lua_stack(3, &size); // float
|
||||
l2c_agent.get_lua_stack(4, &x); // float
|
||||
l2c_agent.get_lua_stack(5, &y); // float
|
||||
l2c_agent.get_lua_stack(6, &z); // float
|
||||
l2c_agent.get_lua_stack(7, &x2); // float or void
|
||||
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()) {
|
||||
Vector3f color = ID_COLORS[(id.raw + 3) % 8];
|
||||
generate_hitbox_effects(&l2c_agent, &joint, &size, &x, &y, &z, &x2, &y2, &z2, &color);
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
void CATCH_replace(u64 a1) {
|
||||
L2CAgent l2c_agent;
|
||||
l2c_agent.L2CAgent_constr(a1);
|
||||
|
||||
// get all necessary grabbox params
|
||||
L2CValue id, joint, size, x, y, z, x2, y2, z2;
|
||||
l2c_agent.get_lua_stack(1, &id); // int
|
||||
l2c_agent.get_lua_stack(2, &joint); // hash40
|
||||
l2c_agent.get_lua_stack(3, &size); // float
|
||||
l2c_agent.get_lua_stack(4, &x); // float
|
||||
l2c_agent.get_lua_stack(5, &y); // float
|
||||
l2c_agent.get_lua_stack(6, &z); // float
|
||||
l2c_agent.get_lua_stack(7, &x2); // float or void
|
||||
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()) {
|
||||
Vector3f color = ID_COLORS[(id.raw + 3) % 8];
|
||||
generate_hitbox_effects(&l2c_agent, &joint, &size, &x, &y, &z, &x2, &y2, &z2, &color);
|
||||
}
|
||||
}
|
||||
} // namespace app::sv_animcmd
|
||||
|
||||
void hitbox_vis_main() {
|
||||
effect_manager_addr = SaltySDCore_FindSymbol("_ZN3lib9SingletonINS_13EffectManagerEE9instance_E");
|
||||
effect_manager_addr = SaltySDCore_FindSymbol(
|
||||
"_ZN3lib9SingletonINS_13EffectManagerEE9instance_E");
|
||||
|
||||
AttackModule_set_attack_lua_state = (void (*)(u64, u64))SaltySDCore_FindSymbol("_ZN3app10sv_animcmd6ATTACKEP9lua_State") + 0xD0 - 0x70;
|
||||
Catch_jumpback = SaltySDCore_FindSymbol("_ZN3app10sv_animcmd5CATCHEP9lua_State") + (4*4);
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app10sv_animcmd6ATTACKEP9lua_State",
|
||||
(u64)&ATTACK_replace);
|
||||
AttackModule_set_attack_lua_state = (void (*)(u64, u64))SaltySDCore_FindSymbol("_ZN3app10sv_animcmd6ATTACKEP9lua_State") +
|
||||
0xD0 - 0x70;
|
||||
Catch_jumpback = SaltySDCore_FindSymbol("_ZN3app10sv_animcmd5CATCHEP9lua_State") + (4 * 4);
|
||||
SaltySD_function_replace_sym("_ZN3app10sv_animcmd6ATTACKEP9lua_State",
|
||||
(u64)&ATTACK_replace);
|
||||
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app10sv_animcmd5CATCHEP9lua_State",
|
||||
(u64)&CATCH_replace);
|
||||
SaltySD_function_replace_sym("_ZN3app10sv_animcmd5CATCHEP9lua_State",
|
||||
(u64)&CATCH_replace);
|
||||
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind28AttackModule__clear_all_implEPNS_26BattleObjectModuleAccessorE",
|
||||
(u64)&AttackModule::clear_all_replace);
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind28AttackModule__clear_all_implEPNS_26BattleObjectModuleAccessorE",
|
||||
(u64)&AttackModule::clear_all_replace);
|
||||
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind28GrabModule__set_rebound_implEPNS_26BattleObjectModuleAccessorEb",
|
||||
(u64)&GrabModule::set_rebound_replace);
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind28GrabModule__set_rebound_implEPNS_26BattleObjectModuleAccessorEb",
|
||||
(u64)&GrabModule::set_rebound_replace);
|
||||
}
|
||||
|
||||
#endif // HITBOX_VISUALIZER_H
|
||||
#endif // HITBOX_VISUALIZER_H
|
||||
|
|
112
source/main.cpp
112
source/main.cpp
|
@ -1,36 +1,36 @@
|
|||
#include <switch.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <switch/kernel/ipc.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <sys/reent.h>
|
||||
#include <switch/kernel/ipc.h>
|
||||
|
||||
#include "useful/useful.h"
|
||||
|
||||
#include "saltysd/saltysd_core.h"
|
||||
#include "saltysd/saltysd_ipc.h"
|
||||
#include "saltysd/saltysd_dynamic.h"
|
||||
#include "saltysd/saltysd_ipc.h"
|
||||
|
||||
#include "saltysd/saltysd_helper.hpp"
|
||||
#include "imports/lib/l2c.hpp"
|
||||
#include "imports/app/sv_animcmd.hpp"
|
||||
#include "imports/lib/l2c.hpp"
|
||||
#include "saltysd/saltysd_helper.hpp"
|
||||
|
||||
#include "hitbox_visualizer.hpp"
|
||||
#include "script_replacement.hpp"
|
||||
#include "training_mods.hpp"
|
||||
|
||||
extern "C" {
|
||||
extern u32 __start__;
|
||||
extern u32 __start__;
|
||||
|
||||
static char g_heap[0x8000];
|
||||
static char g_heap[0x8000];
|
||||
|
||||
void __libnx_init(void* ctx, Handle main_thread, void* saved_lr);
|
||||
void __attribute__((weak)) NORETURN __libnx_exit(int rc);
|
||||
void __nx_exit(int, void*);
|
||||
void __libc_fini_array(void);
|
||||
void __libc_init_array(void);
|
||||
void __libnx_init(void* ctx, Handle main_thread, void* saved_lr);
|
||||
void __attribute__((weak)) NORETURN __libnx_exit(int rc);
|
||||
void __nx_exit(int, void*);
|
||||
void __libc_fini_array(void);
|
||||
void __libc_init_array(void);
|
||||
}
|
||||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
|
@ -40,57 +40,59 @@ void* orig_ctx;
|
|||
void* orig_saved_lr;
|
||||
|
||||
void __libnx_init(void* ctx, Handle main_thread, void* saved_lr) {
|
||||
extern char* fake_heap_start;
|
||||
extern char* fake_heap_end;
|
||||
extern char* fake_heap_start;
|
||||
extern char* fake_heap_end;
|
||||
|
||||
fake_heap_start = &g_heap[0];
|
||||
fake_heap_end = &g_heap[sizeof g_heap];
|
||||
|
||||
orig_ctx = ctx;
|
||||
orig_main_thread = main_thread;
|
||||
orig_saved_lr = saved_lr;
|
||||
|
||||
// Call constructors.
|
||||
//void __libc_init_array(void);
|
||||
__libc_init_array();
|
||||
fake_heap_start = &g_heap[0];
|
||||
fake_heap_end = &g_heap[sizeof g_heap];
|
||||
|
||||
orig_ctx = ctx;
|
||||
orig_main_thread = main_thread;
|
||||
orig_saved_lr = saved_lr;
|
||||
|
||||
// Call constructors.
|
||||
// void __libc_init_array(void);
|
||||
__libc_init_array();
|
||||
}
|
||||
|
||||
void __attribute__((weak)) NORETURN __libnx_exit(int rc) {
|
||||
// Call destructors.
|
||||
//void __libc_fini_array(void);
|
||||
__libc_fini_array();
|
||||
// Call destructors.
|
||||
// void __libc_fini_array(void);
|
||||
__libc_fini_array();
|
||||
|
||||
SaltySD_printf("SaltySD Plugin: jumping to %p\n", orig_saved_lr);
|
||||
SaltySD_printf("SaltySD Plugin: jumping to %p\n", orig_saved_lr);
|
||||
|
||||
__nx_exit(0, orig_saved_lr);
|
||||
while (true);
|
||||
__nx_exit(0, orig_saved_lr);
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SaltySD_printf("SaltySD Plugin: alive\n");
|
||||
|
||||
// Get anchor for imports
|
||||
// do not remove if you plan on using IMPORT
|
||||
ANCHOR_ABS = SaltySDCore_getCodeStart();
|
||||
int main(int argc, char* argv[]) {
|
||||
SaltySD_printf("SaltySD Plugin: alive\n");
|
||||
|
||||
/*
|
||||
Example of string replacement:
|
||||
replaces the title screen's version number with the string
|
||||
below.
|
||||
*/
|
||||
|
||||
const char *ver = "Ver. %d.%d.%d";
|
||||
u64 version_string = SaltySDCore_findCode((u8 *)ver, strlen(ver));
|
||||
if (version_string) {
|
||||
SaltySD_Memcpy(version_string, (u64) "Salty v%d%d%d", 13);
|
||||
}
|
||||
// Get anchor for imports
|
||||
// do not remove if you plan on using IMPORT
|
||||
ANCHOR_ABS = SaltySDCore_getCodeStart();
|
||||
|
||||
// Necessary for script replacement
|
||||
SaltySD_function_replace_sym("_ZN3lib8L2CAgent15clear_lua_stackEv", (u64) &clear_lua_stack_replace);
|
||||
|
||||
// Add function replacements here
|
||||
hitbox_vis_main();
|
||||
training_mods_main();
|
||||
/*
|
||||
Example of string replacement:
|
||||
replaces the title screen's version number with the string
|
||||
below.
|
||||
*/
|
||||
|
||||
__libnx_exit(0);
|
||||
const char* ver = "Ver. %d.%d.%d";
|
||||
u64 version_string = SaltySDCore_findCode((u8*)ver, strlen(ver));
|
||||
if (version_string) {
|
||||
SaltySD_Memcpy(version_string, (u64) "Salty v%d%d%d", 13);
|
||||
}
|
||||
|
||||
// Necessary for script replacement
|
||||
SaltySD_function_replace_sym("_ZN3lib8L2CAgent15clear_lua_stackEv",
|
||||
(u64)&clear_lua_stack_replace);
|
||||
|
||||
// Add function replacements here
|
||||
hitbox_vis_main();
|
||||
training_mods_main();
|
||||
|
||||
__libnx_exit(0);
|
||||
}
|
||||
|
|
|
@ -8,15 +8,16 @@
|
|||
#include "useful/const_value_table.h"
|
||||
#include "useful/raygun_printer.hpp"
|
||||
|
||||
#include "imports/lib/l2c.hpp"
|
||||
#include "acmd_wrapper.hpp"
|
||||
#include "imports/lib/l2c.hpp"
|
||||
|
||||
#include "taunt_toggles.h"
|
||||
|
||||
using namespace lib;
|
||||
using namespace app::lua_bind;
|
||||
|
||||
void sv_replace_status_func(u64 l2c_agentbase, int status_kind, u64 key, void* func);
|
||||
void sv_replace_status_func(u64 l2c_agentbase, int status_kind, u64 key,
|
||||
void* func);
|
||||
|
||||
u64 appeal_lw_replace(L2CAgent* l2c_agent, void* variadic);
|
||||
u64 appeal_hi_replace(L2CAgent* l2c_agent, void* variadic);
|
||||
|
@ -26,146 +27,128 @@ u64 pre_GuardDamage_replace(L2CAgent* l2c_fighter, L2CAgent* l2c_agent);
|
|||
void replace_scripts(L2CAgent* l2c_agent, u8 category, int kind) {
|
||||
// fighter
|
||||
if (category == BATTLE_OBJECT_CATEGORY_FIGHTER) {
|
||||
// taunt toggles
|
||||
l2c_agent->sv_set_function_hash(&appeal_lw_replace, hash40("effect_appeallwl"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_lw_replace, hash40("effect_appeallwr"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_hi_replace, hash40("effect_appealhil"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_hi_replace, hash40("effect_appealhir"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_s_replace, hash40("effect_appealsl"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_s_replace, hash40("effect_appealsr"));
|
||||
// taunt toggles
|
||||
l2c_agent->sv_set_function_hash(&appeal_lw_replace,
|
||||
hash40("effect_appeallwl"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_lw_replace,
|
||||
hash40("effect_appeallwr"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_hi_replace,
|
||||
hash40("effect_appealhil"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_hi_replace,
|
||||
hash40("effect_appealhir"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_s_replace,
|
||||
hash40("effect_appealsl"));
|
||||
l2c_agent->sv_set_function_hash(&appeal_s_replace,
|
||||
hash40("effect_appealsr"));
|
||||
}
|
||||
}
|
||||
|
||||
u64 appeal_lw_replace(L2CAgent* l2c_agent, void* variadic) {
|
||||
ACMD acmd = ACMD(l2c_agent);
|
||||
|
||||
|
||||
acmd.frame(1);
|
||||
if (acmd.is_excute()) {
|
||||
if (is_training_mode()) {
|
||||
TOGGLE_STATE = (TOGGLE_STATE + 1) % NUM_TOGGLE_STATES;
|
||||
const char* toggle_strings[NUM_TOGGLE_STATES] = {
|
||||
"NONE",
|
||||
"MASH\nAIRDODGE",
|
||||
"MASH\nJUMP",
|
||||
"MASH\nATTACK",
|
||||
"MASH\nRANDOM",
|
||||
"INFINITE\nSHIELD",
|
||||
"HOLD\nSHIELD",
|
||||
"LEDGE\nOPTION"
|
||||
};
|
||||
|
||||
print_string(acmd.module_accessor, toggle_strings[TOGGLE_STATE]);
|
||||
}
|
||||
if (is_training_mode()) {
|
||||
TOGGLE_STATE = (TOGGLE_STATE + 1) % NUM_TOGGLE_STATES;
|
||||
const char* toggle_strings[NUM_TOGGLE_STATES] = {
|
||||
"NONE", "MASH\nAIRDODGE", "MASH\nJUMP",
|
||||
"MASH\nATTACK", "MASH\nRANDOM", "INFINITE\nSHIELD",
|
||||
"HOLD\nSHIELD", "LEDGE\nOPTION"};
|
||||
|
||||
print_string(acmd.module_accessor, toggle_strings[TOGGLE_STATE]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 appeal_hi_replace(L2CAgent* l2c_agent, void* variadic) {
|
||||
ACMD acmd = ACMD(l2c_agent);
|
||||
ACMD acmd = ACMD(l2c_agent);
|
||||
|
||||
acmd.frame(1);
|
||||
if (acmd.is_excute()) {
|
||||
if (is_training_mode()) {
|
||||
HITBOX_VIS = !HITBOX_VIS;
|
||||
if (HITBOX_VIS)
|
||||
print_string(acmd.module_accessor, "HITBOX\nVIS");
|
||||
else
|
||||
print_string(acmd.module_accessor, "NO\nHITBOX");
|
||||
}
|
||||
}
|
||||
acmd.frame(1);
|
||||
if (acmd.is_excute()) {
|
||||
if (is_training_mode()) {
|
||||
HITBOX_VIS = !HITBOX_VIS;
|
||||
if (HITBOX_VIS)
|
||||
print_string(acmd.module_accessor, "HITBOX\nVIS");
|
||||
else
|
||||
print_string(acmd.module_accessor, "NO\nHITBOX");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 appeal_s_replace(L2CAgent* l2c_agent, void* variadic) {
|
||||
ACMD acmd = ACMD(l2c_agent);
|
||||
ACMD acmd = ACMD(l2c_agent);
|
||||
|
||||
acmd.frame(1);
|
||||
if (acmd.is_excute()) {
|
||||
if (is_training_mode()) {
|
||||
if (TOGGLE_STATE == LEDGE_OPTION) {
|
||||
LEDGE_STATE = (LEDGE_STATE + 1) % NUM_LEDGE_STATES;
|
||||
const char* LEDGE_strings[NUM_LEDGE_STATES] = {
|
||||
"RANDOM",
|
||||
"NORMAL",
|
||||
"ROLL",
|
||||
"JUMP",
|
||||
"ATTACK"
|
||||
};
|
||||
acmd.frame(1);
|
||||
if (acmd.is_excute()) {
|
||||
if (is_training_mode()) {
|
||||
if (TOGGLE_STATE == LEDGE_OPTION) {
|
||||
LEDGE_STATE = (LEDGE_STATE + 1) % NUM_LEDGE_STATES;
|
||||
const char* LEDGE_strings[NUM_LEDGE_STATES] = {
|
||||
"RANDOM", "NORMAL", "ROLL", "JUMP", "ATTACK"};
|
||||
|
||||
print_string(acmd.module_accessor, LEDGE_strings[LEDGE_STATE]);
|
||||
} else if (TOGGLE_STATE == MASH_ATTACK) {
|
||||
ATTACK_STATE = (ATTACK_STATE + 1) % NUM_ATTACK_STATES;
|
||||
const char* ATTACK_strings[NUM_ATTACK_STATES] = {
|
||||
"NAIR",
|
||||
"FAIR",
|
||||
"BAIR",
|
||||
"UPAIR",
|
||||
"DAIR",
|
||||
"NEUTRAL B",
|
||||
"SIDE B",
|
||||
"UP B",
|
||||
"DOWN B"
|
||||
};
|
||||
print_string(acmd.module_accessor, LEDGE_strings[LEDGE_STATE]);
|
||||
} else if (TOGGLE_STATE == MASH_ATTACK) {
|
||||
ATTACK_STATE = (ATTACK_STATE + 1) % NUM_ATTACK_STATES;
|
||||
const char* ATTACK_strings[NUM_ATTACK_STATES] = {
|
||||
"NAIR", "FAIR", "BAIR", "UPAIR", "DAIR",
|
||||
"NEUTRAL B", "SIDE B", "UP B", "DOWN B"};
|
||||
|
||||
print_string(acmd.module_accessor, ATTACK_strings[ATTACK_STATE]);
|
||||
} else {
|
||||
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",
|
||||
"RANDOM\nIN AWAY"
|
||||
};
|
||||
print_string(acmd.module_accessor,
|
||||
ATTACK_strings[ATTACK_STATE]);
|
||||
} else {
|
||||
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", "RANDOM\nIN AWAY"};
|
||||
|
||||
print_string(acmd.module_accessor, DI_strings[DI_STATE]);
|
||||
}
|
||||
}
|
||||
}
|
||||
print_string(acmd.module_accessor, DI_strings[DI_STATE]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* sv_get_status_func(u64 l2c_agentbase, int status_kind, u64 key) {
|
||||
u64 unk48 = LOAD64(l2c_agentbase + 0x48);
|
||||
u64 unk50 = LOAD64(l2c_agentbase + 0x50);
|
||||
if (0x2E8BA2E8BA2E8BA3LL * ((unk50 - unk48) >> 4) > (u64)status_kind)
|
||||
return *(void **)(unk48 + 0xB0LL * status_kind + (key << 32 >> 29));
|
||||
u64 unk48 = LOAD64(l2c_agentbase + 0x48);
|
||||
u64 unk50 = LOAD64(l2c_agentbase + 0x50);
|
||||
if (0x2E8BA2E8BA2E8BA3LL * ((unk50 - unk48) >> 4) > (u64)status_kind)
|
||||
return *(void**)(unk48 + 0xB0LL * status_kind + (key << 32 >> 29));
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sv_replace_status_func(u64 l2c_agentbase, int status_kind, u64 key, void* func) {
|
||||
u64 unk48 = LOAD64(l2c_agentbase + 0x48);
|
||||
u64 unk50 = LOAD64(l2c_agentbase + 0x50);
|
||||
if (0x2E8BA2E8BA2E8BA3LL * ((unk50 - unk48) >> 4) > (u64)status_kind) {
|
||||
*(void **)(unk48 + 0xB0LL * status_kind + (key << 32 >> 29)) = func;
|
||||
}
|
||||
void sv_replace_status_func(u64 l2c_agentbase, int status_kind, u64 key,
|
||||
void* func) {
|
||||
u64 unk48 = LOAD64(l2c_agentbase + 0x48);
|
||||
u64 unk50 = LOAD64(l2c_agentbase + 0x50);
|
||||
if (0x2E8BA2E8BA2E8BA3LL * ((unk50 - unk48) >> 4) > (u64)status_kind) {
|
||||
*(void**)(unk48 + 0xB0LL * status_kind + (key << 32 >> 29)) = func;
|
||||
}
|
||||
}
|
||||
|
||||
u64 clear_lua_stack_replace(u64 l2c_agent) {
|
||||
u64 lua_state = LOAD64(l2c_agent + 8);
|
||||
if ((lua_state - 8) && LOAD64(lua_state - 8) && (LOAD64(LOAD64(lua_state - 8) + 416LL))) {
|
||||
u8 battle_object_category = *(u8 *)(LOAD64(lua_state - 8) + 404LL);
|
||||
int battle_object_kind = *(int *)(LOAD64(lua_state - 8) + 408LL);
|
||||
replace_scripts((L2CAgent*)l2c_agent, battle_object_category, battle_object_kind);
|
||||
}
|
||||
u64 lua_state = LOAD64(l2c_agent + 8);
|
||||
if ((lua_state - 8) && LOAD64(lua_state - 8) &&
|
||||
(LOAD64(LOAD64(lua_state - 8) + 416LL))) {
|
||||
u8 battle_object_category = *(u8*)(LOAD64(lua_state - 8) + 404LL);
|
||||
int battle_object_kind = *(int*)(LOAD64(lua_state - 8) + 408LL);
|
||||
replace_scripts((L2CAgent*)l2c_agent, battle_object_category,
|
||||
battle_object_kind);
|
||||
}
|
||||
|
||||
// Original clear_lua_stack:
|
||||
u64 v1 = LOAD64(l2c_agent + 8);
|
||||
u64 v2 = LOAD64(v1 + 16);
|
||||
u64 i = LOAD64(LOAD64(v1 + 32)) + 16LL;
|
||||
for (; v2 < i; v2 = LOAD64(v1 + 16)) {
|
||||
LOAD64(v1 + 16) = v2 + 16;
|
||||
*(u32 *)(v2 + 8) = 0;
|
||||
}
|
||||
LOAD64(v1 + 16) = i;
|
||||
return l2c_agent;
|
||||
// Original clear_lua_stack:
|
||||
u64 v1 = LOAD64(l2c_agent + 8);
|
||||
u64 v2 = LOAD64(v1 + 16);
|
||||
u64 i = LOAD64(LOAD64(v1 + 32)) + 16LL;
|
||||
for (; v2 < i; v2 = LOAD64(v1 + 16)) {
|
||||
LOAD64(v1 + 16) = v2 + 16;
|
||||
*(u32*)(v2 + 8) = 0;
|
||||
}
|
||||
LOAD64(v1 + 16) = i;
|
||||
return l2c_agent;
|
||||
}
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
#define TRAINING_MODS_H
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#include "useful/useful.h"
|
||||
#include "useful/crc32.h"
|
||||
#include "useful/const_value_table.h"
|
||||
#include "useful/crc32.h"
|
||||
#include "useful/useful.h"
|
||||
|
||||
#include "useful/raygun_printer.hpp"
|
||||
|
||||
#include "acmd_wrapper.hpp"
|
||||
#include "imports/lib/l2c.hpp"
|
||||
#include "saltysd/saltysd_dynamic.h"
|
||||
#include "saltysd/saltysd_helper.hpp"
|
||||
#include "acmd_wrapper.hpp"
|
||||
#include "taunt_toggles.h"
|
||||
|
||||
using namespace lib;
|
||||
|
@ -23,357 +23,385 @@ using namespace app::sv_animcmd;
|
|||
u64 fighter_manager_addr;
|
||||
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
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 {
|
||||
namespace WorkModule {
|
||||
// Force DI
|
||||
float get_float_replace(u64 module_accessor, int var) {
|
||||
// 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));
|
||||
namespace WorkModule {
|
||||
// Force DI
|
||||
float get_float_replace(u64 module_accessor, int var) {
|
||||
// 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));
|
||||
|
||||
float ret_val = get_float(work_module, var);
|
||||
float ret_val = get_float(work_module, var);
|
||||
|
||||
if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X || var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor) && is_in_hitstun(module_accessor)) {
|
||||
if (DI_STATE != NONE) {
|
||||
float angle = (DI_STATE - 1) * M_PI / 4.0;
|
||||
if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X ||
|
||||
var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y) {
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor) &&
|
||||
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;
|
||||
// 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_X)
|
||||
return cos(angle);
|
||||
|
||||
if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y)
|
||||
return sin(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y)
|
||||
return sin(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float get_param_float_replace(u64 module_accessor, u64 param_type, u64 param_hash) {
|
||||
if (is_training_mode()) {
|
||||
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 999.0;
|
||||
// doesn't work, somehow. This parameter isn't checked?
|
||||
if (param_hash == hash40("shield_damage_mul")) return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
// 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));
|
||||
float get_param_float_replace(u64 module_accessor, u64 param_type,
|
||||
u64 param_hash) {
|
||||
if (is_training_mode()) {
|
||||
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 999.0;
|
||||
// doesn't work, somehow. This parameter isn't checked?
|
||||
if (param_hash == hash40("shield_damage_mul")) return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return get_param_float(work_module, param_type, param_hash);
|
||||
}
|
||||
// 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));
|
||||
|
||||
// Force ledge option
|
||||
u64 enable_transition_term_replace(u64 module_accessor, int transition_id) {
|
||||
if (TOGGLE_STATE == LEDGE_OPTION && is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (StatusModule::status_kind(module_accessor) == FIGHTER_STATUS_KIND_CLIFF_WAIT) {
|
||||
if (transition_id == FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB) {
|
||||
int status = 0;
|
||||
int ledge_case = LEDGE_STATE;
|
||||
|
||||
if (LEDGE_STATE == RANDOM_LEDGE)
|
||||
ledge_case = app::sv_math::rand(hash40("fighter"), 4) + 1;
|
||||
return get_param_float(work_module, param_type, param_hash);
|
||||
}
|
||||
|
||||
switch (ledge_case) {
|
||||
case NEUTRAL_LEDGE:
|
||||
status = FIGHTER_STATUS_KIND_CLIFF_CLIMB; break;
|
||||
case ROLL_LEDGE:
|
||||
status = FIGHTER_STATUS_KIND_CLIFF_ESCAPE; break;
|
||||
case JUMP_LEDGE:
|
||||
status = FIGHTER_STATUS_KIND_CLIFF_JUMP1; break;
|
||||
case ATTACK_LEDGE:
|
||||
status = FIGHTER_STATUS_KIND_CLIFF_ATTACK; break;
|
||||
}
|
||||
|
||||
StatusModule::change_status_request_from_script(module_accessor, status, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Force ledge option
|
||||
u64 enable_transition_term_replace(u64 module_accessor, int transition_id) {
|
||||
if (TOGGLE_STATE == LEDGE_OPTION && is_training_mode() &&
|
||||
is_operation_cpu(module_accessor)) {
|
||||
if (StatusModule::status_kind(module_accessor) == FIGHTER_STATUS_KIND_CLIFF_WAIT) {
|
||||
if (transition_id == FIGHTER_STATUS_TRANSITION_TERM_ID_CONT_CLIFF_CLIMB) {
|
||||
int status = 0;
|
||||
int ledge_case = LEDGE_STATE;
|
||||
|
||||
// call original WorkModule::enable_transition_term_group_impl
|
||||
u64 work_module = load_module(module_accessor, 0x50);
|
||||
u64 (*enable_transition_term)(u64, int) =
|
||||
(u64(*)(u64, int))(load_module_impl(work_module, 0x188));
|
||||
if (LEDGE_STATE == RANDOM_LEDGE)
|
||||
ledge_case = app::sv_math::rand(hash40("fighter"), 4) + 1;
|
||||
|
||||
return enable_transition_term(work_module, transition_id);
|
||||
}
|
||||
} // namespace WorkModule
|
||||
switch (ledge_case) {
|
||||
case NEUTRAL_LEDGE:
|
||||
status = FIGHTER_STATUS_KIND_CLIFF_CLIMB; break;
|
||||
case ROLL_LEDGE:
|
||||
status = FIGHTER_STATUS_KIND_CLIFF_ESCAPE; break;
|
||||
case JUMP_LEDGE:
|
||||
status = FIGHTER_STATUS_KIND_CLIFF_JUMP1; break;
|
||||
case ATTACK_LEDGE:
|
||||
status = FIGHTER_STATUS_KIND_CLIFF_ATTACK; break;
|
||||
}
|
||||
|
||||
namespace ControlModule {
|
||||
int get_command_flag_cat_replace(u64 module_accessor, int category) {
|
||||
// call original
|
||||
u64 control_module = load_module(module_accessor, 0x48);
|
||||
int (*get_command_flag_cat)(u64, int) =
|
||||
(int (*)(u64, int))load_module_impl(control_module, 0x350);
|
||||
int flag = get_command_flag_cat(control_module, category);
|
||||
StatusModule::change_status_request_from_script(module_accessor, status, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (is_in_hitstun(module_accessor)) {
|
||||
if (TOGGLE_STATE == MASH_AIRDODGE)
|
||||
if (category == FIGHTER_PAD_COMMAND_CATEGORY1)
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
|
||||
// call original WorkModule::enable_transition_term_group_impl
|
||||
u64 work_module = load_module(module_accessor, 0x50);
|
||||
u64 (*enable_transition_term)(u64, int) =
|
||||
(u64(*)(u64, int))(load_module_impl(work_module, 0x188));
|
||||
|
||||
if (TOGGLE_STATE == MASH_JUMP)
|
||||
if (category == FIGHTER_PAD_COMMAND_CATEGORY1)
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;
|
||||
return enable_transition_term(work_module, transition_id);
|
||||
}
|
||||
} // namespace WorkModule
|
||||
|
||||
if (TOGGLE_STATE == MASH_ATTACK)
|
||||
if (category == FIGHTER_PAD_COMMAND_CATEGORY1) {
|
||||
switch (ATTACK_STATE) {
|
||||
case MASH_NAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_N"); break;
|
||||
case MASH_FAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_F"); break;
|
||||
case MASH_BAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_B"); break;
|
||||
case MASH_UPAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_HI"); break;
|
||||
case MASH_DAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_LW"); break;
|
||||
case MASH_NEUTRAL_B:
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N; break;
|
||||
case MASH_SIDE_B:
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S; break;
|
||||
case MASH_UP_B:
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI; break;
|
||||
case MASH_DOWN_B:
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW; break;
|
||||
}
|
||||
}
|
||||
namespace ControlModule {
|
||||
int get_command_flag_cat_replace(u64 module_accessor, int category) {
|
||||
// call original
|
||||
u64 control_module = load_module(module_accessor, 0x48);
|
||||
int (*get_command_flag_cat)(u64, int) =
|
||||
(int (*)(u64, int))load_module_impl(control_module, 0x350);
|
||||
int flag = get_command_flag_cat(control_module, category);
|
||||
|
||||
if (TOGGLE_STATE == MASH_RANDOM)
|
||||
if (category == FIGHTER_PAD_COMMAND_CATEGORY1) {
|
||||
int random_commands[] = {
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE,
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_N"),
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_F"),
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_B"),
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_HI"),
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_LW"),
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
};
|
||||
if (is_training_mode() && is_operation_cpu(module_accessor)) {
|
||||
if (is_in_hitstun(module_accessor)) {
|
||||
if (TOGGLE_STATE == MASH_AIRDODGE)
|
||||
if (category == FIGHTER_PAD_COMMAND_CATEGORY1)
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;
|
||||
|
||||
int random_cmd_index = app::sv_math::rand(hash40("fighter"), 11);
|
||||
if (TOGGLE_STATE == MASH_JUMP)
|
||||
if (category == FIGHTER_PAD_COMMAND_CATEGORY1)
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;
|
||||
|
||||
flag |= random_commands[random_cmd_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TOGGLE_STATE == MASH_ATTACK)
|
||||
if (category == FIGHTER_PAD_COMMAND_CATEGORY1) {
|
||||
switch (ATTACK_STATE) {
|
||||
case MASH_NAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_N"); break;
|
||||
case MASH_FAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_F"); break;
|
||||
case MASH_BAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_B"); break;
|
||||
case MASH_UPAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_HI"); break;
|
||||
case MASH_DAIR:
|
||||
flag |= lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_LW"); break;
|
||||
case MASH_NEUTRAL_B:
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N; break;
|
||||
case MASH_SIDE_B:
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S; break;
|
||||
case MASH_UP_B:
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI; break;
|
||||
case MASH_DOWN_B:
|
||||
flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW; break;
|
||||
}
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
if (TOGGLE_STATE == MASH_RANDOM)
|
||||
if (category == FIGHTER_PAD_COMMAND_CATEGORY1) {
|
||||
int random_commands[] = {
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE,
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_N"),
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_F"),
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_B"),
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_HI"),
|
||||
lua_const("FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_AIR_LW"),
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
|
||||
FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
|
||||
};
|
||||
|
||||
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;
|
||||
if (TOGGLE_STATE == MASH_AIRDODGE && is_in_hitstun(module_accessor))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int random_cmd_index =
|
||||
app::sv_math::rand(hash40("fighter"), 11);
|
||||
|
||||
// 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);
|
||||
}
|
||||
flag |= random_commands[random_cmd_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
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;
|
||||
if (TOGGLE_STATE == MASH_AIRDODGE && is_in_hitstun(module_accessor))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#define SAVE_STATE 1
|
||||
#define DEFAULT 2
|
||||
#define CAMERA_MOVE 3
|
||||
#define POS_MOVE 4
|
||||
// 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);
|
||||
}
|
||||
|
||||
int save_state_player_state = DEFAULT;
|
||||
int save_state_cpu_state = DEFAULT;
|
||||
bool save_state_move_alert = false;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
float save_state_x_player = 0;
|
||||
float save_state_y_player = 0;
|
||||
float save_state_percent_player = 0;
|
||||
float save_state_lr_player = 1.0;
|
||||
int save_state_situation_kind_player = 0;
|
||||
// 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);
|
||||
}
|
||||
|
||||
float save_state_x_cpu = 0;
|
||||
float save_state_y_cpu = 0;
|
||||
float save_state_percent_cpu = 0;
|
||||
float save_state_lr_cpu = 1.0;
|
||||
int save_state_situation_kind_cpu = 0;
|
||||
#define SAVE_STATE 1
|
||||
#define DEFAULT 2
|
||||
#define CAMERA_MOVE 3
|
||||
#define POS_MOVE 4
|
||||
|
||||
int get_pad_flag_replace(u64 module_accessor) {
|
||||
if (is_training_mode()) {
|
||||
float* save_state_x;
|
||||
float* save_state_y;
|
||||
float* save_state_percent;
|
||||
float* save_state_lr;
|
||||
int* save_state_situation_kind;
|
||||
int* save_state;
|
||||
if (is_operation_cpu(module_accessor)) {
|
||||
save_state_x = &save_state_x_cpu;
|
||||
save_state_y = &save_state_y_cpu;
|
||||
save_state_percent = &save_state_percent_cpu;
|
||||
save_state_lr = &save_state_lr_cpu;
|
||||
save_state_situation_kind = &save_state_situation_kind_cpu;
|
||||
save_state = &save_state_cpu_state;
|
||||
} else {
|
||||
save_state_x = &save_state_x_player;
|
||||
save_state_y = &save_state_y_player;
|
||||
save_state_percent = &save_state_percent_player;
|
||||
save_state_lr = &save_state_lr_player;
|
||||
save_state_situation_kind = &save_state_situation_kind_player;
|
||||
save_state = &save_state_player_state;
|
||||
}
|
||||
int save_state_player_state = DEFAULT;
|
||||
int save_state_cpu_state = DEFAULT;
|
||||
bool save_state_move_alert = false;
|
||||
|
||||
// Grab + Dpad up: reset state
|
||||
if (ControlModule::check_button_on(module_accessor, CONTROL_PAD_BUTTON_CATCH) &&
|
||||
ControlModule::check_button_trigger(module_accessor, CONTROL_PAD_BUTTON_APPEAL_HI)) {
|
||||
if (*save_state == DEFAULT) {
|
||||
save_state_player_state = CAMERA_MOVE;
|
||||
save_state_cpu_state = CAMERA_MOVE;
|
||||
}
|
||||
}
|
||||
float save_state_x_player = 0;
|
||||
float save_state_y_player = 0;
|
||||
float save_state_percent_player = 0;
|
||||
float save_state_lr_player = 1.0;
|
||||
int save_state_situation_kind_player = 0;
|
||||
|
||||
// move to camera bounds
|
||||
if (*save_state == CAMERA_MOVE) {
|
||||
*save_state = POS_MOVE;
|
||||
float save_state_x_cpu = 0;
|
||||
float save_state_y_cpu = 0;
|
||||
float save_state_percent_cpu = 0;
|
||||
float save_state_lr_cpu = 1.0;
|
||||
int save_state_situation_kind_cpu = 0;
|
||||
|
||||
float left_right = (*save_state_x > 0) - (*save_state_x < 0);
|
||||
float y_pos = 0;
|
||||
if (*save_state_situation_kind == SITUATION_KIND_GROUND) y_pos = -50;
|
||||
int get_pad_flag_replace(u64 module_accessor) {
|
||||
if (is_training_mode()) {
|
||||
float* save_state_x;
|
||||
float* save_state_y;
|
||||
float* save_state_percent;
|
||||
float* save_state_lr;
|
||||
int* save_state_situation_kind;
|
||||
int* save_state;
|
||||
if (is_operation_cpu(module_accessor)) {
|
||||
save_state_x = &save_state_x_cpu;
|
||||
save_state_y = &save_state_y_cpu;
|
||||
save_state_percent = &save_state_percent_cpu;
|
||||
save_state_lr = &save_state_lr_cpu;
|
||||
save_state_situation_kind = &save_state_situation_kind_cpu;
|
||||
save_state = &save_state_cpu_state;
|
||||
} else {
|
||||
save_state_x = &save_state_x_player;
|
||||
save_state_y = &save_state_y_player;
|
||||
save_state_percent = &save_state_percent_player;
|
||||
save_state_lr = &save_state_lr_player;
|
||||
save_state_situation_kind = &save_state_situation_kind_player;
|
||||
save_state = &save_state_player_state;
|
||||
}
|
||||
|
||||
Vector3f pos = {.x = left_right * 50, .y = y_pos, .z = 0};
|
||||
PostureModule::set_pos(module_accessor, &pos);
|
||||
StatusModule::set_situation_kind(module_accessor, SITUATION_KIND_AIR, 0);
|
||||
}
|
||||
// Grab + Dpad up: reset state
|
||||
if (ControlModule::check_button_on(module_accessor,
|
||||
CONTROL_PAD_BUTTON_CATCH) &&
|
||||
ControlModule::check_button_trigger(module_accessor,
|
||||
CONTROL_PAD_BUTTON_APPEAL_HI)) {
|
||||
if (*save_state == DEFAULT) {
|
||||
save_state_player_state = CAMERA_MOVE;
|
||||
save_state_cpu_state = CAMERA_MOVE;
|
||||
}
|
||||
}
|
||||
|
||||
// move to correct pos
|
||||
if (*save_state == POS_MOVE) {
|
||||
*save_state = DEFAULT;
|
||||
// move to camera bounds
|
||||
if (*save_state == CAMERA_MOVE) {
|
||||
*save_state = POS_MOVE;
|
||||
|
||||
Vector3f pos = {.x = *save_state_x, .y = *save_state_y, .z = 0};
|
||||
PostureModule::set_pos(module_accessor, &pos);
|
||||
PostureModule::set_lr(module_accessor, *save_state_lr);
|
||||
DamageModule::add_damage(module_accessor, -1.0 * DamageModule::damage(module_accessor, 0), 0);
|
||||
DamageModule::add_damage(module_accessor, *save_state_percent, 0);
|
||||
StatusModule::set_situation_kind(module_accessor, *save_state_situation_kind, 0);
|
||||
float left_right = (*save_state_x > 0) - (*save_state_x < 0);
|
||||
float y_pos = 0;
|
||||
if (*save_state_situation_kind == SITUATION_KIND_GROUND)
|
||||
y_pos = -50;
|
||||
|
||||
// Doesn't work, and I don't know why yet.
|
||||
/*if (*save_state_situation_kind == SITUATION_KIND_GROUND)
|
||||
StatusModule::change_status_request(module_accessor, FIGHTER_STATUS_KIND_WAIT, 0);
|
||||
else if (*save_state_situation_kind == SITUATION_KIND_AIR)
|
||||
StatusModule::change_status_request(module_accessor, FIGHTER_STATUS_KIND_FALL, 0);
|
||||
else if (*save_state_situation_kind == SITUATION_KIND_CLIFF)
|
||||
StatusModule::change_status_request(module_accessor, FIGHTER_STATUS_KIND_CLIFF_CATCH, 0);
|
||||
*/
|
||||
}
|
||||
Vector3f pos = {.x = left_right * 50, .y = y_pos, .z = 0};
|
||||
PostureModule::set_pos(module_accessor, &pos);
|
||||
StatusModule::set_situation_kind(module_accessor,
|
||||
SITUATION_KIND_AIR, 0);
|
||||
}
|
||||
|
||||
// Grab + Dpad down: Save state
|
||||
if (ControlModule::check_button_on(module_accessor, CONTROL_PAD_BUTTON_CATCH) &&
|
||||
ControlModule::check_button_trigger(module_accessor, CONTROL_PAD_BUTTON_APPEAL_LW)) {
|
||||
save_state_player_state = SAVE_STATE;
|
||||
save_state_cpu_state = SAVE_STATE;
|
||||
}
|
||||
// move to correct pos
|
||||
if (*save_state == POS_MOVE) {
|
||||
*save_state = DEFAULT;
|
||||
|
||||
if (*save_state == SAVE_STATE) {
|
||||
*save_state = DEFAULT;
|
||||
Vector3f pos = {.x = *save_state_x, .y = *save_state_y, .z = 0};
|
||||
PostureModule::set_pos(module_accessor, &pos);
|
||||
PostureModule::set_lr(module_accessor, *save_state_lr);
|
||||
DamageModule::add_damage(
|
||||
module_accessor,
|
||||
-1.0 * DamageModule::damage(module_accessor, 0), 0);
|
||||
DamageModule::add_damage(module_accessor, *save_state_percent, 0);
|
||||
StatusModule::set_situation_kind(module_accessor,
|
||||
*save_state_situation_kind, 0);
|
||||
|
||||
*save_state_x = PostureModule::pos_x(module_accessor);
|
||||
*save_state_y = PostureModule::pos_y(module_accessor);
|
||||
*save_state_lr = PostureModule::lr(module_accessor);
|
||||
*save_state_percent = DamageModule::damage(module_accessor, 0);
|
||||
*save_state_situation_kind = StatusModule::situation_kind(module_accessor);
|
||||
}
|
||||
}
|
||||
// Doesn't work, and I don't know why yet.
|
||||
/*if (*save_state_situation_kind == SITUATION_KIND_GROUND)
|
||||
StatusModule::change_status_request(module_accessor,
|
||||
FIGHTER_STATUS_KIND_WAIT, 0); else if (*save_state_situation_kind ==
|
||||
SITUATION_KIND_AIR)
|
||||
StatusModule::change_status_request(module_accessor,
|
||||
FIGHTER_STATUS_KIND_FALL, 0); else if (*save_state_situation_kind ==
|
||||
SITUATION_KIND_CLIFF)
|
||||
StatusModule::change_status_request(module_accessor,
|
||||
FIGHTER_STATUS_KIND_CLIFF_CATCH, 0);
|
||||
*/
|
||||
}
|
||||
|
||||
// call original
|
||||
u64 control_module = load_module(module_accessor, 0x48);
|
||||
int (*get_pad_flag)(u64) =
|
||||
(int (*)(u64))load_module_impl(control_module, 0x348);
|
||||
return get_pad_flag(control_module);
|
||||
}
|
||||
} // namespace ControlModule
|
||||
// Grab + Dpad down: Save state
|
||||
if (ControlModule::check_button_on(module_accessor,
|
||||
CONTROL_PAD_BUTTON_CATCH) &&
|
||||
ControlModule::check_button_trigger(module_accessor,
|
||||
CONTROL_PAD_BUTTON_APPEAL_LW)) {
|
||||
save_state_player_state = SAVE_STATE;
|
||||
save_state_cpu_state = SAVE_STATE;
|
||||
}
|
||||
|
||||
if (*save_state == SAVE_STATE) {
|
||||
*save_state = DEFAULT;
|
||||
|
||||
*save_state_x = PostureModule::pos_x(module_accessor);
|
||||
*save_state_y = PostureModule::pos_y(module_accessor);
|
||||
*save_state_lr = PostureModule::lr(module_accessor);
|
||||
*save_state_percent = DamageModule::damage(module_accessor, 0);
|
||||
*save_state_situation_kind =
|
||||
StatusModule::situation_kind(module_accessor);
|
||||
}
|
||||
}
|
||||
|
||||
// call original
|
||||
u64 control_module = load_module(module_accessor, 0x48);
|
||||
int (*get_pad_flag)(u64) =
|
||||
(int (*)(u64))load_module_impl(control_module, 0x348);
|
||||
return get_pad_flag(control_module);
|
||||
}
|
||||
} // namespace ControlModule
|
||||
} // namespace app::lua_bind
|
||||
|
||||
void training_mods_main() {
|
||||
fighter_manager_addr = SaltySDCore_FindSymbol("_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E");
|
||||
// Mash airdodge/jump
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind40ControlModule__get_command_flag_cat_implEPNS_26BattleObjectModuleAccessorEi",
|
||||
(u64)&ControlModule::get_command_flag_cat_replace);
|
||||
|
||||
// Set DI
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind26WorkModule__get_float_implEPNS_26BattleObjectModuleAccessorEi",
|
||||
(u64)&WorkModule::get_float_replace);
|
||||
fighter_manager_addr = SaltySDCore_FindSymbol(
|
||||
"_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E");
|
||||
// Mash airdodge/jump
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind40ControlModule__get_command_flag_cat_implEPNS_"
|
||||
"26BattleObjectModuleAccessorEi",
|
||||
(u64)&ControlModule::get_command_flag_cat_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);
|
||||
// Set DI
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind26WorkModule__get_float_implEPNS_"
|
||||
"26BattleObjectModuleAccessorEi",
|
||||
(u64)&WorkModule::get_float_replace);
|
||||
|
||||
// Ledge options
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind39WorkModule__enable_transition_term_implEPNS_26BattleObjectModuleAccessorEi",
|
||||
(u64)&WorkModule::enable_transition_term_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);
|
||||
|
||||
// Save states: in beta
|
||||
/*SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind32ControlModule__get_pad_flag_implEPNS_26BattleObjectModuleAccessorE",
|
||||
(u64)&ControlModule::get_pad_flag_replace);*/
|
||||
// Ledge options
|
||||
SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind39WorkModule__enable_transition_term_implEPNS_"
|
||||
"26BattleObjectModuleAccessorEi",
|
||||
(u64)&WorkModule::enable_transition_term_replace);
|
||||
|
||||
// Save states: in beta
|
||||
/*SaltySD_function_replace_sym(
|
||||
"_ZN3app8lua_bind32ControlModule__get_pad_flag_implEPNS_26BattleObjectModuleAccessorE",
|
||||
(u64)&ControlModule::get_pad_flag_replace);*/
|
||||
}
|
||||
|
||||
#endif // TRAINING_MODS_H
|
||||
#endif // TRAINING_MODS_H
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef RAYGUN_PRINTER_H
|
||||
#define RAYGUN_PRINTER_H
|
||||
|
||||
#include <switch.h>
|
||||
#include <ctype.h>
|
||||
#include <switch.h>
|
||||
|
||||
#include "useful.h"
|
||||
|
||||
|
@ -18,106 +18,62 @@ using namespace app::lua_bind;
|
|||
segment data list : {Z, Y, X, ZRot, Size}
|
||||
segment labels :
|
||||
_
|
||||
|_| from top to top left, clockwise: a->f + g mid + \|/ from top mid to top left, clockwise: h->m + --two half g's: n, o
|
||||
|_| from top to top left, clockwise: a->f + g mid + \|/ from top mid to
|
||||
top left, clockwise: h->m + --two half g's: n, o
|
||||
|_| /|\
|
||||
*/
|
||||
|
||||
const float segment_dict[15][5] = {
|
||||
{0, RAYGUN_HEIGHT*2, 0, 0, 0.25}, // a
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH, 90, 0.25}, // b
|
||||
{0, 0, RAYGUN_LENGTH, 90, 0.25}, // c
|
||||
{0, 0, 0, 0, 0.25}, // d
|
||||
{0, 0, 0, 90, 0.25}, // e
|
||||
{0, RAYGUN_HEIGHT, 0, 90, 0.25}, // f
|
||||
{0, RAYGUN_HEIGHT, 0, 0, 0.25}, // g mid
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH/2, 90, 0.25}, // h
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH/2, 52, 0.2}, // i
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH/2, -52, 0.2}, // j
|
||||
{0, 0, RAYGUN_LENGTH/2, 90, 0.25}, // k
|
||||
{0, RAYGUN_HEIGHT/2, RAYGUN_LENGTH*3/16, 52, 0.2}, // l
|
||||
{0, RAYGUN_HEIGHT*3/2, RAYGUN_LENGTH*3/16, -52, 0.2}, // m
|
||||
{0, RAYGUN_HEIGHT, 0, 0, 0.15}, // n
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH/2, 0, 0.15}, // o
|
||||
};
|
||||
{0, RAYGUN_HEIGHT * 2, 0, 0, 0.25}, // a
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH, 90, 0.25}, // b
|
||||
{0, 0, RAYGUN_LENGTH, 90, 0.25}, // c
|
||||
{0, 0, 0, 0, 0.25}, // d
|
||||
{0, 0, 0, 90, 0.25}, // e
|
||||
{0, RAYGUN_HEIGHT, 0, 90, 0.25}, // f
|
||||
{0, RAYGUN_HEIGHT, 0, 0, 0.25}, // g mid
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH / 2, 90, 0.25}, // h
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH / 2, 52, 0.2}, // i
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH / 2, -52, 0.2}, // j
|
||||
{0, 0, RAYGUN_LENGTH / 2, 90, 0.25}, // k
|
||||
{0, RAYGUN_HEIGHT / 2, RAYGUN_LENGTH * 3 / 16, 52, 0.2}, // l
|
||||
{0, RAYGUN_HEIGHT * 3 / 2, RAYGUN_LENGTH * 3 / 16, -52, 0.2}, // m
|
||||
{0, RAYGUN_HEIGHT, 0, 0, 0.15}, // n
|
||||
{0, RAYGUN_HEIGHT, RAYGUN_LENGTH / 2, 0, 0.15}, // o
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
Segments making up each character, each index corresponding to:
|
||||
'A' through 'Z', '0' through '9', ' ', '-', '+', '#' (where '#' is all segments)
|
||||
'A' through 'Z', '0' through '9', ' ', '-', '+', '#' (where '#' is all
|
||||
segments)
|
||||
*/
|
||||
const char* alphabet[] = {
|
||||
"abcefg",
|
||||
"adefijn",
|
||||
"adef",
|
||||
"eflm",
|
||||
"adefn",
|
||||
"aefn",
|
||||
"acdefo",
|
||||
"bcefg",
|
||||
"adhk",
|
||||
"bcd",
|
||||
"efnij",
|
||||
"def",
|
||||
"bcefim",
|
||||
"bcefjm",
|
||||
"abcdef",
|
||||
"abefg",
|
||||
"abcdefj",
|
||||
"aefijn",
|
||||
"acdfg",
|
||||
"ahk",
|
||||
"bcdef",
|
||||
"efil",
|
||||
"bcefjl",
|
||||
"ijlm",
|
||||
"ikm",
|
||||
"adil",
|
||||
"abcdef",
|
||||
"ef",
|
||||
"abdeg",
|
||||
"abcdg",
|
||||
"bcfg",
|
||||
"acdfg",
|
||||
"acdefg",
|
||||
"abc",
|
||||
"abcdefg",
|
||||
"abcdfg",
|
||||
"",
|
||||
"g",
|
||||
"ghk",
|
||||
"abcdefhijklmno",
|
||||
const char* alphabet[] = {
|
||||
"abcefg", "adefijn", "adef", "eflm", "adefn",
|
||||
"aefn", "acdefo", "bcefg", "adhk", "bcd",
|
||||
"efnij", "def", "bcefim", "bcefjm", "abcdef",
|
||||
"abefg", "abcdefj", "aefijn", "acdfg", "ahk",
|
||||
"bcdef", "efil", "bcefjl", "ijlm", "ikm",
|
||||
"adil", "abcdef", "ef", "abdeg", "abcdg",
|
||||
"bcfg", "acdfg", "acdefg", "abc", "abcdefg",
|
||||
"abcdfg", "", "g", "ghk", "abcdefhijklmno",
|
||||
};
|
||||
|
||||
// Each index is a segment's corresponding flipped segment, for when facing left
|
||||
const char segment_rev[15] = {
|
||||
'a',
|
||||
'f',
|
||||
'e',
|
||||
'd',
|
||||
'c',
|
||||
'b',
|
||||
'g',
|
||||
'h',
|
||||
'm',
|
||||
'l',
|
||||
'k',
|
||||
'j',
|
||||
'i',
|
||||
'o',
|
||||
'n',
|
||||
'a', 'f', 'e', 'd', 'c', 'b', 'g', 'h', 'm', 'l', 'k', 'j', 'i', 'o', 'n',
|
||||
};
|
||||
|
||||
void show_segment(u64 battle_object_module_accessor, float z, float y, float x, float zrot, float size) {
|
||||
Hash40 raygunShot = { .hash = 0x11e470b07fLL };
|
||||
Hash40 top = { .hash = 0x031ed91fcaLL };
|
||||
void show_segment(u64 battle_object_module_accessor, float z, float y, float x,
|
||||
float zrot, float size) {
|
||||
Hash40 raygunShot = {.hash = 0x11e470b07fLL};
|
||||
Hash40 top = {.hash = 0x031ed91fcaLL};
|
||||
|
||||
Vector3f pos = { .x = x, .y = y, .z = z };
|
||||
Vector3f rot = { .x = 0, .y = 90, .z = zrot };
|
||||
Vector3f random = { .x = 0, .y = 0, .z = 0 };
|
||||
Vector3f pos = {.x = x, .y = y, .z = z};
|
||||
Vector3f rot = {.x = 0, .y = 90, .z = zrot};
|
||||
Vector3f random = {.x = 0, .y = 0, .z = 0};
|
||||
|
||||
EffectModule::req_on_joint(battle_object_module_accessor, raygunShot.hash, top.hash,
|
||||
&pos, &rot, size,
|
||||
&random, &random,
|
||||
0, 0, 0, 0);
|
||||
EffectModule::req_on_joint(battle_object_module_accessor, raygunShot.hash,
|
||||
top.hash, &pos, &rot, size, &random, &random, 0,
|
||||
0, 0, 0);
|
||||
}
|
||||
|
||||
int alphabet_index(char to_print) {
|
||||
|
@ -137,10 +93,10 @@ int alphabet_index(char to_print) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
void print_char( u64 module_accessor, char to_print, int line_num, float horiz_offset, float facing_left) {
|
||||
void print_char(u64 module_accessor, char to_print, int line_num,
|
||||
float horiz_offset, float facing_left) {
|
||||
int alph_index = alphabet_index(to_print);
|
||||
if (alph_index < 0 || alph_index >= 40)
|
||||
return;
|
||||
if (alph_index < 0 || alph_index >= 40) return;
|
||||
const char* segment_str = alphabet[alph_index];
|
||||
int num_segments = strlen(segment_str);
|
||||
|
||||
|
@ -152,7 +108,7 @@ void print_char( u64 module_accessor, char to_print, int line_num, float horiz_o
|
|||
|
||||
if (facing_left == -1) {
|
||||
index = segment_rev[index] - 'a';
|
||||
}
|
||||
}
|
||||
segment = segment_dict[index];
|
||||
|
||||
float z = segment[0];
|
||||
|
@ -160,17 +116,16 @@ void print_char( u64 module_accessor, char to_print, int line_num, float horiz_o
|
|||
float x = segment[2] + horiz_offset;
|
||||
float zrot = segment[3];
|
||||
|
||||
if (facing_left == -1)
|
||||
zrot *= -1;
|
||||
if (facing_left == -1) zrot *= -1;
|
||||
|
||||
float size = segment[4];
|
||||
show_segment(module_accessor, z, y, x, zrot, size);
|
||||
}
|
||||
}
|
||||
|
||||
void print_string( u64 module_accessor, const char* print_str) {
|
||||
void print_string(u64 module_accessor, const char* print_str) {
|
||||
// Delete any previous strings
|
||||
Hash40 raygunShot = { .hash = 0x11e470b07fLL };
|
||||
Hash40 raygunShot = {.hash = 0x11e470b07fLL};
|
||||
EffectModule::kill_kind(module_accessor, raygunShot.hash, 0, 1);
|
||||
|
||||
int line_num = 0;
|
||||
|
@ -181,7 +136,7 @@ void print_string( u64 module_accessor, const char* print_str) {
|
|||
|
||||
if (strlen(print_str) <= 8 && strchr(print_str, '\n') == NULL) {
|
||||
line_num = 1;
|
||||
}
|
||||
}
|
||||
horiz_offset = 0;
|
||||
char_num = 0;
|
||||
for (size_t i = 0; i < strlen(print_str); i++) {
|
||||
|
@ -193,15 +148,16 @@ void print_string( u64 module_accessor, const char* print_str) {
|
|||
continue;
|
||||
}
|
||||
|
||||
print_char(module_accessor, toupper(curr_char), line_num, horiz_offset, facing_left);
|
||||
print_char(module_accessor, toupper(curr_char), line_num, horiz_offset,
|
||||
facing_left);
|
||||
|
||||
char_num++;
|
||||
// short characters
|
||||
if (curr_char == 'D' || curr_char == '1') {
|
||||
horiz_offset += facing_left * (RAYGUN_LENGTH/2 + 3);
|
||||
horiz_offset += facing_left * (RAYGUN_LENGTH / 2 + 3);
|
||||
} else {
|
||||
horiz_offset += facing_left * (RAYGUN_LENGTH + 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (char_num > 8) {
|
||||
horiz_offset = 0;
|
||||
|
@ -211,4 +167,4 @@ void print_string( u64 module_accessor, const char* print_str) {
|
|||
}
|
||||
}
|
||||
|
||||
#endif // RAYGUN_PRINTER_H
|
||||
#endif // RAYGUN_PRINTER_H
|
||||
|
|
|
@ -1,56 +1,63 @@
|
|||
#ifndef USEFUL_VISUAL_H
|
||||
#define USEFUL_VISUAL_H
|
||||
|
||||
#include "useful.h"
|
||||
#include <math.h>
|
||||
#include "useful.h"
|
||||
|
||||
/**
|
||||
* Rounds a number to the nearest multiple of another number.
|
||||
*/
|
||||
float round_to(float val, float align) {
|
||||
return roundf(val / align) * align;
|
||||
}
|
||||
float round_to(float val, float align) { return roundf(val / align) * align; }
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two numbers, without bounds checking.
|
||||
*/
|
||||
float lerp(float min, float max, float t) {
|
||||
return min + (max - min) * t;
|
||||
}
|
||||
float lerp(float min, float max, float t) { return min + (max - min) * t; }
|
||||
|
||||
float unlerp(float min, float max, float val) {
|
||||
return (val - min) / (max - min);
|
||||
return (val - min) / (max - min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two numbers, with bounds checking.
|
||||
*/
|
||||
float lerp_bounded(float min, float max, float t) {
|
||||
return t <= 0 ? min : t >= 1 ? max : lerp(min, max, t);
|
||||
return t <= 0 ? min : t >= 1 ? max : lerp(min, max, t);
|
||||
}
|
||||
|
||||
float unlerp_bounded(float min, float max, float val) {
|
||||
return val <= min ? 0 : val >= max ? 1 : unlerp(min, max, val);
|
||||
return val <= min ? 0 : val >= max ? 1 : unlerp(min, max, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly nterpolates between two colors, with bounds checking, accounting for gamma.
|
||||
* arguments:
|
||||
* - min_color (Vector3f) -- xyz maps to rgb, components are usually in the range [0.0f, 1.0f] but can go beyond to account for super-bright or super-dark colors
|
||||
* Linearly nterpolates between two colors, with bounds checking, accounting for
|
||||
* gamma. arguments:
|
||||
* - min_color (Vector3f) -- xyz maps to rgb, components are usually in the
|
||||
* range [0.0f, 1.0f] but can go beyond to account for super-bright or
|
||||
* super-dark colors
|
||||
* - max_Color (Vector3f) -- same as minColor
|
||||
* - t (float) -- how far to interpolate between the colors
|
||||
* - gamma (float = 2.0f) -- used for color correction, helps avoid ugly dark colors when interpolating b/t bright colors
|
||||
* - gamma (float = 2.0f) -- used for color correction, helps avoid ugly dark
|
||||
* colors when interpolating b/t bright colors
|
||||
*/
|
||||
|
||||
Vector3f color_lerp(Vector3f min_color, Vector3f max_color, float t, float gamma = 2.0f) {
|
||||
float gamma_inv = 1.0f / gamma;
|
||||
float align = 1.0f / 255.0f; // color components must be a multiple of 1/255
|
||||
return {
|
||||
round_to(powf(lerp_bounded(powf(min_color.x, gamma), powf(max_color.x, gamma), t), gamma_inv), align),
|
||||
round_to(powf(lerp_bounded(powf(min_color.y, gamma), powf(max_color.y, gamma), t), gamma_inv), align),
|
||||
round_to(powf(lerp_bounded(powf(min_color.z, gamma), powf(max_color.z, gamma), t), gamma_inv), align)
|
||||
};
|
||||
Vector3f color_lerp(Vector3f min_color, Vector3f max_color, float t,
|
||||
float gamma = 2.0f) {
|
||||
float gamma_inv = 1.0f / gamma;
|
||||
float align =
|
||||
1.0f / 255.0f; // color components must be a multiple of 1/255
|
||||
return {round_to(powf(lerp_bounded(powf(min_color.x, gamma),
|
||||
powf(max_color.x, gamma), t),
|
||||
gamma_inv),
|
||||
align),
|
||||
round_to(powf(lerp_bounded(powf(min_color.y, gamma),
|
||||
powf(max_color.y, gamma), t),
|
||||
gamma_inv),
|
||||
align),
|
||||
round_to(powf(lerp_bounded(powf(min_color.z, gamma),
|
||||
powf(max_color.z, gamma), t),
|
||||
gamma_inv),
|
||||
align)};
|
||||
}
|
||||
|
||||
|
||||
#endif // USEFUL_VISUAL_H
|
||||
#endif // USEFUL_VISUAL_H
|
||||
|
|
Loading…
Reference in a new issue