diff --git a/EEex/EEex.tp2 b/EEex/EEex.tp2 index 895b02d..3d05f4f 100644 --- a/EEex/EEex.tp2 +++ b/EEex/EEex.tp2 @@ -65,7 +65,7 @@ BEGIN @1 LABEL ~B3-EEex-Main~ DESIGNATED 1 REQUIRE_PREDICATE (GAME_IS ~bgee bg2ee eet iwdee~ AND FILE_EXISTS ~data/PATCH26.BIF~) @1000 // Game not supported. REQUIRE_PREDICATE MOD_IS_INSTALLED ~EEex.tp2~ 0 @1001 // This component requires the core component to be installed. - ACTION_FOR_EACH file IN ACTION OBJECT TRIGGER BEGIN + ACTION_FOR_EACH file IN ACTION OBJECT TRIGGER EXTSTATE SPLSTATE BEGIN COPY ~EEex/patch/%file%.IDS~ ~EEex/patch~ COUNT_2DA_ROWS 2 rows FOR (i = 0; i <= rows; ++i) BEGIN diff --git a/EEex/copy/EEex_scripts/EEex_Action_Patch.lua b/EEex/copy/EEex_scripts/EEex_Action_Patch.lua index b9d4bf7..a842363 100644 --- a/EEex/copy/EEex_scripts/EEex_Action_Patch.lua +++ b/EEex/copy/EEex_scripts/EEex_Action_Patch.lua @@ -3,6 +3,73 @@ EEex_DisableCodeProtection() + --[[ + +-------------------------------------------------------------------------------------------------------------+ + | Block disallowed actions while B3_STATE_DAZED is active | + +-------------------------------------------------------------------------------------------------------------+ + | [EEex.dll] EEex::Action_Hook_ShouldDazeBlockAction(evaluator: CGameAIBase*) -> int | + | return: | + | -> 0 - Allow the current action | + | -> !0 - Current action was converted to NoAction(); keep the engine on its normal dispatch path | + +-------------------------------------------------------------------------------------------------------------+ + --]] + + EEex_HookBeforeConditionalJumpWithLabels(EEex_Label("Hook-CGameAIBase::ExecuteAction()-DefaultJmp"), 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(8) + mov qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-8)], r8 + + mov rcx, rbx ; pAIBase + call #L(EEex::Action_Hook_ShouldDazeBlockAction) + + mov r8, qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-8)] + test eax, eax + jz daze_allow_base + + xor r8d, r8d ; Dispatch as NoAction() + + daze_allow_base: + #DESTROY_SHADOW_SPACE + cmp r8d, 0x1D5 + ]]} + ) + + EEex_HookBeforeConditionalJumpWithLabels(EEex_Label("Hook-CGameSprite::ExecuteAction()-DefaultJmp"), 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(32) + mov qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-8)], rcx + mov qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-16)], rdx + mov qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-24)], r9 + mov qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-32)], r10 + + mov rcx, rdi ; pSprite as CGameAIBase + call #L(EEex::Action_Hook_ShouldDazeBlockAction) + + mov r10, qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-32)] + mov r9, qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-24)] + mov rdx, qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-16)] + mov rcx, qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-8)] + test eax, eax + jz daze_allow_sprite + + xor ecx, ecx ; Dispatch as NoAction() + + daze_allow_sprite: + #DESTROY_SHADOW_SPACE + cmp ecx, 0x1D7 + ]]} + ) + --[[ +--------------------------------------------------------------------------------+ | Implement new actions | diff --git a/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua b/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua index 871cb2f..a42cc46 100644 --- a/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua +++ b/EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua @@ -665,6 +665,38 @@ EEex_HookIntegrityWatchdogRegister.R11 }) + --[[ + +--------------------------------------------------------------------------------------------------------------+ + | Opcode #328 - support SPLSTATE ids above 255 | + +--------------------------------------------------------------------------------------------------------------+ + | Vanilla CGameEffectSetSpellState::ApplyEffect() writes only into CDerivedStats' 256-bit spell-state array. | + | EEex mirrors active-mode op328 applications whose ids are in the extended unsigned-word range. | + +--------------------------------------------------------------------------------------------------------------+ + | [EEex.dll] EEex::Opcode_Hook_SetSpellState_BeforeApplyEffect(pEffect: CGameEffect*, pSprite: CGameSprite*) | + +--------------------------------------------------------------------------------------------------------------+ + --]] + + EEex_HookBeforeRestoreWithLabels(EEex_Label("CGameEffectSetSpellState::ApplyEffect"), 0, 8, 8, { + {"stack_mod", 8}, + {"hook_integrity_watchdog_ignore_registers", { + EEex_HookIntegrityWatchdogRegister.RAX, EEex_HookIntegrityWatchdogRegister.R8, EEex_HookIntegrityWatchdogRegister.R9, + EEex_HookIntegrityWatchdogRegister.R10, EEex_HookIntegrityWatchdogRegister.R11 + }}}, + {[[ + #MAKE_SHADOW_SPACE(16) + mov qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-8)], rcx + mov qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-16)], rdx + + ; rcx already pEffect + ; rdx already pSprite + call #L(EEex::Opcode_Hook_SetSpellState_BeforeApplyEffect) + + mov rdx, qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-16)] + mov rcx, qword ptr ss:[rsp+#SHADOW_SPACE_BOTTOM(-8)] + #DESTROY_SHADOW_SPACE + ]]} + ) + ----------------------------------- -- New Opcodes -- ----------------------------------- @@ -1111,6 +1143,30 @@ ]]}, }) + --[[ + +-----------------------------------------------------------------------------------------------------------------+ + | New Opcode #417 (Daze) | + +-----------------------------------------------------------------------------------------------------------------+ + | Set B3_STATE_DAZED for the effect's duration and expose its hard-coded B3_DAZED (SPLSTATE 1234) mapping. | + | Opcode 328 can expose B3_DAZED, but only opcode 417 applies the behavioral dazed condition. | + +-----------------------------------------------------------------------------------------------------------------+ + | [EEex.dll] EEex::Opcode_Hook_Daze_ApplyEffect(pEffect: CGameEffect*, pSprite: CGameSprite*) -> int | + | return: | + | -> 0 - Halt effect list processing | + | -> !0 - Continue effect list processing | + +-----------------------------------------------------------------------------------------------------------------+ + --]] + + local EEex_Daze = genOpcodeDecode({ + ["ApplyEffect"] = {[[ + #STACK_MOD(8) ; This was called, the ret ptr broke alignment + #MAKE_SHADOW_SPACE + call #L(EEex::Opcode_Hook_Daze_ApplyEffect) + #DESTROY_SHADOW_SPACE + ret + ]]}, + }) + --[[ +-------------------------------------+ | [JIT] Decode switch for new opcodes | @@ -1154,8 +1210,13 @@ _409: cmp eax, 409 - jne #L(jmp_success) + jne _417 ]], EEex_EnableActionListener, [[ + + _417: + cmp eax, 417 + jne #L(jmp_success) + ]], EEex_Daze, [[ ]]}) ) EEex_HookIntegrityWatchdog_IgnoreStackSizes(EEex_Label("Hook-CGameEffect::DecodeEffect()-DefaultJmp"), {{0x60, 8}}) diff --git a/EEex/copy/EEex_scripts/EEex_Stats_Patch.lua b/EEex/copy/EEex_scripts/EEex_Stats_Patch.lua index cacdcbd..00c28de 100644 --- a/EEex/copy/EEex_scripts/EEex_Stats_Patch.lua +++ b/EEex/copy/EEex_scripts/EEex_Stats_Patch.lua @@ -163,6 +163,41 @@ }) ) + --[[ + +--------------------------------------------------------------------------------------------------------------+ + | Allow engine to fetch extended spell-state values | + +--------------------------------------------------------------------------------------------------------------+ + | * Vanilla CDerivedStats::GetSpellState() supports only SPLSTATE ids 0-255 | + | * EEex stores ids 256-65535 in side storage rebuilt with the normal derived-stat reload lifecycle | + | * B3_STATE_DAZED is hard-mapped to B3_DAZED, so GetSpellState(1234) sees opcode 417's condition state | + +--------------------------------------------------------------------------------------------------------------+ + | [EEex.dll] EEex::Stats_Hook_OnGettingUnknownSpellState(pStats: CDerivedStats*, nSpellStateId: uint) -> int | + | return -> Whether the extended spell state is active | + +--------------------------------------------------------------------------------------------------------------+ + --]] + + EEex_HookConditionalJumpOnSuccessWithLabels(EEex_Label("Hook-CDerivedStats::GetSpellState()-OutOfBoundsJmp"), 5, { + {"stack_mod", 8}, + {"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 + }}}, + EEex_FlattenTable({ + {[[ + #MAKE_SHADOW_SPACE + + ; rcx already pStats + ; edx already nSpellStateId + call #L(EEex::Stats_Hook_OnGettingUnknownSpellState) + + #DESTROY_SHADOW_SPACE + #MANUAL_HOOK_EXIT(0) + ret + ]]}, + }) + ) + EEex_EnableCodeProtection() end)() diff --git a/EEex/loader/InfinityLoader.db b/EEex/loader/InfinityLoader.db index 0b182a9..e5c73af 100644 --- a/EEex/loader/InfinityLoader.db +++ b/EEex/loader/InfinityLoader.db @@ -206,6 +206,10 @@ Pattern=48895C240855488BEC4883EC20 [CDerivedStats::GetSpellState] Pattern=81FA000100007320 +[Hook-CDerivedStats::GetSpellState()-OutOfBoundsJmp] +Pattern=81FA000100007320 +Operations=ADD 6 + [CDerivedStats::GetWizardLevelCast] Pattern=40534883EC200FB6C2488BD9FFC8 @@ -284,6 +288,9 @@ Operations=ADD -11 Pattern=49895B1057 Operations=ADD -3 +[CGameEffectSetSpellState::ApplyEffect] +Pattern=4883EC2883794800 + [CGameObject::InControl] Pattern=80BAC902000001750D Operations=ADD -7 diff --git a/EEex/patch/EXTSTATE.IDS b/EEex/patch/EXTSTATE.IDS new file mode 100644 index 0000000..02b6a10 --- /dev/null +++ b/EEex/patch/EXTSTATE.IDS @@ -0,0 +1 @@ +0x10000000 B3_STATE_DAZED \ No newline at end of file diff --git a/EEex/patch/SPLSTATE.IDS b/EEex/patch/SPLSTATE.IDS new file mode 100644 index 0000000..c534631 --- /dev/null +++ b/EEex/patch/SPLSTATE.IDS @@ -0,0 +1 @@ +1234 B3_DAZED \ No newline at end of file