Skip to content

Commit

Permalink
Do not archive non-persistent logical NPC
Browse files Browse the repository at this point in the history
Fix #22
  • Loading branch information
szapp committed Jun 14, 2020
1 parent 9ad2314 commit 4d2ae76
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ BIN_BASE := core \
hook_unarchiveVobs \
hook_unarchiveNpcs \
hook_setVobToTransient \
hook_archiveWorldCountLogicalNpc \
hook_archiveWorldWriteLogicalNpc \
hook_oCSpawnManager__Archive \
hook_fastexit \
hook_CGameManager_destructor \
hook_libExit \
Expand Down
1 change: 1 addition & 0 deletions src/core.asm
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ section .text
%include "func/initMenu.asm"
%include "func/initContent.asm"
%include "func/conEvalFunc.asm"
%include "func/oCSpawnManager__Archive_fix.asm"
%include "func/zCPlayerInfo__GetName_empty.asm"


Expand Down
40 changes: 40 additions & 0 deletions src/exec/misc.asm
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,46 @@ setVobToTransient:
jmp g1g2(0x5F638D,0x62485D)


global checkNpcTransient1
checkNpcTransient1:
resetStackoffset g1g2(0x5C,0x94)
call DWORD [edx+0x104] ; oCNpc.IsSelfPlayer(void)
test eax, eax
jnz .back

%if GOTHIC_BASE_VERSION == 1
test BYTE [ecx+0xF5], 0x1 ; zCVob.dontwritetoarchive
%elif GOTHIC_BASE_VERSION == 2
test BYTE [ecx+0x114], 0x10 ; zCVob.dontwritetoarchive
%endif
jz .back
mov eax, 0x1
verifyStackoffset g1g2(0x5C,0x94)

.back:
jmp g1g2(0x6D652A,0x77F66A)+6


global checkNpcTransient2
checkNpcTransient2:
resetStackoffset g1g2(0x5C,0x94)
call DWORD [eax+0x104] ; oCNpc.IsSelfPlayer(void)
test eax, eax
jnz .back

%if GOTHIC_BASE_VERSION == 1
test BYTE [ecx+0xF5], 0x1 ; zCVob.dontwritetoarchive
%elif GOTHIC_BASE_VERSION == 2
test BYTE [ecx+0x114], 0x10 ; zCVob.dontwritetoarchive
%endif
jz .back
mov eax, 0x1
verifyStackoffset g1g2(0x5C,0x94)

.back:
jmp g1g2(0x6D65A3,0x77F6E1)+6


global removeInvalidNpcs
removeInvalidNpcs:
resetStackoffset g1g2(0x58,0x8C)
Expand Down
133 changes: 133 additions & 0 deletions src/func/oCSpawnManager__Archive_fix.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
; void __thiscall oCSpawnManager::Archive(class zCArchiver &)
; Re-implement oCSpawnManager::Archive to exclude non-persistent NPC
global oCSpawnManager__Archive_fix
oCSpawnManager__Archive_fix:
resetStackoffset
%assign var_total 0x8 ; int
%assign var_element -0x8 ; oTSpawnNode*
%assign var_startpos -0x4 ; int
%assign arg_1 +0x4 ; zCArchiver &
%assign arg_total 0x4

sub esp, var_total
pusha

mov esi, [esp+stackoffset+arg_1] ; arc
mov eax, [esi]
mov ebx, ecx
mov ecx, esi
call DWORD [eax+0x100] ; arc->InSaveGame(void)
test eax, eax
jz .loc_end

mov eax, [esi] ; Store cursor pos for changed writing order
mov ecx, esi
call DWORD [eax+0x12C] ; arc->StoreGetPos(void)
mov [esp+stackoffset+var_startpos], eax
mov eax, [esi]
xor edx, edx ; Write zero for now
push edx
mov edx, char_noOfEntries
mov ecx, esi
call DWORD [eax+0x10] ; arc->WriteInt(char const *,int)
addStack 4

mov eax, [ebx+zCArray.numInArray]
xor edi, edi
xor ebp, ebp
test eax, eax
jle .loc_loopend

.loc_loop:
mov ecx, [ebx]
mov edx, [ecx+edi*0x4]
mov [esp+stackoffset+var_element], edx ; oTSpawnNode*

mov ecx, [edx] ; oTSpawnNode.npc
%if GOTHIC_BASE_VERSION == 1
test BYTE [ecx+0xF5], 0x1 ; zCVob.dontwritetoarchive
%elif GOTHIC_BASE_VERSION == 2
test BYTE [ecx+0x114], 0x10 ; zCVob.dontwritetoarchive
%endif
jnz .loc_next

mov eax, [esi]
push ecx
mov edx, char_npc
mov ecx, esi
call DWORD [eax+0x40] ; arc->WriteObject(char const *,zCObject *)
addStack 4

mov edx, [esp+stackoffset+var_element]
mov eax, [esi]
add edx, 0x4 ; oTSpawnNode.spawnPos[3]
push edx
mov edx, char_spawnPos
mov ecx, esi
call DWORD [eax+0x28] ; arc->WriteVec3(char const *,zVEC3 const &)
addStack 4

mov edx, [esp+stackoffset+var_element]
mov eax, [esi]
push DWORD [edx+0x10] ; oTSpawnNode.timer
mov edx, char_timer
mov ecx, esi
call DWORD [eax+0x1C] ; arc->WriteFloat(char const *,float)
addStack 4

