/FinalFantasy7Remake-Menu

Final Fantasy Vii Remake Internal Cheat w/ Dear ImGui

Primary LanguageC++

FinalFantasy7Remake-Menu

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.

Codacy Badge Static Badge image

FEATURES

  • Party Stats Manager
  • Basic Cheats

USAGE

  • 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

UPDATING

Main Game Offset
constexpr auto oGameBase{ 0x57B9260 }; // 48 8B 05 ? ? ? ? 4C 89 B4 24 ? ? ? ? 44 0F B6 76
Pause Game
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
__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
__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
__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
__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
__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
__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);
}

CONTRIBUTING

  • 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
/*
* 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 ?
*
*/

References & Credits

Dear ImGui
MinHook
DX11-Internal-Base