KAZIK/src_graphics/native_poker.inc
Игорь Федосеев 2024aacd31 feat(tower): implement 3D Hell Tower mode and clean legacy console code
- Add 3D Hell Tower mode with 10 boss floors, briefings, and outcome tracking across games
- Refactor poker.asm by removing >10,600 lines of dead legacy console games and menus
- Rebuild poker.exe with clean binary output and update .gitignore
2026-10-15 19:49:50 +03:00

629 lines
14 KiB
PHP

; Heads-up no-limit Hold'em: real shuffled deck, four betting streets, no console.
InitNativePoker3D PROC
mov cardExitActive3D, 0
call LoadCardTableAssets3D
test eax, eax
jz @F
mov pkState3D, PK_IDLE
mov pkError3D, 0
mov pkPot3D, 0
mov pkAiMessage3D, 0
mov pkStreet3D, 0
mov pkBoardCount3D, 0
mov pkResult3D, 0
mov pkChipTimer3D, 320
call ClearKeys3D
mov eax, 1
@@:
ret
InitNativePoker3D ENDP
PokerPay3D PROC uses ebx actor:DWORD,amount:DWORD
mov ebx, actor
mov eax, amount
mov edx, bankroll
test ebx, ebx
jz @F
mov edx, pkStack3D
@@:
cmp eax, edx
jbe @F
mov eax, edx
@@:
test ebx, ebx
jnz poker_pay_dealer
sub bankroll, eax
jmp poker_pay_pot
poker_pay_dealer:
sub pkStack3D, eax
poker_pay_pot:
add pkPaid3D[ebx*4], eax
add pkPot3D, eax
mov pkChipAmount3D, eax
mov pkChipActor3D, ebx
mov pkChipTimer3D, 0
ret
PokerPay3D ENDP
StartNativePoker3D PROC uses ebx esi
cmp pkState3D, PK_IDLE
je @F
cmp pkState3D, PK_RESULT
jne poker_start_done
@@:
mov eax, bankroll
cmp eax, pkBlind3D
jb poker_start_empty
mov pkStack3D, eax
xor pkButton3D, 1
mov pkStreet3D, 0
mov pkPot3D, 0
mov pkPaid3D[0], 0
mov pkPaid3D[4], 0
mov pkActed3D[0], 0
mov pkActed3D[4], 0
mov pkRaisedCount3D, 0
mov pkCanRaise3D, 1
mov pkBoardCount3D, 0
mov pkOldBoardCount3D, 0
mov pkCursor3D, 4
mov pkResult3D, 0
mov pkError3D, 0
mov pkAiMessage3D, 0
mov eax, pkBlind3D
mov pkMinRaise3D, eax
mov pkRaise3D, eax
mov pkCurrent3D, eax
invoke ShuffleCards3D, OFFSET pkDeck3D
mov esi, pkButton3D
xor esi, 1
shl esi, 3 ; first card goes to the non-button player
mov ebx, esi
xor ebx, 8
mov eax, pkDeck3D[0]
mov pkHole3D[esi], eax
mov eax, pkDeck3D[4]
mov pkHole3D[ebx], eax
mov eax, pkDeck3D[8]
mov pkHole3D[esi+4], eax
mov eax, pkDeck3D[12]
mov pkHole3D[ebx+4], eax
mov ebx, pkButton3D
mov eax, pkBlind3D
shr eax, 1
invoke PokerPay3D, ebx, eax
xor ebx, 1
invoke PokerPay3D, ebx, pkBlind3D
mov eax, pkButton3D
mov pkTurn3D, eax
mov pkTimer3D, 0
mov pkState3D, PK_DEAL
call ClearKeys3D
invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1
call SaveProgress3D
poker_start_done:
ret
poker_start_empty:
mov pkError3D, 1
ret
StartNativePoker3D ENDP
PokerNextTurn3D PROC actor:DWORD
mov eax, pkPaid3D[0]
cmp eax, pkPaid3D[4]
jne poker_switch_turn
cmp bankroll, 0
je poker_finish_street
cmp pkStack3D, 0
je poker_finish_street
cmp pkActed3D[0], 0
je poker_switch_turn
cmp pkActed3D[4], 0
jne poker_finish_street
poker_switch_turn:
mov eax, actor
xor eax, 1
mov pkTurn3D, eax
mov pkTimer3D, 0
mov pkState3D, PK_PLAYER
call ClearKeys3D
mov eax, pkTurn3D
test eax, eax
jz @F
mov pkState3D, PK_AI
@@:
ret
poker_finish_street:
call PokerNextStreet3D
ret
PokerNextTurn3D ENDP
PokerCall3D PROC uses ebx esi actor:DWORD
mov pkError3D, 0
mov ebx, actor
mov eax, pkCurrent3D
sub eax, pkPaid3D[ebx*4]
invoke PokerPay3D, ebx, eax
mov pkActed3D[ebx*4], 1
; Heads-up unmatched all-in excess is returned; no phantom side pot.
mov eax, pkPaid3D[ebx*4]
cmp eax, pkCurrent3D
jae poker_call_next
mov esi, ebx
xor esi, 1
mov edx, pkPaid3D[esi*4]
sub edx, eax
sub pkPot3D, edx
mov pkPaid3D[esi*4], eax
mov pkCurrent3D, eax
test esi, esi
jnz @F
add bankroll, edx
jmp poker_call_next
@@:
add pkStack3D, edx
poker_call_next:
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
invoke PokerNextTurn3D, ebx
ret
PokerCall3D ENDP
PokerRaise3D PROC uses ebx esi edi actor:DWORD,extra:DWORD
local owed:DWORD,available:DWORD
cmp pkCanRaise3D, 0
je poker_raise_done
mov ebx, actor
mov esi, ebx
xor esi, 1
mov eax, pkCurrent3D
sub eax, pkPaid3D[ebx*4]
mov owed, eax
mov eax, bankroll
test ebx, ebx
jz @F
mov eax, pkStack3D
@@:
mov available, eax
mov edi, extra
add edi, owed
cmp edi, eax
jbe @F
mov edi, eax
@@:
; Never ask the opponent to cover more than their effective stack.
mov eax, bankroll
test esi, esi
jz @F
mov eax, pkStack3D
@@:
add eax, pkPaid3D[esi*4]
sub eax, pkPaid3D[ebx*4]
cmp edi, eax
jbe @F
mov edi, eax
@@:
cmp edi, owed
jbe poker_raise_as_call
mov eax, edi
sub eax, owed
cmp eax, pkMinRaise3D
jae poker_full_raise
cmp edi, available
jne poker_raise_invalid
; A short all-in does not reopen raising for a player who already acted.
mov pkCanRaise3D, 0
jmp poker_commit_raise
poker_full_raise:
mov pkMinRaise3D, eax
mov pkRaise3D, eax
mov pkActed3D[esi*4], 0
mov pkCanRaise3D, 1
poker_commit_raise:
mov pkError3D, 0
invoke PokerPay3D, ebx, edi
mov eax, pkPaid3D[ebx*4]
mov pkCurrent3D, eax
mov pkActed3D[ebx*4], 1
inc pkRaisedCount3D
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
invoke PokerNextTurn3D, ebx
poker_raise_done:
ret
poker_raise_invalid:
cmp actor, 0
jne poker_raise_as_call
mov pkError3D, 2
ret
poker_raise_as_call:
cmp actor, 1
jne @F
mov pkAiMessage3D, 1
cmp owed, 0
je @F
mov pkAiMessage3D, 2
@@:
invoke PokerCall3D, ebx
ret
PokerRaise3D ENDP
PokerFold3D PROC actor:DWORD
cmp pkState3D, PK_RESULT
je poker_fold_done
mov pkResult3D, 0
mov pkOutcome3D, 1
cmp actor, 0
je poker_fold_player
mov eax, pkPot3D
add bankroll, eax
mov pkOutcome3D, 0
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
jmp poker_fold_settled
poker_fold_player:
mov eax, pkPot3D
add pkStack3D, eax
invoke PlayCasinoSound3D, OFFSET soundRoundLose, 0, 1
poker_fold_settled:
mov pkState3D, PK_RESULT
call ClearKeys3D
xor eax,eax
cmp pkOutcome3D,0
sete al
invoke NpcRecordRound3D,2,eax
call SaveProgress3D
poker_fold_done:
ret
PokerFold3D ENDP
PokerNextStreet3D PROC uses ebx esi
cmp pkStreet3D, 3
je poker_begin_reveal
inc pkStreet3D
mov eax, pkBoardCount3D
mov pkOldBoardCount3D, eax
mov eax, pkStreet3D
add eax, 2
mov pkBoardCount3D, eax
inc pkCursor3D ; burn one card before each board street
mov esi, pkOldBoardCount3D
poker_deal_board:
mov ebx, pkCursor3D
mov eax, pkDeck3D[ebx*4]
mov pkBoard3D[esi*4], eax
inc pkCursor3D
inc esi
cmp esi, pkBoardCount3D
jb poker_deal_board
mov pkPaid3D[0], 0
mov pkPaid3D[4], 0
mov pkActed3D[0], 0
mov pkActed3D[4], 0
mov pkCurrent3D, 0
mov pkRaisedCount3D, 0
mov pkCanRaise3D, 1
mov eax, pkBlind3D
mov pkMinRaise3D, eax
mov pkRaise3D, eax
mov eax, pkButton3D
xor eax, 1
mov pkTurn3D, eax
mov pkTimer3D, 0
mov pkState3D, PK_BOARD
invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1
ret
poker_begin_reveal:
mov pkTimer3D, 0
mov pkState3D, PK_REVEAL
ret
PokerNextStreet3D ENDP
PokerShowdown3D PROC uses ebx esi edi
cmp pkState3D, PK_RESULT
je poker_showdown_done
xor ebx, ebx
poker_evaluate_player:
lea edi, pkEvalHand3D
lea esi, pkHole3D[ebx*8]
movsd
movsd
lea esi, pkBoard3D
mov ecx, 5
rep movsd
invoke EvaluateNativePoker3D, OFFSET pkEvalHand3D, 7
mov pkScore3D[ebx*4], eax
inc ebx
cmp ebx, 2
jb poker_evaluate_player
mov pkResult3D, 1
mov eax, pkScore3D[0]
cmp eax, pkScore3D[4]
ja poker_showdown_lose
je poker_showdown_tie
mov eax, pkPot3D
add bankroll, eax
mov pkOutcome3D, 0
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
jmp poker_showdown_settled
poker_showdown_lose:
mov eax, pkPot3D
add pkStack3D, eax
mov pkOutcome3D, 1
invoke PlayCasinoSound3D, OFFSET soundRoundLose, 0, 1
jmp poker_showdown_settled
poker_showdown_tie:
mov eax, pkPot3D
shr eax, 1
mov edx, pkPot3D
and edx, 1
cmp pkButton3D, 1
jne @F
add eax, edx ; odd chip goes to the non-button player
@@:
add bankroll, eax
mov edx, pkPot3D
sub edx, eax
add pkStack3D, edx
mov pkOutcome3D, 2
poker_showdown_settled:
mov pkState3D, PK_RESULT
call ClearKeys3D
xor eax,eax
cmp pkOutcome3D,0
sete al
invoke NpcRecordRound3D,2,eax
call SaveProgress3D
poker_showdown_done:
ret
PokerShowdown3D ENDP
; The AI sees only its two cards and the already exposed board. No player cards/future deck.
PokerAIDecide3D PROC uses ebx esi edi
local strength:DWORD,owed:DWORD
mov eax, pkCurrent3D
sub eax, pkPaid3D[4]
mov owed, eax
cmp pkBoardCount3D, 3
jae poker_ai_postflop
mov eax, pkHole3D[8]
xor edx, edx
mov ecx, 13
div ecx
mov esi, edx
mov eax, pkHole3D[12]
xor edx, edx
div ecx
mov strength, 0
cmp esi, edx
je poker_ai_pair
cmp esi, 8
jb @F
inc strength
@@:
cmp edx, 8
jb poker_ai_odds
inc strength
jmp poker_ai_odds
poker_ai_pair:
mov strength, 3
cmp esi, 7
jb poker_ai_odds
mov strength, 5
jmp poker_ai_odds
poker_ai_postflop:
lea edi, pkEvalHand3D
lea esi, pkHole3D[8]
movsd
movsd
lea esi, pkBoard3D
mov ecx, pkBoardCount3D
rep movsd
mov eax, pkBoardCount3D
add eax, 2
invoke EvaluateNativePoker3D, OFFSET pkEvalHand3D, eax
invoke NativePokerClass3D, eax
inc eax
mov strength, eax
poker_ai_odds:
invoke RandomRange3D, 100
mov ebx, eax
cmp owed, 0
je poker_ai_consider_raise
mov eax, pkBlind3D
imul eax, 2
cmp owed, eax
jbe poker_ai_small_call
cmp strength, 3
jae poker_ai_consider_raise
cmp ebx, 18
jb poker_ai_call
jmp poker_ai_fold
poker_ai_small_call:
cmp strength, 1
jae poker_ai_consider_raise
cmp ebx, 32
jb poker_ai_fold
poker_ai_consider_raise:
cmp pkCanRaise3D, 0
je poker_ai_call
cmp pkRaisedCount3D, 2
jae poker_ai_call
cmp bankroll, 0
je poker_ai_call
cmp strength, 3
jae poker_ai_strong_raise
cmp ebx, 9
jae poker_ai_call
jmp poker_ai_raise
poker_ai_strong_raise:
cmp ebx, 62
jae poker_ai_call
poker_ai_raise:
mov pkAiMessage3D, 3
invoke PokerRaise3D, 1, pkMinRaise3D
ret
poker_ai_fold:
mov pkAiMessage3D, 4
invoke PokerFold3D, 1
ret
poker_ai_call:
mov pkAiMessage3D, 1
cmp owed, 0
je @F
mov pkAiMessage3D, 2
@@:
invoke PokerCall3D, 1
ret
PokerAIDecide3D ENDP
HandleNativePoker3D PROC uses ebx
call HandleCardExit3D
test eax, eax
jnz poker_input_done
invoke CardTableMouse3D, MODE_POKER
cmp cardExitActive3D, 0
jne poker_input_done
cmp engineMode, MODE_POKER
jne poker_input_done
cmp pkChipTimer3D, 320
jae @F
mov eax, deltaTime3D
add pkChipTimer3D, eax
@@:
cmp pkState3D, PK_IDLE
je poker_ready_input
cmp pkState3D, PK_RESULT
je poker_ready_input
cmp pkState3D, PK_PLAYER
je poker_player_input
mov eax, deltaTime3D
add pkTimer3D, eax
cmp pkState3D, PK_AI
jne poker_animate_deal
cmp pkTimer3D, 650
jb poker_input_done
call PokerAIDecide3D
ret
poker_animate_deal:
cmp pkState3D, PK_REVEAL
jne @F
cmp pkTimer3D, 650
jb poker_input_done
call PokerShowdown3D
ret
@@:
mov eax, TABLE_FLIGHT_MS*4
cmp pkState3D, PK_DEAL
je poker_animation_limit
mov eax, pkBoardCount3D
sub eax, pkOldBoardCount3D
imul eax, TABLE_FLIGHT_MS
poker_animation_limit:
cmp pkTimer3D, eax
jb poker_input_done
mov pkTimer3D, 0
cmp pkState3D, PK_BOARD
jne poker_begin_turn
cmp bankroll, 0
je poker_runout
cmp pkStack3D, 0
je poker_runout
poker_begin_turn:
mov pkState3D, PK_PLAYER
call ClearKeys3D
cmp pkTurn3D, 0
je poker_input_done
mov pkState3D, PK_AI
ret
poker_runout:
call PokerNextStreet3D
ret
poker_ready_input:
invoke Pressed3D, 26h
test eax, eax
jz @F
cmp pkBlind3D, 1000
jae @F
add pkBlind3D, 50
@@:
invoke Pressed3D, 28h
test eax, eax
jz @F
cmp pkBlind3D, 50
jbe @F
sub pkBlind3D, 50
@@:
cmp tournamentMode, 1
jne poker_regular_start
cmp pkState3D, PK_RESULT
jne poker_regular_start
invoke Pressed3D, 20h
test eax, eax
jnz poker_tourney_report
invoke Pressed3D, 0Dh
test eax, eax
jnz poker_tourney_report
ret
poker_tourney_report:
cmp pkOutcome3D, 1
je poker_tourney_loss
invoke TowerReportRoundOutcome, 1
ret
poker_tourney_loss:
invoke TowerReportRoundOutcome, 2
ret
poker_regular_start:
invoke Pressed3D, 20h
test eax, eax
jz poker_input_done
call StartNativePoker3D
ret
poker_player_input:
invoke Pressed3D, 41h
test eax, eax
jz @F
invoke PokerRaise3D, 0, bankroll
ret
@@:
invoke Pressed3D, 26h
test eax, eax
jz @F
cmp pkRaise3D, 50000
jae @F
mov eax, pkBlind3D
add pkRaise3D, eax
@@:
invoke Pressed3D, 28h
test eax, eax
jz @F
mov eax, pkMinRaise3D
cmp pkRaise3D, eax
jbe @F
mov eax, pkBlind3D
sub pkRaise3D, eax
mov eax, pkMinRaise3D
cmp pkRaise3D, eax
jae @F
mov pkRaise3D, eax
@@:
invoke Pressed3D, 46h
test eax, eax
jz @F
invoke PokerFold3D, 0
ret
@@:
invoke Pressed3D, 52h
test eax, eax
jz @F
invoke PokerRaise3D, 0, pkRaise3D
ret
@@:
invoke Pressed3D, 43h
test eax, eax
jnz poker_player_call
invoke Pressed3D, 20h
test eax, eax
jz poker_input_done
poker_player_call:
invoke PokerCall3D, 0
poker_input_done:
ret
HandleNativePoker3D ENDP