mov eax, [ebx+zCArray.numInArray]
inc ebp

.loc_next:
inc edi
cmp edi, eax
jl .loc_loop

.loc_loopend:
mov eax, [esi]
mov ecx, esi
call DWORD [eax+0x12C] ; arc->StoreGetPos(void)
mov edx, [esp+stackoffset+var_startpos]
push eax
mov eax, [esi]
mov ecx, esi
call DWORD [eax+0x130] ; arc-StoreSeek(ulong)

mov eax, [esi]
push ebp
mov edx, char_noOfEntries
mov ecx, esi
call DWORD [eax+0x10] ; arc->WriteInt(char const *,int)
addStack 4

pop edx
test ebp, ebp
jz .loc_writelast

mov eax, [esi]
mov ecx, esi
call DWORD [eax+0x130] ; arc->StoreSeek(ulong)

.loc_writelast:
mov ecx, [ebx+0x0C] ; oCSpawnManager.spawningEnabled
mov eax, [esi]
push ecx
mov edx, char_spawningEnabled
mov ecx, esi
call DWORD [eax+0x20] ; arc->WriteBool(char const *,int)
addStack 4
%if GOTHIC_BASE_VERSION == 2
mov ecx, [ebx+0x20] ; oCSpawnManager.spawnFlags
mov eax, [esi]
push ecx
mov edx, char_spawnFlags
mov ecx, esi
call DWORD [eax+0x10] ; arc->WriteInt(char const *,int)
addStack 4
%endif

.loc_end:
popa
add esp, var_total
ret arg_total
verifyStackoffset
21 changes: 21 additions & 0 deletions src/hook_archiveWorldCountLogicalNpc.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
; Hook oCWorld::Archive to ignore counting of logical NPC that are non-persistent

%include "inc/macros.inc"

%if GOTHIC_BASE_VERSION == 1
%include "inc/symbols_g1.inc"
%elif GOTHIC_BASE_VERSION == 2
%include "inc/symbols_g2.inc"
%endif

%ifidn __OUTPUT_FORMAT__, bin
org g1g2(0x6D652A,0x77F66A)
%endif

bits 32


section .text align=1 ; Prevent auto-alignment

jmp checkNpcTransient1
nop
21 changes: 21 additions & 0 deletions src/hook_archiveWorldWriteLogicalNpc.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
; Hook oCWorld::Archive to ignore writing of logical NPC that are non-persistent

%include "inc/macros.inc"

%if GOTHIC_BASE_VERSION == 1
%include "inc/symbols_g1.inc"
%elif GOTHIC_BASE_VERSION == 2
%include "inc/symbols_g2.inc"
%endif

%ifidn __OUTPUT_FORMAT__, bin
org g1g2(0x6D65A3,0x77F6E1)
%endif

bits 32


section .text align=1 ; Prevent auto-alignment

jmp checkNpcTransient2
nop
20 changes: 20 additions & 0 deletions src/hook_oCSpawnManager__Archive.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
; Hook oCSpawnManager::Archive

%include "inc/macros.inc"

%if GOTHIC_BASE_VERSION == 1
%include "inc/symbols_g1.inc"
%elif GOTHIC_BASE_VERSION == 2
%include "inc/symbols_g2.inc"
%endif

%ifidn __OUTPUT_FORMAT__, bin
org g1g2(0x6D0F40,0x7797F0)
%endif

bits 32


section .text align=1 ; Prevent auto-alignment

jmp oCSpawnManager__Archive_fix
5 changes: 5 additions & 0 deletions src/inc/engine_g1.inc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@
%define char_lf 0x82D200 ; 0xA, 0
%define char_line 0x8520AC ; ' ( line ', 0
%define char_spaceClosingParanthesis 0x8520A8 ; ' )', 0
%define char_npc 0x8510E0 ; 'npc', 0
%define char_spawnPos 0x8510D4 ; 'spawnPos', 0
%define char_timer 0x8510CC ; 'timer', 0
%define char_noOfEntries 0x8510E4 ; 'NoOfEntries', 0
%define char_spawningEnabled 0x8510BC ; 'spawningEnabled', 0
%define char_zStartupWindowed 0x846978 ; 'zStartupWindowed', 0
%define char_settings 0x82BD98 ; 'SETTINGS', 0
%define char_meatbug_mds 0x84E358 ; 'Meatbug.mds', 0
Expand Down
6 changes: 6 additions & 0 deletions src/inc/engine_g2.inc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@
%define char_lf 0x89150C ; 0xA, 0
%define char_line 0x8BBD34 ; ' line ( ', 0
%define char_spaceClosingParanthesis 0x8BBD30 ; ' )', 0
%define char_npc 0x8BAE5C ; 'npc', 0
%define char_spawnPos 0x8BAE50 ; 'spawnPos', 0
%define char_timer 0x8BAE48 ; 'timer', 0
%define char_noOfEntries 0x8BAE60 ; 'NoOfEntries', 0
%define char_spawningEnabled 0x8BAE38 ; 'spawningEnabled', 0
%define char_spawnFlags 0x8BAE2C ; 'spawnFlags', 0
%define char_zStartupWindowed 0x8AA930 ; 'zStartupWindowed', 0
%define char_settings 0x8948A0 ; 'SETTINGS', 0
%define char_meatbug_mds 0x8B85F8 ; 'Meatbug.mds', 0
Expand Down

0 comments on commit 4d2ae76

Please sign in to comment.