Important
- This cheat menu is intended for educational and single-player use only.
- Use cheats responsibly and respect the terms of use of the games you are modifying.
Note
- Party Stats Manager
- Basic Cheats
- Compile Solution ( DLL )
- Launch FF7 Remake Integrade as you normally would
- Inject DLL with program of choice ( CheatEngine, Process Hacker, GH Injector . . . )
- A beep will announce the success of the hooking of dx11 and a welcome message will be displayed.
- Navigate the menu with controller , keyboard and/or mouse
Main Game Offset
FinalFantasy7Remake-Menu/include/Game.h
Line 26 in 8bd9d81
constexpr auto oGameBase{ 0x57B9260 }; // 48 8B 05 ? ? ? ? 4C 89 B4 24 ? ? ? ? 44 0F B6 76 |
Pause Game
FinalFantasy7Remake-Menu/src/Game.cpp
Lines 268 to 311 in 8bd9d81
void AGame::Hooks::AScene_Update_hook(__int64 p) | |
{ | |
/// PORT NOTES | |
/* | |
// AOB: E8 ? ? ? ? 48 8B 0D ? ? ? ? 48 8B 89 ? ? ? ? 48 83 C4 | |
// STUB: void __fastcall sub_1416B44A0(__int64 a1) | |
// INSTRUCTION: *(_BYTE *)(a1 + 0x4FC) = 0; | |
// ASM: mov byte ptr [rcx+4FCh], 0 | |
This function is constantly executed. xref the function in IDA to get the following calling convention | |
{ | |
v18 = *(_QWORD *)(qword_1457B95B0 + 0x3D0); // method of dynamic analysis | |
if ( !v18 || !(unsigned __int8)sub_1416D4720(*(_QWORD *)(qword_1457B95B0 + 0x3D0)) ) | |
v18 = 0i64; | |
sub_1416B44A0(v18); // this function | |
} | |
Using ReClass one could look at "p" [ qword_1457B95B0 + 0x3D0 ] while pausing the game to visually see changes being made. | |
Additional information will be obtained by utilizing "Tactical Mode" in game. This will show a float value of 1.0 changing to 0.10f to signify the time scale shift. | |
We can simulate pausing the game by hooking the function and returning shortly after apply a hack to force time scale to 0 and set the pause flag to 1. | |
// FINDING AGAIN | |
This function can originally be found by doing a memory scan of changed values 1 - 0 when pausing the game. After finding the variable in question you can xref what changes the value to get this function. | |
*/ | |
auto pScene = reinterpret_cast<AScene*>(p); | |
if (pScene && g_Engine->m_ShowMenu) | |
{ | |
// @TODO: this doesnt make the pause menu show up , however setting this flag requires the user to manually unpause the game. | |
// pScene->SetPauseState(true); | |
pScene->SetTimeScale(0.00f); | |
} | |
if (pScene && AGame::bPauseGame) | |
pScene->SetTimeScale(pScene->GetTimeScale() * 0.0f); | |
if (pScene && AGame::bModTimeScale) | |
pScene->SetTimeScale(AGame::fTimeScalar); | |
// exec original fn | |
AScene_Update_stub(p); | |
} |
Gamepad Input
FinalFantasy7Remake-Menu/src/Game.cpp
Lines 253 to 265 in 8bd9d81
__int64 AGame::Hooks::XInput_State_hook(__int64 a1) | |
{ | |
/// PORT NOTES | |
/* | |
// AOB: 48 8B C4 48 89 58 ? 48 89 70 ? 48 89 78 ? 55 41 54 41 55 41 56 41 57 48 8D 68 ? 48 81 EC ? ? ? ? 0F 29 70 ? 0F 29 78 ? 44 0F 29 40 ? 44 0F 29 48 ? 44 0F 29 50 ? 44 0F 29 98 ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 ? 48 8B D9 | |
*/ | |
// Whenever the menu is shown , we wont pass controller inputs to the game | |
if (g_Engine->m_ShowMenu) | |
return 0; | |
XInput_State_stub(a1); | |
} |
Infinite Health
FinalFantasy7Remake-Menu/src/Game.cpp
Lines 314 to 389 in 8bd9d81
__int64 AGame::Hooks::APlayerState_SetHealth_hook(unsigned __int8 index, int health) | |
{ | |
/// PORT NOTES | |
/* | |
// AOB: E8 ? ? ? ? 0F B6 CB E8 ? ? ? ? 8B D0 | |
// STUB: __int64 __fastcall APlayerState_SubHealth(unsigned __int8, int) | |
// INSTRUCTION: *(_DWORD *)(((unsigned __int64)a1 << 6) + result + 0x30) = a2; | |
// ASM: mov [rcx+rax+30h], edi | |
// FINDING AGAIN | |
This function is relatively easy to find. | |
First find Clouds HP by doing some scans on changed values in between taking damage from enemies. | |
Figure out which function is adjusting the health value by checking what changes the hp value. | |
[NOTE] this function is also good for inspecting "AGameState" and obtaining the new global pointer to the class and contained structures | |
.text:0000000140AFB6C0 mov [rsp+arg_0], rbx // | |
.text:0000000140AFB6C5 push rdi // | |
.text:0000000140AFB6C6 sub rsp, 20h // | |
.text:0000000140AFB6CA mov rax, cs:qword_1457B9268 // this points to AGameState | |
.text:0000000140AFB6D1 mov edi, edx // | |
.text:0000000140AFB6D3 movzx ebx, cl // | |
.text:0000000140AFB6D6 test rax, rax // | |
.text:0000000140AFB6D9 jnz short loc_140AFB715 // | |
.text:0000000140AFB6DB mov rcx, cs:qword_1457F5148 // | |
.text:0000000140AFB6E2 test rcx, rcx // | |
.text:0000000140AFB6E5 jnz short loc_140AFB6F3 // | |
.text:0000000140AFB6E7 call sub_141C22CC0 // | |
.text:0000000140AFB6EC mov rcx, cs:qword_1457F5148 // | |
.text:0000000140AFB6F3 // | |
.text:0000000140AFB6F3 loc_140AFB6F3: // | |
.text:0000000140AFB6F3 mov rax, [rcx] // | |
.text:0000000140AFB6F6 xor r8d, r8d // | |
.text:0000000140AFB6F9 mov edx, 0B6DF0h // | |
.text:0000000140AFB6FE call qword ptr [rax+10h] // | |
.text:0000000140AFB701 test rax, rax // | |
.text:0000000140AFB704 jz short loc_140AFB70E // | |
.text:0000000140AFB706 mov rcx, rax // | |
.text:0000000140AFB709 call sub_140B26300 // | |
.text:0000000140AFB70E // | |
.text:0000000140AFB70E loc_140AFB70E: // | |
.text:0000000140AFB70E mov cs:qword_1457B9268, rax // | |
.text:0000000140AFB715 // | |
.text:0000000140AFB715 loc_140AFB715: // | |
.text:0000000140AFB715 mov rax, [rax+0B6D80h] // | |
.text:0000000140AFB71C cmp bl, 8 // | |
.text:0000000140AFB71F jnb short loc_140AFB73C // | |
.text:0000000140AFB721 test byte ptr cs:dword_1457B9260, 10h // | |
.text:0000000140AFB728 ja short loc_140AFB73C // | |
.text:0000000140AFB72A mov rax, [rax+3E60h] // | |
.text:0000000140AFB731 movzx ecx, bl // | |
.text:0000000140AFB734 shl rcx, 6 // | |
.text:0000000140AFB738 mov [rcx+rax+30h], edi // [!] This instruction subtracts hp from party members | |
.text:0000000140AFB73C // | |
.text:0000000140AFB73C loc_140AFB73C: // | |
.text:0000000140AFB73C mov rbx, [rsp+28h+arg_0] // | |
.text:0000000140AFB741 add rsp, 20h // | |
.text:0000000140AFB745 pop rdi // | |
.text:0000000140AFB746 retn | |
*/ | |
// Generate a structure based on the input params | |
// - Party Member Index & Stats | |
auto pSetHealth = OnSetHealth(index, health); | |
if (g_Console->m_bVerbose && pSetHealth.Diff > 0) | |
Console::Log("[+] [Hooking::APlayerState_SetHealth_hook(%d, %d)]\n- diff: %d\n- isTakeDmg: %d\n- isHealing: %d\n- origHealth: %d / %d\n- newHealth: %d / %d\n- bNullDmg: %d\n\n", | |
index, health, pSetHealth.Diff, pSetHealth.bTakingDmg, pSetHealth.bHealing, health + pSetHealth.Diff, pSetHealth.PlayerStats.MaxHP, health, pSetHealth.PlayerStats.MaxHP, AGame::bNullDmg); | |
// prevent damage to party member | |
if (AGame::bNullDmg && pSetHealth.bTakingDmg) | |
return 0; | |
// exec original fn | |
return APlayerState_SetHealth_stub(index, health); | |
} |
Infinite Mana
FinalFantasy7Remake-Menu/src/Game.cpp
Lines 392 to 492 in 8bd9d81
__int64 AGame::Hooks::APlayerState_SetMana_hook(unsigned __int8 index, int mana) | |
{ | |
/// PORT NOTES | |
/* | |
// AOB: E8 ? ? ? ? 48 83 C6 ? 48 3B F5 0F 85 ? ? ? ? 4C 8B 74 24 ? 48 8B 7C 24 ? 48 8B 5C 24 ? 48 83 C4 | |
// STUB: __int64 __fastcall APlayerState_SetMp(unsigned __int8 a1, int a2) | |
// INSTRUCTION: *(_DWORD *)(result + ((unsigned __int64)a1 << 6) + 56) = a2; | |
// ASM: mov [rax+rcx+38],edi | |
.text:0000000140AFB8D0 ; __int64 __fastcall APlayerState_SetMp(unsigned __int8, int) | |
.text:0000000140AFB8D0 APlayerState_SetMp proc near | |
.text:0000000140AFB8D0 | |
.text:0000000140AFB8D0 arg_0 = qword ptr 8 | |
.text:0000000140AFB8D0 | |
.text:0000000140AFB8D0 mov [rsp+arg_0], rbx | |
.text:0000000140AFB8D5 push rdi | |
.text:0000000140AFB8D6 sub rsp, 20h | |
.text:0000000140AFB8DA mov rax, cs:qword_1457B9268 | |
.text:0000000140AFB8E1 mov edi, edx | |
.text:0000000140AFB8E3 movzx ebx, cl | |
.text:0000000140AFB8E6 test rax, rax | |
.text:0000000140AFB8E9 jnz short loc_140AFB925 | |
.text:0000000140AFB8EB mov rcx, cs:qword_1457F5148 | |
.text:0000000140AFB8F2 test rcx, rcx | |
.text:0000000140AFB8F5 jnz short loc_140AFB903 | |
.text:0000000140AFB8F7 call sub_141C22CC0 | |
.text:0000000140AFB8FC mov rcx, cs:qword_1457F5148 | |
.text:0000000140AFB903 | |
.text:0000000140AFB903 loc_140AFB903: | |
.text:0000000140AFB903 mov rax, [rcx] | |
.text:0000000140AFB906 xor r8d, r8d | |
.text:0000000140AFB909 mov edx, 0B6DF0h | |
.text:0000000140AFB90E call qword ptr [rax+10h] | |
.text:0000000140AFB911 test rax, rax | |
.text:0000000140AFB914 jz short loc_140AFB91E | |
.text:0000000140AFB916 mov rcx, rax | |
.text:0000000140AFB919 call sub_140B26300 | |
.text:0000000140AFB91E | |
.text:0000000140AFB91E loc_140AFB91E: | |
.text:0000000140AFB91E mov cs:qword_1457B9268, rax | |
.text:0000000140AFB925 | |
.text:0000000140AFB925 loc_140AFB925: | |
.text:0000000140AFB925 cmp bl, 8 | |
.text:0000000140AFB928 jnb short loc_140AFB943 | |
.text:0000000140AFB92A mov rax, [rax+0B6D80h] | |
.text:0000000140AFB931 movzx ecx, bl | |
.text:0000000140AFB934 shl rcx, 6 | |
.text:0000000140AFB938 mov rax, [rax+3E60h] | |
.text:0000000140AFB93F mov [rax+rcx+38h], edi | |
.text:0000000140AFB943 | |
.text:0000000140AFB943 loc_140AFB943: | |
.text:0000000140AFB943 mov rbx, [rsp+28h+arg_0] | |
.text:0000000140AFB948 add rsp, 20h | |
.text:0000000140AFB94C pop rdi | |
.text:0000000140AFB94D retn | |
.text:0000000140AFB94D APlayerState_SetMp endp | |
__int64 __fastcall APlayerState_SetMp(unsigned __int8 a1, int a2) | |
{ | |
__int64 result; // rax | |
__int64 v5; // rcx | |
result = qword_1457B9268; | |
if ( !qword_1457B9268 ) | |
{ | |
v5 = qword_1457F5148; | |
if ( !qword_1457F5148 ) | |
{ | |
sub_141C22CC0(); | |
v5 = qword_1457F5148; | |
} | |
result = (*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)v5 + 16i64))(v5, 749040i64, 0i64); | |
if ( result ) | |
result = sub_140B26300(result); | |
qword_1457B9268 = result; | |
} | |
if ( a1 < 8u ) | |
{ | |
result = *(_QWORD *)(*(_QWORD *)(result + 748928) + 15968i64); | |
*(_DWORD *)(result + ((unsigned __int64)a1 << 6) + 56) = a2; | |
} | |
return result; | |
} | |
*/ | |
// Generate a structure based on the input params | |
// - Party Member Index & Stats | |
auto pSetMana = OnSetMana(index, mana); | |
if (g_Console->m_bVerbose && pSetMana.Diff > 0) | |
Console::Log("[+] [Hooking::APlayerState_SetMana_hook(%d, %d)]\n- diff: %d\n- isUsingMana: %d\n- isHealingMana: %d\n- origMana: %d / %d\n- newMana: %d / %d\n- bNullMgk: %d\n\n", | |
index, mana, pSetMana.Diff, pSetMana.bUsing, pSetMana.bRestoring, mana + pSetMana.Diff, pSetMana.PlayerStats.MaxMP, mana, pSetMana.PlayerStats.MaxMP, AGame::bNullMgk); | |
// prevent damage to party member | |
if (AGame::bNullMgk && pSetMana.bUsing) | |
return 0; | |
// exec original fn | |
return APlayerState_SetMana_stub(index, mana); | |
} |
Infinite Items
FinalFantasy7Remake-Menu/src/Game.cpp
Lines 495 to 696 in 8bd9d81
__int64 AGame::Hooks::APlayerState_SubItem_hook(__int64 p, int index) | |
{ | |
/// PORT NOTES | |
/* | |
// AOB: E8 ? ? ? ? B0 ? EB ? CC CC CC CC CC CC CC 48 89 5C 24 ? 57 [ CALL ] | |
// STUB: __int64 __fastcall APlayerState_SubItem(__int64 a1, int a2) | |
// INSTRUCTION: v13 = *(_DWORD *)(v12 + 0xC) - *((_DWORD *)v11 + 3); | |
// ASM: mov ecx,[rdx+0C] | |
a1 + 0x18 = PlayerStats ( pCloudState or pPlayerStats for the user ? ) | |
a1 + 0x48 = InventoryIndex | |
a1 + 0x48 + 0X0C = ItemCount | |
v4 = a1 + 8i64 * a2; | |
v11 = *(__int64 **)(v4 + 0x48); // inventory | |
v12 = *v11; // Slot | |
v13 = *(_DWORD *)(v12 + 0xC) - *((_DWORD *)v11 + 3); // sub item | |
// FINDING AGAIN | |
This function is relatively easy to find. | |
First find an item by doing some scans on changed values in between using said item. | |
Figure out which function is adjusting the count value by checking what changes the item count value. | |
.text:0000000140B1CAF0 ; __int64 __fastcall APlayerState_SubItem(__int64, int) | |
.text:0000000140B1CAF0 APlayerState_SubItem proc near | |
.text:0000000140B1CAF0 | |
.text:0000000140B1CAF0 arg_0 = qword ptr 8 | |
.text:0000000140B1CAF0 arg_8 = qword ptr 10h | |
.text:0000000140B1CAF0 arg_10 = qword ptr 18h | |
.text:0000000140B1CAF0 arg_18 = qword ptr 20h | |
.text:0000000140B1CAF0 | |
.text:0000000140B1CAF0 mov [rsp+arg_10], rbp | |
.text:0000000140B1CAF5 mov [rsp+arg_18], rsi | |
.text:0000000140B1CAFA push rdi | |
.text:0000000140B1CAFB sub rsp, 20h | |
.text:0000000140B1CAFF movsxd rax, edx | |
.text:0000000140B1CB02 mov rbp, rcx | |
.text:0000000140B1CB05 lea rsi, ds:0[rax*8] | |
.text:0000000140B1CB0D add rsi, rcx | |
.text:0000000140B1CB10 mov rdi, [rsi+48h] | |
.text:0000000140B1CB14 test rdi, rdi | |
.text:0000000140B1CB17 jz loc_140B1CC2A | |
.text:0000000140B1CB1D | |
.text:0000000140B1CB1D loc_140B1CB1D: | |
.text:0000000140B1CB1D mov [rsp+28h+arg_0], rbx | |
.text:0000000140B1CB22 mov [rsp+28h+arg_8], r14 | |
.text:0000000140B1CB27 call sub_140FCB3D0 | |
.text:0000000140B1CB2C xor r14d, r14d | |
.text:0000000140B1CB2F test al, al | |
.text:0000000140B1CB31 jz loc_140B1CBCC | |
.text:0000000140B1CB37 test rdi, rdi | |
.text:0000000140B1CB3A jz loc_140B1CBCC | |
.text:0000000140B1CB40 mov ebx, r14d | |
.text:0000000140B1CB43 lea rax, [rbp+368h] | |
.text:0000000140B1CB4A mov ecx, r14d | |
.text:0000000140B1CB4D nop dword ptr [rax] | |
.text:0000000140B1CB50 | |
.text:0000000140B1CB50 loc_140B1CB50: | |
.text:0000000140B1CB50 cmp [rax], r14 | |
.text:0000000140B1CB53 jz short loc_140B1CB66 | |
.text:0000000140B1CB55 inc ebx | |
.text:0000000140B1CB57 inc rcx | |
.text:0000000140B1CB5A add rax, 8 | |
.text:0000000140B1CB5E cmp rcx, 64h ; 'd' | |
.text:0000000140B1CB62 jl short loc_140B1CB50 | |
.text:0000000140B1CB64 jmp short loc_140B1CBCC | |
.text:0000000140B1CB66 ; --------------------------------------------------------------------------- | |
.text:0000000140B1CB66 | |
.text:0000000140B1CB66 loc_140B1CB66: | |
.text:0000000140B1CB66 mov rcx, cs:qword_1457F5148 | |
.text:0000000140B1CB6D test rcx, rcx | |
.text:0000000140B1CB70 jnz short loc_140B1CB7E | |
.text:0000000140B1CB72 call sub_141C22CC0 | |
.text:0000000140B1CB77 mov rcx, cs:qword_1457F5148 | |
.text:0000000140B1CB7E | |
.text:0000000140B1CB7E loc_140B1CB7E: | |
.text:0000000140B1CB7E mov rax, [rcx] | |
.text:0000000140B1CB81 xor r8d, r8d | |
.text:0000000140B1CB84 lea edx, [r8+18h] | |
.text:0000000140B1CB88 call qword ptr [rax+10h] | |
.text:0000000140B1CB8B mov rcx, rax | |
.text:0000000140B1CB8E test rax, rax | |
.text:0000000140B1CB91 jz short loc_140B1CBA7 | |
.text:0000000140B1CB93 mov [rax], r14 | |
.text:0000000140B1CB96 mov dword ptr [rax+8], 0FFFFFFFFh | |
.text:0000000140B1CB9D mov [rax+0Ch], r14d | |
.text:0000000140B1CBA1 mov [rax+10h], r14b | |
.text:0000000140B1CBA5 jmp short loc_140B1CBAA | |
.text:0000000140B1CBA7 ; --------------------------------------------------------------------------- | |
.text:0000000140B1CBA7 | |
.text:0000000140B1CBA7 loc_140B1CBA7: | |
.text:0000000140B1CBA7 mov rcx, r14 | |
.text:0000000140B1CBAA | |
.text:0000000140B1CBAA loc_140B1CBAA: | |
.text:0000000140B1CBAA movsxd rax, ebx | |
.text:0000000140B1CBAD mov [rbp+rax*8+368h], rcx | |
.text:0000000140B1CBB5 test rcx, rcx | |
.text:0000000140B1CBB8 jz short loc_140B1CBCC | |
.text:0000000140B1CBBA mov rax, [rdi] | |
.text:0000000140B1CBBD mov [rcx], rax | |
.text:0000000140B1CBC0 mov eax, [rdi+8] | |
.text:0000000140B1CBC3 mov [rcx+8], eax | |
.text:0000000140B1CBC6 mov eax, [rdi+0Ch] | |
.text:0000000140B1CBC9 mov [rcx+0Ch], eax | |
.text:0000000140B1CBCC | |
.text:0000000140B1CBCC loc_140B1CBCC: | |
.text:0000000140B1CBCC | |
.text:0000000140B1CBCC mov rbx, [rsi+48h] | |
.text:0000000140B1CBD0 mov rdx, [rbx] | |
.text:0000000140B1CBD3 test rdx, rdx | |
.text:0000000140B1CBD6 jz short loc_140B1CBF6 | |
.text:0000000140B1CBD8 mov ecx, [rdx+0Ch] | |
.text:0000000140B1CBDB mov eax, r14d | |
.text:0000000140B1CBDE sub ecx, [rbx+0Ch] | |
.text:0000000140B1CBE1 cmovns eax, ecx | |
.text:0000000140B1CBE4 mov [rdx+0Ch], eax | |
.text:0000000140B1CBE7 mov dword ptr [rbx+8], 0FFFFFFFFh | |
.text:0000000140B1CBEE mov [rbx+0Ch], r14d | |
.text:0000000140B1CBF2 mov rbx, [rsi+48h] | |
.text:0000000140B1CBF6 | |
.text:0000000140B1CBF6 loc_140B1CBF6: | |
.text:0000000140B1CBF6 test rbx, rbx | |
.text:0000000140B1CBF9 jz short loc_140B1CC20 | |
.text:0000000140B1CBFB mov rcx, cs:qword_1457F5148 | |
.text:0000000140B1CC02 test rcx, rcx | |
.text:0000000140B1CC05 jnz short loc_140B1CC13 | |
.text:0000000140B1CC07 call sub_141C22CC0 | |
.text:0000000140B1CC0C mov rcx, cs:qword_1457F5148 | |
.text:0000000140B1CC13 | |
.text:0000000140B1CC13 loc_140B1CC13: | |
.text:0000000140B1CC13 mov rax, [rcx] | |
.text:0000000140B1CC16 mov rdx, rbx | |
.text:0000000140B1CC19 call qword ptr [rax+20h] | |
.text:0000000140B1CC1C mov [rsi+48h], r14 | |
.text:0000000140B1CC20 | |
.text:0000000140B1CC20 loc_140B1CC20: | |
.text:0000000140B1CC20 mov rbx, [rsp+28h+arg_0] | |
.text:0000000140B1CC25 mov r14, [rsp+28h+arg_8] | |
.text:0000000140B1CC2A | |
.text:0000000140B1CC2A loc_140B1CC2A: | |
.text:0000000140B1CC2A | |
.text:0000000140B1CC2A mov rbp, [rsp+28h+arg_10] | |
.text:0000000140B1CC2F mov rsi, [rsp+28h+arg_18] | |
.text:0000000140B1CC34 add rsp, 20h | |
.text:0000000140B1CC38 pop rdi | |
.text:0000000140B1CC39 retn | |
.text:0000000140B1CC39 APlayerState_SubItem endp | |
*/ | |
/// IDA PSUEDOCODE | |
/* | |
v4 = a1 + 8i64 * a2; | |
v11 = *(__int64 **)(v4 + 0x48); // inventory | |
v12 = *v11; // Slot | |
v13 = *(_DWORD *)(v12 + 0xC) - *((_DWORD *)v11 + 3); // sub item | |
// ADJUSTED FOR READABILITY | |
auto v4 = p + 8 * index; // OnSubItem* | |
AInventory* v11 = *(__int64**)(v4 + 0x48); // inventory | |
AItemSlot* v12 = reinterpret_cast<AItemSlot*>(*v11); // ItemSlot | |
int sub_amount = *((__int32*)v11 + 3); // sub amount | |
int v13 = v12->count - sub_amount; // sub item new amount | |
*/ | |
/// | |
/* | |
/// RECREATION | |
// auto pUseItem = reinterpret_cast<OnUseItem*> (p); | |
// AItemSlot oItem = pUseItem->GetInventory()->Item; | |
/// Get Other Slots | |
// AItemSlot* slot = pUseItem->GetItemSlot(index + 1); | |
// auto slot_item_count = slot->count; | |
*/ | |
auto v4 = p + 8 * index; // OnSubItem* | |
auto v11 = *(__int64**)(v4 + 0x48); // inventory | |
AItem* v12 = reinterpret_cast<AItem*>(*v11); // ItemSlot | |
int sub_amount = *((__int32*)v11 + 3); // sub amount | |
int v13 = v12->Count - sub_amount; // sub item new amount | |
if (g_Console->m_bVerbose) | |
Console::Log("[+] [Hooking::APlayerState_SubItem(0x%llX, %d)]\n- subAmount: %d\n- origCount: %d\n- newCount: %d\n- bNullItem: %d\n\n", | |
p, index, sub_amount, v12->Count, v13, AGame::bNullItem); | |
if (AGame::bNullItem) | |
{ | |
auto result = APlayerState_SubItem_stub(p, index); | |
// Set new amount ( revert change ) | |
v12->Count = (v13 + sub_amount); | |
return result; | |
} | |
// exec original fn | |
return APlayerState_SubItem_stub(p, index); | |
} |
Enemy Stats
FinalFantasy7Remake-Menu/src/Game.cpp
Lines 699 to 755 in 8bd9d81
__int64 AGame::Hooks::ATargetEntity_GetHP_hook(__int64 p) | |
{ | |
static bool bEditing{ false }; // used so can call this function [ pTarget->GetHP() ] // recursion safety | |
auto pTarget = reinterpret_cast<ATarget*>(p); | |
if (!bEditing && pTarget && pTarget->IsValid()) | |
{ | |
bEditing = true; | |
// target level is adjusted | |
if (AGame::bModTargetLevel) | |
pTarget->SetLevel(iLevelScalar); | |
// target health is restored ( note: target can still die if damage taken is > maxhp ) | |
if (AGame::bNullTargetDmg) | |
pTarget->SetHP(pTarget->GetHPMax()); | |
// target wont attack player | |
if (AGame::bNoTargetAttack) | |
{ | |
// Attack Rate | |
pTarget->SetAttackRate(0.0f); | |
// Special Attack Timer | |
pTarget->SetSpAtkTime(0.0f); | |
// Special Attack Threshold | |
pTarget->SetSpAtkTimeMax(0.0f); | |
} | |
// prevents targets from attacking , sets max level and sets defenses to 0 | |
// - apply Auto Kill || Auto Stagger for increased effects | |
if (AGame::bXpFarm) | |
{ | |
// Set Level for rewards | |
pTarget->SetLevel(9999); | |
// prevent targets from attacking party | |
pTarget->SetAttackRate(0.0f); | |
// prevent targets from using special attacks | |
pTarget->SetSpAtkTimeMax(0.0f); | |
// set target defense to 0 for critical hits | |
pTarget->SetDefense(0); | |
// set target magic defense to 0 for critical magic hits | |
pTarget->SetMagicDef(0); | |
} | |
// target is killed | |
if (AGame::bKillTarget) | |
pTarget->SetHP(0); | |
bEditing = false; | |
} | |
return ATargetEntity_GetHP_stub(p); | |
} |
Enemy Stagger
FinalFantasy7Remake-Menu/src/Game.cpp
Lines 758 to 768 in 8bd9d81
__int64 AGame::Hooks::ATargetEntity_GetStaggerAmount_hook(__int64 a1) | |
{ | |
if (AGame::bTargetAlwaysStagger) | |
{ | |
auto pEnt = reinterpret_cast<ATargetStagger*>(a1); | |
if (pEnt) | |
pEnt->Stagger = pEnt->StaggerMax; | |
} | |
return ATargetEntity_GetStaggerAmount_stub(a1); | |
} |
- Issues are to be used for programming error only such as application crashing induced by methods in the module. Please refrain from opening issues in regards to outdated offsets.
- Pull requests are welcome , please adhere to the coding guidlines as outlined below
GUIDELINES
FinalFantasy7Remake-Menu/include/Game.h
Lines 7 to 22 in 8bd9d81
/* | |
* GENERAL GUIDELINES | |
* | |
* namespace : global game member variables. should be constexpr as the values will never change. | |
* struct : offsets arranged with padding to align with game memory. member variables are public by default. | |
* class : implies the "struct" has virtual methods, member variables should be made private with methods for accessing data for safety | |
* enum : should be as close to the origin data structure as possible. i.e EItemType would reside above AItem | |
* member vars : [bool : b<name> : bValid] [enum : e<Name> : eType] [pointer : p<Name> : pInstance] [static pointer : g<Name>] [global : g_<prefix><Name> : g_bRunning] | |
* A<StructName> : all game engine general purpose class and struct names should be prefixed with A to signify it is a game engine related data structure | |
* T<StructName> : all game engine template class and struct names should be prefixed with T to signify that it is both a templated and game related data structure. | |
* | |
* ternary : keep it basic and readable. | |
* recursion : would batman ? | |
* | |
*/ |