From 4b06d8a0343cdeb57ed77809b2dd66703c055c85 Mon Sep 17 00:00:00 2001 From: Scouter407 <59450096+Scouter407@users.noreply.github.com> Date: Sun, 15 Dec 2024 17:29:03 -0500 Subject: [PATCH] Fixed the mod --- Source.cpp | 198 +++++++++++++++++++++++++---------------------------- 1 file changed, 93 insertions(+), 105 deletions(-) diff --git a/Source.cpp b/Source.cpp index 6ccf108..3ef7b5c 100644 --- a/Source.cpp +++ b/Source.cpp @@ -4,170 +4,158 @@ #include #include #include - -UInt32 SkillCheckVar = 0; -char newSkillString[516]; -char customOffset[8] = "%s[%s] "; -char customOffset1[7] = "%s%s"; -char MWString[14] = "Melee Weapons"; -char EWString[15] = "Energy Weapons"; +#include // For std::memset namespace DiaCondExtended { + // Constants for the various actor value strings + const char MWString[] = "Melee Weapons"; + const char EWString[] = "Energy Weapons"; + const char unknown[] = "unknown"; + + UInt32 SkillCheckVar = 0; // Actor Value Code (AV Code) + char newSkillString[516]; // Buffer for formatted skill check string + char customOffset[8] = "%s[%s] "; + char customOffset1[7] = "%s%s"; // Format string for success case - //Takes the Actor Value Code stored in SkillCheckVar and converts it to a string + // Returns a string representation of the Actor Value (AV) code const char* GetSkillCheckString() { - const char* name = nullptr; if (SkillCheckVar <= eActorVal_FalloutMax) { - //I'm so, so sorry if you speak another language, I'm lazy AF - //If either MeleeWeapons or EnergyWeapons, changes the string to have a space - if (SkillCheckVar == 0x26) - { - name = MWString; - } - else if (SkillCheckVar == 0x22) - { - name = EWString; - } - - else - { - name = GetActorValueString(SkillCheckVar); - } - } - else - { - name = "unknown"; - } - return name; + if (SkillCheckVar == 0x26) { return MWString; } + if (SkillCheckVar == 0x22) { return EWString; } + return GetActorValueString(SkillCheckVar); // Fetch the Actor Value string + } + return unknown; } - //Grabs the AVcode from the ECX register at this address and stores it in SkillCheckVar + // Hook to grab the AV code from the ECX register and store it in SkillCheckVar _declspec(naked) void __fastcall GetAvCodeHook() { static const UInt32 returnAddr = 0x763C40; + _asm { - mov[ebp - 0x23C], ecx //Rewriting Overwritten Address - mov SkillCheckVar, ecx //ECX = AvCode --> SkillCheckVar - jmp returnAddr + mov[ebp - 0x23C], ecx // Save ECX value + mov SkillCheckVar, ecx // Store ECX value as the AV code + jmp returnAddr // Return to original function } } - //Wipes the string buffer before the loop starts, so that the 'AV/Perk' category in the GECK is irrelevant + // Clears the string buffer at the start of processing _declspec(naked) void __fastcall WipeBuffer() { - static const UInt32 FormatString = 0x406D00; static const UInt32 returnAddr = 0x763BD9; + _asm { - mov[ebp - 0x230], eax //Rewriting Overwritten Address - lea edi, [ebp - 0x208] - mov ecx, 0x200 - xor eax, eax - rep stosb //Cleared StringBuffer - jmp returnAddr + lea edi, [ebp - 0x208] // Load address of string buffer + mov ecx, 0x200 // Set buffer size + xor eax, eax // Clear eax register (used by rep stosb) + rep stosb // Fill string buffer with zeros + jmp returnAddr // Return to original function } } - //Modifies the construction of the failure string. + // Modifies the failure string construction _declspec(naked) void __stdcall StringModFail() { - static const UInt32 FormatString = 0x406D00; - static const UInt32 offsetAddr = 0x01072850; static const UInt32 returnAddr = 0x763CB7; + static const UInt32 offsetAddr = 0x01072850; + _asm { - call GetSkillCheckString - push eax //eax = AvCode - push offsetAddr //"%s %d/%d" - push 0x200 - lea eax, newSkillString - push eax - call FormatString //FormatString(newSkillString, 512, "%s %d/%d", AvCode, ClampedActorValueI, ComparisonValue) - add esp, 0x18 //2 arguments before jump + 4 new arguments = 6 arguments = 24 bits - - lea eax, newSkillString //Concatenated String - push eax - lea edx, [ebp - 0x208] //StringBuffer - push edx - push offset customOffset //"%s[%s] " - push 0x200 - lea eax, [ebp - 0x208] - push eax - call FormatString //FormatString(StringBuffer, 512, "%s[%s] ", StringBuffer, newSkillString) - add esp, 0x14 //Need to clean 20 bits for 5 arguments - - jmp returnAddr + call GetSkillCheckString // Get AV code string + push eax // Push AV code string to the stack + push offsetAddr // Push format string for failure + push 0x200 // Buffer size for formatted string + lea eax, newSkillString // Load address of newSkillString + push eax // Push buffer for formatted string + call FormatString // Format the failure string + + add esp, 0x18 // Clean up the stack (4 arguments) + lea eax, newSkillString // Load the concatenated failure string + push eax // Push formatted string + lea edx, [ebp - 0x208] // Load address of string buffer + push edx // Push string buffer to the stack + push offset customOffset // Push format string for success message + push 0x200 // Buffer size for formatted string + lea eax, [ebp - 0x208] // Load address of string buffer + push eax // Push string buffer + call FormatString // Format the success string + + add esp, 0x14 // Clean up the stack + jmp returnAddr // Return to the original function } } - //Modifies the construction of the success string. + // Modifies the success string construction _declspec(naked) void __stdcall StringModPass() { - static const UInt32 FormatString = 0x406D00; - static const UInt32 offsetAddr = 0x0104700C; static const UInt32 returnAddr = 0x763CE4; + static const UInt32 offsetAddr = 0x0104700C; + _asm { - call GetSkillCheckString - push eax //eax = AvCode - push offsetAddr //"%s %d" - push 0x200 - lea eax, newSkillString - push eax - call FormatString //FormatString(newSkillString, 512, "%s %d", AvCode, ComparisonValue) - add esp, 0x14 - - lea eax, newSkillString //Concatenated String - push eax - lea edx, [ebp - 0x208] //StringBuffer - push edx - push offset customOffset //"%s[%s] " - push 0x200 - lea eax, [ebp - 0x208] - push eax - call FormatString //FormatString(StringBuffer, 512, "%s[%s] ", StringBuffer, newSkillString) - - jmp returnAddr + call GetSkillCheckString // Get AV code string + push eax // Push AV code string to the stack + push offsetAddr // Push format string for success + push 0x200 // Buffer size for formatted string + lea eax, newSkillString // Load address of newSkillString + push eax // Push buffer for formatted string + call FormatString // Format the success string + + add esp, 0x14 // Clean up the stack + lea eax, newSkillString // Load the concatenated success string + push eax // Push formatted string + lea edx, [ebp - 0x208] // Load address of string buffer + push edx // Push string buffer to the stack + push offset customOffset // Push format string for success message + push 0x200 // Buffer size for formatted string + lea eax, [ebp - 0x208] // Load address of string buffer + push eax // Push string buffer + call FormatString // Format the string buffer + + jmp returnAddr // Return to the original function } } - //Removes the appended ']' at the end of the skill tag + // Removes the appended ']' at the end of the skill tag _declspec(naked) void __fastcall EndModString() { static const UInt32 returnAddr = 0x763D1E; _asm { - push offset customOffset1 - jmp returnAddr + push offset customOffset1 // Push the modified format string + jmp returnAddr // Return to the original function } } - //Function to initialize hooks + // Initializes all hooks for modifying dialogue conditions void InitHooks() { - UInt32 avHookAddr = 0x763C3A; //This is an Address where the ECX Register = AvCode - UInt32 loopStartAddr = 0x763BD3; //This Address is the start of the For Loop - UInt32 failStrAddr = 0x763C97; //This Address is for the String Buffer right before the string is formatted (Failure Condition) - UInt32 passStrAddr = 0x763CC7; //This Address is for the String Buffer right before the string is formatted (Success Condition) - UInt32 endFormatAddr = 0x763D19; //THis Address pushes the string definition "%s] %s" as an offset to close the Skill Tag up; ']' - - ULONG_PTR breakAddr1 = 0x763CE7; //breakAddr1 and 2 are responsible for the break at the end of the for loop - ULONG_PTR breakAddr2 = 0x763CE8; - - //Extend Dialogue Conditions + // Memory addresses for hook locations + const UInt32 avHookAddr = 0x763C3A; + const UInt32 loopStartAddr = 0x763BD3; + const UInt32 failStrAddr = 0x763C97; + const UInt32 passStrAddr = 0x763CC7; + const UInt32 endFormatAddr = 0x763D19; + + // Break addresses for loop control + const ULONG_PTR breakAddr1 = 0x763CE7; + const ULONG_PTR breakAddr2 = 0x763CE8; + + // Write the hooks into the game code WriteRelJump(avHookAddr, UInt32(GetAvCodeHook)); WriteRelJump(loopStartAddr, UInt32(WipeBuffer)); WriteRelJump(failStrAddr, UInt32(StringModFail)); WriteRelJump(passStrAddr, UInt32(StringModPass)); WriteRelJump(endFormatAddr, UInt32(EndModString)); - //Remove loop break + // Remove the loop break instructions to modify loop behavior PatchMemoryNop(breakAddr1, 1); PatchMemoryNop(breakAddr2, 1); } -} \ No newline at end of file +}