From 6aa29e23dac3952bf185f1996c1442adbf2624f8 Mon Sep 17 00:00:00 2001 From: Bubb13 <36863623+Bubb13@users.noreply.github.com> Date: Fri, 18 Jan 2019 21:30:30 -0800 Subject: [PATCH] New gameplay behaviors are now disabled by default --- EEex/copy/B3_Books.lua | 11 +++++ EEex/copy/B3_Hotke.lua | 107 +++++++++++++++++++++++++++++++++++++++++ EEex/copy/B3_Invis.lua | 94 ++++++++++++++++++++++++++++++++++++ EEex/copy/EEex_AHo.lua | 7 +-- EEex/copy/EEex_INI.lua | 6 +++ EEex/copy/EEex_Mac.lua | 14 ++++++ EEex/copy/EEex_Opc.lua | 17 ++++--- EEex/copy/M__EEex.lua | 30 +++++++++++- 8 files changed, 273 insertions(+), 13 deletions(-) create mode 100644 EEex/copy/B3_Books.lua create mode 100644 EEex/copy/B3_Hotke.lua create mode 100644 EEex/copy/B3_Invis.lua create mode 100644 EEex/copy/EEex_INI.lua diff --git a/EEex/copy/B3_Books.lua b/EEex/copy/B3_Books.lua new file mode 100644 index 0000000..4f06111 --- /dev/null +++ b/EEex/copy/B3_Books.lua @@ -0,0 +1,11 @@ + +function B3Books_InstallBookChanges() + + EEex_DisableCodeProtection() + + EEex_WriteAssembly(0x6870F6, {"!jmp_byte"}) -- force bookMode to true + EEex_WriteAssembly(0x709287, {"!jmp_byte"}) -- force hasMageBook to true + + EEex_EnableCodeProtection() +end +B3Books_InstallBookChanges() diff --git a/EEex/copy/B3_Hotke.lua b/EEex/copy/B3_Hotke.lua new file mode 100644 index 0000000..4bf4d87 --- /dev/null +++ b/EEex/copy/B3_Hotke.lua @@ -0,0 +1,107 @@ + +B3Hotkey_PrintKeys = false +function B3Hotkey_TogglePrintKeys() + if not B3Hotkey_PrintKeys then + B3Hotkey_PrintKeys = true + Infinity_DisplayString("[EEex] Enabled Key-Pressed Output") + else + B3Hotkey_PrintKeys = false + Infinity_DisplayString("[EEex] Disabled Key-Pressed Output") + end +end + +B3Hotkey_Hotkeys = { + {B3Hotkey_TogglePrintKeys, 3, 0x60}, -- Key-Pressed Output Toggle + --{"SPWI112", 3, 0x61, 0x73, 0x64}, -- Example keybinding... +} + +function B3Hotkey_AttemptToCastViaHotkey(resref) + local actorID = EEex_GetActorIDSelected() + if actorID ~= 0x0 then + local useCGameButtonList = function(m_CGameSprite, m_CGameButtonList) + local found = false + EEex_IterateCPtrList(m_CGameButtonList, function(m_CButtonData) + -- m_CButtonData.m_abilityId.m_res + local m_res = EEex_ReadLString(m_CButtonData + 0x1C + 0x6, 0x8) + if m_res == resref then + -- Unlike most other functions, CGameSprite::ReadySpell() expects the CButtonData + -- arg to be passed by VALUE, not by reference. EEex's call() function isn't designed + -- to do that, so the hacky hilarity that follows is required... + local stackArgs = {} + table.insert(stackArgs, 0x0) + for i = 0x30, 0x0, -0x4 do + table.insert(stackArgs, EEex_ReadDword(m_CButtonData + i)) + end + EEex_Call(EEex_Label("CGameSprite::ReadySpell"), stackArgs, m_CGameSprite, 0x0) + found = true + return true -- breaks out of EEex_IterateCPtrList() + end + end) + EEex_FreeCPtrList(m_CGameButtonList) + return found + end + local m_CGameSprite = EEex_GetActorShare(actorID) + local spellButtonDataList = EEex_Call(EEex_Label("CGameSprite::GetQuickButtons"), {0, 2}, m_CGameSprite, 0x0) + if useCGameButtonList(m_CGameSprite, spellButtonDataList) then return end + local innateButtonDataList = EEex_Call(EEex_Label("CGameSprite::GetQuickButtons"), {0, 4}, m_CGameSprite, 0x0) + useCGameButtonList(m_CGameSprite, innateButtonDataList) + end +end + +B3Hotkey_LastSuccessfulHotkey = nil + +function B3Hotkey_KeyPressedListener(key) + if worldScreen == e:GetActiveEngine() then + if B3Hotkey_PrintKeys then + Infinity_DisplayString("[EEex] Pressed: "..EEex_ToHex(key)) + end + local completedMatch = false + for _, hotkeyDef in ipairs(B3Hotkey_Hotkeys) do + local stage = hotkeyDef[2] + if stage ~= 0 then + if hotkeyDef[stage] == key then + if stage ~= #hotkeyDef then + hotkeyDef[2] = stage + 1 -- Advance + else + -- Success + hotkeyDef[2] = 0 -- Stop Processing + B3Hotkey_LastSuccessfulHotkey = hotkeyDef + completedMatch = true + end + + else + -- Fail + hotkeyDef[2] = 0 -- Stop Processing + end + end + end + if not completedMatch then + B3Hotkey_LastSuccessfulHotkey = nil + end + end +end +EEex_AddKeyPressedListener(B3Hotkey_KeyPressedListener) + +function B3Hotkey_KeyReleasedListener(key) + if B3Hotkey_LastSuccessfulHotkey ~= nil then + local hotkeyValue = B3Hotkey_LastSuccessfulHotkey[1] + local hotkeyValueType = type(hotkeyValue) + if hotkeyValueType == "string" then + B3Hotkey_AttemptToCastViaHotkey(hotkeyValue) + elseif hotkeyValueType == "function" then + hotkeyValue() + end + end + B3Hotkey_LastSuccessfulHotkey = nil + for _, hotkeyDef in ipairs(B3Hotkey_Hotkeys) do + hotkeyDef[2] = 3 + end +end +EEex_AddKeyReleasedListener(B3Hotkey_KeyReleasedListener) + +function B3Hotkey_ResetListener() + EEex_AddKeyPressedListener(B3Hotkey_KeyPressedListener) + EEex_AddKeyReleasedListener(B3Hotkey_KeyReleasedListener) + EEex_AddResetListener(B3Hotkey_ResetListener) +end +EEex_AddResetListener(B3Hotkey_ResetListener) diff --git a/EEex/copy/B3_Invis.lua b/EEex/copy/B3_Invis.lua new file mode 100644 index 0000000..b0f4235 --- /dev/null +++ b/EEex/copy/B3_Invis.lua @@ -0,0 +1,94 @@ + +B3Invis_RenderAsInvisible = false + +function B3Invis_InstallOpcode193Changes() + + EEex_DisableCodeProtection() + + local canSeeInvisAddress = EEex_WriteAssemblyAuto({[[ + !build_stack_frame + !sub_esp_byte 04 + !push_registers + !mov_eax_[dword] *g_pBaldurChitin + !mov_eax_[eax+dword] #D14 + !mov_esi_[eax+dword] #3E54 + !test_esi_esi + !je_dword >fail + !xor_ebx_ebx + @loop + !lea_ecx_[ebp+byte] FC + !push_ecx + !push_[esi+byte] 08 + !call >CGameObjectArray::GetShare + !mov_ecx_[ebp+byte] FC + !cmp_[ecx+dword]_byte #C08 00 + !jne_dword >found + !mov_esi_[esi] + !test_esi_esi + !jne_dword >loop + @fail + !mov_ebx #01 + @found + !mov_eax_ebx + !restore_stack_frame + !ret + ]]}) + + local invisCheckHook1 = EEex_WriteAssemblyAuto({[[ + !push_complete_state + !cmp_[esi+dword]_byte #2D07 00 + !je_dword >ret + !call ]], {canSeeInvisAddress, 4, 4}, [[ + !cmp_eax_byte 00 + @ret + !pop_complete_state + !ret + ]]}) + + local invisCheckHook2 = EEex_WriteAssemblyAuto({[[ + !push_complete_state + !cmp_[ebx+dword]_byte #2D07 00 + !je_dword >ret + !call ]], {canSeeInvisAddress, 4, 4}, [[ + !cmp_eax_byte 00 + @ret + !pop_complete_state + !ret + ]]}) + + local forceCircleHook = EEex_WriteAssemblyAuto({[[ + !push_complete_state + !cmp_[eax+dword]_byte #9B 00 + !jne_dword >ret + !cmp_[ebx+dword]_byte #2D07 00 + !je_dword >ret + !call ]], {canSeeInvisAddress, 4, 4}, [[ + !cmp_eax_byte 01 + @ret + !pop_complete_state + !ret + ]]}) + + EEex_WriteAssembly(0x6EE5F1, {"!call", {invisCheckHook1, 4, 4}, "!nop !nop"}) + EEex_WriteAssembly(0x6FC1C2, {"!call", {invisCheckHook2, 4, 4}, "!nop !nop"}) + EEex_WriteAssembly(0x6FC237, {"!call", {forceCircleHook, 4, 4}, "!nop !nop"}) + + if B3Invis_RenderAsInvisible then + + local invisCheckHook3 = EEex_WriteAssemblyAuto({[[ + !push_complete_state + !cmp_[ebx+dword]_byte #2D07 00 + !je_dword >ret + !call ]], {canSeeInvisAddress, 4, 4}, [[ + !cmp_eax_byte 01 + @ret + !pop_complete_state + !ret + ]]}) + + EEex_WriteAssembly(0x6F9170, {"!call", {invisCheckHook2, 4, 4}, "!nop !nop"}) + EEex_WriteAssembly(0x6F9970, {"!call", {invisCheckHook3, 4, 4}, "!nop !nop"}) + end + EEex_EnableCodeProtection() +end +B3Invis_InstallOpcode193Changes() diff --git a/EEex/copy/EEex_AHo.lua b/EEex/copy/EEex_AHo.lua index 72970f8..17e02a5 100644 --- a/EEex/copy/EEex_AHo.lua +++ b/EEex/copy/EEex_AHo.lua @@ -77,10 +77,11 @@ function EEex_SetActionPointY(actionData, newY) end function EEex_HookAction(actionData) - for _, func in ipairs(EEex_HookActionFunctions) do - func(actionData) - end + local hooksCopy = EEex_HookActionFunctions EEex_HookActionFunctions = {} + for _, hook in ipairs(hooksCopy) do + hook(actionData) + end end function EEex_InstallActionHook() diff --git a/EEex/copy/EEex_INI.lua b/EEex/copy/EEex_INI.lua new file mode 100644 index 0000000..e8e5733 --- /dev/null +++ b/EEex/copy/EEex_INI.lua @@ -0,0 +1,6 @@ + +EEex_Modules = { + ["B3_Books"] = false, + ["B3_Hotke"] = false, + ["B3_Invis"] = false, +} diff --git a/EEex/copy/EEex_Mac.lua b/EEex/copy/EEex_Mac.lua index 21940f6..a04d0df 100644 --- a/EEex/copy/EEex_Mac.lua +++ b/EEex/copy/EEex_Mac.lua @@ -33,10 +33,14 @@ for _, macroEntry in ipairs({ {"cmove_eax_ebx", "0F 44 C3"}, {"cmovne_eax_ebx", "0F 45 C3"}, {"cmovne_eax_edi", "0F 45 C7"}, + {"cmp_[eax+dword]_byte", "80 B8"}, {"cmp_[ebp+byte]_byte", "83 7D"}, {"cmp_[ebp+byte]_ebx", "39 5D"}, + {"cmp_[ebx+dword]_byte", "80 BB"}, {"cmp_[ecx+byte]_byte", "83 79"}, {"cmp_[ecx+byte]_esi", "39 71"}, + {"cmp_[ecx+dword]_byte", "80 B9"}, + {"cmp_[esi+dword]_byte", "80 BE"}, {"cmp_eax_byte", "83 F8"}, {"cmp_eax_dword", "3D"}, {"cmp_eax_ebx", "3B C3"}, @@ -114,7 +118,9 @@ for _, macroEntry in ipairs({ {"mov_eax_[esi+byte]", "8B 46"}, {"mov_eax_[esi+dword]", "8B 86"}, {"mov_eax_[esi]", "8B 46 00"}, + {"mov_eax_ebx", "8B C3"}, {"mov_eax_edx", "8B C2"}, + {"mov_ebx", "BB"}, {"mov_ebx_eax", "8B D8"}, {"mov_ebx_esp", "8B DC"}, {"mov_ecx_[ebp+byte]", "8B 4D"}, @@ -128,6 +134,7 @@ for _, macroEntry in ipairs({ {"mov_edi_eax", "8B F8"}, {"mov_edi_esp", "8B FC"}, {"mov_edx", "BA"}, + {"mov_edx_[eax+dword]", "8B 90"}, {"mov_edx_[ebx+byte]", "8B 53"}, {"mov_edx_[ebx+dword]", "8B 93"}, {"mov_edx_[ebx]", "8B 53 00"}, @@ -139,6 +146,8 @@ for _, macroEntry in ipairs({ {"mov_edx_[edx]", "8B 52 00"}, {"mov_edx_eax", "8B D0"}, {"mov_esi", "BE"}, + {"mov_esi_[eax+dword]", "8B B0"}, + {"mov_esi_[esi]", "8B 36"}, {"mov_esi_eax", "8B F0"}, {"mov_esp_[ebp+byte]", "8B 65"}, {"mov_esp_[ebp+dword]", "8B A5"}, @@ -147,12 +156,15 @@ for _, macroEntry in ipairs({ {"nop", "90"}, {"pop_eax", "58"}, {"pop_ecx", "59"}, + {"pop_complete_state", "5F 5E 5A 59 5B 58 5D"}, {"pop_state", "5F 5E 5A 59 5B 5D"}, {"push_[dword]", "FF 35"}, {"push_[ebp+byte]", "FF 75"}, {"push_[ebp+dword]", "FF B5"}, {"push_[ebp]", "FF 75 00"}, {"push_[edi+byte]", "FF 77"}, + {"push_[edx+byte]", "FF 72"}, + {"push_[esi+byte]", "FF 76"}, {"push_byte", "6A"}, {"push_dword", "68"}, {"push_eax", "50"}, @@ -161,6 +173,7 @@ for _, macroEntry in ipairs({ {"push_edx", "52"}, {"push_esi", "56"}, {"push_registers", "53 51 52 56 57"}, + {"push_complete_state", "55 8B EC 50 53 51 52 56 57"}, {"push_state", "55 8B EC 53 51 52 56 57"}, {"restore_stack_frame", "5F 5E 5A 59 5B 8B E5 5D"}, {"ret", "C3"}, @@ -178,6 +191,7 @@ for _, macroEntry in ipairs({ {"test_eax_eax", "85 C0"}, {"test_edi_edi", "85 FF"}, {"test_edx_edx", "85 D2"}, + {"test_esi_esi", "85 F6"}, {"xor_eax_eax", "33 C0"}, {"xor_ebx_ebx", "33 DB"}, --[[ diff --git a/EEex/copy/EEex_Opc.lua b/EEex/copy/EEex_Opc.lua index b251290..de88992 100644 --- a/EEex/copy/EEex_Opc.lua +++ b/EEex/copy/EEex_Opc.lua @@ -14,16 +14,17 @@ function EEex_InstallOpcodeChanges() EEex_WriteAssembly(0x5903AA, {"!nop !nop"}) EEex_WriteAssembly(0x5903DC, {"!nop !nop !nop !nop !nop !nop"}) - EEex_WriteAssembly(0x6870F6, {"!jmp_byte"}) -- force bookMode to true - EEex_WriteAssembly(0x709287, {"!jmp_byte"}) -- force hasMageBook to true + -- Set strref of opcode #324 to Special + EEex_WriteAssembly(0x57F805, {"8B 7E 44 90 90"}) - -- 0x617DBA - Render's spell icon - - EEex_WriteAssembly(0x57F805, {"8B 7E 44 90 90"}) -- Set strref of opcode #324 to Special - --EEex_WriteAssembly(0x52CBE8, {"!nop !nop !nop"}) -- Remove Opcode #262 hard limit - --EEex_WriteAssembly(0x60C7B3, {"90 90 90"}) -- Remove Opcode #262 hard limit - --EEex_WriteAssembly(0x60C7B9, {"90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90"}) -- Remove Opcode #262 hard limit + -- (Opcode #262) Not ready yet... + --[[ + EEex_WriteAssembly(0x52CBE8, {"!nop !nop !nop"}) + EEex_WriteAssembly(0x60C7B3, {"90 90 90"}) + EEex_WriteAssembly(0x60C7B9, {"90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90"}) + --]] EEex_EnableCodeProtection() + end EEex_InstallOpcodeChanges() diff --git a/EEex/copy/M__EEex.lua b/EEex/copy/M__EEex.lua index 74fac58..0b3e0d6 100644 --- a/EEex/copy/M__EEex.lua +++ b/EEex/copy/M__EEex.lua @@ -364,7 +364,7 @@ function EEex_CalcWriteLength(address, args) else toReturn = toReturn + macroResult end - elseif prefix ~= "@" then + elseif prefix ~= "@" and prefix ~= "$" then toReturn = toReturn + 1 end end @@ -431,7 +431,7 @@ function EEex_CalcLabelOffset(address, args, label) else toReturn = toReturn + macroResult end - elseif prefix == "@" then + elseif prefix == "@" or prefix == "$" then local argLabel = string.sub(section, 2, #section) if argLabel == label then return true @@ -786,6 +786,7 @@ Core function that writes assembly declarations into memory. args syntax => @label = Defines a local label that can be used in the above two operations. (only in current EEex_WriteAssembly call, use EEex_DefineAssemblyLabel() if you want to create a global label) + $label = Defines a global label !macro = Writes macro's bytes. b) table: @@ -882,6 +883,9 @@ function EEex_WriteAssembly(address, args, funcOverride) else currentWriteAddress = currentWriteAddress + macroResult end + elseif prefix == "$" then + local label = string.sub(section, 2, #section) + EEex_DefineAssemblyLabel(label, currentWriteAddress) elseif prefix ~= "@" then local byte = tonumber(section, 16) funcOverride(currentWriteAddress, byte) @@ -1481,6 +1485,17 @@ Infinity_DoFile("EEex_Tri") -- New Triggers / Trigger Changes Infinity_DoFile("EEex_Obj") -- New Script Objects Infinity_DoFile("EEex_Ren") -- Render Hook +-------------- +-- Modules -- +-------------- + +Infinity_DoFile("EEex_INI") -- Define modules... +for moduleName, moduleEnabled in pairs(EEex_Modules) do + if moduleEnabled then + Infinity_DoFile(moduleName) + end +end + --------------------- -- Input Details -- --------------------- @@ -1690,6 +1705,17 @@ function EEex_GetActorIDSelected() end end +function EEex_GetAllActorIDSelected() + local ids = {} + local g_pBaldurChitin = EEex_ReadDword(EEex_Label("g_pBaldurChitin")) -- (CBaldurChitin) + local m_pObjectGame = EEex_ReadDword(g_pBaldurChitin + 0xD14) -- (CInfGame) + local CPtrList = m_pObjectGame + 0x3E50 + EEex_IterateCPtrList(CPtrList, function(actorID) + table.insert(ids, actorID) + end) + return ids +end + ------------------------------ -- Actionbar Manipulation -- ------------------------------