KAZIK/src_graphics/observer.inc
Artvasil09 23dc40ee5c feat: implement native darts mini-game, AI observer mode, and fortune session assets
- Darts: native 500-point match against Max with sway/fatigue mouse aim, parabolic throw camera, raster arm animations, and 16 camera-relative flying dart views

- AI Observer: autonomous spectator mode for Hold'em, Blackjack, Durak, and Billiards with profile isolation and playback controls

- Fortune Session: raster sprite packs, mist/orb animations, tarot divination spreads, and pack tools

- Hall Integration: wall dartboard in lounge, observer terminal dispatch, and bot turn hooks

- Packaging & Verification: updated installer streaming hash, synchronized launcher, passing check suites and release smoke checks
2026-10-24 22:10:25 +03:00

494 lines
11 KiB
PHP

; Spectator control supplies decisions to the real native games, never simulated results.
.code
BeginObserver3D PROC uses esi edi
lea esi,screenBuffer
lea edi,obsBackground3D
mov ecx,SCREEN_SIZE
rep movsd
mov engineMode,MODE_OBSERVER
mov obsError3D,0
mov paused3D,0
call ClearKeys3D
mov mouseClick3D,0
ret
BeginObserver3D ENDP
StartObserver3D PROC uses ebx esi
cmp obsActive3D,0
jne obs_start_done
cmp obsSelection3D,OBS_GAME_COUNT
jae obs_start_done
xor esi,esi
obs_save_profile:
mov ebx,obsProfilePointers3D[esi*4]
mov eax,[ebx]
mov obsSavedProfile3D[esi*4],eax
inc esi
cmp esi,LENGTHOF obsProfilePointers3D
jb obs_save_profile
mov obsActive3D,1
mov obsPaused3D,0
mov obsRound3D,0
mov obsWins3D[0],0
mov obsWins3D[4],0
mov obsWins3D[8],0
mov tournamentMode,0
mov cardExitActive3D,0
mov obsError3D,0
mov eax,obsSelection3D
mov eax,obsModes3D[eax*4]
mov engineMode,eax
cmp eax,MODE_POOL
je obs_init_pool
cmp eax,MODE_DURAK
je obs_init_durak
cmp eax,MODE_BLACKJACK
je obs_init_blackjack
call InitNativePoker3D
jmp obs_check_assets
obs_init_durak:
call InitNativeDurak3D
mov eax,obsSelection3D
sub eax,2
mov dkVariant3D,eax
jmp obs_check_assets
obs_init_blackjack:
call InitNativeBlackjack3D
mov cbBotCount3D,0
obs_check_assets:
cmp cardTablePixels3D,0
jne obs_start_round
call StopObserver3D
mov obsError3D,1
ret
obs_init_pool:
mov poolAI3D,1
mov eax,obsSelection3D
sub eax,4
invoke StartBilliards3D,eax
obs_start_round:
call ObserverNewRound3D
obs_start_done:
ret
StartObserver3D ENDP
StopObserver3D PROC uses esi ebx
cmp obsActive3D,0
je obs_stop_menu
; The save barrier remains active until every personal value has been restored.
xor esi,esi
obs_restore_profile:
mov ebx,obsProfilePointers3D[esi*4]
mov eax,obsSavedProfile3D[esi*4]
mov [ebx],eax
inc esi
cmp esi,LENGTHOF obsProfilePointers3D
jb obs_restore_profile
mov obsActive3D,0
obs_stop_menu:
mov engineMode,MODE_OBSERVER
mov paused3D,0
mov cardExitActive3D,0
call ClearKeys3D
mov mouseClick3D,0
invoke PlayCasinoSound3D,0,0,0
ret
StopObserver3D ENDP
ObserverNewRound3D PROC
mov obsTimer3D,0
mov obsResultTimer3D,0
mov obsOutcome3D,0
inc obsRound3D
mov bankroll,10000
cmp engineMode,MODE_POOL
jne @F
call ResetPool3D
ret
@@:
cmp engineMode,MODE_DURAK
jne @F
mov dkBet3D,100
mov dkState3D,DK_IDLE
call StartNativeDurak3D
ret
@@:
cmp engineMode,MODE_BLACKJACK
jne @F
mov cbBet3D,100
mov cbState3D,CB_IDLE
call StartNativeBlackjack3D
ret
@@:
mov pkBlind3D,50
mov pkState3D,PK_IDLE
call StartNativePoker3D
ret
ObserverNewRound3D ENDP
ObserverOutcome3D PROC
cmp engineMode,MODE_POOL
jne @F
cmp poolState3D,POOL_RESULT
jne obs_no_outcome
mov eax,poolWinner3D
inc eax
ret
@@:
cmp engineMode,MODE_DURAK
jne @F
cmp dkState3D,DK_RESULT
jne obs_no_outcome
mov eax,dkOutcome3D
inc eax
ret
@@:
cmp engineMode,MODE_BLACKJACK
jne @F
cmp cbState3D,CB_RESULT
jne obs_no_outcome
mov eax,cbOutcome3D
cmp eax,3
jne obs_number_outcome
mov eax,1
ret
@@:
cmp pkState3D,PK_RESULT
jne obs_no_outcome
mov eax,pkOutcome3D
obs_number_outcome:
inc eax
ret
obs_no_outcome:
xor eax,eax
ret
ObserverOutcome3D ENDP
ObserverBlackjack3D PROC
cmp cbState3D,CB_PLAYER
jne obs_bj_update
cmp obsTimer3D,700
jb obs_bj_update
mov obsTimer3D,0
; Only our hand and the dealer's exposed up-card enter the decision.
cmp cbPlayerScore3D,17
jae obs_bj_stand
cmp cbPlayerScore3D,12
jb obs_bj_hit
mov eax,cbDealer3D[0]
xor edx,edx
mov ecx,13
div ecx
cmp edx,5
jae obs_bj_hit
obs_bj_stand:
invoke FinishBJPlayer3D,-1
jmp obs_bj_update
obs_bj_hit:
call NativeBJHit3D
obs_bj_update:
call HandleNativeBlackjack3D
ret
ObserverBlackjack3D ENDP
ObserverDurak3D PROC
cmp dkState3D,DK_TURN
jne obs_durak_update
cmp dkActor3D,0
jne obs_durak_update
cmp obsTimer3D,700
jb obs_durak_update
mov obsTimer3D,0
invoke DurakBotTurn3D,0
obs_durak_update:
call HandleNativeDurak3D
ret
ObserverDurak3D ENDP
ObserverTick3D PROC uses ebx
cmp obsActive3D,0
je obs_tick_done
call ObserverOutcome3D
test eax,eax
jz obs_tick_game
cmp obsOutcome3D,0
jne obs_result_wait
mov obsOutcome3D,eax
inc obsWins3D[eax*4-4]
mov obsResultTimer3D,0
obs_result_wait:
mov eax,deltaTime3D
add obsResultTimer3D,eax
cmp obsResultTimer3D,3000
jb obs_tick_done
call ObserverNewRound3D
ret
obs_tick_game:
mov eax,deltaTime3D
add obsTimer3D,eax
cmp engineMode,MODE_POOL
jne @F
call HandlePool3D
ret
@@:
cmp engineMode,MODE_DURAK
jne @F
call ObserverDurak3D
ret
@@:
cmp engineMode,MODE_BLACKJACK
jne @F
call ObserverBlackjack3D
ret
@@:
cmp pkState3D,PK_PLAYER
jne obs_poker_update
cmp obsTimer3D,700
jb obs_poker_update
mov obsTimer3D,0
invoke PokerBotAct3D,0
obs_poker_update:
call HandleNativePoker3D
obs_tick_done:
ret
ObserverTick3D ENDP
ObserverFrame3D PROC uses ebx esi
invoke Pressed3D,1Bh
test eax,eax
jz obs_frame_input
cmp obsActive3D,0
je obs_leave_hall
call StopObserver3D
jmp obs_frame_draw
obs_leave_hall:
mov engineMode,MODE_WALK
call ClearKeys3D
mov mouseClick3D,0
jmp obs_frame_draw
obs_frame_input:
cmp obsActive3D,0
jne obs_watch_input
xor esi,esi
obs_menu_digit:
lea eax,[esi+31h]
invoke Pressed3D,eax
test eax,eax
jnz obs_menu_pick
inc esi
cmp esi,OBS_GAME_COUNT
jb obs_menu_digit
invoke Pressed3D,26h
test eax,eax
jz @F
cmp obsSelection3D,0
jne obs_menu_up
mov obsSelection3D,OBS_GAME_COUNT
obs_menu_up:
dec obsSelection3D
@@:
invoke Pressed3D,28h
test eax,eax
jz @F
inc obsSelection3D
cmp obsSelection3D,OBS_GAME_COUNT
jb @F
mov obsSelection3D,0
@@:
invoke Pressed3D,0Dh
test eax,eax
jnz obs_menu_start
cmp mouseClick3D,0
je obs_frame_draw
cmp mouseX3D,16
jb obs_frame_draw
cmp mouseX3D,304
jae obs_frame_draw
mov eax,mouseY3D
sub eax,52
js obs_frame_draw
xor edx,edx
mov ecx,23
div ecx
cmp eax,OBS_GAME_COUNT
jae obs_menu_close_click
cmp edx,20
jae obs_frame_draw
mov esi,eax
obs_menu_pick:
mov obsSelection3D,esi
obs_menu_start:
call StartObserver3D
jmp obs_frame_draw
obs_menu_close_click:
cmp mouseY3D,212
jb obs_frame_draw
jmp obs_leave_hall
obs_watch_input:
invoke Pressed3D,20h
test eax,eax
jnz obs_watch_pause
invoke Pressed3D,9
test eax,eax
jnz obs_watch_speed
invoke Pressed3D,4Eh
test eax,eax
jnz obs_watch_restart
cmp mouseClick3D,0
je obs_watch_tick
cmp mouseY3D,222
jb obs_watch_tick
cmp mouseY3D,239
jae obs_watch_tick
mov eax,mouseX3D
cmp eax,74
jb obs_watch_pause
cmp eax,134
jb obs_watch_speed
cmp eax,226
jb obs_watch_restart
call StopObserver3D
jmp obs_frame_draw
obs_watch_pause:
xor obsPaused3D,1
jmp obs_watch_tick
obs_watch_speed:
shl obsSpeed3D,1
cmp obsSpeed3D,4
jbe obs_watch_tick
mov obsSpeed3D,1
jmp obs_watch_tick
obs_watch_restart:
call ObserverNewRound3D
obs_watch_tick:
; Human game commands never reach the autonomous seats.
call ClearKeys3D
mov mouseClick3D,0
cmp obsPaused3D,0
jne obs_frame_draw
mov ebx,deltaTime3D
mov eax,ebx
imul eax,obsSpeed3D
mov deltaTime3D,eax
add animationClock3D,eax
call ObserverTick3D
mov deltaTime3D,ebx
obs_frame_draw:
call RenderObserver3D
mov mouseClick3D,0
ret
ObserverFrame3D ENDP
RenderObserver3D PROC uses ebx esi edi
cmp obsActive3D,0
jne obs_render_game
lea esi,obsBackground3D
lea edi,screenBuffer
mov ecx,SCREEN_SIZE
rep movsd
invoke DrawBox,0,0,320,240,00151D20h
invoke DrawString8x8,16,18,OFFSET obsTitle,00E8D7ADh
xor ebx,ebx
obs_render_row:
imul esi,ebx,23
add esi,52
mov edi,00728689h
cmp ebx,obsSelection3D
jne @F
mov edi,00E8D7ADh
@@:
invoke DrawBoxBorder,16,esi,288,20,00293436h,edi,1
add esi,6
lea eax,[ebx+1]
invoke FormatNumber,eax,OFFSET hudNumBuffer
invoke DrawString8x8,24,esi,OFFSET hudNumBuffer,edi
invoke DrawString8x8,48,esi,obsNames3D[ebx*4],edi
inc ebx
cmp ebx,OBS_GAME_COUNT
jb obs_render_row
invoke DrawBoxBorder,16,212,288,20,00293436h,00728689h,1
invoke DrawString8x8,136,218,OFFSET obsClose,00E8D7ADh
cmp obsError3D,0
je obs_render_done
invoke DrawString8x8,16,198,OFFSET obsFailed,00DB8B83h
ret
obs_render_game:
cmp engineMode,MODE_POOL
jne @F
call RenderPool3D
jmp obs_render_hud
@@:
cmp engineMode,MODE_DURAK
jne @F
call RenderNativeDurak3D
jmp obs_render_hud
@@:
cmp engineMode,MODE_BLACKJACK
jne @F
call RenderNativeBlackjack3D
jmp obs_render_hud
@@:
call RenderNativePoker3D
obs_render_hud:
invoke DrawBox,0,0,320,32,00151D20h
mov ebx,obsSelection3D
invoke DrawString8x8,8,5,obsNames3D[ebx*4],00E8D7ADh
invoke DrawString8x8,8,20,OFFSET obsFirst,0090CDB2h
invoke FormatNumber,obsWins3D[0],OFFSET hudNumBuffer
invoke DrawString8x8,48,20,OFFSET hudNumBuffer,0090CDB2h
invoke DrawString8x8,88,20,OFFSET obsSecond,00DEA0A0h
invoke FormatNumber,obsWins3D[4],OFFSET hudNumBuffer
invoke DrawString8x8,128,20,OFFSET hudNumBuffer,00DEA0A0h
invoke DrawString8x8,190,20,OFFSET obsRound,00E8D7ADh
invoke FormatNumber,obsRound3D,OFFSET hudNumBuffer
invoke DrawString8x8,254,20,OFFSET hudNumBuffer,00FFFFFFh
invoke DrawBox,0,215,320,25,00151D20h
cmp obsOutcome3D,0
je obs_render_turn
mov ebx,OFFSET obsWin1
cmp obsOutcome3D,1
je @F
mov ebx,OFFSET obsWin2
cmp obsOutcome3D,2
je @F
mov ebx,OFFSET obsDraw
@@:
invoke DrawString8x8,200,5,ebx,00E8D7ADh
jmp obs_render_controls
obs_render_turn:
mov eax,pkTurn3D
cmp engineMode,MODE_POKER
je obs_render_actor
mov eax,dkActor3D
cmp engineMode,MODE_DURAK
je obs_render_actor
mov eax,poolPlayer3D
cmp engineMode,MODE_POOL
je obs_render_actor
xor eax,eax
cmp cbState3D,CB_DEALER
jne obs_render_actor
inc eax
obs_render_actor:
and eax,1
invoke DrawString8x8,232,5,obsTurnNames3D[eax*4],00A7C7C5h
obs_render_controls:
mov ebx,OFFSET obsPause
cmp obsPaused3D,0
je @F
mov ebx,OFFSET obsPlay
@@:
invoke DrawBoxBorder,4,222,66,16,00293436h,00728689h,1
invoke DrawString8x8,14,226,ebx,00FFFFFFh
mov eax,obsSpeed3D
shr eax,1
mov ebx,obsSpeedNames3D[eax*4]
invoke DrawBoxBorder,78,222,48,16,00293436h,00728689h,1
invoke DrawString8x8,94,226,ebx,00FFFFFFh
invoke DrawBoxBorder,138,222,80,16,00293436h,00728689h,1
invoke DrawString8x8,154,226,OFFSET obsRestart,00FFFFFFh
invoke DrawBoxBorder,230,222,86,16,00293436h,00728689h,1
invoke DrawString8x8,254,226,OFFSET obsGames,00FFFFFFh
obs_render_done:
ret
RenderObserver3D ENDP