.386 .model flat, stdcall option casemap:none ArtifactSaveSignature3D PROTO :DWORD ValidateArtifactSave3D PROTO :DWORD includelib kernel32.lib includelib winmm.lib includelib user32.lib includelib ws2_32.lib includelib gdi32.lib STD_INPUT_HANDLE equ -10 STD_OUTPUT_HANDLE equ -11 VK_RETURN equ 0Dh VK_SPACE equ 20h VK_M equ 4Dh FLIP_DELAY equ 650 FLIP_FINAL_DELAY equ 850 GENERIC_READ equ 80000000h GENERIC_WRITE equ 40000000h OPEN_EXISTING equ 3 CREATE_ALWAYS equ 2 FILE_ATTRIBUTE_NORMAL equ 80h INVALID_HANDLE_VALUE equ -1 SAVE_MAGIC equ 31435653h SAVE_SIGN_SIZE equ 276 SAVE_FILE_SIZE equ 312 SAVE_LEGACY_SIZE equ 280 SAVE_ARTIFACT_SIGN_SIZE equ 308 SAVE_SALT equ 0A57C0DEh ENABLE_VIRTUAL_TERMINAL_PROCESSING equ 0004h COLOR_DEFAULT equ 07h COLOR_TITLE equ 0Bh COLOR_MONEY equ 0Ah COLOR_WARN equ 0Eh COLOR_BAD equ 0Ch COLOR_CARD equ 0Fh COLOR_RED_CARD equ 0Ch COLOR_BACK_CARD equ 08h COLOR_TABLE equ 02h COLOR_WOOD equ 06h AF_INET equ 2 SOCK_STREAM equ 1 IPPROTO_TCP equ 6 INADDR_ANY equ 0 SOCKET_ERROR equ -1 ONLINE_PORT_NET equ 8769h ONLINE_MAGIC equ 4E4C4E31h ONLINE_GAME_DICE equ 1 ONLINE_GAME_RR equ 2 ExitProcess PROTO :DWORD GetStdHandle PROTO :DWORD WriteFile PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD WriteConsoleA PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD WriteConsoleW PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD ReadFile PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD SetConsoleOutputCP PROTO :DWORD SetConsoleCP PROTO :DWORD MultiByteToWideChar PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD WideCharToMultiByte PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD GetTickCount PROTO GetLocalTime PROTO :DWORD GetAsyncKeyState PROTO :DWORD GetEnvironmentVariableA PROTO :DWORD, :DWORD, :DWORD CreateDirectoryA PROTO :DWORD, :DWORD Sleep PROTO :DWORD WinExec PROTO :DWORD, :DWORD SetConsoleCursorPosition PROTO :DWORD, :DWORD SetConsoleScreenBufferSize PROTO :DWORD, :DWORD SetConsoleWindowInfo PROTO :DWORD, :DWORD, :DWORD SetConsoleTextAttribute PROTO :DWORD, :DWORD GetConsoleScreenBufferInfo PROTO :DWORD, :DWORD GetConsoleMode PROTO :DWORD, :DWORD SetConsoleMode PROTO :DWORD, :DWORD FillConsoleOutputCharacterA PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD AllocConsole PROTO FreeConsole PROTO GetConsoleWindow PROTO SetConsoleTitleA PROTO :DWORD GetWindowRect PROTO :DWORD, :DWORD SetWindowPos PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD SetFocus PROTO :DWORD ClientToScreen PROTO :DWORD, :DWORD SetCurrentConsoleFontEx PROTO :DWORD, :DWORD, :DWORD mciSendStringA PROTO :DWORD, :DWORD, :DWORD, :DWORD waveOutSetVolume PROTO :DWORD, :DWORD AnimFrameDelay PROTO :DWORD CreateFileA PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD CloseHandle PROTO :DWORD FindFirstFileA PROTO :DWORD, :DWORD FindNextFileA PROTO :DWORD, :DWORD FindClose PROTO :DWORD WSAStartup PROTO :DWORD, :DWORD WSACleanup PROTO socket PROTO :DWORD, :DWORD, :DWORD bind PROTO :DWORD, :DWORD, :DWORD listen PROTO :DWORD, :DWORD accept PROTO :DWORD, :DWORD, :DWORD connect PROTO :DWORD, :DWORD, :DWORD send PROTO :DWORD, :DWORD, :DWORD, :DWORD recv PROTO :DWORD, :DWORD, :DWORD, :DWORD closesocket PROTO :DWORD inet_addr PROTO :DWORD WSAGetLastError PROTO MoveCursor PROTO :DWORD, :DWORD RandomRange PROTO :DWORD PrintUInt PROTO :DWORD UnlockAchievement PROTO :DWORD, :DWORD ShowBestiaryPage PROTO :DWORD, :DWORD, :DWORD .data hOut dd 0 hIn dd 0 charsWritten dd 0 charsRead dd 0 consoleMode dd 0 printLen dd 0 wideLen dd 0 seed dd 0 inputBuffer db 32 dup(0) wideBuffer dw 4096 dup(0) utf8Buffer db 8192 dup(0) deckUsed db 52 dup(0) consoleRectTiny dw 0, 0, 119, 34 consoleRect160 dw 0, 0, 159, 44 consoleRect140 dw 0, 0, 139, 39 consoleRect120 dw 0, 0, 119, 34 ; === Общие счетчики очков и состояние старых карточных режимов === slotMatch dd 0 slotWinMask dd 0 slotBestMultiplier dd 0 slotComboNamePtr dd 0 slotBlockMask dd 0 slotComboCount dd 0 slotJackpotHit dd 0 slotComboNames dd 32 dup(0) slotComboMults dd 32 dup(0) slotComboMasks dd 32 dup(0) slotGrid dd 15 dup(0) rowIndex dd 0 bankroll dd 10000 targetBank dd 50000 cheatLuckyWin dd 0 cheatGodMode dd 0 cheatSlotJackpot dd 0 settingsVolume dd 10 settingsLowSpec dd 0 settingsIntroEnabled dd 1 settingsDbdWindowEnabled dd 0 secretEndingSeen dd 0 vipTaxAmount dd 0 ; === Крупье-комментатор: чтение фраз из dealer_phrases.txt === shopBackOwned dd 1 shopBackStyle dd 0 shopCharmLevel dd 0 shopCharmUses dd 0 achievements dd 0 saveHandle dd 0 findHandle dd 0 selectedAccount dd 0 accountNameLen dd 0 saveBuffer dd 80 dup(0) gamesPlayed dd 0 gamesWon dd 0 gamesLost dd 0 gamesDrawn dd 0 bestWin dd 0 bestLoss dd 0 currentGameId dd 0 gameStatsPlayed dd 11 dup(0) gameStatsWon dd 11 dup(0) gameStatsLost dd 11 dup(0) gameStatsDraw dd 11 dup(0) leaderAccountPtr dd 0 aiDifficulty dd 2 bankRecovered dd 0 saveTampered dd 0 pokerStraight dd 0 pokerFlush dd 0 pokerHigh dd 0 pokerFour dd 0 pokerTrip dd 0 pokerPairHigh dd 0 pokerPairLow dd 0 ; === Черепа и шарик: позиция шарика, выбор и число перемешиваний === durakPlayerHand dd 40 dup(0) durakAIHand dd 40 dup(0) durakPlayerCnt dd 0 durakAICnt dd 0 durakDeckLeft dd 0 durakTrumpCard dd 0 durakTrumpSuit dd 0 durakTableCnt dd 0 durakAttackCards dd 6 dup(0) durakDefenseCards dd 6 dup(0FFFFFFFFh) casinoSuspicion dd 0 stressLevel dd 0 lastGameResult dd 0 tournamentMode dd 0 dailyDateKey dd 0 dailyRewardMask dd 0 dailyProgressPacked dd 0 dailyTaskPacked dd 0 systemTime dw 8 dup(0) rankCounts db 13 dup(0) suitCounts db 4 dup(0) ; === Текст интерфейса: меню, системные сообщения, банк и ставки === nl db 13,10,0 dotSpaceText db ". ",0 clearLines db 13,10,13,10,13,10,13,10,13,10,13,10,0 observerFold1Text db "AI-1 делает фолд.",13,10,0 slotComboHorM db "Гор. M",0 slotComboVertM db "Верт. M",0 slotComboDiagM db "Диаг. M",0 slotComboHorL db "Гор. L",0 slotComboHorXL db "Гор. XL",0 slotComboUp db "Вверх",0 slotComboDown db "Вниз",0 slotComboSky db "Небо",0 slotComboEarth db "Земля",0 slotComboEye db "Глаз",0 slotComboJackpot db "Джекпот",0 ; === Графика карт: рамки, строки, рубашки и переворот === rank2 db "2",0 rank3 db "3",0 rank4 db "4",0 rank5 db "5",0 rank6 db "6",0 rank7 db "7",0 rank8 db "8",0 rank9 db "9",0 rank10 db "10",0 rankJ db "J",0 rankQ db "Q",0 rankK db "K",0 rankA db "A",0 ranks dd OFFSET rank2, OFFSET rank3, OFFSET rank4, OFFSET rank5 dd OFFSET rank6, OFFSET rank7, OFFSET rank8, OFFSET rank9 dd OFFSET rank10, OFFSET rankJ, OFFSET rankQ, OFFSET rankK, OFFSET rankA slotSymbolValues dd 3, 2, 2, 3, 5, 5, 7 cardSoundClose db 'close cardsound',0 cardSoundOpen db 'open "assets\audio\playing_cards_deck_flick_through_001_20485.wav" type waveaudio alias cardsound',0 cardSoundPlay db 'play cardsound from 0',0 cardSoundStop db 'stop cardsound',0 slotSoundClose db 'close slotsound',0 slotSoundOpen db 'open "assets\audio\hKhoJArfEGAxxMewx0UQiddakTdBjFc.wav" type waveaudio alias slotsound',0 slotSoundPlay db 'play slotsound from 0',0 slotSoundStop db 'stop slotsound',0 slotIntroClose db 'close slotintro',0 slotIntroOpen db 'open "assets\audio\Летс гоу гэмблинг.wav" type waveaudio alias slotintro',0 slotIntroPlay db 'play slotintro from 0',0 slotIntroStop db 'stop slotintro',0 jackpotClose db 'close jackpotsound',0 jackpotOpen db 'open "assets\audio\Джэк пот.wav" type waveaudio alias jackpotsound',0 jackpotPlay db 'play jackpotsound from 0',0 jackpotStop db 'stop jackpotsound',0 hakariSoundClose db 'close hakarisound',0 hakariSoundOpen db 'open "assets\audio\hakari_dance.wav" type waveaudio alias hakarisound',0 hakariSoundPlay db 'play hakarisound from 0',0 hakariSoundStop db 'stop hakarisound',0 coinSoundClose db 'close coinsound',0 coinSoundOpen db 'open "assets\audio\Звук монеты брошенной в воздух и упавшей на поверхность.wav" type waveaudio alias coinsound',0 coinSoundPlay db 'play coinsound from 0',0 coinSoundStop db 'stop coinsound',0 bankruptClose db 'close bankruptsound',0 bankruptOpen db 'open "assets\audio\Проигрыш.wav" type waveaudio alias bankruptsound',0 bankruptPlay db 'play bankruptsound from 0',0 bankruptStop db 'stop bankruptsound',0 victoryClose db 'close victorysound',0 victoryOpen db 'open "assets\audio\victory-tf2.wav" type waveaudio alias victorysound',0 victoryPlay db 'play victorysound from 0',0 victoryStop db 'stop victorysound',0 rrSpinClose db 'close rrspinsound',0 rrSpinOpen db 'open "assets\audio\toy-gun-revolver-close-chamber-spin_f1ruc5nd.wav" type waveaudio alias rrspinsound',0 rrSpinPlay db 'play rrspinsound from 0',0 rrSpinStop db 'stop rrspinsound',0 rrDryClose db 'close rrdrysound',0 rrDryOpen db 'open "assets\audio\revolverdryfirec.wav" type waveaudio alias rrdrysound',0 rrDryPlay db 'play rrdrysound from 0',0 rrDryStop db 'stop rrdrysound',0 rrShotClose db 'close rrshotsound',0 rrShotOpen db 'open "assets\audio\b05e1ac8be34248.wav" type waveaudio alias rrshotsound',0 rrShotPlay db 'play rrshotsound from 0',0 rrShotStop db 'stop rrshotsound',0 casinoRouletteSoundClose db 'close casinoroulettesound',0 casinoRouletteSoundOpen db 'open "assets\audio\roulette-wheel-throw-2.wav" type waveaudio alias casinoroulettesound',0 casinoRouletteSoundPlay db 'play casinoroulettesound from 0',0 casinoRouletteSoundStop db 'stop casinoroulettesound',0 stoneSoundClose db 'close stonesound',0 stoneSoundOpen db 'open "assets\audio\moving-stone.wav" type waveaudio alias stonesound',0 stoneSoundPlay db 'play stonesound from 0',0 stoneSoundStop db 'stop stonesound',0 towerMusicClose db 'close towermusic',0 towerMusicStop db 'stop towermusic',0 towerMusicPlay db 'play towermusic repeat',0 towerMusicOpen1 db 'open "assets\music\tower\KEYGEN_CHURCH_-_Hareklavit_75543927.mp3" type mpegvideo alias towermusic',0 towerMusicOpen2 db 'open "assets\music\tower\KEYGEN_CHURCH_-_Ladikerfos_75543991.mp3" type mpegvideo alias towermusic',0 towerMusicOpen3 db 'open "assets\music\tower\Keygen_Church_-_Tenebre_Rosso_Sangue_ULTRAKILL_Original_Game_Soundtrack_79610890.mp3" type mpegvideo alias towermusic',0 towerMusicOpen4 db 'open "assets\music\tower\KEYGEN_CHURCH_-_Tilaskarot_75546826.mp3" type mpegvideo alias towermusic',0 saveFileName db 64 dup(0) saveFullPath db 260 dup(0) saveDirPath db 260 dup(0) accountPatternFull db 260 dup(0) leaderSavePath db 260 dup(0) appDataReady dd 0 accountPattern db "*.dat",0 appDataEnvName db "APPDATA",0 appDataSubDir db "\AssemblerCasino",0 pathSlashText db "\",0 accountList db 20 dup(64 dup(0)) .code ; --- PrintHandRow21: Compatibility stub for npc_mind --- PrintHandRow21 PROC pHand:DWORD, count:DWORD, reveal:DWORD ret PrintHandRow21 ENDP PrintStr PROC uses eax ecx esi, pText:DWORD mov esi, pText xor ecx, ecx count_loop: cmp byte ptr [esi + ecx], 0 je count_done inc ecx jmp count_loop count_done: cmp ecx, 0 je print_done mov printLen, ecx invoke MultiByteToWideChar, 1251, 0, pText, printLen, ADDR wideBuffer, 4096 cmp eax, 0 je print_raw_fallback mov wideLen, eax invoke WriteConsoleW, hOut, ADDR wideBuffer, wideLen, ADDR charsWritten, 0 cmp eax, 0 jne print_done invoke WideCharToMultiByte, 65001, 0, ADDR wideBuffer, wideLen, ADDR utf8Buffer, 8192, 0, 0 cmp eax, 0 je print_raw_fallback invoke WriteFile, hOut, ADDR utf8Buffer, eax, ADDR charsWritten, 0 jmp print_done print_raw_fallback: invoke WriteFile, hOut, pText, printLen, ADDR charsWritten, 0 print_done: ret PrintStr ENDP PrintUtf8 PROC uses eax ecx esi, pText:DWORD mov esi, pText xor ecx, ecx utf8_count_loop: cmp byte ptr [esi + ecx], 0 je utf8_count_done inc ecx jmp utf8_count_loop utf8_count_done: cmp ecx, 0 je utf8_print_done mov printLen, ecx invoke MultiByteToWideChar, 65001, 0, pText, printLen, ADDR wideBuffer, 4096 cmp eax, 0 je utf8_raw_fallback mov wideLen, eax invoke WriteConsoleW, hOut, ADDR wideBuffer, wideLen, ADDR charsWritten, 0 cmp eax, 0 jne utf8_print_done invoke WriteFile, hOut, pText, printLen, ADDR charsWritten, 0 jmp utf8_print_done utf8_raw_fallback: invoke WriteFile, hOut, pText, printLen, ADDR charsWritten, 0 utf8_print_done: ret PrintUtf8 ENDP SetColor PROC attr:DWORD invoke SetConsoleTextAttribute, hOut, attr ret SetColor ENDP ResetColor PROC invoke SetConsoleTextAttribute, hOut, COLOR_DEFAULT ret ResetColor ENDP EnableAnsi PROC uses eax invoke GetConsoleMode, hOut, ADDR consoleMode cmp eax, 0 je enable_ansi_done or consoleMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING invoke SetConsoleMode, hOut, consoleMode enable_ansi_done: ret EnableAnsi ENDP InitSounds PROC uses eax ecx edx invoke mciSendStringA, OFFSET cardSoundClose, 0, 0, 0 invoke mciSendStringA, OFFSET cardSoundOpen, 0, 0, 0 invoke mciSendStringA, OFFSET slotSoundClose, 0, 0, 0 invoke mciSendStringA, OFFSET slotSoundOpen, 0, 0, 0 invoke mciSendStringA, OFFSET slotIntroClose, 0, 0, 0 invoke mciSendStringA, OFFSET slotIntroOpen, 0, 0, 0 invoke mciSendStringA, OFFSET jackpotClose, 0, 0, 0 invoke mciSendStringA, OFFSET jackpotOpen, 0, 0, 0 invoke mciSendStringA, OFFSET hakariSoundClose, 0, 0, 0 invoke mciSendStringA, OFFSET hakariSoundOpen, 0, 0, 0 invoke mciSendStringA, OFFSET coinSoundClose, 0, 0, 0 invoke mciSendStringA, OFFSET coinSoundOpen, 0, 0, 0 invoke mciSendStringA, OFFSET bankruptClose, 0, 0, 0 invoke mciSendStringA, OFFSET bankruptOpen, 0, 0, 0 invoke mciSendStringA, OFFSET victoryClose, 0, 0, 0 invoke mciSendStringA, OFFSET victoryOpen, 0, 0, 0 invoke mciSendStringA, OFFSET rrSpinClose, 0, 0, 0 invoke mciSendStringA, OFFSET rrSpinOpen, 0, 0, 0 invoke mciSendStringA, OFFSET rrDryClose, 0, 0, 0 invoke mciSendStringA, OFFSET rrDryOpen, 0, 0, 0 invoke mciSendStringA, OFFSET rrShotClose, 0, 0, 0 invoke mciSendStringA, OFFSET rrShotOpen, 0, 0, 0 invoke mciSendStringA, OFFSET casinoRouletteSoundClose, 0, 0, 0 invoke mciSendStringA, OFFSET casinoRouletteSoundOpen, 0, 0, 0 invoke mciSendStringA, OFFSET stoneSoundClose, 0, 0, 0 invoke mciSendStringA, OFFSET stoneSoundOpen, 0, 0, 0 ret InitSounds ENDP PlayCardSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET cardSoundStop, 0, 0, 0 invoke mciSendStringA, OFFSET cardSoundPlay, 0, 0, 0 invoke Sleep, 90 ret PlayCardSound ENDP PlaySlotSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET slotSoundStop, 0, 0, 0 invoke mciSendStringA, OFFSET slotSoundPlay, 0, 0, 0 ret PlaySlotSound ENDP PlaySlotIntroSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET slotIntroStop, 0, 0, 0 invoke mciSendStringA, OFFSET slotIntroPlay, 0, 0, 0 ret PlaySlotIntroSound ENDP PlayJackpotSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET jackpotStop, 0, 0, 0 invoke mciSendStringA, OFFSET jackpotPlay, 0, 0, 0 ret PlayJackpotSound ENDP PlayHakariSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET hakariSoundStop, 0, 0, 0 invoke mciSendStringA, OFFSET hakariSoundPlay, 0, 0, 0 ret PlayHakariSound ENDP PlayCoinSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET coinSoundStop, 0, 0, 0 invoke mciSendStringA, OFFSET coinSoundPlay, 0, 0, 0 ret PlayCoinSound ENDP PlayBankruptSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET bankruptStop, 0, 0, 0 invoke mciSendStringA, OFFSET bankruptPlay, 0, 0, 0 ret PlayBankruptSound ENDP PlayVictorySound PROC uses eax ecx edx invoke mciSendStringA, OFFSET victoryStop, 0, 0, 0 invoke mciSendStringA, OFFSET victoryPlay, 0, 0, 0 ret PlayVictorySound ENDP PlayCasinoRouletteSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET casinoRouletteSoundStop, 0, 0, 0 invoke mciSendStringA, OFFSET casinoRouletteSoundPlay, 0, 0, 0 ret PlayCasinoRouletteSound ENDP PlayRouletteSpinSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET rrSpinStop, 0, 0, 0 invoke mciSendStringA, OFFSET rrSpinPlay, 0, 0, 0 ret PlayRouletteSpinSound ENDP PlayRouletteDrySound PROC uses eax ecx edx invoke mciSendStringA, OFFSET rrDryStop, 0, 0, 0 invoke mciSendStringA, OFFSET rrDryPlay, 0, 0, 0 ret PlayRouletteDrySound ENDP PlayRouletteShotSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET rrShotStop, 0, 0, 0 invoke mciSendStringA, OFFSET rrShotPlay, 0, 0, 0 ret PlayRouletteShotSound ENDP PlayStoneSound PROC uses eax ecx edx invoke mciSendStringA, OFFSET stoneSoundStop, 0, 0, 0 invoke mciSendStringA, OFFSET stoneSoundPlay, 0, 0, 0 ret PlayStoneSound ENDP StopTowerMusic PROC invoke mciSendStringA, OFFSET towerMusicStop, 0, 0, 0 invoke mciSendStringA, OFFSET towerMusicClose, 0, 0, 0 ret StopTowerMusic ENDP PlayTowerRandomMusic PROC ; Tower music disabled for now per user request call StopTowerMusic ret PlayTowerRandomMusic ENDP PrintUInt PROC uses eax ebx ecx edx edi, value:DWORD LOCAL buffer[12]:BYTE lea edi, buffer[11] mov byte ptr [edi], 0 mov eax, value cmp eax, 0 jne convert_loop_start dec edi mov byte ptr [edi], '0' invoke PrintStr, edi ret convert_loop_start: mov ebx, 10 convert_loop: xor edx, edx div ebx add dl, '0' dec edi mov byte ptr [edi], dl cmp eax, 0 jne convert_loop invoke PrintStr, edi ret PrintUInt ENDP ReadKey PROC uses ebx read_key_again: invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 cmp charsRead, 0 je read_key_empty movzx eax, byte ptr inputBuffer cmp al, 13 je read_key_again cmp al, 10 je read_key_again mov ebx, eax read_key_drain: invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 cmp charsRead, 0 je read_key_return movzx eax, byte ptr inputBuffer cmp al, 10 jne read_key_drain read_key_return: mov eax, ebx ret read_key_empty: xor eax, eax ret ReadKey ENDP ResetProfileDefaults PROC uses ecx edi call ResetArtifacts3D mov bankroll, 10000 mov targetBank, 50000 mov gamesPlayed, 0 mov gamesWon, 0 mov gamesLost, 0 mov gamesDrawn, 0 mov bestWin, 0 mov bestLoss, 0 mov aiDifficulty, 2 mov cheatLuckyWin, 0 mov cheatGodMode, 0 mov cheatSlotJackpot, 0 mov settingsVolume, 10 mov secretEndingSeen, 0 mov vipTaxAmount, 0 mov bankRecovered, 0 mov shopBackOwned, 1 mov shopBackStyle, 0 mov shopCharmLevel, 0 mov shopCharmUses, 0 mov achievements, 0 mov casinoSuspicion, 0 mov stressLevel, 0 mov lastGameResult, 0 mov currentGameId, 0 mov ecx, 11 mov edi, OFFSET gameStatsPlayed reset_game_stats_loop: mov dword ptr [edi], 0 add edi, 4 loop reset_game_stats_loop mov ecx, 11 mov edi, OFFSET gameStatsWon reset_game_won_loop: mov dword ptr [edi], 0 add edi, 4 loop reset_game_won_loop mov ecx, 11 mov edi, OFFSET gameStatsLost reset_game_lost_loop: mov dword ptr [edi], 0 add edi, 4 loop reset_game_lost_loop mov ecx, 11 mov edi, OFFSET gameStatsDraw reset_game_draw_loop: mov dword ptr [edi], 0 add edi, 4 loop reset_game_draw_loop ret ResetProfileDefaults ENDP CopyCString PROC uses eax esi edi, pDst:DWORD, pSrc:DWORD mov edi, pDst mov esi, pSrc copy_cstring_loop: mov al, [esi] mov [edi], al inc esi inc edi cmp al, 0 jne copy_cstring_loop ret CopyCString ENDP AppendCString PROC uses eax esi edi, pDst:DWORD, pSrc:DWORD mov edi, pDst append_find_end: cmp byte ptr [edi], 0 je append_copy_start inc edi jmp append_find_end append_copy_start: mov esi, pSrc append_copy_loop: mov al, [esi] mov [edi], al inc esi inc edi cmp al, 0 jne append_copy_loop ret AppendCString ENDP BuildAppDataDir PROC uses eax mov appDataReady, 0 cmp nativeProfileActive3D, 0 je build_legacy_appdata call BuildNativeProfileDir3D mov appDataReady, 1 ret build_legacy_appdata: invoke GetEnvironmentVariableA, OFFSET appDataEnvName, OFFSET saveDirPath, 220 cmp eax, 0 je build_appdata_done cmp eax, 220 jae build_appdata_done invoke AppendCString, OFFSET saveDirPath, OFFSET appDataSubDir invoke CreateDirectoryA, OFFSET saveDirPath, 0 mov appDataReady, 1 build_appdata_done: ret BuildAppDataDir ENDP BuildSaveFullPath PROC call BuildAppDataDir cmp appDataReady, 1 jne build_save_local invoke CopyCString, OFFSET saveFullPath, OFFSET saveDirPath invoke AppendCString, OFFSET saveFullPath, OFFSET pathSlashText invoke AppendCString, OFFSET saveFullPath, OFFSET saveFileName ret build_save_local: invoke CopyCString, OFFSET saveFullPath, OFFSET saveFileName ret BuildSaveFullPath ENDP BuildAccountPatternFull PROC call BuildAppDataDir cmp appDataReady, 1 jne build_pattern_local invoke CopyCString, OFFSET accountPatternFull, OFFSET saveDirPath invoke AppendCString, OFFSET accountPatternFull, OFFSET pathSlashText invoke AppendCString, OFFSET accountPatternFull, OFFSET accountPattern ret build_pattern_local: invoke CopyCString, OFFSET accountPatternFull, OFFSET accountPattern ret BuildAccountPatternFull ENDP BuildLeaderSavePath PROC call BuildAppDataDir cmp appDataReady, 1 jne build_leader_local invoke CopyCString, OFFSET leaderSavePath, OFFSET saveDirPath invoke AppendCString, OFFSET leaderSavePath, OFFSET pathSlashText invoke AppendCString, OFFSET leaderSavePath, leaderAccountPtr ret build_leader_local: invoke CopyCString, OFFSET leaderSavePath, leaderAccountPtr ret BuildLeaderSavePath ENDP CalcSaveSignature PROC uses ecx esi edx mov esi, OFFSET saveBuffer mov ecx, SAVE_SIGN_SIZE / 4 mov eax, SAVE_SALT save_signature_loop: rol eax, 5 xor eax, [esi] mov edx, eax shr edx, 16 xor eax, edx add eax, 9E3779B9h add esi, 4 loop save_signature_loop ret CalcSaveSignature ENDP SaveGame PROC uses eax ecx esi edi mov DWORD PTR [saveBuffer], SAVE_MAGIC mov eax, bankroll mov DWORD PTR [saveBuffer+4], eax mov eax, targetBank mov DWORD PTR [saveBuffer+36], eax mov eax, gamesPlayed mov DWORD PTR [saveBuffer+8], eax mov eax, gamesWon mov DWORD PTR [saveBuffer+12], eax mov eax, gamesLost mov DWORD PTR [saveBuffer+16], eax mov eax, gamesDrawn mov DWORD PTR [saveBuffer+20], eax mov eax, bestWin mov DWORD PTR [saveBuffer+24], eax mov eax, bestLoss mov DWORD PTR [saveBuffer+28], eax mov eax, aiDifficulty mov DWORD PTR [saveBuffer+32], eax mov eax, shopBackOwned mov DWORD PTR [saveBuffer+40], eax mov eax, shopBackStyle mov DWORD PTR [saveBuffer+44], eax mov eax, shopCharmLevel mov DWORD PTR [saveBuffer+48], eax mov eax, achievements mov DWORD PTR [saveBuffer+52], eax mov eax, shopCharmUses mov DWORD PTR [saveBuffer+56], eax mov eax, casinoSuspicion mov DWORD PTR [saveBuffer+236], eax mov eax, dailyDateKey mov DWORD PTR [saveBuffer+240], eax mov eax, dailyRewardMask mov DWORD PTR [saveBuffer+244], eax mov eax, dailyProgressPacked mov DWORD PTR [saveBuffer+248], eax mov eax, dailyTaskPacked mov DWORD PTR [saveBuffer+252], eax mov eax, settingsVolume mov DWORD PTR [saveBuffer+256], eax mov eax, secretEndingSeen mov DWORD PTR [saveBuffer+260], eax mov eax, settingsLowSpec mov DWORD PTR [saveBuffer+264], eax mov eax, settingsIntroEnabled mov DWORD PTR [saveBuffer+268], eax mov eax, settingsDbdWindowEnabled mov DWORD PTR [saveBuffer+272], eax mov ecx, 44 mov esi, OFFSET gameStatsPlayed mov edi, OFFSET saveBuffer+60 save_stats_played_loop: mov eax, [esi] mov [edi], eax add esi, 4 add edi, 4 loop save_stats_played_loop call CalcSaveSignature mov DWORD PTR [saveBuffer+SAVE_SIGN_SIZE], eax mov DWORD PTR [saveBuffer+280],32465241h ; ARF2 mov eax,charmCloverUses mov DWORD PTR [saveBuffer+284],eax mov eax,charmHorseshoeUses mov DWORD PTR [saveBuffer+288],eax mov eax,charmSkullUses mov DWORD PTR [saveBuffer+292],eax mov eax,charmDevilUses mov DWORD PTR [saveBuffer+296],eax mov eax,charmEnabledMask3D mov DWORD PTR [saveBuffer+300],eax mov eax,brOwned3D shl eax,16 mov ecx,brEnabled3D and ecx,brOwned3D shl ecx,17 or eax,ecx or eax,2 mov DWORD PTR [saveBuffer+304],eax invoke ArtifactSaveSignature3D,OFFSET saveBuffer mov DWORD PTR [saveBuffer+308],eax call BuildSaveFullPath invoke CreateFileA, OFFSET saveFullPath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 cmp eax, INVALID_HANDLE_VALUE je save_done mov saveHandle, eax invoke WriteFile, saveHandle, ADDR saveBuffer, SAVE_FILE_SIZE, ADDR charsWritten, 0 invoke CloseHandle, saveHandle save_done: ret SaveGame ENDP LoadSave PROC uses eax ecx esi edi call ResetArtifacts3D mov dailyDateKey, 0 mov dailyRewardMask, 0 mov dailyProgressPacked, 0 mov dailyTaskPacked, 0 mov settingsVolume, 10 ; load default for old saves mov secretEndingSeen, 0 mov settingsLowSpec, 0 mov settingsIntroEnabled, 1 mov settingsDbdWindowEnabled, 1 mov saveTampered, 0 call BuildSaveFullPath invoke CreateFileA, OFFSET saveFullPath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 cmp eax, INVALID_HANDLE_VALUE jne load_file_opened cmp appDataReady, 1 jne load_done invoke CreateFileA, OFFSET saveFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 cmp eax, INVALID_HANDLE_VALUE je load_done load_file_opened: mov saveHandle, eax invoke ReadFile, saveHandle, ADDR saveBuffer, SAVE_FILE_SIZE, ADDR charsRead, 0 invoke CloseHandle, saveHandle cmp charsRead, 32 jb load_done mov eax, DWORD PTR [saveBuffer] cmp eax, SAVE_MAGIC jne load_done cmp charsRead, SAVE_LEGACY_SIZE jb load_signature_ok mov edx, DWORD PTR [saveBuffer+SAVE_SIGN_SIZE] call CalcSaveSignature cmp eax, edx jne load_tampered cmp charsRead,SAVE_LEGACY_SIZE je load_signature_ok cmp charsRead,SAVE_FILE_SIZE jne load_tampered invoke ValidateArtifactSave3D,OFFSET saveBuffer test eax,eax jz load_tampered mov eax,DWORD PTR [saveBuffer+284] mov charmCloverUses,eax mov eax,DWORD PTR [saveBuffer+288] mov charmHorseshoeUses,eax mov eax,DWORD PTR [saveBuffer+292] mov charmSkullUses,eax mov eax,DWORD PTR [saveBuffer+296] mov charmDevilUses,eax mov eax,DWORD PTR [saveBuffer+300] mov charmEnabledMask3D,eax mov eax,DWORD PTR [saveBuffer+304] shr eax,16 and eax,1 mov brOwned3D,eax mov eax,DWORD PTR [saveBuffer+304] shr eax,17 and eax,1 mov brEnabled3D,eax load_signature_ok: mov eax, DWORD PTR [saveBuffer+4] mov bankroll, eax cmp eax, 0 jne load_bank_ok cmp nativeProfileActive3D, 0 jne load_bank_ok mov bankroll, 10000 mov bankRecovered, 1 load_bank_ok: mov eax, DWORD PTR [saveBuffer+8] mov gamesPlayed, eax mov eax, DWORD PTR [saveBuffer+12] mov gamesWon, eax mov eax, DWORD PTR [saveBuffer+16] mov gamesLost, eax mov eax, DWORD PTR [saveBuffer+20] mov gamesDrawn, eax mov eax, DWORD PTR [saveBuffer+24] mov bestWin, eax mov eax, DWORD PTR [saveBuffer+28] mov bestLoss, eax cmp charsRead, 36 jb load_done mov eax, DWORD PTR [saveBuffer+32] cmp eax, 1 jb load_done cmp eax, 3 ja load_done mov aiDifficulty, eax cmp charsRead, 40 jb load_done mov eax, DWORD PTR [saveBuffer+36] cmp eax, 50000 jb load_done mov targetBank, eax cmp charsRead, 52 jb load_done mov eax, DWORD PTR [saveBuffer+40] cmp eax, 0 je load_done mov shopBackOwned, eax mov eax, DWORD PTR [saveBuffer+44] cmp eax, 12 ja load_shop_charm mov shopBackStyle, eax load_shop_charm: mov eax, DWORD PTR [saveBuffer+48] cmp eax, 24 ja load_done mov shopCharmLevel, eax cmp charsRead, 56 jb load_done mov eax, DWORD PTR [saveBuffer+52] mov achievements, eax cmp charsRead, 60 jb load_done mov eax, DWORD PTR [saveBuffer+56] cmp eax, 8 ja load_done mov shopCharmUses, eax cmp charsRead, 236 jb load_done mov ecx, 44 mov esi, OFFSET saveBuffer+60 mov edi, OFFSET gameStatsPlayed load_stats_played_loop: mov eax, [esi] mov [edi], eax add esi, 4 add edi, 4 loop load_stats_played_loop cmp charsRead, 240 jb load_done mov eax, DWORD PTR [saveBuffer+236] cmp eax, 100 ja load_done mov casinoSuspicion, eax cmp charsRead, 252 jb load_done mov eax, DWORD PTR [saveBuffer+240] mov dailyDateKey, eax mov eax, DWORD PTR [saveBuffer+244] mov dailyRewardMask, eax mov eax, DWORD PTR [saveBuffer+248] mov dailyProgressPacked, eax cmp charsRead, 256 jb load_daily_check mov eax, DWORD PTR [saveBuffer+252] mov dailyTaskPacked, eax cmp charsRead, 260 jb load_daily_check load_settings_volume: mov eax, DWORD PTR [saveBuffer+256] cmp eax, 10 ja load_secret_seen mov settingsVolume, eax load_secret_seen: cmp charsRead, 264 jb load_daily_check mov eax, DWORD PTR [saveBuffer+260] cmp eax, 1 ja load_low_spec_setting mov secretEndingSeen, eax load_low_spec_setting: cmp charsRead, 268 jb load_daily_check mov eax, DWORD PTR [saveBuffer+264] cmp eax, 2 ja load_intro_setting mov settingsLowSpec, eax load_intro_setting: cmp charsRead, 272 jb load_daily_check mov eax, DWORD PTR [saveBuffer+268] cmp eax, 1 ja load_dbd_setting mov settingsIntroEnabled, eax load_dbd_setting: cmp charsRead, 276 jb load_daily_check mov eax, DWORD PTR [saveBuffer+272] cmp eax, 1 ja load_daily_check mov settingsDbdWindowEnabled, eax load_daily_check: call DailyCheckDate jmp load_done load_tampered: mov bankroll, 10000 mov bankRecovered, 1 mov saveTampered, 1 jmp load_done load_done: ret LoadSave ENDP DailyTaskGoal PROC taskId:DWORD mov eax, taskId cmp eax, 2 je daily_goal_5 cmp eax, 3 je daily_goal_7 cmp eax, 5 je daily_goal_2 cmp eax, 6 je daily_goal_3 cmp eax, 8 je daily_goal_2 cmp eax, 11 je daily_goal_3 cmp eax, 35 je daily_goal_2 cmp eax, 37 je daily_goal_3 cmp eax, 38 je daily_goal_2 cmp eax, 39 je daily_goal_2 mov eax, 1 ret daily_goal_2: mov eax, 2 ret daily_goal_3: mov eax, 3 ret daily_goal_5: mov eax, 5 ret daily_goal_7: mov eax, 7 ret DailyTaskGoal ENDP DailyGenerateTasks PROC uses eax ebx ecx edx mov eax, dailyDateKey xor edx, edx mov ebx, 40 div ebx inc edx mov byte ptr [dailyTaskPacked], dl mov eax, dailyDateKey xor edx, edx mov ebx, 3 div ebx add eax, 17 xor edx, edx mov ebx, 40 div ebx inc edx mov al, dl cmp al, byte ptr [dailyTaskPacked] jne daily_gen_store2 inc al cmp al, 41 jb daily_gen_store2 mov al, 1 daily_gen_store2: mov byte ptr [dailyTaskPacked+1], al mov eax, dailyDateKey xor edx, edx mov ebx, 7 div ebx add eax, 29 xor edx, edx mov ebx, 40 div ebx inc edx mov al, dl daily_gen_unique3: cmp al, byte ptr [dailyTaskPacked] je daily_gen_inc3 cmp al, byte ptr [dailyTaskPacked+1] je daily_gen_inc3 jmp daily_gen_store3 daily_gen_inc3: inc al cmp al, 41 jb daily_gen_unique3 mov al, 1 jmp daily_gen_unique3 daily_gen_store3: mov byte ptr [dailyTaskPacked+2], al mov byte ptr [dailyTaskPacked+3], 0 ret DailyGenerateTasks ENDP DailyCheckDate PROC uses eax ebx invoke GetLocalTime, OFFSET systemTime movzx eax, word ptr [systemTime] imul eax, eax, 10000 movzx ebx, word ptr [systemTime+2] imul ebx, ebx, 100 add eax, ebx movzx ebx, word ptr [systemTime+6] add eax, ebx cmp dailyDateKey, eax je daily_date_has_date mov dailyDateKey, eax mov dailyRewardMask, 0 mov dailyProgressPacked, 0 mov dailyTaskPacked, 0 call DailyGenerateTasks ret daily_date_has_date: cmp byte ptr [dailyTaskPacked], 0 jne daily_date_done call DailyGenerateTasks daily_date_done: ret DailyCheckDate ENDP ApplySoundVolume PROC uses eax edx mov eax, settingsVolume cmp eax, 10 jb volume_scaled mov eax, 0FFFFh jmp volume_pack volume_scaled: imul eax, eax, 6553 volume_pack: mov edx, eax shl edx, 16 or eax, edx invoke waveOutSetVolume, 0FFFFFFFFh, eax ret ApplySoundVolume ENDP ConfigureConsoleSize PROC invoke SetConsoleWindowInfo, hOut, 1, OFFSET consoleRectTiny invoke SetConsoleScreenBufferSize, hOut, 012C00A0h ; 160 x 300 buffer cmp eax, 0 je try_console_140 invoke SetConsoleWindowInfo, hOut, 1, OFFSET consoleRect160 cmp eax, 0 jne console_size_done try_console_140: invoke SetConsoleWindowInfo, hOut, 1, OFFSET consoleRectTiny invoke SetConsoleScreenBufferSize, hOut, 012C008Ch ; 140 x 300 buffer cmp eax, 0 je try_console_120 invoke SetConsoleWindowInfo, hOut, 1, OFFSET consoleRect140 cmp eax, 0 jne console_size_done try_console_120: invoke SetConsoleWindowInfo, hOut, 1, OFFSET consoleRectTiny invoke SetConsoleScreenBufferSize, hOut, 012C0078h ; 120 x 300 buffer cmp eax, 0 je console_size_done invoke SetConsoleWindowInfo, hOut, 1, OFFSET consoleRect120 console_size_done: ret ConfigureConsoleSize ENDP HomeCursor PROC invoke SetConsoleCursorPosition, hOut, 0 ret HomeCursor ENDP ClearView PROC uses eax edx LOCAL csbi[22]:BYTE LOCAL cells:DWORD call ResetColor invoke GetConsoleScreenBufferInfo, hOut, ADDR csbi cmp eax, 0 jne clear_console_buffer invoke PrintStr, OFFSET clearLines ret clear_console_buffer: movzx eax, word ptr csbi[0] movzx edx, word ptr csbi[2] mul edx mov cells, eax invoke FillConsoleOutputCharacterA, hOut, 32, cells, 0, ADDR charsWritten call HomeCursor ret ClearView ENDP RandomRange PROC uses ecx edx, range:DWORD mov eax, seed imul eax, 214013 add eax, 2531011 mov seed, eax shr eax, 16 and eax, 7FFFh xor edx, edx mov ecx, range div ecx mov eax, edx ret RandomRange ENDP ClearPokerCounts PROC uses ecx edi mov ecx, 13 mov edi, OFFSET rankCounts clear_rank_counts: mov byte ptr [edi], 0 inc edi loop clear_rank_counts mov ecx, 4 mov edi, OFFSET suitCounts clear_suit_counts: mov byte ptr [edi], 0 inc edi loop clear_suit_counts ret ClearPokerCounts ENDP EvaluatePokerN PROC uses ebx ecx edx esi edi, pHand:DWORD, cardCount:DWORD call ClearPokerCounts mov pokerStraight, 0 mov pokerFlush, 0 mov pokerHigh, 0 mov pokerFour, 0FFFFFFFFh mov pokerTrip, 0FFFFFFFFh mov pokerPairHigh, 0FFFFFFFFh mov pokerPairLow, 0FFFFFFFFh mov esi, pHand mov ecx, cardCount count_poker_cards: mov eax, [esi] xor edx, edx mov ebx, 13 div ebx inc byte ptr suitCounts[eax] inc byte ptr rankCounts[edx] add esi, 4 loop count_poker_cards mov ecx, 4 xor ebx, ebx check_flush_loop: cmp byte ptr suitCounts[ebx], 5 jb next_flush_suit mov pokerFlush, 1 next_flush_suit: inc ebx loop check_flush_loop mov ecx, 13 mov ebx, 12 find_high_card: cmp byte ptr rankCounts[ebx], 0 jne high_card_found dec ebx loop find_high_card jmp check_wheel_straight high_card_found: mov pokerHigh, ebx check_wheel_straight: cmp byte ptr rankCounts[12], 0 je check_normal_straight cmp byte ptr rankCounts[0], 0 je check_normal_straight cmp byte ptr rankCounts[1], 0 je check_normal_straight cmp byte ptr rankCounts[2], 0 je check_normal_straight cmp byte ptr rankCounts[3], 0 je check_normal_straight mov pokerStraight, 1 mov pokerHigh, 3 jmp scan_duplicates check_normal_straight: mov ebx, 12 normal_straight_loop: cmp ebx, 4 jb scan_duplicates cmp byte ptr rankCounts[ebx], 0 je normal_straight_next mov eax, ebx dec eax cmp byte ptr rankCounts[eax], 0 je normal_straight_next dec eax cmp byte ptr rankCounts[eax], 0 je normal_straight_next dec eax cmp byte ptr rankCounts[eax], 0 je normal_straight_next dec eax cmp byte ptr rankCounts[eax], 0 je normal_straight_next mov pokerStraight, 1 mov pokerHigh, ebx jmp scan_duplicates normal_straight_next: dec ebx jmp normal_straight_loop scan_duplicates: mov ebx, 12 duplicate_loop: cmp ebx, 0FFFFFFFFh je decide_poker_score mov al, byte ptr rankCounts[ebx] cmp al, 4 jne check_trip_count mov pokerFour, ebx jmp duplicate_next check_trip_count: cmp al, 3 jne check_pair_count cmp pokerTrip, 0FFFFFFFFh jne second_trip_as_pair mov pokerTrip, ebx jmp duplicate_next second_trip_as_pair: cmp pokerPairHigh, 0FFFFFFFFh jne duplicate_next mov pokerPairHigh, ebx jmp duplicate_next check_pair_count: cmp al, 2 jne duplicate_next cmp pokerPairHigh, 0FFFFFFFFh jne set_low_pair mov pokerPairHigh, ebx jmp duplicate_next set_low_pair: mov pokerPairLow, ebx duplicate_next: dec ebx jmp duplicate_loop decide_poker_score: cmp pokerStraight, 1 jne not_straight_flush cmp pokerFlush, 1 jne not_straight_flush mov eax, 8000 add eax, pokerHigh ret not_straight_flush: cmp pokerFour, 0FFFFFFFFh je not_four_kind mov eax, 7000 add eax, pokerFour ret not_four_kind: cmp pokerTrip, 0FFFFFFFFh je not_full_house cmp pokerPairHigh, 0FFFFFFFFh je not_full_house mov eax, 6000 add eax, pokerTrip ret not_full_house: cmp pokerFlush, 1 jne not_flush mov eax, 5000 add eax, pokerHigh ret not_flush: cmp pokerStraight, 1 jne not_straight mov eax, 4000 add eax, pokerHigh ret not_straight: cmp pokerTrip, 0FFFFFFFFh je not_three_kind mov eax, 3000 add eax, pokerTrip ret not_three_kind: cmp pokerPairLow, 0FFFFFFFFh je not_two_pair mov eax, pokerPairHigh mov ebx, 13 mul ebx add eax, pokerPairLow add eax, 2000 ret not_two_pair: cmp pokerPairHigh, 0FFFFFFFFh je high_card_score mov eax, 1000 add eax, pokerPairHigh ret high_card_score: mov eax, pokerHigh ret EvaluatePokerN ENDP SlotApplyWin PROC uses ebx ecx edx, pName:DWORD, multiplier:DWORD, maskValue:DWORD mov eax, pName cmp eax, OFFSET slotComboJackpot je slot_apply_jackpot mov eax, maskValue mov ebx, slotBlockMask mov ecx, eax and ecx, ebx cmp ecx, eax je slot_apply_skip or slotBlockMask, eax jmp slot_apply_record slot_apply_jackpot: mov slotJackpotHit, 1 mov eax, maskValue slot_apply_record: or slotWinMask, eax mov ebx, slotMatch mov eax, slotSymbolValues[ebx * 4] mov ebx, multiplier mul ebx mov edx, eax add slotBestMultiplier, edx mov ebx, slotComboCount cmp ebx, 32 jae slot_apply_no_store mov eax, pName mov slotComboNames[ebx * 4], eax mov slotComboMults[ebx * 4], edx mov ecx,maskValue mov slotComboMasks[ebx * 4],ecx inc slotComboCount slot_apply_no_store: mov eax, 1 ret slot_apply_skip: xor eax, eax ret SlotApplyWin ENDP SlotSame3 PROC uses ebx ecx edx, i1:DWORD, i2:DWORD, i3:DWORD mov ebx, i1 mov eax, slotGrid[ebx * 4] mov ecx, i2 cmp eax, slotGrid[ecx * 4] jne slot_same3_no mov edx, i3 cmp eax, slotGrid[edx * 4] jne slot_same3_no mov eax, 1 ret slot_same3_no: xor eax, eax ret SlotSame3 ENDP SlotSame4 PROC uses ebx ecx edx, i1:DWORD, i2:DWORD, i3:DWORD, i4:DWORD mov ebx, i1 mov eax, slotGrid[ebx * 4] mov ecx, i2 cmp eax, slotGrid[ecx * 4] jne slot_same4_no mov edx, i3 cmp eax, slotGrid[edx * 4] jne slot_same4_no mov ebx, i4 cmp eax, slotGrid[ebx * 4] jne slot_same4_no mov eax, 1 ret slot_same4_no: xor eax, eax ret SlotSame4 ENDP SlotSame5 PROC uses ebx ecx edx, i1:DWORD, i2:DWORD, i3:DWORD, i4:DWORD, i5:DWORD mov ebx, i1 mov eax, slotGrid[ebx * 4] mov ecx, i2 cmp eax, slotGrid[ecx * 4] jne slot_same5_no mov edx, i3 cmp eax, slotGrid[edx * 4] jne slot_same5_no mov ebx, i4 cmp eax, slotGrid[ebx * 4] jne slot_same5_no mov ecx, i5 cmp eax, slotGrid[ecx * 4] jne slot_same5_no mov eax, 1 ret slot_same5_no: xor eax, eax ret SlotSame5 ENDP SlotAllSame15 PROC uses ebx ecx mov eax, slotGrid mov ebx, 1 slot_all15_loop: cmp ebx, 15 jae slot_all15_yes mov ecx, slotGrid[ebx * 4] cmp eax, ecx jne slot_all15_no inc ebx jmp slot_all15_loop slot_all15_yes: mov eax, 1 ret slot_all15_no: xor eax, eax ret SlotAllSame15 ENDP SlotTry3 PROC uses ebx, pName:DWORD, multiplier:DWORD, maskValue:DWORD, i1:DWORD, i2:DWORD, i3:DWORD invoke SlotSame3, i1, i2, i3 cmp eax, 0 je slot_try3_no mov ebx, i1 mov eax, slotGrid[ebx * 4] mov slotMatch, eax invoke SlotApplyWin, pName, multiplier, maskValue ret slot_try3_no: xor eax, eax ret SlotTry3 ENDP SlotTry4 PROC uses ebx, pName:DWORD, multiplier:DWORD, maskValue:DWORD, i1:DWORD, i2:DWORD, i3:DWORD, i4:DWORD invoke SlotSame4, i1, i2, i3, i4 cmp eax, 0 je slot_try4_no mov ebx, i1 mov eax, slotGrid[ebx * 4] mov slotMatch, eax invoke SlotApplyWin, pName, multiplier, maskValue ret slot_try4_no: xor eax, eax ret SlotTry4 ENDP SlotTry5 PROC uses ebx, pName:DWORD, multiplier:DWORD, maskValue:DWORD, i1:DWORD, i2:DWORD, i3:DWORD, i4:DWORD, i5:DWORD invoke SlotSame5, i1, i2, i3, i4, i5 cmp eax, 0 je slot_try5_no mov ebx, i1 mov eax, slotGrid[ebx * 4] mov slotMatch, eax invoke SlotApplyWin, pName, multiplier, maskValue ret slot_try5_no: xor eax, eax ret SlotTry5 ENDP EvaluateSlotCombos PROC mov slotWinMask, 0 mov slotBlockMask, 0 mov slotBestMultiplier, 0 mov slotComboNamePtr, 0 mov slotComboCount, 0 mov slotJackpotHit, 0 call SlotAllSame15 cmp eax, 0 je slot_eval_eye mov eax, slotGrid mov slotMatch, eax invoke SlotApplyWin, OFFSET slotComboJackpot, 10, 32767 slot_eval_eye: invoke SlotTry5, OFFSET slotComboEye, 8, 17553, 0, 4, 7, 10, 14 invoke SlotTry5, OFFSET slotComboSky, 7, 31, 0, 1, 2, 3, 4 invoke SlotTry5, OFFSET slotComboEarth, 7, 31744, 10, 11, 12, 13, 14 invoke SlotTry5, OFFSET slotComboUp, 4, 17732, 10, 6, 2, 8, 14 invoke SlotTry5, OFFSET slotComboDown, 4, 4433, 0, 6, 12, 8, 4 invoke SlotTry5, OFFSET slotComboHorXL, 3, 31, 0, 1, 2, 3, 4 invoke SlotTry5, OFFSET slotComboHorXL, 3, 992, 5, 6, 7, 8, 9 invoke SlotTry5, OFFSET slotComboHorXL, 3, 31744, 10, 11, 12, 13, 14 invoke SlotTry4, OFFSET slotComboHorL, 2, 15, 0, 1, 2, 3 invoke SlotTry4, OFFSET slotComboHorL, 2, 30, 1, 2, 3, 4 invoke SlotTry4, OFFSET slotComboHorL, 2, 480, 5, 6, 7, 8 invoke SlotTry4, OFFSET slotComboHorL, 2, 960, 6, 7, 8, 9 invoke SlotTry4, OFFSET slotComboHorL, 2, 15360, 10, 11, 12, 13 invoke SlotTry4, OFFSET slotComboHorL, 2, 30720, 11, 12, 13, 14 invoke SlotTry3, OFFSET slotComboVertM, 1, 1057, 0, 5, 10 invoke SlotTry3, OFFSET slotComboVertM, 1, 2114, 1, 6, 11 invoke SlotTry3, OFFSET slotComboVertM, 1, 4228, 2, 7, 12 invoke SlotTry3, OFFSET slotComboVertM, 1, 8456, 3, 8, 13 invoke SlotTry3, OFFSET slotComboVertM, 1, 16912, 4, 9, 14 invoke SlotTry3, OFFSET slotComboDiagM, 1, 4161, 0, 6, 12 invoke SlotTry3, OFFSET slotComboDiagM, 1, 8322, 1, 7, 13 invoke SlotTry3, OFFSET slotComboDiagM, 1, 16644, 2, 8, 14 invoke SlotTry3, OFFSET slotComboDiagM, 1, 1092, 10, 6, 2 invoke SlotTry3, OFFSET slotComboDiagM, 1, 2184, 11, 7, 3 invoke SlotTry3, OFFSET slotComboDiagM, 1, 4368, 12, 8, 4 invoke SlotTry3, OFFSET slotComboHorM, 1, 7, 0, 1, 2 invoke SlotTry3, OFFSET slotComboHorM, 1, 14, 1, 2, 3 invoke SlotTry3, OFFSET slotComboHorM, 1, 28, 2, 3, 4 invoke SlotTry3, OFFSET slotComboHorM, 1, 224, 5, 6, 7 invoke SlotTry3, OFFSET slotComboHorM, 1, 448, 6, 7, 8 invoke SlotTry3, OFFSET slotComboHorM, 1, 896, 7, 8, 9 invoke SlotTry3, OFFSET slotComboHorM, 1, 7168, 10, 11, 12 invoke SlotTry3, OFFSET slotComboHorM, 1, 14336, 11, 12, 13 invoke SlotTry3, OFFSET slotComboHorM, 1, 28672, 12, 13, 14 ret EvaluateSlotCombos ENDP DurakCardRank PROC uses ecx edx, card:DWORD mov eax, card xor edx, edx mov ecx, 13 div ecx mov eax, edx ret DurakCardRank ENDP DurakCardSuit PROC uses ecx edx, card:DWORD mov eax, card xor edx, edx mov ecx, 13 div ecx ret DurakCardSuit ENDP DrawDurakCard PROC uses ebx ecx edx edi cmp durakDeckLeft, 0 ja draw_durak_random_start mov eax, 0FFFFFFFFh ret ; Сначала пробуем случайно, но не бесконечно: в конце партии иначе можно долго ждать одну карту. draw_durak_random_start: mov rowIndex, 120 draw_durak_try: invoke RandomRange, 52 mov ebx, eax xor edx, edx mov ecx, 13 div ecx cmp edx, 4 jb draw_durak_next_try mov edi, OFFSET deckUsed add edi, ebx cmp byte ptr [edi], 0 je draw_durak_take draw_durak_next_try: dec rowIndex cmp rowIndex, 0 jne draw_durak_try xor ebx, ebx draw_durak_scan_loop: cmp ebx, 52 jae draw_durak_none_left mov eax, ebx xor edx, edx mov ecx, 13 div ecx cmp edx, 4 jb draw_durak_scan_next mov edi, OFFSET deckUsed add edi, ebx cmp byte ptr [edi], 0 je draw_durak_take draw_durak_scan_next: inc ebx jmp draw_durak_scan_loop draw_durak_take: mov edi, OFFSET deckUsed add edi, ebx mov byte ptr [edi], 1 cmp durakDeckLeft, 0 jbe draw_durak_return_card dec durakDeckLeft draw_durak_return_card: mov eax, ebx ret draw_durak_none_left: mov durakDeckLeft, 0 mov eax, 0FFFFFFFFh ret DrawDurakCard ENDP AddDurakCard PROC uses ebx ecx, pHand:DWORD, pCount:DWORD, card:DWORD mov ecx, pCount mov ebx, [ecx] cmp ebx, 40 jae add_durak_done mov eax, pHand mov ecx, card mov [eax + ebx * 4], ecx mov ecx, pCount inc dword ptr [ecx] add_durak_done: ret AddDurakCard ENDP RemoveDurakCard PROC uses ebx ecx edx esi edi, pHand:DWORD, pCount:DWORD, index:DWORD mov esi, pHand mov edi, pCount mov ecx, [edi] mov ebx, index cmp ebx, ecx jae remove_durak_bad mov eax, [esi + ebx * 4] dec ecx mov [edi], ecx remove_durak_shift: cmp ebx, ecx jae remove_durak_done mov edx, [esi + ebx * 4 + 4] mov [esi + ebx * 4], edx inc ebx jmp remove_durak_shift remove_durak_done: ret remove_durak_bad: mov eax, 0FFFFFFFFh ret RemoveDurakCard ENDP CanDurakBeat PROC uses ebx ecx edx esi edi, attackCard:DWORD, defenseCard:DWORD invoke DurakCardSuit, attackCard mov esi, eax invoke DurakCardRank, attackCard mov edi, eax invoke DurakCardSuit, defenseCard mov ebx, eax invoke DurakCardRank, defenseCard mov ecx, eax cmp ebx, esi jne can_durak_check_trump cmp ecx, edi ja can_durak_yes jmp can_durak_no can_durak_check_trump: cmp ebx, durakTrumpSuit jne can_durak_no cmp esi, durakTrumpSuit je can_durak_no can_durak_yes: mov eax, 1 ret can_durak_no: xor eax, eax ret CanDurakBeat ENDP ClearDurakTable PROC uses ecx edi mov durakTableCnt, 0 mov ecx, 6 mov edi, OFFSET durakAttackCards clear_durak_attack_loop: mov dword ptr [edi], 0FFFFFFFFh add edi, 4 loop clear_durak_attack_loop mov ecx, 6 mov edi, OFFSET durakDefenseCards clear_durak_def_loop: mov dword ptr [edi], 0FFFFFFFFh add edi, 4 loop clear_durak_def_loop ret ClearDurakTable ENDP AddDurakAttack PROC uses ebx mov ebx, durakTableCnt cmp ebx, 6 jae add_attack_done mov durakAttackCards[ebx * 4], eax mov durakDefenseCards[ebx * 4], 0FFFFFFFFh inc durakTableCnt add_attack_done: ret AddDurakAttack ENDP DurakTableHasDefense PROC uses ebx mov rowIndex, 0 has_def_loop: mov eax, rowIndex cmp eax, durakTableCnt jae has_def_no mov ebx, eax cmp durakDefenseCards[ebx * 4], 0FFFFFFFFh jne has_def_yes inc rowIndex jmp has_def_loop has_def_yes: mov eax, 1 ret has_def_no: xor eax, eax ret DurakTableHasDefense ENDP DurakFirstUnbeaten PROC uses ebx mov rowIndex, 0 first_unbeaten_loop: mov eax, rowIndex cmp eax, durakTableCnt jae first_unbeaten_none mov ebx, eax cmp durakDefenseCards[ebx * 4], 0FFFFFFFFh je first_unbeaten_found inc rowIndex jmp first_unbeaten_loop first_unbeaten_found: mov eax, rowIndex ret first_unbeaten_none: mov eax, 0FFFFFFFFh ret DurakFirstUnbeaten ENDP DurakAllDefended PROC call DurakFirstUnbeaten cmp eax, 0FFFFFFFFh jne all_def_no mov eax, 1 ret all_def_no: xor eax, eax ret DurakAllDefended ENDP DurakRankOnTable PROC uses ebx ecx edx, card:DWORD invoke DurakCardRank, card mov ecx, eax mov rowIndex, 0 rank_on_table_loop: mov eax, rowIndex cmp eax, durakTableCnt jae rank_on_table_no mov ebx, eax invoke DurakCardRank, durakAttackCards[ebx * 4] cmp eax, ecx je rank_on_table_yes cmp durakDefenseCards[ebx * 4], 0FFFFFFFFh je rank_on_table_next invoke DurakCardRank, durakDefenseCards[ebx * 4] cmp eax, ecx je rank_on_table_yes rank_on_table_next: inc rowIndex jmp rank_on_table_loop rank_on_table_yes: mov eax, 1 ret rank_on_table_no: xor eax, eax ret DurakRankOnTable ENDP CollectDurakTable PROC uses ebx, pHand:DWORD, pCount:DWORD mov rowIndex, 0 collect_table_loop: mov eax, rowIndex cmp eax, durakTableCnt jae collect_table_done mov ebx, eax invoke AddDurakCard, pHand, pCount, durakAttackCards[ebx * 4] cmp durakDefenseCards[ebx * 4], 0FFFFFFFFh je collect_next invoke AddDurakCard, pHand, pCount, durakDefenseCards[ebx * 4] collect_next: inc rowIndex jmp collect_table_loop collect_table_done: call ClearDurakTable ret CollectDurakTable ENDP CheckDurakEnd PROC cmp durakDeckLeft, 0 ja durak_not_finished cmp durakPlayerCnt, 0 jne check_ai_empty cmp durakAICnt, 0 jne durak_player_won mov eax, 3 ret check_ai_empty: cmp durakAICnt, 0 jne durak_not_finished mov eax, 2 ret durak_player_won: mov eax, 1 ret durak_not_finished: xor eax, eax ret CheckDurakEnd ENDP include casino3d.inc IFDEF HELL_TOWER_TEST RunHellTowerTest3D PROC uses ebx esi edi local stageLoop:DWORD call InitPaths3D call Init3DEngine test eax, eax jz test_error_init ; Test-owned session: no persistence or profile money is loaded. mov arrivalConfirmed3D,0 mov bankroll,10000 ; Enter Hell Tower call InitHellTower3D invoke ChooseTowerRelic3D,0 cmp tournamentMode, 1 jne test_error_tower_mode mov stageLoop, 1 stage_test_loop: ; 1. Briefing state frame call HandleHellTowerInput call RenderHellTower3D call Present3D ; 2. Launch current floor minigame call TowerLaunchCurrentFloor cmp towerFloorState, TOWER_STATE_IN_GAME jne test_error_launch ; 3. Win the round on current floor invoke TowerReportRoundOutcome, 1 ; 4. Check outcome state cmp stageLoop, 6 jae stage_check_champ cmp towerFloorState, TOWER_STATE_CLEAR jne test_error_clear_state ; Frame in clear state call HandleHellTowerInput call RenderHellTower3D call Present3D ; Advance to next stage invoke ChooseTowerRelic3D,0 inc towerStage mov towerFloorState, TOWER_STATE_BRIEFING mov towerCalloutAnim, 0 inc stageLoop jmp stage_test_loop stage_check_champ: cmp towerFloorState, TOWER_STATE_CHAMPION jne test_error_champ_state ; Frame in champion state call HandleHellTowerInput call RenderHellTower3D call Present3D ; Exit tower back to hall call TowerExitToHall cmp tournamentMode, 0 jne test_error_exit_mode cmp engineMode, MODE_WALK jne test_error_exit_engine ; Hall walk frame call Present3D ; SUCCESS! mov eax, 0 ret test_error_init: mov eax, 101 ret test_error_tower_mode: mov eax, 102 ret test_error_launch: mov eax, 103 ret test_error_clear_state: mov eax, 104 ret test_error_champ_state: mov eax, 105 ret test_error_exit_mode: mov eax, 106 ret test_error_exit_engine: mov eax, 107 ret RunHellTowerTest3D ENDP ENDIF IFDEF BACKROOMS_TEST include tools/tests/backrooms_test.inc ENDIF main PROC IFDEF BACKROOMS_TEST call RunBackroomsTest3D invoke ExitProcess,eax ENDIF IFDEF HELL_TOWER_TEST call RunHellTowerTest3D invoke ExitProcess,eax ENDIF IFDEF ARTIFACT_TEST call RunArtifactTest3D invoke ExitProcess,eax ENDIF IFDEF CASINO_ACTION_TEST call RunCasinoActionsTest3D invoke ExitProcess, eax ELSE call InitPaths3D invoke CreateMutexA, 0, 1, OFFSET mutexName3D mov mutex3D, eax invoke GetLastError cmp eax, 183 jne main_graphical invoke FindWindowA, OFFSET sz3DClassName, 0 test eax, eax jz main_exit push eax invoke ShowWindow, eax, 9 pop eax invoke SetForegroundWindow, eax jmp main_exit main_graphical: call LoadProgress3D call StartCasino3D main_exit: cmp mutex3D, 0 je @F invoke CloseHandle, mutex3D @@: invoke ExitProcess, 0 ENDIF main ENDP END main