From 0a09fffa4d51b3bc0921c3d365620230243d3a89 Mon Sep 17 00:00:00 2001 From: 4Luke4 Date: Fri, 15 May 2026 17:07:06 +0200 Subject: [PATCH 1/2] Op410/op411 --- EEex/copy/EEex_scripts/EEex_Mix_Patch.lua | 38 ++++++++ EEex/copy/EEex_scripts/EEex_Opcode.lua | 22 +++++ EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua | 94 ++++++++++++++++++-- EEex/loader/InfinityLoader.db | 16 ++++ 4 files changed, 163 insertions(+), 7 deletions(-) diff --git a/EEex/copy/EEex_scripts/EEex_Mix_Patch.lua b/EEex/copy/EEex_scripts/EEex_Mix_Patch.lua index 715689d..ba939e6 100644 --- a/EEex/copy/EEex_scripts/EEex_Mix_Patch.lua +++ b/EEex/copy/EEex_scripts/EEex_Mix_Patch.lua @@ -134,6 +134,44 @@ }) ) + --------------------------------------------------------- + -- [EEex.dll] EEex::Opcode_Hook_ApplyMissMeleeEffects() -- + --------------------------------------------------------- + + EEex_HookConditionalJumpOnSuccessWithLabels(EEex_Label("Hook-CGameSprite::Swing()-MeleeMissResultJmp"), 0, { + {"hook_integrity_watchdog_ignore_registers", { + EEex_HookIntegrityWatchdogRegister.RAX, EEex_HookIntegrityWatchdogRegister.RCX, EEex_HookIntegrityWatchdogRegister.RDX, + EEex_HookIntegrityWatchdogRegister.R8, EEex_HookIntegrityWatchdogRegister.R9, EEex_HookIntegrityWatchdogRegister.R10, + EEex_HookIntegrityWatchdogRegister.R11 + }}}, + {[[ + #MAKE_SHADOW_SPACE + mov rdx, r15 ; target + mov rcx, rbx ; attacker + call #L(EEex::Opcode_Hook_ApplyMissMeleeEffects) + #DESTROY_SHADOW_SPACE + ]]} + ) + + ---------------------------------------------------------- + -- [EEex.dll] EEex::Opcode_Hook_ApplyMissRangedEffects() -- + ---------------------------------------------------------- + + EEex_HookConditionalJumpOnFailWithLabels(EEex_Label("Hook-CGameSprite::Swing()-RangedMissResultJmp"), 7, { + {"hook_integrity_watchdog_ignore_registers", { + EEex_HookIntegrityWatchdogRegister.RAX, EEex_HookIntegrityWatchdogRegister.RCX, EEex_HookIntegrityWatchdogRegister.RDX, + EEex_HookIntegrityWatchdogRegister.R8, EEex_HookIntegrityWatchdogRegister.R9, EEex_HookIntegrityWatchdogRegister.R10, + EEex_HookIntegrityWatchdogRegister.R11 + }}}, + {[[ + #MAKE_SHADOW_SPACE + mov rdx, r15 ; target + mov rcx, rbx ; attacker + call #L(EEex::Opcode_Hook_ApplyMissRangedEffects) + #DESTROY_SHADOW_SPACE + ]]} + ) + EEex_EnableCodeProtection() end)() diff --git a/EEex/copy/EEex_scripts/EEex_Opcode.lua b/EEex/copy/EEex_scripts/EEex_Opcode.lua index 40ea87a..cc96c0a 100644 --- a/EEex/copy/EEex_scripts/EEex_Opcode.lua +++ b/EEex/copy/EEex_scripts/EEex_Opcode.lua @@ -119,6 +119,28 @@ function EEex_Opcode_Private_ApplyExtraRangedEffects(sprite, targetSprite) end) end +function EEex_Opcode_Private_IterateMissEffects(sprite, ranged, func) + + -- op410/op411 children are owned by EEex-side derived-stat storage rather than + -- the vanilla m_cExtraMeleeEffects / m_cExtraRangedEffects lists. + local count = ranged and EEex.GetMissRangedEffectCount(sprite) or EEex.GetMissMeleeEffectCount(sprite) + + for i = 0, count - 1 do + local effect = ranged and EEex.GetMissRangedEffect(sprite, i) or EEex.GetMissMeleeEffect(sprite, i) + if effect ~= nil then + func(effect, i) + end + end +end + +function EEex_Opcode_IterateMissMeleeEffects(sprite, func) + EEex_Opcode_Private_IterateMissEffects(sprite, false, func) +end + +function EEex_Opcode_IterateMissRangedEffects(sprite, func) + EEex_Opcode_Private_IterateMissEffects(sprite, true, func) +end + ----------- -- Hooks -- ----------- diff --git a/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua b/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua index 871cb2f..4efb94a 100644 --- a/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua +++ b/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua @@ -223,7 +223,7 @@ +------------------------------------------------------------------------------------------------------------------------------------------+ | (special & 1) != 0 -> .EFF bypasses op120 | +------------------------------------------------------------------------------------------------------------------------------------------+ - | [EEex.dll] EEex::Opcode_Hook_OnOp248AddTail(pOp248: CGameEffect*, pExtraEffect: CGameEffect*) | + | [EEex.dll] EEex::Opcode_Hook_OnOp248AddTail(pOp248: CGameEffect*, pExtraEffect: CGameEffect*, pNode: CNode*, pSprite: CGameSprite*) | +------------------------------------------------------------------------------------------------------------------------------------------+ | [Lua] [EEex_Mix_Patch.lua] EEex_Opcode_Hook_OnAfterSwingCheckedOp248(sprite: CGameSprite, targetSprite: CGameSprite, blocked: boolean) | +------------------------------------------------------------------------------------------------------------------------------------------+ @@ -234,11 +234,22 @@ --------------------------------------------------- EEex_HookAfterCallWithLabels(EEex_Label("Hook-CGameEffectMeleeEffect::ApplyEffect()-AddTail"), { - {"hook_integrity_watchdog_ignore_registers", {EEex_HookIntegrityWatchdogRegister.RAX}}}, + {"hook_integrity_watchdog_ignore_registers", { + EEex_HookIntegrityWatchdogRegister.RAX, EEex_HookIntegrityWatchdogRegister.RCX, EEex_HookIntegrityWatchdogRegister.RDX, + EEex_HookIntegrityWatchdogRegister.R8, EEex_HookIntegrityWatchdogRegister.R9, EEex_HookIntegrityWatchdogRegister.R10, + EEex_HookIntegrityWatchdogRegister.R11 + }}}, {[[ + ; op410 reuses CGameEffectMeleeEffect::ApplyEffect(), so the child is + ; appended to m_cExtraMeleeEffects first. Pass the newly returned node and + ; sprite to C++ so op410 can detach that exact child into miss-only storage. + mov r9, rsi ; pSprite + mov r8, rax ; pNode mov rdx, rbx ; pEffect - mov rcx, rdi ; pOp248 + mov rcx, rdi ; pOp248 / pOp410 + #MAKE_SHADOW_SPACE(32) call #L(EEex::Opcode_Hook_OnOp248AddTail) + #DESTROY_SHADOW_SPACE ]]} ) @@ -248,7 +259,7 @@ +------------------------------------------------------------------------------------------------------------------------------------------+ | (special & 1) != 0 -> .EFF bypasses op120 | +------------------------------------------------------------------------------------------------------------------------------------------+ - | [EEex.dll] EEex::Opcode_Hook_OnOp249AddTail(pOp249: CGameEffect*, pExtraEffect: CGameEffect*) | + | [EEex.dll] EEex::Opcode_Hook_OnOp249AddTail(pOp249: CGameEffect*, pExtraEffect: CGameEffect*, pNode: CNode*, pSprite: CGameSprite*) | +------------------------------------------------------------------------------------------------------------------------------------------+ | [Lua] [EEex_Mix_Patch.lua] EEex_Opcode_Hook_OnAfterSwingCheckedOp249(sprite: CGameSprite, targetSprite: CGameSprite, blocked: boolean) | +------------------------------------------------------------------------------------------------------------------------------------------+ @@ -265,11 +276,22 @@ ]]}) EEex_HookAfterCallWithLabels(EEex_Label("Hook-CGameEffectRangeEffect::ApplyEffect()-AddTail"), { - {"hook_integrity_watchdog_ignore_registers", {EEex_HookIntegrityWatchdogRegister.RAX}}}, + {"hook_integrity_watchdog_ignore_registers", { + EEex_HookIntegrityWatchdogRegister.RAX, EEex_HookIntegrityWatchdogRegister.RCX, EEex_HookIntegrityWatchdogRegister.RDX, + EEex_HookIntegrityWatchdogRegister.R8, EEex_HookIntegrityWatchdogRegister.R9, EEex_HookIntegrityWatchdogRegister.R10, + EEex_HookIntegrityWatchdogRegister.R11 + }}}, {[[ + ; op411 reuses CGameEffectRangeEffect::ApplyEffect(), so the child is + ; appended to m_cExtraRangedEffects first. Pass the parent, child, node, + ; and sprite to C++ so only op411 children are moved to miss-only storage. + mov r9, rdi ; pSprite + mov r8, rax ; pNode mov rdx, rbx ; pEffect - mov rcx, qword ptr ss:[#$(1)] ]], {op249SavedEffect}, [[ ; pOp249 + mov rcx, qword ptr ss:[#$(1)] ]], {op249SavedEffect}, [[ ; pOp249 / pOp411 + #MAKE_SHADOW_SPACE(32) call #L(EEex::Opcode_Hook_OnOp249AddTail) + #DESTROY_SHADOW_SPACE ]]} ) @@ -1111,6 +1133,54 @@ ]]}, }) + --[[ + +------------------------------------------------------------------------------------------------------------+ + | New Opcode #410 (MeleeMissEffect) | + +------------------------------------------------------------------------------------------------------------+ + | This opcode intentionally reuses CGameEffectMeleeEffect::ApplyEffect() so its child EFF decoding stays | + | byte-for-byte aligned with vanilla op248. The temporary vanilla list insertion is handled by the op248 | + | AddTail hook above: when the parent effect ID is 410, C++ removes the just-added child from | + | m_cExtraMeleeEffects and stores it in EEex-owned miss-only derived-stat storage. | + | | + | EEex_Mix_Patch.lua applies those stored children from the melee attack-roll miss branch only. | + +------------------------------------------------------------------------------------------------------------+ + --]] + + local EEex_MeleeMissEffect = genOpcodeDecode({ + ["ApplyEffect"] = {[[ + #STACK_MOD(8) ; This was called, the ret ptr broke alignment + #MAKE_SHADOW_SPACE + call #L(CGameEffectMeleeEffect::ApplyEffect) + #DESTROY_SHADOW_SPACE + ret + ]]}, + }) + + --[[ + +------------------------------------------------------------------------------------------------------------+ + | New Opcode #411 (RangeMissEffect) | + +------------------------------------------------------------------------------------------------------------+ + | This opcode intentionally reuses CGameEffectRangeEffect::ApplyEffect() so its child EFF decoding stays | + | byte-for-byte aligned with vanilla op249. The temporary vanilla list insertion is handled by the op249 | + | AddTail hook above: when the parent effect ID is 411, C++ removes the just-added child from | + | m_cExtraRangedEffects and stores it in EEex-owned miss-only derived-stat storage. | + | | + | EEex_Mix_Patch.lua applies those stored children from the ranged attack-roll miss branch only; the C++ | + | applicator mirrors op249 target handling, except target type 0 is delivered directly to the missed | + | target because a miss has no later projectile impact to carry preset-target children. | + +------------------------------------------------------------------------------------------------------------+ + --]] + + local EEex_RangeMissEffect = genOpcodeDecode({ + ["ApplyEffect"] = {[[ + #STACK_MOD(8) ; This was called, the ret ptr broke alignment + #MAKE_SHADOW_SPACE + call #L(CGameEffectRangeEffect::ApplyEffect) + #DESTROY_SHADOW_SPACE + ret + ]]}, + }) + --[[ +-------------------------------------+ | [JIT] Decode switch for new opcodes | @@ -1154,8 +1224,18 @@ _409: cmp eax, 409 - jne #L(jmp_success) + jne _410 ]], EEex_EnableActionListener, [[ + + _410: + cmp eax, 410 + jne _411 + ]], EEex_MeleeMissEffect, [[ + + _411: + cmp eax, 411 + jne #L(jmp_success) + ]], EEex_RangeMissEffect, [[ ]]}) ) EEex_HookIntegrityWatchdog_IgnoreStackSizes(EEex_Label("Hook-CGameEffect::DecodeEffect()-DefaultJmp"), {{0x60, 8}}) diff --git a/EEex/loader/InfinityLoader.db b/EEex/loader/InfinityLoader.db index 0b182a9..a801ac0 100644 --- a/EEex/loader/InfinityLoader.db +++ b/EEex/loader/InfinityLoader.db @@ -2235,6 +2235,10 @@ Operations=ADD -10 Pattern=F6472004 Operations=ADD 25 +[CGameEffectMeleeEffect::ApplyEffect] +Pattern=4889442430488BF2 +Operations=ADD -25 + [Hook-CGameEffectOverrideAnimation::ApplyEffect()-LastParam2Jmp] Pattern=4889742420574883EC30488BF1488BFA Operations=ADD 40 @@ -2247,6 +2251,10 @@ Operations=ADD 17 Pattern=4885C9747B Operations=ADD -43 +[CGameEffectRangeEffect::ApplyEffect] +Pattern=4885C9747B +Operations=ADD -43 + [Hook-CGameEffectRangeEffect::ApplyEffect()-AddTail] Pattern=488D8FC81C0000 Operations=ADD 20 @@ -2460,6 +2468,14 @@ Operations=ADD -7 Pattern=4D8D6F0CE95E010000 Operations=ADD 36 +[Hook-CGameSprite::Swing()-RangedMissResultJmp] +Pattern=751A488B8BD84A0000 +Operations=ADD 0 + +[Hook-CGameSprite::Swing()-MeleeMissResultJmp] +Pattern=0F8464080000 +Operations=ADD 0 + [Hook-CGameSprite::Swing()-GetAttackFrameType()] Pattern=488983D84A00004439B3A44E0000 Operations=ADD 75 From 04ea1a69be440dd196c2221f8257ac1417bd870d Mon Sep 17 00:00:00 2001 From: 4Luke4 Date: Sat, 16 May 2026 17:26:22 +0200 Subject: [PATCH 2/2] Formatting --- EEex/copy/EEex_scripts/EEex_Mix_Patch.lua | 8 ++++---- EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/EEex/copy/EEex_scripts/EEex_Mix_Patch.lua b/EEex/copy/EEex_scripts/EEex_Mix_Patch.lua index ba939e6..bfdaf62 100644 --- a/EEex/copy/EEex_scripts/EEex_Mix_Patch.lua +++ b/EEex/copy/EEex_scripts/EEex_Mix_Patch.lua @@ -134,9 +134,9 @@ }) ) - --------------------------------------------------------- + ---------------------------------------------------------- -- [EEex.dll] EEex::Opcode_Hook_ApplyMissMeleeEffects() -- - --------------------------------------------------------- + ---------------------------------------------------------- EEex_HookConditionalJumpOnSuccessWithLabels(EEex_Label("Hook-CGameSprite::Swing()-MeleeMissResultJmp"), 0, { {"hook_integrity_watchdog_ignore_registers", { @@ -153,9 +153,9 @@ ]]} ) - ---------------------------------------------------------- + ----------------------------------------------------------- -- [EEex.dll] EEex::Opcode_Hook_ApplyMissRangedEffects() -- - ---------------------------------------------------------- + ----------------------------------------------------------- EEex_HookConditionalJumpOnFailWithLabels(EEex_Label("Hook-CGameSprite::Swing()-RangedMissResultJmp"), 7, { {"hook_integrity_watchdog_ignore_registers", { diff --git a/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua b/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua index 4efb94a..5c13631 100644 --- a/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua +++ b/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua @@ -223,7 +223,7 @@ +------------------------------------------------------------------------------------------------------------------------------------------+ | (special & 1) != 0 -> .EFF bypasses op120 | +------------------------------------------------------------------------------------------------------------------------------------------+ - | [EEex.dll] EEex::Opcode_Hook_OnOp248AddTail(pOp248: CGameEffect*, pExtraEffect: CGameEffect*, pNode: CNode*, pSprite: CGameSprite*) | + | [EEex.dll] EEex::Opcode_Hook_OnOp248AddTail(pOp248: CGameEffect*, pExtraEffect: CGameEffect*, pNode: CNode*, pSprite: CGameSprite*) | +------------------------------------------------------------------------------------------------------------------------------------------+ | [Lua] [EEex_Mix_Patch.lua] EEex_Opcode_Hook_OnAfterSwingCheckedOp248(sprite: CGameSprite, targetSprite: CGameSprite, blocked: boolean) | +------------------------------------------------------------------------------------------------------------------------------------------+ @@ -259,7 +259,7 @@ +------------------------------------------------------------------------------------------------------------------------------------------+ | (special & 1) != 0 -> .EFF bypasses op120 | +------------------------------------------------------------------------------------------------------------------------------------------+ - | [EEex.dll] EEex::Opcode_Hook_OnOp249AddTail(pOp249: CGameEffect*, pExtraEffect: CGameEffect*, pNode: CNode*, pSprite: CGameSprite*) | + | [EEex.dll] EEex::Opcode_Hook_OnOp249AddTail(pOp249: CGameEffect*, pExtraEffect: CGameEffect*, pNode: CNode*, pSprite: CGameSprite*) | +------------------------------------------------------------------------------------------------------------------------------------------+ | [Lua] [EEex_Mix_Patch.lua] EEex_Opcode_Hook_OnAfterSwingCheckedOp249(sprite: CGameSprite, targetSprite: CGameSprite, blocked: boolean) | +------------------------------------------------------------------------------------------------------------------------------------------+