- Native player-controlled stairs, upper lounge bar, and Hell Tower infernal portal - Cabaret stage with musical acts, audience seating, and interaction - Dedicated cash/trophy wall terminals with native balance and achievement screens - Projecting 3D wall lanterns with ray/plane intersection - Six roaming guests with seated poses and card rank rendering updates - Synchronized launcher hash and updated binaries
437 lines
11 KiB
PHP
437 lines
11 KiB
PHP
NpcDate3D PROC
|
|
IFDEF CASINO_ACTION_TEST
|
|
mov eax,npcDateOverride3D
|
|
test eax,eax
|
|
jnz npc_date_done
|
|
ENDIF
|
|
invoke GetLocalTime,OFFSET npcSystemTime3D
|
|
movzx eax,npcSystemTime3D
|
|
imul eax,10000
|
|
movzx ecx,npcSystemTime3D[2]
|
|
imul ecx,100
|
|
add eax,ecx
|
|
movzx ecx,npcSystemTime3D[6]
|
|
add eax,ecx
|
|
npc_date_done:
|
|
ret
|
|
NpcDate3D ENDP
|
|
|
|
NpcJournalSignature3D PROC uses esi source:DWORD
|
|
mov esi,source
|
|
mov ecx,(NPC_JOURNAL_SIZE-4)/4
|
|
mov eax,4E504351h
|
|
npc_signature_word:
|
|
rol eax,5
|
|
xor eax,[esi]
|
|
add eax,9E3779B9h
|
|
add esi,4
|
|
loop npc_signature_word
|
|
ret
|
|
NpcJournalSignature3D ENDP
|
|
|
|
; Failed, truncated or mismatched journals cannot change the player's balance.
|
|
NpcEnsureJournal3D PROC uses ebx esi edi
|
|
local date:DWORD,io:DWORD
|
|
call NpcDate3D
|
|
mov date,eax
|
|
mov esi,OFFSET savePath3D
|
|
cmp nativeProfileActive3D,0
|
|
je @F
|
|
mov esi,OFFSET saveFullPath
|
|
@@:
|
|
IFDEF CASINO_ACTION_TEST
|
|
cmp npcJournalBasePtr3D,0
|
|
je @F
|
|
mov esi,npcJournalBasePtr3D
|
|
@@:
|
|
ENDIF
|
|
xor ecx,ecx
|
|
npc_journal_path_length:
|
|
cmp ecx,250
|
|
jae npc_journal_invalid_path
|
|
cmp BYTE PTR [esi+ecx],0
|
|
je npc_journal_build_path
|
|
inc ecx
|
|
jmp npc_journal_path_length
|
|
npc_journal_build_path:
|
|
invoke CopyCString,OFFSET npcJournalNextPath3D,esi
|
|
invoke AppendCString,OFFSET npcJournalNextPath3D,OFFSET npcJournalSuffix3D
|
|
invoke lstrcmpiA,OFFSET npcJournalPath3D,OFFSET npcJournalNextPath3D
|
|
test eax,eax
|
|
jnz npc_journal_reset
|
|
cmp npcJournalLoaded3D,1
|
|
jne npc_journal_reset
|
|
mov eax,date
|
|
cmp eax,npcJournalDay3D
|
|
je npc_journal_ready
|
|
npc_journal_reset:
|
|
mov npcAccepted3D,0
|
|
mov npcClaimed3D,0
|
|
lea edi,npcProgress3D
|
|
mov ecx,NPC_IDENTITY_COUNT
|
|
xor eax,eax
|
|
rep stosd
|
|
mov eax,date
|
|
mov npcJournalDay3D,eax
|
|
invoke CopyCString,OFFSET npcJournalPath3D,OFFSET npcJournalNextPath3D
|
|
mov npcJournalLoaded3D,1
|
|
invoke CreateFileA,OFFSET npcJournalPath3D,80000000h,1,0,3,80h,0
|
|
cmp eax,-1
|
|
je npc_journal_ready
|
|
mov ebx,eax
|
|
invoke GetFileSize,ebx,0
|
|
cmp eax,NPC_JOURNAL_SIZE
|
|
jne npc_journal_close
|
|
invoke ReadFile,ebx,OFFSET npcJournalRead3D,NPC_JOURNAL_SIZE,ADDR io,0
|
|
test eax,eax
|
|
jz npc_journal_close
|
|
cmp io,NPC_JOURNAL_SIZE
|
|
jne npc_journal_close
|
|
cmp DWORD PTR npcJournalRead3D,3151504Eh
|
|
jne npc_journal_close
|
|
mov eax,date
|
|
cmp DWORD PTR npcJournalRead3D[4],eax
|
|
jne npc_journal_close
|
|
mov eax,DWORD PTR npcJournalRead3D[8]
|
|
or eax,DWORD PTR npcJournalRead3D[12]
|
|
test eax,0FFFFF000h
|
|
jnz npc_journal_close
|
|
mov eax,DWORD PTR npcJournalRead3D[12]
|
|
not eax
|
|
or eax,DWORD PTR npcJournalRead3D[8]
|
|
cmp eax,-1
|
|
jne npc_journal_close
|
|
invoke NpcJournalSignature3D,OFFSET npcJournalRead3D
|
|
cmp eax,DWORD PTR npcJournalRead3D[NPC_JOURNAL_SIZE-4]
|
|
jne npc_journal_close
|
|
xor esi,esi
|
|
npc_journal_validate_progress:
|
|
invoke NpcContractType3D,esi
|
|
mov eax,npcQuestGoals3D[eax*4]
|
|
cmp DWORD PTR npcJournalRead3D[16+esi*4],eax
|
|
ja npc_journal_close
|
|
inc esi
|
|
cmp esi,NPC_IDENTITY_COUNT
|
|
jb npc_journal_validate_progress
|
|
lea esi,npcJournalRead3D
|
|
lea edi,npcJournal3D
|
|
mov ecx,NPC_JOURNAL_SIZE/4
|
|
rep movsd
|
|
npc_journal_close:
|
|
invoke CloseHandle,ebx
|
|
npc_journal_ready:
|
|
mov eax,1
|
|
ret
|
|
npc_journal_invalid_path:
|
|
mov npcJournalLoaded3D,0
|
|
mov npcJournalIoError3D,1
|
|
xor eax,eax
|
|
ret
|
|
NpcEnsureJournal3D ENDP
|
|
|
|
NpcSaveJournal3D PROC uses ebx
|
|
local io:DWORD,ok:DWORD
|
|
mov npcJournalIoError3D,0
|
|
cmp npcJournalLoaded3D,1
|
|
jne npc_journal_write_fail
|
|
invoke NpcJournalSignature3D,OFFSET npcJournal3D
|
|
mov npcJournalChecksum3D,eax
|
|
invoke CreateDirectoryA,OFFSET runtime3D,0
|
|
invoke CreateFileA,OFFSET npcJournalPath3D,40000000h,0,0,2,80h,0
|
|
cmp eax,-1
|
|
je npc_journal_write_fail
|
|
mov ebx,eax
|
|
invoke WriteFile,ebx,OFFSET npcJournal3D,NPC_JOURNAL_SIZE,ADDR io,0
|
|
mov ok,eax
|
|
invoke CloseHandle,ebx
|
|
cmp ok,0
|
|
je npc_journal_write_fail
|
|
cmp io,NPC_JOURNAL_SIZE
|
|
jne npc_journal_write_fail
|
|
mov eax,1
|
|
ret
|
|
npc_journal_write_fail:
|
|
mov npcJournalIoError3D,1
|
|
xor eax,eax
|
|
ret
|
|
NpcSaveJournal3D ENDP
|
|
|
|
NpcContractType3D PROC identity:DWORD
|
|
mov eax,npcJournalDay3D
|
|
mov ecx,identity
|
|
imul ecx,7
|
|
add eax,ecx
|
|
xor edx,edx
|
|
mov ecx,NPC_IDENTITY_COUNT
|
|
div ecx
|
|
mov eax,edx
|
|
ret
|
|
NpcContractType3D ENDP
|
|
|
|
NpcAcceptContract3D PROC uses ebx identity:DWORD
|
|
mov npcJournalIoError3D,0
|
|
cmp identity,NPC_IDENTITY_COUNT
|
|
jae npc_accept_fail
|
|
call NpcEnsureJournal3D
|
|
test eax,eax
|
|
jz npc_accept_fail
|
|
mov ebx,identity
|
|
bt npcAccepted3D,ebx
|
|
jc npc_accept_fail
|
|
bts npcAccepted3D,ebx
|
|
call NpcSaveJournal3D
|
|
test eax,eax
|
|
jnz npc_accept_done
|
|
btr npcAccepted3D,ebx
|
|
npc_accept_fail:
|
|
xor eax,eax
|
|
npc_accept_done:
|
|
ret
|
|
NpcAcceptContract3D ENDP
|
|
|
|
NpcRecordRound3D PROC uses ebx esi edi game:DWORD,won:DWORD
|
|
call NpcEnsureJournal3D
|
|
test eax,eax
|
|
jz npc_event_done
|
|
cmp npcAccepted3D,0
|
|
je npc_event_done
|
|
xor esi,esi
|
|
xor edi,edi
|
|
npc_event_contract:
|
|
bt npcAccepted3D,esi
|
|
jnc npc_event_next
|
|
bt npcClaimed3D,esi
|
|
jc npc_event_next
|
|
invoke NpcContractType3D,esi
|
|
mov ebx,eax
|
|
mov eax,npcQuestGames3D[ebx*4]
|
|
cmp eax,-1
|
|
je @F
|
|
cmp eax,game
|
|
jne npc_event_next
|
|
@@:
|
|
cmp npcQuestWins3D[ebx*4],0
|
|
je @F
|
|
cmp won,0
|
|
je npc_event_next
|
|
@@:
|
|
mov eax,npcQuestGoals3D[ebx*4]
|
|
cmp npcProgress3D[esi*4],eax
|
|
jae npc_event_next
|
|
inc npcProgress3D[esi*4]
|
|
mov edi,1
|
|
npc_event_next:
|
|
inc esi
|
|
cmp esi,NPC_IDENTITY_COUNT
|
|
jb npc_event_contract
|
|
test edi,edi
|
|
jz npc_event_done
|
|
call NpcSaveJournal3D
|
|
npc_event_done:
|
|
ret
|
|
NpcRecordRound3D ENDP
|
|
|
|
NpcClaimContract3D PROC uses ebx esi identity:DWORD
|
|
mov npcJournalIoError3D,0
|
|
cmp identity,NPC_IDENTITY_COUNT
|
|
jae npc_claim_fail
|
|
call NpcEnsureJournal3D
|
|
test eax,eax
|
|
jz npc_claim_fail
|
|
mov ebx,identity
|
|
bt npcAccepted3D,ebx
|
|
jnc npc_claim_fail
|
|
bt npcClaimed3D,ebx
|
|
jc npc_claim_fail
|
|
invoke NpcContractType3D,ebx
|
|
mov ecx,npcQuestGoals3D[eax*4]
|
|
cmp npcProgress3D[ebx*4],ecx
|
|
jb npc_claim_fail
|
|
mov esi,npcQuestRewards3D[eax*4]
|
|
bts npcClaimed3D,ebx
|
|
call NpcSaveJournal3D
|
|
test eax,eax
|
|
jnz npc_claim_credit
|
|
btr npcClaimed3D,ebx
|
|
jmp npc_claim_fail
|
|
npc_claim_credit:
|
|
add bankroll,esi
|
|
jc @F
|
|
cmp bankroll,1000000000
|
|
jbe npc_claim_save
|
|
@@:
|
|
mov bankroll,1000000000
|
|
npc_claim_save:
|
|
call SaveProgress3D
|
|
mov eax,1
|
|
ret
|
|
npc_claim_fail:
|
|
xor eax,eax
|
|
ret
|
|
NpcClaimContract3D ENDP
|
|
|
|
OpenNpcDialog3D PROC uses ebx
|
|
cmp npcSelected3D,NPC_LIFE_COUNT
|
|
jae npc_dialog_open_fail
|
|
imul ebx,npcSelected3D,SIZEOF NpcLife3D
|
|
cmp npcLife3D[ebx].state,NPC_AWAY
|
|
je npc_dialog_open_fail
|
|
mov eax,npcLife3D[ebx].identity
|
|
mov npcDialogIdentity3D,eax
|
|
mov npcDialogError3D,0
|
|
call NpcEnsureJournal3D
|
|
test eax,eax
|
|
jnz @F
|
|
mov npcDialogError3D,1
|
|
@@:
|
|
mov engineMode,MODE_NPC_DIALOG
|
|
call ClearKeys3D
|
|
mov eax,1
|
|
ret
|
|
npc_dialog_open_fail:
|
|
xor eax,eax
|
|
ret
|
|
OpenNpcDialog3D ENDP
|
|
|
|
CloseNpcDialog3D PROC
|
|
mov engineMode,MODE_WALK
|
|
mov paused3D,0
|
|
call ClearKeys3D
|
|
ret
|
|
CloseNpcDialog3D ENDP
|
|
|
|
HandleNpcDialog3D PROC
|
|
cmp engineMode,MODE_NPC_DIALOG
|
|
jne npc_dialog_handle_done
|
|
call NpcEnsureJournal3D
|
|
cmp mouseClick3D,0
|
|
je npc_dialog_keys
|
|
mov mouseClick3D,0
|
|
cmp mouseY3D,169
|
|
jb npc_dialog_keys
|
|
cmp mouseY3D,190
|
|
jae npc_dialog_keys
|
|
cmp mouseX3D,40
|
|
jb npc_dialog_keys
|
|
cmp mouseX3D,112
|
|
jb npc_dialog_accept
|
|
cmp mouseX3D,120
|
|
jb npc_dialog_keys
|
|
cmp mouseX3D,198
|
|
jb npc_dialog_claim
|
|
cmp mouseX3D,208
|
|
jb npc_dialog_keys
|
|
cmp mouseX3D,280
|
|
jb npc_dialog_close
|
|
npc_dialog_keys:
|
|
invoke Pressed3D,30h
|
|
test eax,eax
|
|
jnz npc_dialog_close
|
|
invoke Pressed3D,31h
|
|
test eax,eax
|
|
jnz npc_dialog_accept
|
|
invoke Pressed3D,32h
|
|
test eax,eax
|
|
jnz npc_dialog_claim
|
|
invoke Pressed3D,0Dh
|
|
test eax,eax
|
|
jz npc_dialog_handle_done
|
|
mov ecx,npcDialogIdentity3D
|
|
bt npcAccepted3D,ecx
|
|
jnc npc_dialog_accept
|
|
jmp npc_dialog_claim
|
|
npc_dialog_accept:
|
|
invoke NpcAcceptContract3D,npcDialogIdentity3D
|
|
jmp npc_dialog_result
|
|
npc_dialog_claim:
|
|
invoke NpcClaimContract3D,npcDialogIdentity3D
|
|
npc_dialog_result:
|
|
mov eax,npcJournalIoError3D
|
|
mov npcDialogError3D,eax
|
|
ret
|
|
npc_dialog_close:
|
|
call CloseNpcDialog3D
|
|
npc_dialog_handle_done:
|
|
ret
|
|
HandleNpcDialog3D ENDP
|
|
|
|
; Preserve original personality names, removing unsupported quote glyphs for the HUD.
|
|
NpcNameText3D PROC uses esi edi identity:DWORD
|
|
mov eax,identity
|
|
cmp eax,NPC_IDENTITY_COUNT
|
|
jae npc_name_empty
|
|
mov esi,npcGuestNames3D[eax*4]
|
|
lea edi,npcNameBuffer3D
|
|
mov ecx,60
|
|
npc_name_copy:
|
|
lodsb
|
|
test al,al
|
|
jz npc_name_finish
|
|
cmp al,0ABh
|
|
je npc_name_copy
|
|
cmp al,0BBh
|
|
je npc_name_copy
|
|
stosb
|
|
loop npc_name_copy
|
|
npc_name_finish:
|
|
mov BYTE PTR [edi],0
|
|
mov eax,OFFSET npcNameBuffer3D
|
|
ret
|
|
npc_name_empty:
|
|
mov npcNameBuffer3D,0
|
|
mov eax,OFFSET npcNameBuffer3D
|
|
ret
|
|
NpcNameText3D ENDP
|
|
|
|
RenderNpcDialog3D PROC uses ebx esi
|
|
cmp engineMode,MODE_NPC_DIALOG
|
|
jne npc_dialog_render_done
|
|
call RenderCeilingAndFloor
|
|
call RenderWalls
|
|
call PrepareCityDepth3D
|
|
call RenderSprites
|
|
call RenderHall3D
|
|
invoke DrawBoxBorder,30,48,260,151,00141B1Dh,00BA9955h,1
|
|
mov ebx,npcDialogIdentity3D
|
|
invoke NpcNameText3D,ebx
|
|
invoke DrawString8x8,42,59,eax,00F4DF9Eh
|
|
mov eax,ebx
|
|
xor edx,edx
|
|
mov ecx,6
|
|
div ecx
|
|
invoke DrawString8x8,42,76,npcGreetings3D[edx*4],00CED8D5h
|
|
invoke DrawString8x8,42,97,OFFSET npcContractTitle3D,00D3C08Fh
|
|
invoke NpcContractType3D,ebx
|
|
mov esi,eax
|
|
invoke DrawString8x8,42,112,npcQuestTexts3D[esi*4],00FFFFFFh
|
|
invoke DrawString8x8,42,130,OFFSET npcProgressText3D,00CED8D5h
|
|
invoke DrawNumber,112,130,npcProgress3D[ebx*4],00FFFFFFh
|
|
invoke DrawString8x8,123,130,OFFSET npcSlashText3D,00CED8D5h
|
|
invoke DrawNumber,149,130,npcQuestGoals3D[esi*4],00FFFFFFh
|
|
invoke DrawString8x8,178,130,OFFSET npcRewardText3D,00D3C08Fh
|
|
invoke DrawNumber,244,130,npcQuestRewards3D[esi*4],00FFFFFFh
|
|
mov eax,OFFSET npcAvailableText3D
|
|
bt npcAccepted3D,ebx
|
|
jnc npc_dialog_status
|
|
mov eax,OFFSET npcActiveText3D
|
|
mov ecx,npcQuestGoals3D[esi*4]
|
|
cmp npcProgress3D[ebx*4],ecx
|
|
jb npc_dialog_status
|
|
mov eax,OFFSET npcReadyText3D
|
|
bt npcClaimed3D,ebx
|
|
jnc npc_dialog_status
|
|
mov eax,OFFSET npcDoneText3D
|
|
npc_dialog_status:
|
|
invoke DrawString8x8,42,150,eax,0087D4A5h
|
|
invoke DrawBoxBorder,40,170,72,18,002D3A32h,0087AA8Eh,1
|
|
invoke DrawString8x8,51,175,OFFSET npcAcceptText3D,00FFFFFFh
|
|
invoke DrawBoxBorder,120,170,78,18,003B3024h,00BA9955h,1
|
|
invoke DrawString8x8,131,175,OFFSET npcClaimText3D,00FFFFFFh
|
|
invoke DrawBoxBorder,208,170,72,18,00212A2Dh,008B999Ah,1
|
|
invoke DrawString8x8,216,175,OFFSET npcCloseText3D,00FFFFFFh
|
|
cmp npcDialogError3D,0
|
|
je npc_dialog_render_done
|
|
invoke DrawString8x8,42,150,OFFSET npcIoErrorText3D,00F89880h
|
|
npc_dialog_render_done:
|
|
ret
|
|
RenderNpcDialog3D ENDP
|