Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion EEex/EEex.tp2
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
67 changes: 67 additions & 0 deletions EEex/copy/EEex_scripts/EEex_Action_Patch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
63 changes: 62 additions & 1 deletion EEex/copy/EEex_scripts/EEex_Opcode_Patch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 --
-----------------------------------
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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}})
Expand Down
35 changes: 35 additions & 0 deletions EEex/copy/EEex_scripts/EEex_Stats_Patch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)()
7 changes: 7 additions & 0 deletions EEex/loader/InfinityLoader.db
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ Pattern=48895C240855488BEC4883EC20
[CDerivedStats::GetSpellState]
Pattern=81FA000100007320

[Hook-CDerivedStats::GetSpellState()-OutOfBoundsJmp]
Pattern=81FA000100007320
Operations=ADD 6

[CDerivedStats::GetWizardLevelCast]
Pattern=40534883EC200FB6C2488BD9FFC8

Expand Down Expand Up @@ -284,6 +288,9 @@ Operations=ADD -11
Pattern=49895B1057
Operations=ADD -3

[CGameEffectSetSpellState::ApplyEffect]
Pattern=4883EC2883794800

[CGameObject::InControl]
Pattern=80BAC902000001750D
Operations=ADD -7
Expand Down
1 change: 1 addition & 0 deletions EEex/patch/EXTSTATE.IDS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0x10000000 B3_STATE_DAZED
1 change: 1 addition & 0 deletions EEex/patch/SPLSTATE.IDS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1234 B3_DAZED