diff --git a/assets/animations/clover/cabinet-v1.bin b/assets/animations/clover/cabinet-v1.bin new file mode 100644 index 0000000..ece2851 Binary files /dev/null and b/assets/animations/clover/cabinet-v1.bin differ diff --git a/assets/animations/clover/manifest.json b/assets/animations/clover/manifest.json new file mode 100644 index 0000000..9d09388 --- /dev/null +++ b/assets/animations/clover/manifest.json @@ -0,0 +1,20 @@ +{ + "symbols": [ + "clover", + "lemon", + "cherries", + "bell", + "diamond", + "chest", + "seven" + ], + "cabinet": [ + 640, + 480 + ], + "symbol": [ + 56, + 56 + ], + "runtime": "MASM; five reels, three complete rows, legacy additive combos" +} diff --git a/assets/animations/clover/symbols-v1.bin b/assets/animations/clover/symbols-v1.bin new file mode 100644 index 0000000..997ea85 Binary files /dev/null and b/assets/animations/clover/symbols-v1.bin differ diff --git a/assets/animations/pyramid/balls-v1.bin b/assets/animations/pyramid/balls-v1.bin new file mode 100644 index 0000000..13428b2 Binary files /dev/null and b/assets/animations/pyramid/balls-v1.bin differ diff --git a/assets/animations/pyramid/table-v1.bin b/assets/animations/pyramid/table-v1.bin new file mode 100644 index 0000000..a934234 Binary files /dev/null and b/assets/animations/pyramid/table-v1.bin differ diff --git a/assets/animations/pyramid/table-v2.bin b/assets/animations/pyramid/table-v2.bin new file mode 100644 index 0000000..14e578f Binary files /dev/null and b/assets/animations/pyramid/table-v2.bin differ diff --git a/assets/animations/roulette/participants-v1.bin b/assets/animations/roulette/participants-v1.bin new file mode 100644 index 0000000..6c861b9 Binary files /dev/null and b/assets/animations/roulette/participants-v1.bin differ diff --git a/assets/animations/tables/blackjack-guests-v1.bin b/assets/animations/tables/blackjack-guests-v1.bin new file mode 100644 index 0000000..3399162 Binary files /dev/null and b/assets/animations/tables/blackjack-guests-v1.bin differ diff --git a/assets/animations/tables/blackjack-room-v1.bin b/assets/animations/tables/blackjack-room-v1.bin new file mode 100644 index 0000000..12aaeb5 Binary files /dev/null and b/assets/animations/tables/blackjack-room-v1.bin differ diff --git a/assets/data/ui-ru.json b/assets/data/ui-ru.json index 081609c..536d4e6 100644 --- a/assets/data/ui-ru.json +++ b/assets/data/ui-ru.json @@ -251,5 +251,109 @@ "symCherry": "ВИШÐ�Я", "symClover": "КЛЕВЕР", "symGem": "Ð�ЛМÐ�З", - "symCrown": "КОРОÐ�Ð�" + "symCrown": "КОРОÐ�Ð�", + "npcName6": "Дмитрий Серов", + "npcName7": "Виктор Громов", + "npcName8": "Григорий ЛиÑ�", + "npcName9": "Павел Мирный", + "npcName10": "Ð�нтон Богатый", + "npcName11": "Ð�лиÑ�а Ветрова", + "npcGreeting0": "Проверим твою выдержку?", + "npcGreeting1": "СегоднÑ� Ñ� играю Ñ�мело.", + "npcGreeting2": "Удача любит терпеливых.", + "npcGreeting3": "Давай Ñ�ыграем без Ñ�пешки.", + "npcGreeting4": "ЕÑ�ть дело Ñ� наградой.", + "npcGreeting5": "Попробуем Ñ�вои Ñ�илы?", + "npcQuest0": "Заверши любые 3 раунда", + "npcQuest1": "ПодброÑ�ÑŒ монетку 3 раза", + "npcQuest2": "Выиграй в монетку", + "npcQuest3": "Сыграй 2 раунда в блÑ�кджек", + "npcQuest4": "Выиграй в блÑ�кджек", + "npcQuest5": "Заверши 2 раздачи покера", + "npcQuest6": "Выиграй раздачу покера", + "npcQuest7": "Сыграй 3 раунда в рулетку", + "npcQuest8": "Выиграй в рулетку", + "npcQuest9": "Крути автомат 3 раза", + "npcQuest10": "Заверши партию в дурака", + "npcQuest11": "Выиграй партию в дурака", + "npcTalkPrompt3D": "[E] ПОГОВОРИТЬ", + "npcContractTitle3D": "ЧЕЛЛЕÐ�ДЖ Ð�Ð� СЕГОДÐ�Я", + "npcProgressText3D": "ПрогреÑ�Ñ�", + "npcRewardText3D": "Ð�аграда", + "npcAcceptText3D": "ВЗЯТЬ", + "npcClaimText3D": "Ð�Ð�ГРÐ�ДÐ�", + "npcCloseText3D": "ЗÐ�КРЫТЬ", + "npcAvailableText3D": "Можно принÑ�ть", + "npcActiveText3D": "ВыполнÑ�етÑ�Ñ�", + "npcReadyText3D": "Готово! Забери награду", + "npcDoneText3D": "Ð�аграда уже получена", + "npcIoErrorText3D": "Ð�е удалоÑ�ÑŒ Ñ�охранить задание", + "cbPartyName0": "ТОЛЯ", + "cbPartyName1": "СЕРГЕЙ", + "cbPartyName2": "Ð�ЛИСÐ�", + "cbBotsLabel3D": "БОТЫ", + "cbBotWaitText3D": "ЖДÐ�Т", + "cbBotHitText3D": "КÐ�РТÐ�", + "cbBotStandText3D": "ХВÐ�ТИТ", + "cbBotBustText3D": "ПЕРЕБОР", + "cbBotWinText3D": "ПОБЕДÐ�", + "cbBotLoseText3D": "ПРОИГРЫШ", + "cbBotPushText3D": "Ð�ИЧЬЯ", + "cbBotNaturalText3D": "БЛЭКДЖЕК", + "cbDealerLabel3D": "ДИЛЕР", + "cbPartyPlayerText3D": "ВЫ", + "rrPartyName0": "ТОЛЯ", + "rrPartyName1": "СЕРГЕЙ", + "rrPartyName2": "ГРИГОРИЙ", + "rrPartyCountText3D": "СОПЕРÐ�ИКИ", + "rrPartyOutText3D": "ВЫБЫЛ", + "rrPartyTurnText3D": "ХОД", + "rrPartyAliveText3D": "ОЖИДÐ�ЕТ", + "rrPartyPoolText3D": "БÐ�Ð�К", + "rrPartyExitText3D": "Раунд ещё не закончен.", + "slotRefundText3D": "ВОЗВРÐ�Т", + "slotNetText3D": "ИТОГ", + "clpTitle3D": "КЛЕВЕР 5x3", + "clpTotalText3D": "МÐ�ОЖИТЕЛЬ", + "clpNoCombo3D": "Ð�ЕТ КОМБИÐ�Ð�ЦИЙ", + "clpSymbolsText3D": "СИМВОЛ", + "clpShapesText3D": "ФИГУРÐ�", + "clpOverlapText3D": "ФИГУРÐ� x СИМВОЛ; СУММÐ�", + "clpShape0": "РЯД 3", + "clpShape1": "РЯД 4", + "clpShape2": "РЯД 5", + "clpShape3": "ВЕРТИКÐ�ЛЬ", + "clpShape4": "ДИÐ�ГОÐ�Ð�ЛЬ", + "clpShape5": "СТРЕЛКÐ� ВВЕРХ", + "clpShape6": "СТРЕЛКÐ� Ð’Ð�ИЗ", + "clpShape7": "ВЕРХÐ�ИЙ РЯД", + "clpShape8": "Ð�ИЖÐ�ИЙ РЯД", + "clpShape9": "ГЛÐ�З", + "clpShape10": "ДЖЕКПОТ", + "clpSymbol0": "КЛЕВЕР", + "clpSymbol1": "ЛИМОÐ�", + "clpSymbol2": "ВИШÐ�Я", + "clpSymbol3": "КОЛОКОЛ", + "clpSymbol4": "Ð�ЛМÐ�З", + "clpSymbol5": "СУÐ�ДУК", + "clpSymbol6": "СЕМЬ", + "slotTripleText3D": "ЦЕÐ�ТР: ТРИ ОДИÐ�Ð�КОВЫХ", + "pyrExit3D": "Ð’ ХОЛЛ", + "pyrTitle3D": "ПИРÐ�МИДÐ�", + "pyrBreakText3D": "РÐ�ЗБИТИЕ", + "pyrTurnText3D": "ХОД", + "pyrCueText3D": "БИТОК", + "pyrGuideText3D": "ПРИЦЕЛ", + "pyrPenaltyText3D": "ШТРÐ�ФÐ�ОЙ ШÐ�Р", + "pyrChoiceText3D": "ПОСЛЕ ШТРÐ�ФÐ�", + "pyrPlayText3D": "ИГРÐ�ТЬ", + "pyrPassText3D": "ПЕРЕДÐ�ТЬ", + "pyrRackText3D": "ПЕРЕБИТЬ", + "pyrTheirBreakText3D": "ЕГО УДÐ�Р", + "pyrNoContactText3D": "Ð�ЕТ КÐ�СÐ�Ð�ИЯ", + "pyrBadBreakText3D": "Ð�ЕВЕРÐ�ЫЙ РÐ�ЗБОЙ", + "pyrBadEndText3D": "Ð�ЕВЕРÐ�ЫЙ УДÐ�Р", + "pyrPlayerName3D": "ВЫ", + "pyrAIName3D": "ИИ", + "pyrSkipText3D": "ПРОПУСК" } diff --git a/assets/sprites/clover/cabinet-v1.png b/assets/sprites/clover/cabinet-v1.png new file mode 100644 index 0000000..bc31185 Binary files /dev/null and b/assets/sprites/clover/cabinet-v1.png differ diff --git a/assets/sprites/clover/prompts.json b/assets/sprites/clover/prompts.json new file mode 100644 index 0000000..d380d98 --- /dev/null +++ b/assets/sprites/clover/prompts.json @@ -0,0 +1,3 @@ +{ + "tool": "built-in image_gen" +} diff --git a/assets/sprites/clover/symbols-v1.png b/assets/sprites/clover/symbols-v1.png new file mode 100644 index 0000000..c8acfd4 Binary files /dev/null and b/assets/sprites/clover/symbols-v1.png differ diff --git a/assets/sprites/pyramid/balls-v1.png b/assets/sprites/pyramid/balls-v1.png new file mode 100644 index 0000000..a171dc2 Binary files /dev/null and b/assets/sprites/pyramid/balls-v1.png differ diff --git a/assets/sprites/pyramid/prompts.json b/assets/sprites/pyramid/prompts.json new file mode 100644 index 0000000..85c5930 --- /dev/null +++ b/assets/sprites/pyramid/prompts.json @@ -0,0 +1,6 @@ +{ + "mode": "built-in image_gen", + "table": "Use case: stylized-concept. Asset type: opaque 4:3 overhead game background for Russian pyramid billiards inside the existing ornate retro casino. Precisely top-down orthographic view, never perspective: one full long wooden Russian billiards table, rich dark burgundy polished wood rails, dark emerald cloth, warm brass sights, broad rounded wood corners, realistic cushions and restrained reflections. Crisp detailed Doom-era pixel-painted bitmap art, not photoreal, not vectors. Playable cloth is a completely empty clean rectangle at x9.375% to90.625% of canvas and y20.833% to75%; this rectangle has exactly 2:1 proportions. No balls, no cue, no people, no lettering, no lights painted on cloth, no symbols. Six small black pocket mouths, corners and midpoints of the two long sides, narrow Russian pyramid pockets, not enormous pool holes. Rails around cloth, hints of crimson casino carpet beyond. Leave top 8% and bottom 16% as dark quiet framing for game HUD. All four table edges visible, table fills most of screen. Consistent pixel textures and physically coherent furniture, no skew or vanishing point, no watermark.", + "table_narrow_edit": "Edit target: supplied Russian billiard overhead table bitmap. Change only the six pocket mouths and immediately adjoining green cushion noses. Reduce all six black pocket-mouth widths and heights to about 50% of their current size, creating genuinely narrow Russian pyramid pockets. Extend the same green felt cushion noses towards these smaller holes, preserving realistic brass collars and shadows. Keep all six pocket centers at exactly the same positions. Preserve every other pixel-art design, orthographic camera, table proportions, wood, carpet, colours, framing, and empty cloth. No balls, no cue, no new objects, no text or watermark. This remains a crisp pixel-painted casino game background, not a photo.", + "balls": "Use case: stylized-concept. Asset type: transparent 4 by 2 equal square cell game sprite atlas with exactly eight Russian billiard ball sprites viewed from directly above, perfectly circular matching anchor/diameter. Top row four ivory white glossy phenolic billiard balls, bottom row four golden amber yellow cue balls. Four slightly different rotation/reflection poses of the same ball, subtle varied surface details; no deformations, no number markings or text. Consistent upper-left warm highlight, softly shaded lower-right edge and faint ivory and honey material tone, high-contrast crisp readable spherical silhouettes, Doom-era richly shaded pixel-painted game style. Each ball fully isolated in its cell with generous transparent gutters, same size and center, no cast shadows extending beyond ball, no background, no grid, no checkerboard, no border, no watermark. This is Russian pyramid: no coloured solids/stripes, only four whites and four identical amber cue ball rotation poses." +} diff --git a/assets/sprites/pyramid/table-v1.png b/assets/sprites/pyramid/table-v1.png new file mode 100644 index 0000000..0736fd4 Binary files /dev/null and b/assets/sprites/pyramid/table-v1.png differ diff --git a/assets/sprites/pyramid/table-v2.png b/assets/sprites/pyramid/table-v2.png new file mode 100644 index 0000000..d424157 Binary files /dev/null and b/assets/sprites/pyramid/table-v2.png differ diff --git a/assets/sprites/roulette/participants-v1.png b/assets/sprites/roulette/participants-v1.png new file mode 100644 index 0000000..17517e9 Binary files /dev/null and b/assets/sprites/roulette/participants-v1.png differ diff --git a/assets/sprites/tables/blackjack-guests-v1.png b/assets/sprites/tables/blackjack-guests-v1.png new file mode 100644 index 0000000..c966633 Binary files /dev/null and b/assets/sprites/tables/blackjack-guests-v1.png differ diff --git a/assets/sprites/tables/blackjack-room-v1.png b/assets/sprites/tables/blackjack-room-v1.png new file mode 100644 index 0000000..3be2fb7 Binary files /dev/null and b/assets/sprites/tables/blackjack-room-v1.png differ diff --git a/bin/poker.exe b/bin/poker.exe index 36806d9..74e1c3c 100644 Binary files a/bin/poker.exe and b/bin/poker.exe differ diff --git a/build/AssemblerCasinoLauncher.cs b/build/AssemblerCasinoLauncher.cs index 9886c83..580db24 100644 --- a/build/AssemblerCasinoLauncher.cs +++ b/build/AssemblerCasinoLauncher.cs @@ -8,7 +8,7 @@ namespace AssemblerCasinoLauncher { static class Program { - const string ExpectedPokerSha256 = "6DE8E29E8A8FCC60C2FB297348BAD5E20697611317EF53C7E5A258BDCADAB657"; + const string ExpectedPokerSha256 = "7E7165F5B9287FCF0F7A7E8F526DD23C0DA5F3A6CF72F08D1A40EB548FFCD428"; [STAThread] static void Main() diff --git a/build/graphics/poker.exe b/build/graphics/poker.exe index 36806d9..8d15494 100644 Binary files a/build/graphics/poker.exe and b/build/graphics/poker.exe differ diff --git a/casino3d.inc b/casino3d.inc index 90d995c..628a60e 100644 --- a/casino3d.inc +++ b/casino3d.inc @@ -1,5480 +1,5517 @@ - -; ============================================================================== -; CASINO 2.5D - MASM32 SOFTWARE RAYCASTER (CP1251) -; Graphical migration; this is not id Software's Doom engine. -; ============================================================================== - -includelib gdi32.lib -includelib winmm.lib - -CreateWindowExA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD -RegisterClassExA PROTO :DWORD -DefWindowProcA PROTO :DWORD,:DWORD,:DWORD,:DWORD -ShowWindow PROTO :DWORD,:DWORD -UpdateWindow PROTO :DWORD -GetDC PROTO :DWORD -ReleaseDC PROTO :DWORD,:DWORD -StretchDIBits PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD -PeekMessageA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD -TranslateMessage PROTO :DWORD -DispatchMessageA PROTO :DWORD -PostQuitMessage PROTO :DWORD -DestroyWindow PROTO :DWORD -SetWindowTextA PROTO :DWORD,:DWORD -SetForegroundWindow PROTO :DWORD -GetConsoleWindow PROTO -GetSystemMetrics PROTO :DWORD -CreateFileA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD -ReadFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD -CloseHandle PROTO :DWORD -GetAsyncKeyState PROTO :DWORD -PlaySoundA PROTO :DWORD,:DWORD,:DWORD -GetModuleFileNameA PROTO :DWORD,:DWORD,:DWORD -CopyFileA PROTO :DWORD,:DWORD,:DWORD -lstrcmpiA PROTO :DWORD,:DWORD -GetFileSize PROTO :DWORD,:DWORD -Sleep PROTO :DWORD - -C3D_POINT STRUCT - x dd ? - y dd ? -C3D_POINT ENDS - -C3D_MSG STRUCT - hwnd dd ? - message dd ? - wParam dd ? - lParam dd ? - time dd ? - pt C3D_POINT <> -C3D_MSG ENDS - -C3D_WNDCLASSEX STRUCT - cbSize dd ? - style dd ? - lpfnWndProc dd ? - cbClsExtra dd ? - cbWndExtra dd ? - hInstance dd ? - hIcon dd ? - hCursor dd ? - hbrBackground dd ? - lpszMenuName dd ? - lpszClassName dd ? - hIconSm dd ? -C3D_WNDCLASSEX ENDS - -C3D_BITMAPINFOHEADER STRUCT - biSize dd ? - biWidth dd ? - biHeight dd ? - biPlanes dw ? - biBitCount dw ? - biCompression dd ? - biSizeImage dd ? - biXPelsPerMeter dd ? - biYPelsPerMeter dd ? - biClrUsed dd ? - biClrImportant dd ? -C3D_BITMAPINFOHEADER ENDS - -C3D_BITMAPINFO STRUCT - bmiHeader C3D_BITMAPINFOHEADER <> - bmiColors dd ? -C3D_BITMAPINFO ENDS - -SpriteObject STRUCT - posX dd ? - posY dd ? - baseTexId dd ? - frameCount dd ? - curFrame dd ? - animTimer dd ? - animSpeed dd ? - interactId dd ? - promptPtr dd ? - distSq dd ? -SpriteObject ENDS - -SCREEN_W equ 640 -SCREEN_H equ 480 -HALF_W equ 320 -HALF_H equ 240 -SCREEN_SIZE equ (SCREEN_W * SCREEN_H) -WIN_SCALE equ 1 -WINDOW_W equ (SCREEN_W * WIN_SCALE) -WINDOW_H equ (SCREEN_H * WIN_SCALE) - -FP_1 equ 65536 -FP_HALF equ 32768 -CHROMA_KEY equ 00FF00FFh - -MODE_WALK equ 0 -MODE_SLOTS equ 1 -MODE_BLACKJACK equ 2 -MODE_ROULETTE equ 3 -MODE_SHOP equ 4 -MODE_ATM equ 5 -MODE_COIN equ 6 -MODE_DICE equ 7 -MODE_SKULLS equ 8 -MODE_SKILL equ 9 - -WS_OVERLAPPEDWINDOW equ 00CF0000h -SW_SHOW equ 5 -SW_HIDE equ 0 -PM_REMOVE equ 1 -WM_DESTROY equ 0002h -WM_CLOSE equ 0010h -WM_QUIT equ 0012h -CS_HREDRAW equ 2 -CS_VREDRAW equ 1 -DIB_RGB_COLORS equ 0 -SRCCOPY equ 00CC0020h -INVALID_FILE_HANDLE equ -1 - -include casino3d_data.inc -include font8x8.inc -include src_graphics\platform_data.inc -include src_graphics\casino_actions_data.inc -include src_graphics\audio_data.inc -include src_graphics\startup_data.inc -include src_graphics\card_tables_data.inc -include src_graphics\native_durak_data.inc -include src_graphics\scene_animation_data.inc -include src_graphics\arrival_data.inc -include src_graphics\city_arrival_data.inc -include src_graphics\merchant_data.inc -include src_graphics\hall_data.inc -include src_graphics\native_wheel_data.inc -include src_graphics\billiards_data.inc -include src_graphics\buckshot_data.inc -include src_graphics\russian_view_data.inc -include src_graphics\unavailable_data.inc -include src_graphics\native_slots_data.inc -include src_graphics\native_coin_data.inc - -.data -ALIGN 4 -h3DInst dd 0 -h3DWnd dd 0 -h3DDC dd 0 -hCasinoConsole dd 0 - -bmi3D C3D_BITMAPINFO <> -msg3D C3D_MSG <> -wc3D C3D_WNDCLASSEX <> - -sz3DClassName db "Casino3DRetroClass",0 -sz3DWindowTitle db 192,241,241,229,236,225,235,229,240,32,202,224,231,232,237,238,32,45,32,50,46,53,68,0 -szTexturesRelPath db "assets\textures\casino3d-hd.bin",0 -szTexturesFullPath db 260 dup(0) - - -playerX dd (16 * FP_1 + FP_HALF) -playerY dd (16 * FP_1 + FP_HALF) -playerAngle dd 384 -playerDirX dd 0 -playerDirY dd -FP_1 -playerPlaneX dd (FP_1 * 66 / 100) -playerPlaneY dd 0 - -engineMode dd 0 -interactTargetId dd 0 -interactPromptPtr dd 0 -dancerLuckBuff dd 0 -flashTimer dd 0 -flashMessage db 128 dup(0) - -promptDancer db "[E] ÊÀÁÀÐÅ - ×ÀÅÂÛÅ $100",0 -promptBlackjack db "[E] ÁËÝÊÄÆÅÊ (21)",0 -promptPoker db 91,69,93,32,207,206,202,197,208,32,40,210,197,213,192,209,209,202,200,201,32,213,206,203,196,197,204,41,0 -promptDurak db "[E] ÊÀÐÒÛ: ÏÎÄÊÈÄÍÎÉ ÄÓÐÀÊ",0 -promptCasinoRoulette db "[E] ÅÂÐÎÏÅÉÑÊÀß ÐÓËÅÒÊÀ",0 -promptClassicSlot db "[E] ÊËÀÑÑÈ×ÅÑÊÈÅ ÑËÎÒÛ 777",0 -promptCloverSlot db "[E] ÑËÎÒÛ CLOVERPIT (5x3)",0 -promptDice db 91,69,93,32,200,195,208,192,32,194,32,202,206,209,210,200,0 -promptSkulls db "[E] ÍÀϨÐÑÒÊÈ (×ÅÐÅÏÀ)",0 -promptCoin db "[E] ÌÎÍÅÒÊÀ (ÎШË/ÐÅØÊÀ)",0 -promptSkillCheck db "[E] ÒÐÅÍÈÐÎÂÊÀ ÐÅÀÊÖÈÈ",0 -promptBuckshot db 91,69,93,32,193,192,202,216,206,210,32,208,211,203,197,210,202,192,0 -promptRussianRoulette db "[E] ÐÓÑÑÊÀß ÐÓËÅÒÊÀ (VIP)",0 -promptOnlineRR db "[E] ÑÅÒÅÂÀß ÐÓËÅÒÊÀ (NET)",0 -promptUmamusume db "[E] ÑÊÀ×ÊÈ ÓÌÀÌÓÑÓÌÝ",0 -promptHellTower db "[E] ÁÀØÍß ÀÄÀ (10 ÝÒÀÆÅÉ)",0 -promptShop db "[E] ÁÓÒÈÊ È ÒÀËÈÑÌÀÍÛ",0 -promptATM db "[E] ÁÀÍÊÎÌÀÒ È ÁÀËÀÍÑ",0 -promptPlayerTerminal db "[E] ÒÅÐÌÈÍÀË: ÑÒÀÒÛ È À×ÈÂÊÈ",0 -promptObserver db "[E] ÐÅÆÈÌ ÍÀÁËÞÄÀÒÅËß (ÈÈ)",0 - -szTitleBlackjack db 202,192,199,200,202,32,51,68,32,45,32,193,203,221,202,196,198,197,202,32,40,50,49,41,0 -szTitlePoker db 202,192,199,200,202,32,51,68,32,45,32,207,206,202,197,208,32,40,210,197,213,192,209,209,202,200,201,32,213,206,203,196 - db 197,204,41,0 -szTitleDurak db 202,192,199,200,202,32,51,68,32,45,32,207,197,208,197,194,206,196,205,206,201,32,196,211,208,192,202,0 -szTitleCasinoRoulette db 202,192,199,200,202,32,51,68,32,45,32,197,194,208,206,207,197,201,209,202,192,223,32,208,211,203,197,210,202,192,0 -szTitleClassicSlot db 202,192,199,200,202,32,51,68,32,45,32,192,194,210,206,204,192,210,32,55,55,55,0 -szTitleCloverSlot db 202,192,199,200,202,32,51,68,32,45,32,202,203,197,194,197,208,205,192,223,32,223,204,192,32,40,53,120,51,41,0 -szTitleDice db 202,192,199,200,202,32,51,68,32,45,32,200,195,208,192,32,194,32,202,206,209,210,200,0 -szTitleSkulls db 202,192,199,200,202,32,51,68,32,45,32,205,192,207,168,208,209,210,202,200,0 -szTitleCoin db 202,192,199,200,202,32,51,68,32,45,32,204,206,205,197,210,202,192,32,40,206,208,168,203,47,208,197,216,202,192,41,0 -szTitleSkillCheck db 202,192,199,200,202,32,51,68,32,45,32,207,208,206,194,197,208,202,192,32,205,192,194,219,202,192,0 -szTitleBuckshot db 202,192,199,200,202,32,51,68,32,45,32,193,192,202,216,206,210,32,208,211,203,197,210,202,192,0 -szTitleRussianRoulette db 202,192,199,200,202,32,51,68,32,45,32,208,211,209,209,202,192,223,32,208,211,203,197,210,202,192,0 -szTitleOnlineRR db 202,192,199,200,202,32,51,68,32,45,32,209,197,210,197,194,192,223,32,208,211,209,209,202,192,223,32,208,211,203,197,210 - db 202,192,0 -szTitleUmamusume db 202,192,199,200,202,32,51,68,32,45,32,195,206,205,202,200,32,211,204,192,204,211,209,211,204,197,0 -szTitleHellTower db 202,192,199,200,202,32,51,68,32,45,32,192,196,209,202,192,223,32,193,192,216,205,223,0 -szTitleShop db 202,192,199,200,202,32,51,68,32,45,32,202,192,208,210,219,32,200,32,210,192,203,200,209,204,192,205,219,0 -szTitleATM db 202,192,199,200,202,32,51,68,32,45,32,193,192,205,202,206,204,192,210,0 -szTitleTerminal db 202,192,199,200,202,32,51,68,32,45,32,203,206,202,192,203,220,205,219,197,32,207,208,206,212,200,203,200,0 -szTitleObserver db 202,192,199,200,202,32,51,68,32,45,32,205,192,193,203,222,196,192,210,197,203,220,32,40,200,200,41,0 -textCabinetFooter db "[ ÂÛÕÎÄ: ÂÂÅÄÈÒÅ 0 / ÂÛÁÅÐÈÒÅ 'N' ÄËß ÂÎÇÂÐÀÒÀ  ÇÀË ]",0 - -msgDancerTipped db "Âû áðîñèëè $100 òàíöîâùèöå! ÓÄÀ×À ÀÊÒÈÂÈÐÎÂÀÍÀ!",0 -msgNeedMoney db "Íåäîñòàòî÷íî äåíåã â êîøåëüêå!",0 -statusHUDFormat db "ÁÀÍÊÐÎËË: $",0 -targetHUDFormat db " ÖÅËÜ: $",0 -luckHUDFormat db " ÓÄÀ×À: +",0 -controlsHUD db "WASD/Ñòðåëêè: Õîäüáà | E: Äåéñòâèå | ESC: Ìåíþ",0 - -NUM_SPRITES equ 22 - -INTERACT_NONE equ 0 -INTERACT_BLACKJACK equ 1 -INTERACT_POKER equ 2 -INTERACT_SLOTS_777 equ 3 -INTERACT_ROULETTE equ 4 -INTERACT_SKULLS equ 5 -INTERACT_SHOP equ 6 -INTERACT_ATM equ 7 -INTERACT_DANCER equ 8 -INTERACT_HELL_TOWER equ 9 -INTERACT_DURAK equ 10 -INTERACT_BUCKSHOT equ 11 -INTERACT_COIN equ 12 -INTERACT_DICE equ 13 -INTERACT_SLOTS_CLOVER equ 14 -INTERACT_UMAMUSUME equ 15 -INTERACT_OBSERVER equ 16 -INTERACT_TERMINAL equ 17 -INTERACT_ONLINE_RR equ 18 -INTERACT_RUSSIAN_ROULETTE equ 19 -INTERACT_SKILL_CHECK equ 20 -ALIGN 4 -casinoSprites SpriteObject NUM_SPRITES dup(<>) -sortedSprites dd NUM_SPRITES dup(0) - -rowDistTable dd 120 dup(0) -rngSeed3D dd 12345678h - -slotBet dd 50 -slotReel1 dd 0 -slotReel2 dd 1 -slotReel3 dd 2 -slotSpinState dd 0 -slotSpinTimer dd 0 -slotWinAmount dd 0 -slotWinMsg db 64 dup(0) - -bjState dd 0 -bjBet dd 100 -bjPlayerCards dd 10 dup(0) -bjPlayerCardCount dd 0 -bjPlayerScore dd 0 -bjDealerCards dd 10 dup(0) -bjDealerCardCount dd 0 -bjDealerScore dd 0 -bjDealerHideHole dd 1 -bjOutcomeMsg db 64 dup(0) - -roulState dd 0 -roulBetType dd 1 -roulBetAmount dd 100 -roulWheelAngle dd 0 -roulBallAngle dd 0 -roulSpinTimer dd 0 -roulWinningNum dd 0 -roulPayout dd 0 -roulOutcomeMsg db 64 dup(0) - -coinRxAnimTable db 26, 22, 16, 6, 16, 22, 26, 22, 16, 6 - -; --- Native 2.5D Coin Flip --- -coin3d_bet dd 50 -coin3d_choice dd 1 ; 1 = Îð¸ë, 2 = Ðåøêà -coin3d_state dd 0 ; 0 = Idle, 1 = Flipping, 2 = Result -coin3d_timer dd 0 -coin3d_result dd 1 ; 1 = Îð¸ë, 2 = Ðåøêà -coin3d_streak dd 0 -coin3d_win dd 0 - -textCoinTitle db "* * * Ç Î Ë Î Ò À ß Ì Î Í Å Ò À * * *",0 -textCoinHeads db "ÎШË",0 -textCoinTails db "ÐÅØÊÀ",0 -textCoinSide1 db "[1] ÎШË",0 -textCoinSide2 db "[2] ÐÅØÊÀ",0 -textCoinFlipping db "ÌÎÍÅÒÀ  ÏÎ˨ÒÅ...",0 -textCoinWin db "ÏÎÁÅÄÀ: +$",0 -textCoinLose db "ÍÅ ÓÃÀÄÀËÈ!",0 -textCoinStreakFmt db "ÑÅÐÈß ÏÎÁÅÄ: x",0 -textCoinSelected db "ÂÛÁÐÀÍÎ",0 -textCoinKey1 db "[1] ÎШË",0 -textCoinKey2 db "[2] ÐÅØÊÀ",0 -textCoinKeySpace db "[SPACE]",0 - -; --- Native 2.5D Dice Game --- -dice3d_bet dd 50 -dice3d_choice dd 1 ; 1 = ׸ò, 2 = Íå÷åò -dice3d_state dd 0 ; 0 = Idle, 1 = Rolling, 2 = Result -dice3d_timer dd 0 -dice3d_val1 dd 4 -dice3d_val2 dd 6 -dice3d_sum dd 10 -dice3d_win dd 0 - -textDiceTitle db 200,195,208,192,32,194,32,202,206,209,210,200,0 -textDiceEven db "[1] רÒ",0 -textDiceOdd db "[2] ÍÅ×ÅÒ",0 -textDiceEvenNums db "2 4 6 ...",0 -textDiceOddNums db "3 5 7 ...",0 -textDiceSumHdr db "ÑÓÌÌÀ: ",0 -textDicePlus db " + ",0 -textDiceEqual db " = ",0 -textDiceEvenResult db " (רÒ)",0 -textDiceOddResult db " (ÍÅ×ÅÒ)",0 -textDiceRolling db "ÊÎÑÒÈ ËÅÒßÒ ÏÎ ÑÓÊÍÓ...",0 -textDiceWin db "ÂÛÈÃÐÛØ: +$",0 -textDiceWinMult db "! (x2)",0 -textDiceLose db "ÏÐÎÈÃÐÛØ!",0 -textDiceKey1 db "[1] רÒ",0 -textDiceKey2 db "[2] ÍÅ×ÅÒ",0 -textDiceKeySpace db "[SPACE]",0 - -; --- Native 2.5D Skulls Game --- -skulls3d_bet dd 50 -skulls3d_state dd 0 ; 0 = Idle, 1 = Show ball, 2 = Shuffle, 3 = Pick, 4 = Reveal -skulls3d_timer dd 0 -skulls3d_ballPos dd 1 ; 0, 1, 2 -skulls3d_choice dd 1 ; 0, 1, 2 -skulls3d_win dd 0 -skulls3d_swapPair0 dd 0 -skulls3d_swapPair1 dd 1 -skulls3d_swapPair2 dd 2 -skulls3d_cup0 dd 0 -skulls3d_cup1 dd 1 -skulls3d_cup2 dd 2 - -textSkullsTitle db "* * * Í À Ï ¨ Ð Ñ Ò Ê È * * *",0 -textSkullsPhase0 db "ÄÅËÀÉ ÑÒÀÂÊÓ È ÆÌÈ [ÏÐÎÁÅË]",0 -textSkullsPhase1 db "ÑÌÎÒÐÈ, ÃÄÅ ÇÎËÎÒÎÉ ØÀÐ...",0 -textSkullsPhase2 db "ÊÐÓ×Ó, ÂÅÐ×Ó, ÇÀÏÓÒÀÒÜ ÕÎ×Ó...",0 -textSkullsPhase3 db "ÃÄÅ ØÀÐ? ÂÛÁÈÐÀÉ: [1], [2] ÈËÈ [3]!",0 -textSkullsWin db "ÂÛÈÃÐÛØ: +$",0 -textSkullsWinMult db "! (x3) ÂÛ ÓÃÀÄÀËÈ!",0 -textSkullsLose db "ÌÈÌÎ! ØÀÐ ÁÛË Â ÄÐÓÃÎÌ ÌÅÑÒÅ!",0 -textSkullsAgain db "[ÏÐÎÁÅË] - ÑÛÃÐÀÒÜ ÅÙ¨ ÐÀÇ",0 -textSkullsKey1 db "[1]",0 -textSkullsKey2 db "[2]",0 -textSkullsKey3 db "[3]",0 -textSkullsKeySpace db "[SPACE] ÑÒÀÐÒ",0 - -; --- Native 2.5D Skill Check (Dead by Daylight Survivor Check) --- -skill3d_bet dd 50 -skill3d_state dd 0 ; 0=Ready, 1=Active, 2=Hit Result, 3=Miss Result, 4=Escaped, 5=Defeated -skill3d_timer dd 0 -skill3d_needle dd 55 ; Needle X (52..268) -skill3d_speed dd 4 -skill3d_dir dd 1 ; 1=Right, -1=Left -skill3d_zone_start dd 140 -skill3d_zone_width dd 48 -skill3d_great_start dd 176 -skill3d_great_width dd 12 -skill3d_hits dd 0 -skill3d_misses dd 0 -skill3d_last_result dd 0 -skill3d_win_amount dd 0 - -textSkillTitle db 61,61,61,32,207,208,206,194,197,208,202,192,32,205,192,194,219,202,192,32,61,61,61,0 -textSkillHitsHdr db "ÕÈÒ: ",0 -textSkillMissHdr db "ÏÐÎÌÀÕ: ",0 -textSkillReadyMsg db "ÍÀÆÌÈÒÅ [ÏÐÎÁÅË] ÄËß ÑÒÀÐÒÀ",0 -textSkillPrompt db "ÍÀÆÌÈÒÅ [ÏÐÎÁÅË]  ÇÎÍÅ!",0 -textSkillHitMsg db "ÕÈÒ! ÒÎ×ÍÎÅ ÏÎÏÀÄÀÍÈÅ!",0 -textSkillGreatMsg db 206,210,203,200,215,205,206,33,32,43,193,206,205,211,209,33,0 -textSkillMissMsg db "ÏÐÎÌÀÕ! ÒÐÅÂÎÃÀ!",0 -textSkillEscape db "ÏÎÁÅà ÓÑÏÅØÅÍ! ÂÛÈÃÐÛØ: +$",0 -textSkillLost db "ÂÛ ÏÎÉÌÀÍÛ! ÏÐÎÈÃÐÛØ ÑÒÀÂÊÈ!",0 -textSkillKeySpace db "[SPACE] ÐÅÀÊÖÈß",0 -textSkillKeyBet db "[ÂÂÅÐÕ/ÂÍÈÇ]",0 - -; --- Shared UI Strings --- -textKeyEsc db "[ESC]",0 -textBankPrompt db "ÁÀÍÊ: $",0 -textBetPrompt db "ÑÒÀÂÊÀ: $",0 -textBetHint db " [W/S]",0 - -shopMsg db 128 dup(0) -atmMsg db 128 dup(0) - -strWin db "ÏÎÁÅÄÀ! +$",0 -strLose db "ÏÐÎÈÃÐÛØ",0 -strJackpot db "ÄÆÅÊÏÎÒ! +$",0 -strPush db 205,200,215,220,223,0 -strDealerBust db "ÄÈËÅÐ ÏÅÐÅÁÐÀË! ÏÎÁÅÄÀ! +$",0 -strPlayerBust db "ÏÅÐÅÁÎÐ (>21)! ÏÐÎÈÃÐÛØ",0 - -sym7 db " 777 ",0 -symBar db " BAR ",0 -symBell db 32,199,194,206,205,0 -symCherry db 194,200,216,205,223,0 -symClover db 202,203,197,194,197,208,0 -symGem db 192,203,204,192,199,0 -symCrown db 202,206,208,206,205,192,0 - -cardRankStr db "A ",0,"2 ",0,"3 ",0,"4 ",0,"5 ",0,"6 ",0,"7 ",0,"8 ",0,"9 ",0,"10",0,"J ",0,"Q ",0,"K ",0 - -.data? -ALIGN 4 -screenBuffer dd SCREEN_SIZE dup(?) -ALIGN 4 -zBuffer dd SCREEN_W dup(?) -ALIGN 4 -texturesBuffer dd (104 * 128 * 128) dup(?) - -hudNumBuffer db 32 dup(?) - -.code - -; --- 3D Window Procedure --- -Casino3DWndProc PROC hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD - invoke WindowEvents3D, hwnd, uMsg, wParam, lParam - ret -Casino3DWndProc ENDP - -; --- Random Generator --- -RandomRange3D PROC maxVal:DWORD - mov eax, rngSeed3D - imul eax, 1103515245 - add eax, 12345 - mov rngSeed3D, eax - shr eax, 16 - and eax, 7FFFh - xor edx, edx - div maxVal - mov eax, edx - ret -RandomRange3D ENDP - -; --- Copy String --- -CopyString3D PROC src:DWORD, dst:DWORD - push esi - push edi - mov esi, src - mov edi, dst -@@: - mov al, [esi] - mov [edi], al - test al, al - jz @F - inc esi - inc edi - jmp @B -@@: - pop edi - pop esi - ret -CopyString3D ENDP - -; --- Format Number to Decimal String --- -FormatNumber PROC num:DWORD, buf:DWORD - push ebx - push esi - push edi - mov eax, num - mov edi, buf - test eax, eax - jns fn_pos - mov BYTE PTR [edi], '-' - inc edi - neg eax -fn_pos: - mov ebx, 10 - push 0 -fn_div: - xor edx, edx - div ebx - add dl, '0' - push edx - test eax, eax - jnz fn_div -fn_pop: - pop eax - test al, al - jz fn_done - mov [edi], al - inc edi - jmp fn_pop -fn_done: - mov BYTE PTR [edi], 0 - pop edi - pop esi - pop ebx - ret -FormatNumber ENDP - -; --- Fast 2D Drawing Primitives --- -DrawBox PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD - -DrawPixel PROC x:DWORD, y:DWORD, color:DWORD - invoke DrawBox, x, y, 1, 1, color - ret -DrawPixel ENDP - -DrawBox PROC x:DWORD, y:DWORD, w:DWORD, h:DWORD, color:DWORD - shl x, 1 - shl y, 1 - shl w, 1 - shl h, 1 - push ebx - push esi - push edi - mov edi, y -box_row_loop: - mov eax, y - add eax, h - cmp edi, eax - jge box_done - cmp edi, 0 - jl next_box_row - cmp edi, SCREEN_H - jge box_done - - mov esi, x -box_col_loop: - mov eax, x - add eax, w - cmp esi, eax - jge next_box_row - cmp esi, 0 - jl next_box_col - cmp esi, SCREEN_W - jge next_box_row - - mov ecx, edi - imul ecx, SCREEN_W - add ecx, esi - mov edx, color - mov [screenBuffer + ecx*4], edx - -next_box_col: - inc esi - jmp box_col_loop - -next_box_row: - inc edi - jmp box_row_loop - -box_done: - pop edi - pop esi - pop ebx - ret -DrawBox ENDP - -DrawBoxBorder PROC uses ebx x:DWORD, y:DWORD, w:DWORD, h:DWORD, fillColor:DWORD, borderColor:DWORD, bWidth:DWORD - invoke DrawBox, x, y, w, h, borderColor - mov eax, x - add eax, bWidth - mov edx, y - add edx, bWidth - mov ecx, w - sub ecx, bWidth - sub ecx, bWidth - mov ebx, h - sub ebx, bWidth - sub ebx, bWidth - invoke DrawBox, eax, edx, ecx, ebx, fillColor - ret -DrawBoxBorder ENDP - -DrawCircle PROC cxVal:DWORD, cyVal:DWORD, radius:DWORD, color:DWORD - push ebx - push esi - push edi - mov eax, radius - neg eax - mov edi, eax -circ_y: - cmp edi, radius - jg circ_done - mov eax, radius - neg eax - mov esi, eax -circ_x: - cmp esi, radius - jg next_circ_y - - mov eax, esi - imul eax, eax - mov ebx, edi - imul ebx, ebx - add eax, ebx - mov edx, radius - imul edx, edx - cmp eax, edx - jg next_circ_x - - mov eax, cxVal - add eax, esi - mov ecx, cyVal - add ecx, edi - invoke DrawPixel, eax, ecx, color - -next_circ_x: - inc esi - jmp circ_x -next_circ_y: - inc edi - jmp circ_y -circ_done: - pop edi - pop esi - pop ebx - ret -DrawCircle ENDP - -DrawChar8x8 PROC uses ebx esi edi x:DWORD, y:DWORD, chVal:DWORD, color:DWORD - local column:DWORD - mov eax, chVal - and eax, 255 - lea esi, [font8x8 + eax*8] - xor edi, edi -glyph_row: - movzx ebx, BYTE PTR [esi+edi] - mov column, 0 -glyph_col: - test ebx, 80h - jz glyph_next - mov eax, x - add eax, column - mov edx, y - add edx, edi - invoke DrawPixel, eax, edx, color -glyph_next: - shl ebx, 1 - inc column - cmp column, 8 - jl glyph_col - inc edi - cmp edi, 8 - jl glyph_row - ret -DrawChar8x8 ENDP - -DrawString8x8 PROC x:DWORD, y:DWORD, strPtr:DWORD, color:DWORD - push ebx - push esi - mov esi, strPtr - mov ebx, x -str_loop: - movzx eax, BYTE PTR [esi] - test al, al - jz str_done - invoke DrawChar8x8, ebx, y, eax, color - add ebx, 8 - inc esi - jmp str_loop -str_done: - pop esi - pop ebx - ret -DrawString8x8 ENDP - -; --- True 3D Perspective Floor & Ceiling Rendering --- - -; --- DDA Raycasting Walls --- -RenderWalls PROC - local col:DWORD - local originalStart:DWORD - local camX:DWORD - local rayDirX:DWORD - local rayDirY:DWORD - local mapX:DWORD - local mapY:DWORD - local deltaDistX:DWORD - local deltaDistY:DWORD - local stepX:DWORD - local stepY:DWORD - local sideDistX:DWORD - local sideDistY:DWORD - local side:DWORD - local perpWallDist:DWORD - local lineH:DWORD - local drawStart:DWORD - local drawEnd:DWORD - local wallHit:DWORD - local texX:DWORD - local texXHD:DWORD - local pixelMaterial:DWORD - local texId:DWORD - local shade:DWORD - - push ebx - push esi - push edi - - mov eax, playerAngle - and eax, 511 - mov ebx, [tableCos + eax*4] - mov playerDirX, ebx - mov ebx, [tableSin + eax*4] - mov playerDirY, ebx - - mov eax, ebx - imul eax, -66 - cdq - mov ecx, 100 - idiv ecx - mov playerPlaneX, eax - - mov eax, playerDirX - imul eax, 66 - cdq - idiv ecx - mov playerPlaneY, eax - - mov col, 0 -col_loop: - cmp col, SCREEN_W - jge walls_done - - mov eax, col - shl eax, 1 - sub eax, SCREEN_W - imul eax, FP_1 - cdq - mov ecx, SCREEN_W - idiv ecx - mov camX, eax - - mov eax, playerPlaneX - imul camX - shrd eax, edx, 16 - add eax, playerDirX - mov rayDirX, eax - - mov eax, playerPlaneY - imul camX - shrd eax, edx, 16 - add eax, playerDirY - mov rayDirY, eax - - mov eax, playerX - sar eax, 16 - mov mapX, eax - mov eax, playerY - sar eax, 16 - mov mapY, eax - - mov eax, rayDirX - test eax, eax - jnz calc_delta_x - mov deltaDistX, 7FFFFFFFh - jmp calc_delta_y -calc_delta_x: - test eax, eax - jns @F - neg eax -@@: - mov ebx, eax - cmp ebx, 4 - jbe delta_x_clamp - xor eax, eax - mov edx, 1 - div ebx - mov deltaDistX, eax - jmp calc_delta_y -delta_x_clamp: - mov deltaDistX, 7FFFFFFFh - -calc_delta_y: - mov eax, rayDirY - test eax, eax - jnz calc_delta_y_ok - mov deltaDistY, 7FFFFFFFh - jmp check_step -calc_delta_y_ok: - test eax, eax - jns @F - neg eax -@@: - mov ebx, eax - cmp ebx, 4 - jbe delta_y_clamp - xor eax, eax - mov edx, 1 - div ebx - mov deltaDistY, eax - jmp check_step -delta_y_clamp: - mov deltaDistY, 7FFFFFFFh - -check_step: - cmp rayDirX, 0 - jge step_x_pos - mov stepX, -1 - mov eax, playerX - mov edx, mapX - shl edx, 16 - sub eax, edx - imul deltaDistX - shrd eax, edx, 16 - mov sideDistX, eax - jmp check_step_y -step_x_pos: - mov stepX, 1 - mov eax, mapX - inc eax - shl eax, 16 - sub eax, playerX - imul deltaDistX - shrd eax, edx, 16 - mov sideDistX, eax - -check_step_y: - cmp rayDirY, 0 - jge step_y_pos - mov stepY, -1 - mov eax, playerY - mov edx, mapY - shl edx, 16 - sub eax, edx - imul deltaDistY - shrd eax, edx, 16 - mov sideDistY, eax - jmp dda_start -step_y_pos: - mov stepY, 1 - mov eax, mapY - inc eax - shl eax, 16 - sub eax, playerY - imul deltaDistY - shrd eax, edx, 16 - mov sideDistY, eax - -dda_start: - xor ecx, ecx -dda_step_loop: - inc ecx - cmp ecx, 64 - jge wall_map_boundary - - mov eax, sideDistX - cmp eax, sideDistY - jge step_in_y - - mov eax, deltaDistX - add sideDistX, eax - mov eax, stepX - add mapX, eax - mov side, 0 - jmp check_tile - -step_in_y: - mov eax, deltaDistY - add sideDistY, eax - mov eax, stepY - add mapY, eax - mov side, 1 - -check_tile: - cmp mapX, 0 - jl wall_map_boundary - cmp mapX, MAP_WIDTH - jge wall_map_boundary - cmp mapY, 0 - jl wall_map_boundary - cmp mapY, MAP_HEIGHT - jge wall_map_boundary - - mov eax, mapY - shl eax, 5 - add eax, mapX - mov edx, worldMap3D - movzx eax, BYTE PTR [edx + eax] - test eax, eax - jnz hit_wall - jmp dda_step_loop - -wall_map_boundary: - cmp outdoorRender3D, 0 - je hit_wall - mov eax, col - mov zBuffer[eax*4], 7FFFFFFFh - jmp next_col - -hit_wall: - cmp side, 0 - jne perp_y - mov eax, sideDistX - sub eax, deltaDistX - mov perpWallDist, eax - jmp perp_done -perp_y: - mov eax, sideDistY - sub eax, deltaDistY - mov perpWallDist, eax - -perp_done: - cmp perpWallDist, 2048 - jge @F - mov perpWallDist, 2048 -@@: - mov eax, col - mov edx, perpWallDist - mov [zBuffer + eax*4], edx - - ; Unit projection is shared by indoor room height and outdoor storeys. - mov eax, SCREEN_H - imul eax, FP_1 - cdq - idiv perpWallDist - mov lineH, eax - - mov eax, lineH - imul viewEye3D - shrd eax, edx, 16 - add eax, viewHorizon3D - mov drawEnd, eax - mov ebx, lineH - mov eax, viewCeiling3D - cmp outdoorRender3D, 0 - je @F - mov eax, CITY_STOREY_HEIGHT -@@: - imul ebx - shrd eax, edx, 16 - mov ebx, eax - mov lineH, ebx - mov eax, drawEnd - sub eax, ebx - mov drawStart, eax - cmp outdoorRender3D, 0 - je wall_store_original_start - ; Floor height is independent of storey height. - mov eax, drawEnd - sub eax, lineH - mov drawStart, eax - mov eax, mapY - shl eax, 5 - add eax, mapX - mov edx, worldMap3D - movzx eax, BYTE PTR [edx+eax] -wall_exterior_tall: - ; Roof projection and texture sampling use the same storey count. - mov eax, lineH - imul eax, CITY_BUILDING_STOREYS-1 - sub drawStart, eax - mov eax, lineH - imul eax, CITY_BUILDING_STOREYS - mov lineH, eax -wall_store_original_start: - mov eax, drawStart - mov originalStart, eax - - cmp side, 0 - jne hit_side_y - mov eax, perpWallDist - imul rayDirY - shrd eax, edx, 16 - add eax, playerY - mov wallHit, eax - jmp calc_tex_x -hit_side_y: - mov eax, perpWallDist - imul rayDirX - shrd eax, edx, 16 - add eax, playerX - mov wallHit, eax - -calc_tex_x: - ; MASK WITH 0FFFFh to prevent texture scrambling! - mov eax, wallHit - and eax, 0FFFFh - mov texXHD, eax - shr eax, 9 - and eax, 127 - mov texX, eax - - cmp side, 0 - jne @F - cmp rayDirX, 0 - jle @F - mov eax, 127 - sub eax, texX - mov texX, eax - xor texXHD, 0FFFFh -@@: - cmp side, 1 - jne select_tex - cmp rayDirY, 0 - jge select_tex - mov eax, 127 - sub eax, texX - mov texX, eax - xor texXHD, 0FFFFh - -select_tex: - mov eax, mapY - shl eax, 5 - add eax, mapX - mov edx, worldMap3D - movzx eax, BYTE PTR [edx + eax] - mov texId, eax - cmp texId, 0 - jne @F - mov texId, 1 -@@: - - mov eax, perpWallDist - shr eax, 13 - mov edx, 256 - sub edx, eax - cmp edx, 75 - jge @F - mov edx, 75 -@@: - cmp side, 1 - jne @F - imul edx, 3 - shr edx, 2 -@@: - mov shade, edx - - cmp drawStart, 0 - jge @F - mov drawStart, 0 -@@: - cmp drawEnd, SCREEN_H - jl @F - mov drawEnd, SCREEN_H - 1 -@@: - - mov eax, lineH - cmp eax, 1 - jge @F - mov eax, 1 - mov lineH, eax -@@: - - mov eax, 128 * FP_1 - cdq - idiv lineH - mov esi, eax ; stepY - - mov eax, drawStart - sub eax, originalStart - imul eax, esi - mov edi, eax ; texPos - - mov ecx, drawStart -draw_stripe_loop: - cmp ecx, drawEnd - jg next_col - - mov eax, edi - shr eax, 16 - and eax, 127 - mov edx, texId - cmp outdoorRender3D, 0 - je wall_sample_material - imul eax, CITY_BUILDING_STOREYS - cmp eax, 128*(CITY_BUILDING_STOREYS-1) - jae wall_lower_storey - push eax - shr eax, 7 - add eax, mapX - add eax, mapY - xor edx, edx - mov ebx, 3 - div ebx - add edx, 65 - pop eax - and eax, 127 - jmp wall_sample_material -wall_lower_storey: - sub eax, 128*(CITY_BUILDING_STOREYS-1) -wall_sample_material: - mov pixelMaterial, edx - cmp outdoorRender3D, 0 - je wall_sample_indoor_hd - cmp hallCityDetail3D.pixels, 0 - je wall_sample_standard - cmp edx, 57 - jb wall_sample_standard - cmp edx, 72 - ja wall_sample_standard - cmp perpWallDist, 6*FP_1 - ja wall_sample_standard - ; Preserve subtexel detail near facades; retain the 128px mip at distance. - push edx - mov eax, edi - shr eax, 15 - imul eax, CITY_BUILDING_STOREYS - and eax, 255 - shl eax, 8 - mov ebx, texXHD - shr ebx, 8 - add eax, ebx - pop edx - sub edx, 57 - shl edx, 16 - add eax, edx - mov ebx, hallCityDetail3D.pixels - mov eax, [ebx+eax*4] - jmp wall_shade_pixel -wall_sample_indoor_hd: - cmp edx, 80 - jb wall_sample_standard - cmp edx, 103 - ja wall_sample_standard - mov ebx, hallRoomHD3D.pixels - cmp edx, 92 - jb wall_sample_room_hd - mov ebx, hallArchitectureHD3D.pixels - sub edx, 12 -wall_sample_room_hd: - test ebx, ebx - jz wall_sample_standard_restore - sub edx, 80 - shl edx, 18 - add ebx, edx - mov eax, edi - shr eax, 15 - and eax, 255 - shl eax, 8 - mov edx, texXHD - shr edx, 8 - add eax, edx - mov eax, [ebx+eax*4] - jmp wall_shade_pixel -wall_sample_standard_restore: - mov edx, texId - mov eax, edi - shr eax, 16 - and eax, 127 -wall_sample_standard: - shl eax, 7 - add eax, texX - - shl edx, 14 - add eax, edx - mov eax, [texturesBuffer + eax*4] - - ; Shade wall pixel -wall_shade_pixel: - mov ebx, shade - cmp outdoorRender3D, 0 - je wall_ambient_shade - push eax - push ecx - invoke IsCityEmissive3D, eax, pixelMaterial - pop ecx - test eax, eax - pop eax - jz wall_ambient_shade - mov ebx, 256 -wall_ambient_shade: - cmp hallLevel3D, 0 - je @F - imul ebx, 7 - shr ebx, 3 -@@: - movzx edx, al - imul edx, ebx - shr edx, 8 - push edx - - movzx edx, ah - imul edx, ebx - shr edx, 8 - shl edx, 8 - - shr eax, 16 - movzx eax, al - imul eax, ebx - shr eax, 8 - shl eax, 16 - or eax, edx - pop edx - or eax, edx - - mov edx, ecx - imul edx, SCREEN_W - add edx, col - mov [screenBuffer + edx*4], eax - - add edi, esi - inc ecx - jmp draw_stripe_loop - -next_col: - inc col - jmp col_loop - -walls_done: - pop edi - pop esi - pop ebx - ret -RenderWalls ENDP - -; --- Render 3D Billboard Sprites --- - -; --- HUD & Minimap Radar --- -RenderHUD PROC uses ebx esi edi - invoke DrawBox, 0, 0, 320, 16, 0014191Dh - invoke DrawString8x8, 8, 4, OFFSET textBank3D, 00D8BC6Ah - invoke FormatNumber, bankroll, OFFSET hudNumBuffer - invoke DrawString8x8, 64, 4, OFFSET hudNumBuffer, 00FFFFFFh - invoke DrawString8x8, 176, 4, OFFSET textWindowKeys3D, 00A8B6BBh - invoke DrawBox, 0, 226, 320, 14, 0014191Dh - invoke DrawString8x8, 12, 230, OFFSET textWalkKeys3D, 00A8B6BBh - invoke DrawBox, 159, 118, 2, 5, 00E7DFC8h - invoke DrawBox, 157, 120, 6, 1, 00E7DFC8h - cmp interactPromptPtr, 0 - je @F - invoke DrawBoxBorder, 4, 199, 312, 18, 0014191Dh, 00D8BC6Ah, 1 - invoke DrawString8x8, 10, 204, interactPromptPtr, 00F5E2B0h -@@: - cmp flashTimer, 0 - je hud_finished - dec flashTimer - invoke DrawBox, 4, 22, 312, 16, 0014191Dh - invoke DrawString8x8, 10, 26, OFFSET flashMessage, 00FFFFFFh -hud_finished: - ret -RenderHUD ENDP - -RenderMinimap PROC uses ebx esi edi - local radarX:DWORD - local radarY:DWORD - local radarSize:DWORD - - mov radarX, 320 - 48 - mov radarY, 20 - mov radarSize, 44 - - invoke DrawBoxBorder, radarX, radarY, radarSize, radarSize, 00101510h, 00FFD700h, 1 - - ; Draw Sprites on radar - cmp hallLevel3D, 0 - jne draw_player_radar - xor esi, esi -radar_spr_loop: - cmp esi, NUM_SPRITES - jge draw_player_radar - mov eax, esi - imul eax, SIZEOF SpriteObject - mov eax, [casinoSprites + eax].posX - sar eax, 16 - imul eax, radarSize - shr eax, 5 - add eax, radarX - mov ebx, eax - - mov eax, esi - imul eax, SIZEOF SpriteObject - mov eax, [casinoSprites + eax].posY - sar eax, 16 - imul eax, radarSize - shr eax, 5 - add eax, radarY - - invoke DrawPixel, ebx, eax, 00FFAA00h - inc esi - jmp radar_spr_loop - -draw_player_radar: - mov eax, playerX - sar eax, 16 - imul eax, radarSize - shr eax, 5 - add eax, radarX - mov ebx, eax - - mov eax, playerY - sar eax, 16 - imul eax, radarSize - shr eax, 5 - add eax, radarY - - invoke DrawCircle, ebx, eax, 2, 00FF2020h - ret -RenderMinimap ENDP - -; ============================================================================== -; IN-ENGINE 2.5D MINI-GAME: SLOTS 777 -; ============================================================================== -HandleSlotsInput PROC - cmp slotSpinState, 1 - je slots_input_done - - invoke Pressed3D, 20h ; SPACE -> Spin - test ah, 80h - jz check_bet_adjust - mov eax, bankroll - cmp eax, slotBet - jl @F - sub eax, slotBet - mov bankroll, eax - mov slotSpinState, 1 - mov slotSpinTimer, 0 - mov slotWinAmount, 0 - invoke PlayCasinoSound3D, OFFSET soundSlotSpin, 0, 1 - jmp slots_input_done -@@: - invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage - mov flashTimer, 60 - -check_bet_adjust: - invoke Pressed3D, 26h ; UP / W - test ah, 80h - jnz inc_bet - invoke Pressed3D, 57h - test ah, 80h - jz check_bet_down -inc_bet: - cmp slotBet, 500 - jge slots_input_done - cmp slotBet, 100 - jge @F - cmp slotBet, 50 - jge set_100 - mov slotBet, 50 - jmp slots_input_done -set_100: - mov slotBet, 100 - jmp slots_input_done -@@: - mov slotBet, 500 - jmp slots_input_done - -check_bet_down: - invoke Pressed3D, 28h ; DOWN / S - test ah, 80h - jnz dec_bet - invoke Pressed3D, 53h - test ah, 80h - jz slots_input_done -dec_bet: - cmp slotBet, 50 - jle set_10 - cmp slotBet, 100 - jle set_50 - mov slotBet, 100 - jmp slots_input_done -set_50: - mov slotBet, 50 - jmp slots_input_done -set_10: - mov slotBet, 10 - -slots_input_done: - ret -HandleSlotsInput ENDP - -RenderSlotsGame PROC uses ebx esi edi - ; Cabinet Background (Dark Cherry Wood & Gold) - invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00150A10h - invoke DrawBoxBorder, 10, 10, 300, 220, 00251015h, 00FFD700h, 3 - - ; Illuminated Top Marquee - invoke DrawBoxBorder, 25, 20, 270, 32, 000A0505h, 00FFFF00h, 2 - invoke DrawString8x8, 55, 32, OFFSET textSlots3D, 00FFD700h - - ; Spinning Animation Logic - cmp slotSpinState, 1 - jne draw_reels - inc slotSpinTimer - - cmp slotSpinTimer, 22 - jge @F - invoke RandomRange3D, 7 - mov slotReel1, eax -@@: - cmp slotSpinTimer, 36 - jge @F - invoke RandomRange3D, 7 - mov slotReel2, eax -@@: - cmp slotSpinTimer, 50 - jge @F - invoke RandomRange3D, 7 - mov slotReel3, eax -@@: - cmp slotSpinTimer, 50 - jl draw_reels - - ; Spin finished! Check outcome! - mov slotSpinState, 0 - mov eax, slotReel1 - cmp eax, slotReel2 - jne check_pairs - cmp eax, slotReel3 - jne check_pairs - - ; 3 Matching! - cmp eax, 0 ; 777! - jne @F - mov eax, slotBet - imul eax, 25 - mov slotWinAmount, eax - add bankroll, eax - invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1 - jmp draw_reels -@@: - cmp eax, 6 ; CROWN! - jne @F - mov eax, slotBet - imul eax, 50 - mov slotWinAmount, eax - add bankroll, eax - invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1 - jmp draw_reels -@@: - mov eax, slotBet - imul eax, 10 - mov slotWinAmount, eax - add bankroll, eax - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - jmp draw_reels - -check_pairs: - mov eax, slotReel1 - cmp eax, slotReel2 - je pair_win - mov eax, slotReel2 - cmp eax, slotReel3 - je pair_win - mov eax, slotReel1 - cmp eax, slotReel3 - je pair_win - jmp draw_reels -pair_win: - mov eax, slotBet - imul eax, 2 - mov slotWinAmount, eax - add bankroll, eax - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - -draw_reels: - ; Reels Window - invoke DrawBoxBorder, 30, 62, 260, 95, 000F0F12h, 0000A5FFh, 2 - - ; Reel 1 (45..105) - invoke DrawBoxBorder, 45, 68, 65, 82, 00F0F0F5h, 00505050h, 2 - mov eax, slotReel1 - call DrawReelSymbolAt1 - - ; Reel 2 (128..188) - invoke DrawBoxBorder, 128, 68, 65, 82, 00F0F0F5h, 00505050h, 2 - mov eax, slotReel2 - call DrawReelSymbolAt2 - - ; Reel 3 (210..270) - invoke DrawBoxBorder, 210, 68, 65, 82, 00F0F0F5h, 00505050h, 2 - mov eax, slotReel3 - call DrawReelSymbolAt3 - - ; Bottom Control Panel - invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 00FFD700h, 1 - - invoke DrawString8x8, 28, 172, OFFSET textBank3D, 00FFD700h - invoke FormatNumber, bankroll, OFFSET hudNumBuffer - invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 00FFFF00h - - invoke DrawString8x8, 175, 172, OFFSET textBet3D, 00FFD700h - invoke FormatNumber, slotBet, OFFSET hudNumBuffer - invoke DrawString8x8, 240, 172, OFFSET hudNumBuffer, 0050FF50h - - cmp slotWinAmount, 0 - jle draw_slot_ctrls - invoke DrawString8x8, 28, 187, OFFSET strWin, 00FFFF00h - invoke FormatNumber, slotWinAmount, OFFSET hudNumBuffer - invoke DrawString8x8, 110, 187, OFFSET hudNumBuffer, 00FFFF00h - -draw_slot_ctrls: - invoke DrawString8x8, 28, 204, OFFSET textSlotsKeys3D, 00A0A0A0h - ret -RenderSlotsGame ENDP - -DrawReelSymbolAt1 PROC - cmp eax, 0 - jne @F - invoke DrawString8x8, 52, 105, OFFSET sym7, 00FF2020h - ret -@@: - cmp eax, 1 - jne @F - invoke DrawString8x8, 52, 105, OFFSET symBar, 00FFAA00h - ret -@@: - cmp eax, 2 - jne @F - invoke DrawString8x8, 52, 105, OFFSET symBell, 00FFD700h - ret -@@: - cmp eax, 3 - jne @F - invoke DrawString8x8, 48, 105, OFFSET symCherry, 000000D0h - ret -@@: - cmp eax, 4 - jne @F - invoke DrawString8x8, 48, 105, OFFSET symClover, 0000A000h - ret -@@: - cmp eax, 5 - jne @F - invoke DrawString8x8, 52, 105, OFFSET symGem, 00FFFF00h - ret -@@: - invoke DrawString8x8, 52, 105, OFFSET symCrown, 00FFD700h - ret -DrawReelSymbolAt1 ENDP - -DrawReelSymbolAt2 PROC - cmp eax, 0 - jne @F - invoke DrawString8x8, 135, 105, OFFSET sym7, 00FF2020h - ret -@@: - cmp eax, 1 - jne @F - invoke DrawString8x8, 135, 105, OFFSET symBar, 00FFAA00h - ret -@@: - cmp eax, 2 - jne @F - invoke DrawString8x8, 135, 105, OFFSET symBell, 00FFD700h - ret -@@: - cmp eax, 3 - jne @F - invoke DrawString8x8, 131, 105, OFFSET symCherry, 000000D0h - ret -@@: - cmp eax, 4 - jne @F - invoke DrawString8x8, 131, 105, OFFSET symClover, 0000A000h - ret -@@: - cmp eax, 5 - jne @F - invoke DrawString8x8, 135, 105, OFFSET symGem, 00FFFF00h - ret -@@: - invoke DrawString8x8, 135, 105, OFFSET symCrown, 00FFD700h - ret -DrawReelSymbolAt2 ENDP - -DrawReelSymbolAt3 PROC - cmp eax, 0 - jne @F - invoke DrawString8x8, 218, 105, OFFSET sym7, 00FF2020h - ret -@@: - cmp eax, 1 - jne @F - invoke DrawString8x8, 218, 105, OFFSET symBar, 00FFAA00h - ret -@@: - cmp eax, 2 - jne @F - invoke DrawString8x8, 218, 105, OFFSET symBell, 00FFD700h - ret -@@: - cmp eax, 3 - jne @F - invoke DrawString8x8, 214, 105, OFFSET symCherry, 000000D0h - ret -@@: - cmp eax, 4 - jne @F - invoke DrawString8x8, 214, 105, OFFSET symClover, 0000A000h - ret -@@: - cmp eax, 5 - jne @F - invoke DrawString8x8, 218, 105, OFFSET symGem, 00FFFF00h - ret -@@: - invoke DrawString8x8, 218, 105, OFFSET symCrown, 00FFD700h - ret -DrawReelSymbolAt3 ENDP - -; ============================================================================== -; IN-ENGINE 2.5D MINI-GAME: BLACKJACK (21) -; ============================================================================== -HandleBlackjackInput PROC uses ebx - cmp bjState, 0 ; Need Deal - jne check_bj_player_turn - invoke Pressed3D, 20h ; SPACE -> Deal - test ah, 80h - jz check_bj_bet_change - mov eax, bankroll - cmp eax, bjBet - jl bj_need_cash - sub eax, bjBet - mov bankroll, eax - - ; Deal 2 cards to player, 2 cards to dealer - mov bjPlayerCardCount, 0 - mov bjDealerCardCount, 0 - mov bjDealerHideHole, 1 - - ; Player Card 1 - invoke RandomRange3D, 13 - inc eax - mov ebx, bjPlayerCardCount - mov [bjPlayerCards + ebx*4], eax - inc bjPlayerCardCount - - ; Dealer Card 1 - invoke RandomRange3D, 13 - inc eax - mov ebx, bjDealerCardCount - mov [bjDealerCards + ebx*4], eax - inc bjDealerCardCount - - ; Player Card 2 - invoke RandomRange3D, 13 - inc eax - mov ebx, bjPlayerCardCount - mov [bjPlayerCards + ebx*4], eax - inc bjPlayerCardCount - - ; Dealer Card 2 (Hole card) - invoke RandomRange3D, 13 - inc eax - mov ebx, bjDealerCardCount - mov [bjDealerCards + ebx*4], eax - inc bjDealerCardCount - - invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1 - - ; Calc Player Score - call CalcPlayerBJScore - cmp bjPlayerScore, 21 - jne set_bj_turn - ; Instant Blackjack! - mov bjDealerHideHole, 0 - mov eax, bjBet - imul eax, 5 - shr eax, 1 - add bankroll, eax - invoke CopyString3D, OFFSET strWin, OFFSET bjOutcomeMsg - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - mov bjState, 2 - ret -set_bj_turn: - mov bjState, 1 - mov BYTE PTR [bjOutcomeMsg], 0 - ret - -bj_need_cash: - invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage - mov flashTimer, 60 - ret - -check_bj_player_turn: - cmp bjState, 1 - jne check_bj_round_over - - invoke Pressed3D, 48h ; 'H' -> Hit - test ah, 80h - jz check_bj_stand - invoke RandomRange3D, 13 - inc eax - mov ebx, bjPlayerCardCount - cmp ebx, 8 - jge @F - mov [bjPlayerCards + ebx*4], eax - inc bjPlayerCardCount -@@: - invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1 - call CalcPlayerBJScore - cmp bjPlayerScore, 21 - jle bj_input_done - ; Bust! - invoke CopyString3D, OFFSET strPlayerBust, OFFSET bjOutcomeMsg - mov bjDealerHideHole, 0 - mov bjState, 2 - ret - -check_bj_stand: - invoke Pressed3D, 53h ; 'S' -> Stand - test ah, 80h - jz bj_input_done - - ; Dealer Turn - mov bjDealerHideHole, 0 -dealer_loop: - call CalcDealerBJScore - cmp bjDealerScore, 17 - jge dealer_finished - invoke RandomRange3D, 13 - inc eax - mov ebx, bjDealerCardCount - cmp ebx, 8 - jge dealer_finished - mov [bjDealerCards + ebx*4], eax - inc bjDealerCardCount - jmp dealer_loop - -dealer_finished: - cmp bjDealerScore, 21 - jle compare_scores - ; Dealer Bust! - mov eax, bjBet - shl eax, 1 - add bankroll, eax - invoke CopyString3D, OFFSET strDealerBust, OFFSET bjOutcomeMsg - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - mov bjState, 2 - ret - -compare_scores: - mov eax, bjPlayerScore - cmp eax, bjDealerScore - jle check_dealer_won - ; Player Won! - mov eax, bjBet - shl eax, 1 - add bankroll, eax - invoke CopyString3D, OFFSET strWin, OFFSET bjOutcomeMsg - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - mov bjState, 2 - ret -check_dealer_won: - cmp eax, bjDealerScore - jl dealer_wins - ; Push (Tie) - mov eax, bjBet - add bankroll, eax - invoke CopyString3D, OFFSET strPush, OFFSET bjOutcomeMsg - mov bjState, 2 - ret -dealer_wins: - invoke CopyString3D, OFFSET strLose, OFFSET bjOutcomeMsg - mov bjState, 2 - ret - -check_bj_round_over: - invoke Pressed3D, 20h ; SPACE -> Next Hand - test ah, 80h - jz bj_input_done - mov bjState, 0 - ret - -check_bj_bet_change: - invoke Pressed3D, 26h ; UP - test ah, 80h - jz @F - cmp bjBet, 500 - jge bj_input_done - add bjBet, 50 - ret -@@: - invoke Pressed3D, 28h ; DOWN - test ah, 80h - jz bj_input_done - cmp bjBet, 50 - jle bj_input_done - sub bjBet, 50 - -bj_input_done: - ret -HandleBlackjackInput ENDP - -CalcPlayerBJScore PROC uses ebx esi - xor eax, eax - xor ebx, ebx - xor esi, esi -calc_p_loop: - cmp esi, bjPlayerCardCount - jge calc_p_done - mov edx, [bjPlayerCards + esi*4] - cmp edx, 10 - jle @F - mov edx, 10 -@@: - cmp edx, 1 - jne add_p_val - inc ebx ; count Aces - add eax, 11 - jmp next_p_card -add_p_val: - add eax, edx -next_p_card: - inc esi - jmp calc_p_loop -calc_p_done: - ; Soft Ace reduction -reduce_p_ace: - cmp eax, 21 - jle store_p_score - test ebx, ebx - jz store_p_score - sub eax, 10 - dec ebx - jmp reduce_p_ace -store_p_score: - mov bjPlayerScore, eax - ret -CalcPlayerBJScore ENDP - -CalcDealerBJScore PROC uses ebx esi - xor eax, eax - xor ebx, ebx - xor esi, esi -calc_d_loop: - cmp esi, bjDealerCardCount - jge calc_d_done - mov edx, [bjDealerCards + esi*4] - cmp edx, 10 - jle @F - mov edx, 10 -@@: - cmp edx, 1 - jne add_d_val - inc ebx - add eax, 11 - jmp next_d_card -add_d_val: - add eax, edx -next_d_card: - inc esi - jmp calc_d_loop -calc_d_done: -reduce_d_ace: - cmp eax, 21 - jle store_d_score - test ebx, ebx - jz store_d_score - sub eax, 10 - dec ebx - jmp reduce_d_ace -store_d_score: - mov bjDealerScore, eax - ret -CalcDealerBJScore ENDP - -RenderBlackjackGame PROC uses ebx esi edi - ; Emerald Felt Table Background - invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 000A3015h - invoke DrawBoxBorder, 10, 10, 300, 220, 000D4018h, 00FFD700h, 3 - - ; Dealer Area Top - invoke DrawString8x8, 25, 20, OFFSET textBJ3D, 00FFD700h - invoke DrawString8x8, 25, 35, OFFSET textDealer3D, 00FFFFFFh - invoke FormatNumber, bjDealerScore, OFFSET hudNumBuffer - invoke DrawString8x8, 120, 35, OFFSET hudNumBuffer, 00FFFF00h - - ; Dealer Cards - xor esi, esi -draw_dealer_cards: - cmp esi, bjDealerCardCount - jge draw_player_bj_area - mov eax, esi - imul eax, 45 - add eax, 25 - mov ebx, eax - - cmp esi, 1 - jne draw_dealer_face - cmp bjDealerHideHole, 1 - jne draw_dealer_face - ; Face Down Card - mov eax, selectedBack3D - mov eax, cardBackColors3D[eax*4] - invoke DrawBoxBorder, ebx, 48, 38, 52, eax, 00FFFFFFh, 2 - jmp next_dealer_card_draw - -draw_dealer_face: - invoke DrawBoxBorder, ebx, 48, 38, 52, 00F0F0F5h, 00000000h, 2 - mov eax, [bjDealerCards + esi*4] - dec eax - imul eax, 3 - lea edx, [cardRankStr + eax] - mov eax, ebx - add eax, 8 - invoke DrawString8x8, eax, 68, edx, 00000000h - -next_dealer_card_draw: - inc esi - jmp draw_dealer_cards - -draw_player_bj_area: - ; Player Area Bottom - invoke DrawString8x8, 25, 110, OFFSET textPlayer3D, 00FFFFFFh - invoke FormatNumber, bjPlayerScore, OFFSET hudNumBuffer - invoke DrawString8x8, 120, 110, OFFSET hudNumBuffer, 0050FF50h - - ; Player Cards - xor esi, esi -draw_player_cards: - cmp esi, bjPlayerCardCount - jge draw_bj_footer - mov eax, esi - imul eax, 45 - add eax, 25 - mov ebx, eax - - invoke DrawBoxBorder, ebx, 124, 38, 52, 00F0F0F5h, 00000000h, 2 - mov eax, [bjPlayerCards + esi*4] - dec eax - imul eax, 3 - lea edx, [cardRankStr + eax] - mov eax, ebx - add eax, 8 - invoke DrawString8x8, eax, 144, edx, 00000000h - - inc esi - jmp draw_player_cards - -draw_bj_footer: - ; Footer Status & Controls - invoke DrawBoxBorder, 20, 182, 280, 42, 00102010h, 00FFD700h, 1 - cmp BYTE PTR [bjOutcomeMsg], 0 - je draw_bj_controls - invoke DrawString8x8, 28, 188, OFFSET bjOutcomeMsg, 00FFFF00h - invoke DrawString8x8, 28, 204, OFFSET textNext3D, 00A0A0A0h - ret - -draw_bj_controls: - invoke DrawString8x8, 28, 188, OFFSET textBJKeys3D, 00FFFFFFh - invoke DrawString8x8, 28, 204, OFFSET textDeal3D, 00A0A0A0h - ret -RenderBlackjackGame ENDP - -; ============================================================================== -; IN-ENGINE 2.5D MINI-GAME: ROULETTE -; ============================================================================== -HandleRouletteInput PROC uses ebx - cmp roulState, 1 - je roul_input_done - - invoke Pressed3D, 31h ; '1' -> RED - test ah, 80h - jz @F - mov roulBetType, 1 -@@: - invoke Pressed3D, 32h ; '2' -> BLACK - test ah, 80h - jz @F - mov roulBetType, 2 -@@: - invoke Pressed3D, 33h ; '3' -> ZERO (0) - test ah, 80h - jz @F - mov roulBetType, 3 -@@: - invoke Pressed3D, 34h ; '4' -> EVEN - test ah, 80h - jz @F - mov roulBetType, 4 -@@: - invoke Pressed3D, 35h ; '5' -> ODD - test ah, 80h - jz check_roul_spin - mov roulBetType, 5 - -check_roul_spin: - invoke Pressed3D, 20h ; SPACE -> Spin - test ah, 80h - jz roul_input_done - mov eax, bankroll - cmp eax, roulBetAmount - jl roul_no_cash - sub eax, roulBetAmount - mov bankroll, eax - mov roulState, 1 - mov roulSpinTimer, 50 - mov roulPayout, 0 - invoke PlayCasinoSound3D, OFFSET soundRoulette, 0, 1 - ret - -roul_no_cash: - invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage - mov flashTimer, 60 - -roul_input_done: - ret -HandleRouletteInput ENDP - -RenderRouletteGame PROC uses ebx esi edi - ; Table felt background - invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00151525h - invoke DrawBoxBorder, 10, 10, 300, 220, 00201525h, 00FFD700h, 3 - - ; 2.5D Rotating Wheel on Left - invoke DrawCircle, 85, 110, 65, 00102550h - invoke DrawCircle, 85, 110, 60, 00FFD700h - invoke DrawCircle, 85, 110, 52, 00101010h - invoke DrawCircle, 85, 110, 22, 00FFD700h ; Center brass turret - - ; Spinning Wheel / Ball Logic - cmp roulState, 1 - jne draw_roul_ball - dec roulSpinTimer - add roulWheelAngle, 8 - sub roulBallAngle, 14 - cmp roulSpinTimer, 0 - jg draw_roul_ball - - ; Wheel stopped! Determine result! - mov roulState, 2 - invoke RandomRange3D, 37 - mov roulWinningNum, eax - - ; Check bet - cmp roulBetType, 1 ; RED - jne check_ro_black - call IsNumberRed - test eax, eax - jz ro_lost - mov eax, roulBetAmount - shl eax, 1 - mov roulPayout, eax - add bankroll, eax - invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - jmp draw_roul_ball - -check_ro_black: - cmp roulBetType, 2 ; BLACK - jne check_ro_zero - cmp roulWinningNum, 0 - je ro_lost - call IsNumberRed - test eax, eax - jnz ro_lost - mov eax, roulBetAmount - shl eax, 1 - mov roulPayout, eax - add bankroll, eax - invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - jmp draw_roul_ball - -check_ro_zero: - cmp roulBetType, 3 ; ZERO - jne check_ro_even - cmp roulWinningNum, 0 - jne ro_lost - mov eax, roulBetAmount - imul eax, 36 - mov roulPayout, eax - add bankroll, eax - invoke CopyString3D, OFFSET strJackpot, OFFSET roulOutcomeMsg - invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1 - jmp draw_roul_ball - -check_ro_even: - cmp roulBetType, 4 ; EVEN - jne check_ro_odd - mov eax, roulWinningNum - test eax, eax - jz ro_lost - test al, 1 - jnz ro_lost - mov eax, roulBetAmount - shl eax, 1 - mov roulPayout, eax - add bankroll, eax - invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - jmp draw_roul_ball - -check_ro_odd: - mov eax, roulWinningNum - test eax, eax - jz ro_lost - test al, 1 - jz ro_lost - mov eax, roulBetAmount - shl eax, 1 - mov roulPayout, eax - add bankroll, eax - invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - jmp draw_roul_ball - -ro_lost: - invoke CopyString3D, OFFSET strLose, OFFSET roulOutcomeMsg - -draw_roul_ball: - ; Draw White Ball on Rim - mov eax, roulBallAngle - and eax, 511 - mov ebx, [tableCos + eax*4] - imul ebx, 42 - sar ebx, 16 - add ebx, 85 - - mov eax, roulBallAngle - and eax, 511 - mov edx, [tableSin + eax*4] - imul edx, 42 - sar edx, 16 - add edx, 110 - invoke DrawCircle, ebx, edx, 3, 00FFFFFFh - - ; Right Betting Board - invoke DrawBoxBorder, 175, 25, 125, 28, 001010C0h, 00FFFFFFh, 2 ; [1] RED - invoke DrawString8x8, 190, 35, OFFSET textRed3D, 00FFFFFFh - - invoke DrawBoxBorder, 175, 60, 125, 28, 00151515h, 00FFFFFFh, 2 ; [2] BLACK - invoke DrawString8x8, 190, 70, OFFSET textBlack3D, 00FFFFFFh - - invoke DrawBoxBorder, 175, 95, 125, 28, 00106010h, 00FFFFFFh, 2 ; [3] ZERO - invoke DrawString8x8, 190, 105, OFFSET textZero3D, 00FFFFFFh - - invoke DrawBoxBorder, 175, 130, 60, 26, 00302020h, 00FFFFFFh, 1 ; [4] EVEN - invoke DrawString8x8, 185, 139, OFFSET textEven3D, 00FFFFFFh - - invoke DrawBoxBorder, 240, 130, 60, 26, 00302020h, 00FFFFFFh, 1 ; [5] ODD - invoke DrawString8x8, 250, 139, OFFSET textOdd3D, 00FFFFFFh - - ; Highlight Active Bet - cmp roulBetType, 1 - jne @F - invoke DrawBoxBorder, 173, 23, 129, 32, 0, 00FFFF00h, 2 -@@: - cmp roulBetType, 2 - jne @F - invoke DrawBoxBorder, 173, 58, 129, 32, 0, 00FFFF00h, 2 -@@: - cmp roulBetType, 3 - jne @F - invoke DrawBoxBorder, 173, 93, 129, 32, 0, 00FFFF00h, 2 -@@: - cmp roulBetType, 4 - jne @F - invoke DrawBoxBorder, 173, 128, 64, 30, 0, 00FFFF00h, 2 -@@: - cmp roulBetType, 5 - jne draw_ro_footer - invoke DrawBoxBorder, 238, 128, 64, 30, 0, 00FFFF00h, 2 - -draw_ro_footer: - invoke DrawBoxBorder, 20, 180, 280, 42, 00101015h, 00FFD700h, 1 - - cmp roulState, 2 - jne @F - invoke DrawString8x8, 28, 186, OFFSET textResult3D, 00FFD700h - invoke FormatNumber, roulWinningNum, OFFSET hudNumBuffer - invoke DrawString8x8, 85, 186, OFFSET hudNumBuffer, 00FFFF00h - invoke DrawString8x8, 130, 186, OFFSET roulOutcomeMsg, 0050FF50h -@@: - invoke DrawString8x8, 28, 202, OFFSET textSpin3D, 00A0A0A0h - ret -RenderRouletteGame ENDP - -IsNumberRed PROC - mov eax, roulWinningNum - cmp eax, 1 - je red_yes - cmp eax, 3 - je red_yes - cmp eax, 5 - je red_yes - cmp eax, 7 - je red_yes - cmp eax, 9 - je red_yes - cmp eax, 12 - je red_yes - cmp eax, 14 - je red_yes - cmp eax, 16 - je red_yes - cmp eax, 18 - je red_yes - cmp eax, 19 - je red_yes - cmp eax, 21 - je red_yes - cmp eax, 23 - je red_yes - cmp eax, 25 - je red_yes - cmp eax, 27 - je red_yes - cmp eax, 30 - je red_yes - cmp eax, 32 - je red_yes - cmp eax, 34 - je red_yes - cmp eax, 36 - je red_yes - xor eax, eax - ret -red_yes: - mov eax, 1 - ret -IsNumberRed ENDP - -; ============================================================================== -; IN-ENGINE 2.5D MINI-GAME: BAR & SHOP -; ============================================================================== -HandleShopInput PROC uses ebx esi - xor esi, esi -shop_choice: - inc esi - lea eax, [esi+30h] - invoke Pressed3D, eax - test eax, eax - jnz shop_chosen - cmp esi, 3 - jb shop_choice - ret -shop_chosen: - bt ownedBacks3D, esi - jc shop_equip - mov ebx, 1500 - cmp esi, 1 - jne @F - mov ebx, 1000 -@@: - cmp bankroll, ebx - jb shop_no_money - sub bankroll, ebx - bts ownedBacks3D, esi -shop_equip: - mov selectedBack3D, esi - invoke CopyString3D, OFFSET textBought3D, OFFSET shopMsg - call SaveProgress3D - ret -shop_no_money: - invoke CopyString3D, OFFSET textNoCash3D, OFFSET shopMsg - ret -HandleShopInput ENDP - -RenderShopGame PROC - invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00150A0Ah - invoke DrawBoxBorder, 10, 10, 300, 220, 00251515h, 00FFD700h, 3 - invoke DrawString8x8, 25, 20, OFFSET textShop3D, 00FFD700h - - invoke DrawBoxBorder, 20, 40, 280, 32, 001A1010h, 00FFFFFFh, 1 - invoke DrawString8x8, 28, 46, OFFSET textItem1_3D, 00FFFF00h - invoke DrawString8x8, 28, 58, OFFSET textShopHint3D, 00A0A0A0h - - invoke DrawBoxBorder, 20, 80, 280, 32, 001A1010h, 00FFFFFFh, 1 - invoke DrawString8x8, 28, 86, OFFSET textItem2_3D, 00FFFF00h - invoke DrawString8x8, 28, 98, OFFSET textShopHint3D, 00A0A0A0h - - invoke DrawBoxBorder, 20, 120, 280, 32, 001A1010h, 00FFFFFFh, 1 - invoke DrawString8x8, 28, 126, OFFSET textItem3_3D, 00FFFF00h - invoke DrawString8x8, 28, 138, OFFSET textShopHint3D, 00A0A0A0h - - invoke DrawBoxBorder, 20, 165, 280, 55, 00100A0Ah, 00FFD700h, 1 - invoke DrawString8x8, 28, 172, OFFSET textBank3D, 00FFD700h - invoke FormatNumber, bankroll, OFFSET hudNumBuffer - invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 00FFFF00h - - cmp BYTE PTR [shopMsg], 0 - je @F - invoke DrawString8x8, 28, 188, OFFSET shopMsg, 0050FF50h -@@: - invoke DrawString8x8, 28, 204, OFFSET textBack3D, 00A0A0A0h - ret -RenderShopGame ENDP - -; ============================================================================== -; IN-ENGINE 2.5D MINI-GAME: ATM TERMINAL -; ============================================================================== -HandleATMInput PROC - ret -HandleATMInput ENDP - -RenderATMGame PROC - invoke DrawBox, 0, 0, 320, 240, 00172120h - invoke DrawString8x8, 24, 30, OFFSET textATM3D, 00D8BC6Ah - invoke DrawString8x8, 24, 70, OFFSET textBank3D, 00FFFFFFh - invoke FormatNumber, bankroll, OFFSET hudNumBuffer - invoke DrawString8x8, 96, 70, OFFSET hudNumBuffer, 0089DAB2h - invoke DrawString8x8, 24, 115, OFFSET textATMNote3D, 00B7C8C1h - invoke DrawString8x8, 24, 140, OFFSET textATMNote2_3D, 00B7C8C1h - invoke DrawString8x8, 24, 208, OFFSET textBack3D, 00D8BC6Ah - ret -RenderATMGame ENDP - -; ============================================================================== -; ============================================================================== -; ============================================================================== -; SHARED RICH UI PROCEDURES -; ============================================================================== -DrawKeycap3D PROC uses ebx esi edi, x:DWORD, y:DWORD, strPtr:DWORD, isActive:DWORD - local keyW:DWORD - mov esi, strPtr - xor ecx, ecx -keycap_len: - mov al, [esi+ecx] - test al, al - jz keycap_len_done - inc ecx - jmp keycap_len -keycap_len_done: - shl ecx, 3 - add ecx, 8 - mov keyW, ecx - - ; Drop shadow - mov eax, y - add eax, 2 - invoke DrawBox, x, eax, keyW, 13, 0008080Ch - - ; Border and Fill - cmp isActive, 0 - je keycap_inactive - mov eax, 00FFFF00h ; Bright Yellow active border - mov edx, 001B4B22h ; Casino Green active fill - mov ebx, 00FFFF00h ; Bright Yellow active text - jmp keycap_draw_box -keycap_inactive: - mov eax, 00606870h ; Slate inactive border - mov edx, 001A1C22h ; Charcoal inactive fill - mov ebx, 00D0D8E0h ; Silver inactive text - -keycap_draw_box: - push ebx - invoke DrawBoxBorder, x, y, keyW, 13, edx, eax, 1 - pop ebx - - ; Text label - mov eax, x - add eax, 4 - mov edx, y - add edx, 3 - invoke DrawString8x8, eax, edx, strPtr, ebx - - mov eax, keyW - add eax, 4 - ret -DrawKeycap3D ENDP - -DrawChipStack PROC uses ebx esi edi, x:DWORD, y:DWORD, chipCount:DWORD - mov edi, chipCount - xor esi, esi -chip_loop: - cmp esi, edi - jge chip_done - mov eax, esi - shl eax, 2 - mov edx, y - sub edx, eax - - ; Shadow - mov eax, x - add eax, 2 - mov ecx, edx - add ecx, 5 - invoke DrawBox, eax, ecx, 20, 2, 00061004h - - ; Red Clay Chip body with white rim - invoke DrawBoxBorder, x, edx, 24, 6, 00B81515h, 00FFFFFFh, 1 - - ; White stripe inlays - mov eax, x - add eax, 4 - mov ecx, edx - add ecx, 1 - invoke DrawBox, eax, ecx, 3, 4, 00FFFFFFh - - mov eax, x - add eax, 17 - mov ecx, edx - add ecx, 1 - invoke DrawBox, eax, ecx, 3, 4, 00FFFFFFh - - inc esi - jmp chip_loop -chip_done: - ret -DrawChipStack ENDP - -DrawDetailedCoin PROC uses ebx esi edi, cxVal:DWORD, cyVal:DWORD, rxVal:DWORD, ryVal:DWORD, outerColor:DWORD, innerColor:DWORD, reliefType:DWORD - local rxSq:DWORD - local rySq:DWORD - local rxRySq:DWORD - local threshSq:DWORD - local curDy:DWORD - local curDx:DWORD - local curX:DWORD - local curY:DWORD - - mov eax, rxVal - cmp eax, 0 - jle coin_draw_done - mov eax, ryVal - cmp eax, 0 - jle coin_draw_done - - mov eax, rxVal - imul eax, rxVal - mov rxSq, eax - - mov eax, ryVal - imul eax, ryVal - mov rySq, eax - - imul eax, rxSq - mov rxRySq, eax - - ; 3/4 threshold for rim bevel - mov ecx, 3 - imul eax, ecx - shr eax, 2 - mov threshSq, eax - - ; Scan rows - mov eax, ryVal - neg eax - mov curDy, eax -coin_row_loop: - mov eax, curDy - cmp eax, ryVal - jg coin_relief_check - - mov edx, cyVal - add edx, curDy - mov curY, edx - - ; Scan columns - mov eax, rxVal - neg eax - mov curDx, eax -coin_col_loop: - mov eax, curDx - cmp eax, rxVal - jg coin_col_next_row - - mov ecx, cxVal - add ecx, curDx - mov curX, ecx - - ; val = dx*dx*rySq + dy*dy*rxSq - mov eax, curDx - imul eax, curDx - imul eax, rySq - mov ebx, eax - - mov eax, curDy - imul eax, curDy - imul eax, rxSq - add eax, ebx - - cmp eax, rxRySq - ja coin_pixel_outside - - cmp eax, threshSq - jb coin_draw_inner - invoke DrawPixel, curX, curY, outerColor - jmp coin_pixel_outside -coin_draw_inner: - invoke DrawPixel, curX, curY, innerColor - -coin_pixel_outside: - inc curDx - jmp coin_col_loop - -coin_col_next_row: - inc curDy - jmp coin_row_loop - -coin_relief_check: - cmp rxVal, 14 - jl coin_draw_done - - cmp reliefType, 1 - je coin_draw_eagle - cmp reliefType, 2 - je coin_draw_numeral - jmp coin_draw_done - -coin_draw_eagle: - ; Imperial Eagle relief (Dark Gold 009A7A00h / Bright 00FFD700h) - mov eax, cxVal - sub eax, 3 - mov edx, cyVal - sub edx, 14 - invoke DrawBox, eax, edx, 7, 2, 009A7A00h - - mov eax, cxVal - sub eax, 4 - mov edx, cyVal - sub edx, 12 - invoke DrawBox, eax, edx, 9, 2, 009A7A00h - - mov eax, cxVal - sub eax, 2 - mov edx, cyVal - sub edx, 9 - invoke DrawBox, eax, edx, 5, 12, 009A7A00h - - mov eax, cxVal - sub eax, 1 - mov edx, cyVal - sub edx, 8 - invoke DrawBox, eax, edx, 3, 10, 00FFD700h - - mov eax, cxVal - sub eax, 10 - mov edx, cyVal - sub edx, 8 - invoke DrawBox, eax, edx, 7, 3, 009A7A00h - - mov eax, cxVal - sub eax, 13 - mov edx, cyVal - sub edx, 5 - invoke DrawBox, eax, edx, 10, 3, 009A7A00h - - mov eax, cxVal - sub eax, 11 - mov edx, cyVal - sub edx, 2 - invoke DrawBox, eax, edx, 7, 3, 009A7A00h - - mov eax, cxVal - add eax, 4 - mov edx, cyVal - sub edx, 8 - invoke DrawBox, eax, edx, 7, 3, 009A7A00h - - mov eax, cxVal - add eax, 4 - mov edx, cyVal - sub edx, 5 - invoke DrawBox, eax, edx, 10, 3, 009A7A00h - - mov eax, cxVal - add eax, 5 - mov edx, cyVal - sub edx, 2 - invoke DrawBox, eax, edx, 7, 3, 009A7A00h - - mov eax, cxVal - sub eax, 4 - mov edx, cyVal - add edx, 4 - invoke DrawBox, eax, edx, 9, 3, 009A7A00h - - mov eax, cxVal - sub eax, 3 - mov edx, cyVal - add edx, 7 - invoke DrawBox, eax, edx, 7, 3, 009A7A00h - jmp coin_draw_done - -coin_draw_numeral: - ; Roman numeral 'I' & laurel - mov eax, cxVal - sub eax, 5 - mov edx, cyVal - sub edx, 10 - invoke DrawBox, eax, edx, 11, 3, 009A7A00h - - mov eax, cxVal - sub eax, 2 - mov edx, cyVal - sub edx, 7 - invoke DrawBox, eax, edx, 5, 14, 009A7A00h - - mov eax, cxVal - sub eax, 1 - mov edx, cyVal - sub edx, 6 - invoke DrawBox, eax, edx, 3, 12, 00FFD700h - - mov eax, cxVal - sub eax, 6 - mov edx, cyVal - add edx, 7 - invoke DrawBox, eax, edx, 13, 3, 009A7A00h - - ; Laurel dots - mov eax, cxVal - sub eax, 12 - mov edx, cyVal - sub edx, 8 - invoke DrawBox, eax, edx, 2, 2, 009A7A00h - - mov eax, cxVal - add eax, 11 - mov edx, cyVal - sub edx, 8 - invoke DrawBox, eax, edx, 2, 2, 009A7A00h - - mov eax, cxVal - sub eax, 12 - mov edx, cyVal - invoke DrawBox, eax, edx, 2, 2, 009A7A00h - - mov eax, cxVal - add eax, 11 - mov edx, cyVal - invoke DrawBox, eax, edx, 2, 2, 009A7A00h - - mov eax, cxVal - sub eax, 12 - mov edx, cyVal - add edx, 8 - invoke DrawBox, eax, edx, 2, 2, 009A7A00h - - mov eax, cxVal - add eax, 11 - mov edx, cyVal - add edx, 8 - invoke DrawBox, eax, edx, 2, 2, 009A7A00h - -coin_draw_done: - ret -DrawDetailedCoin ENDP - -; ============================================================================== -; IN-ENGINE 2.5D MINI-GAME: COIN FLIP -; ============================================================================== -InitCoinGame PROC - call InitNativeCoin3D - ret -InitCoinGame ENDP - -HandleCoinInput PROC - call HandleNativeCoin3D - ret -; Retained legacy frame-count prototype, excluded from the executable. -IF 0 - cmp coin3d_state, 0 - je coin_handle_idle - cmp coin3d_state, 1 - je coin_handle_flipping - cmp coin3d_state, 2 - je coin_handle_result - ret - -coin_handle_idle: - invoke Pressed3D, 26h ; UP - test eax, eax - jnz coin_bet_up - invoke Pressed3D, 57h ; 'W' - test eax, eax - jnz coin_bet_up - invoke Pressed3D, 28h ; DOWN - test eax, eax - jnz coin_bet_down - invoke Pressed3D, 53h ; 'S' - test eax, eax - jnz coin_bet_down - invoke Pressed3D, 31h ; '1' - test eax, eax - jnz coin_pick_1 - invoke Pressed3D, 32h ; '2' - test eax, eax - jnz coin_pick_2 - invoke Pressed3D, 20h ; SPACE - test eax, eax - jnz coin_start_flip - ret - -coin_bet_up: - mov eax, coin3d_bet - add eax, 50 - cmp eax, bankroll - jle @F - mov eax, bankroll -@@: - cmp eax, 5000 - jle @F - mov eax, 5000 -@@: - mov coin3d_bet, eax - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -coin_bet_down: - mov eax, coin3d_bet - sub eax, 50 - cmp eax, 50 - jge @F - mov eax, 50 -@@: - mov coin3d_bet, eax - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -coin_pick_1: - mov coin3d_choice, 1 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -coin_pick_2: - mov coin3d_choice, 2 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -coin_start_flip: - mov eax, coin3d_bet - cmp eax, bankroll - jle @F - mov eax, bankroll - mov coin3d_bet, eax - test eax, eax - jz coin_done -@@: - mov eax, coin3d_bet - sub bankroll, eax - mov coin3d_state, 1 - mov coin3d_timer, 40 - invoke PlayCasinoSound3D, OFFSET soundCoin, 0, 1 - ret - -coin_handle_flipping: - dec coin3d_timer - cmp coin3d_timer, 0 - jg coin_done - invoke RandomRange3D, 2 - inc eax - mov coin3d_result, eax - mov edx, coin3d_choice - cmp eax, edx - jne coin_flip_lost - - ; Won! - inc coin3d_streak - mov eax, coin3d_bet - shl eax, 1 - add bankroll, eax - mov coin3d_win, eax - mov coin3d_state, 2 - invoke PlayCasinoSound3D, OFFSET soundCoinDing, 0, 1 - ret - -coin_flip_lost: - mov coin3d_streak, 0 - mov coin3d_win, 0 - mov coin3d_state, 2 - invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 - ret - -coin_handle_result: - invoke Pressed3D, 20h - test eax, eax - jz coin_done - mov coin3d_state, 0 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 -coin_done: - ret -ENDIF -HandleCoinInput ENDP - -RenderCoinGame PROC uses ebx esi edi - local cyVal:DWORD - local rxVal:DWORD - local kx:DWORD - - call RenderNativeCoin3D - ret -IF 0 - ; Background & Cabinet border - invoke DrawBox, 0, 0, 320, 240, 00140906h - invoke DrawBoxBorder, 6, 6, 308, 228, 0022150Fh, 00482E1Bh, 3 - - ; Header - invoke DrawBoxBorder, 20, 12, 280, 26, 001C100Ah, 00FFD700h, 2 - invoke DrawString8x8, 44, 21, OFFSET textCoinTitle, 00FFFF00h - - ; Corner rivets - invoke DrawBox, 12, 12, 3, 3, 00FFD700h - invoke DrawBox, 306, 12, 3, 3, 00FFD700h - invoke DrawBox, 12, 226, 3, 3, 00FFD700h - invoke DrawBox, 306, 226, 3, 3, 00FFD700h - - ; Status meters - invoke DrawBoxBorder, 20, 44, 110, 18, 000E1A0Ah, 00224B1Ah, 1 - invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch - invoke FormatNumber, bankroll, OFFSET hudNumBuffer - invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch - - invoke DrawBoxBorder, 190, 44, 110, 18, 001A100Ah, 003A2814h, 1 - invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h - invoke FormatNumber, coin3d_bet, OFFSET hudNumBuffer - invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h - - ; Left: Heads - cmp coin3d_choice, 1 - jne coin_left_inactive - invoke DrawBoxBorder, 20, 72, 76, 68, 00101828h, 00FFFF00h, 2 - invoke DrawString8x8, 30, 78, OFFSET textCoinSide1, 00FFFF00h - invoke DrawDetailedCoin, 58, 106, 14, 14, 00D0A000h, 00FFD700h, 1 - invoke DrawString8x8, 24, 126, OFFSET textCoinSelected, 003CFF3Ch - jmp coin_right_side -coin_left_inactive: - invoke DrawBoxBorder, 20, 72, 76, 68, 000A101Ch, 00404855h, 1 - invoke DrawString8x8, 30, 78, OFFSET textCoinSide1, 00D0D8E0h - invoke DrawDetailedCoin, 58, 106, 14, 14, 009A7A00h, 00D0A000h, 1 - -coin_right_side: - ; Right: Tails - cmp coin3d_choice, 2 - jne coin_right_inactive - invoke DrawBoxBorder, 224, 72, 76, 68, 00101828h, 00FFFF00h, 2 - invoke DrawString8x8, 234, 78, OFFSET textCoinSide2, 00FFFF00h - invoke DrawDetailedCoin, 262, 106, 14, 14, 00D0A000h, 00FFD700h, 2 - invoke DrawString8x8, 228, 126, OFFSET textCoinSelected, 003CFF3Ch - jmp coin_center_area -coin_right_inactive: - invoke DrawBoxBorder, 224, 72, 76, 68, 000A101Ch, 00404855h, 1 - invoke DrawString8x8, 234, 78, OFFSET textCoinSide2, 00D0D8E0h - invoke DrawDetailedCoin, 262, 106, 14, 14, 009A7A00h, 00D0A000h, 2 - -coin_center_area: - ; Center spotlight - invoke DrawCircle, 160, 110, 48, 00121620h - invoke DrawCircle, 160, 110, 44, 00FFD700h - invoke DrawCircle, 160, 110, 42, 000E141Eh - - cmp coin3d_state, 1 - je coin_render_flipping - cmp coin3d_state, 2 - je coin_render_result - - ; Idle coin - invoke DrawDetailedCoin, 160, 110, 26, 26, 00D0A000h, 00FFD700h, coin3d_choice - jmp coin_render_keys - -coin_render_flipping: - mov eax, coin3d_timer - and eax, 7 - movzx eax, byte ptr [coinRxAnimTable + eax] - mov rxVal, eax - invoke DrawDetailedCoin, 160, 110, rxVal, 26, 00D0A000h, 00FFD700h, 0 - invoke DrawString8x8, 88, 160, OFFSET textCoinFlipping, 00FFFF00h - jmp coin_render_keys - -coin_render_result: - invoke DrawDetailedCoin, 160, 110, 26, 26, 00D0A000h, 00FFD700h, coin3d_result - mov eax, coin3d_result - cmp eax, coin3d_choice - jne coin_render_loss_msg - - ; Win banner - invoke DrawBoxBorder, 44, 154, 232, 22, 000E141Eh, 003CFF3Ch, 1 - invoke DrawString8x8, 64, 161, OFFSET textCoinWin, 003CFF3Ch - invoke FormatNumber, coin3d_win, OFFSET hudNumBuffer - invoke DrawString8x8, 152, 161, OFFSET hudNumBuffer, 003CFF3Ch - jmp coin_render_keys - -coin_render_loss_msg: - invoke DrawBoxBorder, 44, 154, 232, 22, 000E141Eh, 00C81414h, 1 - invoke DrawString8x8, 114, 161, OFFSET textCoinLose, 00FF6464h - -coin_render_keys: - mov kx, 16 - xor eax, eax - cmp coin3d_choice, 1 - sete al - invoke DrawKeycap3D, kx, 192, OFFSET textCoinKey1, eax - add kx, eax - - xor eax, eax - cmp coin3d_choice, 2 - sete al - invoke DrawKeycap3D, kx, 192, OFFSET textCoinKey2, eax - add kx, eax - - invoke DrawKeycap3D, kx, 192, OFFSET textCoinKeySpace, 1 - add kx, eax - - invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0 - ret -ENDIF -RenderCoinGame ENDP - -; ============================================================================== -; IN-ENGINE 2.5D MINI-GAME: CRAPS / DICE -; ============================================================================== -DrawCrapsDie PROC uses ebx esi edi, x:DWORD, y:DWORD, sizeVal:DWORD, valNum:DWORD - ; Drop shadow - mov eax, x - add eax, 3 - mov edx, y - add edx, sizeVal - invoke DrawBox, eax, edx, sizeVal, 3, 00081403h - - mov eax, x - add eax, sizeVal - mov edx, y - add edx, 3 - invoke DrawBox, eax, edx, 3, sizeVal, 00081403h - - ; Ivory body & bevel - invoke DrawBoxBorder, x, y, sizeVal, sizeVal, 00FAF4F0h, 00403535h, 1 - mov eax, x - inc eax - mov edx, y - inc edx - mov ecx, sizeVal - sub ecx, 2 - invoke DrawBox, eax, edx, ecx, 1, 00FFFFFFh - invoke DrawBox, eax, edx, 1, ecx, 00FFFFFFh - - ; Ruby pips (00C81515h) - mov eax, valNum - test al, 1 - jz @F - ; Center pip - mov eax, x - add eax, 18 - mov edx, y - add edx, 18 - invoke DrawCircle, eax, edx, 3, 00C81515h - dec eax - dec edx - invoke DrawPixel, eax, edx, 00FFFFFFh -@@: - cmp valNum, 2 - jl die_pips_done - mov eax, x - add eax, 9 - mov edx, y - add edx, 9 - invoke DrawCircle, eax, edx, 3, 00C81515h - mov eax, x - add eax, 27 - mov edx, y - add edx, 27 - invoke DrawCircle, eax, edx, 3, 00C81515h - - cmp valNum, 4 - jl die_pips_done - mov eax, x - add eax, 27 - mov edx, y - add edx, 9 - invoke DrawCircle, eax, edx, 3, 00C81515h - mov eax, x - add eax, 9 - mov edx, y - add edx, 27 - invoke DrawCircle, eax, edx, 3, 00C81515h - - cmp valNum, 6 - jl die_pips_done - mov eax, x - add eax, 9 - mov edx, y - add edx, 18 - invoke DrawCircle, eax, edx, 3, 00C81515h - mov eax, x - add eax, 27 - mov edx, y - add edx, 18 - invoke DrawCircle, eax, edx, 3, 00C81515h - -die_pips_done: - ret -DrawCrapsDie ENDP - -InitDiceGame PROC - mov dice3d_state, 0 - mov dice3d_timer, 0 - mov dice3d_win, 0 - ret -InitDiceGame ENDP - -HandleDiceInput PROC - cmp dice3d_state, 0 - je dice_handle_idle - cmp dice3d_state, 1 - je dice_handle_rolling - cmp dice3d_state, 2 - je dice_handle_result - ret - -dice_handle_idle: - invoke Pressed3D, 26h ; UP - test eax, eax - jnz dice_bet_up - invoke Pressed3D, 57h ; 'W' - test eax, eax - jnz dice_bet_up - invoke Pressed3D, 28h ; DOWN - test eax, eax - jnz dice_bet_down - invoke Pressed3D, 53h ; 'S' - test eax, eax - jnz dice_bet_down - invoke Pressed3D, 31h ; '1' - test eax, eax - jnz dice_pick_1 - invoke Pressed3D, 32h ; '2' - test eax, eax - jnz dice_pick_2 - invoke Pressed3D, 20h ; SPACE - test eax, eax - jnz dice_start_roll - ret - -dice_bet_up: - mov eax, dice3d_bet - add eax, 50 - cmp eax, bankroll - jle @F - mov eax, bankroll -@@: - cmp eax, 5000 - jle @F - mov eax, 5000 -@@: - mov dice3d_bet, eax - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -dice_bet_down: - mov eax, dice3d_bet - sub eax, 50 - cmp eax, 50 - jge @F - mov eax, 50 -@@: - mov dice3d_bet, eax - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -dice_pick_1: - mov dice3d_choice, 1 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -dice_pick_2: - mov dice3d_choice, 2 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -dice_start_roll: - mov eax, dice3d_bet - cmp eax, bankroll - jle @F - mov eax, bankroll - mov dice3d_bet, eax - test eax, eax - jz dice_done -@@: - mov eax, dice3d_bet - test eax, eax - jle dice_done - sub bankroll, eax - mov dice3d_state, 1 - mov dice3d_timer, 0 - invoke RandomRange3D, 6 - inc eax - mov dice3d_val1, eax - invoke RandomRange3D, 6 - inc eax - mov dice3d_val2, eax - invoke PlayCasinoSound3D, OFFSET soundDiceRoll, 0, 1 - call SaveProgress3D - ret - -dice_handle_rolling: - mov eax, deltaTime3D - add dice3d_timer, eax - cmp dice3d_timer, 1600 - jb dice_done - mov dice3d_timer, 1600 - mov eax, dice3d_val2 - mov edx, dice3d_val1 - add edx, eax - mov dice3d_sum, edx - - ; Parity check - mov eax, edx - and eax, 1 - jnz dice_sum_is_odd - ; Even - mov eax, 1 - jmp dice_check_win -dice_sum_is_odd: - mov eax, 2 - -dice_check_win: - cmp eax, dice3d_choice - jne dice_roll_lost - - ; Won! - mov eax, dice3d_bet - shl eax, 1 - add bankroll, eax - mov dice3d_win, eax - mov dice3d_state, 2 - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - call SaveProgress3D - ret - -dice_roll_lost: - mov dice3d_win, 0 - mov dice3d_state, 2 - invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 - call SaveProgress3D - ret - -dice_handle_result: - invoke Pressed3D, 20h - test eax, eax - jz dice_done - mov dice3d_state, 0 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 -dice_done: - ret -HandleDiceInput ENDP - -RenderDiceGame PROC uses ebx esi edi - local kx:DWORD - - ; Mahogany frame & Deep Felt Green table - invoke DrawBox, 0, 0, 320, 240, 00140906h - invoke DrawBoxBorder, 6, 6, 308, 228, 000A3816h, 00FFD700h, 2 - - ; Header - invoke DrawBoxBorder, 20, 12, 280, 26, 00072E13h, 00FFD700h, 2 - invoke DrawString8x8, 116, 21, OFFSET textDiceTitle, 00FFFF00h - - ; Status - invoke DrawBoxBorder, 20, 44, 110, 18, 00072E13h, 001B4B22h, 1 - invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch - invoke FormatNumber, bankroll, OFFSET hudNumBuffer - invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch - - invoke DrawBoxBorder, 190, 44, 110, 18, 00072E13h, 001B4B22h, 1 - invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h - invoke FormatNumber, dice3d_bet, OFFSET hudNumBuffer - invoke DrawString8x8, 258, 49, OFFSET hudNumBuffer, 00FFD700h - - ; [1] ×¨Ò - cmp dice3d_choice, 1 - jne dice_even_inactive - invoke DrawBoxBorder, 16, 70, 88, 48, 00072E13h, 00FFFF00h, 2 - invoke DrawString8x8, 30, 76, OFFSET textDiceEven, 00FFFF00h - invoke DrawString8x8, 22, 90, OFFSET textDiceEvenNums, 00FFD700h - invoke DrawString8x8, 26, 104, OFFSET textCoinSelected, 003CFF3Ch - jmp dice_odd_side -dice_even_inactive: - invoke DrawBoxBorder, 16, 70, 88, 48, 00072E13h, 001B4B22h, 1 - invoke DrawString8x8, 30, 76, OFFSET textDiceEven, 00D0D8E0h - invoke DrawString8x8, 22, 90, OFFSET textDiceEvenNums, 0080B090h - -dice_odd_side: - ; [2] ÍÅ×ÅÒ - cmp dice3d_choice, 2 - jne dice_odd_inactive - invoke DrawBoxBorder, 216, 70, 88, 48, 00072E13h, 00FFFF00h, 2 - invoke DrawString8x8, 226, 76, OFFSET textDiceOdd, 00FFFF00h - invoke DrawString8x8, 224, 90, OFFSET textDiceOddNums, 00FFD700h - invoke DrawString8x8, 226, 104, OFFSET textCoinSelected, 003CFF3Ch - jmp dice_center_cubes -dice_odd_inactive: - invoke DrawBoxBorder, 216, 70, 88, 48, 00072E13h, 001B4B22h, 1 - invoke DrawString8x8, 226, 76, OFFSET textDiceOdd, 00D0D8E0h - invoke DrawString8x8, 224, 90, OFFSET textDiceOddNums, 0080B090h - -dice_center_cubes: - call RenderDiceThrow3D - - cmp dice3d_state, 1 - je dice_render_rolling - cmp dice3d_state, 2 - je dice_render_result - jmp dice_render_keys - -dice_render_rolling: - invoke DrawString8x8, 76, 138, OFFSET textDiceRolling, 00FFFF00h - jmp dice_render_keys - -dice_render_result: - invoke DrawBoxBorder, 36, 130, 248, 36, 00072E13h, 00FFD700h, 1 - invoke DrawString8x8, 44, 135, OFFSET textDiceSumHdr, 00FFD700h - invoke FormatNumber, dice3d_val1, OFFSET hudNumBuffer - invoke DrawString8x8, 92, 135, OFFSET hudNumBuffer, 00FFFF00h - invoke DrawString8x8, 110, 135, OFFSET textDicePlus, 00FFD700h - invoke FormatNumber, dice3d_val2, OFFSET hudNumBuffer - invoke DrawString8x8, 126, 135, OFFSET hudNumBuffer, 00FFFF00h - invoke DrawString8x8, 144, 135, OFFSET textDiceEqual, 00FFD700h - invoke FormatNumber, dice3d_sum, OFFSET hudNumBuffer - invoke DrawString8x8, 168, 135, OFFSET hudNumBuffer, 00FFFF00h - - mov eax, dice3d_sum - and eax, 1 - jnz dice_render_odd_res - invoke DrawString8x8, 186, 135, OFFSET textDiceEvenResult, 003CFF3Ch - jmp dice_render_outcome -dice_render_odd_res: - invoke DrawString8x8, 186, 135, OFFSET textDiceOddResult, 003CFF3Ch - -dice_render_outcome: - mov eax, dice3d_win - test eax, eax - jz dice_render_loss_outcome - invoke DrawString8x8, 68, 150, OFFSET textDiceWin, 003CFF3Ch - invoke FormatNumber, dice3d_win, OFFSET hudNumBuffer - invoke DrawString8x8, 156, 150, OFFSET hudNumBuffer, 003CFF3Ch - invoke DrawString8x8, 188, 150, OFFSET textDiceWinMult, 003CFF3Ch - jmp dice_render_keys - -dice_render_loss_outcome: - invoke DrawString8x8, 116, 150, OFFSET textDiceLose, 00FF6464h - -dice_render_keys: - mov kx, 16 - xor eax, eax - cmp dice3d_choice, 1 - sete al - invoke DrawKeycap3D, kx, 192, OFFSET textDiceKey1, eax - add kx, eax - - xor eax, eax - cmp dice3d_choice, 2 - sete al - invoke DrawKeycap3D, kx, 192, OFFSET textDiceKey2, eax - add kx, eax - - invoke DrawKeycap3D, kx, 192, OFFSET textDiceKeySpace, 1 - add kx, eax - - invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0 - ret -RenderDiceGame ENDP - -; ============================================================================== -; IN-ENGINE 2.5D MINI-GAME: SKULLS & CUPS (ÍÀϨÐÑÒÊÈ) -; ============================================================================== -DrawGlowingOrb PROC uses ebx esi edi, cxVal:DWORD, cyVal:DWORD - invoke DrawCircle, cxVal, cyVal, 14, 002E1E08h - invoke DrawCircle, cxVal, cyVal, 11, 00583A10h - invoke DrawCircle, cxVal, cyVal, 8, 008A581Ah - invoke DrawCircle, cxVal, cyVal, 6, 00D0B000h - invoke DrawCircle, cxVal, cyVal, 4, 00FFE000h - mov eax, cxVal - dec eax - mov edx, cyVal - dec edx - invoke DrawCircle, eax, edx, 2, 00FFFF80h - dec eax - dec edx - invoke DrawPixel, eax, edx, 00FFFFFFh - ret -DrawGlowingOrb ENDP - -DrawGothicCup PROC uses ebx esi edi, x:DWORD, y:DWORD, cupId:DWORD, isLifted:DWORD, hasBall:DWORD - local liftY:DWORD - - mov eax, y - cmp isLifted, 0 - je @F - sub eax, 36 -@@: - mov liftY, eax - - ; Drop shadow - cmp isLifted, 0 - jne cup_shadow_lifted - mov eax, x - add eax, 6 - mov edx, y - add edx, 42 - invoke DrawBox, eax, edx, 36, 4, 0010040Ah - jmp cup_ball_check -cup_shadow_lifted: - mov eax, x - add eax, 10 - mov edx, y - add edx, 42 - invoke DrawBox, eax, edx, 28, 2, 001A0612h - -cup_ball_check: - cmp isLifted, 0 - je cup_body_draw - cmp hasBall, 0 - je cup_body_draw - mov eax, x - add eax, 24 - mov edx, y - add edx, 26 - invoke DrawGlowingOrb, eax, edx - -cup_body_draw: - ; Base pedestal - mov eax, x - add eax, 6 - mov edx, liftY - add edx, 36 - invoke DrawBoxBorder, eax, edx, 36, 6, 00301A22h, 00D0B000h, 1 - - ; Stem - mov eax, x - add eax, 18 - mov edx, liftY - add edx, 28 - invoke DrawBox, eax, edx, 12, 8, 00452533h - mov eax, x - add eax, 22 - invoke DrawBox, eax, edx, 4, 8, 006E4055h - - ; Goblet Bowl - mov eax, x - add eax, 8 - mov edx, liftY - add edx, 8 - invoke DrawBoxBorder, eax, edx, 32, 20, 00401E2Dh, 00FFD700h, 1 - - mov eax, x - add eax, 14 - mov edx, liftY - add edx, 10 - invoke DrawBox, eax, edx, 6, 16, 00703550h - mov eax, x - add eax, 17 - invoke DrawBox, eax, edx, 3, 16, 00A05078h - - ; Golden Rim - mov eax, x - add eax, 4 - mov edx, liftY - add edx, 2 - invoke DrawBoxBorder, eax, edx, 40, 7, 00200A15h, 00FFFF00h, 1 - mov eax, x - add eax, 12 - mov edx, liftY - add edx, 4 - invoke DrawBox, eax, edx, 16, 2, 00FFFF00h - - ; Skull face emblem - mov eax, x - add eax, 21 - mov edx, liftY - add edx, 12 - invoke DrawBox, eax, edx, 6, 5, 00FFD700h - mov eax, x - add eax, 22 - mov edx, liftY - add edx, 17 - invoke DrawBox, eax, edx, 4, 3, 00FFD700h - mov eax, x - add eax, 22 - mov edx, liftY - add edx, 14 - invoke DrawPixel, eax, edx, 00200A15h - mov eax, x - add eax, 24 - invoke DrawPixel, eax, edx, 00200A15h - - ; Cup number label - mov eax, x - add eax, 21 - mov edx, liftY - add edx, 24 - mov ecx, cupId - add ecx, '1' - invoke DrawChar8x8, eax, edx, ecx, 00FFFF00h - ret -DrawGothicCup ENDP - -InitSkullsGame PROC - mov skulls3d_state, 0 - mov skulls3d_timer, 0 - mov skulls3d_win, 0 - mov skulls3d_choice, 1 - mov skulls3d_cup0, 0 - mov skulls3d_cup1, 1 - mov skulls3d_cup2, 2 - invoke RandomRange3D, 3 - mov skulls3d_ballPos, eax - ret -InitSkullsGame ENDP - -FinalizeSkullsGuess PROC uses ebx - mov eax, skulls3d_choice - cmp eax, skulls3d_ballPos - jne skulls_guess_wrong - - ; Correct! 3x payout - mov eax, skulls3d_bet - imul eax, 3 - add bankroll, eax - mov skulls3d_win, eax - mov skulls3d_state, 4 - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - ret - -skulls_guess_wrong: - mov skulls3d_win, 0 - mov skulls3d_state, 4 - invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 - ret -FinalizeSkullsGuess ENDP - -HandleSkullsInput PROC - cmp skulls3d_state, 0 - je skulls_handle_idle - cmp skulls3d_state, 1 - je skulls_handle_show - cmp skulls3d_state, 2 - je skulls_handle_shuffle - cmp skulls3d_state, 3 - je skulls_handle_pick - cmp skulls3d_state, 4 - je skulls_handle_reveal - ret - -skulls_handle_idle: - invoke Pressed3D, 26h ; UP - test eax, eax - jnz skulls_bet_up - invoke Pressed3D, 57h ; 'W' - test eax, eax - jnz skulls_bet_up - invoke Pressed3D, 28h ; DOWN - test eax, eax - jnz skulls_bet_down - invoke Pressed3D, 53h ; 'S' - test eax, eax - jnz skulls_bet_down - invoke Pressed3D, 20h ; SPACE - test eax, eax - jnz skulls_start_game - ret - -skulls_bet_up: - mov eax, skulls3d_bet - add eax, 50 - cmp eax, bankroll - jle @F - mov eax, bankroll -@@: - cmp eax, 5000 - jle @F - mov eax, 5000 -@@: - mov skulls3d_bet, eax - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -skulls_bet_down: - mov eax, skulls3d_bet - sub eax, 50 - cmp eax, 50 - jge @F - mov eax, 50 -@@: - mov skulls3d_bet, eax - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -skulls_start_game: - mov eax, skulls3d_bet - cmp eax, bankroll - jle @F - mov eax, bankroll - mov skulls3d_bet, eax - test eax, eax - jz skulls_input_done -@@: - mov eax, skulls3d_bet - sub bankroll, eax - invoke RandomRange3D, 3 - mov skulls3d_ballPos, eax - mov skulls3d_cup0, 0 - mov skulls3d_cup1, 1 - mov skulls3d_cup2, 2 - - ; Pre-generate 3 dynamic swap pairs - invoke RandomRange3D, 3 - mov skulls3d_swapPair0, eax - invoke RandomRange3D, 3 - mov skulls3d_swapPair1, eax - invoke RandomRange3D, 3 - mov skulls3d_swapPair2, eax - - mov skulls3d_state, 1 - mov skulls3d_timer, 0 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -skulls_handle_show: - inc skulls3d_timer - cmp skulls3d_timer, 45 - jl skulls_input_done - ; Transition to Phase 2: Active Shuffle Animation - mov skulls3d_state, 2 - mov skulls3d_timer, 0 - invoke PlayCasinoSound3D, OFFSET soundShuffle, 0, 1 - ret - -skulls_handle_shuffle: - inc skulls3d_timer - cmp skulls3d_timer, 60 - jl skulls_input_done - ; Transition to Phase 3: Pick cup - mov skulls3d_state, 3 - mov skulls3d_timer, 0 - ret - -skulls_handle_pick: - invoke Pressed3D, 31h ; '1' - test eax, eax - jnz skulls_pick_1 - invoke Pressed3D, 32h ; '2' - test eax, eax - jnz skulls_pick_2 - invoke Pressed3D, 33h ; '3' - test eax, eax - jnz skulls_pick_3 - ret - -skulls_pick_1: - mov skulls3d_choice, 0 - call FinalizeSkullsGuess - ret - -skulls_pick_2: - mov skulls3d_choice, 1 - call FinalizeSkullsGuess - ret - -skulls_pick_3: - mov skulls3d_choice, 2 - call FinalizeSkullsGuess - ret - -skulls_handle_reveal: - invoke Pressed3D, 20h - test eax, eax - jz skulls_input_done - mov skulls3d_state, 0 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 -skulls_input_done: - ret -HandleSkullsInput ENDP - -RenderSkullsGame PROC uses ebx esi edi - local kx:DWORD - local passTick:DWORD, curPair:DWORD, swapSlotA:DWORD, swapSlotB:DWORD - local xA:DWORD, xB:DWORD, curXA:DWORD, curXB:DWORD, curYA:DWORD, curYB:DWORD - local distX:DWORD, dxVal:DWORD, archY:DWORD - - ; Mahogany & Gothic Purple table - invoke DrawBox, 0, 0, 320, 240, 00140906h - invoke DrawBoxBorder, 6, 6, 308, 228, 00300F22h, 00FFD700h, 2 - - ; Header - invoke DrawBoxBorder, 20, 12, 280, 26, 001A0812h, 00FFD700h, 2 - invoke DrawString8x8, 44, 21, OFFSET textSkullsTitle, 00FFFF00h - - ; Status - invoke DrawBoxBorder, 20, 44, 110, 18, 001A0812h, 00452033h, 1 - invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch - invoke FormatNumber, bankroll, OFFSET hudNumBuffer - invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch - - invoke DrawBoxBorder, 190, 44, 110, 18, 001A0812h, 00452033h, 1 - invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h - invoke FormatNumber, skulls3d_bet, OFFSET hudNumBuffer - invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h - - ; Phase Prompts - cmp skulls3d_state, 0 - jne @F - invoke DrawString8x8, 56, 62, OFFSET textSkullsPhase0, 00FFD700h - jmp skulls_draw_idle_cups -@@: - cmp skulls3d_state, 1 - jne @F - invoke DrawString8x8, 56, 62, OFFSET textSkullsPhase1, 00FFFF00h - jmp skulls_draw_phase1_cups -@@: - cmp skulls3d_state, 2 - jne @F - invoke DrawString8x8, 44, 62, OFFSET textSkullsPhase2, 00FFFF00h - jmp skulls_draw_animated_cups -@@: - cmp skulls3d_state, 3 - jne @F - invoke DrawString8x8, 28, 62, OFFSET textSkullsPhase3, 00FFFF00h - jmp skulls_draw_idle_cups -@@: - ; Phase 4: Reveal outcome - mov eax, skulls3d_win - test eax, eax - jz skulls_reveal_loss_text - invoke DrawString8x8, 40, 62, OFFSET textSkullsWin, 003CFF3Ch - invoke FormatNumber, skulls3d_win, OFFSET hudNumBuffer - invoke DrawString8x8, 136, 62, OFFSET hudNumBuffer, 003CFF3Ch - invoke DrawString8x8, 168, 62, OFFSET textSkullsWinMult, 003CFF3Ch - jmp skulls_draw_reveal_cups - -skulls_reveal_loss_text: - invoke DrawString8x8, 40, 62, OFFSET textSkullsLose, 00FF6464h - jmp skulls_draw_reveal_cups - -skulls_draw_idle_cups: - ; Draw resting cups at static slots: Slot 0 (X=36), Slot 1 (X=136), Slot 2 (X=236) - invoke DrawGothicCup, 36, 114, skulls3d_cup0, 0, 0 - invoke DrawGothicCup, 136, 114, skulls3d_cup1, 0, 0 - invoke DrawGothicCup, 236, 114, skulls3d_cup2, 0, 0 - jmp skulls_render_controls - -skulls_draw_phase1_cups: - ; Draw with golden ball showing under starting cup - mov ebx, 0 - mov edx, 0 - cmp skulls3d_ballPos, 0 - jne @F - mov ebx, 1 - mov edx, 1 -@@: - invoke DrawGothicCup, 36, 114, skulls3d_cup0, ebx, edx - - mov ebx, 0 - mov edx, 0 - cmp skulls3d_ballPos, 1 - jne @F - mov ebx, 1 - mov edx, 1 -@@: - invoke DrawGothicCup, 136, 114, skulls3d_cup1, ebx, edx - - mov ebx, 0 - mov edx, 0 - cmp skulls3d_ballPos, 2 - jne @F - mov ebx, 1 - mov edx, 1 -@@: - invoke DrawGothicCup, 236, 114, skulls3d_cup2, ebx, edx - jmp skulls_render_controls - -skulls_draw_animated_cups: - ; 60 frames = 3 passes of 20 frames - mov eax, skulls3d_timer - cmp eax, 20 - jbe pass_0 - cmp eax, 40 - jbe pass_1 - sub eax, 41 - mov passTick, eax - mov eax, skulls3d_swapPair2 - mov curPair, eax - jmp setup_pass - -pass_0: - dec eax - mov passTick, eax - mov eax, skulls3d_swapPair0 - mov curPair, eax - jmp setup_pass - -pass_1: - sub eax, 21 - mov passTick, eax - mov eax, skulls3d_swapPair1 - mov curPair, eax - -setup_pass: - ; curPair determines swap pair: - ; 0: swap slot 0 (X=36) and slot 1 (X=136) - ; 1: swap slot 1 (X=136) and slot 2 (X=236) - ; 2: swap slot 0 (X=36) and slot 2 (X=236) - cmp curPair, 1 - je pair_1 - cmp curPair, 2 - je pair_2 - mov swapSlotA, 0 - mov swapSlotB, 1 - mov xA, 36 - mov xB, 136 - jmp calc_coords -pair_1: - mov swapSlotA, 1 - mov swapSlotB, 2 - mov xA, 136 - mov xB, 236 - jmp calc_coords -pair_2: - mov swapSlotA, 0 - mov swapSlotB, 2 - mov xA, 36 - mov xB, 236 - -calc_coords: - ; distX = xB - xA - mov eax, xB - sub eax, xA - mov distX, eax - - ; dxVal = (distX * passTick) / 20 - mov eax, distX - imul eax, passTick - xor edx, edx - mov ecx, 20 - div ecx - mov dxVal, eax - - ; curXA = xA + dxVal - mov eax, xA - add eax, dxVal - mov curXA, eax - - ; curXB = xB - dxVal - mov eax, xB - sub eax, dxVal - mov curXB, eax - - ; archY = (passTick * (20 - passTick)) / 10 - mov eax, passTick - mov ecx, 20 - sub ecx, eax - imul eax, ecx - xor edx, edx - mov ecx, 10 - div ecx - mov archY, eax - - ; Cup A hops UP: 114 - archY - mov eax, 114 - sub eax, archY - mov curYA, eax - - ; Cup B hops DOWN: 114 + archY - mov eax, 114 - add eax, archY - mov curYB, eax - - ; Check if pass ended (frame 19): swap ball position and cups - cmp passTick, 19 - jne draw_active_shuffle - - ; Swap ball position if involved - mov eax, skulls3d_ballPos - cmp eax, swapSlotA - jne check_ball_b - mov edx, swapSlotB - mov skulls3d_ballPos, edx - jmp swap_slot_identities -check_ball_b: - cmp eax, swapSlotB - jne swap_slot_identities - mov edx, swapSlotA - mov skulls3d_ballPos, edx - -swap_slot_identities: - cmp curPair, 1 - je swap_ids_1_2 - cmp curPair, 2 - je swap_ids_0_2 - ; swap 0 and 1 - mov eax, skulls3d_cup0 - xchg eax, skulls3d_cup1 - mov skulls3d_cup0, eax - jmp swap_sound_tick -swap_ids_1_2: - mov eax, skulls3d_cup1 - xchg eax, skulls3d_cup2 - mov skulls3d_cup1, eax - jmp swap_sound_tick -swap_ids_0_2: - mov eax, skulls3d_cup0 - xchg eax, skulls3d_cup2 - mov skulls3d_cup0, eax - -swap_sound_tick: - invoke PlayCasinoSound3D, OFFSET soundShuffle, 0, 1 - -draw_active_shuffle: - ; Draw stationary cup - cmp curPair, 1 - je draw_stat_cup0 - cmp curPair, 2 - je draw_stat_cup1 - ; Stationary cup is slot 2 (X=236) - invoke DrawGothicCup, 236, 114, skulls3d_cup2, 0, 0 - jmp draw_moving_cups -draw_stat_cup0: - ; Stationary cup is slot 0 (X=36) - invoke DrawGothicCup, 36, 114, skulls3d_cup0, 0, 0 - jmp draw_moving_cups -draw_stat_cup1: - ; Stationary cup is slot 1 (X=136) - invoke DrawGothicCup, 136, 114, skulls3d_cup1, 0, 0 - -draw_moving_cups: - ; Moving Cup A and Moving Cup B - cmp curPair, 1 - je ids_pair_1 - cmp curPair, 2 - je ids_pair_2 - mov eax, skulls3d_cup0 - mov ebx, skulls3d_cup1 - jmp draw_the_pair -ids_pair_1: - mov eax, skulls3d_cup1 - mov ebx, skulls3d_cup2 - jmp draw_the_pair -ids_pair_2: - mov eax, skulls3d_cup0 - mov ebx, skulls3d_cup2 - -draw_the_pair: - push ebx - invoke DrawGothicCup, curXA, curYA, eax, 0, 0 - pop ebx - invoke DrawGothicCup, curXB, curYB, ebx, 0, 0 - jmp skulls_render_controls - -skulls_draw_reveal_cups: - ; Reveal Phase: lift chosen cup and lift actual ball cup if different - ; Slot 0 - mov ebx, 0 - mov edx, 0 - cmp skulls3d_choice, 0 - je slot0_is_lifted - cmp skulls3d_ballPos, 0 - jne @F -slot0_is_lifted: - mov ebx, 1 - cmp skulls3d_ballPos, 0 - sete dl -@@: - invoke DrawGothicCup, 36, 114, skulls3d_cup0, ebx, edx - - ; Slot 1 - mov ebx, 0 - mov edx, 0 - cmp skulls3d_choice, 1 - je slot1_is_lifted - cmp skulls3d_ballPos, 1 - jne @F -slot1_is_lifted: - mov ebx, 1 - cmp skulls3d_ballPos, 1 - sete dl -@@: - invoke DrawGothicCup, 136, 114, skulls3d_cup1, ebx, edx - - ; Slot 2 - mov ebx, 0 - mov edx, 0 - cmp skulls3d_choice, 2 - je slot2_is_lifted - cmp skulls3d_ballPos, 2 - jne @F -slot2_is_lifted: - mov ebx, 1 - cmp skulls3d_ballPos, 2 - sete dl -@@: - invoke DrawGothicCup, 236, 114, skulls3d_cup2, ebx, edx - -skulls_render_controls: - ; Cup selection slot labels [1], [2], [3] - invoke DrawString8x8, 54, 168, OFFSET textSkullsKey1, 00D0D8E0h - invoke DrawString8x8, 150, 168, OFFSET textSkullsKey2, 00D0D8E0h - invoke DrawString8x8, 250, 168, OFFSET textSkullsKey3, 00D0D8E0h - - ; Keycaps - mov kx, 16 - xor eax, eax - cmp skulls3d_state, 3 - je key1_active - cmp skulls3d_choice, 0 - sete al - jmp draw_key1 -key1_active: - mov eax, 1 -draw_key1: - invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey1, eax - add kx, eax - - xor eax, eax - cmp skulls3d_state, 3 - je key2_active - cmp skulls3d_choice, 1 - sete al - jmp draw_key2 -key2_active: - mov eax, 1 -draw_key2: - invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey2, eax - add kx, eax - - xor eax, eax - cmp skulls3d_state, 3 - je key3_active - cmp skulls3d_choice, 2 - sete al - jmp draw_key3 -key3_active: - mov eax, 1 -draw_key3: - invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey3, eax - add kx, eax - - xor eax, eax - cmp skulls3d_state, 0 - je start_active - cmp skulls3d_state, 4 - je start_active - jmp draw_start_key -start_active: - mov eax, 1 -draw_start_key: - invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKeySpace, eax - add kx, eax - - invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0 - ret -RenderSkullsGame ENDP - -InitSkillGame PROC - mov skill3d_state, 0 - mov skill3d_timer, 0 - mov skill3d_hits, 0 - mov skill3d_misses, 0 - mov skill3d_needle, 55 - mov skill3d_speed, 4 - mov skill3d_dir, 1 - mov skill3d_last_result, 0 - mov skill3d_win_amount, 0 - - ; Randomize initial zone: 80 + RandomRange(90) -> 80..170 - invoke RandomRange3D, 90 - add eax, 80 - mov skill3d_zone_start, eax - - ; Great zone: start + 20 + RandomRange(12) - invoke RandomRange3D, 12 - add eax, skill3d_zone_start - add eax, 20 - mov skill3d_great_start, eax - ret -InitSkillGame ENDP - -HandleSkillInput PROC uses ebx esi - mov eax, skill3d_state - cmp eax, 0 - je skill_handle_ready - cmp eax, 1 - je skill_handle_active - cmp eax, 2 - je skill_handle_round_wait - cmp eax, 3 - je skill_handle_round_wait - cmp eax, 4 - je skill_handle_end_wait - cmp eax, 5 - je skill_handle_end_wait - ret - -skill_handle_ready: - invoke Pressed3D, 26h ; UP - test eax, eax - jnz skill_bet_up - invoke Pressed3D, 57h ; 'W' - test eax, eax - jnz skill_bet_up - invoke Pressed3D, 28h ; DOWN - test eax, eax - jnz skill_bet_down - invoke Pressed3D, 53h ; 'S' - test eax, eax - jnz skill_bet_down - jmp skill_check_start - -skill_bet_up: - mov eax, skill3d_bet - add eax, 50 - cmp eax, bankroll - jle @F - mov eax, bankroll -@@: - cmp eax, 5000 - jle @F - mov eax, 5000 -@@: - mov skill3d_bet, eax - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -skill_bet_down: - mov eax, skill3d_bet - sub eax, 50 - cmp eax, 50 - jge @F - mov eax, 50 -@@: - mov skill3d_bet, eax - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -skill_check_start: - invoke Pressed3D, 20h ; SPACE - test eax, eax - jz skill_input_done - - ; Deduct bet on game start if beginning of run - mov eax, skill3d_hits - or eax, skill3d_misses - jnz @F - mov eax, skill3d_bet - cmp eax, bankroll - jle skill_has_funds - mov eax, bankroll - mov skill3d_bet, eax - test eax, eax - jz skill_input_done -skill_has_funds: - mov eax, skill3d_bet - sub bankroll, eax -@@: - mov skill3d_state, 1 - mov skill3d_needle, 55 - mov skill3d_dir, 1 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret - -skill_handle_active: - ; Move needle smoothly - mov eax, skill3d_needle - mov edx, skill3d_speed - cmp skill3d_dir, 1 - je skill_move_right - sub eax, edx - cmp eax, 52 - jge skill_update_needle - mov eax, 52 - mov skill3d_dir, 1 - jmp skill_update_needle -skill_move_right: - add eax, edx - cmp eax, 268 - jle skill_update_needle - mov eax, 268 - mov skill3d_dir, -1 -skill_update_needle: - mov skill3d_needle, eax - - ; Check SPACE pressed (Reaction Hit Attempt!) - invoke Pressed3D, 20h - test eax, eax - jz skill_input_done - - ; Is needle in Great Sweet Spot? - mov eax, skill3d_needle - mov edx, skill3d_great_start - cmp eax, edx - jl check_success_zone - add edx, skill3d_great_width - cmp eax, edx - jg check_success_zone - - ; GREAT HIT! - mov skill3d_last_result, 2 - add skill3d_hits, 2 - mov skill3d_state, 2 - mov skill3d_timer, 40 - invoke PlayCasinoSound3D, OFFSET soundSkillPerfect, 0, 1 - jmp skill_check_finish_round - -check_success_zone: - mov eax, skill3d_needle - mov edx, skill3d_zone_start - cmp eax, edx - jl skill_was_miss - add edx, skill3d_zone_width - cmp eax, edx - jg skill_was_miss - - ; NORMAL HIT! - mov skill3d_last_result, 1 - inc skill3d_hits - mov skill3d_state, 2 - mov skill3d_timer, 40 - invoke PlayCasinoSound3D, OFFSET soundSkillHit, 0, 1 - jmp skill_check_finish_round - -skill_was_miss: - ; MISS! - mov skill3d_last_result, 0 - inc skill3d_misses - mov skill3d_state, 3 - mov skill3d_timer, 45 - invoke PlayCasinoSound3D, OFFSET soundSkillMiss, 0, 1 - -skill_check_finish_round: - cmp skill3d_hits, 5 - jge skill_game_escaped - cmp skill3d_misses, 3 - jge skill_game_lost - ret - -skill_game_escaped: - mov skill3d_state, 4 - mov skill3d_timer, 0 - ; Payout: 3x total return (+$2x bet profit) - mov eax, skill3d_bet - imul eax, 3 - add bankroll, eax - mov eax, skill3d_bet - shl eax, 1 - mov skill3d_win_amount, eax - invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 - ret - -skill_game_lost: - mov skill3d_state, 5 - mov skill3d_timer, 0 - invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 - ret - -skill_handle_round_wait: - dec skill3d_timer - cmp skill3d_timer, 0 - jg skill_input_done - - ; Next round setup - invoke RandomRange3D, 90 - add eax, 80 - mov skill3d_zone_start, eax - - invoke RandomRange3D, 12 - add eax, skill3d_zone_start - add eax, 20 - mov skill3d_great_start, eax - - mov eax, skill3d_hits - shr eax, 1 - add eax, 4 - mov skill3d_speed, eax - mov skill3d_state, 1 - ret - -skill_handle_end_wait: - invoke Pressed3D, 20h - test eax, eax - jz skill_input_done - call InitSkillGame - ret - -skill_input_done: - ret -HandleSkillInput ENDP - -RenderSkillGame PROC uses ebx esi edi - local kx:DWORD - local tx:DWORD - - ; Industrial Steel bezel - invoke DrawBox, 0, 0, 320, 240, 00121416h - invoke DrawBoxBorder, 6, 6, 308, 228, 001A1D20h, 00FFD700h, 2 - - ; Header - invoke DrawBoxBorder, 20, 12, 280, 26, 00121418h, 00FFD700h, 2 - invoke DrawString8x8, 40, 21, OFFSET textSkillTitle, 00FFFF00h - - ; Status - invoke DrawBoxBorder, 20, 44, 110, 18, 00121418h, 002A3540h, 1 - invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch - invoke FormatNumber, bankroll, OFFSET hudNumBuffer - invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch - - invoke DrawBoxBorder, 190, 44, 110, 18, 00121418h, 002A3540h, 1 - invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h - invoke FormatNumber, skill3d_bet, OFFSET hudNumBuffer - invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h - - ; Survivor Progress - invoke DrawString8x8, 24, 70, OFFSET textSkillHitsHdr, 003CFF3Ch - invoke FormatNumber, skill3d_hits, OFFSET hudNumBuffer - invoke DrawString8x8, 64, 70, OFFSET hudNumBuffer, 003CFF3Ch - - invoke DrawString8x8, 180, 70, OFFSET textSkillMissHdr, 00FF6464h - invoke FormatNumber, skill3d_misses, OFFSET hudNumBuffer - invoke DrawString8x8, 240, 70, OFFSET hudNumBuffer, 00FF6464h - - ; Dial Frame (Track: X=50..270, Y=102..134) - invoke DrawBoxBorder, 50, 102, 220, 32, 000F1114h, 00404855h, 2 - - ; Calibrated ticks - mov tx, 60 -skill_ticks_loop: - cmp tx, 260 - jge skill_draw_zones - invoke DrawBox, tx, 104, 1, 6, 00303845h - invoke DrawBox, tx, 126, 1, 6, 00303845h - add tx, 12 - jmp skill_ticks_loop - -skill_draw_zones: - ; Normal Success Zone (Green) - invoke DrawBoxBorder, skill3d_zone_start, 106, skill3d_zone_width, 24, 00155020h, 003CFF3Ch, 1 - - ; Great Zone (Gold) - invoke DrawBoxBorder, skill3d_great_start, 106, skill3d_great_width, 24, 00FFD700h, 00FFFF00h, 1 - - ; Pointer / Needle at skill3d_needle - mov eax, skill3d_needle - dec eax - invoke DrawBox, eax, 98, 3, 40, 00FFFFFFh - mov eax, skill3d_needle - sub eax, 2 - invoke DrawBox, eax, 96, 5, 2, 00FF3030h - invoke DrawBox, eax, 138, 5, 2, 00FF3030h - - ; Center prompts / outcome - cmp skill3d_state, 0 - jne @F - invoke DrawString8x8, 52, 150, OFFSET textSkillReadyMsg, 00FFD700h - invoke DrawString8x8, 76, 166, OFFSET textSkillPrompt, 00D0D8E0h - jmp skill_render_keys -@@: - cmp skill3d_state, 1 - jne @F - invoke DrawString8x8, 76, 150, OFFSET textSkillPrompt, 00FFFF00h - jmp skill_render_keys -@@: - cmp skill3d_state, 2 - jne @F - cmp skill3d_last_result, 2 - jne skill_normal_hit_text - invoke DrawString8x8, 36, 150, OFFSET textSkillGreatMsg, 00FFFF00h - jmp skill_render_keys -skill_normal_hit_text: - invoke DrawString8x8, 64, 150, OFFSET textSkillHitMsg, 003CFF3Ch - jmp skill_render_keys -@@: - cmp skill3d_state, 3 - jne @F - invoke DrawString8x8, 88, 150, OFFSET textSkillMissMsg, 00FF6464h - jmp skill_render_keys -@@: - cmp skill3d_state, 4 - jne @F - invoke DrawString8x8, 48, 150, OFFSET textSkillEscape, 003CFF3Ch - invoke FormatNumber, skill3d_win_amount, OFFSET hudNumBuffer - invoke DrawString8x8, 240, 150, OFFSET hudNumBuffer, 003CFF3Ch - invoke DrawString8x8, 64, 166, OFFSET textSkullsAgain, 00FFD700h - jmp skill_render_keys -@@: - invoke DrawString8x8, 44, 150, OFFSET textSkillLost, 00FF6464h - invoke DrawString8x8, 64, 166, OFFSET textSkullsAgain, 00FFD700h - -skill_render_keys: - mov kx, 16 - invoke DrawKeycap3D, kx, 192, OFFSET textSkillKeySpace, 1 - add kx, eax - - invoke DrawKeycap3D, kx, 192, OFFSET textSkillKeyBet, 0 - add kx, eax - - invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0 - ret -RenderSkillGame ENDP - -HandlePlayerInput PROC uses ebx esi edi - local speed:DWORD - local nextX:DWORD - local nextY:DWORD - mov eax, deltaTime3D - imul eax, 200 - mov speed, eax - cmp keys3D[10h], 0 - je @F - shl speed, 1 -@@: - mov eax, deltaTime3D - shr eax, 2 - inc eax - cmp keys3D[41h], 0 - jne input_turn_left - cmp keys3D[25h], 0 - je input_right -input_turn_left: - sub playerAngle, eax -input_right: - cmp keys3D[44h], 0 - jne input_turn_right - cmp keys3D[27h], 0 - je input_forward -input_turn_right: - add playerAngle, eax -input_forward: - and playerAngle, 511 - call UpdateCamera3D - xor edi, edi - cmp keys3D[57h], 0 - jne input_go_forward - cmp keys3D[26h], 0 - je input_back -input_go_forward: - inc edi -input_back: - cmp keys3D[53h], 0 - jne input_go_back - cmp keys3D[28h], 0 - je input_move -input_go_back: - dec edi -input_move: - test edi, edi - jz input_action - imul edi, speed - mov eax, playerDirX - imul edi - shrd eax, edx, 16 - add eax, playerX - mov nextX, eax - mov eax, playerDirY - imul edi - shrd eax, edx, 16 - add eax, playerY - mov nextY, eax - invoke CanWalk3D, nextX, playerY - test eax, eax - jz @F - mov eax, nextX - mov playerX, eax -@@: - invoke CanWalk3D, playerX, nextY - test eax, eax - jz input_action - mov eax, nextY - mov playerY, eax -input_action: - invoke Pressed3D, 45h - test eax, eax - jz @F - call Trigger3DInteraction -@@: - ret -HandlePlayerInput ENDP - -CheckInteractions PROC uses ebx esi edi - local nearest:DWORD - mov nearest, 262144 - mov interactTargetId, 0 - mov interactPromptPtr, 0 - xor esi, esi -interaction_scan: - cmp esi, NUM_SPRITES - jge interaction_done - imul edi, esi, SIZEOF SpriteObject - cmp [casinoSprites+edi].interactId, 0 - je interaction_next - mov eax, [casinoSprites+edi].posX - sub eax, playerX - sar eax, 8 - mov ebx, eax - imul eax, eax - mov ecx, eax - mov eax, [casinoSprites+edi].posY - sub eax, playerY - sar eax, 8 - mov edx, eax - imul eax, eax - add ecx, eax - cmp ecx, nearest - jae interaction_next - ; Only target objects in front of the camera. - mov eax, playerDirX - sar eax, 8 - imul eax, ebx - mov ebx, playerDirY - sar ebx, 8 - imul ebx, edx - add eax, ebx - cmp eax, 18000 - jl interaction_next - mov nearest, ecx - mov eax, [casinoSprites+edi].interactId - mov interactTargetId, eax - mov eax, [casinoSprites+edi].promptPtr - mov interactPromptPtr, eax -interaction_next: - inc esi - jmp interaction_scan -interaction_done: - call CheckHallInteractions3D - ret -CheckInteractions ENDP - -; --- RenderCabinetBezel: Îòðèñîâêà àðêàäíîãî áåçåëÿ òåðìèíàëà íà 3D ýêðàíå --- -RenderCabinetBezel PROC uses ebx esi edi, pTitle:DWORD - ; Çàòåìíÿåì 3D-çàë â áóôåðå êàäðà (äåëèì ÿðêîñòü ïîïîëàì) - mov ecx, SCREEN_SIZE - xor esi, esi -dim_bezel_loop: - mov eax, [screenBuffer + esi*4] - shr eax, 1 - and eax, 007F7F7Fh - mov [screenBuffer + esi*4], eax - inc esi - loop dim_bezel_loop - - ; Âíåøíÿÿ çîëîòàÿ ðàìêà òåðìèíàëà - invoke DrawBoxBorder, 10, 14, 300, 212, 000C0E14h, 00D8BC6Ah, 2 - - ; Øàïêà òåðìèíàëà ñ íàçâàíèåì èãðû - invoke DrawBox, 12, 16, 296, 16, 00221A10h - invoke DrawString8x8, 20, 20, pTitle, 00F5E2B0h - - ; Ïîäâàëüíàÿ ïëàøêà ñ ïîäñêàçêîé ïî âûõîäó - invoke DrawBox, 12, 210, 296, 14, 00141416h - invoke DrawString8x8, 20, 213, OFFSET textCabinetFooter, 00AAAAAAh - - ; Âûâîäèì êàäð áåçåëÿ â îêíî - call Present3D - ret -RenderCabinetBezel ENDP - -; --- LaunchClassicGame: Âñòðàèâàíèå èãðû â UI òåðìèíàëà êàçèíî --- -LaunchClassicGame PROC uses ebx esi edi, pGameProc:DWORD, gameId:DWORD, pTitle:DWORD - LOCAL rcClient[16]:BYTE - LOCAL ptScreen[8]:BYTE - LOCAL fontInfo[84]:BYTE - LOCAL conWnd:DWORD - LOCAL conW:DWORD, conH:DWORD, conX:DWORD, conY:DWORD - LOCAL viewW:DWORD, viewH:DWORD - LOCAL offsetX:DWORD, offsetY:DWORD - - mov eax, gameId - mov currentGameId, eax - - ; 1. Ðèñóåì çîëîòîé áåçåëü òåðìèíàëà íà 3D ýêðàíå - cmp pTitle, 0 - je @F - invoke RenderCabinetBezel, pTitle -@@: - - ; 2. Âûäåëÿåì êîíñîëü - invoke AllocConsole - test eax, eax - jz launch_ret - - invoke GetStdHandle, STD_OUTPUT_HANDLE - mov hOut, eax - invoke GetStdHandle, STD_INPUT_HANDLE - mov hIn, eax - - invoke SetConsoleCP, 1251 - invoke SetConsoleOutputCP, 1251 - - cmp pTitle, 0 - je @F - invoke SetConsoleTitleA, pTitle -@@: - call EnableAnsi - call ConfigureConsoleSize - - ; 3. Íàñòðàèâàåì øðèôò Consolas Bold 16pt - lea edi, fontInfo - xor eax, eax - mov ecx, 21 - rep stosd - mov dword ptr fontInfo[0], 84 ; cbSize - mov word ptr fontInfo[8], 0 ; dwFontSize.X - mov word ptr fontInfo[10], 16 ; dwFontSize.Y - mov dword ptr fontInfo[16], 700 ; FontWeight = FW_BOLD - mov word ptr fontInfo[20], 'C' - mov word ptr fontInfo[22], 'o' - mov word ptr fontInfo[24], 'n' - mov word ptr fontInfo[26], 's' - mov word ptr fontInfo[28], 'o' - mov word ptr fontInfo[30], 'l' - mov word ptr fontInfo[32], 'a' - mov word ptr fontInfo[34], 's' - mov word ptr fontInfo[36], 0 - lea eax, fontInfo - invoke SetCurrentConsoleFontEx, hOut, 0, eax - - ; 4. Ïîëó÷àåì äåñêðèïòîð îêíà êîíñîëè - invoke GetConsoleWindow - mov conWnd, eax - test eax, eax - jz run_game_body - - ; 5. Ñíèìàåì ñèñòåìíóþ ðàìêó Windows è çàãîëîâîê ñ êíîïêàìè çàêðûòèÿ/ñâîðà÷èâàíèÿ - invoke GetWindowLongA, conWnd, -16 ; GWL_STYLE - and eax, NOT (00C00000h or 00040000h or 00080000h or 00010000h or 00020000h) - or eax, 80000000h ; WS_POPUP - invoke SetWindowLongA, conWnd, -16, eax - - ; Ñâÿçûâàåì êàê äî÷åðíåå/ïðèíàäëåæàùåå îêíî ê îêíó èãðû - cmp h3DWnd, 0 - je show_con_fallback - invoke SetWindowLongA, conWnd, -8, h3DWnd ; GWL_HWNDPARENT - - ; 6. Âû÷èñëÿåì òî÷íûå êîîðäèíàòû äëÿ ïîñàäêè ýêðàíà âíóòðü áåçåëÿ - lea eax, rcClient - invoke GetClientRect, h3DWnd, eax - mov esi, dword ptr rcClient[8] ; øèðèíà êëèåíòñêîé îáëàñòè - mov edi, dword ptr rcClient[12] ; âûñîòà êëèåíòñêîé îáëàñòè - test esi, esi - jz show_con_fallback - test edi, edi - jz show_con_fallback - - ; Ðàñ÷åò âüþïîðòà 4:3 òî÷íî êàê â Present3D - mov viewW, esi - mov eax, esi - imul eax, 3 - shr eax, 2 - cmp eax, edi - jle calc_view_h - mov eax, edi - imul eax, 4 - xor edx, edx - mov ecx, 3 - div ecx - mov viewW, eax - mov eax, edi -calc_view_h: - mov viewH, eax - - mov ebx, esi - sub ebx, viewW - shr ebx, 1 - mov offsetX, ebx - - mov ebx, edi - sub ebx, viewH - shr ebx, 1 - mov offsetY, ebx - - ; Ýêðàííûå êîîðäèíàòû ëåâîãî âåðõíåãî óãëà êëèåíòñêîé îáëàñòè - mov dword ptr ptScreen[0], 0 - mov dword ptr ptScreen[4], 0 - lea eax, ptScreen - invoke ClientToScreen, h3DWnd, eax - - ; conW = viewW * 280 / 320 (âíóòðåííåå îêíî áåçåëÿ) - mov eax, viewW - imul eax, 280 - xor edx, edx - mov ecx, 320 - div ecx - mov conW, eax - - ; conH = viewH * 168 / 240 - mov eax, viewH - imul eax, 168 - xor edx, edx - mov ecx, 240 - div ecx - mov conH, eax - - ; conX = ptScreen.x + offsetX + (viewW * 20 / 320) - mov eax, viewW - imul eax, 20 - xor edx, edx - mov ecx, 320 - div ecx - add eax, offsetX - add eax, dword ptr ptScreen[0] - mov conX, eax - - ; conY = ptScreen.y + offsetY + (viewH * 38 / 240) - mov eax, viewH - imul eax, 38 - xor edx, edx - mov ecx, 240 - div ecx - add eax, offsetY - add eax, dword ptr ptScreen[4] - mov conY, eax - - ; Ïîçèöèîíèðóåì áåçðàìî÷íûé ýêðàí òî÷íî âíóòðü çîëîòîé ðàìêè áåçåëÿ - invoke SetWindowPos, conWnd, 0, conX, conY, conW, conH, 20h or 40h ; SWP_FRAMECHANGED | SWP_SHOWWINDOW - jmp set_con_focus - -show_con_fallback: - invoke ShowWindow, conWnd, 5 ; SW_SHOW -set_con_focus: - invoke SetForegroundWindow, conWnd - invoke SetFocus, conWnd - -run_game_body: - invoke PlayCasinoSound3D, 0, 0, 0 - call InitSounds - ; Çàïóñê îðèãèíàëüíîé èãðû! - call pGameProc - call CloseLegacySounds3D - - ; Çàêðûâàåì êîíñîëü - invoke FreeConsole - mov hOut, 0 - mov hIn, 0 - - ; Âîçâðàùàåì ôîêóñ â îêíî 3D èãðû - cmp h3DWnd, 0 - je cleanup_game_input - invoke SetForegroundWindow, h3DWnd - invoke SetFocus, h3DWnd - -cleanup_game_input: - mov ecx, 256 - xor eax, eax - lea edi, keys3D - rep stosb - mov ecx, 256 - lea edi, pressedKeys3D - rep stosb - - invoke GetTickCount - mov previousTick3D, eax - mov frameStart3D, eax - mov deltaTime3D, 0 - - call SaveProgress3D - -launch_ret: - ret -LaunchClassicGame ENDP - -Trigger3DInteraction PROC - call TriggerHallInteraction3D - test eax, eax - jnz trigger_done - mov eax, interactTargetId - test eax, eax - jz trigger_done - - cmp eax, INTERACT_DANCER - jne check_target_bj - cmp bankroll, 100 - jl dancer_no_cash - sub bankroll, 100 - inc dancerLuckBuff - invoke CopyString3D, OFFSET textTips3D, OFFSET flashMessage - mov flashTimer, 100 - invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 - ret -dancer_no_cash: - invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage - mov flashTimer, 60 - ret - -check_target_bj: - cmp eax, INTERACT_BLACKJACK - jne check_target_poker - call InitNativeBlackjack3D - mov engineMode, MODE_BLACKJACK - ret - -check_target_poker: - cmp eax, INTERACT_POKER - jne check_target_durak - call InitNativePoker3D - test eax, eax - jz target_unported - mov engineMode, MODE_POKER - ret - -check_target_durak: - cmp eax, INTERACT_DURAK - jne check_target_slots777 - call InitNativeDurak3D - mov engineMode, MODE_DURAK - ret - -check_target_slots777: - cmp eax, INTERACT_SLOTS_777 - jne check_target_slots_clover - call InitNativeSlots3D - test eax,eax - jz target_unported - mov engineMode,MODE_SLOTS - ret - -check_target_slots_clover: - cmp eax, INTERACT_SLOTS_CLOVER - jne check_target_roulette - call BeginUnavailable3D - ret - -check_target_roulette: - cmp eax, INTERACT_ROULETTE - jne check_target_dice - call InitNativeWheel3D - mov engineMode, MODE_ROULETTE - ret - -check_target_dice: - cmp eax, INTERACT_DICE - jne check_target_skulls - call InitDiceGame - mov engineMode, MODE_DICE - ret - -check_target_skulls: - cmp eax, INTERACT_SKULLS - jne check_target_coin - call InitSkullsGame - mov engineMode, MODE_SKULLS - ret - -check_target_coin: - cmp eax, INTERACT_COIN - jne check_target_skill - call InitCoinGame - mov engineMode, MODE_COIN - ret - -check_target_skill: - cmp eax, INTERACT_SKILL_CHECK - jne check_target_buckshot - call InitSkillGame - mov engineMode, MODE_SKILL - ret - -check_target_buckshot: - cmp eax, INTERACT_BUCKSHOT - jne check_target_rr - call InitBuckshot3D - mov engineMode, MODE_BUCKSHOT - ret - -check_target_rr: - cmp eax, INTERACT_RUSSIAN_ROULETTE - jne check_target_online_rr - call InitRussianGame3D - test eax, eax - jz @F - mov engineMode, MODE_RUSSIAN -@@: - ret - -check_target_online_rr: - cmp eax, INTERACT_ONLINE_RR - jne check_target_umamusume - call BeginUnavailable3D - ret - -check_target_umamusume: - cmp eax, INTERACT_UMAMUSUME - jne check_target_hell - call BeginUnavailable3D - ret - -check_target_hell: - cmp eax, INTERACT_HELL_TOWER - jne check_target_shop - call BeginUnavailable3D - ret - -check_target_shop: - cmp eax, INTERACT_SHOP - jne check_target_atm - call BeginMerchant3D - ret - -check_target_atm: - cmp eax, INTERACT_ATM - jne check_target_terminal - mov engineMode, MODE_ATM - ret - -check_target_terminal: - cmp eax, INTERACT_TERMINAL - jne check_target_observer - call BeginUnavailable3D - ret - -check_target_observer: - cmp eax, INTERACT_OBSERVER - jne target_unported - call BeginUnavailable3D - ret - -target_unported: - call BeginUnavailable3D -trigger_done: - ret -Trigger3DInteraction ENDP - -; --- Engine Initialization --- -Init3DEngine PROC - local screenCX:DWORD - local screenCY:DWORD - local posX:DWORD - local posY:DWORD - local bytesRead:DWORD - - push ebx - push esi - push edi - - call LoadDisplaySettings3D - call Create3DWindow - test eax, eax - jz init_failed - call LoadTextures3D - test eax, eax - jz init_failed - - call InitializeCasinoSprites3D - - call InitHall3D - call BeginStartup3D - call RenderStartup3D - invoke ShowWindow, h3DWnd, SW_SHOW - invoke UpdateWindow, h3DWnd - invoke SetForegroundWindow, h3DWnd - mov eax, 1 - jmp init_return -init_failed: - xor eax, eax -init_return: - pop edi - pop esi - pop ebx - ret -Init3DEngine ENDP - -InitializeCasinoSprites3D PROC -init_sprites_table: - ; Sprite 0: VIP Dancer 1 (Stage Left) - mov casinoSprites[0*SIZEOF SpriteObject].posX, (13 * FP_1 + FP_HALF) - mov casinoSprites[0*SIZEOF SpriteObject].posY, (4 * FP_1) - mov casinoSprites[0*SIZEOF SpriteObject].baseTexId, 10 - mov casinoSprites[0*SIZEOF SpriteObject].frameCount, 12 - mov casinoSprites[0*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[0*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[0*SIZEOF SpriteObject].animSpeed, 5 - mov casinoSprites[0*SIZEOF SpriteObject].interactId, INTERACT_DANCER - mov casinoSprites[0*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer - - ; Sprite 1: VIP Dancer 2 (Center Stage Star) - mov casinoSprites[1*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF) - mov casinoSprites[1*SIZEOF SpriteObject].posY, (3 * FP_1 + FP_HALF) - mov casinoSprites[1*SIZEOF SpriteObject].baseTexId, 10 - mov casinoSprites[1*SIZEOF SpriteObject].frameCount, 12 - mov casinoSprites[1*SIZEOF SpriteObject].curFrame, 2 - mov casinoSprites[1*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[1*SIZEOF SpriteObject].animSpeed, 5 - mov casinoSprites[1*SIZEOF SpriteObject].interactId, INTERACT_DANCER - mov casinoSprites[1*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer - - ; Sprite 2: VIP Dancer 3 (Stage Right) - mov casinoSprites[2*SIZEOF SpriteObject].posX, (19 * FP_1 + FP_HALF) - mov casinoSprites[2*SIZEOF SpriteObject].posY, (4 * FP_1) - mov casinoSprites[2*SIZEOF SpriteObject].baseTexId, 10 - mov casinoSprites[2*SIZEOF SpriteObject].frameCount, 12 - mov casinoSprites[2*SIZEOF SpriteObject].curFrame, 1 - mov casinoSprites[2*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[2*SIZEOF SpriteObject].animSpeed, 5 - mov casinoSprites[2*SIZEOF SpriteObject].interactId, INTERACT_DANCER - mov casinoSprites[2*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer - - ; Sprite 3: VIP Blackjack (Front Center Left) - mov casinoSprites[3*SIZEOF SpriteObject].posX, (12 * FP_1 + FP_HALF) - mov casinoSprites[3*SIZEOF SpriteObject].posY, (8 * FP_1) - mov casinoSprites[3*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[3*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[3*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[3*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[3*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[3*SIZEOF SpriteObject].interactId, INTERACT_BLACKJACK - mov casinoSprites[3*SIZEOF SpriteObject].promptPtr, OFFSET promptBlackjack - - ; Sprite 4: European Roulette Table (Front Center) - mov casinoSprites[4*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF) - mov casinoSprites[4*SIZEOF SpriteObject].posY, (10 * FP_1) - mov casinoSprites[4*SIZEOF SpriteObject].baseTexId, 31 - mov casinoSprites[4*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[4*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[4*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[4*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[4*SIZEOF SpriteObject].interactId, INTERACT_ROULETTE - mov casinoSprites[4*SIZEOF SpriteObject].promptPtr, OFFSET promptCasinoRoulette - - ; Sprite 5: Texas Hold'em Poker Table (Front Center Right) - mov casinoSprites[5*SIZEOF SpriteObject].posX, (20 * FP_1 + FP_HALF) - mov casinoSprites[5*SIZEOF SpriteObject].posY, (8 * FP_1) - mov casinoSprites[5*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[5*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[5*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[5*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[5*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[5*SIZEOF SpriteObject].interactId, INTERACT_POKER - mov casinoSprites[5*SIZEOF SpriteObject].promptPtr, OFFSET promptPoker - - ; Sprite 6: Podkidnoy Durak Card Table - mov casinoSprites[6*SIZEOF SpriteObject].posX, (24 * FP_1 + FP_HALF) - mov casinoSprites[6*SIZEOF SpriteObject].posY, (8 * FP_1) - mov casinoSprites[6*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[6*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[6*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[6*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[6*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[6*SIZEOF SpriteObject].interactId, INTERACT_DURAK - mov casinoSprites[6*SIZEOF SpriteObject].promptPtr, OFFSET promptDurak - - ; Sprite 7: Classic Slots 777 (West Arcade 1) - mov casinoSprites[7*SIZEOF SpriteObject].posX, (6 * FP_1) - mov casinoSprites[7*SIZEOF SpriteObject].posY, (8 * FP_1) - mov casinoSprites[7*SIZEOF SpriteObject].baseTexId, 24 - mov casinoSprites[7*SIZEOF SpriteObject].frameCount, 3 - mov casinoSprites[7*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[7*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[7*SIZEOF SpriteObject].animSpeed, 8 - mov casinoSprites[7*SIZEOF SpriteObject].interactId, INTERACT_SLOTS_777 - mov casinoSprites[7*SIZEOF SpriteObject].promptPtr, OFFSET promptClassicSlot - - ; Sprite 8: CloverPit Slots 5x3 (West Arcade 2) - mov casinoSprites[8*SIZEOF SpriteObject].posX, (6 * FP_1) - mov casinoSprites[8*SIZEOF SpriteObject].posY, (11 * FP_1) - mov casinoSprites[8*SIZEOF SpriteObject].baseTexId, 24 - mov casinoSprites[8*SIZEOF SpriteObject].frameCount, 3 - mov casinoSprites[8*SIZEOF SpriteObject].curFrame, 1 - mov casinoSprites[8*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[8*SIZEOF SpriteObject].animSpeed, 8 - mov casinoSprites[8*SIZEOF SpriteObject].interactId, INTERACT_SLOTS_CLOVER - mov casinoSprites[8*SIZEOF SpriteObject].promptPtr, OFFSET promptCloverSlot - - ; Sprite 9: Craps & Dice Table (West Arcade 3) - mov casinoSprites[9*SIZEOF SpriteObject].posX, (6 * FP_1) - mov casinoSprites[9*SIZEOF SpriteObject].posY, (14 * FP_1) - mov casinoSprites[9*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[9*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[9*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[9*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[9*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[9*SIZEOF SpriteObject].interactId, INTERACT_DICE - mov casinoSprites[9*SIZEOF SpriteObject].promptPtr, OFFSET promptDice - - ; Sprite 10: Skulls & Cups Table - mov casinoSprites[10*SIZEOF SpriteObject].posX, (10 * FP_1) - mov casinoSprites[10*SIZEOF SpriteObject].posY, (15 * FP_1) - mov casinoSprites[10*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[10*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[10*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[10*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[10*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[10*SIZEOF SpriteObject].interactId, INTERACT_SKULLS - mov casinoSprites[10*SIZEOF SpriteObject].promptPtr, OFFSET promptSkulls - - ; Sprite 11: Coin Toss Stand - mov casinoSprites[11*SIZEOF SpriteObject].posX, (14 * FP_1) - mov casinoSprites[11*SIZEOF SpriteObject].posY, (15 * FP_1) - mov casinoSprites[11*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[11*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[11*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[11*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[11*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[11*SIZEOF SpriteObject].interactId, INTERACT_COIN - mov casinoSprites[11*SIZEOF SpriteObject].promptPtr, OFFSET promptCoin - - ; Sprite 12: Skill Check Stand - mov casinoSprites[12*SIZEOF SpriteObject].posX, (18 * FP_1) - mov casinoSprites[12*SIZEOF SpriteObject].posY, (15 * FP_1) - mov casinoSprites[12*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[12*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[12*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[12*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[12*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[12*SIZEOF SpriteObject].interactId, INTERACT_SKILL_CHECK - mov casinoSprites[12*SIZEOF SpriteObject].promptPtr, OFFSET promptSkillCheck - - ; Sprite 13: Umamusume Derby Lounge - mov casinoSprites[13*SIZEOF SpriteObject].posX, (22 * FP_1) - mov casinoSprites[13*SIZEOF SpriteObject].posY, (15 * FP_1) - mov casinoSprites[13*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[13*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[13*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[13*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[13*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[13*SIZEOF SpriteObject].interactId, INTERACT_UMAMUSUME - mov casinoSprites[13*SIZEOF SpriteObject].promptPtr, OFFSET promptUmamusume - - ; Sprite 14: Boutique & Shop (East Wing) - mov casinoSprites[14*SIZEOF SpriteObject].posX, (26 * FP_1) - mov casinoSprites[14*SIZEOF SpriteObject].posY, (12 * FP_1) - mov casinoSprites[14*SIZEOF SpriteObject].baseTexId, 32 - mov casinoSprites[14*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[14*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[14*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[14*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[14*SIZEOF SpriteObject].interactId, INTERACT_SHOP - mov casinoSprites[14*SIZEOF SpriteObject].promptPtr, OFFSET promptShop - - ; Sprite 15: Cashier & ATM (East Wing) - mov casinoSprites[15*SIZEOF SpriteObject].posX, (26 * FP_1) - mov casinoSprites[15*SIZEOF SpriteObject].posY, (16 * FP_1) - mov casinoSprites[15*SIZEOF SpriteObject].baseTexId, 33 - mov casinoSprites[15*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[15*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[15*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[15*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[15*SIZEOF SpriteObject].interactId, INTERACT_ATM - mov casinoSprites[15*SIZEOF SpriteObject].promptPtr, OFFSET promptATM - - ; Sprite 16: Player Terminal (East Wing) - mov casinoSprites[16*SIZEOF SpriteObject].posX, (26 * FP_1) - mov casinoSprites[16*SIZEOF SpriteObject].posY, (20 * FP_1) - mov casinoSprites[16*SIZEOF SpriteObject].baseTexId, 33 - mov casinoSprites[16*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[16*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[16*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[16*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[16*SIZEOF SpriteObject].interactId, INTERACT_TERMINAL - mov casinoSprites[16*SIZEOF SpriteObject].promptPtr, OFFSET promptPlayerTerminal - - ; Sprite 17: Buckshot Roulette (South-West) - mov casinoSprites[17*SIZEOF SpriteObject].posX, (12 * FP_1) - mov casinoSprites[17*SIZEOF SpriteObject].posY, (22 * FP_1) - mov casinoSprites[17*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[17*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[17*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[17*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[17*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[17*SIZEOF SpriteObject].interactId, INTERACT_BUCKSHOT - mov casinoSprites[17*SIZEOF SpriteObject].promptPtr, OFFSET promptBuckshot - - ; Sprite 18: Observer Lounge (South-East) - mov casinoSprites[18*SIZEOF SpriteObject].posX, (20 * FP_1) - mov casinoSprites[18*SIZEOF SpriteObject].posY, (22 * FP_1) - mov casinoSprites[18*SIZEOF SpriteObject].baseTexId, 30 - mov casinoSprites[18*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[18*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[18*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[18*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[18*SIZEOF SpriteObject].interactId, INTERACT_OBSERVER - mov casinoSprites[18*SIZEOF SpriteObject].promptPtr, OFFSET promptObserver - - ; Sprite 19: Russian Roulette (Backroom Entrance) - mov casinoSprites[19*SIZEOF SpriteObject].posX, (16 * FP_1) - mov casinoSprites[19*SIZEOF SpriteObject].posY, (25 * FP_1) - mov casinoSprites[19*SIZEOF SpriteObject].baseTexId, 34 - mov casinoSprites[19*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[19*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[19*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[19*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[19*SIZEOF SpriteObject].interactId, INTERACT_RUSSIAN_ROULETTE - mov casinoSprites[19*SIZEOF SpriteObject].promptPtr, OFFSET promptRussianRoulette - - ; Sprite 20: Online Russian Roulette (Backroom Secret Terminal) - mov casinoSprites[20*SIZEOF SpriteObject].posX, (18 * FP_1) - mov casinoSprites[20*SIZEOF SpriteObject].posY, (25 * FP_1) - mov casinoSprites[20*SIZEOF SpriteObject].baseTexId, 34 - mov casinoSprites[20*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[20*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[20*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[20*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[20*SIZEOF SpriteObject].interactId, INTERACT_ONLINE_RR - mov casinoSprites[20*SIZEOF SpriteObject].promptPtr, OFFSET promptOnlineRR - - ; Sprite 21: Hell Tower Portal (South Wing Deep End) - mov casinoSprites[21*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF) - mov casinoSprites[21*SIZEOF SpriteObject].posY, (29 * FP_1) - mov casinoSprites[21*SIZEOF SpriteObject].baseTexId, 4 - mov casinoSprites[21*SIZEOF SpriteObject].frameCount, 1 - mov casinoSprites[21*SIZEOF SpriteObject].curFrame, 0 - mov casinoSprites[21*SIZEOF SpriteObject].animTimer, 0 - mov casinoSprites[21*SIZEOF SpriteObject].animSpeed, 1 - mov casinoSprites[21*SIZEOF SpriteObject].interactId, INTERACT_HELL_TOWER - mov casinoSprites[21*SIZEOF SpriteObject].promptPtr, OFFSET promptHellTower - ret -InitializeCasinoSprites3D ENDP - -include src_graphics\audio_code.inc -include src_graphics\dice_animation.inc -include src_graphics\russian_roulette.inc -include src_graphics\startup_code.inc -include src_graphics\card_table_assets.inc -include src_graphics\poker_evaluator.inc -include src_graphics\native_poker.inc -include src_graphics\native_blackjack.inc -include src_graphics\native_durak.inc -include src_graphics\card_tables_render.inc -include src_graphics\durak_render.inc -include src_graphics\card_table_input.inc -include src_graphics\scene_animation.inc -include src_graphics\native_slots.inc -include src_graphics\native_coin.inc -include src_graphics\graphic_profiles.inc -include src_graphics\city_arrival_scene.inc -include src_graphics\arrival_scene.inc -include src_graphics\merchant_scene.inc -include src_graphics\hall_scene.inc -include src_graphics\native_wheel.inc -include src_graphics\billiards.inc -include src_graphics\buckshot.inc -include src_graphics\russian_table.inc -include src_graphics\unavailable.inc - -; --- Main Loop of the 3D Casino Engine --- -StartCasino3D PROC uses ebx esi edi - call Init3DEngine - test eax, eax - jz engine_shutdown - invoke GetTickCount - mov rngSeed3D, eax - mov previousTick3D, eax -engine_loop: - invoke PeekMessageA, OFFSET msg3D, 0, 0, 0, PM_REMOVE - test eax, eax - jz dispatch_frame - cmp msg3D.message, WM_QUIT - je engine_shutdown - invoke TranslateMessage, OFFSET msg3D - invoke DispatchMessageA, OFFSET msg3D - jmp engine_loop - -dispatch_frame: - invoke GetTickCount - mov frameStart3D, eax - sub eax, previousTick3D - cmp eax, 50 - jbe @F - mov eax, 50 -@@: - mov deltaTime3D, eax - mov eax, frameStart3D - mov previousTick3D, eax - invoke GetForegroundWindow - cmp eax, h3DWnd - jne engine_idle - invoke IsIconic, h3DWnd - test eax, eax - jnz engine_idle - invoke Pressed3D, 7Ah - test eax, eax - jz @F - call ToggleFullscreen3D -@@: - invoke Pressed3D, 1Bh - test eax, eax - jz engine_tick - cmp engineMode, MODE_INTRO - jne @F - call FinishStartup3D - jmp engine_tick -@@: - cmp engineMode, MODE_ARRIVAL - jne @F - call ArrivalEscape3D - jmp engine_tick -@@: - cmp engineMode, MODE_WALK - jne leave_table - xor paused3D, 1 - jmp engine_tick -leave_table: - call CardTableEscape3D - test eax, eax - jnz engine_tick - call TableBusy3D - test eax, eax - jz leave_idle_table - xor paused3D, 1 - call ClearKeys3D - jmp engine_tick -leave_idle_table: - mov paused3D, 0 - mov engineMode, MODE_WALK - call ClearKeys3D - invoke PlayCasinoSound3D, 0, 0, 0 -engine_tick: - cmp paused3D, 0 - jne draw_pause - mov eax, deltaTime3D - add animationClock3D, eax - cmp engineMode, MODE_INTRO - jne check_arrival_mode - call HandleStartupInput3D - cmp engineMode, MODE_INTRO - jne check_arrival_mode - call RenderStartup3D - jmp present_frame -check_arrival_mode: - cmp engineMode, MODE_ARRIVAL - jne check_walk_mode - call HandleArrival3D - cmp engineMode, MODE_WALK - je check_walk_mode - call RenderArrival3D - jmp present_frame -check_walk_mode: - cmp engineMode, MODE_WALK - jne check_slots_mode - call UpdateHall3D - call UpdateCamera3D - call CheckInteractions - call HandlePlayerInput - call UpdateCamera3D - call RenderCeilingAndFloor - call RenderWalls - call PrepareCityDepth3D - call RenderSprites - call RenderHall3D - call RenderHUD - call RenderMinimap - jmp present_frame -check_slots_mode: - cmp engineMode, MODE_UNAVAILABLE - jne @F - call HandleUnavailable3D - call RenderUnavailable3D - jmp present_frame -@@: - cmp engineMode, MODE_POOL - jne @F - call HandlePool3D - call RenderPool3D - jmp present_frame -@@: - cmp engineMode, MODE_BAR - jne @F - call HandleBar3D - call RenderBar3D - jmp present_frame -@@: - cmp engineMode, MODE_STAIRS - jne @F - call HandleStairs3D - call RenderStairs3D - jmp present_frame -@@: - cmp engineMode, MODE_SLOTS - jne check_bj_mode - call HandleNativeSlots3D - cmp engineMode,MODE_WALK - je check_walk_mode - call RenderNativeSlots3D - jmp present_frame -check_bj_mode: - cmp engineMode, MODE_BLACKJACK - jne check_poker_mode - call HandleNativeBlackjack3D - cmp engineMode, MODE_WALK - je check_walk_mode - call RenderNativeBlackjack3D - jmp present_frame -check_poker_mode: - cmp engineMode, MODE_POKER - jne check_durak_mode - call HandleNativePoker3D - cmp engineMode, MODE_WALK - je check_walk_mode - call RenderNativePoker3D - jmp present_frame -check_durak_mode: - cmp engineMode, MODE_DURAK - jne check_roul_mode - call HandleNativeDurak3D - cmp engineMode, MODE_WALK - je check_walk_mode - call RenderNativeDurak3D - jmp present_frame -check_roul_mode: - cmp engineMode, MODE_ROULETTE - jne check_shop_mode - call HandleNativeWheel3D - call RenderNativeWheel3D - jmp present_frame -check_shop_mode: - cmp engineMode, MODE_SHOP - jne check_atm_mode - call HandleMerchant3D - call RenderMerchant3D - jmp present_frame -check_atm_mode: - cmp engineMode, MODE_ATM - jne check_coin_mode - call HandleATMInput - call RenderATMGame - jmp present_frame -check_coin_mode: - cmp engineMode, MODE_COIN - jne check_dice_mode - call HandleCoinInput - call RenderCoinGame - jmp present_frame -check_dice_mode: - cmp engineMode, MODE_DICE - jne check_skulls_mode - call HandleDiceInput - call RenderDiceGame - jmp present_frame -check_skulls_mode: - cmp engineMode, MODE_SKULLS - jne check_skill_mode - call HandleSkullsInput - call RenderSkullsGame - jmp present_frame -check_skill_mode: - cmp engineMode, MODE_SKILL - jne check_buckshot_mode - call HandleSkillInput - call RenderSkillGame - jmp present_frame -check_buckshot_mode: - cmp engineMode, MODE_BUCKSHOT - jne check_russian_mode - call HandleBuckshot3D - call RenderBuckshot3D - jmp present_frame -check_russian_mode: - cmp engineMode, MODE_RUSSIAN - jne present_frame - call HandleRussianInput3D - call RenderRussianGame3D - jmp present_frame -draw_pause: - invoke DrawBoxBorder, 28, 36, 264, 168, 00151C21h, 00D8BC6Ah, 2 - invoke DrawString8x8, 44, 48, OFFSET textPause3D, 00FFFFFFh - cmp displayFill3D, 0 - je @F - invoke DrawString8x8, 44, 72, OFFSET textDisplayFill3D, 00D8BC6Ah - jmp pause_draw_quality -@@: - invoke DrawString8x8, 44, 72, OFFSET textDisplayFit3D, 00D8BC6Ah -pause_draw_quality: - invoke DrawString8x8, 44, 92, OFFSET textLowSpec3D, 00D8BC6Ah - mov eax, settingsLowSpec - cmp eax, 0 - jne @F - mov edx, OFFSET textLowSpecOff3D - jmp pause_draw_quality_value -@@: - cmp eax, 1 - jne @F - mov edx, OFFSET textLowSpecEco3D - jmp pause_draw_quality_value -@@: - mov edx, OFFSET textLowSpecQuiet3D -pause_draw_quality_value: - invoke DrawString8x8, 208, 92, edx, 00FFFFFFh - invoke DrawString8x8, 44, 112, OFFSET textVolumeKeys3D, 00D8BC6Ah - invoke DrawString8x8, 44, 130, OFFSET textSoundLevel3D, 00BBBBBBh - invoke FormatNumber, settingsVolume, OFFSET hudNumBuffer - invoke DrawString8x8, 124, 130, OFFSET hudNumBuffer, 00FFFFFFh - invoke DrawString8x8, 44, 150, OFFSET textFullscreenKey3D, 00A0A0A0h - invoke DrawString8x8, 44, 170, OFFSET textResume3D, 00D8BC6Ah - invoke DrawString8x8, 44, 188, OFFSET textQuit3D, 00BBBBBBh - invoke Pressed3D, 31h - test eax, eax - jz @F - xor displayFill3D, 1 - call SaveDisplaySettings3D -@@: - invoke Pressed3D, 32h - test eax, eax - jz @F - inc settingsLowSpec - cmp settingsLowSpec, 3 - jb pause_low_spec_saved - mov settingsLowSpec, 0 -pause_low_spec_saved: - call SaveProgress3D -@@: - invoke Pressed3D, 0BBh - test eax, eax - jz @F - cmp settingsVolume, 10 - jae @F - inc settingsVolume - call ApplySoundVolume - call SaveProgress3D -@@: - invoke Pressed3D, 0BDh - test eax, eax - jz @F - mov eax, settingsVolume - test eax, eax - jz @F - dec settingsVolume - call ApplySoundVolume - call SaveProgress3D -@@: - invoke Pressed3D, 51h - test eax, eax - jz @F - call SaveProgress3D - jmp engine_shutdown -present_frame: - mov eax, engineMode - cmp eax, lastPersistMode3D - je @F - cmp eax, MODE_WALK - jne @F - call SaveProgress3D -@@: - mov eax, engineMode - mov lastPersistMode3D, eax - call Present3D - mov mouseClick3D, 0 - lea edi, pressedKeys3D - xor eax, eax - mov ecx, 64 - rep stosd - invoke GetTickCount - sub eax, frameStart3D - mov ecx, 16 - cmp settingsLowSpec, 1 - jne @F - mov ecx, 24 -@@: - cmp settingsLowSpec, 2 - jne @F - mov ecx, 33 -@@: - cmp eax, ecx - jae engine_loop - sub ecx, eax - invoke Sleep, ecx - jmp engine_loop -engine_idle: - invoke Sleep, 50 - jmp engine_loop -engine_shutdown: - call SaveProgress3D - invoke PlayCasinoSound3D, 0, 0, 0 - call FreeRussianAssets3D - call FreeStartupAssets3D - call FreeCardTableAssets3D - call FreeBuckshotAssets3D - call FreeNativeSlots3D - call FreeArrivalAssets3D - cmp h3DDC, 0 - je @F - invoke ReleaseDC, h3DWnd, h3DDC - mov h3DDC, 0 -@@: - cmp h3DWnd, 0 - je @F - invoke DestroyWindow, h3DWnd - mov h3DWnd, 0 -@@: - ret -StartCasino3D ENDP - -include src_graphics\platform_code.inc - -IFDEF CASINO_ACTION_TEST -include tools\tests\casino_actions_test.inc -ENDIF + +; ============================================================================== +; CASINO 2.5D - MASM32 SOFTWARE RAYCASTER (CP1251) +; Graphical migration; this is not id Software's Doom engine. +; ============================================================================== + +includelib gdi32.lib +includelib winmm.lib + +CreateWindowExA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD +RegisterClassExA PROTO :DWORD +DefWindowProcA PROTO :DWORD,:DWORD,:DWORD,:DWORD +ShowWindow PROTO :DWORD,:DWORD +UpdateWindow PROTO :DWORD +GetDC PROTO :DWORD +ReleaseDC PROTO :DWORD,:DWORD +StretchDIBits PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD +PeekMessageA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD +TranslateMessage PROTO :DWORD +DispatchMessageA PROTO :DWORD +PostQuitMessage PROTO :DWORD +DestroyWindow PROTO :DWORD +SetWindowTextA PROTO :DWORD,:DWORD +SetForegroundWindow PROTO :DWORD +GetConsoleWindow PROTO +GetSystemMetrics PROTO :DWORD +CreateFileA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD +ReadFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD +CloseHandle PROTO :DWORD +GetAsyncKeyState PROTO :DWORD +PlaySoundA PROTO :DWORD,:DWORD,:DWORD +GetModuleFileNameA PROTO :DWORD,:DWORD,:DWORD +CopyFileA PROTO :DWORD,:DWORD,:DWORD +lstrcmpiA PROTO :DWORD,:DWORD +GetFileSize PROTO :DWORD,:DWORD +Sleep PROTO :DWORD + +C3D_POINT STRUCT + x dd ? + y dd ? +C3D_POINT ENDS + +C3D_MSG STRUCT + hwnd dd ? + message dd ? + wParam dd ? + lParam dd ? + time dd ? + pt C3D_POINT <> +C3D_MSG ENDS + +C3D_WNDCLASSEX STRUCT + cbSize dd ? + style dd ? + lpfnWndProc dd ? + cbClsExtra dd ? + cbWndExtra dd ? + hInstance dd ? + hIcon dd ? + hCursor dd ? + hbrBackground dd ? + lpszMenuName dd ? + lpszClassName dd ? + hIconSm dd ? +C3D_WNDCLASSEX ENDS + +C3D_BITMAPINFOHEADER STRUCT + biSize dd ? + biWidth dd ? + biHeight dd ? + biPlanes dw ? + biBitCount dw ? + biCompression dd ? + biSizeImage dd ? + biXPelsPerMeter dd ? + biYPelsPerMeter dd ? + biClrUsed dd ? + biClrImportant dd ? +C3D_BITMAPINFOHEADER ENDS + +C3D_BITMAPINFO STRUCT + bmiHeader C3D_BITMAPINFOHEADER <> + bmiColors dd ? +C3D_BITMAPINFO ENDS + +SpriteObject STRUCT + posX dd ? + posY dd ? + baseTexId dd ? + frameCount dd ? + curFrame dd ? + animTimer dd ? + animSpeed dd ? + interactId dd ? + promptPtr dd ? + distSq dd ? +SpriteObject ENDS + +SCREEN_W equ 640 +SCREEN_H equ 480 +HALF_W equ 320 +HALF_H equ 240 +SCREEN_SIZE equ (SCREEN_W * SCREEN_H) +WIN_SCALE equ 1 +WINDOW_W equ (SCREEN_W * WIN_SCALE) +WINDOW_H equ (SCREEN_H * WIN_SCALE) + +FP_1 equ 65536 +FP_HALF equ 32768 +CHROMA_KEY equ 00FF00FFh + +MODE_WALK equ 0 +MODE_SLOTS equ 1 +MODE_BLACKJACK equ 2 +MODE_ROULETTE equ 3 +MODE_SHOP equ 4 +MODE_ATM equ 5 +MODE_COIN equ 6 +MODE_DICE equ 7 +MODE_SKULLS equ 8 +MODE_SKILL equ 9 + +WS_OVERLAPPEDWINDOW equ 00CF0000h +SW_SHOW equ 5 +SW_HIDE equ 0 +PM_REMOVE equ 1 +WM_DESTROY equ 0002h +WM_CLOSE equ 0010h +WM_QUIT equ 0012h +CS_HREDRAW equ 2 +CS_VREDRAW equ 1 +DIB_RGB_COLORS equ 0 +SRCCOPY equ 00CC0020h +INVALID_FILE_HANDLE equ -1 + +include casino3d_data.inc +include font8x8.inc +include src_graphics\platform_data.inc +include src_graphics\casino_actions_data.inc +include src_graphics\audio_data.inc +include src_graphics\startup_data.inc +include src_graphics\card_tables_data.inc +include src_graphics\native_durak_data.inc +include src_graphics\scene_animation_data.inc +include src_graphics\arrival_data.inc +include src_graphics\city_arrival_data.inc +include src_graphics\merchant_data.inc +include src_graphics\hall_data.inc +include src_graphics\npc_mind_data.inc +include src_graphics\npc_life_data.inc +include src_graphics\native_wheel_data.inc +include src_graphics\billiards_data.inc +include src_graphics\buckshot_data.inc +include src_graphics\russian_view_data.inc +include src_graphics\unavailable_data.inc +include src_graphics\native_slots_data.inc +include src_graphics\native_clover_data.inc +include src_graphics\native_coin_data.inc + +.data +ALIGN 4 +h3DInst dd 0 +h3DWnd dd 0 +h3DDC dd 0 +hCasinoConsole dd 0 + +bmi3D C3D_BITMAPINFO <> +msg3D C3D_MSG <> +wc3D C3D_WNDCLASSEX <> + +sz3DClassName db "Casino3DRetroClass",0 +sz3DWindowTitle db 192,241,241,229,236,225,235,229,240,32,202,224,231,232,237,238,32,45,32,50,46,53,68,0 +szTexturesRelPath db "assets\textures\casino3d-hd.bin",0 +szTexturesFullPath db 260 dup(0) + + +playerX dd (16 * FP_1 + FP_HALF) +playerY dd (16 * FP_1 + FP_HALF) +playerAngle dd 384 +playerDirX dd 0 +playerDirY dd -FP_1 +playerPlaneX dd (FP_1 * 66 / 100) +playerPlaneY dd 0 + +engineMode dd 0 +interactTargetId dd 0 +interactPromptPtr dd 0 +dancerLuckBuff dd 0 +flashTimer dd 0 +flashMessage db 128 dup(0) + +promptDancer db "[E] ÊÀÁÀÐÅ - ×ÀÅÂÛÅ $100",0 +promptBlackjack db "[E] ÁËÝÊÄÆÅÊ (21)",0 +promptPoker db 91,69,93,32,207,206,202,197,208,32,40,210,197,213,192,209,209,202,200,201,32,213,206,203,196,197,204,41,0 +promptDurak db "[E] ÊÀÐÒÛ: ÏÎÄÊÈÄÍÎÉ ÄÓÐÀÊ",0 +promptCasinoRoulette db "[E] ÅÂÐÎÏÅÉÑÊÀß ÐÓËÅÒÊÀ",0 +promptClassicSlot db "[E] ÊËÀÑÑÈ×ÅÑÊÈÅ ÑËÎÒÛ 777",0 +promptCloverSlot db "[E] ÑËÎÒÛ CLOVERPIT (5x3)",0 +promptDice db 91,69,93,32,200,195,208,192,32,194,32,202,206,209,210,200,0 +promptSkulls db "[E] ÍÀϨÐÑÒÊÈ (×ÅÐÅÏÀ)",0 +promptCoin db "[E] ÌÎÍÅÒÊÀ (ÎШË/ÐÅØÊÀ)",0 +promptSkillCheck db "[E] ÒÐÅÍÈÐÎÂÊÀ ÐÅÀÊÖÈÈ",0 +promptBuckshot db 91,69,93,32,193,192,202,216,206,210,32,208,211,203,197,210,202,192,0 +promptRussianRoulette db "[E] ÐÓÑÑÊÀß ÐÓËÅÒÊÀ (VIP)",0 +promptOnlineRR db "[E] ÑÅÒÅÂÀß ÐÓËÅÒÊÀ (NET)",0 +promptUmamusume db "[E] ÑÊÀ×ÊÈ ÓÌÀÌÓÑÓÌÝ",0 +promptHellTower db "[E] ÁÀØÍß ÀÄÀ (10 ÝÒÀÆÅÉ)",0 +promptShop db "[E] ÁÓÒÈÊ È ÒÀËÈÑÌÀÍÛ",0 +promptATM db "[E] ÁÀÍÊÎÌÀÒ È ÁÀËÀÍÑ",0 +promptPlayerTerminal db "[E] ÒÅÐÌÈÍÀË: ÑÒÀÒÛ È À×ÈÂÊÈ",0 +promptObserver db "[E] ÐÅÆÈÌ ÍÀÁËÞÄÀÒÅËß (ÈÈ)",0 + +szTitleBlackjack db 202,192,199,200,202,32,51,68,32,45,32,193,203,221,202,196,198,197,202,32,40,50,49,41,0 +szTitlePoker db 202,192,199,200,202,32,51,68,32,45,32,207,206,202,197,208,32,40,210,197,213,192,209,209,202,200,201,32,213,206,203,196 + db 197,204,41,0 +szTitleDurak db 202,192,199,200,202,32,51,68,32,45,32,207,197,208,197,194,206,196,205,206,201,32,196,211,208,192,202,0 +szTitleCasinoRoulette db 202,192,199,200,202,32,51,68,32,45,32,197,194,208,206,207,197,201,209,202,192,223,32,208,211,203,197,210,202,192,0 +szTitleClassicSlot db 202,192,199,200,202,32,51,68,32,45,32,192,194,210,206,204,192,210,32,55,55,55,0 +szTitleCloverSlot db 202,192,199,200,202,32,51,68,32,45,32,202,203,197,194,197,208,205,192,223,32,223,204,192,32,40,53,120,51,41,0 +szTitleDice db 202,192,199,200,202,32,51,68,32,45,32,200,195,208,192,32,194,32,202,206,209,210,200,0 +szTitleSkulls db 202,192,199,200,202,32,51,68,32,45,32,205,192,207,168,208,209,210,202,200,0 +szTitleCoin db 202,192,199,200,202,32,51,68,32,45,32,204,206,205,197,210,202,192,32,40,206,208,168,203,47,208,197,216,202,192,41,0 +szTitleSkillCheck db 202,192,199,200,202,32,51,68,32,45,32,207,208,206,194,197,208,202,192,32,205,192,194,219,202,192,0 +szTitleBuckshot db 202,192,199,200,202,32,51,68,32,45,32,193,192,202,216,206,210,32,208,211,203,197,210,202,192,0 +szTitleRussianRoulette db 202,192,199,200,202,32,51,68,32,45,32,208,211,209,209,202,192,223,32,208,211,203,197,210,202,192,0 +szTitleOnlineRR db 202,192,199,200,202,32,51,68,32,45,32,209,197,210,197,194,192,223,32,208,211,209,209,202,192,223,32,208,211,203,197,210 + db 202,192,0 +szTitleUmamusume db 202,192,199,200,202,32,51,68,32,45,32,195,206,205,202,200,32,211,204,192,204,211,209,211,204,197,0 +szTitleHellTower db 202,192,199,200,202,32,51,68,32,45,32,192,196,209,202,192,223,32,193,192,216,205,223,0 +szTitleShop db 202,192,199,200,202,32,51,68,32,45,32,202,192,208,210,219,32,200,32,210,192,203,200,209,204,192,205,219,0 +szTitleATM db 202,192,199,200,202,32,51,68,32,45,32,193,192,205,202,206,204,192,210,0 +szTitleTerminal db 202,192,199,200,202,32,51,68,32,45,32,203,206,202,192,203,220,205,219,197,32,207,208,206,212,200,203,200,0 +szTitleObserver db 202,192,199,200,202,32,51,68,32,45,32,205,192,193,203,222,196,192,210,197,203,220,32,40,200,200,41,0 +textCabinetFooter db "[ ÂÛÕÎÄ: ÂÂÅÄÈÒÅ 0 / ÂÛÁÅÐÈÒÅ 'N' ÄËß ÂÎÇÂÐÀÒÀ  ÇÀË ]",0 + +msgDancerTipped db "Âû áðîñèëè $100 òàíöîâùèöå! ÓÄÀ×À ÀÊÒÈÂÈÐÎÂÀÍÀ!",0 +msgNeedMoney db "Íåäîñòàòî÷íî äåíåã â êîøåëüêå!",0 +statusHUDFormat db "ÁÀÍÊÐÎËË: $",0 +targetHUDFormat db " ÖÅËÜ: $",0 +luckHUDFormat db " ÓÄÀ×À: +",0 +controlsHUD db "WASD/Ñòðåëêè: Õîäüáà | E: Äåéñòâèå | ESC: Ìåíþ",0 + +NUM_SPRITES equ 22 + +INTERACT_NONE equ 0 +INTERACT_BLACKJACK equ 1 +INTERACT_POKER equ 2 +INTERACT_SLOTS_777 equ 3 +INTERACT_ROULETTE equ 4 +INTERACT_SKULLS equ 5 +INTERACT_SHOP equ 6 +INTERACT_ATM equ 7 +INTERACT_DANCER equ 8 +INTERACT_HELL_TOWER equ 9 +INTERACT_DURAK equ 10 +INTERACT_BUCKSHOT equ 11 +INTERACT_COIN equ 12 +INTERACT_DICE equ 13 +INTERACT_SLOTS_CLOVER equ 14 +INTERACT_UMAMUSUME equ 15 +INTERACT_OBSERVER equ 16 +INTERACT_TERMINAL equ 17 +INTERACT_ONLINE_RR equ 18 +INTERACT_RUSSIAN_ROULETTE equ 19 +INTERACT_SKILL_CHECK equ 20 +ALIGN 4 +casinoSprites SpriteObject NUM_SPRITES dup(<>) +sortedSprites dd NUM_SPRITES dup(0) + +rowDistTable dd 120 dup(0) +rngSeed3D dd 12345678h + +slotBet dd 50 +slotReel1 dd 0 +slotReel2 dd 1 +slotReel3 dd 2 +slotSpinState dd 0 +slotSpinTimer dd 0 +slotWinAmount dd 0 +slotWinMsg db 64 dup(0) + +bjState dd 0 +bjBet dd 100 +bjPlayerCards dd 10 dup(0) +bjPlayerCardCount dd 0 +bjPlayerScore dd 0 +bjDealerCards dd 10 dup(0) +bjDealerCardCount dd 0 +bjDealerScore dd 0 +bjDealerHideHole dd 1 +bjOutcomeMsg db 64 dup(0) + +roulState dd 0 +roulBetType dd 1 +roulBetAmount dd 100 +roulWheelAngle dd 0 +roulBallAngle dd 0 +roulSpinTimer dd 0 +roulWinningNum dd 0 +roulPayout dd 0 +roulOutcomeMsg db 64 dup(0) + +coinRxAnimTable db 26, 22, 16, 6, 16, 22, 26, 22, 16, 6 + +; --- Native 2.5D Coin Flip --- +coin3d_bet dd 50 +coin3d_choice dd 1 ; 1 = Îð¸ë, 2 = Ðåøêà +coin3d_state dd 0 ; 0 = Idle, 1 = Flipping, 2 = Result +coin3d_timer dd 0 +coin3d_result dd 1 ; 1 = Îð¸ë, 2 = Ðåøêà +coin3d_streak dd 0 +coin3d_win dd 0 + +textCoinTitle db "* * * Ç Î Ë Î Ò À ß Ì Î Í Å Ò À * * *",0 +textCoinHeads db "ÎШË",0 +textCoinTails db "ÐÅØÊÀ",0 +textCoinSide1 db "[1] ÎШË",0 +textCoinSide2 db "[2] ÐÅØÊÀ",0 +textCoinFlipping db "ÌÎÍÅÒÀ  ÏÎ˨ÒÅ...",0 +textCoinWin db "ÏÎÁÅÄÀ: +$",0 +textCoinLose db "ÍÅ ÓÃÀÄÀËÈ!",0 +textCoinStreakFmt db "ÑÅÐÈß ÏÎÁÅÄ: x",0 +textCoinSelected db "ÂÛÁÐÀÍÎ",0 +textCoinKey1 db "[1] ÎШË",0 +textCoinKey2 db "[2] ÐÅØÊÀ",0 +textCoinKeySpace db "[SPACE]",0 + +; --- Native 2.5D Dice Game --- +dice3d_bet dd 50 +dice3d_choice dd 1 ; 1 = ׸ò, 2 = Íå÷åò +dice3d_state dd 0 ; 0 = Idle, 1 = Rolling, 2 = Result +dice3d_timer dd 0 +dice3d_val1 dd 4 +dice3d_val2 dd 6 +dice3d_sum dd 10 +dice3d_win dd 0 + +textDiceTitle db 200,195,208,192,32,194,32,202,206,209,210,200,0 +textDiceEven db "[1] רÒ",0 +textDiceOdd db "[2] ÍÅ×ÅÒ",0 +textDiceEvenNums db "2 4 6 ...",0 +textDiceOddNums db "3 5 7 ...",0 +textDiceSumHdr db "ÑÓÌÌÀ: ",0 +textDicePlus db " + ",0 +textDiceEqual db " = ",0 +textDiceEvenResult db " (רÒ)",0 +textDiceOddResult db " (ÍÅ×ÅÒ)",0 +textDiceRolling db "ÊÎÑÒÈ ËÅÒßÒ ÏÎ ÑÓÊÍÓ...",0 +textDiceWin db "ÂÛÈÃÐÛØ: +$",0 +textDiceWinMult db "! (x2)",0 +textDiceLose db "ÏÐÎÈÃÐÛØ!",0 +textDiceKey1 db "[1] רÒ",0 +textDiceKey2 db "[2] ÍÅ×ÅÒ",0 +textDiceKeySpace db "[SPACE]",0 + +; --- Native 2.5D Skulls Game --- +skulls3d_bet dd 50 +skulls3d_state dd 0 ; 0 = Idle, 1 = Show ball, 2 = Shuffle, 3 = Pick, 4 = Reveal +skulls3d_timer dd 0 +skulls3d_ballPos dd 1 ; 0, 1, 2 +skulls3d_choice dd 1 ; 0, 1, 2 +skulls3d_win dd 0 +skulls3d_swapPair0 dd 0 +skulls3d_swapPair1 dd 1 +skulls3d_swapPair2 dd 2 +skulls3d_cup0 dd 0 +skulls3d_cup1 dd 1 +skulls3d_cup2 dd 2 + +textSkullsTitle db "* * * Í À Ï ¨ Ð Ñ Ò Ê È * * *",0 +textSkullsPhase0 db "ÄÅËÀÉ ÑÒÀÂÊÓ È ÆÌÈ [ÏÐÎÁÅË]",0 +textSkullsPhase1 db "ÑÌÎÒÐÈ, ÃÄÅ ÇÎËÎÒÎÉ ØÀÐ...",0 +textSkullsPhase2 db "ÊÐÓ×Ó, ÂÅÐ×Ó, ÇÀÏÓÒÀÒÜ ÕÎ×Ó...",0 +textSkullsPhase3 db "ÃÄÅ ØÀÐ? ÂÛÁÈÐÀÉ: [1], [2] ÈËÈ [3]!",0 +textSkullsWin db "ÂÛÈÃÐÛØ: +$",0 +textSkullsWinMult db "! (x3) ÂÛ ÓÃÀÄÀËÈ!",0 +textSkullsLose db "ÌÈÌÎ! ØÀÐ ÁÛË Â ÄÐÓÃÎÌ ÌÅÑÒÅ!",0 +textSkullsAgain db "[ÏÐÎÁÅË] - ÑÛÃÐÀÒÜ ÅÙ¨ ÐÀÇ",0 +textSkullsKey1 db "[1]",0 +textSkullsKey2 db "[2]",0 +textSkullsKey3 db "[3]",0 +textSkullsKeySpace db "[SPACE] ÑÒÀÐÒ",0 + +; --- Native 2.5D Skill Check (Dead by Daylight Survivor Check) --- +skill3d_bet dd 50 +skill3d_state dd 0 ; 0=Ready, 1=Active, 2=Hit Result, 3=Miss Result, 4=Escaped, 5=Defeated +skill3d_timer dd 0 +skill3d_needle dd 55 ; Needle X (52..268) +skill3d_speed dd 4 +skill3d_dir dd 1 ; 1=Right, -1=Left +skill3d_zone_start dd 140 +skill3d_zone_width dd 48 +skill3d_great_start dd 176 +skill3d_great_width dd 12 +skill3d_hits dd 0 +skill3d_misses dd 0 +skill3d_last_result dd 0 +skill3d_win_amount dd 0 + +textSkillTitle db 61,61,61,32,207,208,206,194,197,208,202,192,32,205,192,194,219,202,192,32,61,61,61,0 +textSkillHitsHdr db "ÕÈÒ: ",0 +textSkillMissHdr db "ÏÐÎÌÀÕ: ",0 +textSkillReadyMsg db "ÍÀÆÌÈÒÅ [ÏÐÎÁÅË] ÄËß ÑÒÀÐÒÀ",0 +textSkillPrompt db "ÍÀÆÌÈÒÅ [ÏÐÎÁÅË]  ÇÎÍÅ!",0 +textSkillHitMsg db "ÕÈÒ! ÒÎ×ÍÎÅ ÏÎÏÀÄÀÍÈÅ!",0 +textSkillGreatMsg db 206,210,203,200,215,205,206,33,32,43,193,206,205,211,209,33,0 +textSkillMissMsg db "ÏÐÎÌÀÕ! ÒÐÅÂÎÃÀ!",0 +textSkillEscape db "ÏÎÁÅà ÓÑÏÅØÅÍ! ÂÛÈÃÐÛØ: +$",0 +textSkillLost db "ÂÛ ÏÎÉÌÀÍÛ! ÏÐÎÈÃÐÛØ ÑÒÀÂÊÈ!",0 +textSkillKeySpace db "[SPACE] ÐÅÀÊÖÈß",0 +textSkillKeyBet db "[ÂÂÅÐÕ/ÂÍÈÇ]",0 + +; --- Shared UI Strings --- +textKeyEsc db "[ESC]",0 +textBankPrompt db "ÁÀÍÊ: $",0 +textBetPrompt db "ÑÒÀÂÊÀ: $",0 +textBetHint db " [W/S]",0 + +shopMsg db 128 dup(0) +atmMsg db 128 dup(0) + +strWin db "ÏÎÁÅÄÀ! +$",0 +strLose db "ÏÐÎÈÃÐÛØ",0 +strJackpot db "ÄÆÅÊÏÎÒ! +$",0 +strPush db 205,200,215,220,223,0 +strDealerBust db "ÄÈËÅÐ ÏÅÐÅÁÐÀË! ÏÎÁÅÄÀ! +$",0 +strPlayerBust db "ÏÅÐÅÁÎÐ (>21)! ÏÐÎÈÃÐÛØ",0 + +sym7 db " 777 ",0 +symBar db " BAR ",0 +symBell db 32,199,194,206,205,0 +symCherry db 194,200,216,205,223,0 +symClover db 202,203,197,194,197,208,0 +symGem db 192,203,204,192,199,0 +symCrown db 202,206,208,206,205,192,0 + +cardRankStr db "A ",0,"2 ",0,"3 ",0,"4 ",0,"5 ",0,"6 ",0,"7 ",0,"8 ",0,"9 ",0,"10",0,"J ",0,"Q ",0,"K ",0 + +.data? +ALIGN 4 +screenBuffer dd SCREEN_SIZE dup(?) +ALIGN 4 +zBuffer dd SCREEN_W dup(?) +ALIGN 4 +texturesBuffer dd (104 * 128 * 128) dup(?) + +hudNumBuffer db 32 dup(?) + +.code + +; --- 3D Window Procedure --- +Casino3DWndProc PROC hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD + invoke WindowEvents3D, hwnd, uMsg, wParam, lParam + ret +Casino3DWndProc ENDP + +; --- Random Generator --- +RandomRange3D PROC maxVal:DWORD + mov eax, rngSeed3D + imul eax, 1103515245 + add eax, 12345 + mov rngSeed3D, eax + shr eax, 16 + and eax, 7FFFh + xor edx, edx + div maxVal + mov eax, edx + ret +RandomRange3D ENDP + +; --- Copy String --- +CopyString3D PROC src:DWORD, dst:DWORD + push esi + push edi + mov esi, src + mov edi, dst +@@: + mov al, [esi] + mov [edi], al + test al, al + jz @F + inc esi + inc edi + jmp @B +@@: + pop edi + pop esi + ret +CopyString3D ENDP + +; --- Format Number to Decimal String --- +FormatNumber PROC num:DWORD, buf:DWORD + push ebx + push esi + push edi + mov eax, num + mov edi, buf + test eax, eax + jns fn_pos + mov BYTE PTR [edi], '-' + inc edi + neg eax +fn_pos: + mov ebx, 10 + push 0 +fn_div: + xor edx, edx + div ebx + add dl, '0' + push edx + test eax, eax + jnz fn_div +fn_pop: + pop eax + test al, al + jz fn_done + mov [edi], al + inc edi + jmp fn_pop +fn_done: + mov BYTE PTR [edi], 0 + pop edi + pop esi + pop ebx + ret +FormatNumber ENDP + +; --- Fast 2D Drawing Primitives --- +DrawBox PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD + +DrawPixel PROC x:DWORD, y:DWORD, color:DWORD + invoke DrawBox, x, y, 1, 1, color + ret +DrawPixel ENDP + +DrawBox PROC x:DWORD, y:DWORD, w:DWORD, h:DWORD, color:DWORD + shl x, 1 + shl y, 1 + shl w, 1 + shl h, 1 + push ebx + push esi + push edi + mov edi, y +box_row_loop: + mov eax, y + add eax, h + cmp edi, eax + jge box_done + cmp edi, 0 + jl next_box_row + cmp edi, SCREEN_H + jge box_done + + mov esi, x +box_col_loop: + mov eax, x + add eax, w + cmp esi, eax + jge next_box_row + cmp esi, 0 + jl next_box_col + cmp esi, SCREEN_W + jge next_box_row + + mov ecx, edi + imul ecx, SCREEN_W + add ecx, esi + mov edx, color + mov [screenBuffer + ecx*4], edx + +next_box_col: + inc esi + jmp box_col_loop + +next_box_row: + inc edi + jmp box_row_loop + +box_done: + pop edi + pop esi + pop ebx + ret +DrawBox ENDP + +DrawBoxBorder PROC uses ebx x:DWORD, y:DWORD, w:DWORD, h:DWORD, fillColor:DWORD, borderColor:DWORD, bWidth:DWORD + invoke DrawBox, x, y, w, h, borderColor + mov eax, x + add eax, bWidth + mov edx, y + add edx, bWidth + mov ecx, w + sub ecx, bWidth + sub ecx, bWidth + mov ebx, h + sub ebx, bWidth + sub ebx, bWidth + invoke DrawBox, eax, edx, ecx, ebx, fillColor + ret +DrawBoxBorder ENDP + +DrawCircle PROC cxVal:DWORD, cyVal:DWORD, radius:DWORD, color:DWORD + push ebx + push esi + push edi + mov eax, radius + neg eax + mov edi, eax +circ_y: + cmp edi, radius + jg circ_done + mov eax, radius + neg eax + mov esi, eax +circ_x: + cmp esi, radius + jg next_circ_y + + mov eax, esi + imul eax, eax + mov ebx, edi + imul ebx, ebx + add eax, ebx + mov edx, radius + imul edx, edx + cmp eax, edx + jg next_circ_x + + mov eax, cxVal + add eax, esi + mov ecx, cyVal + add ecx, edi + invoke DrawPixel, eax, ecx, color + +next_circ_x: + inc esi + jmp circ_x +next_circ_y: + inc edi + jmp circ_y +circ_done: + pop edi + pop esi + pop ebx + ret +DrawCircle ENDP + +DrawChar8x8 PROC uses ebx esi edi x:DWORD, y:DWORD, chVal:DWORD, color:DWORD + local column:DWORD + mov eax, chVal + and eax, 255 + lea esi, [font8x8 + eax*8] + xor edi, edi +glyph_row: + movzx ebx, BYTE PTR [esi+edi] + mov column, 0 +glyph_col: + test ebx, 80h + jz glyph_next + mov eax, x + add eax, column + mov edx, y + add edx, edi + invoke DrawPixel, eax, edx, color +glyph_next: + shl ebx, 1 + inc column + cmp column, 8 + jl glyph_col + inc edi + cmp edi, 8 + jl glyph_row + ret +DrawChar8x8 ENDP + +DrawString8x8 PROC x:DWORD, y:DWORD, strPtr:DWORD, color:DWORD + push ebx + push esi + mov esi, strPtr + mov ebx, x +str_loop: + movzx eax, BYTE PTR [esi] + test al, al + jz str_done + invoke DrawChar8x8, ebx, y, eax, color + add ebx, 8 + inc esi + jmp str_loop +str_done: + pop esi + pop ebx + ret +DrawString8x8 ENDP + +; --- True 3D Perspective Floor & Ceiling Rendering --- + +; --- DDA Raycasting Walls --- +RenderWalls PROC + local col:DWORD + local originalStart:DWORD + local camX:DWORD + local rayDirX:DWORD + local rayDirY:DWORD + local mapX:DWORD + local mapY:DWORD + local deltaDistX:DWORD + local deltaDistY:DWORD + local stepX:DWORD + local stepY:DWORD + local sideDistX:DWORD + local sideDistY:DWORD + local side:DWORD + local perpWallDist:DWORD + local lineH:DWORD + local drawStart:DWORD + local drawEnd:DWORD + local wallHit:DWORD + local texX:DWORD + local texXHD:DWORD + local pixelMaterial:DWORD + local texId:DWORD + local shade:DWORD + + push ebx + push esi + push edi + + mov eax, playerAngle + and eax, 511 + mov ebx, [tableCos + eax*4] + mov playerDirX, ebx + mov ebx, [tableSin + eax*4] + mov playerDirY, ebx + + mov eax, ebx + imul eax, -66 + cdq + mov ecx, 100 + idiv ecx + mov playerPlaneX, eax + + mov eax, playerDirX + imul eax, 66 + cdq + idiv ecx + mov playerPlaneY, eax + + mov col, 0 +col_loop: + cmp col, SCREEN_W + jge walls_done + + mov eax, col + shl eax, 1 + sub eax, SCREEN_W + imul eax, FP_1 + cdq + mov ecx, SCREEN_W + idiv ecx + mov camX, eax + + mov eax, playerPlaneX + imul camX + shrd eax, edx, 16 + add eax, playerDirX + mov rayDirX, eax + + mov eax, playerPlaneY + imul camX + shrd eax, edx, 16 + add eax, playerDirY + mov rayDirY, eax + + mov eax, playerX + sar eax, 16 + mov mapX, eax + mov eax, playerY + sar eax, 16 + mov mapY, eax + + mov eax, rayDirX + test eax, eax + jnz calc_delta_x + mov deltaDistX, 7FFFFFFFh + jmp calc_delta_y +calc_delta_x: + test eax, eax + jns @F + neg eax +@@: + mov ebx, eax + cmp ebx, 4 + jbe delta_x_clamp + xor eax, eax + mov edx, 1 + div ebx + mov deltaDistX, eax + jmp calc_delta_y +delta_x_clamp: + mov deltaDistX, 7FFFFFFFh + +calc_delta_y: + mov eax, rayDirY + test eax, eax + jnz calc_delta_y_ok + mov deltaDistY, 7FFFFFFFh + jmp check_step +calc_delta_y_ok: + test eax, eax + jns @F + neg eax +@@: + mov ebx, eax + cmp ebx, 4 + jbe delta_y_clamp + xor eax, eax + mov edx, 1 + div ebx + mov deltaDistY, eax + jmp check_step +delta_y_clamp: + mov deltaDistY, 7FFFFFFFh + +check_step: + cmp rayDirX, 0 + jge step_x_pos + mov stepX, -1 + mov eax, playerX + mov edx, mapX + shl edx, 16 + sub eax, edx + imul deltaDistX + shrd eax, edx, 16 + mov sideDistX, eax + jmp check_step_y +step_x_pos: + mov stepX, 1 + mov eax, mapX + inc eax + shl eax, 16 + sub eax, playerX + imul deltaDistX + shrd eax, edx, 16 + mov sideDistX, eax + +check_step_y: + cmp rayDirY, 0 + jge step_y_pos + mov stepY, -1 + mov eax, playerY + mov edx, mapY + shl edx, 16 + sub eax, edx + imul deltaDistY + shrd eax, edx, 16 + mov sideDistY, eax + jmp dda_start +step_y_pos: + mov stepY, 1 + mov eax, mapY + inc eax + shl eax, 16 + sub eax, playerY + imul deltaDistY + shrd eax, edx, 16 + mov sideDistY, eax + +dda_start: + xor ecx, ecx +dda_step_loop: + inc ecx + cmp ecx, 64 + jge wall_map_boundary + + mov eax, sideDistX + cmp eax, sideDistY + jge step_in_y + + mov eax, deltaDistX + add sideDistX, eax + mov eax, stepX + add mapX, eax + mov side, 0 + jmp check_tile + +step_in_y: + mov eax, deltaDistY + add sideDistY, eax + mov eax, stepY + add mapY, eax + mov side, 1 + +check_tile: + cmp mapX, 0 + jl wall_map_boundary + cmp mapX, MAP_WIDTH + jge wall_map_boundary + cmp mapY, 0 + jl wall_map_boundary + cmp mapY, MAP_HEIGHT + jge wall_map_boundary + + mov eax, mapY + shl eax, 5 + add eax, mapX + mov edx, worldMap3D + movzx eax, BYTE PTR [edx + eax] + test eax, eax + jnz hit_wall + jmp dda_step_loop + +wall_map_boundary: + cmp outdoorRender3D, 0 + je hit_wall + mov eax, col + mov zBuffer[eax*4], 7FFFFFFFh + jmp next_col + +hit_wall: + cmp side, 0 + jne perp_y + mov eax, sideDistX + sub eax, deltaDistX + mov perpWallDist, eax + jmp perp_done +perp_y: + mov eax, sideDistY + sub eax, deltaDistY + mov perpWallDist, eax + +perp_done: + cmp perpWallDist, 2048 + jge @F + mov perpWallDist, 2048 +@@: + mov eax, col + mov edx, perpWallDist + mov [zBuffer + eax*4], edx + + ; Unit projection is shared by indoor room height and outdoor storeys. + mov eax, SCREEN_H + imul eax, FP_1 + cdq + idiv perpWallDist + mov lineH, eax + + mov eax, lineH + imul viewEye3D + shrd eax, edx, 16 + add eax, viewHorizon3D + mov drawEnd, eax + mov ebx, lineH + mov eax, viewCeiling3D + cmp outdoorRender3D, 0 + je @F + mov eax, CITY_STOREY_HEIGHT +@@: + imul ebx + shrd eax, edx, 16 + mov ebx, eax + mov lineH, ebx + mov eax, drawEnd + sub eax, ebx + mov drawStart, eax + cmp outdoorRender3D, 0 + je wall_store_original_start + ; Floor height is independent of storey height. + mov eax, drawEnd + sub eax, lineH + mov drawStart, eax + mov eax, mapY + shl eax, 5 + add eax, mapX + mov edx, worldMap3D + movzx eax, BYTE PTR [edx+eax] +wall_exterior_tall: + ; Roof projection and texture sampling use the same storey count. + mov eax, lineH + imul eax, CITY_BUILDING_STOREYS-1 + sub drawStart, eax + mov eax, lineH + imul eax, CITY_BUILDING_STOREYS + mov lineH, eax +wall_store_original_start: + mov eax, drawStart + mov originalStart, eax + + cmp side, 0 + jne hit_side_y + mov eax, perpWallDist + imul rayDirY + shrd eax, edx, 16 + add eax, playerY + mov wallHit, eax + jmp calc_tex_x +hit_side_y: + mov eax, perpWallDist + imul rayDirX + shrd eax, edx, 16 + add eax, playerX + mov wallHit, eax + +calc_tex_x: + ; MASK WITH 0FFFFh to prevent texture scrambling! + mov eax, wallHit + and eax, 0FFFFh + mov texXHD, eax + shr eax, 9 + and eax, 127 + mov texX, eax + + cmp side, 0 + jne @F + cmp rayDirX, 0 + jle @F + mov eax, 127 + sub eax, texX + mov texX, eax + xor texXHD, 0FFFFh +@@: + cmp side, 1 + jne select_tex + cmp rayDirY, 0 + jge select_tex + mov eax, 127 + sub eax, texX + mov texX, eax + xor texXHD, 0FFFFh + +select_tex: + mov eax, mapY + shl eax, 5 + add eax, mapX + mov edx, worldMap3D + movzx eax, BYTE PTR [edx + eax] + mov texId, eax + cmp texId, 0 + jne @F + mov texId, 1 +@@: + + mov eax, perpWallDist + shr eax, 13 + mov edx, 256 + sub edx, eax + cmp edx, 75 + jge @F + mov edx, 75 +@@: + cmp side, 1 + jne @F + imul edx, 3 + shr edx, 2 +@@: + mov shade, edx + + cmp drawStart, 0 + jge @F + mov drawStart, 0 +@@: + cmp drawEnd, SCREEN_H + jl @F + mov drawEnd, SCREEN_H - 1 +@@: + + mov eax, lineH + cmp eax, 1 + jge @F + mov eax, 1 + mov lineH, eax +@@: + + mov eax, 128 * FP_1 + cdq + idiv lineH + mov esi, eax ; stepY + + mov eax, drawStart + sub eax, originalStart + imul eax, esi + mov edi, eax ; texPos + + mov ecx, drawStart +draw_stripe_loop: + cmp ecx, drawEnd + jg next_col + + mov eax, edi + shr eax, 16 + and eax, 127 + mov edx, texId + cmp outdoorRender3D, 0 + je wall_sample_material + imul eax, CITY_BUILDING_STOREYS + cmp eax, 128*(CITY_BUILDING_STOREYS-1) + jae wall_lower_storey + push eax + shr eax, 7 + add eax, mapX + add eax, mapY + xor edx, edx + mov ebx, 3 + div ebx + add edx, 65 + pop eax + and eax, 127 + jmp wall_sample_material +wall_lower_storey: + sub eax, 128*(CITY_BUILDING_STOREYS-1) +wall_sample_material: + mov pixelMaterial, edx + cmp outdoorRender3D, 0 + je wall_sample_indoor_hd + cmp hallCityDetail3D.pixels, 0 + je wall_sample_standard + cmp edx, 57 + jb wall_sample_standard + cmp edx, 72 + ja wall_sample_standard + cmp perpWallDist, 6*FP_1 + ja wall_sample_standard + ; Preserve subtexel detail near facades; retain the 128px mip at distance. + push edx + mov eax, edi + shr eax, 15 + imul eax, CITY_BUILDING_STOREYS + and eax, 255 + shl eax, 8 + mov ebx, texXHD + shr ebx, 8 + add eax, ebx + pop edx + sub edx, 57 + shl edx, 16 + add eax, edx + mov ebx, hallCityDetail3D.pixels + mov eax, [ebx+eax*4] + jmp wall_shade_pixel +wall_sample_indoor_hd: + cmp edx, 80 + jb wall_sample_standard + cmp edx, 103 + ja wall_sample_standard + mov ebx, hallRoomHD3D.pixels + cmp edx, 92 + jb wall_sample_room_hd + mov ebx, hallArchitectureHD3D.pixels + sub edx, 12 +wall_sample_room_hd: + test ebx, ebx + jz wall_sample_standard_restore + sub edx, 80 + shl edx, 18 + add ebx, edx + mov eax, edi + shr eax, 15 + and eax, 255 + shl eax, 8 + mov edx, texXHD + shr edx, 8 + add eax, edx + mov eax, [ebx+eax*4] + jmp wall_shade_pixel +wall_sample_standard_restore: + mov edx, texId + mov eax, edi + shr eax, 16 + and eax, 127 +wall_sample_standard: + shl eax, 7 + add eax, texX + + shl edx, 14 + add eax, edx + mov eax, [texturesBuffer + eax*4] + + ; Shade wall pixel +wall_shade_pixel: + mov ebx, shade + cmp outdoorRender3D, 0 + je wall_ambient_shade + push eax + push ecx + invoke IsCityEmissive3D, eax, pixelMaterial + pop ecx + test eax, eax + pop eax + jz wall_ambient_shade + mov ebx, 256 +wall_ambient_shade: + cmp hallLevel3D, 0 + je @F + imul ebx, 7 + shr ebx, 3 +@@: + movzx edx, al + imul edx, ebx + shr edx, 8 + push edx + + movzx edx, ah + imul edx, ebx + shr edx, 8 + shl edx, 8 + + shr eax, 16 + movzx eax, al + imul eax, ebx + shr eax, 8 + shl eax, 16 + or eax, edx + pop edx + or eax, edx + + mov edx, ecx + imul edx, SCREEN_W + add edx, col + mov [screenBuffer + edx*4], eax + + add edi, esi + inc ecx + jmp draw_stripe_loop + +next_col: + inc col + jmp col_loop + +walls_done: + pop edi + pop esi + pop ebx + ret +RenderWalls ENDP + +; --- Render 3D Billboard Sprites --- + +; --- HUD & Minimap Radar --- +RenderHUD PROC uses ebx esi edi + invoke DrawBox, 0, 0, 320, 16, 0014191Dh + invoke DrawString8x8, 8, 4, OFFSET textBank3D, 00D8BC6Ah + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 64, 4, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 176, 4, OFFSET textWindowKeys3D, 00A8B6BBh + invoke DrawBox, 0, 226, 320, 14, 0014191Dh + invoke DrawString8x8, 12, 230, OFFSET textWalkKeys3D, 00A8B6BBh + invoke DrawBox, 159, 118, 2, 5, 00E7DFC8h + invoke DrawBox, 157, 120, 6, 1, 00E7DFC8h + cmp interactPromptPtr, 0 + je @F + invoke DrawBoxBorder, 4, 199, 312, 18, 0014191Dh, 00D8BC6Ah, 1 + invoke DrawString8x8, 10, 204, interactPromptPtr, 00F5E2B0h +@@: + cmp flashTimer, 0 + je hud_finished + dec flashTimer + invoke DrawBox, 4, 22, 312, 16, 0014191Dh + invoke DrawString8x8, 10, 26, OFFSET flashMessage, 00FFFFFFh +hud_finished: + ret +RenderHUD ENDP + +RenderMinimap PROC uses ebx esi edi + local radarX:DWORD + local radarY:DWORD + local radarSize:DWORD + + mov radarX, 320 - 48 + mov radarY, 20 + mov radarSize, 44 + + invoke DrawBoxBorder, radarX, radarY, radarSize, radarSize, 00101510h, 00FFD700h, 1 + + ; Draw Sprites on radar + cmp hallLevel3D, 0 + jne draw_player_radar + xor esi, esi +radar_spr_loop: + cmp esi, NUM_SPRITES + jge draw_player_radar + mov eax, esi + imul eax, SIZEOF SpriteObject + mov eax, [casinoSprites + eax].posX + sar eax, 16 + imul eax, radarSize + shr eax, 5 + add eax, radarX + mov ebx, eax + + mov eax, esi + imul eax, SIZEOF SpriteObject + mov eax, [casinoSprites + eax].posY + sar eax, 16 + imul eax, radarSize + shr eax, 5 + add eax, radarY + + invoke DrawPixel, ebx, eax, 00FFAA00h + inc esi + jmp radar_spr_loop + +draw_player_radar: + mov eax, playerX + sar eax, 16 + imul eax, radarSize + shr eax, 5 + add eax, radarX + mov ebx, eax + + mov eax, playerY + sar eax, 16 + imul eax, radarSize + shr eax, 5 + add eax, radarY + + invoke DrawCircle, ebx, eax, 2, 00FF2020h + ret +RenderMinimap ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: SLOTS 777 +; ============================================================================== +HandleSlotsInput PROC + cmp slotSpinState, 1 + je slots_input_done + + invoke Pressed3D, 20h ; SPACE -> Spin + test ah, 80h + jz check_bet_adjust + mov eax, bankroll + cmp eax, slotBet + jl @F + sub eax, slotBet + mov bankroll, eax + mov slotSpinState, 1 + mov slotSpinTimer, 0 + mov slotWinAmount, 0 + invoke PlayCasinoSound3D, OFFSET soundSlotSpin, 0, 1 + jmp slots_input_done +@@: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + +check_bet_adjust: + invoke Pressed3D, 26h ; UP / W + test ah, 80h + jnz inc_bet + invoke Pressed3D, 57h + test ah, 80h + jz check_bet_down +inc_bet: + cmp slotBet, 500 + jge slots_input_done + cmp slotBet, 100 + jge @F + cmp slotBet, 50 + jge set_100 + mov slotBet, 50 + jmp slots_input_done +set_100: + mov slotBet, 100 + jmp slots_input_done +@@: + mov slotBet, 500 + jmp slots_input_done + +check_bet_down: + invoke Pressed3D, 28h ; DOWN / S + test ah, 80h + jnz dec_bet + invoke Pressed3D, 53h + test ah, 80h + jz slots_input_done +dec_bet: + cmp slotBet, 50 + jle set_10 + cmp slotBet, 100 + jle set_50 + mov slotBet, 100 + jmp slots_input_done +set_50: + mov slotBet, 50 + jmp slots_input_done +set_10: + mov slotBet, 10 + +slots_input_done: + ret +HandleSlotsInput ENDP + +RenderSlotsGame PROC uses ebx esi edi + ; Cabinet Background (Dark Cherry Wood & Gold) + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00150A10h + invoke DrawBoxBorder, 10, 10, 300, 220, 00251015h, 00FFD700h, 3 + + ; Illuminated Top Marquee + invoke DrawBoxBorder, 25, 20, 270, 32, 000A0505h, 00FFFF00h, 2 + invoke DrawString8x8, 55, 32, OFFSET textSlots3D, 00FFD700h + + ; Spinning Animation Logic + cmp slotSpinState, 1 + jne draw_reels + inc slotSpinTimer + + cmp slotSpinTimer, 22 + jge @F + invoke RandomRange3D, 7 + mov slotReel1, eax +@@: + cmp slotSpinTimer, 36 + jge @F + invoke RandomRange3D, 7 + mov slotReel2, eax +@@: + cmp slotSpinTimer, 50 + jge @F + invoke RandomRange3D, 7 + mov slotReel3, eax +@@: + cmp slotSpinTimer, 50 + jl draw_reels + + ; Spin finished! Check outcome! + mov slotSpinState, 0 + mov eax, slotReel1 + cmp eax, slotReel2 + jne check_pairs + cmp eax, slotReel3 + jne check_pairs + + ; 3 Matching! + cmp eax, 0 ; 777! + jne @F + mov eax, slotBet + imul eax, 25 + mov slotWinAmount, eax + add bankroll, eax + invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1 + jmp draw_reels +@@: + cmp eax, 6 ; CROWN! + jne @F + mov eax, slotBet + imul eax, 50 + mov slotWinAmount, eax + add bankroll, eax + invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1 + jmp draw_reels +@@: + mov eax, slotBet + imul eax, 10 + mov slotWinAmount, eax + add bankroll, eax + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + jmp draw_reels + +check_pairs: + mov eax, slotReel1 + cmp eax, slotReel2 + je pair_win + mov eax, slotReel2 + cmp eax, slotReel3 + je pair_win + mov eax, slotReel1 + cmp eax, slotReel3 + je pair_win + jmp draw_reels +pair_win: + mov eax, slotBet + imul eax, 2 + mov slotWinAmount, eax + add bankroll, eax + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + +draw_reels: + ; Reels Window + invoke DrawBoxBorder, 30, 62, 260, 95, 000F0F12h, 0000A5FFh, 2 + + ; Reel 1 (45..105) + invoke DrawBoxBorder, 45, 68, 65, 82, 00F0F0F5h, 00505050h, 2 + mov eax, slotReel1 + call DrawReelSymbolAt1 + + ; Reel 2 (128..188) + invoke DrawBoxBorder, 128, 68, 65, 82, 00F0F0F5h, 00505050h, 2 + mov eax, slotReel2 + call DrawReelSymbolAt2 + + ; Reel 3 (210..270) + invoke DrawBoxBorder, 210, 68, 65, 82, 00F0F0F5h, 00505050h, 2 + mov eax, slotReel3 + call DrawReelSymbolAt3 + + ; Bottom Control Panel + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 00FFD700h, 1 + + invoke DrawString8x8, 28, 172, OFFSET textBank3D, 00FFD700h + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 00FFFF00h + + invoke DrawString8x8, 175, 172, OFFSET textBet3D, 00FFD700h + invoke FormatNumber, slotBet, OFFSET hudNumBuffer + invoke DrawString8x8, 240, 172, OFFSET hudNumBuffer, 0050FF50h + + cmp slotWinAmount, 0 + jle draw_slot_ctrls + invoke DrawString8x8, 28, 187, OFFSET strWin, 00FFFF00h + invoke FormatNumber, slotWinAmount, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 187, OFFSET hudNumBuffer, 00FFFF00h + +draw_slot_ctrls: + invoke DrawString8x8, 28, 204, OFFSET textSlotsKeys3D, 00A0A0A0h + ret +RenderSlotsGame ENDP + +DrawReelSymbolAt1 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 52, 105, OFFSET sym7, 00FF2020h + ret +@@: + cmp eax, 1 + jne @F + invoke DrawString8x8, 52, 105, OFFSET symBar, 00FFAA00h + ret +@@: + cmp eax, 2 + jne @F + invoke DrawString8x8, 52, 105, OFFSET symBell, 00FFD700h + ret +@@: + cmp eax, 3 + jne @F + invoke DrawString8x8, 48, 105, OFFSET symCherry, 000000D0h + ret +@@: + cmp eax, 4 + jne @F + invoke DrawString8x8, 48, 105, OFFSET symClover, 0000A000h + ret +@@: + cmp eax, 5 + jne @F + invoke DrawString8x8, 52, 105, OFFSET symGem, 00FFFF00h + ret +@@: + invoke DrawString8x8, 52, 105, OFFSET symCrown, 00FFD700h + ret +DrawReelSymbolAt1 ENDP + +DrawReelSymbolAt2 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 135, 105, OFFSET sym7, 00FF2020h + ret +@@: + cmp eax, 1 + jne @F + invoke DrawString8x8, 135, 105, OFFSET symBar, 00FFAA00h + ret +@@: + cmp eax, 2 + jne @F + invoke DrawString8x8, 135, 105, OFFSET symBell, 00FFD700h + ret +@@: + cmp eax, 3 + jne @F + invoke DrawString8x8, 131, 105, OFFSET symCherry, 000000D0h + ret +@@: + cmp eax, 4 + jne @F + invoke DrawString8x8, 131, 105, OFFSET symClover, 0000A000h + ret +@@: + cmp eax, 5 + jne @F + invoke DrawString8x8, 135, 105, OFFSET symGem, 00FFFF00h + ret +@@: + invoke DrawString8x8, 135, 105, OFFSET symCrown, 00FFD700h + ret +DrawReelSymbolAt2 ENDP + +DrawReelSymbolAt3 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 218, 105, OFFSET sym7, 00FF2020h + ret +@@: + cmp eax, 1 + jne @F + invoke DrawString8x8, 218, 105, OFFSET symBar, 00FFAA00h + ret +@@: + cmp eax, 2 + jne @F + invoke DrawString8x8, 218, 105, OFFSET symBell, 00FFD700h + ret +@@: + cmp eax, 3 + jne @F + invoke DrawString8x8, 214, 105, OFFSET symCherry, 000000D0h + ret +@@: + cmp eax, 4 + jne @F + invoke DrawString8x8, 214, 105, OFFSET symClover, 0000A000h + ret +@@: + cmp eax, 5 + jne @F + invoke DrawString8x8, 218, 105, OFFSET symGem, 00FFFF00h + ret +@@: + invoke DrawString8x8, 218, 105, OFFSET symCrown, 00FFD700h + ret +DrawReelSymbolAt3 ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: BLACKJACK (21) +; ============================================================================== +HandleBlackjackInput PROC uses ebx + cmp bjState, 0 ; Need Deal + jne check_bj_player_turn + invoke Pressed3D, 20h ; SPACE -> Deal + test ah, 80h + jz check_bj_bet_change + mov eax, bankroll + cmp eax, bjBet + jl bj_need_cash + sub eax, bjBet + mov bankroll, eax + + ; Deal 2 cards to player, 2 cards to dealer + mov bjPlayerCardCount, 0 + mov bjDealerCardCount, 0 + mov bjDealerHideHole, 1 + + ; Player Card 1 + invoke RandomRange3D, 13 + inc eax + mov ebx, bjPlayerCardCount + mov [bjPlayerCards + ebx*4], eax + inc bjPlayerCardCount + + ; Dealer Card 1 + invoke RandomRange3D, 13 + inc eax + mov ebx, bjDealerCardCount + mov [bjDealerCards + ebx*4], eax + inc bjDealerCardCount + + ; Player Card 2 + invoke RandomRange3D, 13 + inc eax + mov ebx, bjPlayerCardCount + mov [bjPlayerCards + ebx*4], eax + inc bjPlayerCardCount + + ; Dealer Card 2 (Hole card) + invoke RandomRange3D, 13 + inc eax + mov ebx, bjDealerCardCount + mov [bjDealerCards + ebx*4], eax + inc bjDealerCardCount + + invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1 + + ; Calc Player Score + call CalcPlayerBJScore + cmp bjPlayerScore, 21 + jne set_bj_turn + ; Instant Blackjack! + mov bjDealerHideHole, 0 + mov eax, bjBet + imul eax, 5 + shr eax, 1 + add bankroll, eax + invoke CopyString3D, OFFSET strWin, OFFSET bjOutcomeMsg + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + mov bjState, 2 + ret +set_bj_turn: + mov bjState, 1 + mov BYTE PTR [bjOutcomeMsg], 0 + ret + +bj_need_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + ret + +check_bj_player_turn: + cmp bjState, 1 + jne check_bj_round_over + + invoke Pressed3D, 48h ; 'H' -> Hit + test ah, 80h + jz check_bj_stand + invoke RandomRange3D, 13 + inc eax + mov ebx, bjPlayerCardCount + cmp ebx, 8 + jge @F + mov [bjPlayerCards + ebx*4], eax + inc bjPlayerCardCount +@@: + invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1 + call CalcPlayerBJScore + cmp bjPlayerScore, 21 + jle bj_input_done + ; Bust! + invoke CopyString3D, OFFSET strPlayerBust, OFFSET bjOutcomeMsg + mov bjDealerHideHole, 0 + mov bjState, 2 + ret + +check_bj_stand: + invoke Pressed3D, 53h ; 'S' -> Stand + test ah, 80h + jz bj_input_done + + ; Dealer Turn + mov bjDealerHideHole, 0 +dealer_loop: + call CalcDealerBJScore + cmp bjDealerScore, 17 + jge dealer_finished + invoke RandomRange3D, 13 + inc eax + mov ebx, bjDealerCardCount + cmp ebx, 8 + jge dealer_finished + mov [bjDealerCards + ebx*4], eax + inc bjDealerCardCount + jmp dealer_loop + +dealer_finished: + cmp bjDealerScore, 21 + jle compare_scores + ; Dealer Bust! + mov eax, bjBet + shl eax, 1 + add bankroll, eax + invoke CopyString3D, OFFSET strDealerBust, OFFSET bjOutcomeMsg + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + mov bjState, 2 + ret + +compare_scores: + mov eax, bjPlayerScore + cmp eax, bjDealerScore + jle check_dealer_won + ; Player Won! + mov eax, bjBet + shl eax, 1 + add bankroll, eax + invoke CopyString3D, OFFSET strWin, OFFSET bjOutcomeMsg + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + mov bjState, 2 + ret +check_dealer_won: + cmp eax, bjDealerScore + jl dealer_wins + ; Push (Tie) + mov eax, bjBet + add bankroll, eax + invoke CopyString3D, OFFSET strPush, OFFSET bjOutcomeMsg + mov bjState, 2 + ret +dealer_wins: + invoke CopyString3D, OFFSET strLose, OFFSET bjOutcomeMsg + mov bjState, 2 + ret + +check_bj_round_over: + invoke Pressed3D, 20h ; SPACE -> Next Hand + test ah, 80h + jz bj_input_done + mov bjState, 0 + ret + +check_bj_bet_change: + invoke Pressed3D, 26h ; UP + test ah, 80h + jz @F + cmp bjBet, 500 + jge bj_input_done + add bjBet, 50 + ret +@@: + invoke Pressed3D, 28h ; DOWN + test ah, 80h + jz bj_input_done + cmp bjBet, 50 + jle bj_input_done + sub bjBet, 50 + +bj_input_done: + ret +HandleBlackjackInput ENDP + +CalcPlayerBJScore PROC uses ebx esi + xor eax, eax + xor ebx, ebx + xor esi, esi +calc_p_loop: + cmp esi, bjPlayerCardCount + jge calc_p_done + mov edx, [bjPlayerCards + esi*4] + cmp edx, 10 + jle @F + mov edx, 10 +@@: + cmp edx, 1 + jne add_p_val + inc ebx ; count Aces + add eax, 11 + jmp next_p_card +add_p_val: + add eax, edx +next_p_card: + inc esi + jmp calc_p_loop +calc_p_done: + ; Soft Ace reduction +reduce_p_ace: + cmp eax, 21 + jle store_p_score + test ebx, ebx + jz store_p_score + sub eax, 10 + dec ebx + jmp reduce_p_ace +store_p_score: + mov bjPlayerScore, eax + ret +CalcPlayerBJScore ENDP + +CalcDealerBJScore PROC uses ebx esi + xor eax, eax + xor ebx, ebx + xor esi, esi +calc_d_loop: + cmp esi, bjDealerCardCount + jge calc_d_done + mov edx, [bjDealerCards + esi*4] + cmp edx, 10 + jle @F + mov edx, 10 +@@: + cmp edx, 1 + jne add_d_val + inc ebx + add eax, 11 + jmp next_d_card +add_d_val: + add eax, edx +next_d_card: + inc esi + jmp calc_d_loop +calc_d_done: +reduce_d_ace: + cmp eax, 21 + jle store_d_score + test ebx, ebx + jz store_d_score + sub eax, 10 + dec ebx + jmp reduce_d_ace +store_d_score: + mov bjDealerScore, eax + ret +CalcDealerBJScore ENDP + +RenderBlackjackGame PROC uses ebx esi edi + ; Emerald Felt Table Background + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 000A3015h + invoke DrawBoxBorder, 10, 10, 300, 220, 000D4018h, 00FFD700h, 3 + + ; Dealer Area Top + invoke DrawString8x8, 25, 20, OFFSET textBJ3D, 00FFD700h + invoke DrawString8x8, 25, 35, OFFSET textDealer3D, 00FFFFFFh + invoke FormatNumber, bjDealerScore, OFFSET hudNumBuffer + invoke DrawString8x8, 120, 35, OFFSET hudNumBuffer, 00FFFF00h + + ; Dealer Cards + xor esi, esi +draw_dealer_cards: + cmp esi, bjDealerCardCount + jge draw_player_bj_area + mov eax, esi + imul eax, 45 + add eax, 25 + mov ebx, eax + + cmp esi, 1 + jne draw_dealer_face + cmp bjDealerHideHole, 1 + jne draw_dealer_face + ; Face Down Card + mov eax, selectedBack3D + mov eax, cardBackColors3D[eax*4] + invoke DrawBoxBorder, ebx, 48, 38, 52, eax, 00FFFFFFh, 2 + jmp next_dealer_card_draw + +draw_dealer_face: + invoke DrawBoxBorder, ebx, 48, 38, 52, 00F0F0F5h, 00000000h, 2 + mov eax, [bjDealerCards + esi*4] + dec eax + imul eax, 3 + lea edx, [cardRankStr + eax] + mov eax, ebx + add eax, 8 + invoke DrawString8x8, eax, 68, edx, 00000000h + +next_dealer_card_draw: + inc esi + jmp draw_dealer_cards + +draw_player_bj_area: + ; Player Area Bottom + invoke DrawString8x8, 25, 110, OFFSET textPlayer3D, 00FFFFFFh + invoke FormatNumber, bjPlayerScore, OFFSET hudNumBuffer + invoke DrawString8x8, 120, 110, OFFSET hudNumBuffer, 0050FF50h + + ; Player Cards + xor esi, esi +draw_player_cards: + cmp esi, bjPlayerCardCount + jge draw_bj_footer + mov eax, esi + imul eax, 45 + add eax, 25 + mov ebx, eax + + invoke DrawBoxBorder, ebx, 124, 38, 52, 00F0F0F5h, 00000000h, 2 + mov eax, [bjPlayerCards + esi*4] + dec eax + imul eax, 3 + lea edx, [cardRankStr + eax] + mov eax, ebx + add eax, 8 + invoke DrawString8x8, eax, 144, edx, 00000000h + + inc esi + jmp draw_player_cards + +draw_bj_footer: + ; Footer Status & Controls + invoke DrawBoxBorder, 20, 182, 280, 42, 00102010h, 00FFD700h, 1 + cmp BYTE PTR [bjOutcomeMsg], 0 + je draw_bj_controls + invoke DrawString8x8, 28, 188, OFFSET bjOutcomeMsg, 00FFFF00h + invoke DrawString8x8, 28, 204, OFFSET textNext3D, 00A0A0A0h + ret + +draw_bj_controls: + invoke DrawString8x8, 28, 188, OFFSET textBJKeys3D, 00FFFFFFh + invoke DrawString8x8, 28, 204, OFFSET textDeal3D, 00A0A0A0h + ret +RenderBlackjackGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: ROULETTE +; ============================================================================== +HandleRouletteInput PROC uses ebx + cmp roulState, 1 + je roul_input_done + + invoke Pressed3D, 31h ; '1' -> RED + test ah, 80h + jz @F + mov roulBetType, 1 +@@: + invoke Pressed3D, 32h ; '2' -> BLACK + test ah, 80h + jz @F + mov roulBetType, 2 +@@: + invoke Pressed3D, 33h ; '3' -> ZERO (0) + test ah, 80h + jz @F + mov roulBetType, 3 +@@: + invoke Pressed3D, 34h ; '4' -> EVEN + test ah, 80h + jz @F + mov roulBetType, 4 +@@: + invoke Pressed3D, 35h ; '5' -> ODD + test ah, 80h + jz check_roul_spin + mov roulBetType, 5 + +check_roul_spin: + invoke Pressed3D, 20h ; SPACE -> Spin + test ah, 80h + jz roul_input_done + mov eax, bankroll + cmp eax, roulBetAmount + jl roul_no_cash + sub eax, roulBetAmount + mov bankroll, eax + mov roulState, 1 + mov roulSpinTimer, 50 + mov roulPayout, 0 + invoke PlayCasinoSound3D, OFFSET soundRoulette, 0, 1 + ret + +roul_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + +roul_input_done: + ret +HandleRouletteInput ENDP + +RenderRouletteGame PROC uses ebx esi edi + ; Table felt background + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00151525h + invoke DrawBoxBorder, 10, 10, 300, 220, 00201525h, 00FFD700h, 3 + + ; 2.5D Rotating Wheel on Left + invoke DrawCircle, 85, 110, 65, 00102550h + invoke DrawCircle, 85, 110, 60, 00FFD700h + invoke DrawCircle, 85, 110, 52, 00101010h + invoke DrawCircle, 85, 110, 22, 00FFD700h ; Center brass turret + + ; Spinning Wheel / Ball Logic + cmp roulState, 1 + jne draw_roul_ball + dec roulSpinTimer + add roulWheelAngle, 8 + sub roulBallAngle, 14 + cmp roulSpinTimer, 0 + jg draw_roul_ball + + ; Wheel stopped! Determine result! + mov roulState, 2 + invoke RandomRange3D, 37 + mov roulWinningNum, eax + + ; Check bet + cmp roulBetType, 1 ; RED + jne check_ro_black + call IsNumberRed + test eax, eax + jz ro_lost + mov eax, roulBetAmount + shl eax, 1 + mov roulPayout, eax + add bankroll, eax + invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + jmp draw_roul_ball + +check_ro_black: + cmp roulBetType, 2 ; BLACK + jne check_ro_zero + cmp roulWinningNum, 0 + je ro_lost + call IsNumberRed + test eax, eax + jnz ro_lost + mov eax, roulBetAmount + shl eax, 1 + mov roulPayout, eax + add bankroll, eax + invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + jmp draw_roul_ball + +check_ro_zero: + cmp roulBetType, 3 ; ZERO + jne check_ro_even + cmp roulWinningNum, 0 + jne ro_lost + mov eax, roulBetAmount + imul eax, 36 + mov roulPayout, eax + add bankroll, eax + invoke CopyString3D, OFFSET strJackpot, OFFSET roulOutcomeMsg + invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1 + jmp draw_roul_ball + +check_ro_even: + cmp roulBetType, 4 ; EVEN + jne check_ro_odd + mov eax, roulWinningNum + test eax, eax + jz ro_lost + test al, 1 + jnz ro_lost + mov eax, roulBetAmount + shl eax, 1 + mov roulPayout, eax + add bankroll, eax + invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + jmp draw_roul_ball + +check_ro_odd: + mov eax, roulWinningNum + test eax, eax + jz ro_lost + test al, 1 + jz ro_lost + mov eax, roulBetAmount + shl eax, 1 + mov roulPayout, eax + add bankroll, eax + invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + jmp draw_roul_ball + +ro_lost: + invoke CopyString3D, OFFSET strLose, OFFSET roulOutcomeMsg + +draw_roul_ball: + ; Draw White Ball on Rim + mov eax, roulBallAngle + and eax, 511 + mov ebx, [tableCos + eax*4] + imul ebx, 42 + sar ebx, 16 + add ebx, 85 + + mov eax, roulBallAngle + and eax, 511 + mov edx, [tableSin + eax*4] + imul edx, 42 + sar edx, 16 + add edx, 110 + invoke DrawCircle, ebx, edx, 3, 00FFFFFFh + + ; Right Betting Board + invoke DrawBoxBorder, 175, 25, 125, 28, 001010C0h, 00FFFFFFh, 2 ; [1] RED + invoke DrawString8x8, 190, 35, OFFSET textRed3D, 00FFFFFFh + + invoke DrawBoxBorder, 175, 60, 125, 28, 00151515h, 00FFFFFFh, 2 ; [2] BLACK + invoke DrawString8x8, 190, 70, OFFSET textBlack3D, 00FFFFFFh + + invoke DrawBoxBorder, 175, 95, 125, 28, 00106010h, 00FFFFFFh, 2 ; [3] ZERO + invoke DrawString8x8, 190, 105, OFFSET textZero3D, 00FFFFFFh + + invoke DrawBoxBorder, 175, 130, 60, 26, 00302020h, 00FFFFFFh, 1 ; [4] EVEN + invoke DrawString8x8, 185, 139, OFFSET textEven3D, 00FFFFFFh + + invoke DrawBoxBorder, 240, 130, 60, 26, 00302020h, 00FFFFFFh, 1 ; [5] ODD + invoke DrawString8x8, 250, 139, OFFSET textOdd3D, 00FFFFFFh + + ; Highlight Active Bet + cmp roulBetType, 1 + jne @F + invoke DrawBoxBorder, 173, 23, 129, 32, 0, 00FFFF00h, 2 +@@: + cmp roulBetType, 2 + jne @F + invoke DrawBoxBorder, 173, 58, 129, 32, 0, 00FFFF00h, 2 +@@: + cmp roulBetType, 3 + jne @F + invoke DrawBoxBorder, 173, 93, 129, 32, 0, 00FFFF00h, 2 +@@: + cmp roulBetType, 4 + jne @F + invoke DrawBoxBorder, 173, 128, 64, 30, 0, 00FFFF00h, 2 +@@: + cmp roulBetType, 5 + jne draw_ro_footer + invoke DrawBoxBorder, 238, 128, 64, 30, 0, 00FFFF00h, 2 + +draw_ro_footer: + invoke DrawBoxBorder, 20, 180, 280, 42, 00101015h, 00FFD700h, 1 + + cmp roulState, 2 + jne @F + invoke DrawString8x8, 28, 186, OFFSET textResult3D, 00FFD700h + invoke FormatNumber, roulWinningNum, OFFSET hudNumBuffer + invoke DrawString8x8, 85, 186, OFFSET hudNumBuffer, 00FFFF00h + invoke DrawString8x8, 130, 186, OFFSET roulOutcomeMsg, 0050FF50h +@@: + invoke DrawString8x8, 28, 202, OFFSET textSpin3D, 00A0A0A0h + ret +RenderRouletteGame ENDP + +IsNumberRed PROC + mov eax, roulWinningNum + cmp eax, 1 + je red_yes + cmp eax, 3 + je red_yes + cmp eax, 5 + je red_yes + cmp eax, 7 + je red_yes + cmp eax, 9 + je red_yes + cmp eax, 12 + je red_yes + cmp eax, 14 + je red_yes + cmp eax, 16 + je red_yes + cmp eax, 18 + je red_yes + cmp eax, 19 + je red_yes + cmp eax, 21 + je red_yes + cmp eax, 23 + je red_yes + cmp eax, 25 + je red_yes + cmp eax, 27 + je red_yes + cmp eax, 30 + je red_yes + cmp eax, 32 + je red_yes + cmp eax, 34 + je red_yes + cmp eax, 36 + je red_yes + xor eax, eax + ret +red_yes: + mov eax, 1 + ret +IsNumberRed ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: BAR & SHOP +; ============================================================================== +HandleShopInput PROC uses ebx esi + xor esi, esi +shop_choice: + inc esi + lea eax, [esi+30h] + invoke Pressed3D, eax + test eax, eax + jnz shop_chosen + cmp esi, 3 + jb shop_choice + ret +shop_chosen: + bt ownedBacks3D, esi + jc shop_equip + mov ebx, 1500 + cmp esi, 1 + jne @F + mov ebx, 1000 +@@: + cmp bankroll, ebx + jb shop_no_money + sub bankroll, ebx + bts ownedBacks3D, esi +shop_equip: + mov selectedBack3D, esi + invoke CopyString3D, OFFSET textBought3D, OFFSET shopMsg + call SaveProgress3D + ret +shop_no_money: + invoke CopyString3D, OFFSET textNoCash3D, OFFSET shopMsg + ret +HandleShopInput ENDP + +RenderShopGame PROC + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00150A0Ah + invoke DrawBoxBorder, 10, 10, 300, 220, 00251515h, 00FFD700h, 3 + invoke DrawString8x8, 25, 20, OFFSET textShop3D, 00FFD700h + + invoke DrawBoxBorder, 20, 40, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 46, OFFSET textItem1_3D, 00FFFF00h + invoke DrawString8x8, 28, 58, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 80, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 86, OFFSET textItem2_3D, 00FFFF00h + invoke DrawString8x8, 28, 98, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 120, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 126, OFFSET textItem3_3D, 00FFFF00h + invoke DrawString8x8, 28, 138, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 165, 280, 55, 00100A0Ah, 00FFD700h, 1 + invoke DrawString8x8, 28, 172, OFFSET textBank3D, 00FFD700h + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 00FFFF00h + + cmp BYTE PTR [shopMsg], 0 + je @F + invoke DrawString8x8, 28, 188, OFFSET shopMsg, 0050FF50h +@@: + invoke DrawString8x8, 28, 204, OFFSET textBack3D, 00A0A0A0h + ret +RenderShopGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: ATM TERMINAL +; ============================================================================== +HandleATMInput PROC + ret +HandleATMInput ENDP + +RenderATMGame PROC + invoke DrawBox, 0, 0, 320, 240, 00172120h + invoke DrawString8x8, 24, 30, OFFSET textATM3D, 00D8BC6Ah + invoke DrawString8x8, 24, 70, OFFSET textBank3D, 00FFFFFFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 96, 70, OFFSET hudNumBuffer, 0089DAB2h + invoke DrawString8x8, 24, 115, OFFSET textATMNote3D, 00B7C8C1h + invoke DrawString8x8, 24, 140, OFFSET textATMNote2_3D, 00B7C8C1h + invoke DrawString8x8, 24, 208, OFFSET textBack3D, 00D8BC6Ah + ret +RenderATMGame ENDP + +; ============================================================================== +; ============================================================================== +; ============================================================================== +; SHARED RICH UI PROCEDURES +; ============================================================================== +DrawKeycap3D PROC uses ebx esi edi, x:DWORD, y:DWORD, strPtr:DWORD, isActive:DWORD + local keyW:DWORD + mov esi, strPtr + xor ecx, ecx +keycap_len: + mov al, [esi+ecx] + test al, al + jz keycap_len_done + inc ecx + jmp keycap_len +keycap_len_done: + shl ecx, 3 + add ecx, 8 + mov keyW, ecx + + ; Drop shadow + mov eax, y + add eax, 2 + invoke DrawBox, x, eax, keyW, 13, 0008080Ch + + ; Border and Fill + cmp isActive, 0 + je keycap_inactive + mov eax, 00FFFF00h ; Bright Yellow active border + mov edx, 001B4B22h ; Casino Green active fill + mov ebx, 00FFFF00h ; Bright Yellow active text + jmp keycap_draw_box +keycap_inactive: + mov eax, 00606870h ; Slate inactive border + mov edx, 001A1C22h ; Charcoal inactive fill + mov ebx, 00D0D8E0h ; Silver inactive text + +keycap_draw_box: + push ebx + invoke DrawBoxBorder, x, y, keyW, 13, edx, eax, 1 + pop ebx + + ; Text label + mov eax, x + add eax, 4 + mov edx, y + add edx, 3 + invoke DrawString8x8, eax, edx, strPtr, ebx + + mov eax, keyW + add eax, 4 + ret +DrawKeycap3D ENDP + +DrawChipStack PROC uses ebx esi edi, x:DWORD, y:DWORD, chipCount:DWORD + mov edi, chipCount + xor esi, esi +chip_loop: + cmp esi, edi + jge chip_done + mov eax, esi + shl eax, 2 + mov edx, y + sub edx, eax + + ; Shadow + mov eax, x + add eax, 2 + mov ecx, edx + add ecx, 5 + invoke DrawBox, eax, ecx, 20, 2, 00061004h + + ; Red Clay Chip body with white rim + invoke DrawBoxBorder, x, edx, 24, 6, 00B81515h, 00FFFFFFh, 1 + + ; White stripe inlays + mov eax, x + add eax, 4 + mov ecx, edx + add ecx, 1 + invoke DrawBox, eax, ecx, 3, 4, 00FFFFFFh + + mov eax, x + add eax, 17 + mov ecx, edx + add ecx, 1 + invoke DrawBox, eax, ecx, 3, 4, 00FFFFFFh + + inc esi + jmp chip_loop +chip_done: + ret +DrawChipStack ENDP + +DrawDetailedCoin PROC uses ebx esi edi, cxVal:DWORD, cyVal:DWORD, rxVal:DWORD, ryVal:DWORD, outerColor:DWORD, innerColor:DWORD, reliefType:DWORD + local rxSq:DWORD + local rySq:DWORD + local rxRySq:DWORD + local threshSq:DWORD + local curDy:DWORD + local curDx:DWORD + local curX:DWORD + local curY:DWORD + + mov eax, rxVal + cmp eax, 0 + jle coin_draw_done + mov eax, ryVal + cmp eax, 0 + jle coin_draw_done + + mov eax, rxVal + imul eax, rxVal + mov rxSq, eax + + mov eax, ryVal + imul eax, ryVal + mov rySq, eax + + imul eax, rxSq + mov rxRySq, eax + + ; 3/4 threshold for rim bevel + mov ecx, 3 + imul eax, ecx + shr eax, 2 + mov threshSq, eax + + ; Scan rows + mov eax, ryVal + neg eax + mov curDy, eax +coin_row_loop: + mov eax, curDy + cmp eax, ryVal + jg coin_relief_check + + mov edx, cyVal + add edx, curDy + mov curY, edx + + ; Scan columns + mov eax, rxVal + neg eax + mov curDx, eax +coin_col_loop: + mov eax, curDx + cmp eax, rxVal + jg coin_col_next_row + + mov ecx, cxVal + add ecx, curDx + mov curX, ecx + + ; val = dx*dx*rySq + dy*dy*rxSq + mov eax, curDx + imul eax, curDx + imul eax, rySq + mov ebx, eax + + mov eax, curDy + imul eax, curDy + imul eax, rxSq + add eax, ebx + + cmp eax, rxRySq + ja coin_pixel_outside + + cmp eax, threshSq + jb coin_draw_inner + invoke DrawPixel, curX, curY, outerColor + jmp coin_pixel_outside +coin_draw_inner: + invoke DrawPixel, curX, curY, innerColor + +coin_pixel_outside: + inc curDx + jmp coin_col_loop + +coin_col_next_row: + inc curDy + jmp coin_row_loop + +coin_relief_check: + cmp rxVal, 14 + jl coin_draw_done + + cmp reliefType, 1 + je coin_draw_eagle + cmp reliefType, 2 + je coin_draw_numeral + jmp coin_draw_done + +coin_draw_eagle: + ; Imperial Eagle relief (Dark Gold 009A7A00h / Bright 00FFD700h) + mov eax, cxVal + sub eax, 3 + mov edx, cyVal + sub edx, 14 + invoke DrawBox, eax, edx, 7, 2, 009A7A00h + + mov eax, cxVal + sub eax, 4 + mov edx, cyVal + sub edx, 12 + invoke DrawBox, eax, edx, 9, 2, 009A7A00h + + mov eax, cxVal + sub eax, 2 + mov edx, cyVal + sub edx, 9 + invoke DrawBox, eax, edx, 5, 12, 009A7A00h + + mov eax, cxVal + sub eax, 1 + mov edx, cyVal + sub edx, 8 + invoke DrawBox, eax, edx, 3, 10, 00FFD700h + + mov eax, cxVal + sub eax, 10 + mov edx, cyVal + sub edx, 8 + invoke DrawBox, eax, edx, 7, 3, 009A7A00h + + mov eax, cxVal + sub eax, 13 + mov edx, cyVal + sub edx, 5 + invoke DrawBox, eax, edx, 10, 3, 009A7A00h + + mov eax, cxVal + sub eax, 11 + mov edx, cyVal + sub edx, 2 + invoke DrawBox, eax, edx, 7, 3, 009A7A00h + + mov eax, cxVal + add eax, 4 + mov edx, cyVal + sub edx, 8 + invoke DrawBox, eax, edx, 7, 3, 009A7A00h + + mov eax, cxVal + add eax, 4 + mov edx, cyVal + sub edx, 5 + invoke DrawBox, eax, edx, 10, 3, 009A7A00h + + mov eax, cxVal + add eax, 5 + mov edx, cyVal + sub edx, 2 + invoke DrawBox, eax, edx, 7, 3, 009A7A00h + + mov eax, cxVal + sub eax, 4 + mov edx, cyVal + add edx, 4 + invoke DrawBox, eax, edx, 9, 3, 009A7A00h + + mov eax, cxVal + sub eax, 3 + mov edx, cyVal + add edx, 7 + invoke DrawBox, eax, edx, 7, 3, 009A7A00h + jmp coin_draw_done + +coin_draw_numeral: + ; Roman numeral 'I' & laurel + mov eax, cxVal + sub eax, 5 + mov edx, cyVal + sub edx, 10 + invoke DrawBox, eax, edx, 11, 3, 009A7A00h + + mov eax, cxVal + sub eax, 2 + mov edx, cyVal + sub edx, 7 + invoke DrawBox, eax, edx, 5, 14, 009A7A00h + + mov eax, cxVal + sub eax, 1 + mov edx, cyVal + sub edx, 6 + invoke DrawBox, eax, edx, 3, 12, 00FFD700h + + mov eax, cxVal + sub eax, 6 + mov edx, cyVal + add edx, 7 + invoke DrawBox, eax, edx, 13, 3, 009A7A00h + + ; Laurel dots + mov eax, cxVal + sub eax, 12 + mov edx, cyVal + sub edx, 8 + invoke DrawBox, eax, edx, 2, 2, 009A7A00h + + mov eax, cxVal + add eax, 11 + mov edx, cyVal + sub edx, 8 + invoke DrawBox, eax, edx, 2, 2, 009A7A00h + + mov eax, cxVal + sub eax, 12 + mov edx, cyVal + invoke DrawBox, eax, edx, 2, 2, 009A7A00h + + mov eax, cxVal + add eax, 11 + mov edx, cyVal + invoke DrawBox, eax, edx, 2, 2, 009A7A00h + + mov eax, cxVal + sub eax, 12 + mov edx, cyVal + add edx, 8 + invoke DrawBox, eax, edx, 2, 2, 009A7A00h + + mov eax, cxVal + add eax, 11 + mov edx, cyVal + add edx, 8 + invoke DrawBox, eax, edx, 2, 2, 009A7A00h + +coin_draw_done: + ret +DrawDetailedCoin ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: COIN FLIP +; ============================================================================== +InitCoinGame PROC + call InitNativeCoin3D + ret +InitCoinGame ENDP + +HandleCoinInput PROC + call HandleNativeCoin3D + ret +; Retained legacy frame-count prototype, excluded from the executable. +IF 0 + cmp coin3d_state, 0 + je coin_handle_idle + cmp coin3d_state, 1 + je coin_handle_flipping + cmp coin3d_state, 2 + je coin_handle_result + ret + +coin_handle_idle: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz coin_bet_up + invoke Pressed3D, 57h ; 'W' + test eax, eax + jnz coin_bet_up + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz coin_bet_down + invoke Pressed3D, 53h ; 'S' + test eax, eax + jnz coin_bet_down + invoke Pressed3D, 31h ; '1' + test eax, eax + jnz coin_pick_1 + invoke Pressed3D, 32h ; '2' + test eax, eax + jnz coin_pick_2 + invoke Pressed3D, 20h ; SPACE + test eax, eax + jnz coin_start_flip + ret + +coin_bet_up: + mov eax, coin3d_bet + add eax, 50 + cmp eax, bankroll + jle @F + mov eax, bankroll +@@: + cmp eax, 5000 + jle @F + mov eax, 5000 +@@: + mov coin3d_bet, eax + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +coin_bet_down: + mov eax, coin3d_bet + sub eax, 50 + cmp eax, 50 + jge @F + mov eax, 50 +@@: + mov coin3d_bet, eax + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +coin_pick_1: + mov coin3d_choice, 1 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +coin_pick_2: + mov coin3d_choice, 2 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +coin_start_flip: + mov eax, coin3d_bet + cmp eax, bankroll + jle @F + mov eax, bankroll + mov coin3d_bet, eax + test eax, eax + jz coin_done +@@: + mov eax, coin3d_bet + sub bankroll, eax + mov coin3d_state, 1 + mov coin3d_timer, 40 + invoke PlayCasinoSound3D, OFFSET soundCoin, 0, 1 + ret + +coin_handle_flipping: + dec coin3d_timer + cmp coin3d_timer, 0 + jg coin_done + invoke RandomRange3D, 2 + inc eax + mov coin3d_result, eax + mov edx, coin3d_choice + cmp eax, edx + jne coin_flip_lost + + ; Won! + inc coin3d_streak + mov eax, coin3d_bet + shl eax, 1 + add bankroll, eax + mov coin3d_win, eax + mov coin3d_state, 2 + invoke PlayCasinoSound3D, OFFSET soundCoinDing, 0, 1 + ret + +coin_flip_lost: + mov coin3d_streak, 0 + mov coin3d_win, 0 + mov coin3d_state, 2 + invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 + ret + +coin_handle_result: + invoke Pressed3D, 20h + test eax, eax + jz coin_done + mov coin3d_state, 0 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 +coin_done: + ret +ENDIF +HandleCoinInput ENDP + +RenderCoinGame PROC uses ebx esi edi + local cyVal:DWORD + local rxVal:DWORD + local kx:DWORD + + call RenderNativeCoin3D + ret +IF 0 + ; Background & Cabinet border + invoke DrawBox, 0, 0, 320, 240, 00140906h + invoke DrawBoxBorder, 6, 6, 308, 228, 0022150Fh, 00482E1Bh, 3 + + ; Header + invoke DrawBoxBorder, 20, 12, 280, 26, 001C100Ah, 00FFD700h, 2 + invoke DrawString8x8, 44, 21, OFFSET textCoinTitle, 00FFFF00h + + ; Corner rivets + invoke DrawBox, 12, 12, 3, 3, 00FFD700h + invoke DrawBox, 306, 12, 3, 3, 00FFD700h + invoke DrawBox, 12, 226, 3, 3, 00FFD700h + invoke DrawBox, 306, 226, 3, 3, 00FFD700h + + ; Status meters + invoke DrawBoxBorder, 20, 44, 110, 18, 000E1A0Ah, 00224B1Ah, 1 + invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch + + invoke DrawBoxBorder, 190, 44, 110, 18, 001A100Ah, 003A2814h, 1 + invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h + invoke FormatNumber, coin3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h + + ; Left: Heads + cmp coin3d_choice, 1 + jne coin_left_inactive + invoke DrawBoxBorder, 20, 72, 76, 68, 00101828h, 00FFFF00h, 2 + invoke DrawString8x8, 30, 78, OFFSET textCoinSide1, 00FFFF00h + invoke DrawDetailedCoin, 58, 106, 14, 14, 00D0A000h, 00FFD700h, 1 + invoke DrawString8x8, 24, 126, OFFSET textCoinSelected, 003CFF3Ch + jmp coin_right_side +coin_left_inactive: + invoke DrawBoxBorder, 20, 72, 76, 68, 000A101Ch, 00404855h, 1 + invoke DrawString8x8, 30, 78, OFFSET textCoinSide1, 00D0D8E0h + invoke DrawDetailedCoin, 58, 106, 14, 14, 009A7A00h, 00D0A000h, 1 + +coin_right_side: + ; Right: Tails + cmp coin3d_choice, 2 + jne coin_right_inactive + invoke DrawBoxBorder, 224, 72, 76, 68, 00101828h, 00FFFF00h, 2 + invoke DrawString8x8, 234, 78, OFFSET textCoinSide2, 00FFFF00h + invoke DrawDetailedCoin, 262, 106, 14, 14, 00D0A000h, 00FFD700h, 2 + invoke DrawString8x8, 228, 126, OFFSET textCoinSelected, 003CFF3Ch + jmp coin_center_area +coin_right_inactive: + invoke DrawBoxBorder, 224, 72, 76, 68, 000A101Ch, 00404855h, 1 + invoke DrawString8x8, 234, 78, OFFSET textCoinSide2, 00D0D8E0h + invoke DrawDetailedCoin, 262, 106, 14, 14, 009A7A00h, 00D0A000h, 2 + +coin_center_area: + ; Center spotlight + invoke DrawCircle, 160, 110, 48, 00121620h + invoke DrawCircle, 160, 110, 44, 00FFD700h + invoke DrawCircle, 160, 110, 42, 000E141Eh + + cmp coin3d_state, 1 + je coin_render_flipping + cmp coin3d_state, 2 + je coin_render_result + + ; Idle coin + invoke DrawDetailedCoin, 160, 110, 26, 26, 00D0A000h, 00FFD700h, coin3d_choice + jmp coin_render_keys + +coin_render_flipping: + mov eax, coin3d_timer + and eax, 7 + movzx eax, byte ptr [coinRxAnimTable + eax] + mov rxVal, eax + invoke DrawDetailedCoin, 160, 110, rxVal, 26, 00D0A000h, 00FFD700h, 0 + invoke DrawString8x8, 88, 160, OFFSET textCoinFlipping, 00FFFF00h + jmp coin_render_keys + +coin_render_result: + invoke DrawDetailedCoin, 160, 110, 26, 26, 00D0A000h, 00FFD700h, coin3d_result + mov eax, coin3d_result + cmp eax, coin3d_choice + jne coin_render_loss_msg + + ; Win banner + invoke DrawBoxBorder, 44, 154, 232, 22, 000E141Eh, 003CFF3Ch, 1 + invoke DrawString8x8, 64, 161, OFFSET textCoinWin, 003CFF3Ch + invoke FormatNumber, coin3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 152, 161, OFFSET hudNumBuffer, 003CFF3Ch + jmp coin_render_keys + +coin_render_loss_msg: + invoke DrawBoxBorder, 44, 154, 232, 22, 000E141Eh, 00C81414h, 1 + invoke DrawString8x8, 114, 161, OFFSET textCoinLose, 00FF6464h + +coin_render_keys: + mov kx, 16 + xor eax, eax + cmp coin3d_choice, 1 + sete al + invoke DrawKeycap3D, kx, 192, OFFSET textCoinKey1, eax + add kx, eax + + xor eax, eax + cmp coin3d_choice, 2 + sete al + invoke DrawKeycap3D, kx, 192, OFFSET textCoinKey2, eax + add kx, eax + + invoke DrawKeycap3D, kx, 192, OFFSET textCoinKeySpace, 1 + add kx, eax + + invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0 + ret +ENDIF +RenderCoinGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: CRAPS / DICE +; ============================================================================== +DrawCrapsDie PROC uses ebx esi edi, x:DWORD, y:DWORD, sizeVal:DWORD, valNum:DWORD + ; Drop shadow + mov eax, x + add eax, 3 + mov edx, y + add edx, sizeVal + invoke DrawBox, eax, edx, sizeVal, 3, 00081403h + + mov eax, x + add eax, sizeVal + mov edx, y + add edx, 3 + invoke DrawBox, eax, edx, 3, sizeVal, 00081403h + + ; Ivory body & bevel + invoke DrawBoxBorder, x, y, sizeVal, sizeVal, 00FAF4F0h, 00403535h, 1 + mov eax, x + inc eax + mov edx, y + inc edx + mov ecx, sizeVal + sub ecx, 2 + invoke DrawBox, eax, edx, ecx, 1, 00FFFFFFh + invoke DrawBox, eax, edx, 1, ecx, 00FFFFFFh + + ; Ruby pips (00C81515h) + mov eax, valNum + test al, 1 + jz @F + ; Center pip + mov eax, x + add eax, 18 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 3, 00C81515h + dec eax + dec edx + invoke DrawPixel, eax, edx, 00FFFFFFh +@@: + cmp valNum, 2 + jl die_pips_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 3, 00C81515h + mov eax, x + add eax, 27 + mov edx, y + add edx, 27 + invoke DrawCircle, eax, edx, 3, 00C81515h + + cmp valNum, 4 + jl die_pips_done + mov eax, x + add eax, 27 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 3, 00C81515h + mov eax, x + add eax, 9 + mov edx, y + add edx, 27 + invoke DrawCircle, eax, edx, 3, 00C81515h + + cmp valNum, 6 + jl die_pips_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 3, 00C81515h + mov eax, x + add eax, 27 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 3, 00C81515h + +die_pips_done: + ret +DrawCrapsDie ENDP + +InitDiceGame PROC + mov dice3d_state, 0 + mov dice3d_timer, 0 + mov dice3d_win, 0 + ret +InitDiceGame ENDP + +HandleDiceInput PROC + cmp dice3d_state, 0 + je dice_handle_idle + cmp dice3d_state, 1 + je dice_handle_rolling + cmp dice3d_state, 2 + je dice_handle_result + ret + +dice_handle_idle: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz dice_bet_up + invoke Pressed3D, 57h ; 'W' + test eax, eax + jnz dice_bet_up + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz dice_bet_down + invoke Pressed3D, 53h ; 'S' + test eax, eax + jnz dice_bet_down + invoke Pressed3D, 31h ; '1' + test eax, eax + jnz dice_pick_1 + invoke Pressed3D, 32h ; '2' + test eax, eax + jnz dice_pick_2 + invoke Pressed3D, 20h ; SPACE + test eax, eax + jnz dice_start_roll + ret + +dice_bet_up: + mov eax, dice3d_bet + add eax, 50 + cmp eax, bankroll + jle @F + mov eax, bankroll +@@: + cmp eax, 5000 + jle @F + mov eax, 5000 +@@: + mov dice3d_bet, eax + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +dice_bet_down: + mov eax, dice3d_bet + sub eax, 50 + cmp eax, 50 + jge @F + mov eax, 50 +@@: + mov dice3d_bet, eax + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +dice_pick_1: + mov dice3d_choice, 1 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +dice_pick_2: + mov dice3d_choice, 2 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +dice_start_roll: + mov eax, dice3d_bet + cmp eax, bankroll + jle @F + mov eax, bankroll + mov dice3d_bet, eax + test eax, eax + jz dice_done +@@: + mov eax, dice3d_bet + test eax, eax + jle dice_done + sub bankroll, eax + mov dice3d_state, 1 + mov dice3d_timer, 0 + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax + invoke PlayCasinoSound3D, OFFSET soundDiceRoll, 0, 1 + call SaveProgress3D + ret + +dice_handle_rolling: + mov eax, deltaTime3D + add dice3d_timer, eax + cmp dice3d_timer, 1600 + jb dice_done + mov dice3d_timer, 1600 + mov eax, dice3d_val2 + mov edx, dice3d_val1 + add edx, eax + mov dice3d_sum, edx + + ; Parity check + mov eax, edx + and eax, 1 + jnz dice_sum_is_odd + ; Even + mov eax, 1 + jmp dice_check_win +dice_sum_is_odd: + mov eax, 2 + +dice_check_win: + cmp eax, dice3d_choice + jne dice_roll_lost + + ; Won! + mov eax, dice3d_bet + shl eax, 1 + add bankroll, eax + mov dice3d_win, eax + mov dice3d_state, 2 + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + invoke NpcRecordRound3D,8,1 + call SaveProgress3D + ret + +dice_roll_lost: + mov dice3d_win, 0 + mov dice3d_state, 2 + invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 + invoke NpcRecordRound3D,8,0 + call SaveProgress3D + ret + +dice_handle_result: + invoke Pressed3D, 20h + test eax, eax + jz dice_done + mov dice3d_state, 0 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 +dice_done: + ret +HandleDiceInput ENDP + +RenderDiceGame PROC uses ebx esi edi + local kx:DWORD + + ; Mahogany frame & Deep Felt Green table + invoke DrawBox, 0, 0, 320, 240, 00140906h + invoke DrawBoxBorder, 6, 6, 308, 228, 000A3816h, 00FFD700h, 2 + + ; Header + invoke DrawBoxBorder, 20, 12, 280, 26, 00072E13h, 00FFD700h, 2 + invoke DrawString8x8, 116, 21, OFFSET textDiceTitle, 00FFFF00h + + ; Status + invoke DrawBoxBorder, 20, 44, 110, 18, 00072E13h, 001B4B22h, 1 + invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch + + invoke DrawBoxBorder, 190, 44, 110, 18, 00072E13h, 001B4B22h, 1 + invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h + invoke FormatNumber, dice3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 258, 49, OFFSET hudNumBuffer, 00FFD700h + + ; [1] ×¨Ò + cmp dice3d_choice, 1 + jne dice_even_inactive + invoke DrawBoxBorder, 16, 70, 88, 48, 00072E13h, 00FFFF00h, 2 + invoke DrawString8x8, 30, 76, OFFSET textDiceEven, 00FFFF00h + invoke DrawString8x8, 22, 90, OFFSET textDiceEvenNums, 00FFD700h + invoke DrawString8x8, 26, 104, OFFSET textCoinSelected, 003CFF3Ch + jmp dice_odd_side +dice_even_inactive: + invoke DrawBoxBorder, 16, 70, 88, 48, 00072E13h, 001B4B22h, 1 + invoke DrawString8x8, 30, 76, OFFSET textDiceEven, 00D0D8E0h + invoke DrawString8x8, 22, 90, OFFSET textDiceEvenNums, 0080B090h + +dice_odd_side: + ; [2] ÍÅ×ÅÒ + cmp dice3d_choice, 2 + jne dice_odd_inactive + invoke DrawBoxBorder, 216, 70, 88, 48, 00072E13h, 00FFFF00h, 2 + invoke DrawString8x8, 226, 76, OFFSET textDiceOdd, 00FFFF00h + invoke DrawString8x8, 224, 90, OFFSET textDiceOddNums, 00FFD700h + invoke DrawString8x8, 226, 104, OFFSET textCoinSelected, 003CFF3Ch + jmp dice_center_cubes +dice_odd_inactive: + invoke DrawBoxBorder, 216, 70, 88, 48, 00072E13h, 001B4B22h, 1 + invoke DrawString8x8, 226, 76, OFFSET textDiceOdd, 00D0D8E0h + invoke DrawString8x8, 224, 90, OFFSET textDiceOddNums, 0080B090h + +dice_center_cubes: + call RenderDiceThrow3D + + cmp dice3d_state, 1 + je dice_render_rolling + cmp dice3d_state, 2 + je dice_render_result + jmp dice_render_keys + +dice_render_rolling: + invoke DrawString8x8, 76, 138, OFFSET textDiceRolling, 00FFFF00h + jmp dice_render_keys + +dice_render_result: + invoke DrawBoxBorder, 36, 130, 248, 36, 00072E13h, 00FFD700h, 1 + invoke DrawString8x8, 44, 135, OFFSET textDiceSumHdr, 00FFD700h + invoke FormatNumber, dice3d_val1, OFFSET hudNumBuffer + invoke DrawString8x8, 92, 135, OFFSET hudNumBuffer, 00FFFF00h + invoke DrawString8x8, 110, 135, OFFSET textDicePlus, 00FFD700h + invoke FormatNumber, dice3d_val2, OFFSET hudNumBuffer + invoke DrawString8x8, 126, 135, OFFSET hudNumBuffer, 00FFFF00h + invoke DrawString8x8, 144, 135, OFFSET textDiceEqual, 00FFD700h + invoke FormatNumber, dice3d_sum, OFFSET hudNumBuffer + invoke DrawString8x8, 168, 135, OFFSET hudNumBuffer, 00FFFF00h + + mov eax, dice3d_sum + and eax, 1 + jnz dice_render_odd_res + invoke DrawString8x8, 186, 135, OFFSET textDiceEvenResult, 003CFF3Ch + jmp dice_render_outcome +dice_render_odd_res: + invoke DrawString8x8, 186, 135, OFFSET textDiceOddResult, 003CFF3Ch + +dice_render_outcome: + mov eax, dice3d_win + test eax, eax + jz dice_render_loss_outcome + invoke DrawString8x8, 68, 150, OFFSET textDiceWin, 003CFF3Ch + invoke FormatNumber, dice3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 156, 150, OFFSET hudNumBuffer, 003CFF3Ch + invoke DrawString8x8, 188, 150, OFFSET textDiceWinMult, 003CFF3Ch + jmp dice_render_keys + +dice_render_loss_outcome: + invoke DrawString8x8, 116, 150, OFFSET textDiceLose, 00FF6464h + +dice_render_keys: + mov kx, 16 + xor eax, eax + cmp dice3d_choice, 1 + sete al + invoke DrawKeycap3D, kx, 192, OFFSET textDiceKey1, eax + add kx, eax + + xor eax, eax + cmp dice3d_choice, 2 + sete al + invoke DrawKeycap3D, kx, 192, OFFSET textDiceKey2, eax + add kx, eax + + invoke DrawKeycap3D, kx, 192, OFFSET textDiceKeySpace, 1 + add kx, eax + + invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0 + ret +RenderDiceGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: SKULLS & CUPS (ÍÀϨÐÑÒÊÈ) +; ============================================================================== +DrawGlowingOrb PROC uses ebx esi edi, cxVal:DWORD, cyVal:DWORD + invoke DrawCircle, cxVal, cyVal, 14, 002E1E08h + invoke DrawCircle, cxVal, cyVal, 11, 00583A10h + invoke DrawCircle, cxVal, cyVal, 8, 008A581Ah + invoke DrawCircle, cxVal, cyVal, 6, 00D0B000h + invoke DrawCircle, cxVal, cyVal, 4, 00FFE000h + mov eax, cxVal + dec eax + mov edx, cyVal + dec edx + invoke DrawCircle, eax, edx, 2, 00FFFF80h + dec eax + dec edx + invoke DrawPixel, eax, edx, 00FFFFFFh + ret +DrawGlowingOrb ENDP + +DrawGothicCup PROC uses ebx esi edi, x:DWORD, y:DWORD, cupId:DWORD, isLifted:DWORD, hasBall:DWORD + local liftY:DWORD + + mov eax, y + cmp isLifted, 0 + je @F + sub eax, 36 +@@: + mov liftY, eax + + ; Drop shadow + cmp isLifted, 0 + jne cup_shadow_lifted + mov eax, x + add eax, 6 + mov edx, y + add edx, 42 + invoke DrawBox, eax, edx, 36, 4, 0010040Ah + jmp cup_ball_check +cup_shadow_lifted: + mov eax, x + add eax, 10 + mov edx, y + add edx, 42 + invoke DrawBox, eax, edx, 28, 2, 001A0612h + +cup_ball_check: + cmp isLifted, 0 + je cup_body_draw + cmp hasBall, 0 + je cup_body_draw + mov eax, x + add eax, 24 + mov edx, y + add edx, 26 + invoke DrawGlowingOrb, eax, edx + +cup_body_draw: + ; Base pedestal + mov eax, x + add eax, 6 + mov edx, liftY + add edx, 36 + invoke DrawBoxBorder, eax, edx, 36, 6, 00301A22h, 00D0B000h, 1 + + ; Stem + mov eax, x + add eax, 18 + mov edx, liftY + add edx, 28 + invoke DrawBox, eax, edx, 12, 8, 00452533h + mov eax, x + add eax, 22 + invoke DrawBox, eax, edx, 4, 8, 006E4055h + + ; Goblet Bowl + mov eax, x + add eax, 8 + mov edx, liftY + add edx, 8 + invoke DrawBoxBorder, eax, edx, 32, 20, 00401E2Dh, 00FFD700h, 1 + + mov eax, x + add eax, 14 + mov edx, liftY + add edx, 10 + invoke DrawBox, eax, edx, 6, 16, 00703550h + mov eax, x + add eax, 17 + invoke DrawBox, eax, edx, 3, 16, 00A05078h + + ; Golden Rim + mov eax, x + add eax, 4 + mov edx, liftY + add edx, 2 + invoke DrawBoxBorder, eax, edx, 40, 7, 00200A15h, 00FFFF00h, 1 + mov eax, x + add eax, 12 + mov edx, liftY + add edx, 4 + invoke DrawBox, eax, edx, 16, 2, 00FFFF00h + + ; Skull face emblem + mov eax, x + add eax, 21 + mov edx, liftY + add edx, 12 + invoke DrawBox, eax, edx, 6, 5, 00FFD700h + mov eax, x + add eax, 22 + mov edx, liftY + add edx, 17 + invoke DrawBox, eax, edx, 4, 3, 00FFD700h + mov eax, x + add eax, 22 + mov edx, liftY + add edx, 14 + invoke DrawPixel, eax, edx, 00200A15h + mov eax, x + add eax, 24 + invoke DrawPixel, eax, edx, 00200A15h + + ; Cup number label + mov eax, x + add eax, 21 + mov edx, liftY + add edx, 24 + mov ecx, cupId + add ecx, '1' + invoke DrawChar8x8, eax, edx, ecx, 00FFFF00h + ret +DrawGothicCup ENDP + +InitSkullsGame PROC + mov skulls3d_state, 0 + mov skulls3d_timer, 0 + mov skulls3d_win, 0 + mov skulls3d_choice, 1 + mov skulls3d_cup0, 0 + mov skulls3d_cup1, 1 + mov skulls3d_cup2, 2 + invoke RandomRange3D, 3 + mov skulls3d_ballPos, eax + ret +InitSkullsGame ENDP + +FinalizeSkullsGuess PROC uses ebx + cmp skulls3d_state,3 + jne skulls_guess_done + mov eax, skulls3d_choice + cmp eax, skulls3d_ballPos + jne skulls_guess_wrong + + ; Correct! 3x payout + mov eax, skulls3d_bet + imul eax, 3 + add bankroll, eax + mov skulls3d_win, eax + mov skulls3d_state, 4 + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + invoke NpcRecordRound3D,9,1 + call SaveProgress3D + ret + +skulls_guess_wrong: + mov skulls3d_win, 0 + mov skulls3d_state, 4 + invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 + invoke NpcRecordRound3D,9,0 + call SaveProgress3D +skulls_guess_done: + ret +FinalizeSkullsGuess ENDP + +HandleSkullsInput PROC + cmp skulls3d_state, 0 + je skulls_handle_idle + cmp skulls3d_state, 1 + je skulls_handle_show + cmp skulls3d_state, 2 + je skulls_handle_shuffle + cmp skulls3d_state, 3 + je skulls_handle_pick + cmp skulls3d_state, 4 + je skulls_handle_reveal + ret + +skulls_handle_idle: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz skulls_bet_up + invoke Pressed3D, 57h ; 'W' + test eax, eax + jnz skulls_bet_up + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz skulls_bet_down + invoke Pressed3D, 53h ; 'S' + test eax, eax + jnz skulls_bet_down + invoke Pressed3D, 20h ; SPACE + test eax, eax + jnz skulls_start_game + ret + +skulls_bet_up: + mov eax, skulls3d_bet + add eax, 50 + cmp eax, bankroll + jle @F + mov eax, bankroll +@@: + cmp eax, 5000 + jle @F + mov eax, 5000 +@@: + mov skulls3d_bet, eax + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +skulls_bet_down: + mov eax, skulls3d_bet + sub eax, 50 + cmp eax, 50 + jge @F + mov eax, 50 +@@: + mov skulls3d_bet, eax + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +skulls_start_game: + mov eax, skulls3d_bet + cmp eax, bankroll + jle @F + mov eax, bankroll + mov skulls3d_bet, eax + test eax, eax + jz skulls_input_done +@@: + mov eax, skulls3d_bet + sub bankroll, eax + invoke RandomRange3D, 3 + mov skulls3d_ballPos, eax + mov skulls3d_cup0, 0 + mov skulls3d_cup1, 1 + mov skulls3d_cup2, 2 + + ; Pre-generate 3 dynamic swap pairs + invoke RandomRange3D, 3 + mov skulls3d_swapPair0, eax + invoke RandomRange3D, 3 + mov skulls3d_swapPair1, eax + invoke RandomRange3D, 3 + mov skulls3d_swapPair2, eax + + mov skulls3d_state, 1 + mov skulls3d_timer, 0 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +skulls_handle_show: + inc skulls3d_timer + cmp skulls3d_timer, 45 + jl skulls_input_done + ; Transition to Phase 2: Active Shuffle Animation + mov skulls3d_state, 2 + mov skulls3d_timer, 0 + invoke PlayCasinoSound3D, OFFSET soundShuffle, 0, 1 + ret + +skulls_handle_shuffle: + inc skulls3d_timer + cmp skulls3d_timer, 60 + jl skulls_input_done + ; Transition to Phase 3: Pick cup + mov skulls3d_state, 3 + mov skulls3d_timer, 0 + ret + +skulls_handle_pick: + invoke Pressed3D, 31h ; '1' + test eax, eax + jnz skulls_pick_1 + invoke Pressed3D, 32h ; '2' + test eax, eax + jnz skulls_pick_2 + invoke Pressed3D, 33h ; '3' + test eax, eax + jnz skulls_pick_3 + ret + +skulls_pick_1: + mov skulls3d_choice, 0 + call FinalizeSkullsGuess + ret + +skulls_pick_2: + mov skulls3d_choice, 1 + call FinalizeSkullsGuess + ret + +skulls_pick_3: + mov skulls3d_choice, 2 + call FinalizeSkullsGuess + ret + +skulls_handle_reveal: + invoke Pressed3D, 20h + test eax, eax + jz skulls_input_done + mov skulls3d_state, 0 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 +skulls_input_done: + ret +HandleSkullsInput ENDP + +RenderSkullsGame PROC uses ebx esi edi + local kx:DWORD + local passTick:DWORD, curPair:DWORD, swapSlotA:DWORD, swapSlotB:DWORD + local xA:DWORD, xB:DWORD, curXA:DWORD, curXB:DWORD, curYA:DWORD, curYB:DWORD + local distX:DWORD, dxVal:DWORD, archY:DWORD + + ; Mahogany & Gothic Purple table + invoke DrawBox, 0, 0, 320, 240, 00140906h + invoke DrawBoxBorder, 6, 6, 308, 228, 00300F22h, 00FFD700h, 2 + + ; Header + invoke DrawBoxBorder, 20, 12, 280, 26, 001A0812h, 00FFD700h, 2 + invoke DrawString8x8, 44, 21, OFFSET textSkullsTitle, 00FFFF00h + + ; Status + invoke DrawBoxBorder, 20, 44, 110, 18, 001A0812h, 00452033h, 1 + invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch + + invoke DrawBoxBorder, 190, 44, 110, 18, 001A0812h, 00452033h, 1 + invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h + invoke FormatNumber, skulls3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h + + ; Phase Prompts + cmp skulls3d_state, 0 + jne @F + invoke DrawString8x8, 56, 62, OFFSET textSkullsPhase0, 00FFD700h + jmp skulls_draw_idle_cups +@@: + cmp skulls3d_state, 1 + jne @F + invoke DrawString8x8, 56, 62, OFFSET textSkullsPhase1, 00FFFF00h + jmp skulls_draw_phase1_cups +@@: + cmp skulls3d_state, 2 + jne @F + invoke DrawString8x8, 44, 62, OFFSET textSkullsPhase2, 00FFFF00h + jmp skulls_draw_animated_cups +@@: + cmp skulls3d_state, 3 + jne @F + invoke DrawString8x8, 28, 62, OFFSET textSkullsPhase3, 00FFFF00h + jmp skulls_draw_idle_cups +@@: + ; Phase 4: Reveal outcome + mov eax, skulls3d_win + test eax, eax + jz skulls_reveal_loss_text + invoke DrawString8x8, 40, 62, OFFSET textSkullsWin, 003CFF3Ch + invoke FormatNumber, skulls3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 136, 62, OFFSET hudNumBuffer, 003CFF3Ch + invoke DrawString8x8, 168, 62, OFFSET textSkullsWinMult, 003CFF3Ch + jmp skulls_draw_reveal_cups + +skulls_reveal_loss_text: + invoke DrawString8x8, 40, 62, OFFSET textSkullsLose, 00FF6464h + jmp skulls_draw_reveal_cups + +skulls_draw_idle_cups: + ; Draw resting cups at static slots: Slot 0 (X=36), Slot 1 (X=136), Slot 2 (X=236) + invoke DrawGothicCup, 36, 114, skulls3d_cup0, 0, 0 + invoke DrawGothicCup, 136, 114, skulls3d_cup1, 0, 0 + invoke DrawGothicCup, 236, 114, skulls3d_cup2, 0, 0 + jmp skulls_render_controls + +skulls_draw_phase1_cups: + ; Draw with golden ball showing under starting cup + mov ebx, 0 + mov edx, 0 + cmp skulls3d_ballPos, 0 + jne @F + mov ebx, 1 + mov edx, 1 +@@: + invoke DrawGothicCup, 36, 114, skulls3d_cup0, ebx, edx + + mov ebx, 0 + mov edx, 0 + cmp skulls3d_ballPos, 1 + jne @F + mov ebx, 1 + mov edx, 1 +@@: + invoke DrawGothicCup, 136, 114, skulls3d_cup1, ebx, edx + + mov ebx, 0 + mov edx, 0 + cmp skulls3d_ballPos, 2 + jne @F + mov ebx, 1 + mov edx, 1 +@@: + invoke DrawGothicCup, 236, 114, skulls3d_cup2, ebx, edx + jmp skulls_render_controls + +skulls_draw_animated_cups: + ; 60 frames = 3 passes of 20 frames + mov eax, skulls3d_timer + cmp eax, 20 + jbe pass_0 + cmp eax, 40 + jbe pass_1 + sub eax, 41 + mov passTick, eax + mov eax, skulls3d_swapPair2 + mov curPair, eax + jmp setup_pass + +pass_0: + dec eax + mov passTick, eax + mov eax, skulls3d_swapPair0 + mov curPair, eax + jmp setup_pass + +pass_1: + sub eax, 21 + mov passTick, eax + mov eax, skulls3d_swapPair1 + mov curPair, eax + +setup_pass: + ; curPair determines swap pair: + ; 0: swap slot 0 (X=36) and slot 1 (X=136) + ; 1: swap slot 1 (X=136) and slot 2 (X=236) + ; 2: swap slot 0 (X=36) and slot 2 (X=236) + cmp curPair, 1 + je pair_1 + cmp curPair, 2 + je pair_2 + mov swapSlotA, 0 + mov swapSlotB, 1 + mov xA, 36 + mov xB, 136 + jmp calc_coords +pair_1: + mov swapSlotA, 1 + mov swapSlotB, 2 + mov xA, 136 + mov xB, 236 + jmp calc_coords +pair_2: + mov swapSlotA, 0 + mov swapSlotB, 2 + mov xA, 36 + mov xB, 236 + +calc_coords: + ; distX = xB - xA + mov eax, xB + sub eax, xA + mov distX, eax + + ; dxVal = (distX * passTick) / 20 + mov eax, distX + imul eax, passTick + xor edx, edx + mov ecx, 20 + div ecx + mov dxVal, eax + + ; curXA = xA + dxVal + mov eax, xA + add eax, dxVal + mov curXA, eax + + ; curXB = xB - dxVal + mov eax, xB + sub eax, dxVal + mov curXB, eax + + ; archY = (passTick * (20 - passTick)) / 10 + mov eax, passTick + mov ecx, 20 + sub ecx, eax + imul eax, ecx + xor edx, edx + mov ecx, 10 + div ecx + mov archY, eax + + ; Cup A hops UP: 114 - archY + mov eax, 114 + sub eax, archY + mov curYA, eax + + ; Cup B hops DOWN: 114 + archY + mov eax, 114 + add eax, archY + mov curYB, eax + + ; Check if pass ended (frame 19): swap ball position and cups + cmp passTick, 19 + jne draw_active_shuffle + + ; Swap ball position if involved + mov eax, skulls3d_ballPos + cmp eax, swapSlotA + jne check_ball_b + mov edx, swapSlotB + mov skulls3d_ballPos, edx + jmp swap_slot_identities +check_ball_b: + cmp eax, swapSlotB + jne swap_slot_identities + mov edx, swapSlotA + mov skulls3d_ballPos, edx + +swap_slot_identities: + cmp curPair, 1 + je swap_ids_1_2 + cmp curPair, 2 + je swap_ids_0_2 + ; swap 0 and 1 + mov eax, skulls3d_cup0 + xchg eax, skulls3d_cup1 + mov skulls3d_cup0, eax + jmp swap_sound_tick +swap_ids_1_2: + mov eax, skulls3d_cup1 + xchg eax, skulls3d_cup2 + mov skulls3d_cup1, eax + jmp swap_sound_tick +swap_ids_0_2: + mov eax, skulls3d_cup0 + xchg eax, skulls3d_cup2 + mov skulls3d_cup0, eax + +swap_sound_tick: + invoke PlayCasinoSound3D, OFFSET soundShuffle, 0, 1 + +draw_active_shuffle: + ; Draw stationary cup + cmp curPair, 1 + je draw_stat_cup0 + cmp curPair, 2 + je draw_stat_cup1 + ; Stationary cup is slot 2 (X=236) + invoke DrawGothicCup, 236, 114, skulls3d_cup2, 0, 0 + jmp draw_moving_cups +draw_stat_cup0: + ; Stationary cup is slot 0 (X=36) + invoke DrawGothicCup, 36, 114, skulls3d_cup0, 0, 0 + jmp draw_moving_cups +draw_stat_cup1: + ; Stationary cup is slot 1 (X=136) + invoke DrawGothicCup, 136, 114, skulls3d_cup1, 0, 0 + +draw_moving_cups: + ; Moving Cup A and Moving Cup B + cmp curPair, 1 + je ids_pair_1 + cmp curPair, 2 + je ids_pair_2 + mov eax, skulls3d_cup0 + mov ebx, skulls3d_cup1 + jmp draw_the_pair +ids_pair_1: + mov eax, skulls3d_cup1 + mov ebx, skulls3d_cup2 + jmp draw_the_pair +ids_pair_2: + mov eax, skulls3d_cup0 + mov ebx, skulls3d_cup2 + +draw_the_pair: + push ebx + invoke DrawGothicCup, curXA, curYA, eax, 0, 0 + pop ebx + invoke DrawGothicCup, curXB, curYB, ebx, 0, 0 + jmp skulls_render_controls + +skulls_draw_reveal_cups: + ; Reveal Phase: lift chosen cup and lift actual ball cup if different + ; Slot 0 + mov ebx, 0 + mov edx, 0 + cmp skulls3d_choice, 0 + je slot0_is_lifted + cmp skulls3d_ballPos, 0 + jne @F +slot0_is_lifted: + mov ebx, 1 + cmp skulls3d_ballPos, 0 + sete dl +@@: + invoke DrawGothicCup, 36, 114, skulls3d_cup0, ebx, edx + + ; Slot 1 + mov ebx, 0 + mov edx, 0 + cmp skulls3d_choice, 1 + je slot1_is_lifted + cmp skulls3d_ballPos, 1 + jne @F +slot1_is_lifted: + mov ebx, 1 + cmp skulls3d_ballPos, 1 + sete dl +@@: + invoke DrawGothicCup, 136, 114, skulls3d_cup1, ebx, edx + + ; Slot 2 + mov ebx, 0 + mov edx, 0 + cmp skulls3d_choice, 2 + je slot2_is_lifted + cmp skulls3d_ballPos, 2 + jne @F +slot2_is_lifted: + mov ebx, 1 + cmp skulls3d_ballPos, 2 + sete dl +@@: + invoke DrawGothicCup, 236, 114, skulls3d_cup2, ebx, edx + +skulls_render_controls: + ; Cup selection slot labels [1], [2], [3] + invoke DrawString8x8, 54, 168, OFFSET textSkullsKey1, 00D0D8E0h + invoke DrawString8x8, 150, 168, OFFSET textSkullsKey2, 00D0D8E0h + invoke DrawString8x8, 250, 168, OFFSET textSkullsKey3, 00D0D8E0h + + ; Keycaps + mov kx, 16 + xor eax, eax + cmp skulls3d_state, 3 + je key1_active + cmp skulls3d_choice, 0 + sete al + jmp draw_key1 +key1_active: + mov eax, 1 +draw_key1: + invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey1, eax + add kx, eax + + xor eax, eax + cmp skulls3d_state, 3 + je key2_active + cmp skulls3d_choice, 1 + sete al + jmp draw_key2 +key2_active: + mov eax, 1 +draw_key2: + invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey2, eax + add kx, eax + + xor eax, eax + cmp skulls3d_state, 3 + je key3_active + cmp skulls3d_choice, 2 + sete al + jmp draw_key3 +key3_active: + mov eax, 1 +draw_key3: + invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey3, eax + add kx, eax + + xor eax, eax + cmp skulls3d_state, 0 + je start_active + cmp skulls3d_state, 4 + je start_active + jmp draw_start_key +start_active: + mov eax, 1 +draw_start_key: + invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKeySpace, eax + add kx, eax + + invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0 + ret +RenderSkullsGame ENDP + +InitSkillGame PROC + mov skill3d_state, 0 + mov skill3d_timer, 0 + mov skill3d_hits, 0 + mov skill3d_misses, 0 + mov skill3d_needle, 55 + mov skill3d_speed, 4 + mov skill3d_dir, 1 + mov skill3d_last_result, 0 + mov skill3d_win_amount, 0 + + ; Randomize initial zone: 80 + RandomRange(90) -> 80..170 + invoke RandomRange3D, 90 + add eax, 80 + mov skill3d_zone_start, eax + + ; Great zone: start + 20 + RandomRange(12) + invoke RandomRange3D, 12 + add eax, skill3d_zone_start + add eax, 20 + mov skill3d_great_start, eax + ret +InitSkillGame ENDP + +HandleSkillInput PROC uses ebx esi + mov eax, skill3d_state + cmp eax, 0 + je skill_handle_ready + cmp eax, 1 + je skill_handle_active + cmp eax, 2 + je skill_handle_round_wait + cmp eax, 3 + je skill_handle_round_wait + cmp eax, 4 + je skill_handle_end_wait + cmp eax, 5 + je skill_handle_end_wait + ret + +skill_handle_ready: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz skill_bet_up + invoke Pressed3D, 57h ; 'W' + test eax, eax + jnz skill_bet_up + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz skill_bet_down + invoke Pressed3D, 53h ; 'S' + test eax, eax + jnz skill_bet_down + jmp skill_check_start + +skill_bet_up: + mov eax, skill3d_bet + add eax, 50 + cmp eax, bankroll + jle @F + mov eax, bankroll +@@: + cmp eax, 5000 + jle @F + mov eax, 5000 +@@: + mov skill3d_bet, eax + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +skill_bet_down: + mov eax, skill3d_bet + sub eax, 50 + cmp eax, 50 + jge @F + mov eax, 50 +@@: + mov skill3d_bet, eax + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +skill_check_start: + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz skill_input_done + + ; Deduct bet on game start if beginning of run + mov eax, skill3d_hits + or eax, skill3d_misses + jnz @F + mov eax, skill3d_bet + cmp eax, bankroll + jle skill_has_funds + mov eax, bankroll + mov skill3d_bet, eax + test eax, eax + jz skill_input_done +skill_has_funds: + mov eax, skill3d_bet + sub bankroll, eax +@@: + mov skill3d_state, 1 + mov skill3d_needle, 55 + mov skill3d_dir, 1 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret + +skill_handle_active: + ; Move needle smoothly + mov eax, skill3d_needle + mov edx, skill3d_speed + cmp skill3d_dir, 1 + je skill_move_right + sub eax, edx + cmp eax, 52 + jge skill_update_needle + mov eax, 52 + mov skill3d_dir, 1 + jmp skill_update_needle +skill_move_right: + add eax, edx + cmp eax, 268 + jle skill_update_needle + mov eax, 268 + mov skill3d_dir, -1 +skill_update_needle: + mov skill3d_needle, eax + + ; Check SPACE pressed (Reaction Hit Attempt!) + invoke Pressed3D, 20h + test eax, eax + jz skill_input_done + + ; Is needle in Great Sweet Spot? + mov eax, skill3d_needle + mov edx, skill3d_great_start + cmp eax, edx + jl check_success_zone + add edx, skill3d_great_width + cmp eax, edx + jg check_success_zone + + ; GREAT HIT! + mov skill3d_last_result, 2 + add skill3d_hits, 2 + mov skill3d_state, 2 + mov skill3d_timer, 40 + invoke PlayCasinoSound3D, OFFSET soundSkillPerfect, 0, 1 + jmp skill_check_finish_round + +check_success_zone: + mov eax, skill3d_needle + mov edx, skill3d_zone_start + cmp eax, edx + jl skill_was_miss + add edx, skill3d_zone_width + cmp eax, edx + jg skill_was_miss + + ; NORMAL HIT! + mov skill3d_last_result, 1 + inc skill3d_hits + mov skill3d_state, 2 + mov skill3d_timer, 40 + invoke PlayCasinoSound3D, OFFSET soundSkillHit, 0, 1 + jmp skill_check_finish_round + +skill_was_miss: + ; MISS! + mov skill3d_last_result, 0 + inc skill3d_misses + mov skill3d_state, 3 + mov skill3d_timer, 45 + invoke PlayCasinoSound3D, OFFSET soundSkillMiss, 0, 1 + +skill_check_finish_round: + cmp skill3d_hits, 5 + jge skill_game_escaped + cmp skill3d_misses, 3 + jge skill_game_lost + ret + +skill_game_escaped: + mov skill3d_state, 4 + mov skill3d_timer, 0 + ; Payout: 3x total return (+$2x bet profit) + mov eax, skill3d_bet + imul eax, 3 + add bankroll, eax + mov eax, skill3d_bet + shl eax, 1 + mov skill3d_win_amount, eax + invoke NpcRecordRound3D,10,1 + call SaveProgress3D + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 + ret + +skill_game_lost: + mov skill3d_state, 5 + mov skill3d_timer, 0 + invoke NpcRecordRound3D,10,0 + call SaveProgress3D + invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 + ret + +skill_handle_round_wait: + dec skill3d_timer + cmp skill3d_timer, 0 + jg skill_input_done + + ; Next round setup + invoke RandomRange3D, 90 + add eax, 80 + mov skill3d_zone_start, eax + + invoke RandomRange3D, 12 + add eax, skill3d_zone_start + add eax, 20 + mov skill3d_great_start, eax + + mov eax, skill3d_hits + shr eax, 1 + add eax, 4 + mov skill3d_speed, eax + mov skill3d_state, 1 + ret + +skill_handle_end_wait: + invoke Pressed3D, 20h + test eax, eax + jz skill_input_done + call InitSkillGame + ret + +skill_input_done: + ret +HandleSkillInput ENDP + +RenderSkillGame PROC uses ebx esi edi + local kx:DWORD + local tx:DWORD + + ; Industrial Steel bezel + invoke DrawBox, 0, 0, 320, 240, 00121416h + invoke DrawBoxBorder, 6, 6, 308, 228, 001A1D20h, 00FFD700h, 2 + + ; Header + invoke DrawBoxBorder, 20, 12, 280, 26, 00121418h, 00FFD700h, 2 + invoke DrawString8x8, 40, 21, OFFSET textSkillTitle, 00FFFF00h + + ; Status + invoke DrawBoxBorder, 20, 44, 110, 18, 00121418h, 002A3540h, 1 + invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch + + invoke DrawBoxBorder, 190, 44, 110, 18, 00121418h, 002A3540h, 1 + invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h + invoke FormatNumber, skill3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h + + ; Survivor Progress + invoke DrawString8x8, 24, 70, OFFSET textSkillHitsHdr, 003CFF3Ch + invoke FormatNumber, skill3d_hits, OFFSET hudNumBuffer + invoke DrawString8x8, 64, 70, OFFSET hudNumBuffer, 003CFF3Ch + + invoke DrawString8x8, 180, 70, OFFSET textSkillMissHdr, 00FF6464h + invoke FormatNumber, skill3d_misses, OFFSET hudNumBuffer + invoke DrawString8x8, 240, 70, OFFSET hudNumBuffer, 00FF6464h + + ; Dial Frame (Track: X=50..270, Y=102..134) + invoke DrawBoxBorder, 50, 102, 220, 32, 000F1114h, 00404855h, 2 + + ; Calibrated ticks + mov tx, 60 +skill_ticks_loop: + cmp tx, 260 + jge skill_draw_zones + invoke DrawBox, tx, 104, 1, 6, 00303845h + invoke DrawBox, tx, 126, 1, 6, 00303845h + add tx, 12 + jmp skill_ticks_loop + +skill_draw_zones: + ; Normal Success Zone (Green) + invoke DrawBoxBorder, skill3d_zone_start, 106, skill3d_zone_width, 24, 00155020h, 003CFF3Ch, 1 + + ; Great Zone (Gold) + invoke DrawBoxBorder, skill3d_great_start, 106, skill3d_great_width, 24, 00FFD700h, 00FFFF00h, 1 + + ; Pointer / Needle at skill3d_needle + mov eax, skill3d_needle + dec eax + invoke DrawBox, eax, 98, 3, 40, 00FFFFFFh + mov eax, skill3d_needle + sub eax, 2 + invoke DrawBox, eax, 96, 5, 2, 00FF3030h + invoke DrawBox, eax, 138, 5, 2, 00FF3030h + + ; Center prompts / outcome + cmp skill3d_state, 0 + jne @F + invoke DrawString8x8, 52, 150, OFFSET textSkillReadyMsg, 00FFD700h + invoke DrawString8x8, 76, 166, OFFSET textSkillPrompt, 00D0D8E0h + jmp skill_render_keys +@@: + cmp skill3d_state, 1 + jne @F + invoke DrawString8x8, 76, 150, OFFSET textSkillPrompt, 00FFFF00h + jmp skill_render_keys +@@: + cmp skill3d_state, 2 + jne @F + cmp skill3d_last_result, 2 + jne skill_normal_hit_text + invoke DrawString8x8, 36, 150, OFFSET textSkillGreatMsg, 00FFFF00h + jmp skill_render_keys +skill_normal_hit_text: + invoke DrawString8x8, 64, 150, OFFSET textSkillHitMsg, 003CFF3Ch + jmp skill_render_keys +@@: + cmp skill3d_state, 3 + jne @F + invoke DrawString8x8, 88, 150, OFFSET textSkillMissMsg, 00FF6464h + jmp skill_render_keys +@@: + cmp skill3d_state, 4 + jne @F + invoke DrawString8x8, 48, 150, OFFSET textSkillEscape, 003CFF3Ch + invoke FormatNumber, skill3d_win_amount, OFFSET hudNumBuffer + invoke DrawString8x8, 240, 150, OFFSET hudNumBuffer, 003CFF3Ch + invoke DrawString8x8, 64, 166, OFFSET textSkullsAgain, 00FFD700h + jmp skill_render_keys +@@: + invoke DrawString8x8, 44, 150, OFFSET textSkillLost, 00FF6464h + invoke DrawString8x8, 64, 166, OFFSET textSkullsAgain, 00FFD700h + +skill_render_keys: + mov kx, 16 + invoke DrawKeycap3D, kx, 192, OFFSET textSkillKeySpace, 1 + add kx, eax + + invoke DrawKeycap3D, kx, 192, OFFSET textSkillKeyBet, 0 + add kx, eax + + invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0 + ret +RenderSkillGame ENDP + +HandlePlayerInput PROC uses ebx esi edi + local speed:DWORD + local nextX:DWORD + local nextY:DWORD + mov eax, deltaTime3D + imul eax, 200 + mov speed, eax + cmp keys3D[10h], 0 + je @F + shl speed, 1 +@@: + mov eax, deltaTime3D + shr eax, 2 + inc eax + cmp keys3D[41h], 0 + jne input_turn_left + cmp keys3D[25h], 0 + je input_right +input_turn_left: + sub playerAngle, eax +input_right: + cmp keys3D[44h], 0 + jne input_turn_right + cmp keys3D[27h], 0 + je input_forward +input_turn_right: + add playerAngle, eax +input_forward: + and playerAngle, 511 + call UpdateCamera3D + xor edi, edi + cmp keys3D[57h], 0 + jne input_go_forward + cmp keys3D[26h], 0 + je input_back +input_go_forward: + inc edi +input_back: + cmp keys3D[53h], 0 + jne input_go_back + cmp keys3D[28h], 0 + je input_move +input_go_back: + dec edi +input_move: + test edi, edi + jz input_action + imul edi, speed + mov eax, playerDirX + imul edi + shrd eax, edx, 16 + add eax, playerX + mov nextX, eax + mov eax, playerDirY + imul edi + shrd eax, edx, 16 + add eax, playerY + mov nextY, eax + invoke CanWalk3D, nextX, playerY + test eax, eax + jz @F + mov eax, nextX + mov playerX, eax +@@: + invoke CanWalk3D, playerX, nextY + test eax, eax + jz input_action + mov eax, nextY + mov playerY, eax +input_action: + invoke Pressed3D, 45h + test eax, eax + jz @F + call Trigger3DInteraction +@@: + ret +HandlePlayerInput ENDP + +CheckInteractions PROC uses ebx esi edi + local nearest:DWORD + mov nearest, 262144 + mov interactTargetId, 0 + mov interactPromptPtr, 0 + xor esi, esi +interaction_scan: + cmp esi, NUM_SPRITES + jge interaction_done + imul edi, esi, SIZEOF SpriteObject + cmp [casinoSprites+edi].interactId, 0 + je interaction_next + mov eax, [casinoSprites+edi].posX + sub eax, playerX + sar eax, 8 + mov ebx, eax + imul eax, eax + mov ecx, eax + mov eax, [casinoSprites+edi].posY + sub eax, playerY + sar eax, 8 + mov edx, eax + imul eax, eax + add ecx, eax + cmp ecx, nearest + jae interaction_next + ; Only target objects in front of the camera. + mov eax, playerDirX + sar eax, 8 + imul eax, ebx + mov ebx, playerDirY + sar ebx, 8 + imul ebx, edx + add eax, ebx + cmp eax, 18000 + jl interaction_next + mov nearest, ecx + mov eax, [casinoSprites+edi].interactId + mov interactTargetId, eax + mov eax, [casinoSprites+edi].promptPtr + mov interactPromptPtr, eax +interaction_next: + inc esi + jmp interaction_scan +interaction_done: + call CheckHallInteractions3D + ret +CheckInteractions ENDP + +; --- RenderCabinetBezel: Îòðèñîâêà àðêàäíîãî áåçåëÿ òåðìèíàëà íà 3D ýêðàíå --- +RenderCabinetBezel PROC uses ebx esi edi, pTitle:DWORD + ; Çàòåìíÿåì 3D-çàë â áóôåðå êàäðà (äåëèì ÿðêîñòü ïîïîëàì) + mov ecx, SCREEN_SIZE + xor esi, esi +dim_bezel_loop: + mov eax, [screenBuffer + esi*4] + shr eax, 1 + and eax, 007F7F7Fh + mov [screenBuffer + esi*4], eax + inc esi + loop dim_bezel_loop + + ; Âíåøíÿÿ çîëîòàÿ ðàìêà òåðìèíàëà + invoke DrawBoxBorder, 10, 14, 300, 212, 000C0E14h, 00D8BC6Ah, 2 + + ; Øàïêà òåðìèíàëà ñ íàçâàíèåì èãðû + invoke DrawBox, 12, 16, 296, 16, 00221A10h + invoke DrawString8x8, 20, 20, pTitle, 00F5E2B0h + + ; Ïîäâàëüíàÿ ïëàøêà ñ ïîäñêàçêîé ïî âûõîäó + invoke DrawBox, 12, 210, 296, 14, 00141416h + invoke DrawString8x8, 20, 213, OFFSET textCabinetFooter, 00AAAAAAh + + ; Âûâîäèì êàäð áåçåëÿ â îêíî + call Present3D + ret +RenderCabinetBezel ENDP + +; --- LaunchClassicGame: Âñòðàèâàíèå èãðû â UI òåðìèíàëà êàçèíî --- +LaunchClassicGame PROC uses ebx esi edi, pGameProc:DWORD, gameId:DWORD, pTitle:DWORD + LOCAL rcClient[16]:BYTE + LOCAL ptScreen[8]:BYTE + LOCAL fontInfo[84]:BYTE + LOCAL conWnd:DWORD + LOCAL conW:DWORD, conH:DWORD, conX:DWORD, conY:DWORD + LOCAL viewW:DWORD, viewH:DWORD + LOCAL offsetX:DWORD, offsetY:DWORD + + mov eax, gameId + mov currentGameId, eax + + ; 1. Ðèñóåì çîëîòîé áåçåëü òåðìèíàëà íà 3D ýêðàíå + cmp pTitle, 0 + je @F + invoke RenderCabinetBezel, pTitle +@@: + + ; 2. Âûäåëÿåì êîíñîëü + invoke AllocConsole + test eax, eax + jz launch_ret + + invoke GetStdHandle, STD_OUTPUT_HANDLE + mov hOut, eax + invoke GetStdHandle, STD_INPUT_HANDLE + mov hIn, eax + + invoke SetConsoleCP, 1251 + invoke SetConsoleOutputCP, 1251 + + cmp pTitle, 0 + je @F + invoke SetConsoleTitleA, pTitle +@@: + call EnableAnsi + call ConfigureConsoleSize + + ; 3. Íàñòðàèâàåì øðèôò Consolas Bold 16pt + lea edi, fontInfo + xor eax, eax + mov ecx, 21 + rep stosd + mov dword ptr fontInfo[0], 84 ; cbSize + mov word ptr fontInfo[8], 0 ; dwFontSize.X + mov word ptr fontInfo[10], 16 ; dwFontSize.Y + mov dword ptr fontInfo[16], 700 ; FontWeight = FW_BOLD + mov word ptr fontInfo[20], 'C' + mov word ptr fontInfo[22], 'o' + mov word ptr fontInfo[24], 'n' + mov word ptr fontInfo[26], 's' + mov word ptr fontInfo[28], 'o' + mov word ptr fontInfo[30], 'l' + mov word ptr fontInfo[32], 'a' + mov word ptr fontInfo[34], 's' + mov word ptr fontInfo[36], 0 + lea eax, fontInfo + invoke SetCurrentConsoleFontEx, hOut, 0, eax + + ; 4. Ïîëó÷àåì äåñêðèïòîð îêíà êîíñîëè + invoke GetConsoleWindow + mov conWnd, eax + test eax, eax + jz run_game_body + + ; 5. Ñíèìàåì ñèñòåìíóþ ðàìêó Windows è çàãîëîâîê ñ êíîïêàìè çàêðûòèÿ/ñâîðà÷èâàíèÿ + invoke GetWindowLongA, conWnd, -16 ; GWL_STYLE + and eax, NOT (00C00000h or 00040000h or 00080000h or 00010000h or 00020000h) + or eax, 80000000h ; WS_POPUP + invoke SetWindowLongA, conWnd, -16, eax + + ; Ñâÿçûâàåì êàê äî÷åðíåå/ïðèíàäëåæàùåå îêíî ê îêíó èãðû + cmp h3DWnd, 0 + je show_con_fallback + invoke SetWindowLongA, conWnd, -8, h3DWnd ; GWL_HWNDPARENT + + ; 6. Âû÷èñëÿåì òî÷íûå êîîðäèíàòû äëÿ ïîñàäêè ýêðàíà âíóòðü áåçåëÿ + lea eax, rcClient + invoke GetClientRect, h3DWnd, eax + mov esi, dword ptr rcClient[8] ; øèðèíà êëèåíòñêîé îáëàñòè + mov edi, dword ptr rcClient[12] ; âûñîòà êëèåíòñêîé îáëàñòè + test esi, esi + jz show_con_fallback + test edi, edi + jz show_con_fallback + + ; Ðàñ÷åò âüþïîðòà 4:3 òî÷íî êàê â Present3D + mov viewW, esi + mov eax, esi + imul eax, 3 + shr eax, 2 + cmp eax, edi + jle calc_view_h + mov eax, edi + imul eax, 4 + xor edx, edx + mov ecx, 3 + div ecx + mov viewW, eax + mov eax, edi +calc_view_h: + mov viewH, eax + + mov ebx, esi + sub ebx, viewW + shr ebx, 1 + mov offsetX, ebx + + mov ebx, edi + sub ebx, viewH + shr ebx, 1 + mov offsetY, ebx + + ; Ýêðàííûå êîîðäèíàòû ëåâîãî âåðõíåãî óãëà êëèåíòñêîé îáëàñòè + mov dword ptr ptScreen[0], 0 + mov dword ptr ptScreen[4], 0 + lea eax, ptScreen + invoke ClientToScreen, h3DWnd, eax + + ; conW = viewW * 280 / 320 (âíóòðåííåå îêíî áåçåëÿ) + mov eax, viewW + imul eax, 280 + xor edx, edx + mov ecx, 320 + div ecx + mov conW, eax + + ; conH = viewH * 168 / 240 + mov eax, viewH + imul eax, 168 + xor edx, edx + mov ecx, 240 + div ecx + mov conH, eax + + ; conX = ptScreen.x + offsetX + (viewW * 20 / 320) + mov eax, viewW + imul eax, 20 + xor edx, edx + mov ecx, 320 + div ecx + add eax, offsetX + add eax, dword ptr ptScreen[0] + mov conX, eax + + ; conY = ptScreen.y + offsetY + (viewH * 38 / 240) + mov eax, viewH + imul eax, 38 + xor edx, edx + mov ecx, 240 + div ecx + add eax, offsetY + add eax, dword ptr ptScreen[4] + mov conY, eax + + ; Ïîçèöèîíèðóåì áåçðàìî÷íûé ýêðàí òî÷íî âíóòðü çîëîòîé ðàìêè áåçåëÿ + invoke SetWindowPos, conWnd, 0, conX, conY, conW, conH, 20h or 40h ; SWP_FRAMECHANGED | SWP_SHOWWINDOW + jmp set_con_focus + +show_con_fallback: + invoke ShowWindow, conWnd, 5 ; SW_SHOW +set_con_focus: + invoke SetForegroundWindow, conWnd + invoke SetFocus, conWnd + +run_game_body: + invoke PlayCasinoSound3D, 0, 0, 0 + call InitSounds + ; Çàïóñê îðèãèíàëüíîé èãðû! + call pGameProc + call CloseLegacySounds3D + + ; Çàêðûâàåì êîíñîëü + invoke FreeConsole + mov hOut, 0 + mov hIn, 0 + + ; Âîçâðàùàåì ôîêóñ â îêíî 3D èãðû + cmp h3DWnd, 0 + je cleanup_game_input + invoke SetForegroundWindow, h3DWnd + invoke SetFocus, h3DWnd + +cleanup_game_input: + mov ecx, 256 + xor eax, eax + lea edi, keys3D + rep stosb + mov ecx, 256 + lea edi, pressedKeys3D + rep stosb + + invoke GetTickCount + mov previousTick3D, eax + mov frameStart3D, eax + mov deltaTime3D, 0 + + call SaveProgress3D + +launch_ret: + ret +LaunchClassicGame ENDP + +Trigger3DInteraction PROC + call TriggerHallInteraction3D + test eax, eax + jnz trigger_done + mov eax, interactTargetId + test eax, eax + jz trigger_done + + cmp eax, INTERACT_DANCER + jne check_target_bj + cmp bankroll, 100 + jl dancer_no_cash + sub bankroll, 100 + inc dancerLuckBuff + invoke CopyString3D, OFFSET textTips3D, OFFSET flashMessage + mov flashTimer, 100 + invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1 + ret +dancer_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + ret + +check_target_bj: + cmp eax, INTERACT_BLACKJACK + jne check_target_poker + call InitNativeBlackjack3D + mov engineMode, MODE_BLACKJACK + ret + +check_target_poker: + cmp eax, INTERACT_POKER + jne check_target_durak + call InitNativePoker3D + test eax, eax + jz target_unported + mov engineMode, MODE_POKER + ret + +check_target_durak: + cmp eax, INTERACT_DURAK + jne check_target_slots777 + call InitNativeDurak3D + mov engineMode, MODE_DURAK + ret + +check_target_slots777: + cmp eax, INTERACT_SLOTS_777 + jne check_target_slots_clover + call InitNativeSlots3D + test eax,eax + jz target_unported + mov engineMode,MODE_SLOTS + ret + +check_target_slots_clover: + cmp eax, INTERACT_SLOTS_CLOVER + jne check_target_roulette + call InitNativeClover3D + test eax,eax + jz target_unported + mov engineMode,MODE_CLOVER + ret + +check_target_roulette: + cmp eax, INTERACT_ROULETTE + jne check_target_dice + call InitNativeWheel3D + mov engineMode, MODE_ROULETTE + ret + +check_target_dice: + cmp eax, INTERACT_DICE + jne check_target_skulls + call InitDiceGame + mov engineMode, MODE_DICE + ret + +check_target_skulls: + cmp eax, INTERACT_SKULLS + jne check_target_coin + call InitSkullsGame + mov engineMode, MODE_SKULLS + ret + +check_target_coin: + cmp eax, INTERACT_COIN + jne check_target_skill + call InitCoinGame + mov engineMode, MODE_COIN + ret + +check_target_skill: + cmp eax, INTERACT_SKILL_CHECK + jne check_target_buckshot + call InitSkillGame + mov engineMode, MODE_SKILL + ret + +check_target_buckshot: + cmp eax, INTERACT_BUCKSHOT + jne check_target_rr + call InitBuckshot3D + mov engineMode, MODE_BUCKSHOT + ret + +check_target_rr: + cmp eax, INTERACT_RUSSIAN_ROULETTE + jne check_target_online_rr + call InitRussianGame3D + test eax, eax + jz @F + mov engineMode, MODE_RUSSIAN +@@: + ret + +check_target_online_rr: + cmp eax, INTERACT_ONLINE_RR + jne check_target_umamusume + call BeginUnavailable3D + ret + +check_target_umamusume: + cmp eax, INTERACT_UMAMUSUME + jne check_target_hell + call BeginUnavailable3D + ret + +check_target_hell: + cmp eax, INTERACT_HELL_TOWER + jne check_target_shop + call BeginUnavailable3D + ret + +check_target_shop: + cmp eax, INTERACT_SHOP + jne check_target_atm + call BeginMerchant3D + ret + +check_target_atm: + cmp eax, INTERACT_ATM + jne check_target_terminal + mov engineMode, MODE_ATM + ret + +check_target_terminal: + cmp eax, INTERACT_TERMINAL + jne check_target_observer + call BeginUnavailable3D + ret + +check_target_observer: + cmp eax, INTERACT_OBSERVER + jne target_unported + call BeginUnavailable3D + ret + +target_unported: + call BeginUnavailable3D +trigger_done: + ret +Trigger3DInteraction ENDP + +; --- Engine Initialization --- +Init3DEngine PROC + local screenCX:DWORD + local screenCY:DWORD + local posX:DWORD + local posY:DWORD + local bytesRead:DWORD + + push ebx + push esi + push edi + + call LoadDisplaySettings3D + call Create3DWindow + test eax, eax + jz init_failed + call LoadTextures3D + test eax, eax + jz init_failed + + call InitializeCasinoSprites3D + + call InitHall3D + call BeginStartup3D + call RenderStartup3D + invoke ShowWindow, h3DWnd, SW_SHOW + invoke UpdateWindow, h3DWnd + invoke SetForegroundWindow, h3DWnd + mov eax, 1 + jmp init_return +init_failed: + xor eax, eax +init_return: + pop edi + pop esi + pop ebx + ret +Init3DEngine ENDP + +InitializeCasinoSprites3D PROC +init_sprites_table: + ; Sprite 0: VIP Dancer 1 (Stage Left) + mov casinoSprites[0*SIZEOF SpriteObject].posX, (13 * FP_1 + FP_HALF) + mov casinoSprites[0*SIZEOF SpriteObject].posY, (4 * FP_1) + mov casinoSprites[0*SIZEOF SpriteObject].baseTexId, 10 + mov casinoSprites[0*SIZEOF SpriteObject].frameCount, 12 + mov casinoSprites[0*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[0*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[0*SIZEOF SpriteObject].animSpeed, 5 + mov casinoSprites[0*SIZEOF SpriteObject].interactId, INTERACT_DANCER + mov casinoSprites[0*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer + + ; Sprite 1: VIP Dancer 2 (Center Stage Star) + mov casinoSprites[1*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF) + mov casinoSprites[1*SIZEOF SpriteObject].posY, (3 * FP_1 + FP_HALF) + mov casinoSprites[1*SIZEOF SpriteObject].baseTexId, 10 + mov casinoSprites[1*SIZEOF SpriteObject].frameCount, 12 + mov casinoSprites[1*SIZEOF SpriteObject].curFrame, 2 + mov casinoSprites[1*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[1*SIZEOF SpriteObject].animSpeed, 5 + mov casinoSprites[1*SIZEOF SpriteObject].interactId, INTERACT_DANCER + mov casinoSprites[1*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer + + ; Sprite 2: VIP Dancer 3 (Stage Right) + mov casinoSprites[2*SIZEOF SpriteObject].posX, (19 * FP_1 + FP_HALF) + mov casinoSprites[2*SIZEOF SpriteObject].posY, (4 * FP_1) + mov casinoSprites[2*SIZEOF SpriteObject].baseTexId, 10 + mov casinoSprites[2*SIZEOF SpriteObject].frameCount, 12 + mov casinoSprites[2*SIZEOF SpriteObject].curFrame, 1 + mov casinoSprites[2*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[2*SIZEOF SpriteObject].animSpeed, 5 + mov casinoSprites[2*SIZEOF SpriteObject].interactId, INTERACT_DANCER + mov casinoSprites[2*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer + + ; Sprite 3: VIP Blackjack (Front Center Left) + mov casinoSprites[3*SIZEOF SpriteObject].posX, (12 * FP_1 + FP_HALF) + mov casinoSprites[3*SIZEOF SpriteObject].posY, (8 * FP_1) + mov casinoSprites[3*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[3*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[3*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[3*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[3*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[3*SIZEOF SpriteObject].interactId, INTERACT_BLACKJACK + mov casinoSprites[3*SIZEOF SpriteObject].promptPtr, OFFSET promptBlackjack + + ; Sprite 4: European Roulette Table (Front Center) + mov casinoSprites[4*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF) + mov casinoSprites[4*SIZEOF SpriteObject].posY, (10 * FP_1) + mov casinoSprites[4*SIZEOF SpriteObject].baseTexId, 31 + mov casinoSprites[4*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[4*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[4*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[4*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[4*SIZEOF SpriteObject].interactId, INTERACT_ROULETTE + mov casinoSprites[4*SIZEOF SpriteObject].promptPtr, OFFSET promptCasinoRoulette + + ; Sprite 5: Texas Hold'em Poker Table (Front Center Right) + mov casinoSprites[5*SIZEOF SpriteObject].posX, (20 * FP_1 + FP_HALF) + mov casinoSprites[5*SIZEOF SpriteObject].posY, (8 * FP_1) + mov casinoSprites[5*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[5*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[5*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[5*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[5*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[5*SIZEOF SpriteObject].interactId, INTERACT_POKER + mov casinoSprites[5*SIZEOF SpriteObject].promptPtr, OFFSET promptPoker + + ; Sprite 6: Podkidnoy Durak Card Table + mov casinoSprites[6*SIZEOF SpriteObject].posX, (24 * FP_1 + FP_HALF) + mov casinoSprites[6*SIZEOF SpriteObject].posY, (8 * FP_1) + mov casinoSprites[6*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[6*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[6*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[6*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[6*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[6*SIZEOF SpriteObject].interactId, INTERACT_DURAK + mov casinoSprites[6*SIZEOF SpriteObject].promptPtr, OFFSET promptDurak + + ; Sprite 7: Classic Slots 777 (West Arcade 1) + mov casinoSprites[7*SIZEOF SpriteObject].posX, (6 * FP_1) + mov casinoSprites[7*SIZEOF SpriteObject].posY, (8 * FP_1) + mov casinoSprites[7*SIZEOF SpriteObject].baseTexId, 24 + mov casinoSprites[7*SIZEOF SpriteObject].frameCount, 3 + mov casinoSprites[7*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[7*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[7*SIZEOF SpriteObject].animSpeed, 8 + mov casinoSprites[7*SIZEOF SpriteObject].interactId, INTERACT_SLOTS_777 + mov casinoSprites[7*SIZEOF SpriteObject].promptPtr, OFFSET promptClassicSlot + + ; Sprite 8: CloverPit Slots 5x3 (West Arcade 2) + mov casinoSprites[8*SIZEOF SpriteObject].posX, (6 * FP_1) + mov casinoSprites[8*SIZEOF SpriteObject].posY, (11 * FP_1) + mov casinoSprites[8*SIZEOF SpriteObject].baseTexId, 24 + mov casinoSprites[8*SIZEOF SpriteObject].frameCount, 3 + mov casinoSprites[8*SIZEOF SpriteObject].curFrame, 1 + mov casinoSprites[8*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[8*SIZEOF SpriteObject].animSpeed, 8 + mov casinoSprites[8*SIZEOF SpriteObject].interactId, INTERACT_SLOTS_CLOVER + mov casinoSprites[8*SIZEOF SpriteObject].promptPtr, OFFSET promptCloverSlot + + ; Sprite 9: Craps & Dice Table (West Arcade 3) + mov casinoSprites[9*SIZEOF SpriteObject].posX, (6 * FP_1) + mov casinoSprites[9*SIZEOF SpriteObject].posY, (14 * FP_1) + mov casinoSprites[9*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[9*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[9*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[9*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[9*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[9*SIZEOF SpriteObject].interactId, INTERACT_DICE + mov casinoSprites[9*SIZEOF SpriteObject].promptPtr, OFFSET promptDice + + ; Sprite 10: Skulls & Cups Table + mov casinoSprites[10*SIZEOF SpriteObject].posX, (10 * FP_1) + mov casinoSprites[10*SIZEOF SpriteObject].posY, (15 * FP_1) + mov casinoSprites[10*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[10*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[10*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[10*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[10*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[10*SIZEOF SpriteObject].interactId, INTERACT_SKULLS + mov casinoSprites[10*SIZEOF SpriteObject].promptPtr, OFFSET promptSkulls + + ; Sprite 11: Coin Toss Stand + mov casinoSprites[11*SIZEOF SpriteObject].posX, (14 * FP_1) + mov casinoSprites[11*SIZEOF SpriteObject].posY, (15 * FP_1) + mov casinoSprites[11*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[11*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[11*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[11*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[11*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[11*SIZEOF SpriteObject].interactId, INTERACT_COIN + mov casinoSprites[11*SIZEOF SpriteObject].promptPtr, OFFSET promptCoin + + ; Sprite 12: Skill Check Stand + mov casinoSprites[12*SIZEOF SpriteObject].posX, (18 * FP_1) + mov casinoSprites[12*SIZEOF SpriteObject].posY, (15 * FP_1) + mov casinoSprites[12*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[12*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[12*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[12*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[12*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[12*SIZEOF SpriteObject].interactId, INTERACT_SKILL_CHECK + mov casinoSprites[12*SIZEOF SpriteObject].promptPtr, OFFSET promptSkillCheck + + ; Sprite 13: Umamusume Derby Lounge + mov casinoSprites[13*SIZEOF SpriteObject].posX, (22 * FP_1) + mov casinoSprites[13*SIZEOF SpriteObject].posY, (15 * FP_1) + mov casinoSprites[13*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[13*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[13*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[13*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[13*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[13*SIZEOF SpriteObject].interactId, INTERACT_UMAMUSUME + mov casinoSprites[13*SIZEOF SpriteObject].promptPtr, OFFSET promptUmamusume + + ; Sprite 14: Boutique & Shop (East Wing) + mov casinoSprites[14*SIZEOF SpriteObject].posX, (26 * FP_1) + mov casinoSprites[14*SIZEOF SpriteObject].posY, (12 * FP_1) + mov casinoSprites[14*SIZEOF SpriteObject].baseTexId, 32 + mov casinoSprites[14*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[14*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[14*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[14*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[14*SIZEOF SpriteObject].interactId, INTERACT_SHOP + mov casinoSprites[14*SIZEOF SpriteObject].promptPtr, OFFSET promptShop + + ; Sprite 15: Cashier & ATM (East Wing) + mov casinoSprites[15*SIZEOF SpriteObject].posX, (26 * FP_1) + mov casinoSprites[15*SIZEOF SpriteObject].posY, (16 * FP_1) + mov casinoSprites[15*SIZEOF SpriteObject].baseTexId, 33 + mov casinoSprites[15*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[15*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[15*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[15*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[15*SIZEOF SpriteObject].interactId, INTERACT_ATM + mov casinoSprites[15*SIZEOF SpriteObject].promptPtr, OFFSET promptATM + + ; Sprite 16: Player Terminal (East Wing) + mov casinoSprites[16*SIZEOF SpriteObject].posX, (26 * FP_1) + mov casinoSprites[16*SIZEOF SpriteObject].posY, (20 * FP_1) + mov casinoSprites[16*SIZEOF SpriteObject].baseTexId, 33 + mov casinoSprites[16*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[16*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[16*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[16*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[16*SIZEOF SpriteObject].interactId, INTERACT_TERMINAL + mov casinoSprites[16*SIZEOF SpriteObject].promptPtr, OFFSET promptPlayerTerminal + + ; Sprite 17: Buckshot Roulette (South-West) + mov casinoSprites[17*SIZEOF SpriteObject].posX, (12 * FP_1) + mov casinoSprites[17*SIZEOF SpriteObject].posY, (22 * FP_1) + mov casinoSprites[17*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[17*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[17*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[17*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[17*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[17*SIZEOF SpriteObject].interactId, INTERACT_BUCKSHOT + mov casinoSprites[17*SIZEOF SpriteObject].promptPtr, OFFSET promptBuckshot + + ; Sprite 18: Observer Lounge (South-East) + mov casinoSprites[18*SIZEOF SpriteObject].posX, (20 * FP_1) + mov casinoSprites[18*SIZEOF SpriteObject].posY, (22 * FP_1) + mov casinoSprites[18*SIZEOF SpriteObject].baseTexId, 30 + mov casinoSprites[18*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[18*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[18*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[18*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[18*SIZEOF SpriteObject].interactId, INTERACT_OBSERVER + mov casinoSprites[18*SIZEOF SpriteObject].promptPtr, OFFSET promptObserver + + ; Sprite 19: Russian Roulette (Backroom Entrance) + mov casinoSprites[19*SIZEOF SpriteObject].posX, (16 * FP_1) + mov casinoSprites[19*SIZEOF SpriteObject].posY, (25 * FP_1) + mov casinoSprites[19*SIZEOF SpriteObject].baseTexId, 34 + mov casinoSprites[19*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[19*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[19*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[19*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[19*SIZEOF SpriteObject].interactId, INTERACT_RUSSIAN_ROULETTE + mov casinoSprites[19*SIZEOF SpriteObject].promptPtr, OFFSET promptRussianRoulette + + ; Sprite 20: Online Russian Roulette (Backroom Secret Terminal) + mov casinoSprites[20*SIZEOF SpriteObject].posX, (18 * FP_1) + mov casinoSprites[20*SIZEOF SpriteObject].posY, (25 * FP_1) + mov casinoSprites[20*SIZEOF SpriteObject].baseTexId, 34 + mov casinoSprites[20*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[20*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[20*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[20*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[20*SIZEOF SpriteObject].interactId, INTERACT_ONLINE_RR + mov casinoSprites[20*SIZEOF SpriteObject].promptPtr, OFFSET promptOnlineRR + + ; Sprite 21: Hell Tower Portal (South Wing Deep End) + mov casinoSprites[21*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF) + mov casinoSprites[21*SIZEOF SpriteObject].posY, (29 * FP_1) + mov casinoSprites[21*SIZEOF SpriteObject].baseTexId, 4 + mov casinoSprites[21*SIZEOF SpriteObject].frameCount, 1 + mov casinoSprites[21*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[21*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[21*SIZEOF SpriteObject].animSpeed, 1 + mov casinoSprites[21*SIZEOF SpriteObject].interactId, INTERACT_HELL_TOWER + mov casinoSprites[21*SIZEOF SpriteObject].promptPtr, OFFSET promptHellTower + ret +InitializeCasinoSprites3D ENDP + +include src_graphics\audio_code.inc +include src_graphics\dice_animation.inc +include src_graphics\russian_roulette.inc +include src_graphics\startup_code.inc +include src_graphics\card_table_assets.inc +include src_graphics\poker_evaluator.inc +include src_graphics\native_poker.inc +include src_graphics\native_blackjack.inc +include src_graphics\native_durak.inc +include src_graphics\card_tables_render.inc +include src_graphics\durak_render.inc +include src_graphics\card_table_input.inc +include src_graphics\scene_animation.inc +include src_graphics\native_slots.inc +include src_graphics\native_clover.inc +include src_graphics\native_coin.inc +include src_graphics\graphic_profiles.inc +include src_graphics\city_arrival_scene.inc +include src_graphics\arrival_scene.inc +include src_graphics\merchant_scene.inc +include src_graphics\hall_scene.inc +include src_graphics\npc_mind.inc +include src_graphics\npc_life.inc +include src_graphics\npc_contracts.inc +include src_graphics\native_wheel.inc +include src_graphics\billiards.inc +include src_graphics\buckshot.inc +include src_graphics\russian_table.inc +include src_graphics\unavailable.inc + +; --- Main Loop of the 3D Casino Engine --- +StartCasino3D PROC uses ebx esi edi + call Init3DEngine + test eax, eax + jz engine_shutdown + invoke GetTickCount + mov rngSeed3D, eax + mov previousTick3D, eax +engine_loop: + invoke PeekMessageA, OFFSET msg3D, 0, 0, 0, PM_REMOVE + test eax, eax + jz dispatch_frame + cmp msg3D.message, WM_QUIT + je engine_shutdown + invoke TranslateMessage, OFFSET msg3D + invoke DispatchMessageA, OFFSET msg3D + jmp engine_loop + +dispatch_frame: + invoke GetTickCount + mov frameStart3D, eax + sub eax, previousTick3D + cmp eax, 50 + jbe @F + mov eax, 50 +@@: + mov deltaTime3D, eax + mov eax, frameStart3D + mov previousTick3D, eax + invoke GetForegroundWindow + cmp eax, h3DWnd + jne engine_idle + invoke IsIconic, h3DWnd + test eax, eax + jnz engine_idle + invoke Pressed3D, 7Ah + test eax, eax + jz @F + call ToggleFullscreen3D +@@: + invoke Pressed3D, 1Bh + test eax, eax + jz engine_tick + cmp engineMode, MODE_INTRO + jne @F + call FinishStartup3D + jmp engine_tick +@@: + cmp engineMode, MODE_ARRIVAL + jne @F + call ArrivalEscape3D + jmp engine_tick +@@: + cmp engineMode, MODE_WALK + jne leave_table + xor paused3D, 1 + jmp engine_tick +leave_table: + call CardTableEscape3D + test eax, eax + jnz engine_tick + call TableBusy3D + test eax, eax + jz leave_idle_table + xor paused3D, 1 + call ClearKeys3D + jmp engine_tick +leave_idle_table: + mov paused3D, 0 + mov engineMode, MODE_WALK + call ClearKeys3D + invoke PlayCasinoSound3D, 0, 0, 0 +engine_tick: + cmp paused3D, 0 + jne draw_pause + mov eax, deltaTime3D + add animationClock3D, eax + cmp engineMode, MODE_INTRO + jne check_arrival_mode + call HandleStartupInput3D + cmp engineMode, MODE_INTRO + jne check_arrival_mode + call RenderStartup3D + jmp present_frame +check_arrival_mode: + cmp engineMode, MODE_ARRIVAL + jne check_walk_mode + call HandleArrival3D + cmp engineMode, MODE_WALK + je check_walk_mode + call RenderArrival3D + jmp present_frame +check_walk_mode: + cmp engineMode, MODE_WALK + jne check_slots_mode + call UpdateHall3D + call UpdateCamera3D + call CheckInteractions + call HandlePlayerInput + call UpdateCamera3D + call RenderCeilingAndFloor + call RenderWalls + call PrepareCityDepth3D + call RenderSprites + call RenderHall3D + call RenderHUD + call RenderMinimap + jmp present_frame +check_slots_mode: + cmp engineMode,MODE_CLOVER + jne @F + call HandleNativeClover3D + call RenderNativeClover3D + jmp present_frame +@@: + cmp engineMode,MODE_NPC_DIALOG + jne @F + call HandleNpcDialog3D + call RenderNpcDialog3D + jmp present_frame +@@: + cmp engineMode, MODE_UNAVAILABLE + jne @F + call HandleUnavailable3D + call RenderUnavailable3D + jmp present_frame +@@: + cmp engineMode, MODE_POOL + jne @F + call HandlePool3D + call RenderPool3D + jmp present_frame +@@: + cmp engineMode, MODE_BAR + jne @F + call HandleBar3D + call RenderBar3D + jmp present_frame +@@: + cmp engineMode, MODE_STAIRS + jne @F + call HandleStairs3D + call RenderStairs3D + jmp present_frame +@@: + cmp engineMode, MODE_SLOTS + jne check_bj_mode + call HandleNativeSlots3D + cmp engineMode,MODE_WALK + je check_walk_mode + call RenderNativeSlots3D + jmp present_frame +check_bj_mode: + cmp engineMode, MODE_BLACKJACK + jne check_poker_mode + call HandleNativeBlackjack3D + cmp engineMode, MODE_WALK + je check_walk_mode + call RenderNativeBlackjack3D + jmp present_frame +check_poker_mode: + cmp engineMode, MODE_POKER + jne check_durak_mode + call HandleNativePoker3D + cmp engineMode, MODE_WALK + je check_walk_mode + call RenderNativePoker3D + jmp present_frame +check_durak_mode: + cmp engineMode, MODE_DURAK + jne check_roul_mode + call HandleNativeDurak3D + cmp engineMode, MODE_WALK + je check_walk_mode + call RenderNativeDurak3D + jmp present_frame +check_roul_mode: + cmp engineMode, MODE_ROULETTE + jne check_shop_mode + call HandleNativeWheel3D + call RenderNativeWheel3D + jmp present_frame +check_shop_mode: + cmp engineMode, MODE_SHOP + jne check_atm_mode + call HandleMerchant3D + call RenderMerchant3D + jmp present_frame +check_atm_mode: + cmp engineMode, MODE_ATM + jne check_coin_mode + call HandleATMInput + call RenderATMGame + jmp present_frame +check_coin_mode: + cmp engineMode, MODE_COIN + jne check_dice_mode + call HandleCoinInput + call RenderCoinGame + jmp present_frame +check_dice_mode: + cmp engineMode, MODE_DICE + jne check_skulls_mode + call HandleDiceInput + call RenderDiceGame + jmp present_frame +check_skulls_mode: + cmp engineMode, MODE_SKULLS + jne check_skill_mode + call HandleSkullsInput + call RenderSkullsGame + jmp present_frame +check_skill_mode: + cmp engineMode, MODE_SKILL + jne check_buckshot_mode + call HandleSkillInput + call RenderSkillGame + jmp present_frame +check_buckshot_mode: + cmp engineMode, MODE_BUCKSHOT + jne check_russian_mode + call HandleBuckshot3D + call RenderBuckshot3D + jmp present_frame +check_russian_mode: + cmp engineMode, MODE_RUSSIAN + jne present_frame + call HandleRussianInput3D + call RenderRussianGame3D + jmp present_frame +draw_pause: + invoke DrawBoxBorder, 28, 36, 264, 168, 00151C21h, 00D8BC6Ah, 2 + invoke DrawString8x8, 44, 48, OFFSET textPause3D, 00FFFFFFh + cmp displayFill3D, 0 + je @F + invoke DrawString8x8, 44, 72, OFFSET textDisplayFill3D, 00D8BC6Ah + jmp pause_draw_quality +@@: + invoke DrawString8x8, 44, 72, OFFSET textDisplayFit3D, 00D8BC6Ah +pause_draw_quality: + invoke DrawString8x8, 44, 92, OFFSET textLowSpec3D, 00D8BC6Ah + mov eax, settingsLowSpec + cmp eax, 0 + jne @F + mov edx, OFFSET textLowSpecOff3D + jmp pause_draw_quality_value +@@: + cmp eax, 1 + jne @F + mov edx, OFFSET textLowSpecEco3D + jmp pause_draw_quality_value +@@: + mov edx, OFFSET textLowSpecQuiet3D +pause_draw_quality_value: + invoke DrawString8x8, 208, 92, edx, 00FFFFFFh + invoke DrawString8x8, 44, 112, OFFSET textVolumeKeys3D, 00D8BC6Ah + invoke DrawString8x8, 44, 130, OFFSET textSoundLevel3D, 00BBBBBBh + invoke FormatNumber, settingsVolume, OFFSET hudNumBuffer + invoke DrawString8x8, 124, 130, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 44, 150, OFFSET textFullscreenKey3D, 00A0A0A0h + invoke DrawString8x8, 44, 170, OFFSET textResume3D, 00D8BC6Ah + invoke DrawString8x8, 44, 188, OFFSET textQuit3D, 00BBBBBBh + invoke Pressed3D, 31h + test eax, eax + jz @F + xor displayFill3D, 1 + call SaveDisplaySettings3D +@@: + invoke Pressed3D, 32h + test eax, eax + jz @F + inc settingsLowSpec + cmp settingsLowSpec, 3 + jb pause_low_spec_saved + mov settingsLowSpec, 0 +pause_low_spec_saved: + call SaveProgress3D +@@: + invoke Pressed3D, 0BBh + test eax, eax + jz @F + cmp settingsVolume, 10 + jae @F + inc settingsVolume + call ApplySoundVolume + call SaveProgress3D +@@: + invoke Pressed3D, 0BDh + test eax, eax + jz @F + mov eax, settingsVolume + test eax, eax + jz @F + dec settingsVolume + call ApplySoundVolume + call SaveProgress3D +@@: + invoke Pressed3D, 51h + test eax, eax + jz @F + call SaveProgress3D + jmp engine_shutdown +present_frame: + mov eax, engineMode + cmp eax, lastPersistMode3D + je @F + cmp eax, MODE_WALK + jne @F + call SaveProgress3D +@@: + mov eax, engineMode + mov lastPersistMode3D, eax + call Present3D + mov mouseClick3D, 0 + lea edi, pressedKeys3D + xor eax, eax + mov ecx, 64 + rep stosd + invoke GetTickCount + sub eax, frameStart3D + mov ecx, 16 + cmp settingsLowSpec, 1 + jne @F + mov ecx, 24 +@@: + cmp settingsLowSpec, 2 + jne @F + mov ecx, 33 +@@: + cmp eax, ecx + jae engine_loop + sub ecx, eax + invoke Sleep, ecx + jmp engine_loop +engine_idle: + invoke Sleep, 50 + jmp engine_loop +engine_shutdown: + call SaveProgress3D + invoke PlayCasinoSound3D, 0, 0, 0 + call FreeRussianAssets3D + call FreeStartupAssets3D + call FreeCardTableAssets3D + call FreeBuckshotAssets3D + call FreeNativeSlots3D + call FreeNativeClover3D + call FreePyramidAssets3D + call FreeArrivalAssets3D + cmp h3DDC, 0 + je @F + invoke ReleaseDC, h3DWnd, h3DDC + mov h3DDC, 0 +@@: + cmp h3DWnd, 0 + je @F + invoke DestroyWindow, h3DWnd + mov h3DWnd, 0 +@@: + ret +StartCasino3D ENDP + +include src_graphics\platform_code.inc + +IFDEF CASINO_ACTION_TEST +include tools\tests\casino_actions_test.inc +ENDIF diff --git a/dist/Assembler Casino.exe b/dist/Assembler Casino.exe index e5169b8..880d27e 100644 Binary files a/dist/Assembler Casino.exe and b/dist/Assembler Casino.exe differ diff --git a/docs/native-blackjack-party.md b/docs/native-blackjack-party.md new file mode 100644 index 0000000..8a4f6d5 --- /dev/null +++ b/docs/native-blackjack-party.md @@ -0,0 +1,71 @@ +# Native Blackjack: Shared Table + +## Implemented + +The graphical blackjack table can seat the player and zero to three AI guests, +with a house dealer. The existing solo mode remains the default. Before a hand, +the four numbered controls select the guest count (also keys 0, 1, 2, 3). +Selection is locked until the hand has ended. Choosing a different count after +a result clears that displayed hand without touching the wallet. + +All seats receive actual identities from one shuffled 52-card deck. The deal +is round-robin, followed by the player's turn, timed guest decisions and the +dealer's turn. Each guest has a separate hand, virtual stake and result. +Guest stakes do not come from the player's balance. Guests do not yet have +persistent wallets or bring the hall visitor's identity to their table seat. + +Tolya is cautious, Sergey hits more aggressively, and Alisa adapts her stopping +threshold to the dealer's upcard. A two-card eleven can double against an +appropriate upcard. Decisions never examine the hidden dealer card, another +seat's hand or future deck cards. These are limited personality strategies, +not a complete optimal blackjack strategy chart. Dealer stands on all 17s; +player blackjack pays 3:2, pushes return the deducted stake. + +A player bust or natural no longer truncates the guests' turns. A dealer +natural resolves all seats immediately. The existing exit confirmation freezes +the table and forfeits only the player's stake on confirmation. Settlement and +NPC challenge progress happen once for the player, never once per guest. + +## Artwork + +`assets/sprites/tables/blackjack-guests-v1.png` was generated with the built-in +image generator as one transparent three-column, two-row sprite sheet. +Each adult character has an attentive pose and a card-request gesture. +`tools/generators/pack_blackjack_guests.py` normalizes its six cells into +160-by-160 BGRA frames in `assets/animations/tables/blackjack-guests-v1.bin`. +These are two poses per guest, not a full continuous character animation. +Native timed card flights and queued dealer-hand sprites animate each draw. +`blackjack-room-v1.png` and its compiled ANM1 background put the guests behind +the far wooden rim instead of drawing their bodies directly on the felt. + +Generation prompt: detailed hand-painted Doom-era pixel sprites, transparent +background, three seated adult guests (bald gray-suited man, dark-haired navy- +jacketed man, auburn-haired emerald-dressed woman); identical anchors and scale +across attentive/extended-hand rows; warm amber light, burgundy shadows; no +table, cards, chips, chairs, text or cross-cell overlap. + +Room prompt: empty first-person vintage casino background in the same detailed +pixel style; three empty burgundy chairs behind a wooden blackjack-table rim +at 52% canvas height, green felt below, front padded rim at 90%; dark wood, +brass lights, no people, text or cards. The built-in generator's first room +plate was edited to lower the far rim to the intended midpoint. + +## Verification + +`tools/tests/blackjack_party_test.inc` runs in the native action suite: +600 complete hands across all three guest counts; exact deck consumption and +card uniqueness; bounded counts; independent player payout; natural/push/bust; +no hidden-card dependence; actual mouse and keyboard selection; safe exit and +frozen timers; render purity and six framebuffer captures. + +`check_blackjack_party.py --parity` compares the tested and shipping MASM +procedures and inspects the native captures. `test_blackjack_party.ps1` is a +focused native probe linked against the action-test object. + +## Still Pending + +Native three/four-player poker, Russian roulette and Buckshot are separate +features. They are not implemented by this blackjack work, and the old console +four-seat poker loop is not connected to the graphical table. Poker still needs +correct multiplayer betting, all-ins, side pots and tie splits before that +loop can become a graphical game. diff --git a/docs/native-clover.md b/docs/native-clover.md new file mode 100644 index 0000000..11ca3d4 --- /dev/null +++ b/docs/native-clover.md @@ -0,0 +1,67 @@ +# Native Clover 5x3 + +The runtime is MASM x86 only. `native_clover.inc` owns input, five timed reel +strips, clipping, final-board evaluation, settlement, paid-combo selection and +rendering. The original assembly `EvaluateSlotCombos` is reused directly; the +console `GameSlot`, its sleeps, console output and payout functions are never +called by this mode. + +## Rules + +Fifteen final symbols are sampled once when the stake is debited. Symbol values: +clover 3, lemon 2, cherries 2, bell 3, diamond 5, chest 5, seven 7. +Each paid pattern contributes its factor times its symbol value. Contributions +are added; a pattern entirely covered by earlier paid patterns is not paid +again. Original order: jackpot, eye, sky/earth, up/down arrows, rows 5, rows 4, +verticals, diagonals, rows 3. The jackpot is additive, matching the original +game, not a replacement for the remaining matches. + +Displayed multipliers and credited payouts include any returned stake. The +separate net field is actual credit minus the frozen stake. A bank-cap-clipped +payout displays only the money actually credited. The bank cap is 1,000,000,000. +777 uses the same gross/net convention, with neutral feedback for a stake +refund, not victory feedback. Its unchanged strip/table has theoretical gross +RTP 90.025% under independent uniform stop selection; this is not a guarantee +for the actual pseudo-random generator or any individual session. + +## Interaction + +Space/Enter spins, W/S or Up/Down change the idle stake, P opens/closes the pay +table, Left/Right select an actually paid combo. All controls have clickable +equivalents. Escape first closes the pay table; during a paid spin it queues +leaving until settlement/save completes, otherwise it returns to the hall. +No pause menu or console fallback is opened. + +The result grid highlights the selected paid mask, with its type, multiplier, +index/count, aggregate multiplier, gross payout and net separately. Only the +middle line of the separate 777 machine pays; its payout panel says the stake +is included. + +## Assets + +Generated with the built-in image generator, then copied to +`assets/sprites/clover/cabinet-v1.png` and `symbols-v1.png`. The cabinet is opaque +640x480, symbols seven alpha-tested 56x56 frames. `pack_clover_assets.py` is an +offline packer, not a non-assembly game implementation. + +Cabinet prompt: wide front-facing Clover machine in a richly furnished retro +casino, emerald enamel/worn brass/crimson trim, crisp textured Doom-era pixel +art; one large blank near-black rectangular reel bay, no baked symbols, +dividers, letters or people, straight-on framing. +Symbol prompt: transparent equal-cell 4x2 pixel-painted atlas, clover/lemon/ +cherries/bell on top, diamond/chest/red seven below, final cell empty; isolated, +centered, consistent apparent size and readable silhouettes, no grid/background. + +## Verification And Scope + +Independent offline fixture oracle covers 553 boards, including all seven +jackpots and each pattern. Native tests cover 500 paid spins at four update +rates, frozen RNG/stake, exact final tape rows, monotonic stopping, queued exit, +idempotent payout, bank cap, missing funds and six framebuffer captures. +`check_clover.py --parity` checks assets, real framebuffer clipping, all fifteen +complete cells, selected paid-mask changes and tested/shipping assembly code. + +Native talisman modifiers and legacy console achievement/dance side effects +are not ported by this change. NPC challenges count native slot rounds and +classify only positive net results as wins. No claim of completing every legacy +Clover feature or its balance is made. diff --git a/docs/native-european-roulette.md b/docs/native-european-roulette.md index 068e980..a528df2 100644 --- a/docs/native-european-roulette.md +++ b/docs/native-european-roulette.md @@ -43,6 +43,12 @@ queued departure and result persistence. Six framebuffer captures cover draft, launch, fast/slow rotation, landing and result. The shipping loader probe also loads/frees wheel packs from both the project root and TEMP. +Additional native captures cover all 37 settled results and isolated distant +and rotating labels. The offline checker compares every foreground digit pixel +with an independent font mask, verifies the large central result, and checks +that labels never overlap at any of the 512 rotation angles. Small labels write +physical framebuffer pixels directly; they do not use the coarser UI grid. + The dealer background is currently a static pose. This is a native animated wheel/table scene, not a complete animated croupier performance or a physical simulation of a freely rolling ball. diff --git a/docs/native-russian-party.md b/docs/native-russian-party.md new file mode 100644 index 0000000..bb3bfb0 --- /dev/null +++ b/docs/native-russian-party.md @@ -0,0 +1,59 @@ +# Native Russian Roulette: Multiple Opponents + +## Rules + +The existing one-opponent game remains the default. Ready-screen controls select +one, two or three opponents; Left/Right changes the selection. The existing +1/2/3 keys still choose the number of loaded cartridges. Mouse controls also +start the round, fire on the player's turn, and open the exit confirmation. + +The round locks its participant count and player's stake at the start. In the +group variant, all participants use one cylinder in cyclic order. Each takes +their own turn; there is no selectable target. A live shot consumes that loaded +round and removes the current participant. Empty chambers pass to the next +remaining participant, skipping eliminated seats. The last surviving player +receives the initial stake times the initial participant count. Opponent stakes +are virtual casino stakes, not withdrawals from the player's account. + +An exhausted cylinder is reloaded and spun without another payment. Reloading +does not restore eliminated opponents or change the locked pool. The player's +elimination preserves the existing glitch/dark/G-man/return sequence. The match +is recorded once for NPC challenges; intermediate opponent eliminations are +not extra paid wins. Confirmed early exit forfeits the already-paid stake. + +Escape opens the shared leave/continue dialog in both solo and party modes; +the dialog freezes the scene and cylinder. Cancelling resumes the same turn. +Leaving after settlement does not make a second payout or challenge event. + +## Graphics + +Three distinct neutral seated opponents use six frames from +`assets/sprites/roulette/participants-v1.png`, generated with the built-in image +generator and packed offline into `assets/animations/roulette/participants-v1.bin`. +The active seat is named/highlighted; an eliminated seat fades and becomes empty. +The existing first-person player and cylinder animations are retained. + +The party view passes the existing revolver along the tabletop. The opponents +currently have idle/conversational poses, not complete individual cinematic +firing animations. The attempted new firing-pose sheet was rejected by the +image tool and is not a shipped asset. No replacement has been disguised as a +full new shooting animation. One-opponent firing remains the existing scene. + +Neutral sprite prompt: three waist-up adult casino guests, bald waistcoated +man, dark-haired charcoal-jacketed man, older gray-haired brown-jacketed man; +three columns by two rows, attentive idle and calm palm-up conversation; +same identity/scale/anchors, transparent background, crisp late-1990s pixel +sprites, amber light and crimson shadows; no objects, weapons, wounds or text. + +## Verification + +`russian_party_test.inc` covers 600 complete group matches at 16/50/250 ms +updates, 1..3 loaded rounds, elimination order, unchanged cylinder between +empty chambers, reload-without-payment, locked-pool settlement, render purity, +all active pre-result exit phases, zero bank and invalid bullet count. +The existing 2000 solo-round tests still run. Native captures and tested/shipping +procedure parity are checked by `check_russian_party.py --parity`. + +The runtime remains MASM. Python only packs assets and checks captures; +the existing C# launcher remains packaging, not game code. Multiplayer poker +and Buckshot are still separate unfinished features. diff --git a/docs/native-slots.md b/docs/native-slots.md index fd09385..e6ae268 100644 --- a/docs/native-slots.md +++ b/docs/native-slots.md @@ -14,7 +14,10 @@ stake is charged; animation and repeated renderer calls cannot reroll them. Three matches pay gross multipliers: seven 100, cherries 8, lemon 10, bell 15, BAR 25, grapes 12, diamond 60 and crown 150. Exactly two cherries pay 2x; any other exact pair returns 1x. No match pays nothing. Gross payouts include -the charged stake. Under uniformly sampled stops the configured return is +the charged stake. The footer separates actual credited payout from signed net +profit/loss. An exact non-cherry pair is a neutral stake refund, with no victory +sound or winning-line flash. The pay table identifies the middle paying line. +Under independently and uniformly sampled stops the configured return is 7202 / 8000 = 90.025%; this is not a guarantee of individual-session results. Stake choices are 10, 50, 100, 500, 1000, 5000 and 10000. The native bank cap @@ -59,6 +62,6 @@ the shipping and test COFF code for every slot handler. `test_street_asset_paths.ps1` also initializes/frees the shipping native slot cabinet from project-root and TEMP working directories, without launching a window. -CloverPit, talisman effects, native achievements and slot-specific profile -statistics still need separate integration; the native 777 does not call their -legacy console implementations. +CloverPit now has a separate native 5x3 machine; see `native-clover.md`. Talisman +effects, native achievements and slot-specific profile statistics still need +separate integration; neither machine calls their legacy console implementations. diff --git a/docs/npc-life.md b/docs/npc-life.md new file mode 100644 index 0000000..f6dc7bd --- /dev/null +++ b/docs/npc-life.md @@ -0,0 +1,53 @@ +# Native Visitors and Contracts + +The graphical runtime remains MASM. The user's six personality records in +`npc_mind_data.inc` are retained. The visible people now read the positions of +those records instead of a separate, unrelated square-loop animation. + +`npc_life.inc` owns bounded 32x32 BFS navigation, millisecond walking with +fractional carry, standing, seated lounge visits, entrance departures and +replacement visitors. All proposed steps check the existing body-clearance, +furniture/stage collision rules, the player and other visitors. A blocked person +stops animating their feet and chooses another destination after waiting. +The six active slots alternate between twelve identities. Standing/walking and +seated poses use the existing interior sprite pack; a full animated transition +into a chair and additional directional interior poses are not implemented yet. +Exterior people use outdoor sprites and long sidewalk routes, not courtyard +pacing or indoor guest sprites. + +Press E when the conversation prompt appears. The owned graphical modal has +accept, reward and close commands. Mouse, 1/2, Enter, 0 and Escape work without +console input. The conversation holds the scene while it is open. + +Twelve contract types cover played/won rounds of native coin, blackjack, poker, +European roulette, 777 and Durak. The any-round contract also counts Russian +roulette, Buckshot, dice, cups and skill checks. Only settled paid rounds count, with wins +requiring a positive result rather than a push. Progress starts after acceptance; +tasks remain associated with visitor identity even while that person is absent. +Offers rotate with the local calendar and visitors. Rewards range from $150 to +$700 and are capped by the game's existing billion-dollar balance limit. + +Each local save has a companion `.npc` journal. It contains a date, bounded +accepted/claimed masks, capped progress and a checksum. Truncated, malformed, +wrong-date and cross-profile journals are not imported. Completed contracts +cannot be claimed twice after closing/reopening the dialog or restarting. +Journal write failures do not award repeatable money. The existing wallet save +and companion journal are separate writes; an abrupt power loss between them +can lose the reward credit, so this is not a transactional banking system. +The original save format and the legacy forty-task daily pool are unchanged. + +Native tests exercise ten reachable destinations, equal-time movement at three +update rates, two minutes of body-clearance checks for all six visitors, capped +progress, early/double claims, persistence, profile isolation, day rollover, +mouse dialog commands and Escape. They use only journals inside build fixtures. +`check_npc_life.py --parity` checks three native framebuffer captures and +tested/shipping procedure parity. + +## Multiplayer Tables + +The user's legacy four-seat poker/personality code is preserved. It is not +called from the graphical casino because it uses console input/output. The +existing native tables remain heads-up. Native three/four-seat poker needs +proper repeated betting turns, ties, all-ins/side pots, exit settlement and +seated opponent rendering before it can replace that loop. Russian roulette +and Buckshot likewise still use their existing two-actor scenes. diff --git a/poker.asm b/poker.asm index 3245292..8479877 100644 --- a/poker.asm +++ b/poker.asm @@ -1,15207 +1,15234 @@ -.386 -.model flat, stdcall -option casemap:none - -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 280 -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 -PrintSlotSymbol PROTO :DWORD -RandomRange PROTO :DWORD -PrintUInt PROTO :DWORD -UnlockAchievement PROTO :DWORD, :DWORD -ShowBestiaryPage PROTO :DWORD, :DWORD, :DWORD - -.data -; === Ãëîáàëüíûå äåñêðèïòîðû, áóôåðû êîíñîëè, RNG è âðåìåííàÿ ïàìÿòü === -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) -cheatBuffer db 32 dup(0) -wideBuffer dw 4096 dup(0) -utf8Buffer db 8192 dup(0) -frameBuffer db 32768 dup(0) -deckUsed db 52 dup(0) -onlineWsaData db 400 dup(0) -onlineAddr db 16 dup(0) -onlineIp db 32 dup(0) -onlineListenSock dd -1 -onlinePeerSock dd -1 -onlineWsaReady dd 0 -onlinePacket dd 0, 0 -onlineLocalRoll dd 0 -onlineRemoteRoll dd 0 -onlineGameMode dd 0 -onlineHostIp dd 0 -onlineAction dd 1 -consoleRectTiny dw 0, 0, 119, 34 -consoleRect160 dw 0, 0, 159, 44 -consoleRect140 dw 0, 0, 139, 39 -consoleRect120 dw 0, 0, 119, 34 - -; === Îáùèå ñ÷åò÷èêè î÷êîâ è ñîñòîÿíèå ñòàðûõ êàðòî÷íûõ ðåæèìîâ === -playerTotal dd 0 -dealerTotal dd 0 -playerAces dd 0 -dealerAces dd 0 -playerCards dd 0 -; === Ñîñòîÿíèå CloverPit / ñëîò-ìàøèí: ñåòêà, âûïëàòû, êîìáèíàöèè === -slotA dd 0 -slotB dd 0 -slotC dd 0 -slotD dd 0 -slotE dd 0 -slotMatch dd 0 -slotWinMask dd 0 -slotCurrentCell 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) -slotGrid dd 15 dup(0) -slotVisible dd 0 -; === Îáùàÿ êàðòî÷íàÿ ìîäåëü: ðóêè èãðîêà, AI è êàðòû íà ñòîëå === -playerHand21 dd 10 dup(0) -aiHand21 dd 10 dup(0) -communityHand dd 5 dup(0) -pokerPlayerEvalHand dd 7 dup(0) -pokerAIEvalHand dd 7 dup(0) -playerCnt21 dd 0 -aiCnt21 dd 0 -communityCnt dd 0 -revealAI21 dd 0 -dangerLvl21 dd 0 -cardsLeft21 dd 0 -rowIndex dd 0 -pokerPlayerScore dd 0 -pokerAIScore dd 0 -pokerEvalCount dd 0 -; === Ýêîíîìèêà àêêàóíòà: áàíê, öåëü, ñòàâêà è ÷èò-ôëàãè === -bankroll dd 10000 -targetBank dd 50000 -currentBet dd 0 -cheatLuckyWin dd 0 -cheatGodMode dd 0 -cheatSlotJackpot dd 0 -settingsVolume dd 10 -settingsLowSpec dd 0 -settingsIntroEnabled dd 1 -settingsDbdWindowEnabled dd 0 -animFrameCounter dd 0 -animWidth dd 0 -animHeight dd 0 -secretEndingSeen dd 0 -vipTaxAmount dd 0 -; === Êðóïüå-êîììåíòàòîð: ÷òåíèå ôðàç èç dealer_phrases.txt === -dealerFileHandle dd 0 -dealerLineLen dd 0 -dealerPhraseCount dd 0 -dealerPhrasePick dd 0 -dealerScanMode dd 0 -dealerWantedTag db 0 -; === Ìàãàçèí: êóïëåííûå ðóáàøêè, âûáðàííàÿ ðóáàøêà è òàëèñìàíû === -shopBackOwned dd 1 -shopBackStyle dd 0 -shopCharmLevel dd 0 -shopCharmUses dd 0 -achievements dd 0 -pokerRaiseAmount dd 0 -pokerAIRaiseAmount dd 0 -; === Ôàéëû, àêêàóíòû, ñîõðàíåíèÿ, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ === -saveHandle dd 0 -achievementHandle dd 0 -findHandle dd 0 -danceHandle dd 0 -danceBytes dd 0 -frameBytes dd 0 -introLoopSeen dd 0 -introSkipLoop dd 0 -accountCount 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) -leaderBestBank dd 0 -leaderBestWins dd 0 -leaderBestLosses dd 0 -leaderValidCount dd 0 -leaderScanIndex dd 0 -leaderAccountPtr dd 0 -leaderBestGameWins dd 11 dup(0) -leaderBestGameLosses dd 11 dup(0) -leaderBestBankName db 64 dup(0) -leaderBestWinsName db 64 dup(0) -leaderBestLossName db 64 dup(0) -leaderBestGameWinNames db 11 dup(64 dup(0)) -leaderBestGameLossNames db 11 dup(64 dup(0)) -; === Íàñòðîéêè ñëîæíîñòè, âðåìåííûå ïåðåìåííûå ïîêåðà è ìèíè-èãð === -aiDifficulty dd 2 -bankRecovered dd 0 -saveTampered dd 0 -pokerReplaceIndex dd 0 -pokerReplaced dd 0 -pokerStraight dd 0 -pokerFlush dd 0 -pokerHigh dd 0 -pokerFour dd 0 -pokerTrip dd 0 -pokerPairHigh dd 0 -pokerPairLow dd 0 -; === ×åðåïà è øàðèê: ïîçèöèÿ øàðèêà, âûáîð è ÷èñëî ïåðåìåøèâàíèé === -skullBallPos dd 0 -skullGuess dd 0 -skullStep dd 0 -skullMax dd 0 -; === Ðóññêàÿ ðóëåòêà: áàðàáàí, ïàòðîíû, õîä è ìíîæèòåëü === -rrBulletMask dd 0 -rrBullets dd 0 -rrChamber dd 0 -rrTurn dd 0 -rrPayout dd 0 -; === Buckshot Roulette: ïàòðîíû, çäîðîâüå, ïðåäìåòû è ñîñòîÿíèå õîäà === -bsShells dd 8 dup(0) -bsShellIndex dd 0 -bsShellCount dd 0 -bsLiveCount dd 0 -bsBlankCount dd 0 -bsPlayerHP dd 0 -bsAIHP dd 0 -bsTurn dd 0 -bsDamage dd 1 -bsKnownShell dd 0FFFFFFFFh -bsSkipPlayer dd 0 -bsSkipAI dd 0 -bsPlayerGlass dd 0 -bsPlayerSaw dd 0 -bsPlayerBeer dd 0 -bsPlayerCuffs dd 0 -bsAIGlass dd 0 -bsAISaw dd 0 -bsAIBeer dd 0 -bsAICuffs dd 0 -bsTarget dd 0 -bsShell dd 0 -bsAction dd 0 -; === Ìèíè-èãðû îðåë/ðåøêà, êîñòè è êàçèíî-ðóëåòêà === -coinPick dd 0 -coinResult dd 0 -diceA dd 0 -diceB dd 0 -diceSum dd 0 -diceChoice dd 0 -casinoRouletteBetType dd 0 -casinoRouletteBetNumber dd 0 -casinoRouletteResult dd 0 -casinoRouletteResultIndex dd 0 -casinoRouletteSpinIndex dd 0 -casinoRouletteSpinSteps dd 0 -casinoRouletteSpinCounter dd 0 -casinoRouletteVisibleCount 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 -durakAttackCard dd 0FFFFFFFFh -durakDefenseCard dd 0FFFFFFFFh -durakPlayerTurn dd 1 -durakChoice dd 0 -durakTableCnt dd 0 -durakAttackCards dd 6 dup(0) -durakDefenseCards dd 6 dup(0FFFFFFFFh) -durakTempHand dd 6 dup(0) -durakSafeTurns dd 0 -durakLoopGuard dd 0 -; === Skill Check, ñòðåññ, ïîäîçðåíèå êàçèíî è òóðíèð-áàøíÿ === -skillNeedle dd 0 -skillDir dd 1 -skillSuccessStart dd 0 -skillSuccessEnd dd 0 -skillPerfectPos dd 0 -skillGaugeIndex dd 0 -skillFrameCount dd 0 -skillHits dd 0 -skillMisses dd 0 -skillResult dd 0 -skillPerfects dd 0 -skillDelay dd 45 -casinoSuspicion dd 0 -stressLevel dd 0 -lastGameResult dd 0 -tournamentStage dd 0 -tournamentMode dd 0 -dailyDateKey dd 0 -dailyRewardMask dd 0 -dailyProgressPacked dd 0 -dailyTaskPacked dd 0 -systemTime dw 8 dup(0) -pulseCycles dd 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 - -titleText db "==============================",13,10 - db " ASSEMBLER CASINO",13,10 - db "==============================",13,10,0 -menuText db "1. Ìàãàçèí",13,10 - db "2. 21 / Î÷êî",13,10 - db "3. Poker",13,10 - db "4. CloverPit",13,10 - db "5. ×åðåïà è øàðèê",13,10 - db "6. Ðóññêàÿ ðóëåòêà",13,10 - db "7. Îðåë è ðåøêà",13,10 - db "8. Êîñòè",13,10 - db "9. Êàçèíî-ðóëåòêà",13,10 - db "10. Slot machine",13,10 - db "11. Äóðàê",13,10 - db "12. Êðþê: Skill Check",13,10 - db "13. Buckshot Roulette",13,10 - db "14. Íàáëþäàòåëü AI vs AI",13,10 - db "15. Îáó÷åíèå",13,10 - db "16. Äîñòèæåíèÿ",13,10 - db "17. Ñòàòèñòèêà ïî èãðàì",13,10 - db "18. Åæåäíåâíûå çàäàíèÿ",13,10 - db "19. Íàñòðîéêè",13,10 - db "20. Online Casino (Radmin)",13,10 - db "21. Umamusume Ñêà÷êè",13,10 - - db "25. 3D-ÊÀÇÈÍÎ (DOOM / Wolf3D Raycaster 2.5D) [NEW]",13,10 - - db "0. Exit",13,10,0 -choiceText db "Âûáîð: ",0 -badChoiceText db "Íåò òàêîãî ïóíêòà.",13,10,0 -accountMenuText db "1. Âîéòè â àêêàóíò",13,10 - db "2. Ñîçäàòü àêêàóíò",13,10,0 -accountPromptText db "Ââåäèòå èìÿ àêêàóíòà ëàòèíèöåé: ",0 -accountBadText db "Èìÿ äîëæíî ñîäåðæàòü õîòÿ áû îäíó áóêâó èëè öèôðó.",13,10,0 -accountLoginText db "Àêêàóíò çàãðóæåí: ",0 -accountCreateText db "Àêêàóíò ñîçäàí: ",0 -accountListTitle db "Âûáåðèòå àêêàóíò:",13,10,0 -accountNoFilesText db "Ñîõðàíåííûõ àêêàóíòîâ ïîêà íåò.",13,10,0 -accountSelectText db "Íîìåð àêêàóíòà: ",0 -pauseText db 13,10,"Íàæìèòå ëþáóþ êëàâèøó...",0 -bankText db "Âàø áàíê: $",0 -betText db "Ââåäèòå ñòàâêó: $",0 -betChosenText db "Âû ïîñòàâèëè $",0 -badBetText db "Ñòàâêà äîëæíà áûòü ÷èñëîì áîëüøå 0.",13,10,0 -tooBigBetText db "Ó âàñ íåò ñòîëüêî äåíåã.",13,10,0 -suspicionText db "Ïîäîçðåíèå êàçèíî: ",0 -suspicionCalmText db "òèõî",13,10,0 -suspicionWatchText db "çà òîáîé ñìîòðÿò",13,10,0 -suspicionHuntText db "îõðàíà ðÿäîì",13,10,0 -suspicionUpText db "Ïîäîçðåíèå âûðîñëî.",13,10,0 -suspicionFineText db "Îõðàíà çàìåòèëà ìóòíóþ èãðó. Øòðàô: $",0 -stressText db "Ñòðåññ ñòàâêè: ",0 -stressLowText db "ñïîêîéíî",13,10,0 -stressMidText db "ïóëüñ ðàñòåò",13,10,0 -stressHighText db "ðóêè äðîæàò",13,10,0 -stressMaxText db "ïàíèêà",13,10,0 -cheatMoveText db "Øóëåðñòâî: 3 - ïîäñìîòðåòü, 4 - ïîäìåíèòü êàðòó.",13,10,0 -cheatPeekText db "Òû íåçàìåòíî ïîäñìîòðåë êàðòó:",13,10,0 -cheatSwapText db "Òû ïîäìåíèë êàðòó ïîä ðóêàâîì.",13,10,0 -cheatNoTargetText db "Ñåé÷àñ íå÷åãî ïîäìåíÿòü.",13,10,0 -tournamentTitle db 13,10,"--- Ñåêðåòíûé ðåæèì: Àäñêàÿ áàøíÿ ---",13,10,0 -tournamentIntro db "Àäñêàÿ áàøíÿ êàçèíî: 10 ýòàïîâ ïîäðÿä. Ïðîèãðàë - íà÷èíàåøü çàíîâî.",13,10 - db "Âõîä ñêðûò. Êîä 666 ïðèíÿò. Ìóçûêó ìîæíî ìåíÿòü êëàâèøåé M ïåðåä ýòàïîì.",13,10,0 -tournamentStageText db 13,10,"Ýòàï áàøíè: ",0 -tournamentMusicHint db "M - ñëó÷àéíî ñìåíèòü ìóçûêó áàøíè, ëþáàÿ äðóãàÿ êëàâèøà - íà÷àòü ýòàï",13,10,0 -secretHellText db 13,10,"Ñåêðåòíûé êîä ïðèíÿò. Êàçèíî îïóñêàåò òåáÿ â Àäñêóþ áàøíþ...",13,10,0 -hellStageCurseText db "Ïðîêëÿòèå ýòàïà: ",0 -hellCurse1 db "êðóïüå áîëüøå íå ìîðãàåò.",13,10,0 -hellCurse2 db "ìóçûêà èãðàåò, äàæå åñëè òû ïðîèãðûâàåøü.",13,10,0 -hellCurse3 db "êàæäàÿ ñòàâêà ïàõíåò ñåðîé.",13,10,0 -hellCurse4 db "îõðàííèê óæå çíàåò òâîå èìÿ.",13,10,0 -tournamentFailText db 13,10,"Àäñêàÿ áàøíÿ çàêðûëà äâåðè. Òóðíèð íà÷èíàåòñÿ çàíîâî.",13,10,0 -tournamentWinText db 13,10,"ÒÛ ÂÛÆÈË Â ÀÄÑÊÎÉ ÁÀØÍÅ! Ñåêðåòíûé áîíóñ: $66600",13,10,0 -tournamentFire1 db 13,10," . * .",13,10," ASSEMBLER CASINO",13,10," . | .",13,10," ___ /---\ ___",13,10," /___\ | T | /___\",13,10,0 -tournamentFire2 db 13,10," * \ | / \ | / *",13,10," -- TOWER CLEARED --",13,10," * / | \ / | \ *",13,10," ___ /---\ ___",13,10," /___\ | 10| /___\",13,10,0 -tournamentFire3 db 13,10," * . * . * . * . * . * . *",13,10," $$$ FIREWORKS $$$",13,10," . * . * . * . * . * . * .",13,10," \ \ | / /",13,10," \__\_|_/__/",13,10,0 -tournamentFire4 db 13,10," ============ JACKPOT SKY ============",13,10," * * * * *",13,10," * CASINO CHAMPION *",13,10," * * * * *",13,10," =====================================",13,10,0 -dailyTitle db 13,10,"--- Åæåäíåâíûå çàäàíèÿ ---",13,10,0 -dailyIntro db "Êàæäûé êàëåíäàðíûé äåíü êàçèíî âûáèðàåò 3 çàäàíèÿ èç 40.",13,10,0 -dailyDateText db "Äàòà çàäàíèÿ: ",0 -dailyPoolText db "Ïóë çàäàíèé: 40. Ñåãîäíÿ âûáðàíî: 3",13,10,0 -dailySlashText db " / ",0 -dailyRewardText db " Íàãðàäà: $",0 -dailyClaimText db "Åæåäíåâíàÿ íàãðàäà ïîëó÷åíà: +$",0 -dailyDoneText db " [ïîëó÷åíî]",13,10,0 -dailyOpenText db " [â ïðîöåññå]",13,10,0 -settingsTitle db 13,10,"--- Íàñòðîéêè êàçèíî ---",13,10,0 -settingsMenuText db "1. Òèøå",13,10 - db "2. Ãðîì÷å",13,10 - db "3. Ïðîôèëü àíèìàöèé",13,10 - db "4. Ïåðåêëþ÷èòü èíòðî",13,10 - db "5. Ïåðåêëþ÷èòü DBD-îêíî",13,10 - db "0. Íàçàä",13,10 - db "Âûáîð: ",0 -settingsVolumeText db "Ãðîìêîñòü: ",0 -settingsVolumeHint db "0 - áåç çâóêà, 10 - ìàêñèìóì",13,10,0 -settingsModeText db "Ïðîôèëü àíèìàöèé: ",0 -settingsNormalText db "îáû÷íûé",13,10,0 -settingsLowText db "ñëàáûé ÏÊ",13,10,0 -settingsIntroText db "Èíòðî: ",0 -settingsDbdText db "DBD-îêíî: ",0 -settingsOnText db "âêë",13,10,0 -settingsOffText db "âûêë",13,10,0 -settingsCinematicText db "Cinematic - ìàêñèìóì",13,10,0 -settingsAdaptiveText db "Adaptive - ìÿã÷å",13,10,0 -settingsStableText db "Stable - ìåíüøå ðÿáè",13,10,0 -settingsAnimHintText db "Cinematic: âñå êàäðû; Adaptive: ìåíüøå ðÿáè; Stable: äëÿ ñëàáûõ ÏÊ.",13,10,0 -vipStatusText db "VIP-ñòàòóñ: ",0 -vipBronzeText db "Bronze",13,10,0 -vipSilverText db "Silver",13,10,0 -vipGoldText db "Gold",13,10,0 -vipDiamondText db "Diamond",13,10,0 -vipTaxText db "Êîìèññèÿ êàçèíî: $",0 -secretEndingTitle db 13,10,"========================================",13,10," ÊÀÇÈÍÎ ÏÐÈÇÍÀËÎ ÒÅÁß ÑÂÎÈÌ",13,10,"========================================",13,10,0 -secretEndingBody db "Òû ñîáðàë âñå äîñòèæåíèÿ, ñêóïèë ðóáàøêè è âûíåñ áàíê òàê, ÷òî êðóïüå áîëüøå íå ñïîðèò.",13,10,"Äâåðè ñëóæåáíîãî ëèôòà îòêðûâàþòñÿ. Íà òàáëè÷êå îäíà ôðàçà: HOUSE PLAYER.",13,10,"Ñåêðåòíàÿ êîíöîâêà îòêðûòà.",13,10,0 -secretEndingArt1 db " .---. .---. .---.",13,10," / $ / / VIP / / $ /",13,10," \\____/ \\____/ \\____/",13,10,0 -secretEndingArt2 db " ======= ASSEMBLER CASINO PRIVATE FLOOR =======",13,10," cards slots roulette secrets",13,10," =================================================",13,10,0 -dailyReadyText db " [ãîòîâî ê ïîëó÷åíèþ]",13,10,0 -dailyTaskName01 db "Ñûãðàòü 3 èãðû",0 -dailyTaskName02 db "Ñûãðàòü 5 èãð",0 -dailyTaskName03 db "Ñûãðàòü 7 èãð",0 -dailyTaskName04 db "Ïîáåäèòü 1 ðàç",0 -dailyTaskName05 db "Ïîáåäèòü 2 ðàçà",0 -dailyTaskName06 db "Ïîáåäèòü 3 ðàçà",0 -dailyTaskName07 db "Ïðîèãðàòü 1 ðàç",0 -dailyTaskName08 db "Ïðîèãðàòü 2 ðàçà",0 -dailyTaskName09 db "Ñäåëàòü íè÷üþ 1 ðàç",0 -dailyTaskName10 db "Ïîñòàâèòü îò $5000",0 -dailyTaskName11 db "Ïîñòàâèòü îò $5000 òðè ðàçà",0 -dailyTaskName12 db "Ïîñòàâèòü îò $10000",0 -dailyTaskName13 db "Ñûãðàòü â 21",0 -dailyTaskName14 db "Ïîáåäèòü â 21",0 -dailyTaskName15 db "Ñûãðàòü â Poker",0 -dailyTaskName16 db "Ïîáåäèòü â Poker",0 -dailyTaskName17 db "Ñûãðàòü â CloverPit",0 -dailyTaskName18 db "Ïîáåäèòü â CloverPit",0 -dailyTaskName19 db "Ñûãðàòü â ðóññêóþ ðóëåòêó",0 -dailyTaskName20 db "Ïîáåäèòü â ðóññêóþ ðóëåòêó",0 -dailyTaskName21 db "Ñûãðàòü â ÷åðåïà",0 -dailyTaskName22 db "Ïîáåäèòü â ÷åðåïà",0 -dailyTaskName23 db "Ñûãðàòü â îðëà è ðåøêó",0 -dailyTaskName24 db "Ïîáåäèòü â îðëà è ðåøêó",0 -dailyTaskName25 db "Ñûãðàòü â êîñòè",0 -dailyTaskName26 db "Ïîáåäèòü â êîñòè",0 -dailyTaskName27 db "Ñûãðàòü â êàçèíî-ðóëåòêó",0 -dailyTaskName28 db "Ïîáåäèòü â êàçèíî-ðóëåòêó",0 -dailyTaskName29 db "Ñûãðàòü â Slot machine",0 -dailyTaskName30 db "Ïîáåäèòü â Slot machine",0 -dailyTaskName31 db "Ñûãðàòü â äóðàêà",0 -dailyTaskName32 db "Ïîáåäèòü â äóðàêà",0 -dailyTaskName33 db "Ñûãðàòü â Skill Check",0 -dailyTaskName34 db "Ïîáåäèòü â Skill Check",0 -dailyTaskName35 db "Ñûãðàòü 2 êàðòî÷íûå èãðû",0 -dailyTaskName36 db "Ïîáåäèòü â êàðòî÷íîé èãðå",0 -dailyTaskName37 db "Ñûãðàòü 3 èãðû óäà÷è",0 -dailyTaskName38 db "Ïîáåäèòü 2 ðàçà â èãðàõ óäà÷è",0 -dailyTaskName39 db "Ñûãðàòü 2 îïàñíûå èãðû",0 -dailyTaskName40 db "Ïîáåäèòü â îïàñíîé èãðå",0 -dailyTaskNameTable dd OFFSET dailyTaskName01, OFFSET dailyTaskName02, OFFSET dailyTaskName03, OFFSET dailyTaskName04 - dd OFFSET dailyTaskName05, OFFSET dailyTaskName06, OFFSET dailyTaskName07, OFFSET dailyTaskName08 - dd OFFSET dailyTaskName09, OFFSET dailyTaskName10, OFFSET dailyTaskName11, OFFSET dailyTaskName12 - dd OFFSET dailyTaskName13, OFFSET dailyTaskName14, OFFSET dailyTaskName15, OFFSET dailyTaskName16 - dd OFFSET dailyTaskName17, OFFSET dailyTaskName18, OFFSET dailyTaskName19, OFFSET dailyTaskName20 - dd OFFSET dailyTaskName21, OFFSET dailyTaskName22, OFFSET dailyTaskName23, OFFSET dailyTaskName24 - dd OFFSET dailyTaskName25, OFFSET dailyTaskName26, OFFSET dailyTaskName27, OFFSET dailyTaskName28 - dd OFFSET dailyTaskName29, OFFSET dailyTaskName30, OFFSET dailyTaskName31, OFFSET dailyTaskName32 - dd OFFSET dailyTaskName33, OFFSET dailyTaskName34, OFFSET dailyTaskName35, OFFSET dailyTaskName36 - dd OFFSET dailyTaskName37, OFFSET dailyTaskName38, OFFSET dailyTaskName39, OFFSET dailyTaskName40 -cheatAppliedText db "CHEAT ACTIVATED: ",0 -cheatBadText db "Unknown cheat code.",13,10,0 -cheatMoneyText db "+$50000",13,10,0 -cheatSevenText db "+$7777",13,10,0 -cheatWinText db "next loss becomes win",13,10,0 -cheatGodText db "losses become wins",13,10,0 -cheatFairText db "fair play restored",13,10,0 -cheatGoalText db "bank moved to current goal",13,10,0 -cheatResetText db "bank reset to $10000",13,10,0 -cheatEasyText db "AI difficulty EASY",13,10,0 -cheatNormalText db "AI difficulty NORMAL",13,10,0 -cheatHardText db "AI difficulty HARD",13,10,0 -cheatJackpotText db "next slot spin is forced jackpot",13,10,0 -cheatRichText db "+$250000",13,10,0 -cheatDoubleText db "bank doubled",13,10,0 -cheatPoorText db "bank set to $1",13,10,0 -cheatShopText db "+$30000 for shop",13,10,0 -cheatBacksText db "all card backs unlocked",13,10,0 -cheatCharmText db "luck talisman maxed",13,10,0 -cheatNoCharmText db "luck talisman removed",13,10,0 -cheatAchText db "all achievements unlocked",13,10,0 -cheatSavedText db "CHEAT: loss changed into win.",13,10,0 -cheatCodeMoney db "MONEYRAIN",0 -cheatCodeSeven db "SEVENS",0 -cheatCodeWin db "WINNEXT",0 -cheatCodeGod db "GODMODE",0 -cheatCodeFair db "FAIRPLAY",0 -cheatCodeGoal db "GOAL",0 -cheatCodeReset db "RESETBANK",0 -cheatCodeEasy db "EASYAI",0 -cheatCodeNormal db "NORMALAI",0 -cheatCodeHard db "HARDAI",0 -cheatCodeJackpot db "JACKPOT",0 -cheatCodeRich db "HIGHROLLER",0 -cheatCodeDouble db "DOUBLECASH",0 -cheatCodePoor db "ONEBUCK",0 -cheatCodeShop db "SHOPPING",0 -cheatCodeBacks db "ALLBACKS",0 -cheatCodeCharm db "MAXCHARM",0 -cheatCodeNoCharm db "NOCHARM",0 -cheatCodeAch db "ACHIEVER",0 -moneyWinText db "Âûèãðûø: +$",0 -moneyLoseText db "Ïðîèãðûø: -$",0 -moneyDrawText db "Ñòàâêà âîçâðàùàåòñÿ.",13,10,0 -casinoKickText db 13,10,"Ó âàñ íå îñòàëîñü äåíåã. Âàñ âûâîäÿò èç êàçèíî.",13,10,0 -casinoExitText db "Íàæìèòå ëþáóþ êëàâèøó, ÷òîáû âûéòè...",0 -welcomeText db 13,10,"Äîáðî ïîæàëîâàòü â ASSEMBLER CASINO!",13,10,"Óäà÷à ëþáèò ñìåëûõ, íî êàçèíî ëþáèò ìàòåìàòèêó.",13,10,0 -difficultyText db 13,10,"Ñëîæíîñòü AI: 1 - Easy, 2 - Normal, 3 - Hard: ",0 -difficultyNowText db "Ñëîæíîñòü AI: ",0 -easyName db "Easy",13,10,0 -normalName db "Normal",13,10,0 -hardName db "Hard",13,10,0 -statsGamesText db "Èãð ñûãðàíî: ",0 -statsWinsText db "Ïîáåä: ",0 -statsLossText db "Ïîðàæåíèé: ",0 -statsDrawText db "Íè÷üèõ: ",0 -statsBestWinText db "Ìàêñ. âûèãðûø: $",0 -statsBestLossText db "Ìàêñ. ïðîèãðûø: $",0 -statsByGameTitle db 13,10,"--- Ñòàòèñòèêà è ëèäåðû êàçèíî ---",13,10,0 -statsLinePlayed db " èãð: ",0 -statsLineWins db " ïîáåä: ",0 -statsLineLoss db " ïîðàæåíèé: ",0 -statsLineDraw db " íè÷üèõ: ",0 -leaderCurrentTitle db "Òåêóùèé àêêàóíò:",13,10,0 -leaderTitle db 13,10,"Ëèäåðû ñðåäè âñåõ àêêàóíòîâ:",13,10,0 -leaderNoDataText db "Íåò ñîõðàíåíèé àêêàóíòîâ.",13,10,0 -leaderBankText db "Ñàìûé áîëüøîé áàíê: ",0 -leaderWinsText db "Áîëüøå âñåãî ïîáåä: ",0 -leaderLossText db "Áîëüøå âñåãî ïîðàæåíèé: ",0 -leaderGameTitle db 13,10,"Ëèäåðû ïî èãðàì:",13,10,0 -leaderGameWinText db " ïîáåäû: ",0 -leaderGameLossText db " ïîðàæåíèÿ: ",0 -leaderDashText db "-",0 -leaderOpenText db " (",0 -leaderCloseText db ")",0 -leaderMoneyPrefix db "$",0 -statsGame21 db "21 / Î÷êî",0 -statsGamePoker db "Poker",0 -statsGameClover db "CloverPit",0 -statsGameRR db "Ðóññêàÿ ðóëåòêà",0 -statsGameSkulls db "×åðåïà",0 -statsGameCoin db "Îðåë/ðåøêà",0 -statsGameDice db "Êîñòè",0 -statsGameCasinoRoulette db "Êàçèíî-ðóëåòêà",0 -statsGameClassicSlot db "Slot machine",0 -statsGameDurak db "Äóðàê",0 -statsGameSkillCheck db "Êðþê: Skill Check",0 -statsGameNames dd OFFSET statsGame21, OFFSET statsGamePoker, OFFSET statsGameClover, OFFSET statsGameRR, OFFSET statsGameSkulls - dd OFFSET statsGameCoin, OFFSET statsGameDice, OFFSET statsGameCasinoRoulette, OFFSET statsGameClassicSlot, OFFSET statsGameDurak - dd OFFSET statsGameSkillCheck -bankRecoveredText db "Ïîñëå ïðîøëîãî âèçèòà êàçèíî âûäàëî íîâûé ñòàðòîâûé áàíê: $10000",13,10,0 -saveTamperedText db "Ñîõðàíåíèå ïîâðåæäåíî èëè èçìåíåíî. Êàçèíî âûäàëî ÷èñòûé ñòàðòîâûé áàíê.",13,10,0 -goalText db "Öåëü èãðû: äîâåñòè áàíê äî $",0 -victoryText db 13,10,"+====================================+",13,10 - db "| ÄÆÅÊÏÎÒ ÆÈÇÍÈ |",13,10 - db "+====================================+",13,10,13,10,0 -victoryReachedText db "Òû ïîäíÿë áàíê äî $",0 -victoryTailText db "Îõðàíà óæå íåðâíè÷àåò.",13,10 - db "Êàçèíî ïðèçíàåò ïîðàæåíèå.",13,10,13,10 - db "Çàáèðàé âûèãðûø è óõîäè êðàñèâî.",13,10,0 -victoryExitText db "Íàæìèòå ëþáóþ êëàâèøó, ÷òîáû ïðîäîëæèòü èãðó...",0 -nextGoalText db "Ñëåäóþùàÿ öåëü: $",0 -croupierPrefix db 13,10,"Êðóïüå: ",0 -croupierWin1 db "Êðàñèâî. Ôèøêè èäóò ê âàì.",13,10,0 -croupierWin2 db "Ñòîë ñåãîäíÿ ÿâíî íà âàøåé ñòîðîíå.",13,10,0 -croupierWin3 db "Õîðîøèé óäàð ïî áàíêó êàçèíî.",13,10,0 -croupierLose1 db "Êàçèíî çàáèðàåò ñòàâêó.",13,10,0 -croupierLose2 db "Íå ëó÷øèé ðàñêëàä, íî âå÷åð åùå æèâîé.",13,10,0 -croupierLose3 db "Ôèøêè óõîäÿò ñî ñòîëà.",13,10,0 -croupierDraw1 db "Ñòàâêà îñòàåòñÿ ïðè âàñ.",13,10,0 -croupierDraw2 db "Íèêòî íå ñäâèíóë áàíê. Èãðàåì äàëüøå.",13,10,0 -croupierDraw3 db "Ðîâíî. Áåç ïîáåäèòåëÿ.",13,10,0 -croupierWinList dd OFFSET croupierWin1, OFFSET croupierWin2, OFFSET croupierWin3 -croupierLoseList dd OFFSET croupierLose1, OFFSET croupierLose2, OFFSET croupierLose3 -croupierDrawList dd OFFSET croupierDraw1, OFFSET croupierDraw2, OFFSET croupierDraw3 -dealerFileName db "assets\data\dealer_phrases.txt",0 -pulseTitleText db 13,10,"Ïóëüñ ñòàâêè:",13,10,0 -pulseFrame1 db " _/\_ ñïîêîéíî",13,10,0 -pulseFrame2 db " _/\/\_ íàïðÿæåíèå",13,10,0 -pulseFrame3 db " _/\/\/\_ ðèñê",13,10,0 -pulseFrame4 db " _/\/\/\/\_ ñåðäöå êîëîòèòñÿ",13,10,0 -pulseFrame5 db " _/\/\_/\_ âäîõ...",13,10,0 -observerTitle db 13,10,"--- Íàáëþäàòåëü AI vs AI ---",13,10,0 -observerIntro db "AI-1 è AI-2 èãðàþò 5 áûñòðûõ ðàóíäîâ â 21 áåç ñòàâîê.",13,10,0 -observerRoundText db 13,10,"Ðàóíä ",0 -observerAI1Text db "AI-1 î÷êè: ",0 -observerAI2Text db "AI-2 î÷êè: ",0 -observerWin1Text db "AI-1 çàáèðàåò ðàóíä.",13,10,0 -observerWin2Text db "AI-2 çàáèðàåò ðàóíä.",13,10,0 -observerDrawText db "Íè÷üÿ ìåæäó æåëåçêàìè.",13,10,0 -observerDoneText db 13,10,"Íàáëþäåíèå îêîí÷åíî.",13,10,0 -observerMenuText db "1. Ðóññêàÿ ðóëåòêà",13,10 - db "2. 21 / Î÷êî",13,10 - db "3. Poker",13,10 - db "4. Äóðàê",13,10 - db "0. Íàçàä",13,10 - db "Âûáîð: ",0 -observer21Title db 13,10,"--- AI vs AI: 21 / Î÷êî ---",13,10,0 -observerPokerTitle db 13,10,"--- AI vs AI: Poker ---",13,10,0 -observerDurakTitle db 13,10,"--- AI vs AI: Äóðàê ---",13,10,0 -observerRRTitle db 13,10,"--- AI vs AI: Ðóññêàÿ ðóëåòêà ---",13,10,0 -observerAI1CardsText db 13,10,"Êàðòû AI-1:",13,10,0 -observerAI2CardsText db 13,10,"Êàðòû AI-2:",13,10,0 -observerAI1RaiseText db "AI-1 ïîâûøàåò ñòàâêó.",13,10,0 -observerAI2RaiseText db "AI-2 ïîâûøàåò ñòàâêó.",13,10,0 -observerCallText db "Ñîïåðíèê îòâå÷àåò.",13,10,0 -observerFold1Text db "AI-1 äåëàåò ôîëä.",13,10,0 -observerFold2Text db "AI-2 äåëàåò ôîëä.",13,10,0 -observerShotAI1Text db "Âûñòðåë äîñòàëñÿ AI-1. Ïîáåäèë AI-2.",13,10,0 -observerShotAI2Text db "Âûñòðåë äîñòàëñÿ AI-2. Ïîáåäèë AI-1.",13,10,0 -shopMainMenuText db "1. Ðóáàøêè êàðò",13,10 - db "2. Òàëèñìàíû",13,10 - db "3. Áåñòèàðèé òàëèñìàíîâ",13,10 - db "0. Íàçàä",13,10 - db "Âûáîð: ",0 -shopBackTitle db 13,10,"--- Ìàãàçèí: ðóáàøêè êàðò ---",13,10,0 -shopCharmTitle db 13,10,"--- Ìàãàçèí: òàëèñìàíû ---",13,10,0 -shopBackMenuText db "1. Ñèíÿÿ ðóáàøêà êàðò - $3000",13,10 - db "2. Êðàñíàÿ ðóáàøêà êàðò - $3000",13,10 - db "3. Çîëîòàÿ ðóáàøêà êàðò - $10000",13,10 - db "4. Ðóáàøêà ×åðåï - $12000",13,10 - db "5. Rubashka CloverPit - $15000",13,10 - db "6. Rubashka Arcane kart - $17000",13,10 - db "7. Rubashka Noir kart - $18000",13,10 - db "8. Rubashka Diamond kart - $20000",13,10 - db "9. Rubashka Rider kart - $22000",13,10 - db "10. Rubashka Bee kart - $22000",13,10 - db "11. Rubashka Fan kart - $23000",13,10 - db "12. Rubashka Web kart - $24000",13,10 - db "0. Íàçàä",13,10 - db "Âûáîð: ",0 -shopCharmMenuText db "1. Òàëèñìàí Êëåâåð: 7%, 3 çàðÿäà - $12000",13,10 - db "2. Òàëèñìàí Êîëîêîë: 14%, 3 çàðÿäà, +4 ïîäîçðåíèÿ - $18000",13,10 - db "3. Òàëèñìàí Àëìàç: 21%, 3 çàðÿäà, +8 ïîäîçðåíèÿ - $25000",13,10 - db "4. Òàëèñìàí ×åðåï: 28%, 2 çàðÿäà, øòðàô ïîëîâèíà ñòàâêè - $32000",13,10 - db "5. Òàëèñìàí Ïàóòèíà: 35%, 1 çàðÿä, +20 ïîäîçðåíèÿ - $40000",13,10 - db "6. Òàëèñìàí Ï÷åëà: 12%, 5 çàðÿäîâ - $30000",13,10 - db "7. Òàëèñìàí Ëóíà: 18%, 4 çàðÿäà, +8 ïîäîçðåíèÿ - $36000",13,10 - db "8. Òàëèñìàí Êîðîíà: 24%, 2 çàðÿäà, +12 ïîäîçðåíèÿ - $52000",13,10 - db "9. Òàëèñìàí Çåðêàëî: 16%, 4 çàðÿäà, +6 ïîäîçðåíèÿ - $42000",13,10 - db "10. Òàëèñìàí Êîñòü: 10%, 6 çàðÿäîâ - $35000",13,10 - db "11. Êðîâàâàÿ ìîíåòà: 40%, 1 çàðÿä, øòðàô 25% ñòàâêè è +25 ïîäîçðåíèÿ - $65000",13,10 - db "12. Ïåñî÷íûå ÷àñû: 22%, 2 çàðÿäà, +15 ïîäîçðåíèÿ - $48000",13,10 - db "13. Ïîäêîâà: 9%, 8 çàðÿäîâ - $39000",13,10 - db "14. Ìàñêà äæîêåðà: 33%, 1 çàðÿä, +30 ïîäîçðåíèÿ - $70000",13,10 - db "15. Ïåðî ôåíèêñà: 26%, 2 çàðÿäà, +10 ïîäîçðåíèÿ - $56000",13,10 - db "16. Ñëîìàííûé êîìïàñ: 19%, 3 çàðÿäà, +12 ïîäîçðåíèÿ - $44000",13,10 - db "17. Çîëîòîé çóá: 15%, 5 çàðÿäîâ, øòðàô 20% ñòàâêè - $47000",13,10 - db "18. Õðóñòàëüíûé ãëàç: 31%, 1 çàðÿä, +18 ïîäîçðåíèÿ - $60000",13,10 - db "19. Ðæàâûé êëþ÷: 13%, 6 çàðÿäîâ - $41000",13,10 - db "20. ×åðíàÿ ñâå÷à: 38%, 1 çàðÿä, øòðàô 33% ñòàâêè è +35 ïîäîçðåíèÿ - $76000",13,10 - db "21. Ñ÷àñòëèâàÿ ôèøêà: 20%, 4 çàðÿäà - $50000",13,10 - db "22. Çìåèíîå êîëüöî: 29%, 2 çàðÿäà, +16 ïîäîçðåíèÿ - $62000",13,10 - db "23. Îñêîëîê òóçà: 17%, 5 çàðÿäîâ, +7 ïîäîçðåíèÿ - $53000",13,10 - db "24. Äîãîâîð ñ äüÿâîëîì: 50%, 1 çàðÿä, øòðàô 50% ñòàâêè è +45 ïîäîçðåíèÿ - $100000",13,10 - db "0. Íàçàä",13,10 - db "Âûáîð: ",0 -shopTitle db 13,10,"--- Ìàãàçèí êàçèíî ---",13,10,0 -shopMenuText db "1. Ñèíÿÿ ðóáàøêà êàðò - $3000",13,10 - db "2. Êðàñíàÿ ðóáàøêà êàðò - $3000",13,10 - db "3. Çîëîòàÿ ðóáàøêà êàðò - $10000",13,10 - db "4. Ðóáàøêà ×åðåï - $12000",13,10 - db "5. Ðóáàøêà CloverPit - $15000",13,10 - db "6. Òàëèñìàí Êëåâåð: 7%, 3 çàðÿäà - $12000",13,10 - db "7. Òàëèñìàí Êîëîêîë: 14%, 3 çàðÿäà - $18000",13,10 - db "8. Òàëèñìàí Àëìàç: 21%, 3 çàðÿäà - $25000",13,10 - db "9. Rubashka Arcane kart - $17000",13,10 - db "10. Rubashka Noir kart - $18000",13,10 - db "11. Rubashka Diamond kart - $20000",13,10 - db "12. Rubashka Rider kart - $22000",13,10 - db "13. Rubashka Bee kart - $22000",13,10 - db "14. Rubashka Fan kart - $23000",13,10 - db "15. Rubashka Web kart - $24000",13,10 - db "0. Íàçàä",13,10 - db "Âûáîð: ",0 -shopBackText db "Òåêóùàÿ ðóáàøêà: ",0 -shopBackGray db "Ñåðàÿ",13,10,0 -shopBackBlue db "Ñèíÿÿ âîëíà",13,10,0 -shopBackRed db "Êðàñíûé êðåñò",13,10,0 -shopBackGold db "Çîëîòîé áëåñê",13,10,0 -shopBackSkull db "×åðåï",13,10,0 -shopBackClover db "CloverPit",13,10,0 -shopBackArcane db "Arcane",13,10,0 -shopBackNoir db "Noir",13,10,0 -shopBackDiamond db "Diamond",13,10,0 -shopBackRider db "Rider",13,10,0 -shopBackBee db "Bee",13,10,0 -shopBackFan db "Fan",13,10,0 -shopBackWeb db "Web",13,10,0 -shopCharmText db "Òàëèñìàí: ",0 -shopCharmNone db "íåò",13,10,0 -shopCharmClover db "Êëåâåð",0 -shopCharmBell db "Êîëîêîë",0 -shopCharmDiamond db "Àëìàç",0 -shopCharmSkull db "×åðåï",0 -shopCharmWeb db "Ïàóòèíà",0 -shopCharmBee db "Ï÷åëà",0 -shopCharmMoon db "Ëóíà",0 -shopCharmCrown db "Êîðîíà",0 -shopCharmMirror db "Çåðêàëî",0 -shopCharmDice db "Êîñòü",0 -shopCharmBlood db "Êðîâàâàÿ ìîíåòà",0 -shopCharmHourglass db "Ïåñî÷íûå ÷àñû",0 -shopCharmHorseshoe db "Ïîäêîâà",0 -shopCharmJoker db "Ìàñêà äæîêåðà",0 -shopCharmPhoenix db "Ïåðî ôåíèêñà",0 -shopCharmCompass db "Ñëîìàííûé êîìïàñ",0 -shopCharmTooth db "Çîëîòîé çóá",0 -shopCharmEye db "Õðóñòàëüíûé ãëàç",0 -shopCharmKey db "Ðæàâûé êëþ÷",0 -shopCharmCandle db "×åðíàÿ ñâå÷à",0 -shopCharmChip db "Ñ÷àñòëèâàÿ ôèøêà",0 -shopCharmSnake db "Çìåèíîå êîëüöî",0 -shopCharmAce db "Îñêîëîê òóçà",0 -shopCharmDevil db "Äîãîâîð ñ äüÿâîëîì",0 -bestiaryTitle db 13,10,"--- Áåñòèàðèé òàëèñìàíîâ ---",13,10,0 -bestiaryMenuText db "--- Îáû÷íûå ---",13,10 - db "1. Êëåâåð",13,10 - db "2. Êîëîêîë",13,10 - db "6. Ï÷åëà",13,10 - db "10. Êîñòü",13,10 - db "13. Ïîäêîâà",13,10 - db "19. Ðæàâûé êëþ÷",13,10 - db "--- Ðåäêèå ---",13,10 - db "3. Àëìàç",13,10 - db "7. Ëóíà",13,10 - db "9. Çåðêàëî",13,10 - db "12. Ïåñî÷íûå ÷àñû",13,10 - db "15. Ïåðî ôåíèêñà",13,10 - db "16. Ñëîìàííûé êîìïàñ",13,10 - db "17. Çîëîòîé çóá",13,10 - db "21. Ñ÷àñòëèâàÿ ôèøêà",13,10 - db "23. Îñêîëîê òóçà",13,10 - db "--- Ïðîêëÿòûå ---",13,10 - db "4. ×åðåï",13,10 - db "5. Ïàóòèíà",13,10 - db "11. Êðîâàâàÿ ìîíåòà",13,10 - db "14. Ìàñêà äæîêåðà",13,10 - db "20. ×åðíàÿ ñâå÷à",13,10 - db "22. Çìåèíîå êîëüöî",13,10 - db "--- Ëåãåíäàðíûå ---",13,10 - db "8. Êîðîíà",13,10 - db "18. Õðóñòàëüíûé ãëàç",13,10 - db "24. Äîãîâîð ñ äüÿâîëîì",13,10 - db "0. Íàçàä",13,10 - db "Âûáîð: ",0 -bestiaryGoodText db "Ïëþñ: ",0 -bestiaryBadText db "Ìèíóñ: ",0 -bestiaryBackText db 13,10,"0 - íàçàä ê ñïèñêó áåñòèàðèÿ: ",0 -bestiaryCloverArt db 13,10," .-. .-.",13,10," .' V '. CLOVER",13,10," \ \|/ /",13,10," `-+-'",13,10,0 -bestiaryBellArt db 13,10," .---.",13,10," / ___ \ BELL",13,10," / / \ ",13,10," \_\___/_/",13,10," (_) ",13,10,0 -bestiaryDiamondArt db 13,10," /",13,10," /##\ DIAMOND",13,10," /####",13,10," \####/",13,10," \##/",13,10," \/",13,10,0 -bestiarySkullArt db 13,10," .-''''-.",13,10," / O O \ SKULL",13,10," | __ |",13,10," | .____. |",13,10," \__||||__/",13,10,0 -bestiaryWebArt db 13,10," \ | /",13,10," ---\ | /--- WEB",13,10," ---- @ ----",13,10," ---/ | \---",13,10," / | ",13,10,0 -bestiaryBeeArt db 13,10," __",13,10," __/o \__ BEE",13,10," / \__/ ",13,10," \__/==\__/",13,10," \__/",13,10,0 -bestiaryMoonArt db 13,10," .--.",13,10," .' _/ MOON",13,10," / .'",13,10," \ '.",13,10," '.__",13,10,0 -bestiaryCloverInfo db "Êëåâåð: 7%, 3 çàðÿäà.",13,10,"Ïëþñ: ìîæåò ïîëíîñòüþ ñïàñòè ïðîèãðàííóþ ñòàâêó.",13,10,"Ìèíóñ: ñëàáûé øàíñ, áåç äîïîëíèòåëüíûõ áîíóñîâ.",13,10,0 -bestiaryBellInfo db "Êîëîêîë: 14%, 3 çàðÿäà.",13,10,"Ïëþñ: ÷àùå ñïàñàåò ïðîèãðûø.",13,10,"Ìèíóñ: çâîí ïðèâëåêàåò êàçèíî: +4 ïîäîçðåíèÿ ïðè ñðàáàòûâàíèè.",13,10,0 -bestiaryDiamondInfo db "Àëìàç: 21%, 3 çàðÿäà.",13,10,"Ïëþñ: ñèëüíûé øàíñ ñïàñåíèÿ.",13,10,"Ìèíóñ: áëåñê ïàëèòñÿ îõðàíå: +8 ïîäîçðåíèÿ.",13,10,0 -bestiarySkullInfo db "×åðåï: 28%, 2 çàðÿäà.",13,10,"Ïëþñ: âûñîêèé øàíñ íå ïîòåðÿòü âñþ ñòàâêó.",13,10,"Ìèíóñ: çàáèðàåò ïîëîâèíó ñòàâêè äàæå ïðè ñïàñåíèè.",13,10,0 -bestiaryWebInfo db "Ïàóòèíà: 35%, 1 çàðÿä.",13,10,"Ïëþñ: ïî÷òè àâàðèéíàÿ êíîïêà ïðîòèâ ïðîèãðûøà.",13,10,"Ìèíóñ: +20 ïîäîçðåíèÿ, çàðÿä îäèí.",13,10,0 -bestiaryBeeInfo db "Ï÷åëà: 12%, 5 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî ïîïûòîê, õîðîøèé òàëèñìàí íà äëèííóþ èãðó.",13,10,"Ìèíóñ: øàíñ íèæå, ÷åì ó äîðîãèõ òàëèñìàíîâ.",13,10,0 -bestiaryMoonInfo db "Ëóíà: 18%, 4 çàðÿäà.",13,10,"Ïëþñ: áàëàíñ øàíñà è çàðÿäîâ.",13,10,"Ìèíóñ: ëóííûé ñâåò âûäàåò øóëåðà: +8 ïîäîçðåíèÿ.",13,10,0 -bestiaryCrownArt db 13,10," _^_",13,10," .'___'. CROWN",13,10," /_/|_|\_",13,10," /___",13,10,0 -bestiaryMirrorArt db 13,10," .----.",13,10," / .--. \ MIRROR",13,10," | | <> | |",13,10," \ '--' /",13,10," '----'",13,10,0 -bestiaryDiceArt db 13,10," +-----+",13,10," | o o | DICE",13,10," | o |",13,10," | o o |",13,10," +-----+",13,10,0 -bestiaryBloodArt db 13,10," .---.",13,10," / $ $ \ BLOOD COIN",13,10," | *** |",13,10," \_===_/",13,10," drip",13,10,0 -bestiaryHourglassArt db 13,10," \-----/",13,10," \.../ HOURGLASS",13,10," \./",13,10," /\",13,10," /___",13,10,0 -bestiaryCrownInfo db "Êîðîíà: 24%, 2 çàðÿäà.",13,10,"Ïëþñ: ñîëèäíûé øàíñ ñïàñåíèÿ.",13,10,"Ìèíóñ: êîðîíà ñëèøêîì çàìåòíà: +12 ïîäîçðåíèÿ.",13,10,0 -bestiaryMirrorInfo db "Çåðêàëî: 16%, 4 çàðÿäà.",13,10,"Ïëþñ: íåñêîëüêî ñòàáèëüíûõ ïîïûòîê îáìàíóòü ïðîèãðûø.",13,10,"Ìèíóñ: îòðàæåíèå ïàëèò ðóêè: +6 ïîäîçðåíèÿ.",13,10,0 -bestiaryDiceInfo db "Êîñòü: 10%, 6 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî çàðÿäîâ, ìîæíî æèòü äîëãî.",13,10,"Ìèíóñ: øàíñ ìàëåíüêèé, ýòî òàëèñìàí òåðïåíèÿ.",13,10,0 -bestiaryBloodInfo db "Êðîâàâàÿ ìîíåòà: 40%, 1 çàðÿä.",13,10,"Ïëþñ: ñàìûé ðåçêèé øàíñ ñïàñåíèÿ.",13,10,"Ìèíóñ: çàáèðàåò 25% ñòàâêè è äàåò +25 ïîäîçðåíèÿ.",13,10,0 -bestiaryHourglassInfo db "Ïåñî÷íûå ÷àñû: 22%, 2 çàðÿäà.",13,10,"Ïëþñ: íàäåæíåå ñðåäíåãî.",13,10,"Ìèíóñ: âðåìÿ íå ëþáèò ñâèäåòåëåé: +15 ïîäîçðåíèÿ.",13,10,0 -bestiaryHorseshoeArt db 13,10," __ __",13,10," / \_/ \ HORSESHOE",13,10," | o o |",13,10," \__ __/",13,10," |_|",13,10,0 -bestiaryJokerArt db 13,10," .-^^-.",13,10," / o o \ JOKER",13,10," | .--. |",13,10," \_\__/ _/",13,10," /==\",13,10,0 -bestiaryPhoenixArt db 13,10," /\",13,10," ___/ \___ PHOENIX",13,10," / / /\ \ ",13,10," /_||_\",13,10," \/",13,10,0 -bestiaryCompassArt db 13,10," .---.",13,10," / N \ COMPASS",13,10," | W-+-E |",13,10," \ S /",13,10," '--?'",13,10,0 -bestiaryToothArt db 13,10," .--.",13,10," /$ $\ GOLD TOOTH",13,10," | __ |",13,10," \____/",13,10," drip",13,10,0 -bestiaryEyeArt db 13,10," .-------.",13,10," / .---. \ EYE",13,10," | ( 0 ) |",13,10," \ '---' /",13,10," '-------'",13,10,0 -bestiaryKeyArt db 13,10," __",13,10," ___/ \___ KEY",13,10," (___ ___)",13,10," |__|==",13,10," ==",13,10,0 -bestiaryCandleArt db 13,10," )",13,10," ( ) CANDLE",13,10," .-#-.",13,10," |###|",13,10," |___|",13,10,0 -bestiaryChipArt db 13,10," .-----.",13,10," / $ $ $ \ CHIP",13,10," | $ 777 $ |",13,10," \ $ $ $ /",13,10," '-----'",13,10,0 -bestiarySnakeArt db 13,10," __",13,10," __/ \__ SNAKE RING",13,10," / _ _ ",13,10," \_/ \/ \_/",13,10," hiss",13,10,0 -bestiaryAceArt db 13,10," .---.",13,10," / A \ ACE SHARD",13,10," | ^ |",13,10," \ /_\ /",13,10," '---'",13,10,0 -bestiaryDevilArt db 13,10," /\ /\",13,10," / \_/ \ DEVIL",13,10," | $ $ |",13,10," | ___ |",13,10," \_/###\_/",13,10,0 -bestiaryHorseshoeInfo db "Ïîäêîâà: 9%, 8 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî ïîïûòîê, õîðîøî äëÿ äëèííûõ ñåññèé.",13,10,"Ìèíóñ: øàíñ ìàëåíüêèé, ñïàñàåò ðåäêî.",13,10,0 -bestiaryJokerInfo db "Ìàñêà äæîêåðà: 33%, 1 çàðÿä.",13,10,"Ïëþñ: ñèëüíûé øàíñ ðåçêî îòìåíèòü ïðîèãðûø.",13,10,"Ìèíóñ: ñëèøêîì òåàòðàëüíî: +30 ïîäîçðåíèÿ.",13,10,0 -bestiaryPhoenixInfo db "Ïåðî ôåíèêñà: 26%, 2 çàðÿäà.",13,10,"Ïëþñ: õîðîøèé øàíñ, áóäòî ñòàâêà âîñêðåñàåò èç ïåïëà.",13,10,"Ìèíóñ: +10 ïîäîçðåíèÿ ïðè ñðàáàòûâàíèè.",13,10,0 -bestiaryCompassInfo db "Ñëîìàííûé êîìïàñ: 19%, 3 çàðÿäà.",13,10,"Ïëþñ: ñðåäíèé òàëèñìàí áåç äåíåæíîãî øòðàôà.",13,10,"Ìèíóñ: âåäåò êðèâî: +12 ïîäîçðåíèÿ.",13,10,0 -bestiaryToothInfo db "Çîëîòîé çóá: 15%, 5 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî çàðÿäîâ ïðè íîðìàëüíîì øàíñå.",13,10,"Ìèíóñ: áåðåò ïëàòó 20% ñòàâêè ïðè ñïàñåíèè.",13,10,0 -bestiaryEyeInfo db "Õðóñòàëüíûé ãëàç: 31%, 1 çàðÿä.",13,10,"Ïëþñ: ïî÷òè âèäèò ïðîèãðûø çàðàíåå.",13,10,"Ìèíóñ: +18 ïîäîçðåíèÿ, çàðÿä îäèí.",13,10,0 -bestiaryKeyInfo db "Ðæàâûé êëþ÷: 13%, 6 çàðÿäîâ.",13,10,"Ïëþñ: äåøåâëå ìîùíûõ òàëèñìàíîâ è äîëãî æèâåò.",13,10,"Ìèíóñ: øàíñ ñëàáûé, êëþ÷ ÷àñòî íå ïîäõîäèò.",13,10,0 -bestiaryCandleInfo db "×åðíàÿ ñâå÷à: 38%, 1 çàðÿä.",13,10,"Ïëþñ: î÷åíü ñèëüíûé øàíñ ñïàñåíèÿ.",13,10,"Ìèíóñ: øòðàô 33% ñòàâêè è +35 ïîäîçðåíèÿ.",13,10,0 -bestiaryChipInfo db "Ñ÷àñòëèâàÿ ôèøêà: 20%, 4 çàðÿäà.",13,10,"Ïëþñ: ðîâíûé óíèâåðñàëüíûé òàëèñìàí.",13,10,"Ìèíóñ: áåç ÿðêîãî áîíóñà, ïðîñòî íàäåæíîñòü.",13,10,0 -bestiarySnakeInfo db "Çìåèíîå êîëüöî: 29%, 2 çàðÿäà.",13,10,"Ïëþñ: âûñîêèé øàíñ íà äâà ñïàñåíèÿ.",13,10,"Ìèíóñ: øèïèò íà îõðàíó: +16 ïîäîçðåíèÿ.",13,10,0 -bestiaryAceInfo db "Îñêîëîê òóçà: 17%, 5 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî çàðÿäîâ è ÷óòü áîëüøå óäà÷è, ÷åì ó êëþ÷à.",13,10,"Ìèíóñ: +7 ïîäîçðåíèÿ.",13,10,0 -bestiaryDevilInfo db "Äîãîâîð ñ äüÿâîëîì: 50%, 1 çàðÿä.",13,10,"Ïëþñ: ñàìûé ìîùíûé øàíñ ñïàñòè ïðîèãðûø.",13,10,"Ìèíóñ: øòðàô 50% ñòàâêè è +45 ïîäîçðåíèÿ.",13,10,0 -charmPenaltyText db "Öåíà òàëèñìàíà: $",0 -shopCharmUsesText db ", çàðÿäîâ: ",0 -shopBoughtText db "Ïîêóïêà âûïîëíåíà.",13,10,0 -shopSelectedText db "Ðóáàøêà âûáðàíà.",13,10,0 -shopCharmBurnText db "Òàëèñìàí ñãîðåë.",13,10,0 -shopCharmSaveText db 13,10,"Òàëèñìàí âñïûõíóë è ñïàñ ñòàâêó!",13,10,0 -achMenuTitle db 13,10,"--- Äîñòèæåíèÿ ---",13,10,0 -achPopupTop db 13,10,"+--------------------------------------+",13,10,0 -achPopupTitle db "| ÄÎÑÒÈÆÅÍÈÅ ÎÒÊÐÛÒÎ |",13,10,0 -achPopupLeft db "| ",0 -achPopupBottom db "+--------------------------------------+",13,10,0 -achDoneText db "[x] ",0 -achTodoText db "[ ] ",0 -achFirstWinName db "Ïåðâûé âûèãðûø",13,10,0 -achFirstLossName db "Ïåðâûé ïðîèãðûø",13,10,0 -achJackpotName db "Äæåêïîò ïîéìàí",13,10,0 -achHighRollerName db "Áîëüøàÿ ñòàâêà",13,10,0 -achShopperName db "Ïîêóïàòåëü êàçèíî",13,10,0 -achCharmName db "Òàëèñìàí ñðàáîòàë",13,10,0 -achGoalName db "Öåëü äîñòèãíóòà",13,10,0 -achCloverPitName db "CloverPit ðàçîãðåëñÿ",13,10,0 -achClassicSlotName db "Ñòàðûé àâòîìàò ïëàòèò",13,10,0 -achPokerRaiseName db "Ñòàâêà ïîâûøåíà",13,10,0 -achPokerBluffName db "Áëåô ñðàáîòàë",13,10,0 -achRouletteWinName db "Êîëåñî ñóäüáû",13,10,0 -achRussianWinName db "Ñóõîé ùåë÷îê",13,10,0 -achDurakWinName db "Íå äóðàê",13,10,0 -achBackCollectorName db "Êîëëåêöèîíåð ðóáàøåê",13,10,0 -achCharmBuyerName db "Òàëèñìàí â êàðìàíå",13,10,0 -achObserverName db "Ëîæà íàáëþäàòåëÿ",13,10,0 -achSkillCheckName db "Ñ êðþêà ñîðâàëñÿ",13,10,0 -achievementFileName db "runtime\achievement.txt",0 -achievementCmd db "cmd /c start ""Achievement"" tools\tests\achievement_popup.bat",0 -skillTitle db 13,10,"--- Êðþê: Skill Check ---",13,10,0 -skillIntro db "Ïîïàäàé ïî çåëåíîé çîíå. PERFECT äàåò äâîéíîé ïðîãðåññ.",13,10 - db "3 ïðîìàõà - òüìà çàáèðàåò ñòàâêó. 5 ïðîãðåññà - òû ñðûâàåøüñÿ ñ êðþêà.",13,10 - db "Íàæèìàé SPACE èëè ENTER.",13,10,0 -skillHookArt db 13,10 - db " || .:!!!!!!!!!!:.",13,10 - db " || .:!##############!:.",13,10 - db " _____||_____ !#### ENTITY #####!",13,10 - db " /____ ____/ ':!#############!:'",13,10 - db " | | ''!!####!!''",13,10 - db " | | _J",13,10 - db " | | __/ |",13,10 - db " _____| |_____ .-' .-^-. .---- RED LOCKER ----.",13,10 - db " | WOODEN WALL | / /.-.\\\\ | [] [] [] [] [] |",13,10 - db " | || || || || || | |( )| | | [] [] [] [] [] |",13,10 - db " | || || || || || | /|\\___/|\\| | [] [] [] [] [] |",13,10 - db " | || || || || || |__/ | / \\ | \\__ |__________________|",13,10 - db " | || || || || || /_/ \\_\\ J J J",13,10 - db " |________________| _/ \\_ chains and hooks",13,10 - db " >>> SPACE / ENTER - ëîâèòü skill check <<<",13,10,0 -skillStateText db "Ñîñòîÿíèå: ",0 -skillStateGood db "äåðæèøüñÿ",13,10,0 -skillStateWarn db "öåïü ñêðèïèò",13,10,0 -skillStateBad db "òüìà ðÿäîì",13,10,0 -skillProgressText db "Ïðîãðåññ ïîáåãà: ",0 -skillMissText db "Ïðîìàõè: ",0 -skillGaugeHint db 13,10,"Áîëüøîé skill check:",13,10,0 -skillGaugeLeft db "[",0 -skillGaugeRight db "]",13,10,0 -skillGaugeEmpty db "-",0 -skillGaugeSuccess db "#",0 -skillGaugePerfect db "@",0 -skillGaugeNeedle db "|",0 -skillSuccessText db 13,10,"Óñïåõ. Òû óäåðæàëñÿ íà êðþêå.",13,10,0 -skillPerfectText db 13,10,"PERFECT! Ðûâîê ïî÷òè ñîðâàë êðþê.",13,10,0 -skillFailText db 13,10,"Ïðîìàõ. Êðþê äåðíóë ñèëüíåå.",13,10,0 -skillEscapeText db 13,10,"Òû ñîðâàëñÿ ñ êðþêà è âûðâàëñÿ èç òóìàíà!",13,10,0 -skillDarkText db 13,10,"Òüìà çàáðàëà òåáÿ. Ñòàâêà ñãîðåëà.",13,10,0 -coinTitle db 13,10,"--- Îðåë è ðåøêà ---",13,10,0 -coinIntroText db "Óãàäàé ñòîðîíó ìîíåòû. Ïîáåäà äàåò âûèãðûø ðàçìåðîì ñî ñòàâêó.",13,10,0 -coinChoiceText db "1 - Îðåë, 2 - Ðåøêà: ",0 -coinSpinText db "Ìîíåòà ëåòèò...",13,10,0 -; === ASCII-êàäðû àíèìàöèè ìîíåòû === -coinFrame1 db 13,10 - db " ( O )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame2 db 13,10 - db " ( / )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame3 db 13,10 - db " ( | )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame4 db 13,10 - db " ( \ )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame5 db 13,10 - db " ( - )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame6 db 13,10 - db " ( / )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame7 db 13,10 - db " ( | )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame8 db 13,10 - db " ( \ )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame9 db 13,10 - db " ( O )",13,10 - db 13,10 - db " ___________________",13,10,0 -coinFrame10 db 13,10 - db " ( / )",13,10 - db " ",13,10 - db " ___________________",13,10,0 -coinFrame11 db 13,10 - db " ( | )",13,10 - db " ",13,10 - db " ___________________",13,10,0 -coinFrame12 db 13,10 - db " ( \ )",13,10 - db " ",13,10 - db " ___________________",13,10,0 -coinFrame13 db 13,10 - db " ( - )",13,10 - db " ",13,10 - db " ___________________",13,10,0 -coinFrame14 db 13,10 - db " ( O )",13,10 - db " ",13,10 - db " ___________________",13,10,0 -coinPickText db "Òû âûáðàë: ",0 -coinResultText db "Âûïàëî: ",0 -coinHeadsText db "Îðåë",13,10,0 -coinTailsText db "Ðåøêà",13,10,0 -diceTitle db 13,10,"--- Êîñòè ---",13,10,0 -diceIntroText db "Óãàäàé ÷åòíîñòü ñóììû äâóõ êîñòåé. Ïîáåäà äàåò âûèãðûø ðàçìåðîì ñî ñòàâêó.",13,10,0 -diceChoiceText db "1 - ÷åò, 2 - íå÷åò: ",0 -diceRollText db "Êîñòè ëåòÿò ïî ñòîëó...",13,10,0 -diceFirstText db "Ïåðâàÿ êîñòü: ",0 -diceSecondText db "Âòîðàÿ êîñòü: ",0 -diceSumText db "Ñóììà: ",0 -diceEvenText db "×åò",13,10,0 -diceOddText db "Íå÷åò",13,10,0 -; === Êàçèíî-ðóëåòêà: òåêñòû, êîëåñî, öâåòà è êàðìàíû === -casinoRouletteTitle db 13,10,"--- Êàçèíî-ðóëåòêà ---",13,10,0 -casinoRouletteIntro db "Åâðîïåéñêîå êîëåñî: 0 çåëåíûé, ïîëîâèíà ÷èñåë êðàñíûå, ïîëîâèíà ÷åðíûå.",13,10 - db "Ñòàâêà íà ÷èñëî ïëàòèò x35, îñòàëüíûå ñòàâêè ïëàòÿò x1.",13,10,0 -casinoRouletteBetMenu db "1 - ÷èñëî 0-36",13,10 - db "2 - êðàñíîå",13,10 - db "3 - ÷åðíîå",13,10 - db "4 - ÷åò",13,10 - db "5 - íå÷åò",13,10 - db "Âûáîð ñòàâêè: ",0 -casinoRouletteNumberAsk db "Ââåäèòå ÷èñëî 0-36: ",0 -casinoRouletteBadNumber db " ðóëåòêå åñòü òîëüêî ÷èñëà îò 0 äî 36.",13,10,0 -casinoRouletteSpinText db "Øàðèê ñêà÷åò ïî êàðìàíàì êîëåñà... Èòîãîâûé êàðìàí ïðÿìî ïîä ñòðåëêîé ñâåðõó.",13,10,0 -casinoRouletteResultText db 13,10,"Øàðèê îñòàíîâèëñÿ íà: ",0 -casinoRouletteWinText db "Ñòàâêà ñûãðàëà.",13,10,0 -casinoRouletteLoseText db "Ñòàâêà íå ñûãðàëà.",13,10,0 -casinoRouletteWheelTop db " =============================================================",13,10 - db " o",13,10 - db " v",13,10,0 -casinoRouletteWheelBottom db " =============================================================",13,10,0 -casinoRoulettePad db " ",0 -rouletteBigSidePad db " ",0 -rouletteBigSideGap1 db " .-------------------------------------------------. ",0 -rouletteBigSideGap2 db " / .-------------------------------------. \ ",0 -rouletteBigSideGap3 db " | / . . . . . . . . . . . . . . \ | ",0 -rouletteBigSideGap4 db " | | \\ | // ( O ) \\ | | ",0 -rouletteBigSideGap5 db " | | // | \\ --+-- // | | ",0 -rouletteBigSideGap6 db " | \ . . . . . . . . . . . . \ | | ",0 -roulettePocketLeft db "[",0 -roulettePocketRight db "] ",0 -rouletteNumSpace db " ",0 -rouletteRedName db "êðàñíîå",13,10,0 -rouletteBlackName db "÷åðíîå",13,10,0 -rouletteGreenName db "çåëåíûé íîëü",13,10,0 -rouletteWheel dd 0,32,15,19,4,21,2,25,17,34,6,27,13,36,11,30,8,23,10 - dd 5,24,16,33,1,20,14,31,9,22,18,29,7,28,12,35,3,26 -rouletteColors db 0,1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1 - db 1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1 -bankLevelText db "Óðîâåíü áàíêà: ",0 -bankLevelNewbie db "Íîâè÷îê",13,10,0 -bankLevelPlayer db "Èãðîê",13,10,0 -bankLevelHigh db "Õàéðîëëåð",13,10,0 -bankLevelLegend db "Ëåãåíäà êàçèíî",13,10,0 - - -; === Òåêñòû êàðòî÷íûõ èãð: 21, ïîêåð, äóðàê è ïîäñêàçêè === -hitText db "Âçÿòü êàðòó? (y/n): ",0 -againText db "Ñûãðàòü åùå? (y/n): ",0 -yourCardText db 13,10,"Òâîÿ êàðòà:",13,10,0 -dealerCardText db 13,10,"Êàðòà äèëåðà:",13,10,0 -aiThinkText db 13,10,"AI äóìàåò...",13,10,0 -aiMoveText db 13,10,"AI áåðåò êàðòó!",13,10,0 -aiCardsText db 13,10,"Êàðòû AI:",13,10,0 -playerCardsText db 13,10,"Òâîè êàðòû:",13,10,0 -yourScoreText db "Òâîè î÷êè: ",0 -dealerScoreText db "Î÷êè äèëåðà: ",0 -aiScoreText db "Î÷êè AI: ",0 -bustText db "Ïåðåáîð. Òû ïðîèãðàë.",13,10,0 -dealerBustText db "Ó äèëåðà ïåðåáîð. Òû âûèãðàë!",13,10,0 -winText db "Òû âûèãðàë!",13,10,0 -loseText db "Òû ïðîèãðàë.",13,10,0 -drawText db "Íè÷üÿ.",13,10,0 -blackjackText db "Blackjack!",13,10,0 - -twentyOneTitle db 13,10,"--- 21 / Î÷êî ---",13,10,0 -blackjackTitle db 13,10,"--- Blackjack ---",13,10,0 -pokerTitle db 13,10,"--- Poker ---",13,10,0 -slotTitle db 13,10,"--- CloverPit ---",13,10,0 -classicSlotTitle db 13,10,"--- Slot machine ---",13,10,0 -durakTitle db 13,10,"--- Äóðàê ---",13,10,0 -durakInfoText db "Êîçûðü: ",0 -durakDeckText db "Êàðò â êîëîäå: ",0 -durakAICardsText db "Êàðò ó AI: ",0 -durakYourHandText db 13,10,"Òâîè êàðòû:",13,10,0 -durakTableText db 13,10,"Íà ñòîëå: ",0 -durakAttackAsk db "Âûáåðè êàðòó äëÿ àòàêè: ",0 -durakDefendAsk db "×åì áèòü? 0 - âçÿòü: ",0 -durakBadMoveText db "Òàê íåëüçÿ. Âûáåðè äðóãóþ êàðòó.",13,10,0 -durakAITakeText db "AI íå ñìîã îòáèòüñÿ è âçÿë êàðòó.",13,10,0 -durakAIDefendText db "AI îòáèëñÿ êàðòîé: ",0 -durakAIAttackText db "AI àòàêóåò: ",0 -durakPlayerTakeText db "Òû âçÿë êàðòó.",13,10,0 -durakPlayerDefendText db "Òû îòáèëñÿ.",13,10,0 -durakWinText db "Òû âûøåë èç èãðû áåç êàðò. Ïîáåäà!",13,10,0 -durakLoseText db "AI èçáàâèëñÿ îò êàðò ðàíüøå òåáÿ. Òû ïðîèãðàë.",13,10,0 -trainingTitle db 13,10,"--- Îáó÷åíèå ---",13,10,0 -trainingText db "Ãëàâíîå: ñíà÷àëà âûáåðè ñòàâêó. Åñëè áàíê óïàäåò äî 0, êàçèíî âûâåäåò òåáÿ.",13,10 - db "Ìàãàçèí: ðóáàøêè ìåíÿþò âèä çàêðûòûõ êàðò, òàëèñìàíû ìîãóò ñïàñòè ïðîèãðàííóþ ñòàâêó.",13,10 - db "21 / Î÷êî: áåðè êàðòû äî 21. Ïåðåáîð - ïîðàæåíèå. AI äîáèðàåò ïîñëå âñêðûòèÿ.",13,10 - db "Poker: ó òåáÿ 2 êàðòû, íà ñòîëå 3+1+1. Ìîæíî èãðàòü, ôîëäèòü è ïîâûøàòü ñòàâêó.",13,10 - db "CloverPit: ïîëå 5x3. Ïëàòÿò ðàçíûå ëèíèè è ôèãóðû èç îäèíàêîâûõ ñèìâîëîâ.",13,10 - db "×åðåïà: çàïîìíè, ãäå øàðèê, ïîòîì ñëåäè çà ïåðåìåøèâàíèåì ÷åðåïîâ.",13,10 - db "Ðóññêàÿ ðóëåòêà: Easy/Normal/Hard çàäàþò 1/2/3 îïàñíûå êàìåðû áàðàáàíà.",13,10 - db "Îðåë è ðåøêà: âûáåðè ñòîðîíó ìîíåòû è äîæäèñü ïàäåíèÿ.",13,10 - db "Êîñòè: óãàäàé ÷åòíîñòü ñóììû äâóõ êóáèêîâ.",13,10 - db "Êàçèíî-ðóëåòêà: ìîæíî ñòàâèòü íà ÷èñëî, öâåò, ÷åò/íå÷åò, äþæèíû, ïîëîâèíû è êîëîíêè.",13,10 - db "Slot machine: ñòàðàÿ 3x3 ñëîò-ìàøèíà ñ âûïàäåíèåì áàðàáàíîâ è ñðåäíåé ëèíèåé.",13,10 - db "Äóðàê: àòàêóé, ïîäêèäûâàé ñîâïàäàþùèå ðàíãè, îòáèâàéñÿ èëè ïåðåâîäè õîä.",13,10 - db "Êðþê: Skill Check: SPACE/ENTER ïî çåëåíîé çîíå. PERFECT äàåò äâîéíîé ïðîãðåññ.",13,10 - db "Buckshot Roulette: ñ÷èòàé æèâûå/õîëîñòûå, èñïîëüçóé ïðåäìåòû è âûáèðàé öåëü âûñòðåëà.",13,10 - db "Íàáëþäàòåëü: AI vs AI èãðàåò áåç òâîèõ ñòàâîê, ïðîñòî äëÿ ïðîñìîòðà.",13,10 - db "Äîñòèæåíèÿ è ñòàòèñòèêà ñîõðàíÿþòñÿ â àêêàóíò.",13,10,0 -durakDeckVisualText db "Êîëîäà: [ðóáàøêà], èç-ïîä íåå òîð÷èò êîçûðü ",0 -durakAIFaceText db 13,10,"Êàðòû AI:",13,10,0 -durakThrowAsk db "Ïîäêèíóòü êàðòó? 0 - áèòî: ",0 -durakTransferText db "Ïåðåâîä! Õîä ïåðåõîäèò îáðàòíî.",13,10,0 -durakTablePairsText db 13,10,"Êàðòû íà ñòîëå:",13,10,0 -durakSlashText db " / ",0 -durakUnbeatenText db " _ ",0 -durakStuckText db "Ïàðòèÿ çàøëà â òóïèê. Ñ÷èòàåì íè÷üþ.",13,10,0 -skullsTitle db 13,10,"--- ×åðåïà è øàðèê ---",13,10,0 -skullsIntroText db "Ñëåäè çà øàðèêîì. Âûïëàòà çà ïîáåäó: x2.",13,10,0 -skullsShowText db "Ñìîòðè âíèìàòåëüíî: øàðèê ñåé÷àñ çäåñü.",13,10,0 -skullsHideText db "×åðåïà çàêðûâàþò øàðèê...",13,10,0 -skullsShuffleText db "×åðåïà ñêîëüçÿò ïî ñòîëó...",13,10,0 -skullsGuessText db "Ãäå øàðèê? 1 / 2 / 3: ",0 -skullsWinText db "Âåðíî! Øàðèê íàéäåí.",13,10,0 -skullsLoseText db "Ìèìî. Øàðèê áûë ïîä äðóãèì ÷åðåïîì.",13,10,0 -skullsBallText db "Øàðèê áûë ïîä ÷åðåïîì ",0 -skullsSwap12Text db " \\______/",13,10," / \",13,10,0 -skullsSwap23Text db " \\______/",13,10," / \",13,10,0 -skullsSwap13Text db " \\____________________/",13,10," / \",13,10,0 -rouletteTitle db 13,10,"--- Ðóññêàÿ ðóëåòêà ---",13,10,0 -rrIntroText db "Áàðàáàí íà 6 êàìåð. Easy: 1 îïàñíàÿ, Normal: 2, Hard: 3.",13,10,"AI èãðàåò ñ òîáîé ïî î÷åðåäè. Êòî ïîïàë íà îïàñíóþ êàìåðó - ïðîèãðàë.",13,10,0 -rrDangerText db "Îïàñíûõ êàìåð â áàðàáàíå: ",0 -rrSpinText db "Áàðàáàí âðàùàåòñÿ... ",0 -rrSpin1 db "|",13,10,0 -rrSpin2 db "/",13,10,0 -rrSpin3 db "-",13,10,0 -rrSpin4 db "\\",13,10,0 -rrStartsPlayerText db "Ðåâîëüâåð îñòàíîâèëñÿ íà òåáå. Òû ñòðåëÿåøü ïåðâûì.",13,10,0 -rrStartsAIText db "Ðåâîëüâåð îñòàíîâèëñÿ íà AI. Îí ñòðåëÿåò ïåðâûì.",13,10,0 -rrPlayerTurnText db "Òâîé õîä. Íàæìè ëþáóþ êëàâèøó, ÷òîáû íàæàòü íà ñïóñê...",0 -rrAITurnText db "Õîä AI. Îí ïîäíèìàåò ðåâîëüâåð...",13,10,0 -rrClickText db "Ùåë÷îê. Ïóñòî.",13,10,0 -rrBangText db "ÁÀÕ!",13,10,0 -rrPlayerLoseText db "Òåáå íå ïîâåçëî. Ñòàâêà óõîäèò êàçèíî.",13,10,0 -rrAIShotText db "AI âûáûë. Òû ïåðåæèë ýòó ïàðòèþ.",13,10,0 -rrPayoutText db "Âûïëàòà ðóëåòêè çàâèñèò îò ñëîæíîñòè.",13,10,0 -buckshotTitle db 13,10,"--- Buckshot Roulette ---",13,10,0 -buckshotIntro db "Äðîáîâèê çàðÿæåí æèâûìè è õîëîñòûìè ïàòðîíàìè â íåèçâåñòíîì ïîðÿäêå.",13,10 - db "Ñòðåëÿé â ñåáÿ èëè AI. Õîëîñòîé â ñåáÿ îñòàâëÿåò õîä òåáå.",13,10 - db "Ëóïà ðàñêðûâàåò òåêóùèé ïàòðîí, ïèëà äàåò 2 óðîíà, ïèâî âûáðàñûâàåò ïàòðîí, íàðó÷íèêè ïðîïóñêàþò õîä AI.",13,10,0 -bsShotgunArt db 13,10 - db " ,_______________________________________________",13,10 - db " |_________________,----------._ [____] ""-,__",13,10 - db " (_(||||||||||||)___________/ ""--.__",13,10 - db " `----------' [ ))""-, \",13,10 - db " "" `--.__ |",13,10 - db " `----'",13,10 - db " DOUBLE BARREL CASINO",13,10,0 -bsShotgunLoad1 db 13,10 - db " ,_______________________________________________",13,10 - db " |_________________,----------._ [____] ""-,__",13,10 - db " (_(||||||||||||)___________/ ""--.__",13,10 - db " `----------' [ ))""-, \",13,10 - db " "" `--.__ |",13,10 - db " `----'",13,10 - db " Êðóïüå áåðåò äðîáîâèê ñî ñòîëà...",13,10,0 -bsShotgunLoad2 db 13,10 - db " ,_______________________________________________",13,10 - db " |_________________,----------._ [____] ""-,__",13,10 - db " (_(||||||||||||)______/__/ ""--.__",13,10 - db " `----------' / LIVE] ",13,10 - db " __/ BLANK] .__ |",13,10 - db " `----'",13,10 - db " Ñòâîë ïðèîòêðûò. Ïàòðîíû ó êàçåííîé ÷àñòè.",13,10,0 -bsShotgunLoad3 db 13,10 - db " ,_______________________________________________",13,10 - db " |_________________,----------._ [____] ""-,__",13,10 - db " (_(||||||||||||)___________/ ""--.__",13,10 - db " `----------' [ ))""-, \",13,10 - db " "" `--.__ |",13,10 - db " `----'",13,10 - db " ÙÅËÊ. Äðîáîâèê çàêðûò.",13,10,0 -bsShotgunFire db 13,10 - db " *** BOOM ***",13,10 - db " ,_______________________________________________ ***",13,10 - db " |_________________,----------._ [____] ""-,__ *****",13,10 - db " (_(||||||||||||)___________/ ""--.__ ***",13,10 - db " `----------' [ ))""-, \ *",13,10 - db " "" `--.__ |",13,10 - db " `----'",13,10,0 -bsShotgunDry db 13,10 - db " ,_______________________________________________",13,10 - db " |_________________,----------._ [____] ""-,__ click",13,10 - db " (_(||||||||||||)___________/ ""--.__",13,10 - db " `----------' [ ))""-, \",13,10 - db " "" `--.__ |",13,10 - db " `----'",13,10,0 -bsHPText db "HP: òû ",0 -bsAIHPText db " / AI ",0 -bsShellInfoText db "Ïàòðîíû â ðàóíäå: ",0 -bsLiveText db " æèâûõ, ",0 -bsBlankText db " õîëîñòûõ",13,10,0 -bsLeftText db "Îñòàëîñü â äðîáîâèêå: ",0 -bsKnownUnknownText db "Òåêóùèé ïàòðîí: íåèçâåñòíî",13,10,0 -bsKnownLiveText db "Òåêóùèé ïàòðîí: ÆÈÂÎÉ",13,10,0 -bsKnownBlankText db "Òåêóùèé ïàòðîí: õîëîñòîé",13,10,0 -bsItemsText db "Ïðåäìåòû: ëóïà ",0 -bsSawText db ", ïèëà ",0 -bsBeerText db ", ïèâî ",0 -bsCuffsText db ", íàðó÷íèêè ",0 -bsMenuText db 13,10,"1. Ñòðåëÿòü â ñåáÿ",13,10 - db "2. Ñòðåëÿòü â AI",13,10 - db "3. Ëóïà",13,10 - db "4. Ïèëà",13,10 - db "5. Ïèâî",13,10 - db "6. Íàðó÷íèêè",13,10 - db "Âûáîð: ",0 -bsLoadText db 13,10,"Êðóïüå çàðÿæàåò äðîáîâèê...",13,10,0 -bsLiveLoadedText db "Æèâîé ïàòðîí",13,10,0 -bsBlankLoadedText db "Õîëîñòîé ïàòðîí",13,10,0 -bsPlayerTurnText db 13,10,"Òâîé õîä.",13,10,0 -bsAITurnText db 13,10,"Õîä AI...",13,10,0 -bsShootPlayerText db "Âûñòðåë â òåáÿ.",13,10,0 -bsShootAIText db "Âûñòðåë â AI.",13,10,0 -bsDryText db "Ùåë÷îê. Õîëîñòîé.",13,10,0 -bsHitText db "ÁÀÕ! Óðîí: ",0 -bsGlassUseText db "Ëóïà ïîêàçûâàåò ïàòðîí.",13,10,0 -bsSawUseText db "Ïèëà íàäðåçàåò ñòâîë. Ñëåäóþùèé æèâîé âûñòðåë ñèëüíåå.",13,10,0 -bsBeerUseText db "Ïèâî. Ïàòðîí âûëåòàåò èç äðîáîâèêà: ",0 -bsCuffsUseText db "Íàðó÷íèêè çàùåëêíóëèñü. AI ïðîïóñòèò õîä.",13,10,0 -bsNoItemText db "Ýòîãî ïðåäìåòà íåò.",13,10,0 -bsAISawText db "AI èñïîëüçóåò ïèëó.",13,10,0 -bsAIGlassText db "AI ñìîòðèò ïàòðîí ÷åðåç ëóïó.",13,10,0 -bsAIBeerText db "AI âûáðàñûâàåò ïàòðîí ïèâîì.",13,10,0 -bsAICuffsText db "AI íàäåâàåò íà òåáÿ íàðó÷íèêè.",13,10,0 -bsSkipPlayerText db "Òû â íàðó÷íèêàõ è ïðîïóñêàåøü õîä.",13,10,0 -bsSkipAIText db "AI â íàðó÷íèêàõ è ïðîïóñêàåò õîä.",13,10,0 -bsWinText db "AI ïàäàåò. Òû çàáèðàåøü áàíê ñòîëà.",13,10,0 -bsLoseText db "Òû ïàäàåøü. Êðóïüå çàáèðàåò ñòàâêó.",13,10,0 -rrGunUp db 117,117,36,96,36,36,36,117,117,36,36,36,13,10 - - db 80,42,36,96,36,36,36,36,36,36,36,36,13,10 - - db 63,42,36,32,36,36,36,36,36,36,36,36,13,10 - - db 36,58,36,32,36,36,36,36,36,36,36,36,13,10 - - db 34,58,36,32,36,36,36,36,36,36,36,36,13,10 - - db 32,78,36,32,36,36,36,36,36,36,36,36,13,10 - - db 32,32,36,32,36,36,36,36,36,36,36,36,13,10 - - db 32,32,36,32,36,36,36,36,36,36,36,36,13,10 - - db 32,32,36,32,36,36,36,36,36,36,36,36,13,10 - - db 32,32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,36,36,82,82,36,36,36,36,36,36,13,10 - - db 32,32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,36,32,36,36,36,36,36,64,36,36,13,10 - - db 32,32,36,32,36,36,36,36,36,36,36,36,13,10 - - db 32,32,36,32,36,36,36,36,36,36,36,36,36,117,117,76,13,10 - - db 32,32,36,32,36,36,36,36,36,36,36,36,36,117,117,42,42,42,117,46,46,13,10 - - db 32,32,36,32,36,36,36,36,36,36,36,36,36,32,96,42,42,42,117,36,42,116,13,10 - - db 32,32,36,120,120,117,117,36,117,36,36,36,36,117,117,117,107,46,36,36,36,63,13,10 - - db 32,32,36,120,36,117,117,56,117,96,96,96,36,117,117,117,54,46,34,36,63,63,13,10 - - db 32,32,36,36,36,63,36,36,36,96,96,96,36,36,36,36,36,96,34,34,63,63,13,10 - - db 32,32,36,36,36,63,36,36,36,32,32,32,36,36,36,36,75,32,32,32,36,36,32,46,46,13,10 - - db 32,32,36,36,36,72,36,36,36,32,32,32,36,36,36,36,75,46,32,32,36,36,36,36,36,78,115,46,13,10 - - db 32,32,36,36,36,36,36,36,36,32,32,32,36,36,36,36,88,46,32,32,82,34,36,36,36,37,37,46,78,13,10 - - db 32,32,36,36,36,37,117,117,36,32,32,32,117,117,117,36,58,58,32,32,82,117,117,117,32,32,34,63,63,58,13,10 - - db 32,32,36,36,36,37,117,117,33,32,32,32,36,117,36,36,36,58,32,32,124,124,117,117,117,117,42,63,36,36,13,10 - - db 32,32,36,63,63,78,32,32,32,32,32,32,36,39,36,36,36,32,32,32,36,36,42,117,117,117,33,39,58,36,13,10 - - db 32,32,36,63,63,46,46,46,46,46,46,46,46,36,36,36,36,32,32,32,36,42,42,96,32,32,100,100,34,34,13,10 - - db 36,46,36,82,100,46,46,46,46,36,46,46,34,63,55,36,117,111,32,32,53,117,117,46,46,43,42,42,42,13,10 - - db 39,42,64,82,46,96,96,34,34,42,42,64,34,34,96,117,117,111,117,120,120,117,96,96,85,43,33,96,13,10 - - db 42,42,64,42,42,120,117,117,42,42,42,34,32,32,32,42,82,82,117,120,36,34,96,96,37,37,13,10 - - db 32,32,32,42,42,120,78,42,42,37,37,32,32,32,32,46,46,117,46,100,36,46,46,117,37,36,36,111,46,13,10 - - db 32,32,32,32,32,34,78,78,96,37,46,46,32,32,36,46,46,34,46,100,117,36,36,36,36,36,36,36,36,36,117,117 - - db 46,46,13,10 - - db 32,32,32,32,32,56,56,64,46,109,34,58,58,58,82,42,34,34,120,36,36,36,36,36,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,99,13,10 - - db 32,32,32,32,32,36,36,101,34,34,34,58,78,64,32,32,32,32,36,36,78,96,34,36,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,36,64,32,32,32,34,78,37,117,117,46,32,32,63,63,117,117,117,36,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,96,96,96,34,42,117,36,36,36,36,36,36,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,36,36,36,36,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,94,94,36,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,42,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,42,42,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,96 - - db 34,43,36,36,36,42,36,36,36,36,36,36,62,13,10 - - db 0 - -rrGunUpLeft db 32,32,32,32,32,32,32,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,99,13,10 - - db 32,32,32,32,32,32,36,36,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,62,13,10 - - db 32,32,32,32,32,117,32,36,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,62,13,10 - - db 32,32,32,32,36,36,36,36,36,36,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,62,62,13,10 - - db 32,32,32,36,32,36,36,36,32,36,36,32,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,46,32,78,58,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,32,36,62,13,10 - - db 32,32,36,32,36,36,32,36,36,36,32,36,36,32,32,32,32,32,32,32,32,32,32,32,32,46,116,32,32,32,32,32 - - db 32,32,115,46,63,32,36,32,32,32,32,32,32,32,32,32,32,36,32,36,36,36,32,36,36,32,36,62,13,10 - - db 32,36,96,36,36,36,36,36,36,36,36,36,36,36,36,32,32,32,32,32,32,32,32,32,46,36,36,63,63,32,32,46 - - db 36,78,37,34,63,36,36,34,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 - - db 117,32,36,32,32,36,36,36,32,36,36,32,36,36,36,32,32,32,32,32,32,32,32,42,117,32,36,63,32,63,32,36 - - db 32,36,32,32,42,39,34,32,32,32,32,32,32,32,46,36,36,32,36,36,32,36,36,36,32,36,36,32,36,13,10 - - db 80,42,36,36,32,36,36,36,36,36,36,36,36,36,36,36,36,32,32,32,117,76,42,42,46,36,36,34,63,36,36,36 - - db 36,117,117,117,33,100,42,42,32,32,32,32,117,46,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,63,58,32,36,32,32,36,36,36,32,36,36,32,36,36,32,36,32,117,32,117,42,32,107,46,34,32,32,36,32,34 - - db 117,32,117,117,32,32,42,96,32,32,32,117,32,36,36,32,36,36,32,36,36,36,32,36,36,32,36,13,10 - - db 32,32,36,58,32,36,32,36,32,36,36,32,36,36,36,32,36,36,32,36,117,32,96,117,54,32,96,32,32,32,82,117 - - db 32,117,117,32,32,43,33,32,32,46,32,36,36,32,36,36,36,32,36,36,32,36,36,36,32,36,13,10 - - db 32,32,34,32,78,36,36,32,36,36,36,36,36,36,36,64,36,36,36,36,36,32,117,117,36,36,75,46,32,32,32,124 - - db 124,36,42,96,46,85,37,32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,42,36,13,10 - - db 32,32,32,32,32,32,32,36,36,36,32,82,36,32,36,36,32,36,36,36,32,36,117,32,36,36,75,32,46,32,32,32 - - db 36,32,42,117,96,32,37,36,32,36,36,36,32,36,36,32,36,36,32,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,36,36,36,82,36,36,36,36,36,36,36,36,36,36,96,36,36,36,36,36,88,58,58,32,32 - - db 32,36,117,117,96,96,37,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,32,36,36,32,36,96,32,96,36,36,32,36,36,32,36,32,32 - - db 32,32,120,32,34,46,36,32,36,36,32,36,36,32,36,36,36,32,36,36,32,43,13,10 - - db 32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,36,36,36,117,96,96,96,32,32,36,36,117,36,36,36,36,111 - - db 32,117,120,36,46,36,36,36,36,36,36,36,36,36,36,36,36,36,36,96,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,36,32,32,36,36,32,117,56,36,32,32,32,32,32,117,117,32,36,36,32,117 - - db 111,32,117,100,117,32,36,34,32,36,36,36,32,36,36,32,36,36,32,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,32,117,117,32,36,36,32,32,32,32,32,36,39,32,36,36,117 - - db 32,82,46,32,100,36,96,32,117,36,32,36,36,32,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,36,36,120,120,36,63,36,36,36,36,36,32,32,32,36,46,36,55,96,42 - - db 82,46,34,46,36,36,117,117,36,36,36,36,36,36,36,42,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,120,32,36,63,36,32,36,36,32,32,32,46,32,34,34,32,32 - - db 46,32,46,34,36,32,63,36,32,36,36,36,32,42,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,117,117,33,32,46,46,46,64,34,32,32 - - db 36,46,34,32,32,63,36,36,36,36,94,94,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,37,32,117,32,46,32,36,42,32,34,32,32 - - db 32,82,32,32,32,117,36,32,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,37,32,32,46,46,42,32,42,32,32,32 - - db 58,32,32,46,42,32,32,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,63,46,46,46,34,42,42,37,46,46,58 - - db 78,64,117,96,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,63,32,63,46,96,32,117,42,32,37,34,58 - - db 32,37,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,63,100,46,120,117,42,78,96,109,34,34 - - db 78,32,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,82,32,42,120,78,32,64,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,32,64,42,42,32,34,56,32,101,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,39,42,64,32,42,32,56,36,36,64,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,42,32,32,32,32,32,32,36,13,10 - - db 0 - -rrGunLeft db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,99,62,62,62,62,62,62,62,62,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 46,36,36,36,36,36,36,36,36,36,43,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 46,36,36,36,36,36,36,36,36,36,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 117,36,36,36,36,36,36,36,36,36,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 117,36,36,36,36,36,36,36,36,36,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,58,36,36,34,32,32,32,32 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,78,63,36,58,34,42,32,32,46 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,46,63,63,39,100,42,96,32,111 - - db 36,36,36,36,36,36,36,36,36,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,115,37,34,42,33,100,42,33,32,36 - - db 36,36,36,36,36,36,36,36,36,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,78,37,32,117,117,32,43,43,37,36 - - db 36,36,36,36,36,36,36,36,36,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,36,36,32,117,117,32,46,85,37,37 - - db 36,36,36,36,36,36,36,36,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,36,36,117,117,117,96,46,96,96,117 - - db 36,36,36,36,36,36,36,36,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,117,117,42,42,117,96,96,46 - - db 36,36,34,117,36,36,36,94,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,116,63,63,63,36,36,34,117,124,36,42,117,117,34,46 - - db 36,36,96,117,36,36,36,94,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,42,36,63,63,36,36,82,82,124,36,36,53,120,36,36 - - db 117,36,78,117,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,36,36,36,34,32,32,32,32,32,32,32,32,120,120,100 - - db 100,36,36,63,36,36,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,117,117,36,34,34,32,32,32,32,32,32,32,32,117,117,46 - - db 46,120,36,63,36,36,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,42,42,46,46,96,32,46,46,58,58,32,32,111,111,82,117 - - db 34,34,32,32,117,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,42,42,107,54,36,75,75,88,58,36,36,36,117,117,82,46 - - db 46,34,32,32,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,76,42,42,117,117,36,36,36,36,36,36,36,36,36,117,42,46 - - db 46,42,32,46,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,117,117,96,117,117,36,36,36,36,117,36,36,36,55,96,32,32 - - db 36,82,32,117,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,117,117,32,117,117,36,36,36,36,117,117,39,36,63,34,32,32 - - db 32,58,64,117,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,117,36,36,46,34,34,32,32 - - db 32,58,78,37,96,13,10 - - db 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,96,96,32,32,32,32,32,32,46,46,64,34,32 - - db 46,58,58,78,13,10 - - db 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,96,96,32,32,32,32,32,32,46,46,42,42,37 - - db 46,34,34,34,13,10 - - db 36,36,36,36,36,36,36,36,36,36,36,36,36,64,36,36,36,36,36,96,96,32,32,32,32,32,32,46,36,42,42,37 - - db 37,109,34,13,10 - - db 117,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,117,117,36,36,36,36,36,33,32,46,46,34,42,42 - - db 96,46,34,13,10 - - db 117,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,56,36,36,36,36,117,117,32,46,46,34,117,42 - - db 78,64,101,13,10 - - db 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,117,117,36,36,36,36,117,117,32,46,46,96,117,78 - - db 78,56,36,64,13,10 - - db 36,36,36,36,36,36,36,36,36,36,36,82,36,36,36,36,36,36,117,117,63,63,72,36,37,37,78,46,46,96,120,120 - - db 34,56,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,36,82,36,36,36,36,36,36,120,36,36,36,36,36,36,36,63,63,100,46,42,42 - - db 13,10 - - db 96,96,32,32,32,32,32,32,32,36,36,36,36,32,32,32,32,32,120,120,36,36,36,36,36,36,63,63,82,82,42,42 - - db 13,10 - - db 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,64,64,13 - - db 10 - - db 117,42,42,58,58,78,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,42,42,13 - - db 10 - - db 117,80,63,36,34,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,39,42,13 - - db 10 - - db 0 - -rrGunDownLeft db 32,32,32,32,32,32,62,36,13,10 - - db 32,32,32,32,32,62,36,32,36,13,10 - - db 32,32,32,62,62,36,36,36,36,36,13,10 - - db 32,32,32,62,36,32,36,36,36,32,36,13,10 - - db 32,32,62,36,32,36,36,32,36,36,32,36,13,10 - - db 32,62,36,36,36,36,36,36,36,36,36,42,36,13,10 - - db 99,36,32,36,36,32,36,36,36,32,36,36,32,36,13,10 - - db 32,36,36,36,36,36,36,36,36,36,36,36,36,36,43,13,10 - - db 32,32,36,36,32,36,36,32,36,36,32,36,36,36,32,34,13,10 - - db 32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,96,96,13,10 - - db 32,32,32,32,36,32,36,36,36,32,36,36,32,36,36,36,13,10 - - db 32,32,32,32,32,36,36,32,36,36,32,36,36,36,32,36,36,13,10 - - db 32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,42,13,10 - - db 32,32,32,32,32,32,32,36,36,32,36,36,32,36,36,36,32,36,42,13,10 - - db 32,32,32,32,32,32,32,46,36,36,36,36,36,36,36,36,36,36,36,96,13,10 - - db 32,32,32,32,32,32,32,32,46,36,32,36,36,36,32,36,36,32,36,42,13,10 - - db 32,32,32,32,32,32,32,32,117,32,36,36,32,36,36,36,32,36,36,32,34,13,10 - - db 32,32,32,32,32,32,32,32,32,117,36,36,36,36,36,36,36,36,36,36,94,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,94,13,10 - - db 32,32,32,32,32,32,32,32,32,32,46,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,36,32,117,36,32,36,34,13,10 - - db 32,32,32,32,32,32,34,32,42,96,32,32,36,36,32,36,34,32,117,36,36,32,34,13,10 - - db 32,32,32,32,32,36,36,34,42,42,33,37,37,37,36,36,36,96,117,63,36,36,13,10 - - db 32,32,32,32,58,32,36,39,100,32,43,85,32,96,46,36,32,36,36,32,63,117,13,10 - - db 32,32,32,32,78,63,63,42,33,32,32,46,96,96,34,46,117,100,36,36,32,32,42,34,13,10 - - db 32,32,32,32,32,46,34,32,117,117,32,96,117,117,32,36,100,32,46,34,32,32,46,96,13,10 - - db 32,32,32,32,46,115,37,32,117,117,117,42,42,117,120,120,117,46,34,46,34,32,32,117,96,96,13,10 - - db 32,32,32,32,32,32,78,36,117,32,117,36,32,36,32,117,32,82,46,32,46,82,32,64,37,13,10 - - db 32,32,32,32,32,32,36,32,36,117,32,124,36,32,32,32,111,32,82,46,36,32,58,78,32,78,13,10 - - db 32,32,32,32,32,32,46,36,36,34,117,124,32,32,32,111,117,117,42,32,32,32,32,58,58,34,13,10 - - db 32,32,32,32,32,32,32,32,36,32,82,32,32,32,32,36,32,36,96,32,32,32,32,46,34,34,13,10 - - db 32,32,32,32,32,32,32,63,36,36,32,32,32,58,36,36,36,36,55,34,34,34,32,46,37,109,34,101,64,13,10 - - db 32,32,32,32,32,32,63,32,63,32,32,32,46,58,32,36,36,32,36,34,64,32,42,37,32,96,64,32,36,36,13,10 - - db 32,32,32,32,32,32,63,63,34,32,32,46,32,88,36,36,32,39,46,32,46,42,32,42,42,78,32,56,36,13,10 - - db 32,32,32,32,32,116,36,36,36,34,96,75,75,36,36,117,117,36,36,46,46,36,42,42,117,42,78,34,56,13,10 - - db 32,32,32,32,32,46,36,32,36,46,32,36,36,36,32,36,117,32,32,32,46,32,46,34,32,117,120,13,10 - - db 32,32,32,32,32,32,46,117,46,107,54,36,36,36,36,36,32,32,32,32,32,46,46,46,96,120,42,42,42,13,10 - - db 32,32,32,32,32,32,32,42,42,32,117,117,32,36,36,32,32,32,32,32,33,32,32,46,46,46,32,42,13,10 - - db 32,32,32,32,32,32,32,32,42,42,96,117,117,36,96,32,32,32,36,36,117,117,32,46,63,100,82,64,64,13,10 - - db 32,32,32,32,32,32,32,32,76,117,32,32,36,96,32,96,32,32,36,36,117,32,37,63,32,63,36,32,42,42,13,10 - - db 32,32,32,32,32,32,32,32,117,32,117,36,32,36,96,96,32,36,36,32,36,37,32,36,63,36,32,46,39,13,10 - - db 32,32,32,32,32,32,32,32,32,117,36,36,36,36,36,96,36,36,36,36,36,36,36,36,36,36,32,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,117,56,32,36,63,36,32,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,117,117,63,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,36,32,36,36,32,36,36,36,32,117,36,32,36,36,13,10 - - db 32,32,32,32,32,32,32,32,36,36,32,64,36,36,32,36,36,32,120,120,36,13,10 - - db 32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,120,36,36,13,10 - - db 32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,36,32,32,36,13,10 - - db 32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,32,36,36,13,10 - - db 32,32,32,36,32,36,36,32,36,36,32,36,82,36,32,32,36,13,10 - - db 32,32,32,36,36,32,36,36,36,32,36,36,32,82,36,36,13,10 - - db 32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,36,36,36,32,36,36,32,36,36,32,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,36,32,36,36,13,10 - - db 32,36,32,36,36,32,36,36,36,32,32,36,13,10 - - db 32,32,117,36,36,36,36,36,36,32,36,36,13,10 - - db 32,32,32,36,32,36,36,32,32,36,32,78,13,10 - - db 32,32,32,32,36,32,36,32,36,32,58,13,10 - - db 32,32,32,32,32,36,96,36,36,58,36,34,13,10 - - db 32,32,32,32,32,32,36,32,42,63,13,10 - - db 32,32,32,32,32,32,32,117,80,13,10 - - db 0 - -rrGunDown db 62,36,36,36,36,36,36,42,36,36,36,43,34,96,96,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,42,42,96,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,42,34,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,94,94,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,34,34,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,117,42,34,96,96 - - db 96,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,117,117,117,63,63,32,32,46,117,117 - - db 37,78,34,32,32,32,64,36,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,34,96,78,36,36,32,32,32,32,64 - - db 78,58,34,34,34,101,36,36,13,10 - - db 99,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,120,34,34,42,82,58 - - db 58,58,34,109,46,64,56,56,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,46,46,117,117,36,36,36,36,36,36,36,36,36,117,100,46,34,46,46,36,32 - - db 32,46,46,37,96,78,78,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,111,36,36,37,117,46,46,36,100,46,117,46,46,32,32 - - db 32,32,37,37,42,42,78,120,42,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,37,37,96,96,34,36,120,117,82,82,42,32,32 - - db 32,34,42,42,42,117,117,120,42,42,64,42,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,33,43,85,96,96,117,120,120,117,111,117,117,96,34 - - db 34,64,42,42,34,34,96,96,46,82,64,42,39,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,42,42,42,43,46,46,117,117,53,32,32,111,117,36,55,63 - - db 34,46,46,36,46,46,46,46,100,82,36,46,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,100,100,32,32,96,42,42,36,32,32,32,36,36,36,36 - - db 46,46,46,46,46,46,46,46,63,63,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,58,39,33,117,117,117,42,36,36,32,32,32,36,36,36,39 - - db 36,32,32,32,32,32,32,78,63,63,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,63,42,117,117,117,117,124,124,32,32,58,36,36,36,117 - - db 36,32,32,32,33,117,117,37,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,58,63,63,34,32,32,117,117,117,82,32,32,58,58,36,117,117 - - db 117,32,32,32,36,117,117,37,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,78,46,37,37,36,36,36,34,82,32,32,46,88,36,36,36 - - db 36,32,32,32,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,115,78,36,36,36,36,36,32,32,46,75,36,36,36 - - db 36,32,32,32,36,36,36,72,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,46,32,36,36,32,32,32,75,36,36,36 - - db 36,32,32,32,36,36,36,63,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,63,63,34,34,96,36,36,36,36 - - db 36,96,96,96,36,36,36,63,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,63,63,36,34,46,54,117,117,117 - - db 36,96,96,96,117,56,117,117,36,120,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,63,36,36,36,46,107,117,117,117 - - db 36,36,36,36,117,36,117,117,120,120,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,116,42,36,117,42,42,42,96,32 - - db 36,36,36,36,36,36,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,46,117,42,42,42,117,117 - - db 36,36,36,36,36,36,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,76,117,117 - - db 36,36,36,36,36,36,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,64,36,36,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,82,82,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,32,36,78,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,32,36,58,34,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,32,36,58,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,32,36,42,63,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,36,36,36,36,36,96,36,42,80,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,36,36,36,117,117,36,36,36,96,36,117,117,13,10 - - db 0 - -rrGunDownRight db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 36,32,32,32,32,32,32,42,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64 - - db 36,36,56,32,42,32,64,42,39,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,101 - - db 32,56,34,32,42,42,64,32,46,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34 - - db 64,32,78,120,42,32,82,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,32,78,34,34,109 - - db 96,78,42,117,120,46,100,63,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,37,32,58,34,37 - - db 32,42,117,32,96,46,63,32,63,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,96,117,64,78,58,46,46 - - db 37,42,42,34,46,46,46,63,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,32,32,42,46,32,32,58,32,32,32 - - db 42,32,42,46,46,32,32,37,32,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,32,36,117,32,32,32,82,32,32,32,34 - - db 32,42,36,32,46,32,117,32,37,36,32,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,94,94,36,36,36,36,63,32,32,34,46,36,32,32,34 - - db 64,46,46,46,32,33,117,117,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,42,32,36,36,36,32,36,63,32,36,34,46,32,46,32,32,34 - - db 34,32,46,32,32,32,36,36,32,36,63,36,32,120,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,42,42,36,36,36,36,36,36,36,117,117,36,36,46,34,46,82,42,96,55 - - db 36,46,36,32,32,32,36,36,36,36,36,63,36,120,120,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,117,32,96,36,100,32,46,82,32,117,36,36 - - db 32,39,36,32,32,32,32,32,36,36,32,117,117,32,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,96,32,36,36,32,36,36,32,36,36,36,32,34,36,32,117,100,117,32,111,117,32,36 - - db 36,32,117,117,32,32,32,32,32,36,56,117,32,36,36,32,32,36,13,10 - - db 32,32,32,32,32,32,32,32,34,96,36,36,36,36,36,36,36,36,36,36,36,36,36,36,46,36,120,117,32,111,36,36 - - db 36,36,117,36,36,32,32,96,96,96,117,36,36,36,36,36,36,32,36,36,13,10 - - db 32,32,32,32,32,32,32,43,32,36,36,32,36,36,36,32,36,36,32,36,36,32,36,46,34,32,120,32,32,32,32,36 - - db 32,36,36,32,36,36,96,32,96,36,32,36,36,32,36,36,36,32,36,36,13,10 - - db 32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,37,96,96,117,117,36,32,32,32,58 - - db 58,88,36,36,36,36,36,96,36,36,36,36,36,36,36,36,36,36,82,36,36,36,13,10 - - db 32,32,32,32,32,36,32,36,36,36,32,36,36,32,36,36,32,36,36,36,32,36,37,32,96,117,42,32,36,32,32,32 - - db 46,32,75,36,36,32,117,36,32,36,36,36,32,36,36,32,36,82,32,36,36,36,13,10 - - db 32,32,32,32,36,42,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,32,37,85,46,96,42,36,124,124,32,32 - - db 32,46,75,36,36,117,117,32,36,36,36,36,36,64,36,36,36,36,36,36,36,32,36,36,78,32,34,13,10 - - db 32,32,32,36,32,36,36,36,32,36,36,32,36,36,36,32,36,36,32,46,32,32,33,43,32,32,117,117,32,117,82,32 - - db 32,32,96,32,54,117,96,32,117,36,32,36,36,32,36,36,36,32,36,36,32,36,32,36,32,58,36,13,10 - - db 32,32,36,32,36,36,32,36,36,36,32,36,36,32,36,36,32,117,32,32,32,96,42,32,32,117,117,32,117,34,32,36 - - db 32,32,34,46,107,32,42,117,32,117,32,36,32,36,36,32,36,36,32,36,36,36,32,32,36,32,58,63,13,10 - - db 32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,46,117,32,32,32,32,42,42,100,33,117,117,117,36,36,36,36 - - db 63,34,36,36,46,42,42,76,117,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,32,36,36,42,80,13,10 - - db 36,32,36,36,32,36,36,36,32,36,36,32,36,36,46,32,32,32,32,32,32,32,34,39,42,32,32,36,32,36,32,63 - - db 32,63,36,32,117,42,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,36,32,32,36,32,117,13,10 - - db 62,36,36,36,36,36,36,36,36,36,36,36,36,32,32,32,32,32,32,32,32,34,36,36,63,34,37,78,36,46,32,32 - - db 63,63,36,36,46,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,96,36,13,10 - - db 32,62,36,32,36,36,32,36,36,36,32,36,32,32,32,32,32,32,32,32,32,32,36,32,63,46,115,32,32,32,32,32 - - db 32,32,116,46,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,32,36,36,32,36,13,10 - - db 32,32,62,36,32,36,36,36,32,36,36,32,32,32,32,32,32,32,32,32,32,32,32,58,78,32,46,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,32,36,36,36,32,36,13,10 - - db 32,32,62,62,36,36,36,36,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,62,36,32,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,117,13,10 - - db 32,32,32,32,32,62,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,13,10 - - db 32,32,32,32,32,32,99,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,13,10 - - db 0 - -rrGunRight db 32,32,32,32,32,32,32,32,32,32,32,32,42,39,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,32,34,36,63,80,117,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,42,42,46,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 - - db 32,32,32,32,32,78,58,58,42,42,117,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,64,64,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,42,42,82,82,63,63,36,36,36,36,36,36,120,120,32,32,32,32,32,36,36 - - db 36,36,32,32,32,32,32,32,32,96,96,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,42,42,46,100,63,63,36,36,36,36,36,36,36,120,36,36,36,36,36,36,82 - - db 36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,36,36,56,34,120,120,96,46,46,78,37,37,36,72,63,63,117,117,36,36,36,36,36,36,82 - - db 36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,64,36,56,78,78,117,96,46,46,32,117,117,36,36,36,36,117,117,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,101,64,78,42,117,34,46,46,32,117,117,36,36,36,36,56,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,117,13,10 - - db 32,32,32,32,32,32,32,32,34,46,96,42,42,34,46,46,32,33,36,36,36,36,36,117,117,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,117,13,10 - - db 32,32,32,32,32,32,32,32,34,109,37,37,42,42,36,46,32,32,32,32,32,32,96,96,36,36,36,36,36,64,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,34,34,34,46,37,42,42,46,46,32,32,32,32,32,32,96,96,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,78,58,58,46,32,34,64,46,46,32,32,32,32,32,32,96,96,36,36,36,36,36,36,36,36 - - db 36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,96,37,78,58,32,32,32,34,34,46,36,36,117,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,96,117,64,58,32,32,32,34,63,36,39,117,117,36,36,36,36,117,117,32,117,117,13,10 - - db 32,32,32,32,32,32,96,117,32,82,36,32,32,96,55,36,36,36,117,36,36,36,36,117,117,96,117,117,13,10 - - db 32,32,32,32,32,32,34,46,32,42,46,46,42,117,36,36,36,36,36,36,36,36,36,117,117,42,42,76,13,10 - - db 32,32,32,32,32,32,42,32,32,34,46,46,82,117,117,36,36,36,58,88,75,75,36,54,107,42,42,13,10 - - db 32,32,32,32,32,32,117,32,32,34,34,117,82,111,111,32,32,58,58,46,46,32,96,46,46,42,42,13,10 - - db 32,32,32,32,34,36,36,63,36,120,46,46,117,117,32,32,32,32,32,32,32,32,34,34,36,117,117,13,10 - - db 32,32,32,32,34,36,36,63,36,36,100,100,120,120,32,32,32,32,32,32,32,32,34,36,36,36,46,13,10 - - db 32,32,32,32,36,36,36,117,78,36,117,36,36,120,53,36,36,124,82,82,36,36,63,63,36,42,46,13,10 - - db 32,32,32,94,36,36,36,117,96,36,36,46,34,117,117,42,36,124,117,34,36,36,63,63,63,116,13,10 - - db 32,32,32,94,36,36,36,117,34,36,36,46,96,96,117,42,42,117,117,36,36,13,10 - - db 32,32,34,36,36,36,36,36,36,36,36,117,96,96,46,96,117,117,117,36,36,46,13,10 - - db 32,32,42,36,36,36,36,36,36,36,36,37,37,85,46,32,117,117,32,36,36,46,13,10 - - db 32,96,36,36,36,36,36,36,36,36,36,36,37,43,43,32,117,117,32,37,78,13,10 - - db 32,42,36,36,36,36,36,36,36,36,36,36,32,33,42,100,33,42,34,37,115,13,10 - - db 32,42,36,36,36,36,36,36,36,36,36,111,32,96,42,100,39,63,63,46,46,13,10 - - db 32,36,36,36,36,36,36,36,36,36,36,46,32,32,42,34,58,36,63,78,13,10 - - db 32,36,36,36,36,36,36,36,36,36,36,32,32,32,32,34,36,36,58,13,10 - - db 96,36,36,36,36,36,36,36,36,36,117,13,10 - - db 96,36,36,36,36,36,36,36,36,36,117,13,10 - - db 34,36,36,36,36,36,36,36,36,36,46,13,10 - - db 43,36,36,36,36,36,36,36,36,36,46,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 42,36,36,36,36,36,36,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 36,36,36,36,36,36,36,36,36,36,13,10 - - db 62,62,62,62,62,62,62,62,62,99,13,10 - - db 0 - -rrGunUpRight db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,80,117,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,63,42,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,36,58,36,36,96,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,58,32,36,32,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,78,32,36,32,32,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,36,36,36,117,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,32,36,36,36,32,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,32,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,82,32,36,36,32,36,36,36,32,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,32,36,82,36,32,36,36,32,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,36,32,32,36,36,36,32,36,36,32,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,36,36,120,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,36,120,120,32,36,36,32,36,36,64,32,36,36,13,10 - - db 32,32,32,32,32,32,32,32,36,36,32,36,117,32,36,36,36,32,36,36,32,36,13,10 - - db 32,32,32,32,32,32,36,36,36,36,36,63,117,117,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,36,36,32,36,63,36,32,56,117,32,36,36,36,13,10 - - db 32,36,32,32,36,36,36,36,36,36,36,36,36,36,96,36,36,36,36,36,117,13,10 - - db 32,39,46,32,36,63,36,32,37,36,32,36,36,32,96,96,36,32,36,117,32,117,13,10 - - db 42,42,32,36,63,32,63,37,32,117,36,36,32,32,96,32,96,36,32,32,117,76,13,10 - - db 32,64,64,82,100,63,46,32,117,117,36,36,32,32,32,96,36,117,117,96,42,42,13,10 - - db 32,32,42,32,46,46,46,32,32,33,32,32,32,32,32,36,36,32,117,117,32,42,42,13,10 - - db 32,42,42,42,120,96,46,46,46,32,32,32,32,32,36,36,36,36,36,54,107,46,117,46,13,10 - - db 32,32,32,120,117,32,34,46,32,46,32,32,32,117,36,32,36,36,36,32,46,36,32,36,46,13,10 - - db 32,56,34,78,42,117,42,42,36,46,46,36,36,117,117,36,36,75,75,96,34,36,36,36,116,13,10 - - db 32,36,56,32,78,42,42,32,42,46,32,46,39,32,36,36,88,32,46,32,32,34,63,63,13,10 - - db 36,36,32,64,96,32,37,42,32,64,34,36,32,36,36,32,58,46,32,32,32,63,32,63,13,10 - - db 32,64,101,34,109,37,46,32,34,34,34,55,36,36,36,36,58,32,32,32,36,36,63,13,10 - - db 32,32,32,32,34,34,46,32,32,32,32,96,36,32,36,32,32,32,32,82,32,36,13,10 - - db 32,32,32,32,34,58,58,32,32,32,32,42,117,117,111,32,32,32,124,117,34,36,36,46,13,10 - - db 32,32,32,32,78,32,78,58,32,36,46,82,32,111,32,32,32,36,124,32,117,36,32,36,13,10 - - db 32,32,32,32,32,37,64,32,82,46,32,46,82,32,117,32,36,32,36,117,32,117,36,78,13,10 - - db 32,32,32,32,96,96,117,32,32,34,46,34,46,117,120,120,117,42,42,117,117,117,32,37,115,46,13,10 - - db 32,32,32,32,32,32,96,46,32,32,34,46,32,100,36,32,117,117,96,32,117,117,32,34,46,13,10 - - db 32,32,32,32,32,32,34,42,32,32,36,36,100,117,46,34,96,96,46,32,32,33,42,63,63,78,13,10 - - db 32,32,32,32,32,32,32,32,117,63,32,36,36,32,36,46,96,32,85,43,32,100,39,36,32,58,13,10 - - db 32,32,32,32,32,32,32,32,36,36,63,117,96,36,36,36,37,37,37,33,42,42,34,36,36,13,10 - - db 32,32,32,32,32,32,32,34,32,36,36,117,32,34,36,32,36,36,32,32,96,42,32,34,13,10 - - db 32,32,32,32,32,32,32,32,34,36,32,36,117,32,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,46,13,10 - - db 32,32,32,32,32,32,32,32,32,94,36,36,32,36,36,32,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,94,36,36,36,36,36,36,36,36,36,36,117,13,10 - - db 32,32,32,32,32,32,32,32,32,34,32,36,36,32,36,36,36,32,36,36,32,117,13,10 - - db 32,32,32,32,32,32,32,32,32,32,42,36,32,36,36,32,36,36,36,32,36,46,13,10 - - db 32,32,32,32,32,32,32,32,32,32,96,36,36,36,36,36,36,36,36,36,36,36,46,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,42,36,32,36,36,36,32,36,36,32,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,42,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,32,36,36,32,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,36,32,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,96,96,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,32,36,36,36,32,36,36,32,36,36,32,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,43,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,32,36,36,36,32,36,36,32,36,99,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,42,36,36,36,36,36,36,36,36,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,32,36,36,32,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,36,32,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,62,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,62,13,10 - - db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,62,13,10 - - db 0 - -pokerReplaceText db "Ïîìåíÿòü êàðòó ",0 -pokerReplaceTail db "? (y/n): ",0 -pokerAIExchangeText db 13,10,"AI äóìàåò íàä îáìåíîì...",13,10,0 -pokerRevealText db 13,10,"AI âñêðûâàåò ïîêåðíóþ ðóêó...",13,10,0 -pokerYourComboText db "Òâîÿ êîìáèíàöèÿ: ",0 -pokerAIComboText db "Êîìáèíàöèÿ AI: ",0 -pokerTableText db 13,10,"Êàðòû íà ñòîëå:",13,10,0 -pokerHintText db "Ïîäñêàçêà: ñåé÷àñ ó òåáÿ ",0 -pokerDecisionText db "1 - èãðàòü, 2 - ïîâûñèòü ñòàâêó, 0 - ôîëä: ",0 -pokerPotText db "Áàíê ðàóíäà: $",0 -pokerBetText db "Òâîÿ òåêóùàÿ ñòàâêà: $",0 -pokerChipTitle db "Ôèøêè:",13,10,0 -pokerChipHigh db " [###]",13,10,0 -pokerChipMid db " [===]",13,10,0 -pokerChipLow db " [___]",13,10,0 -pokerRaiseAskText db "Íà ñêîëüêî ïîâûñèòü ñòàâêó: $",0 -pokerRaisedText db "Òû ïîâûñèë ñòàâêó. Íîâàÿ ñòàâêà: $",0 -pokerBadRaiseText db "Ïîâûøåíèå äîëæíî áûòü áîëüøå 0 è íå áîëüøå òâîåãî áàíêà.",13,10,0 -pokerAICallRaiseText db 13,10,"AI îòâå÷àåò íà ñòàâêó.",13,10,0 -pokerAIFoldRaiseText db 13,10,"AI íå ïðèíèìàåò ïîâûøåíèå è äåëàåò ôîëä. Òû âûèãðàë!",13,10,0 -pokerHardIntroText db "Hard Poker: îäèí ðàç ìîæíî çàìåíèòü îäíó êàðìàííóþ êàðòó.",13,10,0 -pokerHardExchangeText db "Çàìåíèòü êàðòó? 1 - ïåðâóþ, 2 - âòîðóþ, 0 - íå ìåíÿòü: ",0 -pokerHardAIExchangeText db 13,10,"AI ïåðåñìàòðèâàåò êàðìàííûå êàðòû...",13,10,0 -pokerAIRaiseText db 13,10,"AI ïîâûøàåò ñòàâêó íà $",0 -pokerCallRaiseText db "Îòâåòèòü? 1 - êîëë, 0 - ôîëä: ",0 -pokerPlayerCallText db "Òû îòâåòèë íà ïîâûøåíèå. Íîâàÿ ñòàâêà: $",0 -pokerFoldToRaiseText db 13,10,"Òû ñáðîñèë êàðòû ïîñëå ïîâûøåíèÿ AI.",13,10,"Òû ïðîèãðàë.",13,10,0 -pokerFoldText db 13,10,"Òû ñäåëàë ôîëä.",13,10,"Òû ïðîèãðàë.",13,10,0 -pokerAIFoldText db 13,10,"AI ñäåëàë ôîëä. Òû âûèãðàë!",13,10,0 -pokerNextCardText db 13,10,"Îòêðûâàåòñÿ ñëåäóþùàÿ êàðòà...",13,10,0 -pokerHighName db "Ñòàðøàÿ êàðòà",13,10,0 -pokerPairName db "Ïàðà",13,10,0 -pokerTwoPairName db "Äâå ïàðû",13,10,0 -pokerTripsName db "Òðîéêà",13,10,0 -pokerStraightName db "Ñòðèò",13,10,0 -pokerFlushName db "Ôëåø",13,10,0 -pokerFullHouseName db "Ôóëë õàóñ",13,10,0 -pokerFourName db "Êàðå",13,10,0 -pokerStraightFlushName db "Ñòðèò-ôëåø",13,10,0 - -; === Òåêñòû è ñèìâîëû ñëîò-ìàøèí === -slotPullText db "Êðóòèì áàðàáàíû...",13,10,0 -slotLeft db "[ ",0 -slotMid db " ] [ ",0 -slotRight db " ]",13,10,0 -slotJackpot db "Äæåêïîò!",13,10,0 -slotPair db "Êîìáèíàöèÿ ñûãðàëà!",13,10,0 -slotPayoutText db "Âûïëàòà x",0 -slotPayTableText db "Ñèìâîëû: LEM/CHR x2, CLV/BEL x3, DIA/BOX x5, 777 x7.",13,10 - db "Êîìáèíàöèè: Ãîð.M/Âåðò.M/Äèàã.M x1, Ãîð.L x2, Ãîð.XL x3",13,10 - db "Ââåðõ/Âíèç x4, Íåáî/Çåìëÿ x7, Ãëàç x8, Äæåêïîò x10.",13,10,0 -slotEmpty db "Íå ïîâåçëî.",13,10,0 -slotComboText db "Êîìáèíàöèÿ: ",0 -slotMultiplierText db "Ìíîæèòåëü: x",0 -slotTotalMultiplierText db "Èòîãîâûé ìíîæèòåëü: x",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 - -; === Ãðàôèêà êàðò: ðàìêè, ñòðîêè, ðóáàøêè è ïåðåâîðîò === -cardTop db 0E2h, 094h, 08Ch, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 090h, 13,10,0 -cardBottom db 0E2h, 094h, 094h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 098h, 13,10,0 -cardEmpty db 0E2h, 094h, 082h, " ", 0E2h, 094h, 082h, 13,10,0 -cardSuitLeft db 0E2h, 094h, 082h, " ", 0 -cardSuitRight db " ", 0E2h, 094h, 082h, 13,10,0 -cardRankOneL db 0E2h, 094h, 082h, " ", 0 -cardRankOneR db " ", 0E2h, 094h, 082h, 13,10,0 -cardRankTenL db 0E2h, 094h, 082h, " ", 0 -cardRankTenR db " ", 0E2h, 094h, 082h, 13,10,0 -cardCenterL db 0E2h, 094h, 082h, " ", 0 -cardCenterR db " ", 0E2h, 094h, 082h, 13,10,0 -cardTopSeg db 0E2h, 094h, 08Ch, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 090h, 0 -cardBottomSeg db 0E2h, 094h, 094h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 098h, 0 -cardEmptySeg db 0E2h, 094h, 082h, " ", 0E2h, 094h, 082h, 0 -cardBackSeg db 0E2h, 094h, 082h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 094h, 082h, 0 -cardBackBlueSeg db 0E2h, 094h, 082h, "~~*~~*~~*", 0E2h, 094h, 082h, 0 -cardBackRedSeg db 0E2h, 094h, 082h, "XX+XX+XX+", 0E2h, 094h, 082h, 0 -cardBackGoldSeg db 0E2h, 094h, 082h, "$*$*$*$*$", 0E2h, 094h, 082h, 0 -cardBackSkullSeg db 0E2h, 094h, 082h, "|o",0E2h,098h,0A0h," v ",0E2h,098h,0A0h,"o|", 0E2h, 094h, 082h, 0 -cardBackCloverSeg db 0E2h, 094h, 082h, "$+ ",0E2h,099h,0A3h,"$",0E2h,099h,0A3h," +$", 0E2h, 094h, 082h, 0 -backGray1 db 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 -backGray2 db 0E2h,094h,082h,"|#|#|#|#|",0E2h,094h,082h,0 -backGray3 db 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 -backGray4 db 0E2h,094h,082h,"|#|#|#|#|",0E2h,094h,082h,0 -backGray5 db 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 -backBlue1 db 0E2h,094h,082h,"\\==*==//",0E2h,094h,082h,0 -backBlue2 db 0E2h,094h,082h,"/ ___ /",0E2h,094h,082h,0 -backBlue3 db 0E2h,094h,082h,"| (@@@) |",0E2h,094h,082h,0 -backBlue4 db 0E2h,094h,082h,"/ ~~~ /",0E2h,094h,082h,0 -backBlue5 db 0E2h,094h,082h,"//==*==//",0E2h,094h,082h,0 -backRed1 db 0E2h,094h,082h,"ooooooooo",0E2h,094h,082h,0 -backRed2 db 0E2h,094h,082h,"oXXXxXXXo",0E2h,094h,082h,0 -backRed3 db 0E2h,094h,082h,"oXX---XXo",0E2h,094h,082h,0 -backRed4 db 0E2h,094h,082h,"oXXXxXXXo",0E2h,094h,082h,0 -backRed5 db 0E2h,094h,082h,"ooooooooo",0E2h,094h,082h,0 -backGold1 db 0E2h,094h,082h,"{$*$$$*$}",0E2h,094h,082h,0 -backGold2 db 0E2h,094h,082h,"*/^ $ ^/*",0E2h,094h,082h,0 -backGold3 db 0E2h,094h,082h,"$ <@@@> $",0E2h,094h,082h,0 -backGold4 db 0E2h,094h,082h,"*v/ $ /v*",0E2h,094h,082h,0 -backGold5 db 0E2h,094h,082h,"{$*$$$*$}",0E2h,094h,082h,0 -backSkull1 db 0E2h,094h,082h,"._.---._.",0E2h,094h,082h,0 -backSkull2 db 0E2h,094h,082h,"/,(o o),\",0E2h,094h,082h,0 -backSkull3 db 0E2h,094h,082h,"| ^ |",0E2h,094h,082h,0 -backSkull4 db 0E2h,094h,082h,"\ '-=-' /",0E2h,094h,082h,0 -backSkull5 db 0E2h,094h,082h,"~|==|==|~",0E2h,094h,082h,0 -backClover1 db 0E2h,094h,082h,"+o+$$$+o+",0E2h,094h,082h,0 -backClover2 db 0E2h,094h,082h,"o ",0E2h,098h,098h," + ",0E2h,098h,098h," o",0E2h,094h,082h,0 -backClover3 db 0E2h,094h,082h,"$+ ",0E2h,099h,0A3h,"$",0E2h,099h,0A3h," +$",0E2h,094h,082h,0 -backClover4 db 0E2h,094h,082h,"o ",0E2h,098h,098h," | ",0E2h,098h,098h," o",0E2h,094h,082h,0 -backClover5 db 0E2h,094h,082h,"+o+$$$+o+",0E2h,094h,082h,0 -backArcane1 db 0E2h,094h,082h,".~*~*~*~.",0E2h,094h,082h,0 -backArcane2 db 0E2h,094h,082h,"/__~_~__\",0E2h,094h,082h,0 -backArcane3 db 0E2h,094h,082h,"|_/\/\_ |",0E2h,094h,082h,0 -backArcane4 db 0E2h,094h,082h,"| \_/\_/|",0E2h,094h,082h,0 -backArcane5 db 0E2h,094h,082h,"'--===--'",0E2h,094h,082h,0 -backNoir1 db 0E2h,094h,082h,"((\\_//))",0E2h,094h,082h,0 -backNoir2 db 0E2h,094h,082h,"// | \\",0E2h,094h,082h,0 -backNoir3 db 0E2h,094h,082h,"--(#*#)--",0E2h,094h,082h,0 -backNoir4 db 0E2h,094h,082h,"\\__|__//",0E2h,094h,082h,0 -backNoir5 db 0E2h,094h,082h,"((//~\\))",0E2h,094h,082h,0 -backDiamond1 db 0E2h,094h,082h,"<><###><>",0E2h,094h,082h,0 -backDiamond2 db 0E2h,094h,082h,"/\ /\",0E2h,094h,082h,0 -backDiamond3 db 0E2h,094h,082h,"*$*",0E2h,094h,082h,0 -backDiamond4 db 0E2h,094h,082h,"\/ \/",0E2h,094h,082h,0 -backDiamond5 db 0E2h,094h,082h,"<><###><>",0E2h,094h,082h,0 -backRider1 db 0E2h,094h,082h,".oO===Oo.",0E2h,094h,082h,0 -backRider2 db 0E2h,094h,082h,"(/ .-. /)",0E2h,094h,082h,0 -backRider3 db 0E2h,094h,082h,"o-( @ )-o",0E2h,094h,082h,0 -backRider4 db 0E2h,094h,082h,"(/ '-' /)",0E2h,094h,082h,0 -backRider5 db 0E2h,094h,082h,"'oO===Oo'",0E2h,094h,082h,0 -backBee1 db 0E2h,094h,082h,"<>.<>.<>.",0E2h,094h,082h,0 -backBee2 db 0E2h,094h,082h,".<>.<><>.",0E2h,094h,082h,0 -backBee3 db 0E2h,094h,082h,"<> BEE <>",0E2h,094h,082h,0 -backBee4 db 0E2h,094h,082h,".<>.<><>.",0E2h,094h,082h,0 -backBee5 db 0E2h,094h,082h,"<>.<>.<>.",0E2h,094h,082h,0 -backFan1 db 0E2h,094h,082h,"\\|/\\|//",0E2h,094h,082h,0 -backFan2 db 0E2h,094h,082h," -\\|//- ",0E2h,094h,082h,0 -backFan3 db 0E2h,094h,082h,"<(( o ))>",0E2h,094h,082h,0 -backFan4 db 0E2h,094h,082h," -//|\\- ",0E2h,094h,082h,0 -backFan5 db 0E2h,094h,082h,"//|/|/|\\",0E2h,094h,082h,0 -backWeb1 db 0E2h,094h,082h,"\\..|..//",0E2h,094h,082h,0 -backWeb2 db 0E2h,094h,082h,".\\.|.//.",0E2h,094h,082h,0 -backWeb3 db 0E2h,094h,082h,"--(o-o)--",0E2h,094h,082h,0 -backWeb4 db 0E2h,094h,082h,".//|.|\\.",0E2h,094h,082h,0 -backWeb5 db 0E2h,094h,082h,"//''-''\\",0E2h,094h,082h,0 -cardFlipLeft db 0E2h, 094h, 082h, " \ ", 0E2h, 094h, 082h, 0 -cardFlipMid db 0E2h, 094h, 082h, " | ", 0E2h, 094h, 082h, 0 -cardFlipRight db 0E2h, 094h, 082h, " / ", 0E2h, 094h, 082h, 0 -cardSuitRightSeg db " ", 0E2h, 094h, 082h, 0 -cardRankOneRSeg db " ", 0E2h, 094h, 082h, 0 -cardRankTenRSeg db " ", 0E2h, 094h, 082h, 0 -cardCenterRSeg db " ", 0E2h, 094h, 082h, 0 -cardGap db " ",0 -revealText db 13,10,"AI âñêðûâàåò êàðòû...",13,10,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 - -suitSpades db 0E2h, 099h, 0A0h, 0 -suitHearts db 0E2h, 099h, 0A5h, 0 -suitClubs db 0E2h, 099h, 0A3h, 0 -suitDiamonds db 0E2h, 099h, 0A6h, 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 -suits dd OFFSET suitSpades, OFFSET suitHearts, OFFSET suitClubs, OFFSET suitDiamonds -pokerNames dd OFFSET pokerHighName, OFFSET pokerPairName, OFFSET pokerTwoPairName - dd OFFSET pokerTripsName, OFFSET pokerStraightName, OFFSET pokerFlushName - dd OFFSET pokerFullHouseName, OFFSET pokerFourName, OFFSET pokerStraightFlushName - -slot0 db "CLV",0 -slot1 db "LEM",0 -slot2 db "CHR",0 -slot3 db "BEL",0 -slot4 db "DIA",0 -slot5 db "BOX",0 -slot6 db "777",0 -slotSymbols dd OFFSET slot0, OFFSET slot1, OFFSET slot2 - dd OFFSET slot3, OFFSET slot4, OFFSET slot5, OFFSET slot6 -slotSymbolValues dd 3, 2, 2, 3, 5, 5, 7 -classicSlot0 db "7",0 -classicSlot1 db "BAR",0 -classicSlot2 db "$",0 -classicSlot3 db "*",0 -classicSlot4 db "#",0 -classicSlot5 db "A",0 -classicSlotSymbols dd OFFSET classicSlot0, OFFSET classicSlot1, OFFSET classicSlot2 - dd OFFSET classicSlot3, OFFSET classicSlot4, OFFSET classicSlot5 -classicSlotPayTableText db "Êëàññè÷åñêèé ñëîò 3x3. Âûèãðûøíàÿ ëèíèÿ - ñðåäíÿÿ.",13,10 - db "777 x10, $$$ x7, BAR x5, AAA x4, *** / ### x3, ïàðà x2.",13,10,0 -classicSlotJackpot db "Äæåêïîò! Òðè îäèíàêîâûõ.",13,10,0 -classicSlotPair db "Ïàðà íà ëèíèè!",13,10,0 -classicSlotEmpty db "Íå ïîâåçëî.",13,10,0 -classicSlotBorder db '+-----+-----+-----+',13,10,0 -classicSlotPayline db '----- WIN LINE -----',13,10,0 -; === MCI-êîìàíäû çâóêîâûõ ôàéëîâ === -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 -slotBorder db '+-----+-----+-----+-----+-----+',13,10,0 -slotWall db '|',0 -slotWinLeft db '>',0 -slotWinRight db '<',0 -slotCellBlank db ' ',0 -slotPadTwo db ' ',0 -slotPadOne db ' ',0 -skullSeg1 db 020h, 020h, 020h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 084h, 020h, 020h, 020h, 020h, 020h, 020h, 0 -skullSeg2 db 020h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 088h, 0E2h, 096h, 080h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 084h, 020h, 0E2h, 096h, 080h, 0E2h, 096h, 088h, 0E2h, 096h, 084h, 020h, 020h, 020h, 020h, 0 -skullSeg3 db 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 0 -skullSeg4 db 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 080h, 020h, 020h, 0E2h, 096h, 080h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 0 -skullSeg5 db 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 084h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 0 -skullSeg6 db 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 0E2h, 096h, 080h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 080h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 020h, 0 -skullSeg7 db 020h, 020h, 020h, 0E2h, 096h, 080h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 080h, 020h, 020h, 020h, 020h, 020h, 0 -skullSeg8 db 020h, 020h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 020h, 020h, 020h, 0 -skullNums db " [1] [2] [3]",13,10,0 -skullBlankBall db 13,10,13,10,13,10,0 -skullBall1 db " .***.",13,10," (* O *)",13,10," `***'",13,10,0 -skullBall2 db " .***.",13,10," (* O *)",13,10," `***'",13,10,0 -skullBall3 db " .***.",13,10," (* O *)",13,10," `***'",13,10,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 -saveExt db '.dat',0 -accountPattern db "*.dat",0 -appDataEnvName db "APPDATA",0 -appDataSubDir db "\AssemblerCasino",0 -pathSlashText db "\",0 -runtimeDir db "runtime",0 -danceFileName db "assets\animations\hakari_dance.ans",0 -casinoIntroFile db "assets\animations\casino_intro.ans",0 -dbdHookFileName db "assets\animations\dbd_hook.ans",0 -dbdHookCmd db "cmd /c start ""DBD Hook"" tools\previews\preview_dbd_hook.bat",0 -dbdHookStopFile db "runtime\dbd_hook.stop",0 -animProfileFile db "runtime\anim_profile.txt",0 -animProfileDigits db "012",0 -ansiExitIntro db 1Bh,"[0m",1Bh,"[?25h",1Bh,"[2J",1Bh,"[H",0 -accountList db 20 dup(64 dup(0)) -findData db 320 dup(0) - - -; --- Umamusume Pretty Derby Data --- -umaTitleText db 13,10,"=== UMAMUSUME PRETTY DERBY (ÑÊÀ×ÊÈ) ===",13,10,0 -umaMenuText db "Âûáåðèòå âàøó äåâ÷îíêó-ëîøàäêó:",13,10 - db "1. Special Week (Ñïåöèàë Óèê) - Êîýô. x4 (Ñáàëàíñèðîâàííàÿ)",13,10 - db "2. Silence Suzuka (Ñàéëåíñ Ñóäçóêà) - Êîýô. x3 (Ðåçâûé ñòàðò)",13,10 - db "3. Tokai Teio (Òîêàé Òýéîí) - Êîýô. x5 (Ôèíèøíûé ñïóðò)",13,10 - db "4. Gold Ship (Ãîëä Øèï) - Êîýô. x8 (Íåïðåäñêàçóåìàÿ!)",13,10 - db "5. Mejiro McQueen (Ìýäçèðî Ìàêêóèí) - Êîýô. x6 (Ñòàéåð)",13,10,0 -umaChoiceText db "Âàø âûáîð (1-5): ",0 -umaTrackHeader db 13,10,"--- ÒÐÀÑÑÀ ÒÐÈÓÌÔÀ ---",13,10,0 -umaFinishText db " |FINISH|",13,10,0 -umaHorse1Name db "1. Special Week : ",0 -umaHorse2Name db "2. Silence Suzuka : ",0 -umaHorse3Name db "3. Tokai Teio : ",0 -umaHorse4Name db "4. Gold Ship : ",0 -umaHorse5Name db "5. Mejiro McQueen : ",0 -umaWinAnnouncement db 13,10,"Ïîáåäèòåëü ñêà÷åê: ",0 -umaYouWinText db " ÏÎÁÅÄÀ! Âàø âûáîð ïðèøåë ïåðâûì! Âû âûèãðàëè $",0 -umaYouLoseText db " Óâû, âàø âûáîð íå çàíÿë 1-å ìåñòî. Óäà÷à óëûáíåòñÿ â ñëåäóþùèé ðàç!",13,10,0 -umaStepChar db "=",0 -umaHeadChar db ">",0 -umaHorseNames dd OFFSET umaHorse1Name, OFFSET umaHorse2Name, OFFSET umaHorse3Name, OFFSET umaHorse4Name, OFFSET umaHorse5Name -umaMultipliers dd 4, 3, 5, 8, 6 - -umaPos dd 5 dup(0) -umaChoice dd 0 -umaWinner dd 0 - -.code -; --- PrintStr: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -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: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -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: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -SetColor PROC attr:DWORD - invoke SetConsoleTextAttribute, hOut, attr - ret -SetColor ENDP - -; --- ResetColor: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -ResetColor PROC - invoke SetConsoleTextAttribute, hOut, COLOR_DEFAULT - ret -ResetColor ENDP - -; --- EnableAnsi: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -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 - -; --- SetSuitColor: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -SetSuitColor PROC suitIndex:DWORD - mov eax, suitIndex - cmp eax, 1 - je set_red_suit - cmp eax, 3 - je set_red_suit - invoke SetColor, COLOR_CARD - ret -set_red_suit: - invoke SetColor, COLOR_RED_CARD - ret -SetSuitColor ENDP - -; --- SetCardBackColor: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -SetCardBackColor PROC - mov eax, shopBackStyle - cmp eax, 1 - je card_back_blue - cmp eax, 2 - je card_back_red - cmp eax, 3 - je card_back_gold - cmp eax, 4 - je card_back_skull - cmp eax, 5 - je card_back_clover - cmp eax, 6 - je card_back_arcane - cmp eax, 7 - je card_back_noir - cmp eax, 8 - je card_back_diamond - cmp eax, 9 - je card_back_rider - cmp eax, 10 - je card_back_bee - cmp eax, 11 - je card_back_fan - cmp eax, 12 - je card_back_web - invoke SetColor, COLOR_BACK_CARD - ret -card_back_blue: - invoke SetColor, COLOR_TITLE - ret -card_back_red: - invoke SetColor, COLOR_BAD - ret -card_back_gold: - invoke SetColor, COLOR_WARN - ret -card_back_skull: - invoke SetColor, COLOR_BAD - ret -card_back_clover: - invoke SetColor, COLOR_MONEY - ret -card_back_arcane: - invoke SetColor, COLOR_TITLE - ret -card_back_noir: - invoke SetColor, COLOR_CARD - ret -card_back_diamond: - invoke SetColor, COLOR_TITLE - ret -card_back_rider: - invoke SetColor, COLOR_WARN - ret -card_back_bee: - invoke SetColor, COLOR_WARN - ret -card_back_fan: - invoke SetColor, COLOR_TITLE - ret -card_back_web: - invoke SetColor, COLOR_CARD - ret -SetCardBackColor ENDP -; --- PrintCardBackSegLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCardBackSegLine PROC lineNo:DWORD - mov eax, shopBackStyle - cmp eax, 1 - je back_line_blue - cmp eax, 2 - je back_line_red - cmp eax, 3 - je back_line_gold - cmp eax, 4 - je back_line_skull - cmp eax, 5 - je back_line_clover - cmp eax, 6 - je back_line_arcane - cmp eax, 7 - je back_line_noir - cmp eax, 8 - je back_line_diamond - cmp eax, 9 - je back_line_rider - cmp eax, 10 - je back_line_bee - cmp eax, 11 - je back_line_fan - cmp eax, 12 - je back_line_web -back_line_gray: - mov eax, lineNo - cmp eax, 1 - je back_gray_1 - cmp eax, 2 - je back_gray_2 - cmp eax, 3 - je back_gray_3 - cmp eax, 4 - je back_gray_4 - invoke PrintUtf8, OFFSET backGray5 - ret -back_gray_1: - invoke PrintUtf8, OFFSET backGray1 - ret -back_gray_2: - invoke PrintUtf8, OFFSET backGray2 - ret -back_gray_3: - invoke PrintUtf8, OFFSET backGray3 - ret -back_gray_4: - invoke PrintUtf8, OFFSET backGray4 - ret -back_line_blue: - mov eax, lineNo - cmp eax, 1 - je back_blue_1 - cmp eax, 2 - je back_blue_2 - cmp eax, 3 - je back_blue_3 - cmp eax, 4 - je back_blue_4 - invoke PrintUtf8, OFFSET backBlue5 - ret -back_blue_1: - invoke PrintUtf8, OFFSET backBlue1 - ret -back_blue_2: - invoke PrintUtf8, OFFSET backBlue2 - ret -back_blue_3: - invoke PrintUtf8, OFFSET backBlue3 - ret -back_blue_4: - invoke PrintUtf8, OFFSET backBlue4 - ret -back_line_red: - mov eax, lineNo - cmp eax, 1 - je back_red_1 - cmp eax, 2 - je back_red_2 - cmp eax, 3 - je back_red_3 - cmp eax, 4 - je back_red_4 - invoke PrintUtf8, OFFSET backRed5 - ret -back_red_1: - invoke PrintUtf8, OFFSET backRed1 - ret -back_red_2: - invoke PrintUtf8, OFFSET backRed2 - ret -back_red_3: - invoke PrintUtf8, OFFSET backRed3 - ret -back_red_4: - invoke PrintUtf8, OFFSET backRed4 - ret -back_line_gold: - mov eax, lineNo - cmp eax, 1 - je back_gold_1 - cmp eax, 2 - je back_gold_2 - cmp eax, 3 - je back_gold_3 - cmp eax, 4 - je back_gold_4 - invoke PrintUtf8, OFFSET backGold5 - ret -back_gold_1: - invoke PrintUtf8, OFFSET backGold1 - ret -back_gold_2: - invoke PrintUtf8, OFFSET backGold2 - ret -back_gold_3: - invoke PrintUtf8, OFFSET backGold3 - ret -back_gold_4: - invoke PrintUtf8, OFFSET backGold4 - ret -back_line_skull: - mov eax, lineNo - cmp eax, 1 - je back_skull_1 - cmp eax, 2 - je back_skull_2 - cmp eax, 3 - je back_skull_3 - cmp eax, 4 - je back_skull_4 - invoke PrintUtf8, OFFSET backSkull5 - ret -back_skull_1: - invoke PrintUtf8, OFFSET backSkull1 - ret -back_skull_2: - invoke PrintUtf8, OFFSET backSkull2 - ret -back_skull_3: - invoke PrintUtf8, OFFSET backSkull3 - ret -back_skull_4: - invoke PrintUtf8, OFFSET backSkull4 - ret -back_line_clover: - mov eax, lineNo - cmp eax, 1 - je back_clover_1 - cmp eax, 2 - je back_clover_2 - cmp eax, 3 - je back_clover_3 - cmp eax, 4 - je back_clover_4 - invoke PrintUtf8, OFFSET backClover5 - ret -back_clover_1: - invoke PrintUtf8, OFFSET backClover1 - ret -back_clover_2: - invoke PrintUtf8, OFFSET backClover2 - ret -back_clover_3: - invoke PrintUtf8, OFFSET backClover3 - ret -back_clover_4: - invoke PrintUtf8, OFFSET backClover4 - ret -back_line_arcane: - mov eax, lineNo - cmp eax, 1 - je back_arcane_1 - cmp eax, 2 - je back_arcane_2 - cmp eax, 3 - je back_arcane_3 - cmp eax, 4 - je back_arcane_4 - invoke PrintUtf8, OFFSET backArcane5 - ret -back_arcane_1: - invoke PrintUtf8, OFFSET backArcane1 - ret -back_arcane_2: - invoke PrintUtf8, OFFSET backArcane2 - ret -back_arcane_3: - invoke PrintUtf8, OFFSET backArcane3 - ret -back_arcane_4: - invoke PrintUtf8, OFFSET backArcane4 - ret -back_line_noir: - mov eax, lineNo - cmp eax, 1 - je back_noir_1 - cmp eax, 2 - je back_noir_2 - cmp eax, 3 - je back_noir_3 - cmp eax, 4 - je back_noir_4 - invoke PrintUtf8, OFFSET backNoir5 - ret -back_noir_1: - invoke PrintUtf8, OFFSET backNoir1 - ret -back_noir_2: - invoke PrintUtf8, OFFSET backNoir2 - ret -back_noir_3: - invoke PrintUtf8, OFFSET backNoir3 - ret -back_noir_4: - invoke PrintUtf8, OFFSET backNoir4 - ret -back_line_diamond: - mov eax, lineNo - cmp eax, 1 - je back_diamond_1 - cmp eax, 2 - je back_diamond_2 - cmp eax, 3 - je back_diamond_3 - cmp eax, 4 - je back_diamond_4 - invoke PrintUtf8, OFFSET backDiamond5 - ret -back_diamond_1: - invoke PrintUtf8, OFFSET backDiamond1 - ret -back_diamond_2: - invoke PrintUtf8, OFFSET backDiamond2 - ret -back_diamond_3: - invoke PrintUtf8, OFFSET backDiamond3 - ret -back_diamond_4: - invoke PrintUtf8, OFFSET backDiamond4 - ret -back_line_rider: - mov eax, lineNo - cmp eax, 1 - je back_rider_1 - cmp eax, 2 - je back_rider_2 - cmp eax, 3 - je back_rider_3 - cmp eax, 4 - je back_rider_4 - invoke PrintUtf8, OFFSET backRider5 - ret -back_rider_1: - invoke PrintUtf8, OFFSET backRider1 - ret -back_rider_2: - invoke PrintUtf8, OFFSET backRider2 - ret -back_rider_3: - invoke PrintUtf8, OFFSET backRider3 - ret -back_rider_4: - invoke PrintUtf8, OFFSET backRider4 - ret -back_line_bee: - mov eax, lineNo - cmp eax, 1 - je back_bee_1 - cmp eax, 2 - je back_bee_2 - cmp eax, 3 - je back_bee_3 - cmp eax, 4 - je back_bee_4 - invoke PrintUtf8, OFFSET backBee5 - ret -back_bee_1: - invoke PrintUtf8, OFFSET backBee1 - ret -back_bee_2: - invoke PrintUtf8, OFFSET backBee2 - ret -back_bee_3: - invoke PrintUtf8, OFFSET backBee3 - ret -back_bee_4: - invoke PrintUtf8, OFFSET backBee4 - ret -back_line_fan: - mov eax, lineNo - cmp eax, 1 - je back_fan_1 - cmp eax, 2 - je back_fan_2 - cmp eax, 3 - je back_fan_3 - cmp eax, 4 - je back_fan_4 - invoke PrintUtf8, OFFSET backFan5 - ret -back_fan_1: - invoke PrintUtf8, OFFSET backFan1 - ret -back_fan_2: - invoke PrintUtf8, OFFSET backFan2 - ret -back_fan_3: - invoke PrintUtf8, OFFSET backFan3 - ret -back_fan_4: - invoke PrintUtf8, OFFSET backFan4 - ret -back_line_web: - mov eax, lineNo - cmp eax, 1 - je back_web_1 - cmp eax, 2 - je back_web_2 - cmp eax, 3 - je back_web_3 - cmp eax, 4 - je back_web_4 - invoke PrintUtf8, OFFSET backWeb5 - ret -back_web_1: - invoke PrintUtf8, OFFSET backWeb1 - ret -back_web_2: - invoke PrintUtf8, OFFSET backWeb2 - ret -back_web_3: - invoke PrintUtf8, OFFSET backWeb3 - ret -back_web_4: - invoke PrintUtf8, OFFSET backWeb4 - ret -PrintCardBackSegLine ENDP - -; --- PrintCardBackSeg: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCardBackSeg PROC - invoke PrintCardBackSegLine, 3 - ret -PrintCardBackSeg ENDP - -; --- PrintSuit: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSuit PROC uses eax, suitIndex:DWORD - invoke SetSuitColor, suitIndex - mov eax, suitIndex - invoke PrintUtf8, suits[eax * 4] - call ResetColor - ret -PrintSuit ENDP - -; --- PrintMoney: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintMoney PROC value:DWORD - invoke SetColor, COLOR_MONEY - invoke PrintUInt, value - call ResetColor - ret -PrintMoney ENDP - -; --- PrintTitleColor: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintTitleColor PROC pText:DWORD - invoke SetColor, COLOR_TITLE - invoke PrintStr, pText - call ResetColor - ret -PrintTitleColor ENDP - -; --- ColorPrint: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -ColorPrint PROC pText:DWORD, attr:DWORD - invoke SetColor, attr - invoke PrintStr, pText - call ResetColor - ret -ColorPrint ENDP - -; --- PrintWinEvent: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintWinEvent PROC - invoke ColorPrint, OFFSET winText, COLOR_MONEY - ret -PrintWinEvent ENDP - -; --- PrintLoseEvent: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintLoseEvent PROC - invoke ColorPrint, OFFSET loseText, COLOR_BAD - ret -PrintLoseEvent ENDP - -; --- PrintDrawEvent: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintDrawEvent PROC - invoke ColorPrint, OFFSET drawText, COLOR_WARN - ret -PrintDrawEvent ENDP - -; --- PrintCroupierFromList: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCroupierFromList PROC uses eax ebx, pList:DWORD - invoke RandomRange, 3 - shl eax, 2 - mov ebx, pList - add ebx, eax - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET croupierPrefix - invoke PrintStr, DWORD PTR [ebx] - call ResetColor - ret -PrintCroupierFromList ENDP - -; --- DealerProcessLine: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -DealerProcessLine PROC uses eax edx - mov eax, dealerLineLen - cmp eax, 3 - jb dealer_process_done - mov al, byte ptr [frameBuffer] - cmp al, dealerWantedTag - jne dealer_process_done - cmp byte ptr [frameBuffer+1], '|' - jne dealer_process_done - cmp dealerScanMode, 0 - jne dealer_process_select - inc dealerPhraseCount - ret - -dealer_process_select: - mov eax, dealerPhraseCount - cmp eax, dealerPhrasePick - jne dealer_process_next - mov eax, OFFSET frameBuffer - add eax, dealerLineLen - mov byte ptr [eax], 0 - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET croupierPrefix - mov edx, OFFSET frameBuffer - add edx, 2 - invoke PrintStr, edx - invoke PrintStr, OFFSET nl - call ResetColor - mov dealerPhrasePick, 0FFFFFFFFh -dealer_process_next: - inc dealerPhraseCount -dealer_process_done: - ret -DealerProcessLine ENDP - -; --- DealerScanFile: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -DealerScanFile PROC uses eax edx, mode:DWORD - mov eax, mode - mov dealerScanMode, eax - mov dealerLineLen, 0 - invoke CreateFileA, OFFSET dealerFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 - cmp eax, INVALID_HANDLE_VALUE - jne dealer_scan_opened - xor eax, eax - ret - -dealer_scan_opened: - mov dealerFileHandle, eax - -dealer_scan_loop: - invoke ReadFile, dealerFileHandle, ADDR inputBuffer, 1, ADDR charsRead, 0 - cmp charsRead, 0 - je dealer_scan_eof - mov al, byte ptr inputBuffer - cmp al, 13 - je dealer_scan_loop - cmp al, 10 - je dealer_scan_line_end - mov edx, dealerLineLen - cmp edx, 32760 - jae dealer_scan_loop - mov byte ptr [frameBuffer + edx], al - inc dealerLineLen - jmp dealer_scan_loop - -dealer_scan_line_end: - call DealerProcessLine - mov dealerLineLen, 0 - jmp dealer_scan_loop - -dealer_scan_eof: - cmp dealerLineLen, 0 - je dealer_scan_close - call DealerProcessLine - -dealer_scan_close: - invoke CloseHandle, dealerFileHandle - mov eax, 1 - ret -DealerScanFile ENDP - -; --- PrintCroupierFromFile: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCroupierFromFile PROC uses eax, wanted:DWORD, pFallback:DWORD - mov eax, wanted - mov dealerWantedTag, al - mov dealerPhraseCount, 0 - invoke DealerScanFile, 0 - cmp eax, 0 - je croupier_file_fallback - cmp dealerPhraseCount, 0 - je croupier_file_fallback - invoke RandomRange, dealerPhraseCount - mov dealerPhrasePick, eax - mov dealerPhraseCount, 0 - invoke DealerScanFile, 1 - ret -croupier_file_fallback: - invoke PrintCroupierFromList, pFallback - ret -PrintCroupierFromFile ENDP - -; --- PrintCroupierWin: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCroupierWin PROC - invoke PrintCroupierFromFile, 'W', OFFSET croupierWinList - ret -PrintCroupierWin ENDP - -; --- PrintCroupierLose: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCroupierLose PROC - invoke PrintCroupierFromFile, 'L', OFFSET croupierLoseList - ret -PrintCroupierLose ENDP - -; --- PrintCroupierDraw: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCroupierDraw PROC - invoke PrintCroupierFromFile, 'D', OFFSET croupierDrawList - ret -PrintCroupierDraw ENDP - -; --- FlushFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -FlushFrame PROC uses eax ebx ecx edx esi edi - LOCAL csbi[22]:BYTE - LOCAL X_start:DWORD - LOCAL Y_start:DWORD - LOCAL nextLinePtr:DWORD - LOCAL currentLineIndex:DWORD - - cmp frameBytes, 0 - je flush_frame_done - - mov eax, OFFSET frameBuffer - add eax, frameBytes - mov byte ptr [eax], 0 - - cmp animWidth, 0 - je print_default - cmp animHeight, 0 - je print_default - - call ClearView - - lea eax, csbi - invoke GetConsoleScreenBufferInfo, hOut, eax - cmp eax, 0 - je print_default - - movzx ecx, word ptr csbi[14] - movzx esi, word ptr csbi[10] - sub ecx, esi - inc ecx - - movzx edx, word ptr csbi[16] - movzx esi, word ptr csbi[12] - sub edx, esi - inc edx - - mov eax, ecx - cmp eax, animWidth - jbe set_x_left - sub eax, animWidth - shr eax, 1 - add ax, word ptr csbi[10] - movzx eax, ax - mov X_start, eax - jmp x_calculated -set_x_left: - movzx eax, word ptr csbi[10] - mov X_start, eax -x_calculated: - - mov eax, edx - cmp eax, animHeight - jbe set_y_top - sub eax, animHeight - shr eax, 1 - add ax, word ptr csbi[12] - movzx eax, ax - mov Y_start, eax - jmp y_calculated -set_y_top: - movzx eax, word ptr csbi[12] - mov Y_start, eax -y_calculated: - - mov esi, OFFSET frameBuffer -skip_lead_loop: - cmp byte ptr [esi], 1Bh - jne check_lead_newline - cmp byte ptr [esi+1], '[' - jne check_lead_newline - - cmp byte ptr [esi+2], '2' - jne check_lead_H - cmp byte ptr [esi+3], 'J' - jne check_lead_newline - add esi, 4 - jmp skip_lead_loop - -check_lead_H: - cmp byte ptr [esi+2], 'H' - jne check_lead_hide - add esi, 3 - jmp skip_lead_loop - -check_lead_hide: - cmp byte ptr [esi+2], '?' - jne check_lead_newline - cmp byte ptr [esi+3], '2' - jne check_lead_newline - cmp byte ptr [esi+4], '5' - jne check_lead_newline - cmp byte ptr [esi+5], 'l' - jne check_lead_show - add esi, 6 - jmp skip_lead_loop - -check_lead_show: - cmp byte ptr [esi+5], 'h' - jne check_lead_newline - add esi, 6 - jmp skip_lead_loop - -check_lead_newline: - mov al, [esi] - cmp al, 0Dh - je skip_lead_nl_char - cmp al, 0Ah - je skip_lead_nl_char - jmp done_lead_skipping -skip_lead_nl_char: - inc esi - jmp skip_lead_loop -done_lead_skipping: - - mov currentLineIndex, 0 -line_parse_loop: - cmp byte ptr [esi], 0 - je print_done - - mov edi, esi -find_line_end: - mov al, [edi] - cmp al, 0 - je line_end_found - cmp al, 0Dh - je line_end_found - cmp al, 0Ah - je line_end_found - inc edi - jmp find_line_end -line_end_found: - mov dl, [edi] - mov byte ptr [edi], 0 - - mov ebx, edi - cmp dl, 0 - je next_line_ptr_done - inc ebx - mov al, [ebx] - cmp al, 0Dh - je skip_nl_chars - cmp al, 0Ah - je skip_nl_chars - jmp next_line_ptr_done -skip_nl_chars: - inc ebx - mov al, [ebx] - cmp al, 0Dh - je skip_nl_chars - cmp al, 0Ah - je skip_nl_chars -next_line_ptr_done: - mov nextLinePtr, ebx - - mov eax, currentLineIndex - add eax, Y_start - - movzx edx, word ptr csbi[16] - cmp eax, edx - jg skip_this_line - - invoke MoveCursor, X_start, eax - invoke PrintUtf8, esi - -skip_this_line: - mov esi, nextLinePtr - inc currentLineIndex - jmp line_parse_loop - -print_default: - invoke PrintUtf8, OFFSET frameBuffer - -print_done: - mov frameBytes, 0 -flush_frame_done: - ret -FlushFrame ENDP - -; --- PlayHakariDance: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayHakariDance PROC uses eax ebx ecx edx esi edi - mov animWidth, 118 - mov animHeight, 43 - invoke CreateFileA, OFFSET danceFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 - cmp eax, INVALID_HANDLE_VALUE - jne hakari_file_ok - invoke mciSendStringA, OFFSET hakariSoundStop, 0, 0, 0 - mov animWidth, 0 - mov animHeight, 0 - ret -hakari_file_ok: - mov danceHandle, eax - mov frameBytes, 0 - mov animFrameCounter, 0 - -hakari_read_loop: - invoke ReadFile, danceHandle, ADDR inputBuffer, 1, ADDR danceBytes, 0 - cmp danceBytes, 0 - je hakari_finish - mov al, byte ptr inputBuffer - cmp al, 0Ch - je hakari_show_frame - mov edx, frameBytes - cmp edx, 32760 - jae hakari_show_frame_keep_char - mov [frameBuffer + edx], al - inc frameBytes - jmp hakari_read_loop - -hakari_show_frame_keep_char: - call ClearView - call FlushFrame - invoke AnimFrameDelay, 12 - invoke Sleep, eax - mov al, byte ptr inputBuffer - mov [frameBuffer], al - mov frameBytes, 1 - jmp hakari_read_loop - -hakari_show_frame: - call AnimShouldDrawFrame - cmp eax, 1 - jne hakari_skip_frame - call ClearView - call FlushFrame - invoke AnimFrameDelay, 12 - invoke Sleep, eax - jmp hakari_read_loop -hakari_skip_frame: - mov frameBytes, 0 - jmp hakari_read_loop - -hakari_finish: - call ClearView - call FlushFrame - invoke CloseHandle, danceHandle - invoke mciSendStringA, OFFSET hakariSoundStop, 0, 0, 0 - invoke Sleep, 40 - call ClearView - mov animWidth, 0 - mov animHeight, 0 - ret -PlayHakariDance ENDP - -; --- WriteAnimProfileFile: shares animation profile with helper windows --- -WriteAnimProfileFile PROC uses eax ebx edx - invoke CreateFileA, OFFSET animProfileFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 - cmp eax, INVALID_HANDLE_VALUE - je write_anim_profile_done - mov ebx, eax - mov edx, settingsLowSpec - cmp edx, 2 - jbe write_anim_profile_value_ok - xor edx, edx -write_anim_profile_value_ok: - mov al, byte ptr [animProfileDigits + edx] - mov byte ptr [inputBuffer], al - invoke WriteFile, ebx, ADDR inputBuffer, 1, ADDR charsWritten, 0 - invoke CloseHandle, ebx -write_anim_profile_done: - ret -WriteAnimProfileFile ENDP -; --- PlayDbDHookScene: ïîêàäðîâàÿ àíèìàöèÿ êðþêà èç Dead by Daylight --- -PlayDbDHookScene PROC uses eax - cmp settingsDbdWindowEnabled, 1 - jne play_dbd_done - invoke WinExec, OFFSET dbdHookCmd, 1 -play_dbd_done: - ret -PlayDbDHookScene ENDP - -; --- StopDbDHookScene: çàêðûâàåò îòäåëüíîå îêíî DBD-àíèìàöèè ÷åðåç ôàéë-ñèãíàë --- -StopDbDHookScene PROC uses eax - invoke CreateFileA, OFFSET dbdHookStopFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 - cmp eax, INVALID_HANDLE_VALUE - je stop_dbd_done - invoke CloseHandle, eax -stop_dbd_done: - ret -StopDbDHookScene ENDP - -; --- IntroMaybeLoopMarker: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -IntroMaybeLoopMarker PROC - cmp frameBytes, 10 - jne intro_marker_no - cmp byte ptr [frameBuffer], '@' - jne intro_marker_no - cmp byte ptr [frameBuffer+1], '@' - jne intro_marker_no - cmp byte ptr [frameBuffer+2], 'L' - jne intro_marker_no - cmp byte ptr [frameBuffer+3], 'O' - jne intro_marker_no - cmp byte ptr [frameBuffer+4], 'O' - jne intro_marker_no - cmp byte ptr [frameBuffer+5], 'P' - jne intro_marker_no - cmp byte ptr [frameBuffer+6], '@' - jne intro_marker_no - cmp byte ptr [frameBuffer+7], '@' - jne intro_marker_no - mov introLoopSeen, 1 - mov introSkipLoop, 0 - mov frameBytes, 0 - mov eax, 1 - ret -intro_marker_no: - xor eax, eax - ret -IntroMaybeLoopMarker ENDP - -; --- IntroHandleFrameEnd: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -IntroHandleFrameEnd PROC - call IntroMaybeLoopMarker - cmp eax, 1 - je intro_handle_done - cmp introSkipLoop, 1 - je intro_discard_frame - call AnimShouldDrawFrame - cmp eax, 1 - jne intro_discard_frame - call FlushFrame - invoke AnimFrameDelay, 45 - invoke Sleep, eax - ret -intro_discard_frame: - mov frameBytes, 0 -intro_handle_done: - ret -IntroHandleFrameEnd ENDP - -; --- PlayCasinoIntro: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayCasinoIntro PROC uses eax ebx ecx edx esi edi - cmp settingsIntroEnabled, 1 - jne intro_disabled - mov introLoopSeen, 0 - mov introSkipLoop, 0 - mov animFrameCounter, 0 - mov animWidth, 64 - mov animHeight, 21 -intro_restart_file: - invoke CreateFileA, OFFSET casinoIntroFile, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 - cmp eax, INVALID_HANDLE_VALUE - jne intro_file_ok - mov animWidth, 0 - mov animHeight, 0 - ret -intro_file_ok: - mov danceHandle, eax - mov frameBytes, 0 - -intro_read_loop: - invoke GetAsyncKeyState, VK_RETURN - test ax, 8000h - jnz intro_exit - invoke ReadFile, danceHandle, ADDR inputBuffer, 1, ADDR danceBytes, 0 - cmp danceBytes, 0 - je intro_restart_cycle - mov al, byte ptr inputBuffer - cmp al, 0Ch - je intro_show_frame - mov edx, frameBytes - cmp edx, 32760 - jae intro_show_frame_keep_char - mov [frameBuffer + edx], al - inc frameBytes - jmp intro_read_loop - -intro_show_frame_keep_char: - call IntroHandleFrameEnd - mov al, byte ptr inputBuffer - mov [frameBuffer], al - mov frameBytes, 1 - jmp intro_read_loop - -intro_show_frame: - call IntroHandleFrameEnd - jmp intro_read_loop - -intro_restart_cycle: - call FlushFrame - invoke CloseHandle, danceHandle - cmp introLoopSeen, 1 - jne intro_restart_file - mov introSkipLoop, 1 - jmp intro_restart_file - -intro_exit: - invoke CloseHandle, danceHandle - invoke PrintUtf8, OFFSET ansiExitIntro - invoke Sleep, 180 -intro_disabled: - mov animWidth, 0 - mov animHeight, 0 - ret -PlayCasinoIntro ENDP -; --- InitSounds: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -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: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -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: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlaySlotSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET slotSoundStop, 0, 0, 0 - invoke mciSendStringA, OFFSET slotSoundPlay, 0, 0, 0 - ret -PlaySlotSound ENDP - -; --- PlaySlotIntroSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlaySlotIntroSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET slotIntroStop, 0, 0, 0 - invoke mciSendStringA, OFFSET slotIntroPlay, 0, 0, 0 - ret -PlaySlotIntroSound ENDP - -; --- PlayJackpotSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayJackpotSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET jackpotStop, 0, 0, 0 - invoke mciSendStringA, OFFSET jackpotPlay, 0, 0, 0 - ret -PlayJackpotSound ENDP - -; --- PlayHakariSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayHakariSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET hakariSoundStop, 0, 0, 0 - invoke mciSendStringA, OFFSET hakariSoundPlay, 0, 0, 0 - ret -PlayHakariSound ENDP - -; --- PlayCoinSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayCoinSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET coinSoundStop, 0, 0, 0 - invoke mciSendStringA, OFFSET coinSoundPlay, 0, 0, 0 - ret -PlayCoinSound ENDP - -; --- PlayBankruptSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayBankruptSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET bankruptStop, 0, 0, 0 - invoke mciSendStringA, OFFSET bankruptPlay, 0, 0, 0 - ret -PlayBankruptSound ENDP - -; --- PlayVictorySound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayVictorySound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET victoryStop, 0, 0, 0 - invoke mciSendStringA, OFFSET victoryPlay, 0, 0, 0 - ret -PlayVictorySound ENDP - -; --- PlayCasinoRouletteSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayCasinoRouletteSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET casinoRouletteSoundStop, 0, 0, 0 - invoke mciSendStringA, OFFSET casinoRouletteSoundPlay, 0, 0, 0 - ret -PlayCasinoRouletteSound ENDP -; --- PlayRouletteSpinSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayRouletteSpinSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET rrSpinStop, 0, 0, 0 - invoke mciSendStringA, OFFSET rrSpinPlay, 0, 0, 0 - ret -PlayRouletteSpinSound ENDP - -; --- PlayRouletteDrySound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayRouletteDrySound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET rrDryStop, 0, 0, 0 - invoke mciSendStringA, OFFSET rrDryPlay, 0, 0, 0 - ret -PlayRouletteDrySound ENDP - -; --- PlayRouletteShotSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayRouletteShotSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET rrShotStop, 0, 0, 0 - invoke mciSendStringA, OFFSET rrShotPlay, 0, 0, 0 - ret -PlayRouletteShotSound ENDP - -; --- PlayStoneSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayStoneSound PROC uses eax ecx edx - invoke mciSendStringA, OFFSET stoneSoundStop, 0, 0, 0 - invoke mciSendStringA, OFFSET stoneSoundPlay, 0, 0, 0 - ret -PlayStoneSound ENDP - -; --- StopTowerMusic: ìóçûêà òóðíèð-áàøíè --- -StopTowerMusic PROC - invoke mciSendStringA, OFFSET towerMusicStop, 0, 0, 0 - invoke mciSendStringA, OFFSET towerMusicClose, 0, 0, 0 - ret -StopTowerMusic ENDP - -; --- PlayTowerRandomMusic: ñëó÷àéíàÿ ìóçûêà òóðíèð-áàøíè --- -PlayTowerRandomMusic PROC uses eax - call StopTowerMusic - invoke RandomRange, 4 - cmp eax, 0 - je tower_music_1 - cmp eax, 1 - je tower_music_2 - cmp eax, 2 - je tower_music_3 -tower_music_4: - invoke mciSendStringA, OFFSET towerMusicOpen4, 0, 0, 0 - jmp tower_music_play -tower_music_1: - invoke mciSendStringA, OFFSET towerMusicOpen1, 0, 0, 0 - jmp tower_music_play -tower_music_2: - invoke mciSendStringA, OFFSET towerMusicOpen2, 0, 0, 0 - jmp tower_music_play -tower_music_3: - invoke mciSendStringA, OFFSET towerMusicOpen3, 0, 0, 0 -tower_music_play: - invoke mciSendStringA, OFFSET towerMusicPlay, 0, 0, 0 - ret -PlayTowerRandomMusic ENDP - -; --- PrintSlotCell: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSlotCell PROC uses eax ebx ecx, value:DWORD - invoke PrintStr, OFFSET slotWall - mov eax, slotCurrentCell - mov ebx, 1 - mov ecx, eax - shl ebx, cl - mov eax, slotWinMask - test eax, ebx - je slot_cell_normal - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET slotWinLeft - invoke PrintSlotSymbol, value - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET slotWinRight - call ResetColor - ret -slot_cell_normal: - invoke PrintStr, OFFSET slotPadOne - invoke PrintSlotSymbol, value - invoke PrintStr, OFFSET slotPadOne - ret -PrintSlotCell ENDP -; --- PrintSlotBlankCell: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSlotBlankCell PROC - invoke PrintStr, OFFSET slotWall - invoke PrintStr, OFFSET slotCellBlank - ret -PrintSlotBlankCell ENDP - -; --- PrintSlotPaddingRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSlotPaddingRow PROC - call PrintSlotBlankCell - call PrintSlotBlankCell - call PrintSlotBlankCell - call PrintSlotBlankCell - call PrintSlotBlankCell - invoke PrintStr, OFFSET slotWall - invoke PrintStr, OFFSET nl - ret -PrintSlotPaddingRow ENDP -; --- PrintSlotWindow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSlotWindow PROC uses eax ebx - call ClearView - invoke PrintTitleColor, OFFSET slotTitle - invoke PrintStr, OFFSET slotBorder - - mov rowIndex, 0 -slot_window_row_loop: - cmp rowIndex, 3 - jae slot_window_done - call PrintSlotPaddingRow - mov ebx, rowIndex - imul ebx, 5 - - cmp slotVisible, 1 - jb slot_blank_col1 - mov slotCurrentCell, ebx - invoke PrintSlotCell, slotGrid[ebx * 4] - jmp slot_col2 -slot_blank_col1: - call PrintSlotBlankCell - -slot_col2: - cmp slotVisible, 2 - jb slot_blank_col2 - mov eax, ebx - inc eax - mov slotCurrentCell, eax - invoke PrintSlotCell, slotGrid[eax * 4] - jmp slot_col3 -slot_blank_col2: - call PrintSlotBlankCell - -slot_col3: - cmp slotVisible, 3 - jb slot_blank_col3 - mov eax, ebx - add eax, 2 - mov slotCurrentCell, eax - invoke PrintSlotCell, slotGrid[eax * 4] - jmp slot_col4 -slot_blank_col3: - call PrintSlotBlankCell - -slot_col4: - cmp slotVisible, 4 - jb slot_blank_col4 - mov eax, ebx - add eax, 3 - mov slotCurrentCell, eax - invoke PrintSlotCell, slotGrid[eax * 4] - jmp slot_col5 -slot_blank_col4: - call PrintSlotBlankCell - -slot_col5: - cmp slotVisible, 5 - jb slot_blank_col5 - mov eax, ebx - add eax, 4 - mov slotCurrentCell, eax - invoke PrintSlotCell, slotGrid[eax * 4] - jmp slot_row_end -slot_blank_col5: - call PrintSlotBlankCell - -slot_row_end: - invoke PrintStr, OFFSET slotWall - invoke PrintStr, OFFSET nl - call PrintSlotPaddingRow - invoke PrintStr, OFFSET slotBorder - inc rowIndex - jmp slot_window_row_loop - -slot_window_done: - ret -PrintSlotWindow ENDP - -; --- FillSlotColumn: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -FillSlotColumn PROC uses eax ebx, column:DWORD - mov ebx, column - invoke RandomRange, 7 - mov slotGrid[ebx * 4], eax - mov ebx, column - add ebx, 5 - invoke RandomRange, 7 - mov slotGrid[ebx * 4], eax - mov ebx, column - add ebx, 10 - invoke RandomRange, 7 - mov slotGrid[ebx * 4], eax - ret -FillSlotColumn ENDP -; --- PrintUInt: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -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: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- -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 - -; --- ReadAnyKey: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- -ReadAnyKey PROC -read_any_again: - invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 - cmp charsRead, 0 - je read_any_empty - movzx eax, byte ptr inputBuffer - ret -read_any_empty: - xor eax, eax - ret -ReadAnyKey ENDP - -; --- ReadUInt: ââîä ÷èñëà îäíîé ñòðîêîé, áåç çàâèñàíèÿ íà CR/LF --- -ReadUInt PROC uses ebx ecx edx esi edi - xor ebx, ebx ; parsed number - xor edi, edi ; digit count - invoke ReadFile, hIn, ADDR inputBuffer, 31, ADDR charsRead, 0 - cmp charsRead, 0 - je read_uint_zero - - mov esi, OFFSET inputBuffer - mov ecx, charsRead -read_uint_parse_loop: - cmp ecx, 0 - je read_uint_end - movzx eax, byte ptr [esi] - inc esi - dec ecx - cmp al, 13 - je read_uint_end - cmp al, 10 - je read_uint_end - cmp al, ' ' - je read_uint_parse_loop - cmp al, 9 - je read_uint_parse_loop - cmp al, '0' - jb read_uint_bad - cmp al, '9' - ja read_uint_bad - - sub al, '0' - movzx edx, al - mov eax, ebx - imul eax, eax, 10 - add eax, edx - mov ebx, eax - inc edi - jmp read_uint_parse_loop - -read_uint_end: - cmp edi, 0 - je read_uint_zero - mov eax, ebx - ret - -read_uint_bad: - xor eax, eax - ret - -read_uint_zero: - xor eax, eax - ret -ReadUInt ENDP - -; --- StrEqual: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- -StrEqual PROC uses esi edi ebx, pLeft:DWORD, pRight:DWORD - mov esi, pLeft - mov edi, pRight -str_equal_loop: - mov al, [esi] - mov bl, [edi] - cmp al, bl - jne str_not_equal - cmp al, 0 - je str_is_equal - inc esi - inc edi - jmp str_equal_loop -str_is_equal: - mov eax, 1 - ret -str_not_equal: - xor eax, eax - ret -StrEqual ENDP - -; --- PrintCheatApplied: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCheatApplied PROC pText:DWORD - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET cheatAppliedText - invoke PrintStr, pText - call ResetColor - ret -PrintCheatApplied ENDP - -; --- ApplyCheatCode: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -ApplyCheatCode PROC pCode:DWORD - invoke StrEqual, pCode, OFFSET cheatCodeMoney - cmp eax, 1 - je cheat_money - invoke StrEqual, pCode, OFFSET cheatCodeSeven - cmp eax, 1 - je cheat_sevens - invoke StrEqual, pCode, OFFSET cheatCodeWin - cmp eax, 1 - je cheat_win_next - invoke StrEqual, pCode, OFFSET cheatCodeGod - cmp eax, 1 - je cheat_god - invoke StrEqual, pCode, OFFSET cheatCodeFair - cmp eax, 1 - je cheat_fair - invoke StrEqual, pCode, OFFSET cheatCodeGoal - cmp eax, 1 - je cheat_goal - invoke StrEqual, pCode, OFFSET cheatCodeReset - cmp eax, 1 - je cheat_reset - invoke StrEqual, pCode, OFFSET cheatCodeEasy - cmp eax, 1 - je cheat_easy - invoke StrEqual, pCode, OFFSET cheatCodeNormal - cmp eax, 1 - je cheat_normal - invoke StrEqual, pCode, OFFSET cheatCodeHard - cmp eax, 1 - je cheat_hard - invoke StrEqual, pCode, OFFSET cheatCodeJackpot - cmp eax, 1 - je cheat_jackpot - invoke StrEqual, pCode, OFFSET cheatCodeRich - cmp eax, 1 - je cheat_rich - invoke StrEqual, pCode, OFFSET cheatCodeDouble - cmp eax, 1 - je cheat_double - invoke StrEqual, pCode, OFFSET cheatCodePoor - cmp eax, 1 - je cheat_poor - invoke StrEqual, pCode, OFFSET cheatCodeShop - cmp eax, 1 - je cheat_shop - invoke StrEqual, pCode, OFFSET cheatCodeBacks - cmp eax, 1 - je cheat_backs - invoke StrEqual, pCode, OFFSET cheatCodeCharm - cmp eax, 1 - je cheat_max_charm - invoke StrEqual, pCode, OFFSET cheatCodeNoCharm - cmp eax, 1 - je cheat_no_charm - invoke StrEqual, pCode, OFFSET cheatCodeAch - cmp eax, 1 - je cheat_ach - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET cheatBadText - call ResetColor - xor eax, eax - ret - -cheat_money: - add bankroll, 50000 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatMoneyText - call PrintBank - call CheckVictory - mov eax, 1 - ret -cheat_sevens: - add bankroll, 7777 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatSevenText - call PrintBank - call CheckVictory - mov eax, 1 - ret -cheat_win_next: - mov cheatLuckyWin, 1 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatWinText - mov eax, 1 - ret -cheat_god: - mov cheatGodMode, 1 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatGodText - mov eax, 1 - ret -cheat_fair: - mov cheatLuckyWin, 0 - mov cheatGodMode, 0 - mov casinoSuspicion, 0 - call SaveGame - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET cheatAppliedText - invoke PrintStr, OFFSET cheatFairText - call ResetColor - mov eax, 1 - ret -cheat_goal: - mov eax, targetBank - mov bankroll, eax - call SaveGame - invoke PrintCheatApplied, OFFSET cheatGoalText - call PrintBank - call CheckVictory - mov eax, 1 - ret -cheat_reset: - mov bankroll, 10000 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatResetText - call PrintBank - mov eax, 1 - ret -cheat_easy: - mov aiDifficulty, 1 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatEasyText - mov eax, 1 - ret -cheat_normal: - mov aiDifficulty, 2 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatNormalText - mov eax, 1 - ret -cheat_hard: - mov aiDifficulty, 3 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatHardText - mov eax, 1 - ret -cheat_jackpot: - mov cheatSlotJackpot, 1 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatJackpotText - mov eax, 1 - ret -cheat_rich: - add bankroll, 250000 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatRichText - call PrintBank - call CheckVictory - mov eax, 1 - ret -cheat_double: - mov eax, bankroll - add bankroll, eax - call SaveGame - invoke PrintCheatApplied, OFFSET cheatDoubleText - call PrintBank - call CheckVictory - mov eax, 1 - ret -cheat_poor: - mov bankroll, 1 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatPoorText - call PrintBank - mov eax, 1 - ret -cheat_shop: - add bankroll, 30000 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatShopText - call PrintBank - call CheckVictory - mov eax, 1 - ret -cheat_backs: - mov shopBackOwned, 1FFFh - call SaveGame - invoke PrintCheatApplied, OFFSET cheatBacksText - mov eax, 1 - ret -cheat_max_charm: - mov shopCharmLevel, 5 - mov shopCharmUses, 1 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatCharmText - mov eax, 1 - ret -cheat_no_charm: - mov shopCharmLevel, 0 - call SaveGame - invoke PrintCheatApplied, OFFSET cheatNoCharmText - mov eax, 1 - ret -cheat_ach: - mov achievements, 7FFFFh - call SaveGame - invoke PrintCheatApplied, OFFSET cheatAchText - mov eax, 1 - ret -ApplyCheatCode ENDP - -; --- ReadBetInput: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- -ReadBetInput PROC uses ebx ecx edx esi edi - mov ecx, 32 - mov edi, OFFSET cheatBuffer - xor eax, eax - rep stosb - - xor ebx, ebx ; parsed numeric bet - xor esi, esi ; stored input length - xor edi, edi ; 0 = number, 1 = cheat/code -read_bet_loop: - invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 - cmp charsRead, 0 - je read_bet_finish - movzx eax, byte ptr inputBuffer - cmp al, 13 - je read_bet_drain_lf - cmp al, 10 - je read_bet_finish - cmp al, ' ' - je read_bet_loop - cmp al, 9 - je read_bet_loop - - cmp al, 'a' - jb read_bet_store - cmp al, 'z' - ja read_bet_store - sub al, 20h - -read_bet_store: - cmp esi, 31 - jae read_bet_after_store - mov cheatBuffer[esi], al -read_bet_after_store: - inc esi - - cmp edi, 0 - jne read_bet_loop - cmp al, '0' - jb read_bet_mark_code - cmp al, '9' - ja read_bet_mark_code - movzx edx, al - sub edx, '0' - imul ebx, ebx, 10 - add ebx, edx - jmp read_bet_loop - -read_bet_mark_code: - mov edi, 1 - jmp read_bet_loop - -read_bet_drain_lf: - invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 - cmp charsRead, 0 - je read_bet_finish - movzx eax, byte ptr inputBuffer - cmp al, 10 - jne read_bet_drain_lf - -read_bet_finish: - cmp esi, 0 - je read_bet_empty - cmp edi, 0 - jne read_bet_cheat - mov eax, ebx - ret - -read_bet_cheat: - invoke ApplyCheatCode, OFFSET cheatBuffer - cmp eax, 1 - je read_bet_cheat_ok - mov eax, 0FFFFFFFEh - ret -read_bet_cheat_ok: - mov eax, 0FFFFFFFFh - ret -read_bet_empty: - xor eax, eax - ret -ReadBetInput ENDP - -; --- Pause: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- -PauseConsole PROC - invoke PrintStr, OFFSET pauseText - call ReadAnyKey - ret -PauseConsole ENDP - -; --- PrintBank: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintBank PROC - invoke PrintStr, OFFSET bankText - invoke PrintMoney, bankroll - invoke PrintStr, OFFSET nl - ret -PrintBank ENDP -; --- PrintGoal: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintGoal PROC - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET goalText - call ResetColor - invoke PrintMoney, targetBank - invoke PrintStr, OFFSET nl - ret -PrintGoal ENDP - -; --- ResetProfileDefaults: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -ResetProfileDefaults PROC uses ecx edi - 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 - -; --- ReadAccountName: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- -; --- CopyCString: êîïèðîâàíèå ASCIIZ-ñòðîêè --- -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: äîïèñûâàåò ASCIIZ-ñòðîêó â êîíåö áóôåðà --- -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: ïóòü ê %APPDATA%\AssemblerCasino --- -BuildNativeProfileDir3D PROTO -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: ïîëíûé ïóòü òåêóùåãî àêêàóíòà --- -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: ìàñêà ïîèñêà àêêàóíòîâ --- -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: ïîëíûé ïóòü àêêàóíòà äëÿ òàáëèö ëèäåðîâ --- -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 -ReadAccountName PROC uses eax ecx edi - mov ecx, 64 - mov edi, OFFSET saveFileName -clear_account_name: - mov byte ptr [edi], 0 - inc edi - loop clear_account_name - - mov accountNameLen, 0 - mov edi, OFFSET saveFileName -read_account_loop: - invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 - cmp charsRead, 0 - je account_name_done - mov al, byte ptr inputBuffer - cmp al, 13 - je account_name_drain_lf - cmp al, 10 - je account_name_done - - cmp accountNameLen, 50 - jae read_account_loop - cmp al, '0' - jb check_account_upper - cmp al, '9' - jbe store_account_char -check_account_upper: - cmp al, 'A' - jb check_account_lower - cmp al, 'Z' - jbe store_account_char -check_account_lower: - cmp al, 'a' - jb check_account_symbols - cmp al, 'z' - jbe store_account_char -check_account_symbols: - cmp al, '_' - je store_account_char - cmp al, '-' - je store_account_char - jmp read_account_loop -store_account_char: - mov [edi], al - inc edi - inc accountNameLen - jmp read_account_loop - -account_name_drain_lf: - invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 - cmp charsRead, 0 - je account_name_done - mov al, byte ptr inputBuffer - cmp al, 10 - jne account_name_drain_lf - -account_name_done: - cmp accountNameLen, 0 - je account_name_return - mov byte ptr [edi], '.' - inc edi - mov byte ptr [edi], 'd' - inc edi - mov byte ptr [edi], 'a' - inc edi - mov byte ptr [edi], 't' - inc edi - mov byte ptr [edi], 0 -account_name_return: - ret -ReadAccountName ENDP - -; --- AskAccountName: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -AskAccountName PROC -ask_account_name_again: - invoke PrintStr, OFFSET accountPromptText - call ReadAccountName - cmp accountNameLen, 0 - jne account_name_ok - invoke PrintStr, OFFSET accountBadText - jmp ask_account_name_again -account_name_ok: - ret -AskAccountName ENDP - -; --- CopyFindAccountName: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -CopyFindAccountName PROC uses eax ecx esi edi - mov eax, accountCount - shl eax, 6 - mov edi, OFFSET accountList - add edi, eax - mov esi, OFFSET findData - add esi, 44 - mov ecx, 63 -copy_find_name_loop: - mov al, [esi] - mov [edi], al - cmp al, 0 - je copy_find_name_done - inc esi - inc edi - loop copy_find_name_loop - mov byte ptr [edi], 0 -copy_find_name_done: - ret -CopyFindAccountName ENDP - -; --- CopySelectedAccountName: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -CopySelectedAccountName PROC uses eax ecx esi edi - mov eax, selectedAccount - dec eax - shl eax, 6 - mov esi, OFFSET accountList - add esi, eax - mov edi, OFFSET saveFileName - mov ecx, 63 -copy_selected_name_loop: - mov al, [esi] - mov [edi], al - cmp al, 0 - je copy_selected_name_done - inc esi - inc edi - loop copy_selected_name_loop - mov byte ptr [edi], 0 -copy_selected_name_done: - ret -CopySelectedAccountName ENDP - -; --- CollectAccounts: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -CollectAccounts PROC uses eax - mov accountCount, 0 - call BuildAccountPatternFull - invoke FindFirstFileA, OFFSET accountPatternFull, OFFSET findData - cmp eax, INVALID_HANDLE_VALUE - je collect_accounts_done - mov findHandle, eax -collect_accounts_loop: - mov eax, DWORD PTR [findData] - test eax, 10h - jne collect_accounts_next - cmp accountCount, 20 - jae collect_accounts_close - call CopyFindAccountName - inc accountCount -collect_accounts_next: - invoke FindNextFileA, findHandle, OFFSET findData - cmp eax, 0 - jne collect_accounts_loop -collect_accounts_close: - invoke FindClose, findHandle -collect_accounts_done: - ret -CollectAccounts ENDP - -; --- PrintAccountList: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintAccountList PROC uses eax ebx - invoke PrintStr, OFFSET accountListTitle - mov ebx, 0 -print_account_loop: - cmp ebx, accountCount - jae print_account_done - mov eax, ebx - inc eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET dotSpaceText - mov eax, ebx - shl eax, 6 - add eax, OFFSET accountList - invoke PrintStr, eax - invoke PrintStr, OFFSET nl - inc ebx - jmp print_account_loop -print_account_done: - ret -PrintAccountList ENDP - -; --- SelectExistingAccount: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -SelectExistingAccount PROC -select_account_again: - call ClearView - invoke PrintTitleColor, OFFSET titleText - call CollectAccounts - cmp accountCount, 0 - jne accounts_available - invoke PrintStr, OFFSET accountNoFilesText - call PauseConsole - xor eax, eax - ret -accounts_available: - call PrintAccountList - invoke PrintStr, OFFSET accountSelectText - call ReadUInt - cmp eax, 1 - jb select_account_bad - cmp eax, accountCount - ja select_account_bad - mov selectedAccount, eax - call CopySelectedAccountName - mov eax, 1 - ret -select_account_bad: - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp select_account_again -SelectExistingAccount ENDP - -; --- AccountMenu: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -AccountMenu PROC -account_menu_loop: - call ClearView - invoke PrintTitleColor, OFFSET titleText - invoke PrintStr, OFFSET accountMenuText - invoke PrintStr, OFFSET choiceText - call ReadKey - cmp al, '1' - je account_login - cmp al, '2' - je account_create - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp account_menu_loop - -account_login: - call ResetProfileDefaults - call SelectExistingAccount - cmp eax, 1 - jne account_menu_loop - call LoadSave - invoke PrintStr, OFFSET accountLoginText - invoke PrintStr, OFFSET saveFileName - invoke PrintStr, OFFSET nl - invoke Sleep, 700 - ret - -account_create: - call ClearView - invoke PrintTitleColor, OFFSET titleText - call ResetProfileDefaults - call AskAccountName - call SaveGame - invoke PrintStr, OFFSET accountCreateText - invoke PrintStr, OFFSET saveFileName - invoke PrintStr, OFFSET nl - invoke Sleep, 700 - ret -AccountMenu ENDP -; --- CalcSaveSignature: ïðîñòàÿ ïîäïèñü ñîõðàíåíèÿ îò ðó÷íîé ïðàâêè --- -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: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -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 - 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: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -LoadSave PROC uses eax ecx esi edi - 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_FILE_SIZE - jb load_signature_ok - mov edx, DWORD PTR [saveBuffer+SAVE_SIGN_SIZE] - call CalcSaveSignature - cmp eax, edx - jne load_tampered -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 - -; --- RegisterGamePlayed: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -RegisterGamePlayed PROC uses eax ebx - mov eax, currentGameId - cmp eax, 1 - jb register_game_played_done - cmp eax, 11 - ja register_game_played_done - dec eax - mov ebx, eax - inc dword ptr gameStatsPlayed[ebx * 4] -register_game_played_done: - ret -RegisterGamePlayed ENDP - -; --- RegisterGameWin: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -RegisterGameWin PROC uses eax ebx - call RegisterGamePlayed - mov eax, currentGameId - cmp eax, 1 - jb register_game_win_done - cmp eax, 10 - ja register_game_win_done - dec eax - mov ebx, eax - inc dword ptr gameStatsWon[ebx * 4] -register_game_win_done: - ret -RegisterGameWin ENDP - -; --- RegisterGameLoss: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -RegisterGameLoss PROC uses eax ebx - call RegisterGamePlayed - mov eax, currentGameId - cmp eax, 1 - jb register_game_loss_done - cmp eax, 10 - ja register_game_loss_done - dec eax - mov ebx, eax - inc dword ptr gameStatsLost[ebx * 4] -register_game_loss_done: - ret -RegisterGameLoss ENDP - -; --- RegisterGameDraw: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -RegisterGameDraw PROC uses eax ebx - call RegisterGamePlayed - mov eax, currentGameId - cmp eax, 1 - jb register_game_draw_done - cmp eax, 10 - ja register_game_draw_done - dec eax - mov ebx, eax - inc dword ptr gameStatsDraw[ebx * 4] -register_game_draw_done: - ret -RegisterGameDraw ENDP -; --- RegisterWin: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -RegisterWin PROC uses eax, amount:DWORD - inc gamesPlayed - inc gamesWon - call DailyAddWin - call RegisterGameWin - mov eax, amount - cmp eax, bestWin - jbe register_win_save - mov bestWin, eax -register_win_save: - call SaveGame - ret -RegisterWin ENDP - -; --- RegisterLoss: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -RegisterLoss PROC uses eax, amount:DWORD - inc gamesPlayed - inc gamesLost - call DailyAddLoss - call RegisterGameLoss - mov eax, amount - cmp eax, bestLoss - jbe register_loss_save - mov bestLoss, eax -register_loss_save: - invoke UnlockAchievement, 2, OFFSET achFirstLossName -register_loss_ach_done: - call SaveGame - ret -RegisterLoss ENDP - -; --- RegisterDraw: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -RegisterDraw PROC - inc gamesPlayed - inc gamesDrawn - call DailyAddDraw - call RegisterGameDraw - call SaveGame - ret -RegisterDraw ENDP - -; --- DailyTaskGoal: öåëü çàäàíèÿ èç ïóëà 40 --- -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 - -; --- DailyTaskReward: äåíåæíàÿ íàãðàäà çàäàíèÿ èç ïóëà 40 --- -DailyTaskReward PROC taskId:DWORD - mov eax, taskId - cmp eax, 12 - je daily_reward_big - cmp eax, 30 - je daily_reward_big - cmp eax, 34 - je daily_reward_big - cmp eax, 36 - je daily_reward_big - cmp eax, 38 - je daily_reward_mid - cmp eax, 40 - je daily_reward_mid - cmp eax, 10 - jb daily_reward_small - cmp eax, 28 - jbe daily_reward_mid - mov eax, 2000 - ret -daily_reward_small: - mov eax, 1000 - ret -daily_reward_mid: - mov eax, 2500 - ret -daily_reward_big: - mov eax, 4000 - ret -DailyTaskReward ENDP - -; --- DailyGenerateTasks: âûáèðàåò 3 çàäàíèÿ èç 40 ïî êàëåíäàðíîé äàòå --- -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: êàëåíäàðíûå åæåäíåâíûå çàäàíèÿ --- -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 - -; --- DailyTaskMatches: ïðîâåðÿåò, ðåàãèðóåò ëè çàäàíèå íà ñîáûòèå --- -; eventType: 1 played, 2 win, 3 loss, 4 draw, 5 bet>=5000, 6 bet>=10000 -DailyTaskMatches PROC uses ebx ecx edx, taskId:DWORD, eventType:DWORD - mov eax, taskId - mov ebx, eventType - cmp eax, 1 - je daily_match_play_any - cmp eax, 2 - je daily_match_play_any - cmp eax, 3 - je daily_match_play_any - cmp eax, 4 - je daily_match_win_any - cmp eax, 5 - je daily_match_win_any - cmp eax, 6 - je daily_match_win_any - cmp eax, 7 - je daily_match_loss_any - cmp eax, 8 - je daily_match_loss_any - cmp eax, 9 - je daily_match_draw_any - cmp eax, 10 - je daily_match_bet5 - cmp eax, 11 - je daily_match_bet5 - cmp eax, 12 - je daily_match_bet10 - - cmp eax, 13 - jb daily_match_none - cmp eax, 34 - ja daily_match_groups - mov ecx, eax - sub ecx, 13 - shr ecx, 1 - inc ecx - ; map compact game order 1..11 to actual currentGameId - cmp ecx, 3 - jb daily_match_game_ready - cmp ecx, 3 - je daily_match_game_clover - cmp ecx, 4 - je daily_match_game_rr - cmp ecx, 5 - je daily_match_game_skulls - cmp ecx, 6 - je daily_match_game_coin - cmp ecx, 7 - je daily_match_game_dice - cmp ecx, 8 - je daily_match_game_casino_roulette - cmp ecx, 9 - je daily_match_game_slot - cmp ecx, 10 - je daily_match_game_durak - mov ecx, 11 - jmp daily_match_game_ready -daily_match_game_clover: - mov ecx, 3 - jmp daily_match_game_ready -daily_match_game_rr: - mov ecx, 4 - jmp daily_match_game_ready -daily_match_game_skulls: - mov ecx, 5 - jmp daily_match_game_ready -daily_match_game_coin: - mov ecx, 6 - jmp daily_match_game_ready -daily_match_game_dice: - mov ecx, 7 - jmp daily_match_game_ready -daily_match_game_casino_roulette: - mov ecx, 8 - jmp daily_match_game_ready -daily_match_game_slot: - mov ecx, 9 - jmp daily_match_game_ready -daily_match_game_durak: - mov ecx, 10 -daily_match_game_ready: - cmp currentGameId, ecx - jne daily_match_none - test eax, 1 - jnz daily_match_play_any - jmp daily_match_win_any - -daily_match_groups: - cmp eax, 35 - je daily_match_card_play - cmp eax, 36 - je daily_match_card_win - cmp eax, 37 - je daily_match_luck_play - cmp eax, 38 - je daily_match_luck_win - cmp eax, 39 - je daily_match_risk_play - cmp eax, 40 - je daily_match_risk_win - jmp daily_match_none - -daily_match_play_any: - cmp ebx, 1 - je daily_match_yes - jmp daily_match_none -daily_match_win_any: - cmp ebx, 2 - je daily_match_yes - jmp daily_match_none -daily_match_loss_any: - cmp ebx, 3 - je daily_match_yes - jmp daily_match_none -daily_match_draw_any: - cmp ebx, 4 - je daily_match_yes - jmp daily_match_none -daily_match_bet5: - cmp ebx, 5 - je daily_match_yes - jmp daily_match_none -daily_match_bet10: - cmp ebx, 6 - je daily_match_yes - jmp daily_match_none - -daily_match_card_play: - cmp ebx, 1 - jne daily_match_none - cmp currentGameId, 1 - je daily_match_yes - cmp currentGameId, 2 - je daily_match_yes - cmp currentGameId, 10 - je daily_match_yes - jmp daily_match_none -daily_match_card_win: - cmp ebx, 2 - jne daily_match_none - cmp currentGameId, 1 - je daily_match_yes - cmp currentGameId, 2 - je daily_match_yes - cmp currentGameId, 10 - je daily_match_yes - jmp daily_match_none -daily_match_luck_play: - cmp ebx, 1 - jne daily_match_none - cmp currentGameId, 3 - je daily_match_yes - cmp currentGameId, 6 - je daily_match_yes - cmp currentGameId, 7 - je daily_match_yes - cmp currentGameId, 8 - je daily_match_yes - cmp currentGameId, 9 - je daily_match_yes - jmp daily_match_none -daily_match_luck_win: - cmp ebx, 2 - jne daily_match_none - cmp currentGameId, 3 - je daily_match_yes - cmp currentGameId, 6 - je daily_match_yes - cmp currentGameId, 7 - je daily_match_yes - cmp currentGameId, 8 - je daily_match_yes - cmp currentGameId, 9 - je daily_match_yes - jmp daily_match_none -daily_match_risk_play: - cmp ebx, 1 - jne daily_match_none - cmp currentGameId, 4 - je daily_match_yes - cmp currentGameId, 5 - je daily_match_yes - cmp currentGameId, 11 - je daily_match_yes - jmp daily_match_none -daily_match_risk_win: - cmp ebx, 2 - jne daily_match_none - cmp currentGameId, 4 - je daily_match_yes - cmp currentGameId, 5 - je daily_match_yes - cmp currentGameId, 11 - je daily_match_yes - jmp daily_match_none - -daily_match_yes: - mov eax, 1 - ret -daily_match_none: - xor eax, eax - ret -DailyTaskMatches ENDP - -; --- DailyApplyEvent: ïðèìåíÿåò èãðîâîå ñîáûòèå ê òð¸ì çàäàíèÿì äíÿ --- -DailyApplyEvent PROC uses eax ebx ecx edx esi, eventType:DWORD - call DailyCheckDate - mov esi, 0 -daily_apply_loop: - cmp esi, 3 - jae daily_apply_done - movzx eax, byte ptr [dailyTaskPacked + esi] - cmp eax, 0 - je daily_apply_next - mov ebx, eax - invoke DailyTaskMatches, ebx, eventType - cmp eax, 1 - jne daily_apply_next - movzx ecx, byte ptr [dailyProgressPacked + esi] - invoke DailyTaskGoal, ebx - cmp ecx, eax - jae daily_apply_next - inc byte ptr [dailyProgressPacked + esi] -daily_apply_next: - inc esi - jmp daily_apply_loop -daily_apply_done: - ret -DailyApplyEvent ENDP - -DailyAddPlayed PROC - invoke DailyApplyEvent, 1 - ret -DailyAddPlayed ENDP - -DailyAddWin PROC - call DailyAddPlayed - invoke DailyApplyEvent, 2 - ret -DailyAddWin ENDP - -DailyAddLoss PROC - call DailyAddPlayed - invoke DailyApplyEvent, 3 - ret -DailyAddLoss ENDP - -DailyAddDraw PROC - call DailyAddPlayed - invoke DailyApplyEvent, 4 - ret -DailyAddDraw ENDP - -DailyAddHighBet PROC - call DailyCheckDate - cmp currentBet, 5000 - jb daily_bet_done - invoke DailyApplyEvent, 5 - cmp currentBet, 10000 - jb daily_bet_done - invoke DailyApplyEvent, 6 -daily_bet_done: - ret -DailyAddHighBet ENDP - -; --- DailyClaimSlot: âûäà÷à íàãðàäû çà îäèí ñëîò åæåäíåâêè --- -DailyClaimSlot PROC uses eax ebx ecx edx, slotIndex:DWORD, maskValue:DWORD - mov eax, dailyRewardMask - and eax, maskValue - cmp eax, 0 - jne daily_claim_slot_done - mov ecx, slotIndex - movzx ebx, byte ptr [dailyTaskPacked + ecx] - cmp ebx, 0 - je daily_claim_slot_done - movzx edx, byte ptr [dailyProgressPacked + ecx] - invoke DailyTaskGoal, ebx - cmp edx, eax - jb daily_claim_slot_done - mov eax, maskValue - or dailyRewardMask, eax - invoke DailyTaskReward, ebx - add bankroll, eax - push eax - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET dailyClaimText - pop eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - call ResetColor -daily_claim_slot_done: - ret -DailyClaimSlot ENDP - -DailyClaimRewards PROC - call DailyCheckDate - invoke DailyClaimSlot, 0, 1 - invoke DailyClaimSlot, 1, 2 - invoke DailyClaimSlot, 2, 4 - call SaveGame - ret -DailyClaimRewards ENDP - -; --- PrintDailySlot: ñòðîêà îäíîãî åæåäíåâíîãî çàäàíèÿ --- -PrintDailySlot PROC uses eax ebx ecx edx, slotIndex:DWORD, maskValue:DWORD - mov ecx, slotIndex - mov eax, ecx - inc eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET dotSpaceText - movzx ebx, byte ptr [dailyTaskPacked + ecx] - cmp ebx, 1 - jb daily_slot_done - cmp ebx, 40 - ja daily_slot_done - mov eax, ebx - dec eax - mov edx, dword ptr [dailyTaskNameTable + eax * 4] - invoke PrintStr, edx - invoke PrintStr, OFFSET dailySlashText - mov ecx, slotIndex - movzx eax, byte ptr [dailyProgressPacked + ecx] - push eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET dailySlashText - invoke DailyTaskGoal, ebx - mov edx, eax - invoke PrintUInt, edx - invoke PrintStr, OFFSET dailyRewardText - invoke DailyTaskReward, ebx - invoke PrintUInt, eax - mov eax, dailyRewardMask - and eax, maskValue - cmp eax, 0 - jne daily_slot_status_done - pop eax - cmp eax, edx - jae daily_slot_status_ready - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET dailyOpenText - call ResetColor - ret -daily_slot_status_ready: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET dailyReadyText - call ResetColor - ret -daily_slot_status_done: - pop eax - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET dailyDoneText - call ResetColor - ret -daily_slot_done: - ret -PrintDailySlot ENDP - -GameDailyTasks PROC - call ClearView - invoke PrintTitleColor, OFFSET dailyTitle - invoke PrintStr, OFFSET dailyIntro - call DailyClaimRewards - call PrintBank - invoke PrintStr, OFFSET dailyDateText - invoke PrintUInt, dailyDateKey - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET dailyPoolText - invoke PrintDailySlot, 0, 1 - invoke PrintDailySlot, 1, 2 - invoke PrintDailySlot, 2, 4 - call PauseConsole - ret -GameDailyTasks ENDP - -; --- PrintDifficultyName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintDifficultyName PROC - cmp aiDifficulty, 1 - je print_easy_name - cmp aiDifficulty, 3 - je print_hard_name - invoke PrintStr, OFFSET normalName - ret -print_easy_name: - invoke PrintStr, OFFSET easyName - ret -print_hard_name: - invoke PrintStr, OFFSET hardName - ret -PrintDifficultyName ENDP - -; --- PrintBankLevelName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintBankLevelName PROC - mov eax, bankroll - cmp eax, 100000 - jae print_level_legend - cmp eax, 50000 - jae print_level_high - cmp eax, 20000 - jae print_level_player - invoke PrintStr, OFFSET bankLevelNewbie - ret -print_level_player: - invoke PrintStr, OFFSET bankLevelPlayer - ret -print_level_high: - invoke PrintStr, OFFSET bankLevelHigh - ret -print_level_legend: - invoke PrintStr, OFFSET bankLevelLegend - ret -PrintBankLevelName ENDP - -; --- PrintBankLevel: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintBankLevel PROC - invoke PrintStr, OFFSET bankLevelText - call PrintBankLevelName - ret -PrintBankLevel ENDP - -; --- ApplySoundVolume: íàñòðîéêè ãðîìêîñòè WinMM, 0-10 --- -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 -; --- AnimShouldDrawFrame: animation profile frame skipper --- -AnimShouldDrawFrame PROC uses ecx edx - inc animFrameCounter - mov eax, settingsLowSpec - cmp eax, 0 - je anim_draw_yes - cmp eax, 1 - je anim_adaptive_check - mov eax, animFrameCounter - xor edx, edx - mov ecx, 3 - div ecx - cmp edx, 1 - je anim_draw_yes - xor eax, eax - ret -anim_adaptive_check: - mov eax, animFrameCounter - and eax, 1 - cmp eax, 1 - je anim_draw_yes - xor eax, eax - ret -anim_draw_yes: - mov eax, 1 - ret -AnimShouldDrawFrame ENDP - -; --- AnimFrameDelay: keeps scene timing while reducing redraws --- -AnimFrameDelay PROC baseDelay:DWORD - mov eax, baseDelay - cmp settingsLowSpec, 1 - je anim_delay_adaptive - cmp settingsLowSpec, 2 - je anim_delay_stable - ret -anim_delay_adaptive: - shl eax, 1 - ret -anim_delay_stable: - imul eax, eax, 3 - ret -AnimFrameDelay ENDP - -; --- PrintVIPStatus: VIP-ñòàòóñ ïî ðàçìåðó áàíêà --- -PrintVIPStatus PROC - invoke PrintStr, OFFSET vipStatusText - mov eax, bankroll - cmp eax, 500000 - jae print_vip_diamond - cmp eax, 250000 - jae print_vip_gold - cmp eax, 100000 - jae print_vip_silver - invoke PrintStr, OFFSET vipBronzeText - ret -print_vip_silver: - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET vipSilverText - call ResetColor - ret -print_vip_gold: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET vipGoldText - call ResetColor - ret -print_vip_diamond: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET vipDiamondText - call ResetColor - ret -PrintVIPStatus ENDP - -; --- ApplyVIPTax: êàçèíî áåðåò êîìèññèþ ñ áîëüøèõ VIP-ñòàâîê --- -ApplyVIPTax PROC uses eax ebx edx - mov vipTaxAmount, 0 - mov eax, bankroll - cmp eax, 100000 - jb vip_tax_done - mov eax, currentBet - cmp bankroll, 500000 - jae vip_tax_diamond - cmp bankroll, 250000 - jae vip_tax_gold - mov ebx, 1 - jmp vip_tax_calc -vip_tax_gold: - mov ebx, 2 - jmp vip_tax_calc -vip_tax_diamond: - mov ebx, 3 -vip_tax_calc: - mul ebx - mov ebx, 100 - xor edx, edx - div ebx - cmp eax, 0 - jne vip_tax_have - mov eax, 1 -vip_tax_have: - mov vipTaxAmount, eax - cmp bankroll, eax - jae vip_tax_sub - mov eax, bankroll - mov vipTaxAmount, eax -vip_tax_sub: - sub bankroll, eax - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET vipTaxText - invoke PrintUInt, vipTaxAmount - invoke PrintStr, OFFSET nl - call ResetColor - call SaveGame -vip_tax_done: - ret -ApplyVIPTax ENDP - -; --- CheckSecretEnding: ñåêðåòíàÿ êîíöîâêà çà ïîëíîå çàêðûòèå êàçèíî --- -CheckSecretEnding PROC uses eax - cmp secretEndingSeen, 0 - jne secret_ending_done - mov eax, achievements - and eax, 3FFFFh - cmp eax, 3FFFFh - jne secret_ending_done - mov eax, shopBackOwned - and eax, 1FFFh - cmp eax, 1FFFh - jne secret_ending_done - cmp bankroll, 1000000 - jb secret_ending_done - mov secretEndingSeen, 1 - call SaveGame - call ClearView - call PlayVictorySound - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET secretEndingTitle - invoke PrintStr, OFFSET secretEndingArt1 - invoke Sleep, 500 - invoke PrintStr, OFFSET secretEndingArt2 - call ResetColor - invoke PrintStr, OFFSET secretEndingBody - call PauseConsole -secret_ending_done: - ret -CheckSecretEnding ENDP - -; --- GameSettings: íàñòðîéêè çâóêà è èãðîâûõ îïöèé --- -GameSettings PROC -settings_loop: - call ClearView - invoke PrintTitleColor, OFFSET settingsTitle - invoke PrintStr, OFFSET settingsVolumeText - invoke PrintUInt, settingsVolume - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET settingsVolumeHint - call PrintVIPStatus - - invoke PrintStr, OFFSET settingsModeText - cmp settingsLowSpec, 0 - je settings_print_cinematic - cmp settingsLowSpec, 1 - je settings_print_adaptive - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET settingsStableText - call ResetColor - jmp settings_print_intro -settings_print_cinematic: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET settingsCinematicText - call ResetColor - jmp settings_print_intro -settings_print_adaptive: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET settingsAdaptiveText - call ResetColor -settings_print_intro: - invoke PrintStr, OFFSET settingsIntroText - cmp settingsIntroEnabled, 1 - je settings_intro_on - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET settingsOffText - call ResetColor - jmp settings_print_dbd -settings_intro_on: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET settingsOnText - call ResetColor -settings_print_dbd: - invoke PrintStr, OFFSET settingsDbdText - cmp settingsDbdWindowEnabled, 1 - je settings_dbd_on - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET settingsOffText - call ResetColor - jmp settings_show_menu -settings_dbd_on: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET settingsOnText - call ResetColor -settings_show_menu: - invoke PrintStr, OFFSET settingsAnimHintText - invoke PrintStr, OFFSET settingsMenuText - call ReadUInt - cmp eax, 0 - je settings_exit - cmp eax, 1 - je settings_quieter - cmp eax, 2 - je settings_louder - cmp eax, 3 - je settings_toggle_low - cmp eax, 4 - je settings_toggle_intro - cmp eax, 5 - je settings_toggle_dbd - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp settings_loop -settings_quieter: - cmp settingsVolume, 0 - jbe settings_apply - dec settingsVolume - jmp settings_apply -settings_louder: - cmp settingsVolume, 10 - jae settings_apply - inc settingsVolume - jmp settings_apply -settings_toggle_low: - inc settingsLowSpec - cmp settingsLowSpec, 3 - jb settings_apply - mov settingsLowSpec, 0 - jmp settings_apply -settings_toggle_intro: - mov eax, settingsIntroEnabled - xor eax, 1 - mov settingsIntroEnabled, eax - jmp settings_apply -settings_toggle_dbd: - mov eax, settingsDbdWindowEnabled - xor eax, 1 - mov settingsDbdWindowEnabled, eax -settings_apply: - call ApplySoundVolume - call SaveGame - jmp settings_loop -settings_exit: - ret -GameSettings ENDP -; --- CalcStressLevel: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -CalcStressLevel PROC uses eax ebx edx - mov stressLevel, 0 - cmp bankroll, 0 - je calc_stress_done - cmp currentBet, 0 - je calc_stress_done - mov eax, currentBet - mov ebx, 100 - mul ebx - mov ebx, bankroll - xor edx, edx - div ebx - cmp eax, 75 - jae calc_stress_max - cmp eax, 50 - jae calc_stress_high - cmp eax, 25 - jae calc_stress_mid - jmp calc_stress_done -calc_stress_mid: - mov stressLevel, 1 - jmp calc_stress_done -calc_stress_high: - mov stressLevel, 2 - jmp calc_stress_done -calc_stress_max: - mov stressLevel, 3 -calc_stress_done: - ret -CalcStressLevel ENDP - -; --- PrintStressLevel: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintStressLevel PROC - invoke PrintStr, OFFSET stressText - mov eax, stressLevel - cmp eax, 0 - je print_stress_low - cmp eax, 1 - je print_stress_mid - cmp eax, 2 - je print_stress_high - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET stressMaxText - call ResetColor - ret -print_stress_low: - invoke PrintStr, OFFSET stressLowText - ret -print_stress_mid: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET stressMidText - call ResetColor - ret -print_stress_high: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET stressHighText - call ResetColor - ret -PrintStressLevel ENDP - -; --- PrintSuspicion: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSuspicion PROC - invoke PrintStr, OFFSET suspicionText - mov eax, casinoSuspicion - cmp eax, 44 - jae print_suspicion_hunt - cmp eax, 25 - jae print_suspicion_watch - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET suspicionCalmText - call ResetColor - ret -print_suspicion_watch: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET suspicionWatchText - call ResetColor - ret -print_suspicion_hunt: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET suspicionHuntText - call ResetColor - ret -PrintSuspicion ENDP - -; --- AddSuspicion: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -AddSuspicion PROC uses eax ebx, amount:DWORD - mov eax, casinoSuspicion - add eax, amount - cmp eax, 100 - jbe add_suspicion_store - mov eax, 100 -add_suspicion_store: - mov casinoSuspicion, eax - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET suspicionUpText - call ResetColor - call SaveGame - ret -AddSuspicion ENDP - -; --- CheckCasinoHeat: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -CheckCasinoHeat PROC uses eax ebx - mov eax, casinoSuspicion - cmp eax, 44 - jb casino_heat_done - sub eax, 40 - mov ebx, eax - invoke RandomRange, 100 - cmp eax, ebx - jae casino_heat_done - mov eax, currentBet - shr eax, 1 - cmp eax, 1 - jae casino_heat_have_fine - mov eax, 1 -casino_heat_have_fine: - cmp bankroll, eax - jae casino_heat_sub - mov eax, bankroll -casino_heat_sub: - sub bankroll, eax - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET suspicionFineText - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - call ResetColor - call PrintBank - call SaveGame -casino_heat_done: - ret -CheckCasinoHeat ENDP -; --- ShowStats: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -ShowStats PROC - invoke PrintStr, OFFSET difficultyNowText - call PrintDifficultyName - call PrintBankLevel - invoke PrintStr, OFFSET statsGamesText - invoke PrintUInt, gamesPlayed - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET statsWinsText - invoke PrintUInt, gamesWon - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET statsLossText - invoke PrintUInt, gamesLost - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET statsDrawText - invoke PrintUInt, gamesDrawn - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET statsBestWinText - invoke PrintUInt, bestWin - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET statsBestLossText - invoke PrintUInt, bestLoss - invoke PrintStr, OFFSET nl - call PrintSuspicion - ret -ShowStats ENDP - - -; --- WriteAchievementPopup: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -WriteAchievementPopup PROC uses eax ecx esi, pName:DWORD - mov esi, pName - xor ecx, ecx -achievement_len_loop: - mov al, [esi + ecx] - cmp al, 0 - je achievement_len_ready - cmp al, 13 - je achievement_len_ready - cmp ecx, 64 - jae achievement_len_ready - inc ecx - jmp achievement_len_loop -achievement_len_ready: - invoke CreateFileA, OFFSET achievementFileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 - cmp eax, INVALID_HANDLE_VALUE - je achievement_popup_run - mov achievementHandle, eax - invoke WriteFile, achievementHandle, pName, ecx, ADDR charsWritten, 0 - invoke CloseHandle, achievementHandle -achievement_popup_run: - invoke WinExec, OFFSET achievementCmd, 1 - ret -WriteAchievementPopup ENDP - -; --- UnlockAchievement: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -UnlockAchievement PROC uses eax ebx, maskValue:DWORD, pName:DWORD - mov eax, achievements - mov ebx, maskValue - test eax, ebx - jz unlock_achievement_new - ret -unlock_achievement_new: - or eax, ebx - mov achievements, eax - call SaveGame - invoke WriteAchievementPopup, pName - ret -UnlockAchievement ENDP - -; --- PrintAchievementLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintAchievementLine PROC uses eax ebx, maskValue:DWORD, pName:DWORD - mov eax, achievements - mov ebx, maskValue - test eax, ebx - jz print_achievement_locked - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET achDoneText - call ResetColor - jmp print_achievement_name -print_achievement_locked: - invoke SetColor, COLOR_BACK_CARD - invoke PrintStr, OFFSET achTodoText - call ResetColor -print_achievement_name: - invoke PrintStr, pName - ret -PrintAchievementLine ENDP -; --- ShowWelcome: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -ShowWelcome PROC - call ClearView - invoke PrintTitleColor, OFFSET titleText - invoke PrintStr, OFFSET welcomeText - call PrintGoal - cmp bankRecovered, 0 - je welcome_check_tampered - invoke PrintStr, OFFSET bankRecoveredText -welcome_check_tampered: - cmp saveTampered, 0 - je welcome_bank_normal - invoke PrintStr, OFFSET saveTamperedText -welcome_bank_normal: - call PrintBank - call ShowStats - call PauseConsole - ret -ShowWelcome ENDP - -; --- SelectDifficulty: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -SelectDifficulty PROC -select_difficulty_again: - call ClearView - invoke PrintTitleColor, OFFSET titleText - invoke PrintStr, OFFSET difficultyText - call ReadKey - cmp al, '1' - je set_easy_ai - cmp al, '2' - je set_normal_ai - cmp al, '3' - je set_hard_ai - jmp select_difficulty_again -set_easy_ai: - mov aiDifficulty, 1 - jmp difficulty_selected -set_normal_ai: - mov aiDifficulty, 2 - jmp difficulty_selected -set_hard_ai: - mov aiDifficulty, 3 -difficulty_selected: - call SaveGame - ret -SelectDifficulty ENDP - -; --- ShowPokerChips: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -ShowPokerChips PROC uses eax ebx edx - invoke PrintStr, OFFSET pokerChipTitle - - mov eax, currentBet - mov ebx, 5000 - xor edx, edx - div ebx - add eax, 5 - cmp eax, 10 - jbe poker_chips_count_ready - mov eax, 10 -poker_chips_count_ready: - mov rowIndex, eax - -poker_chips_loop: - cmp rowIndex, 0 - je poker_chips_done - mov eax, rowIndex - cmp eax, 7 - ja poker_chips_high - cmp eax, 4 - ja poker_chips_mid - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET pokerChipLow - jmp poker_chips_next -poker_chips_mid: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET pokerChipMid - jmp poker_chips_next -poker_chips_high: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET pokerChipHigh -poker_chips_next: - dec rowIndex - jmp poker_chips_loop - -poker_chips_done: - call ResetColor - ret -ShowPokerChips ENDP - -; --- ShowPokerMoney: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -ShowPokerMoney PROC uses eax ebx - call ShowPokerChips - invoke PrintStr, OFFSET pokerPotText - mov eax, currentBet - mov ebx, 2 - mul ebx - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET pokerBetText - invoke PrintUInt, currentBet - invoke PrintStr, OFFSET nl - ret -ShowPokerMoney ENDP - -; --- PromptPokerRaise: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -PromptPokerRaise PROC uses ebx - call PrintBank - invoke PrintStr, OFFSET pokerRaiseAskText - call ReadUInt - cmp eax, 0 - je raise_bad - mov pokerRaiseAmount, eax - mov ebx, currentBet - add ebx, eax - cmp ebx, bankroll - ja raise_bad - mov currentBet, ebx - invoke PrintStr, OFFSET pokerRaisedText - invoke PrintUInt, currentBet - invoke PrintStr, OFFSET nl - mov eax, 1 - ret -raise_bad: - invoke PrintStr, OFFSET pokerBadRaiseText - xor eax, eax - ret -PromptPokerRaise ENDP - -; --- PaySlotMultiplier: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -PaySlotMultiplier PROC uses eax ebx edx, multiplier:DWORD - mov lastGameResult, 1 - mov eax, currentBet - mov ebx, multiplier - mul ebx - mov pokerRaiseAmount, eax - add bankroll, eax - invoke PrintStr, OFFSET slotPayoutText - invoke PrintUInt, multiplier - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET moneyWinText - invoke PrintUInt, pokerRaiseAmount - invoke PrintStr, OFFSET nl - invoke RegisterWin, pokerRaiseAmount - invoke UnlockAchievement, 1, OFFSET achFirstWinName - call PrintBank - call PrintCroupierWin - cmp multiplier, 10 - jb slot_multiplier_no_ach - invoke UnlockAchievement, 4, OFFSET achJackpotName -slot_multiplier_no_ach: - call CheckVictory - ret -PaySlotMultiplier ENDP -; --- CheckBankrupt: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -CheckBankrupt PROC - cmp bankroll, 0 - ja bankroll_ok - call PlayBankruptSound - invoke Sleep, 300 - invoke PrintStr, OFFSET casinoKickText - invoke PrintStr, OFFSET casinoExitText - call ReadAnyKey - invoke ExitProcess, 0 -bankroll_ok: - ret -CheckBankrupt ENDP -; --- CheckVictory: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -CheckVictory PROC - mov eax, bankroll - cmp eax, targetBank - jb victory_not_yet - call PlayVictorySound - call ClearView - invoke PrintTitleColor, OFFSET titleText - invoke PrintStr, OFFSET victoryText - invoke PrintStr, OFFSET victoryReachedText - invoke PrintUInt, targetBank - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET victoryTailText - call PrintBank - -advance_victory_goal: - mov eax, bankroll - cmp eax, targetBank - jb victory_goal_ready - add targetBank, 50000 - jmp advance_victory_goal -victory_goal_ready: - call SaveGame - invoke UnlockAchievement, 40h, OFFSET achGoalName - invoke PrintStr, OFFSET nextGoalText - invoke PrintUInt, targetBank - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET victoryExitText - call CheckSecretEnding -victory_secret_checked: - call ReadAnyKey - ret -victory_not_yet: - call CheckSecretEnding - ret -CheckVictory ENDP - -; --- ShowStressPulse: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -ShowStressPulse PROC uses eax ebx edx - cmp bankroll, 0 - je stress_pulse_done - mov eax, currentBet - cmp eax, 0 - je stress_pulse_done - mov ebx, 100 - mul ebx - mov ebx, bankroll - xor edx, edx - div ebx - cmp eax, 25 - jb stress_pulse_done - - invoke PrintStr, OFFSET pulseTitleText - cmp eax, 50 - jae stress_pulse_hot - invoke SetColor, COLOR_WARN - jmp stress_pulse_frames -stress_pulse_hot: - invoke SetColor, COLOR_BAD -stress_pulse_frames: - mov eax, stressLevel - inc eax - mov pulseCycles, eax -stress_pulse_cycle: - invoke PrintStr, OFFSET pulseFrame1 - invoke Sleep, 70 - invoke PrintStr, OFFSET pulseFrame2 - invoke Sleep, 70 - invoke PrintStr, OFFSET pulseFrame3 - invoke Sleep, 70 - invoke PrintStr, OFFSET pulseFrame4 - invoke Sleep, 70 - invoke PrintStr, OFFSET pulseFrame5 - invoke Sleep, 90 - dec pulseCycles - cmp pulseCycles, 0 - jne stress_pulse_cycle - call ResetColor -stress_pulse_done: - ret -ShowStressPulse ENDP - -; --- PromptBet: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -PromptBet PROC -prompt_bet_again: - call CheckBankrupt - call PrintBank - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET betText - call ReadBetInput - push eax - call ResetColor - pop eax - cmp eax, 0FFFFFFFFh - je prompt_bet_again - cmp eax, 0FFFFFFFEh - je prompt_bet_again - cmp eax, 0FFFFFFFDh - je prompt_bet_again - cmp eax, 0 - jne bet_check_money - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET badBetText - call ResetColor - jmp prompt_bet_again - -bet_check_money: - cmp eax, bankroll - jbe bet_store - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET tooBigBetText - call ResetColor - jmp prompt_bet_again -bet_store: - mov currentBet, eax - call ApplyVIPTax - cmp currentBet, 10000 - jb bet_highroller_done - invoke UnlockAchievement, 8, OFFSET achHighRollerName -bet_highroller_done: - call DailyAddHighBet - invoke PrintStr, OFFSET betChosenText - invoke PrintMoney, currentBet - invoke PrintStr, OFFSET nl - call CalcStressLevel - call PrintStressLevel - call ShowStressPulse - invoke Sleep, 500 - ret -PromptBet ENDP - -; --- PayWin: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -PayWin PROC - mov lastGameResult, 1 - mov eax, currentBet - add bankroll, eax - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET moneyWinText - invoke PrintUInt, currentBet - call ResetColor - invoke PrintStr, OFFSET nl - invoke RegisterWin, currentBet - invoke UnlockAchievement, 1, OFFSET achFirstWinName - call PrintBank - call PrintCroupierWin - call CheckVictory - ret -PayWin ENDP - -; --- TryCharmSave: òàëèñìàíû ñïàñàþò ñòàâêó, íî ó ñèëüíûõ åñòü öåíà --- -TryCharmSave PROC uses ebx ecx edx - cmp shopCharmLevel, 0 - jne charm_has_level - xor eax, eax - ret -charm_has_level: - cmp shopCharmUses, 0 - jne charm_has_uses - mov shopCharmLevel, 0 - xor eax, eax - ret -charm_has_uses: - mov ebx, shopCharmLevel - cmp ebx, 1 - je charm_chance_clover - cmp ebx, 2 - je charm_chance_bell - cmp ebx, 3 - je charm_chance_diamond - cmp ebx, 4 - je charm_chance_skull - cmp ebx, 5 - je charm_chance_web - cmp ebx, 6 - je charm_chance_bee - cmp ebx, 7 - je charm_chance_moon - cmp ebx, 8 - je charm_chance_crown - cmp ebx, 9 - je charm_chance_mirror - cmp ebx, 10 - je charm_chance_dice - cmp ebx, 11 - je charm_chance_blood - cmp ebx, 12 - je charm_chance_hourglass - cmp ebx, 13 - je charm_chance_horseshoe - cmp ebx, 14 - je charm_chance_joker - cmp ebx, 15 - je charm_chance_phoenix - cmp ebx, 16 - je charm_chance_compass - cmp ebx, 17 - je charm_chance_tooth - cmp ebx, 18 - je charm_chance_eye - cmp ebx, 19 - je charm_chance_key - cmp ebx, 20 - je charm_chance_candle - cmp ebx, 21 - je charm_chance_chip - cmp ebx, 22 - je charm_chance_snake - cmp ebx, 23 - je charm_chance_ace - cmp ebx, 24 - je charm_chance_devil - xor eax, eax - ret -charm_chance_clover: - mov ecx, 7 - jmp charm_roll -charm_chance_bell: - mov ecx, 14 - jmp charm_roll -charm_chance_diamond: - mov ecx, 21 - jmp charm_roll -charm_chance_skull: - mov ecx, 28 - jmp charm_roll -charm_chance_web: - mov ecx, 35 - jmp charm_roll -charm_chance_bee: - mov ecx, 12 - jmp charm_roll -charm_chance_moon: - mov ecx, 18 - jmp charm_roll -charm_chance_crown: - mov ecx, 24 - jmp charm_roll -charm_chance_mirror: - mov ecx, 16 - jmp charm_roll -charm_chance_dice: - mov ecx, 10 - jmp charm_roll -charm_chance_blood: - mov ecx, 40 - jmp charm_roll -charm_chance_hourglass: - mov ecx, 22 - jmp charm_roll -charm_chance_horseshoe: - mov ecx, 9 - jmp charm_roll -charm_chance_joker: - mov ecx, 33 - jmp charm_roll -charm_chance_phoenix: - mov ecx, 26 - jmp charm_roll -charm_chance_compass: - mov ecx, 19 - jmp charm_roll -charm_chance_tooth: - mov ecx, 15 - jmp charm_roll -charm_chance_eye: - mov ecx, 31 - jmp charm_roll -charm_chance_key: - mov ecx, 13 - jmp charm_roll -charm_chance_candle: - mov ecx, 38 - jmp charm_roll -charm_chance_chip: - mov ecx, 20 - jmp charm_roll -charm_chance_snake: - mov ecx, 29 - jmp charm_roll -charm_chance_ace: - mov ecx, 17 - jmp charm_roll -charm_chance_devil: - mov ecx, 50 -charm_roll: - invoke RandomRange, 100 - cmp eax, ecx - jb charm_save_hit - xor eax, eax - ret - -charm_save_hit: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopCharmSaveText - call ResetColor - dec shopCharmUses - - mov ebx, shopCharmLevel - cmp ebx, 2 - je charm_penalty_bell - cmp ebx, 3 - je charm_penalty_diamond - cmp ebx, 4 - je charm_penalty_skull - cmp ebx, 5 - je charm_penalty_web - cmp ebx, 7 - je charm_penalty_moon - cmp ebx, 8 - je charm_penalty_crown - cmp ebx, 9 - je charm_penalty_mirror - cmp ebx, 11 - je charm_penalty_blood - cmp ebx, 12 - je charm_penalty_hourglass - cmp ebx, 14 - je charm_penalty_joker - cmp ebx, 15 - je charm_penalty_phoenix - cmp ebx, 16 - je charm_penalty_compass - cmp ebx, 17 - je charm_penalty_tooth - cmp ebx, 18 - je charm_penalty_eye - cmp ebx, 20 - je charm_penalty_candle - cmp ebx, 22 - je charm_penalty_snake - cmp ebx, 23 - je charm_penalty_ace - cmp ebx, 24 - je charm_penalty_devil - jmp charm_penalty_done - -charm_penalty_bell: - invoke AddSuspicion, 4 - jmp charm_penalty_done -charm_penalty_diamond: - invoke AddSuspicion, 8 - jmp charm_penalty_done -charm_penalty_web: - invoke AddSuspicion, 20 - jmp charm_penalty_done -charm_penalty_moon: - invoke AddSuspicion, 8 - jmp charm_penalty_done -charm_penalty_crown: - invoke AddSuspicion, 12 - jmp charm_penalty_done -charm_penalty_mirror: - invoke AddSuspicion, 6 - jmp charm_penalty_done -charm_penalty_hourglass: - invoke AddSuspicion, 15 - jmp charm_penalty_done -charm_penalty_joker: - invoke AddSuspicion, 30 - jmp charm_penalty_done -charm_penalty_phoenix: - invoke AddSuspicion, 10 - jmp charm_penalty_done -charm_penalty_compass: - invoke AddSuspicion, 12 - jmp charm_penalty_done -charm_penalty_eye: - invoke AddSuspicion, 18 - jmp charm_penalty_done -charm_penalty_snake: - invoke AddSuspicion, 16 - jmp charm_penalty_done -charm_penalty_ace: - invoke AddSuspicion, 7 - jmp charm_penalty_done -charm_penalty_blood: - invoke AddSuspicion, 25 - mov ebx, 4 - jmp charm_take_fraction -charm_penalty_skull: - mov ebx, 2 - jmp charm_take_fraction -charm_penalty_tooth: - mov ebx, 5 - jmp charm_take_fraction -charm_penalty_candle: - invoke AddSuspicion, 35 - mov ebx, 3 - jmp charm_take_fraction -charm_penalty_devil: - invoke AddSuspicion, 45 - mov ebx, 2 -charm_take_fraction: - mov eax, currentBet - xor edx, edx - div ebx - cmp eax, 1 - jae charm_have_price - mov eax, 1 -charm_have_price: - cmp bankroll, eax - jae charm_sub_price - mov eax, bankroll -charm_sub_price: - sub bankroll, eax - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET charmPenaltyText - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - call ResetColor - -charm_penalty_done: - call RegisterDraw - invoke UnlockAchievement, 20h, OFFSET achCharmName - cmp shopCharmUses, 0 - jne charm_still_alive - mov shopCharmLevel, 0 - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET shopCharmBurnText - call ResetColor -charm_still_alive: - call SaveGame - call PrintBank - call PrintCroupierDraw - mov eax, 1 - ret -TryCharmSave ENDP - -; --- PayLose: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -PayLose PROC - cmp cheatGodMode, 0 - jne pay_lose_cheat_win - cmp cheatLuckyWin, 0 - jne pay_lose_cheat_once - jmp pay_lose_normal -pay_lose_cheat_once: - mov cheatLuckyWin, 0 -pay_lose_cheat_win: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET cheatSavedText - call ResetColor - call PayWin - ret -pay_lose_normal: - call TryCharmSave - cmp eax, 1 - je pay_lose_charm_saved - mov eax, currentBet - cmp bankroll, eax - jae pay_lose_sub - mov bankroll, 0 - jmp pay_lose_done -pay_lose_sub: - sub bankroll, eax -pay_lose_done: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET moneyLoseText - invoke PrintUInt, currentBet - call ResetColor - invoke PrintStr, OFFSET nl - invoke RegisterLoss, currentBet - call PrintBank - call PrintCroupierLose - call CheckBankrupt -pay_lose_charm_saved: - ret -PayLose ENDP - -; --- PayDraw: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -PayDraw PROC - mov lastGameResult, 3 - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET moneyDrawText - call ResetColor - call RegisterDraw - call PrintBank - call PrintCroupierDraw - ret -PayDraw ENDP - -; --- PaySlotPair: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -PaySlotPair PROC - mov lastGameResult, 1 - mov eax, currentBet - add bankroll, eax - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET moneyWinText - invoke PrintUInt, currentBet - call ResetColor - invoke PrintStr, OFFSET nl - call PrintBank - ret -PaySlotPair ENDP - -; --- PaySlotJackpot: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -PaySlotJackpot PROC uses ebx - mov lastGameResult, 1 - mov eax, currentBet - mov ebx, 5 - mul ebx - add bankroll, eax - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET moneyWinText - invoke PrintUInt, eax - call ResetColor - invoke PrintStr, OFFSET nl - call PrintBank - invoke UnlockAchievement, 4, OFFSET achJackpotName - ret -PaySlotJackpot ENDP - -; --- ConfigureConsoleSize: çàäàåò ñòàðòîâûé ðàçìåð îêíà êîíñîëè áåç ìàñøòàáèðîâàíèÿ ASCII --- -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: ñëóæåáíûå ôóíêöèè êîíñîëè è ñëó÷àéíûõ ÷èñåë --- -HomeCursor PROC - invoke SetConsoleCursorPosition, hOut, 0 - ret -HomeCursor ENDP - -; --- ClearView: ñëóæåáíûå ôóíêöèè êîíñîëè è ñëó÷àéíûõ ÷èñåë --- -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: ñëóæåáíûå ôóíêöèè êîíñîëè è ñëó÷àéíûõ ÷èñåë --- -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 - -; --- ResetDeck: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -ResetDeck PROC uses ecx edi - mov ecx, 52 - mov edi, OFFSET deckUsed -reset_loop: - mov byte ptr [edi], 0 - inc edi - loop reset_loop - ret -ResetDeck ENDP - -; --- DrawCard: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -DrawCard PROC uses edi -draw_again: - invoke RandomRange, 52 - mov edi, OFFSET deckUsed - add edi, eax - cmp byte ptr [edi], 0 - jne draw_again - mov byte ptr [edi], 1 - ret -DrawCard ENDP -; --- CardValue21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -CardValue21 PROC uses ecx edx, card:DWORD - mov eax, card - xor edx, edx - mov ecx, 13 - div ecx - mov eax, edx - cmp eax, 8 - jbe numeric_card - cmp eax, 9 - je jack_card - cmp eax, 10 - je queen_card - cmp eax, 11 - je king_card - mov eax, 11 - ret -numeric_card: - add eax, 2 - ret -jack_card: - mov eax, 2 - ret -queen_card: - mov eax, 3 - ret -king_card: - mov eax, 4 - ret -CardValue21 ENDP - -; --- CardValueBJ: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -CardValueBJ PROC uses ecx edx, card:DWORD - mov eax, card - xor edx, edx - mov ecx, 13 - div ecx - mov eax, edx - cmp eax, 8 - jbe bj_numeric - cmp eax, 12 - je bj_ace - mov eax, 10 - ret -bj_numeric: - add eax, 2 - ret -bj_ace: - mov eax, 11 - ret -CardValueBJ ENDP - -; --- AdjustPlayerAces: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -AdjustPlayerAces PROC -adjust_player: - cmp playerTotal, 21 - jbe adjust_player_done - cmp playerAces, 0 - je adjust_player_done - sub playerTotal, 10 - dec playerAces - jmp adjust_player -adjust_player_done: - ret -AdjustPlayerAces ENDP - -; --- AdjustDealerAces: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -AdjustDealerAces PROC -adjust_dealer: - cmp dealerTotal, 21 - jbe adjust_dealer_done - cmp dealerAces, 0 - je adjust_dealer_done - sub dealerTotal, 10 - dec dealerAces - jmp adjust_dealer -adjust_dealer_done: - ret -AdjustDealerAces ENDP - -; --- PrintScore: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintScore PROC - invoke PrintStr, OFFSET yourScoreText - invoke PrintUInt, playerTotal - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET dealerScoreText - invoke PrintUInt, dealerTotal - invoke PrintStr, OFFSET nl - ret -PrintScore ENDP - -; --- PrintCard: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCard PROC uses eax ebx ecx edx esi, card:DWORD - mov eax, card - xor edx, edx - mov ecx, 13 - div ecx - mov ebx, eax - mov esi, edx - - invoke PrintUtf8, OFFSET cardTop - invoke PrintUtf8, OFFSET cardSuitLeft - invoke PrintSuit, ebx - invoke PrintUtf8, OFFSET cardSuitRight - - cmp esi, 8 - jne one_rank - invoke PrintUtf8, OFFSET cardRankTenL - invoke PrintStr, ranks[esi * 4] - invoke PrintUtf8, OFFSET cardRankTenR - jmp rank_done -one_rank: - invoke PrintUtf8, OFFSET cardRankOneL - invoke PrintStr, ranks[esi * 4] - invoke PrintUtf8, OFFSET cardRankOneR -rank_done: - invoke PrintUtf8, OFFSET cardEmpty - invoke PrintUtf8, OFFSET cardEmpty - invoke PrintUtf8, OFFSET cardCenterL - invoke PrintSuit, ebx - invoke PrintUtf8, OFFSET cardCenterR - invoke PrintUtf8, OFFSET cardBottom - ret -PrintCard ENDP - -; --- AddPlayer21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -AddPlayer21 PROC uses eax ebx - call PlayCardSound - call DrawCard - mov ebx, eax - invoke PrintStr, OFFSET yourCardText - invoke PrintCard, ebx - invoke CardValue21, ebx - add playerTotal, eax - ret -AddPlayer21 ENDP - -; --- AddDealer21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -AddDealer21 PROC uses eax ebx - call PlayCardSound - call DrawCard - mov ebx, eax - invoke PrintStr, OFFSET dealerCardText - invoke PrintCard, ebx - invoke CardValue21, ebx - add dealerTotal, eax - ret -AddDealer21 ENDP - -; --- Reset21Hands: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -Reset21Hands PROC - mov playerTotal, 0 - mov dealerTotal, 0 - mov playerCnt21, 0 - mov aiCnt21, 0 - mov revealAI21, 0 - ret -Reset21Hands ENDP - -; --- DrawPlayer21Hand: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -DrawPlayer21Hand PROC uses ebx ecx - cmp playerCnt21, 10 - jae draw_player21_done - call PlayCardSound - call DrawCard - mov ebx, playerCnt21 - mov playerHand21[ebx * 4], eax - inc playerCnt21 -draw_player21_done: - ret -DrawPlayer21Hand ENDP - -; --- DrawAI21Hand: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -DrawAI21Hand PROC uses ebx ecx - cmp aiCnt21, 10 - jae draw_ai21_done - call PlayCardSound - call DrawCard - mov ebx, aiCnt21 - mov aiHand21[ebx * 4], eax - inc aiCnt21 -draw_ai21_done: - ret -DrawAI21Hand ENDP - -; --- PrintHandTop: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintHandTop PROC uses eax, count:DWORD - mov rowIndex, 0 -top_loop: - mov eax, rowIndex - cmp eax, count - jae top_done - invoke PrintUtf8, OFFSET cardTopSeg - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp top_loop -top_done: - invoke PrintStr, OFFSET nl - ret -PrintHandTop ENDP - -; --- PrintHandBottom: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintHandBottom PROC uses eax, count:DWORD - mov rowIndex, 0 -bottom_loop: - mov eax, rowIndex - cmp eax, count - jae bottom_done - invoke PrintUtf8, OFFSET cardBottomSeg - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp bottom_loop -bottom_done: - invoke PrintStr, OFFSET nl - ret -PrintHandBottom ENDP - -; --- PrintHandBlankLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintHandBlankLine PROC uses eax, count:DWORD, reveal:DWORD - mov rowIndex, 0 -blank_loop: - mov eax, rowIndex - cmp eax, count - jae blank_done - cmp reveal, 0 - je blank_hidden - invoke PrintUtf8, OFFSET cardEmptySeg - jmp blank_next -blank_hidden: - call SetCardBackColor - invoke PrintCardBackSegLine, 4 - call ResetColor -blank_next: - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp blank_loop -blank_done: - invoke PrintStr, OFFSET nl - ret -PrintHandBlankLine ENDP - -; --- PrintHandSuitLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintHandSuitLine PROC uses eax ebx ecx edx, pHand:DWORD, count:DWORD, reveal:DWORD - LOCAL suitIndex:DWORD - - mov rowIndex, 0 -suit_loop: - mov eax, rowIndex - cmp eax, count - jae suit_done - cmp reveal, 0 - je suit_hidden - - mov ebx, pHand - mov eax, [ebx + eax * 4] - xor edx, edx - mov ecx, 13 - div ecx - mov suitIndex, eax - - invoke PrintUtf8, OFFSET cardSuitLeft - mov eax, suitIndex - invoke PrintSuit, eax - invoke PrintUtf8, OFFSET cardSuitRightSeg - jmp suit_next -suit_hidden: - call SetCardBackColor - invoke PrintCardBackSegLine, 1 - call ResetColor -suit_next: - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp suit_loop -suit_done: - invoke PrintStr, OFFSET nl - ret -PrintHandSuitLine ENDP - -; --- PrintHandRankLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintHandRankLine PROC uses eax ebx ecx edx, pHand:DWORD, count:DWORD, reveal:DWORD - LOCAL rankIndex:DWORD - - mov rowIndex, 0 -rank_loop_row: - mov eax, rowIndex - cmp eax, count - jae rank_done_row - cmp reveal, 0 - je rank_hidden - - mov ebx, pHand - mov eax, [ebx + eax * 4] - xor edx, edx - mov ecx, 13 - div ecx - mov rankIndex, edx - - cmp edx, 8 - jne rank_one_char - invoke PrintUtf8, OFFSET cardRankTenL - mov eax, rankIndex - invoke PrintStr, ranks[eax * 4] - invoke PrintUtf8, OFFSET cardRankTenRSeg - jmp rank_next -rank_one_char: - invoke PrintUtf8, OFFSET cardRankOneL - mov eax, rankIndex - invoke PrintStr, ranks[eax * 4] - invoke PrintUtf8, OFFSET cardRankOneRSeg - jmp rank_next -rank_hidden: - call SetCardBackColor - invoke PrintCardBackSegLine, 2 - call ResetColor -rank_next: - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp rank_loop_row -rank_done_row: - invoke PrintStr, OFFSET nl - ret -PrintHandRankLine ENDP - -; --- PrintHandCenterLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintHandCenterLine PROC uses eax ebx ecx edx, pHand:DWORD, count:DWORD, reveal:DWORD - LOCAL suitIndex:DWORD - - mov rowIndex, 0 -center_loop: - mov eax, rowIndex - cmp eax, count - jae center_done - cmp reveal, 0 - je center_hidden - - mov ebx, pHand - mov eax, [ebx + eax * 4] - xor edx, edx - mov ecx, 13 - div ecx - mov suitIndex, eax - - invoke PrintUtf8, OFFSET cardCenterL - mov eax, suitIndex - invoke PrintSuit, eax - invoke PrintUtf8, OFFSET cardCenterRSeg - jmp center_next -center_hidden: - call SetCardBackColor - invoke PrintCardBackSegLine, 5 - call ResetColor -center_next: - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp center_loop -center_done: - invoke PrintStr, OFFSET nl - ret -PrintHandCenterLine ENDP - -; --- PrintHandRow21: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintHandRow21 PROC pHand:DWORD, count:DWORD, reveal:DWORD - invoke PrintHandTop, count - invoke PrintHandSuitLine, pHand, count, reveal - invoke PrintHandRankLine, pHand, count, reveal - invoke PrintHandBlankLine, count, reveal - invoke PrintHandBlankLine, count, reveal - invoke PrintHandCenterLine, pHand, count, reveal - invoke PrintHandBottom, count - ret -PrintHandRow21 ENDP - -; --- PrintCommunitySuitLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCommunitySuitLine PROC uses eax ebx ecx edx - LOCAL suitIndex:DWORD - - mov rowIndex, 0 -community_suit_loop: - mov eax, rowIndex - cmp eax, 5 - jae community_suit_done - cmp eax, communityCnt - jae community_suit_hidden - - mov eax, communityHand[eax * 4] - xor edx, edx - mov ecx, 13 - div ecx - mov suitIndex, eax - invoke PrintUtf8, OFFSET cardSuitLeft - mov eax, suitIndex - invoke PrintSuit, eax - invoke PrintUtf8, OFFSET cardSuitRightSeg - jmp community_suit_next -community_suit_hidden: - call SetCardBackColor - invoke PrintCardBackSegLine, 1 - call ResetColor -community_suit_next: - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp community_suit_loop -community_suit_done: - invoke PrintStr, OFFSET nl - ret -PrintCommunitySuitLine ENDP - -; --- PrintCommunityRankLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCommunityRankLine PROC uses eax ecx edx - LOCAL rankIndex:DWORD - - mov rowIndex, 0 -community_rank_loop: - mov eax, rowIndex - cmp eax, 5 - jae community_rank_done - cmp eax, communityCnt - jae community_rank_hidden - - mov eax, communityHand[eax * 4] - xor edx, edx - mov ecx, 13 - div ecx - mov rankIndex, edx - cmp edx, 8 - jne community_rank_one - invoke PrintUtf8, OFFSET cardRankTenL - mov eax, rankIndex - invoke PrintStr, ranks[eax * 4] - invoke PrintUtf8, OFFSET cardRankTenRSeg - jmp community_rank_next -community_rank_one: - invoke PrintUtf8, OFFSET cardRankOneL - mov eax, rankIndex - invoke PrintStr, ranks[eax * 4] - invoke PrintUtf8, OFFSET cardRankOneRSeg - jmp community_rank_next -community_rank_hidden: - call SetCardBackColor - invoke PrintCardBackSegLine, 2 - call ResetColor -community_rank_next: - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp community_rank_loop -community_rank_done: - invoke PrintStr, OFFSET nl - ret -PrintCommunityRankLine ENDP - -; --- PrintCommunityBlankLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCommunityBlankLine PROC uses eax - mov rowIndex, 0 -community_blank_loop: - mov eax, rowIndex - cmp eax, 5 - jae community_blank_done - cmp eax, communityCnt - jae community_blank_hidden - invoke PrintUtf8, OFFSET cardEmptySeg - jmp community_blank_next -community_blank_hidden: - call SetCardBackColor - invoke PrintCardBackSegLine, 4 - call ResetColor -community_blank_next: - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp community_blank_loop -community_blank_done: - invoke PrintStr, OFFSET nl - ret -PrintCommunityBlankLine ENDP - -; --- PrintCommunityCenterLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCommunityCenterLine PROC uses eax ecx edx - LOCAL suitIndex:DWORD - - mov rowIndex, 0 -community_center_loop: - mov eax, rowIndex - cmp eax, 5 - jae community_center_done - cmp eax, communityCnt - jae community_center_hidden - - mov eax, communityHand[eax * 4] - xor edx, edx - mov ecx, 13 - div ecx - mov suitIndex, eax - invoke PrintUtf8, OFFSET cardCenterL - mov eax, suitIndex - invoke PrintSuit, eax - invoke PrintUtf8, OFFSET cardCenterRSeg - jmp community_center_next -community_center_hidden: - call SetCardBackColor - invoke PrintCardBackSegLine, 5 - call ResetColor -community_center_next: - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp community_center_loop -community_center_done: - invoke PrintStr, OFFSET nl - ret -PrintCommunityCenterLine ENDP - -; --- PrintCommunityRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCommunityRow PROC - invoke PrintHandTop, 5 - call PrintCommunitySuitLine - call PrintCommunityRankLine - call PrintCommunityBlankLine - call PrintCommunityBlankLine - call PrintCommunityCenterLine - invoke PrintHandBottom, 5 - ret -PrintCommunityRow ENDP - -; --- PrintFlipLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintFlipLine PROC uses eax, count:DWORD, pSegment:DWORD - mov rowIndex, 0 -flip_line_loop: - mov eax, rowIndex - cmp eax, count - jae flip_line_done - invoke PrintUtf8, pSegment - invoke PrintUtf8, OFFSET cardGap - inc rowIndex - jmp flip_line_loop -flip_line_done: - invoke PrintStr, OFFSET nl - ret -PrintFlipLine ENDP - -; --- PrintFlipCards: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintFlipCards PROC count:DWORD, pSegment:DWORD - invoke PrintHandTop, count - invoke PrintFlipLine, count, pSegment - invoke PrintFlipLine, count, pSegment - invoke PrintFlipLine, count, pSegment - invoke PrintFlipLine, count, pSegment - invoke PrintFlipLine, count, pSegment - invoke PrintHandBottom, count - ret -PrintFlipCards ENDP - -; --- ShowRevealFrame21: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -ShowRevealFrame21 PROC pSegment:DWORD - call ClearView - invoke PrintTitleColor, OFFSET twentyOneTitle - invoke PrintStr, OFFSET revealText - invoke PrintStr, OFFSET aiCardsText - invoke PrintFlipCards, aiCnt21, pSegment - invoke PrintStr, OFFSET playerCardsText - invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 - call CalcPlayerScore21 - invoke PrintStr, OFFSET yourScoreText - invoke PrintUInt, playerTotal - invoke PrintStr, OFFSET nl - ret -ShowRevealFrame21 ENDP - -; --- AnimateReveal21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -AnimateReveal21 PROC - call PlayCardSound - invoke ShowRevealFrame21, OFFSET cardBackSeg - invoke Sleep, FLIP_DELAY - invoke ShowRevealFrame21, OFFSET cardFlipLeft - invoke Sleep, FLIP_DELAY - invoke ShowRevealFrame21, OFFSET cardFlipMid - invoke Sleep, FLIP_DELAY - invoke ShowRevealFrame21, OFFSET cardFlipRight - invoke Sleep, FLIP_DELAY - mov revealAI21, 1 - call ClearView - invoke PrintTitleColor, OFFSET twentyOneTitle - call ShowAllCards21 - invoke Sleep, FLIP_FINAL_DELAY - ret -AnimateReveal21 ENDP - -; --- CalcPlayerScore21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -CalcPlayerScore21 PROC uses eax ebx - mov playerTotal, 0 - mov rowIndex, 0 -calc_player21_loop: - mov eax, rowIndex - cmp eax, playerCnt21 - jae calc_player21_done - mov ebx, playerHand21[eax * 4] - invoke CardValue21, ebx - add playerTotal, eax - inc rowIndex - jmp calc_player21_loop -calc_player21_done: - ret -CalcPlayerScore21 ENDP - -; --- CalcAIScore21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -CalcAIScore21 PROC uses eax ebx - mov dealerTotal, 0 - mov rowIndex, 0 -calc_ai21_loop: - mov eax, rowIndex - cmp eax, aiCnt21 - jae calc_ai21_done - mov ebx, aiHand21[eax * 4] - invoke CardValue21, ebx - add dealerTotal, eax - inc rowIndex - jmp calc_ai21_loop -calc_ai21_done: - ret -CalcAIScore21 ENDP - -; --- ShowAllCards21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -ShowAllCards21 PROC - cmp revealAI21, 0 - jne show_ai_cards - invoke PrintStr, OFFSET aiThinkText -show_ai_cards: - invoke PrintStr, OFFSET aiCardsText - invoke PrintHandRow21, OFFSET aiHand21, aiCnt21, revealAI21 - invoke PrintStr, OFFSET playerCardsText - invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 - - call CalcPlayerScore21 - call CalcAIScore21 - invoke PrintStr, OFFSET yourScoreText - invoke PrintUInt, playerTotal - invoke PrintStr, OFFSET nl - cmp revealAI21, 0 - je show_cards_done - invoke PrintStr, OFFSET aiScoreText - invoke PrintUInt, dealerTotal - invoke PrintStr, OFFSET nl -show_cards_done: - ret -ShowAllCards21 ENDP -; --- PeekUnusedCard: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -PeekUnusedCard PROC uses edi -peek_unused_again: - invoke RandomRange, 52 - mov edi, OFFSET deckUsed - add edi, eax - cmp byte ptr [edi], 0 - jne peek_unused_again - ret -PeekUnusedCard ENDP - -; --- CheatPeek21: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -CheatPeek21 PROC uses eax ebx - invoke PrintStr, OFFSET cheatPeekText - call PeekUnusedCard - mov ebx, eax - invoke PrintCard, ebx - invoke AddSuspicion, 12 - call CheckCasinoHeat - call PauseConsole - ret -CheatPeek21 ENDP - -; --- CheatSwap21: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -CheatSwap21 PROC uses eax ebx - cmp playerCnt21, 0 - je cheat_swap21_none - call DrawCard - mov ebx, playerCnt21 - dec ebx - mov playerHand21[ebx * 4], eax - call CalcPlayerScore21 - invoke PrintStr, OFFSET cheatSwapText - invoke AddSuspicion, 18 - call CheckCasinoHeat - call PauseConsole - ret -cheat_swap21_none: - invoke PrintStr, OFFSET cheatNoTargetText - call PauseConsole - ret -CheatSwap21 ENDP - -; --- CheatPeekPoker: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -CheatPeekPoker PROC uses eax ebx - mov ebx, communityCnt - cmp ebx, 5 - jb cheat_peek_poker_table - invoke PrintStr, OFFSET cheatPeekText - mov ebx, 0 - mov eax, aiHand21[ebx * 4] - invoke PrintCard, eax - jmp cheat_peek_poker_done -cheat_peek_poker_table: - invoke PrintStr, OFFSET cheatPeekText - mov eax, communityHand[ebx * 4] - invoke PrintCard, eax -cheat_peek_poker_done: - invoke AddSuspicion, 12 - call CheckCasinoHeat - call PauseConsole - ret -CheatPeekPoker ENDP - -; --- CheatSwapPoker: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -CheatSwapPoker PROC uses eax - cmp playerCnt21, 0 - je cheat_swap_poker_none - call DrawCard - mov DWORD PTR playerHand21[0], eax - invoke PrintStr, OFFSET cheatSwapText - invoke AddSuspicion, 18 - call CheckCasinoHeat - call PauseConsole - ret -cheat_swap_poker_none: - invoke PrintStr, OFFSET cheatNoTargetText - call PauseConsole - ret -CheatSwapPoker ENDP - - -; --- CountDanger21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -CountDanger21 PROC uses eax ebx esi - call CalcAIScore21 - mov dangerLvl21, 0 - mov cardsLeft21, 0 - mov rowIndex, 0 -danger_loop: - mov eax, rowIndex - cmp eax, 52 - jae danger_done - mov esi, OFFSET deckUsed - cmp byte ptr [esi + eax], 0 - jne danger_next - - inc cardsLeft21 - invoke CardValue21, rowIndex - mov ebx, dealerTotal - add ebx, eax - cmp ebx, 21 - jbe danger_next - inc dangerLvl21 -danger_next: - inc rowIndex - jmp danger_loop -danger_done: - ret -CountDanger21 ENDP - -; --- FinalScreen21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -FinalScreen21 PROC - call ClearView - mov revealAI21, 1 - call ShowAllCards21 - - mov eax, playerTotal - mov ebx, dealerTotal - cmp eax, 21 - ja final_21_lose - cmp ebx, 21 - ja final_21_win - cmp eax, ebx - ja final_21_win - jb final_21_lose - call PrintDrawEvent - call PayDraw - ret -final_21_win: - call PrintWinEvent - call PayWin - ret -final_21_lose: - call PrintLoseEvent - call PayLose - ret -FinalScreen21 ENDP - -; --- ResetPokerHands: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -ResetPokerHands PROC - mov playerCnt21, 0 - mov aiCnt21, 0 - mov communityCnt, 0 - mov revealAI21, 0 - ret -ResetPokerHands ENDP - -; --- DrawCommunityPoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -DrawCommunityPoker PROC uses ebx ecx - cmp communityCnt, 5 - jae draw_community_done - call PlayCardSound - call DrawCard - mov ebx, communityCnt - mov communityHand[ebx * 4], eax - inc communityCnt -draw_community_done: - ret -DrawCommunityPoker ENDP - -; --- DealPokerHands: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -DealPokerHands PROC uses ecx - mov ecx, 2 -deal_poker_hands_loop: - call DrawPlayer21Hand - call DrawAI21Hand - loop deal_poker_hands_loop - - mov ecx, 5 -deal_poker_table_loop: - call DrawCommunityPoker - loop deal_poker_table_loop - mov communityCnt, 3 - ret -DealPokerHands ENDP - -; --- ShowPokerTable: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -ShowPokerTable PROC - invoke PrintStr, OFFSET aiCardsText - invoke PrintHandRow21, OFFSET aiHand21, aiCnt21, revealAI21 - invoke PrintStr, OFFSET pokerTableText - call PrintCommunityRow - invoke PrintStr, OFFSET playerCardsText - invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 - ret -ShowPokerTable ENDP - -; --- ShowPokerRevealFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -ShowPokerRevealFrame PROC pSegment:DWORD - call ClearView - invoke PrintTitleColor, OFFSET pokerTitle - invoke PrintStr, OFFSET pokerRevealText - invoke PrintStr, OFFSET aiCardsText - invoke PrintFlipCards, aiCnt21, pSegment - invoke PrintStr, OFFSET pokerTableText - call PrintCommunityRow - invoke PrintStr, OFFSET playerCardsText - invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 - ret -ShowPokerRevealFrame ENDP - -; --- AnimateRevealPoker: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -AnimateRevealPoker PROC - call PlayCardSound - invoke ShowPokerRevealFrame, OFFSET cardBackSeg - invoke Sleep, FLIP_DELAY - invoke ShowPokerRevealFrame, OFFSET cardFlipLeft - invoke Sleep, FLIP_DELAY - invoke ShowPokerRevealFrame, OFFSET cardFlipMid - invoke Sleep, FLIP_DELAY - invoke ShowPokerRevealFrame, OFFSET cardFlipRight - invoke Sleep, FLIP_DELAY - mov revealAI21, 1 - call ClearView - invoke PrintTitleColor, OFFSET pokerTitle - call ShowPokerTable - invoke Sleep, FLIP_FINAL_DELAY - ret -AnimateRevealPoker ENDP - -; --- ClearPokerCounts: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -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: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -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 - -; --- EvaluatePoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -EvaluatePoker PROC pHand:DWORD - invoke EvaluatePokerN, pHand, 5 - ret -EvaluatePoker ENDP - -; --- PrintPokerHandName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintPokerHandName PROC uses eax ebx edx, score:DWORD - mov eax, score - xor edx, edx - mov ebx, 1000 - div ebx - invoke PrintStr, pokerNames[eax * 4] - ret -PrintPokerHandName ENDP - -; --- BuildPokerEvalHand: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -BuildPokerEvalHand PROC uses eax ebx esi edi, pHole:DWORD, pOut:DWORD - mov esi, pHole - mov edi, pOut - - mov eax, [esi] - mov [edi], eax - mov eax, [esi + 4] - mov [edi + 4], eax - - mov eax, communityCnt - add eax, 2 - mov pokerEvalCount, eax - - mov ebx, 0 -build_table_cards: - cmp ebx, communityCnt - jae build_eval_done - mov eax, communityHand[ebx * 4] - mov [edi + ebx * 4 + 8], eax - inc ebx - jmp build_table_cards -build_eval_done: - ret -BuildPokerEvalHand ENDP - -; --- ShowPokerHint: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -ShowPokerHint PROC - invoke BuildPokerEvalHand, OFFSET playerHand21, OFFSET pokerPlayerEvalHand - invoke EvaluatePokerN, OFFSET pokerPlayerEvalHand, pokerEvalCount - mov pokerPlayerScore, eax - invoke PrintStr, OFFSET pokerHintText - invoke PrintPokerHandName, pokerPlayerScore - ret -ShowPokerHint ENDP - -; --- ShowPokerResult: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -ShowPokerResult PROC uses ebx - invoke BuildPokerEvalHand, OFFSET playerHand21, OFFSET pokerPlayerEvalHand - mov ebx, pokerEvalCount - invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand - mov pokerEvalCount, ebx - - invoke EvaluatePokerN, OFFSET pokerPlayerEvalHand, pokerEvalCount - mov pokerPlayerScore, eax - invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount - mov pokerAIScore, eax - - invoke PrintStr, OFFSET pokerYourComboText - invoke PrintPokerHandName, pokerPlayerScore - invoke PrintStr, OFFSET pokerAIComboText - invoke PrintPokerHandName, pokerAIScore - - mov eax, pokerPlayerScore - cmp eax, pokerAIScore - ja poker_player_win - jb poker_ai_win - call PrintDrawEvent - call PayDraw - ret -poker_player_win: - call PrintWinEvent - call PayWin - ret -poker_ai_win: - call PrintLoseEvent - call PayLose - ret -ShowPokerResult ENDP - -; --- PokerAIDecide: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -PokerAIDecide PROC uses ebx edx - invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand - invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount - mov pokerAIScore, eax - - mov eax, pokerAIScore - xor edx, edx - mov ebx, 1000 - div ebx - cmp eax, 1 - jae ai_will_play - - cmp aiDifficulty, 1 - je ai_easy_decide - cmp aiDifficulty, 3 - je ai_hard_decide - -ai_normal_decide: - mov eax, pokerAIScore - cmp eax, 11 - jae ai_normal_random - jmp ai_will_fold -ai_normal_random: - invoke RandomRange, 3 - cmp eax, 0 - je ai_will_fold - jmp ai_will_play - -ai_easy_decide: - invoke RandomRange, 2 - cmp eax, 0 - je ai_will_play - mov eax, pokerAIScore - cmp eax, 10 - jae ai_will_play - jmp ai_will_fold - -ai_hard_decide: - mov eax, pokerAIScore - cmp eax, 10 - jae ai_hard_high_card - invoke RandomRange, 3 - cmp eax, 0 - je ai_will_play - jmp ai_will_fold -ai_hard_high_card: - invoke RandomRange, 4 - cmp eax, 0 - je ai_will_fold - jmp ai_will_play - -ai_will_fold: - xor eax, eax - ret -ai_will_play: - mov eax, 1 - ret -PokerAIDecide ENDP - -; --- PokerAICallRaise: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -PokerAICallRaise PROC uses ebx ecx edx - invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand - invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount - mov pokerAIScore, eax - - mov eax, pokerAIScore - xor edx, edx - mov ebx, 1000 - div ebx - mov ecx, eax - cmp ecx, 1 - jae ai_call_raise - - mov eax, pokerRaiseAmount - mov ebx, 2 - mul ebx - cmp eax, currentBet - ja ai_big_raise - - cmp aiDifficulty, 1 - je ai_easy_call_bluff - cmp aiDifficulty, 3 - je ai_hard_call_bluff - invoke RandomRange, 3 - cmp eax, 0 - jne ai_call_raise - jmp ai_fold_raise - -ai_big_raise: - cmp aiDifficulty, 1 - je ai_easy_big_raise - cmp aiDifficulty, 3 - je ai_fold_raise - invoke RandomRange, 5 - cmp eax, 0 - je ai_call_raise - jmp ai_fold_raise - -ai_easy_call_bluff: - invoke RandomRange, 2 - cmp eax, 0 - je ai_call_raise - jmp ai_fold_raise - -ai_easy_big_raise: - invoke RandomRange, 3 - cmp eax, 0 - jne ai_call_raise - jmp ai_fold_raise - -ai_hard_call_bluff: - mov eax, pokerAIScore - cmp eax, 12 - jae ai_call_raise - jmp ai_fold_raise - -ai_fold_raise: - xor eax, eax - ret -ai_call_raise: - mov eax, 1 - ret -PokerAICallRaise ENDP - - -; --- HardPokerPlayerExchange: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -HardPokerPlayerExchange PROC uses eax ebx - cmp aiDifficulty, 3 - jne hard_player_exchange_done - call ClearView - invoke PrintTitleColor, OFFSET pokerTitle - call ShowPokerTable - call ShowPokerHint - invoke PrintStr, OFFSET pokerHardIntroText - invoke PrintStr, OFFSET pokerHardExchangeText - call ReadKey - cmp al, '1' - je hard_replace_first - cmp al, '2' - je hard_replace_second - jmp hard_player_exchange_done -hard_replace_first: - xor ebx, ebx - jmp hard_replace_card -hard_replace_second: - mov ebx, 1 -hard_replace_card: - call PlayCardSound - call DrawCard - mov playerHand21[ebx * 4], eax -hard_player_exchange_done: - ret -HardPokerPlayerExchange ENDP - -; --- HardPokerAIExchange: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -HardPokerAIExchange PROC uses eax ebx ecx edx - cmp aiDifficulty, 3 - jne hard_ai_exchange_done - invoke PrintStr, OFFSET pokerHardAIExchangeText - invoke Sleep, 650 - - mov eax, aiHand21[0] - xor edx, edx - mov ecx, 13 - div ecx - mov ebx, edx - - mov eax, aiHand21[4] - xor edx, edx - mov ecx, 13 - div ecx - - cmp ebx, edx - je hard_ai_exchange_done - cmp ebx, 8 - jb hard_ai_check_second - cmp edx, 8 - jae hard_ai_exchange_done - -hard_ai_check_second: - cmp ebx, edx - jbe hard_replace_ai_first - mov ebx, 1 - jmp hard_replace_ai_card -hard_replace_ai_first: - xor ebx, ebx -hard_replace_ai_card: - call PlayCardSound - call DrawCard - mov aiHand21[ebx * 4], eax -hard_ai_exchange_done: - ret -HardPokerAIExchange ENDP - -; --- PokerAIRaiseMaybe: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -PokerAIRaiseMaybe PROC uses ebx ecx edx - invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand - invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount - mov pokerAIScore, eax - - mov eax, bankroll - sub eax, currentBet - cmp eax, 0 - jbe ai_no_raise - mov ecx, eax - - mov eax, pokerAIScore - xor edx, edx - mov ebx, 1000 - div ebx - cmp eax, 2 - jae ai_strong_raise - cmp eax, 1 - je ai_pair_raise_check - - cmp aiDifficulty, 3 - jne ai_no_raise - mov eax, pokerAIScore - cmp eax, 12 - jne ai_no_raise - invoke RandomRange, 7 - cmp eax, 0 - jne ai_no_raise - mov eax, currentBet - xor edx, edx - mov ebx, 3 - div ebx - jmp ai_raise_amount_ready - -ai_pair_raise_check: - cmp aiDifficulty, 1 - je ai_easy_pair_raise - cmp aiDifficulty, 2 - je ai_normal_pair_raise - invoke RandomRange, 3 - cmp eax, 0 - je ai_no_raise - mov eax, currentBet - xor edx, edx - mov ebx, 2 - div ebx - jmp ai_raise_amount_ready - -ai_easy_pair_raise: - invoke RandomRange, 5 - cmp eax, 0 - jne ai_no_raise - mov eax, currentBet - xor edx, edx - mov ebx, 3 - div ebx - jmp ai_raise_amount_ready - -ai_normal_pair_raise: - invoke RandomRange, 3 - cmp eax, 0 - je ai_no_raise - mov eax, currentBet - xor edx, edx - mov ebx, 2 - div ebx - jmp ai_raise_amount_ready - -ai_strong_raise: - cmp aiDifficulty, 1 - je ai_easy_strong_raise - cmp aiDifficulty, 2 - je ai_normal_strong_raise - mov eax, currentBet - jmp ai_raise_amount_ready - -ai_easy_strong_raise: - invoke RandomRange, 3 - cmp eax, 0 - jne ai_no_raise - mov eax, currentBet - xor edx, edx - mov ebx, 2 - div ebx - jmp ai_raise_amount_ready - -ai_normal_strong_raise: - invoke RandomRange, 2 - cmp eax, 0 - je ai_no_raise - mov eax, currentBet - xor edx, edx - mov ebx, 2 - div ebx - jmp ai_raise_amount_ready - -ai_raise_amount_ready: - cmp eax, 50 - jae ai_raise_min_ok - mov eax, 50 -ai_raise_min_ok: - cmp eax, ecx - jbe ai_raise_store - mov eax, ecx -ai_raise_store: - cmp eax, 0 - jbe ai_no_raise - mov pokerAIRaiseAmount, eax - mov pokerRaiseAmount, eax - mov eax, 1 - ret -ai_no_raise: - xor eax, eax - ret -PokerAIRaiseMaybe ENDP -; --- PokerPlayerExchange: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -PokerPlayerExchange PROC uses eax ebx - mov pokerReplaceIndex, 0 -player_exchange_loop: - cmp pokerReplaceIndex, 5 - jae player_exchange_done - call ClearView - invoke PrintTitleColor, OFFSET pokerTitle - call ShowPokerTable - invoke PrintStr, OFFSET pokerReplaceText - mov eax, pokerReplaceIndex - inc eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET pokerReplaceTail - call ReadKey - cmp al, 'y' - je replace_player_card - cmp al, 'Y' - je replace_player_card - cmp al, '1' - je replace_player_card - jmp next_player_exchange -replace_player_card: - call DrawCard - mov ebx, pokerReplaceIndex - mov playerHand21[ebx * 4], eax -next_player_exchange: - inc pokerReplaceIndex - jmp player_exchange_loop -player_exchange_done: - ret -PokerPlayerExchange ENDP - -; --- PokerAIExchange: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -PokerAIExchange PROC uses eax ebx ecx edx - invoke EvaluatePoker, OFFSET aiHand21 - xor edx, edx - mov ebx, 1000 - div ebx - cmp eax, 4 - jae ai_exchange_done - - mov pokerReplaced, 0 - mov pokerReplaceIndex, 0 -ai_exchange_loop: - cmp pokerReplaceIndex, 5 - jae ai_exchange_done - cmp pokerReplaced, 3 - jae ai_exchange_done - - mov ebx, pokerReplaceIndex - mov eax, aiHand21[ebx * 4] - xor edx, edx - mov ecx, 13 - div ecx - cmp byte ptr rankCounts[edx], 1 - jne next_ai_exchange - call DrawCard - mov ebx, pokerReplaceIndex - mov aiHand21[ebx * 4], eax - inc pokerReplaced -next_ai_exchange: - inc pokerReplaceIndex - jmp ai_exchange_loop -ai_exchange_done: - ret -PokerAIExchange ENDP - -; --- AddPlayerBJ: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -AddPlayerBJ PROC uses eax ebx edx - call DrawCard - mov ebx, eax - invoke PrintStr, OFFSET yourCardText - invoke PrintCard, ebx - invoke CardValueBJ, ebx - add playerTotal, eax - cmp eax, 11 - jne no_player_ace - inc playerAces -no_player_ace: - inc playerCards - call AdjustPlayerAces - ret -AddPlayerBJ ENDP - -; --- AddDealerBJ: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -AddDealerBJ PROC uses eax ebx - call DrawCard - mov ebx, eax - invoke PrintStr, OFFSET dealerCardText - invoke PrintCard, ebx - invoke CardValueBJ, ebx - add dealerTotal, eax - cmp eax, 11 - jne no_dealer_ace - inc dealerAces -no_dealer_ace: - call AdjustDealerAces - ret -AddDealerBJ ENDP - -; --- CompareTotals: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -CompareTotals PROC - call PrintScore - cmp playerTotal, 21 - ja player_lost - cmp dealerTotal, 21 - ja dealer_lost - mov eax, playerTotal - cmp eax, dealerTotal - ja player_won - jb player_lost - call PrintDrawEvent - ret -player_won: - call PrintWinEvent - ret -player_lost: - call PrintLoseEvent - ret -dealer_lost: - invoke PrintStr, OFFSET dealerBustText - ret -CompareTotals ENDP - -; --- Game21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -Game21 PROC -start_21: - call ClearView - invoke PrintTitleColor, OFFSET twentyOneTitle - call PromptBet - call ResetDeck - call Reset21Hands - - call DrawPlayer21Hand - call DrawPlayer21Hand - call DrawAI21Hand - call DrawAI21Hand - -player_21_loop: - call ClearView - invoke PrintTitleColor, OFFSET twentyOneTitle - call ShowAllCards21 - - cmp playerTotal, 21 - ja player_21_bust - cmp playerTotal, 21 - je ai_21_turn - - invoke PrintStr, OFFSET hitText - invoke PrintStr, OFFSET cheatMoveText - call ReadKey - cmp al, '1' - je hit_21 - cmp al, 'y' - je hit_21 - cmp al, 'Y' - je hit_21 - cmp al, '3' - je cheat_peek_21_action - cmp al, '4' - je cheat_swap_21_action - jmp ai_21_turn -cheat_peek_21_action: - call CheatPeek21 - jmp player_21_loop -cheat_swap_21_action: - call CheatSwap21 - jmp player_21_loop -hit_21: - cmp playerCnt21, 10 - jae ai_21_turn - call DrawPlayer21Hand - jmp player_21_loop - -player_21_bust: - invoke PrintStr, OFFSET bustText - call PayLose - jmp ask_21_again - -ai_21_turn: -ai_21_cycle: - call ClearView - invoke PrintTitleColor, OFFSET twentyOneTitle - call ShowAllCards21 - - cmp playerTotal, 21 - ja finish_21 - cmp dealerTotal, 21 - je finish_21 - cmp aiDifficulty, 1 - je ai_21_easy - cmp aiDifficulty, 2 - je ai_21_normal - cmp dealerTotal, 12 - jb ai_21_must_hit - - mov eax, dealerTotal - cmp eax, playerTotal - jae finish_21 - - call CountDanger21 - mov eax, dangerLvl21 - mov ebx, 2 - mul ebx - cmp eax, cardsLeft21 - ja finish_21 - jmp ai_21_must_hit - -ai_21_easy: - cmp dealerTotal, 16 - jb ai_21_must_hit - jmp finish_21 - -ai_21_normal: - cmp dealerTotal, 17 - jb ai_21_must_hit - jmp finish_21 - -ai_21_must_hit: - cmp aiCnt21, 10 - jae finish_21 - invoke PrintStr, OFFSET aiMoveText - invoke Sleep, 650 - call DrawAI21Hand - call CalcAIScore21 - cmp dealerTotal, 21 - ja finish_21 - jmp ai_21_cycle - -finish_21: - call AnimateReveal21 - call FinalScreen21 -ask_21_again: - cmp tournamentMode, 1 - je game21_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je start_21 - cmp al, 'Y' - je start_21 -game21_tournament_return: - ret -Game21 ENDP - -; --- GamePoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -GamePoker PROC -start_poker: - call ClearView - invoke PrintTitleColor, OFFSET pokerTitle - call PromptBet - call ResetDeck - call ResetPokerHands - call DealPokerHands - call HardPokerPlayerExchange - call HardPokerAIExchange - -poker_stage_loop: - call ClearView - invoke PrintTitleColor, OFFSET pokerTitle - call ShowPokerTable - call ShowPokerHint - call ShowPokerMoney - cmp communityCnt, 5 - jae poker_showdown - invoke PrintStr, OFFSET pokerDecisionText - invoke PrintStr, OFFSET cheatMoveText - call ReadKey - cmp al, '1' - je poker_play - cmp al, 'y' - je poker_play - cmp al, 'Y' - je poker_play - cmp al, '2' - je poker_raise - cmp al, 'r' - je poker_raise - cmp al, 'R' - je poker_raise - cmp al, '3' - je poker_cheat_peek - cmp al, '4' - je poker_cheat_swap - invoke PrintStr, OFFSET pokerFoldText - call PayLose - jmp ask_poker_again - -poker_cheat_peek: - call CheatPeekPoker - jmp poker_stage_loop -poker_cheat_swap: - call CheatSwapPoker - jmp poker_stage_loop - -poker_raise: - call PromptPokerRaise - cmp eax, 0 - je poker_stage_loop - invoke UnlockAchievement, 200h, OFFSET achPokerRaiseName - invoke PrintStr, OFFSET aiThinkText - invoke Sleep, 700 - call PokerAICallRaise - cmp eax, 0 - jne poker_raise_called - invoke PrintStr, OFFSET pokerAIFoldRaiseText - invoke UnlockAchievement, 400h, OFFSET achPokerBluffName - call PayWin - jmp ask_poker_again -poker_raise_called: - invoke PrintStr, OFFSET pokerAICallRaiseText - invoke Sleep, 700 - jmp poker_next_stage - -poker_play: - invoke PrintStr, OFFSET aiThinkText - invoke Sleep, 700 - call PokerAIDecide - cmp eax, 0 - jne poker_ai_plays - invoke PrintStr, OFFSET pokerAIFoldText - call PayWin - jmp ask_poker_again - -poker_ai_plays: - call PokerAIRaiseMaybe - cmp eax, 0 - je poker_next_stage - invoke PrintStr, OFFSET pokerAIRaiseText - invoke PrintUInt, pokerAIRaiseAmount - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET pokerCallRaiseText - call ReadKey - cmp al, '1' - je poker_call_ai_raise - cmp al, 'y' - je poker_call_ai_raise - cmp al, 'Y' - je poker_call_ai_raise - invoke PrintStr, OFFSET pokerFoldToRaiseText - call PayLose - jmp ask_poker_again -poker_call_ai_raise: - mov eax, currentBet - add eax, pokerAIRaiseAmount - cmp eax, bankroll - jbe poker_call_ai_raise_ok - invoke PrintStr, OFFSET tooBigBetText - invoke PrintStr, OFFSET pokerFoldToRaiseText - call PayLose - jmp ask_poker_again -poker_call_ai_raise_ok: - mov currentBet, eax - invoke PrintStr, OFFSET pokerPlayerCallText - invoke PrintUInt, currentBet - invoke PrintStr, OFFSET nl - invoke Sleep, 700 -poker_next_stage: - cmp communityCnt, 5 - jae poker_showdown - invoke PrintStr, OFFSET pokerNextCardText - invoke Sleep, 900 - inc communityCnt - jmp poker_stage_loop - -poker_showdown: - call AnimateRevealPoker - call ShowPokerResult - -ask_poker_again: - cmp tournamentMode, 1 - je poker_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je start_poker - cmp al, 'Y' - je start_poker -poker_tournament_return: - ret -GamePoker ENDP - -; --- PrintSlotSymbol: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSlotSymbol PROC uses eax, value:DWORD - mov eax, value - cmp eax, 0 - je slot_symbol_green - cmp eax, 1 - je slot_symbol_yellow - cmp eax, 2 - je slot_symbol_red - cmp eax, 3 - je slot_symbol_yellow - cmp eax, 4 - je slot_symbol_cyan - cmp eax, 5 - je slot_symbol_yellow - invoke SetColor, COLOR_BAD - jmp slot_symbol_print -slot_symbol_green: - invoke SetColor, COLOR_MONEY - jmp slot_symbol_print -slot_symbol_yellow: - invoke SetColor, COLOR_WARN - jmp slot_symbol_print -slot_symbol_red: - invoke SetColor, COLOR_BAD - jmp slot_symbol_print -slot_symbol_cyan: - invoke SetColor, COLOR_TITLE -slot_symbol_print: - mov eax, value - invoke PrintStr, slotSymbols[eax * 4] - call ResetColor - ret -PrintSlotSymbol ENDP - -; --- MoveCursor: ñëóæåáíûå ôóíêöèè êîíñîëè è ñëó÷àéíûõ ÷èñåë --- -MoveCursor PROC uses eax edx, xPos:DWORD, yPos:DWORD - mov eax, yPos - shl eax, 16 - mov edx, xPos - and edx, 0FFFFh - or eax, edx - invoke SetConsoleCursorPosition, hOut, eax - ret -MoveCursor ENDP - -; --- PrintSkullAt: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSkullAt PROC uses eax, xPos:DWORD, yPos:DWORD - mov eax, yPos - invoke MoveCursor, xPos, eax - invoke PrintUtf8, OFFSET skullSeg1 - mov eax, yPos - inc eax - invoke MoveCursor, xPos, eax - invoke PrintUtf8, OFFSET skullSeg2 - mov eax, yPos - add eax, 2 - invoke MoveCursor, xPos, eax - invoke PrintUtf8, OFFSET skullSeg3 - mov eax, yPos - add eax, 3 - invoke MoveCursor, xPos, eax - invoke PrintUtf8, OFFSET skullSeg4 - mov eax, yPos - add eax, 4 - invoke MoveCursor, xPos, eax - invoke PrintUtf8, OFFSET skullSeg5 - mov eax, yPos - add eax, 5 - invoke MoveCursor, xPos, eax - invoke PrintUtf8, OFFSET skullSeg6 - mov eax, yPos - add eax, 6 - invoke MoveCursor, xPos, eax - invoke PrintUtf8, OFFSET skullSeg7 - mov eax, yPos - add eax, 7 - invoke MoveCursor, xPos, eax - invoke PrintUtf8, OFFSET skullSeg8 - ret -PrintSkullAt ENDP - -; --- ShowSkullSlideFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -ShowSkullSlideFrame PROC x1:DWORD, y1:DWORD, x2:DWORD, y2:DWORD, x3:DWORD, y3:DWORD - call ClearView - invoke PrintTitleColor, OFFSET skullsTitle - invoke PrintStr, OFFSET skullsShuffleText - invoke PrintSkullAt, x1, y1 - invoke PrintSkullAt, x2, y2 - invoke PrintSkullAt, x3, y3 - invoke Sleep, 220 - ret -ShowSkullSlideFrame ENDP - -; --- AnimateSkullSwap12: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- -AnimateSkullSwap12 PROC - invoke ShowSkullSlideFrame, 0, 5, 18, 5, 36, 5 - invoke ShowSkullSlideFrame, 4, 6, 14, 4, 36, 5 - invoke ShowSkullSlideFrame, 8, 7, 10, 3, 36, 5 - invoke ShowSkullSlideFrame, 14, 6, 4, 4, 36, 5 - invoke ShowSkullSlideFrame, 18, 5, 0, 5, 36, 5 - ret -AnimateSkullSwap12 ENDP - -; --- AnimateSkullSwap23: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- -AnimateSkullSwap23 PROC - invoke ShowSkullSlideFrame, 0, 5, 18, 5, 36, 5 - invoke ShowSkullSlideFrame, 0, 5, 22, 6, 32, 4 - invoke ShowSkullSlideFrame, 0, 5, 26, 7, 28, 3 - invoke ShowSkullSlideFrame, 0, 5, 32, 6, 22, 4 - invoke ShowSkullSlideFrame, 0, 5, 36, 5, 18, 5 - ret -AnimateSkullSwap23 ENDP - -; --- AnimateSkullSwap13: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- -AnimateSkullSwap13 PROC - invoke ShowSkullSlideFrame, 0, 5, 18, 5, 36, 5 - invoke ShowSkullSlideFrame, 8, 7, 18, 5, 28, 3 - invoke ShowSkullSlideFrame, 18, 8, 18, 5, 18, 2 - invoke ShowSkullSlideFrame, 28, 7, 18, 5, 8, 3 - invoke ShowSkullSlideFrame, 36, 5, 18, 5, 0, 5 - ret -AnimateSkullSwap13 ENDP - - -; --- PrintSkullRows: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSkullRows PROC - invoke PrintUtf8, OFFSET skullSeg1 - invoke PrintUtf8, OFFSET skullSeg1 - invoke PrintUtf8, OFFSET skullSeg1 - invoke PrintStr, OFFSET nl - invoke PrintUtf8, OFFSET skullSeg2 - invoke PrintUtf8, OFFSET skullSeg2 - invoke PrintUtf8, OFFSET skullSeg2 - invoke PrintStr, OFFSET nl - invoke PrintUtf8, OFFSET skullSeg3 - invoke PrintUtf8, OFFSET skullSeg3 - invoke PrintUtf8, OFFSET skullSeg3 - invoke PrintStr, OFFSET nl - invoke PrintUtf8, OFFSET skullSeg4 - invoke PrintUtf8, OFFSET skullSeg4 - invoke PrintUtf8, OFFSET skullSeg4 - invoke PrintStr, OFFSET nl - invoke PrintUtf8, OFFSET skullSeg5 - invoke PrintUtf8, OFFSET skullSeg5 - invoke PrintUtf8, OFFSET skullSeg5 - invoke PrintStr, OFFSET nl - invoke PrintUtf8, OFFSET skullSeg6 - invoke PrintUtf8, OFFSET skullSeg6 - invoke PrintUtf8, OFFSET skullSeg6 - invoke PrintStr, OFFSET nl - invoke PrintUtf8, OFFSET skullSeg7 - invoke PrintUtf8, OFFSET skullSeg7 - invoke PrintUtf8, OFFSET skullSeg7 - invoke PrintStr, OFFSET nl - invoke PrintUtf8, OFFSET skullSeg8 - invoke PrintUtf8, OFFSET skullSeg8 - invoke PrintUtf8, OFFSET skullSeg8 - invoke PrintStr, OFFSET nl - ret -PrintSkullRows ENDP -; --- PrintSkulls: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSkulls PROC reveal:DWORD - call PrintSkullRows - invoke PrintStr, OFFSET skullNums - cmp reveal, 0 - je print_skull_blank_ball - mov eax, skullBallPos - cmp eax, 0 - je print_skull_ball_1 - cmp eax, 1 - je print_skull_ball_2 - invoke PrintStr, OFFSET skullBall3 - ret -print_skull_ball_1: - invoke PrintStr, OFFSET skullBall1 - ret -print_skull_ball_2: - invoke PrintStr, OFFSET skullBall2 - ret -print_skull_blank_ball: - invoke PrintStr, OFFSET skullBlankBall - ret -PrintSkulls ENDP -; --- PrintSkullFaces: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintSkullFaces PROC - call PrintSkullRows - invoke PrintStr, OFFSET skullBlankBall - ret -PrintSkullFaces ENDP -; --- ShowSkullShuffleFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -ShowSkullShuffleFrame PROC pSwapText:DWORD - call ClearView - invoke PrintTitleColor, OFFSET skullsTitle - invoke PrintStr, OFFSET skullsShuffleText - invoke PrintStr, pSwapText - call PrintSkullFaces - invoke Sleep, 400 - ret -ShowSkullShuffleFrame ENDP - -; --- ShuffleSkulls: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- -ShuffleSkulls PROC uses eax ebx - cmp aiDifficulty, 1 - je skulls_easy_steps - cmp aiDifficulty, 3 - je skulls_hard_steps - -skulls_normal_steps: - invoke RandomRange, 4 - add eax, 9 - jmp skulls_store_steps - -skulls_easy_steps: - invoke RandomRange, 4 - add eax, 5 - jmp skulls_store_steps - -skulls_hard_steps: - invoke RandomRange, 5 - add eax, 12 - -skulls_store_steps: - mov skullMax, eax - mov skullStep, 0 - -shuffle_skulls_loop: - mov eax, skullStep - cmp eax, skullMax - jae shuffle_skulls_done - - cmp skullStep, 0 - je skulls_play_first_move_sound - mov eax, skullMax - dec eax - cmp skullStep, eax - je skulls_play_last_move_sound - jmp skulls_after_move_sound - -skulls_play_first_move_sound: - call PlayStoneSound - invoke Sleep, 180 - jmp skulls_after_move_sound -skulls_play_last_move_sound: - call PlayStoneSound - -skulls_after_move_sound: - invoke RandomRange, 3 - cmp eax, 0 - je shuffle_12 - cmp eax, 1 - je shuffle_23 - jmp shuffle_13 - -shuffle_12: - mov eax, skullBallPos - cmp eax, 0 - je ball_12_to_2 - cmp eax, 1 - je ball_12_to_1 - jmp show_shuffle_12 -ball_12_to_2: - mov skullBallPos, 1 - jmp show_shuffle_12 -ball_12_to_1: - mov skullBallPos, 0 -show_shuffle_12: - call AnimateSkullSwap12 - jmp shuffle_next - -shuffle_23: - mov eax, skullBallPos - cmp eax, 1 - je ball_23_to_3 - cmp eax, 2 - je ball_23_to_2 - jmp show_shuffle_23 -ball_23_to_3: - mov skullBallPos, 2 - jmp show_shuffle_23 -ball_23_to_2: - mov skullBallPos, 1 -show_shuffle_23: - call AnimateSkullSwap23 - jmp shuffle_next - -shuffle_13: - mov eax, skullBallPos - cmp eax, 0 - je ball_13_to_3 - cmp eax, 2 - je ball_13_to_1 - jmp show_shuffle_13 -ball_13_to_3: - mov skullBallPos, 2 - jmp show_shuffle_13 -ball_13_to_1: - mov skullBallPos, 0 -show_shuffle_13: - call AnimateSkullSwap13 - -shuffle_next: - inc skullStep - jmp shuffle_skulls_loop -shuffle_skulls_done: - ret -ShuffleSkulls ENDP - -; --- GameSkulls: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- -GameSkulls PROC -skulls_start: - call ClearView - invoke PrintTitleColor, OFFSET skullsTitle - invoke PrintStr, OFFSET skullsIntroText - call PromptBet - invoke RandomRange, 3 - mov skullBallPos, eax - - call ClearView - invoke PrintTitleColor, OFFSET skullsTitle - invoke PrintStr, OFFSET skullsShowText - invoke PrintSkulls, 1 - invoke Sleep, 1600 - - call ClearView - invoke PrintTitleColor, OFFSET skullsTitle - invoke PrintStr, OFFSET skullsHideText - invoke PrintSkulls, 0 - invoke Sleep, 800 - - call ShuffleSkulls - -skulls_guess_again: - call ClearView - invoke PrintTitleColor, OFFSET skullsTitle - invoke PrintSkulls, 0 - invoke PrintStr, OFFSET skullsGuessText - call ReadKey - cmp al, '1' - je skull_guess_1 - cmp al, '2' - je skull_guess_2 - cmp al, '3' - je skull_guess_3 - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp skulls_guess_again - -skull_guess_1: - mov skullGuess, 0 - jmp skulls_reveal -skull_guess_2: - mov skullGuess, 1 - jmp skulls_reveal -skull_guess_3: - mov skullGuess, 2 - -skulls_reveal: - call ClearView - invoke PrintTitleColor, OFFSET skullsTitle - invoke PrintSkulls, 1 - invoke PrintStr, OFFSET skullsBallText - mov eax, skullBallPos - inc eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - - mov eax, skullGuess - cmp eax, skullBallPos - jne skulls_lost - invoke PrintStr, OFFSET skullsWinText - invoke PaySlotMultiplier, 2 - jmp ask_skulls_again - -skulls_lost: - invoke PrintStr, OFFSET skullsLoseText - call PayLose - -ask_skulls_again: - cmp tournamentMode, 1 - je skulls_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je skulls_start - cmp al, 'Y' - je skulls_start -skulls_tournament_return: - ret -GameSkulls ENDP -; --- PrintRevolver: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRevolver PROC pGun:DWORD - invoke SetColor, COLOR_WARN - invoke PrintStr, pGun - call ResetColor - ret -PrintRevolver ENDP - -; --- PrintRouletteTurnGun: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRouletteTurnGun PROC - cmp rrTurn, 0 - jne print_rr_ai_gun - invoke PrintRevolver, OFFSET rrGunDown - ret -print_rr_ai_gun: - invoke PrintRevolver, OFFSET rrGunUp - ret -PrintRouletteTurnGun ENDP - -; --- ShowRouletteStatus: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -ShowRouletteStatus PROC - call ClearView - invoke PrintTitleColor, OFFSET rouletteTitle - call PrintRouletteTurnGun - invoke PrintStr, OFFSET rrDangerText - invoke PrintUInt, rrBullets - invoke PrintStr, OFFSET nl - ret -ShowRouletteStatus ENDP - -; --- ShowRouletteSpinFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -ShowRouletteSpinFrame PROC pGun:DWORD - call ClearView - invoke PrintTitleColor, OFFSET rouletteTitle - invoke PrintRevolver, pGun - invoke PrintStr, OFFSET rrSpinText - invoke Sleep, 85 - ret -ShowRouletteSpinFrame ENDP - -; --- AnimateRouletteSpin: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -AnimateRouletteSpin PROC - invoke ShowRouletteSpinFrame, OFFSET rrGunUp - invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDown - invoke ShowRouletteSpinFrame, OFFSET rrGunDownRight - invoke ShowRouletteSpinFrame, OFFSET rrGunRight - invoke ShowRouletteSpinFrame, OFFSET rrGunUpRight - invoke ShowRouletteSpinFrame, OFFSET rrGunUp - invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDown - invoke ShowRouletteSpinFrame, OFFSET rrGunDownRight - invoke ShowRouletteSpinFrame, OFFSET rrGunRight - invoke ShowRouletteSpinFrame, OFFSET rrGunUpRight - cmp rrTurn, 0 - jne roulette_spin_ai_final - invoke ShowRouletteSpinFrame, OFFSET rrGunUp - invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDown - jmp roulette_spin_final_message -roulette_spin_ai_final: - invoke ShowRouletteSpinFrame, OFFSET rrGunUp -roulette_spin_final_message: - call ShowRouletteStatus - cmp rrTurn, 0 - jne roulette_start_ai - invoke PrintStr, OFFSET rrStartsPlayerText - jmp roulette_start_done -roulette_start_ai: - invoke PrintStr, OFFSET rrStartsAIText -roulette_start_done: - invoke Sleep, 400 - ret -AnimateRouletteSpin ENDP - -; --- SetupRoulette: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -SetupRoulette PROC uses eax ebx ecx edx - mov rrBulletMask, 0 - mov eax, aiDifficulty - mov rrBullets, eax - mov ecx, eax -roulette_place_loop: - cmp ecx, 0 - je roulette_setup_done_bullets -roulette_pick_chamber: - invoke RandomRange, 6 - mov ebx, 1 - push ecx - mov ecx, eax - shl ebx, cl - pop ecx - mov edx, rrBulletMask - test edx, ebx - jne roulette_pick_chamber - or rrBulletMask, ebx - dec ecx - jmp roulette_place_loop -roulette_setup_done_bullets: - invoke RandomRange, 6 - mov rrChamber, eax - invoke RandomRange, 2 - mov rrTurn, eax - ret -SetupRoulette ENDP - -; --- RouletteChamberLoaded: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -RouletteChamberLoaded PROC uses ecx edx - mov edx, 1 - mov ecx, rrChamber - shl edx, cl - mov eax, rrBulletMask - test eax, edx - jne roulette_loaded - xor eax, eax - ret -roulette_loaded: - mov eax, 1 - ret -RouletteChamberLoaded ENDP - -; --- AdvanceRouletteChamber: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -AdvanceRouletteChamber PROC - inc rrChamber - cmp rrChamber, 6 - jb advance_roulette_done - mov rrChamber, 0 -advance_roulette_done: - ret -AdvanceRouletteChamber ENDP - -; --- PrintBang: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintBang PROC - call PlayRouletteShotSound - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET rrBangText - call ResetColor - ret -PrintBang ENDP - -; --- GameRoulette: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -GameRoulette PROC -roulette_start: - call ClearView - invoke PrintTitleColor, OFFSET rouletteTitle - invoke PrintStr, OFFSET rrIntroText - call PromptBet - call PlayRouletteSpinSound - call SetupRoulette - call AnimateRouletteSpin - -roulette_turn_loop: - call ShowRouletteStatus - cmp rrTurn, 0 - je roulette_player_turn - -roulette_ai_turn: - invoke PrintStr, OFFSET rrAITurnText - invoke Sleep, 900 - call RouletteChamberLoaded - cmp eax, 1 - je roulette_ai_dead - call PlayRouletteDrySound - invoke PrintStr, OFFSET rrClickText - invoke Sleep, 900 - call AdvanceRouletteChamber - mov rrTurn, 0 - jmp roulette_turn_loop - -roulette_player_turn: - invoke PrintStr, OFFSET rrPlayerTurnText - call ReadAnyKey - invoke PrintStr, OFFSET nl - call RouletteChamberLoaded - cmp eax, 1 - je roulette_player_dead - call PlayRouletteDrySound - invoke PrintStr, OFFSET rrClickText - invoke Sleep, 900 - call AdvanceRouletteChamber - mov rrTurn, 1 - jmp roulette_turn_loop - -roulette_player_dead: - call PrintBang - invoke PrintStr, OFFSET rrPlayerLoseText - call PayLose - jmp ask_roulette_again - -roulette_ai_dead: - invoke UnlockAchievement, 1000h, OFFSET achRussianWinName - call PrintBang - invoke PrintStr, OFFSET rrAIShotText - invoke PrintStr, OFFSET rrPayoutText - mov eax, aiDifficulty - inc eax - mov rrPayout, eax - invoke PaySlotMultiplier, rrPayout - -ask_roulette_again: - cmp tournamentMode, 1 - je roulette_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je roulette_start - cmp al, 'Y' - je roulette_start -roulette_tournament_return: - ret -GameRoulette ENDP - - -; --- ShowBuckshotFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -ShowBuckshotFrame PROC pFrame:DWORD, frameDelay:DWORD - call ClearView - invoke PrintTitleColor, OFFSET buckshotTitle - invoke SetColor, COLOR_CARD - invoke PrintStr, pFrame - call ResetColor - invoke Sleep, frameDelay - ret -ShowBuckshotFrame ENDP - -; --- AnimateBuckshotLoad: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -AnimateBuckshotLoad PROC - invoke ShowBuckshotFrame, OFFSET bsShotgunLoad1, 180 - invoke ShowBuckshotFrame, OFFSET bsShotgunLoad2, 260 - invoke ShowBuckshotFrame, OFFSET bsShotgunLoad3, 260 - ret -AnimateBuckshotLoad ENDP - -; --- AnimateBuckshotFire: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -AnimateBuckshotFire PROC - invoke ShowBuckshotFrame, OFFSET bsShotgunFire, 220 - ret -AnimateBuckshotFire ENDP - -; --- AnimateBuckshotDry: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -AnimateBuckshotDry PROC - invoke ShowBuckshotFrame, OFFSET bsShotgunDry, 180 - ret -AnimateBuckshotDry ENDP -; --- BuckshotGiveItems: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotGiveItems PROC uses eax - invoke RandomRange, 2 - inc eax - mov bsPlayerGlass, eax - invoke RandomRange, 2 - mov bsPlayerSaw, eax - invoke RandomRange, 2 - inc eax - mov bsPlayerBeer, eax - invoke RandomRange, 2 - mov bsPlayerCuffs, eax - invoke RandomRange, 2 - inc eax - mov bsAIGlass, eax - invoke RandomRange, 2 - mov bsAISaw, eax - invoke RandomRange, 2 - inc eax - mov bsAIBeer, eax - invoke RandomRange, 2 - mov bsAICuffs, eax - ret -BuckshotGiveItems ENDP - -; --- BuckshotLoad: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -BuckshotLoad PROC uses eax ebx ecx edi - invoke RandomRange, 5 - add eax, 4 - mov bsShellCount, eax - mov bsShellIndex, 0 - mov bsLiveCount, 0 - mov bsBlankCount, 0 - mov bsKnownShell, 0FFFFFFFFh - mov edi, OFFSET bsShells - mov ecx, bsShellCount -bs_load_loop: - invoke RandomRange, 2 - mov [edi], eax - cmp eax, 1 - je bs_count_live - inc bsBlankCount - jmp bs_count_done -bs_count_live: - inc bsLiveCount -bs_count_done: - add edi, 4 - loop bs_load_loop - cmp bsLiveCount, 0 - jne bs_has_live - mov dword ptr bsShells, 1 - inc bsLiveCount - dec bsBlankCount -bs_has_live: - cmp bsBlankCount, 0 - jne bs_has_blank - mov dword ptr bsShells+4, 0 - inc bsBlankCount - dec bsLiveCount -bs_has_blank: - invoke PrintStr, OFFSET bsLoadText - invoke PrintUInt, bsLiveCount - invoke PrintStr, OFFSET bsLiveText - invoke PrintUInt, bsBlankCount - invoke PrintStr, OFFSET bsBlankText - invoke Sleep, 900 - ret -BuckshotLoad ENDP - -; --- BuckshotCurrentShell: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotCurrentShell PROC uses ebx - mov ebx, bsShellIndex - mov eax, bsShells[ebx*4] - ret -BuckshotCurrentShell ENDP - -; --- BuckshotAdvance: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotAdvance PROC - cmp bsShell, 1 - je bs_advance_live - cmp bsBlankCount, 0 - je bs_advance_count_done - dec bsBlankCount - jmp bs_advance_count_done -bs_advance_live: - cmp bsLiveCount, 0 - je bs_advance_count_done - dec bsLiveCount -bs_advance_count_done: - inc bsShellIndex - mov bsKnownShell, 0FFFFFFFFh - mov bsDamage, 1 - ret -BuckshotAdvance ENDP - -; --- BuckshotRemaining: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotRemaining PROC uses ebx - mov eax, bsShellCount - sub eax, bsShellIndex - ret -BuckshotRemaining ENDP - -; --- BuckshotPrintKnown: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotPrintKnown PROC - mov eax, bsKnownShell - cmp eax, 1 - je bs_print_known_live - cmp eax, 0 - je bs_print_known_blank - invoke PrintStr, OFFSET bsKnownUnknownText - ret -bs_print_known_live: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET bsKnownLiveText - call ResetColor - ret -bs_print_known_blank: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET bsKnownBlankText - call ResetColor - ret -BuckshotPrintKnown ENDP - -; --- BuckshotStatus: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotStatus PROC - call ClearView - invoke PrintTitleColor, OFFSET buckshotTitle - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET bsShotgunArt - call ResetColor - invoke PrintStr, OFFSET bsHPText - invoke PrintUInt, bsPlayerHP - invoke PrintStr, OFFSET bsAIHPText - invoke PrintUInt, bsAIHP - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET bsShellInfoText - invoke PrintUInt, bsLiveCount - invoke PrintStr, OFFSET bsLiveText - invoke PrintUInt, bsBlankCount - invoke PrintStr, OFFSET bsBlankText - invoke PrintStr, OFFSET bsLeftText - call BuckshotRemaining - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - call BuckshotPrintKnown - invoke PrintStr, OFFSET bsItemsText - invoke PrintUInt, bsPlayerGlass - invoke PrintStr, OFFSET bsSawText - invoke PrintUInt, bsPlayerSaw - invoke PrintStr, OFFSET bsBeerText - invoke PrintUInt, bsPlayerBeer - invoke PrintStr, OFFSET bsCuffsText - invoke PrintUInt, bsPlayerCuffs - invoke PrintStr, OFFSET nl - ret -BuckshotStatus ENDP - -; --- BuckshotAfterShotTurn: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotAfterShotTurn PROC - cmp bsShell, 1 - je bs_after_switch - cmp bsTurn, 0 - je bs_after_player_blank - cmp bsTarget, 1 - je bs_after_keep - jmp bs_after_switch -bs_after_player_blank: - cmp bsTarget, 0 - je bs_after_keep -bs_after_switch: - xor bsTurn, 1 -bs_after_keep: - cmp bsTurn, 0 - je bs_check_skip_player - cmp bsSkipAI, 0 - je bs_after_done - mov bsSkipAI, 0 - invoke PrintStr, OFFSET bsSkipAIText - invoke Sleep, 800 - mov bsTurn, 0 - ret -bs_check_skip_player: - cmp bsSkipPlayer, 0 - je bs_after_done - mov bsSkipPlayer, 0 - invoke PrintStr, OFFSET bsSkipPlayerText - invoke Sleep, 800 - mov bsTurn, 1 -bs_after_done: - ret -BuckshotAfterShotTurn ENDP - -; --- BuckshotShoot: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotShoot PROC uses eax ebx - call BuckshotCurrentShell - mov bsShell, eax - cmp bsTarget, 0 - je bs_shoot_player_text - invoke PrintStr, OFFSET bsShootAIText - jmp bs_shoot_text_done -bs_shoot_player_text: - invoke PrintStr, OFFSET bsShootPlayerText -bs_shoot_text_done: - cmp bsShell, 1 - je bs_live_shot - call AnimateBuckshotDry - call PlayRouletteDrySound - invoke PrintStr, OFFSET bsDryText - call BuckshotAdvance - invoke Sleep, 900 - call BuckshotAfterShotTurn - ret -bs_live_shot: - call AnimateBuckshotFire - call PlayRouletteShotSound - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET bsHitText - invoke PrintUInt, bsDamage - invoke PrintStr, OFFSET nl - call ResetColor - mov eax, bsDamage - cmp bsTarget, 0 - je bs_damage_player - cmp bsAIHP, eax - ja bs_sub_ai - mov bsAIHP, 0 - jmp bs_damage_done -bs_sub_ai: - sub bsAIHP, eax - jmp bs_damage_done -bs_damage_player: - cmp bsPlayerHP, eax - ja bs_sub_player - mov bsPlayerHP, 0 - jmp bs_damage_done -bs_sub_player: - sub bsPlayerHP, eax -bs_damage_done: - call BuckshotAdvance - invoke Sleep, 1000 - call BuckshotAfterShotTurn - ret -BuckshotShoot ENDP - -; --- BuckshotUseGlass: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotUseGlass PROC - call BuckshotCurrentShell - mov bsKnownShell, eax - invoke PrintStr, OFFSET bsGlassUseText - call BuckshotPrintKnown - invoke Sleep, 1000 - ret -BuckshotUseGlass ENDP - -; --- BuckshotUseBeer: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotUseBeer PROC - call BuckshotCurrentShell - mov bsShell, eax - invoke PrintStr, OFFSET bsBeerUseText - cmp bsShell, 1 - je bs_beer_live - invoke PrintStr, OFFSET bsBlankLoadedText - jmp bs_beer_done -bs_beer_live: - invoke PrintStr, OFFSET bsLiveLoadedText -bs_beer_done: - call BuckshotAdvance - invoke Sleep, 1000 - ret -BuckshotUseBeer ENDP - -; --- BuckshotPlayerTurn: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotPlayerTurn PROC -bs_player_again: - call BuckshotStatus - invoke PrintStr, OFFSET bsPlayerTurnText - invoke PrintStr, OFFSET bsMenuText - call ReadKey - cmp al, '1' - je bs_player_self - cmp al, '2' - je bs_player_ai - cmp al, '3' - je bs_player_glass - cmp al, '4' - je bs_player_saw - cmp al, '5' - je bs_player_beer - cmp al, '6' - je bs_player_cuffs - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp bs_player_again -bs_player_self: - mov bsTarget, 0 - call BuckshotShoot - ret -bs_player_ai: - mov bsTarget, 1 - call BuckshotShoot - ret -bs_player_glass: - cmp bsPlayerGlass, 0 - je bs_player_no_item - dec bsPlayerGlass - call BuckshotUseGlass - jmp bs_player_again -bs_player_saw: - cmp bsPlayerSaw, 0 - je bs_player_no_item - dec bsPlayerSaw - mov bsDamage, 2 - invoke PrintStr, OFFSET bsSawUseText - invoke Sleep, 900 - jmp bs_player_again -bs_player_beer: - cmp bsPlayerBeer, 0 - je bs_player_no_item - dec bsPlayerBeer - call BuckshotUseBeer - call BuckshotRemaining - cmp eax, 0 - je bs_player_done - jmp bs_player_again -bs_player_cuffs: - cmp bsPlayerCuffs, 0 - je bs_player_no_item - dec bsPlayerCuffs - mov bsSkipAI, 1 - invoke PrintStr, OFFSET bsCuffsUseText - invoke Sleep, 900 - jmp bs_player_again -bs_player_no_item: - invoke PrintStr, OFFSET bsNoItemText - invoke Sleep, 800 - jmp bs_player_again -bs_player_done: - ret -BuckshotPlayerTurn ENDP - -; --- BuckshotAITurn: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -BuckshotAITurn PROC - call BuckshotStatus - invoke PrintStr, OFFSET bsAITurnText - invoke Sleep, 900 - cmp bsKnownShell, 0FFFFFFFFh - jne bs_ai_known - cmp bsAIGlass, 0 - je bs_ai_no_glass - dec bsAIGlass - invoke PrintStr, OFFSET bsAIGlassText - call BuckshotUseGlass -bs_ai_no_glass: -bs_ai_known: - cmp bsKnownShell, 1 - je bs_ai_live - cmp bsKnownShell, 0 - je bs_ai_blank - mov eax, bsLiveCount - cmp eax, bsBlankCount - jae bs_ai_live -bs_ai_blank: - mov bsTarget, 1 - call BuckshotShoot - ret -bs_ai_live: - cmp bsAISaw, 0 - je bs_ai_maybe_cuffs - dec bsAISaw - mov bsDamage, 2 - invoke PrintStr, OFFSET bsAISawText - invoke Sleep, 700 -bs_ai_maybe_cuffs: - cmp bsAICuffs, 0 - je bs_ai_shoot_player - dec bsAICuffs - mov bsSkipPlayer, 1 - invoke PrintStr, OFFSET bsAICuffsText - invoke Sleep, 700 -bs_ai_shoot_player: - mov bsTarget, 0 - call BuckshotShoot - ret -BuckshotAITurn ENDP - -; --- GameBuckshot: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- -GameBuckshot PROC -buckshot_start: - call ClearView - invoke PrintTitleColor, OFFSET buckshotTitle - invoke PrintStr, OFFSET buckshotIntro - call PromptBet - mov bsPlayerHP, 4 - mov bsAIHP, 4 - mov bsTurn, 0 - mov bsDamage, 1 - mov bsSkipPlayer, 0 - mov bsSkipAI, 0 - call BuckshotGiveItems - call PlayRouletteSpinSound - call AnimateBuckshotLoad - call BuckshotLoad -buckshot_loop: - call BuckshotRemaining - cmp eax, 0 - jne buckshot_has_shells - call AnimateBuckshotLoad - call BuckshotLoad -buckshot_has_shells: - cmp bsPlayerHP, 0 - je buckshot_lost - cmp bsAIHP, 0 - je buckshot_won - cmp bsTurn, 0 - je buckshot_player - call BuckshotAITurn - jmp buckshot_loop -buckshot_player: - call BuckshotPlayerTurn - jmp buckshot_loop -buckshot_won: - call BuckshotStatus - invoke PrintStr, OFFSET bsWinText - invoke PaySlotMultiplier, 3 - jmp buckshot_again -buckshot_lost: - call BuckshotStatus - invoke PrintStr, OFFSET bsLoseText - call PayLose -buckshot_again: - call SaveGame - cmp tournamentMode, 1 - je buckshot_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je buckshot_start - cmp al, 'Y' - je buckshot_start -buckshot_tournament_return: - ret -GameBuckshot ENDP -; --- PrintDiceParity: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintDiceParity PROC parity:DWORD - cmp parity, 1 - jne print_dice_odd - invoke PrintStr, OFFSET diceEvenText - ret -print_dice_odd: - invoke PrintStr, OFFSET diceOddText - ret -PrintDiceParity ENDP - -; --- GameDice: êîñòè: áðîñîê, ÷åòíîñòü è ðåçóëüòàò --- -GameDice PROC -dice_start: - call ClearView - invoke PrintTitleColor, OFFSET diceTitle - invoke PrintStr, OFFSET diceIntroText - call PromptBet - -dice_choose: - call ClearView - invoke PrintTitleColor, OFFSET diceTitle - invoke PrintStr, OFFSET diceIntroText - call PrintBank - invoke PrintStr, OFFSET diceChoiceText - call ReadKey - cmp al, '1' - je dice_pick_even - cmp al, '2' - je dice_pick_odd - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp dice_choose - -dice_pick_even: - mov diceChoice, 1 - jmp dice_roll -dice_pick_odd: - mov diceChoice, 2 - -dice_roll: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET diceRollText - call ResetColor - invoke Sleep, 500 - invoke RandomRange, 6 - inc eax - mov diceA, eax - invoke RandomRange, 6 - inc eax - mov diceB, eax - mov eax, diceA - add eax, diceB - mov diceSum, eax - invoke PrintStr, OFFSET diceFirstText - invoke PrintUInt, diceA - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET diceSecondText - invoke PrintUInt, diceB - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET diceSumText - invoke PrintUInt, diceSum - invoke PrintStr, OFFSET nl - mov eax, diceSum - and eax, 1 - cmp eax, 0 - je dice_result_even - mov eax, 2 - jmp dice_compare -dice_result_even: - mov eax, 1 -dice_compare: - cmp eax, diceChoice - je dice_win - call PrintLoseEvent - call PayLose - jmp dice_again -dice_win: - call PrintWinEvent - call PayWin - -dice_again: - cmp tournamentMode, 1 - je dice_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je dice_start - cmp al, 'Y' - je dice_start -dice_tournament_return: - ret -GameDice ENDP -; --- Online Dice: Radmin LAN match without a separate server process --- -onlineTitle db 13,10,"--- Online Casino (Radmin) ---",13,10,0 -onlineMenuText db "1. Host room",13,10,"2. Join room",13,10,"0. Back",13,10,0 -onlineHostInfo db "Give your Radmin IPv4 and port 27015 to your friend.",13,10,"Waiting for one player...",13,10,0 -onlineJoinPrompt db "Host Radmin IPv4: ",0 -onlineConnectingText db "Connecting...",13,10,0 -onlineConnectedText db "Connected.",13,10,0 -onlineYouRollText db "Your roll: ",0 -onlineFriendRollText db "Friend roll: ",0 -onlineWinText db "You win this friendly match.",13,10,0 -onlineLoseText db "Friend wins this friendly match.",13,10,0 -onlineDrawText db "Draw. Same roll.",13,10,0 -onlineErrorText db "Network error. Winsock code: ",0 -onlineBadIpText db "IPv4 address is invalid.",13,10,0 - -OnlineStartWinsock PROC - invoke WSAStartup, 0202h, OFFSET onlineWsaData - test eax, eax - jnz online_start_fail - mov onlineWsaReady, 1 - mov eax, 1 - ret -online_start_fail: - xor eax, eax - ret -OnlineStartWinsock ENDP - -OnlineCleanup PROC - cmp onlinePeerSock, -1 - je online_cleanup_listener - invoke closesocket, onlinePeerSock - mov onlinePeerSock, -1 -online_cleanup_listener: - cmp onlineListenSock, -1 - je online_cleanup_wsa - invoke closesocket, onlineListenSock - mov onlineListenSock, -1 -online_cleanup_wsa: - cmp onlineWsaReady, 1 - jne online_cleanup_done - invoke WSACleanup - mov onlineWsaReady, 0 -online_cleanup_done: - ret -OnlineCleanup ENDP - -OnlineBuildAddress PROC uses eax ecx edi - lea edi, onlineAddr - xor eax, eax - mov ecx, 4 - rep stosd - mov word ptr onlineAddr, AF_INET - mov word ptr onlineAddr+2, ONLINE_PORT_NET - ret -OnlineBuildAddress ENDP - -ReadOnlineIp PROC uses eax ecx esi edi - lea edi, onlineIp - xor eax, eax - mov ecx, 32 - rep stosb - invoke ReadFile, hIn, OFFSET onlineIp, 31, ADDR charsRead, 0 - mov ecx, charsRead - cmp ecx, 31 - jbe online_ip_len_ok - mov ecx, 31 -online_ip_len_ok: - mov byte ptr onlineIp[ecx], 0 - mov esi, OFFSET onlineIp -online_ip_trim: - cmp ecx, 0 - je online_ip_done - mov al, [esi] - cmp al, 13 - je online_ip_end - cmp al, 10 - je online_ip_end - inc esi - dec ecx - jmp online_ip_trim -online_ip_end: - mov byte ptr [esi], 0 -online_ip_done: - ret -ReadOnlineIp ENDP - -NetSendAll PROC uses esi edi, hSocket:DWORD, pData:DWORD, byteCount:DWORD - mov esi, pData - mov edi, byteCount -online_send_loop: - cmp edi, 0 - je online_send_ok - invoke send, hSocket, esi, edi, 0 - test eax, eax - jle online_send_fail - add esi, eax - sub edi, eax - jmp online_send_loop -online_send_ok: - mov eax, 1 - ret -online_send_fail: - xor eax, eax - ret -NetSendAll ENDP - -NetRecvAll PROC uses esi edi, hSocket:DWORD, pData:DWORD, byteCount:DWORD - mov esi, pData - mov edi, byteCount -online_recv_loop: - cmp edi, 0 - je online_recv_ok - invoke recv, hSocket, esi, edi, 0 - test eax, eax - jle online_recv_fail - add esi, eax - sub edi, eax - jmp online_recv_loop -online_recv_ok: - mov eax, 1 - ret -online_recv_fail: - xor eax, eax - ret -NetRecvAll ENDP - -PrintOnlineError PROC - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET onlineErrorText - invoke WSAGetLastError - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - call ResetColor - ret -PrintOnlineError ENDP - -ShowOnlineResult PROC - call ClearView - invoke PrintTitleColor, OFFSET onlineTitle - invoke PrintStr, OFFSET onlineYouRollText - invoke PrintUInt, onlineLocalRoll - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET onlineFriendRollText - invoke PrintUInt, onlineRemoteRoll - invoke PrintStr, OFFSET nl - mov eax, onlineLocalRoll - cmp eax, onlineRemoteRoll - ja online_result_win - jb online_result_lose - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET onlineDrawText - call ResetColor - jmp online_result_done -online_result_win: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET onlineWinText - call ResetColor - jmp online_result_done -online_result_lose: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET onlineLoseText - call ResetColor -online_result_done: - ret -ShowOnlineResult ENDP - -OnlineHostGameText db "Choose online game:",13,10,"1. Dice 1v1",13,10,"2. Russian Roulette 1v1",13,10,"0. Back",13,10,0 -OnlineModeDiceText db "Room mode: Dice 1v1",13,10,0 -OnlineModeRRText db "Room mode: Russian Roulette 1v1",13,10,0 -OnlineProtocolText db "Players use different online protocol versions.",13,10,0 -OnlineRRYourTurnText db "Your turn. Press any key to pull the trigger...",0 -OnlineRRWaitText db "Friend is holding the revolver. Waiting for the trigger...",13,10,0 -OnlineRRStartsYouText db "The revolver points at you. You shoot first.",13,10,0 -OnlineRRStartsFriendText db "The revolver points at your friend. Friend shoots first.",13,10,0 -OnlineRRWinText db "Your friend caught the loaded chamber. You survived.",13,10,0 -OnlineRRLoseText db "The loaded chamber was yours. You lost.",13,10,0 - -OnlineHostConnect PROC - call OnlineStartWinsock - test eax, eax - jz online_host_connect_error - invoke socket, AF_INET, SOCK_STREAM, IPPROTO_TCP - cmp eax, SOCKET_ERROR - je online_host_connect_error - mov onlineListenSock, eax - call OnlineBuildAddress - invoke bind, onlineListenSock, OFFSET onlineAddr, 16 - test eax, eax - jnz online_host_connect_error - invoke listen, onlineListenSock, 1 - test eax, eax - jnz online_host_connect_error - call ClearView - invoke PrintTitleColor, OFFSET onlineTitle - invoke PrintStr, OFFSET onlineHostInfo - invoke accept, onlineListenSock, 0, 0 - cmp eax, SOCKET_ERROR - je online_host_connect_error - mov onlinePeerSock, eax - invoke closesocket, onlineListenSock - mov onlineListenSock, -1 - invoke PrintStr, OFFSET onlineConnectedText - mov eax, 1 - ret -online_host_connect_error: - call PrintOnlineError - call OnlineCleanup - call PauseConsole - xor eax, eax - ret -OnlineHostConnect ENDP - -OnlineJoinConnect PROC - call OnlineStartWinsock - test eax, eax - jz online_join_connect_error - call ClearView - invoke PrintTitleColor, OFFSET onlineTitle - invoke PrintStr, OFFSET onlineJoinPrompt - call ReadOnlineIp - invoke inet_addr, OFFSET onlineIp - cmp eax, 0FFFFFFFFh - je online_join_connect_bad_ip - mov onlineHostIp, eax - invoke socket, AF_INET, SOCK_STREAM, IPPROTO_TCP - cmp eax, SOCKET_ERROR - je online_join_connect_error - mov onlinePeerSock, eax - call OnlineBuildAddress - mov eax, onlineHostIp - mov dword ptr onlineAddr+4, eax - invoke PrintStr, OFFSET onlineConnectingText - invoke connect, onlinePeerSock, OFFSET onlineAddr, 16 - test eax, eax - jnz online_join_connect_error - invoke PrintStr, OFFSET onlineConnectedText - mov eax, 1 - ret -online_join_connect_bad_ip: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET onlineBadIpText - call ResetColor - call OnlineCleanup - call PauseConsole - xor eax, eax - ret -online_join_connect_error: - call PrintOnlineError - call OnlineCleanup - call PauseConsole - xor eax, eax - ret -OnlineJoinConnect ENDP - -OnlineDiceSessionHost PROC - invoke RandomRange, 6 - inc eax - mov onlinePacket, eax - mov onlineLocalRoll, eax - invoke RandomRange, 6 - inc eax - mov onlinePacket+4, eax - mov onlineRemoteRoll, eax - invoke NetSendAll, onlinePeerSock, OFFSET onlinePacket, 8 - test eax, eax - jz online_dice_host_fail - invoke Sleep, 450 - call ShowOnlineResult - mov eax, 1 - ret -online_dice_host_fail: - xor eax, eax - ret -OnlineDiceSessionHost ENDP - -OnlineDiceSessionClient PROC - invoke NetRecvAll, onlinePeerSock, OFFSET onlinePacket, 8 - test eax, eax - jz online_dice_client_fail - mov eax, onlinePacket+4 - mov onlineLocalRoll, eax - mov eax, onlinePacket - mov onlineRemoteRoll, eax - invoke Sleep, 450 - call ShowOnlineResult - mov eax, 1 - ret -online_dice_client_fail: - xor eax, eax - ret -OnlineDiceSessionClient ENDP - -ShowOnlineRRStatus PROC role:DWORD - call ClearView - invoke PrintTitleColor, OFFSET rouletteTitle - mov eax, rrTurn - cmp eax, role - jne online_rr_status_friend - invoke PrintRevolver, OFFSET rrGunDown - jmp online_rr_status_info -online_rr_status_friend: - invoke PrintRevolver, OFFSET rrGunUp -online_rr_status_info: - invoke PrintStr, OFFSET rrDangerText - invoke PrintUInt, rrBullets - invoke PrintStr, OFFSET nl - ret -ShowOnlineRRStatus ENDP - -AnimateOnlineRRStart PROC role:DWORD - invoke ShowRouletteSpinFrame, OFFSET rrGunUp - invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDown - invoke ShowRouletteSpinFrame, OFFSET rrGunDownRight - invoke ShowRouletteSpinFrame, OFFSET rrGunRight - invoke ShowRouletteSpinFrame, OFFSET rrGunUpRight - invoke ShowRouletteSpinFrame, OFFSET rrGunUp - invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft - invoke ShowRouletteSpinFrame, OFFSET rrGunDown - invoke ShowRouletteSpinFrame, OFFSET rrGunDownRight - invoke ShowRouletteSpinFrame, OFFSET rrGunRight - invoke ShowRouletteSpinFrame, OFFSET rrGunUpRight - invoke ShowOnlineRRStatus, role - mov eax, rrTurn - cmp eax, role - jne online_rr_start_friend - invoke PrintStr, OFFSET OnlineRRStartsYouText - ret -online_rr_start_friend: - invoke PrintStr, OFFSET OnlineRRStartsFriendText - ret -AnimateOnlineRRStart ENDP - -ShowOnlineRRShot PROC role:DWORD - cmp onlinePacket, 1 - je online_rr_shot_bang - call PlayRouletteDrySound - invoke PrintStr, OFFSET rrClickText - invoke Sleep, 850 - ret -online_rr_shot_bang: - call PrintBang - mov eax, onlinePacket+4 - cmp eax, role - jne online_rr_shot_win - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET OnlineRRLoseText - call ResetColor - ret -online_rr_shot_win: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET OnlineRRWinText - call ResetColor - ret -ShowOnlineRRShot ENDP - -OnlineRRSessionHost PROC - call SetupRoulette - mov eax, rrBullets - mov onlinePacket, eax - mov eax, rrTurn - mov onlinePacket+4, eax - invoke NetSendAll, onlinePeerSock, OFFSET onlinePacket, 8 - test eax, eax - jz online_rr_host_fail - call PlayRouletteSpinSound - invoke AnimateOnlineRRStart, 0 -online_rr_host_loop: - invoke ShowOnlineRRStatus, 0 - cmp rrTurn, 0 - je online_rr_host_own_turn - invoke PrintStr, OFFSET OnlineRRWaitText - invoke NetRecvAll, onlinePeerSock, OFFSET onlineAction, 4 - test eax, eax - jz online_rr_host_fail - jmp online_rr_host_fire -online_rr_host_own_turn: - invoke PrintStr, OFFSET OnlineRRYourTurnText - call ReadAnyKey - invoke PrintStr, OFFSET nl -online_rr_host_fire: - mov onlinePacket, 0 - call RouletteChamberLoaded - cmp eax, 1 - jne online_rr_host_event_ready - mov onlinePacket, 1 -online_rr_host_event_ready: - mov eax, rrTurn - mov onlinePacket+4, eax - invoke NetSendAll, onlinePeerSock, OFFSET onlinePacket, 8 - test eax, eax - jz online_rr_host_fail - invoke ShowOnlineRRShot, 0 - cmp onlinePacket, 1 - je online_rr_host_done - call AdvanceRouletteChamber - xor rrTurn, 1 - jmp online_rr_host_loop -online_rr_host_done: - mov eax, 1 - ret -online_rr_host_fail: - xor eax, eax - ret -OnlineRRSessionHost ENDP - -OnlineRRSessionClient PROC - invoke NetRecvAll, onlinePeerSock, OFFSET onlinePacket, 8 - test eax, eax - jz online_rr_client_fail - mov eax, onlinePacket - mov rrBullets, eax - mov eax, onlinePacket+4 - mov rrTurn, eax - call PlayRouletteSpinSound - invoke AnimateOnlineRRStart, 1 -online_rr_client_loop: - invoke ShowOnlineRRStatus, 1 - cmp rrTurn, 1 - jne online_rr_client_wait - invoke PrintStr, OFFSET OnlineRRYourTurnText - call ReadAnyKey - invoke PrintStr, OFFSET nl - mov onlineAction, 1 - invoke NetSendAll, onlinePeerSock, OFFSET onlineAction, 4 - test eax, eax - jz online_rr_client_fail - jmp online_rr_client_receive -online_rr_client_wait: - invoke PrintStr, OFFSET OnlineRRWaitText -online_rr_client_receive: - invoke NetRecvAll, onlinePeerSock, OFFSET onlinePacket, 8 - test eax, eax - jz online_rr_client_fail - mov eax, onlinePacket+4 - mov rrTurn, eax - invoke ShowOnlineRRShot, 1 - cmp onlinePacket, 1 - je online_rr_client_done - xor rrTurn, 1 - jmp online_rr_client_loop -online_rr_client_done: - mov eax, 1 - ret -online_rr_client_fail: - xor eax, eax - ret -OnlineRRSessionClient ENDP - -GameOnlineCasino PROC -online_casino_menu: - call ClearView - invoke PrintTitleColor, OFFSET onlineTitle - invoke PrintStr, OFFSET onlineMenuText - invoke PrintStr, OFFSET choiceText - call ReadKey - cmp al, '1' - je online_casino_host_choose - cmp al, '2' - je online_casino_join - cmp al, '0' - je online_casino_done - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET badChoiceText - call ResetColor - invoke Sleep, 650 - jmp online_casino_menu -online_casino_host_choose: - call ClearView - invoke PrintTitleColor, OFFSET onlineTitle - invoke PrintStr, OFFSET OnlineHostGameText - invoke PrintStr, OFFSET choiceText - call ReadKey - cmp al, '1' - je online_casino_host_dice - cmp al, '2' - je online_casino_host_rr - cmp al, '0' - je online_casino_menu - invoke PrintStr, OFFSET badChoiceText - invoke Sleep, 650 - jmp online_casino_host_choose -online_casino_host_dice: - mov onlineGameMode, ONLINE_GAME_DICE - jmp online_casino_host_connect -online_casino_host_rr: - mov onlineGameMode, ONLINE_GAME_RR -online_casino_host_connect: - call OnlineHostConnect - test eax, eax - jz online_casino_done - mov onlinePacket, ONLINE_MAGIC - mov eax, onlineGameMode - mov onlinePacket+4, eax - invoke NetSendAll, onlinePeerSock, OFFSET onlinePacket, 8 - test eax, eax - jz online_casino_session_error - cmp onlineGameMode, ONLINE_GAME_DICE - je online_casino_run_host_dice - invoke PrintStr, OFFSET OnlineModeRRText - call OnlineRRSessionHost - jmp online_casino_session_done -online_casino_run_host_dice: - invoke PrintStr, OFFSET OnlineModeDiceText - call OnlineDiceSessionHost - jmp online_casino_session_done -online_casino_join: - call OnlineJoinConnect - test eax, eax - jz online_casino_done - invoke NetRecvAll, onlinePeerSock, OFFSET onlinePacket, 8 - test eax, eax - jz online_casino_session_error - cmp onlinePacket, ONLINE_MAGIC - jne online_casino_protocol_error - mov eax, onlinePacket+4 - mov onlineGameMode, eax - cmp eax, ONLINE_GAME_DICE - je online_casino_run_client_dice - cmp eax, ONLINE_GAME_RR - je online_casino_run_client_rr - jmp online_casino_protocol_error -online_casino_run_client_dice: - invoke PrintStr, OFFSET OnlineModeDiceText - call OnlineDiceSessionClient - jmp online_casino_session_done -online_casino_run_client_rr: - invoke PrintStr, OFFSET OnlineModeRRText - call OnlineRRSessionClient -online_casino_session_done: - test eax, eax - jz online_casino_session_error - call OnlineCleanup - call PauseConsole - ret -online_casino_protocol_error: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET OnlineProtocolText - call ResetColor - call OnlineCleanup - call PauseConsole - ret -online_casino_session_error: - call PrintOnlineError - call OnlineCleanup - call PauseConsole -online_casino_done: - ret -GameOnlineCasino ENDP - -; --- PrintCoinSide: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintCoinSide PROC side:DWORD - cmp side, 1 - jne print_coin_tails - invoke PrintStr, OFFSET coinHeadsText - ret -print_coin_tails: - invoke PrintStr, OFFSET coinTailsText - ret -PrintCoinSide ENDP - -; --- ShowCoinFlipFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -ShowCoinFlipFrame PROC uses eax, pFrame:DWORD - call ClearView - invoke PrintTitleColor, OFFSET coinTitle - invoke PrintStr, OFFSET coinIntroText - call PrintBank - invoke PrintStr, OFFSET coinPickText - invoke PrintCoinSide, coinPick - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET coinSpinText - mov eax, pFrame - invoke PrintStr, eax - call ResetColor - invoke Sleep, 170 - ret -ShowCoinFlipFrame ENDP - -; --- AnimateCoinFlip: îðåë è ðåøêà: âûáîð ñòîðîíû, çâóê è àíèìàöèÿ ìîíåòû --- -AnimateCoinFlip PROC - invoke ShowCoinFlipFrame, OFFSET coinFrame1 - invoke ShowCoinFlipFrame, OFFSET coinFrame2 - invoke ShowCoinFlipFrame, OFFSET coinFrame3 - invoke ShowCoinFlipFrame, OFFSET coinFrame4 - invoke ShowCoinFlipFrame, OFFSET coinFrame5 - invoke ShowCoinFlipFrame, OFFSET coinFrame6 - invoke ShowCoinFlipFrame, OFFSET coinFrame7 - invoke ShowCoinFlipFrame, OFFSET coinFrame8 - invoke ShowCoinFlipFrame, OFFSET coinFrame9 - invoke ShowCoinFlipFrame, OFFSET coinFrame10 - invoke ShowCoinFlipFrame, OFFSET coinFrame11 - invoke ShowCoinFlipFrame, OFFSET coinFrame12 - invoke ShowCoinFlipFrame, OFFSET coinFrame13 - invoke ShowCoinFlipFrame, OFFSET coinFrame14 - ret -AnimateCoinFlip ENDP - -; --- GameCoin: îðåë è ðåøêà: âûáîð ñòîðîíû, çâóê è àíèìàöèÿ ìîíåòû --- -GameCoin PROC -coin_start: - call ClearView - invoke PrintTitleColor, OFFSET coinTitle - invoke PrintStr, OFFSET coinIntroText - call PromptBet - -coin_choose: - call ClearView - invoke PrintTitleColor, OFFSET coinTitle - invoke PrintStr, OFFSET coinIntroText - call PrintBank - invoke PrintStr, OFFSET coinChoiceText - call ReadKey - cmp al, '1' - je coin_pick_heads - cmp al, '2' - je coin_pick_tails - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp coin_choose - -coin_pick_heads: - mov coinPick, 1 - jmp coin_flip -coin_pick_tails: - mov coinPick, 2 - -coin_flip: - invoke PrintStr, OFFSET coinPickText - invoke PrintCoinSide, coinPick - call PlayCoinSound - call AnimateCoinFlip - invoke RandomRange, 2 - inc eax - mov coinResult, eax - invoke PrintStr, OFFSET coinResultText - invoke PrintCoinSide, coinResult - mov eax, coinPick - cmp eax, coinResult - je coin_win - call PrintLoseEvent - call PayLose - jmp coin_again -coin_win: - call PrintWinEvent - call PayWin - -coin_again: - cmp tournamentMode, 1 - je coin_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je coin_start - cmp al, 'Y' - je coin_start -coin_tournament_return: - ret -GameCoin ENDP - -; --- PrintRouletteColorName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRouletteColorName PROC uses eax ebx, value:DWORD - mov eax, value - cmp eax, 0 - jne roulette_color_not_zero - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET rouletteGreenName - call ResetColor - ret -roulette_color_not_zero: - movzx ebx, byte ptr [rouletteColors + eax] - cmp ebx, 1 - jne roulette_color_black - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET rouletteRedName - call ResetColor - ret -roulette_color_black: - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET rouletteBlackName - call ResetColor - ret -PrintRouletteColorName ENDP - -; --- PrintRouletteNumberColored: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRouletteNumberColored PROC uses eax ebx, value:DWORD - mov eax, value - cmp eax, 0 - jne roulette_number_not_zero - invoke SetColor, COLOR_MONEY - jmp roulette_number_print -roulette_number_not_zero: - movzx ebx, byte ptr [rouletteColors + eax] - cmp ebx, 1 - jne roulette_number_black - invoke SetColor, COLOR_BAD - jmp roulette_number_print -roulette_number_black: - invoke SetColor, COLOR_CARD -roulette_number_print: - invoke PrintUInt, value - call ResetColor - ret -PrintRouletteNumberColored ENDP - -; --- PrintRoulettePocket: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRoulettePocket PROC uses eax, wheelIndex:DWORD - invoke PrintStr, OFFSET roulettePocketLeft - mov eax, wheelIndex - mov eax, [rouletteWheel + eax * 4] - push eax - cmp eax, 10 - jae roulette_pocket_no_pad - invoke PrintStr, OFFSET rouletteNumSpace -roulette_pocket_no_pad: - pop eax - invoke PrintRouletteNumberColored, eax - invoke PrintStr, OFFSET roulettePocketRight - ret -PrintRoulettePocket ENDP - -; --- PrintRoulettePocketOffset: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRoulettePocketOffset PROC uses eax, wheelOffset:DWORD - mov eax, casinoRouletteSpinIndex - add eax, wheelOffset -roulette_offset_wrap: - cmp eax, 37 - jb roulette_offset_ready - sub eax, 37 - jmp roulette_offset_wrap -roulette_offset_ready: - invoke PrintRoulettePocket, eax - ret -PrintRoulettePocketOffset ENDP - -; --- PrintRouletteTopRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRouletteTopRow PROC - invoke PrintStr, OFFSET casinoRoulettePad - invoke PrintRoulettePocketOffset, 31 - invoke PrintRoulettePocketOffset, 32 - invoke PrintRoulettePocketOffset, 33 - invoke PrintRoulettePocketOffset, 34 - invoke PrintRoulettePocketOffset, 35 - invoke PrintRoulettePocketOffset, 36 - invoke PrintRoulettePocketOffset, 0 - invoke PrintRoulettePocketOffset, 1 - invoke PrintRoulettePocketOffset, 2 - invoke PrintRoulettePocketOffset, 3 - invoke PrintRoulettePocketOffset, 4 - invoke PrintRoulettePocketOffset, 5 - invoke PrintRoulettePocketOffset, 6 - invoke PrintStr, OFFSET nl - ret -PrintRouletteTopRow ENDP - -; --- PrintRouletteBottomRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRouletteBottomRow PROC - invoke PrintStr, OFFSET casinoRoulettePad - invoke PrintRoulettePocketOffset, 24 - invoke PrintRoulettePocketOffset, 23 - invoke PrintRoulettePocketOffset, 22 - invoke PrintRoulettePocketOffset, 21 - invoke PrintRoulettePocketOffset, 20 - invoke PrintRoulettePocketOffset, 19 - invoke PrintRoulettePocketOffset, 18 - invoke PrintRoulettePocketOffset, 17 - invoke PrintRoulettePocketOffset, 16 - invoke PrintRoulettePocketOffset, 15 - invoke PrintRoulettePocketOffset, 14 - invoke PrintRoulettePocketOffset, 13 - invoke PrintStr, OFFSET nl - ret -PrintRouletteBottomRow ENDP - -; --- PrintRouletteSideRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintRouletteSideRow PROC leftOffset:DWORD, pGap:DWORD, rightOffset:DWORD - invoke SetColor, COLOR_WOOD - invoke PrintStr, OFFSET rouletteBigSidePad - call ResetColor - invoke PrintRoulettePocketOffset, leftOffset - invoke SetColor, COLOR_TABLE - invoke PrintStr, pGap - call ResetColor - invoke PrintRoulettePocketOffset, rightOffset - invoke PrintStr, OFFSET nl - ret -PrintRouletteSideRow ENDP - -; --- ShowCasinoRouletteFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -ShowCasinoRouletteFrame PROC - call ClearView - invoke PrintTitleColor, OFFSET casinoRouletteTitle - invoke SetColor, COLOR_WOOD - invoke PrintStr, OFFSET casinoRouletteWheelTop - call ResetColor - call PrintRouletteTopRow - invoke PrintRouletteSideRow, 30, OFFSET rouletteBigSideGap1, 7 - invoke PrintRouletteSideRow, 29, OFFSET rouletteBigSideGap2, 8 - invoke PrintRouletteSideRow, 28, OFFSET rouletteBigSideGap3, 9 - invoke PrintRouletteSideRow, 27, OFFSET rouletteBigSideGap4, 10 - invoke PrintRouletteSideRow, 26, OFFSET rouletteBigSideGap5, 11 - invoke PrintRouletteSideRow, 25, OFFSET rouletteBigSideGap6, 12 - call PrintRouletteBottomRow - invoke SetColor, COLOR_WOOD - invoke PrintStr, OFFSET casinoRouletteWheelBottom - call ResetColor - invoke PrintStr, OFFSET casinoRouletteSpinText - ret -ShowCasinoRouletteFrame ENDP - -; --- AnimateCasinoRouletteSpin: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -AnimateCasinoRouletteSpin PROC uses eax ebx edx - invoke GetTickCount - xor seed, eax - invoke RandomRange, 37 - mov casinoRouletteResultIndex, eax - mov ebx, eax - mov eax, [rouletteWheel + ebx * 4] - mov casinoRouletteResult, eax - - invoke RandomRange, 18 - add eax, 72 - mov casinoRouletteSpinSteps, eax - mov casinoRouletteSpinCounter, eax - - xor edx, edx - mov ebx, 37 - div ebx - mov eax, casinoRouletteResultIndex - add eax, 37 - sub eax, edx - cmp eax, 37 - jb casino_roulette_start_ready - sub eax, 37 -casino_roulette_start_ready: - mov casinoRouletteSpinIndex, eax - -casino_roulette_spin_loop: - inc casinoRouletteSpinIndex - cmp casinoRouletteSpinIndex, 37 - jb casino_roulette_spin_index_ok - mov casinoRouletteSpinIndex, 0 -casino_roulette_spin_index_ok: - call ShowCasinoRouletteFrame - mov eax, casinoRouletteSpinCounter - cmp eax, 12 - jbe casino_roulette_sleep_slow - cmp eax, 26 - jbe casino_roulette_sleep_mid - invoke Sleep, 45 - jmp casino_roulette_after_sleep -casino_roulette_sleep_mid: - invoke Sleep, 95 - jmp casino_roulette_after_sleep -casino_roulette_sleep_slow: - invoke Sleep, 170 -casino_roulette_after_sleep: - dec casinoRouletteSpinCounter - cmp casinoRouletteSpinCounter, 0 - jne casino_roulette_spin_loop - mov ebx, casinoRouletteSpinIndex - mov casinoRouletteResultIndex, ebx - mov eax, [rouletteWheel + ebx * 4] - mov casinoRouletteResult, eax - ret -AnimateCasinoRouletteSpin ENDP - -; --- CasinoRouletteEvaluate: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -CasinoRouletteEvaluate PROC uses eax ebx edx - invoke PrintStr, OFFSET casinoRouletteResultText - invoke PrintRouletteNumberColored, casinoRouletteResult - invoke PrintStr, OFFSET rouletteNumSpace - invoke PrintRouletteColorName, casinoRouletteResult - - mov eax, casinoRouletteBetType - cmp eax, 1 - je casino_roulette_eval_number - cmp eax, 2 - je casino_roulette_eval_red - cmp eax, 3 - je casino_roulette_eval_black - cmp eax, 4 - je casino_roulette_eval_even - cmp eax, 5 - je casino_roulette_eval_odd - cmp eax, 6 - je casino_roulette_eval_dozen1 - cmp eax, 7 - je casino_roulette_eval_dozen2 - cmp eax, 8 - je casino_roulette_eval_dozen3 - cmp eax, 9 - je casino_roulette_eval_low - cmp eax, 10 - je casino_roulette_eval_high - cmp eax, 11 - je casino_roulette_eval_col1 - cmp eax, 12 - je casino_roulette_eval_col2 - cmp eax, 13 - je casino_roulette_eval_col3 - jmp casino_roulette_lost - -casino_roulette_eval_number: - mov eax, casinoRouletteResult - cmp eax, casinoRouletteBetNumber - jne casino_roulette_lost - invoke UnlockAchievement, 800h, OFFSET achRouletteWinName - invoke PrintStr, OFFSET casinoRouletteWinText - invoke PaySlotMultiplier, 35 - ret - -casino_roulette_eval_red: - mov eax, casinoRouletteResult - movzx ebx, byte ptr [rouletteColors + eax] - cmp ebx, 1 - je casino_roulette_won_even_money - jmp casino_roulette_lost - -casino_roulette_eval_black: - mov eax, casinoRouletteResult - movzx ebx, byte ptr [rouletteColors + eax] - cmp ebx, 2 - je casino_roulette_won_even_money - jmp casino_roulette_lost - -casino_roulette_eval_even: - mov eax, casinoRouletteResult - cmp eax, 0 - je casino_roulette_lost - test eax, 1 - jz casino_roulette_won_even_money - jmp casino_roulette_lost - -casino_roulette_eval_odd: - mov eax, casinoRouletteResult - cmp eax, 0 - je casino_roulette_lost - test eax, 1 - jnz casino_roulette_won_even_money - jmp casino_roulette_lost - -casino_roulette_eval_dozen1: - mov eax, casinoRouletteResult - cmp eax, 1 - jb casino_roulette_lost - cmp eax, 12 - jbe casino_roulette_won_double - jmp casino_roulette_lost -casino_roulette_eval_dozen2: - mov eax, casinoRouletteResult - cmp eax, 13 - jb casino_roulette_lost - cmp eax, 24 - jbe casino_roulette_won_double - jmp casino_roulette_lost -casino_roulette_eval_dozen3: - mov eax, casinoRouletteResult - cmp eax, 25 - jb casino_roulette_lost - cmp eax, 36 - jbe casino_roulette_won_double - jmp casino_roulette_lost -casino_roulette_eval_low: - mov eax, casinoRouletteResult - cmp eax, 1 - jb casino_roulette_lost - cmp eax, 18 - jbe casino_roulette_won_even_money - jmp casino_roulette_lost -casino_roulette_eval_high: - mov eax, casinoRouletteResult - cmp eax, 36 - jbe casino_roulette_won_even_money - jmp casino_roulette_lost -casino_roulette_eval_col1: - mov eax, casinoRouletteResult - cmp eax, 0 - je casino_roulette_lost - dec eax - xor edx, edx - mov ebx, 3 - div ebx - cmp edx, 0 - je casino_roulette_won_double - jmp casino_roulette_lost -casino_roulette_eval_col2: - mov eax, casinoRouletteResult - cmp eax, 0 - je casino_roulette_lost - dec eax - xor edx, edx - mov ebx, 3 - div ebx - cmp edx, 1 - je casino_roulette_won_double - jmp casino_roulette_lost -casino_roulette_eval_col3: - mov eax, casinoRouletteResult - cmp eax, 0 - je casino_roulette_lost - dec eax - xor edx, edx - mov ebx, 3 - div ebx - cmp edx, 2 - je casino_roulette_won_double - jmp casino_roulette_lost - -casino_roulette_won_double: - invoke UnlockAchievement, 800h, OFFSET achRouletteWinName - invoke PrintStr, OFFSET casinoRouletteWinText - invoke PaySlotMultiplier, 2 - ret -casino_roulette_won_even_money: - invoke UnlockAchievement, 800h, OFFSET achRouletteWinName - invoke PrintStr, OFFSET casinoRouletteWinText - call PayWin - ret -casino_roulette_lost: - invoke PrintStr, OFFSET casinoRouletteLoseText - call PayLose - ret -CasinoRouletteEvaluate ENDP - -; --- GameCasinoRoulette: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -GameCasinoRoulette PROC -casino_roulette_start: - call ClearView - invoke PrintTitleColor, OFFSET casinoRouletteTitle - invoke PrintStr, OFFSET casinoRouletteIntro - call PromptBet - -casino_roulette_choose: - call ClearView - invoke PrintTitleColor, OFFSET casinoRouletteTitle - invoke PrintStr, OFFSET casinoRouletteIntro - call PrintBank - invoke PrintStr, OFFSET casinoRouletteBetMenu - call ReadUInt - cmp eax, 1 - je casino_roulette_choose_number - cmp eax, 2 - je casino_roulette_choose_red - cmp eax, 3 - je casino_roulette_choose_black - cmp eax, 4 - je casino_roulette_choose_even - cmp eax, 5 - je casino_roulette_choose_odd - cmp eax, 6 - je casino_roulette_choose_dozen1 - cmp eax, 7 - je casino_roulette_choose_dozen2 - cmp eax, 8 - je casino_roulette_choose_dozen3 - cmp eax, 9 - je casino_roulette_choose_low - cmp eax, 10 - je casino_roulette_choose_high - cmp eax, 11 - je casino_roulette_choose_col1 - cmp eax, 12 - je casino_roulette_choose_col2 - cmp eax, 13 - je casino_roulette_choose_col3 - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp casino_roulette_choose - -casino_roulette_choose_number: - mov casinoRouletteBetType, 1 - invoke PrintStr, OFFSET casinoRouletteNumberAsk - call ReadUInt - cmp eax, 36 - ja casino_roulette_bad_number - mov casinoRouletteBetNumber, eax - jmp casino_roulette_spin -casino_roulette_bad_number: - invoke PrintStr, OFFSET casinoRouletteBadNumber - call PauseConsole - jmp casino_roulette_choose - -casino_roulette_choose_red: - mov casinoRouletteBetType, 2 - jmp casino_roulette_spin -casino_roulette_choose_black: - mov casinoRouletteBetType, 3 - jmp casino_roulette_spin -casino_roulette_choose_even: - mov casinoRouletteBetType, 4 - jmp casino_roulette_spin -casino_roulette_choose_odd: - mov casinoRouletteBetType, 5 - jmp casino_roulette_spin -casino_roulette_choose_dozen1: - mov casinoRouletteBetType, 6 - jmp casino_roulette_spin -casino_roulette_choose_dozen2: - mov casinoRouletteBetType, 7 - jmp casino_roulette_spin -casino_roulette_choose_dozen3: - mov casinoRouletteBetType, 8 - jmp casino_roulette_spin -casino_roulette_choose_low: - mov casinoRouletteBetType, 9 - jmp casino_roulette_spin -casino_roulette_choose_high: - mov casinoRouletteBetType, 10 - jmp casino_roulette_spin -casino_roulette_choose_col1: - mov casinoRouletteBetType, 11 - jmp casino_roulette_spin -casino_roulette_choose_col2: - mov casinoRouletteBetType, 12 - jmp casino_roulette_spin -casino_roulette_choose_col3: - mov casinoRouletteBetType, 13 - -casino_roulette_spin: - call PlayCasinoRouletteSound - call AnimateCasinoRouletteSpin - call CasinoRouletteEvaluate - -casino_roulette_again: - cmp tournamentMode, 1 - je casino_roulette_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je casino_roulette_start - cmp al, 'Y' - je casino_roulette_start -casino_roulette_tournament_return: - ret -GameCasinoRoulette ENDP -; --- SlotApplyWin: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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 - inc slotComboCount -slot_apply_no_store: - mov eax, 1 - ret - -slot_apply_skip: - xor eax, eax - ret -SlotApplyWin ENDP - -; --- SlotSame3: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -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 - -; --- AwardSlotWin: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -AwardSlotWin PROC uses ebx - invoke UnlockAchievement, 80h, OFFSET achCloverPitName - call PrintSlotWindow - invoke PrintStr, OFFSET slotPair - mov slotCurrentCell, 0 -slot_award_combo_loop: - mov eax, slotCurrentCell - cmp eax, slotComboCount - jae slot_award_combo_done - invoke PrintStr, OFFSET slotComboText - mov ebx, slotCurrentCell - mov eax, slotComboNames[ebx * 4] - invoke PrintStr, eax - invoke PrintStr, OFFSET cardGap - invoke PrintStr, OFFSET slotMultiplierText - mov ebx, slotCurrentCell - mov eax, slotComboMults[ebx * 4] - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - inc slotCurrentCell - jmp slot_award_combo_loop -slot_award_combo_done: - invoke PrintStr, OFFSET slotTotalMultiplierText - invoke PrintUInt, slotBestMultiplier - invoke PrintStr, OFFSET nl - cmp slotJackpotHit, 1 - jne slot_award_regular - call PlayJackpotSound - invoke Sleep, 650 - call PlayHakariSound - call PlayHakariDance - call PrintSlotWindow -slot_award_regular: - invoke PaySlotMultiplier, slotBestMultiplier - ret -AwardSlotWin ENDP -; --- GameSlot: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -GameSlot PROC -slot_start: - call ClearView - invoke PrintTitleColor, OFFSET slotTitle - invoke PrintStr, OFFSET slotPayTableText - call PromptBet - call PlaySlotSound - invoke Sleep, 400 - invoke PrintStr, OFFSET slotPullText - mov slotWinMask, 0 - mov slotVisible, 0 - call PrintSlotWindow - invoke Sleep, 1400 - - invoke FillSlotColumn, 0 - mov slotVisible, 1 - call PrintSlotWindow - invoke Sleep, 620 - - invoke FillSlotColumn, 1 - mov slotVisible, 2 - call PrintSlotWindow - invoke Sleep, 620 - - invoke FillSlotColumn, 2 - mov slotVisible, 3 - call PrintSlotWindow - invoke Sleep, 620 - - invoke FillSlotColumn, 3 - mov slotVisible, 4 - call PrintSlotWindow - invoke Sleep, 620 - - invoke FillSlotColumn, 4 - mov slotVisible, 5 - call PrintSlotWindow - invoke Sleep, 450 - - cmp cheatSlotJackpot, 1 - jne slot_no_forced_jackpot - mov cheatSlotJackpot, 0 - mov ecx, 15 - mov edi, OFFSET slotGrid -slot_force_jackpot_loop: - mov dword ptr [edi], 6 - add edi, 4 - loop slot_force_jackpot_loop - call PrintSlotWindow - invoke Sleep, 300 -slot_no_forced_jackpot: - - call EvaluateSlotCombos - cmp slotBestMultiplier, 0 - jne slot_has_win - invoke PrintStr, OFFSET slotEmpty - call PayLose - jmp ask_slot_again - -slot_has_win: - call AwardSlotWin - -ask_slot_again: - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je slot_start - cmp al, 'Y' - je slot_start - ret -GameSlot ENDP -; --- PrintClassicSlotSymbol: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintClassicSlotSymbol PROC uses eax, value:DWORD - mov eax, value - cmp eax, 0 - je classic_symbol_red - cmp eax, 1 - je classic_symbol_yellow - cmp eax, 2 - je classic_symbol_green - cmp eax, 5 - je classic_symbol_cyan - invoke SetColor, COLOR_WARN - jmp classic_symbol_print -classic_symbol_red: - invoke SetColor, COLOR_BAD - jmp classic_symbol_print -classic_symbol_yellow: - invoke SetColor, COLOR_WARN - jmp classic_symbol_print -classic_symbol_green: - invoke SetColor, COLOR_MONEY - jmp classic_symbol_print -classic_symbol_cyan: - invoke SetColor, COLOR_TITLE -classic_symbol_print: - mov eax, value - invoke PrintStr, classicSlotSymbols[eax * 4] - call ResetColor - ret -PrintClassicSlotSymbol ENDP - -; --- PrintClassicSlotCell: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintClassicSlotCell PROC uses eax, value:DWORD - mov eax, value - cmp eax, 1 - je classic_slot_cell_bar - invoke PrintStr, OFFSET slotWall - invoke PrintStr, OFFSET slotPadTwo - invoke PrintClassicSlotSymbol, value - invoke PrintStr, OFFSET slotPadTwo - ret -classic_slot_cell_bar: - invoke PrintStr, OFFSET slotWall - invoke PrintStr, OFFSET slotPadOne - invoke PrintClassicSlotSymbol, value - invoke PrintStr, OFFSET slotPadOne - ret -PrintClassicSlotCell ENDP - -; --- PrintClassicSlotBlankCell: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintClassicSlotBlankCell PROC - invoke PrintStr, OFFSET slotWall - invoke PrintStr, OFFSET slotCellBlank - ret -PrintClassicSlotBlankCell ENDP - -; --- PrintClassicSlotWindow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintClassicSlotWindow PROC uses eax ebx - call ClearView - invoke PrintTitleColor, OFFSET classicSlotTitle - invoke PrintStr, OFFSET classicSlotBorder - - mov rowIndex, 0 -classic_slot_window_row_loop: - cmp rowIndex, 3 - jae classic_slot_window_done - mov ebx, rowIndex - imul ebx, 3 - - cmp slotVisible, 1 - jb classic_slot_blank_col1 - invoke PrintClassicSlotCell, slotGrid[ebx * 4] - jmp classic_slot_col2 -classic_slot_blank_col1: - call PrintClassicSlotBlankCell - -classic_slot_col2: - cmp slotVisible, 2 - jb classic_slot_blank_col2 - mov eax, ebx - inc eax - invoke PrintClassicSlotCell, slotGrid[eax * 4] - jmp classic_slot_col3 -classic_slot_blank_col2: - call PrintClassicSlotBlankCell - -classic_slot_col3: - cmp slotVisible, 3 - jb classic_slot_blank_col3 - mov eax, ebx - add eax, 2 - invoke PrintClassicSlotCell, slotGrid[eax * 4] - jmp classic_slot_row_end -classic_slot_blank_col3: - call PrintClassicSlotBlankCell - -classic_slot_row_end: - invoke PrintStr, OFFSET slotWall - invoke PrintStr, OFFSET nl - cmp rowIndex, 1 - jne classic_no_payline - invoke PrintStr, OFFSET classicSlotPayline -classic_no_payline: - invoke PrintStr, OFFSET classicSlotBorder - inc rowIndex - jmp classic_slot_window_row_loop - -classic_slot_window_done: - ret -PrintClassicSlotWindow ENDP - -; --- FillClassicSlotColumn: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -FillClassicSlotColumn PROC uses eax ebx, column:DWORD - mov ebx, column - invoke RandomRange, 6 - mov slotGrid[ebx * 4], eax - mov ebx, column - add ebx, 3 - invoke RandomRange, 6 - mov slotGrid[ebx * 4], eax - mov ebx, column - add ebx, 7 - invoke RandomRange, 6 - mov slotGrid[ebx * 4], eax - ret -FillClassicSlotColumn ENDP - -; --- DurakCardRank: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -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: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -DurakCardSuit PROC uses ecx edx, card:DWORD - mov eax, card - xor edx, edx - mov ecx, 13 - div ecx - ret -DurakCardSuit ENDP - -; --- DrawDurakCard: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -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 - -; --- PrintDurakCardName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintDurakCardName PROC uses eax ebx ecx edx, card:DWORD - mov eax, card - cmp eax, 0FFFFFFFFh - jne print_durak_card_real - invoke PrintStr, OFFSET durakUnbeatenText - ret -print_durak_card_real: - xor edx, edx - mov ecx, 13 - div ecx - mov ebx, eax - mov eax, edx - invoke PrintStr, ranks[eax * 4] - invoke PrintSuit, ebx - ret -PrintDurakCardName ENDP - -; --- AddDurakCard: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -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: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -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: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -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 - -; --- DrawDurakPlayer: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -DrawDurakPlayer PROC - call PlayCardSound - call DrawDurakCard - cmp eax, 0FFFFFFFFh - je draw_durak_player_done - invoke AddDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, eax -draw_durak_player_done: - ret -DrawDurakPlayer ENDP - -; --- DrawDurakAI: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -DrawDurakAI PROC - call PlayCardSound - call DrawDurakCard - cmp eax, 0FFFFFFFFh - je draw_durak_ai_done - invoke AddDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, eax -draw_durak_ai_done: - ret -DrawDurakAI ENDP - -; --- RefillDurakHands: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -RefillDurakHands PROC -refill_player_loop: - cmp durakPlayerCnt, 6 - jae refill_ai_loop - cmp durakDeckLeft, 0 - jbe refill_ai_loop - call DrawDurakPlayer - jmp refill_player_loop -refill_ai_loop: - cmp durakAICnt, 6 - jae refill_done - cmp durakDeckLeft, 0 - jbe refill_done - call DrawDurakAI - jmp refill_ai_loop -refill_done: - ret -RefillDurakHands ENDP -; --- RefillDurakHandsAIFirst: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -RefillDurakHandsAIFirst PROC -refill_ai_first_loop: - cmp durakAICnt, 6 - jae refill_player_after_ai_loop - cmp durakDeckLeft, 0 - jbe refill_player_after_ai_loop - call DrawDurakAI - jmp refill_ai_first_loop -refill_player_after_ai_loop: - cmp durakPlayerCnt, 6 - jae refill_ai_first_done - cmp durakDeckLeft, 0 - jbe refill_ai_first_done - call DrawDurakPlayer - jmp refill_player_after_ai_loop -refill_ai_first_done: - ret -RefillDurakHandsAIFirst ENDP - -; --- PrintDurakHand: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintDurakHand PROC uses eax ebx, pHand:DWORD, count:DWORD - mov rowIndex, 0 -print_durak_hand_loop: - mov eax, rowIndex - cmp eax, count - jae print_durak_hand_done - inc eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET dotSpaceText - mov ebx, pHand - mov eax, rowIndex - invoke PrintDurakCardName, dword ptr [ebx + eax * 4] - invoke PrintStr, OFFSET cardGap - inc rowIndex - jmp print_durak_hand_loop -print_durak_hand_done: - invoke PrintStr, OFFSET nl - ret -PrintDurakHand ENDP - -; --- PrintDurakTable: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintDurakTable PROC uses ebx - cmp durakTableCnt, 0 - je print_table_done - invoke PrintStr, OFFSET durakTablePairsText - invoke PrintHandRow21, OFFSET durakAttackCards, durakTableCnt, 1 - mov rowIndex, 0 -print_table_pairs_loop: - mov eax, rowIndex - cmp eax, durakTableCnt - jae print_table_done - inc eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET dotSpaceText - mov ebx, rowIndex - invoke PrintDurakCardName, durakAttackCards[ebx * 4] - invoke PrintStr, OFFSET durakSlashText - invoke PrintDurakCardName, durakDefenseCards[ebx * 4] - invoke PrintStr, OFFSET nl - inc rowIndex - jmp print_table_pairs_loop -print_table_done: - ret -PrintDurakTable ENDP - -; --- ShowDurakTable: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -ShowDurakTable PROC - call ClearView - invoke PrintTitleColor, OFFSET durakTitle - invoke PrintStr, OFFSET durakDeckVisualText - invoke PrintDurakCardName, durakTrumpCard - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET durakDeckText - invoke PrintUInt, durakDeckLeft - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET durakAICardsText - invoke PrintUInt, durakAICnt - invoke PrintStr, OFFSET nl - cmp durakAICnt, 10 - ja show_ai_no_graphics - invoke PrintStr, OFFSET durakAIFaceText - invoke PrintHandRow21, OFFSET durakAIHand, durakAICnt, 0 -show_ai_no_graphics: - call PrintDurakTable - invoke PrintStr, OFFSET durakYourHandText - cmp durakPlayerCnt, 10 - ja show_player_list_only - invoke PrintHandRow21, OFFSET durakPlayerHand, durakPlayerCnt, 1 -show_player_list_only: - invoke PrintDurakHand, OFFSET durakPlayerHand, durakPlayerCnt - ret -ShowDurakTable ENDP - -; --- FindAIDurakDefense: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -FindAIDurakDefense PROC uses ebx ecx, tableIndex:DWORD - mov rowIndex, 0 -find_ai_defense_loop: - mov eax, rowIndex - cmp eax, durakAICnt - jae find_ai_defense_no - mov ebx, OFFSET durakAIHand - mov ecx, [ebx + eax * 4] - mov ebx, tableIndex - invoke CanDurakBeat, durakAttackCards[ebx * 4], ecx - cmp eax, 1 - je find_ai_defense_yes - inc rowIndex - jmp find_ai_defense_loop -find_ai_defense_yes: - mov eax, rowIndex - ret -find_ai_defense_no: - mov eax, 0FFFFFFFFh - ret -FindAIDurakDefense ENDP - -; --- AIDefendAll: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -AIDefendAll PROC uses ebx - mov durakLoopGuard, 0 -ai_defend_loop: - inc durakLoopGuard - cmp durakLoopGuard, 20 - ja ai_defend_fail - call DurakFirstUnbeaten - cmp eax, 0FFFFFFFFh - je ai_defend_success - mov ebx, eax - invoke FindAIDurakDefense, ebx - cmp eax, 0FFFFFFFFh - je ai_defend_fail - invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, eax - mov durakDefenseCards[ebx * 4], eax - jmp ai_defend_loop -ai_defend_success: - mov eax, 1 - ret -ai_defend_fail: - xor eax, eax - ret -AIDefendAll ENDP - -; --- FindAIThrowIn: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -FindAIThrowIn PROC uses ebx ecx - cmp durakTableCnt, 6 - jae ai_throw_none - mov eax, durakTableCnt - cmp eax, durakPlayerCnt - jae ai_throw_none - mov rowIndex, 0 -ai_throw_loop: - mov eax, rowIndex - cmp eax, durakAICnt - jae ai_throw_none - mov ebx, OFFSET durakAIHand - mov ecx, [ebx + eax * 4] - invoke DurakRankOnTable, ecx - cmp eax, 1 - je ai_throw_found - inc rowIndex - jmp ai_throw_loop -ai_throw_found: - mov eax, rowIndex - ret -ai_throw_none: - mov eax, 0FFFFFFFFh - ret -FindAIThrowIn ENDP - -; --- CheckDurakEnd: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -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 - -; --- SetupDurak: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -SetupDurak PROC uses ecx - call ResetDeck - mov durakPlayerCnt, 0 - mov durakAICnt, 0 - mov durakDeckLeft, 36 - mov durakPlayerTurn, 1 - mov durakSafeTurns, 0 - call ClearDurakTable - call DrawDurakCard - mov durakTrumpCard, eax - invoke DurakCardSuit, eax - mov durakTrumpSuit, eax - mov ecx, 6 -setup_durak_deal: - call DrawDurakPlayer - call DrawDurakAI - loop setup_durak_deal - ret -SetupDurak ENDP - -; --- PlayerOpenAttackLoop: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayerOpenAttackLoop PROC uses ebx ecx -player_open_attack_loop: - mov eax, durakTableCnt - cmp eax, 6 - jae player_open_attack_done - cmp eax, durakAICnt - jae player_open_attack_done - call ShowDurakTable - invoke PrintStr, OFFSET durakThrowAsk - call ReadUInt - cmp eax, 0 - je player_open_attack_done - cmp eax, 1 - jb player_open_attack_bad - cmp eax, durakPlayerCnt - ja player_open_attack_bad - dec eax - mov durakChoice, eax - mov ebx, OFFSET durakPlayerHand - mov ecx, [ebx + eax * 4] - invoke DurakRankOnTable, ecx - cmp eax, 1 - jne player_open_attack_bad - invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, durakChoice - call AddDurakAttack - jmp player_open_attack_loop -player_open_attack_bad: - invoke PrintStr, OFFSET durakBadMoveText - invoke Sleep, 650 - jmp player_open_attack_loop -player_open_attack_done: - ret -PlayerOpenAttackLoop ENDP - -; --- AIInitialThrowLoop: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -AIInitialThrowLoop PROC - mov durakLoopGuard, 0 -ai_initial_throw_loop: - inc durakLoopGuard - cmp durakLoopGuard, 20 - ja ai_initial_throw_done - call FindAIThrowIn - cmp eax, 0FFFFFFFFh - je ai_initial_throw_done - invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, eax - call AddDurakAttack - jmp ai_initial_throw_loop -ai_initial_throw_done: - ret -AIInitialThrowLoop ENDP -; --- PlayerThrowLoop: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayerThrowLoop PROC uses ebx ecx - mov durakLoopGuard, 0 -player_throw_loop: - inc durakLoopGuard - cmp durakLoopGuard, 30 - ja player_throw_done - call ShowDurakTable - call AIDefendAll - cmp eax, 1 - je player_throw_after_defense - invoke CollectDurakTable, OFFSET durakAIHand, OFFSET durakAICnt - invoke PrintStr, OFFSET durakAITakeText - mov durakPlayerTurn, 1 - call RefillDurakHands - call PauseConsole - ret -player_throw_after_defense: - call ShowDurakTable - invoke PrintStr, OFFSET durakThrowAsk - call ReadUInt - cmp eax, 0 - je player_throw_done - cmp eax, 1 - jb player_throw_bad - cmp eax, durakPlayerCnt - ja player_throw_bad - cmp durakTableCnt, 6 - jae player_throw_bad - dec eax - mov durakChoice, eax - mov ebx, OFFSET durakPlayerHand - mov ecx, [ebx + eax * 4] - invoke DurakRankOnTable, ecx - cmp eax, 1 - jne player_throw_bad - invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, durakChoice - call AddDurakAttack - jmp player_throw_loop -player_throw_bad: - invoke PrintStr, OFFSET durakBadMoveText - invoke Sleep, 650 - jmp player_throw_loop -player_throw_done: - call ClearDurakTable - mov durakPlayerTurn, 0 - call RefillDurakHands - ret -PlayerThrowLoop ENDP - -; --- PlayerDefendLoop: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayerDefendLoop PROC uses ebx ecx - mov durakLoopGuard, 0 -player_defend_loop: - inc durakLoopGuard - cmp durakLoopGuard, 30 - ja player_take_table - call DurakAllDefended - cmp eax, 1 - je player_defended_all - call ShowDurakTable - invoke PrintStr, OFFSET durakDefendAsk - call ReadUInt - cmp eax, 0 - je player_take_table - cmp eax, 1 - jb player_def_bad - cmp eax, durakPlayerCnt - ja player_def_bad - dec eax - mov durakChoice, eax - mov ebx, OFFSET durakPlayerHand - mov ecx, [ebx + eax * 4] - - call DurakTableHasDefense - cmp eax, 0 - jne player_try_beat - invoke DurakRankOnTable, ecx - cmp eax, 1 - jne player_try_beat - mov eax, durakTableCnt - cmp durakAICnt, eax - jbe player_try_beat - invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, durakChoice - call AddDurakAttack - invoke PrintStr, OFFSET durakTransferText - call PauseConsole - call PlayerThrowLoop - ret - -player_try_beat: - call DurakFirstUnbeaten - mov ebx, eax - mov ecx, OFFSET durakPlayerHand - mov eax, durakChoice - mov ecx, [ecx + eax * 4] - invoke CanDurakBeat, durakAttackCards[ebx * 4], ecx - cmp eax, 1 - jne player_def_bad - invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, durakChoice - mov durakDefenseCards[ebx * 4], eax - jmp player_defend_loop -player_def_bad: - invoke PrintStr, OFFSET durakBadMoveText - invoke Sleep, 650 - jmp player_defend_loop -player_take_table: - invoke CollectDurakTable, OFFSET durakPlayerHand, OFFSET durakPlayerCnt - invoke PrintStr, OFFSET durakPlayerTakeText - mov durakPlayerTurn, 0 - call RefillDurakHandsAIFirst - call PauseConsole - ret -player_defended_all: - call FindAIThrowIn - cmp eax, 0FFFFFFFFh - je player_defense_done - invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, eax - call AddDurakAttack - jmp player_defend_loop -player_defense_done: - invoke PrintStr, OFFSET durakPlayerDefendText - call ClearDurakTable - mov durakPlayerTurn, 1 - call RefillDurakHandsAIFirst - call PauseConsole - ret -PlayerDefendLoop ENDP - -; --- GameDurak: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -GameDurak PROC - durak_start: - call ClearView - invoke PrintTitleColor, OFFSET durakTitle - call PromptBet - call SetupDurak - -durak_round_loop: - call CheckDurakEnd - cmp eax, 1 - je durak_finish_win - cmp eax, 2 - je durak_finish_lose - cmp eax, 3 - je durak_finish_draw - inc durakSafeTurns - cmp durakSafeTurns, 300 - ja durak_finish_stuck - call ClearDurakTable - cmp durakPlayerTurn, 1 - je durak_check_player_attack - jmp durak_check_ai_attack - -durak_check_player_attack: - cmp durakPlayerCnt, 0 - jne durak_player_attack - cmp durakDeckLeft, 0 - jbe durak_round_loop - call RefillDurakHands - cmp durakPlayerCnt, 0 - jne durak_player_attack - jmp durak_finish_stuck - -durak_check_ai_attack: - cmp durakAICnt, 0 - jne durak_ai_attack - cmp durakDeckLeft, 0 - jbe durak_round_loop - call RefillDurakHandsAIFirst - cmp durakAICnt, 0 - jne durak_ai_attack - jmp durak_finish_stuck - -durak_player_attack: -player_attack_choose: - call ShowDurakTable - invoke PrintStr, OFFSET durakAttackAsk - call ReadUInt - cmp eax, 1 - jb player_attack_bad - cmp eax, durakPlayerCnt - ja player_attack_bad - dec eax - invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, eax - call AddDurakAttack - call PlayerOpenAttackLoop - call PlayerThrowLoop - jmp durak_round_loop -player_attack_bad: - invoke PrintStr, OFFSET durakBadMoveText - invoke Sleep, 650 - jmp player_attack_choose - -durak_ai_attack: - cmp durakAICnt, 0 - jne durak_ai_has_card - call RefillDurakHandsAIFirst - cmp durakAICnt, 0 - je durak_round_loop -durak_ai_has_card: - invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, 0 - call AddDurakAttack - call AIInitialThrowLoop - call PlayerDefendLoop - jmp durak_round_loop - -durak_finish_win: - invoke UnlockAchievement, 2000h, OFFSET achDurakWinName - call ShowDurakTable - invoke PrintStr, OFFSET durakWinText - call PayWin - jmp durak_again - -durak_finish_lose: - call ShowDurakTable - invoke PrintStr, OFFSET durakLoseText - call PayLose - jmp durak_again - -durak_finish_stuck: - call ShowDurakTable - invoke PrintStr, OFFSET durakStuckText - call PayDraw - jmp durak_again - -durak_finish_draw: - call ShowDurakTable - invoke PrintStr, OFFSET drawText - call PayDraw - -durak_again: - cmp tournamentMode, 1 - je durak_tournament_return - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je durak_start - cmp al, 'Y' - je durak_start -durak_tournament_return: - ret -GameDurak ENDP -; --- GameClassicSlot: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- -GameClassicSlot PROC -classic_slot_start: - call ClearView - invoke PrintTitleColor, OFFSET classicSlotTitle - invoke PrintStr, OFFSET classicSlotPayTableText - call PromptBet - call PlaySlotSound - invoke Sleep, 400 - invoke PrintStr, OFFSET slotPullText - mov slotWinMask, 0 - mov slotVisible, 0 - call PrintClassicSlotWindow - invoke Sleep, 1600 - - invoke FillClassicSlotColumn, 0 - mov slotVisible, 1 - call PrintClassicSlotWindow - invoke Sleep, 750 - - invoke FillClassicSlotColumn, 1 - mov slotVisible, 2 - call PrintClassicSlotWindow - invoke Sleep, 750 - - invoke FillClassicSlotColumn, 2 - mov slotVisible, 3 - call PrintClassicSlotWindow - invoke Sleep, 450 - - cmp cheatSlotJackpot, 1 - jne classic_no_forced_jackpot - mov cheatSlotJackpot, 0 - mov dword ptr slotGrid[12], 0 - mov dword ptr slotGrid[16], 0 - mov dword ptr slotGrid[20], 0 - call PrintClassicSlotWindow - invoke Sleep, 300 -classic_no_forced_jackpot: - - mov eax, slotGrid[12] - mov slotA, eax - mov eax, slotGrid[16] - mov slotB, eax - mov eax, slotGrid[20] - mov slotC, eax - - mov eax, slotA - cmp eax, slotB - jne classic_slot_check_pair_1 - mov eax, slotB - cmp eax, slotC - jne classic_slot_pair - invoke UnlockAchievement, 100h, OFFSET achClassicSlotName - call PlayJackpotSound - invoke PrintStr, OFFSET classicSlotJackpot - invoke Sleep, 650 - call PlayHakariSound - call PlayHakariDance - call PrintClassicSlotWindow - mov eax, slotA - cmp eax, 0 - je classic_slot_pay_777 - cmp eax, 2 - je classic_slot_pay_dollar - cmp eax, 1 - je classic_slot_pay_bar - cmp eax, 5 - je classic_slot_pay_aaa - invoke PaySlotMultiplier, 3 - jmp classic_ask_slot_again -classic_slot_pay_777: - invoke UnlockAchievement, 100h, OFFSET achClassicSlotName - invoke PaySlotMultiplier, 10 - jmp classic_ask_slot_again -classic_slot_pay_dollar: - invoke PaySlotMultiplier, 7 - jmp classic_ask_slot_again -classic_slot_pay_bar: - invoke PaySlotMultiplier, 5 - jmp classic_ask_slot_again -classic_slot_pay_aaa: - invoke PaySlotMultiplier, 4 - jmp classic_ask_slot_again - -classic_slot_check_pair_1: - mov eax, slotA - cmp eax, slotC - je classic_slot_pair - mov eax, slotB - cmp eax, slotC - je classic_slot_pair - invoke PrintStr, OFFSET classicSlotEmpty - call PayLose - jmp classic_ask_slot_again - -classic_slot_pair: - invoke UnlockAchievement, 100h, OFFSET achClassicSlotName - invoke PrintStr, OFFSET classicSlotPair - invoke PaySlotMultiplier, 2 - -classic_ask_slot_again: - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je classic_slot_start - cmp al, 'Y' - je classic_slot_start - ret -GameClassicSlot ENDP -; --- ObserverDrawAI1: ðåæèì íàáëþäàòåëÿ AI vs AI --- -ObserverDrawAI1 PROC - call DrawPlayer21Hand - call CalcPlayerScore21 - ret -ObserverDrawAI1 ENDP - -; --- ObserverDrawAI2: ðåæèì íàáëþäàòåëÿ AI vs AI --- -ObserverDrawAI2 PROC - call DrawAI21Hand - call CalcAIScore21 - ret -ObserverDrawAI2 ENDP - -; --- ObserverShow21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -ObserverShow21 PROC - call ClearView - invoke PrintTitleColor, OFFSET observer21Title - invoke PrintStr, OFFSET observerAI1CardsText - invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 - invoke PrintStr, OFFSET observerAI1Text - invoke PrintUInt, playerTotal - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET observerAI2CardsText - invoke PrintHandRow21, OFFSET aiHand21, aiCnt21, 1 - invoke PrintStr, OFFSET observerAI2Text - invoke PrintUInt, dealerTotal - invoke PrintStr, OFFSET nl - ret -ObserverShow21 ENDP - -; --- GameObserver21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- -GameObserver21 PROC - call ClearView - invoke PrintTitleColor, OFFSET observer21Title - call ResetDeck - mov playerCnt21, 0 - mov aiCnt21, 0 - mov revealAI21, 1 - call ObserverDrawAI1 - call ObserverDrawAI1 - call ObserverDrawAI2 - call ObserverDrawAI2 -observer21_loop: - call ObserverShow21 - invoke Sleep, 750 - cmp playerTotal, 17 - jae observer21_ai2 - call ObserverDrawAI1 - jmp observer21_loop -observer21_ai2: - cmp dealerTotal, 17 - jae observer21_compare - call ObserverDrawAI2 - jmp observer21_loop -observer21_compare: - call ObserverShow21 - mov eax, playerTotal - cmp eax, 21 - ja observer21_ai1_bust - mov eax, dealerTotal - cmp eax, 21 - ja observer21_ai1_win - mov eax, playerTotal - cmp eax, dealerTotal - ja observer21_ai1_win - jb observer21_ai2_win - invoke PrintStr, OFFSET observerDrawText - jmp observer21_done -observer21_ai1_bust: - mov eax, dealerTotal - cmp eax, 21 - ja observer21_draw - jmp observer21_ai2_win -observer21_draw: - invoke PrintStr, OFFSET observerDrawText - jmp observer21_done -observer21_ai1_win: - invoke PrintStr, OFFSET observerWin1Text - jmp observer21_done -observer21_ai2_win: - invoke PrintStr, OFFSET observerWin2Text -observer21_done: - call PauseConsole - ret -GameObserver21 ENDP - -; --- ObserverPokerEvaluate: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -ObserverPokerEvaluate PROC - invoke BuildPokerEvalHand, OFFSET playerHand21, OFFSET pokerPlayerEvalHand - invoke EvaluatePokerN, OFFSET pokerPlayerEvalHand, pokerEvalCount - mov pokerPlayerScore, eax - invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand - invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount - mov pokerAIScore, eax - ret -ObserverPokerEvaluate ENDP - -; --- ObserverShowPoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -ObserverShowPoker PROC - call ClearView - invoke PrintTitleColor, OFFSET observerPokerTitle - call ShowPokerTable - call ShowPokerMoney - call ObserverPokerEvaluate - invoke PrintStr, OFFSET pokerYourComboText - invoke PrintPokerHandName, pokerPlayerScore - invoke PrintStr, OFFSET pokerAIComboText - invoke PrintPokerHandName, pokerAIScore - ret -ObserverShowPoker ENDP - -; --- ObserverPokerDecision: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -ObserverPokerDecision PROC uses ebx edx - call ObserverPokerEvaluate - mov eax, pokerPlayerScore - cmp eax, 9 - ja observer_poker_ai2_check_fold - invoke RandomRange, 4 - cmp eax, 0 - je observer_poker_ai1_fold -observer_poker_ai2_check_fold: - mov eax, pokerAIScore - cmp eax, 9 - ja observer_poker_raise_check - invoke RandomRange, 4 - cmp eax, 0 - je observer_poker_ai2_fold -observer_poker_raise_check: - mov eax, pokerPlayerScore - cmp eax, 1000 - jb observer_poker_ai2_raise_check - invoke RandomRange, 2 - cmp eax, 0 - jne observer_poker_ai2_raise_check - invoke PrintStr, OFFSET observerAI1RaiseText - add currentBet, 500 - invoke Sleep, 450 - mov eax, pokerAIScore - cmp eax, pokerPlayerScore - jae observer_poker_call_1 - invoke RandomRange, 2 - cmp eax, 0 - je observer_poker_ai2_fold -observer_poker_call_1: - invoke PrintStr, OFFSET observerCallText -observer_poker_ai2_raise_check: - mov eax, pokerAIScore - cmp eax, 1000 - jb observer_poker_continue - invoke RandomRange, 2 - cmp eax, 0 - jne observer_poker_continue - invoke PrintStr, OFFSET observerAI2RaiseText - add currentBet, 500 - invoke Sleep, 450 - mov eax, pokerPlayerScore - cmp eax, pokerAIScore - jae observer_poker_call_2 - invoke RandomRange, 2 - cmp eax, 0 - je observer_poker_ai1_fold -observer_poker_call_2: - invoke PrintStr, OFFSET observerCallText -observer_poker_continue: - xor eax, eax - ret -observer_poker_ai1_fold: - invoke PrintStr, OFFSET observerFold1Text - mov eax, 2 - ret -observer_poker_ai2_fold: - invoke PrintStr, OFFSET observerFold2Text - mov eax, 1 - ret -ObserverPokerDecision ENDP - -; --- GameObserverPoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- -GameObserverPoker PROC - call ClearView - invoke PrintTitleColor, OFFSET observerPokerTitle - call ResetDeck - call ResetPokerHands - mov revealAI21, 1 - mov currentBet, 500 - call DealPokerHands -observer_poker_stage_loop: - call ObserverShowPoker - invoke Sleep, 700 - cmp communityCnt, 5 - jae observer_poker_showdown - call ObserverPokerDecision - cmp eax, 1 - je observer_poker_ai1_wins - cmp eax, 2 - je observer_poker_ai2_wins - invoke PrintStr, OFFSET pokerNextCardText - invoke Sleep, 700 - inc communityCnt - jmp observer_poker_stage_loop -observer_poker_showdown: - call ObserverShowPoker - mov eax, pokerPlayerScore - cmp eax, pokerAIScore - ja observer_poker_ai1_wins - jb observer_poker_ai2_wins - invoke PrintStr, OFFSET observerDrawText - jmp observer_poker_done -observer_poker_ai1_wins: - invoke PrintStr, OFFSET observerWin1Text - jmp observer_poker_done -observer_poker_ai2_wins: - invoke PrintStr, OFFSET observerWin2Text -observer_poker_done: - call PauseConsole - ret -GameObserverPoker ENDP - -; --- FindPlayerDurakDefense: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -FindPlayerDurakDefense PROC uses ebx ecx, tableIndex:DWORD - mov rowIndex, 0 -find_player_defense_loop: - mov eax, rowIndex - cmp eax, durakPlayerCnt - jae find_player_defense_no - mov ebx, OFFSET durakPlayerHand - mov ecx, [ebx + eax * 4] - mov ebx, tableIndex - invoke CanDurakBeat, durakAttackCards[ebx * 4], ecx - cmp eax, 1 - je find_player_defense_yes - inc rowIndex - jmp find_player_defense_loop -find_player_defense_yes: - mov eax, rowIndex - ret -find_player_defense_no: - mov eax, 0FFFFFFFFh - ret -FindPlayerDurakDefense ENDP - -; --- PlayerAIDefendAll: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayerAIDefendAll PROC uses ebx -player_ai_defend_loop: - call DurakFirstUnbeaten - cmp eax, 0FFFFFFFFh - je player_ai_defend_success - mov ebx, eax - invoke FindPlayerDurakDefense, ebx - cmp eax, 0FFFFFFFFh - je player_ai_defend_fail - invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, eax - mov durakDefenseCards[ebx * 4], eax - jmp player_ai_defend_loop -player_ai_defend_success: - mov eax, 1 - ret -player_ai_defend_fail: - xor eax, eax - ret -PlayerAIDefendAll ENDP - -; --- FindPlayerThrowIn: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -FindPlayerThrowIn PROC uses ebx ecx - cmp durakTableCnt, 6 - jae player_ai_throw_none - mov eax, durakTableCnt - cmp eax, durakAICnt - jae player_ai_throw_none - mov rowIndex, 0 -player_ai_throw_loop: - mov eax, rowIndex - cmp eax, durakPlayerCnt - jae player_ai_throw_none - mov ebx, OFFSET durakPlayerHand - mov ecx, [ebx + eax * 4] - invoke DurakRankOnTable, ecx - cmp eax, 1 - je player_ai_throw_found - inc rowIndex - jmp player_ai_throw_loop -player_ai_throw_found: - mov eax, rowIndex - ret -player_ai_throw_none: - mov eax, 0FFFFFFFFh - ret -FindPlayerThrowIn ENDP - -; --- PlayerAIInitialThrowLoop: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- -PlayerAIInitialThrowLoop PROC -player_ai_initial_throw_loop: - call FindPlayerThrowIn - cmp eax, 0FFFFFFFFh - je player_ai_initial_throw_done - invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, eax - call AddDurakAttack - jmp player_ai_initial_throw_loop -player_ai_initial_throw_done: - ret -PlayerAIInitialThrowLoop ENDP - -; --- ShowDurakObserverTable: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -ShowDurakObserverTable PROC - call ClearView - invoke PrintTitleColor, OFFSET observerDurakTitle - invoke PrintStr, OFFSET durakDeckVisualText - invoke PrintDurakCardName, durakTrumpCard - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET durakDeckText - invoke PrintUInt, durakDeckLeft - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET observerAI1CardsText - invoke PrintHandRow21, OFFSET durakPlayerHand, durakPlayerCnt, 1 - call PrintDurakTable - invoke PrintStr, OFFSET observerAI2CardsText - invoke PrintHandRow21, OFFSET durakAIHand, durakAICnt, 1 - ret -ShowDurakObserverTable ENDP - -; --- GameObserverDurak: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- -GameObserverDurak PROC - call SetupDurak - mov pokerReplaceIndex, 0 -observer_durak_loop: - inc pokerReplaceIndex - cmp pokerReplaceIndex, 32 - ja observer_durak_draw - call CheckDurakEnd - cmp eax, 1 - je observer_durak_ai1_win - cmp eax, 2 - je observer_durak_ai2_win - cmp eax, 3 - je observer_durak_draw - call ClearDurakTable - cmp durakPlayerTurn, 1 - je observer_durak_ai1_attack - jmp observer_durak_ai2_attack -observer_durak_ai1_attack: - cmp durakPlayerCnt, 0 - je observer_durak_ai1_win - invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, 0 - call AddDurakAttack - call PlayerAIInitialThrowLoop - call ShowDurakObserverTable - invoke Sleep, 750 - call AIDefendAll - cmp eax, 1 - je observer_durak_ai2_defended - invoke CollectDurakTable, OFFSET durakAIHand, OFFSET durakAICnt - invoke PrintStr, OFFSET durakAITakeText - mov durakPlayerTurn, 1 - call RefillDurakHands - invoke Sleep, 850 - jmp observer_durak_loop -observer_durak_ai2_defended: - call ShowDurakObserverTable - invoke Sleep, 750 - call ClearDurakTable - mov durakPlayerTurn, 0 - call RefillDurakHands - jmp observer_durak_loop -observer_durak_ai2_attack: - cmp durakAICnt, 0 - je observer_durak_ai2_win - invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, 0 - call AddDurakAttack - call AIInitialThrowLoop - call ShowDurakObserverTable - invoke Sleep, 750 - call PlayerAIDefendAll - cmp eax, 1 - je observer_durak_ai1_defended - invoke CollectDurakTable, OFFSET durakPlayerHand, OFFSET durakPlayerCnt - invoke PrintStr, OFFSET durakPlayerTakeText - mov durakPlayerTurn, 0 - call RefillDurakHandsAIFirst - invoke Sleep, 850 - jmp observer_durak_loop -observer_durak_ai1_defended: - call ShowDurakObserverTable - invoke Sleep, 750 - call ClearDurakTable - mov durakPlayerTurn, 1 - call RefillDurakHandsAIFirst - jmp observer_durak_loop -observer_durak_ai1_win: - call ShowDurakObserverTable - invoke PrintStr, OFFSET observerWin1Text - jmp observer_durak_done -observer_durak_ai2_win: - call ShowDurakObserverTable - invoke PrintStr, OFFSET observerWin2Text - jmp observer_durak_done -observer_durak_draw: - call ShowDurakObserverTable - invoke PrintStr, OFFSET observerDrawText -observer_durak_done: - call PauseConsole - ret -GameObserverDurak ENDP - -; --- GameObserverRoulette: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- -GameObserverRoulette PROC - call ClearView - invoke PrintTitleColor, OFFSET observerRRTitle - call PlayRouletteSpinSound - call SetupRoulette - call AnimateRouletteSpin -observer_rr_loop: - call ShowRouletteStatus - cmp rrTurn, 0 - je observer_rr_ai1_turn - invoke PrintStr, OFFSET rrAITurnText - invoke Sleep, 850 - call RouletteChamberLoaded - cmp eax, 1 - je observer_rr_ai2_dead - call PlayRouletteDrySound - invoke PrintStr, OFFSET rrClickText - invoke Sleep, 750 - call AdvanceRouletteChamber - mov rrTurn, 0 - jmp observer_rr_loop -observer_rr_ai1_turn: - invoke PrintStr, OFFSET rrPlayerTurnText - invoke Sleep, 850 - call RouletteChamberLoaded - cmp eax, 1 - je observer_rr_ai1_dead - call PlayRouletteDrySound - invoke PrintStr, OFFSET rrClickText - invoke Sleep, 750 - call AdvanceRouletteChamber - mov rrTurn, 1 - jmp observer_rr_loop -observer_rr_ai1_dead: - call PrintBang - invoke PrintStr, OFFSET observerShotAI1Text - jmp observer_rr_done -observer_rr_ai2_dead: - call PrintBang - invoke PrintStr, OFFSET observerShotAI2Text -observer_rr_done: - call PauseConsole - ret -GameObserverRoulette ENDP - -; --- GameObserver: ðåæèì íàáëþäàòåëÿ AI vs AI --- -GameObserver PROC -observer_menu_loop: - call ClearView - invoke PrintTitleColor, OFFSET observerTitle - invoke PrintStr, OFFSET observerMenuText - call ReadUInt - cmp eax, 0 - je observer_exit - cmp eax, 1 - je observer_run_rr - cmp eax, 2 - je observer_run_21 - cmp eax, 3 - je observer_run_poker - cmp eax, 4 - je observer_run_durak - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp observer_menu_loop -observer_run_rr: - invoke UnlockAchievement, 10000h, OFFSET achObserverName - call GameObserverRoulette - jmp observer_menu_loop -observer_run_21: - mov currentGameId, 1 - invoke UnlockAchievement, 10000h, OFFSET achObserverName - call GameObserver21 - jmp observer_menu_loop -observer_run_poker: - mov currentGameId, 2 - invoke UnlockAchievement, 10000h, OFFSET achObserverName - call GameObserverPoker - jmp observer_menu_loop -observer_run_durak: - mov currentGameId, 10 - invoke UnlockAchievement, 10000h, OFFSET achObserverName - call GameObserverDurak - jmp observer_menu_loop -observer_exit: - ret -GameObserver ENDP - -; --- PrintShopBackName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintShopBackName PROC - mov eax, shopBackStyle - cmp eax, 1 - je print_shop_back_blue - cmp eax, 2 - je print_shop_back_red - cmp eax, 3 - je print_shop_back_gold - cmp eax, 4 - je print_shop_back_skull - cmp eax, 5 - je print_shop_back_clover - cmp eax, 6 - je print_shop_back_arcane - cmp eax, 7 - je print_shop_back_noir - cmp eax, 8 - je print_shop_back_diamond - cmp eax, 9 - je print_shop_back_rider - cmp eax, 10 - je print_shop_back_bee - cmp eax, 11 - je print_shop_back_fan - cmp eax, 12 - je print_shop_back_web - invoke PrintStr, OFFSET shopBackGray - ret -print_shop_back_blue: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopBackBlue - call ResetColor - ret -print_shop_back_red: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET shopBackRed - call ResetColor - ret -print_shop_back_gold: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopBackGold - call ResetColor - ret -print_shop_back_skull: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET shopBackSkull - call ResetColor - ret -print_shop_back_clover: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET shopBackClover - call ResetColor - ret -print_shop_back_arcane: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopBackArcane - call ResetColor - ret -print_shop_back_noir: - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET shopBackNoir - call ResetColor - ret -print_shop_back_diamond: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopBackDiamond - call ResetColor - ret -print_shop_back_rider: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopBackRider - call ResetColor - ret -print_shop_back_bee: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopBackBee - call ResetColor - ret -print_shop_back_fan: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopBackFan - call ResetColor - ret -print_shop_back_web: - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET shopBackWeb - call ResetColor - ret -PrintShopBackName ENDP - -; --- PrintShopCharmName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintShopCharmName PROC - mov eax, shopCharmLevel - cmp eax, 1 - je print_shop_charm_clover - cmp eax, 2 - je print_shop_charm_bell - cmp eax, 3 - je print_shop_charm_diamond - cmp eax, 4 - je print_shop_charm_skull - cmp eax, 5 - je print_shop_charm_web - cmp eax, 6 - je print_shop_charm_bee - cmp eax, 7 - je print_shop_charm_moon - cmp eax, 8 - je print_shop_charm_crown - cmp eax, 9 - je print_shop_charm_mirror - cmp eax, 10 - je print_shop_charm_dice - cmp eax, 11 - je print_shop_charm_blood - cmp eax, 12 - je print_shop_charm_hourglass - cmp eax, 13 - je print_shop_charm_horseshoe - cmp eax, 14 - je print_shop_charm_joker - cmp eax, 15 - je print_shop_charm_phoenix - cmp eax, 16 - je print_shop_charm_compass - cmp eax, 17 - je print_shop_charm_tooth - cmp eax, 18 - je print_shop_charm_eye - cmp eax, 19 - je print_shop_charm_key - cmp eax, 20 - je print_shop_charm_candle - cmp eax, 21 - je print_shop_charm_chip - cmp eax, 22 - je print_shop_charm_snake - cmp eax, 23 - je print_shop_charm_ace - cmp eax, 24 - je print_shop_charm_devil - invoke PrintStr, OFFSET shopCharmNone - ret -print_shop_charm_clover: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET shopCharmClover - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_bell: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopCharmBell - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_diamond: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopCharmDiamond - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_skull: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET shopCharmSkull - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_web: - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET shopCharmWeb - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_bee: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopCharmBee - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_moon: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopCharmMoon - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_crown: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopCharmCrown - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_mirror: - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET shopCharmMirror - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_dice: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopCharmDice - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_blood: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET shopCharmBlood - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_hourglass: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopCharmHourglass - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_horseshoe: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET shopCharmHorseshoe - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_joker: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET shopCharmJoker - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_phoenix: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopCharmPhoenix - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_compass: - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET shopCharmCompass - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_tooth: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopCharmTooth - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_eye: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopCharmEye - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_key: - invoke SetColor, COLOR_CARD - invoke PrintStr, OFFSET shopCharmKey - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_candle: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET shopCharmCandle - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_chip: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET shopCharmChip - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_snake: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET shopCharmSnake - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_ace: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET shopCharmAce - call ResetColor - jmp print_shop_charm_uses -print_shop_charm_devil: - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET shopCharmDevil - call ResetColor -print_shop_charm_uses: - invoke PrintStr, OFFSET shopCharmUsesText - invoke PrintUInt, shopCharmUses - invoke PrintStr, OFFSET nl - ret -PrintShopCharmName ENDP - -; --- PrintShopStatus: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintShopStatus PROC - call PrintBank - invoke PrintStr, OFFSET shopBackText - call PrintShopBackName - invoke PrintStr, OFFSET shopCharmText - call PrintShopCharmName - invoke PrintStr, OFFSET nl - ret -PrintShopStatus ENDP - -; --- ShopBuyBack: ìàãàçèí ðóáàøåê, òàëèñìàíîâ è ïîêóïîê --- -ShopBuyBack PROC uses eax ebx, style:DWORD, cost:DWORD, maskValue:DWORD - mov eax, shopBackOwned - mov ebx, maskValue - test eax, ebx - jne shop_back_already_owned - - mov eax, cost - cmp bankroll, eax - jae shop_back_buy - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET tooBigBetText - call ResetColor - ret -shop_back_buy: - sub bankroll, eax - mov eax, shopBackOwned - or eax, ebx - mov shopBackOwned, eax - mov eax, style - mov shopBackStyle, eax - call SaveGame - invoke UnlockAchievement, 10h, OFFSET achShopperName - mov eax, shopBackOwned - and eax, 1FFFh - cmp eax, 1FFFh - jne shop_back_collector_skip - invoke UnlockAchievement, 4000h, OFFSET achBackCollectorName -shop_back_collector_skip: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET shopBoughtText - call ResetColor - call PrintBank - call CheckBankrupt - ret -shop_back_already_owned: - mov eax, style - mov shopBackStyle, eax - call SaveGame - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET shopSelectedText - call ResetColor - ret -ShopBuyBack ENDP - -; --- ShopBuyCharm: ïîêóïêà òàëèñìàíà ñ ðàçíûìè çàðÿäàìè --- -ShopBuyCharm PROC uses eax, charmLevel:DWORD, cost:DWORD - mov eax, cost - cmp bankroll, eax - jae shop_charm_buy - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET tooBigBetText - call ResetColor - ret -shop_charm_buy: - sub bankroll, eax - mov eax, charmLevel - mov shopCharmLevel, eax - cmp eax, 5 - je shop_charm_one_use - cmp eax, 11 - je shop_charm_one_use - cmp eax, 14 - je shop_charm_one_use - cmp eax, 18 - je shop_charm_one_use - cmp eax, 20 - je shop_charm_one_use - cmp eax, 24 - je shop_charm_one_use - cmp eax, 4 - je shop_charm_two_uses - cmp eax, 8 - je shop_charm_two_uses - cmp eax, 12 - je shop_charm_two_uses - cmp eax, 15 - je shop_charm_two_uses - cmp eax, 22 - je shop_charm_two_uses - cmp eax, 7 - je shop_charm_four_uses - cmp eax, 9 - je shop_charm_four_uses - cmp eax, 21 - je shop_charm_four_uses - cmp eax, 6 - je shop_charm_five_uses - cmp eax, 17 - je shop_charm_five_uses - cmp eax, 23 - je shop_charm_five_uses - cmp eax, 10 - je shop_charm_six_uses - cmp eax, 19 - je shop_charm_six_uses - cmp eax, 13 - je shop_charm_eight_uses - mov shopCharmUses, 3 - jmp shop_charm_store -shop_charm_one_use: - mov shopCharmUses, 1 - jmp shop_charm_store -shop_charm_two_uses: - mov shopCharmUses, 2 - jmp shop_charm_store -shop_charm_four_uses: - mov shopCharmUses, 4 - jmp shop_charm_store -shop_charm_five_uses: - mov shopCharmUses, 5 - jmp shop_charm_store -shop_charm_six_uses: - mov shopCharmUses, 6 - jmp shop_charm_store -shop_charm_eight_uses: - mov shopCharmUses, 8 -shop_charm_store: - call SaveGame - invoke UnlockAchievement, 10h, OFFSET achShopperName - invoke UnlockAchievement, 8000h, OFFSET achCharmBuyerName - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET shopBoughtText - call ResetColor - call PrintBank - call CheckBankrupt - ret -ShopBuyCharm ENDP - -; --- ShowBestiaryPage: êàðòî÷êà òàëèñìàíà â áåñòèàðèè --- -ShowBestiaryPage PROC artPtr:DWORD, infoPtr:DWORD, colorValue:DWORD - call ClearView - invoke SetColor, colorValue - invoke PrintStr, artPtr - call ResetColor - invoke PrintStr, infoPtr - invoke PrintStr, OFFSET bestiaryBackText - call ReadKey - ret -ShowBestiaryPage ENDP - -; --- GameCharmBestiary: ýíöèêëîïåäèÿ òàëèñìàíîâ ñ ASCII-àðòàìè --- -GameCharmBestiary PROC -bestiary_loop: - call ClearView - invoke PrintTitleColor, OFFSET bestiaryTitle - invoke PrintStr, OFFSET bestiaryMenuText - call ReadUInt - cmp eax, 0 - je bestiary_exit - cmp eax, 1 - je bestiary_clover - cmp eax, 2 - je bestiary_bell - cmp eax, 3 - je bestiary_diamond - cmp eax, 4 - je bestiary_skull - cmp eax, 5 - je bestiary_web - cmp eax, 6 - je bestiary_bee - cmp eax, 7 - je bestiary_moon - cmp eax, 8 - je bestiary_crown - cmp eax, 9 - je bestiary_mirror - cmp eax, 10 - je bestiary_dice - cmp eax, 11 - je bestiary_blood - cmp eax, 12 - je bestiary_hourglass - cmp eax, 13 - je bestiary_horseshoe - cmp eax, 14 - je bestiary_joker - cmp eax, 15 - je bestiary_phoenix - cmp eax, 16 - je bestiary_compass - cmp eax, 17 - je bestiary_tooth - cmp eax, 18 - je bestiary_eye - cmp eax, 19 - je bestiary_key - cmp eax, 20 - je bestiary_candle - cmp eax, 21 - je bestiary_chip - cmp eax, 22 - je bestiary_snake - cmp eax, 23 - je bestiary_ace - cmp eax, 24 - je bestiary_devil - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp bestiary_loop -bestiary_clover: - invoke ShowBestiaryPage, OFFSET bestiaryCloverArt, OFFSET bestiaryCloverInfo, COLOR_MONEY - jmp bestiary_loop -bestiary_bell: - invoke ShowBestiaryPage, OFFSET bestiaryBellArt, OFFSET bestiaryBellInfo, COLOR_WARN - jmp bestiary_loop -bestiary_diamond: - invoke ShowBestiaryPage, OFFSET bestiaryDiamondArt, OFFSET bestiaryDiamondInfo, COLOR_TITLE - jmp bestiary_loop -bestiary_skull: - invoke ShowBestiaryPage, OFFSET bestiarySkullArt, OFFSET bestiarySkullInfo, COLOR_BAD - jmp bestiary_loop -bestiary_web: - invoke ShowBestiaryPage, OFFSET bestiaryWebArt, OFFSET bestiaryWebInfo, COLOR_CARD - jmp bestiary_loop -bestiary_bee: - invoke ShowBestiaryPage, OFFSET bestiaryBeeArt, OFFSET bestiaryBeeInfo, COLOR_WARN - jmp bestiary_loop -bestiary_moon: - invoke ShowBestiaryPage, OFFSET bestiaryMoonArt, OFFSET bestiaryMoonInfo, COLOR_TITLE - jmp bestiary_loop -bestiary_crown: - invoke ShowBestiaryPage, OFFSET bestiaryCrownArt, OFFSET bestiaryCrownInfo, COLOR_WARN - jmp bestiary_loop -bestiary_mirror: - invoke ShowBestiaryPage, OFFSET bestiaryMirrorArt, OFFSET bestiaryMirrorInfo, COLOR_CARD - jmp bestiary_loop -bestiary_dice: - invoke ShowBestiaryPage, OFFSET bestiaryDiceArt, OFFSET bestiaryDiceInfo, COLOR_TITLE - jmp bestiary_loop -bestiary_blood: - invoke ShowBestiaryPage, OFFSET bestiaryBloodArt, OFFSET bestiaryBloodInfo, COLOR_BAD - jmp bestiary_loop -bestiary_hourglass: - invoke ShowBestiaryPage, OFFSET bestiaryHourglassArt, OFFSET bestiaryHourglassInfo, COLOR_WARN - jmp bestiary_loop -bestiary_horseshoe: - invoke ShowBestiaryPage, OFFSET bestiaryHorseshoeArt, OFFSET bestiaryHorseshoeInfo, COLOR_MONEY - jmp bestiary_loop -bestiary_joker: - invoke ShowBestiaryPage, OFFSET bestiaryJokerArt, OFFSET bestiaryJokerInfo, COLOR_BAD - jmp bestiary_loop -bestiary_phoenix: - invoke ShowBestiaryPage, OFFSET bestiaryPhoenixArt, OFFSET bestiaryPhoenixInfo, COLOR_WARN - jmp bestiary_loop -bestiary_compass: - invoke ShowBestiaryPage, OFFSET bestiaryCompassArt, OFFSET bestiaryCompassInfo, COLOR_CARD - jmp bestiary_loop -bestiary_tooth: - invoke ShowBestiaryPage, OFFSET bestiaryToothArt, OFFSET bestiaryToothInfo, COLOR_WARN - jmp bestiary_loop -bestiary_eye: - invoke ShowBestiaryPage, OFFSET bestiaryEyeArt, OFFSET bestiaryEyeInfo, COLOR_TITLE - jmp bestiary_loop -bestiary_key: - invoke ShowBestiaryPage, OFFSET bestiaryKeyArt, OFFSET bestiaryKeyInfo, COLOR_CARD - jmp bestiary_loop -bestiary_candle: - invoke ShowBestiaryPage, OFFSET bestiaryCandleArt, OFFSET bestiaryCandleInfo, COLOR_BAD - jmp bestiary_loop -bestiary_chip: - invoke ShowBestiaryPage, OFFSET bestiaryChipArt, OFFSET bestiaryChipInfo, COLOR_MONEY - jmp bestiary_loop -bestiary_snake: - invoke ShowBestiaryPage, OFFSET bestiarySnakeArt, OFFSET bestiarySnakeInfo, COLOR_MONEY - jmp bestiary_loop -bestiary_ace: - invoke ShowBestiaryPage, OFFSET bestiaryAceArt, OFFSET bestiaryAceInfo, COLOR_TITLE - jmp bestiary_loop -bestiary_devil: - invoke ShowBestiaryPage, OFFSET bestiaryDevilArt, OFFSET bestiaryDevilInfo, COLOR_BAD - jmp bestiary_loop -bestiary_exit: - ret -GameCharmBestiary ENDP - -; --- GameShop: ìàãàçèí ðóáàøåê, òàëèñìàíîâ è ïîêóïîê --- -GameShop PROC -shop_loop: - call ClearView - invoke PrintTitleColor, OFFSET shopTitle - call PrintShopStatus - invoke PrintStr, OFFSET shopMainMenuText - call ReadUInt - cmp eax, 0 - je shop_exit - cmp eax, 1 - je shop_backs_menu - cmp eax, 2 - je shop_charms_menu - cmp eax, 3 - je shop_bestiary_menu - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp shop_loop - -shop_bestiary_menu: - call GameCharmBestiary - jmp shop_loop - -shop_backs_menu: - call ClearView - invoke PrintTitleColor, OFFSET shopBackTitle - call PrintShopStatus - invoke PrintStr, OFFSET shopBackMenuText - call ReadUInt - cmp eax, 0 - je shop_loop - cmp eax, 1 - je shop_blue - cmp eax, 2 - je shop_red - cmp eax, 3 - je shop_gold - cmp eax, 4 - je shop_skull - cmp eax, 5 - je shop_clover_back - cmp eax, 6 - je shop_arcane - cmp eax, 7 - je shop_noir - cmp eax, 8 - je shop_diamond_back - cmp eax, 9 - je shop_rider - cmp eax, 10 - je shop_bee - cmp eax, 11 - je shop_fan - cmp eax, 12 - je shop_web - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp shop_backs_menu - -shop_charms_menu: - call ClearView - invoke PrintTitleColor, OFFSET shopCharmTitle - call PrintShopStatus - invoke PrintStr, OFFSET shopCharmMenuText - call ReadUInt - cmp eax, 0 - je shop_loop - cmp eax, 1 - je buy_charm_clover - cmp eax, 2 - je buy_charm_bell - cmp eax, 3 - je buy_charm_diamond - cmp eax, 4 - je buy_charm_skull - cmp eax, 5 - je buy_charm_web - cmp eax, 6 - je buy_charm_bee_item - cmp eax, 7 - je buy_charm_moon - cmp eax, 8 - je buy_charm_crown - cmp eax, 9 - je buy_charm_mirror - cmp eax, 10 - je buy_charm_dice - cmp eax, 11 - je buy_charm_blood - cmp eax, 12 - je buy_charm_hourglass - cmp eax, 13 - je buy_charm_horseshoe - cmp eax, 14 - je buy_charm_joker - cmp eax, 15 - je buy_charm_phoenix - cmp eax, 16 - je buy_charm_compass - cmp eax, 17 - je buy_charm_tooth - cmp eax, 18 - je buy_charm_eye - cmp eax, 19 - je buy_charm_key - cmp eax, 20 - je buy_charm_candle - cmp eax, 21 - je buy_charm_chip - cmp eax, 22 - je buy_charm_snake - cmp eax, 23 - je buy_charm_ace - cmp eax, 24 - je buy_charm_devil - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp shop_charms_menu - -shop_blue: - invoke ShopBuyBack, 1, 3000, 2 - call PauseConsole - jmp shop_backs_menu -shop_red: - invoke ShopBuyBack, 2, 3000, 4 - call PauseConsole - jmp shop_backs_menu -shop_gold: - invoke ShopBuyBack, 3, 10000, 8 - call PauseConsole - jmp shop_backs_menu -shop_skull: - invoke ShopBuyBack, 4, 12000, 10h - call PauseConsole - jmp shop_backs_menu -shop_clover_back: - invoke ShopBuyBack, 5, 15000, 20h - call PauseConsole - jmp shop_backs_menu -shop_arcane: - invoke ShopBuyBack, 6, 17000, 40h - call PauseConsole - jmp shop_backs_menu -shop_noir: - invoke ShopBuyBack, 7, 18000, 80h - call PauseConsole - jmp shop_backs_menu -shop_diamond_back: - invoke ShopBuyBack, 8, 20000, 100h - call PauseConsole - jmp shop_backs_menu -shop_rider: - invoke ShopBuyBack, 9, 22000, 200h - call PauseConsole - jmp shop_backs_menu -shop_bee: - invoke ShopBuyBack, 10, 22000, 400h - call PauseConsole - jmp shop_backs_menu -shop_fan: - invoke ShopBuyBack, 11, 23000, 800h - call PauseConsole - jmp shop_backs_menu -shop_web: - invoke ShopBuyBack, 12, 24000, 1000h - call PauseConsole - jmp shop_backs_menu - -buy_charm_clover: - invoke ShopBuyCharm, 1, 12000 - call PauseConsole - jmp shop_charms_menu -buy_charm_bell: - invoke ShopBuyCharm, 2, 18000 - call PauseConsole - jmp shop_charms_menu -buy_charm_diamond: - invoke ShopBuyCharm, 3, 25000 - call PauseConsole - jmp shop_charms_menu -buy_charm_skull: - invoke ShopBuyCharm, 4, 32000 - call PauseConsole - jmp shop_charms_menu -buy_charm_web: - invoke ShopBuyCharm, 5, 40000 - call PauseConsole - jmp shop_charms_menu -buy_charm_bee_item: - invoke ShopBuyCharm, 6, 30000 - call PauseConsole - jmp shop_charms_menu -buy_charm_moon: - invoke ShopBuyCharm, 7, 36000 - call PauseConsole - jmp shop_charms_menu -buy_charm_crown: - invoke ShopBuyCharm, 8, 52000 - call PauseConsole - jmp shop_charms_menu -buy_charm_mirror: - invoke ShopBuyCharm, 9, 42000 - call PauseConsole - jmp shop_charms_menu -buy_charm_dice: - invoke ShopBuyCharm, 10, 35000 - call PauseConsole - jmp shop_charms_menu -buy_charm_blood: - invoke ShopBuyCharm, 11, 65000 - call PauseConsole - jmp shop_charms_menu -buy_charm_hourglass: - invoke ShopBuyCharm, 12, 48000 - call PauseConsole - jmp shop_charms_menu -buy_charm_horseshoe: - invoke ShopBuyCharm, 13, 39000 - call PauseConsole - jmp shop_charms_menu -buy_charm_joker: - invoke ShopBuyCharm, 14, 70000 - call PauseConsole - jmp shop_charms_menu -buy_charm_phoenix: - invoke ShopBuyCharm, 15, 56000 - call PauseConsole - jmp shop_charms_menu -buy_charm_compass: - invoke ShopBuyCharm, 16, 44000 - call PauseConsole - jmp shop_charms_menu -buy_charm_tooth: - invoke ShopBuyCharm, 17, 47000 - call PauseConsole - jmp shop_charms_menu -buy_charm_eye: - invoke ShopBuyCharm, 18, 60000 - call PauseConsole - jmp shop_charms_menu -buy_charm_key: - invoke ShopBuyCharm, 19, 41000 - call PauseConsole - jmp shop_charms_menu -buy_charm_candle: - invoke ShopBuyCharm, 20, 76000 - call PauseConsole - jmp shop_charms_menu -buy_charm_chip: - invoke ShopBuyCharm, 21, 50000 - call PauseConsole - jmp shop_charms_menu -buy_charm_snake: - invoke ShopBuyCharm, 22, 62000 - call PauseConsole - jmp shop_charms_menu -buy_charm_ace: - invoke ShopBuyCharm, 23, 53000 - call PauseConsole - jmp shop_charms_menu -buy_charm_devil: - invoke ShopBuyCharm, 24, 100000 - call PauseConsole - jmp shop_charms_menu -shop_exit: - ret -GameShop ENDP - - -; --- CopyName: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -CopyName PROC uses eax ecx esi edi, pDst:DWORD, pSrc:DWORD - mov edi, pDst - mov esi, pSrc - mov ecx, 63 -copy_name_loop: - mov al, [esi] - cmp al, '.' - je copy_name_stop - mov [edi], al - cmp al, 0 - je copy_name_done - inc esi - inc edi - loop copy_name_loop -copy_name_stop: - mov byte ptr [edi], 0 -copy_name_done: - ret -CopyName ENDP - -; --- ClearLeaderboards: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -ClearLeaderboards PROC uses eax ecx edi - mov leaderBestBank, 0 - mov leaderBestWins, 0 - mov leaderBestLosses, 0 - mov leaderValidCount, 0 - mov ecx, 22 - mov edi, OFFSET leaderBestGameWins -clear_leader_counts: - mov dword ptr [edi], 0 - add edi, 4 - loop clear_leader_counts - mov ecx, 1600 - mov edi, OFFSET leaderBestBankName -clear_leader_names: - mov byte ptr [edi], 0 - inc edi - loop clear_leader_names - ret -ClearLeaderboards ENDP - -; --- LeaderboardUpdateGame: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -LeaderboardUpdateGame PROC uses eax ebx edx - mov ebx, rowIndex - mov eax, DWORD PTR [saveBuffer+104+ebx*4] - cmp eax, leaderBestGameWins[ebx*4] - jbe leaderboard_check_losses - mov leaderBestGameWins[ebx*4], eax - mov edx, ebx - shl edx, 6 - add edx, OFFSET leaderBestGameWinNames - invoke CopyName, edx, leaderAccountPtr -leaderboard_check_losses: - mov eax, DWORD PTR [saveBuffer+148+ebx*4] - cmp eax, leaderBestGameLosses[ebx*4] - jbe leaderboard_game_done - mov leaderBestGameLosses[ebx*4], eax - mov edx, ebx - shl edx, 6 - add edx, OFFSET leaderBestGameLossNames - invoke CopyName, edx, leaderAccountPtr -leaderboard_game_done: - ret -LeaderboardUpdateGame ENDP - -; --- LeaderboardReadAccount: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- -LeaderboardReadAccount PROC uses eax - call BuildLeaderSavePath - invoke CreateFileA, OFFSET leaderSavePath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 - cmp eax, INVALID_HANDLE_VALUE - jne leaderboard_file_opened - cmp appDataReady, 1 - jne leaderboard_read_done - invoke CreateFileA, leaderAccountPtr, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 - cmp eax, INVALID_HANDLE_VALUE - je leaderboard_read_done -leaderboard_file_opened: - mov saveHandle, eax - invoke ReadFile, saveHandle, ADDR saveBuffer, SAVE_FILE_SIZE, ADDR charsRead, 0 - invoke CloseHandle, saveHandle - cmp charsRead, 32 - jb leaderboard_read_done - mov eax, DWORD PTR [saveBuffer] - cmp eax, SAVE_MAGIC - jne leaderboard_read_done - cmp charsRead, SAVE_FILE_SIZE - jb leaderboard_signature_ok - mov edx, DWORD PTR [saveBuffer+SAVE_SIGN_SIZE] - call CalcSaveSignature - cmp eax, edx - jne leaderboard_read_done -leaderboard_signature_ok: - inc leaderValidCount - mov eax, DWORD PTR [saveBuffer+4] - cmp eax, leaderBestBank - jbe leaderboard_check_total_wins - mov leaderBestBank, eax - invoke CopyName, OFFSET leaderBestBankName, leaderAccountPtr -leaderboard_check_total_wins: - mov eax, DWORD PTR [saveBuffer+12] - cmp eax, leaderBestWins - jbe leaderboard_check_total_losses - mov leaderBestWins, eax - invoke CopyName, OFFSET leaderBestWinsName, leaderAccountPtr -leaderboard_check_total_losses: - mov eax, DWORD PTR [saveBuffer+16] - cmp eax, leaderBestLosses - jbe leaderboard_check_games - mov leaderBestLosses, eax - invoke CopyName, OFFSET leaderBestLossName, leaderAccountPtr -leaderboard_check_games: - cmp charsRead, 236 - jb leaderboard_read_done - mov rowIndex, 0 -leaderboard_game_loop: - cmp rowIndex, 11 - jae leaderboard_read_done - call LeaderboardUpdateGame - inc rowIndex - jmp leaderboard_game_loop -leaderboard_read_done: - ret -LeaderboardReadAccount ENDP - -; --- BuildLeaderboards: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -BuildLeaderboards PROC uses eax - call ClearLeaderboards - call CollectAccounts - mov leaderScanIndex, 0 -leaderboard_account_loop: - mov eax, leaderScanIndex - cmp eax, accountCount - jae leaderboard_build_done - shl eax, 6 - add eax, OFFSET accountList - mov leaderAccountPtr, eax - call LeaderboardReadAccount - inc leaderScanIndex - jmp leaderboard_account_loop -leaderboard_build_done: - ret -BuildLeaderboards ENDP - -; --- PrintLeaderPair: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintLeaderPair PROC uses eax, pName:DWORD, value:DWORD - mov eax, value - cmp eax, 0 - jne print_leader_pair_value - invoke PrintStr, OFFSET leaderDashText - ret -print_leader_pair_value: - invoke PrintStr, pName - invoke PrintStr, OFFSET leaderOpenText - invoke PrintUInt, value - invoke PrintStr, OFFSET leaderCloseText - ret -PrintLeaderPair ENDP - -; --- PrintLeaderGameLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintLeaderGameLine PROC uses eax ebx edx - mov eax, rowIndex - invoke PrintStr, statsGameNames[eax*4] - invoke PrintStr, OFFSET leaderGameWinText - mov ebx, rowIndex - mov edx, ebx - shl edx, 6 - add edx, OFFSET leaderBestGameWinNames - invoke PrintLeaderPair, edx, leaderBestGameWins[ebx*4] - invoke PrintStr, OFFSET leaderGameLossText - mov ebx, rowIndex - mov edx, ebx - shl edx, 6 - add edx, OFFSET leaderBestGameLossNames - invoke PrintLeaderPair, edx, leaderBestGameLosses[ebx*4] - invoke PrintStr, OFFSET nl - ret -PrintLeaderGameLine ENDP - -; --- PrintLeaderboards: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintLeaderboards PROC - call BuildLeaderboards - invoke PrintTitleColor, OFFSET leaderTitle - cmp leaderValidCount, 0 - jne print_leaders_have_data - invoke PrintStr, OFFSET leaderNoDataText - ret -print_leaders_have_data: - invoke PrintStr, OFFSET leaderBankText - invoke PrintStr, OFFSET leaderBestBankName - invoke PrintStr, OFFSET leaderOpenText - invoke PrintStr, OFFSET leaderMoneyPrefix - invoke PrintUInt, leaderBestBank - invoke PrintStr, OFFSET leaderCloseText - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET leaderWinsText - invoke PrintLeaderPair, OFFSET leaderBestWinsName, leaderBestWins - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET leaderLossText - invoke PrintLeaderPair, OFFSET leaderBestLossName, leaderBestLosses - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET leaderGameTitle - mov rowIndex, 0 -leader_print_game_loop: - cmp rowIndex, 11 - jae leader_print_done - call PrintLeaderGameLine - inc rowIndex - jmp leader_print_game_loop -leader_print_done: - ret -PrintLeaderboards ENDP -; --- PrintGameStatLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- -PrintGameStatLine PROC uses eax ebx - mov eax, rowIndex - invoke PrintStr, statsGameNames[eax * 4] - invoke PrintStr, OFFSET statsLinePlayed - mov ebx, rowIndex - invoke PrintUInt, gameStatsPlayed[ebx * 4] - invoke PrintStr, OFFSET statsLineWins - mov ebx, rowIndex - invoke PrintUInt, gameStatsWon[ebx * 4] - invoke PrintStr, OFFSET statsLineLoss - mov ebx, rowIndex - invoke PrintUInt, gameStatsLost[ebx * 4] - invoke PrintStr, OFFSET statsLineDraw - mov ebx, rowIndex - invoke PrintUInt, gameStatsDraw[ebx * 4] - invoke PrintStr, OFFSET nl - ret -PrintGameStatLine ENDP - -; --- GameStatsByGame: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -GameStatsByGame PROC - call ClearView - invoke PrintTitleColor, OFFSET statsByGameTitle - invoke PrintStr, OFFSET leaderCurrentTitle - mov rowIndex, 0 -stats_by_game_loop: - cmp rowIndex, 11 - jae stats_by_game_done - call PrintGameStatLine - inc rowIndex - jmp stats_by_game_loop -stats_by_game_done: - call PrintLeaderboards - call PauseConsole - ret -GameStatsByGame ENDP - -; --- SkillCheckFlushKeys: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- -SkillCheckFlushKeys PROC - invoke GetAsyncKeyState, VK_SPACE - invoke GetAsyncKeyState, VK_RETURN - invoke Sleep, 80 - invoke GetAsyncKeyState, VK_SPACE - invoke GetAsyncKeyState, VK_RETURN - ret -SkillCheckFlushKeys ENDP - -; --- SkillCheckPollKey: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- -SkillCheckPollKey PROC - invoke GetAsyncKeyState, VK_SPACE - test ax, 0001h - jne skill_key_pressed - invoke GetAsyncKeyState, VK_RETURN - test ax, 0001h - jne skill_key_pressed - xor eax, eax - ret -skill_key_pressed: - mov eax, 1 - ret -SkillCheckPollKey ENDP - -; --- SkillCheckDraw: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- -SkillCheckDraw PROC uses eax ebx edx - call ClearView - invoke PrintTitleColor, OFFSET skillTitle - invoke PrintStr, OFFSET skillIntro - - invoke PrintStr, OFFSET skillStateText - mov eax, skillMisses - cmp eax, 0 - je skill_draw_state_good - cmp eax, 1 - je skill_draw_state_warn - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET skillStateBad - call ResetColor - jmp skill_draw_state_done -skill_draw_state_good: - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET skillStateGood - call ResetColor - jmp skill_draw_state_done -skill_draw_state_warn: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET skillStateWarn - call ResetColor -skill_draw_state_done: - invoke PrintStr, OFFSET skillProgressText - invoke PrintUInt, skillHits - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET skillMissText - invoke PrintUInt, skillMisses - invoke PrintStr, OFFSET nl - invoke PrintStr, OFFSET skillGaugeHint - invoke PrintStr, OFFSET skillGaugeLeft - - mov skillGaugeIndex, 0 -skill_draw_gauge_loop: - mov eax, skillGaugeIndex - cmp eax, 45 - jae skill_draw_gauge_done - cmp eax, skillNeedle - je skill_draw_needle - cmp eax, skillPerfectPos - je skill_draw_perfect - cmp eax, skillSuccessStart - jb skill_draw_empty - cmp eax, skillSuccessEnd - ja skill_draw_empty - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET skillGaugeSuccess - call ResetColor - jmp skill_draw_next -skill_draw_perfect: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET skillGaugePerfect - call ResetColor - jmp skill_draw_next -skill_draw_needle: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET skillGaugeNeedle - call ResetColor - jmp skill_draw_next -skill_draw_empty: - invoke PrintStr, OFFSET skillGaugeEmpty -skill_draw_next: - inc skillGaugeIndex - jmp skill_draw_gauge_loop -skill_draw_gauge_done: - invoke PrintStr, OFFSET skillGaugeRight - invoke PrintStr, OFFSET skillGaugeLeft - mov skillGaugeIndex, 0 -skill_draw_gauge_loop2: - mov eax, skillGaugeIndex - cmp eax, 45 - jae skill_draw_gauge_done2 - cmp eax, skillNeedle - je skill_draw_needle2 - cmp eax, skillPerfectPos - je skill_draw_perfect2 - cmp eax, skillSuccessStart - jb skill_draw_empty2 - cmp eax, skillSuccessEnd - ja skill_draw_empty2 - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET skillGaugeSuccess - call ResetColor - jmp skill_draw_next2 -skill_draw_perfect2: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET skillGaugePerfect - call ResetColor - jmp skill_draw_next2 -skill_draw_needle2: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET skillGaugeNeedle - call ResetColor - jmp skill_draw_next2 -skill_draw_empty2: - invoke PrintStr, OFFSET skillGaugeEmpty -skill_draw_next2: - inc skillGaugeIndex - jmp skill_draw_gauge_loop2 -skill_draw_gauge_done2: - invoke PrintStr, OFFSET skillGaugeRight - - invoke PrintStr, OFFSET skillGaugeLeft - mov skillGaugeIndex, 0 -skill_draw_gauge_loop3: - mov eax, skillGaugeIndex - cmp eax, 45 - jae skill_draw_gauge_done3 - cmp eax, skillNeedle - je skill_draw_needle3 - cmp eax, skillPerfectPos - je skill_draw_perfect3 - cmp eax, skillSuccessStart - jb skill_draw_empty3 - cmp eax, skillSuccessEnd - ja skill_draw_empty3 - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET skillGaugeSuccess - call ResetColor - jmp skill_draw_next3 -skill_draw_perfect3: - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET skillGaugePerfect - call ResetColor - jmp skill_draw_next3 -skill_draw_needle3: - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET skillGaugeNeedle - call ResetColor - jmp skill_draw_next3 -skill_draw_empty3: - invoke PrintStr, OFFSET skillGaugeEmpty -skill_draw_next3: - inc skillGaugeIndex - jmp skill_draw_gauge_loop3 -skill_draw_gauge_done3: - invoke PrintStr, OFFSET skillGaugeRight - ret -SkillCheckDraw ENDP - -; --- SkillCheckMoveNeedle: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- -SkillCheckMoveNeedle PROC uses eax - mov eax, skillDir - cmp eax, 0FFFFFFFFh - je skill_move_left -skill_move_right: - mov eax, skillNeedle - inc eax - cmp eax, 44 - jbe skill_move_store_right - mov eax, 43 - mov skillDir, 0FFFFFFFFh -skill_move_store_right: - mov skillNeedle, eax - ret -skill_move_left: - mov eax, skillNeedle - cmp eax, 0 - ja skill_move_dec - mov eax, 1 - mov skillDir, 1 - mov skillNeedle, eax - ret -skill_move_dec: - dec eax - mov skillNeedle, eax - ret -SkillCheckMoveNeedle ENDP - -; --- SkillCheckEvaluate: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- -SkillCheckEvaluate PROC uses eax - mov eax, skillNeedle - cmp eax, skillPerfectPos - je skill_eval_perfect - cmp eax, skillSuccessStart - jb skill_eval_fail - cmp eax, skillSuccessEnd - ja skill_eval_fail - mov skillResult, 1 - ret -skill_eval_perfect: - mov skillResult, 2 - ret -skill_eval_fail: - mov skillResult, 0 - ret -SkillCheckEvaluate ENDP - -; --- SkillCheckRound: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- -SkillCheckRound PROC uses eax ebx - invoke RandomRange, 27 - add eax, 8 - mov skillSuccessStart, eax - mov ebx, eax - add ebx, 7 - mov skillSuccessEnd, ebx - invoke RandomRange, 6 - add eax, skillSuccessStart - inc eax - mov skillPerfectPos, eax - invoke RandomRange, 45 - mov skillNeedle, eax - invoke RandomRange, 2 - cmp eax, 0 - je skill_round_left - mov skillDir, 1 - jmp skill_round_begin -skill_round_left: - mov skillDir, 0FFFFFFFFh -skill_round_begin: - mov skillFrameCount, 0 - mov skillResult, 0 - mov eax, skillHits - mov ebx, eax - shl ebx, 2 - add eax, ebx - mov ebx, 45 - sub ebx, eax - mov eax, stressLevel - shl eax, 2 - sub ebx, eax - cmp ebx, 18 - jae skill_delay_ready - mov ebx, 18 -skill_delay_ready: - mov skillDelay, ebx - call SkillCheckFlushKeys -skill_round_loop: - call SkillCheckDraw - mov eax, skillDelay - invoke Sleep, eax - call SkillCheckPollKey - cmp eax, 1 - je skill_round_pressed - call SkillCheckMoveNeedle - inc skillFrameCount - cmp skillFrameCount, 120 - jb skill_round_loop - mov skillResult, 0 - ret -skill_round_pressed: - call SkillCheckEvaluate - ret -SkillCheckRound ENDP - -; --- GameSkillCheck: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- -GameSkillCheck PROC -skill_game_start: - call ClearView - invoke PrintTitleColor, OFFSET skillTitle - invoke PrintStr, OFFSET skillIntro - call PromptBet - call PlayDbDHookScene - mov skillHits, 0 - mov skillMisses, 0 - mov skillPerfects, 0 -skill_game_loop: - call SkillCheckRound - call SkillCheckDraw - mov eax, skillResult - cmp eax, 2 - je skill_game_perfect - cmp eax, 1 - je skill_game_success -skill_game_fail: - inc skillMisses - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET skillFailText - call ResetColor - invoke Sleep, 850 - cmp skillMisses, 3 - jae skill_game_lost - jmp skill_game_loop -skill_game_success: - inc skillHits - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET skillSuccessText - call ResetColor - invoke Sleep, 750 - cmp skillHits, 5 - jae skill_game_won - jmp skill_game_loop -skill_game_perfect: - add skillHits, 2 - inc skillPerfects - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET skillPerfectText - call ResetColor - invoke Sleep, 850 - cmp skillHits, 5 - jae skill_game_won - jmp skill_game_loop -skill_game_won: - call StopDbDHookScene - call SkillCheckDraw - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET skillEscapeText - call ResetColor - invoke PaySlotMultiplier, 2 - invoke UnlockAchievement, 20000h, OFFSET achSkillCheckName - call SaveGame - jmp skill_game_again -skill_game_lost: - call StopDbDHookScene - call SkillCheckDraw - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET skillDarkText - call ResetColor - call PayLose - call SaveGame -skill_game_again: - cmp tournamentMode, 1 - je skill_game_exit - invoke PrintStr, OFFSET againText - call ReadKey - cmp al, 'y' - je skill_game_start - cmp al, 'Y' - je skill_game_start -skill_game_exit: - ret -GameSkillCheck ENDP -; --- GameAchievements: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- -GameAchievements PROC - call ClearView - invoke PrintTitleColor, OFFSET achMenuTitle - invoke PrintAchievementLine, 1, OFFSET achFirstWinName - invoke PrintAchievementLine, 2, OFFSET achFirstLossName - invoke PrintAchievementLine, 4, OFFSET achJackpotName - invoke PrintAchievementLine, 8, OFFSET achHighRollerName - invoke PrintAchievementLine, 10h, OFFSET achShopperName - invoke PrintAchievementLine, 20h, OFFSET achCharmName - invoke PrintAchievementLine, 40h, OFFSET achGoalName - invoke PrintAchievementLine, 80h, OFFSET achCloverPitName - invoke PrintAchievementLine, 100h, OFFSET achClassicSlotName - invoke PrintAchievementLine, 200h, OFFSET achPokerRaiseName - invoke PrintAchievementLine, 400h, OFFSET achPokerBluffName - invoke PrintAchievementLine, 800h, OFFSET achRouletteWinName - invoke PrintAchievementLine, 1000h, OFFSET achRussianWinName - invoke PrintAchievementLine, 2000h, OFFSET achDurakWinName - invoke PrintAchievementLine, 4000h, OFFSET achBackCollectorName - invoke PrintAchievementLine, 8000h, OFFSET achCharmBuyerName - invoke PrintAchievementLine, 10000h, OFFSET achObserverName - invoke PrintAchievementLine, 20000h, OFFSET achSkillCheckName - call PauseConsole - ret -GameAchievements ENDP -; --- GameTraining: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- -GameTraining PROC - call ClearView - invoke PrintTitleColor, OFFSET trainingTitle - invoke PrintStr, OFFSET trainingText - call PauseConsole - ret -GameTraining ENDP -; --- ShowTournamentStage: òóðíèð-áàøíÿ è ïîáåäíàÿ àíèìàöèÿ ôèíàëà --- -ShowTournamentStage PROC - call ClearView - invoke PrintTitleColor, OFFSET tournamentTitle - invoke PrintStr, OFFSET tournamentStageText - invoke PrintUInt, tournamentStage - invoke PrintStr, OFFSET nl - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET hellStageCurseText - invoke RandomRange, 4 - cmp eax, 0 - je hell_stage_curse1 - cmp eax, 1 - je hell_stage_curse2 - cmp eax, 2 - je hell_stage_curse3 - invoke PrintStr, OFFSET hellCurse4 - jmp hell_stage_curse_done -hell_stage_curse1: - invoke PrintStr, OFFSET hellCurse1 - jmp hell_stage_curse_done -hell_stage_curse2: - invoke PrintStr, OFFSET hellCurse2 - jmp hell_stage_curse_done -hell_stage_curse3: - invoke PrintStr, OFFSET hellCurse3 -hell_stage_curse_done: - call ResetColor - invoke PrintStr, OFFSET tournamentMusicHint - call ReadKey - cmp al, 'm' - je tower_stage_change_music - cmp al, 'M' - jne tower_stage_done -tower_stage_change_music: - call PlayTowerRandomMusic -tower_stage_done: - ret -ShowTournamentStage ENDP - -; --- AnimateTournamentVictory: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- -AnimateTournamentVictory PROC - call PlayVictorySound - call ClearView - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET tournamentFire1 - call ResetColor - invoke Sleep, 360 - call ClearView - invoke SetColor, COLOR_TITLE - invoke PrintStr, OFFSET tournamentFire2 - call ResetColor - invoke Sleep, 360 - call ClearView - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET tournamentFire3 - call ResetColor - invoke Sleep, 420 - call ClearView - invoke SetColor, COLOR_WARN - invoke PrintStr, OFFSET tournamentFire4 - call ResetColor - invoke Sleep, 520 - ret -AnimateTournamentVictory ENDP - -; --- GameTournament: òóðíèð-áàøíÿ è ïîáåäíàÿ àíèìàöèÿ ôèíàëà --- -GameTournament PROC - mov tournamentMode, 1 - call ClearView - invoke PrintTitleColor, OFFSET tournamentTitle - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET secretHellText - call ResetColor - invoke PrintStr, OFFSET tournamentIntro - call PauseConsole - call PlayTowerRandomMusic ; tower start - - mov tournamentStage, 1 - call ShowTournamentStage - mov currentGameId, 6 - mov lastGameResult, 0 - call GameCoin - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 2 - call ShowTournamentStage - mov currentGameId, 7 - mov lastGameResult, 0 - call GameDice - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 3 - call ShowTournamentStage - mov currentGameId, 5 - mov lastGameResult, 0 - call GameSkulls - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 4 - call ShowTournamentStage - mov currentGameId, 1 - mov lastGameResult, 0 - call Game21 - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 5 - call ShowTournamentStage - mov currentGameId, 2 - mov lastGameResult, 0 - call GamePoker - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 6 - call ShowTournamentStage - mov currentGameId, 4 - mov lastGameResult, 0 - call GameRoulette - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 7 - call ShowTournamentStage - mov currentGameId, 8 - mov lastGameResult, 0 - call GameCasinoRoulette - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 8 - call ShowTournamentStage - mov currentGameId, 10 - mov lastGameResult, 0 - call GameDurak - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 9 - call ShowTournamentStage - mov currentGameId, 11 - mov lastGameResult, 0 - call GameSkillCheck - cmp lastGameResult, 2 - je tournament_failed - - mov tournamentStage, 10 - call ShowTournamentStage - mov currentGameId, 0 - mov lastGameResult, 0 - call GameBuckshot - cmp lastGameResult, 2 - je tournament_failed - - call StopTowerMusic ; before tower victory - call AnimateTournamentVictory - invoke SetColor, COLOR_MONEY - invoke PrintStr, OFFSET tournamentWinText - call ResetColor - mov currentBet, 66600 - call PayWin - call SaveGame - mov tournamentMode, 0 - call PauseConsole - ret - -tournament_failed: - call StopTowerMusic ; tower failed - invoke SetColor, COLOR_BAD - invoke PrintStr, OFFSET tournamentFailText - call ResetColor - mov tournamentMode, 0 - call PauseConsole - ret -GameTournament ENDP - - -; --- GameUmamusume: Umamusume Pretty Derby Minigame --- -GameUmamusume PROC uses ebx esi edi - invoke PrintStr, OFFSET umaTitleText - call PromptBet - cmp eax, 0 - jle uma_exit - -uma_select_horse: - invoke PrintStr, OFFSET umaMenuText - invoke PrintStr, OFFSET umaChoiceText - call ReadBetInput - cmp eax, 1 - jl uma_invalid - cmp eax, 5 - jg uma_invalid - mov umaChoice, eax - jmp uma_start_race - -uma_invalid: - invoke PrintStr, OFFSET badChoiceText - jmp uma_select_horse - -uma_start_race: - xor eax, eax - mov umaPos[0], eax - mov umaPos[4], eax - mov umaPos[8], eax - mov umaPos[12], eax - mov umaPos[16], eax - mov umaWinner, 0 - -uma_race_loop: - invoke PrintStr, OFFSET clearLines - invoke PrintStr, OFFSET umaTrackHeader - - ; Horse 1: Special Week (1-3) - invoke RandomRange, 3 - inc eax - add umaPos[0], eax - - ; Horse 2: Silence Suzuka (1-4) - invoke RandomRange, 4 - inc eax - add umaPos[4], eax - - ; Horse 3: Tokai Teio (1-3, boost if pos > 18) - invoke RandomRange, 3 - inc eax - cmp umaPos[8], 18 - jbe uma_t3_no_boost - add eax, 2 -uma_t3_no_boost: - add umaPos[8], eax - - ; Horse 4: Gold Ship (0-6 wildcard) - invoke RandomRange, 7 - add umaPos[12], eax - - ; Horse 5: Mejiro McQueen (steady 2-4) - invoke RandomRange, 3 - add eax, 2 - add umaPos[16], eax - - ; Render track - mov ecx, 0 -uma_render_lane: - push ecx - mov eax, [umaHorseNames + ecx*4] - invoke PrintStr, eax - - mov ebx, [umaPos + ecx*4] - cmp ebx, 0 - jbe uma_render_head - mov edi, ebx -uma_print_step: - push edi - invoke PrintStr, OFFSET umaStepChar - pop edi - dec edi - jnz uma_print_step - -uma_render_head: - invoke PrintStr, OFFSET umaHeadChar - invoke PrintStr, OFFSET umaFinishText - - pop ecx - inc ecx - cmp ecx, 5 - jl uma_render_lane - - ; Check if finish reached (>= 35) - mov eax, 0 -uma_check_finish: - cmp dword ptr [umaPos + eax*4], 35 - jge uma_finish_reached - inc eax - cmp eax, 5 - jl uma_check_finish - - invoke Sleep, 180 - jmp uma_race_loop - -uma_finish_reached: - mov ebx, 0 - mov edi, 1 - mov ecx, 0 -uma_find_max: - mov edx, [umaPos + ecx*4] - cmp edx, ebx - jle uma_next_max - mov ebx, edx - lea edi, [ecx + 1] -uma_next_max: - inc ecx - cmp ecx, 5 - jl uma_find_max - - mov umaWinner, edi - invoke PrintStr, OFFSET umaWinAnnouncement - mov eax, edi - dec eax - mov eax, [umaHorseNames + eax*4] - invoke PrintStr, eax - invoke PrintStr, OFFSET nl - - mov eax, umaChoice - cmp eax, umaWinner - jne uma_race_lost - - invoke PrintStr, OFFSET umaYouWinText - mov ecx, umaChoice - dec ecx - mov eax, currentBet - mov edx, [umaMultipliers + ecx*4] - imul eax, edx - push eax - invoke PrintUInt, eax - invoke PrintStr, OFFSET nl - pop eax - call PayWin - call PrintWinEvent - jmp uma_race_done - -uma_race_lost: - invoke PrintStr, OFFSET umaYouLoseText - call PayLose - call PrintLoseEvent - -uma_race_done: - call PauseConsole -uma_exit: - ret -GameUmamusume ENDP - -; --- GamePlayerTerminal: Èãðîâîé òåðìèíàë (ñòàòèñòèêà, à÷èâêè, êâåñòû) --- -titleTerminal db "=== ÒÅÐÌÈÍÀË ÈÃÐÎÊÀ ===",13,10,0 -textTerminalMenu db "1. Äîñòèæåíèÿ",13,10,"2. Ñòàòèñòèêà ïî èãðàì",13,10,"3. Åæåäíåâíûå çàäàíèÿ",13,10,"4. Ãëàâíîå ìåíþ è ÷èòû",13,10,"0. Íàçàä â êàçèíî",13,10,0 - -GamePlayerTerminal PROC -terminal_loop: - call ClearView - invoke PrintTitleColor, OFFSET titleTerminal - invoke PrintStr, OFFSET textTerminalMenu - invoke PrintStr, OFFSET choiceText - call ReadKey - cmp al, '1' - je term_ach - cmp al, '2' - je term_stats - cmp al, '3' - je term_daily - cmp al, '4' - je term_classic_menu - cmp al, '0' - je term_exit - cmp al, 1Bh - je term_exit - jmp terminal_loop -term_ach: - call GameAchievements - jmp terminal_loop -term_stats: - call GameStatsByGame - jmp terminal_loop -term_daily: - call GameDailyTasks - jmp terminal_loop -term_classic_menu: - call MainMenu - jmp terminal_loop -term_exit: - ret -GamePlayerTerminal ENDP - -include casino3d.inc - - - -; --- AutoLoadAccountFast: àâòîçàãðóçêà ïðîôèëÿ áåç áëîêèðîâêè â CMD --- -AutoLoadAccountFast PROC - call ResetProfileDefaults - call CollectAccounts - cmp accountCount, 0 - jbe autoload_exit - mov selectedAccount, 1 - call CopySelectedAccountName - call LoadSave -autoload_exit: - ret -AutoLoadAccountFast ENDP - -; --- MainMenu: òî÷êà âõîäà, ãëàâíîå ìåíþ è ìàðøðóòèçàöèÿ ïî èãðàì --- - -MainMenu PROC -menu_loop: - call DailyCheckDate - call CheckSecretEnding - invoke PrintStr, OFFSET clearLines - invoke PrintTitleColor, OFFSET titleText - call PrintBank - call PrintGoal - call ShowStats - invoke PrintStr, OFFSET menuText - invoke PrintStr, OFFSET choiceText - call ReadBetInput - cmp eax, 0FFFFFFFFh - je menu_loop - cmp eax, 0FFFFFFFDh - je menu_loop - cmp eax, 1 - je run_shop - cmp eax, 2 - je run_21 - cmp eax, 3 - je run_poker - cmp eax, 4 - je run_slot - cmp eax, 5 - je run_skulls - cmp eax, 6 - je run_roulette - cmp eax, 7 - je run_coin - cmp eax, 8 - je run_dice - cmp eax, 9 - je run_casino_roulette - cmp eax, 10 - je run_classic_slot - cmp eax, 11 - je run_durak - cmp eax, 12 - je run_skill_check - cmp eax, 13 - je run_buckshot - cmp eax, 14 - je run_observer - cmp eax, 15 - je run_training - cmp eax, 16 - je run_achievements - cmp eax, 17 - je run_stats_by_game - cmp eax, 18 - je run_daily - cmp eax, 19 - je run_settings - cmp eax, 20 - je run_online_dice - cmp eax, 21 - je run_umamusume - cmp eax, 25 - - je run_casino_3d - - cmp eax, 666 - je run_hell_tower - cmp eax, 0 - je exit_menu - invoke PrintStr, OFFSET badChoiceText - call PauseConsole - jmp menu_loop -run_21: - mov currentGameId, 1 - call Game21 - jmp menu_loop -run_poker: - mov currentGameId, 2 - call GamePoker - jmp menu_loop -run_slot: - mov currentGameId, 3 - call PlaySlotIntroSound - call GameSlot - jmp menu_loop -run_skulls: - mov currentGameId, 5 - call GameSkulls - jmp menu_loop -run_coin: - mov currentGameId, 6 - call GameCoin - jmp menu_loop -run_dice: - mov currentGameId, 7 - call GameDice - jmp menu_loop -run_roulette: - mov currentGameId, 4 - call GameRoulette - jmp menu_loop -run_casino_roulette: - mov currentGameId, 8 - call GameCasinoRoulette - jmp menu_loop -run_classic_slot: - mov currentGameId, 9 - call PlaySlotIntroSound - call GameClassicSlot - jmp menu_loop -run_durak: - mov currentGameId, 10 - call GameDurak - jmp menu_loop -run_training: - mov currentGameId, 0 - call GameTraining - jmp menu_loop -run_observer: - mov currentGameId, 0 - call GameObserver - jmp menu_loop -run_shop: - mov currentGameId, 0 - call GameShop - jmp menu_loop -run_achievements: - mov currentGameId, 0 - call GameAchievements - jmp menu_loop -run_stats_by_game: - mov currentGameId, 0 - call GameStatsByGame - jmp menu_loop -run_daily: - mov currentGameId, 0 - call GameDailyTasks - jmp menu_loop -run_settings: - mov currentGameId, 0 - call GameSettings - jmp menu_loop -run_online_dice: - mov currentGameId, 0 - call GameOnlineCasino - jmp menu_loop -run_umamusume: - mov currentGameId, 0 - call GameUmamusume - jmp menu_loop -run_casino_3d: - - call StartCasino3D - - jmp menu_loop - -run_hell_tower: - mov currentGameId, 0 - call GameTournament - jmp menu_loop -run_skill_check: - mov tournamentMode, 0 - mov currentGameId, 11 - call GameSkillCheck - jmp menu_loop -run_buckshot: - mov currentGameId, 0 - call GameBuckshot - jmp menu_loop -exit_menu: - ret -MainMenu ENDP - -; --- main: òî÷êà âõîäà, ãëàâíîå ìåíþ è ìàðøðóòèçàöèÿ ïî èãðàì --- -main PROC -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 +.386 +.model flat, stdcall +option casemap:none + +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 280 +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 +PrintSlotSymbol PROTO :DWORD +RandomRange PROTO :DWORD +PrintUInt PROTO :DWORD +UnlockAchievement PROTO :DWORD, :DWORD +ShowBestiaryPage PROTO :DWORD, :DWORD, :DWORD + +.data +; === Ãëîáàëüíûå äåñêðèïòîðû, áóôåðû êîíñîëè, RNG è âðåìåííàÿ ïàìÿòü === +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) +cheatBuffer db 32 dup(0) +wideBuffer dw 4096 dup(0) +utf8Buffer db 8192 dup(0) +frameBuffer db 32768 dup(0) +deckUsed db 52 dup(0) +onlineWsaData db 400 dup(0) +onlineAddr db 16 dup(0) +onlineIp db 32 dup(0) +onlineListenSock dd -1 +onlinePeerSock dd -1 +onlineWsaReady dd 0 +onlinePacket dd 0, 0 +onlineLocalRoll dd 0 +onlineRemoteRoll dd 0 +onlineGameMode dd 0 +onlineHostIp dd 0 +onlineAction dd 1 +consoleRectTiny dw 0, 0, 119, 34 +consoleRect160 dw 0, 0, 159, 44 +consoleRect140 dw 0, 0, 139, 39 +consoleRect120 dw 0, 0, 119, 34 + +; === Îáùèå ñ÷åò÷èêè î÷êîâ è ñîñòîÿíèå ñòàðûõ êàðòî÷íûõ ðåæèìîâ === +playerTotal dd 0 +dealerTotal dd 0 +playerAces dd 0 +dealerAces dd 0 +playerCards dd 0 +; === Ñîñòîÿíèå CloverPit / ñëîò-ìàøèí: ñåòêà, âûïëàòû, êîìáèíàöèè === +slotA dd 0 +slotB dd 0 +slotC dd 0 +slotD dd 0 +slotE dd 0 +slotMatch dd 0 +slotWinMask dd 0 +slotCurrentCell 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) +slotVisible dd 0 +; === Îáùàÿ êàðòî÷íàÿ ìîäåëü: ðóêè èãðîêà, AI è êàðòû íà ñòîëå === +playerHand21 dd 10 dup(0) +aiHand21 dd 10 dup(0) +communityHand dd 5 dup(0) +pokerPlayerEvalHand dd 7 dup(0) +pokerAIEvalHand dd 7 dup(0) +playerCnt21 dd 0 +aiCnt21 dd 0 +communityCnt dd 0 +revealAI21 dd 0 +dangerLvl21 dd 0 +cardsLeft21 dd 0 +rowIndex dd 0 +pokerPlayerScore dd 0 +pokerAIScore dd 0 +pokerEvalCount dd 0 +; === Ýêîíîìèêà àêêàóíòà: áàíê, öåëü, ñòàâêà è ÷èò-ôëàãè === +bankroll dd 10000 +targetBank dd 50000 +currentBet dd 0 +cheatLuckyWin dd 0 +cheatGodMode dd 0 +cheatSlotJackpot dd 0 +settingsVolume dd 10 +settingsLowSpec dd 0 +settingsIntroEnabled dd 1 +settingsDbdWindowEnabled dd 0 +animFrameCounter dd 0 +animWidth dd 0 +animHeight dd 0 +secretEndingSeen dd 0 +vipTaxAmount dd 0 +; === Êðóïüå-êîììåíòàòîð: ÷òåíèå ôðàç èç dealer_phrases.txt === +dealerFileHandle dd 0 +dealerLineLen dd 0 +dealerPhraseCount dd 0 +dealerPhrasePick dd 0 +dealerScanMode dd 0 +dealerWantedTag db 0 +; === Ìàãàçèí: êóïëåííûå ðóáàøêè, âûáðàííàÿ ðóáàøêà è òàëèñìàíû === +shopBackOwned dd 1 +shopBackStyle dd 0 +shopCharmLevel dd 0 +shopCharmUses dd 0 +achievements dd 0 +pokerRaiseAmount dd 0 +pokerAIRaiseAmount dd 0 +; === Ôàéëû, àêêàóíòû, ñîõðàíåíèÿ, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ === +saveHandle dd 0 +achievementHandle dd 0 +findHandle dd 0 +danceHandle dd 0 +danceBytes dd 0 +frameBytes dd 0 +introLoopSeen dd 0 +introSkipLoop dd 0 +accountCount 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) +leaderBestBank dd 0 +leaderBestWins dd 0 +leaderBestLosses dd 0 +leaderValidCount dd 0 +leaderScanIndex dd 0 +leaderAccountPtr dd 0 +leaderBestGameWins dd 11 dup(0) +leaderBestGameLosses dd 11 dup(0) +leaderBestBankName db 64 dup(0) +leaderBestWinsName db 64 dup(0) +leaderBestLossName db 64 dup(0) +leaderBestGameWinNames db 11 dup(64 dup(0)) +leaderBestGameLossNames db 11 dup(64 dup(0)) +; === Íàñòðîéêè ñëîæíîñòè, âðåìåííûå ïåðåìåííûå ïîêåðà è ìèíè-èãð === +aiDifficulty dd 2 +bankRecovered dd 0 +saveTampered dd 0 +pokerReplaceIndex dd 0 +pokerReplaced dd 0 +pokerStraight dd 0 +pokerFlush dd 0 +pokerHigh dd 0 +pokerFour dd 0 +pokerTrip dd 0 +pokerPairHigh dd 0 +pokerPairLow dd 0 +; === ×åðåïà è øàðèê: ïîçèöèÿ øàðèêà, âûáîð è ÷èñëî ïåðåìåøèâàíèé === +skullBallPos dd 0 +skullGuess dd 0 +skullStep dd 0 +skullMax dd 0 +; === Ðóññêàÿ ðóëåòêà: áàðàáàí, ïàòðîíû, õîä è ìíîæèòåëü === +rrBulletMask dd 0 +rrBullets dd 0 +rrChamber dd 0 +rrTurn dd 0 +rrPayout dd 0 +; === Buckshot Roulette: ïàòðîíû, çäîðîâüå, ïðåäìåòû è ñîñòîÿíèå õîäà === +bsShells dd 8 dup(0) +bsShellIndex dd 0 +bsShellCount dd 0 +bsLiveCount dd 0 +bsBlankCount dd 0 +bsPlayerHP dd 0 +bsAIHP dd 0 +bsTurn dd 0 +bsDamage dd 1 +bsKnownShell dd 0FFFFFFFFh +bsSkipPlayer dd 0 +bsSkipAI dd 0 +bsPlayerGlass dd 0 +bsPlayerSaw dd 0 +bsPlayerBeer dd 0 +bsPlayerCuffs dd 0 +bsAIGlass dd 0 +bsAISaw dd 0 +bsAIBeer dd 0 +bsAICuffs dd 0 +bsTarget dd 0 +bsShell dd 0 +bsAction dd 0 +; === Ìèíè-èãðû îðåë/ðåøêà, êîñòè è êàçèíî-ðóëåòêà === +coinPick dd 0 +coinResult dd 0 +diceA dd 0 +diceB dd 0 +diceSum dd 0 +diceChoice dd 0 +casinoRouletteBetType dd 0 +casinoRouletteBetNumber dd 0 +casinoRouletteResult dd 0 +casinoRouletteResultIndex dd 0 +casinoRouletteSpinIndex dd 0 +casinoRouletteSpinSteps dd 0 +casinoRouletteSpinCounter dd 0 +casinoRouletteVisibleCount 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 +durakAttackCard dd 0FFFFFFFFh +durakDefenseCard dd 0FFFFFFFFh +durakPlayerTurn dd 1 +durakChoice dd 0 +durakTableCnt dd 0 +durakAttackCards dd 6 dup(0) +durakDefenseCards dd 6 dup(0FFFFFFFFh) +durakTempHand dd 6 dup(0) +durakSafeTurns dd 0 +durakLoopGuard dd 0 +; === Skill Check, ñòðåññ, ïîäîçðåíèå êàçèíî è òóðíèð-áàøíÿ === +skillNeedle dd 0 +skillDir dd 1 +skillSuccessStart dd 0 +skillSuccessEnd dd 0 +skillPerfectPos dd 0 +skillGaugeIndex dd 0 +skillFrameCount dd 0 +skillHits dd 0 +skillMisses dd 0 +skillResult dd 0 +skillPerfects dd 0 +skillDelay dd 45 +casinoSuspicion dd 0 +stressLevel dd 0 +lastGameResult dd 0 +tournamentStage dd 0 +tournamentMode dd 0 +dailyDateKey dd 0 +dailyRewardMask dd 0 +dailyProgressPacked dd 0 +dailyTaskPacked dd 0 +systemTime dw 8 dup(0) +pulseCycles dd 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 + +titleText db "==============================",13,10 + db " ASSEMBLER CASINO",13,10 + db "==============================",13,10,0 +menuText db "1. Ìàãàçèí",13,10 + db "2. 21 / Î÷êî",13,10 + db "3. Poker",13,10 + db "4. CloverPit",13,10 + db "5. ×åðåïà è øàðèê",13,10 + db "6. Ðóññêàÿ ðóëåòêà",13,10 + db "7. Îðåë è ðåøêà",13,10 + db "8. Êîñòè",13,10 + db "9. Êàçèíî-ðóëåòêà",13,10 + db "10. Slot machine",13,10 + db "11. Äóðàê",13,10 + db "12. Êðþê: Skill Check",13,10 + db "13. Buckshot Roulette",13,10 + db "14. Íàáëþäàòåëü AI vs AI",13,10 + db "15. Îáó÷åíèå",13,10 + db "16. Äîñòèæåíèÿ",13,10 + db "17. Ñòàòèñòèêà ïî èãðàì",13,10 + db "18. Åæåäíåâíûå çàäàíèÿ",13,10 + db "19. Íàñòðîéêè",13,10 + db "20. Online Casino (Radmin)",13,10 + db "21. Umamusume Ñêà÷êè",13,10 + + db "25. 3D-ÊÀÇÈÍÎ (DOOM / Wolf3D Raycaster 2.5D) [NEW]",13,10 + + db "0. Exit",13,10,0 +choiceText db "Âûáîð: ",0 +badChoiceText db "Íåò òàêîãî ïóíêòà.",13,10,0 +accountMenuText db "1. Âîéòè â àêêàóíò",13,10 + db "2. Ñîçäàòü àêêàóíò",13,10,0 +accountPromptText db "Ââåäèòå èìÿ àêêàóíòà ëàòèíèöåé: ",0 +accountBadText db "Èìÿ äîëæíî ñîäåðæàòü õîòÿ áû îäíó áóêâó èëè öèôðó.",13,10,0 +accountLoginText db "Àêêàóíò çàãðóæåí: ",0 +accountCreateText db "Àêêàóíò ñîçäàí: ",0 +accountListTitle db "Âûáåðèòå àêêàóíò:",13,10,0 +accountNoFilesText db "Ñîõðàíåííûõ àêêàóíòîâ ïîêà íåò.",13,10,0 +accountSelectText db "Íîìåð àêêàóíòà: ",0 +pauseText db 13,10,"Íàæìèòå ëþáóþ êëàâèøó...",0 +bankText db "Âàø áàíê: $",0 +betText db "Ââåäèòå ñòàâêó: $",0 +betChosenText db "Âû ïîñòàâèëè $",0 +badBetText db "Ñòàâêà äîëæíà áûòü ÷èñëîì áîëüøå 0.",13,10,0 +tooBigBetText db "Ó âàñ íåò ñòîëüêî äåíåã.",13,10,0 +suspicionText db "Ïîäîçðåíèå êàçèíî: ",0 +suspicionCalmText db "òèõî",13,10,0 +suspicionWatchText db "çà òîáîé ñìîòðÿò",13,10,0 +suspicionHuntText db "îõðàíà ðÿäîì",13,10,0 +suspicionUpText db "Ïîäîçðåíèå âûðîñëî.",13,10,0 +suspicionFineText db "Îõðàíà çàìåòèëà ìóòíóþ èãðó. Øòðàô: $",0 +stressText db "Ñòðåññ ñòàâêè: ",0 +stressLowText db "ñïîêîéíî",13,10,0 +stressMidText db "ïóëüñ ðàñòåò",13,10,0 +stressHighText db "ðóêè äðîæàò",13,10,0 +stressMaxText db "ïàíèêà",13,10,0 +cheatMoveText db "Øóëåðñòâî: 3 - ïîäñìîòðåòü, 4 - ïîäìåíèòü êàðòó.",13,10,0 +cheatPeekText db "Òû íåçàìåòíî ïîäñìîòðåë êàðòó:",13,10,0 +cheatSwapText db "Òû ïîäìåíèë êàðòó ïîä ðóêàâîì.",13,10,0 +cheatNoTargetText db "Ñåé÷àñ íå÷åãî ïîäìåíÿòü.",13,10,0 +tournamentTitle db 13,10,"--- Ñåêðåòíûé ðåæèì: Àäñêàÿ áàøíÿ ---",13,10,0 +tournamentIntro db "Àäñêàÿ áàøíÿ êàçèíî: 10 ýòàïîâ ïîäðÿä. Ïðîèãðàë - íà÷èíàåøü çàíîâî.",13,10 + db "Âõîä ñêðûò. Êîä 666 ïðèíÿò. Ìóçûêó ìîæíî ìåíÿòü êëàâèøåé M ïåðåä ýòàïîì.",13,10,0 +tournamentStageText db 13,10,"Ýòàï áàøíè: ",0 +tournamentMusicHint db "M - ñëó÷àéíî ñìåíèòü ìóçûêó áàøíè, ëþáàÿ äðóãàÿ êëàâèøà - íà÷àòü ýòàï",13,10,0 +secretHellText db 13,10,"Ñåêðåòíûé êîä ïðèíÿò. Êàçèíî îïóñêàåò òåáÿ â Àäñêóþ áàøíþ...",13,10,0 +hellStageCurseText db "Ïðîêëÿòèå ýòàïà: ",0 +hellCurse1 db "êðóïüå áîëüøå íå ìîðãàåò.",13,10,0 +hellCurse2 db "ìóçûêà èãðàåò, äàæå åñëè òû ïðîèãðûâàåøü.",13,10,0 +hellCurse3 db "êàæäàÿ ñòàâêà ïàõíåò ñåðîé.",13,10,0 +hellCurse4 db "îõðàííèê óæå çíàåò òâîå èìÿ.",13,10,0 +tournamentFailText db 13,10,"Àäñêàÿ áàøíÿ çàêðûëà äâåðè. Òóðíèð íà÷èíàåòñÿ çàíîâî.",13,10,0 +tournamentWinText db 13,10,"ÒÛ ÂÛÆÈË Â ÀÄÑÊÎÉ ÁÀØÍÅ! Ñåêðåòíûé áîíóñ: $66600",13,10,0 +tournamentFire1 db 13,10," . * .",13,10," ASSEMBLER CASINO",13,10," . | .",13,10," ___ /---\ ___",13,10," /___\ | T | /___\",13,10,0 +tournamentFire2 db 13,10," * \ | / \ | / *",13,10," -- TOWER CLEARED --",13,10," * / | \ / | \ *",13,10," ___ /---\ ___",13,10," /___\ | 10| /___\",13,10,0 +tournamentFire3 db 13,10," * . * . * . * . * . * . *",13,10," $$$ FIREWORKS $$$",13,10," . * . * . * . * . * . * .",13,10," \ \ | / /",13,10," \__\_|_/__/",13,10,0 +tournamentFire4 db 13,10," ============ JACKPOT SKY ============",13,10," * * * * *",13,10," * CASINO CHAMPION *",13,10," * * * * *",13,10," =====================================",13,10,0 +dailyTitle db 13,10,"--- Åæåäíåâíûå çàäàíèÿ ---",13,10,0 +dailyIntro db "Êàæäûé êàëåíäàðíûé äåíü êàçèíî âûáèðàåò 3 çàäàíèÿ èç 40.",13,10,0 +dailyDateText db "Äàòà çàäàíèÿ: ",0 +dailyPoolText db "Ïóë çàäàíèé: 40. Ñåãîäíÿ âûáðàíî: 3",13,10,0 +dailySlashText db " / ",0 +dailyRewardText db " Íàãðàäà: $",0 +dailyClaimText db "Åæåäíåâíàÿ íàãðàäà ïîëó÷åíà: +$",0 +dailyDoneText db " [ïîëó÷åíî]",13,10,0 +dailyOpenText db " [â ïðîöåññå]",13,10,0 +settingsTitle db 13,10,"--- Íàñòðîéêè êàçèíî ---",13,10,0 +settingsMenuText db "1. Òèøå",13,10 + db "2. Ãðîì÷å",13,10 + db "3. Ïðîôèëü àíèìàöèé",13,10 + db "4. Ïåðåêëþ÷èòü èíòðî",13,10 + db "5. Ïåðåêëþ÷èòü DBD-îêíî",13,10 + db "0. Íàçàä",13,10 + db "Âûáîð: ",0 +settingsVolumeText db "Ãðîìêîñòü: ",0 +settingsVolumeHint db "0 - áåç çâóêà, 10 - ìàêñèìóì",13,10,0 +settingsModeText db "Ïðîôèëü àíèìàöèé: ",0 +settingsNormalText db "îáû÷íûé",13,10,0 +settingsLowText db "ñëàáûé ÏÊ",13,10,0 +settingsIntroText db "Èíòðî: ",0 +settingsDbdText db "DBD-îêíî: ",0 +settingsOnText db "âêë",13,10,0 +settingsOffText db "âûêë",13,10,0 +settingsCinematicText db "Cinematic - ìàêñèìóì",13,10,0 +settingsAdaptiveText db "Adaptive - ìÿã÷å",13,10,0 +settingsStableText db "Stable - ìåíüøå ðÿáè",13,10,0 +settingsAnimHintText db "Cinematic: âñå êàäðû; Adaptive: ìåíüøå ðÿáè; Stable: äëÿ ñëàáûõ ÏÊ.",13,10,0 +vipStatusText db "VIP-ñòàòóñ: ",0 +vipBronzeText db "Bronze",13,10,0 +vipSilverText db "Silver",13,10,0 +vipGoldText db "Gold",13,10,0 +vipDiamondText db "Diamond",13,10,0 +vipTaxText db "Êîìèññèÿ êàçèíî: $",0 +secretEndingTitle db 13,10,"========================================",13,10," ÊÀÇÈÍÎ ÏÐÈÇÍÀËÎ ÒÅÁß ÑÂÎÈÌ",13,10,"========================================",13,10,0 +secretEndingBody db "Òû ñîáðàë âñå äîñòèæåíèÿ, ñêóïèë ðóáàøêè è âûíåñ áàíê òàê, ÷òî êðóïüå áîëüøå íå ñïîðèò.",13,10,"Äâåðè ñëóæåáíîãî ëèôòà îòêðûâàþòñÿ. Íà òàáëè÷êå îäíà ôðàçà: HOUSE PLAYER.",13,10,"Ñåêðåòíàÿ êîíöîâêà îòêðûòà.",13,10,0 +secretEndingArt1 db " .---. .---. .---.",13,10," / $ / / VIP / / $ /",13,10," \\____/ \\____/ \\____/",13,10,0 +secretEndingArt2 db " ======= ASSEMBLER CASINO PRIVATE FLOOR =======",13,10," cards slots roulette secrets",13,10," =================================================",13,10,0 +dailyReadyText db " [ãîòîâî ê ïîëó÷åíèþ]",13,10,0 +dailyTaskName01 db "Ñûãðàòü 3 èãðû",0 +dailyTaskName02 db "Ñûãðàòü 5 èãð",0 +dailyTaskName03 db "Ñûãðàòü 7 èãð",0 +dailyTaskName04 db "Ïîáåäèòü 1 ðàç",0 +dailyTaskName05 db "Ïîáåäèòü 2 ðàçà",0 +dailyTaskName06 db "Ïîáåäèòü 3 ðàçà",0 +dailyTaskName07 db "Ïðîèãðàòü 1 ðàç",0 +dailyTaskName08 db "Ïðîèãðàòü 2 ðàçà",0 +dailyTaskName09 db "Ñäåëàòü íè÷üþ 1 ðàç",0 +dailyTaskName10 db "Ïîñòàâèòü îò $5000",0 +dailyTaskName11 db "Ïîñòàâèòü îò $5000 òðè ðàçà",0 +dailyTaskName12 db "Ïîñòàâèòü îò $10000",0 +dailyTaskName13 db "Ñûãðàòü â 21",0 +dailyTaskName14 db "Ïîáåäèòü â 21",0 +dailyTaskName15 db "Ñûãðàòü â Poker",0 +dailyTaskName16 db "Ïîáåäèòü â Poker",0 +dailyTaskName17 db "Ñûãðàòü â CloverPit",0 +dailyTaskName18 db "Ïîáåäèòü â CloverPit",0 +dailyTaskName19 db "Ñûãðàòü â ðóññêóþ ðóëåòêó",0 +dailyTaskName20 db "Ïîáåäèòü â ðóññêóþ ðóëåòêó",0 +dailyTaskName21 db "Ñûãðàòü â ÷åðåïà",0 +dailyTaskName22 db "Ïîáåäèòü â ÷åðåïà",0 +dailyTaskName23 db "Ñûãðàòü â îðëà è ðåøêó",0 +dailyTaskName24 db "Ïîáåäèòü â îðëà è ðåøêó",0 +dailyTaskName25 db "Ñûãðàòü â êîñòè",0 +dailyTaskName26 db "Ïîáåäèòü â êîñòè",0 +dailyTaskName27 db "Ñûãðàòü â êàçèíî-ðóëåòêó",0 +dailyTaskName28 db "Ïîáåäèòü â êàçèíî-ðóëåòêó",0 +dailyTaskName29 db "Ñûãðàòü â Slot machine",0 +dailyTaskName30 db "Ïîáåäèòü â Slot machine",0 +dailyTaskName31 db "Ñûãðàòü â äóðàêà",0 +dailyTaskName32 db "Ïîáåäèòü â äóðàêà",0 +dailyTaskName33 db "Ñûãðàòü â Skill Check",0 +dailyTaskName34 db "Ïîáåäèòü â Skill Check",0 +dailyTaskName35 db "Ñûãðàòü 2 êàðòî÷íûå èãðû",0 +dailyTaskName36 db "Ïîáåäèòü â êàðòî÷íîé èãðå",0 +dailyTaskName37 db "Ñûãðàòü 3 èãðû óäà÷è",0 +dailyTaskName38 db "Ïîáåäèòü 2 ðàçà â èãðàõ óäà÷è",0 +dailyTaskName39 db "Ñûãðàòü 2 îïàñíûå èãðû",0 +dailyTaskName40 db "Ïîáåäèòü â îïàñíîé èãðå",0 +dailyTaskNameTable dd OFFSET dailyTaskName01, OFFSET dailyTaskName02, OFFSET dailyTaskName03, OFFSET dailyTaskName04 + dd OFFSET dailyTaskName05, OFFSET dailyTaskName06, OFFSET dailyTaskName07, OFFSET dailyTaskName08 + dd OFFSET dailyTaskName09, OFFSET dailyTaskName10, OFFSET dailyTaskName11, OFFSET dailyTaskName12 + dd OFFSET dailyTaskName13, OFFSET dailyTaskName14, OFFSET dailyTaskName15, OFFSET dailyTaskName16 + dd OFFSET dailyTaskName17, OFFSET dailyTaskName18, OFFSET dailyTaskName19, OFFSET dailyTaskName20 + dd OFFSET dailyTaskName21, OFFSET dailyTaskName22, OFFSET dailyTaskName23, OFFSET dailyTaskName24 + dd OFFSET dailyTaskName25, OFFSET dailyTaskName26, OFFSET dailyTaskName27, OFFSET dailyTaskName28 + dd OFFSET dailyTaskName29, OFFSET dailyTaskName30, OFFSET dailyTaskName31, OFFSET dailyTaskName32 + dd OFFSET dailyTaskName33, OFFSET dailyTaskName34, OFFSET dailyTaskName35, OFFSET dailyTaskName36 + dd OFFSET dailyTaskName37, OFFSET dailyTaskName38, OFFSET dailyTaskName39, OFFSET dailyTaskName40 +cheatAppliedText db "CHEAT ACTIVATED: ",0 +cheatBadText db "Unknown cheat code.",13,10,0 +cheatMoneyText db "+$50000",13,10,0 +cheatSevenText db "+$7777",13,10,0 +cheatWinText db "next loss becomes win",13,10,0 +cheatGodText db "losses become wins",13,10,0 +cheatFairText db "fair play restored",13,10,0 +cheatGoalText db "bank moved to current goal",13,10,0 +cheatResetText db "bank reset to $10000",13,10,0 +cheatEasyText db "AI difficulty EASY",13,10,0 +cheatNormalText db "AI difficulty NORMAL",13,10,0 +cheatHardText db "AI difficulty HARD",13,10,0 +cheatJackpotText db "next slot spin is forced jackpot",13,10,0 +cheatRichText db "+$250000",13,10,0 +cheatDoubleText db "bank doubled",13,10,0 +cheatPoorText db "bank set to $1",13,10,0 +cheatShopText db "+$30000 for shop",13,10,0 +cheatBacksText db "all card backs unlocked",13,10,0 +cheatCharmText db "luck talisman maxed",13,10,0 +cheatNoCharmText db "luck talisman removed",13,10,0 +cheatAchText db "all achievements unlocked",13,10,0 +cheatSavedText db "CHEAT: loss changed into win.",13,10,0 +cheatCodeMoney db "MONEYRAIN",0 +cheatCodeSeven db "SEVENS",0 +cheatCodeWin db "WINNEXT",0 +cheatCodeGod db "GODMODE",0 +cheatCodeFair db "FAIRPLAY",0 +cheatCodeGoal db "GOAL",0 +cheatCodeReset db "RESETBANK",0 +cheatCodeEasy db "EASYAI",0 +cheatCodeNormal db "NORMALAI",0 +cheatCodeHard db "HARDAI",0 +cheatCodeJackpot db "JACKPOT",0 +cheatCodeRich db "HIGHROLLER",0 +cheatCodeDouble db "DOUBLECASH",0 +cheatCodePoor db "ONEBUCK",0 +cheatCodeShop db "SHOPPING",0 +cheatCodeBacks db "ALLBACKS",0 +cheatCodeCharm db "MAXCHARM",0 +cheatCodeNoCharm db "NOCHARM",0 +cheatCodeAch db "ACHIEVER",0 +moneyWinText db "Âûèãðûø: +$",0 +moneyLoseText db "Ïðîèãðûø: -$",0 +moneyDrawText db "Ñòàâêà âîçâðàùàåòñÿ.",13,10,0 +casinoKickText db 13,10,"Ó âàñ íå îñòàëîñü äåíåã. Âàñ âûâîäÿò èç êàçèíî.",13,10,0 +casinoExitText db "Íàæìèòå ëþáóþ êëàâèøó, ÷òîáû âûéòè...",0 +welcomeText db 13,10,"Äîáðî ïîæàëîâàòü â ASSEMBLER CASINO!",13,10,"Óäà÷à ëþáèò ñìåëûõ, íî êàçèíî ëþáèò ìàòåìàòèêó.",13,10,0 +difficultyText db 13,10,"Ñëîæíîñòü AI: 1 - Easy, 2 - Normal, 3 - Hard: ",0 +difficultyNowText db "Ñëîæíîñòü AI: ",0 +easyName db "Easy",13,10,0 +normalName db "Normal",13,10,0 +hardName db "Hard",13,10,0 +statsGamesText db "Èãð ñûãðàíî: ",0 +statsWinsText db "Ïîáåä: ",0 +statsLossText db "Ïîðàæåíèé: ",0 +statsDrawText db "Íè÷üèõ: ",0 +statsBestWinText db "Ìàêñ. âûèãðûø: $",0 +statsBestLossText db "Ìàêñ. ïðîèãðûø: $",0 +statsByGameTitle db 13,10,"--- Ñòàòèñòèêà è ëèäåðû êàçèíî ---",13,10,0 +statsLinePlayed db " èãð: ",0 +statsLineWins db " ïîáåä: ",0 +statsLineLoss db " ïîðàæåíèé: ",0 +statsLineDraw db " íè÷üèõ: ",0 +leaderCurrentTitle db "Òåêóùèé àêêàóíò:",13,10,0 +leaderTitle db 13,10,"Ëèäåðû ñðåäè âñåõ àêêàóíòîâ:",13,10,0 +leaderNoDataText db "Íåò ñîõðàíåíèé àêêàóíòîâ.",13,10,0 +leaderBankText db "Ñàìûé áîëüøîé áàíê: ",0 +leaderWinsText db "Áîëüøå âñåãî ïîáåä: ",0 +leaderLossText db "Áîëüøå âñåãî ïîðàæåíèé: ",0 +leaderGameTitle db 13,10,"Ëèäåðû ïî èãðàì:",13,10,0 +leaderGameWinText db " ïîáåäû: ",0 +leaderGameLossText db " ïîðàæåíèÿ: ",0 +leaderDashText db "-",0 +leaderOpenText db " (",0 +leaderCloseText db ")",0 +leaderMoneyPrefix db "$",0 +statsGame21 db "21 / Î÷êî",0 +statsGamePoker db "Poker",0 +statsGameClover db "CloverPit",0 +statsGameRR db "Ðóññêàÿ ðóëåòêà",0 +statsGameSkulls db "×åðåïà",0 +statsGameCoin db "Îðåë/ðåøêà",0 +statsGameDice db "Êîñòè",0 +statsGameCasinoRoulette db "Êàçèíî-ðóëåòêà",0 +statsGameClassicSlot db "Slot machine",0 +statsGameDurak db "Äóðàê",0 +statsGameSkillCheck db "Êðþê: Skill Check",0 +statsGameNames dd OFFSET statsGame21, OFFSET statsGamePoker, OFFSET statsGameClover, OFFSET statsGameRR, OFFSET statsGameSkulls + dd OFFSET statsGameCoin, OFFSET statsGameDice, OFFSET statsGameCasinoRoulette, OFFSET statsGameClassicSlot, OFFSET statsGameDurak + dd OFFSET statsGameSkillCheck +bankRecoveredText db "Ïîñëå ïðîøëîãî âèçèòà êàçèíî âûäàëî íîâûé ñòàðòîâûé áàíê: $10000",13,10,0 +saveTamperedText db "Ñîõðàíåíèå ïîâðåæäåíî èëè èçìåíåíî. Êàçèíî âûäàëî ÷èñòûé ñòàðòîâûé áàíê.",13,10,0 +goalText db "Öåëü èãðû: äîâåñòè áàíê äî $",0 +victoryText db 13,10,"+====================================+",13,10 + db "| ÄÆÅÊÏÎÒ ÆÈÇÍÈ |",13,10 + db "+====================================+",13,10,13,10,0 +victoryReachedText db "Òû ïîäíÿë áàíê äî $",0 +victoryTailText db "Îõðàíà óæå íåðâíè÷àåò.",13,10 + db "Êàçèíî ïðèçíàåò ïîðàæåíèå.",13,10,13,10 + db "Çàáèðàé âûèãðûø è óõîäè êðàñèâî.",13,10,0 +victoryExitText db "Íàæìèòå ëþáóþ êëàâèøó, ÷òîáû ïðîäîëæèòü èãðó...",0 +nextGoalText db "Ñëåäóþùàÿ öåëü: $",0 +croupierPrefix db 13,10,"Êðóïüå: ",0 +croupierWin1 db "Êðàñèâî. Ôèøêè èäóò ê âàì.",13,10,0 +croupierWin2 db "Ñòîë ñåãîäíÿ ÿâíî íà âàøåé ñòîðîíå.",13,10,0 +croupierWin3 db "Õîðîøèé óäàð ïî áàíêó êàçèíî.",13,10,0 +croupierLose1 db "Êàçèíî çàáèðàåò ñòàâêó.",13,10,0 +croupierLose2 db "Íå ëó÷øèé ðàñêëàä, íî âå÷åð åùå æèâîé.",13,10,0 +croupierLose3 db "Ôèøêè óõîäÿò ñî ñòîëà.",13,10,0 +croupierDraw1 db "Ñòàâêà îñòàåòñÿ ïðè âàñ.",13,10,0 +croupierDraw2 db "Íèêòî íå ñäâèíóë áàíê. Èãðàåì äàëüøå.",13,10,0 +croupierDraw3 db "Ðîâíî. Áåç ïîáåäèòåëÿ.",13,10,0 +croupierWinList dd OFFSET croupierWin1, OFFSET croupierWin2, OFFSET croupierWin3 +croupierLoseList dd OFFSET croupierLose1, OFFSET croupierLose2, OFFSET croupierLose3 +croupierDrawList dd OFFSET croupierDraw1, OFFSET croupierDraw2, OFFSET croupierDraw3 +dealerFileName db "assets\data\dealer_phrases.txt",0 +pulseTitleText db 13,10,"Ïóëüñ ñòàâêè:",13,10,0 +pulseFrame1 db " _/\_ ñïîêîéíî",13,10,0 +pulseFrame2 db " _/\/\_ íàïðÿæåíèå",13,10,0 +pulseFrame3 db " _/\/\/\_ ðèñê",13,10,0 +pulseFrame4 db " _/\/\/\/\_ ñåðäöå êîëîòèòñÿ",13,10,0 +pulseFrame5 db " _/\/\_/\_ âäîõ...",13,10,0 +observerTitle db 13,10,"--- Íàáëþäàòåëü AI vs AI ---",13,10,0 +observerIntro db "AI-1 è AI-2 èãðàþò 5 áûñòðûõ ðàóíäîâ â 21 áåç ñòàâîê.",13,10,0 +observerRoundText db 13,10,"Ðàóíä ",0 +observerAI1Text db "AI-1 î÷êè: ",0 +observerAI2Text db "AI-2 î÷êè: ",0 +observerWin1Text db "AI-1 çàáèðàåò ðàóíä.",13,10,0 +observerWin2Text db "AI-2 çàáèðàåò ðàóíä.",13,10,0 +observerDrawText db "Íè÷üÿ ìåæäó æåëåçêàìè.",13,10,0 +observerDoneText db 13,10,"Íàáëþäåíèå îêîí÷åíî.",13,10,0 +observerMenuText db "1. Ðóññêàÿ ðóëåòêà",13,10 + db "2. 21 / Î÷êî",13,10 + db "3. Poker",13,10 + db "4. Äóðàê",13,10 + db "0. Íàçàä",13,10 + db "Âûáîð: ",0 +observer21Title db 13,10,"--- AI vs AI: 21 / Î÷êî ---",13,10,0 +observerPokerTitle db 13,10,"--- AI vs AI: Poker ---",13,10,0 +observerDurakTitle db 13,10,"--- AI vs AI: Äóðàê ---",13,10,0 +observerRRTitle db 13,10,"--- AI vs AI: Ðóññêàÿ ðóëåòêà ---",13,10,0 +observerAI1CardsText db 13,10,"Êàðòû AI-1:",13,10,0 +observerAI2CardsText db 13,10,"Êàðòû AI-2:",13,10,0 +observerAI1RaiseText db "AI-1 ïîâûøàåò ñòàâêó.",13,10,0 +observerAI2RaiseText db "AI-2 ïîâûøàåò ñòàâêó.",13,10,0 +observerCallText db "Ñîïåðíèê îòâå÷àåò.",13,10,0 +observerFold1Text db "AI-1 äåëàåò ôîëä.",13,10,0 +observerFold2Text db "AI-2 äåëàåò ôîëä.",13,10,0 +observerShotAI1Text db "Âûñòðåë äîñòàëñÿ AI-1. Ïîáåäèë AI-2.",13,10,0 +observerShotAI2Text db "Âûñòðåë äîñòàëñÿ AI-2. Ïîáåäèë AI-1.",13,10,0 +shopMainMenuText db "1. Ðóáàøêè êàðò",13,10 + db "2. Òàëèñìàíû",13,10 + db "3. Áåñòèàðèé òàëèñìàíîâ",13,10 + db "0. Íàçàä",13,10 + db "Âûáîð: ",0 +shopBackTitle db 13,10,"--- Ìàãàçèí: ðóáàøêè êàðò ---",13,10,0 +shopCharmTitle db 13,10,"--- Ìàãàçèí: òàëèñìàíû ---",13,10,0 +shopBackMenuText db "1. Ñèíÿÿ ðóáàøêà êàðò - $3000",13,10 + db "2. Êðàñíàÿ ðóáàøêà êàðò - $3000",13,10 + db "3. Çîëîòàÿ ðóáàøêà êàðò - $10000",13,10 + db "4. Ðóáàøêà ×åðåï - $12000",13,10 + db "5. Rubashka CloverPit - $15000",13,10 + db "6. Rubashka Arcane kart - $17000",13,10 + db "7. Rubashka Noir kart - $18000",13,10 + db "8. Rubashka Diamond kart - $20000",13,10 + db "9. Rubashka Rider kart - $22000",13,10 + db "10. Rubashka Bee kart - $22000",13,10 + db "11. Rubashka Fan kart - $23000",13,10 + db "12. Rubashka Web kart - $24000",13,10 + db "0. Íàçàä",13,10 + db "Âûáîð: ",0 +shopCharmMenuText db "1. Òàëèñìàí Êëåâåð: 7%, 3 çàðÿäà - $12000",13,10 + db "2. Òàëèñìàí Êîëîêîë: 14%, 3 çàðÿäà, +4 ïîäîçðåíèÿ - $18000",13,10 + db "3. Òàëèñìàí Àëìàç: 21%, 3 çàðÿäà, +8 ïîäîçðåíèÿ - $25000",13,10 + db "4. Òàëèñìàí ×åðåï: 28%, 2 çàðÿäà, øòðàô ïîëîâèíà ñòàâêè - $32000",13,10 + db "5. Òàëèñìàí Ïàóòèíà: 35%, 1 çàðÿä, +20 ïîäîçðåíèÿ - $40000",13,10 + db "6. Òàëèñìàí Ï÷åëà: 12%, 5 çàðÿäîâ - $30000",13,10 + db "7. Òàëèñìàí Ëóíà: 18%, 4 çàðÿäà, +8 ïîäîçðåíèÿ - $36000",13,10 + db "8. Òàëèñìàí Êîðîíà: 24%, 2 çàðÿäà, +12 ïîäîçðåíèÿ - $52000",13,10 + db "9. Òàëèñìàí Çåðêàëî: 16%, 4 çàðÿäà, +6 ïîäîçðåíèÿ - $42000",13,10 + db "10. Òàëèñìàí Êîñòü: 10%, 6 çàðÿäîâ - $35000",13,10 + db "11. Êðîâàâàÿ ìîíåòà: 40%, 1 çàðÿä, øòðàô 25% ñòàâêè è +25 ïîäîçðåíèÿ - $65000",13,10 + db "12. Ïåñî÷íûå ÷àñû: 22%, 2 çàðÿäà, +15 ïîäîçðåíèÿ - $48000",13,10 + db "13. Ïîäêîâà: 9%, 8 çàðÿäîâ - $39000",13,10 + db "14. Ìàñêà äæîêåðà: 33%, 1 çàðÿä, +30 ïîäîçðåíèÿ - $70000",13,10 + db "15. Ïåðî ôåíèêñà: 26%, 2 çàðÿäà, +10 ïîäîçðåíèÿ - $56000",13,10 + db "16. Ñëîìàííûé êîìïàñ: 19%, 3 çàðÿäà, +12 ïîäîçðåíèÿ - $44000",13,10 + db "17. Çîëîòîé çóá: 15%, 5 çàðÿäîâ, øòðàô 20% ñòàâêè - $47000",13,10 + db "18. Õðóñòàëüíûé ãëàç: 31%, 1 çàðÿä, +18 ïîäîçðåíèÿ - $60000",13,10 + db "19. Ðæàâûé êëþ÷: 13%, 6 çàðÿäîâ - $41000",13,10 + db "20. ×åðíàÿ ñâå÷à: 38%, 1 çàðÿä, øòðàô 33% ñòàâêè è +35 ïîäîçðåíèÿ - $76000",13,10 + db "21. Ñ÷àñòëèâàÿ ôèøêà: 20%, 4 çàðÿäà - $50000",13,10 + db "22. Çìåèíîå êîëüöî: 29%, 2 çàðÿäà, +16 ïîäîçðåíèÿ - $62000",13,10 + db "23. Îñêîëîê òóçà: 17%, 5 çàðÿäîâ, +7 ïîäîçðåíèÿ - $53000",13,10 + db "24. Äîãîâîð ñ äüÿâîëîì: 50%, 1 çàðÿä, øòðàô 50% ñòàâêè è +45 ïîäîçðåíèÿ - $100000",13,10 + db "0. Íàçàä",13,10 + db "Âûáîð: ",0 +shopTitle db 13,10,"--- Ìàãàçèí êàçèíî ---",13,10,0 +shopMenuText db "1. Ñèíÿÿ ðóáàøêà êàðò - $3000",13,10 + db "2. Êðàñíàÿ ðóáàøêà êàðò - $3000",13,10 + db "3. Çîëîòàÿ ðóáàøêà êàðò - $10000",13,10 + db "4. Ðóáàøêà ×åðåï - $12000",13,10 + db "5. Ðóáàøêà CloverPit - $15000",13,10 + db "6. Òàëèñìàí Êëåâåð: 7%, 3 çàðÿäà - $12000",13,10 + db "7. Òàëèñìàí Êîëîêîë: 14%, 3 çàðÿäà - $18000",13,10 + db "8. Òàëèñìàí Àëìàç: 21%, 3 çàðÿäà - $25000",13,10 + db "9. Rubashka Arcane kart - $17000",13,10 + db "10. Rubashka Noir kart - $18000",13,10 + db "11. Rubashka Diamond kart - $20000",13,10 + db "12. Rubashka Rider kart - $22000",13,10 + db "13. Rubashka Bee kart - $22000",13,10 + db "14. Rubashka Fan kart - $23000",13,10 + db "15. Rubashka Web kart - $24000",13,10 + db "0. Íàçàä",13,10 + db "Âûáîð: ",0 +shopBackText db "Òåêóùàÿ ðóáàøêà: ",0 +shopBackGray db "Ñåðàÿ",13,10,0 +shopBackBlue db "Ñèíÿÿ âîëíà",13,10,0 +shopBackRed db "Êðàñíûé êðåñò",13,10,0 +shopBackGold db "Çîëîòîé áëåñê",13,10,0 +shopBackSkull db "×åðåï",13,10,0 +shopBackClover db "CloverPit",13,10,0 +shopBackArcane db "Arcane",13,10,0 +shopBackNoir db "Noir",13,10,0 +shopBackDiamond db "Diamond",13,10,0 +shopBackRider db "Rider",13,10,0 +shopBackBee db "Bee",13,10,0 +shopBackFan db "Fan",13,10,0 +shopBackWeb db "Web",13,10,0 +shopCharmText db "Òàëèñìàí: ",0 +shopCharmNone db "íåò",13,10,0 +shopCharmClover db "Êëåâåð",0 +shopCharmBell db "Êîëîêîë",0 +shopCharmDiamond db "Àëìàç",0 +shopCharmSkull db "×åðåï",0 +shopCharmWeb db "Ïàóòèíà",0 +shopCharmBee db "Ï÷åëà",0 +shopCharmMoon db "Ëóíà",0 +shopCharmCrown db "Êîðîíà",0 +shopCharmMirror db "Çåðêàëî",0 +shopCharmDice db "Êîñòü",0 +shopCharmBlood db "Êðîâàâàÿ ìîíåòà",0 +shopCharmHourglass db "Ïåñî÷íûå ÷àñû",0 +shopCharmHorseshoe db "Ïîäêîâà",0 +shopCharmJoker db "Ìàñêà äæîêåðà",0 +shopCharmPhoenix db "Ïåðî ôåíèêñà",0 +shopCharmCompass db "Ñëîìàííûé êîìïàñ",0 +shopCharmTooth db "Çîëîòîé çóá",0 +shopCharmEye db "Õðóñòàëüíûé ãëàç",0 +shopCharmKey db "Ðæàâûé êëþ÷",0 +shopCharmCandle db "×åðíàÿ ñâå÷à",0 +shopCharmChip db "Ñ÷àñòëèâàÿ ôèøêà",0 +shopCharmSnake db "Çìåèíîå êîëüöî",0 +shopCharmAce db "Îñêîëîê òóçà",0 +shopCharmDevil db "Äîãîâîð ñ äüÿâîëîì",0 +bestiaryTitle db 13,10,"--- Áåñòèàðèé òàëèñìàíîâ ---",13,10,0 +bestiaryMenuText db "--- Îáû÷íûå ---",13,10 + db "1. Êëåâåð",13,10 + db "2. Êîëîêîë",13,10 + db "6. Ï÷åëà",13,10 + db "10. Êîñòü",13,10 + db "13. Ïîäêîâà",13,10 + db "19. Ðæàâûé êëþ÷",13,10 + db "--- Ðåäêèå ---",13,10 + db "3. Àëìàç",13,10 + db "7. Ëóíà",13,10 + db "9. Çåðêàëî",13,10 + db "12. Ïåñî÷íûå ÷àñû",13,10 + db "15. Ïåðî ôåíèêñà",13,10 + db "16. Ñëîìàííûé êîìïàñ",13,10 + db "17. Çîëîòîé çóá",13,10 + db "21. Ñ÷àñòëèâàÿ ôèøêà",13,10 + db "23. Îñêîëîê òóçà",13,10 + db "--- Ïðîêëÿòûå ---",13,10 + db "4. ×åðåï",13,10 + db "5. Ïàóòèíà",13,10 + db "11. Êðîâàâàÿ ìîíåòà",13,10 + db "14. Ìàñêà äæîêåðà",13,10 + db "20. ×åðíàÿ ñâå÷à",13,10 + db "22. Çìåèíîå êîëüöî",13,10 + db "--- Ëåãåíäàðíûå ---",13,10 + db "8. Êîðîíà",13,10 + db "18. Õðóñòàëüíûé ãëàç",13,10 + db "24. Äîãîâîð ñ äüÿâîëîì",13,10 + db "0. Íàçàä",13,10 + db "Âûáîð: ",0 +bestiaryGoodText db "Ïëþñ: ",0 +bestiaryBadText db "Ìèíóñ: ",0 +bestiaryBackText db 13,10,"0 - íàçàä ê ñïèñêó áåñòèàðèÿ: ",0 +bestiaryCloverArt db 13,10," .-. .-.",13,10," .' V '. CLOVER",13,10," \ \|/ /",13,10," `-+-'",13,10,0 +bestiaryBellArt db 13,10," .---.",13,10," / ___ \ BELL",13,10," / / \ ",13,10," \_\___/_/",13,10," (_) ",13,10,0 +bestiaryDiamondArt db 13,10," /",13,10," /##\ DIAMOND",13,10," /####",13,10," \####/",13,10," \##/",13,10," \/",13,10,0 +bestiarySkullArt db 13,10," .-''''-.",13,10," / O O \ SKULL",13,10," | __ |",13,10," | .____. |",13,10," \__||||__/",13,10,0 +bestiaryWebArt db 13,10," \ | /",13,10," ---\ | /--- WEB",13,10," ---- @ ----",13,10," ---/ | \---",13,10," / | ",13,10,0 +bestiaryBeeArt db 13,10," __",13,10," __/o \__ BEE",13,10," / \__/ ",13,10," \__/==\__/",13,10," \__/",13,10,0 +bestiaryMoonArt db 13,10," .--.",13,10," .' _/ MOON",13,10," / .'",13,10," \ '.",13,10," '.__",13,10,0 +bestiaryCloverInfo db "Êëåâåð: 7%, 3 çàðÿäà.",13,10,"Ïëþñ: ìîæåò ïîëíîñòüþ ñïàñòè ïðîèãðàííóþ ñòàâêó.",13,10,"Ìèíóñ: ñëàáûé øàíñ, áåç äîïîëíèòåëüíûõ áîíóñîâ.",13,10,0 +bestiaryBellInfo db "Êîëîêîë: 14%, 3 çàðÿäà.",13,10,"Ïëþñ: ÷àùå ñïàñàåò ïðîèãðûø.",13,10,"Ìèíóñ: çâîí ïðèâëåêàåò êàçèíî: +4 ïîäîçðåíèÿ ïðè ñðàáàòûâàíèè.",13,10,0 +bestiaryDiamondInfo db "Àëìàç: 21%, 3 çàðÿäà.",13,10,"Ïëþñ: ñèëüíûé øàíñ ñïàñåíèÿ.",13,10,"Ìèíóñ: áëåñê ïàëèòñÿ îõðàíå: +8 ïîäîçðåíèÿ.",13,10,0 +bestiarySkullInfo db "×åðåï: 28%, 2 çàðÿäà.",13,10,"Ïëþñ: âûñîêèé øàíñ íå ïîòåðÿòü âñþ ñòàâêó.",13,10,"Ìèíóñ: çàáèðàåò ïîëîâèíó ñòàâêè äàæå ïðè ñïàñåíèè.",13,10,0 +bestiaryWebInfo db "Ïàóòèíà: 35%, 1 çàðÿä.",13,10,"Ïëþñ: ïî÷òè àâàðèéíàÿ êíîïêà ïðîòèâ ïðîèãðûøà.",13,10,"Ìèíóñ: +20 ïîäîçðåíèÿ, çàðÿä îäèí.",13,10,0 +bestiaryBeeInfo db "Ï÷åëà: 12%, 5 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî ïîïûòîê, õîðîøèé òàëèñìàí íà äëèííóþ èãðó.",13,10,"Ìèíóñ: øàíñ íèæå, ÷åì ó äîðîãèõ òàëèñìàíîâ.",13,10,0 +bestiaryMoonInfo db "Ëóíà: 18%, 4 çàðÿäà.",13,10,"Ïëþñ: áàëàíñ øàíñà è çàðÿäîâ.",13,10,"Ìèíóñ: ëóííûé ñâåò âûäàåò øóëåðà: +8 ïîäîçðåíèÿ.",13,10,0 +bestiaryCrownArt db 13,10," _^_",13,10," .'___'. CROWN",13,10," /_/|_|\_",13,10," /___",13,10,0 +bestiaryMirrorArt db 13,10," .----.",13,10," / .--. \ MIRROR",13,10," | | <> | |",13,10," \ '--' /",13,10," '----'",13,10,0 +bestiaryDiceArt db 13,10," +-----+",13,10," | o o | DICE",13,10," | o |",13,10," | o o |",13,10," +-----+",13,10,0 +bestiaryBloodArt db 13,10," .---.",13,10," / $ $ \ BLOOD COIN",13,10," | *** |",13,10," \_===_/",13,10," drip",13,10,0 +bestiaryHourglassArt db 13,10," \-----/",13,10," \.../ HOURGLASS",13,10," \./",13,10," /\",13,10," /___",13,10,0 +bestiaryCrownInfo db "Êîðîíà: 24%, 2 çàðÿäà.",13,10,"Ïëþñ: ñîëèäíûé øàíñ ñïàñåíèÿ.",13,10,"Ìèíóñ: êîðîíà ñëèøêîì çàìåòíà: +12 ïîäîçðåíèÿ.",13,10,0 +bestiaryMirrorInfo db "Çåðêàëî: 16%, 4 çàðÿäà.",13,10,"Ïëþñ: íåñêîëüêî ñòàáèëüíûõ ïîïûòîê îáìàíóòü ïðîèãðûø.",13,10,"Ìèíóñ: îòðàæåíèå ïàëèò ðóêè: +6 ïîäîçðåíèÿ.",13,10,0 +bestiaryDiceInfo db "Êîñòü: 10%, 6 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî çàðÿäîâ, ìîæíî æèòü äîëãî.",13,10,"Ìèíóñ: øàíñ ìàëåíüêèé, ýòî òàëèñìàí òåðïåíèÿ.",13,10,0 +bestiaryBloodInfo db "Êðîâàâàÿ ìîíåòà: 40%, 1 çàðÿä.",13,10,"Ïëþñ: ñàìûé ðåçêèé øàíñ ñïàñåíèÿ.",13,10,"Ìèíóñ: çàáèðàåò 25% ñòàâêè è äàåò +25 ïîäîçðåíèÿ.",13,10,0 +bestiaryHourglassInfo db "Ïåñî÷íûå ÷àñû: 22%, 2 çàðÿäà.",13,10,"Ïëþñ: íàäåæíåå ñðåäíåãî.",13,10,"Ìèíóñ: âðåìÿ íå ëþáèò ñâèäåòåëåé: +15 ïîäîçðåíèÿ.",13,10,0 +bestiaryHorseshoeArt db 13,10," __ __",13,10," / \_/ \ HORSESHOE",13,10," | o o |",13,10," \__ __/",13,10," |_|",13,10,0 +bestiaryJokerArt db 13,10," .-^^-.",13,10," / o o \ JOKER",13,10," | .--. |",13,10," \_\__/ _/",13,10," /==\",13,10,0 +bestiaryPhoenixArt db 13,10," /\",13,10," ___/ \___ PHOENIX",13,10," / / /\ \ ",13,10," /_||_\",13,10," \/",13,10,0 +bestiaryCompassArt db 13,10," .---.",13,10," / N \ COMPASS",13,10," | W-+-E |",13,10," \ S /",13,10," '--?'",13,10,0 +bestiaryToothArt db 13,10," .--.",13,10," /$ $\ GOLD TOOTH",13,10," | __ |",13,10," \____/",13,10," drip",13,10,0 +bestiaryEyeArt db 13,10," .-------.",13,10," / .---. \ EYE",13,10," | ( 0 ) |",13,10," \ '---' /",13,10," '-------'",13,10,0 +bestiaryKeyArt db 13,10," __",13,10," ___/ \___ KEY",13,10," (___ ___)",13,10," |__|==",13,10," ==",13,10,0 +bestiaryCandleArt db 13,10," )",13,10," ( ) CANDLE",13,10," .-#-.",13,10," |###|",13,10," |___|",13,10,0 +bestiaryChipArt db 13,10," .-----.",13,10," / $ $ $ \ CHIP",13,10," | $ 777 $ |",13,10," \ $ $ $ /",13,10," '-----'",13,10,0 +bestiarySnakeArt db 13,10," __",13,10," __/ \__ SNAKE RING",13,10," / _ _ ",13,10," \_/ \/ \_/",13,10," hiss",13,10,0 +bestiaryAceArt db 13,10," .---.",13,10," / A \ ACE SHARD",13,10," | ^ |",13,10," \ /_\ /",13,10," '---'",13,10,0 +bestiaryDevilArt db 13,10," /\ /\",13,10," / \_/ \ DEVIL",13,10," | $ $ |",13,10," | ___ |",13,10," \_/###\_/",13,10,0 +bestiaryHorseshoeInfo db "Ïîäêîâà: 9%, 8 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî ïîïûòîê, õîðîøî äëÿ äëèííûõ ñåññèé.",13,10,"Ìèíóñ: øàíñ ìàëåíüêèé, ñïàñàåò ðåäêî.",13,10,0 +bestiaryJokerInfo db "Ìàñêà äæîêåðà: 33%, 1 çàðÿä.",13,10,"Ïëþñ: ñèëüíûé øàíñ ðåçêî îòìåíèòü ïðîèãðûø.",13,10,"Ìèíóñ: ñëèøêîì òåàòðàëüíî: +30 ïîäîçðåíèÿ.",13,10,0 +bestiaryPhoenixInfo db "Ïåðî ôåíèêñà: 26%, 2 çàðÿäà.",13,10,"Ïëþñ: õîðîøèé øàíñ, áóäòî ñòàâêà âîñêðåñàåò èç ïåïëà.",13,10,"Ìèíóñ: +10 ïîäîçðåíèÿ ïðè ñðàáàòûâàíèè.",13,10,0 +bestiaryCompassInfo db "Ñëîìàííûé êîìïàñ: 19%, 3 çàðÿäà.",13,10,"Ïëþñ: ñðåäíèé òàëèñìàí áåç äåíåæíîãî øòðàôà.",13,10,"Ìèíóñ: âåäåò êðèâî: +12 ïîäîçðåíèÿ.",13,10,0 +bestiaryToothInfo db "Çîëîòîé çóá: 15%, 5 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî çàðÿäîâ ïðè íîðìàëüíîì øàíñå.",13,10,"Ìèíóñ: áåðåò ïëàòó 20% ñòàâêè ïðè ñïàñåíèè.",13,10,0 +bestiaryEyeInfo db "Õðóñòàëüíûé ãëàç: 31%, 1 çàðÿä.",13,10,"Ïëþñ: ïî÷òè âèäèò ïðîèãðûø çàðàíåå.",13,10,"Ìèíóñ: +18 ïîäîçðåíèÿ, çàðÿä îäèí.",13,10,0 +bestiaryKeyInfo db "Ðæàâûé êëþ÷: 13%, 6 çàðÿäîâ.",13,10,"Ïëþñ: äåøåâëå ìîùíûõ òàëèñìàíîâ è äîëãî æèâåò.",13,10,"Ìèíóñ: øàíñ ñëàáûé, êëþ÷ ÷àñòî íå ïîäõîäèò.",13,10,0 +bestiaryCandleInfo db "×åðíàÿ ñâå÷à: 38%, 1 çàðÿä.",13,10,"Ïëþñ: î÷åíü ñèëüíûé øàíñ ñïàñåíèÿ.",13,10,"Ìèíóñ: øòðàô 33% ñòàâêè è +35 ïîäîçðåíèÿ.",13,10,0 +bestiaryChipInfo db "Ñ÷àñòëèâàÿ ôèøêà: 20%, 4 çàðÿäà.",13,10,"Ïëþñ: ðîâíûé óíèâåðñàëüíûé òàëèñìàí.",13,10,"Ìèíóñ: áåç ÿðêîãî áîíóñà, ïðîñòî íàäåæíîñòü.",13,10,0 +bestiarySnakeInfo db "Çìåèíîå êîëüöî: 29%, 2 çàðÿäà.",13,10,"Ïëþñ: âûñîêèé øàíñ íà äâà ñïàñåíèÿ.",13,10,"Ìèíóñ: øèïèò íà îõðàíó: +16 ïîäîçðåíèÿ.",13,10,0 +bestiaryAceInfo db "Îñêîëîê òóçà: 17%, 5 çàðÿäîâ.",13,10,"Ïëþñ: ìíîãî çàðÿäîâ è ÷óòü áîëüøå óäà÷è, ÷åì ó êëþ÷à.",13,10,"Ìèíóñ: +7 ïîäîçðåíèÿ.",13,10,0 +bestiaryDevilInfo db "Äîãîâîð ñ äüÿâîëîì: 50%, 1 çàðÿä.",13,10,"Ïëþñ: ñàìûé ìîùíûé øàíñ ñïàñòè ïðîèãðûø.",13,10,"Ìèíóñ: øòðàô 50% ñòàâêè è +45 ïîäîçðåíèÿ.",13,10,0 +charmPenaltyText db "Öåíà òàëèñìàíà: $",0 +shopCharmUsesText db ", çàðÿäîâ: ",0 +shopBoughtText db "Ïîêóïêà âûïîëíåíà.",13,10,0 +shopSelectedText db "Ðóáàøêà âûáðàíà.",13,10,0 +shopCharmBurnText db "Òàëèñìàí ñãîðåë.",13,10,0 +shopCharmSaveText db 13,10,"Òàëèñìàí âñïûõíóë è ñïàñ ñòàâêó!",13,10,0 +achMenuTitle db 13,10,"--- Äîñòèæåíèÿ ---",13,10,0 +achPopupTop db 13,10,"+--------------------------------------+",13,10,0 +achPopupTitle db "| ÄÎÑÒÈÆÅÍÈÅ ÎÒÊÐÛÒÎ |",13,10,0 +achPopupLeft db "| ",0 +achPopupBottom db "+--------------------------------------+",13,10,0 +achDoneText db "[x] ",0 +achTodoText db "[ ] ",0 +achFirstWinName db "Ïåðâûé âûèãðûø",13,10,0 +achFirstLossName db "Ïåðâûé ïðîèãðûø",13,10,0 +achJackpotName db "Äæåêïîò ïîéìàí",13,10,0 +achHighRollerName db "Áîëüøàÿ ñòàâêà",13,10,0 +achShopperName db "Ïîêóïàòåëü êàçèíî",13,10,0 +achCharmName db "Òàëèñìàí ñðàáîòàë",13,10,0 +achGoalName db "Öåëü äîñòèãíóòà",13,10,0 +achCloverPitName db "CloverPit ðàçîãðåëñÿ",13,10,0 +achClassicSlotName db "Ñòàðûé àâòîìàò ïëàòèò",13,10,0 +achPokerRaiseName db "Ñòàâêà ïîâûøåíà",13,10,0 +achPokerBluffName db "Áëåô ñðàáîòàë",13,10,0 +achRouletteWinName db "Êîëåñî ñóäüáû",13,10,0 +achRussianWinName db "Ñóõîé ùåë÷îê",13,10,0 +achDurakWinName db "Íå äóðàê",13,10,0 +achBackCollectorName db "Êîëëåêöèîíåð ðóáàøåê",13,10,0 +achCharmBuyerName db "Òàëèñìàí â êàðìàíå",13,10,0 +achObserverName db "Ëîæà íàáëþäàòåëÿ",13,10,0 +achSkillCheckName db "Ñ êðþêà ñîðâàëñÿ",13,10,0 +achievementFileName db "runtime\achievement.txt",0 +achievementCmd db "cmd /c start ""Achievement"" tools\tests\achievement_popup.bat",0 +skillTitle db 13,10,"--- Êðþê: Skill Check ---",13,10,0 +skillIntro db "Ïîïàäàé ïî çåëåíîé çîíå. PERFECT äàåò äâîéíîé ïðîãðåññ.",13,10 + db "3 ïðîìàõà - òüìà çàáèðàåò ñòàâêó. 5 ïðîãðåññà - òû ñðûâàåøüñÿ ñ êðþêà.",13,10 + db "Íàæèìàé SPACE èëè ENTER.",13,10,0 +skillHookArt db 13,10 + db " || .:!!!!!!!!!!:.",13,10 + db " || .:!##############!:.",13,10 + db " _____||_____ !#### ENTITY #####!",13,10 + db " /____ ____/ ':!#############!:'",13,10 + db " | | ''!!####!!''",13,10 + db " | | _J",13,10 + db " | | __/ |",13,10 + db " _____| |_____ .-' .-^-. .---- RED LOCKER ----.",13,10 + db " | WOODEN WALL | / /.-.\\\\ | [] [] [] [] [] |",13,10 + db " | || || || || || | |( )| | | [] [] [] [] [] |",13,10 + db " | || || || || || | /|\\___/|\\| | [] [] [] [] [] |",13,10 + db " | || || || || || |__/ | / \\ | \\__ |__________________|",13,10 + db " | || || || || || /_/ \\_\\ J J J",13,10 + db " |________________| _/ \\_ chains and hooks",13,10 + db " >>> SPACE / ENTER - ëîâèòü skill check <<<",13,10,0 +skillStateText db "Ñîñòîÿíèå: ",0 +skillStateGood db "äåðæèøüñÿ",13,10,0 +skillStateWarn db "öåïü ñêðèïèò",13,10,0 +skillStateBad db "òüìà ðÿäîì",13,10,0 +skillProgressText db "Ïðîãðåññ ïîáåãà: ",0 +skillMissText db "Ïðîìàõè: ",0 +skillGaugeHint db 13,10,"Áîëüøîé skill check:",13,10,0 +skillGaugeLeft db "[",0 +skillGaugeRight db "]",13,10,0 +skillGaugeEmpty db "-",0 +skillGaugeSuccess db "#",0 +skillGaugePerfect db "@",0 +skillGaugeNeedle db "|",0 +skillSuccessText db 13,10,"Óñïåõ. Òû óäåðæàëñÿ íà êðþêå.",13,10,0 +skillPerfectText db 13,10,"PERFECT! Ðûâîê ïî÷òè ñîðâàë êðþê.",13,10,0 +skillFailText db 13,10,"Ïðîìàõ. Êðþê äåðíóë ñèëüíåå.",13,10,0 +skillEscapeText db 13,10,"Òû ñîðâàëñÿ ñ êðþêà è âûðâàëñÿ èç òóìàíà!",13,10,0 +skillDarkText db 13,10,"Òüìà çàáðàëà òåáÿ. Ñòàâêà ñãîðåëà.",13,10,0 +coinTitle db 13,10,"--- Îðåë è ðåøêà ---",13,10,0 +coinIntroText db "Óãàäàé ñòîðîíó ìîíåòû. Ïîáåäà äàåò âûèãðûø ðàçìåðîì ñî ñòàâêó.",13,10,0 +coinChoiceText db "1 - Îðåë, 2 - Ðåøêà: ",0 +coinSpinText db "Ìîíåòà ëåòèò...",13,10,0 +; === ASCII-êàäðû àíèìàöèè ìîíåòû === +coinFrame1 db 13,10 + db " ( O )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame2 db 13,10 + db " ( / )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame3 db 13,10 + db " ( | )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame4 db 13,10 + db " ( \ )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame5 db 13,10 + db " ( - )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame6 db 13,10 + db " ( / )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame7 db 13,10 + db " ( | )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame8 db 13,10 + db " ( \ )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame9 db 13,10 + db " ( O )",13,10 + db 13,10 + db " ___________________",13,10,0 +coinFrame10 db 13,10 + db " ( / )",13,10 + db " ",13,10 + db " ___________________",13,10,0 +coinFrame11 db 13,10 + db " ( | )",13,10 + db " ",13,10 + db " ___________________",13,10,0 +coinFrame12 db 13,10 + db " ( \ )",13,10 + db " ",13,10 + db " ___________________",13,10,0 +coinFrame13 db 13,10 + db " ( - )",13,10 + db " ",13,10 + db " ___________________",13,10,0 +coinFrame14 db 13,10 + db " ( O )",13,10 + db " ",13,10 + db " ___________________",13,10,0 +coinPickText db "Òû âûáðàë: ",0 +coinResultText db "Âûïàëî: ",0 +coinHeadsText db "Îðåë",13,10,0 +coinTailsText db "Ðåøêà",13,10,0 +diceTitle db 13,10,"--- Êîñòè ---",13,10,0 +diceIntroText db "Óãàäàé ÷åòíîñòü ñóììû äâóõ êîñòåé. Ïîáåäà äàåò âûèãðûø ðàçìåðîì ñî ñòàâêó.",13,10,0 +diceChoiceText db "1 - ÷åò, 2 - íå÷åò: ",0 +diceRollText db "Êîñòè ëåòÿò ïî ñòîëó...",13,10,0 +diceFirstText db "Ïåðâàÿ êîñòü: ",0 +diceSecondText db "Âòîðàÿ êîñòü: ",0 +diceSumText db "Ñóììà: ",0 +diceEvenText db "×åò",13,10,0 +diceOddText db "Íå÷åò",13,10,0 +; === Êàçèíî-ðóëåòêà: òåêñòû, êîëåñî, öâåòà è êàðìàíû === +casinoRouletteTitle db 13,10,"--- Êàçèíî-ðóëåòêà ---",13,10,0 +casinoRouletteIntro db "Åâðîïåéñêîå êîëåñî: 0 çåëåíûé, ïîëîâèíà ÷èñåë êðàñíûå, ïîëîâèíà ÷åðíûå.",13,10 + db "Ñòàâêà íà ÷èñëî ïëàòèò x35, îñòàëüíûå ñòàâêè ïëàòÿò x1.",13,10,0 +casinoRouletteBetMenu db "1 - ÷èñëî 0-36",13,10 + db "2 - êðàñíîå",13,10 + db "3 - ÷åðíîå",13,10 + db "4 - ÷åò",13,10 + db "5 - íå÷åò",13,10 + db "Âûáîð ñòàâêè: ",0 +casinoRouletteNumberAsk db "Ââåäèòå ÷èñëî 0-36: ",0 +casinoRouletteBadNumber db " ðóëåòêå åñòü òîëüêî ÷èñëà îò 0 äî 36.",13,10,0 +casinoRouletteSpinText db "Øàðèê ñêà÷åò ïî êàðìàíàì êîëåñà... Èòîãîâûé êàðìàí ïðÿìî ïîä ñòðåëêîé ñâåðõó.",13,10,0 +casinoRouletteResultText db 13,10,"Øàðèê îñòàíîâèëñÿ íà: ",0 +casinoRouletteWinText db "Ñòàâêà ñûãðàëà.",13,10,0 +casinoRouletteLoseText db "Ñòàâêà íå ñûãðàëà.",13,10,0 +casinoRouletteWheelTop db " =============================================================",13,10 + db " o",13,10 + db " v",13,10,0 +casinoRouletteWheelBottom db " =============================================================",13,10,0 +casinoRoulettePad db " ",0 +rouletteBigSidePad db " ",0 +rouletteBigSideGap1 db " .-------------------------------------------------. ",0 +rouletteBigSideGap2 db " / .-------------------------------------. \ ",0 +rouletteBigSideGap3 db " | / . . . . . . . . . . . . . . \ | ",0 +rouletteBigSideGap4 db " | | \\ | // ( O ) \\ | | ",0 +rouletteBigSideGap5 db " | | // | \\ --+-- // | | ",0 +rouletteBigSideGap6 db " | \ . . . . . . . . . . . . \ | | ",0 +roulettePocketLeft db "[",0 +roulettePocketRight db "] ",0 +rouletteNumSpace db " ",0 +rouletteRedName db "êðàñíîå",13,10,0 +rouletteBlackName db "÷åðíîå",13,10,0 +rouletteGreenName db "çåëåíûé íîëü",13,10,0 +rouletteWheel dd 0,32,15,19,4,21,2,25,17,34,6,27,13,36,11,30,8,23,10 + dd 5,24,16,33,1,20,14,31,9,22,18,29,7,28,12,35,3,26 +rouletteColors db 0,1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1 + db 1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1 +bankLevelText db "Óðîâåíü áàíêà: ",0 +bankLevelNewbie db "Íîâè÷îê",13,10,0 +bankLevelPlayer db "Èãðîê",13,10,0 +bankLevelHigh db "Õàéðîëëåð",13,10,0 +bankLevelLegend db "Ëåãåíäà êàçèíî",13,10,0 + + +; === Òåêñòû êàðòî÷íûõ èãð: 21, ïîêåð, äóðàê è ïîäñêàçêè === +hitText db "Âçÿòü êàðòó? (y/n): ",0 +againText db "Ñûãðàòü åùå? (y/n): ",0 +yourCardText db 13,10,"Òâîÿ êàðòà:",13,10,0 +dealerCardText db 13,10,"Êàðòà äèëåðà:",13,10,0 +aiThinkText db 13,10,"AI äóìàåò...",13,10,0 +aiMoveText db 13,10,"AI áåðåò êàðòó!",13,10,0 +aiCardsText db 13,10,"Êàðòû AI:",13,10,0 +playerCardsText db 13,10,"Òâîè êàðòû:",13,10,0 +yourScoreText db "Òâîè î÷êè: ",0 +dealerScoreText db "Î÷êè äèëåðà: ",0 +aiScoreText db "Î÷êè AI: ",0 +bustText db "Ïåðåáîð. Òû ïðîèãðàë.",13,10,0 +dealerBustText db "Ó äèëåðà ïåðåáîð. Òû âûèãðàë!",13,10,0 +winText db "Òû âûèãðàë!",13,10,0 +loseText db "Òû ïðîèãðàë.",13,10,0 +drawText db "Íè÷üÿ.",13,10,0 +blackjackText db "Blackjack!",13,10,0 + +twentyOneTitle db 13,10,"--- 21 / Î÷êî ---",13,10,0 +blackjackTitle db 13,10,"--- Blackjack ---",13,10,0 +pokerTitle db 13,10,"--- Poker ---",13,10,0 +pokerModeMenuText db "1. Êëàññè÷åñêèé ïîêåð 1 íà 1 (ïðîòèâ Äèëåðà)",13,10 + db "2. Ñòîë íà 4 ïåðñîíû (Âû ïðîòèâ ïîñåòèòåëåé êàçèíî)",13,10 + db "0. Âûõîä â ãëàâíîå ìåíþ",13,10 + db "Âûáîð: ",0 +slotTitle db 13,10,"--- CloverPit ---",13,10,0 +classicSlotTitle db 13,10,"--- Slot machine ---",13,10,0 +durakTitle db 13,10,"--- Äóðàê ---",13,10,0 +durakInfoText db "Êîçûðü: ",0 +durakDeckText db "Êàðò â êîëîäå: ",0 +durakAICardsText db "Êàðò ó AI: ",0 +durakYourHandText db 13,10,"Òâîè êàðòû:",13,10,0 +durakTableText db 13,10,"Íà ñòîëå: ",0 +durakAttackAsk db "Âûáåðè êàðòó äëÿ àòàêè: ",0 +durakDefendAsk db "×åì áèòü? 0 - âçÿòü: ",0 +durakBadMoveText db "Òàê íåëüçÿ. Âûáåðè äðóãóþ êàðòó.",13,10,0 +durakAITakeText db "AI íå ñìîã îòáèòüñÿ è âçÿë êàðòó.",13,10,0 +durakAIDefendText db "AI îòáèëñÿ êàðòîé: ",0 +durakAIAttackText db "AI àòàêóåò: ",0 +durakPlayerTakeText db "Òû âçÿë êàðòó.",13,10,0 +durakPlayerDefendText db "Òû îòáèëñÿ.",13,10,0 +durakWinText db "Òû âûøåë èç èãðû áåç êàðò. Ïîáåäà!",13,10,0 +durakLoseText db "AI èçáàâèëñÿ îò êàðò ðàíüøå òåáÿ. Òû ïðîèãðàë.",13,10,0 +trainingTitle db 13,10,"--- Îáó÷åíèå ---",13,10,0 +trainingText db "Ãëàâíîå: ñíà÷àëà âûáåðè ñòàâêó. Åñëè áàíê óïàäåò äî 0, êàçèíî âûâåäåò òåáÿ.",13,10 + db "Ìàãàçèí: ðóáàøêè ìåíÿþò âèä çàêðûòûõ êàðò, òàëèñìàíû ìîãóò ñïàñòè ïðîèãðàííóþ ñòàâêó.",13,10 + db "21 / Î÷êî: áåðè êàðòû äî 21. Ïåðåáîð - ïîðàæåíèå. AI äîáèðàåò ïîñëå âñêðûòèÿ.",13,10 + db "Poker: ó òåáÿ 2 êàðòû, íà ñòîëå 3+1+1. Ìîæíî èãðàòü, ôîëäèòü è ïîâûøàòü ñòàâêó.",13,10 + db "CloverPit: ïîëå 5x3. Ïëàòÿò ðàçíûå ëèíèè è ôèãóðû èç îäèíàêîâûõ ñèìâîëîâ.",13,10 + db "×åðåïà: çàïîìíè, ãäå øàðèê, ïîòîì ñëåäè çà ïåðåìåøèâàíèåì ÷åðåïîâ.",13,10 + db "Ðóññêàÿ ðóëåòêà: Easy/Normal/Hard çàäàþò 1/2/3 îïàñíûå êàìåðû áàðàáàíà.",13,10 + db "Îðåë è ðåøêà: âûáåðè ñòîðîíó ìîíåòû è äîæäèñü ïàäåíèÿ.",13,10 + db "Êîñòè: óãàäàé ÷åòíîñòü ñóììû äâóõ êóáèêîâ.",13,10 + db "Êàçèíî-ðóëåòêà: ìîæíî ñòàâèòü íà ÷èñëî, öâåò, ÷åò/íå÷åò, äþæèíû, ïîëîâèíû è êîëîíêè.",13,10 + db "Slot machine: ñòàðàÿ 3x3 ñëîò-ìàøèíà ñ âûïàäåíèåì áàðàáàíîâ è ñðåäíåé ëèíèåé.",13,10 + db "Äóðàê: àòàêóé, ïîäêèäûâàé ñîâïàäàþùèå ðàíãè, îòáèâàéñÿ èëè ïåðåâîäè õîä.",13,10 + db "Êðþê: Skill Check: SPACE/ENTER ïî çåëåíîé çîíå. PERFECT äàåò äâîéíîé ïðîãðåññ.",13,10 + db "Buckshot Roulette: ñ÷èòàé æèâûå/õîëîñòûå, èñïîëüçóé ïðåäìåòû è âûáèðàé öåëü âûñòðåëà.",13,10 + db "Íàáëþäàòåëü: AI vs AI èãðàåò áåç òâîèõ ñòàâîê, ïðîñòî äëÿ ïðîñìîòðà.",13,10 + db "Äîñòèæåíèÿ è ñòàòèñòèêà ñîõðàíÿþòñÿ â àêêàóíò.",13,10,0 +durakDeckVisualText db "Êîëîäà: [ðóáàøêà], èç-ïîä íåå òîð÷èò êîçûðü ",0 +durakAIFaceText db 13,10,"Êàðòû AI:",13,10,0 +durakThrowAsk db "Ïîäêèíóòü êàðòó? 0 - áèòî: ",0 +durakTransferText db "Ïåðåâîä! Õîä ïåðåõîäèò îáðàòíî.",13,10,0 +durakTablePairsText db 13,10,"Êàðòû íà ñòîëå:",13,10,0 +durakSlashText db " / ",0 +durakUnbeatenText db " _ ",0 +durakStuckText db "Ïàðòèÿ çàøëà â òóïèê. Ñ÷èòàåì íè÷üþ.",13,10,0 +skullsTitle db 13,10,"--- ×åðåïà è øàðèê ---",13,10,0 +skullsIntroText db "Ñëåäè çà øàðèêîì. Âûïëàòà çà ïîáåäó: x2.",13,10,0 +skullsShowText db "Ñìîòðè âíèìàòåëüíî: øàðèê ñåé÷àñ çäåñü.",13,10,0 +skullsHideText db "×åðåïà çàêðûâàþò øàðèê...",13,10,0 +skullsShuffleText db "×åðåïà ñêîëüçÿò ïî ñòîëó...",13,10,0 +skullsGuessText db "Ãäå øàðèê? 1 / 2 / 3: ",0 +skullsWinText db "Âåðíî! Øàðèê íàéäåí.",13,10,0 +skullsLoseText db "Ìèìî. Øàðèê áûë ïîä äðóãèì ÷åðåïîì.",13,10,0 +skullsBallText db "Øàðèê áûë ïîä ÷åðåïîì ",0 +skullsSwap12Text db " \\______/",13,10," / \",13,10,0 +skullsSwap23Text db " \\______/",13,10," / \",13,10,0 +skullsSwap13Text db " \\____________________/",13,10," / \",13,10,0 +rouletteTitle db 13,10,"--- Ðóññêàÿ ðóëåòêà ---",13,10,0 +rrIntroText db "Áàðàáàí íà 6 êàìåð. Easy: 1 îïàñíàÿ, Normal: 2, Hard: 3.",13,10,"AI èãðàåò ñ òîáîé ïî î÷åðåäè. Êòî ïîïàë íà îïàñíóþ êàìåðó - ïðîèãðàë.",13,10,0 +rrDangerText db "Îïàñíûõ êàìåð â áàðàáàíå: ",0 +rrSpinText db "Áàðàáàí âðàùàåòñÿ... ",0 +rrSpin1 db "|",13,10,0 +rrSpin2 db "/",13,10,0 +rrSpin3 db "-",13,10,0 +rrSpin4 db "\\",13,10,0 +rrStartsPlayerText db "Ðåâîëüâåð îñòàíîâèëñÿ íà òåáå. Òû ñòðåëÿåøü ïåðâûì.",13,10,0 +rrStartsAIText db "Ðåâîëüâåð îñòàíîâèëñÿ íà AI. Îí ñòðåëÿåò ïåðâûì.",13,10,0 +rrPlayerTurnText db "Òâîé õîä. Íàæìè ëþáóþ êëàâèøó, ÷òîáû íàæàòü íà ñïóñê...",0 +rrAITurnText db "Õîä AI. Îí ïîäíèìàåò ðåâîëüâåð...",13,10,0 +rrClickText db "Ùåë÷îê. Ïóñòî.",13,10,0 +rrBangText db "ÁÀÕ!",13,10,0 +rrPlayerLoseText db "Òåáå íå ïîâåçëî. Ñòàâêà óõîäèò êàçèíî.",13,10,0 +rrAIShotText db "AI âûáûë. Òû ïåðåæèë ýòó ïàðòèþ.",13,10,0 +rrPayoutText db "Âûïëàòà ðóëåòêè çàâèñèò îò ñëîæíîñòè.",13,10,0 +buckshotTitle db 13,10,"--- Buckshot Roulette ---",13,10,0 +buckshotIntro db "Äðîáîâèê çàðÿæåí æèâûìè è õîëîñòûìè ïàòðîíàìè â íåèçâåñòíîì ïîðÿäêå.",13,10 + db "Ñòðåëÿé â ñåáÿ èëè AI. Õîëîñòîé â ñåáÿ îñòàâëÿåò õîä òåáå.",13,10 + db "Ëóïà ðàñêðûâàåò òåêóùèé ïàòðîí, ïèëà äàåò 2 óðîíà, ïèâî âûáðàñûâàåò ïàòðîí, íàðó÷íèêè ïðîïóñêàþò õîä AI.",13,10,0 +bsShotgunArt db 13,10 + db " ,_______________________________________________",13,10 + db " |_________________,----------._ [____] ""-,__",13,10 + db " (_(||||||||||||)___________/ ""--.__",13,10 + db " `----------' [ ))""-, \",13,10 + db " "" `--.__ |",13,10 + db " `----'",13,10 + db " DOUBLE BARREL CASINO",13,10,0 +bsShotgunLoad1 db 13,10 + db " ,_______________________________________________",13,10 + db " |_________________,----------._ [____] ""-,__",13,10 + db " (_(||||||||||||)___________/ ""--.__",13,10 + db " `----------' [ ))""-, \",13,10 + db " "" `--.__ |",13,10 + db " `----'",13,10 + db " Êðóïüå áåðåò äðîáîâèê ñî ñòîëà...",13,10,0 +bsShotgunLoad2 db 13,10 + db " ,_______________________________________________",13,10 + db " |_________________,----------._ [____] ""-,__",13,10 + db " (_(||||||||||||)______/__/ ""--.__",13,10 + db " `----------' / LIVE] ",13,10 + db " __/ BLANK] .__ |",13,10 + db " `----'",13,10 + db " Ñòâîë ïðèîòêðûò. Ïàòðîíû ó êàçåííîé ÷àñòè.",13,10,0 +bsShotgunLoad3 db 13,10 + db " ,_______________________________________________",13,10 + db " |_________________,----------._ [____] ""-,__",13,10 + db " (_(||||||||||||)___________/ ""--.__",13,10 + db " `----------' [ ))""-, \",13,10 + db " "" `--.__ |",13,10 + db " `----'",13,10 + db " ÙÅËÊ. Äðîáîâèê çàêðûò.",13,10,0 +bsShotgunFire db 13,10 + db " *** BOOM ***",13,10 + db " ,_______________________________________________ ***",13,10 + db " |_________________,----------._ [____] ""-,__ *****",13,10 + db " (_(||||||||||||)___________/ ""--.__ ***",13,10 + db " `----------' [ ))""-, \ *",13,10 + db " "" `--.__ |",13,10 + db " `----'",13,10,0 +bsShotgunDry db 13,10 + db " ,_______________________________________________",13,10 + db " |_________________,----------._ [____] ""-,__ click",13,10 + db " (_(||||||||||||)___________/ ""--.__",13,10 + db " `----------' [ ))""-, \",13,10 + db " "" `--.__ |",13,10 + db " `----'",13,10,0 +bsHPText db "HP: òû ",0 +bsAIHPText db " / AI ",0 +bsShellInfoText db "Ïàòðîíû â ðàóíäå: ",0 +bsLiveText db " æèâûõ, ",0 +bsBlankText db " õîëîñòûõ",13,10,0 +bsLeftText db "Îñòàëîñü â äðîáîâèêå: ",0 +bsKnownUnknownText db "Òåêóùèé ïàòðîí: íåèçâåñòíî",13,10,0 +bsKnownLiveText db "Òåêóùèé ïàòðîí: ÆÈÂÎÉ",13,10,0 +bsKnownBlankText db "Òåêóùèé ïàòðîí: õîëîñòîé",13,10,0 +bsItemsText db "Ïðåäìåòû: ëóïà ",0 +bsSawText db ", ïèëà ",0 +bsBeerText db ", ïèâî ",0 +bsCuffsText db ", íàðó÷íèêè ",0 +bsMenuText db 13,10,"1. Ñòðåëÿòü â ñåáÿ",13,10 + db "2. Ñòðåëÿòü â AI",13,10 + db "3. Ëóïà",13,10 + db "4. Ïèëà",13,10 + db "5. Ïèâî",13,10 + db "6. Íàðó÷íèêè",13,10 + db "Âûáîð: ",0 +bsLoadText db 13,10,"Êðóïüå çàðÿæàåò äðîáîâèê...",13,10,0 +bsLiveLoadedText db "Æèâîé ïàòðîí",13,10,0 +bsBlankLoadedText db "Õîëîñòîé ïàòðîí",13,10,0 +bsPlayerTurnText db 13,10,"Òâîé õîä.",13,10,0 +bsAITurnText db 13,10,"Õîä AI...",13,10,0 +bsShootPlayerText db "Âûñòðåë â òåáÿ.",13,10,0 +bsShootAIText db "Âûñòðåë â AI.",13,10,0 +bsDryText db "Ùåë÷îê. Õîëîñòîé.",13,10,0 +bsHitText db "ÁÀÕ! Óðîí: ",0 +bsGlassUseText db "Ëóïà ïîêàçûâàåò ïàòðîí.",13,10,0 +bsSawUseText db "Ïèëà íàäðåçàåò ñòâîë. Ñëåäóþùèé æèâîé âûñòðåë ñèëüíåå.",13,10,0 +bsBeerUseText db "Ïèâî. Ïàòðîí âûëåòàåò èç äðîáîâèêà: ",0 +bsCuffsUseText db "Íàðó÷íèêè çàùåëêíóëèñü. AI ïðîïóñòèò õîä.",13,10,0 +bsNoItemText db "Ýòîãî ïðåäìåòà íåò.",13,10,0 +bsAISawText db "AI èñïîëüçóåò ïèëó.",13,10,0 +bsAIGlassText db "AI ñìîòðèò ïàòðîí ÷åðåç ëóïó.",13,10,0 +bsAIBeerText db "AI âûáðàñûâàåò ïàòðîí ïèâîì.",13,10,0 +bsAICuffsText db "AI íàäåâàåò íà òåáÿ íàðó÷íèêè.",13,10,0 +bsSkipPlayerText db "Òû â íàðó÷íèêàõ è ïðîïóñêàåøü õîä.",13,10,0 +bsSkipAIText db "AI â íàðó÷íèêàõ è ïðîïóñêàåò õîä.",13,10,0 +bsWinText db "AI ïàäàåò. Òû çàáèðàåøü áàíê ñòîëà.",13,10,0 +bsLoseText db "Òû ïàäàåøü. Êðóïüå çàáèðàåò ñòàâêó.",13,10,0 +rrGunUp db 117,117,36,96,36,36,36,117,117,36,36,36,13,10 + + db 80,42,36,96,36,36,36,36,36,36,36,36,13,10 + + db 63,42,36,32,36,36,36,36,36,36,36,36,13,10 + + db 36,58,36,32,36,36,36,36,36,36,36,36,13,10 + + db 34,58,36,32,36,36,36,36,36,36,36,36,13,10 + + db 32,78,36,32,36,36,36,36,36,36,36,36,13,10 + + db 32,32,36,32,36,36,36,36,36,36,36,36,13,10 + + db 32,32,36,32,36,36,36,36,36,36,36,36,13,10 + + db 32,32,36,32,36,36,36,36,36,36,36,36,13,10 + + db 32,32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,36,36,82,82,36,36,36,36,36,36,13,10 + + db 32,32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,36,32,36,36,36,36,36,64,36,36,13,10 + + db 32,32,36,32,36,36,36,36,36,36,36,36,13,10 + + db 32,32,36,32,36,36,36,36,36,36,36,36,36,117,117,76,13,10 + + db 32,32,36,32,36,36,36,36,36,36,36,36,36,117,117,42,42,42,117,46,46,13,10 + + db 32,32,36,32,36,36,36,36,36,36,36,36,36,32,96,42,42,42,117,36,42,116,13,10 + + db 32,32,36,120,120,117,117,36,117,36,36,36,36,117,117,117,107,46,36,36,36,63,13,10 + + db 32,32,36,120,36,117,117,56,117,96,96,96,36,117,117,117,54,46,34,36,63,63,13,10 + + db 32,32,36,36,36,63,36,36,36,96,96,96,36,36,36,36,36,96,34,34,63,63,13,10 + + db 32,32,36,36,36,63,36,36,36,32,32,32,36,36,36,36,75,32,32,32,36,36,32,46,46,13,10 + + db 32,32,36,36,36,72,36,36,36,32,32,32,36,36,36,36,75,46,32,32,36,36,36,36,36,78,115,46,13,10 + + db 32,32,36,36,36,36,36,36,36,32,32,32,36,36,36,36,88,46,32,32,82,34,36,36,36,37,37,46,78,13,10 + + db 32,32,36,36,36,37,117,117,36,32,32,32,117,117,117,36,58,58,32,32,82,117,117,117,32,32,34,63,63,58,13,10 + + db 32,32,36,36,36,37,117,117,33,32,32,32,36,117,36,36,36,58,32,32,124,124,117,117,117,117,42,63,36,36,13,10 + + db 32,32,36,63,63,78,32,32,32,32,32,32,36,39,36,36,36,32,32,32,36,36,42,117,117,117,33,39,58,36,13,10 + + db 32,32,36,63,63,46,46,46,46,46,46,46,46,36,36,36,36,32,32,32,36,42,42,96,32,32,100,100,34,34,13,10 + + db 36,46,36,82,100,46,46,46,46,36,46,46,34,63,55,36,117,111,32,32,53,117,117,46,46,43,42,42,42,13,10 + + db 39,42,64,82,46,96,96,34,34,42,42,64,34,34,96,117,117,111,117,120,120,117,96,96,85,43,33,96,13,10 + + db 42,42,64,42,42,120,117,117,42,42,42,34,32,32,32,42,82,82,117,120,36,34,96,96,37,37,13,10 + + db 32,32,32,42,42,120,78,42,42,37,37,32,32,32,32,46,46,117,46,100,36,46,46,117,37,36,36,111,46,13,10 + + db 32,32,32,32,32,34,78,78,96,37,46,46,32,32,36,46,46,34,46,100,117,36,36,36,36,36,36,36,36,36,117,117 + + db 46,46,13,10 + + db 32,32,32,32,32,56,56,64,46,109,34,58,58,58,82,42,34,34,120,36,36,36,36,36,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,99,13,10 + + db 32,32,32,32,32,36,36,101,34,34,34,58,78,64,32,32,32,32,36,36,78,96,34,36,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,36,64,32,32,32,34,78,37,117,117,46,32,32,63,63,117,117,117,36,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,96,96,96,34,42,117,36,36,36,36,36,36,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,36,36,36,36,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,94,94,36,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,42,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,42,42,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,96 + + db 34,43,36,36,36,42,36,36,36,36,36,36,62,13,10 + + db 0 + +rrGunUpLeft db 32,32,32,32,32,32,32,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,99,13,10 + + db 32,32,32,32,32,32,36,36,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,62,13,10 + + db 32,32,32,32,32,117,32,36,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,62,13,10 + + db 32,32,32,32,36,36,36,36,36,36,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,62,62,13,10 + + db 32,32,32,36,32,36,36,36,32,36,36,32,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,46,32,78,58,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,32,36,62,13,10 + + db 32,32,36,32,36,36,32,36,36,36,32,36,36,32,32,32,32,32,32,32,32,32,32,32,32,46,116,32,32,32,32,32 + + db 32,32,115,46,63,32,36,32,32,32,32,32,32,32,32,32,32,36,32,36,36,36,32,36,36,32,36,62,13,10 + + db 32,36,96,36,36,36,36,36,36,36,36,36,36,36,36,32,32,32,32,32,32,32,32,32,46,36,36,63,63,32,32,46 + + db 36,78,37,34,63,36,36,34,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,62,13,10 + + db 117,32,36,32,32,36,36,36,32,36,36,32,36,36,36,32,32,32,32,32,32,32,32,42,117,32,36,63,32,63,32,36 + + db 32,36,32,32,42,39,34,32,32,32,32,32,32,32,46,36,36,32,36,36,32,36,36,36,32,36,36,32,36,13,10 + + db 80,42,36,36,32,36,36,36,36,36,36,36,36,36,36,36,36,32,32,32,117,76,42,42,46,36,36,34,63,36,36,36 + + db 36,117,117,117,33,100,42,42,32,32,32,32,117,46,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,63,58,32,36,32,32,36,36,36,32,36,36,32,36,36,32,36,32,117,32,117,42,32,107,46,34,32,32,36,32,34 + + db 117,32,117,117,32,32,42,96,32,32,32,117,32,36,36,32,36,36,32,36,36,36,32,36,36,32,36,13,10 + + db 32,32,36,58,32,36,32,36,32,36,36,32,36,36,36,32,36,36,32,36,117,32,96,117,54,32,96,32,32,32,82,117 + + db 32,117,117,32,32,43,33,32,32,46,32,36,36,32,36,36,36,32,36,36,32,36,36,36,32,36,13,10 + + db 32,32,34,32,78,36,36,32,36,36,36,36,36,36,36,64,36,36,36,36,36,32,117,117,36,36,75,46,32,32,32,124 + + db 124,36,42,96,46,85,37,32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,42,36,13,10 + + db 32,32,32,32,32,32,32,36,36,36,32,82,36,32,36,36,32,36,36,36,32,36,117,32,36,36,75,32,46,32,32,32 + + db 36,32,42,117,96,32,37,36,32,36,36,36,32,36,36,32,36,36,32,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,36,36,36,82,36,36,36,36,36,36,36,36,36,36,96,36,36,36,36,36,88,58,58,32,32 + + db 32,36,117,117,96,96,37,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,32,36,36,32,36,96,32,96,36,36,32,36,36,32,36,32,32 + + db 32,32,120,32,34,46,36,32,36,36,32,36,36,32,36,36,36,32,36,36,32,43,13,10 + + db 32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,36,36,36,117,96,96,96,32,32,36,36,117,36,36,36,36,111 + + db 32,117,120,36,46,36,36,36,36,36,36,36,36,36,36,36,36,36,36,96,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,36,32,32,36,36,32,117,56,36,32,32,32,32,32,117,117,32,36,36,32,117 + + db 111,32,117,100,117,32,36,34,32,36,36,36,32,36,36,32,36,36,32,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,32,117,117,32,36,36,32,32,32,32,32,36,39,32,36,36,117 + + db 32,82,46,32,100,36,96,32,117,36,32,36,36,32,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,36,36,120,120,36,63,36,36,36,36,36,32,32,32,36,46,36,55,96,42 + + db 82,46,34,46,36,36,117,117,36,36,36,36,36,36,36,42,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,120,32,36,63,36,32,36,36,32,32,32,46,32,34,34,32,32 + + db 46,32,46,34,36,32,63,36,32,36,36,36,32,42,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,117,117,33,32,46,46,46,64,34,32,32 + + db 36,46,34,32,32,63,36,36,36,36,94,94,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,37,32,117,32,46,32,36,42,32,34,32,32 + + db 32,82,32,32,32,117,36,32,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,37,32,32,46,46,42,32,42,32,32,32 + + db 58,32,32,46,42,32,32,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,63,46,46,46,34,42,42,37,46,46,58 + + db 78,64,117,96,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,63,32,63,46,96,32,117,42,32,37,34,58 + + db 32,37,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,63,100,46,120,117,42,78,96,109,34,34 + + db 78,32,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,82,32,42,120,78,32,64,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,32,64,42,42,32,34,56,32,101,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,39,42,64,32,42,32,56,36,36,64,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,42,32,32,32,32,32,32,36,13,10 + + db 0 + +rrGunLeft db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,99,62,62,62,62,62,62,62,62,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 46,36,36,36,36,36,36,36,36,36,43,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 46,36,36,36,36,36,36,36,36,36,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 117,36,36,36,36,36,36,36,36,36,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 117,36,36,36,36,36,36,36,36,36,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,58,36,36,34,32,32,32,32 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,78,63,36,58,34,42,32,32,46 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,46,63,63,39,100,42,96,32,111 + + db 36,36,36,36,36,36,36,36,36,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,115,37,34,42,33,100,42,33,32,36 + + db 36,36,36,36,36,36,36,36,36,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,78,37,32,117,117,32,43,43,37,36 + + db 36,36,36,36,36,36,36,36,36,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,36,36,32,117,117,32,46,85,37,37 + + db 36,36,36,36,36,36,36,36,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,36,36,117,117,117,96,46,96,96,117 + + db 36,36,36,36,36,36,36,36,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,117,117,42,42,117,96,96,46 + + db 36,36,34,117,36,36,36,94,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,116,63,63,63,36,36,34,117,124,36,42,117,117,34,46 + + db 36,36,96,117,36,36,36,94,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,42,36,63,63,36,36,82,82,124,36,36,53,120,36,36 + + db 117,36,78,117,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,36,36,36,34,32,32,32,32,32,32,32,32,120,120,100 + + db 100,36,36,63,36,36,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,117,117,36,34,34,32,32,32,32,32,32,32,32,117,117,46 + + db 46,120,36,63,36,36,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,42,42,46,46,96,32,46,46,58,58,32,32,111,111,82,117 + + db 34,34,32,32,117,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,42,42,107,54,36,75,75,88,58,36,36,36,117,117,82,46 + + db 46,34,32,32,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,76,42,42,117,117,36,36,36,36,36,36,36,36,36,117,42,46 + + db 46,42,32,46,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,117,117,96,117,117,36,36,36,36,117,36,36,36,55,96,32,32 + + db 36,82,32,117,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,117,117,32,117,117,36,36,36,36,117,117,39,36,63,34,32,32 + + db 32,58,64,117,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,117,36,36,46,34,34,32,32 + + db 32,58,78,37,96,13,10 + + db 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,96,96,32,32,32,32,32,32,46,46,64,34,32 + + db 46,58,58,78,13,10 + + db 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,96,96,32,32,32,32,32,32,46,46,42,42,37 + + db 46,34,34,34,13,10 + + db 36,36,36,36,36,36,36,36,36,36,36,36,36,64,36,36,36,36,36,96,96,32,32,32,32,32,32,46,36,42,42,37 + + db 37,109,34,13,10 + + db 117,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,117,117,36,36,36,36,36,33,32,46,46,34,42,42 + + db 96,46,34,13,10 + + db 117,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,56,36,36,36,36,117,117,32,46,46,34,117,42 + + db 78,64,101,13,10 + + db 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,117,117,36,36,36,36,117,117,32,46,46,96,117,78 + + db 78,56,36,64,13,10 + + db 36,36,36,36,36,36,36,36,36,36,36,82,36,36,36,36,36,36,117,117,63,63,72,36,37,37,78,46,46,96,120,120 + + db 34,56,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,36,82,36,36,36,36,36,36,120,36,36,36,36,36,36,36,63,63,100,46,42,42 + + db 13,10 + + db 96,96,32,32,32,32,32,32,32,36,36,36,36,32,32,32,32,32,120,120,36,36,36,36,36,36,63,63,82,82,42,42 + + db 13,10 + + db 36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,64,64,13 + + db 10 + + db 117,42,42,58,58,78,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,42,42,13 + + db 10 + + db 117,80,63,36,34,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,39,42,13 + + db 10 + + db 0 + +rrGunDownLeft db 32,32,32,32,32,32,62,36,13,10 + + db 32,32,32,32,32,62,36,32,36,13,10 + + db 32,32,32,62,62,36,36,36,36,36,13,10 + + db 32,32,32,62,36,32,36,36,36,32,36,13,10 + + db 32,32,62,36,32,36,36,32,36,36,32,36,13,10 + + db 32,62,36,36,36,36,36,36,36,36,36,42,36,13,10 + + db 99,36,32,36,36,32,36,36,36,32,36,36,32,36,13,10 + + db 32,36,36,36,36,36,36,36,36,36,36,36,36,36,43,13,10 + + db 32,32,36,36,32,36,36,32,36,36,32,36,36,36,32,34,13,10 + + db 32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,96,96,13,10 + + db 32,32,32,32,36,32,36,36,36,32,36,36,32,36,36,36,13,10 + + db 32,32,32,32,32,36,36,32,36,36,32,36,36,36,32,36,36,13,10 + + db 32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,42,13,10 + + db 32,32,32,32,32,32,32,36,36,32,36,36,32,36,36,36,32,36,42,13,10 + + db 32,32,32,32,32,32,32,46,36,36,36,36,36,36,36,36,36,36,36,96,13,10 + + db 32,32,32,32,32,32,32,32,46,36,32,36,36,36,32,36,36,32,36,42,13,10 + + db 32,32,32,32,32,32,32,32,117,32,36,36,32,36,36,36,32,36,36,32,34,13,10 + + db 32,32,32,32,32,32,32,32,32,117,36,36,36,36,36,36,36,36,36,36,94,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,94,13,10 + + db 32,32,32,32,32,32,32,32,32,32,46,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,36,32,117,36,32,36,34,13,10 + + db 32,32,32,32,32,32,34,32,42,96,32,32,36,36,32,36,34,32,117,36,36,32,34,13,10 + + db 32,32,32,32,32,36,36,34,42,42,33,37,37,37,36,36,36,96,117,63,36,36,13,10 + + db 32,32,32,32,58,32,36,39,100,32,43,85,32,96,46,36,32,36,36,32,63,117,13,10 + + db 32,32,32,32,78,63,63,42,33,32,32,46,96,96,34,46,117,100,36,36,32,32,42,34,13,10 + + db 32,32,32,32,32,46,34,32,117,117,32,96,117,117,32,36,100,32,46,34,32,32,46,96,13,10 + + db 32,32,32,32,46,115,37,32,117,117,117,42,42,117,120,120,117,46,34,46,34,32,32,117,96,96,13,10 + + db 32,32,32,32,32,32,78,36,117,32,117,36,32,36,32,117,32,82,46,32,46,82,32,64,37,13,10 + + db 32,32,32,32,32,32,36,32,36,117,32,124,36,32,32,32,111,32,82,46,36,32,58,78,32,78,13,10 + + db 32,32,32,32,32,32,46,36,36,34,117,124,32,32,32,111,117,117,42,32,32,32,32,58,58,34,13,10 + + db 32,32,32,32,32,32,32,32,36,32,82,32,32,32,32,36,32,36,96,32,32,32,32,46,34,34,13,10 + + db 32,32,32,32,32,32,32,63,36,36,32,32,32,58,36,36,36,36,55,34,34,34,32,46,37,109,34,101,64,13,10 + + db 32,32,32,32,32,32,63,32,63,32,32,32,46,58,32,36,36,32,36,34,64,32,42,37,32,96,64,32,36,36,13,10 + + db 32,32,32,32,32,32,63,63,34,32,32,46,32,88,36,36,32,39,46,32,46,42,32,42,42,78,32,56,36,13,10 + + db 32,32,32,32,32,116,36,36,36,34,96,75,75,36,36,117,117,36,36,46,46,36,42,42,117,42,78,34,56,13,10 + + db 32,32,32,32,32,46,36,32,36,46,32,36,36,36,32,36,117,32,32,32,46,32,46,34,32,117,120,13,10 + + db 32,32,32,32,32,32,46,117,46,107,54,36,36,36,36,36,32,32,32,32,32,46,46,46,96,120,42,42,42,13,10 + + db 32,32,32,32,32,32,32,42,42,32,117,117,32,36,36,32,32,32,32,32,33,32,32,46,46,46,32,42,13,10 + + db 32,32,32,32,32,32,32,32,42,42,96,117,117,36,96,32,32,32,36,36,117,117,32,46,63,100,82,64,64,13,10 + + db 32,32,32,32,32,32,32,32,76,117,32,32,36,96,32,96,32,32,36,36,117,32,37,63,32,63,36,32,42,42,13,10 + + db 32,32,32,32,32,32,32,32,117,32,117,36,32,36,96,96,32,36,36,32,36,37,32,36,63,36,32,46,39,13,10 + + db 32,32,32,32,32,32,32,32,32,117,36,36,36,36,36,96,36,36,36,36,36,36,36,36,36,36,32,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,117,56,32,36,63,36,32,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,117,117,63,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,36,32,36,36,32,36,36,36,32,117,36,32,36,36,13,10 + + db 32,32,32,32,32,32,32,32,36,36,32,64,36,36,32,36,36,32,120,120,36,13,10 + + db 32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,120,36,36,13,10 + + db 32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,36,32,32,36,13,10 + + db 32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,32,36,36,13,10 + + db 32,32,32,36,32,36,36,32,36,36,32,36,82,36,32,32,36,13,10 + + db 32,32,32,36,36,32,36,36,36,32,36,36,32,82,36,36,13,10 + + db 32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,36,36,36,32,36,36,32,36,36,32,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,36,32,36,36,13,10 + + db 32,36,32,36,36,32,36,36,36,32,32,36,13,10 + + db 32,32,117,36,36,36,36,36,36,32,36,36,13,10 + + db 32,32,32,36,32,36,36,32,32,36,32,78,13,10 + + db 32,32,32,32,36,32,36,32,36,32,58,13,10 + + db 32,32,32,32,32,36,96,36,36,58,36,34,13,10 + + db 32,32,32,32,32,32,36,32,42,63,13,10 + + db 32,32,32,32,32,32,32,117,80,13,10 + + db 0 + +rrGunDown db 62,36,36,36,36,36,36,42,36,36,36,43,34,96,96,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,42,42,96,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,42,34,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,94,94,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,34,34,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,117,42,34,96,96 + + db 96,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,117,117,117,63,63,32,32,46,117,117 + + db 37,78,34,32,32,32,64,36,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,34,96,78,36,36,32,32,32,32,64 + + db 78,58,34,34,34,101,36,36,13,10 + + db 99,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,120,34,34,42,82,58 + + db 58,58,34,109,46,64,56,56,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,46,46,117,117,36,36,36,36,36,36,36,36,36,117,100,46,34,46,46,36,32 + + db 32,46,46,37,96,78,78,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,111,36,36,37,117,46,46,36,100,46,117,46,46,32,32 + + db 32,32,37,37,42,42,78,120,42,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,37,37,96,96,34,36,120,117,82,82,42,32,32 + + db 32,34,42,42,42,117,117,120,42,42,64,42,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,33,43,85,96,96,117,120,120,117,111,117,117,96,34 + + db 34,64,42,42,34,34,96,96,46,82,64,42,39,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,42,42,42,43,46,46,117,117,53,32,32,111,117,36,55,63 + + db 34,46,46,36,46,46,46,46,100,82,36,46,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,34,100,100,32,32,96,42,42,36,32,32,32,36,36,36,36 + + db 46,46,46,46,46,46,46,46,63,63,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,58,39,33,117,117,117,42,36,36,32,32,32,36,36,36,39 + + db 36,32,32,32,32,32,32,78,63,63,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,63,42,117,117,117,117,124,124,32,32,58,36,36,36,117 + + db 36,32,32,32,33,117,117,37,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,58,63,63,34,32,32,117,117,117,82,32,32,58,58,36,117,117 + + db 117,32,32,32,36,117,117,37,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,78,46,37,37,36,36,36,34,82,32,32,46,88,36,36,36 + + db 36,32,32,32,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,115,78,36,36,36,36,36,32,32,46,75,36,36,36 + + db 36,32,32,32,36,36,36,72,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,46,32,36,36,32,32,32,75,36,36,36 + + db 36,32,32,32,36,36,36,63,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,63,63,34,34,96,36,36,36,36 + + db 36,96,96,96,36,36,36,63,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,63,63,36,34,46,54,117,117,117 + + db 36,96,96,96,117,56,117,117,36,120,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,63,36,36,36,46,107,117,117,117 + + db 36,36,36,36,117,36,117,117,120,120,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,116,42,36,117,42,42,42,96,32 + + db 36,36,36,36,36,36,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,46,46,117,42,42,42,117,117 + + db 36,36,36,36,36,36,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,76,117,117 + + db 36,36,36,36,36,36,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,64,36,36,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,82,82,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,32,36,78,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,32,36,58,34,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,32,36,58,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,32,36,42,63,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,36,36,36,36,36,96,36,42,80,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,36,36,36,117,117,36,36,36,96,36,117,117,13,10 + + db 0 + +rrGunDownRight db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 36,32,32,32,32,32,32,42,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64 + + db 36,36,56,32,42,32,64,42,39,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,101 + + db 32,56,34,32,42,42,64,32,46,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34 + + db 64,32,78,120,42,32,82,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,32,78,34,34,109 + + db 96,78,42,117,120,46,100,63,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,37,32,58,34,37 + + db 32,42,117,32,96,46,63,32,63,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,96,117,64,78,58,46,46 + + db 37,42,42,34,46,46,46,63,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,32,32,42,46,32,32,58,32,32,32 + + db 42,32,42,46,46,32,32,37,32,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,32,36,117,32,32,32,82,32,32,32,34 + + db 32,42,36,32,46,32,117,32,37,36,32,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,94,94,36,36,36,36,63,32,32,34,46,36,32,32,34 + + db 64,46,46,46,32,33,117,117,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,96,42,32,36,36,36,32,36,63,32,36,34,46,32,46,32,32,34 + + db 34,32,46,32,32,32,36,36,32,36,63,36,32,120,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,42,42,36,36,36,36,36,36,36,117,117,36,36,46,34,46,82,42,96,55 + + db 36,46,36,32,32,32,36,36,36,36,36,63,36,120,120,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,117,32,96,36,100,32,46,82,32,117,36,36 + + db 32,39,36,32,32,32,32,32,36,36,32,117,117,32,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,96,32,36,36,32,36,36,32,36,36,36,32,34,36,32,117,100,117,32,111,117,32,36 + + db 36,32,117,117,32,32,32,32,32,36,56,117,32,36,36,32,32,36,13,10 + + db 32,32,32,32,32,32,32,32,34,96,36,36,36,36,36,36,36,36,36,36,36,36,36,36,46,36,120,117,32,111,36,36 + + db 36,36,117,36,36,32,32,96,96,96,117,36,36,36,36,36,36,32,36,36,13,10 + + db 32,32,32,32,32,32,32,43,32,36,36,32,36,36,36,32,36,36,32,36,36,32,36,46,34,32,120,32,32,32,32,36 + + db 32,36,36,32,36,36,96,32,96,36,32,36,36,32,36,36,36,32,36,36,13,10 + + db 32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,37,96,96,117,117,36,32,32,32,58 + + db 58,88,36,36,36,36,36,96,36,36,36,36,36,36,36,36,36,36,82,36,36,36,13,10 + + db 32,32,32,32,32,36,32,36,36,36,32,36,36,32,36,36,32,36,36,36,32,36,37,32,96,117,42,32,36,32,32,32 + + db 46,32,75,36,36,32,117,36,32,36,36,36,32,36,36,32,36,82,32,36,36,36,13,10 + + db 32,32,32,32,36,42,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,32,37,85,46,96,42,36,124,124,32,32 + + db 32,46,75,36,36,117,117,32,36,36,36,36,36,64,36,36,36,36,36,36,36,32,36,36,78,32,34,13,10 + + db 32,32,32,36,32,36,36,36,32,36,36,32,36,36,36,32,36,36,32,46,32,32,33,43,32,32,117,117,32,117,82,32 + + db 32,32,96,32,54,117,96,32,117,36,32,36,36,32,36,36,36,32,36,36,32,36,32,36,32,58,36,13,10 + + db 32,32,36,32,36,36,32,36,36,36,32,36,36,32,36,36,32,117,32,32,32,96,42,32,32,117,117,32,117,34,32,36 + + db 32,32,34,46,107,32,42,117,32,117,32,36,32,36,36,32,36,36,32,36,36,36,32,32,36,32,58,63,13,10 + + db 32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,46,117,32,32,32,32,42,42,100,33,117,117,117,36,36,36,36 + + db 63,34,36,36,46,42,42,76,117,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,32,36,36,42,80,13,10 + + db 36,32,36,36,32,36,36,36,32,36,36,32,36,36,46,32,32,32,32,32,32,32,34,39,42,32,32,36,32,36,32,63 + + db 32,63,36,32,117,42,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,36,32,32,36,32,117,13,10 + + db 62,36,36,36,36,36,36,36,36,36,36,36,36,32,32,32,32,32,32,32,32,34,36,36,63,34,37,78,36,46,32,32 + + db 63,63,36,36,46,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,96,36,13,10 + + db 32,62,36,32,36,36,32,36,36,36,32,36,32,32,32,32,32,32,32,32,32,32,36,32,63,46,115,32,32,32,32,32 + + db 32,32,116,46,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,32,36,36,32,36,13,10 + + db 32,32,62,36,32,36,36,36,32,36,36,32,32,32,32,32,32,32,32,32,32,32,32,58,78,32,46,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,32,36,36,36,32,36,13,10 + + db 32,32,62,62,36,36,36,36,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,62,36,32,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,117,13,10 + + db 32,32,32,32,32,62,36,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,13,10 + + db 32,32,32,32,32,32,99,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,13,10 + + db 0 + +rrGunRight db 32,32,32,32,32,32,32,32,32,32,32,32,42,39,36,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,32,34,36,63,80,117,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,42,42,46,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 + + db 32,32,32,32,32,78,58,58,42,42,117,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,64,64,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,42,42,82,82,63,63,36,36,36,36,36,36,120,120,32,32,32,32,32,36,36 + + db 36,36,32,32,32,32,32,32,32,96,96,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,42,42,46,100,63,63,36,36,36,36,36,36,36,120,36,36,36,36,36,36,82 + + db 36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,36,36,56,34,120,120,96,46,46,78,37,37,36,72,63,63,117,117,36,36,36,36,36,36,82 + + db 36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,64,36,56,78,78,117,96,46,46,32,117,117,36,36,36,36,117,117,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,101,64,78,42,117,34,46,46,32,117,117,36,36,36,36,56,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,117,13,10 + + db 32,32,32,32,32,32,32,32,34,46,96,42,42,34,46,46,32,33,36,36,36,36,36,117,117,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,117,13,10 + + db 32,32,32,32,32,32,32,32,34,109,37,37,42,42,36,46,32,32,32,32,32,32,96,96,36,36,36,36,36,64,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,34,34,34,46,37,42,42,46,46,32,32,32,32,32,32,96,96,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,78,58,58,46,32,34,64,46,46,32,32,32,32,32,32,96,96,36,36,36,36,36,36,36,36 + + db 36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,96,37,78,58,32,32,32,34,34,46,36,36,117,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,96,117,64,58,32,32,32,34,63,36,39,117,117,36,36,36,36,117,117,32,117,117,13,10 + + db 32,32,32,32,32,32,96,117,32,82,36,32,32,96,55,36,36,36,117,36,36,36,36,117,117,96,117,117,13,10 + + db 32,32,32,32,32,32,34,46,32,42,46,46,42,117,36,36,36,36,36,36,36,36,36,117,117,42,42,76,13,10 + + db 32,32,32,32,32,32,42,32,32,34,46,46,82,117,117,36,36,36,58,88,75,75,36,54,107,42,42,13,10 + + db 32,32,32,32,32,32,117,32,32,34,34,117,82,111,111,32,32,58,58,46,46,32,96,46,46,42,42,13,10 + + db 32,32,32,32,34,36,36,63,36,120,46,46,117,117,32,32,32,32,32,32,32,32,34,34,36,117,117,13,10 + + db 32,32,32,32,34,36,36,63,36,36,100,100,120,120,32,32,32,32,32,32,32,32,34,36,36,36,46,13,10 + + db 32,32,32,32,36,36,36,117,78,36,117,36,36,120,53,36,36,124,82,82,36,36,63,63,36,42,46,13,10 + + db 32,32,32,94,36,36,36,117,96,36,36,46,34,117,117,42,36,124,117,34,36,36,63,63,63,116,13,10 + + db 32,32,32,94,36,36,36,117,34,36,36,46,96,96,117,42,42,117,117,36,36,13,10 + + db 32,32,34,36,36,36,36,36,36,36,36,117,96,96,46,96,117,117,117,36,36,46,13,10 + + db 32,32,42,36,36,36,36,36,36,36,36,37,37,85,46,32,117,117,32,36,36,46,13,10 + + db 32,96,36,36,36,36,36,36,36,36,36,36,37,43,43,32,117,117,32,37,78,13,10 + + db 32,42,36,36,36,36,36,36,36,36,36,36,32,33,42,100,33,42,34,37,115,13,10 + + db 32,42,36,36,36,36,36,36,36,36,36,111,32,96,42,100,39,63,63,46,46,13,10 + + db 32,36,36,36,36,36,36,36,36,36,36,46,32,32,42,34,58,36,63,78,13,10 + + db 32,36,36,36,36,36,36,36,36,36,36,32,32,32,32,34,36,36,58,13,10 + + db 96,36,36,36,36,36,36,36,36,36,117,13,10 + + db 96,36,36,36,36,36,36,36,36,36,117,13,10 + + db 34,36,36,36,36,36,36,36,36,36,46,13,10 + + db 43,36,36,36,36,36,36,36,36,36,46,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 42,36,36,36,36,36,36,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 36,36,36,36,36,36,36,36,36,36,13,10 + + db 62,62,62,62,62,62,62,62,62,99,13,10 + + db 0 + +rrGunUpRight db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,80,117,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,63,42,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,36,58,36,36,96,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,58,32,36,32,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,78,32,36,32,32,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,36,36,36,117,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,32,36,36,36,32,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,32,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,82,32,36,36,32,36,36,36,32,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,32,36,82,36,32,36,36,32,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,36,32,32,36,36,36,32,36,36,32,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,36,36,120,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,36,120,120,32,36,36,32,36,36,64,32,36,36,13,10 + + db 32,32,32,32,32,32,32,32,36,36,32,36,117,32,36,36,36,32,36,36,32,36,13,10 + + db 32,32,32,32,32,32,36,36,36,36,36,63,117,117,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,36,36,32,36,63,36,32,56,117,32,36,36,36,13,10 + + db 32,36,32,32,36,36,36,36,36,36,36,36,36,36,96,36,36,36,36,36,117,13,10 + + db 32,39,46,32,36,63,36,32,37,36,32,36,36,32,96,96,36,32,36,117,32,117,13,10 + + db 42,42,32,36,63,32,63,37,32,117,36,36,32,32,96,32,96,36,32,32,117,76,13,10 + + db 32,64,64,82,100,63,46,32,117,117,36,36,32,32,32,96,36,117,117,96,42,42,13,10 + + db 32,32,42,32,46,46,46,32,32,33,32,32,32,32,32,36,36,32,117,117,32,42,42,13,10 + + db 32,42,42,42,120,96,46,46,46,32,32,32,32,32,36,36,36,36,36,54,107,46,117,46,13,10 + + db 32,32,32,120,117,32,34,46,32,46,32,32,32,117,36,32,36,36,36,32,46,36,32,36,46,13,10 + + db 32,56,34,78,42,117,42,42,36,46,46,36,36,117,117,36,36,75,75,96,34,36,36,36,116,13,10 + + db 32,36,56,32,78,42,42,32,42,46,32,46,39,32,36,36,88,32,46,32,32,34,63,63,13,10 + + db 36,36,32,64,96,32,37,42,32,64,34,36,32,36,36,32,58,46,32,32,32,63,32,63,13,10 + + db 32,64,101,34,109,37,46,32,34,34,34,55,36,36,36,36,58,32,32,32,36,36,63,13,10 + + db 32,32,32,32,34,34,46,32,32,32,32,96,36,32,36,32,32,32,32,82,32,36,13,10 + + db 32,32,32,32,34,58,58,32,32,32,32,42,117,117,111,32,32,32,124,117,34,36,36,46,13,10 + + db 32,32,32,32,78,32,78,58,32,36,46,82,32,111,32,32,32,36,124,32,117,36,32,36,13,10 + + db 32,32,32,32,32,37,64,32,82,46,32,46,82,32,117,32,36,32,36,117,32,117,36,78,13,10 + + db 32,32,32,32,96,96,117,32,32,34,46,34,46,117,120,120,117,42,42,117,117,117,32,37,115,46,13,10 + + db 32,32,32,32,32,32,96,46,32,32,34,46,32,100,36,32,117,117,96,32,117,117,32,34,46,13,10 + + db 32,32,32,32,32,32,34,42,32,32,36,36,100,117,46,34,96,96,46,32,32,33,42,63,63,78,13,10 + + db 32,32,32,32,32,32,32,32,117,63,32,36,36,32,36,46,96,32,85,43,32,100,39,36,32,58,13,10 + + db 32,32,32,32,32,32,32,32,36,36,63,117,96,36,36,36,37,37,37,33,42,42,34,36,36,13,10 + + db 32,32,32,32,32,32,32,34,32,36,36,117,32,34,36,32,36,36,32,32,96,42,32,34,13,10 + + db 32,32,32,32,32,32,32,32,34,36,32,36,117,32,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,36,46,13,10 + + db 32,32,32,32,32,32,32,32,32,94,36,36,32,36,36,32,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,94,36,36,36,36,36,36,36,36,36,36,117,13,10 + + db 32,32,32,32,32,32,32,32,32,34,32,36,36,32,36,36,36,32,36,36,32,117,13,10 + + db 32,32,32,32,32,32,32,32,32,32,42,36,32,36,36,32,36,36,36,32,36,46,13,10 + + db 32,32,32,32,32,32,32,32,32,32,96,36,36,36,36,36,36,36,36,36,36,36,46,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,42,36,32,36,36,36,32,36,36,32,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,42,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,32,36,36,36,32,36,36,32,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,32,36,36,32,36,36,36,32,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,96,96,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,34,32,36,36,36,32,36,36,32,36,36,32,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,43,36,36,36,36,36,36,36,36,36,36,36,36,36,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,32,36,36,36,32,36,36,32,36,99,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,42,36,36,36,36,36,36,36,36,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,32,36,36,32,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,36,36,32,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,62,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,32,36,62,13,10 + + db 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,36,62,13,10 + + db 0 + +pokerReplaceText db "Ïîìåíÿòü êàðòó ",0 +pokerReplaceTail db "? (y/n): ",0 +pokerAIExchangeText db 13,10,"AI äóìàåò íàä îáìåíîì...",13,10,0 +pokerRevealText db 13,10,"AI âñêðûâàåò ïîêåðíóþ ðóêó...",13,10,0 +pokerYourComboText db "Òâîÿ êîìáèíàöèÿ: ",0 +pokerAIComboText db "Êîìáèíàöèÿ AI: ",0 +pokerTableText db 13,10,"Êàðòû íà ñòîëå:",13,10,0 +pokerHintText db "Ïîäñêàçêà: ñåé÷àñ ó òåáÿ ",0 +pokerDecisionText db "1 - èãðàòü, 2 - ïîâûñèòü ñòàâêó, 0 - ôîëä: ",0 +pokerPotText db "Áàíê ðàóíäà: $",0 +pokerBetText db "Òâîÿ òåêóùàÿ ñòàâêà: $",0 +pokerChipTitle db "Ôèøêè:",13,10,0 +pokerChipHigh db " [###]",13,10,0 +pokerChipMid db " [===]",13,10,0 +pokerChipLow db " [___]",13,10,0 +pokerRaiseAskText db "Íà ñêîëüêî ïîâûñèòü ñòàâêó: $",0 +pokerRaisedText db "Òû ïîâûñèë ñòàâêó. Íîâàÿ ñòàâêà: $",0 +pokerBadRaiseText db "Ïîâûøåíèå äîëæíî áûòü áîëüøå 0 è íå áîëüøå òâîåãî áàíêà.",13,10,0 +pokerAICallRaiseText db 13,10,"AI îòâå÷àåò íà ñòàâêó.",13,10,0 +pokerAIFoldRaiseText db 13,10,"AI íå ïðèíèìàåò ïîâûøåíèå è äåëàåò ôîëä. Òû âûèãðàë!",13,10,0 +pokerHardIntroText db "Hard Poker: îäèí ðàç ìîæíî çàìåíèòü îäíó êàðìàííóþ êàðòó.",13,10,0 +pokerHardExchangeText db "Çàìåíèòü êàðòó? 1 - ïåðâóþ, 2 - âòîðóþ, 0 - íå ìåíÿòü: ",0 +pokerHardAIExchangeText db 13,10,"AI ïåðåñìàòðèâàåò êàðìàííûå êàðòû...",13,10,0 +pokerAIRaiseText db 13,10,"AI ïîâûøàåò ñòàâêó íà $",0 +pokerCallRaiseText db "Îòâåòèòü? 1 - êîëë, 0 - ôîëä: ",0 +pokerPlayerCallText db "Òû îòâåòèë íà ïîâûøåíèå. Íîâàÿ ñòàâêà: $",0 +pokerFoldToRaiseText db 13,10,"Òû ñáðîñèë êàðòû ïîñëå ïîâûøåíèÿ AI.",13,10,"Òû ïðîèãðàë.",13,10,0 +pokerFoldText db 13,10,"Òû ñäåëàë ôîëä.",13,10,"Òû ïðîèãðàë.",13,10,0 +pokerAIFoldText db 13,10,"AI ñäåëàë ôîëä. Òû âûèãðàë!",13,10,0 +pokerNextCardText db 13,10,"Îòêðûâàåòñÿ ñëåäóþùàÿ êàðòà...",13,10,0 +pokerHighName db "Ñòàðøàÿ êàðòà",13,10,0 +pokerPairName db "Ïàðà",13,10,0 +pokerTwoPairName db "Äâå ïàðû",13,10,0 +pokerTripsName db "Òðîéêà",13,10,0 +pokerStraightName db "Ñòðèò",13,10,0 +pokerFlushName db "Ôëåø",13,10,0 +pokerFullHouseName db "Ôóëë õàóñ",13,10,0 +pokerFourName db "Êàðå",13,10,0 +pokerStraightFlushName db "Ñòðèò-ôëåø",13,10,0 + +; === Òåêñòû è ñèìâîëû ñëîò-ìàøèí === +slotPullText db "Êðóòèì áàðàáàíû...",13,10,0 +slotLeft db "[ ",0 +slotMid db " ] [ ",0 +slotRight db " ]",13,10,0 +slotJackpot db "Äæåêïîò!",13,10,0 +slotPair db "Êîìáèíàöèÿ ñûãðàëà!",13,10,0 +slotPayoutText db "Âûïëàòà x",0 +slotPayTableText db "Ñèìâîëû: LEM/CHR x2, CLV/BEL x3, DIA/BOX x5, 777 x7.",13,10 + db "Êîìáèíàöèè: Ãîð.M/Âåðò.M/Äèàã.M x1, Ãîð.L x2, Ãîð.XL x3",13,10 + db "Ââåðõ/Âíèç x4, Íåáî/Çåìëÿ x7, Ãëàç x8, Äæåêïîò x10.",13,10,0 +slotEmpty db "Íå ïîâåçëî.",13,10,0 +slotComboText db "Êîìáèíàöèÿ: ",0 +slotMultiplierText db "Ìíîæèòåëü: x",0 +slotTotalMultiplierText db "Èòîãîâûé ìíîæèòåëü: x",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 + +; === Ãðàôèêà êàðò: ðàìêè, ñòðîêè, ðóáàøêè è ïåðåâîðîò === +cardTop db 0E2h, 094h, 08Ch, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 090h, 13,10,0 +cardBottom db 0E2h, 094h, 094h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 098h, 13,10,0 +cardEmpty db 0E2h, 094h, 082h, " ", 0E2h, 094h, 082h, 13,10,0 +cardSuitLeft db 0E2h, 094h, 082h, " ", 0 +cardSuitRight db " ", 0E2h, 094h, 082h, 13,10,0 +cardRankOneL db 0E2h, 094h, 082h, " ", 0 +cardRankOneR db " ", 0E2h, 094h, 082h, 13,10,0 +cardRankTenL db 0E2h, 094h, 082h, " ", 0 +cardRankTenR db " ", 0E2h, 094h, 082h, 13,10,0 +cardCenterL db 0E2h, 094h, 082h, " ", 0 +cardCenterR db " ", 0E2h, 094h, 082h, 13,10,0 +cardTopSeg db 0E2h, 094h, 08Ch, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 090h, 0 +cardBottomSeg db 0E2h, 094h, 094h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 098h, 0 +cardEmptySeg db 0E2h, 094h, 082h, " ", 0E2h, 094h, 082h, 0 +cardBackSeg db 0E2h, 094h, 082h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 094h, 082h, 0 +cardBackBlueSeg db 0E2h, 094h, 082h, "~~*~~*~~*", 0E2h, 094h, 082h, 0 +cardBackRedSeg db 0E2h, 094h, 082h, "XX+XX+XX+", 0E2h, 094h, 082h, 0 +cardBackGoldSeg db 0E2h, 094h, 082h, "$*$*$*$*$", 0E2h, 094h, 082h, 0 +cardBackSkullSeg db 0E2h, 094h, 082h, "|o",0E2h,098h,0A0h," v ",0E2h,098h,0A0h,"o|", 0E2h, 094h, 082h, 0 +cardBackCloverSeg db 0E2h, 094h, 082h, "$+ ",0E2h,099h,0A3h,"$",0E2h,099h,0A3h," +$", 0E2h, 094h, 082h, 0 +backGray1 db 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 +backGray2 db 0E2h,094h,082h,"|#|#|#|#|",0E2h,094h,082h,0 +backGray3 db 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 +backGray4 db 0E2h,094h,082h,"|#|#|#|#|",0E2h,094h,082h,0 +backGray5 db 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 +backBlue1 db 0E2h,094h,082h,"\\==*==//",0E2h,094h,082h,0 +backBlue2 db 0E2h,094h,082h,"/ ___ /",0E2h,094h,082h,0 +backBlue3 db 0E2h,094h,082h,"| (@@@) |",0E2h,094h,082h,0 +backBlue4 db 0E2h,094h,082h,"/ ~~~ /",0E2h,094h,082h,0 +backBlue5 db 0E2h,094h,082h,"//==*==//",0E2h,094h,082h,0 +backRed1 db 0E2h,094h,082h,"ooooooooo",0E2h,094h,082h,0 +backRed2 db 0E2h,094h,082h,"oXXXxXXXo",0E2h,094h,082h,0 +backRed3 db 0E2h,094h,082h,"oXX---XXo",0E2h,094h,082h,0 +backRed4 db 0E2h,094h,082h,"oXXXxXXXo",0E2h,094h,082h,0 +backRed5 db 0E2h,094h,082h,"ooooooooo",0E2h,094h,082h,0 +backGold1 db 0E2h,094h,082h,"{$*$$$*$}",0E2h,094h,082h,0 +backGold2 db 0E2h,094h,082h,"*/^ $ ^/*",0E2h,094h,082h,0 +backGold3 db 0E2h,094h,082h,"$ <@@@> $",0E2h,094h,082h,0 +backGold4 db 0E2h,094h,082h,"*v/ $ /v*",0E2h,094h,082h,0 +backGold5 db 0E2h,094h,082h,"{$*$$$*$}",0E2h,094h,082h,0 +backSkull1 db 0E2h,094h,082h,"._.---._.",0E2h,094h,082h,0 +backSkull2 db 0E2h,094h,082h,"/,(o o),\",0E2h,094h,082h,0 +backSkull3 db 0E2h,094h,082h,"| ^ |",0E2h,094h,082h,0 +backSkull4 db 0E2h,094h,082h,"\ '-=-' /",0E2h,094h,082h,0 +backSkull5 db 0E2h,094h,082h,"~|==|==|~",0E2h,094h,082h,0 +backClover1 db 0E2h,094h,082h,"+o+$$$+o+",0E2h,094h,082h,0 +backClover2 db 0E2h,094h,082h,"o ",0E2h,098h,098h," + ",0E2h,098h,098h," o",0E2h,094h,082h,0 +backClover3 db 0E2h,094h,082h,"$+ ",0E2h,099h,0A3h,"$",0E2h,099h,0A3h," +$",0E2h,094h,082h,0 +backClover4 db 0E2h,094h,082h,"o ",0E2h,098h,098h," | ",0E2h,098h,098h," o",0E2h,094h,082h,0 +backClover5 db 0E2h,094h,082h,"+o+$$$+o+",0E2h,094h,082h,0 +backArcane1 db 0E2h,094h,082h,".~*~*~*~.",0E2h,094h,082h,0 +backArcane2 db 0E2h,094h,082h,"/__~_~__\",0E2h,094h,082h,0 +backArcane3 db 0E2h,094h,082h,"|_/\/\_ |",0E2h,094h,082h,0 +backArcane4 db 0E2h,094h,082h,"| \_/\_/|",0E2h,094h,082h,0 +backArcane5 db 0E2h,094h,082h,"'--===--'",0E2h,094h,082h,0 +backNoir1 db 0E2h,094h,082h,"((\\_//))",0E2h,094h,082h,0 +backNoir2 db 0E2h,094h,082h,"// | \\",0E2h,094h,082h,0 +backNoir3 db 0E2h,094h,082h,"--(#*#)--",0E2h,094h,082h,0 +backNoir4 db 0E2h,094h,082h,"\\__|__//",0E2h,094h,082h,0 +backNoir5 db 0E2h,094h,082h,"((//~\\))",0E2h,094h,082h,0 +backDiamond1 db 0E2h,094h,082h,"<><###><>",0E2h,094h,082h,0 +backDiamond2 db 0E2h,094h,082h,"/\ /\",0E2h,094h,082h,0 +backDiamond3 db 0E2h,094h,082h,"*$*",0E2h,094h,082h,0 +backDiamond4 db 0E2h,094h,082h,"\/ \/",0E2h,094h,082h,0 +backDiamond5 db 0E2h,094h,082h,"<><###><>",0E2h,094h,082h,0 +backRider1 db 0E2h,094h,082h,".oO===Oo.",0E2h,094h,082h,0 +backRider2 db 0E2h,094h,082h,"(/ .-. /)",0E2h,094h,082h,0 +backRider3 db 0E2h,094h,082h,"o-( @ )-o",0E2h,094h,082h,0 +backRider4 db 0E2h,094h,082h,"(/ '-' /)",0E2h,094h,082h,0 +backRider5 db 0E2h,094h,082h,"'oO===Oo'",0E2h,094h,082h,0 +backBee1 db 0E2h,094h,082h,"<>.<>.<>.",0E2h,094h,082h,0 +backBee2 db 0E2h,094h,082h,".<>.<><>.",0E2h,094h,082h,0 +backBee3 db 0E2h,094h,082h,"<> BEE <>",0E2h,094h,082h,0 +backBee4 db 0E2h,094h,082h,".<>.<><>.",0E2h,094h,082h,0 +backBee5 db 0E2h,094h,082h,"<>.<>.<>.",0E2h,094h,082h,0 +backFan1 db 0E2h,094h,082h,"\\|/\\|//",0E2h,094h,082h,0 +backFan2 db 0E2h,094h,082h," -\\|//- ",0E2h,094h,082h,0 +backFan3 db 0E2h,094h,082h,"<(( o ))>",0E2h,094h,082h,0 +backFan4 db 0E2h,094h,082h," -//|\\- ",0E2h,094h,082h,0 +backFan5 db 0E2h,094h,082h,"//|/|/|\\",0E2h,094h,082h,0 +backWeb1 db 0E2h,094h,082h,"\\..|..//",0E2h,094h,082h,0 +backWeb2 db 0E2h,094h,082h,".\\.|.//.",0E2h,094h,082h,0 +backWeb3 db 0E2h,094h,082h,"--(o-o)--",0E2h,094h,082h,0 +backWeb4 db 0E2h,094h,082h,".//|.|\\.",0E2h,094h,082h,0 +backWeb5 db 0E2h,094h,082h,"//''-''\\",0E2h,094h,082h,0 +cardFlipLeft db 0E2h, 094h, 082h, " \ ", 0E2h, 094h, 082h, 0 +cardFlipMid db 0E2h, 094h, 082h, " | ", 0E2h, 094h, 082h, 0 +cardFlipRight db 0E2h, 094h, 082h, " / ", 0E2h, 094h, 082h, 0 +cardSuitRightSeg db " ", 0E2h, 094h, 082h, 0 +cardRankOneRSeg db " ", 0E2h, 094h, 082h, 0 +cardRankTenRSeg db " ", 0E2h, 094h, 082h, 0 +cardCenterRSeg db " ", 0E2h, 094h, 082h, 0 +cardGap db " ",0 +revealText db 13,10,"AI âñêðûâàåò êàðòû...",13,10,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 + +suitSpades db 0E2h, 099h, 0A0h, 0 +suitHearts db 0E2h, 099h, 0A5h, 0 +suitClubs db 0E2h, 099h, 0A3h, 0 +suitDiamonds db 0E2h, 099h, 0A6h, 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 +suits dd OFFSET suitSpades, OFFSET suitHearts, OFFSET suitClubs, OFFSET suitDiamonds +pokerNames dd OFFSET pokerHighName, OFFSET pokerPairName, OFFSET pokerTwoPairName + dd OFFSET pokerTripsName, OFFSET pokerStraightName, OFFSET pokerFlushName + dd OFFSET pokerFullHouseName, OFFSET pokerFourName, OFFSET pokerStraightFlushName + +slot0 db "CLV",0 +slot1 db "LEM",0 +slot2 db "CHR",0 +slot3 db "BEL",0 +slot4 db "DIA",0 +slot5 db "BOX",0 +slot6 db "777",0 +slotSymbols dd OFFSET slot0, OFFSET slot1, OFFSET slot2 + dd OFFSET slot3, OFFSET slot4, OFFSET slot5, OFFSET slot6 +slotSymbolValues dd 3, 2, 2, 3, 5, 5, 7 +classicSlot0 db "7",0 +classicSlot1 db "BAR",0 +classicSlot2 db "$",0 +classicSlot3 db "*",0 +classicSlot4 db "#",0 +classicSlot5 db "A",0 +classicSlotSymbols dd OFFSET classicSlot0, OFFSET classicSlot1, OFFSET classicSlot2 + dd OFFSET classicSlot3, OFFSET classicSlot4, OFFSET classicSlot5 +classicSlotPayTableText db "Êëàññè÷åñêèé ñëîò 3x3. Âûèãðûøíàÿ ëèíèÿ - ñðåäíÿÿ.",13,10 + db "777 x10, $$$ x7, BAR x5, AAA x4, *** / ### x3, ïàðà x2.",13,10,0 +classicSlotJackpot db "Äæåêïîò! Òðè îäèíàêîâûõ.",13,10,0 +classicSlotPair db "Ïàðà íà ëèíèè!",13,10,0 +classicSlotEmpty db "Íå ïîâåçëî.",13,10,0 +classicSlotBorder db '+-----+-----+-----+',13,10,0 +classicSlotPayline db '----- WIN LINE -----',13,10,0 +; === MCI-êîìàíäû çâóêîâûõ ôàéëîâ === +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 +slotBorder db '+-----+-----+-----+-----+-----+',13,10,0 +slotWall db '|',0 +slotWinLeft db '>',0 +slotWinRight db '<',0 +slotCellBlank db ' ',0 +slotPadTwo db ' ',0 +slotPadOne db ' ',0 +skullSeg1 db 020h, 020h, 020h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 084h, 020h, 020h, 020h, 020h, 020h, 020h, 0 +skullSeg2 db 020h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 088h, 0E2h, 096h, 080h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 084h, 020h, 0E2h, 096h, 080h, 0E2h, 096h, 088h, 0E2h, 096h, 084h, 020h, 020h, 020h, 020h, 0 +skullSeg3 db 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 0 +skullSeg4 db 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 080h, 020h, 020h, 0E2h, 096h, 080h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 0 +skullSeg5 db 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 084h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 0 +skullSeg6 db 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 0E2h, 096h, 080h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 080h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 020h, 0 +skullSeg7 db 020h, 020h, 020h, 0E2h, 096h, 080h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 080h, 020h, 020h, 020h, 020h, 020h, 0 +skullSeg8 db 020h, 020h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 020h, 020h, 020h, 020h, 0 +skullNums db " [1] [2] [3]",13,10,0 +skullBlankBall db 13,10,13,10,13,10,0 +skullBall1 db " .***.",13,10," (* O *)",13,10," `***'",13,10,0 +skullBall2 db " .***.",13,10," (* O *)",13,10," `***'",13,10,0 +skullBall3 db " .***.",13,10," (* O *)",13,10," `***'",13,10,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 +saveExt db '.dat',0 +accountPattern db "*.dat",0 +appDataEnvName db "APPDATA",0 +appDataSubDir db "\AssemblerCasino",0 +pathSlashText db "\",0 +runtimeDir db "runtime",0 +danceFileName db "assets\animations\hakari_dance.ans",0 +casinoIntroFile db "assets\animations\casino_intro.ans",0 +dbdHookFileName db "assets\animations\dbd_hook.ans",0 +dbdHookCmd db "cmd /c start ""DBD Hook"" tools\previews\preview_dbd_hook.bat",0 +dbdHookStopFile db "runtime\dbd_hook.stop",0 +animProfileFile db "runtime\anim_profile.txt",0 +animProfileDigits db "012",0 +ansiExitIntro db 1Bh,"[0m",1Bh,"[?25h",1Bh,"[2J",1Bh,"[H",0 +accountList db 20 dup(64 dup(0)) +findData db 320 dup(0) + + +; --- Umamusume Pretty Derby Data --- +umaTitleText db 13,10,"=== UMAMUSUME PRETTY DERBY (ÑÊÀ×ÊÈ) ===",13,10,0 +umaMenuText db "Âûáåðèòå âàøó äåâ÷îíêó-ëîøàäêó:",13,10 + db "1. Special Week (Ñïåöèàë Óèê) - Êîýô. x4 (Ñáàëàíñèðîâàííàÿ)",13,10 + db "2. Silence Suzuka (Ñàéëåíñ Ñóäçóêà) - Êîýô. x3 (Ðåçâûé ñòàðò)",13,10 + db "3. Tokai Teio (Òîêàé Òýéîí) - Êîýô. x5 (Ôèíèøíûé ñïóðò)",13,10 + db "4. Gold Ship (Ãîëä Øèï) - Êîýô. x8 (Íåïðåäñêàçóåìàÿ!)",13,10 + db "5. Mejiro McQueen (Ìýäçèðî Ìàêêóèí) - Êîýô. x6 (Ñòàéåð)",13,10,0 +umaChoiceText db "Âàø âûáîð (1-5): ",0 +umaTrackHeader db 13,10,"--- ÒÐÀÑÑÀ ÒÐÈÓÌÔÀ ---",13,10,0 +umaFinishText db " |FINISH|",13,10,0 +umaHorse1Name db "1. Special Week : ",0 +umaHorse2Name db "2. Silence Suzuka : ",0 +umaHorse3Name db "3. Tokai Teio : ",0 +umaHorse4Name db "4. Gold Ship : ",0 +umaHorse5Name db "5. Mejiro McQueen : ",0 +umaWinAnnouncement db 13,10,"Ïîáåäèòåëü ñêà÷åê: ",0 +umaYouWinText db " ÏÎÁÅÄÀ! Âàø âûáîð ïðèøåë ïåðâûì! Âû âûèãðàëè $",0 +umaYouLoseText db " Óâû, âàø âûáîð íå çàíÿë 1-å ìåñòî. Óäà÷à óëûáíåòñÿ â ñëåäóþùèé ðàç!",13,10,0 +umaStepChar db "=",0 +umaHeadChar db ">",0 +umaHorseNames dd OFFSET umaHorse1Name, OFFSET umaHorse2Name, OFFSET umaHorse3Name, OFFSET umaHorse4Name, OFFSET umaHorse5Name +umaMultipliers dd 4, 3, 5, 8, 6 + +umaPos dd 5 dup(0) +umaChoice dd 0 +umaWinner dd 0 + +.code +; --- PrintStr: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +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: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +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: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +SetColor PROC attr:DWORD + invoke SetConsoleTextAttribute, hOut, attr + ret +SetColor ENDP + +; --- ResetColor: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +ResetColor PROC + invoke SetConsoleTextAttribute, hOut, COLOR_DEFAULT + ret +ResetColor ENDP + +; --- EnableAnsi: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +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 + +; --- SetSuitColor: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +SetSuitColor PROC suitIndex:DWORD + mov eax, suitIndex + cmp eax, 1 + je set_red_suit + cmp eax, 3 + je set_red_suit + invoke SetColor, COLOR_CARD + ret +set_red_suit: + invoke SetColor, COLOR_RED_CARD + ret +SetSuitColor ENDP + +; --- SetCardBackColor: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +SetCardBackColor PROC + mov eax, shopBackStyle + cmp eax, 1 + je card_back_blue + cmp eax, 2 + je card_back_red + cmp eax, 3 + je card_back_gold + cmp eax, 4 + je card_back_skull + cmp eax, 5 + je card_back_clover + cmp eax, 6 + je card_back_arcane + cmp eax, 7 + je card_back_noir + cmp eax, 8 + je card_back_diamond + cmp eax, 9 + je card_back_rider + cmp eax, 10 + je card_back_bee + cmp eax, 11 + je card_back_fan + cmp eax, 12 + je card_back_web + invoke SetColor, COLOR_BACK_CARD + ret +card_back_blue: + invoke SetColor, COLOR_TITLE + ret +card_back_red: + invoke SetColor, COLOR_BAD + ret +card_back_gold: + invoke SetColor, COLOR_WARN + ret +card_back_skull: + invoke SetColor, COLOR_BAD + ret +card_back_clover: + invoke SetColor, COLOR_MONEY + ret +card_back_arcane: + invoke SetColor, COLOR_TITLE + ret +card_back_noir: + invoke SetColor, COLOR_CARD + ret +card_back_diamond: + invoke SetColor, COLOR_TITLE + ret +card_back_rider: + invoke SetColor, COLOR_WARN + ret +card_back_bee: + invoke SetColor, COLOR_WARN + ret +card_back_fan: + invoke SetColor, COLOR_TITLE + ret +card_back_web: + invoke SetColor, COLOR_CARD + ret +SetCardBackColor ENDP +; --- PrintCardBackSegLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCardBackSegLine PROC lineNo:DWORD + mov eax, shopBackStyle + cmp eax, 1 + je back_line_blue + cmp eax, 2 + je back_line_red + cmp eax, 3 + je back_line_gold + cmp eax, 4 + je back_line_skull + cmp eax, 5 + je back_line_clover + cmp eax, 6 + je back_line_arcane + cmp eax, 7 + je back_line_noir + cmp eax, 8 + je back_line_diamond + cmp eax, 9 + je back_line_rider + cmp eax, 10 + je back_line_bee + cmp eax, 11 + je back_line_fan + cmp eax, 12 + je back_line_web +back_line_gray: + mov eax, lineNo + cmp eax, 1 + je back_gray_1 + cmp eax, 2 + je back_gray_2 + cmp eax, 3 + je back_gray_3 + cmp eax, 4 + je back_gray_4 + invoke PrintUtf8, OFFSET backGray5 + ret +back_gray_1: + invoke PrintUtf8, OFFSET backGray1 + ret +back_gray_2: + invoke PrintUtf8, OFFSET backGray2 + ret +back_gray_3: + invoke PrintUtf8, OFFSET backGray3 + ret +back_gray_4: + invoke PrintUtf8, OFFSET backGray4 + ret +back_line_blue: + mov eax, lineNo + cmp eax, 1 + je back_blue_1 + cmp eax, 2 + je back_blue_2 + cmp eax, 3 + je back_blue_3 + cmp eax, 4 + je back_blue_4 + invoke PrintUtf8, OFFSET backBlue5 + ret +back_blue_1: + invoke PrintUtf8, OFFSET backBlue1 + ret +back_blue_2: + invoke PrintUtf8, OFFSET backBlue2 + ret +back_blue_3: + invoke PrintUtf8, OFFSET backBlue3 + ret +back_blue_4: + invoke PrintUtf8, OFFSET backBlue4 + ret +back_line_red: + mov eax, lineNo + cmp eax, 1 + je back_red_1 + cmp eax, 2 + je back_red_2 + cmp eax, 3 + je back_red_3 + cmp eax, 4 + je back_red_4 + invoke PrintUtf8, OFFSET backRed5 + ret +back_red_1: + invoke PrintUtf8, OFFSET backRed1 + ret +back_red_2: + invoke PrintUtf8, OFFSET backRed2 + ret +back_red_3: + invoke PrintUtf8, OFFSET backRed3 + ret +back_red_4: + invoke PrintUtf8, OFFSET backRed4 + ret +back_line_gold: + mov eax, lineNo + cmp eax, 1 + je back_gold_1 + cmp eax, 2 + je back_gold_2 + cmp eax, 3 + je back_gold_3 + cmp eax, 4 + je back_gold_4 + invoke PrintUtf8, OFFSET backGold5 + ret +back_gold_1: + invoke PrintUtf8, OFFSET backGold1 + ret +back_gold_2: + invoke PrintUtf8, OFFSET backGold2 + ret +back_gold_3: + invoke PrintUtf8, OFFSET backGold3 + ret +back_gold_4: + invoke PrintUtf8, OFFSET backGold4 + ret +back_line_skull: + mov eax, lineNo + cmp eax, 1 + je back_skull_1 + cmp eax, 2 + je back_skull_2 + cmp eax, 3 + je back_skull_3 + cmp eax, 4 + je back_skull_4 + invoke PrintUtf8, OFFSET backSkull5 + ret +back_skull_1: + invoke PrintUtf8, OFFSET backSkull1 + ret +back_skull_2: + invoke PrintUtf8, OFFSET backSkull2 + ret +back_skull_3: + invoke PrintUtf8, OFFSET backSkull3 + ret +back_skull_4: + invoke PrintUtf8, OFFSET backSkull4 + ret +back_line_clover: + mov eax, lineNo + cmp eax, 1 + je back_clover_1 + cmp eax, 2 + je back_clover_2 + cmp eax, 3 + je back_clover_3 + cmp eax, 4 + je back_clover_4 + invoke PrintUtf8, OFFSET backClover5 + ret +back_clover_1: + invoke PrintUtf8, OFFSET backClover1 + ret +back_clover_2: + invoke PrintUtf8, OFFSET backClover2 + ret +back_clover_3: + invoke PrintUtf8, OFFSET backClover3 + ret +back_clover_4: + invoke PrintUtf8, OFFSET backClover4 + ret +back_line_arcane: + mov eax, lineNo + cmp eax, 1 + je back_arcane_1 + cmp eax, 2 + je back_arcane_2 + cmp eax, 3 + je back_arcane_3 + cmp eax, 4 + je back_arcane_4 + invoke PrintUtf8, OFFSET backArcane5 + ret +back_arcane_1: + invoke PrintUtf8, OFFSET backArcane1 + ret +back_arcane_2: + invoke PrintUtf8, OFFSET backArcane2 + ret +back_arcane_3: + invoke PrintUtf8, OFFSET backArcane3 + ret +back_arcane_4: + invoke PrintUtf8, OFFSET backArcane4 + ret +back_line_noir: + mov eax, lineNo + cmp eax, 1 + je back_noir_1 + cmp eax, 2 + je back_noir_2 + cmp eax, 3 + je back_noir_3 + cmp eax, 4 + je back_noir_4 + invoke PrintUtf8, OFFSET backNoir5 + ret +back_noir_1: + invoke PrintUtf8, OFFSET backNoir1 + ret +back_noir_2: + invoke PrintUtf8, OFFSET backNoir2 + ret +back_noir_3: + invoke PrintUtf8, OFFSET backNoir3 + ret +back_noir_4: + invoke PrintUtf8, OFFSET backNoir4 + ret +back_line_diamond: + mov eax, lineNo + cmp eax, 1 + je back_diamond_1 + cmp eax, 2 + je back_diamond_2 + cmp eax, 3 + je back_diamond_3 + cmp eax, 4 + je back_diamond_4 + invoke PrintUtf8, OFFSET backDiamond5 + ret +back_diamond_1: + invoke PrintUtf8, OFFSET backDiamond1 + ret +back_diamond_2: + invoke PrintUtf8, OFFSET backDiamond2 + ret +back_diamond_3: + invoke PrintUtf8, OFFSET backDiamond3 + ret +back_diamond_4: + invoke PrintUtf8, OFFSET backDiamond4 + ret +back_line_rider: + mov eax, lineNo + cmp eax, 1 + je back_rider_1 + cmp eax, 2 + je back_rider_2 + cmp eax, 3 + je back_rider_3 + cmp eax, 4 + je back_rider_4 + invoke PrintUtf8, OFFSET backRider5 + ret +back_rider_1: + invoke PrintUtf8, OFFSET backRider1 + ret +back_rider_2: + invoke PrintUtf8, OFFSET backRider2 + ret +back_rider_3: + invoke PrintUtf8, OFFSET backRider3 + ret +back_rider_4: + invoke PrintUtf8, OFFSET backRider4 + ret +back_line_bee: + mov eax, lineNo + cmp eax, 1 + je back_bee_1 + cmp eax, 2 + je back_bee_2 + cmp eax, 3 + je back_bee_3 + cmp eax, 4 + je back_bee_4 + invoke PrintUtf8, OFFSET backBee5 + ret +back_bee_1: + invoke PrintUtf8, OFFSET backBee1 + ret +back_bee_2: + invoke PrintUtf8, OFFSET backBee2 + ret +back_bee_3: + invoke PrintUtf8, OFFSET backBee3 + ret +back_bee_4: + invoke PrintUtf8, OFFSET backBee4 + ret +back_line_fan: + mov eax, lineNo + cmp eax, 1 + je back_fan_1 + cmp eax, 2 + je back_fan_2 + cmp eax, 3 + je back_fan_3 + cmp eax, 4 + je back_fan_4 + invoke PrintUtf8, OFFSET backFan5 + ret +back_fan_1: + invoke PrintUtf8, OFFSET backFan1 + ret +back_fan_2: + invoke PrintUtf8, OFFSET backFan2 + ret +back_fan_3: + invoke PrintUtf8, OFFSET backFan3 + ret +back_fan_4: + invoke PrintUtf8, OFFSET backFan4 + ret +back_line_web: + mov eax, lineNo + cmp eax, 1 + je back_web_1 + cmp eax, 2 + je back_web_2 + cmp eax, 3 + je back_web_3 + cmp eax, 4 + je back_web_4 + invoke PrintUtf8, OFFSET backWeb5 + ret +back_web_1: + invoke PrintUtf8, OFFSET backWeb1 + ret +back_web_2: + invoke PrintUtf8, OFFSET backWeb2 + ret +back_web_3: + invoke PrintUtf8, OFFSET backWeb3 + ret +back_web_4: + invoke PrintUtf8, OFFSET backWeb4 + ret +PrintCardBackSegLine ENDP + +; --- PrintCardBackSeg: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCardBackSeg PROC + invoke PrintCardBackSegLine, 3 + ret +PrintCardBackSeg ENDP + +; --- PrintSuit: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSuit PROC uses eax, suitIndex:DWORD + invoke SetSuitColor, suitIndex + mov eax, suitIndex + invoke PrintUtf8, suits[eax * 4] + call ResetColor + ret +PrintSuit ENDP + +; --- PrintMoney: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintMoney PROC value:DWORD + invoke SetColor, COLOR_MONEY + invoke PrintUInt, value + call ResetColor + ret +PrintMoney ENDP + +; --- PrintTitleColor: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintTitleColor PROC pText:DWORD + invoke SetColor, COLOR_TITLE + invoke PrintStr, pText + call ResetColor + ret +PrintTitleColor ENDP + +; --- ColorPrint: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +ColorPrint PROC pText:DWORD, attr:DWORD + invoke SetColor, attr + invoke PrintStr, pText + call ResetColor + ret +ColorPrint ENDP + +; --- PrintWinEvent: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintWinEvent PROC + invoke ColorPrint, OFFSET winText, COLOR_MONEY + ret +PrintWinEvent ENDP + +; --- PrintLoseEvent: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintLoseEvent PROC + invoke ColorPrint, OFFSET loseText, COLOR_BAD + ret +PrintLoseEvent ENDP + +; --- PrintDrawEvent: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintDrawEvent PROC + invoke ColorPrint, OFFSET drawText, COLOR_WARN + ret +PrintDrawEvent ENDP + +; --- PrintCroupierFromList: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCroupierFromList PROC uses eax ebx, pList:DWORD + invoke RandomRange, 3 + shl eax, 2 + mov ebx, pList + add ebx, eax + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET croupierPrefix + invoke PrintStr, DWORD PTR [ebx] + call ResetColor + ret +PrintCroupierFromList ENDP + +; --- DealerProcessLine: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +DealerProcessLine PROC uses eax edx + mov eax, dealerLineLen + cmp eax, 3 + jb dealer_process_done + mov al, byte ptr [frameBuffer] + cmp al, dealerWantedTag + jne dealer_process_done + cmp byte ptr [frameBuffer+1], '|' + jne dealer_process_done + cmp dealerScanMode, 0 + jne dealer_process_select + inc dealerPhraseCount + ret + +dealer_process_select: + mov eax, dealerPhraseCount + cmp eax, dealerPhrasePick + jne dealer_process_next + mov eax, OFFSET frameBuffer + add eax, dealerLineLen + mov byte ptr [eax], 0 + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET croupierPrefix + mov edx, OFFSET frameBuffer + add edx, 2 + invoke PrintStr, edx + invoke PrintStr, OFFSET nl + call ResetColor + mov dealerPhrasePick, 0FFFFFFFFh +dealer_process_next: + inc dealerPhraseCount +dealer_process_done: + ret +DealerProcessLine ENDP + +; --- DealerScanFile: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +DealerScanFile PROC uses eax edx, mode:DWORD + mov eax, mode + mov dealerScanMode, eax + mov dealerLineLen, 0 + invoke CreateFileA, OFFSET dealerFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + jne dealer_scan_opened + xor eax, eax + ret + +dealer_scan_opened: + mov dealerFileHandle, eax + +dealer_scan_loop: + invoke ReadFile, dealerFileHandle, ADDR inputBuffer, 1, ADDR charsRead, 0 + cmp charsRead, 0 + je dealer_scan_eof + mov al, byte ptr inputBuffer + cmp al, 13 + je dealer_scan_loop + cmp al, 10 + je dealer_scan_line_end + mov edx, dealerLineLen + cmp edx, 32760 + jae dealer_scan_loop + mov byte ptr [frameBuffer + edx], al + inc dealerLineLen + jmp dealer_scan_loop + +dealer_scan_line_end: + call DealerProcessLine + mov dealerLineLen, 0 + jmp dealer_scan_loop + +dealer_scan_eof: + cmp dealerLineLen, 0 + je dealer_scan_close + call DealerProcessLine + +dealer_scan_close: + invoke CloseHandle, dealerFileHandle + mov eax, 1 + ret +DealerScanFile ENDP + +; --- PrintCroupierFromFile: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCroupierFromFile PROC uses eax, wanted:DWORD, pFallback:DWORD + mov eax, wanted + mov dealerWantedTag, al + mov dealerPhraseCount, 0 + invoke DealerScanFile, 0 + cmp eax, 0 + je croupier_file_fallback + cmp dealerPhraseCount, 0 + je croupier_file_fallback + invoke RandomRange, dealerPhraseCount + mov dealerPhrasePick, eax + mov dealerPhraseCount, 0 + invoke DealerScanFile, 1 + ret +croupier_file_fallback: + invoke PrintCroupierFromList, pFallback + ret +PrintCroupierFromFile ENDP + +; --- PrintCroupierWin: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCroupierWin PROC + invoke PrintCroupierFromFile, 'W', OFFSET croupierWinList + ret +PrintCroupierWin ENDP + +; --- PrintCroupierLose: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCroupierLose PROC + invoke PrintCroupierFromFile, 'L', OFFSET croupierLoseList + ret +PrintCroupierLose ENDP + +; --- PrintCroupierDraw: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCroupierDraw PROC + invoke PrintCroupierFromFile, 'D', OFFSET croupierDrawList + ret +PrintCroupierDraw ENDP + +; --- FlushFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +FlushFrame PROC uses eax ebx ecx edx esi edi + LOCAL csbi[22]:BYTE + LOCAL X_start:DWORD + LOCAL Y_start:DWORD + LOCAL nextLinePtr:DWORD + LOCAL currentLineIndex:DWORD + + cmp frameBytes, 0 + je flush_frame_done + + mov eax, OFFSET frameBuffer + add eax, frameBytes + mov byte ptr [eax], 0 + + cmp animWidth, 0 + je print_default + cmp animHeight, 0 + je print_default + + call ClearView + + lea eax, csbi + invoke GetConsoleScreenBufferInfo, hOut, eax + cmp eax, 0 + je print_default + + movzx ecx, word ptr csbi[14] + movzx esi, word ptr csbi[10] + sub ecx, esi + inc ecx + + movzx edx, word ptr csbi[16] + movzx esi, word ptr csbi[12] + sub edx, esi + inc edx + + mov eax, ecx + cmp eax, animWidth + jbe set_x_left + sub eax, animWidth + shr eax, 1 + add ax, word ptr csbi[10] + movzx eax, ax + mov X_start, eax + jmp x_calculated +set_x_left: + movzx eax, word ptr csbi[10] + mov X_start, eax +x_calculated: + + mov eax, edx + cmp eax, animHeight + jbe set_y_top + sub eax, animHeight + shr eax, 1 + add ax, word ptr csbi[12] + movzx eax, ax + mov Y_start, eax + jmp y_calculated +set_y_top: + movzx eax, word ptr csbi[12] + mov Y_start, eax +y_calculated: + + mov esi, OFFSET frameBuffer +skip_lead_loop: + cmp byte ptr [esi], 1Bh + jne check_lead_newline + cmp byte ptr [esi+1], '[' + jne check_lead_newline + + cmp byte ptr [esi+2], '2' + jne check_lead_H + cmp byte ptr [esi+3], 'J' + jne check_lead_newline + add esi, 4 + jmp skip_lead_loop + +check_lead_H: + cmp byte ptr [esi+2], 'H' + jne check_lead_hide + add esi, 3 + jmp skip_lead_loop + +check_lead_hide: + cmp byte ptr [esi+2], '?' + jne check_lead_newline + cmp byte ptr [esi+3], '2' + jne check_lead_newline + cmp byte ptr [esi+4], '5' + jne check_lead_newline + cmp byte ptr [esi+5], 'l' + jne check_lead_show + add esi, 6 + jmp skip_lead_loop + +check_lead_show: + cmp byte ptr [esi+5], 'h' + jne check_lead_newline + add esi, 6 + jmp skip_lead_loop + +check_lead_newline: + mov al, [esi] + cmp al, 0Dh + je skip_lead_nl_char + cmp al, 0Ah + je skip_lead_nl_char + jmp done_lead_skipping +skip_lead_nl_char: + inc esi + jmp skip_lead_loop +done_lead_skipping: + + mov currentLineIndex, 0 +line_parse_loop: + cmp byte ptr [esi], 0 + je print_done + + mov edi, esi +find_line_end: + mov al, [edi] + cmp al, 0 + je line_end_found + cmp al, 0Dh + je line_end_found + cmp al, 0Ah + je line_end_found + inc edi + jmp find_line_end +line_end_found: + mov dl, [edi] + mov byte ptr [edi], 0 + + mov ebx, edi + cmp dl, 0 + je next_line_ptr_done + inc ebx + mov al, [ebx] + cmp al, 0Dh + je skip_nl_chars + cmp al, 0Ah + je skip_nl_chars + jmp next_line_ptr_done +skip_nl_chars: + inc ebx + mov al, [ebx] + cmp al, 0Dh + je skip_nl_chars + cmp al, 0Ah + je skip_nl_chars +next_line_ptr_done: + mov nextLinePtr, ebx + + mov eax, currentLineIndex + add eax, Y_start + + movzx edx, word ptr csbi[16] + cmp eax, edx + jg skip_this_line + + invoke MoveCursor, X_start, eax + invoke PrintUtf8, esi + +skip_this_line: + mov esi, nextLinePtr + inc currentLineIndex + jmp line_parse_loop + +print_default: + invoke PrintUtf8, OFFSET frameBuffer + +print_done: + mov frameBytes, 0 +flush_frame_done: + ret +FlushFrame ENDP + +; --- PlayHakariDance: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayHakariDance PROC uses eax ebx ecx edx esi edi + mov animWidth, 118 + mov animHeight, 43 + invoke CreateFileA, OFFSET danceFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + jne hakari_file_ok + invoke mciSendStringA, OFFSET hakariSoundStop, 0, 0, 0 + mov animWidth, 0 + mov animHeight, 0 + ret +hakari_file_ok: + mov danceHandle, eax + mov frameBytes, 0 + mov animFrameCounter, 0 + +hakari_read_loop: + invoke ReadFile, danceHandle, ADDR inputBuffer, 1, ADDR danceBytes, 0 + cmp danceBytes, 0 + je hakari_finish + mov al, byte ptr inputBuffer + cmp al, 0Ch + je hakari_show_frame + mov edx, frameBytes + cmp edx, 32760 + jae hakari_show_frame_keep_char + mov [frameBuffer + edx], al + inc frameBytes + jmp hakari_read_loop + +hakari_show_frame_keep_char: + call ClearView + call FlushFrame + invoke AnimFrameDelay, 12 + invoke Sleep, eax + mov al, byte ptr inputBuffer + mov [frameBuffer], al + mov frameBytes, 1 + jmp hakari_read_loop + +hakari_show_frame: + call AnimShouldDrawFrame + cmp eax, 1 + jne hakari_skip_frame + call ClearView + call FlushFrame + invoke AnimFrameDelay, 12 + invoke Sleep, eax + jmp hakari_read_loop +hakari_skip_frame: + mov frameBytes, 0 + jmp hakari_read_loop + +hakari_finish: + call ClearView + call FlushFrame + invoke CloseHandle, danceHandle + invoke mciSendStringA, OFFSET hakariSoundStop, 0, 0, 0 + invoke Sleep, 40 + call ClearView + mov animWidth, 0 + mov animHeight, 0 + ret +PlayHakariDance ENDP + +; --- WriteAnimProfileFile: shares animation profile with helper windows --- +WriteAnimProfileFile PROC uses eax ebx edx + invoke CreateFileA, OFFSET animProfileFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + je write_anim_profile_done + mov ebx, eax + mov edx, settingsLowSpec + cmp edx, 2 + jbe write_anim_profile_value_ok + xor edx, edx +write_anim_profile_value_ok: + mov al, byte ptr [animProfileDigits + edx] + mov byte ptr [inputBuffer], al + invoke WriteFile, ebx, ADDR inputBuffer, 1, ADDR charsWritten, 0 + invoke CloseHandle, ebx +write_anim_profile_done: + ret +WriteAnimProfileFile ENDP +; --- PlayDbDHookScene: ïîêàäðîâàÿ àíèìàöèÿ êðþêà èç Dead by Daylight --- +PlayDbDHookScene PROC uses eax + cmp settingsDbdWindowEnabled, 1 + jne play_dbd_done + invoke WinExec, OFFSET dbdHookCmd, 1 +play_dbd_done: + ret +PlayDbDHookScene ENDP + +; --- StopDbDHookScene: çàêðûâàåò îòäåëüíîå îêíî DBD-àíèìàöèè ÷åðåç ôàéë-ñèãíàë --- +StopDbDHookScene PROC uses eax + invoke CreateFileA, OFFSET dbdHookStopFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + je stop_dbd_done + invoke CloseHandle, eax +stop_dbd_done: + ret +StopDbDHookScene ENDP + +; --- IntroMaybeLoopMarker: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +IntroMaybeLoopMarker PROC + cmp frameBytes, 10 + jne intro_marker_no + cmp byte ptr [frameBuffer], '@' + jne intro_marker_no + cmp byte ptr [frameBuffer+1], '@' + jne intro_marker_no + cmp byte ptr [frameBuffer+2], 'L' + jne intro_marker_no + cmp byte ptr [frameBuffer+3], 'O' + jne intro_marker_no + cmp byte ptr [frameBuffer+4], 'O' + jne intro_marker_no + cmp byte ptr [frameBuffer+5], 'P' + jne intro_marker_no + cmp byte ptr [frameBuffer+6], '@' + jne intro_marker_no + cmp byte ptr [frameBuffer+7], '@' + jne intro_marker_no + mov introLoopSeen, 1 + mov introSkipLoop, 0 + mov frameBytes, 0 + mov eax, 1 + ret +intro_marker_no: + xor eax, eax + ret +IntroMaybeLoopMarker ENDP + +; --- IntroHandleFrameEnd: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +IntroHandleFrameEnd PROC + call IntroMaybeLoopMarker + cmp eax, 1 + je intro_handle_done + cmp introSkipLoop, 1 + je intro_discard_frame + call AnimShouldDrawFrame + cmp eax, 1 + jne intro_discard_frame + call FlushFrame + invoke AnimFrameDelay, 45 + invoke Sleep, eax + ret +intro_discard_frame: + mov frameBytes, 0 +intro_handle_done: + ret +IntroHandleFrameEnd ENDP + +; --- PlayCasinoIntro: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayCasinoIntro PROC uses eax ebx ecx edx esi edi + cmp settingsIntroEnabled, 1 + jne intro_disabled + mov introLoopSeen, 0 + mov introSkipLoop, 0 + mov animFrameCounter, 0 + mov animWidth, 64 + mov animHeight, 21 +intro_restart_file: + invoke CreateFileA, OFFSET casinoIntroFile, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + jne intro_file_ok + mov animWidth, 0 + mov animHeight, 0 + ret +intro_file_ok: + mov danceHandle, eax + mov frameBytes, 0 + +intro_read_loop: + invoke GetAsyncKeyState, VK_RETURN + test ax, 8000h + jnz intro_exit + invoke ReadFile, danceHandle, ADDR inputBuffer, 1, ADDR danceBytes, 0 + cmp danceBytes, 0 + je intro_restart_cycle + mov al, byte ptr inputBuffer + cmp al, 0Ch + je intro_show_frame + mov edx, frameBytes + cmp edx, 32760 + jae intro_show_frame_keep_char + mov [frameBuffer + edx], al + inc frameBytes + jmp intro_read_loop + +intro_show_frame_keep_char: + call IntroHandleFrameEnd + mov al, byte ptr inputBuffer + mov [frameBuffer], al + mov frameBytes, 1 + jmp intro_read_loop + +intro_show_frame: + call IntroHandleFrameEnd + jmp intro_read_loop + +intro_restart_cycle: + call FlushFrame + invoke CloseHandle, danceHandle + cmp introLoopSeen, 1 + jne intro_restart_file + mov introSkipLoop, 1 + jmp intro_restart_file + +intro_exit: + invoke CloseHandle, danceHandle + invoke PrintUtf8, OFFSET ansiExitIntro + invoke Sleep, 180 +intro_disabled: + mov animWidth, 0 + mov animHeight, 0 + ret +PlayCasinoIntro ENDP +; --- InitSounds: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +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: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +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: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlaySlotSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET slotSoundStop, 0, 0, 0 + invoke mciSendStringA, OFFSET slotSoundPlay, 0, 0, 0 + ret +PlaySlotSound ENDP + +; --- PlaySlotIntroSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlaySlotIntroSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET slotIntroStop, 0, 0, 0 + invoke mciSendStringA, OFFSET slotIntroPlay, 0, 0, 0 + ret +PlaySlotIntroSound ENDP + +; --- PlayJackpotSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayJackpotSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET jackpotStop, 0, 0, 0 + invoke mciSendStringA, OFFSET jackpotPlay, 0, 0, 0 + ret +PlayJackpotSound ENDP + +; --- PlayHakariSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayHakariSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET hakariSoundStop, 0, 0, 0 + invoke mciSendStringA, OFFSET hakariSoundPlay, 0, 0, 0 + ret +PlayHakariSound ENDP + +; --- PlayCoinSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayCoinSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET coinSoundStop, 0, 0, 0 + invoke mciSendStringA, OFFSET coinSoundPlay, 0, 0, 0 + ret +PlayCoinSound ENDP + +; --- PlayBankruptSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayBankruptSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET bankruptStop, 0, 0, 0 + invoke mciSendStringA, OFFSET bankruptPlay, 0, 0, 0 + ret +PlayBankruptSound ENDP + +; --- PlayVictorySound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayVictorySound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET victoryStop, 0, 0, 0 + invoke mciSendStringA, OFFSET victoryPlay, 0, 0, 0 + ret +PlayVictorySound ENDP + +; --- PlayCasinoRouletteSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayCasinoRouletteSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET casinoRouletteSoundStop, 0, 0, 0 + invoke mciSendStringA, OFFSET casinoRouletteSoundPlay, 0, 0, 0 + ret +PlayCasinoRouletteSound ENDP +; --- PlayRouletteSpinSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayRouletteSpinSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET rrSpinStop, 0, 0, 0 + invoke mciSendStringA, OFFSET rrSpinPlay, 0, 0, 0 + ret +PlayRouletteSpinSound ENDP + +; --- PlayRouletteDrySound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayRouletteDrySound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET rrDryStop, 0, 0, 0 + invoke mciSendStringA, OFFSET rrDryPlay, 0, 0, 0 + ret +PlayRouletteDrySound ENDP + +; --- PlayRouletteShotSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayRouletteShotSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET rrShotStop, 0, 0, 0 + invoke mciSendStringA, OFFSET rrShotPlay, 0, 0, 0 + ret +PlayRouletteShotSound ENDP + +; --- PlayStoneSound: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayStoneSound PROC uses eax ecx edx + invoke mciSendStringA, OFFSET stoneSoundStop, 0, 0, 0 + invoke mciSendStringA, OFFSET stoneSoundPlay, 0, 0, 0 + ret +PlayStoneSound ENDP + +; --- StopTowerMusic: ìóçûêà òóðíèð-áàøíè --- +StopTowerMusic PROC + invoke mciSendStringA, OFFSET towerMusicStop, 0, 0, 0 + invoke mciSendStringA, OFFSET towerMusicClose, 0, 0, 0 + ret +StopTowerMusic ENDP + +; --- PlayTowerRandomMusic: ñëó÷àéíàÿ ìóçûêà òóðíèð-áàøíè --- +PlayTowerRandomMusic PROC uses eax + call StopTowerMusic + invoke RandomRange, 4 + cmp eax, 0 + je tower_music_1 + cmp eax, 1 + je tower_music_2 + cmp eax, 2 + je tower_music_3 +tower_music_4: + invoke mciSendStringA, OFFSET towerMusicOpen4, 0, 0, 0 + jmp tower_music_play +tower_music_1: + invoke mciSendStringA, OFFSET towerMusicOpen1, 0, 0, 0 + jmp tower_music_play +tower_music_2: + invoke mciSendStringA, OFFSET towerMusicOpen2, 0, 0, 0 + jmp tower_music_play +tower_music_3: + invoke mciSendStringA, OFFSET towerMusicOpen3, 0, 0, 0 +tower_music_play: + invoke mciSendStringA, OFFSET towerMusicPlay, 0, 0, 0 + ret +PlayTowerRandomMusic ENDP + +; --- PrintSlotCell: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSlotCell PROC uses eax ebx ecx, value:DWORD + invoke PrintStr, OFFSET slotWall + mov eax, slotCurrentCell + mov ebx, 1 + mov ecx, eax + shl ebx, cl + mov eax, slotWinMask + test eax, ebx + je slot_cell_normal + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET slotWinLeft + invoke PrintSlotSymbol, value + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET slotWinRight + call ResetColor + ret +slot_cell_normal: + invoke PrintStr, OFFSET slotPadOne + invoke PrintSlotSymbol, value + invoke PrintStr, OFFSET slotPadOne + ret +PrintSlotCell ENDP +; --- PrintSlotBlankCell: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSlotBlankCell PROC + invoke PrintStr, OFFSET slotWall + invoke PrintStr, OFFSET slotCellBlank + ret +PrintSlotBlankCell ENDP + +; --- PrintSlotPaddingRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSlotPaddingRow PROC + call PrintSlotBlankCell + call PrintSlotBlankCell + call PrintSlotBlankCell + call PrintSlotBlankCell + call PrintSlotBlankCell + invoke PrintStr, OFFSET slotWall + invoke PrintStr, OFFSET nl + ret +PrintSlotPaddingRow ENDP +; --- PrintSlotWindow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSlotWindow PROC uses eax ebx + call ClearView + invoke PrintTitleColor, OFFSET slotTitle + invoke PrintStr, OFFSET slotBorder + + mov rowIndex, 0 +slot_window_row_loop: + cmp rowIndex, 3 + jae slot_window_done + call PrintSlotPaddingRow + mov ebx, rowIndex + imul ebx, 5 + + cmp slotVisible, 1 + jb slot_blank_col1 + mov slotCurrentCell, ebx + invoke PrintSlotCell, slotGrid[ebx * 4] + jmp slot_col2 +slot_blank_col1: + call PrintSlotBlankCell + +slot_col2: + cmp slotVisible, 2 + jb slot_blank_col2 + mov eax, ebx + inc eax + mov slotCurrentCell, eax + invoke PrintSlotCell, slotGrid[eax * 4] + jmp slot_col3 +slot_blank_col2: + call PrintSlotBlankCell + +slot_col3: + cmp slotVisible, 3 + jb slot_blank_col3 + mov eax, ebx + add eax, 2 + mov slotCurrentCell, eax + invoke PrintSlotCell, slotGrid[eax * 4] + jmp slot_col4 +slot_blank_col3: + call PrintSlotBlankCell + +slot_col4: + cmp slotVisible, 4 + jb slot_blank_col4 + mov eax, ebx + add eax, 3 + mov slotCurrentCell, eax + invoke PrintSlotCell, slotGrid[eax * 4] + jmp slot_col5 +slot_blank_col4: + call PrintSlotBlankCell + +slot_col5: + cmp slotVisible, 5 + jb slot_blank_col5 + mov eax, ebx + add eax, 4 + mov slotCurrentCell, eax + invoke PrintSlotCell, slotGrid[eax * 4] + jmp slot_row_end +slot_blank_col5: + call PrintSlotBlankCell + +slot_row_end: + invoke PrintStr, OFFSET slotWall + invoke PrintStr, OFFSET nl + call PrintSlotPaddingRow + invoke PrintStr, OFFSET slotBorder + inc rowIndex + jmp slot_window_row_loop + +slot_window_done: + ret +PrintSlotWindow ENDP + +; --- FillSlotColumn: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +FillSlotColumn PROC uses eax ebx, column:DWORD + mov ebx, column + invoke RandomRange, 7 + mov slotGrid[ebx * 4], eax + mov ebx, column + add ebx, 5 + invoke RandomRange, 7 + mov slotGrid[ebx * 4], eax + mov ebx, column + add ebx, 10 + invoke RandomRange, 7 + mov slotGrid[ebx * 4], eax + ret +FillSlotColumn ENDP +; --- PrintUInt: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +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: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- +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 + +; --- ReadAnyKey: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- +ReadAnyKey PROC +read_any_again: + invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 + cmp charsRead, 0 + je read_any_empty + movzx eax, byte ptr inputBuffer + ret +read_any_empty: + xor eax, eax + ret +ReadAnyKey ENDP + +; --- ReadUInt: ââîä ÷èñëà îäíîé ñòðîêîé, áåç çàâèñàíèÿ íà CR/LF --- +ReadUInt PROC uses ebx ecx edx esi edi + xor ebx, ebx ; parsed number + xor edi, edi ; digit count + invoke ReadFile, hIn, ADDR inputBuffer, 31, ADDR charsRead, 0 + cmp charsRead, 0 + je read_uint_zero + + mov esi, OFFSET inputBuffer + mov ecx, charsRead +read_uint_parse_loop: + cmp ecx, 0 + je read_uint_end + movzx eax, byte ptr [esi] + inc esi + dec ecx + cmp al, 13 + je read_uint_end + cmp al, 10 + je read_uint_end + cmp al, ' ' + je read_uint_parse_loop + cmp al, 9 + je read_uint_parse_loop + cmp al, '0' + jb read_uint_bad + cmp al, '9' + ja read_uint_bad + + sub al, '0' + movzx edx, al + mov eax, ebx + imul eax, eax, 10 + add eax, edx + mov ebx, eax + inc edi + jmp read_uint_parse_loop + +read_uint_end: + cmp edi, 0 + je read_uint_zero + mov eax, ebx + ret + +read_uint_bad: + xor eax, eax + ret + +read_uint_zero: + xor eax, eax + ret +ReadUInt ENDP + +; --- StrEqual: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- +StrEqual PROC uses esi edi ebx, pLeft:DWORD, pRight:DWORD + mov esi, pLeft + mov edi, pRight +str_equal_loop: + mov al, [esi] + mov bl, [edi] + cmp al, bl + jne str_not_equal + cmp al, 0 + je str_is_equal + inc esi + inc edi + jmp str_equal_loop +str_is_equal: + mov eax, 1 + ret +str_not_equal: + xor eax, eax + ret +StrEqual ENDP + +; --- PrintCheatApplied: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCheatApplied PROC pText:DWORD + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET cheatAppliedText + invoke PrintStr, pText + call ResetColor + ret +PrintCheatApplied ENDP + +; --- ApplyCheatCode: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +ApplyCheatCode PROC pCode:DWORD + invoke StrEqual, pCode, OFFSET cheatCodeMoney + cmp eax, 1 + je cheat_money + invoke StrEqual, pCode, OFFSET cheatCodeSeven + cmp eax, 1 + je cheat_sevens + invoke StrEqual, pCode, OFFSET cheatCodeWin + cmp eax, 1 + je cheat_win_next + invoke StrEqual, pCode, OFFSET cheatCodeGod + cmp eax, 1 + je cheat_god + invoke StrEqual, pCode, OFFSET cheatCodeFair + cmp eax, 1 + je cheat_fair + invoke StrEqual, pCode, OFFSET cheatCodeGoal + cmp eax, 1 + je cheat_goal + invoke StrEqual, pCode, OFFSET cheatCodeReset + cmp eax, 1 + je cheat_reset + invoke StrEqual, pCode, OFFSET cheatCodeEasy + cmp eax, 1 + je cheat_easy + invoke StrEqual, pCode, OFFSET cheatCodeNormal + cmp eax, 1 + je cheat_normal + invoke StrEqual, pCode, OFFSET cheatCodeHard + cmp eax, 1 + je cheat_hard + invoke StrEqual, pCode, OFFSET cheatCodeJackpot + cmp eax, 1 + je cheat_jackpot + invoke StrEqual, pCode, OFFSET cheatCodeRich + cmp eax, 1 + je cheat_rich + invoke StrEqual, pCode, OFFSET cheatCodeDouble + cmp eax, 1 + je cheat_double + invoke StrEqual, pCode, OFFSET cheatCodePoor + cmp eax, 1 + je cheat_poor + invoke StrEqual, pCode, OFFSET cheatCodeShop + cmp eax, 1 + je cheat_shop + invoke StrEqual, pCode, OFFSET cheatCodeBacks + cmp eax, 1 + je cheat_backs + invoke StrEqual, pCode, OFFSET cheatCodeCharm + cmp eax, 1 + je cheat_max_charm + invoke StrEqual, pCode, OFFSET cheatCodeNoCharm + cmp eax, 1 + je cheat_no_charm + invoke StrEqual, pCode, OFFSET cheatCodeAch + cmp eax, 1 + je cheat_ach + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET cheatBadText + call ResetColor + xor eax, eax + ret + +cheat_money: + add bankroll, 50000 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatMoneyText + call PrintBank + call CheckVictory + mov eax, 1 + ret +cheat_sevens: + add bankroll, 7777 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatSevenText + call PrintBank + call CheckVictory + mov eax, 1 + ret +cheat_win_next: + mov cheatLuckyWin, 1 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatWinText + mov eax, 1 + ret +cheat_god: + mov cheatGodMode, 1 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatGodText + mov eax, 1 + ret +cheat_fair: + mov cheatLuckyWin, 0 + mov cheatGodMode, 0 + mov casinoSuspicion, 0 + call SaveGame + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET cheatAppliedText + invoke PrintStr, OFFSET cheatFairText + call ResetColor + mov eax, 1 + ret +cheat_goal: + mov eax, targetBank + mov bankroll, eax + call SaveGame + invoke PrintCheatApplied, OFFSET cheatGoalText + call PrintBank + call CheckVictory + mov eax, 1 + ret +cheat_reset: + mov bankroll, 10000 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatResetText + call PrintBank + mov eax, 1 + ret +cheat_easy: + mov aiDifficulty, 1 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatEasyText + mov eax, 1 + ret +cheat_normal: + mov aiDifficulty, 2 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatNormalText + mov eax, 1 + ret +cheat_hard: + mov aiDifficulty, 3 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatHardText + mov eax, 1 + ret +cheat_jackpot: + mov cheatSlotJackpot, 1 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatJackpotText + mov eax, 1 + ret +cheat_rich: + add bankroll, 250000 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatRichText + call PrintBank + call CheckVictory + mov eax, 1 + ret +cheat_double: + mov eax, bankroll + add bankroll, eax + call SaveGame + invoke PrintCheatApplied, OFFSET cheatDoubleText + call PrintBank + call CheckVictory + mov eax, 1 + ret +cheat_poor: + mov bankroll, 1 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatPoorText + call PrintBank + mov eax, 1 + ret +cheat_shop: + add bankroll, 30000 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatShopText + call PrintBank + call CheckVictory + mov eax, 1 + ret +cheat_backs: + mov shopBackOwned, 1FFFh + call SaveGame + invoke PrintCheatApplied, OFFSET cheatBacksText + mov eax, 1 + ret +cheat_max_charm: + mov shopCharmLevel, 5 + mov shopCharmUses, 1 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatCharmText + mov eax, 1 + ret +cheat_no_charm: + mov shopCharmLevel, 0 + call SaveGame + invoke PrintCheatApplied, OFFSET cheatNoCharmText + mov eax, 1 + ret +cheat_ach: + mov achievements, 7FFFFh + call SaveGame + invoke PrintCheatApplied, OFFSET cheatAchText + mov eax, 1 + ret +ApplyCheatCode ENDP + +; --- ReadBetInput: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- +ReadBetInput PROC uses ebx ecx edx esi edi + mov ecx, 32 + mov edi, OFFSET cheatBuffer + xor eax, eax + rep stosb + + xor ebx, ebx ; parsed numeric bet + xor esi, esi ; stored input length + xor edi, edi ; 0 = number, 1 = cheat/code +read_bet_loop: + invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 + cmp charsRead, 0 + je read_bet_finish + movzx eax, byte ptr inputBuffer + cmp al, 13 + je read_bet_drain_lf + cmp al, 10 + je read_bet_finish + cmp al, ' ' + je read_bet_loop + cmp al, 9 + je read_bet_loop + + cmp al, 'a' + jb read_bet_store + cmp al, 'z' + ja read_bet_store + sub al, 20h + +read_bet_store: + cmp esi, 31 + jae read_bet_after_store + mov cheatBuffer[esi], al +read_bet_after_store: + inc esi + + cmp edi, 0 + jne read_bet_loop + cmp al, '0' + jb read_bet_mark_code + cmp al, '9' + ja read_bet_mark_code + movzx edx, al + sub edx, '0' + imul ebx, ebx, 10 + add ebx, edx + jmp read_bet_loop + +read_bet_mark_code: + mov edi, 1 + jmp read_bet_loop + +read_bet_drain_lf: + invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 + cmp charsRead, 0 + je read_bet_finish + movzx eax, byte ptr inputBuffer + cmp al, 10 + jne read_bet_drain_lf + +read_bet_finish: + cmp esi, 0 + je read_bet_empty + cmp edi, 0 + jne read_bet_cheat + mov eax, ebx + ret + +read_bet_cheat: + invoke ApplyCheatCode, OFFSET cheatBuffer + cmp eax, 1 + je read_bet_cheat_ok + mov eax, 0FFFFFFFEh + ret +read_bet_cheat_ok: + mov eax, 0FFFFFFFFh + ret +read_bet_empty: + xor eax, eax + ret +ReadBetInput ENDP + +; --- Pause: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- +PauseConsole PROC + invoke PrintStr, OFFSET pauseText + call ReadAnyKey + ret +PauseConsole ENDP + +; --- PrintBank: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintBank PROC + invoke PrintStr, OFFSET bankText + invoke PrintMoney, bankroll + invoke PrintStr, OFFSET nl + ret +PrintBank ENDP +; --- PrintGoal: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintGoal PROC + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET goalText + call ResetColor + invoke PrintMoney, targetBank + invoke PrintStr, OFFSET nl + ret +PrintGoal ENDP + +; --- ResetProfileDefaults: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +ResetProfileDefaults PROC uses ecx edi + 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 + +; --- ReadAccountName: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- +; --- CopyCString: êîïèðîâàíèå ASCIIZ-ñòðîêè --- +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: äîïèñûâàåò ASCIIZ-ñòðîêó â êîíåö áóôåðà --- +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: ïóòü ê %APPDATA%\AssemblerCasino --- +BuildNativeProfileDir3D PROTO +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: ïîëíûé ïóòü òåêóùåãî àêêàóíòà --- +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: ìàñêà ïîèñêà àêêàóíòîâ --- +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: ïîëíûé ïóòü àêêàóíòà äëÿ òàáëèö ëèäåðîâ --- +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 +ReadAccountName PROC uses eax ecx edi + mov ecx, 64 + mov edi, OFFSET saveFileName +clear_account_name: + mov byte ptr [edi], 0 + inc edi + loop clear_account_name + + mov accountNameLen, 0 + mov edi, OFFSET saveFileName +read_account_loop: + invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 + cmp charsRead, 0 + je account_name_done + mov al, byte ptr inputBuffer + cmp al, 13 + je account_name_drain_lf + cmp al, 10 + je account_name_done + + cmp accountNameLen, 50 + jae read_account_loop + cmp al, '0' + jb check_account_upper + cmp al, '9' + jbe store_account_char +check_account_upper: + cmp al, 'A' + jb check_account_lower + cmp al, 'Z' + jbe store_account_char +check_account_lower: + cmp al, 'a' + jb check_account_symbols + cmp al, 'z' + jbe store_account_char +check_account_symbols: + cmp al, '_' + je store_account_char + cmp al, '-' + je store_account_char + jmp read_account_loop +store_account_char: + mov [edi], al + inc edi + inc accountNameLen + jmp read_account_loop + +account_name_drain_lf: + invoke ReadFile, hIn, ADDR inputBuffer, 1, ADDR charsRead, 0 + cmp charsRead, 0 + je account_name_done + mov al, byte ptr inputBuffer + cmp al, 10 + jne account_name_drain_lf + +account_name_done: + cmp accountNameLen, 0 + je account_name_return + mov byte ptr [edi], '.' + inc edi + mov byte ptr [edi], 'd' + inc edi + mov byte ptr [edi], 'a' + inc edi + mov byte ptr [edi], 't' + inc edi + mov byte ptr [edi], 0 +account_name_return: + ret +ReadAccountName ENDP + +; --- AskAccountName: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +AskAccountName PROC +ask_account_name_again: + invoke PrintStr, OFFSET accountPromptText + call ReadAccountName + cmp accountNameLen, 0 + jne account_name_ok + invoke PrintStr, OFFSET accountBadText + jmp ask_account_name_again +account_name_ok: + ret +AskAccountName ENDP + +; --- CopyFindAccountName: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +CopyFindAccountName PROC uses eax ecx esi edi + mov eax, accountCount + shl eax, 6 + mov edi, OFFSET accountList + add edi, eax + mov esi, OFFSET findData + add esi, 44 + mov ecx, 63 +copy_find_name_loop: + mov al, [esi] + mov [edi], al + cmp al, 0 + je copy_find_name_done + inc esi + inc edi + loop copy_find_name_loop + mov byte ptr [edi], 0 +copy_find_name_done: + ret +CopyFindAccountName ENDP + +; --- CopySelectedAccountName: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +CopySelectedAccountName PROC uses eax ecx esi edi + mov eax, selectedAccount + dec eax + shl eax, 6 + mov esi, OFFSET accountList + add esi, eax + mov edi, OFFSET saveFileName + mov ecx, 63 +copy_selected_name_loop: + mov al, [esi] + mov [edi], al + cmp al, 0 + je copy_selected_name_done + inc esi + inc edi + loop copy_selected_name_loop + mov byte ptr [edi], 0 +copy_selected_name_done: + ret +CopySelectedAccountName ENDP + +; --- CollectAccounts: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +CollectAccounts PROC uses eax + mov accountCount, 0 + call BuildAccountPatternFull + invoke FindFirstFileA, OFFSET accountPatternFull, OFFSET findData + cmp eax, INVALID_HANDLE_VALUE + je collect_accounts_done + mov findHandle, eax +collect_accounts_loop: + mov eax, DWORD PTR [findData] + test eax, 10h + jne collect_accounts_next + cmp accountCount, 20 + jae collect_accounts_close + call CopyFindAccountName + inc accountCount +collect_accounts_next: + invoke FindNextFileA, findHandle, OFFSET findData + cmp eax, 0 + jne collect_accounts_loop +collect_accounts_close: + invoke FindClose, findHandle +collect_accounts_done: + ret +CollectAccounts ENDP + +; --- PrintAccountList: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintAccountList PROC uses eax ebx + invoke PrintStr, OFFSET accountListTitle + mov ebx, 0 +print_account_loop: + cmp ebx, accountCount + jae print_account_done + mov eax, ebx + inc eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET dotSpaceText + mov eax, ebx + shl eax, 6 + add eax, OFFSET accountList + invoke PrintStr, eax + invoke PrintStr, OFFSET nl + inc ebx + jmp print_account_loop +print_account_done: + ret +PrintAccountList ENDP + +; --- SelectExistingAccount: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +SelectExistingAccount PROC +select_account_again: + call ClearView + invoke PrintTitleColor, OFFSET titleText + call CollectAccounts + cmp accountCount, 0 + jne accounts_available + invoke PrintStr, OFFSET accountNoFilesText + call PauseConsole + xor eax, eax + ret +accounts_available: + call PrintAccountList + invoke PrintStr, OFFSET accountSelectText + call ReadUInt + cmp eax, 1 + jb select_account_bad + cmp eax, accountCount + ja select_account_bad + mov selectedAccount, eax + call CopySelectedAccountName + mov eax, 1 + ret +select_account_bad: + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp select_account_again +SelectExistingAccount ENDP + +; --- AccountMenu: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +AccountMenu PROC +account_menu_loop: + call ClearView + invoke PrintTitleColor, OFFSET titleText + invoke PrintStr, OFFSET accountMenuText + invoke PrintStr, OFFSET choiceText + call ReadKey + cmp al, '1' + je account_login + cmp al, '2' + je account_create + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp account_menu_loop + +account_login: + call ResetProfileDefaults + call SelectExistingAccount + cmp eax, 1 + jne account_menu_loop + call LoadSave + invoke PrintStr, OFFSET accountLoginText + invoke PrintStr, OFFSET saveFileName + invoke PrintStr, OFFSET nl + invoke Sleep, 700 + ret + +account_create: + call ClearView + invoke PrintTitleColor, OFFSET titleText + call ResetProfileDefaults + call AskAccountName + call SaveGame + invoke PrintStr, OFFSET accountCreateText + invoke PrintStr, OFFSET saveFileName + invoke PrintStr, OFFSET nl + invoke Sleep, 700 + ret +AccountMenu ENDP +; --- CalcSaveSignature: ïðîñòàÿ ïîäïèñü ñîõðàíåíèÿ îò ðó÷íîé ïðàâêè --- +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: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +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 + 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: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +LoadSave PROC uses eax ecx esi edi + 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_FILE_SIZE + jb load_signature_ok + mov edx, DWORD PTR [saveBuffer+SAVE_SIGN_SIZE] + call CalcSaveSignature + cmp eax, edx + jne load_tampered +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 + +; --- RegisterGamePlayed: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +RegisterGamePlayed PROC uses eax ebx + mov eax, currentGameId + cmp eax, 1 + jb register_game_played_done + cmp eax, 11 + ja register_game_played_done + dec eax + mov ebx, eax + inc dword ptr gameStatsPlayed[ebx * 4] +register_game_played_done: + ret +RegisterGamePlayed ENDP + +; --- RegisterGameWin: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +RegisterGameWin PROC uses eax ebx + call RegisterGamePlayed + mov eax, currentGameId + cmp eax, 1 + jb register_game_win_done + cmp eax, 10 + ja register_game_win_done + dec eax + mov ebx, eax + inc dword ptr gameStatsWon[ebx * 4] +register_game_win_done: + ret +RegisterGameWin ENDP + +; --- RegisterGameLoss: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +RegisterGameLoss PROC uses eax ebx + call RegisterGamePlayed + mov eax, currentGameId + cmp eax, 1 + jb register_game_loss_done + cmp eax, 10 + ja register_game_loss_done + dec eax + mov ebx, eax + inc dword ptr gameStatsLost[ebx * 4] +register_game_loss_done: + ret +RegisterGameLoss ENDP + +; --- RegisterGameDraw: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +RegisterGameDraw PROC uses eax ebx + call RegisterGamePlayed + mov eax, currentGameId + cmp eax, 1 + jb register_game_draw_done + cmp eax, 10 + ja register_game_draw_done + dec eax + mov ebx, eax + inc dword ptr gameStatsDraw[ebx * 4] +register_game_draw_done: + ret +RegisterGameDraw ENDP +; --- RegisterWin: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +RegisterWin PROC uses eax, amount:DWORD + inc gamesPlayed + inc gamesWon + call DailyAddWin + call RegisterGameWin + mov eax, amount + cmp eax, bestWin + jbe register_win_save + mov bestWin, eax +register_win_save: + call SaveGame + ret +RegisterWin ENDP + +; --- RegisterLoss: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +RegisterLoss PROC uses eax, amount:DWORD + inc gamesPlayed + inc gamesLost + call DailyAddLoss + call RegisterGameLoss + mov eax, amount + cmp eax, bestLoss + jbe register_loss_save + mov bestLoss, eax +register_loss_save: + invoke UnlockAchievement, 2, OFFSET achFirstLossName +register_loss_ach_done: + call SaveGame + ret +RegisterLoss ENDP + +; --- RegisterDraw: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +RegisterDraw PROC + inc gamesPlayed + inc gamesDrawn + call DailyAddDraw + call RegisterGameDraw + call SaveGame + ret +RegisterDraw ENDP + +; --- DailyTaskGoal: öåëü çàäàíèÿ èç ïóëà 40 --- +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 + +; --- DailyTaskReward: äåíåæíàÿ íàãðàäà çàäàíèÿ èç ïóëà 40 --- +DailyTaskReward PROC taskId:DWORD + mov eax, taskId + cmp eax, 12 + je daily_reward_big + cmp eax, 30 + je daily_reward_big + cmp eax, 34 + je daily_reward_big + cmp eax, 36 + je daily_reward_big + cmp eax, 38 + je daily_reward_mid + cmp eax, 40 + je daily_reward_mid + cmp eax, 10 + jb daily_reward_small + cmp eax, 28 + jbe daily_reward_mid + mov eax, 2000 + ret +daily_reward_small: + mov eax, 1000 + ret +daily_reward_mid: + mov eax, 2500 + ret +daily_reward_big: + mov eax, 4000 + ret +DailyTaskReward ENDP + +; --- DailyGenerateTasks: âûáèðàåò 3 çàäàíèÿ èç 40 ïî êàëåíäàðíîé äàòå --- +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: êàëåíäàðíûå åæåäíåâíûå çàäàíèÿ --- +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 + +; --- DailyTaskMatches: ïðîâåðÿåò, ðåàãèðóåò ëè çàäàíèå íà ñîáûòèå --- +; eventType: 1 played, 2 win, 3 loss, 4 draw, 5 bet>=5000, 6 bet>=10000 +DailyTaskMatches PROC uses ebx ecx edx, taskId:DWORD, eventType:DWORD + mov eax, taskId + mov ebx, eventType + cmp eax, 1 + je daily_match_play_any + cmp eax, 2 + je daily_match_play_any + cmp eax, 3 + je daily_match_play_any + cmp eax, 4 + je daily_match_win_any + cmp eax, 5 + je daily_match_win_any + cmp eax, 6 + je daily_match_win_any + cmp eax, 7 + je daily_match_loss_any + cmp eax, 8 + je daily_match_loss_any + cmp eax, 9 + je daily_match_draw_any + cmp eax, 10 + je daily_match_bet5 + cmp eax, 11 + je daily_match_bet5 + cmp eax, 12 + je daily_match_bet10 + + cmp eax, 13 + jb daily_match_none + cmp eax, 34 + ja daily_match_groups + mov ecx, eax + sub ecx, 13 + shr ecx, 1 + inc ecx + ; map compact game order 1..11 to actual currentGameId + cmp ecx, 3 + jb daily_match_game_ready + cmp ecx, 3 + je daily_match_game_clover + cmp ecx, 4 + je daily_match_game_rr + cmp ecx, 5 + je daily_match_game_skulls + cmp ecx, 6 + je daily_match_game_coin + cmp ecx, 7 + je daily_match_game_dice + cmp ecx, 8 + je daily_match_game_casino_roulette + cmp ecx, 9 + je daily_match_game_slot + cmp ecx, 10 + je daily_match_game_durak + mov ecx, 11 + jmp daily_match_game_ready +daily_match_game_clover: + mov ecx, 3 + jmp daily_match_game_ready +daily_match_game_rr: + mov ecx, 4 + jmp daily_match_game_ready +daily_match_game_skulls: + mov ecx, 5 + jmp daily_match_game_ready +daily_match_game_coin: + mov ecx, 6 + jmp daily_match_game_ready +daily_match_game_dice: + mov ecx, 7 + jmp daily_match_game_ready +daily_match_game_casino_roulette: + mov ecx, 8 + jmp daily_match_game_ready +daily_match_game_slot: + mov ecx, 9 + jmp daily_match_game_ready +daily_match_game_durak: + mov ecx, 10 +daily_match_game_ready: + cmp currentGameId, ecx + jne daily_match_none + test eax, 1 + jnz daily_match_play_any + jmp daily_match_win_any + +daily_match_groups: + cmp eax, 35 + je daily_match_card_play + cmp eax, 36 + je daily_match_card_win + cmp eax, 37 + je daily_match_luck_play + cmp eax, 38 + je daily_match_luck_win + cmp eax, 39 + je daily_match_risk_play + cmp eax, 40 + je daily_match_risk_win + jmp daily_match_none + +daily_match_play_any: + cmp ebx, 1 + je daily_match_yes + jmp daily_match_none +daily_match_win_any: + cmp ebx, 2 + je daily_match_yes + jmp daily_match_none +daily_match_loss_any: + cmp ebx, 3 + je daily_match_yes + jmp daily_match_none +daily_match_draw_any: + cmp ebx, 4 + je daily_match_yes + jmp daily_match_none +daily_match_bet5: + cmp ebx, 5 + je daily_match_yes + jmp daily_match_none +daily_match_bet10: + cmp ebx, 6 + je daily_match_yes + jmp daily_match_none + +daily_match_card_play: + cmp ebx, 1 + jne daily_match_none + cmp currentGameId, 1 + je daily_match_yes + cmp currentGameId, 2 + je daily_match_yes + cmp currentGameId, 10 + je daily_match_yes + jmp daily_match_none +daily_match_card_win: + cmp ebx, 2 + jne daily_match_none + cmp currentGameId, 1 + je daily_match_yes + cmp currentGameId, 2 + je daily_match_yes + cmp currentGameId, 10 + je daily_match_yes + jmp daily_match_none +daily_match_luck_play: + cmp ebx, 1 + jne daily_match_none + cmp currentGameId, 3 + je daily_match_yes + cmp currentGameId, 6 + je daily_match_yes + cmp currentGameId, 7 + je daily_match_yes + cmp currentGameId, 8 + je daily_match_yes + cmp currentGameId, 9 + je daily_match_yes + jmp daily_match_none +daily_match_luck_win: + cmp ebx, 2 + jne daily_match_none + cmp currentGameId, 3 + je daily_match_yes + cmp currentGameId, 6 + je daily_match_yes + cmp currentGameId, 7 + je daily_match_yes + cmp currentGameId, 8 + je daily_match_yes + cmp currentGameId, 9 + je daily_match_yes + jmp daily_match_none +daily_match_risk_play: + cmp ebx, 1 + jne daily_match_none + cmp currentGameId, 4 + je daily_match_yes + cmp currentGameId, 5 + je daily_match_yes + cmp currentGameId, 11 + je daily_match_yes + jmp daily_match_none +daily_match_risk_win: + cmp ebx, 2 + jne daily_match_none + cmp currentGameId, 4 + je daily_match_yes + cmp currentGameId, 5 + je daily_match_yes + cmp currentGameId, 11 + je daily_match_yes + jmp daily_match_none + +daily_match_yes: + mov eax, 1 + ret +daily_match_none: + xor eax, eax + ret +DailyTaskMatches ENDP + +; --- DailyApplyEvent: ïðèìåíÿåò èãðîâîå ñîáûòèå ê òð¸ì çàäàíèÿì äíÿ --- +DailyApplyEvent PROC uses eax ebx ecx edx esi, eventType:DWORD + call DailyCheckDate + mov esi, 0 +daily_apply_loop: + cmp esi, 3 + jae daily_apply_done + movzx eax, byte ptr [dailyTaskPacked + esi] + cmp eax, 0 + je daily_apply_next + mov ebx, eax + invoke DailyTaskMatches, ebx, eventType + cmp eax, 1 + jne daily_apply_next + movzx ecx, byte ptr [dailyProgressPacked + esi] + invoke DailyTaskGoal, ebx + cmp ecx, eax + jae daily_apply_next + inc byte ptr [dailyProgressPacked + esi] +daily_apply_next: + inc esi + jmp daily_apply_loop +daily_apply_done: + ret +DailyApplyEvent ENDP + +DailyAddPlayed PROC + invoke DailyApplyEvent, 1 + ret +DailyAddPlayed ENDP + +DailyAddWin PROC + call DailyAddPlayed + invoke DailyApplyEvent, 2 + ret +DailyAddWin ENDP + +DailyAddLoss PROC + call DailyAddPlayed + invoke DailyApplyEvent, 3 + ret +DailyAddLoss ENDP + +DailyAddDraw PROC + call DailyAddPlayed + invoke DailyApplyEvent, 4 + ret +DailyAddDraw ENDP + +DailyAddHighBet PROC + call DailyCheckDate + cmp currentBet, 5000 + jb daily_bet_done + invoke DailyApplyEvent, 5 + cmp currentBet, 10000 + jb daily_bet_done + invoke DailyApplyEvent, 6 +daily_bet_done: + ret +DailyAddHighBet ENDP + +; --- DailyClaimSlot: âûäà÷à íàãðàäû çà îäèí ñëîò åæåäíåâêè --- +DailyClaimSlot PROC uses eax ebx ecx edx, slotIndex:DWORD, maskValue:DWORD + mov eax, dailyRewardMask + and eax, maskValue + cmp eax, 0 + jne daily_claim_slot_done + mov ecx, slotIndex + movzx ebx, byte ptr [dailyTaskPacked + ecx] + cmp ebx, 0 + je daily_claim_slot_done + movzx edx, byte ptr [dailyProgressPacked + ecx] + invoke DailyTaskGoal, ebx + cmp edx, eax + jb daily_claim_slot_done + mov eax, maskValue + or dailyRewardMask, eax + invoke DailyTaskReward, ebx + add bankroll, eax + push eax + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET dailyClaimText + pop eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + call ResetColor +daily_claim_slot_done: + ret +DailyClaimSlot ENDP + +DailyClaimRewards PROC + call DailyCheckDate + invoke DailyClaimSlot, 0, 1 + invoke DailyClaimSlot, 1, 2 + invoke DailyClaimSlot, 2, 4 + call SaveGame + ret +DailyClaimRewards ENDP + +; --- PrintDailySlot: ñòðîêà îäíîãî åæåäíåâíîãî çàäàíèÿ --- +PrintDailySlot PROC uses eax ebx ecx edx, slotIndex:DWORD, maskValue:DWORD + mov ecx, slotIndex + mov eax, ecx + inc eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET dotSpaceText + movzx ebx, byte ptr [dailyTaskPacked + ecx] + cmp ebx, 1 + jb daily_slot_done + cmp ebx, 40 + ja daily_slot_done + mov eax, ebx + dec eax + mov edx, dword ptr [dailyTaskNameTable + eax * 4] + invoke PrintStr, edx + invoke PrintStr, OFFSET dailySlashText + mov ecx, slotIndex + movzx eax, byte ptr [dailyProgressPacked + ecx] + push eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET dailySlashText + invoke DailyTaskGoal, ebx + mov edx, eax + invoke PrintUInt, edx + invoke PrintStr, OFFSET dailyRewardText + invoke DailyTaskReward, ebx + invoke PrintUInt, eax + mov eax, dailyRewardMask + and eax, maskValue + cmp eax, 0 + jne daily_slot_status_done + pop eax + cmp eax, edx + jae daily_slot_status_ready + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET dailyOpenText + call ResetColor + ret +daily_slot_status_ready: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET dailyReadyText + call ResetColor + ret +daily_slot_status_done: + pop eax + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET dailyDoneText + call ResetColor + ret +daily_slot_done: + ret +PrintDailySlot ENDP + +GameDailyTasks PROC + call ClearView + invoke PrintTitleColor, OFFSET dailyTitle + invoke PrintStr, OFFSET dailyIntro + call DailyClaimRewards + call PrintBank + invoke PrintStr, OFFSET dailyDateText + invoke PrintUInt, dailyDateKey + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET dailyPoolText + invoke PrintDailySlot, 0, 1 + invoke PrintDailySlot, 1, 2 + invoke PrintDailySlot, 2, 4 + call PauseConsole + ret +GameDailyTasks ENDP + +; --- PrintDifficultyName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintDifficultyName PROC + cmp aiDifficulty, 1 + je print_easy_name + cmp aiDifficulty, 3 + je print_hard_name + invoke PrintStr, OFFSET normalName + ret +print_easy_name: + invoke PrintStr, OFFSET easyName + ret +print_hard_name: + invoke PrintStr, OFFSET hardName + ret +PrintDifficultyName ENDP + +; --- PrintBankLevelName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintBankLevelName PROC + mov eax, bankroll + cmp eax, 100000 + jae print_level_legend + cmp eax, 50000 + jae print_level_high + cmp eax, 20000 + jae print_level_player + invoke PrintStr, OFFSET bankLevelNewbie + ret +print_level_player: + invoke PrintStr, OFFSET bankLevelPlayer + ret +print_level_high: + invoke PrintStr, OFFSET bankLevelHigh + ret +print_level_legend: + invoke PrintStr, OFFSET bankLevelLegend + ret +PrintBankLevelName ENDP + +; --- PrintBankLevel: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintBankLevel PROC + invoke PrintStr, OFFSET bankLevelText + call PrintBankLevelName + ret +PrintBankLevel ENDP + +; --- ApplySoundVolume: íàñòðîéêè ãðîìêîñòè WinMM, 0-10 --- +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 +; --- AnimShouldDrawFrame: animation profile frame skipper --- +AnimShouldDrawFrame PROC uses ecx edx + inc animFrameCounter + mov eax, settingsLowSpec + cmp eax, 0 + je anim_draw_yes + cmp eax, 1 + je anim_adaptive_check + mov eax, animFrameCounter + xor edx, edx + mov ecx, 3 + div ecx + cmp edx, 1 + je anim_draw_yes + xor eax, eax + ret +anim_adaptive_check: + mov eax, animFrameCounter + and eax, 1 + cmp eax, 1 + je anim_draw_yes + xor eax, eax + ret +anim_draw_yes: + mov eax, 1 + ret +AnimShouldDrawFrame ENDP + +; --- AnimFrameDelay: keeps scene timing while reducing redraws --- +AnimFrameDelay PROC baseDelay:DWORD + mov eax, baseDelay + cmp settingsLowSpec, 1 + je anim_delay_adaptive + cmp settingsLowSpec, 2 + je anim_delay_stable + ret +anim_delay_adaptive: + shl eax, 1 + ret +anim_delay_stable: + imul eax, eax, 3 + ret +AnimFrameDelay ENDP + +; --- PrintVIPStatus: VIP-ñòàòóñ ïî ðàçìåðó áàíêà --- +PrintVIPStatus PROC + invoke PrintStr, OFFSET vipStatusText + mov eax, bankroll + cmp eax, 500000 + jae print_vip_diamond + cmp eax, 250000 + jae print_vip_gold + cmp eax, 100000 + jae print_vip_silver + invoke PrintStr, OFFSET vipBronzeText + ret +print_vip_silver: + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET vipSilverText + call ResetColor + ret +print_vip_gold: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET vipGoldText + call ResetColor + ret +print_vip_diamond: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET vipDiamondText + call ResetColor + ret +PrintVIPStatus ENDP + +; --- ApplyVIPTax: êàçèíî áåðåò êîìèññèþ ñ áîëüøèõ VIP-ñòàâîê --- +ApplyVIPTax PROC uses eax ebx edx + mov vipTaxAmount, 0 + mov eax, bankroll + cmp eax, 100000 + jb vip_tax_done + mov eax, currentBet + cmp bankroll, 500000 + jae vip_tax_diamond + cmp bankroll, 250000 + jae vip_tax_gold + mov ebx, 1 + jmp vip_tax_calc +vip_tax_gold: + mov ebx, 2 + jmp vip_tax_calc +vip_tax_diamond: + mov ebx, 3 +vip_tax_calc: + mul ebx + mov ebx, 100 + xor edx, edx + div ebx + cmp eax, 0 + jne vip_tax_have + mov eax, 1 +vip_tax_have: + mov vipTaxAmount, eax + cmp bankroll, eax + jae vip_tax_sub + mov eax, bankroll + mov vipTaxAmount, eax +vip_tax_sub: + sub bankroll, eax + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET vipTaxText + invoke PrintUInt, vipTaxAmount + invoke PrintStr, OFFSET nl + call ResetColor + call SaveGame +vip_tax_done: + ret +ApplyVIPTax ENDP + +; --- CheckSecretEnding: ñåêðåòíàÿ êîíöîâêà çà ïîëíîå çàêðûòèå êàçèíî --- +CheckSecretEnding PROC uses eax + cmp secretEndingSeen, 0 + jne secret_ending_done + mov eax, achievements + and eax, 3FFFFh + cmp eax, 3FFFFh + jne secret_ending_done + mov eax, shopBackOwned + and eax, 1FFFh + cmp eax, 1FFFh + jne secret_ending_done + cmp bankroll, 1000000 + jb secret_ending_done + mov secretEndingSeen, 1 + call SaveGame + call ClearView + call PlayVictorySound + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET secretEndingTitle + invoke PrintStr, OFFSET secretEndingArt1 + invoke Sleep, 500 + invoke PrintStr, OFFSET secretEndingArt2 + call ResetColor + invoke PrintStr, OFFSET secretEndingBody + call PauseConsole +secret_ending_done: + ret +CheckSecretEnding ENDP + +; --- GameSettings: íàñòðîéêè çâóêà è èãðîâûõ îïöèé --- +GameSettings PROC +settings_loop: + call ClearView + invoke PrintTitleColor, OFFSET settingsTitle + invoke PrintStr, OFFSET settingsVolumeText + invoke PrintUInt, settingsVolume + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET settingsVolumeHint + call PrintVIPStatus + + invoke PrintStr, OFFSET settingsModeText + cmp settingsLowSpec, 0 + je settings_print_cinematic + cmp settingsLowSpec, 1 + je settings_print_adaptive + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET settingsStableText + call ResetColor + jmp settings_print_intro +settings_print_cinematic: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET settingsCinematicText + call ResetColor + jmp settings_print_intro +settings_print_adaptive: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET settingsAdaptiveText + call ResetColor +settings_print_intro: + invoke PrintStr, OFFSET settingsIntroText + cmp settingsIntroEnabled, 1 + je settings_intro_on + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET settingsOffText + call ResetColor + jmp settings_print_dbd +settings_intro_on: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET settingsOnText + call ResetColor +settings_print_dbd: + invoke PrintStr, OFFSET settingsDbdText + cmp settingsDbdWindowEnabled, 1 + je settings_dbd_on + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET settingsOffText + call ResetColor + jmp settings_show_menu +settings_dbd_on: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET settingsOnText + call ResetColor +settings_show_menu: + invoke PrintStr, OFFSET settingsAnimHintText + invoke PrintStr, OFFSET settingsMenuText + call ReadUInt + cmp eax, 0 + je settings_exit + cmp eax, 1 + je settings_quieter + cmp eax, 2 + je settings_louder + cmp eax, 3 + je settings_toggle_low + cmp eax, 4 + je settings_toggle_intro + cmp eax, 5 + je settings_toggle_dbd + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp settings_loop +settings_quieter: + cmp settingsVolume, 0 + jbe settings_apply + dec settingsVolume + jmp settings_apply +settings_louder: + cmp settingsVolume, 10 + jae settings_apply + inc settingsVolume + jmp settings_apply +settings_toggle_low: + inc settingsLowSpec + cmp settingsLowSpec, 3 + jb settings_apply + mov settingsLowSpec, 0 + jmp settings_apply +settings_toggle_intro: + mov eax, settingsIntroEnabled + xor eax, 1 + mov settingsIntroEnabled, eax + jmp settings_apply +settings_toggle_dbd: + mov eax, settingsDbdWindowEnabled + xor eax, 1 + mov settingsDbdWindowEnabled, eax +settings_apply: + call ApplySoundVolume + call SaveGame + jmp settings_loop +settings_exit: + ret +GameSettings ENDP +; --- CalcStressLevel: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +CalcStressLevel PROC uses eax ebx edx + mov stressLevel, 0 + cmp bankroll, 0 + je calc_stress_done + cmp currentBet, 0 + je calc_stress_done + mov eax, currentBet + mov ebx, 100 + mul ebx + mov ebx, bankroll + xor edx, edx + div ebx + cmp eax, 75 + jae calc_stress_max + cmp eax, 50 + jae calc_stress_high + cmp eax, 25 + jae calc_stress_mid + jmp calc_stress_done +calc_stress_mid: + mov stressLevel, 1 + jmp calc_stress_done +calc_stress_high: + mov stressLevel, 2 + jmp calc_stress_done +calc_stress_max: + mov stressLevel, 3 +calc_stress_done: + ret +CalcStressLevel ENDP + +; --- PrintStressLevel: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintStressLevel PROC + invoke PrintStr, OFFSET stressText + mov eax, stressLevel + cmp eax, 0 + je print_stress_low + cmp eax, 1 + je print_stress_mid + cmp eax, 2 + je print_stress_high + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET stressMaxText + call ResetColor + ret +print_stress_low: + invoke PrintStr, OFFSET stressLowText + ret +print_stress_mid: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET stressMidText + call ResetColor + ret +print_stress_high: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET stressHighText + call ResetColor + ret +PrintStressLevel ENDP + +; --- PrintSuspicion: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSuspicion PROC + invoke PrintStr, OFFSET suspicionText + mov eax, casinoSuspicion + cmp eax, 44 + jae print_suspicion_hunt + cmp eax, 25 + jae print_suspicion_watch + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET suspicionCalmText + call ResetColor + ret +print_suspicion_watch: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET suspicionWatchText + call ResetColor + ret +print_suspicion_hunt: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET suspicionHuntText + call ResetColor + ret +PrintSuspicion ENDP + +; --- AddSuspicion: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +AddSuspicion PROC uses eax ebx, amount:DWORD + mov eax, casinoSuspicion + add eax, amount + cmp eax, 100 + jbe add_suspicion_store + mov eax, 100 +add_suspicion_store: + mov casinoSuspicion, eax + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET suspicionUpText + call ResetColor + call SaveGame + ret +AddSuspicion ENDP + +; --- CheckCasinoHeat: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +CheckCasinoHeat PROC uses eax ebx + mov eax, casinoSuspicion + cmp eax, 44 + jb casino_heat_done + sub eax, 40 + mov ebx, eax + invoke RandomRange, 100 + cmp eax, ebx + jae casino_heat_done + mov eax, currentBet + shr eax, 1 + cmp eax, 1 + jae casino_heat_have_fine + mov eax, 1 +casino_heat_have_fine: + cmp bankroll, eax + jae casino_heat_sub + mov eax, bankroll +casino_heat_sub: + sub bankroll, eax + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET suspicionFineText + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + call ResetColor + call PrintBank + call SaveGame +casino_heat_done: + ret +CheckCasinoHeat ENDP +; --- ShowStats: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +ShowStats PROC + invoke PrintStr, OFFSET difficultyNowText + call PrintDifficultyName + call PrintBankLevel + invoke PrintStr, OFFSET statsGamesText + invoke PrintUInt, gamesPlayed + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET statsWinsText + invoke PrintUInt, gamesWon + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET statsLossText + invoke PrintUInt, gamesLost + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET statsDrawText + invoke PrintUInt, gamesDrawn + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET statsBestWinText + invoke PrintUInt, bestWin + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET statsBestLossText + invoke PrintUInt, bestLoss + invoke PrintStr, OFFSET nl + call PrintSuspicion + ret +ShowStats ENDP + + +; --- WriteAchievementPopup: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +WriteAchievementPopup PROC uses eax ecx esi, pName:DWORD + mov esi, pName + xor ecx, ecx +achievement_len_loop: + mov al, [esi + ecx] + cmp al, 0 + je achievement_len_ready + cmp al, 13 + je achievement_len_ready + cmp ecx, 64 + jae achievement_len_ready + inc ecx + jmp achievement_len_loop +achievement_len_ready: + invoke CreateFileA, OFFSET achievementFileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + je achievement_popup_run + mov achievementHandle, eax + invoke WriteFile, achievementHandle, pName, ecx, ADDR charsWritten, 0 + invoke CloseHandle, achievementHandle +achievement_popup_run: + invoke WinExec, OFFSET achievementCmd, 1 + ret +WriteAchievementPopup ENDP + +; --- UnlockAchievement: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +UnlockAchievement PROC uses eax ebx, maskValue:DWORD, pName:DWORD + mov eax, achievements + mov ebx, maskValue + test eax, ebx + jz unlock_achievement_new + ret +unlock_achievement_new: + or eax, ebx + mov achievements, eax + call SaveGame + invoke WriteAchievementPopup, pName + ret +UnlockAchievement ENDP + +; --- PrintAchievementLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintAchievementLine PROC uses eax ebx, maskValue:DWORD, pName:DWORD + mov eax, achievements + mov ebx, maskValue + test eax, ebx + jz print_achievement_locked + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET achDoneText + call ResetColor + jmp print_achievement_name +print_achievement_locked: + invoke SetColor, COLOR_BACK_CARD + invoke PrintStr, OFFSET achTodoText + call ResetColor +print_achievement_name: + invoke PrintStr, pName + ret +PrintAchievementLine ENDP +; --- ShowWelcome: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +ShowWelcome PROC + call ClearView + invoke PrintTitleColor, OFFSET titleText + invoke PrintStr, OFFSET welcomeText + call PrintGoal + cmp bankRecovered, 0 + je welcome_check_tampered + invoke PrintStr, OFFSET bankRecoveredText +welcome_check_tampered: + cmp saveTampered, 0 + je welcome_bank_normal + invoke PrintStr, OFFSET saveTamperedText +welcome_bank_normal: + call PrintBank + call ShowStats + call PauseConsole + ret +ShowWelcome ENDP + +; --- SelectDifficulty: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +SelectDifficulty PROC +select_difficulty_again: + call ClearView + invoke PrintTitleColor, OFFSET titleText + invoke PrintStr, OFFSET difficultyText + call ReadKey + cmp al, '1' + je set_easy_ai + cmp al, '2' + je set_normal_ai + cmp al, '3' + je set_hard_ai + jmp select_difficulty_again +set_easy_ai: + mov aiDifficulty, 1 + jmp difficulty_selected +set_normal_ai: + mov aiDifficulty, 2 + jmp difficulty_selected +set_hard_ai: + mov aiDifficulty, 3 +difficulty_selected: + call SaveGame + ret +SelectDifficulty ENDP + +; --- ShowPokerChips: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +ShowPokerChips PROC uses eax ebx edx + invoke PrintStr, OFFSET pokerChipTitle + + mov eax, currentBet + mov ebx, 5000 + xor edx, edx + div ebx + add eax, 5 + cmp eax, 10 + jbe poker_chips_count_ready + mov eax, 10 +poker_chips_count_ready: + mov rowIndex, eax + +poker_chips_loop: + cmp rowIndex, 0 + je poker_chips_done + mov eax, rowIndex + cmp eax, 7 + ja poker_chips_high + cmp eax, 4 + ja poker_chips_mid + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET pokerChipLow + jmp poker_chips_next +poker_chips_mid: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET pokerChipMid + jmp poker_chips_next +poker_chips_high: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET pokerChipHigh +poker_chips_next: + dec rowIndex + jmp poker_chips_loop + +poker_chips_done: + call ResetColor + ret +ShowPokerChips ENDP + +; --- ShowPokerMoney: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +ShowPokerMoney PROC uses eax ebx + call ShowPokerChips + invoke PrintStr, OFFSET pokerPotText + mov eax, currentBet + mov ebx, 2 + mul ebx + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET pokerBetText + invoke PrintUInt, currentBet + invoke PrintStr, OFFSET nl + ret +ShowPokerMoney ENDP + +; --- PromptPokerRaise: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +PromptPokerRaise PROC uses ebx + call PrintBank + invoke PrintStr, OFFSET pokerRaiseAskText + call ReadUInt + cmp eax, 0 + je raise_bad + mov pokerRaiseAmount, eax + mov ebx, currentBet + add ebx, eax + cmp ebx, bankroll + ja raise_bad + mov currentBet, ebx + invoke PrintStr, OFFSET pokerRaisedText + invoke PrintUInt, currentBet + invoke PrintStr, OFFSET nl + mov eax, 1 + ret +raise_bad: + invoke PrintStr, OFFSET pokerBadRaiseText + xor eax, eax + ret +PromptPokerRaise ENDP + +; --- PaySlotMultiplier: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +PaySlotMultiplier PROC uses eax ebx edx, multiplier:DWORD + mov lastGameResult, 1 + mov eax, currentBet + mov ebx, multiplier + mul ebx + mov pokerRaiseAmount, eax + add bankroll, eax + invoke PrintStr, OFFSET slotPayoutText + invoke PrintUInt, multiplier + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET moneyWinText + invoke PrintUInt, pokerRaiseAmount + invoke PrintStr, OFFSET nl + invoke RegisterWin, pokerRaiseAmount + invoke UnlockAchievement, 1, OFFSET achFirstWinName + call PrintBank + call PrintCroupierWin + cmp multiplier, 10 + jb slot_multiplier_no_ach + invoke UnlockAchievement, 4, OFFSET achJackpotName +slot_multiplier_no_ach: + call CheckVictory + ret +PaySlotMultiplier ENDP +; --- CheckBankrupt: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +CheckBankrupt PROC + cmp bankroll, 0 + ja bankroll_ok + call PlayBankruptSound + invoke Sleep, 300 + invoke PrintStr, OFFSET casinoKickText + invoke PrintStr, OFFSET casinoExitText + call ReadAnyKey + invoke ExitProcess, 0 +bankroll_ok: + ret +CheckBankrupt ENDP +; --- CheckVictory: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +CheckVictory PROC + mov eax, bankroll + cmp eax, targetBank + jb victory_not_yet + call PlayVictorySound + call ClearView + invoke PrintTitleColor, OFFSET titleText + invoke PrintStr, OFFSET victoryText + invoke PrintStr, OFFSET victoryReachedText + invoke PrintUInt, targetBank + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET victoryTailText + call PrintBank + +advance_victory_goal: + mov eax, bankroll + cmp eax, targetBank + jb victory_goal_ready + add targetBank, 50000 + jmp advance_victory_goal +victory_goal_ready: + call SaveGame + invoke UnlockAchievement, 40h, OFFSET achGoalName + invoke PrintStr, OFFSET nextGoalText + invoke PrintUInt, targetBank + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET victoryExitText + call CheckSecretEnding +victory_secret_checked: + call ReadAnyKey + ret +victory_not_yet: + call CheckSecretEnding + ret +CheckVictory ENDP + +; --- ShowStressPulse: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +ShowStressPulse PROC uses eax ebx edx + cmp bankroll, 0 + je stress_pulse_done + mov eax, currentBet + cmp eax, 0 + je stress_pulse_done + mov ebx, 100 + mul ebx + mov ebx, bankroll + xor edx, edx + div ebx + cmp eax, 25 + jb stress_pulse_done + + invoke PrintStr, OFFSET pulseTitleText + cmp eax, 50 + jae stress_pulse_hot + invoke SetColor, COLOR_WARN + jmp stress_pulse_frames +stress_pulse_hot: + invoke SetColor, COLOR_BAD +stress_pulse_frames: + mov eax, stressLevel + inc eax + mov pulseCycles, eax +stress_pulse_cycle: + invoke PrintStr, OFFSET pulseFrame1 + invoke Sleep, 70 + invoke PrintStr, OFFSET pulseFrame2 + invoke Sleep, 70 + invoke PrintStr, OFFSET pulseFrame3 + invoke Sleep, 70 + invoke PrintStr, OFFSET pulseFrame4 + invoke Sleep, 70 + invoke PrintStr, OFFSET pulseFrame5 + invoke Sleep, 90 + dec pulseCycles + cmp pulseCycles, 0 + jne stress_pulse_cycle + call ResetColor +stress_pulse_done: + ret +ShowStressPulse ENDP + +; --- PromptBet: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +PromptBet PROC +prompt_bet_again: + call CheckBankrupt + call PrintBank + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET betText + call ReadBetInput + push eax + call ResetColor + pop eax + cmp eax, 0FFFFFFFFh + je prompt_bet_again + cmp eax, 0FFFFFFFEh + je prompt_bet_again + cmp eax, 0FFFFFFFDh + je prompt_bet_again + cmp eax, 0 + jne bet_check_money + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET badBetText + call ResetColor + jmp prompt_bet_again + +bet_check_money: + cmp eax, bankroll + jbe bet_store + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET tooBigBetText + call ResetColor + jmp prompt_bet_again +bet_store: + mov currentBet, eax + call ApplyVIPTax + cmp currentBet, 10000 + jb bet_highroller_done + invoke UnlockAchievement, 8, OFFSET achHighRollerName +bet_highroller_done: + call DailyAddHighBet + invoke PrintStr, OFFSET betChosenText + invoke PrintMoney, currentBet + invoke PrintStr, OFFSET nl + call CalcStressLevel + call PrintStressLevel + call ShowStressPulse + invoke Sleep, 500 + ret +PromptBet ENDP + +; --- PayWin: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +PayWin PROC + mov lastGameResult, 1 + mov eax, currentBet + add bankroll, eax + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET moneyWinText + invoke PrintUInt, currentBet + call ResetColor + invoke PrintStr, OFFSET nl + invoke RegisterWin, currentBet + invoke UnlockAchievement, 1, OFFSET achFirstWinName + call PrintBank + call PrintCroupierWin + call CheckVictory + ret +PayWin ENDP + +; --- TryCharmSave: òàëèñìàíû ñïàñàþò ñòàâêó, íî ó ñèëüíûõ åñòü öåíà --- +TryCharmSave PROC uses ebx ecx edx + cmp shopCharmLevel, 0 + jne charm_has_level + xor eax, eax + ret +charm_has_level: + cmp shopCharmUses, 0 + jne charm_has_uses + mov shopCharmLevel, 0 + xor eax, eax + ret +charm_has_uses: + mov ebx, shopCharmLevel + cmp ebx, 1 + je charm_chance_clover + cmp ebx, 2 + je charm_chance_bell + cmp ebx, 3 + je charm_chance_diamond + cmp ebx, 4 + je charm_chance_skull + cmp ebx, 5 + je charm_chance_web + cmp ebx, 6 + je charm_chance_bee + cmp ebx, 7 + je charm_chance_moon + cmp ebx, 8 + je charm_chance_crown + cmp ebx, 9 + je charm_chance_mirror + cmp ebx, 10 + je charm_chance_dice + cmp ebx, 11 + je charm_chance_blood + cmp ebx, 12 + je charm_chance_hourglass + cmp ebx, 13 + je charm_chance_horseshoe + cmp ebx, 14 + je charm_chance_joker + cmp ebx, 15 + je charm_chance_phoenix + cmp ebx, 16 + je charm_chance_compass + cmp ebx, 17 + je charm_chance_tooth + cmp ebx, 18 + je charm_chance_eye + cmp ebx, 19 + je charm_chance_key + cmp ebx, 20 + je charm_chance_candle + cmp ebx, 21 + je charm_chance_chip + cmp ebx, 22 + je charm_chance_snake + cmp ebx, 23 + je charm_chance_ace + cmp ebx, 24 + je charm_chance_devil + xor eax, eax + ret +charm_chance_clover: + mov ecx, 7 + jmp charm_roll +charm_chance_bell: + mov ecx, 14 + jmp charm_roll +charm_chance_diamond: + mov ecx, 21 + jmp charm_roll +charm_chance_skull: + mov ecx, 28 + jmp charm_roll +charm_chance_web: + mov ecx, 35 + jmp charm_roll +charm_chance_bee: + mov ecx, 12 + jmp charm_roll +charm_chance_moon: + mov ecx, 18 + jmp charm_roll +charm_chance_crown: + mov ecx, 24 + jmp charm_roll +charm_chance_mirror: + mov ecx, 16 + jmp charm_roll +charm_chance_dice: + mov ecx, 10 + jmp charm_roll +charm_chance_blood: + mov ecx, 40 + jmp charm_roll +charm_chance_hourglass: + mov ecx, 22 + jmp charm_roll +charm_chance_horseshoe: + mov ecx, 9 + jmp charm_roll +charm_chance_joker: + mov ecx, 33 + jmp charm_roll +charm_chance_phoenix: + mov ecx, 26 + jmp charm_roll +charm_chance_compass: + mov ecx, 19 + jmp charm_roll +charm_chance_tooth: + mov ecx, 15 + jmp charm_roll +charm_chance_eye: + mov ecx, 31 + jmp charm_roll +charm_chance_key: + mov ecx, 13 + jmp charm_roll +charm_chance_candle: + mov ecx, 38 + jmp charm_roll +charm_chance_chip: + mov ecx, 20 + jmp charm_roll +charm_chance_snake: + mov ecx, 29 + jmp charm_roll +charm_chance_ace: + mov ecx, 17 + jmp charm_roll +charm_chance_devil: + mov ecx, 50 +charm_roll: + invoke RandomRange, 100 + cmp eax, ecx + jb charm_save_hit + xor eax, eax + ret + +charm_save_hit: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopCharmSaveText + call ResetColor + dec shopCharmUses + + mov ebx, shopCharmLevel + cmp ebx, 2 + je charm_penalty_bell + cmp ebx, 3 + je charm_penalty_diamond + cmp ebx, 4 + je charm_penalty_skull + cmp ebx, 5 + je charm_penalty_web + cmp ebx, 7 + je charm_penalty_moon + cmp ebx, 8 + je charm_penalty_crown + cmp ebx, 9 + je charm_penalty_mirror + cmp ebx, 11 + je charm_penalty_blood + cmp ebx, 12 + je charm_penalty_hourglass + cmp ebx, 14 + je charm_penalty_joker + cmp ebx, 15 + je charm_penalty_phoenix + cmp ebx, 16 + je charm_penalty_compass + cmp ebx, 17 + je charm_penalty_tooth + cmp ebx, 18 + je charm_penalty_eye + cmp ebx, 20 + je charm_penalty_candle + cmp ebx, 22 + je charm_penalty_snake + cmp ebx, 23 + je charm_penalty_ace + cmp ebx, 24 + je charm_penalty_devil + jmp charm_penalty_done + +charm_penalty_bell: + invoke AddSuspicion, 4 + jmp charm_penalty_done +charm_penalty_diamond: + invoke AddSuspicion, 8 + jmp charm_penalty_done +charm_penalty_web: + invoke AddSuspicion, 20 + jmp charm_penalty_done +charm_penalty_moon: + invoke AddSuspicion, 8 + jmp charm_penalty_done +charm_penalty_crown: + invoke AddSuspicion, 12 + jmp charm_penalty_done +charm_penalty_mirror: + invoke AddSuspicion, 6 + jmp charm_penalty_done +charm_penalty_hourglass: + invoke AddSuspicion, 15 + jmp charm_penalty_done +charm_penalty_joker: + invoke AddSuspicion, 30 + jmp charm_penalty_done +charm_penalty_phoenix: + invoke AddSuspicion, 10 + jmp charm_penalty_done +charm_penalty_compass: + invoke AddSuspicion, 12 + jmp charm_penalty_done +charm_penalty_eye: + invoke AddSuspicion, 18 + jmp charm_penalty_done +charm_penalty_snake: + invoke AddSuspicion, 16 + jmp charm_penalty_done +charm_penalty_ace: + invoke AddSuspicion, 7 + jmp charm_penalty_done +charm_penalty_blood: + invoke AddSuspicion, 25 + mov ebx, 4 + jmp charm_take_fraction +charm_penalty_skull: + mov ebx, 2 + jmp charm_take_fraction +charm_penalty_tooth: + mov ebx, 5 + jmp charm_take_fraction +charm_penalty_candle: + invoke AddSuspicion, 35 + mov ebx, 3 + jmp charm_take_fraction +charm_penalty_devil: + invoke AddSuspicion, 45 + mov ebx, 2 +charm_take_fraction: + mov eax, currentBet + xor edx, edx + div ebx + cmp eax, 1 + jae charm_have_price + mov eax, 1 +charm_have_price: + cmp bankroll, eax + jae charm_sub_price + mov eax, bankroll +charm_sub_price: + sub bankroll, eax + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET charmPenaltyText + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + call ResetColor + +charm_penalty_done: + call RegisterDraw + invoke UnlockAchievement, 20h, OFFSET achCharmName + cmp shopCharmUses, 0 + jne charm_still_alive + mov shopCharmLevel, 0 + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET shopCharmBurnText + call ResetColor +charm_still_alive: + call SaveGame + call PrintBank + call PrintCroupierDraw + mov eax, 1 + ret +TryCharmSave ENDP + +; --- PayLose: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +PayLose PROC + cmp cheatGodMode, 0 + jne pay_lose_cheat_win + cmp cheatLuckyWin, 0 + jne pay_lose_cheat_once + jmp pay_lose_normal +pay_lose_cheat_once: + mov cheatLuckyWin, 0 +pay_lose_cheat_win: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET cheatSavedText + call ResetColor + call PayWin + ret +pay_lose_normal: + call TryCharmSave + cmp eax, 1 + je pay_lose_charm_saved + mov eax, currentBet + cmp bankroll, eax + jae pay_lose_sub + mov bankroll, 0 + jmp pay_lose_done +pay_lose_sub: + sub bankroll, eax +pay_lose_done: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET moneyLoseText + invoke PrintUInt, currentBet + call ResetColor + invoke PrintStr, OFFSET nl + invoke RegisterLoss, currentBet + call PrintBank + call PrintCroupierLose + call CheckBankrupt +pay_lose_charm_saved: + ret +PayLose ENDP + +; --- PayDraw: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +PayDraw PROC + mov lastGameResult, 3 + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET moneyDrawText + call ResetColor + call RegisterDraw + call PrintBank + call PrintCroupierDraw + ret +PayDraw ENDP + +; --- PaySlotPair: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +PaySlotPair PROC + mov lastGameResult, 1 + mov eax, currentBet + add bankroll, eax + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET moneyWinText + invoke PrintUInt, currentBet + call ResetColor + invoke PrintStr, OFFSET nl + call PrintBank + ret +PaySlotPair ENDP + +; --- PaySlotJackpot: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +PaySlotJackpot PROC uses ebx + mov lastGameResult, 1 + mov eax, currentBet + mov ebx, 5 + mul ebx + add bankroll, eax + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET moneyWinText + invoke PrintUInt, eax + call ResetColor + invoke PrintStr, OFFSET nl + call PrintBank + invoke UnlockAchievement, 4, OFFSET achJackpotName + ret +PaySlotJackpot ENDP + +; --- ConfigureConsoleSize: çàäàåò ñòàðòîâûé ðàçìåð îêíà êîíñîëè áåç ìàñøòàáèðîâàíèÿ ASCII --- +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: ñëóæåáíûå ôóíêöèè êîíñîëè è ñëó÷àéíûõ ÷èñåë --- +HomeCursor PROC + invoke SetConsoleCursorPosition, hOut, 0 + ret +HomeCursor ENDP + +; --- ClearView: ñëóæåáíûå ôóíêöèè êîíñîëè è ñëó÷àéíûõ ÷èñåë --- +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: ñëóæåáíûå ôóíêöèè êîíñîëè è ñëó÷àéíûõ ÷èñåë --- +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 + +; --- ResetDeck: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +ResetDeck PROC uses ecx edi + mov ecx, 52 + mov edi, OFFSET deckUsed +reset_loop: + mov byte ptr [edi], 0 + inc edi + loop reset_loop + ret +ResetDeck ENDP + +; --- DrawCard: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +DrawCard PROC uses edi +draw_again: + invoke RandomRange, 52 + mov edi, OFFSET deckUsed + add edi, eax + cmp byte ptr [edi], 0 + jne draw_again + mov byte ptr [edi], 1 + ret +DrawCard ENDP +; --- CardValue21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +CardValue21 PROC uses ecx edx, card:DWORD + mov eax, card + xor edx, edx + mov ecx, 13 + div ecx + mov eax, edx + cmp eax, 8 + jbe numeric_card + cmp eax, 9 + je jack_card + cmp eax, 10 + je queen_card + cmp eax, 11 + je king_card + mov eax, 11 + ret +numeric_card: + add eax, 2 + ret +jack_card: + mov eax, 2 + ret +queen_card: + mov eax, 3 + ret +king_card: + mov eax, 4 + ret +CardValue21 ENDP + +; --- CardValueBJ: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +CardValueBJ PROC uses ecx edx, card:DWORD + mov eax, card + xor edx, edx + mov ecx, 13 + div ecx + mov eax, edx + cmp eax, 8 + jbe bj_numeric + cmp eax, 12 + je bj_ace + mov eax, 10 + ret +bj_numeric: + add eax, 2 + ret +bj_ace: + mov eax, 11 + ret +CardValueBJ ENDP + +; --- AdjustPlayerAces: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +AdjustPlayerAces PROC +adjust_player: + cmp playerTotal, 21 + jbe adjust_player_done + cmp playerAces, 0 + je adjust_player_done + sub playerTotal, 10 + dec playerAces + jmp adjust_player +adjust_player_done: + ret +AdjustPlayerAces ENDP + +; --- AdjustDealerAces: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +AdjustDealerAces PROC +adjust_dealer: + cmp dealerTotal, 21 + jbe adjust_dealer_done + cmp dealerAces, 0 + je adjust_dealer_done + sub dealerTotal, 10 + dec dealerAces + jmp adjust_dealer +adjust_dealer_done: + ret +AdjustDealerAces ENDP + +; --- PrintScore: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintScore PROC + invoke PrintStr, OFFSET yourScoreText + invoke PrintUInt, playerTotal + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET dealerScoreText + invoke PrintUInt, dealerTotal + invoke PrintStr, OFFSET nl + ret +PrintScore ENDP + +; --- PrintCard: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCard PROC uses eax ebx ecx edx esi, card:DWORD + mov eax, card + xor edx, edx + mov ecx, 13 + div ecx + mov ebx, eax + mov esi, edx + + invoke PrintUtf8, OFFSET cardTop + invoke PrintUtf8, OFFSET cardSuitLeft + invoke PrintSuit, ebx + invoke PrintUtf8, OFFSET cardSuitRight + + cmp esi, 8 + jne one_rank + invoke PrintUtf8, OFFSET cardRankTenL + invoke PrintStr, ranks[esi * 4] + invoke PrintUtf8, OFFSET cardRankTenR + jmp rank_done +one_rank: + invoke PrintUtf8, OFFSET cardRankOneL + invoke PrintStr, ranks[esi * 4] + invoke PrintUtf8, OFFSET cardRankOneR +rank_done: + invoke PrintUtf8, OFFSET cardEmpty + invoke PrintUtf8, OFFSET cardEmpty + invoke PrintUtf8, OFFSET cardCenterL + invoke PrintSuit, ebx + invoke PrintUtf8, OFFSET cardCenterR + invoke PrintUtf8, OFFSET cardBottom + ret +PrintCard ENDP + +; --- AddPlayer21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +AddPlayer21 PROC uses eax ebx + call PlayCardSound + call DrawCard + mov ebx, eax + invoke PrintStr, OFFSET yourCardText + invoke PrintCard, ebx + invoke CardValue21, ebx + add playerTotal, eax + ret +AddPlayer21 ENDP + +; --- AddDealer21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +AddDealer21 PROC uses eax ebx + call PlayCardSound + call DrawCard + mov ebx, eax + invoke PrintStr, OFFSET dealerCardText + invoke PrintCard, ebx + invoke CardValue21, ebx + add dealerTotal, eax + ret +AddDealer21 ENDP + +; --- Reset21Hands: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +Reset21Hands PROC + mov playerTotal, 0 + mov dealerTotal, 0 + mov playerCnt21, 0 + mov aiCnt21, 0 + mov revealAI21, 0 + ret +Reset21Hands ENDP + +; --- DrawPlayer21Hand: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +DrawPlayer21Hand PROC uses ebx ecx + cmp playerCnt21, 10 + jae draw_player21_done + call PlayCardSound + call DrawCard + mov ebx, playerCnt21 + mov playerHand21[ebx * 4], eax + inc playerCnt21 +draw_player21_done: + ret +DrawPlayer21Hand ENDP + +; --- DrawAI21Hand: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +DrawAI21Hand PROC uses ebx ecx + cmp aiCnt21, 10 + jae draw_ai21_done + call PlayCardSound + call DrawCard + mov ebx, aiCnt21 + mov aiHand21[ebx * 4], eax + inc aiCnt21 +draw_ai21_done: + ret +DrawAI21Hand ENDP + +; --- PrintHandTop: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintHandTop PROC uses eax, count:DWORD + mov rowIndex, 0 +top_loop: + mov eax, rowIndex + cmp eax, count + jae top_done + invoke PrintUtf8, OFFSET cardTopSeg + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp top_loop +top_done: + invoke PrintStr, OFFSET nl + ret +PrintHandTop ENDP + +; --- PrintHandBottom: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintHandBottom PROC uses eax, count:DWORD + mov rowIndex, 0 +bottom_loop: + mov eax, rowIndex + cmp eax, count + jae bottom_done + invoke PrintUtf8, OFFSET cardBottomSeg + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp bottom_loop +bottom_done: + invoke PrintStr, OFFSET nl + ret +PrintHandBottom ENDP + +; --- PrintHandBlankLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintHandBlankLine PROC uses eax, count:DWORD, reveal:DWORD + mov rowIndex, 0 +blank_loop: + mov eax, rowIndex + cmp eax, count + jae blank_done + cmp reveal, 0 + je blank_hidden + invoke PrintUtf8, OFFSET cardEmptySeg + jmp blank_next +blank_hidden: + call SetCardBackColor + invoke PrintCardBackSegLine, 4 + call ResetColor +blank_next: + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp blank_loop +blank_done: + invoke PrintStr, OFFSET nl + ret +PrintHandBlankLine ENDP + +; --- PrintHandSuitLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintHandSuitLine PROC uses eax ebx ecx edx, pHand:DWORD, count:DWORD, reveal:DWORD + LOCAL suitIndex:DWORD + + mov rowIndex, 0 +suit_loop: + mov eax, rowIndex + cmp eax, count + jae suit_done + cmp reveal, 0 + je suit_hidden + + mov ebx, pHand + mov eax, [ebx + eax * 4] + xor edx, edx + mov ecx, 13 + div ecx + mov suitIndex, eax + + invoke PrintUtf8, OFFSET cardSuitLeft + mov eax, suitIndex + invoke PrintSuit, eax + invoke PrintUtf8, OFFSET cardSuitRightSeg + jmp suit_next +suit_hidden: + call SetCardBackColor + invoke PrintCardBackSegLine, 1 + call ResetColor +suit_next: + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp suit_loop +suit_done: + invoke PrintStr, OFFSET nl + ret +PrintHandSuitLine ENDP + +; --- PrintHandRankLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintHandRankLine PROC uses eax ebx ecx edx, pHand:DWORD, count:DWORD, reveal:DWORD + LOCAL rankIndex:DWORD + + mov rowIndex, 0 +rank_loop_row: + mov eax, rowIndex + cmp eax, count + jae rank_done_row + cmp reveal, 0 + je rank_hidden + + mov ebx, pHand + mov eax, [ebx + eax * 4] + xor edx, edx + mov ecx, 13 + div ecx + mov rankIndex, edx + + cmp edx, 8 + jne rank_one_char + invoke PrintUtf8, OFFSET cardRankTenL + mov eax, rankIndex + invoke PrintStr, ranks[eax * 4] + invoke PrintUtf8, OFFSET cardRankTenRSeg + jmp rank_next +rank_one_char: + invoke PrintUtf8, OFFSET cardRankOneL + mov eax, rankIndex + invoke PrintStr, ranks[eax * 4] + invoke PrintUtf8, OFFSET cardRankOneRSeg + jmp rank_next +rank_hidden: + call SetCardBackColor + invoke PrintCardBackSegLine, 2 + call ResetColor +rank_next: + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp rank_loop_row +rank_done_row: + invoke PrintStr, OFFSET nl + ret +PrintHandRankLine ENDP + +; --- PrintHandCenterLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintHandCenterLine PROC uses eax ebx ecx edx, pHand:DWORD, count:DWORD, reveal:DWORD + LOCAL suitIndex:DWORD + + mov rowIndex, 0 +center_loop: + mov eax, rowIndex + cmp eax, count + jae center_done + cmp reveal, 0 + je center_hidden + + mov ebx, pHand + mov eax, [ebx + eax * 4] + xor edx, edx + mov ecx, 13 + div ecx + mov suitIndex, eax + + invoke PrintUtf8, OFFSET cardCenterL + mov eax, suitIndex + invoke PrintSuit, eax + invoke PrintUtf8, OFFSET cardCenterRSeg + jmp center_next +center_hidden: + call SetCardBackColor + invoke PrintCardBackSegLine, 5 + call ResetColor +center_next: + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp center_loop +center_done: + invoke PrintStr, OFFSET nl + ret +PrintHandCenterLine ENDP + +; --- PrintHandRow21: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintHandRow21 PROC pHand:DWORD, count:DWORD, reveal:DWORD + invoke PrintHandTop, count + invoke PrintHandSuitLine, pHand, count, reveal + invoke PrintHandRankLine, pHand, count, reveal + invoke PrintHandBlankLine, count, reveal + invoke PrintHandBlankLine, count, reveal + invoke PrintHandCenterLine, pHand, count, reveal + invoke PrintHandBottom, count + ret +PrintHandRow21 ENDP + +; --- PrintCommunitySuitLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCommunitySuitLine PROC uses eax ebx ecx edx + LOCAL suitIndex:DWORD + + mov rowIndex, 0 +community_suit_loop: + mov eax, rowIndex + cmp eax, 5 + jae community_suit_done + cmp eax, communityCnt + jae community_suit_hidden + + mov eax, communityHand[eax * 4] + xor edx, edx + mov ecx, 13 + div ecx + mov suitIndex, eax + invoke PrintUtf8, OFFSET cardSuitLeft + mov eax, suitIndex + invoke PrintSuit, eax + invoke PrintUtf8, OFFSET cardSuitRightSeg + jmp community_suit_next +community_suit_hidden: + call SetCardBackColor + invoke PrintCardBackSegLine, 1 + call ResetColor +community_suit_next: + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp community_suit_loop +community_suit_done: + invoke PrintStr, OFFSET nl + ret +PrintCommunitySuitLine ENDP + +; --- PrintCommunityRankLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCommunityRankLine PROC uses eax ecx edx + LOCAL rankIndex:DWORD + + mov rowIndex, 0 +community_rank_loop: + mov eax, rowIndex + cmp eax, 5 + jae community_rank_done + cmp eax, communityCnt + jae community_rank_hidden + + mov eax, communityHand[eax * 4] + xor edx, edx + mov ecx, 13 + div ecx + mov rankIndex, edx + cmp edx, 8 + jne community_rank_one + invoke PrintUtf8, OFFSET cardRankTenL + mov eax, rankIndex + invoke PrintStr, ranks[eax * 4] + invoke PrintUtf8, OFFSET cardRankTenRSeg + jmp community_rank_next +community_rank_one: + invoke PrintUtf8, OFFSET cardRankOneL + mov eax, rankIndex + invoke PrintStr, ranks[eax * 4] + invoke PrintUtf8, OFFSET cardRankOneRSeg + jmp community_rank_next +community_rank_hidden: + call SetCardBackColor + invoke PrintCardBackSegLine, 2 + call ResetColor +community_rank_next: + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp community_rank_loop +community_rank_done: + invoke PrintStr, OFFSET nl + ret +PrintCommunityRankLine ENDP + +; --- PrintCommunityBlankLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCommunityBlankLine PROC uses eax + mov rowIndex, 0 +community_blank_loop: + mov eax, rowIndex + cmp eax, 5 + jae community_blank_done + cmp eax, communityCnt + jae community_blank_hidden + invoke PrintUtf8, OFFSET cardEmptySeg + jmp community_blank_next +community_blank_hidden: + call SetCardBackColor + invoke PrintCardBackSegLine, 4 + call ResetColor +community_blank_next: + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp community_blank_loop +community_blank_done: + invoke PrintStr, OFFSET nl + ret +PrintCommunityBlankLine ENDP + +; --- PrintCommunityCenterLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCommunityCenterLine PROC uses eax ecx edx + LOCAL suitIndex:DWORD + + mov rowIndex, 0 +community_center_loop: + mov eax, rowIndex + cmp eax, 5 + jae community_center_done + cmp eax, communityCnt + jae community_center_hidden + + mov eax, communityHand[eax * 4] + xor edx, edx + mov ecx, 13 + div ecx + mov suitIndex, eax + invoke PrintUtf8, OFFSET cardCenterL + mov eax, suitIndex + invoke PrintSuit, eax + invoke PrintUtf8, OFFSET cardCenterRSeg + jmp community_center_next +community_center_hidden: + call SetCardBackColor + invoke PrintCardBackSegLine, 5 + call ResetColor +community_center_next: + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp community_center_loop +community_center_done: + invoke PrintStr, OFFSET nl + ret +PrintCommunityCenterLine ENDP + +; --- PrintCommunityRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCommunityRow PROC + invoke PrintHandTop, 5 + call PrintCommunitySuitLine + call PrintCommunityRankLine + call PrintCommunityBlankLine + call PrintCommunityBlankLine + call PrintCommunityCenterLine + invoke PrintHandBottom, 5 + ret +PrintCommunityRow ENDP + +; --- PrintFlipLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintFlipLine PROC uses eax, count:DWORD, pSegment:DWORD + mov rowIndex, 0 +flip_line_loop: + mov eax, rowIndex + cmp eax, count + jae flip_line_done + invoke PrintUtf8, pSegment + invoke PrintUtf8, OFFSET cardGap + inc rowIndex + jmp flip_line_loop +flip_line_done: + invoke PrintStr, OFFSET nl + ret +PrintFlipLine ENDP + +; --- PrintFlipCards: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintFlipCards PROC count:DWORD, pSegment:DWORD + invoke PrintHandTop, count + invoke PrintFlipLine, count, pSegment + invoke PrintFlipLine, count, pSegment + invoke PrintFlipLine, count, pSegment + invoke PrintFlipLine, count, pSegment + invoke PrintFlipLine, count, pSegment + invoke PrintHandBottom, count + ret +PrintFlipCards ENDP + +; --- ShowRevealFrame21: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +ShowRevealFrame21 PROC pSegment:DWORD + call ClearView + invoke PrintTitleColor, OFFSET twentyOneTitle + invoke PrintStr, OFFSET revealText + invoke PrintStr, OFFSET aiCardsText + invoke PrintFlipCards, aiCnt21, pSegment + invoke PrintStr, OFFSET playerCardsText + invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 + call CalcPlayerScore21 + invoke PrintStr, OFFSET yourScoreText + invoke PrintUInt, playerTotal + invoke PrintStr, OFFSET nl + ret +ShowRevealFrame21 ENDP + +; --- AnimateReveal21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +AnimateReveal21 PROC + call PlayCardSound + invoke ShowRevealFrame21, OFFSET cardBackSeg + invoke Sleep, FLIP_DELAY + invoke ShowRevealFrame21, OFFSET cardFlipLeft + invoke Sleep, FLIP_DELAY + invoke ShowRevealFrame21, OFFSET cardFlipMid + invoke Sleep, FLIP_DELAY + invoke ShowRevealFrame21, OFFSET cardFlipRight + invoke Sleep, FLIP_DELAY + mov revealAI21, 1 + call ClearView + invoke PrintTitleColor, OFFSET twentyOneTitle + call ShowAllCards21 + invoke Sleep, FLIP_FINAL_DELAY + ret +AnimateReveal21 ENDP + +; --- CalcPlayerScore21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +CalcPlayerScore21 PROC uses eax ebx + mov playerTotal, 0 + mov rowIndex, 0 +calc_player21_loop: + mov eax, rowIndex + cmp eax, playerCnt21 + jae calc_player21_done + mov ebx, playerHand21[eax * 4] + invoke CardValue21, ebx + add playerTotal, eax + inc rowIndex + jmp calc_player21_loop +calc_player21_done: + ret +CalcPlayerScore21 ENDP + +; --- CalcAIScore21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +CalcAIScore21 PROC uses eax ebx + mov dealerTotal, 0 + mov rowIndex, 0 +calc_ai21_loop: + mov eax, rowIndex + cmp eax, aiCnt21 + jae calc_ai21_done + mov ebx, aiHand21[eax * 4] + invoke CardValue21, ebx + add dealerTotal, eax + inc rowIndex + jmp calc_ai21_loop +calc_ai21_done: + ret +CalcAIScore21 ENDP + +; --- ShowAllCards21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +ShowAllCards21 PROC + cmp revealAI21, 0 + jne show_ai_cards + invoke PrintStr, OFFSET aiThinkText +show_ai_cards: + invoke PrintStr, OFFSET aiCardsText + invoke PrintHandRow21, OFFSET aiHand21, aiCnt21, revealAI21 + invoke PrintStr, OFFSET playerCardsText + invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 + + call CalcPlayerScore21 + call CalcAIScore21 + invoke PrintStr, OFFSET yourScoreText + invoke PrintUInt, playerTotal + invoke PrintStr, OFFSET nl + cmp revealAI21, 0 + je show_cards_done + invoke PrintStr, OFFSET aiScoreText + invoke PrintUInt, dealerTotal + invoke PrintStr, OFFSET nl +show_cards_done: + ret +ShowAllCards21 ENDP +; --- PeekUnusedCard: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +PeekUnusedCard PROC uses edi +peek_unused_again: + invoke RandomRange, 52 + mov edi, OFFSET deckUsed + add edi, eax + cmp byte ptr [edi], 0 + jne peek_unused_again + ret +PeekUnusedCard ENDP + +; --- CheatPeek21: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +CheatPeek21 PROC uses eax ebx + invoke PrintStr, OFFSET cheatPeekText + call PeekUnusedCard + mov ebx, eax + invoke PrintCard, ebx + invoke AddSuspicion, 12 + call CheckCasinoHeat + call PauseConsole + ret +CheatPeek21 ENDP + +; --- CheatSwap21: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +CheatSwap21 PROC uses eax ebx + cmp playerCnt21, 0 + je cheat_swap21_none + call DrawCard + mov ebx, playerCnt21 + dec ebx + mov playerHand21[ebx * 4], eax + call CalcPlayerScore21 + invoke PrintStr, OFFSET cheatSwapText + invoke AddSuspicion, 18 + call CheckCasinoHeat + call PauseConsole + ret +cheat_swap21_none: + invoke PrintStr, OFFSET cheatNoTargetText + call PauseConsole + ret +CheatSwap21 ENDP + +; --- CheatPeekPoker: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +CheatPeekPoker PROC uses eax ebx + mov ebx, communityCnt + cmp ebx, 5 + jb cheat_peek_poker_table + invoke PrintStr, OFFSET cheatPeekText + mov ebx, 0 + mov eax, aiHand21[ebx * 4] + invoke PrintCard, eax + jmp cheat_peek_poker_done +cheat_peek_poker_table: + invoke PrintStr, OFFSET cheatPeekText + mov eax, communityHand[ebx * 4] + invoke PrintCard, eax +cheat_peek_poker_done: + invoke AddSuspicion, 12 + call CheckCasinoHeat + call PauseConsole + ret +CheatPeekPoker ENDP + +; --- CheatSwapPoker: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +CheatSwapPoker PROC uses eax + cmp playerCnt21, 0 + je cheat_swap_poker_none + call DrawCard + mov DWORD PTR playerHand21[0], eax + invoke PrintStr, OFFSET cheatSwapText + invoke AddSuspicion, 18 + call CheckCasinoHeat + call PauseConsole + ret +cheat_swap_poker_none: + invoke PrintStr, OFFSET cheatNoTargetText + call PauseConsole + ret +CheatSwapPoker ENDP + + +; --- CountDanger21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +CountDanger21 PROC uses eax ebx esi + call CalcAIScore21 + mov dangerLvl21, 0 + mov cardsLeft21, 0 + mov rowIndex, 0 +danger_loop: + mov eax, rowIndex + cmp eax, 52 + jae danger_done + mov esi, OFFSET deckUsed + cmp byte ptr [esi + eax], 0 + jne danger_next + + inc cardsLeft21 + invoke CardValue21, rowIndex + mov ebx, dealerTotal + add ebx, eax + cmp ebx, 21 + jbe danger_next + inc dangerLvl21 +danger_next: + inc rowIndex + jmp danger_loop +danger_done: + ret +CountDanger21 ENDP + +; --- FinalScreen21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +FinalScreen21 PROC + call ClearView + mov revealAI21, 1 + call ShowAllCards21 + + mov eax, playerTotal + mov ebx, dealerTotal + cmp eax, 21 + ja final_21_lose + cmp ebx, 21 + ja final_21_win + cmp eax, ebx + ja final_21_win + jb final_21_lose + call PrintDrawEvent + call PayDraw + ret +final_21_win: + call PrintWinEvent + call PayWin + ret +final_21_lose: + call PrintLoseEvent + call PayLose + ret +FinalScreen21 ENDP + +; --- ResetPokerHands: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +ResetPokerHands PROC + mov playerCnt21, 0 + mov aiCnt21, 0 + mov communityCnt, 0 + mov revealAI21, 0 + ret +ResetPokerHands ENDP + +; --- DrawCommunityPoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +DrawCommunityPoker PROC uses ebx ecx + cmp communityCnt, 5 + jae draw_community_done + call PlayCardSound + call DrawCard + mov ebx, communityCnt + mov communityHand[ebx * 4], eax + inc communityCnt +draw_community_done: + ret +DrawCommunityPoker ENDP + +; --- DealPokerHands: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +DealPokerHands PROC uses ecx + mov ecx, 2 +deal_poker_hands_loop: + call DrawPlayer21Hand + call DrawAI21Hand + loop deal_poker_hands_loop + + mov ecx, 5 +deal_poker_table_loop: + call DrawCommunityPoker + loop deal_poker_table_loop + mov communityCnt, 3 + ret +DealPokerHands ENDP + +; --- ShowPokerTable: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +ShowPokerTable PROC + invoke PrintStr, OFFSET aiCardsText + invoke PrintHandRow21, OFFSET aiHand21, aiCnt21, revealAI21 + invoke PrintStr, OFFSET pokerTableText + call PrintCommunityRow + invoke PrintStr, OFFSET playerCardsText + invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 + ret +ShowPokerTable ENDP + +; --- ShowPokerRevealFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +ShowPokerRevealFrame PROC pSegment:DWORD + call ClearView + invoke PrintTitleColor, OFFSET pokerTitle + invoke PrintStr, OFFSET pokerRevealText + invoke PrintStr, OFFSET aiCardsText + invoke PrintFlipCards, aiCnt21, pSegment + invoke PrintStr, OFFSET pokerTableText + call PrintCommunityRow + invoke PrintStr, OFFSET playerCardsText + invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 + ret +ShowPokerRevealFrame ENDP + +; --- AnimateRevealPoker: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +AnimateRevealPoker PROC + call PlayCardSound + invoke ShowPokerRevealFrame, OFFSET cardBackSeg + invoke Sleep, FLIP_DELAY + invoke ShowPokerRevealFrame, OFFSET cardFlipLeft + invoke Sleep, FLIP_DELAY + invoke ShowPokerRevealFrame, OFFSET cardFlipMid + invoke Sleep, FLIP_DELAY + invoke ShowPokerRevealFrame, OFFSET cardFlipRight + invoke Sleep, FLIP_DELAY + mov revealAI21, 1 + call ClearView + invoke PrintTitleColor, OFFSET pokerTitle + call ShowPokerTable + invoke Sleep, FLIP_FINAL_DELAY + ret +AnimateRevealPoker ENDP + +; --- ClearPokerCounts: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +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: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +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 + +; --- EvaluatePoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +EvaluatePoker PROC pHand:DWORD + invoke EvaluatePokerN, pHand, 5 + ret +EvaluatePoker ENDP + +; --- PrintPokerHandName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintPokerHandName PROC uses eax ebx edx, score:DWORD + mov eax, score + xor edx, edx + mov ebx, 1000 + div ebx + invoke PrintStr, pokerNames[eax * 4] + ret +PrintPokerHandName ENDP + +; --- BuildPokerEvalHand: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +BuildPokerEvalHand PROC uses eax ebx esi edi, pHole:DWORD, pOut:DWORD + mov esi, pHole + mov edi, pOut + + mov eax, [esi] + mov [edi], eax + mov eax, [esi + 4] + mov [edi + 4], eax + + mov eax, communityCnt + add eax, 2 + mov pokerEvalCount, eax + + mov ebx, 0 +build_table_cards: + cmp ebx, communityCnt + jae build_eval_done + mov eax, communityHand[ebx * 4] + mov [edi + ebx * 4 + 8], eax + inc ebx + jmp build_table_cards +build_eval_done: + ret +BuildPokerEvalHand ENDP + +; --- ShowPokerHint: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +ShowPokerHint PROC + invoke BuildPokerEvalHand, OFFSET playerHand21, OFFSET pokerPlayerEvalHand + invoke EvaluatePokerN, OFFSET pokerPlayerEvalHand, pokerEvalCount + mov pokerPlayerScore, eax + invoke PrintStr, OFFSET pokerHintText + invoke PrintPokerHandName, pokerPlayerScore + ret +ShowPokerHint ENDP + +; --- ShowPokerResult: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +ShowPokerResult PROC uses ebx + invoke BuildPokerEvalHand, OFFSET playerHand21, OFFSET pokerPlayerEvalHand + mov ebx, pokerEvalCount + invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand + mov pokerEvalCount, ebx + + invoke EvaluatePokerN, OFFSET pokerPlayerEvalHand, pokerEvalCount + mov pokerPlayerScore, eax + invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount + mov pokerAIScore, eax + + invoke PrintStr, OFFSET pokerYourComboText + invoke PrintPokerHandName, pokerPlayerScore + invoke PrintStr, OFFSET pokerAIComboText + invoke PrintPokerHandName, pokerAIScore + + mov eax, pokerPlayerScore + cmp eax, pokerAIScore + ja poker_player_win + jb poker_ai_win + call PrintDrawEvent + call PayDraw + ret +poker_player_win: + call PrintWinEvent + call PayWin + ret +poker_ai_win: + call PrintLoseEvent + call PayLose + ret +ShowPokerResult ENDP + +; --- PokerAIDecide: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +PokerAIDecide PROC uses ebx edx + invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand + invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount + mov pokerAIScore, eax + + mov eax, pokerAIScore + xor edx, edx + mov ebx, 1000 + div ebx + cmp eax, 1 + jae ai_will_play + + cmp aiDifficulty, 1 + je ai_easy_decide + cmp aiDifficulty, 3 + je ai_hard_decide + +ai_normal_decide: + mov eax, pokerAIScore + cmp eax, 11 + jae ai_normal_random + jmp ai_will_fold +ai_normal_random: + invoke RandomRange, 3 + cmp eax, 0 + je ai_will_fold + jmp ai_will_play + +ai_easy_decide: + invoke RandomRange, 2 + cmp eax, 0 + je ai_will_play + mov eax, pokerAIScore + cmp eax, 10 + jae ai_will_play + jmp ai_will_fold + +ai_hard_decide: + mov eax, pokerAIScore + cmp eax, 10 + jae ai_hard_high_card + invoke RandomRange, 3 + cmp eax, 0 + je ai_will_play + jmp ai_will_fold +ai_hard_high_card: + invoke RandomRange, 4 + cmp eax, 0 + je ai_will_fold + jmp ai_will_play + +ai_will_fold: + xor eax, eax + ret +ai_will_play: + mov eax, 1 + ret +PokerAIDecide ENDP + +; --- PokerAICallRaise: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +PokerAICallRaise PROC uses ebx ecx edx + invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand + invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount + mov pokerAIScore, eax + + mov eax, pokerAIScore + xor edx, edx + mov ebx, 1000 + div ebx + mov ecx, eax + cmp ecx, 1 + jae ai_call_raise + + mov eax, pokerRaiseAmount + mov ebx, 2 + mul ebx + cmp eax, currentBet + ja ai_big_raise + + cmp aiDifficulty, 1 + je ai_easy_call_bluff + cmp aiDifficulty, 3 + je ai_hard_call_bluff + invoke RandomRange, 3 + cmp eax, 0 + jne ai_call_raise + jmp ai_fold_raise + +ai_big_raise: + cmp aiDifficulty, 1 + je ai_easy_big_raise + cmp aiDifficulty, 3 + je ai_fold_raise + invoke RandomRange, 5 + cmp eax, 0 + je ai_call_raise + jmp ai_fold_raise + +ai_easy_call_bluff: + invoke RandomRange, 2 + cmp eax, 0 + je ai_call_raise + jmp ai_fold_raise + +ai_easy_big_raise: + invoke RandomRange, 3 + cmp eax, 0 + jne ai_call_raise + jmp ai_fold_raise + +ai_hard_call_bluff: + mov eax, pokerAIScore + cmp eax, 12 + jae ai_call_raise + jmp ai_fold_raise + +ai_fold_raise: + xor eax, eax + ret +ai_call_raise: + mov eax, 1 + ret +PokerAICallRaise ENDP + + +; --- HardPokerPlayerExchange: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +HardPokerPlayerExchange PROC uses eax ebx + cmp aiDifficulty, 3 + jne hard_player_exchange_done + call ClearView + invoke PrintTitleColor, OFFSET pokerTitle + call ShowPokerTable + call ShowPokerHint + invoke PrintStr, OFFSET pokerHardIntroText + invoke PrintStr, OFFSET pokerHardExchangeText + call ReadKey + cmp al, '1' + je hard_replace_first + cmp al, '2' + je hard_replace_second + jmp hard_player_exchange_done +hard_replace_first: + xor ebx, ebx + jmp hard_replace_card +hard_replace_second: + mov ebx, 1 +hard_replace_card: + call PlayCardSound + call DrawCard + mov playerHand21[ebx * 4], eax +hard_player_exchange_done: + ret +HardPokerPlayerExchange ENDP + +; --- HardPokerAIExchange: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +HardPokerAIExchange PROC uses eax ebx ecx edx + cmp aiDifficulty, 3 + jne hard_ai_exchange_done + invoke PrintStr, OFFSET pokerHardAIExchangeText + invoke Sleep, 650 + + mov eax, aiHand21[0] + xor edx, edx + mov ecx, 13 + div ecx + mov ebx, edx + + mov eax, aiHand21[4] + xor edx, edx + mov ecx, 13 + div ecx + + cmp ebx, edx + je hard_ai_exchange_done + cmp ebx, 8 + jb hard_ai_check_second + cmp edx, 8 + jae hard_ai_exchange_done + +hard_ai_check_second: + cmp ebx, edx + jbe hard_replace_ai_first + mov ebx, 1 + jmp hard_replace_ai_card +hard_replace_ai_first: + xor ebx, ebx +hard_replace_ai_card: + call PlayCardSound + call DrawCard + mov aiHand21[ebx * 4], eax +hard_ai_exchange_done: + ret +HardPokerAIExchange ENDP + +; --- PokerAIRaiseMaybe: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +PokerAIRaiseMaybe PROC uses ebx ecx edx + invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand + invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount + mov pokerAIScore, eax + + mov eax, bankroll + sub eax, currentBet + cmp eax, 0 + jbe ai_no_raise + mov ecx, eax + + mov eax, pokerAIScore + xor edx, edx + mov ebx, 1000 + div ebx + cmp eax, 2 + jae ai_strong_raise + cmp eax, 1 + je ai_pair_raise_check + + cmp aiDifficulty, 3 + jne ai_no_raise + mov eax, pokerAIScore + cmp eax, 12 + jne ai_no_raise + invoke RandomRange, 7 + cmp eax, 0 + jne ai_no_raise + mov eax, currentBet + xor edx, edx + mov ebx, 3 + div ebx + jmp ai_raise_amount_ready + +ai_pair_raise_check: + cmp aiDifficulty, 1 + je ai_easy_pair_raise + cmp aiDifficulty, 2 + je ai_normal_pair_raise + invoke RandomRange, 3 + cmp eax, 0 + je ai_no_raise + mov eax, currentBet + xor edx, edx + mov ebx, 2 + div ebx + jmp ai_raise_amount_ready + +ai_easy_pair_raise: + invoke RandomRange, 5 + cmp eax, 0 + jne ai_no_raise + mov eax, currentBet + xor edx, edx + mov ebx, 3 + div ebx + jmp ai_raise_amount_ready + +ai_normal_pair_raise: + invoke RandomRange, 3 + cmp eax, 0 + je ai_no_raise + mov eax, currentBet + xor edx, edx + mov ebx, 2 + div ebx + jmp ai_raise_amount_ready + +ai_strong_raise: + cmp aiDifficulty, 1 + je ai_easy_strong_raise + cmp aiDifficulty, 2 + je ai_normal_strong_raise + mov eax, currentBet + jmp ai_raise_amount_ready + +ai_easy_strong_raise: + invoke RandomRange, 3 + cmp eax, 0 + jne ai_no_raise + mov eax, currentBet + xor edx, edx + mov ebx, 2 + div ebx + jmp ai_raise_amount_ready + +ai_normal_strong_raise: + invoke RandomRange, 2 + cmp eax, 0 + je ai_no_raise + mov eax, currentBet + xor edx, edx + mov ebx, 2 + div ebx + jmp ai_raise_amount_ready + +ai_raise_amount_ready: + cmp eax, 50 + jae ai_raise_min_ok + mov eax, 50 +ai_raise_min_ok: + cmp eax, ecx + jbe ai_raise_store + mov eax, ecx +ai_raise_store: + cmp eax, 0 + jbe ai_no_raise + mov pokerAIRaiseAmount, eax + mov pokerRaiseAmount, eax + mov eax, 1 + ret +ai_no_raise: + xor eax, eax + ret +PokerAIRaiseMaybe ENDP +; --- PokerPlayerExchange: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +PokerPlayerExchange PROC uses eax ebx + mov pokerReplaceIndex, 0 +player_exchange_loop: + cmp pokerReplaceIndex, 5 + jae player_exchange_done + call ClearView + invoke PrintTitleColor, OFFSET pokerTitle + call ShowPokerTable + invoke PrintStr, OFFSET pokerReplaceText + mov eax, pokerReplaceIndex + inc eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET pokerReplaceTail + call ReadKey + cmp al, 'y' + je replace_player_card + cmp al, 'Y' + je replace_player_card + cmp al, '1' + je replace_player_card + jmp next_player_exchange +replace_player_card: + call DrawCard + mov ebx, pokerReplaceIndex + mov playerHand21[ebx * 4], eax +next_player_exchange: + inc pokerReplaceIndex + jmp player_exchange_loop +player_exchange_done: + ret +PokerPlayerExchange ENDP + +; --- PokerAIExchange: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +PokerAIExchange PROC uses eax ebx ecx edx + invoke EvaluatePoker, OFFSET aiHand21 + xor edx, edx + mov ebx, 1000 + div ebx + cmp eax, 4 + jae ai_exchange_done + + mov pokerReplaced, 0 + mov pokerReplaceIndex, 0 +ai_exchange_loop: + cmp pokerReplaceIndex, 5 + jae ai_exchange_done + cmp pokerReplaced, 3 + jae ai_exchange_done + + mov ebx, pokerReplaceIndex + mov eax, aiHand21[ebx * 4] + xor edx, edx + mov ecx, 13 + div ecx + cmp byte ptr rankCounts[edx], 1 + jne next_ai_exchange + call DrawCard + mov ebx, pokerReplaceIndex + mov aiHand21[ebx * 4], eax + inc pokerReplaced +next_ai_exchange: + inc pokerReplaceIndex + jmp ai_exchange_loop +ai_exchange_done: + ret +PokerAIExchange ENDP + +; --- AddPlayerBJ: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +AddPlayerBJ PROC uses eax ebx edx + call DrawCard + mov ebx, eax + invoke PrintStr, OFFSET yourCardText + invoke PrintCard, ebx + invoke CardValueBJ, ebx + add playerTotal, eax + cmp eax, 11 + jne no_player_ace + inc playerAces +no_player_ace: + inc playerCards + call AdjustPlayerAces + ret +AddPlayerBJ ENDP + +; --- AddDealerBJ: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +AddDealerBJ PROC uses eax ebx + call DrawCard + mov ebx, eax + invoke PrintStr, OFFSET dealerCardText + invoke PrintCard, ebx + invoke CardValueBJ, ebx + add dealerTotal, eax + cmp eax, 11 + jne no_dealer_ace + inc dealerAces +no_dealer_ace: + call AdjustDealerAces + ret +AddDealerBJ ENDP + +; --- CompareTotals: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +CompareTotals PROC + call PrintScore + cmp playerTotal, 21 + ja player_lost + cmp dealerTotal, 21 + ja dealer_lost + mov eax, playerTotal + cmp eax, dealerTotal + ja player_won + jb player_lost + call PrintDrawEvent + ret +player_won: + call PrintWinEvent + ret +player_lost: + call PrintLoseEvent + ret +dealer_lost: + invoke PrintStr, OFFSET dealerBustText + ret +CompareTotals ENDP + +; --- Game21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +Game21 PROC +start_21: + call ClearView + invoke PrintTitleColor, OFFSET twentyOneTitle + call PromptBet + call ResetDeck + call Reset21Hands + + call DrawPlayer21Hand + call DrawPlayer21Hand + call DrawAI21Hand + call DrawAI21Hand + +player_21_loop: + call ClearView + invoke PrintTitleColor, OFFSET twentyOneTitle + call ShowAllCards21 + + cmp playerTotal, 21 + ja player_21_bust + cmp playerTotal, 21 + je ai_21_turn + + invoke PrintStr, OFFSET hitText + invoke PrintStr, OFFSET cheatMoveText + call ReadKey + cmp al, '1' + je hit_21 + cmp al, 'y' + je hit_21 + cmp al, 'Y' + je hit_21 + cmp al, '3' + je cheat_peek_21_action + cmp al, '4' + je cheat_swap_21_action + jmp ai_21_turn +cheat_peek_21_action: + call CheatPeek21 + jmp player_21_loop +cheat_swap_21_action: + call CheatSwap21 + jmp player_21_loop +hit_21: + cmp playerCnt21, 10 + jae ai_21_turn + call DrawPlayer21Hand + jmp player_21_loop + +player_21_bust: + invoke PrintStr, OFFSET bustText + call PayLose + jmp ask_21_again + +ai_21_turn: +ai_21_cycle: + call ClearView + invoke PrintTitleColor, OFFSET twentyOneTitle + call ShowAllCards21 + + cmp playerTotal, 21 + ja finish_21 + cmp dealerTotal, 21 + je finish_21 + cmp aiDifficulty, 1 + je ai_21_easy + cmp aiDifficulty, 2 + je ai_21_normal + cmp dealerTotal, 12 + jb ai_21_must_hit + + mov eax, dealerTotal + cmp eax, playerTotal + jae finish_21 + + call CountDanger21 + mov eax, dangerLvl21 + mov ebx, 2 + mul ebx + cmp eax, cardsLeft21 + ja finish_21 + jmp ai_21_must_hit + +ai_21_easy: + cmp dealerTotal, 16 + jb ai_21_must_hit + jmp finish_21 + +ai_21_normal: + cmp dealerTotal, 17 + jb ai_21_must_hit + jmp finish_21 + +ai_21_must_hit: + cmp aiCnt21, 10 + jae finish_21 + invoke PrintStr, OFFSET aiMoveText + invoke Sleep, 650 + call DrawAI21Hand + call CalcAIScore21 + cmp dealerTotal, 21 + ja finish_21 + jmp ai_21_cycle + +finish_21: + call AnimateReveal21 + call FinalScreen21 +ask_21_again: + cmp tournamentMode, 1 + je game21_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je start_21 + cmp al, 'Y' + je start_21 +game21_tournament_return: + ret +Game21 ENDP + +; --- GamePoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +GamePoker PROC +poker_choose_mode: + call ClearView + invoke PrintTitleColor, OFFSET pokerTitle + invoke PrintStr, OFFSET pokerModeMenuText + call ReadKey + cmp al, '1' + je start_poker + cmp al, '2' + je poker_launch_multitable + cmp al, '0' + je poker_mode_exit + jmp poker_choose_mode + +poker_launch_multitable: + call GameMultiPoker + ret + +poker_mode_exit: + ret + +start_poker: + call ClearView + invoke PrintTitleColor, OFFSET pokerTitle + call PromptBet + call ResetDeck + call ResetPokerHands + call DealPokerHands + call HardPokerPlayerExchange + call HardPokerAIExchange + +poker_stage_loop: + call ClearView + invoke PrintTitleColor, OFFSET pokerTitle + call ShowPokerTable + call ShowPokerHint + call ShowPokerMoney + cmp communityCnt, 5 + jae poker_showdown + invoke PrintStr, OFFSET pokerDecisionText + invoke PrintStr, OFFSET cheatMoveText + call ReadKey + cmp al, '1' + je poker_play + cmp al, 'y' + je poker_play + cmp al, 'Y' + je poker_play + cmp al, '2' + je poker_raise + cmp al, 'r' + je poker_raise + cmp al, 'R' + je poker_raise + cmp al, '3' + je poker_cheat_peek + cmp al, '4' + je poker_cheat_swap + invoke PrintStr, OFFSET pokerFoldText + call PayLose + jmp ask_poker_again + +poker_cheat_peek: + call CheatPeekPoker + jmp poker_stage_loop +poker_cheat_swap: + call CheatSwapPoker + jmp poker_stage_loop + +poker_raise: + call PromptPokerRaise + cmp eax, 0 + je poker_stage_loop + invoke UnlockAchievement, 200h, OFFSET achPokerRaiseName + invoke PrintStr, OFFSET aiThinkText + invoke Sleep, 700 + call PokerAICallRaise + cmp eax, 0 + jne poker_raise_called + invoke PrintStr, OFFSET pokerAIFoldRaiseText + invoke UnlockAchievement, 400h, OFFSET achPokerBluffName + call PayWin + jmp ask_poker_again +poker_raise_called: + invoke PrintStr, OFFSET pokerAICallRaiseText + invoke Sleep, 700 + jmp poker_next_stage + +poker_play: + invoke PrintStr, OFFSET aiThinkText + invoke Sleep, 700 + call PokerAIDecide + cmp eax, 0 + jne poker_ai_plays + invoke PrintStr, OFFSET pokerAIFoldText + call PayWin + jmp ask_poker_again + +poker_ai_plays: + call PokerAIRaiseMaybe + cmp eax, 0 + je poker_next_stage + invoke PrintStr, OFFSET pokerAIRaiseText + invoke PrintUInt, pokerAIRaiseAmount + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET pokerCallRaiseText + call ReadKey + cmp al, '1' + je poker_call_ai_raise + cmp al, 'y' + je poker_call_ai_raise + cmp al, 'Y' + je poker_call_ai_raise + invoke PrintStr, OFFSET pokerFoldToRaiseText + call PayLose + jmp ask_poker_again +poker_call_ai_raise: + mov eax, currentBet + add eax, pokerAIRaiseAmount + cmp eax, bankroll + jbe poker_call_ai_raise_ok + invoke PrintStr, OFFSET tooBigBetText + invoke PrintStr, OFFSET pokerFoldToRaiseText + call PayLose + jmp ask_poker_again +poker_call_ai_raise_ok: + mov currentBet, eax + invoke PrintStr, OFFSET pokerPlayerCallText + invoke PrintUInt, currentBet + invoke PrintStr, OFFSET nl + invoke Sleep, 700 +poker_next_stage: + cmp communityCnt, 5 + jae poker_showdown + invoke PrintStr, OFFSET pokerNextCardText + invoke Sleep, 900 + inc communityCnt + jmp poker_stage_loop + +poker_showdown: + call AnimateRevealPoker + call ShowPokerResult + +ask_poker_again: + cmp tournamentMode, 1 + je poker_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je start_poker + cmp al, 'Y' + je start_poker +poker_tournament_return: + ret +GamePoker ENDP + +; --- PrintSlotSymbol: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSlotSymbol PROC uses eax, value:DWORD + mov eax, value + cmp eax, 0 + je slot_symbol_green + cmp eax, 1 + je slot_symbol_yellow + cmp eax, 2 + je slot_symbol_red + cmp eax, 3 + je slot_symbol_yellow + cmp eax, 4 + je slot_symbol_cyan + cmp eax, 5 + je slot_symbol_yellow + invoke SetColor, COLOR_BAD + jmp slot_symbol_print +slot_symbol_green: + invoke SetColor, COLOR_MONEY + jmp slot_symbol_print +slot_symbol_yellow: + invoke SetColor, COLOR_WARN + jmp slot_symbol_print +slot_symbol_red: + invoke SetColor, COLOR_BAD + jmp slot_symbol_print +slot_symbol_cyan: + invoke SetColor, COLOR_TITLE +slot_symbol_print: + mov eax, value + invoke PrintStr, slotSymbols[eax * 4] + call ResetColor + ret +PrintSlotSymbol ENDP + +; --- MoveCursor: ñëóæåáíûå ôóíêöèè êîíñîëè è ñëó÷àéíûõ ÷èñåë --- +MoveCursor PROC uses eax edx, xPos:DWORD, yPos:DWORD + mov eax, yPos + shl eax, 16 + mov edx, xPos + and edx, 0FFFFh + or eax, edx + invoke SetConsoleCursorPosition, hOut, eax + ret +MoveCursor ENDP + +; --- PrintSkullAt: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSkullAt PROC uses eax, xPos:DWORD, yPos:DWORD + mov eax, yPos + invoke MoveCursor, xPos, eax + invoke PrintUtf8, OFFSET skullSeg1 + mov eax, yPos + inc eax + invoke MoveCursor, xPos, eax + invoke PrintUtf8, OFFSET skullSeg2 + mov eax, yPos + add eax, 2 + invoke MoveCursor, xPos, eax + invoke PrintUtf8, OFFSET skullSeg3 + mov eax, yPos + add eax, 3 + invoke MoveCursor, xPos, eax + invoke PrintUtf8, OFFSET skullSeg4 + mov eax, yPos + add eax, 4 + invoke MoveCursor, xPos, eax + invoke PrintUtf8, OFFSET skullSeg5 + mov eax, yPos + add eax, 5 + invoke MoveCursor, xPos, eax + invoke PrintUtf8, OFFSET skullSeg6 + mov eax, yPos + add eax, 6 + invoke MoveCursor, xPos, eax + invoke PrintUtf8, OFFSET skullSeg7 + mov eax, yPos + add eax, 7 + invoke MoveCursor, xPos, eax + invoke PrintUtf8, OFFSET skullSeg8 + ret +PrintSkullAt ENDP + +; --- ShowSkullSlideFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +ShowSkullSlideFrame PROC x1:DWORD, y1:DWORD, x2:DWORD, y2:DWORD, x3:DWORD, y3:DWORD + call ClearView + invoke PrintTitleColor, OFFSET skullsTitle + invoke PrintStr, OFFSET skullsShuffleText + invoke PrintSkullAt, x1, y1 + invoke PrintSkullAt, x2, y2 + invoke PrintSkullAt, x3, y3 + invoke Sleep, 220 + ret +ShowSkullSlideFrame ENDP + +; --- AnimateSkullSwap12: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- +AnimateSkullSwap12 PROC + invoke ShowSkullSlideFrame, 0, 5, 18, 5, 36, 5 + invoke ShowSkullSlideFrame, 4, 6, 14, 4, 36, 5 + invoke ShowSkullSlideFrame, 8, 7, 10, 3, 36, 5 + invoke ShowSkullSlideFrame, 14, 6, 4, 4, 36, 5 + invoke ShowSkullSlideFrame, 18, 5, 0, 5, 36, 5 + ret +AnimateSkullSwap12 ENDP + +; --- AnimateSkullSwap23: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- +AnimateSkullSwap23 PROC + invoke ShowSkullSlideFrame, 0, 5, 18, 5, 36, 5 + invoke ShowSkullSlideFrame, 0, 5, 22, 6, 32, 4 + invoke ShowSkullSlideFrame, 0, 5, 26, 7, 28, 3 + invoke ShowSkullSlideFrame, 0, 5, 32, 6, 22, 4 + invoke ShowSkullSlideFrame, 0, 5, 36, 5, 18, 5 + ret +AnimateSkullSwap23 ENDP + +; --- AnimateSkullSwap13: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- +AnimateSkullSwap13 PROC + invoke ShowSkullSlideFrame, 0, 5, 18, 5, 36, 5 + invoke ShowSkullSlideFrame, 8, 7, 18, 5, 28, 3 + invoke ShowSkullSlideFrame, 18, 8, 18, 5, 18, 2 + invoke ShowSkullSlideFrame, 28, 7, 18, 5, 8, 3 + invoke ShowSkullSlideFrame, 36, 5, 18, 5, 0, 5 + ret +AnimateSkullSwap13 ENDP + + +; --- PrintSkullRows: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSkullRows PROC + invoke PrintUtf8, OFFSET skullSeg1 + invoke PrintUtf8, OFFSET skullSeg1 + invoke PrintUtf8, OFFSET skullSeg1 + invoke PrintStr, OFFSET nl + invoke PrintUtf8, OFFSET skullSeg2 + invoke PrintUtf8, OFFSET skullSeg2 + invoke PrintUtf8, OFFSET skullSeg2 + invoke PrintStr, OFFSET nl + invoke PrintUtf8, OFFSET skullSeg3 + invoke PrintUtf8, OFFSET skullSeg3 + invoke PrintUtf8, OFFSET skullSeg3 + invoke PrintStr, OFFSET nl + invoke PrintUtf8, OFFSET skullSeg4 + invoke PrintUtf8, OFFSET skullSeg4 + invoke PrintUtf8, OFFSET skullSeg4 + invoke PrintStr, OFFSET nl + invoke PrintUtf8, OFFSET skullSeg5 + invoke PrintUtf8, OFFSET skullSeg5 + invoke PrintUtf8, OFFSET skullSeg5 + invoke PrintStr, OFFSET nl + invoke PrintUtf8, OFFSET skullSeg6 + invoke PrintUtf8, OFFSET skullSeg6 + invoke PrintUtf8, OFFSET skullSeg6 + invoke PrintStr, OFFSET nl + invoke PrintUtf8, OFFSET skullSeg7 + invoke PrintUtf8, OFFSET skullSeg7 + invoke PrintUtf8, OFFSET skullSeg7 + invoke PrintStr, OFFSET nl + invoke PrintUtf8, OFFSET skullSeg8 + invoke PrintUtf8, OFFSET skullSeg8 + invoke PrintUtf8, OFFSET skullSeg8 + invoke PrintStr, OFFSET nl + ret +PrintSkullRows ENDP +; --- PrintSkulls: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSkulls PROC reveal:DWORD + call PrintSkullRows + invoke PrintStr, OFFSET skullNums + cmp reveal, 0 + je print_skull_blank_ball + mov eax, skullBallPos + cmp eax, 0 + je print_skull_ball_1 + cmp eax, 1 + je print_skull_ball_2 + invoke PrintStr, OFFSET skullBall3 + ret +print_skull_ball_1: + invoke PrintStr, OFFSET skullBall1 + ret +print_skull_ball_2: + invoke PrintStr, OFFSET skullBall2 + ret +print_skull_blank_ball: + invoke PrintStr, OFFSET skullBlankBall + ret +PrintSkulls ENDP +; --- PrintSkullFaces: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintSkullFaces PROC + call PrintSkullRows + invoke PrintStr, OFFSET skullBlankBall + ret +PrintSkullFaces ENDP +; --- ShowSkullShuffleFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +ShowSkullShuffleFrame PROC pSwapText:DWORD + call ClearView + invoke PrintTitleColor, OFFSET skullsTitle + invoke PrintStr, OFFSET skullsShuffleText + invoke PrintStr, pSwapText + call PrintSkullFaces + invoke Sleep, 400 + ret +ShowSkullShuffleFrame ENDP + +; --- ShuffleSkulls: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- +ShuffleSkulls PROC uses eax ebx + cmp aiDifficulty, 1 + je skulls_easy_steps + cmp aiDifficulty, 3 + je skulls_hard_steps + +skulls_normal_steps: + invoke RandomRange, 4 + add eax, 9 + jmp skulls_store_steps + +skulls_easy_steps: + invoke RandomRange, 4 + add eax, 5 + jmp skulls_store_steps + +skulls_hard_steps: + invoke RandomRange, 5 + add eax, 12 + +skulls_store_steps: + mov skullMax, eax + mov skullStep, 0 + +shuffle_skulls_loop: + mov eax, skullStep + cmp eax, skullMax + jae shuffle_skulls_done + + cmp skullStep, 0 + je skulls_play_first_move_sound + mov eax, skullMax + dec eax + cmp skullStep, eax + je skulls_play_last_move_sound + jmp skulls_after_move_sound + +skulls_play_first_move_sound: + call PlayStoneSound + invoke Sleep, 180 + jmp skulls_after_move_sound +skulls_play_last_move_sound: + call PlayStoneSound + +skulls_after_move_sound: + invoke RandomRange, 3 + cmp eax, 0 + je shuffle_12 + cmp eax, 1 + je shuffle_23 + jmp shuffle_13 + +shuffle_12: + mov eax, skullBallPos + cmp eax, 0 + je ball_12_to_2 + cmp eax, 1 + je ball_12_to_1 + jmp show_shuffle_12 +ball_12_to_2: + mov skullBallPos, 1 + jmp show_shuffle_12 +ball_12_to_1: + mov skullBallPos, 0 +show_shuffle_12: + call AnimateSkullSwap12 + jmp shuffle_next + +shuffle_23: + mov eax, skullBallPos + cmp eax, 1 + je ball_23_to_3 + cmp eax, 2 + je ball_23_to_2 + jmp show_shuffle_23 +ball_23_to_3: + mov skullBallPos, 2 + jmp show_shuffle_23 +ball_23_to_2: + mov skullBallPos, 1 +show_shuffle_23: + call AnimateSkullSwap23 + jmp shuffle_next + +shuffle_13: + mov eax, skullBallPos + cmp eax, 0 + je ball_13_to_3 + cmp eax, 2 + je ball_13_to_1 + jmp show_shuffle_13 +ball_13_to_3: + mov skullBallPos, 2 + jmp show_shuffle_13 +ball_13_to_1: + mov skullBallPos, 0 +show_shuffle_13: + call AnimateSkullSwap13 + +shuffle_next: + inc skullStep + jmp shuffle_skulls_loop +shuffle_skulls_done: + ret +ShuffleSkulls ENDP + +; --- GameSkulls: èãðà ñ ÷åðåïàìè è øàðèêîì, ïåðåìåøèâàíèå è îòðèñîâêà --- +GameSkulls PROC +skulls_start: + call ClearView + invoke PrintTitleColor, OFFSET skullsTitle + invoke PrintStr, OFFSET skullsIntroText + call PromptBet + invoke RandomRange, 3 + mov skullBallPos, eax + + call ClearView + invoke PrintTitleColor, OFFSET skullsTitle + invoke PrintStr, OFFSET skullsShowText + invoke PrintSkulls, 1 + invoke Sleep, 1600 + + call ClearView + invoke PrintTitleColor, OFFSET skullsTitle + invoke PrintStr, OFFSET skullsHideText + invoke PrintSkulls, 0 + invoke Sleep, 800 + + call ShuffleSkulls + +skulls_guess_again: + call ClearView + invoke PrintTitleColor, OFFSET skullsTitle + invoke PrintSkulls, 0 + invoke PrintStr, OFFSET skullsGuessText + call ReadKey + cmp al, '1' + je skull_guess_1 + cmp al, '2' + je skull_guess_2 + cmp al, '3' + je skull_guess_3 + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp skulls_guess_again + +skull_guess_1: + mov skullGuess, 0 + jmp skulls_reveal +skull_guess_2: + mov skullGuess, 1 + jmp skulls_reveal +skull_guess_3: + mov skullGuess, 2 + +skulls_reveal: + call ClearView + invoke PrintTitleColor, OFFSET skullsTitle + invoke PrintSkulls, 1 + invoke PrintStr, OFFSET skullsBallText + mov eax, skullBallPos + inc eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + + mov eax, skullGuess + cmp eax, skullBallPos + jne skulls_lost + invoke PrintStr, OFFSET skullsWinText + invoke PaySlotMultiplier, 2 + jmp ask_skulls_again + +skulls_lost: + invoke PrintStr, OFFSET skullsLoseText + call PayLose + +ask_skulls_again: + cmp tournamentMode, 1 + je skulls_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je skulls_start + cmp al, 'Y' + je skulls_start +skulls_tournament_return: + ret +GameSkulls ENDP +; --- PrintRevolver: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRevolver PROC pGun:DWORD + invoke SetColor, COLOR_WARN + invoke PrintStr, pGun + call ResetColor + ret +PrintRevolver ENDP + +; --- PrintRouletteTurnGun: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRouletteTurnGun PROC + cmp rrTurn, 0 + jne print_rr_ai_gun + invoke PrintRevolver, OFFSET rrGunDown + ret +print_rr_ai_gun: + invoke PrintRevolver, OFFSET rrGunUp + ret +PrintRouletteTurnGun ENDP + +; --- ShowRouletteStatus: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +ShowRouletteStatus PROC + call ClearView + invoke PrintTitleColor, OFFSET rouletteTitle + call PrintRouletteTurnGun + invoke PrintStr, OFFSET rrDangerText + invoke PrintUInt, rrBullets + invoke PrintStr, OFFSET nl + ret +ShowRouletteStatus ENDP + +; --- ShowRouletteSpinFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +ShowRouletteSpinFrame PROC pGun:DWORD + call ClearView + invoke PrintTitleColor, OFFSET rouletteTitle + invoke PrintRevolver, pGun + invoke PrintStr, OFFSET rrSpinText + invoke Sleep, 85 + ret +ShowRouletteSpinFrame ENDP + +; --- AnimateRouletteSpin: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +AnimateRouletteSpin PROC + invoke ShowRouletteSpinFrame, OFFSET rrGunUp + invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDown + invoke ShowRouletteSpinFrame, OFFSET rrGunDownRight + invoke ShowRouletteSpinFrame, OFFSET rrGunRight + invoke ShowRouletteSpinFrame, OFFSET rrGunUpRight + invoke ShowRouletteSpinFrame, OFFSET rrGunUp + invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDown + invoke ShowRouletteSpinFrame, OFFSET rrGunDownRight + invoke ShowRouletteSpinFrame, OFFSET rrGunRight + invoke ShowRouletteSpinFrame, OFFSET rrGunUpRight + cmp rrTurn, 0 + jne roulette_spin_ai_final + invoke ShowRouletteSpinFrame, OFFSET rrGunUp + invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDown + jmp roulette_spin_final_message +roulette_spin_ai_final: + invoke ShowRouletteSpinFrame, OFFSET rrGunUp +roulette_spin_final_message: + call ShowRouletteStatus + cmp rrTurn, 0 + jne roulette_start_ai + invoke PrintStr, OFFSET rrStartsPlayerText + jmp roulette_start_done +roulette_start_ai: + invoke PrintStr, OFFSET rrStartsAIText +roulette_start_done: + invoke Sleep, 400 + ret +AnimateRouletteSpin ENDP + +; --- SetupRoulette: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +SetupRoulette PROC uses eax ebx ecx edx + mov rrBulletMask, 0 + mov eax, aiDifficulty + mov rrBullets, eax + mov ecx, eax +roulette_place_loop: + cmp ecx, 0 + je roulette_setup_done_bullets +roulette_pick_chamber: + invoke RandomRange, 6 + mov ebx, 1 + push ecx + mov ecx, eax + shl ebx, cl + pop ecx + mov edx, rrBulletMask + test edx, ebx + jne roulette_pick_chamber + or rrBulletMask, ebx + dec ecx + jmp roulette_place_loop +roulette_setup_done_bullets: + invoke RandomRange, 6 + mov rrChamber, eax + invoke RandomRange, 2 + mov rrTurn, eax + ret +SetupRoulette ENDP + +; --- RouletteChamberLoaded: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +RouletteChamberLoaded PROC uses ecx edx + mov edx, 1 + mov ecx, rrChamber + shl edx, cl + mov eax, rrBulletMask + test eax, edx + jne roulette_loaded + xor eax, eax + ret +roulette_loaded: + mov eax, 1 + ret +RouletteChamberLoaded ENDP + +; --- AdvanceRouletteChamber: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +AdvanceRouletteChamber PROC + inc rrChamber + cmp rrChamber, 6 + jb advance_roulette_done + mov rrChamber, 0 +advance_roulette_done: + ret +AdvanceRouletteChamber ENDP + +; --- PrintBang: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintBang PROC + call PlayRouletteShotSound + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET rrBangText + call ResetColor + ret +PrintBang ENDP + +; --- GameRoulette: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +GameRoulette PROC +roulette_start: + call ClearView + invoke PrintTitleColor, OFFSET rouletteTitle + invoke PrintStr, OFFSET rrIntroText + call PromptBet + call PlayRouletteSpinSound + call SetupRoulette + call AnimateRouletteSpin + +roulette_turn_loop: + call ShowRouletteStatus + cmp rrTurn, 0 + je roulette_player_turn + +roulette_ai_turn: + invoke PrintStr, OFFSET rrAITurnText + invoke Sleep, 900 + call RouletteChamberLoaded + cmp eax, 1 + je roulette_ai_dead + call PlayRouletteDrySound + invoke PrintStr, OFFSET rrClickText + invoke Sleep, 900 + call AdvanceRouletteChamber + mov rrTurn, 0 + jmp roulette_turn_loop + +roulette_player_turn: + invoke PrintStr, OFFSET rrPlayerTurnText + call ReadAnyKey + invoke PrintStr, OFFSET nl + call RouletteChamberLoaded + cmp eax, 1 + je roulette_player_dead + call PlayRouletteDrySound + invoke PrintStr, OFFSET rrClickText + invoke Sleep, 900 + call AdvanceRouletteChamber + mov rrTurn, 1 + jmp roulette_turn_loop + +roulette_player_dead: + call PrintBang + invoke PrintStr, OFFSET rrPlayerLoseText + call PayLose + jmp ask_roulette_again + +roulette_ai_dead: + invoke UnlockAchievement, 1000h, OFFSET achRussianWinName + call PrintBang + invoke PrintStr, OFFSET rrAIShotText + invoke PrintStr, OFFSET rrPayoutText + mov eax, aiDifficulty + inc eax + mov rrPayout, eax + invoke PaySlotMultiplier, rrPayout + +ask_roulette_again: + cmp tournamentMode, 1 + je roulette_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je roulette_start + cmp al, 'Y' + je roulette_start +roulette_tournament_return: + ret +GameRoulette ENDP + + +; --- ShowBuckshotFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +ShowBuckshotFrame PROC pFrame:DWORD, frameDelay:DWORD + call ClearView + invoke PrintTitleColor, OFFSET buckshotTitle + invoke SetColor, COLOR_CARD + invoke PrintStr, pFrame + call ResetColor + invoke Sleep, frameDelay + ret +ShowBuckshotFrame ENDP + +; --- AnimateBuckshotLoad: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +AnimateBuckshotLoad PROC + invoke ShowBuckshotFrame, OFFSET bsShotgunLoad1, 180 + invoke ShowBuckshotFrame, OFFSET bsShotgunLoad2, 260 + invoke ShowBuckshotFrame, OFFSET bsShotgunLoad3, 260 + ret +AnimateBuckshotLoad ENDP + +; --- AnimateBuckshotFire: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +AnimateBuckshotFire PROC + invoke ShowBuckshotFrame, OFFSET bsShotgunFire, 220 + ret +AnimateBuckshotFire ENDP + +; --- AnimateBuckshotDry: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +AnimateBuckshotDry PROC + invoke ShowBuckshotFrame, OFFSET bsShotgunDry, 180 + ret +AnimateBuckshotDry ENDP +; --- BuckshotGiveItems: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotGiveItems PROC uses eax + invoke RandomRange, 2 + inc eax + mov bsPlayerGlass, eax + invoke RandomRange, 2 + mov bsPlayerSaw, eax + invoke RandomRange, 2 + inc eax + mov bsPlayerBeer, eax + invoke RandomRange, 2 + mov bsPlayerCuffs, eax + invoke RandomRange, 2 + inc eax + mov bsAIGlass, eax + invoke RandomRange, 2 + mov bsAISaw, eax + invoke RandomRange, 2 + inc eax + mov bsAIBeer, eax + invoke RandomRange, 2 + mov bsAICuffs, eax + ret +BuckshotGiveItems ENDP + +; --- BuckshotLoad: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +BuckshotLoad PROC uses eax ebx ecx edi + invoke RandomRange, 5 + add eax, 4 + mov bsShellCount, eax + mov bsShellIndex, 0 + mov bsLiveCount, 0 + mov bsBlankCount, 0 + mov bsKnownShell, 0FFFFFFFFh + mov edi, OFFSET bsShells + mov ecx, bsShellCount +bs_load_loop: + invoke RandomRange, 2 + mov [edi], eax + cmp eax, 1 + je bs_count_live + inc bsBlankCount + jmp bs_count_done +bs_count_live: + inc bsLiveCount +bs_count_done: + add edi, 4 + loop bs_load_loop + cmp bsLiveCount, 0 + jne bs_has_live + mov dword ptr bsShells, 1 + inc bsLiveCount + dec bsBlankCount +bs_has_live: + cmp bsBlankCount, 0 + jne bs_has_blank + mov dword ptr bsShells+4, 0 + inc bsBlankCount + dec bsLiveCount +bs_has_blank: + invoke PrintStr, OFFSET bsLoadText + invoke PrintUInt, bsLiveCount + invoke PrintStr, OFFSET bsLiveText + invoke PrintUInt, bsBlankCount + invoke PrintStr, OFFSET bsBlankText + invoke Sleep, 900 + ret +BuckshotLoad ENDP + +; --- BuckshotCurrentShell: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotCurrentShell PROC uses ebx + mov ebx, bsShellIndex + mov eax, bsShells[ebx*4] + ret +BuckshotCurrentShell ENDP + +; --- BuckshotAdvance: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotAdvance PROC + cmp bsShell, 1 + je bs_advance_live + cmp bsBlankCount, 0 + je bs_advance_count_done + dec bsBlankCount + jmp bs_advance_count_done +bs_advance_live: + cmp bsLiveCount, 0 + je bs_advance_count_done + dec bsLiveCount +bs_advance_count_done: + inc bsShellIndex + mov bsKnownShell, 0FFFFFFFFh + mov bsDamage, 1 + ret +BuckshotAdvance ENDP + +; --- BuckshotRemaining: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotRemaining PROC uses ebx + mov eax, bsShellCount + sub eax, bsShellIndex + ret +BuckshotRemaining ENDP + +; --- BuckshotPrintKnown: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotPrintKnown PROC + mov eax, bsKnownShell + cmp eax, 1 + je bs_print_known_live + cmp eax, 0 + je bs_print_known_blank + invoke PrintStr, OFFSET bsKnownUnknownText + ret +bs_print_known_live: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET bsKnownLiveText + call ResetColor + ret +bs_print_known_blank: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET bsKnownBlankText + call ResetColor + ret +BuckshotPrintKnown ENDP + +; --- BuckshotStatus: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotStatus PROC + call ClearView + invoke PrintTitleColor, OFFSET buckshotTitle + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET bsShotgunArt + call ResetColor + invoke PrintStr, OFFSET bsHPText + invoke PrintUInt, bsPlayerHP + invoke PrintStr, OFFSET bsAIHPText + invoke PrintUInt, bsAIHP + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET bsShellInfoText + invoke PrintUInt, bsLiveCount + invoke PrintStr, OFFSET bsLiveText + invoke PrintUInt, bsBlankCount + invoke PrintStr, OFFSET bsBlankText + invoke PrintStr, OFFSET bsLeftText + call BuckshotRemaining + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + call BuckshotPrintKnown + invoke PrintStr, OFFSET bsItemsText + invoke PrintUInt, bsPlayerGlass + invoke PrintStr, OFFSET bsSawText + invoke PrintUInt, bsPlayerSaw + invoke PrintStr, OFFSET bsBeerText + invoke PrintUInt, bsPlayerBeer + invoke PrintStr, OFFSET bsCuffsText + invoke PrintUInt, bsPlayerCuffs + invoke PrintStr, OFFSET nl + ret +BuckshotStatus ENDP + +; --- BuckshotAfterShotTurn: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotAfterShotTurn PROC + cmp bsShell, 1 + je bs_after_switch + cmp bsTurn, 0 + je bs_after_player_blank + cmp bsTarget, 1 + je bs_after_keep + jmp bs_after_switch +bs_after_player_blank: + cmp bsTarget, 0 + je bs_after_keep +bs_after_switch: + xor bsTurn, 1 +bs_after_keep: + cmp bsTurn, 0 + je bs_check_skip_player + cmp bsSkipAI, 0 + je bs_after_done + mov bsSkipAI, 0 + invoke PrintStr, OFFSET bsSkipAIText + invoke Sleep, 800 + mov bsTurn, 0 + ret +bs_check_skip_player: + cmp bsSkipPlayer, 0 + je bs_after_done + mov bsSkipPlayer, 0 + invoke PrintStr, OFFSET bsSkipPlayerText + invoke Sleep, 800 + mov bsTurn, 1 +bs_after_done: + ret +BuckshotAfterShotTurn ENDP + +; --- BuckshotShoot: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotShoot PROC uses eax ebx + call BuckshotCurrentShell + mov bsShell, eax + cmp bsTarget, 0 + je bs_shoot_player_text + invoke PrintStr, OFFSET bsShootAIText + jmp bs_shoot_text_done +bs_shoot_player_text: + invoke PrintStr, OFFSET bsShootPlayerText +bs_shoot_text_done: + cmp bsShell, 1 + je bs_live_shot + call AnimateBuckshotDry + call PlayRouletteDrySound + invoke PrintStr, OFFSET bsDryText + call BuckshotAdvance + invoke Sleep, 900 + call BuckshotAfterShotTurn + ret +bs_live_shot: + call AnimateBuckshotFire + call PlayRouletteShotSound + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET bsHitText + invoke PrintUInt, bsDamage + invoke PrintStr, OFFSET nl + call ResetColor + mov eax, bsDamage + cmp bsTarget, 0 + je bs_damage_player + cmp bsAIHP, eax + ja bs_sub_ai + mov bsAIHP, 0 + jmp bs_damage_done +bs_sub_ai: + sub bsAIHP, eax + jmp bs_damage_done +bs_damage_player: + cmp bsPlayerHP, eax + ja bs_sub_player + mov bsPlayerHP, 0 + jmp bs_damage_done +bs_sub_player: + sub bsPlayerHP, eax +bs_damage_done: + call BuckshotAdvance + invoke Sleep, 1000 + call BuckshotAfterShotTurn + ret +BuckshotShoot ENDP + +; --- BuckshotUseGlass: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotUseGlass PROC + call BuckshotCurrentShell + mov bsKnownShell, eax + invoke PrintStr, OFFSET bsGlassUseText + call BuckshotPrintKnown + invoke Sleep, 1000 + ret +BuckshotUseGlass ENDP + +; --- BuckshotUseBeer: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotUseBeer PROC + call BuckshotCurrentShell + mov bsShell, eax + invoke PrintStr, OFFSET bsBeerUseText + cmp bsShell, 1 + je bs_beer_live + invoke PrintStr, OFFSET bsBlankLoadedText + jmp bs_beer_done +bs_beer_live: + invoke PrintStr, OFFSET bsLiveLoadedText +bs_beer_done: + call BuckshotAdvance + invoke Sleep, 1000 + ret +BuckshotUseBeer ENDP + +; --- BuckshotPlayerTurn: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotPlayerTurn PROC +bs_player_again: + call BuckshotStatus + invoke PrintStr, OFFSET bsPlayerTurnText + invoke PrintStr, OFFSET bsMenuText + call ReadKey + cmp al, '1' + je bs_player_self + cmp al, '2' + je bs_player_ai + cmp al, '3' + je bs_player_glass + cmp al, '4' + je bs_player_saw + cmp al, '5' + je bs_player_beer + cmp al, '6' + je bs_player_cuffs + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp bs_player_again +bs_player_self: + mov bsTarget, 0 + call BuckshotShoot + ret +bs_player_ai: + mov bsTarget, 1 + call BuckshotShoot + ret +bs_player_glass: + cmp bsPlayerGlass, 0 + je bs_player_no_item + dec bsPlayerGlass + call BuckshotUseGlass + jmp bs_player_again +bs_player_saw: + cmp bsPlayerSaw, 0 + je bs_player_no_item + dec bsPlayerSaw + mov bsDamage, 2 + invoke PrintStr, OFFSET bsSawUseText + invoke Sleep, 900 + jmp bs_player_again +bs_player_beer: + cmp bsPlayerBeer, 0 + je bs_player_no_item + dec bsPlayerBeer + call BuckshotUseBeer + call BuckshotRemaining + cmp eax, 0 + je bs_player_done + jmp bs_player_again +bs_player_cuffs: + cmp bsPlayerCuffs, 0 + je bs_player_no_item + dec bsPlayerCuffs + mov bsSkipAI, 1 + invoke PrintStr, OFFSET bsCuffsUseText + invoke Sleep, 900 + jmp bs_player_again +bs_player_no_item: + invoke PrintStr, OFFSET bsNoItemText + invoke Sleep, 800 + jmp bs_player_again +bs_player_done: + ret +BuckshotPlayerTurn ENDP + +; --- BuckshotAITurn: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +BuckshotAITurn PROC + call BuckshotStatus + invoke PrintStr, OFFSET bsAITurnText + invoke Sleep, 900 + cmp bsKnownShell, 0FFFFFFFFh + jne bs_ai_known + cmp bsAIGlass, 0 + je bs_ai_no_glass + dec bsAIGlass + invoke PrintStr, OFFSET bsAIGlassText + call BuckshotUseGlass +bs_ai_no_glass: +bs_ai_known: + cmp bsKnownShell, 1 + je bs_ai_live + cmp bsKnownShell, 0 + je bs_ai_blank + mov eax, bsLiveCount + cmp eax, bsBlankCount + jae bs_ai_live +bs_ai_blank: + mov bsTarget, 1 + call BuckshotShoot + ret +bs_ai_live: + cmp bsAISaw, 0 + je bs_ai_maybe_cuffs + dec bsAISaw + mov bsDamage, 2 + invoke PrintStr, OFFSET bsAISawText + invoke Sleep, 700 +bs_ai_maybe_cuffs: + cmp bsAICuffs, 0 + je bs_ai_shoot_player + dec bsAICuffs + mov bsSkipPlayer, 1 + invoke PrintStr, OFFSET bsAICuffsText + invoke Sleep, 700 +bs_ai_shoot_player: + mov bsTarget, 0 + call BuckshotShoot + ret +BuckshotAITurn ENDP + +; --- GameBuckshot: Buckshot Roulette: ïàòðîíû, ïðåäìåòû, õîäû èãðîêà è ÈÈ --- +GameBuckshot PROC +buckshot_start: + call ClearView + invoke PrintTitleColor, OFFSET buckshotTitle + invoke PrintStr, OFFSET buckshotIntro + call PromptBet + mov bsPlayerHP, 4 + mov bsAIHP, 4 + mov bsTurn, 0 + mov bsDamage, 1 + mov bsSkipPlayer, 0 + mov bsSkipAI, 0 + call BuckshotGiveItems + call PlayRouletteSpinSound + call AnimateBuckshotLoad + call BuckshotLoad +buckshot_loop: + call BuckshotRemaining + cmp eax, 0 + jne buckshot_has_shells + call AnimateBuckshotLoad + call BuckshotLoad +buckshot_has_shells: + cmp bsPlayerHP, 0 + je buckshot_lost + cmp bsAIHP, 0 + je buckshot_won + cmp bsTurn, 0 + je buckshot_player + call BuckshotAITurn + jmp buckshot_loop +buckshot_player: + call BuckshotPlayerTurn + jmp buckshot_loop +buckshot_won: + call BuckshotStatus + invoke PrintStr, OFFSET bsWinText + invoke PaySlotMultiplier, 3 + jmp buckshot_again +buckshot_lost: + call BuckshotStatus + invoke PrintStr, OFFSET bsLoseText + call PayLose +buckshot_again: + call SaveGame + cmp tournamentMode, 1 + je buckshot_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je buckshot_start + cmp al, 'Y' + je buckshot_start +buckshot_tournament_return: + ret +GameBuckshot ENDP +; --- PrintDiceParity: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintDiceParity PROC parity:DWORD + cmp parity, 1 + jne print_dice_odd + invoke PrintStr, OFFSET diceEvenText + ret +print_dice_odd: + invoke PrintStr, OFFSET diceOddText + ret +PrintDiceParity ENDP + +; --- GameDice: êîñòè: áðîñîê, ÷åòíîñòü è ðåçóëüòàò --- +GameDice PROC +dice_start: + call ClearView + invoke PrintTitleColor, OFFSET diceTitle + invoke PrintStr, OFFSET diceIntroText + call PromptBet + +dice_choose: + call ClearView + invoke PrintTitleColor, OFFSET diceTitle + invoke PrintStr, OFFSET diceIntroText + call PrintBank + invoke PrintStr, OFFSET diceChoiceText + call ReadKey + cmp al, '1' + je dice_pick_even + cmp al, '2' + je dice_pick_odd + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp dice_choose + +dice_pick_even: + mov diceChoice, 1 + jmp dice_roll +dice_pick_odd: + mov diceChoice, 2 + +dice_roll: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET diceRollText + call ResetColor + invoke Sleep, 500 + invoke RandomRange, 6 + inc eax + mov diceA, eax + invoke RandomRange, 6 + inc eax + mov diceB, eax + mov eax, diceA + add eax, diceB + mov diceSum, eax + invoke PrintStr, OFFSET diceFirstText + invoke PrintUInt, diceA + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET diceSecondText + invoke PrintUInt, diceB + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET diceSumText + invoke PrintUInt, diceSum + invoke PrintStr, OFFSET nl + mov eax, diceSum + and eax, 1 + cmp eax, 0 + je dice_result_even + mov eax, 2 + jmp dice_compare +dice_result_even: + mov eax, 1 +dice_compare: + cmp eax, diceChoice + je dice_win + call PrintLoseEvent + call PayLose + jmp dice_again +dice_win: + call PrintWinEvent + call PayWin + +dice_again: + cmp tournamentMode, 1 + je dice_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je dice_start + cmp al, 'Y' + je dice_start +dice_tournament_return: + ret +GameDice ENDP +; --- Online Dice: Radmin LAN match without a separate server process --- +onlineTitle db 13,10,"--- Online Casino (Radmin) ---",13,10,0 +onlineMenuText db "1. Host room",13,10,"2. Join room",13,10,"0. Back",13,10,0 +onlineHostInfo db "Give your Radmin IPv4 and port 27015 to your friend.",13,10,"Waiting for one player...",13,10,0 +onlineJoinPrompt db "Host Radmin IPv4: ",0 +onlineConnectingText db "Connecting...",13,10,0 +onlineConnectedText db "Connected.",13,10,0 +onlineYouRollText db "Your roll: ",0 +onlineFriendRollText db "Friend roll: ",0 +onlineWinText db "You win this friendly match.",13,10,0 +onlineLoseText db "Friend wins this friendly match.",13,10,0 +onlineDrawText db "Draw. Same roll.",13,10,0 +onlineErrorText db "Network error. Winsock code: ",0 +onlineBadIpText db "IPv4 address is invalid.",13,10,0 + +OnlineStartWinsock PROC + invoke WSAStartup, 0202h, OFFSET onlineWsaData + test eax, eax + jnz online_start_fail + mov onlineWsaReady, 1 + mov eax, 1 + ret +online_start_fail: + xor eax, eax + ret +OnlineStartWinsock ENDP + +OnlineCleanup PROC + cmp onlinePeerSock, -1 + je online_cleanup_listener + invoke closesocket, onlinePeerSock + mov onlinePeerSock, -1 +online_cleanup_listener: + cmp onlineListenSock, -1 + je online_cleanup_wsa + invoke closesocket, onlineListenSock + mov onlineListenSock, -1 +online_cleanup_wsa: + cmp onlineWsaReady, 1 + jne online_cleanup_done + invoke WSACleanup + mov onlineWsaReady, 0 +online_cleanup_done: + ret +OnlineCleanup ENDP + +OnlineBuildAddress PROC uses eax ecx edi + lea edi, onlineAddr + xor eax, eax + mov ecx, 4 + rep stosd + mov word ptr onlineAddr, AF_INET + mov word ptr onlineAddr+2, ONLINE_PORT_NET + ret +OnlineBuildAddress ENDP + +ReadOnlineIp PROC uses eax ecx esi edi + lea edi, onlineIp + xor eax, eax + mov ecx, 32 + rep stosb + invoke ReadFile, hIn, OFFSET onlineIp, 31, ADDR charsRead, 0 + mov ecx, charsRead + cmp ecx, 31 + jbe online_ip_len_ok + mov ecx, 31 +online_ip_len_ok: + mov byte ptr onlineIp[ecx], 0 + mov esi, OFFSET onlineIp +online_ip_trim: + cmp ecx, 0 + je online_ip_done + mov al, [esi] + cmp al, 13 + je online_ip_end + cmp al, 10 + je online_ip_end + inc esi + dec ecx + jmp online_ip_trim +online_ip_end: + mov byte ptr [esi], 0 +online_ip_done: + ret +ReadOnlineIp ENDP + +NetSendAll PROC uses esi edi, hSocket:DWORD, pData:DWORD, byteCount:DWORD + mov esi, pData + mov edi, byteCount +online_send_loop: + cmp edi, 0 + je online_send_ok + invoke send, hSocket, esi, edi, 0 + test eax, eax + jle online_send_fail + add esi, eax + sub edi, eax + jmp online_send_loop +online_send_ok: + mov eax, 1 + ret +online_send_fail: + xor eax, eax + ret +NetSendAll ENDP + +NetRecvAll PROC uses esi edi, hSocket:DWORD, pData:DWORD, byteCount:DWORD + mov esi, pData + mov edi, byteCount +online_recv_loop: + cmp edi, 0 + je online_recv_ok + invoke recv, hSocket, esi, edi, 0 + test eax, eax + jle online_recv_fail + add esi, eax + sub edi, eax + jmp online_recv_loop +online_recv_ok: + mov eax, 1 + ret +online_recv_fail: + xor eax, eax + ret +NetRecvAll ENDP + +PrintOnlineError PROC + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET onlineErrorText + invoke WSAGetLastError + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + call ResetColor + ret +PrintOnlineError ENDP + +ShowOnlineResult PROC + call ClearView + invoke PrintTitleColor, OFFSET onlineTitle + invoke PrintStr, OFFSET onlineYouRollText + invoke PrintUInt, onlineLocalRoll + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET onlineFriendRollText + invoke PrintUInt, onlineRemoteRoll + invoke PrintStr, OFFSET nl + mov eax, onlineLocalRoll + cmp eax, onlineRemoteRoll + ja online_result_win + jb online_result_lose + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET onlineDrawText + call ResetColor + jmp online_result_done +online_result_win: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET onlineWinText + call ResetColor + jmp online_result_done +online_result_lose: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET onlineLoseText + call ResetColor +online_result_done: + ret +ShowOnlineResult ENDP + +OnlineHostGameText db "Choose online game:",13,10,"1. Dice 1v1",13,10,"2. Russian Roulette 1v1",13,10,"0. Back",13,10,0 +OnlineModeDiceText db "Room mode: Dice 1v1",13,10,0 +OnlineModeRRText db "Room mode: Russian Roulette 1v1",13,10,0 +OnlineProtocolText db "Players use different online protocol versions.",13,10,0 +OnlineRRYourTurnText db "Your turn. Press any key to pull the trigger...",0 +OnlineRRWaitText db "Friend is holding the revolver. Waiting for the trigger...",13,10,0 +OnlineRRStartsYouText db "The revolver points at you. You shoot first.",13,10,0 +OnlineRRStartsFriendText db "The revolver points at your friend. Friend shoots first.",13,10,0 +OnlineRRWinText db "Your friend caught the loaded chamber. You survived.",13,10,0 +OnlineRRLoseText db "The loaded chamber was yours. You lost.",13,10,0 + +OnlineHostConnect PROC + call OnlineStartWinsock + test eax, eax + jz online_host_connect_error + invoke socket, AF_INET, SOCK_STREAM, IPPROTO_TCP + cmp eax, SOCKET_ERROR + je online_host_connect_error + mov onlineListenSock, eax + call OnlineBuildAddress + invoke bind, onlineListenSock, OFFSET onlineAddr, 16 + test eax, eax + jnz online_host_connect_error + invoke listen, onlineListenSock, 1 + test eax, eax + jnz online_host_connect_error + call ClearView + invoke PrintTitleColor, OFFSET onlineTitle + invoke PrintStr, OFFSET onlineHostInfo + invoke accept, onlineListenSock, 0, 0 + cmp eax, SOCKET_ERROR + je online_host_connect_error + mov onlinePeerSock, eax + invoke closesocket, onlineListenSock + mov onlineListenSock, -1 + invoke PrintStr, OFFSET onlineConnectedText + mov eax, 1 + ret +online_host_connect_error: + call PrintOnlineError + call OnlineCleanup + call PauseConsole + xor eax, eax + ret +OnlineHostConnect ENDP + +OnlineJoinConnect PROC + call OnlineStartWinsock + test eax, eax + jz online_join_connect_error + call ClearView + invoke PrintTitleColor, OFFSET onlineTitle + invoke PrintStr, OFFSET onlineJoinPrompt + call ReadOnlineIp + invoke inet_addr, OFFSET onlineIp + cmp eax, 0FFFFFFFFh + je online_join_connect_bad_ip + mov onlineHostIp, eax + invoke socket, AF_INET, SOCK_STREAM, IPPROTO_TCP + cmp eax, SOCKET_ERROR + je online_join_connect_error + mov onlinePeerSock, eax + call OnlineBuildAddress + mov eax, onlineHostIp + mov dword ptr onlineAddr+4, eax + invoke PrintStr, OFFSET onlineConnectingText + invoke connect, onlinePeerSock, OFFSET onlineAddr, 16 + test eax, eax + jnz online_join_connect_error + invoke PrintStr, OFFSET onlineConnectedText + mov eax, 1 + ret +online_join_connect_bad_ip: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET onlineBadIpText + call ResetColor + call OnlineCleanup + call PauseConsole + xor eax, eax + ret +online_join_connect_error: + call PrintOnlineError + call OnlineCleanup + call PauseConsole + xor eax, eax + ret +OnlineJoinConnect ENDP + +OnlineDiceSessionHost PROC + invoke RandomRange, 6 + inc eax + mov onlinePacket, eax + mov onlineLocalRoll, eax + invoke RandomRange, 6 + inc eax + mov onlinePacket+4, eax + mov onlineRemoteRoll, eax + invoke NetSendAll, onlinePeerSock, OFFSET onlinePacket, 8 + test eax, eax + jz online_dice_host_fail + invoke Sleep, 450 + call ShowOnlineResult + mov eax, 1 + ret +online_dice_host_fail: + xor eax, eax + ret +OnlineDiceSessionHost ENDP + +OnlineDiceSessionClient PROC + invoke NetRecvAll, onlinePeerSock, OFFSET onlinePacket, 8 + test eax, eax + jz online_dice_client_fail + mov eax, onlinePacket+4 + mov onlineLocalRoll, eax + mov eax, onlinePacket + mov onlineRemoteRoll, eax + invoke Sleep, 450 + call ShowOnlineResult + mov eax, 1 + ret +online_dice_client_fail: + xor eax, eax + ret +OnlineDiceSessionClient ENDP + +ShowOnlineRRStatus PROC role:DWORD + call ClearView + invoke PrintTitleColor, OFFSET rouletteTitle + mov eax, rrTurn + cmp eax, role + jne online_rr_status_friend + invoke PrintRevolver, OFFSET rrGunDown + jmp online_rr_status_info +online_rr_status_friend: + invoke PrintRevolver, OFFSET rrGunUp +online_rr_status_info: + invoke PrintStr, OFFSET rrDangerText + invoke PrintUInt, rrBullets + invoke PrintStr, OFFSET nl + ret +ShowOnlineRRStatus ENDP + +AnimateOnlineRRStart PROC role:DWORD + invoke ShowRouletteSpinFrame, OFFSET rrGunUp + invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDown + invoke ShowRouletteSpinFrame, OFFSET rrGunDownRight + invoke ShowRouletteSpinFrame, OFFSET rrGunRight + invoke ShowRouletteSpinFrame, OFFSET rrGunUpRight + invoke ShowRouletteSpinFrame, OFFSET rrGunUp + invoke ShowRouletteSpinFrame, OFFSET rrGunUpLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDownLeft + invoke ShowRouletteSpinFrame, OFFSET rrGunDown + invoke ShowRouletteSpinFrame, OFFSET rrGunDownRight + invoke ShowRouletteSpinFrame, OFFSET rrGunRight + invoke ShowRouletteSpinFrame, OFFSET rrGunUpRight + invoke ShowOnlineRRStatus, role + mov eax, rrTurn + cmp eax, role + jne online_rr_start_friend + invoke PrintStr, OFFSET OnlineRRStartsYouText + ret +online_rr_start_friend: + invoke PrintStr, OFFSET OnlineRRStartsFriendText + ret +AnimateOnlineRRStart ENDP + +ShowOnlineRRShot PROC role:DWORD + cmp onlinePacket, 1 + je online_rr_shot_bang + call PlayRouletteDrySound + invoke PrintStr, OFFSET rrClickText + invoke Sleep, 850 + ret +online_rr_shot_bang: + call PrintBang + mov eax, onlinePacket+4 + cmp eax, role + jne online_rr_shot_win + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET OnlineRRLoseText + call ResetColor + ret +online_rr_shot_win: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET OnlineRRWinText + call ResetColor + ret +ShowOnlineRRShot ENDP + +OnlineRRSessionHost PROC + call SetupRoulette + mov eax, rrBullets + mov onlinePacket, eax + mov eax, rrTurn + mov onlinePacket+4, eax + invoke NetSendAll, onlinePeerSock, OFFSET onlinePacket, 8 + test eax, eax + jz online_rr_host_fail + call PlayRouletteSpinSound + invoke AnimateOnlineRRStart, 0 +online_rr_host_loop: + invoke ShowOnlineRRStatus, 0 + cmp rrTurn, 0 + je online_rr_host_own_turn + invoke PrintStr, OFFSET OnlineRRWaitText + invoke NetRecvAll, onlinePeerSock, OFFSET onlineAction, 4 + test eax, eax + jz online_rr_host_fail + jmp online_rr_host_fire +online_rr_host_own_turn: + invoke PrintStr, OFFSET OnlineRRYourTurnText + call ReadAnyKey + invoke PrintStr, OFFSET nl +online_rr_host_fire: + mov onlinePacket, 0 + call RouletteChamberLoaded + cmp eax, 1 + jne online_rr_host_event_ready + mov onlinePacket, 1 +online_rr_host_event_ready: + mov eax, rrTurn + mov onlinePacket+4, eax + invoke NetSendAll, onlinePeerSock, OFFSET onlinePacket, 8 + test eax, eax + jz online_rr_host_fail + invoke ShowOnlineRRShot, 0 + cmp onlinePacket, 1 + je online_rr_host_done + call AdvanceRouletteChamber + xor rrTurn, 1 + jmp online_rr_host_loop +online_rr_host_done: + mov eax, 1 + ret +online_rr_host_fail: + xor eax, eax + ret +OnlineRRSessionHost ENDP + +OnlineRRSessionClient PROC + invoke NetRecvAll, onlinePeerSock, OFFSET onlinePacket, 8 + test eax, eax + jz online_rr_client_fail + mov eax, onlinePacket + mov rrBullets, eax + mov eax, onlinePacket+4 + mov rrTurn, eax + call PlayRouletteSpinSound + invoke AnimateOnlineRRStart, 1 +online_rr_client_loop: + invoke ShowOnlineRRStatus, 1 + cmp rrTurn, 1 + jne online_rr_client_wait + invoke PrintStr, OFFSET OnlineRRYourTurnText + call ReadAnyKey + invoke PrintStr, OFFSET nl + mov onlineAction, 1 + invoke NetSendAll, onlinePeerSock, OFFSET onlineAction, 4 + test eax, eax + jz online_rr_client_fail + jmp online_rr_client_receive +online_rr_client_wait: + invoke PrintStr, OFFSET OnlineRRWaitText +online_rr_client_receive: + invoke NetRecvAll, onlinePeerSock, OFFSET onlinePacket, 8 + test eax, eax + jz online_rr_client_fail + mov eax, onlinePacket+4 + mov rrTurn, eax + invoke ShowOnlineRRShot, 1 + cmp onlinePacket, 1 + je online_rr_client_done + xor rrTurn, 1 + jmp online_rr_client_loop +online_rr_client_done: + mov eax, 1 + ret +online_rr_client_fail: + xor eax, eax + ret +OnlineRRSessionClient ENDP + +GameOnlineCasino PROC +online_casino_menu: + call ClearView + invoke PrintTitleColor, OFFSET onlineTitle + invoke PrintStr, OFFSET onlineMenuText + invoke PrintStr, OFFSET choiceText + call ReadKey + cmp al, '1' + je online_casino_host_choose + cmp al, '2' + je online_casino_join + cmp al, '0' + je online_casino_done + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET badChoiceText + call ResetColor + invoke Sleep, 650 + jmp online_casino_menu +online_casino_host_choose: + call ClearView + invoke PrintTitleColor, OFFSET onlineTitle + invoke PrintStr, OFFSET OnlineHostGameText + invoke PrintStr, OFFSET choiceText + call ReadKey + cmp al, '1' + je online_casino_host_dice + cmp al, '2' + je online_casino_host_rr + cmp al, '0' + je online_casino_menu + invoke PrintStr, OFFSET badChoiceText + invoke Sleep, 650 + jmp online_casino_host_choose +online_casino_host_dice: + mov onlineGameMode, ONLINE_GAME_DICE + jmp online_casino_host_connect +online_casino_host_rr: + mov onlineGameMode, ONLINE_GAME_RR +online_casino_host_connect: + call OnlineHostConnect + test eax, eax + jz online_casino_done + mov onlinePacket, ONLINE_MAGIC + mov eax, onlineGameMode + mov onlinePacket+4, eax + invoke NetSendAll, onlinePeerSock, OFFSET onlinePacket, 8 + test eax, eax + jz online_casino_session_error + cmp onlineGameMode, ONLINE_GAME_DICE + je online_casino_run_host_dice + invoke PrintStr, OFFSET OnlineModeRRText + call OnlineRRSessionHost + jmp online_casino_session_done +online_casino_run_host_dice: + invoke PrintStr, OFFSET OnlineModeDiceText + call OnlineDiceSessionHost + jmp online_casino_session_done +online_casino_join: + call OnlineJoinConnect + test eax, eax + jz online_casino_done + invoke NetRecvAll, onlinePeerSock, OFFSET onlinePacket, 8 + test eax, eax + jz online_casino_session_error + cmp onlinePacket, ONLINE_MAGIC + jne online_casino_protocol_error + mov eax, onlinePacket+4 + mov onlineGameMode, eax + cmp eax, ONLINE_GAME_DICE + je online_casino_run_client_dice + cmp eax, ONLINE_GAME_RR + je online_casino_run_client_rr + jmp online_casino_protocol_error +online_casino_run_client_dice: + invoke PrintStr, OFFSET OnlineModeDiceText + call OnlineDiceSessionClient + jmp online_casino_session_done +online_casino_run_client_rr: + invoke PrintStr, OFFSET OnlineModeRRText + call OnlineRRSessionClient +online_casino_session_done: + test eax, eax + jz online_casino_session_error + call OnlineCleanup + call PauseConsole + ret +online_casino_protocol_error: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET OnlineProtocolText + call ResetColor + call OnlineCleanup + call PauseConsole + ret +online_casino_session_error: + call PrintOnlineError + call OnlineCleanup + call PauseConsole +online_casino_done: + ret +GameOnlineCasino ENDP + +; --- PrintCoinSide: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintCoinSide PROC side:DWORD + cmp side, 1 + jne print_coin_tails + invoke PrintStr, OFFSET coinHeadsText + ret +print_coin_tails: + invoke PrintStr, OFFSET coinTailsText + ret +PrintCoinSide ENDP + +; --- ShowCoinFlipFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +ShowCoinFlipFrame PROC uses eax, pFrame:DWORD + call ClearView + invoke PrintTitleColor, OFFSET coinTitle + invoke PrintStr, OFFSET coinIntroText + call PrintBank + invoke PrintStr, OFFSET coinPickText + invoke PrintCoinSide, coinPick + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET coinSpinText + mov eax, pFrame + invoke PrintStr, eax + call ResetColor + invoke Sleep, 170 + ret +ShowCoinFlipFrame ENDP + +; --- AnimateCoinFlip: îðåë è ðåøêà: âûáîð ñòîðîíû, çâóê è àíèìàöèÿ ìîíåòû --- +AnimateCoinFlip PROC + invoke ShowCoinFlipFrame, OFFSET coinFrame1 + invoke ShowCoinFlipFrame, OFFSET coinFrame2 + invoke ShowCoinFlipFrame, OFFSET coinFrame3 + invoke ShowCoinFlipFrame, OFFSET coinFrame4 + invoke ShowCoinFlipFrame, OFFSET coinFrame5 + invoke ShowCoinFlipFrame, OFFSET coinFrame6 + invoke ShowCoinFlipFrame, OFFSET coinFrame7 + invoke ShowCoinFlipFrame, OFFSET coinFrame8 + invoke ShowCoinFlipFrame, OFFSET coinFrame9 + invoke ShowCoinFlipFrame, OFFSET coinFrame10 + invoke ShowCoinFlipFrame, OFFSET coinFrame11 + invoke ShowCoinFlipFrame, OFFSET coinFrame12 + invoke ShowCoinFlipFrame, OFFSET coinFrame13 + invoke ShowCoinFlipFrame, OFFSET coinFrame14 + ret +AnimateCoinFlip ENDP + +; --- GameCoin: îðåë è ðåøêà: âûáîð ñòîðîíû, çâóê è àíèìàöèÿ ìîíåòû --- +GameCoin PROC +coin_start: + call ClearView + invoke PrintTitleColor, OFFSET coinTitle + invoke PrintStr, OFFSET coinIntroText + call PromptBet + +coin_choose: + call ClearView + invoke PrintTitleColor, OFFSET coinTitle + invoke PrintStr, OFFSET coinIntroText + call PrintBank + invoke PrintStr, OFFSET coinChoiceText + call ReadKey + cmp al, '1' + je coin_pick_heads + cmp al, '2' + je coin_pick_tails + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp coin_choose + +coin_pick_heads: + mov coinPick, 1 + jmp coin_flip +coin_pick_tails: + mov coinPick, 2 + +coin_flip: + invoke PrintStr, OFFSET coinPickText + invoke PrintCoinSide, coinPick + call PlayCoinSound + call AnimateCoinFlip + invoke RandomRange, 2 + inc eax + mov coinResult, eax + invoke PrintStr, OFFSET coinResultText + invoke PrintCoinSide, coinResult + mov eax, coinPick + cmp eax, coinResult + je coin_win + call PrintLoseEvent + call PayLose + jmp coin_again +coin_win: + call PrintWinEvent + call PayWin + +coin_again: + cmp tournamentMode, 1 + je coin_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je coin_start + cmp al, 'Y' + je coin_start +coin_tournament_return: + ret +GameCoin ENDP + +; --- PrintRouletteColorName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRouletteColorName PROC uses eax ebx, value:DWORD + mov eax, value + cmp eax, 0 + jne roulette_color_not_zero + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET rouletteGreenName + call ResetColor + ret +roulette_color_not_zero: + movzx ebx, byte ptr [rouletteColors + eax] + cmp ebx, 1 + jne roulette_color_black + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET rouletteRedName + call ResetColor + ret +roulette_color_black: + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET rouletteBlackName + call ResetColor + ret +PrintRouletteColorName ENDP + +; --- PrintRouletteNumberColored: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRouletteNumberColored PROC uses eax ebx, value:DWORD + mov eax, value + cmp eax, 0 + jne roulette_number_not_zero + invoke SetColor, COLOR_MONEY + jmp roulette_number_print +roulette_number_not_zero: + movzx ebx, byte ptr [rouletteColors + eax] + cmp ebx, 1 + jne roulette_number_black + invoke SetColor, COLOR_BAD + jmp roulette_number_print +roulette_number_black: + invoke SetColor, COLOR_CARD +roulette_number_print: + invoke PrintUInt, value + call ResetColor + ret +PrintRouletteNumberColored ENDP + +; --- PrintRoulettePocket: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRoulettePocket PROC uses eax, wheelIndex:DWORD + invoke PrintStr, OFFSET roulettePocketLeft + mov eax, wheelIndex + mov eax, [rouletteWheel + eax * 4] + push eax + cmp eax, 10 + jae roulette_pocket_no_pad + invoke PrintStr, OFFSET rouletteNumSpace +roulette_pocket_no_pad: + pop eax + invoke PrintRouletteNumberColored, eax + invoke PrintStr, OFFSET roulettePocketRight + ret +PrintRoulettePocket ENDP + +; --- PrintRoulettePocketOffset: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRoulettePocketOffset PROC uses eax, wheelOffset:DWORD + mov eax, casinoRouletteSpinIndex + add eax, wheelOffset +roulette_offset_wrap: + cmp eax, 37 + jb roulette_offset_ready + sub eax, 37 + jmp roulette_offset_wrap +roulette_offset_ready: + invoke PrintRoulettePocket, eax + ret +PrintRoulettePocketOffset ENDP + +; --- PrintRouletteTopRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRouletteTopRow PROC + invoke PrintStr, OFFSET casinoRoulettePad + invoke PrintRoulettePocketOffset, 31 + invoke PrintRoulettePocketOffset, 32 + invoke PrintRoulettePocketOffset, 33 + invoke PrintRoulettePocketOffset, 34 + invoke PrintRoulettePocketOffset, 35 + invoke PrintRoulettePocketOffset, 36 + invoke PrintRoulettePocketOffset, 0 + invoke PrintRoulettePocketOffset, 1 + invoke PrintRoulettePocketOffset, 2 + invoke PrintRoulettePocketOffset, 3 + invoke PrintRoulettePocketOffset, 4 + invoke PrintRoulettePocketOffset, 5 + invoke PrintRoulettePocketOffset, 6 + invoke PrintStr, OFFSET nl + ret +PrintRouletteTopRow ENDP + +; --- PrintRouletteBottomRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRouletteBottomRow PROC + invoke PrintStr, OFFSET casinoRoulettePad + invoke PrintRoulettePocketOffset, 24 + invoke PrintRoulettePocketOffset, 23 + invoke PrintRoulettePocketOffset, 22 + invoke PrintRoulettePocketOffset, 21 + invoke PrintRoulettePocketOffset, 20 + invoke PrintRoulettePocketOffset, 19 + invoke PrintRoulettePocketOffset, 18 + invoke PrintRoulettePocketOffset, 17 + invoke PrintRoulettePocketOffset, 16 + invoke PrintRoulettePocketOffset, 15 + invoke PrintRoulettePocketOffset, 14 + invoke PrintRoulettePocketOffset, 13 + invoke PrintStr, OFFSET nl + ret +PrintRouletteBottomRow ENDP + +; --- PrintRouletteSideRow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintRouletteSideRow PROC leftOffset:DWORD, pGap:DWORD, rightOffset:DWORD + invoke SetColor, COLOR_WOOD + invoke PrintStr, OFFSET rouletteBigSidePad + call ResetColor + invoke PrintRoulettePocketOffset, leftOffset + invoke SetColor, COLOR_TABLE + invoke PrintStr, pGap + call ResetColor + invoke PrintRoulettePocketOffset, rightOffset + invoke PrintStr, OFFSET nl + ret +PrintRouletteSideRow ENDP + +; --- ShowCasinoRouletteFrame: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +ShowCasinoRouletteFrame PROC + call ClearView + invoke PrintTitleColor, OFFSET casinoRouletteTitle + invoke SetColor, COLOR_WOOD + invoke PrintStr, OFFSET casinoRouletteWheelTop + call ResetColor + call PrintRouletteTopRow + invoke PrintRouletteSideRow, 30, OFFSET rouletteBigSideGap1, 7 + invoke PrintRouletteSideRow, 29, OFFSET rouletteBigSideGap2, 8 + invoke PrintRouletteSideRow, 28, OFFSET rouletteBigSideGap3, 9 + invoke PrintRouletteSideRow, 27, OFFSET rouletteBigSideGap4, 10 + invoke PrintRouletteSideRow, 26, OFFSET rouletteBigSideGap5, 11 + invoke PrintRouletteSideRow, 25, OFFSET rouletteBigSideGap6, 12 + call PrintRouletteBottomRow + invoke SetColor, COLOR_WOOD + invoke PrintStr, OFFSET casinoRouletteWheelBottom + call ResetColor + invoke PrintStr, OFFSET casinoRouletteSpinText + ret +ShowCasinoRouletteFrame ENDP + +; --- AnimateCasinoRouletteSpin: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +AnimateCasinoRouletteSpin PROC uses eax ebx edx + invoke GetTickCount + xor seed, eax + invoke RandomRange, 37 + mov casinoRouletteResultIndex, eax + mov ebx, eax + mov eax, [rouletteWheel + ebx * 4] + mov casinoRouletteResult, eax + + invoke RandomRange, 18 + add eax, 72 + mov casinoRouletteSpinSteps, eax + mov casinoRouletteSpinCounter, eax + + xor edx, edx + mov ebx, 37 + div ebx + mov eax, casinoRouletteResultIndex + add eax, 37 + sub eax, edx + cmp eax, 37 + jb casino_roulette_start_ready + sub eax, 37 +casino_roulette_start_ready: + mov casinoRouletteSpinIndex, eax + +casino_roulette_spin_loop: + inc casinoRouletteSpinIndex + cmp casinoRouletteSpinIndex, 37 + jb casino_roulette_spin_index_ok + mov casinoRouletteSpinIndex, 0 +casino_roulette_spin_index_ok: + call ShowCasinoRouletteFrame + mov eax, casinoRouletteSpinCounter + cmp eax, 12 + jbe casino_roulette_sleep_slow + cmp eax, 26 + jbe casino_roulette_sleep_mid + invoke Sleep, 45 + jmp casino_roulette_after_sleep +casino_roulette_sleep_mid: + invoke Sleep, 95 + jmp casino_roulette_after_sleep +casino_roulette_sleep_slow: + invoke Sleep, 170 +casino_roulette_after_sleep: + dec casinoRouletteSpinCounter + cmp casinoRouletteSpinCounter, 0 + jne casino_roulette_spin_loop + mov ebx, casinoRouletteSpinIndex + mov casinoRouletteResultIndex, ebx + mov eax, [rouletteWheel + ebx * 4] + mov casinoRouletteResult, eax + ret +AnimateCasinoRouletteSpin ENDP + +; --- CasinoRouletteEvaluate: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +CasinoRouletteEvaluate PROC uses eax ebx edx + invoke PrintStr, OFFSET casinoRouletteResultText + invoke PrintRouletteNumberColored, casinoRouletteResult + invoke PrintStr, OFFSET rouletteNumSpace + invoke PrintRouletteColorName, casinoRouletteResult + + mov eax, casinoRouletteBetType + cmp eax, 1 + je casino_roulette_eval_number + cmp eax, 2 + je casino_roulette_eval_red + cmp eax, 3 + je casino_roulette_eval_black + cmp eax, 4 + je casino_roulette_eval_even + cmp eax, 5 + je casino_roulette_eval_odd + cmp eax, 6 + je casino_roulette_eval_dozen1 + cmp eax, 7 + je casino_roulette_eval_dozen2 + cmp eax, 8 + je casino_roulette_eval_dozen3 + cmp eax, 9 + je casino_roulette_eval_low + cmp eax, 10 + je casino_roulette_eval_high + cmp eax, 11 + je casino_roulette_eval_col1 + cmp eax, 12 + je casino_roulette_eval_col2 + cmp eax, 13 + je casino_roulette_eval_col3 + jmp casino_roulette_lost + +casino_roulette_eval_number: + mov eax, casinoRouletteResult + cmp eax, casinoRouletteBetNumber + jne casino_roulette_lost + invoke UnlockAchievement, 800h, OFFSET achRouletteWinName + invoke PrintStr, OFFSET casinoRouletteWinText + invoke PaySlotMultiplier, 35 + ret + +casino_roulette_eval_red: + mov eax, casinoRouletteResult + movzx ebx, byte ptr [rouletteColors + eax] + cmp ebx, 1 + je casino_roulette_won_even_money + jmp casino_roulette_lost + +casino_roulette_eval_black: + mov eax, casinoRouletteResult + movzx ebx, byte ptr [rouletteColors + eax] + cmp ebx, 2 + je casino_roulette_won_even_money + jmp casino_roulette_lost + +casino_roulette_eval_even: + mov eax, casinoRouletteResult + cmp eax, 0 + je casino_roulette_lost + test eax, 1 + jz casino_roulette_won_even_money + jmp casino_roulette_lost + +casino_roulette_eval_odd: + mov eax, casinoRouletteResult + cmp eax, 0 + je casino_roulette_lost + test eax, 1 + jnz casino_roulette_won_even_money + jmp casino_roulette_lost + +casino_roulette_eval_dozen1: + mov eax, casinoRouletteResult + cmp eax, 1 + jb casino_roulette_lost + cmp eax, 12 + jbe casino_roulette_won_double + jmp casino_roulette_lost +casino_roulette_eval_dozen2: + mov eax, casinoRouletteResult + cmp eax, 13 + jb casino_roulette_lost + cmp eax, 24 + jbe casino_roulette_won_double + jmp casino_roulette_lost +casino_roulette_eval_dozen3: + mov eax, casinoRouletteResult + cmp eax, 25 + jb casino_roulette_lost + cmp eax, 36 + jbe casino_roulette_won_double + jmp casino_roulette_lost +casino_roulette_eval_low: + mov eax, casinoRouletteResult + cmp eax, 1 + jb casino_roulette_lost + cmp eax, 18 + jbe casino_roulette_won_even_money + jmp casino_roulette_lost +casino_roulette_eval_high: + mov eax, casinoRouletteResult + cmp eax, 36 + jbe casino_roulette_won_even_money + jmp casino_roulette_lost +casino_roulette_eval_col1: + mov eax, casinoRouletteResult + cmp eax, 0 + je casino_roulette_lost + dec eax + xor edx, edx + mov ebx, 3 + div ebx + cmp edx, 0 + je casino_roulette_won_double + jmp casino_roulette_lost +casino_roulette_eval_col2: + mov eax, casinoRouletteResult + cmp eax, 0 + je casino_roulette_lost + dec eax + xor edx, edx + mov ebx, 3 + div ebx + cmp edx, 1 + je casino_roulette_won_double + jmp casino_roulette_lost +casino_roulette_eval_col3: + mov eax, casinoRouletteResult + cmp eax, 0 + je casino_roulette_lost + dec eax + xor edx, edx + mov ebx, 3 + div ebx + cmp edx, 2 + je casino_roulette_won_double + jmp casino_roulette_lost + +casino_roulette_won_double: + invoke UnlockAchievement, 800h, OFFSET achRouletteWinName + invoke PrintStr, OFFSET casinoRouletteWinText + invoke PaySlotMultiplier, 2 + ret +casino_roulette_won_even_money: + invoke UnlockAchievement, 800h, OFFSET achRouletteWinName + invoke PrintStr, OFFSET casinoRouletteWinText + call PayWin + ret +casino_roulette_lost: + invoke PrintStr, OFFSET casinoRouletteLoseText + call PayLose + ret +CasinoRouletteEvaluate ENDP + +; --- GameCasinoRoulette: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +GameCasinoRoulette PROC +casino_roulette_start: + call ClearView + invoke PrintTitleColor, OFFSET casinoRouletteTitle + invoke PrintStr, OFFSET casinoRouletteIntro + call PromptBet + +casino_roulette_choose: + call ClearView + invoke PrintTitleColor, OFFSET casinoRouletteTitle + invoke PrintStr, OFFSET casinoRouletteIntro + call PrintBank + invoke PrintStr, OFFSET casinoRouletteBetMenu + call ReadUInt + cmp eax, 1 + je casino_roulette_choose_number + cmp eax, 2 + je casino_roulette_choose_red + cmp eax, 3 + je casino_roulette_choose_black + cmp eax, 4 + je casino_roulette_choose_even + cmp eax, 5 + je casino_roulette_choose_odd + cmp eax, 6 + je casino_roulette_choose_dozen1 + cmp eax, 7 + je casino_roulette_choose_dozen2 + cmp eax, 8 + je casino_roulette_choose_dozen3 + cmp eax, 9 + je casino_roulette_choose_low + cmp eax, 10 + je casino_roulette_choose_high + cmp eax, 11 + je casino_roulette_choose_col1 + cmp eax, 12 + je casino_roulette_choose_col2 + cmp eax, 13 + je casino_roulette_choose_col3 + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp casino_roulette_choose + +casino_roulette_choose_number: + mov casinoRouletteBetType, 1 + invoke PrintStr, OFFSET casinoRouletteNumberAsk + call ReadUInt + cmp eax, 36 + ja casino_roulette_bad_number + mov casinoRouletteBetNumber, eax + jmp casino_roulette_spin +casino_roulette_bad_number: + invoke PrintStr, OFFSET casinoRouletteBadNumber + call PauseConsole + jmp casino_roulette_choose + +casino_roulette_choose_red: + mov casinoRouletteBetType, 2 + jmp casino_roulette_spin +casino_roulette_choose_black: + mov casinoRouletteBetType, 3 + jmp casino_roulette_spin +casino_roulette_choose_even: + mov casinoRouletteBetType, 4 + jmp casino_roulette_spin +casino_roulette_choose_odd: + mov casinoRouletteBetType, 5 + jmp casino_roulette_spin +casino_roulette_choose_dozen1: + mov casinoRouletteBetType, 6 + jmp casino_roulette_spin +casino_roulette_choose_dozen2: + mov casinoRouletteBetType, 7 + jmp casino_roulette_spin +casino_roulette_choose_dozen3: + mov casinoRouletteBetType, 8 + jmp casino_roulette_spin +casino_roulette_choose_low: + mov casinoRouletteBetType, 9 + jmp casino_roulette_spin +casino_roulette_choose_high: + mov casinoRouletteBetType, 10 + jmp casino_roulette_spin +casino_roulette_choose_col1: + mov casinoRouletteBetType, 11 + jmp casino_roulette_spin +casino_roulette_choose_col2: + mov casinoRouletteBetType, 12 + jmp casino_roulette_spin +casino_roulette_choose_col3: + mov casinoRouletteBetType, 13 + +casino_roulette_spin: + call PlayCasinoRouletteSound + call AnimateCasinoRouletteSpin + call CasinoRouletteEvaluate + +casino_roulette_again: + cmp tournamentMode, 1 + je casino_roulette_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je casino_roulette_start + cmp al, 'Y' + je casino_roulette_start +casino_roulette_tournament_return: + ret +GameCasinoRoulette ENDP +; --- SlotApplyWin: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +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 + +; --- AwardSlotWin: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +AwardSlotWin PROC uses ebx + invoke UnlockAchievement, 80h, OFFSET achCloverPitName + call PrintSlotWindow + invoke PrintStr, OFFSET slotPair + mov slotCurrentCell, 0 +slot_award_combo_loop: + mov eax, slotCurrentCell + cmp eax, slotComboCount + jae slot_award_combo_done + invoke PrintStr, OFFSET slotComboText + mov ebx, slotCurrentCell + mov eax, slotComboNames[ebx * 4] + invoke PrintStr, eax + invoke PrintStr, OFFSET cardGap + invoke PrintStr, OFFSET slotMultiplierText + mov ebx, slotCurrentCell + mov eax, slotComboMults[ebx * 4] + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + inc slotCurrentCell + jmp slot_award_combo_loop +slot_award_combo_done: + invoke PrintStr, OFFSET slotTotalMultiplierText + invoke PrintUInt, slotBestMultiplier + invoke PrintStr, OFFSET nl + cmp slotJackpotHit, 1 + jne slot_award_regular + call PlayJackpotSound + invoke Sleep, 650 + call PlayHakariSound + call PlayHakariDance + call PrintSlotWindow +slot_award_regular: + invoke PaySlotMultiplier, slotBestMultiplier + ret +AwardSlotWin ENDP +; --- GameSlot: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +GameSlot PROC +slot_start: + call ClearView + invoke PrintTitleColor, OFFSET slotTitle + invoke PrintStr, OFFSET slotPayTableText + call PromptBet + call PlaySlotSound + invoke Sleep, 400 + invoke PrintStr, OFFSET slotPullText + mov slotWinMask, 0 + mov slotVisible, 0 + call PrintSlotWindow + invoke Sleep, 1400 + + invoke FillSlotColumn, 0 + mov slotVisible, 1 + call PrintSlotWindow + invoke Sleep, 620 + + invoke FillSlotColumn, 1 + mov slotVisible, 2 + call PrintSlotWindow + invoke Sleep, 620 + + invoke FillSlotColumn, 2 + mov slotVisible, 3 + call PrintSlotWindow + invoke Sleep, 620 + + invoke FillSlotColumn, 3 + mov slotVisible, 4 + call PrintSlotWindow + invoke Sleep, 620 + + invoke FillSlotColumn, 4 + mov slotVisible, 5 + call PrintSlotWindow + invoke Sleep, 450 + + cmp cheatSlotJackpot, 1 + jne slot_no_forced_jackpot + mov cheatSlotJackpot, 0 + mov ecx, 15 + mov edi, OFFSET slotGrid +slot_force_jackpot_loop: + mov dword ptr [edi], 6 + add edi, 4 + loop slot_force_jackpot_loop + call PrintSlotWindow + invoke Sleep, 300 +slot_no_forced_jackpot: + + call EvaluateSlotCombos + cmp slotBestMultiplier, 0 + jne slot_has_win + invoke PrintStr, OFFSET slotEmpty + call PayLose + jmp ask_slot_again + +slot_has_win: + call AwardSlotWin + +ask_slot_again: + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je slot_start + cmp al, 'Y' + je slot_start + ret +GameSlot ENDP +; --- PrintClassicSlotSymbol: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintClassicSlotSymbol PROC uses eax, value:DWORD + mov eax, value + cmp eax, 0 + je classic_symbol_red + cmp eax, 1 + je classic_symbol_yellow + cmp eax, 2 + je classic_symbol_green + cmp eax, 5 + je classic_symbol_cyan + invoke SetColor, COLOR_WARN + jmp classic_symbol_print +classic_symbol_red: + invoke SetColor, COLOR_BAD + jmp classic_symbol_print +classic_symbol_yellow: + invoke SetColor, COLOR_WARN + jmp classic_symbol_print +classic_symbol_green: + invoke SetColor, COLOR_MONEY + jmp classic_symbol_print +classic_symbol_cyan: + invoke SetColor, COLOR_TITLE +classic_symbol_print: + mov eax, value + invoke PrintStr, classicSlotSymbols[eax * 4] + call ResetColor + ret +PrintClassicSlotSymbol ENDP + +; --- PrintClassicSlotCell: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintClassicSlotCell PROC uses eax, value:DWORD + mov eax, value + cmp eax, 1 + je classic_slot_cell_bar + invoke PrintStr, OFFSET slotWall + invoke PrintStr, OFFSET slotPadTwo + invoke PrintClassicSlotSymbol, value + invoke PrintStr, OFFSET slotPadTwo + ret +classic_slot_cell_bar: + invoke PrintStr, OFFSET slotWall + invoke PrintStr, OFFSET slotPadOne + invoke PrintClassicSlotSymbol, value + invoke PrintStr, OFFSET slotPadOne + ret +PrintClassicSlotCell ENDP + +; --- PrintClassicSlotBlankCell: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintClassicSlotBlankCell PROC + invoke PrintStr, OFFSET slotWall + invoke PrintStr, OFFSET slotCellBlank + ret +PrintClassicSlotBlankCell ENDP + +; --- PrintClassicSlotWindow: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintClassicSlotWindow PROC uses eax ebx + call ClearView + invoke PrintTitleColor, OFFSET classicSlotTitle + invoke PrintStr, OFFSET classicSlotBorder + + mov rowIndex, 0 +classic_slot_window_row_loop: + cmp rowIndex, 3 + jae classic_slot_window_done + mov ebx, rowIndex + imul ebx, 3 + + cmp slotVisible, 1 + jb classic_slot_blank_col1 + invoke PrintClassicSlotCell, slotGrid[ebx * 4] + jmp classic_slot_col2 +classic_slot_blank_col1: + call PrintClassicSlotBlankCell + +classic_slot_col2: + cmp slotVisible, 2 + jb classic_slot_blank_col2 + mov eax, ebx + inc eax + invoke PrintClassicSlotCell, slotGrid[eax * 4] + jmp classic_slot_col3 +classic_slot_blank_col2: + call PrintClassicSlotBlankCell + +classic_slot_col3: + cmp slotVisible, 3 + jb classic_slot_blank_col3 + mov eax, ebx + add eax, 2 + invoke PrintClassicSlotCell, slotGrid[eax * 4] + jmp classic_slot_row_end +classic_slot_blank_col3: + call PrintClassicSlotBlankCell + +classic_slot_row_end: + invoke PrintStr, OFFSET slotWall + invoke PrintStr, OFFSET nl + cmp rowIndex, 1 + jne classic_no_payline + invoke PrintStr, OFFSET classicSlotPayline +classic_no_payline: + invoke PrintStr, OFFSET classicSlotBorder + inc rowIndex + jmp classic_slot_window_row_loop + +classic_slot_window_done: + ret +PrintClassicSlotWindow ENDP + +; --- FillClassicSlotColumn: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +FillClassicSlotColumn PROC uses eax ebx, column:DWORD + mov ebx, column + invoke RandomRange, 6 + mov slotGrid[ebx * 4], eax + mov ebx, column + add ebx, 3 + invoke RandomRange, 6 + mov slotGrid[ebx * 4], eax + mov ebx, column + add ebx, 7 + invoke RandomRange, 6 + mov slotGrid[ebx * 4], eax + ret +FillClassicSlotColumn ENDP + +; --- DurakCardRank: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +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: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +DurakCardSuit PROC uses ecx edx, card:DWORD + mov eax, card + xor edx, edx + mov ecx, 13 + div ecx + ret +DurakCardSuit ENDP + +; --- DrawDurakCard: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +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 + +; --- PrintDurakCardName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintDurakCardName PROC uses eax ebx ecx edx, card:DWORD + mov eax, card + cmp eax, 0FFFFFFFFh + jne print_durak_card_real + invoke PrintStr, OFFSET durakUnbeatenText + ret +print_durak_card_real: + xor edx, edx + mov ecx, 13 + div ecx + mov ebx, eax + mov eax, edx + invoke PrintStr, ranks[eax * 4] + invoke PrintSuit, ebx + ret +PrintDurakCardName ENDP + +; --- AddDurakCard: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +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: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +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: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +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: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +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 + +; --- DrawDurakPlayer: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +DrawDurakPlayer PROC + call PlayCardSound + call DrawDurakCard + cmp eax, 0FFFFFFFFh + je draw_durak_player_done + invoke AddDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, eax +draw_durak_player_done: + ret +DrawDurakPlayer ENDP + +; --- DrawDurakAI: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +DrawDurakAI PROC + call PlayCardSound + call DrawDurakCard + cmp eax, 0FFFFFFFFh + je draw_durak_ai_done + invoke AddDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, eax +draw_durak_ai_done: + ret +DrawDurakAI ENDP + +; --- RefillDurakHands: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +RefillDurakHands PROC +refill_player_loop: + cmp durakPlayerCnt, 6 + jae refill_ai_loop + cmp durakDeckLeft, 0 + jbe refill_ai_loop + call DrawDurakPlayer + jmp refill_player_loop +refill_ai_loop: + cmp durakAICnt, 6 + jae refill_done + cmp durakDeckLeft, 0 + jbe refill_done + call DrawDurakAI + jmp refill_ai_loop +refill_done: + ret +RefillDurakHands ENDP +; --- RefillDurakHandsAIFirst: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +RefillDurakHandsAIFirst PROC +refill_ai_first_loop: + cmp durakAICnt, 6 + jae refill_player_after_ai_loop + cmp durakDeckLeft, 0 + jbe refill_player_after_ai_loop + call DrawDurakAI + jmp refill_ai_first_loop +refill_player_after_ai_loop: + cmp durakPlayerCnt, 6 + jae refill_ai_first_done + cmp durakDeckLeft, 0 + jbe refill_ai_first_done + call DrawDurakPlayer + jmp refill_player_after_ai_loop +refill_ai_first_done: + ret +RefillDurakHandsAIFirst ENDP + +; --- PrintDurakHand: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintDurakHand PROC uses eax ebx, pHand:DWORD, count:DWORD + mov rowIndex, 0 +print_durak_hand_loop: + mov eax, rowIndex + cmp eax, count + jae print_durak_hand_done + inc eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET dotSpaceText + mov ebx, pHand + mov eax, rowIndex + invoke PrintDurakCardName, dword ptr [ebx + eax * 4] + invoke PrintStr, OFFSET cardGap + inc rowIndex + jmp print_durak_hand_loop +print_durak_hand_done: + invoke PrintStr, OFFSET nl + ret +PrintDurakHand ENDP + +; --- PrintDurakTable: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintDurakTable PROC uses ebx + cmp durakTableCnt, 0 + je print_table_done + invoke PrintStr, OFFSET durakTablePairsText + invoke PrintHandRow21, OFFSET durakAttackCards, durakTableCnt, 1 + mov rowIndex, 0 +print_table_pairs_loop: + mov eax, rowIndex + cmp eax, durakTableCnt + jae print_table_done + inc eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET dotSpaceText + mov ebx, rowIndex + invoke PrintDurakCardName, durakAttackCards[ebx * 4] + invoke PrintStr, OFFSET durakSlashText + invoke PrintDurakCardName, durakDefenseCards[ebx * 4] + invoke PrintStr, OFFSET nl + inc rowIndex + jmp print_table_pairs_loop +print_table_done: + ret +PrintDurakTable ENDP + +; --- ShowDurakTable: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +ShowDurakTable PROC + call ClearView + invoke PrintTitleColor, OFFSET durakTitle + invoke PrintStr, OFFSET durakDeckVisualText + invoke PrintDurakCardName, durakTrumpCard + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET durakDeckText + invoke PrintUInt, durakDeckLeft + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET durakAICardsText + invoke PrintUInt, durakAICnt + invoke PrintStr, OFFSET nl + cmp durakAICnt, 10 + ja show_ai_no_graphics + invoke PrintStr, OFFSET durakAIFaceText + invoke PrintHandRow21, OFFSET durakAIHand, durakAICnt, 0 +show_ai_no_graphics: + call PrintDurakTable + invoke PrintStr, OFFSET durakYourHandText + cmp durakPlayerCnt, 10 + ja show_player_list_only + invoke PrintHandRow21, OFFSET durakPlayerHand, durakPlayerCnt, 1 +show_player_list_only: + invoke PrintDurakHand, OFFSET durakPlayerHand, durakPlayerCnt + ret +ShowDurakTable ENDP + +; --- FindAIDurakDefense: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +FindAIDurakDefense PROC uses ebx ecx, tableIndex:DWORD + mov rowIndex, 0 +find_ai_defense_loop: + mov eax, rowIndex + cmp eax, durakAICnt + jae find_ai_defense_no + mov ebx, OFFSET durakAIHand + mov ecx, [ebx + eax * 4] + mov ebx, tableIndex + invoke CanDurakBeat, durakAttackCards[ebx * 4], ecx + cmp eax, 1 + je find_ai_defense_yes + inc rowIndex + jmp find_ai_defense_loop +find_ai_defense_yes: + mov eax, rowIndex + ret +find_ai_defense_no: + mov eax, 0FFFFFFFFh + ret +FindAIDurakDefense ENDP + +; --- AIDefendAll: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +AIDefendAll PROC uses ebx + mov durakLoopGuard, 0 +ai_defend_loop: + inc durakLoopGuard + cmp durakLoopGuard, 20 + ja ai_defend_fail + call DurakFirstUnbeaten + cmp eax, 0FFFFFFFFh + je ai_defend_success + mov ebx, eax + invoke FindAIDurakDefense, ebx + cmp eax, 0FFFFFFFFh + je ai_defend_fail + invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, eax + mov durakDefenseCards[ebx * 4], eax + jmp ai_defend_loop +ai_defend_success: + mov eax, 1 + ret +ai_defend_fail: + xor eax, eax + ret +AIDefendAll ENDP + +; --- FindAIThrowIn: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +FindAIThrowIn PROC uses ebx ecx + cmp durakTableCnt, 6 + jae ai_throw_none + mov eax, durakTableCnt + cmp eax, durakPlayerCnt + jae ai_throw_none + mov rowIndex, 0 +ai_throw_loop: + mov eax, rowIndex + cmp eax, durakAICnt + jae ai_throw_none + mov ebx, OFFSET durakAIHand + mov ecx, [ebx + eax * 4] + invoke DurakRankOnTable, ecx + cmp eax, 1 + je ai_throw_found + inc rowIndex + jmp ai_throw_loop +ai_throw_found: + mov eax, rowIndex + ret +ai_throw_none: + mov eax, 0FFFFFFFFh + ret +FindAIThrowIn ENDP + +; --- CheckDurakEnd: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +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 + +; --- SetupDurak: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +SetupDurak PROC uses ecx + call ResetDeck + mov durakPlayerCnt, 0 + mov durakAICnt, 0 + mov durakDeckLeft, 36 + mov durakPlayerTurn, 1 + mov durakSafeTurns, 0 + call ClearDurakTable + call DrawDurakCard + mov durakTrumpCard, eax + invoke DurakCardSuit, eax + mov durakTrumpSuit, eax + mov ecx, 6 +setup_durak_deal: + call DrawDurakPlayer + call DrawDurakAI + loop setup_durak_deal + ret +SetupDurak ENDP + +; --- PlayerOpenAttackLoop: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayerOpenAttackLoop PROC uses ebx ecx +player_open_attack_loop: + mov eax, durakTableCnt + cmp eax, 6 + jae player_open_attack_done + cmp eax, durakAICnt + jae player_open_attack_done + call ShowDurakTable + invoke PrintStr, OFFSET durakThrowAsk + call ReadUInt + cmp eax, 0 + je player_open_attack_done + cmp eax, 1 + jb player_open_attack_bad + cmp eax, durakPlayerCnt + ja player_open_attack_bad + dec eax + mov durakChoice, eax + mov ebx, OFFSET durakPlayerHand + mov ecx, [ebx + eax * 4] + invoke DurakRankOnTable, ecx + cmp eax, 1 + jne player_open_attack_bad + invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, durakChoice + call AddDurakAttack + jmp player_open_attack_loop +player_open_attack_bad: + invoke PrintStr, OFFSET durakBadMoveText + invoke Sleep, 650 + jmp player_open_attack_loop +player_open_attack_done: + ret +PlayerOpenAttackLoop ENDP + +; --- AIInitialThrowLoop: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +AIInitialThrowLoop PROC + mov durakLoopGuard, 0 +ai_initial_throw_loop: + inc durakLoopGuard + cmp durakLoopGuard, 20 + ja ai_initial_throw_done + call FindAIThrowIn + cmp eax, 0FFFFFFFFh + je ai_initial_throw_done + invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, eax + call AddDurakAttack + jmp ai_initial_throw_loop +ai_initial_throw_done: + ret +AIInitialThrowLoop ENDP +; --- PlayerThrowLoop: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayerThrowLoop PROC uses ebx ecx + mov durakLoopGuard, 0 +player_throw_loop: + inc durakLoopGuard + cmp durakLoopGuard, 30 + ja player_throw_done + call ShowDurakTable + call AIDefendAll + cmp eax, 1 + je player_throw_after_defense + invoke CollectDurakTable, OFFSET durakAIHand, OFFSET durakAICnt + invoke PrintStr, OFFSET durakAITakeText + mov durakPlayerTurn, 1 + call RefillDurakHands + call PauseConsole + ret +player_throw_after_defense: + call ShowDurakTable + invoke PrintStr, OFFSET durakThrowAsk + call ReadUInt + cmp eax, 0 + je player_throw_done + cmp eax, 1 + jb player_throw_bad + cmp eax, durakPlayerCnt + ja player_throw_bad + cmp durakTableCnt, 6 + jae player_throw_bad + dec eax + mov durakChoice, eax + mov ebx, OFFSET durakPlayerHand + mov ecx, [ebx + eax * 4] + invoke DurakRankOnTable, ecx + cmp eax, 1 + jne player_throw_bad + invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, durakChoice + call AddDurakAttack + jmp player_throw_loop +player_throw_bad: + invoke PrintStr, OFFSET durakBadMoveText + invoke Sleep, 650 + jmp player_throw_loop +player_throw_done: + call ClearDurakTable + mov durakPlayerTurn, 0 + call RefillDurakHands + ret +PlayerThrowLoop ENDP + +; --- PlayerDefendLoop: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayerDefendLoop PROC uses ebx ecx + mov durakLoopGuard, 0 +player_defend_loop: + inc durakLoopGuard + cmp durakLoopGuard, 30 + ja player_take_table + call DurakAllDefended + cmp eax, 1 + je player_defended_all + call ShowDurakTable + invoke PrintStr, OFFSET durakDefendAsk + call ReadUInt + cmp eax, 0 + je player_take_table + cmp eax, 1 + jb player_def_bad + cmp eax, durakPlayerCnt + ja player_def_bad + dec eax + mov durakChoice, eax + mov ebx, OFFSET durakPlayerHand + mov ecx, [ebx + eax * 4] + + call DurakTableHasDefense + cmp eax, 0 + jne player_try_beat + invoke DurakRankOnTable, ecx + cmp eax, 1 + jne player_try_beat + mov eax, durakTableCnt + cmp durakAICnt, eax + jbe player_try_beat + invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, durakChoice + call AddDurakAttack + invoke PrintStr, OFFSET durakTransferText + call PauseConsole + call PlayerThrowLoop + ret + +player_try_beat: + call DurakFirstUnbeaten + mov ebx, eax + mov ecx, OFFSET durakPlayerHand + mov eax, durakChoice + mov ecx, [ecx + eax * 4] + invoke CanDurakBeat, durakAttackCards[ebx * 4], ecx + cmp eax, 1 + jne player_def_bad + invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, durakChoice + mov durakDefenseCards[ebx * 4], eax + jmp player_defend_loop +player_def_bad: + invoke PrintStr, OFFSET durakBadMoveText + invoke Sleep, 650 + jmp player_defend_loop +player_take_table: + invoke CollectDurakTable, OFFSET durakPlayerHand, OFFSET durakPlayerCnt + invoke PrintStr, OFFSET durakPlayerTakeText + mov durakPlayerTurn, 0 + call RefillDurakHandsAIFirst + call PauseConsole + ret +player_defended_all: + call FindAIThrowIn + cmp eax, 0FFFFFFFFh + je player_defense_done + invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, eax + call AddDurakAttack + jmp player_defend_loop +player_defense_done: + invoke PrintStr, OFFSET durakPlayerDefendText + call ClearDurakTable + mov durakPlayerTurn, 1 + call RefillDurakHandsAIFirst + call PauseConsole + ret +PlayerDefendLoop ENDP + +; --- GameDurak: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +GameDurak PROC + durak_start: + call ClearView + invoke PrintTitleColor, OFFSET durakTitle + call PromptBet + call SetupDurak + +durak_round_loop: + call CheckDurakEnd + cmp eax, 1 + je durak_finish_win + cmp eax, 2 + je durak_finish_lose + cmp eax, 3 + je durak_finish_draw + inc durakSafeTurns + cmp durakSafeTurns, 300 + ja durak_finish_stuck + call ClearDurakTable + cmp durakPlayerTurn, 1 + je durak_check_player_attack + jmp durak_check_ai_attack + +durak_check_player_attack: + cmp durakPlayerCnt, 0 + jne durak_player_attack + cmp durakDeckLeft, 0 + jbe durak_round_loop + call RefillDurakHands + cmp durakPlayerCnt, 0 + jne durak_player_attack + jmp durak_finish_stuck + +durak_check_ai_attack: + cmp durakAICnt, 0 + jne durak_ai_attack + cmp durakDeckLeft, 0 + jbe durak_round_loop + call RefillDurakHandsAIFirst + cmp durakAICnt, 0 + jne durak_ai_attack + jmp durak_finish_stuck + +durak_player_attack: +player_attack_choose: + call ShowDurakTable + invoke PrintStr, OFFSET durakAttackAsk + call ReadUInt + cmp eax, 1 + jb player_attack_bad + cmp eax, durakPlayerCnt + ja player_attack_bad + dec eax + invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, eax + call AddDurakAttack + call PlayerOpenAttackLoop + call PlayerThrowLoop + jmp durak_round_loop +player_attack_bad: + invoke PrintStr, OFFSET durakBadMoveText + invoke Sleep, 650 + jmp player_attack_choose + +durak_ai_attack: + cmp durakAICnt, 0 + jne durak_ai_has_card + call RefillDurakHandsAIFirst + cmp durakAICnt, 0 + je durak_round_loop +durak_ai_has_card: + invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, 0 + call AddDurakAttack + call AIInitialThrowLoop + call PlayerDefendLoop + jmp durak_round_loop + +durak_finish_win: + invoke UnlockAchievement, 2000h, OFFSET achDurakWinName + call ShowDurakTable + invoke PrintStr, OFFSET durakWinText + call PayWin + jmp durak_again + +durak_finish_lose: + call ShowDurakTable + invoke PrintStr, OFFSET durakLoseText + call PayLose + jmp durak_again + +durak_finish_stuck: + call ShowDurakTable + invoke PrintStr, OFFSET durakStuckText + call PayDraw + jmp durak_again + +durak_finish_draw: + call ShowDurakTable + invoke PrintStr, OFFSET drawText + call PayDraw + +durak_again: + cmp tournamentMode, 1 + je durak_tournament_return + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je durak_start + cmp al, 'Y' + je durak_start +durak_tournament_return: + ret +GameDurak ENDP +; --- GameClassicSlot: ñëîò-ìàøèíû, áàðàáàíû, ñèìâîëû, âûïëàòû è äæåêïîòû --- +GameClassicSlot PROC +classic_slot_start: + call ClearView + invoke PrintTitleColor, OFFSET classicSlotTitle + invoke PrintStr, OFFSET classicSlotPayTableText + call PromptBet + call PlaySlotSound + invoke Sleep, 400 + invoke PrintStr, OFFSET slotPullText + mov slotWinMask, 0 + mov slotVisible, 0 + call PrintClassicSlotWindow + invoke Sleep, 1600 + + invoke FillClassicSlotColumn, 0 + mov slotVisible, 1 + call PrintClassicSlotWindow + invoke Sleep, 750 + + invoke FillClassicSlotColumn, 1 + mov slotVisible, 2 + call PrintClassicSlotWindow + invoke Sleep, 750 + + invoke FillClassicSlotColumn, 2 + mov slotVisible, 3 + call PrintClassicSlotWindow + invoke Sleep, 450 + + cmp cheatSlotJackpot, 1 + jne classic_no_forced_jackpot + mov cheatSlotJackpot, 0 + mov dword ptr slotGrid[12], 0 + mov dword ptr slotGrid[16], 0 + mov dword ptr slotGrid[20], 0 + call PrintClassicSlotWindow + invoke Sleep, 300 +classic_no_forced_jackpot: + + mov eax, slotGrid[12] + mov slotA, eax + mov eax, slotGrid[16] + mov slotB, eax + mov eax, slotGrid[20] + mov slotC, eax + + mov eax, slotA + cmp eax, slotB + jne classic_slot_check_pair_1 + mov eax, slotB + cmp eax, slotC + jne classic_slot_pair + invoke UnlockAchievement, 100h, OFFSET achClassicSlotName + call PlayJackpotSound + invoke PrintStr, OFFSET classicSlotJackpot + invoke Sleep, 650 + call PlayHakariSound + call PlayHakariDance + call PrintClassicSlotWindow + mov eax, slotA + cmp eax, 0 + je classic_slot_pay_777 + cmp eax, 2 + je classic_slot_pay_dollar + cmp eax, 1 + je classic_slot_pay_bar + cmp eax, 5 + je classic_slot_pay_aaa + invoke PaySlotMultiplier, 3 + jmp classic_ask_slot_again +classic_slot_pay_777: + invoke UnlockAchievement, 100h, OFFSET achClassicSlotName + invoke PaySlotMultiplier, 10 + jmp classic_ask_slot_again +classic_slot_pay_dollar: + invoke PaySlotMultiplier, 7 + jmp classic_ask_slot_again +classic_slot_pay_bar: + invoke PaySlotMultiplier, 5 + jmp classic_ask_slot_again +classic_slot_pay_aaa: + invoke PaySlotMultiplier, 4 + jmp classic_ask_slot_again + +classic_slot_check_pair_1: + mov eax, slotA + cmp eax, slotC + je classic_slot_pair + mov eax, slotB + cmp eax, slotC + je classic_slot_pair + invoke PrintStr, OFFSET classicSlotEmpty + call PayLose + jmp classic_ask_slot_again + +classic_slot_pair: + invoke UnlockAchievement, 100h, OFFSET achClassicSlotName + invoke PrintStr, OFFSET classicSlotPair + invoke PaySlotMultiplier, 2 + +classic_ask_slot_again: + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je classic_slot_start + cmp al, 'Y' + je classic_slot_start + ret +GameClassicSlot ENDP +; --- ObserverDrawAI1: ðåæèì íàáëþäàòåëÿ AI vs AI --- +ObserverDrawAI1 PROC + call DrawPlayer21Hand + call CalcPlayerScore21 + ret +ObserverDrawAI1 ENDP + +; --- ObserverDrawAI2: ðåæèì íàáëþäàòåëÿ AI vs AI --- +ObserverDrawAI2 PROC + call DrawAI21Hand + call CalcAIScore21 + ret +ObserverDrawAI2 ENDP + +; --- ObserverShow21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +ObserverShow21 PROC + call ClearView + invoke PrintTitleColor, OFFSET observer21Title + invoke PrintStr, OFFSET observerAI1CardsText + invoke PrintHandRow21, OFFSET playerHand21, playerCnt21, 1 + invoke PrintStr, OFFSET observerAI1Text + invoke PrintUInt, playerTotal + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET observerAI2CardsText + invoke PrintHandRow21, OFFSET aiHand21, aiCnt21, 1 + invoke PrintStr, OFFSET observerAI2Text + invoke PrintUInt, dealerTotal + invoke PrintStr, OFFSET nl + ret +ObserverShow21 ENDP + +; --- GameObserver21: êàðòû, ðóêè, î÷êè è áàçîâàÿ êàðòî÷íàÿ ëîãèêà --- +GameObserver21 PROC + call ClearView + invoke PrintTitleColor, OFFSET observer21Title + call ResetDeck + mov playerCnt21, 0 + mov aiCnt21, 0 + mov revealAI21, 1 + call ObserverDrawAI1 + call ObserverDrawAI1 + call ObserverDrawAI2 + call ObserverDrawAI2 +observer21_loop: + call ObserverShow21 + invoke Sleep, 750 + cmp playerTotal, 17 + jae observer21_ai2 + call ObserverDrawAI1 + jmp observer21_loop +observer21_ai2: + cmp dealerTotal, 17 + jae observer21_compare + call ObserverDrawAI2 + jmp observer21_loop +observer21_compare: + call ObserverShow21 + mov eax, playerTotal + cmp eax, 21 + ja observer21_ai1_bust + mov eax, dealerTotal + cmp eax, 21 + ja observer21_ai1_win + mov eax, playerTotal + cmp eax, dealerTotal + ja observer21_ai1_win + jb observer21_ai2_win + invoke PrintStr, OFFSET observerDrawText + jmp observer21_done +observer21_ai1_bust: + mov eax, dealerTotal + cmp eax, 21 + ja observer21_draw + jmp observer21_ai2_win +observer21_draw: + invoke PrintStr, OFFSET observerDrawText + jmp observer21_done +observer21_ai1_win: + invoke PrintStr, OFFSET observerWin1Text + jmp observer21_done +observer21_ai2_win: + invoke PrintStr, OFFSET observerWin2Text +observer21_done: + call PauseConsole + ret +GameObserver21 ENDP + +; --- ObserverPokerEvaluate: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +ObserverPokerEvaluate PROC + invoke BuildPokerEvalHand, OFFSET playerHand21, OFFSET pokerPlayerEvalHand + invoke EvaluatePokerN, OFFSET pokerPlayerEvalHand, pokerEvalCount + mov pokerPlayerScore, eax + invoke BuildPokerEvalHand, OFFSET aiHand21, OFFSET pokerAIEvalHand + invoke EvaluatePokerN, OFFSET pokerAIEvalHand, pokerEvalCount + mov pokerAIScore, eax + ret +ObserverPokerEvaluate ENDP + +; --- ObserverShowPoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +ObserverShowPoker PROC + call ClearView + invoke PrintTitleColor, OFFSET observerPokerTitle + call ShowPokerTable + call ShowPokerMoney + call ObserverPokerEvaluate + invoke PrintStr, OFFSET pokerYourComboText + invoke PrintPokerHandName, pokerPlayerScore + invoke PrintStr, OFFSET pokerAIComboText + invoke PrintPokerHandName, pokerAIScore + ret +ObserverShowPoker ENDP + +; --- ObserverPokerDecision: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +ObserverPokerDecision PROC uses ebx edx + call ObserverPokerEvaluate + mov eax, pokerPlayerScore + cmp eax, 9 + ja observer_poker_ai2_check_fold + invoke RandomRange, 4 + cmp eax, 0 + je observer_poker_ai1_fold +observer_poker_ai2_check_fold: + mov eax, pokerAIScore + cmp eax, 9 + ja observer_poker_raise_check + invoke RandomRange, 4 + cmp eax, 0 + je observer_poker_ai2_fold +observer_poker_raise_check: + mov eax, pokerPlayerScore + cmp eax, 1000 + jb observer_poker_ai2_raise_check + invoke RandomRange, 2 + cmp eax, 0 + jne observer_poker_ai2_raise_check + invoke PrintStr, OFFSET observerAI1RaiseText + add currentBet, 500 + invoke Sleep, 450 + mov eax, pokerAIScore + cmp eax, pokerPlayerScore + jae observer_poker_call_1 + invoke RandomRange, 2 + cmp eax, 0 + je observer_poker_ai2_fold +observer_poker_call_1: + invoke PrintStr, OFFSET observerCallText +observer_poker_ai2_raise_check: + mov eax, pokerAIScore + cmp eax, 1000 + jb observer_poker_continue + invoke RandomRange, 2 + cmp eax, 0 + jne observer_poker_continue + invoke PrintStr, OFFSET observerAI2RaiseText + add currentBet, 500 + invoke Sleep, 450 + mov eax, pokerPlayerScore + cmp eax, pokerAIScore + jae observer_poker_call_2 + invoke RandomRange, 2 + cmp eax, 0 + je observer_poker_ai1_fold +observer_poker_call_2: + invoke PrintStr, OFFSET observerCallText +observer_poker_continue: + xor eax, eax + ret +observer_poker_ai1_fold: + invoke PrintStr, OFFSET observerFold1Text + mov eax, 2 + ret +observer_poker_ai2_fold: + invoke PrintStr, OFFSET observerFold2Text + mov eax, 1 + ret +ObserverPokerDecision ENDP + +; --- GameObserverPoker: ïîêåð: îöåíêà êîìáèíàöèé, ñòàâêè, ôîëäû è ÈÈ --- +GameObserverPoker PROC + call ClearView + invoke PrintTitleColor, OFFSET observerPokerTitle + call ResetDeck + call ResetPokerHands + mov revealAI21, 1 + mov currentBet, 500 + call DealPokerHands +observer_poker_stage_loop: + call ObserverShowPoker + invoke Sleep, 700 + cmp communityCnt, 5 + jae observer_poker_showdown + call ObserverPokerDecision + cmp eax, 1 + je observer_poker_ai1_wins + cmp eax, 2 + je observer_poker_ai2_wins + invoke PrintStr, OFFSET pokerNextCardText + invoke Sleep, 700 + inc communityCnt + jmp observer_poker_stage_loop +observer_poker_showdown: + call ObserverShowPoker + mov eax, pokerPlayerScore + cmp eax, pokerAIScore + ja observer_poker_ai1_wins + jb observer_poker_ai2_wins + invoke PrintStr, OFFSET observerDrawText + jmp observer_poker_done +observer_poker_ai1_wins: + invoke PrintStr, OFFSET observerWin1Text + jmp observer_poker_done +observer_poker_ai2_wins: + invoke PrintStr, OFFSET observerWin2Text +observer_poker_done: + call PauseConsole + ret +GameObserverPoker ENDP + +; --- FindPlayerDurakDefense: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +FindPlayerDurakDefense PROC uses ebx ecx, tableIndex:DWORD + mov rowIndex, 0 +find_player_defense_loop: + mov eax, rowIndex + cmp eax, durakPlayerCnt + jae find_player_defense_no + mov ebx, OFFSET durakPlayerHand + mov ecx, [ebx + eax * 4] + mov ebx, tableIndex + invoke CanDurakBeat, durakAttackCards[ebx * 4], ecx + cmp eax, 1 + je find_player_defense_yes + inc rowIndex + jmp find_player_defense_loop +find_player_defense_yes: + mov eax, rowIndex + ret +find_player_defense_no: + mov eax, 0FFFFFFFFh + ret +FindPlayerDurakDefense ENDP + +; --- PlayerAIDefendAll: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayerAIDefendAll PROC uses ebx +player_ai_defend_loop: + call DurakFirstUnbeaten + cmp eax, 0FFFFFFFFh + je player_ai_defend_success + mov ebx, eax + invoke FindPlayerDurakDefense, ebx + cmp eax, 0FFFFFFFFh + je player_ai_defend_fail + invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, eax + mov durakDefenseCards[ebx * 4], eax + jmp player_ai_defend_loop +player_ai_defend_success: + mov eax, 1 + ret +player_ai_defend_fail: + xor eax, eax + ret +PlayerAIDefendAll ENDP + +; --- FindPlayerThrowIn: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +FindPlayerThrowIn PROC uses ebx ecx + cmp durakTableCnt, 6 + jae player_ai_throw_none + mov eax, durakTableCnt + cmp eax, durakAICnt + jae player_ai_throw_none + mov rowIndex, 0 +player_ai_throw_loop: + mov eax, rowIndex + cmp eax, durakPlayerCnt + jae player_ai_throw_none + mov ebx, OFFSET durakPlayerHand + mov ecx, [ebx + eax * 4] + invoke DurakRankOnTable, ecx + cmp eax, 1 + je player_ai_throw_found + inc rowIndex + jmp player_ai_throw_loop +player_ai_throw_found: + mov eax, rowIndex + ret +player_ai_throw_none: + mov eax, 0FFFFFFFFh + ret +FindPlayerThrowIn ENDP + +; --- PlayerAIInitialThrowLoop: çâóê, èíòðî èëè ïîêàäðîâàÿ àíèìàöèÿ --- +PlayerAIInitialThrowLoop PROC +player_ai_initial_throw_loop: + call FindPlayerThrowIn + cmp eax, 0FFFFFFFFh + je player_ai_initial_throw_done + invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, eax + call AddDurakAttack + jmp player_ai_initial_throw_loop +player_ai_initial_throw_done: + ret +PlayerAIInitialThrowLoop ENDP + +; --- ShowDurakObserverTable: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +ShowDurakObserverTable PROC + call ClearView + invoke PrintTitleColor, OFFSET observerDurakTitle + invoke PrintStr, OFFSET durakDeckVisualText + invoke PrintDurakCardName, durakTrumpCard + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET durakDeckText + invoke PrintUInt, durakDeckLeft + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET observerAI1CardsText + invoke PrintHandRow21, OFFSET durakPlayerHand, durakPlayerCnt, 1 + call PrintDurakTable + invoke PrintStr, OFFSET observerAI2CardsText + invoke PrintHandRow21, OFFSET durakAIHand, durakAICnt, 1 + ret +ShowDurakObserverTable ENDP + +; --- GameObserverDurak: äóðàê: êîçûðü, àòàêà, çàùèòà, ïîäêèäûâàíèå è äîáîð --- +GameObserverDurak PROC + call SetupDurak + mov pokerReplaceIndex, 0 +observer_durak_loop: + inc pokerReplaceIndex + cmp pokerReplaceIndex, 32 + ja observer_durak_draw + call CheckDurakEnd + cmp eax, 1 + je observer_durak_ai1_win + cmp eax, 2 + je observer_durak_ai2_win + cmp eax, 3 + je observer_durak_draw + call ClearDurakTable + cmp durakPlayerTurn, 1 + je observer_durak_ai1_attack + jmp observer_durak_ai2_attack +observer_durak_ai1_attack: + cmp durakPlayerCnt, 0 + je observer_durak_ai1_win + invoke RemoveDurakCard, OFFSET durakPlayerHand, OFFSET durakPlayerCnt, 0 + call AddDurakAttack + call PlayerAIInitialThrowLoop + call ShowDurakObserverTable + invoke Sleep, 750 + call AIDefendAll + cmp eax, 1 + je observer_durak_ai2_defended + invoke CollectDurakTable, OFFSET durakAIHand, OFFSET durakAICnt + invoke PrintStr, OFFSET durakAITakeText + mov durakPlayerTurn, 1 + call RefillDurakHands + invoke Sleep, 850 + jmp observer_durak_loop +observer_durak_ai2_defended: + call ShowDurakObserverTable + invoke Sleep, 750 + call ClearDurakTable + mov durakPlayerTurn, 0 + call RefillDurakHands + jmp observer_durak_loop +observer_durak_ai2_attack: + cmp durakAICnt, 0 + je observer_durak_ai2_win + invoke RemoveDurakCard, OFFSET durakAIHand, OFFSET durakAICnt, 0 + call AddDurakAttack + call AIInitialThrowLoop + call ShowDurakObserverTable + invoke Sleep, 750 + call PlayerAIDefendAll + cmp eax, 1 + je observer_durak_ai1_defended + invoke CollectDurakTable, OFFSET durakPlayerHand, OFFSET durakPlayerCnt + invoke PrintStr, OFFSET durakPlayerTakeText + mov durakPlayerTurn, 0 + call RefillDurakHandsAIFirst + invoke Sleep, 850 + jmp observer_durak_loop +observer_durak_ai1_defended: + call ShowDurakObserverTable + invoke Sleep, 750 + call ClearDurakTable + mov durakPlayerTurn, 1 + call RefillDurakHandsAIFirst + jmp observer_durak_loop +observer_durak_ai1_win: + call ShowDurakObserverTable + invoke PrintStr, OFFSET observerWin1Text + jmp observer_durak_done +observer_durak_ai2_win: + call ShowDurakObserverTable + invoke PrintStr, OFFSET observerWin2Text + jmp observer_durak_done +observer_durak_draw: + call ShowDurakObserverTable + invoke PrintStr, OFFSET observerDrawText +observer_durak_done: + call PauseConsole + ret +GameObserverDurak ENDP + +; --- GameObserverRoulette: ðóññêàÿ ðóëåòêà èëè êàçèíî-ðóëåòêà --- +GameObserverRoulette PROC + call ClearView + invoke PrintTitleColor, OFFSET observerRRTitle + call PlayRouletteSpinSound + call SetupRoulette + call AnimateRouletteSpin +observer_rr_loop: + call ShowRouletteStatus + cmp rrTurn, 0 + je observer_rr_ai1_turn + invoke PrintStr, OFFSET rrAITurnText + invoke Sleep, 850 + call RouletteChamberLoaded + cmp eax, 1 + je observer_rr_ai2_dead + call PlayRouletteDrySound + invoke PrintStr, OFFSET rrClickText + invoke Sleep, 750 + call AdvanceRouletteChamber + mov rrTurn, 0 + jmp observer_rr_loop +observer_rr_ai1_turn: + invoke PrintStr, OFFSET rrPlayerTurnText + invoke Sleep, 850 + call RouletteChamberLoaded + cmp eax, 1 + je observer_rr_ai1_dead + call PlayRouletteDrySound + invoke PrintStr, OFFSET rrClickText + invoke Sleep, 750 + call AdvanceRouletteChamber + mov rrTurn, 1 + jmp observer_rr_loop +observer_rr_ai1_dead: + call PrintBang + invoke PrintStr, OFFSET observerShotAI1Text + jmp observer_rr_done +observer_rr_ai2_dead: + call PrintBang + invoke PrintStr, OFFSET observerShotAI2Text +observer_rr_done: + call PauseConsole + ret +GameObserverRoulette ENDP + +; --- GameObserver: ðåæèì íàáëþäàòåëÿ AI vs AI --- +GameObserver PROC +observer_menu_loop: + call ClearView + invoke PrintTitleColor, OFFSET observerTitle + invoke PrintStr, OFFSET observerMenuText + call ReadUInt + cmp eax, 0 + je observer_exit + cmp eax, 1 + je observer_run_rr + cmp eax, 2 + je observer_run_21 + cmp eax, 3 + je observer_run_poker + cmp eax, 4 + je observer_run_durak + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp observer_menu_loop +observer_run_rr: + invoke UnlockAchievement, 10000h, OFFSET achObserverName + call GameObserverRoulette + jmp observer_menu_loop +observer_run_21: + mov currentGameId, 1 + invoke UnlockAchievement, 10000h, OFFSET achObserverName + call GameObserver21 + jmp observer_menu_loop +observer_run_poker: + mov currentGameId, 2 + invoke UnlockAchievement, 10000h, OFFSET achObserverName + call GameObserverPoker + jmp observer_menu_loop +observer_run_durak: + mov currentGameId, 10 + invoke UnlockAchievement, 10000h, OFFSET achObserverName + call GameObserverDurak + jmp observer_menu_loop +observer_exit: + ret +GameObserver ENDP + +; --- PrintShopBackName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintShopBackName PROC + mov eax, shopBackStyle + cmp eax, 1 + je print_shop_back_blue + cmp eax, 2 + je print_shop_back_red + cmp eax, 3 + je print_shop_back_gold + cmp eax, 4 + je print_shop_back_skull + cmp eax, 5 + je print_shop_back_clover + cmp eax, 6 + je print_shop_back_arcane + cmp eax, 7 + je print_shop_back_noir + cmp eax, 8 + je print_shop_back_diamond + cmp eax, 9 + je print_shop_back_rider + cmp eax, 10 + je print_shop_back_bee + cmp eax, 11 + je print_shop_back_fan + cmp eax, 12 + je print_shop_back_web + invoke PrintStr, OFFSET shopBackGray + ret +print_shop_back_blue: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopBackBlue + call ResetColor + ret +print_shop_back_red: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET shopBackRed + call ResetColor + ret +print_shop_back_gold: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopBackGold + call ResetColor + ret +print_shop_back_skull: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET shopBackSkull + call ResetColor + ret +print_shop_back_clover: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET shopBackClover + call ResetColor + ret +print_shop_back_arcane: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopBackArcane + call ResetColor + ret +print_shop_back_noir: + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET shopBackNoir + call ResetColor + ret +print_shop_back_diamond: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopBackDiamond + call ResetColor + ret +print_shop_back_rider: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopBackRider + call ResetColor + ret +print_shop_back_bee: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopBackBee + call ResetColor + ret +print_shop_back_fan: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopBackFan + call ResetColor + ret +print_shop_back_web: + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET shopBackWeb + call ResetColor + ret +PrintShopBackName ENDP + +; --- PrintShopCharmName: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintShopCharmName PROC + mov eax, shopCharmLevel + cmp eax, 1 + je print_shop_charm_clover + cmp eax, 2 + je print_shop_charm_bell + cmp eax, 3 + je print_shop_charm_diamond + cmp eax, 4 + je print_shop_charm_skull + cmp eax, 5 + je print_shop_charm_web + cmp eax, 6 + je print_shop_charm_bee + cmp eax, 7 + je print_shop_charm_moon + cmp eax, 8 + je print_shop_charm_crown + cmp eax, 9 + je print_shop_charm_mirror + cmp eax, 10 + je print_shop_charm_dice + cmp eax, 11 + je print_shop_charm_blood + cmp eax, 12 + je print_shop_charm_hourglass + cmp eax, 13 + je print_shop_charm_horseshoe + cmp eax, 14 + je print_shop_charm_joker + cmp eax, 15 + je print_shop_charm_phoenix + cmp eax, 16 + je print_shop_charm_compass + cmp eax, 17 + je print_shop_charm_tooth + cmp eax, 18 + je print_shop_charm_eye + cmp eax, 19 + je print_shop_charm_key + cmp eax, 20 + je print_shop_charm_candle + cmp eax, 21 + je print_shop_charm_chip + cmp eax, 22 + je print_shop_charm_snake + cmp eax, 23 + je print_shop_charm_ace + cmp eax, 24 + je print_shop_charm_devil + invoke PrintStr, OFFSET shopCharmNone + ret +print_shop_charm_clover: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET shopCharmClover + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_bell: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopCharmBell + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_diamond: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopCharmDiamond + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_skull: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET shopCharmSkull + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_web: + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET shopCharmWeb + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_bee: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopCharmBee + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_moon: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopCharmMoon + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_crown: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopCharmCrown + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_mirror: + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET shopCharmMirror + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_dice: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopCharmDice + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_blood: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET shopCharmBlood + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_hourglass: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopCharmHourglass + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_horseshoe: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET shopCharmHorseshoe + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_joker: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET shopCharmJoker + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_phoenix: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopCharmPhoenix + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_compass: + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET shopCharmCompass + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_tooth: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopCharmTooth + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_eye: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopCharmEye + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_key: + invoke SetColor, COLOR_CARD + invoke PrintStr, OFFSET shopCharmKey + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_candle: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET shopCharmCandle + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_chip: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET shopCharmChip + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_snake: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET shopCharmSnake + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_ace: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET shopCharmAce + call ResetColor + jmp print_shop_charm_uses +print_shop_charm_devil: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET shopCharmDevil + call ResetColor +print_shop_charm_uses: + invoke PrintStr, OFFSET shopCharmUsesText + invoke PrintUInt, shopCharmUses + invoke PrintStr, OFFSET nl + ret +PrintShopCharmName ENDP + +; --- PrintShopStatus: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintShopStatus PROC + call PrintBank + invoke PrintStr, OFFSET shopBackText + call PrintShopBackName + invoke PrintStr, OFFSET shopCharmText + call PrintShopCharmName + invoke PrintStr, OFFSET nl + ret +PrintShopStatus ENDP + +; --- ShopBuyBack: ìàãàçèí ðóáàøåê, òàëèñìàíîâ è ïîêóïîê --- +ShopBuyBack PROC uses eax ebx, style:DWORD, cost:DWORD, maskValue:DWORD + mov eax, shopBackOwned + mov ebx, maskValue + test eax, ebx + jne shop_back_already_owned + + mov eax, cost + cmp bankroll, eax + jae shop_back_buy + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET tooBigBetText + call ResetColor + ret +shop_back_buy: + sub bankroll, eax + mov eax, shopBackOwned + or eax, ebx + mov shopBackOwned, eax + mov eax, style + mov shopBackStyle, eax + call SaveGame + invoke UnlockAchievement, 10h, OFFSET achShopperName + mov eax, shopBackOwned + and eax, 1FFFh + cmp eax, 1FFFh + jne shop_back_collector_skip + invoke UnlockAchievement, 4000h, OFFSET achBackCollectorName +shop_back_collector_skip: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET shopBoughtText + call ResetColor + call PrintBank + call CheckBankrupt + ret +shop_back_already_owned: + mov eax, style + mov shopBackStyle, eax + call SaveGame + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET shopSelectedText + call ResetColor + ret +ShopBuyBack ENDP + +; --- ShopBuyCharm: ïîêóïêà òàëèñìàíà ñ ðàçíûìè çàðÿäàìè --- +ShopBuyCharm PROC uses eax, charmLevel:DWORD, cost:DWORD + mov eax, cost + cmp bankroll, eax + jae shop_charm_buy + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET tooBigBetText + call ResetColor + ret +shop_charm_buy: + sub bankroll, eax + mov eax, charmLevel + mov shopCharmLevel, eax + cmp eax, 5 + je shop_charm_one_use + cmp eax, 11 + je shop_charm_one_use + cmp eax, 14 + je shop_charm_one_use + cmp eax, 18 + je shop_charm_one_use + cmp eax, 20 + je shop_charm_one_use + cmp eax, 24 + je shop_charm_one_use + cmp eax, 4 + je shop_charm_two_uses + cmp eax, 8 + je shop_charm_two_uses + cmp eax, 12 + je shop_charm_two_uses + cmp eax, 15 + je shop_charm_two_uses + cmp eax, 22 + je shop_charm_two_uses + cmp eax, 7 + je shop_charm_four_uses + cmp eax, 9 + je shop_charm_four_uses + cmp eax, 21 + je shop_charm_four_uses + cmp eax, 6 + je shop_charm_five_uses + cmp eax, 17 + je shop_charm_five_uses + cmp eax, 23 + je shop_charm_five_uses + cmp eax, 10 + je shop_charm_six_uses + cmp eax, 19 + je shop_charm_six_uses + cmp eax, 13 + je shop_charm_eight_uses + mov shopCharmUses, 3 + jmp shop_charm_store +shop_charm_one_use: + mov shopCharmUses, 1 + jmp shop_charm_store +shop_charm_two_uses: + mov shopCharmUses, 2 + jmp shop_charm_store +shop_charm_four_uses: + mov shopCharmUses, 4 + jmp shop_charm_store +shop_charm_five_uses: + mov shopCharmUses, 5 + jmp shop_charm_store +shop_charm_six_uses: + mov shopCharmUses, 6 + jmp shop_charm_store +shop_charm_eight_uses: + mov shopCharmUses, 8 +shop_charm_store: + call SaveGame + invoke UnlockAchievement, 10h, OFFSET achShopperName + invoke UnlockAchievement, 8000h, OFFSET achCharmBuyerName + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET shopBoughtText + call ResetColor + call PrintBank + call CheckBankrupt + ret +ShopBuyCharm ENDP + +; --- ShowBestiaryPage: êàðòî÷êà òàëèñìàíà â áåñòèàðèè --- +ShowBestiaryPage PROC artPtr:DWORD, infoPtr:DWORD, colorValue:DWORD + call ClearView + invoke SetColor, colorValue + invoke PrintStr, artPtr + call ResetColor + invoke PrintStr, infoPtr + invoke PrintStr, OFFSET bestiaryBackText + call ReadKey + ret +ShowBestiaryPage ENDP + +; --- GameCharmBestiary: ýíöèêëîïåäèÿ òàëèñìàíîâ ñ ASCII-àðòàìè --- +GameCharmBestiary PROC +bestiary_loop: + call ClearView + invoke PrintTitleColor, OFFSET bestiaryTitle + invoke PrintStr, OFFSET bestiaryMenuText + call ReadUInt + cmp eax, 0 + je bestiary_exit + cmp eax, 1 + je bestiary_clover + cmp eax, 2 + je bestiary_bell + cmp eax, 3 + je bestiary_diamond + cmp eax, 4 + je bestiary_skull + cmp eax, 5 + je bestiary_web + cmp eax, 6 + je bestiary_bee + cmp eax, 7 + je bestiary_moon + cmp eax, 8 + je bestiary_crown + cmp eax, 9 + je bestiary_mirror + cmp eax, 10 + je bestiary_dice + cmp eax, 11 + je bestiary_blood + cmp eax, 12 + je bestiary_hourglass + cmp eax, 13 + je bestiary_horseshoe + cmp eax, 14 + je bestiary_joker + cmp eax, 15 + je bestiary_phoenix + cmp eax, 16 + je bestiary_compass + cmp eax, 17 + je bestiary_tooth + cmp eax, 18 + je bestiary_eye + cmp eax, 19 + je bestiary_key + cmp eax, 20 + je bestiary_candle + cmp eax, 21 + je bestiary_chip + cmp eax, 22 + je bestiary_snake + cmp eax, 23 + je bestiary_ace + cmp eax, 24 + je bestiary_devil + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp bestiary_loop +bestiary_clover: + invoke ShowBestiaryPage, OFFSET bestiaryCloverArt, OFFSET bestiaryCloverInfo, COLOR_MONEY + jmp bestiary_loop +bestiary_bell: + invoke ShowBestiaryPage, OFFSET bestiaryBellArt, OFFSET bestiaryBellInfo, COLOR_WARN + jmp bestiary_loop +bestiary_diamond: + invoke ShowBestiaryPage, OFFSET bestiaryDiamondArt, OFFSET bestiaryDiamondInfo, COLOR_TITLE + jmp bestiary_loop +bestiary_skull: + invoke ShowBestiaryPage, OFFSET bestiarySkullArt, OFFSET bestiarySkullInfo, COLOR_BAD + jmp bestiary_loop +bestiary_web: + invoke ShowBestiaryPage, OFFSET bestiaryWebArt, OFFSET bestiaryWebInfo, COLOR_CARD + jmp bestiary_loop +bestiary_bee: + invoke ShowBestiaryPage, OFFSET bestiaryBeeArt, OFFSET bestiaryBeeInfo, COLOR_WARN + jmp bestiary_loop +bestiary_moon: + invoke ShowBestiaryPage, OFFSET bestiaryMoonArt, OFFSET bestiaryMoonInfo, COLOR_TITLE + jmp bestiary_loop +bestiary_crown: + invoke ShowBestiaryPage, OFFSET bestiaryCrownArt, OFFSET bestiaryCrownInfo, COLOR_WARN + jmp bestiary_loop +bestiary_mirror: + invoke ShowBestiaryPage, OFFSET bestiaryMirrorArt, OFFSET bestiaryMirrorInfo, COLOR_CARD + jmp bestiary_loop +bestiary_dice: + invoke ShowBestiaryPage, OFFSET bestiaryDiceArt, OFFSET bestiaryDiceInfo, COLOR_TITLE + jmp bestiary_loop +bestiary_blood: + invoke ShowBestiaryPage, OFFSET bestiaryBloodArt, OFFSET bestiaryBloodInfo, COLOR_BAD + jmp bestiary_loop +bestiary_hourglass: + invoke ShowBestiaryPage, OFFSET bestiaryHourglassArt, OFFSET bestiaryHourglassInfo, COLOR_WARN + jmp bestiary_loop +bestiary_horseshoe: + invoke ShowBestiaryPage, OFFSET bestiaryHorseshoeArt, OFFSET bestiaryHorseshoeInfo, COLOR_MONEY + jmp bestiary_loop +bestiary_joker: + invoke ShowBestiaryPage, OFFSET bestiaryJokerArt, OFFSET bestiaryJokerInfo, COLOR_BAD + jmp bestiary_loop +bestiary_phoenix: + invoke ShowBestiaryPage, OFFSET bestiaryPhoenixArt, OFFSET bestiaryPhoenixInfo, COLOR_WARN + jmp bestiary_loop +bestiary_compass: + invoke ShowBestiaryPage, OFFSET bestiaryCompassArt, OFFSET bestiaryCompassInfo, COLOR_CARD + jmp bestiary_loop +bestiary_tooth: + invoke ShowBestiaryPage, OFFSET bestiaryToothArt, OFFSET bestiaryToothInfo, COLOR_WARN + jmp bestiary_loop +bestiary_eye: + invoke ShowBestiaryPage, OFFSET bestiaryEyeArt, OFFSET bestiaryEyeInfo, COLOR_TITLE + jmp bestiary_loop +bestiary_key: + invoke ShowBestiaryPage, OFFSET bestiaryKeyArt, OFFSET bestiaryKeyInfo, COLOR_CARD + jmp bestiary_loop +bestiary_candle: + invoke ShowBestiaryPage, OFFSET bestiaryCandleArt, OFFSET bestiaryCandleInfo, COLOR_BAD + jmp bestiary_loop +bestiary_chip: + invoke ShowBestiaryPage, OFFSET bestiaryChipArt, OFFSET bestiaryChipInfo, COLOR_MONEY + jmp bestiary_loop +bestiary_snake: + invoke ShowBestiaryPage, OFFSET bestiarySnakeArt, OFFSET bestiarySnakeInfo, COLOR_MONEY + jmp bestiary_loop +bestiary_ace: + invoke ShowBestiaryPage, OFFSET bestiaryAceArt, OFFSET bestiaryAceInfo, COLOR_TITLE + jmp bestiary_loop +bestiary_devil: + invoke ShowBestiaryPage, OFFSET bestiaryDevilArt, OFFSET bestiaryDevilInfo, COLOR_BAD + jmp bestiary_loop +bestiary_exit: + ret +GameCharmBestiary ENDP + +; --- GameShop: ìàãàçèí ðóáàøåê, òàëèñìàíîâ è ïîêóïîê --- +GameShop PROC +shop_loop: + call ClearView + invoke PrintTitleColor, OFFSET shopTitle + call PrintShopStatus + invoke PrintStr, OFFSET shopMainMenuText + call ReadUInt + cmp eax, 0 + je shop_exit + cmp eax, 1 + je shop_backs_menu + cmp eax, 2 + je shop_charms_menu + cmp eax, 3 + je shop_bestiary_menu + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp shop_loop + +shop_bestiary_menu: + call GameCharmBestiary + jmp shop_loop + +shop_backs_menu: + call ClearView + invoke PrintTitleColor, OFFSET shopBackTitle + call PrintShopStatus + invoke PrintStr, OFFSET shopBackMenuText + call ReadUInt + cmp eax, 0 + je shop_loop + cmp eax, 1 + je shop_blue + cmp eax, 2 + je shop_red + cmp eax, 3 + je shop_gold + cmp eax, 4 + je shop_skull + cmp eax, 5 + je shop_clover_back + cmp eax, 6 + je shop_arcane + cmp eax, 7 + je shop_noir + cmp eax, 8 + je shop_diamond_back + cmp eax, 9 + je shop_rider + cmp eax, 10 + je shop_bee + cmp eax, 11 + je shop_fan + cmp eax, 12 + je shop_web + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp shop_backs_menu + +shop_charms_menu: + call ClearView + invoke PrintTitleColor, OFFSET shopCharmTitle + call PrintShopStatus + invoke PrintStr, OFFSET shopCharmMenuText + call ReadUInt + cmp eax, 0 + je shop_loop + cmp eax, 1 + je buy_charm_clover + cmp eax, 2 + je buy_charm_bell + cmp eax, 3 + je buy_charm_diamond + cmp eax, 4 + je buy_charm_skull + cmp eax, 5 + je buy_charm_web + cmp eax, 6 + je buy_charm_bee_item + cmp eax, 7 + je buy_charm_moon + cmp eax, 8 + je buy_charm_crown + cmp eax, 9 + je buy_charm_mirror + cmp eax, 10 + je buy_charm_dice + cmp eax, 11 + je buy_charm_blood + cmp eax, 12 + je buy_charm_hourglass + cmp eax, 13 + je buy_charm_horseshoe + cmp eax, 14 + je buy_charm_joker + cmp eax, 15 + je buy_charm_phoenix + cmp eax, 16 + je buy_charm_compass + cmp eax, 17 + je buy_charm_tooth + cmp eax, 18 + je buy_charm_eye + cmp eax, 19 + je buy_charm_key + cmp eax, 20 + je buy_charm_candle + cmp eax, 21 + je buy_charm_chip + cmp eax, 22 + je buy_charm_snake + cmp eax, 23 + je buy_charm_ace + cmp eax, 24 + je buy_charm_devil + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp shop_charms_menu + +shop_blue: + invoke ShopBuyBack, 1, 3000, 2 + call PauseConsole + jmp shop_backs_menu +shop_red: + invoke ShopBuyBack, 2, 3000, 4 + call PauseConsole + jmp shop_backs_menu +shop_gold: + invoke ShopBuyBack, 3, 10000, 8 + call PauseConsole + jmp shop_backs_menu +shop_skull: + invoke ShopBuyBack, 4, 12000, 10h + call PauseConsole + jmp shop_backs_menu +shop_clover_back: + invoke ShopBuyBack, 5, 15000, 20h + call PauseConsole + jmp shop_backs_menu +shop_arcane: + invoke ShopBuyBack, 6, 17000, 40h + call PauseConsole + jmp shop_backs_menu +shop_noir: + invoke ShopBuyBack, 7, 18000, 80h + call PauseConsole + jmp shop_backs_menu +shop_diamond_back: + invoke ShopBuyBack, 8, 20000, 100h + call PauseConsole + jmp shop_backs_menu +shop_rider: + invoke ShopBuyBack, 9, 22000, 200h + call PauseConsole + jmp shop_backs_menu +shop_bee: + invoke ShopBuyBack, 10, 22000, 400h + call PauseConsole + jmp shop_backs_menu +shop_fan: + invoke ShopBuyBack, 11, 23000, 800h + call PauseConsole + jmp shop_backs_menu +shop_web: + invoke ShopBuyBack, 12, 24000, 1000h + call PauseConsole + jmp shop_backs_menu + +buy_charm_clover: + invoke ShopBuyCharm, 1, 12000 + call PauseConsole + jmp shop_charms_menu +buy_charm_bell: + invoke ShopBuyCharm, 2, 18000 + call PauseConsole + jmp shop_charms_menu +buy_charm_diamond: + invoke ShopBuyCharm, 3, 25000 + call PauseConsole + jmp shop_charms_menu +buy_charm_skull: + invoke ShopBuyCharm, 4, 32000 + call PauseConsole + jmp shop_charms_menu +buy_charm_web: + invoke ShopBuyCharm, 5, 40000 + call PauseConsole + jmp shop_charms_menu +buy_charm_bee_item: + invoke ShopBuyCharm, 6, 30000 + call PauseConsole + jmp shop_charms_menu +buy_charm_moon: + invoke ShopBuyCharm, 7, 36000 + call PauseConsole + jmp shop_charms_menu +buy_charm_crown: + invoke ShopBuyCharm, 8, 52000 + call PauseConsole + jmp shop_charms_menu +buy_charm_mirror: + invoke ShopBuyCharm, 9, 42000 + call PauseConsole + jmp shop_charms_menu +buy_charm_dice: + invoke ShopBuyCharm, 10, 35000 + call PauseConsole + jmp shop_charms_menu +buy_charm_blood: + invoke ShopBuyCharm, 11, 65000 + call PauseConsole + jmp shop_charms_menu +buy_charm_hourglass: + invoke ShopBuyCharm, 12, 48000 + call PauseConsole + jmp shop_charms_menu +buy_charm_horseshoe: + invoke ShopBuyCharm, 13, 39000 + call PauseConsole + jmp shop_charms_menu +buy_charm_joker: + invoke ShopBuyCharm, 14, 70000 + call PauseConsole + jmp shop_charms_menu +buy_charm_phoenix: + invoke ShopBuyCharm, 15, 56000 + call PauseConsole + jmp shop_charms_menu +buy_charm_compass: + invoke ShopBuyCharm, 16, 44000 + call PauseConsole + jmp shop_charms_menu +buy_charm_tooth: + invoke ShopBuyCharm, 17, 47000 + call PauseConsole + jmp shop_charms_menu +buy_charm_eye: + invoke ShopBuyCharm, 18, 60000 + call PauseConsole + jmp shop_charms_menu +buy_charm_key: + invoke ShopBuyCharm, 19, 41000 + call PauseConsole + jmp shop_charms_menu +buy_charm_candle: + invoke ShopBuyCharm, 20, 76000 + call PauseConsole + jmp shop_charms_menu +buy_charm_chip: + invoke ShopBuyCharm, 21, 50000 + call PauseConsole + jmp shop_charms_menu +buy_charm_snake: + invoke ShopBuyCharm, 22, 62000 + call PauseConsole + jmp shop_charms_menu +buy_charm_ace: + invoke ShopBuyCharm, 23, 53000 + call PauseConsole + jmp shop_charms_menu +buy_charm_devil: + invoke ShopBuyCharm, 24, 100000 + call PauseConsole + jmp shop_charms_menu +shop_exit: + ret +GameShop ENDP + + +; --- CopyName: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +CopyName PROC uses eax ecx esi edi, pDst:DWORD, pSrc:DWORD + mov edi, pDst + mov esi, pSrc + mov ecx, 63 +copy_name_loop: + mov al, [esi] + cmp al, '.' + je copy_name_stop + mov [edi], al + cmp al, 0 + je copy_name_done + inc esi + inc edi + loop copy_name_loop +copy_name_stop: + mov byte ptr [edi], 0 +copy_name_done: + ret +CopyName ENDP + +; --- ClearLeaderboards: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +ClearLeaderboards PROC uses eax ecx edi + mov leaderBestBank, 0 + mov leaderBestWins, 0 + mov leaderBestLosses, 0 + mov leaderValidCount, 0 + mov ecx, 22 + mov edi, OFFSET leaderBestGameWins +clear_leader_counts: + mov dword ptr [edi], 0 + add edi, 4 + loop clear_leader_counts + mov ecx, 1600 + mov edi, OFFSET leaderBestBankName +clear_leader_names: + mov byte ptr [edi], 0 + inc edi + loop clear_leader_names + ret +ClearLeaderboards ENDP + +; --- LeaderboardUpdateGame: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +LeaderboardUpdateGame PROC uses eax ebx edx + mov ebx, rowIndex + mov eax, DWORD PTR [saveBuffer+104+ebx*4] + cmp eax, leaderBestGameWins[ebx*4] + jbe leaderboard_check_losses + mov leaderBestGameWins[ebx*4], eax + mov edx, ebx + shl edx, 6 + add edx, OFFSET leaderBestGameWinNames + invoke CopyName, edx, leaderAccountPtr +leaderboard_check_losses: + mov eax, DWORD PTR [saveBuffer+148+ebx*4] + cmp eax, leaderBestGameLosses[ebx*4] + jbe leaderboard_game_done + mov leaderBestGameLosses[ebx*4], eax + mov edx, ebx + shl edx, 6 + add edx, OFFSET leaderBestGameLossNames + invoke CopyName, edx, leaderAccountPtr +leaderboard_game_done: + ret +LeaderboardUpdateGame ENDP + +; --- LeaderboardReadAccount: àêêàóíòû, ôàéëû ñîõðàíåíèé è çàãðóçêà ïðîôèëÿ --- +LeaderboardReadAccount PROC uses eax + call BuildLeaderSavePath + invoke CreateFileA, OFFSET leaderSavePath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + jne leaderboard_file_opened + cmp appDataReady, 1 + jne leaderboard_read_done + invoke CreateFileA, leaderAccountPtr, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 + cmp eax, INVALID_HANDLE_VALUE + je leaderboard_read_done +leaderboard_file_opened: + mov saveHandle, eax + invoke ReadFile, saveHandle, ADDR saveBuffer, SAVE_FILE_SIZE, ADDR charsRead, 0 + invoke CloseHandle, saveHandle + cmp charsRead, 32 + jb leaderboard_read_done + mov eax, DWORD PTR [saveBuffer] + cmp eax, SAVE_MAGIC + jne leaderboard_read_done + cmp charsRead, SAVE_FILE_SIZE + jb leaderboard_signature_ok + mov edx, DWORD PTR [saveBuffer+SAVE_SIGN_SIZE] + call CalcSaveSignature + cmp eax, edx + jne leaderboard_read_done +leaderboard_signature_ok: + inc leaderValidCount + mov eax, DWORD PTR [saveBuffer+4] + cmp eax, leaderBestBank + jbe leaderboard_check_total_wins + mov leaderBestBank, eax + invoke CopyName, OFFSET leaderBestBankName, leaderAccountPtr +leaderboard_check_total_wins: + mov eax, DWORD PTR [saveBuffer+12] + cmp eax, leaderBestWins + jbe leaderboard_check_total_losses + mov leaderBestWins, eax + invoke CopyName, OFFSET leaderBestWinsName, leaderAccountPtr +leaderboard_check_total_losses: + mov eax, DWORD PTR [saveBuffer+16] + cmp eax, leaderBestLosses + jbe leaderboard_check_games + mov leaderBestLosses, eax + invoke CopyName, OFFSET leaderBestLossName, leaderAccountPtr +leaderboard_check_games: + cmp charsRead, 236 + jb leaderboard_read_done + mov rowIndex, 0 +leaderboard_game_loop: + cmp rowIndex, 11 + jae leaderboard_read_done + call LeaderboardUpdateGame + inc rowIndex + jmp leaderboard_game_loop +leaderboard_read_done: + ret +LeaderboardReadAccount ENDP + +; --- BuildLeaderboards: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +BuildLeaderboards PROC uses eax + call ClearLeaderboards + call CollectAccounts + mov leaderScanIndex, 0 +leaderboard_account_loop: + mov eax, leaderScanIndex + cmp eax, accountCount + jae leaderboard_build_done + shl eax, 6 + add eax, OFFSET accountList + mov leaderAccountPtr, eax + call LeaderboardReadAccount + inc leaderScanIndex + jmp leaderboard_account_loop +leaderboard_build_done: + ret +BuildLeaderboards ENDP + +; --- PrintLeaderPair: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintLeaderPair PROC uses eax, pName:DWORD, value:DWORD + mov eax, value + cmp eax, 0 + jne print_leader_pair_value + invoke PrintStr, OFFSET leaderDashText + ret +print_leader_pair_value: + invoke PrintStr, pName + invoke PrintStr, OFFSET leaderOpenText + invoke PrintUInt, value + invoke PrintStr, OFFSET leaderCloseText + ret +PrintLeaderPair ENDP + +; --- PrintLeaderGameLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintLeaderGameLine PROC uses eax ebx edx + mov eax, rowIndex + invoke PrintStr, statsGameNames[eax*4] + invoke PrintStr, OFFSET leaderGameWinText + mov ebx, rowIndex + mov edx, ebx + shl edx, 6 + add edx, OFFSET leaderBestGameWinNames + invoke PrintLeaderPair, edx, leaderBestGameWins[ebx*4] + invoke PrintStr, OFFSET leaderGameLossText + mov ebx, rowIndex + mov edx, ebx + shl edx, 6 + add edx, OFFSET leaderBestGameLossNames + invoke PrintLeaderPair, edx, leaderBestGameLosses[ebx*4] + invoke PrintStr, OFFSET nl + ret +PrintLeaderGameLine ENDP + +; --- PrintLeaderboards: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintLeaderboards PROC + call BuildLeaderboards + invoke PrintTitleColor, OFFSET leaderTitle + cmp leaderValidCount, 0 + jne print_leaders_have_data + invoke PrintStr, OFFSET leaderNoDataText + ret +print_leaders_have_data: + invoke PrintStr, OFFSET leaderBankText + invoke PrintStr, OFFSET leaderBestBankName + invoke PrintStr, OFFSET leaderOpenText + invoke PrintStr, OFFSET leaderMoneyPrefix + invoke PrintUInt, leaderBestBank + invoke PrintStr, OFFSET leaderCloseText + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET leaderWinsText + invoke PrintLeaderPair, OFFSET leaderBestWinsName, leaderBestWins + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET leaderLossText + invoke PrintLeaderPair, OFFSET leaderBestLossName, leaderBestLosses + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET leaderGameTitle + mov rowIndex, 0 +leader_print_game_loop: + cmp rowIndex, 11 + jae leader_print_done + call PrintLeaderGameLine + inc rowIndex + jmp leader_print_game_loop +leader_print_done: + ret +PrintLeaderboards ENDP +; --- PrintGameStatLine: âûâîä òåêñòà, öâåòîâ, êàðòèíîê è ýëåìåíòîâ èíòåðôåéñà --- +PrintGameStatLine PROC uses eax ebx + mov eax, rowIndex + invoke PrintStr, statsGameNames[eax * 4] + invoke PrintStr, OFFSET statsLinePlayed + mov ebx, rowIndex + invoke PrintUInt, gameStatsPlayed[ebx * 4] + invoke PrintStr, OFFSET statsLineWins + mov ebx, rowIndex + invoke PrintUInt, gameStatsWon[ebx * 4] + invoke PrintStr, OFFSET statsLineLoss + mov ebx, rowIndex + invoke PrintUInt, gameStatsLost[ebx * 4] + invoke PrintStr, OFFSET statsLineDraw + mov ebx, rowIndex + invoke PrintUInt, gameStatsDraw[ebx * 4] + invoke PrintStr, OFFSET nl + ret +PrintGameStatLine ENDP + +; --- GameStatsByGame: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +GameStatsByGame PROC + call ClearView + invoke PrintTitleColor, OFFSET statsByGameTitle + invoke PrintStr, OFFSET leaderCurrentTitle + mov rowIndex, 0 +stats_by_game_loop: + cmp rowIndex, 11 + jae stats_by_game_done + call PrintGameStatLine + inc rowIndex + jmp stats_by_game_loop +stats_by_game_done: + call PrintLeaderboards + call PauseConsole + ret +GameStatsByGame ENDP + +; --- SkillCheckFlushKeys: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- +SkillCheckFlushKeys PROC + invoke GetAsyncKeyState, VK_SPACE + invoke GetAsyncKeyState, VK_RETURN + invoke Sleep, 80 + invoke GetAsyncKeyState, VK_SPACE + invoke GetAsyncKeyState, VK_RETURN + ret +SkillCheckFlushKeys ENDP + +; --- SkillCheckPollKey: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- +SkillCheckPollKey PROC + invoke GetAsyncKeyState, VK_SPACE + test ax, 0001h + jne skill_key_pressed + invoke GetAsyncKeyState, VK_RETURN + test ax, 0001h + jne skill_key_pressed + xor eax, eax + ret +skill_key_pressed: + mov eax, 1 + ret +SkillCheckPollKey ENDP + +; --- SkillCheckDraw: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- +SkillCheckDraw PROC uses eax ebx edx + call ClearView + invoke PrintTitleColor, OFFSET skillTitle + invoke PrintStr, OFFSET skillIntro + + invoke PrintStr, OFFSET skillStateText + mov eax, skillMisses + cmp eax, 0 + je skill_draw_state_good + cmp eax, 1 + je skill_draw_state_warn + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET skillStateBad + call ResetColor + jmp skill_draw_state_done +skill_draw_state_good: + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET skillStateGood + call ResetColor + jmp skill_draw_state_done +skill_draw_state_warn: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET skillStateWarn + call ResetColor +skill_draw_state_done: + invoke PrintStr, OFFSET skillProgressText + invoke PrintUInt, skillHits + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET skillMissText + invoke PrintUInt, skillMisses + invoke PrintStr, OFFSET nl + invoke PrintStr, OFFSET skillGaugeHint + invoke PrintStr, OFFSET skillGaugeLeft + + mov skillGaugeIndex, 0 +skill_draw_gauge_loop: + mov eax, skillGaugeIndex + cmp eax, 45 + jae skill_draw_gauge_done + cmp eax, skillNeedle + je skill_draw_needle + cmp eax, skillPerfectPos + je skill_draw_perfect + cmp eax, skillSuccessStart + jb skill_draw_empty + cmp eax, skillSuccessEnd + ja skill_draw_empty + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET skillGaugeSuccess + call ResetColor + jmp skill_draw_next +skill_draw_perfect: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET skillGaugePerfect + call ResetColor + jmp skill_draw_next +skill_draw_needle: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET skillGaugeNeedle + call ResetColor + jmp skill_draw_next +skill_draw_empty: + invoke PrintStr, OFFSET skillGaugeEmpty +skill_draw_next: + inc skillGaugeIndex + jmp skill_draw_gauge_loop +skill_draw_gauge_done: + invoke PrintStr, OFFSET skillGaugeRight + invoke PrintStr, OFFSET skillGaugeLeft + mov skillGaugeIndex, 0 +skill_draw_gauge_loop2: + mov eax, skillGaugeIndex + cmp eax, 45 + jae skill_draw_gauge_done2 + cmp eax, skillNeedle + je skill_draw_needle2 + cmp eax, skillPerfectPos + je skill_draw_perfect2 + cmp eax, skillSuccessStart + jb skill_draw_empty2 + cmp eax, skillSuccessEnd + ja skill_draw_empty2 + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET skillGaugeSuccess + call ResetColor + jmp skill_draw_next2 +skill_draw_perfect2: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET skillGaugePerfect + call ResetColor + jmp skill_draw_next2 +skill_draw_needle2: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET skillGaugeNeedle + call ResetColor + jmp skill_draw_next2 +skill_draw_empty2: + invoke PrintStr, OFFSET skillGaugeEmpty +skill_draw_next2: + inc skillGaugeIndex + jmp skill_draw_gauge_loop2 +skill_draw_gauge_done2: + invoke PrintStr, OFFSET skillGaugeRight + + invoke PrintStr, OFFSET skillGaugeLeft + mov skillGaugeIndex, 0 +skill_draw_gauge_loop3: + mov eax, skillGaugeIndex + cmp eax, 45 + jae skill_draw_gauge_done3 + cmp eax, skillNeedle + je skill_draw_needle3 + cmp eax, skillPerfectPos + je skill_draw_perfect3 + cmp eax, skillSuccessStart + jb skill_draw_empty3 + cmp eax, skillSuccessEnd + ja skill_draw_empty3 + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET skillGaugeSuccess + call ResetColor + jmp skill_draw_next3 +skill_draw_perfect3: + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET skillGaugePerfect + call ResetColor + jmp skill_draw_next3 +skill_draw_needle3: + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET skillGaugeNeedle + call ResetColor + jmp skill_draw_next3 +skill_draw_empty3: + invoke PrintStr, OFFSET skillGaugeEmpty +skill_draw_next3: + inc skillGaugeIndex + jmp skill_draw_gauge_loop3 +skill_draw_gauge_done3: + invoke PrintStr, OFFSET skillGaugeRight + ret +SkillCheckDraw ENDP + +; --- SkillCheckMoveNeedle: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- +SkillCheckMoveNeedle PROC uses eax + mov eax, skillDir + cmp eax, 0FFFFFFFFh + je skill_move_left +skill_move_right: + mov eax, skillNeedle + inc eax + cmp eax, 44 + jbe skill_move_store_right + mov eax, 43 + mov skillDir, 0FFFFFFFFh +skill_move_store_right: + mov skillNeedle, eax + ret +skill_move_left: + mov eax, skillNeedle + cmp eax, 0 + ja skill_move_dec + mov eax, 1 + mov skillDir, 1 + mov skillNeedle, eax + ret +skill_move_dec: + dec eax + mov skillNeedle, eax + ret +SkillCheckMoveNeedle ENDP + +; --- SkillCheckEvaluate: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- +SkillCheckEvaluate PROC uses eax + mov eax, skillNeedle + cmp eax, skillPerfectPos + je skill_eval_perfect + cmp eax, skillSuccessStart + jb skill_eval_fail + cmp eax, skillSuccessEnd + ja skill_eval_fail + mov skillResult, 1 + ret +skill_eval_perfect: + mov skillResult, 2 + ret +skill_eval_fail: + mov skillResult, 0 + ret +SkillCheckEvaluate ENDP + +; --- SkillCheckRound: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- +SkillCheckRound PROC uses eax ebx + invoke RandomRange, 27 + add eax, 8 + mov skillSuccessStart, eax + mov ebx, eax + add ebx, 7 + mov skillSuccessEnd, ebx + invoke RandomRange, 6 + add eax, skillSuccessStart + inc eax + mov skillPerfectPos, eax + invoke RandomRange, 45 + mov skillNeedle, eax + invoke RandomRange, 2 + cmp eax, 0 + je skill_round_left + mov skillDir, 1 + jmp skill_round_begin +skill_round_left: + mov skillDir, 0FFFFFFFFh +skill_round_begin: + mov skillFrameCount, 0 + mov skillResult, 0 + mov eax, skillHits + mov ebx, eax + shl ebx, 2 + add eax, ebx + mov ebx, 45 + sub ebx, eax + mov eax, stressLevel + shl eax, 2 + sub ebx, eax + cmp ebx, 18 + jae skill_delay_ready + mov ebx, 18 +skill_delay_ready: + mov skillDelay, ebx + call SkillCheckFlushKeys +skill_round_loop: + call SkillCheckDraw + mov eax, skillDelay + invoke Sleep, eax + call SkillCheckPollKey + cmp eax, 1 + je skill_round_pressed + call SkillCheckMoveNeedle + inc skillFrameCount + cmp skillFrameCount, 120 + jb skill_round_loop + mov skillResult, 0 + ret +skill_round_pressed: + call SkillCheckEvaluate + ret +SkillCheckRound ENDP + +; --- GameSkillCheck: Skill Check íà êðþêå: øêàëà, ïîïàäàíèÿ è ïðîìàõè --- +GameSkillCheck PROC +skill_game_start: + call ClearView + invoke PrintTitleColor, OFFSET skillTitle + invoke PrintStr, OFFSET skillIntro + call PromptBet + call PlayDbDHookScene + mov skillHits, 0 + mov skillMisses, 0 + mov skillPerfects, 0 +skill_game_loop: + call SkillCheckRound + call SkillCheckDraw + mov eax, skillResult + cmp eax, 2 + je skill_game_perfect + cmp eax, 1 + je skill_game_success +skill_game_fail: + inc skillMisses + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET skillFailText + call ResetColor + invoke Sleep, 850 + cmp skillMisses, 3 + jae skill_game_lost + jmp skill_game_loop +skill_game_success: + inc skillHits + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET skillSuccessText + call ResetColor + invoke Sleep, 750 + cmp skillHits, 5 + jae skill_game_won + jmp skill_game_loop +skill_game_perfect: + add skillHits, 2 + inc skillPerfects + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET skillPerfectText + call ResetColor + invoke Sleep, 850 + cmp skillHits, 5 + jae skill_game_won + jmp skill_game_loop +skill_game_won: + call StopDbDHookScene + call SkillCheckDraw + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET skillEscapeText + call ResetColor + invoke PaySlotMultiplier, 2 + invoke UnlockAchievement, 20000h, OFFSET achSkillCheckName + call SaveGame + jmp skill_game_again +skill_game_lost: + call StopDbDHookScene + call SkillCheckDraw + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET skillDarkText + call ResetColor + call PayLose + call SaveGame +skill_game_again: + cmp tournamentMode, 1 + je skill_game_exit + invoke PrintStr, OFFSET againText + call ReadKey + cmp al, 'y' + je skill_game_start + cmp al, 'Y' + je skill_game_start +skill_game_exit: + ret +GameSkillCheck ENDP +; --- GameAchievements: ñòàòèñòèêà, äîñòèæåíèÿ è òàáëèöû ëèäåðîâ --- +GameAchievements PROC + call ClearView + invoke PrintTitleColor, OFFSET achMenuTitle + invoke PrintAchievementLine, 1, OFFSET achFirstWinName + invoke PrintAchievementLine, 2, OFFSET achFirstLossName + invoke PrintAchievementLine, 4, OFFSET achJackpotName + invoke PrintAchievementLine, 8, OFFSET achHighRollerName + invoke PrintAchievementLine, 10h, OFFSET achShopperName + invoke PrintAchievementLine, 20h, OFFSET achCharmName + invoke PrintAchievementLine, 40h, OFFSET achGoalName + invoke PrintAchievementLine, 80h, OFFSET achCloverPitName + invoke PrintAchievementLine, 100h, OFFSET achClassicSlotName + invoke PrintAchievementLine, 200h, OFFSET achPokerRaiseName + invoke PrintAchievementLine, 400h, OFFSET achPokerBluffName + invoke PrintAchievementLine, 800h, OFFSET achRouletteWinName + invoke PrintAchievementLine, 1000h, OFFSET achRussianWinName + invoke PrintAchievementLine, 2000h, OFFSET achDurakWinName + invoke PrintAchievementLine, 4000h, OFFSET achBackCollectorName + invoke PrintAchievementLine, 8000h, OFFSET achCharmBuyerName + invoke PrintAchievementLine, 10000h, OFFSET achObserverName + invoke PrintAchievementLine, 20000h, OFFSET achSkillCheckName + call PauseConsole + ret +GameAchievements ENDP +; --- GameTraining: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +GameTraining PROC + call ClearView + invoke PrintTitleColor, OFFSET trainingTitle + invoke PrintStr, OFFSET trainingText + call PauseConsole + ret +GameTraining ENDP +; --- ShowTournamentStage: òóðíèð-áàøíÿ è ïîáåäíàÿ àíèìàöèÿ ôèíàëà --- +ShowTournamentStage PROC + call ClearView + invoke PrintTitleColor, OFFSET tournamentTitle + invoke PrintStr, OFFSET tournamentStageText + invoke PrintUInt, tournamentStage + invoke PrintStr, OFFSET nl + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET hellStageCurseText + invoke RandomRange, 4 + cmp eax, 0 + je hell_stage_curse1 + cmp eax, 1 + je hell_stage_curse2 + cmp eax, 2 + je hell_stage_curse3 + invoke PrintStr, OFFSET hellCurse4 + jmp hell_stage_curse_done +hell_stage_curse1: + invoke PrintStr, OFFSET hellCurse1 + jmp hell_stage_curse_done +hell_stage_curse2: + invoke PrintStr, OFFSET hellCurse2 + jmp hell_stage_curse_done +hell_stage_curse3: + invoke PrintStr, OFFSET hellCurse3 +hell_stage_curse_done: + call ResetColor + invoke PrintStr, OFFSET tournamentMusicHint + call ReadKey + cmp al, 'm' + je tower_stage_change_music + cmp al, 'M' + jne tower_stage_done +tower_stage_change_music: + call PlayTowerRandomMusic +tower_stage_done: + ret +ShowTournamentStage ENDP + +; --- AnimateTournamentVictory: áàíê, ñòàâêè, ñòðåññ, ïîäîçðåíèå è ýêîíîìèêà êàçèíî --- +AnimateTournamentVictory PROC + call PlayVictorySound + call ClearView + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET tournamentFire1 + call ResetColor + invoke Sleep, 360 + call ClearView + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET tournamentFire2 + call ResetColor + invoke Sleep, 360 + call ClearView + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET tournamentFire3 + call ResetColor + invoke Sleep, 420 + call ClearView + invoke SetColor, COLOR_WARN + invoke PrintStr, OFFSET tournamentFire4 + call ResetColor + invoke Sleep, 520 + ret +AnimateTournamentVictory ENDP + +; --- GameTournament: òóðíèð-áàøíÿ è ïîáåäíàÿ àíèìàöèÿ ôèíàëà --- +GameTournament PROC + mov tournamentMode, 1 + call ClearView + invoke PrintTitleColor, OFFSET tournamentTitle + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET secretHellText + call ResetColor + invoke PrintStr, OFFSET tournamentIntro + call PauseConsole + call PlayTowerRandomMusic ; tower start + + mov tournamentStage, 1 + call ShowTournamentStage + mov currentGameId, 6 + mov lastGameResult, 0 + call GameCoin + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 2 + call ShowTournamentStage + mov currentGameId, 7 + mov lastGameResult, 0 + call GameDice + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 3 + call ShowTournamentStage + mov currentGameId, 5 + mov lastGameResult, 0 + call GameSkulls + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 4 + call ShowTournamentStage + mov currentGameId, 1 + mov lastGameResult, 0 + call Game21 + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 5 + call ShowTournamentStage + mov currentGameId, 2 + mov lastGameResult, 0 + call GamePoker + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 6 + call ShowTournamentStage + mov currentGameId, 4 + mov lastGameResult, 0 + call GameRoulette + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 7 + call ShowTournamentStage + mov currentGameId, 8 + mov lastGameResult, 0 + call GameCasinoRoulette + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 8 + call ShowTournamentStage + mov currentGameId, 10 + mov lastGameResult, 0 + call GameDurak + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 9 + call ShowTournamentStage + mov currentGameId, 11 + mov lastGameResult, 0 + call GameSkillCheck + cmp lastGameResult, 2 + je tournament_failed + + mov tournamentStage, 10 + call ShowTournamentStage + mov currentGameId, 0 + mov lastGameResult, 0 + call GameBuckshot + cmp lastGameResult, 2 + je tournament_failed + + call StopTowerMusic ; before tower victory + call AnimateTournamentVictory + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET tournamentWinText + call ResetColor + mov currentBet, 66600 + call PayWin + call SaveGame + mov tournamentMode, 0 + call PauseConsole + ret + +tournament_failed: + call StopTowerMusic ; tower failed + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET tournamentFailText + call ResetColor + mov tournamentMode, 0 + call PauseConsole + ret +GameTournament ENDP + + +; --- GameUmamusume: Umamusume Pretty Derby Minigame --- +GameUmamusume PROC uses ebx esi edi + invoke PrintStr, OFFSET umaTitleText + call PromptBet + cmp eax, 0 + jle uma_exit + +uma_select_horse: + invoke PrintStr, OFFSET umaMenuText + invoke PrintStr, OFFSET umaChoiceText + call ReadBetInput + cmp eax, 1 + jl uma_invalid + cmp eax, 5 + jg uma_invalid + mov umaChoice, eax + jmp uma_start_race + +uma_invalid: + invoke PrintStr, OFFSET badChoiceText + jmp uma_select_horse + +uma_start_race: + xor eax, eax + mov umaPos[0], eax + mov umaPos[4], eax + mov umaPos[8], eax + mov umaPos[12], eax + mov umaPos[16], eax + mov umaWinner, 0 + +uma_race_loop: + invoke PrintStr, OFFSET clearLines + invoke PrintStr, OFFSET umaTrackHeader + + ; Horse 1: Special Week (1-3) + invoke RandomRange, 3 + inc eax + add umaPos[0], eax + + ; Horse 2: Silence Suzuka (1-4) + invoke RandomRange, 4 + inc eax + add umaPos[4], eax + + ; Horse 3: Tokai Teio (1-3, boost if pos > 18) + invoke RandomRange, 3 + inc eax + cmp umaPos[8], 18 + jbe uma_t3_no_boost + add eax, 2 +uma_t3_no_boost: + add umaPos[8], eax + + ; Horse 4: Gold Ship (0-6 wildcard) + invoke RandomRange, 7 + add umaPos[12], eax + + ; Horse 5: Mejiro McQueen (steady 2-4) + invoke RandomRange, 3 + add eax, 2 + add umaPos[16], eax + + ; Render track + mov ecx, 0 +uma_render_lane: + push ecx + mov eax, [umaHorseNames + ecx*4] + invoke PrintStr, eax + + mov ebx, [umaPos + ecx*4] + cmp ebx, 0 + jbe uma_render_head + mov edi, ebx +uma_print_step: + push edi + invoke PrintStr, OFFSET umaStepChar + pop edi + dec edi + jnz uma_print_step + +uma_render_head: + invoke PrintStr, OFFSET umaHeadChar + invoke PrintStr, OFFSET umaFinishText + + pop ecx + inc ecx + cmp ecx, 5 + jl uma_render_lane + + ; Check if finish reached (>= 35) + mov eax, 0 +uma_check_finish: + cmp dword ptr [umaPos + eax*4], 35 + jge uma_finish_reached + inc eax + cmp eax, 5 + jl uma_check_finish + + invoke Sleep, 180 + jmp uma_race_loop + +uma_finish_reached: + mov ebx, 0 + mov edi, 1 + mov ecx, 0 +uma_find_max: + mov edx, [umaPos + ecx*4] + cmp edx, ebx + jle uma_next_max + mov ebx, edx + lea edi, [ecx + 1] +uma_next_max: + inc ecx + cmp ecx, 5 + jl uma_find_max + + mov umaWinner, edi + invoke PrintStr, OFFSET umaWinAnnouncement + mov eax, edi + dec eax + mov eax, [umaHorseNames + eax*4] + invoke PrintStr, eax + invoke PrintStr, OFFSET nl + + mov eax, umaChoice + cmp eax, umaWinner + jne uma_race_lost + + invoke PrintStr, OFFSET umaYouWinText + mov ecx, umaChoice + dec ecx + mov eax, currentBet + mov edx, [umaMultipliers + ecx*4] + imul eax, edx + push eax + invoke PrintUInt, eax + invoke PrintStr, OFFSET nl + pop eax + call PayWin + call PrintWinEvent + jmp uma_race_done + +uma_race_lost: + invoke PrintStr, OFFSET umaYouLoseText + call PayLose + call PrintLoseEvent + +uma_race_done: + call PauseConsole +uma_exit: + ret +GameUmamusume ENDP + +; --- GamePlayerTerminal: Èãðîâîé òåðìèíàë (ñòàòèñòèêà, à÷èâêè, êâåñòû) --- +titleTerminal db "=== ÒÅÐÌÈÍÀË ÈÃÐÎÊÀ ===",13,10,0 +textTerminalMenu db "1. Äîñòèæåíèÿ",13,10,"2. Ñòàòèñòèêà ïî èãðàì",13,10,"3. Åæåäíåâíûå çàäàíèÿ",13,10,"4. Ãëàâíîå ìåíþ è ÷èòû",13,10,"0. Íàçàä â êàçèíî",13,10,0 + +GamePlayerTerminal PROC +terminal_loop: + call ClearView + invoke PrintTitleColor, OFFSET titleTerminal + invoke PrintStr, OFFSET textTerminalMenu + invoke PrintStr, OFFSET choiceText + call ReadKey + cmp al, '1' + je term_ach + cmp al, '2' + je term_stats + cmp al, '3' + je term_daily + cmp al, '4' + je term_classic_menu + cmp al, '0' + je term_exit + cmp al, 1Bh + je term_exit + jmp terminal_loop +term_ach: + call GameAchievements + jmp terminal_loop +term_stats: + call GameStatsByGame + jmp terminal_loop +term_daily: + call GameDailyTasks + jmp terminal_loop +term_classic_menu: + call MainMenu + jmp terminal_loop +term_exit: + ret +GamePlayerTerminal ENDP + +include casino3d.inc + + + +; --- AutoLoadAccountFast: àâòîçàãðóçêà ïðîôèëÿ áåç áëîêèðîâêè â CMD --- +AutoLoadAccountFast PROC + call ResetProfileDefaults + call CollectAccounts + cmp accountCount, 0 + jbe autoload_exit + mov selectedAccount, 1 + call CopySelectedAccountName + call LoadSave +autoload_exit: + ret +AutoLoadAccountFast ENDP + +; --- MainMenu: òî÷êà âõîäà, ãëàâíîå ìåíþ è ìàðøðóòèçàöèÿ ïî èãðàì --- + +MainMenu PROC +menu_loop: + call DailyCheckDate + call CheckSecretEnding + invoke PrintStr, OFFSET clearLines + invoke PrintTitleColor, OFFSET titleText + call PrintBank + call PrintGoal + call ShowStats + invoke PrintStr, OFFSET menuText + invoke PrintStr, OFFSET choiceText + call ReadBetInput + cmp eax, 0FFFFFFFFh + je menu_loop + cmp eax, 0FFFFFFFDh + je menu_loop + cmp eax, 1 + je run_shop + cmp eax, 2 + je run_21 + cmp eax, 3 + je run_poker + cmp eax, 4 + je run_slot + cmp eax, 5 + je run_skulls + cmp eax, 6 + je run_roulette + cmp eax, 7 + je run_coin + cmp eax, 8 + je run_dice + cmp eax, 9 + je run_casino_roulette + cmp eax, 10 + je run_classic_slot + cmp eax, 11 + je run_durak + cmp eax, 12 + je run_skill_check + cmp eax, 13 + je run_buckshot + cmp eax, 14 + je run_observer + cmp eax, 15 + je run_training + cmp eax, 16 + je run_achievements + cmp eax, 17 + je run_stats_by_game + cmp eax, 18 + je run_daily + cmp eax, 19 + je run_settings + cmp eax, 20 + je run_online_dice + cmp eax, 21 + je run_umamusume + cmp eax, 25 + + je run_casino_3d + + cmp eax, 666 + je run_hell_tower + cmp eax, 0 + je exit_menu + invoke PrintStr, OFFSET badChoiceText + call PauseConsole + jmp menu_loop +run_21: + mov currentGameId, 1 + call Game21 + jmp menu_loop +run_poker: + mov currentGameId, 2 + call GamePoker + jmp menu_loop +run_slot: + mov currentGameId, 3 + call PlaySlotIntroSound + call GameSlot + jmp menu_loop +run_skulls: + mov currentGameId, 5 + call GameSkulls + jmp menu_loop +run_coin: + mov currentGameId, 6 + call GameCoin + jmp menu_loop +run_dice: + mov currentGameId, 7 + call GameDice + jmp menu_loop +run_roulette: + mov currentGameId, 4 + call GameRoulette + jmp menu_loop +run_casino_roulette: + mov currentGameId, 8 + call GameCasinoRoulette + jmp menu_loop +run_classic_slot: + mov currentGameId, 9 + call PlaySlotIntroSound + call GameClassicSlot + jmp menu_loop +run_durak: + mov currentGameId, 10 + call GameDurak + jmp menu_loop +run_training: + mov currentGameId, 0 + call GameTraining + jmp menu_loop +run_observer: + mov currentGameId, 0 + call GameObserver + jmp menu_loop +run_shop: + mov currentGameId, 0 + call GameShop + jmp menu_loop +run_achievements: + mov currentGameId, 0 + call GameAchievements + jmp menu_loop +run_stats_by_game: + mov currentGameId, 0 + call GameStatsByGame + jmp menu_loop +run_daily: + mov currentGameId, 0 + call GameDailyTasks + jmp menu_loop +run_settings: + mov currentGameId, 0 + call GameSettings + jmp menu_loop +run_online_dice: + mov currentGameId, 0 + call GameOnlineCasino + jmp menu_loop +run_umamusume: + mov currentGameId, 0 + call GameUmamusume + jmp menu_loop +run_casino_3d: + + call StartCasino3D + + jmp menu_loop + +run_hell_tower: + mov currentGameId, 0 + call GameTournament + jmp menu_loop +run_skill_check: + mov tournamentMode, 0 + mov currentGameId, 11 + call GameSkillCheck + jmp menu_loop +run_buckshot: + mov currentGameId, 0 + call GameBuckshot + jmp menu_loop +exit_menu: + ret +MainMenu ENDP + +; --- main: òî÷êà âõîäà, ãëàâíîå ìåíþ è ìàðøðóòèçàöèÿ ïî èãðàì --- +main PROC +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 diff --git a/poker.exe b/poker.exe index 36806d9..74e1c3c 100644 Binary files a/poker.exe and b/poker.exe differ diff --git a/poker.obj b/poker.obj index 63cca68..c8af985 100644 Binary files a/poker.obj and b/poker.obj differ diff --git a/src_graphics/billiards.inc b/src_graphics/billiards.inc index 41801e8..36e1c5f 100644 --- a/src_graphics/billiards.inc +++ b/src_graphics/billiards.inc @@ -29,11 +29,11 @@ pool_rack_row: xor edi, edi pool_rack_ball: mov ecx, poolRackOrder3D[esi*4] - imul eax, ebx, FP_1*9 - add eax, 202*FP_1 + imul eax, ebx, FP_1*43302/10000 + add eax, 225*FP_1 mov poolX3D[ecx*4], eax - imul eax, edi, 10*FP_1 - imul edx, ebx, 5*FP_1 + imul eax, edi, 5*FP_1 + imul edx, ebx, FP_1*5/2 sub eax, edx add eax, 115*FP_1 mov poolY3D[ecx*4], eax @@ -59,6 +59,7 @@ pool_rack_ball: mov poolStill3D, 1 mov poolCalled3D, 1 mov poolCalledPocket3D, 0 + call InitPyramidState3D ret InitPool3D ENDP @@ -73,16 +74,16 @@ PoolCollide3D PROC uses ebx esi edi a:DWORD,b:DWORD je pool_pair_done mov eax, poolX3D[edi*4] sub eax, poolX3D[esi*4] - cmp eax, 10*FP_1 + cmp eax, POOL_DIAMETER jg pool_pair_done - cmp eax, -10*FP_1 + cmp eax, -POOL_DIAMETER jl pool_pair_done mov deltaX, eax mov eax, poolY3D[edi*4] sub eax, poolY3D[esi*4] - cmp eax, 10*FP_1 + cmp eax, POOL_DIAMETER jg pool_pair_done - cmp eax, -10*FP_1 + cmp eax, -POOL_DIAMETER jl pool_pair_done mov deltaY, eax sar eax, 8 @@ -91,7 +92,7 @@ PoolCollide3D PROC uses ebx esi edi a:DWORD,b:DWORD sar ebx, 8 imul ebx, ebx add eax, ebx - cmp eax, 100*256*256 + cmp eax, 25*256*256 jg pool_pair_done test eax, eax jnz @F @@ -140,8 +141,16 @@ PoolCollide3D PROC uses ebx esi edi a:DWORD,b:DWORD shrd eax, edx, 16 add poolVY3D[esi*4], eax sub poolVY3D[edi*4], eax - test esi, esi - jnz pool_pair_separate + invoke PyramidContact3D,esi,edi + cmp esi,pyrCue3D + je @F + cmp edi,pyrCue3D + jne pool_pair_separate + cmp poolFirst3D,-1 + jne pool_pair_separate + mov poolFirst3D,esi + jmp pool_pair_separate +@@: cmp poolFirst3D, -1 jne pool_pair_separate mov poolFirst3D, edi @@ -149,7 +158,7 @@ pool_pair_separate: mov eax, length8 shl eax, 8 neg eax - add eax, 10*FP_1 + add eax, POOL_DIAMETER sar eax, 1 mov correction, eax imul nx @@ -167,20 +176,30 @@ PoolCollide3D ENDP PoolPocketBall3D PROC uses ebx esi ball:DWORD mov esi, ball + cmp poolActive3D[esi*4],0 + je pool_pocket_done xor ebx, ebx pool_pocket_test: mov eax, poolX3D[esi*4] sub eax, poolPocketX3D[ebx*4] + cmp eax,2*FP_1 + jg pool_pocket_next + cmp eax,-2*FP_1 + jl pool_pocket_next sar eax, 8 imul eax, eax mov ecx, eax mov eax, poolY3D[esi*4] sub eax, poolPocketY3D[ebx*4] + cmp eax,2*FP_1 + jg pool_pocket_next + cmp eax,-2*FP_1 + jl pool_pocket_next sar eax, 8 imul eax, eax add eax, ecx - ; The visible 8px mouth is the capture boundary, not a 12px invisible halo. - cmp eax, 64*256*256 + ; Capture is deep inside the narrow mouth; jaws are separate colliders. + cmp eax, 480*480 ja pool_pocket_next pool_pocket_capture: mov poolActive3D[esi*4], 0 @@ -194,6 +213,7 @@ pool_pocket_next: inc ebx cmp ebx, 6 jb pool_pocket_test +pool_pocket_done: ret PoolPocketBall3D ENDP @@ -203,6 +223,7 @@ PoolRailContact3D PROC ball:DWORD cmp poolFirst3D, -1 je @F mov poolRail3D, 1 + invoke PyramidRail3D,ball,pyrRailSide3D @@: ret PoolRailContact3D ENDP @@ -214,16 +235,16 @@ PoolJawContact3D PROC uses ebx esi edi ball:DWORD pool_jaw_test: mov eax, poolX3D[esi*4] sub eax, poolJawX3D[edi*4] - cmp eax, 7*FP_1 + cmp eax, 3*FP_1 jg pool_jaw_next - cmp eax, -7*FP_1 + cmp eax, -3*FP_1 jl pool_jaw_next mov deltaX, eax mov eax, poolY3D[esi*4] sub eax, poolJawY3D[edi*4] - cmp eax, 7*FP_1 + cmp eax, 3*FP_1 jg pool_jaw_next - cmp eax, -7*FP_1 + cmp eax, -3*FP_1 jl pool_jaw_next mov deltaY, eax sar eax, 8 @@ -232,7 +253,7 @@ pool_jaw_test: sar ebx, 8 imul ebx, ebx add eax, ebx - cmp eax, 49*256*256 + cmp eax, 704*704 ja pool_jaw_next test eax, eax jnz @F @@ -277,12 +298,31 @@ pool_jaw_test: imul normY shrd eax, edx, 16 sub poolVY3D[esi*4], eax + mov pyrRailSide3D,0 + cmp edi,6 + jb @F + mov pyrRailSide3D,1 +@@: + cmp edi,1 + je pyr_jaw_left_side + cmp edi,7 + jne @F +pyr_jaw_left_side: + mov pyrRailSide3D,2 +@@: + cmp edi,4 + je pyr_jaw_right_side + cmp edi,10 + jne @F +pyr_jaw_right_side: + mov pyrRailSide3D,3 +@@: invoke PoolRailContact3D,esi pool_jaw_separate: mov eax, distance shl eax, 8 neg eax - add eax, 7*FP_1 + add eax, FP_1*11/4 mov impulse, eax imul normX shrd eax, edx, 16 @@ -303,24 +343,27 @@ PoolStep3D PROC uses ebx esi edi pool_step_ball: cmp poolActive3D[esi*4], 0 je pool_step_next + mov eax,poolX3D[esi*4] + mov pyrPreviousX3D[esi*4],eax mov eax, poolVX3D[esi*4] add poolX3D[esi*4], eax mov eax, poolVY3D[esi*4] add poolY3D[esi*4], eax + invoke PyramidCross3D,esi invoke PoolPocketBall3D, esi cmp poolActive3D[esi*4], 0 je pool_step_next invoke PoolJawContact3D,esi ; Leave the corner throats open. Solid cushions stop at their jaws. - mov ebx, 38*FP_1 - mov edi, 282*FP_1 - cmp poolY3D[esi*4], 64*FP_1 + mov ebx, 30*FP_1+POOL_RADIUS + mov edi, 290*FP_1-POOL_RADIUS + cmp poolY3D[esi*4], 57*FP_1 jle pool_rail_corner_x - cmp poolY3D[esi*4], 166*FP_1 + cmp poolY3D[esi*4], 173*FP_1 jl pool_rail_test_x pool_rail_corner_x: - mov ebx, 32*FP_1 - mov edi, 288*FP_1 + mov ebx, 31*FP_1 + mov edi, 289*FP_1 pool_rail_test_x: cmp poolX3D[esi*4], ebx jge pool_rail_right @@ -342,21 +385,26 @@ pool_rail_bounce_x: mov ecx, 100 idiv ecx mov poolVX3D[esi*4], eax + mov pyrRailSide3D,2 + cmp poolX3D[esi*4],160*FP_1 + jl @F + mov pyrRailSide3D,3 +@@: invoke PoolRailContact3D, esi pool_rail_y: - mov ebx, 58*FP_1 - mov edi, 172*FP_1 - cmp poolX3D[esi*4], 44*FP_1 + mov ebx, 50*FP_1+POOL_RADIUS + mov edi, 180*FP_1-POOL_RADIUS + cmp poolX3D[esi*4], 37*FP_1 jle pool_rail_throat_y - cmp poolX3D[esi*4], 276*FP_1 + cmp poolX3D[esi*4], 283*FP_1 jge pool_rail_throat_y - cmp poolX3D[esi*4], 153*FP_1 + cmp poolX3D[esi*4], 157*FP_1 jl pool_rail_test_y - cmp poolX3D[esi*4], 167*FP_1 + cmp poolX3D[esi*4], 163*FP_1 jg pool_rail_test_y pool_rail_throat_y: - mov ebx, 52*FP_1 - mov edi, 178*FP_1 + mov ebx, 51*FP_1 + mov edi, 179*FP_1 pool_rail_test_y: cmp poolY3D[esi*4], ebx jge pool_rail_bottom @@ -378,6 +426,11 @@ pool_rail_bounce_y: mov ecx, 100 idiv ecx mov poolVY3D[esi*4], eax + mov pyrRailSide3D,0 + cmp poolY3D[esi*4],115*FP_1 + jl @F + mov pyrRailSide3D,1 +@@: invoke PoolRailContact3D, esi pool_step_next: inc esi @@ -402,21 +455,29 @@ pool_contact_inner: xor esi, esi mov poolStill3D, 1 pool_friction_ball: + cmp poolActive3D[esi*4],0 + je pool_sleep_ball + mov eax,poolVX3D[esi*4] + test eax,eax + jns @F + neg eax +@@: + add pyrRoll3D[esi*4],eax mov eax, poolVX3D[esi*4] - sar eax, 8 + sar eax, 4 imul eax, eax mov ecx, poolVY3D[esi*4] - sar ecx, 8 + sar ecx, 4 imul ecx, ecx add eax, ecx - cmp eax, 4 + cmp eax, 64 jbe pool_sleep_ball invoke PoolSqrt3D, eax - shl eax, 8 - cmp eax, 512 + shl eax, 4 + cmp eax, 128 jbe pool_sleep_ball mov ecx, eax - sub eax, 64 + sub eax, 16 xor edx, edx shld edx, eax, 16 shl eax, 16 @@ -442,752 +503,6 @@ pool_friction_next: ret PoolStep3D ENDP -PoolBallLegal3D PROC uses ebx ball:DWORD - mov ecx, poolPlayer3D - mov ebx, poolGroups3D[ecx*4] - mov ecx, ball - xor eax, eax - test ebx, ebx - jz pool_legal_open - cmp poolAtStart3D, 0 - jne pool_legal_group - cmp ecx, 8 - sete al - ret -pool_legal_group: - cmp ebx, 1 - jne pool_legal_stripe - cmp ecx, 1 - jb pool_legal_done - cmp ecx, 7 - seta al - xor eax, 1 - ret -pool_legal_stripe: - cmp ecx, 9 - jb pool_legal_done - cmp ecx, 15 - seta al - xor eax, 1 - ret -pool_legal_open: - test ecx, ecx - jle pool_legal_done - cmp ecx, 8 - je pool_legal_done - cmp ecx, 15 - seta al - xor eax, 1 -pool_legal_done: - ret -PoolBallLegal3D ENDP - -PoolCountGroup3D PROC uses ebx esi - mov poolAtStart3D, 0 - mov ecx, poolPlayer3D - mov ebx, poolGroups3D[ecx*4] - test ebx, ebx - jz pool_count_done - mov esi, 1 -pool_count_ball: - cmp esi, 8 - je pool_count_next - mov eax, 1 - cmp esi, 8 - jb @F - mov eax, 2 -@@: - cmp eax, ebx - jne pool_count_next - mov eax, poolActive3D[esi*4] - add poolAtStart3D, eax -pool_count_next: - inc esi - cmp esi, 16 - jb pool_count_ball -pool_count_done: - ret -PoolCountGroup3D ENDP - -PoolShoot3D PROC - cmp poolState3D, POOL_AIM - jne pool_shoot_done - call PoolCountGroup3D - mov poolFirst3D, -1 - mov poolRail3D, 0 - mov poolBreakRails3D, 0 - mov poolPotted3D, 0 - mov poolFoul3D, 0 - mov poolCharge3D, 0 - mov poolAccumulator3D, 0 - mov poolTime3D, 0 - mov poolState3D, POOL_STRIKE -pool_shoot_done: - ret -PoolShoot3D ENDP - -PoolPlaceCue3D PROC uses ebx esi px:DWORD,py:DWORD - cmp px, 39*FP_1 - jl pool_place_fail - cmp px, 281*FP_1 - jg pool_place_fail - cmp py, 59*FP_1 - jl pool_place_fail - cmp py, 171*FP_1 - jg pool_place_fail - mov esi, 1 -pool_place_ball: - cmp poolActive3D[esi*4], 0 - je pool_place_next - mov eax, px - sub eax, poolX3D[esi*4] - sar eax, 8 - imul eax, eax - mov ebx, eax - mov eax, py - sub eax, poolY3D[esi*4] - sar eax, 8 - imul eax, eax - add eax, ebx - cmp eax, 100*256*256 - jbe pool_place_fail -pool_place_next: - inc esi - cmp esi, 16 - jb pool_place_ball - mov eax, px - mov poolX3D, eax - mov eax, py - mov poolY3D, eax - mov poolActive3D, 1 - mov poolPocket3D, -1 - mov poolSinkTime3D, 0 - mov poolVX3D, 0 - mov poolVY3D, 0 - mov eax, 1 - ret -pool_place_fail: - xor eax, eax - ret -PoolPlaceCue3D ENDP - -PoolFinishShot3D PROC uses ebx esi - mov poolFoul3D, 0 - cmp poolActive3D, 0 - je pool_finish_foul - cmp poolFirst3D, -1 - je pool_finish_foul - cmp poolBreak3D, 0 - jne pool_finish_break - invoke PoolBallLegal3D,poolFirst3D - test eax, eax - jz pool_finish_foul - cmp poolRail3D, 0 - jne pool_finish_eight - cmp poolPotted3D, 0 - jne pool_finish_eight - jmp pool_finish_foul -pool_finish_break: - mov eax, poolPotted3D - and eax, 0FFFEh - jnz pool_finish_eight - mov eax, poolBreakRails3D - and eax, 0FFFEh - xor ecx, ecx -pool_count_break_rails: - test eax, eax - jz @F - lea edx, [eax-1] - and eax, edx - inc ecx - jmp pool_count_break_rails -@@: - cmp ecx, 4 - jae pool_finish_eight -pool_finish_foul: - mov poolFoul3D, 1 -pool_finish_eight: - cmp poolActive3D[8*4], 0 - jne pool_finish_continue - cmp poolBreak3D, 0 - je pool_finish_eight_result - ; A break eight is re-spotted along the foot spot without overlapping survivors. - mov ebx, 220*FP_1 -pool_spot_eight_try: - mov esi, 1 -pool_spot_eight_scan: - cmp esi, 8 - je pool_spot_eight_next - cmp poolActive3D[esi*4], 0 - je pool_spot_eight_next - mov eax, poolX3D[esi*4] - sub eax, ebx - sar eax, 8 - imul eax, eax - mov ecx, eax - mov eax, poolY3D[esi*4] - sub eax, 115*FP_1 - sar eax, 8 - imul eax, eax - add eax, ecx - cmp eax, 100*256*256 - jbe pool_spot_eight_advance -pool_spot_eight_next: - inc esi - cmp esi, 16 - jb pool_spot_eight_scan - mov poolX3D[8*4], ebx - mov poolY3D[8*4], 115*FP_1 - mov poolActive3D[8*4], 1 - mov poolPocket3D[8*4], -1 - jmp pool_finish_continue -pool_spot_eight_advance: - sub ebx, 11*FP_1 - cmp ebx, 39*FP_1 - jge pool_spot_eight_try - call InitPool3D - ret -pool_finish_eight_result: - mov eax, poolPlayer3D - cmp poolFoul3D, 0 - jne pool_eight_lost - cmp poolAtStart3D, 0 - jne pool_eight_lost - mov ecx, poolGroups3D[eax*4] - test ecx, ecx - jz pool_eight_lost - cmp poolCalled3D, 8 - jne pool_eight_lost - mov ecx, poolCalledPocket3D - cmp ecx, poolPocket3D[8*4] - je pool_eight_end -pool_eight_lost: - xor eax, 1 -pool_eight_end: - mov poolWinner3D, eax - mov poolState3D, POOL_RESULT - ret -pool_finish_continue: - mov eax, poolBreak3D - mov poolBreak3D, 0 - cmp poolFoul3D, 0 - jne pool_change_foul - test eax, eax - jz pool_finish_called - cmp poolPotted3D, 0 - jne pool_new_aim - jmp pool_change_player -pool_finish_called: - mov ebx, poolCalled3D - cmp ebx, 1 - jb pool_change_player - cmp ebx, 15 - ja pool_change_player - bt poolPotted3D, ebx - jnc pool_change_player - mov eax, poolCalledPocket3D - cmp eax, poolPocket3D[ebx*4] - jne pool_change_player - invoke PoolBallLegal3D,ebx - test eax, eax - jz pool_change_player - mov ecx, poolPlayer3D - cmp poolGroups3D[ecx*4], 0 - jne pool_new_aim - mov eax, 1 - cmp ebx, 8 - jb @F - mov eax, 2 -@@: - mov poolGroups3D[ecx*4], eax - xor ecx, 1 - xor eax, 3 - mov poolGroups3D[ecx*4], eax - jmp pool_new_aim -pool_change_foul: - xor poolPlayer3D, 1 - mov poolState3D, POOL_HAND - mov poolTime3D, 0 - ret -pool_change_player: - xor poolPlayer3D, 1 -pool_new_aim: - mov poolState3D, POOL_AIM - mov poolTime3D, 0 - ret -PoolFinishShot3D ENDP - -PoolAimPoint3D PROC uses ebx esi edi px:DWORD,py:DWORD - local deltaX:DWORD,deltaY:DWORD,best:DWORD,angle:DWORD - mov eax, px - sub eax, poolX3D - sar eax, 8 - mov deltaX, eax - mov eax, py - sub eax, poolY3D - sar eax, 8 - mov deltaY, eax - mov best, 80000000h - xor esi, esi -pool_aim_direction: - mov eax, tableCos[esi*4] - sar eax, 8 - imul eax, deltaX - mov ebx, eax - mov eax, tableSin[esi*4] - sar eax, 8 - imul eax, deltaY - add eax, ebx - cmp eax, best - jle @F - mov best, eax - mov angle, esi -@@: - inc esi - cmp esi, 512 - jb pool_aim_direction - mov eax, angle - mov poolAngle3D, eax - ret -PoolAimPoint3D ENDP - -; AI selects an actual legal ball and aims a ghost-ball contact towards a pocket. -PoolChooseAI3D PROC uses ebx esi edi - local deltaX:DWORD,deltaY:DWORD,dist:DWORD,targetX:DWORD,targetY:DWORD - call PoolCountGroup3D - mov esi, 1 -pool_ai_target: - cmp poolActive3D[esi*4], 0 - je pool_ai_next - invoke PoolBallLegal3D,esi - test eax, eax - jz pool_ai_next - mov poolCalled3D, esi - xor edi, edi - mov dist, 7FFFFFFFh -pool_ai_pocket: - mov eax, poolPocketX3D[edi*4] - sub eax, poolX3D[esi*4] - sar eax, 8 - imul eax, eax - mov ebx, eax - mov eax, poolPocketY3D[edi*4] - sub eax, poolY3D[esi*4] - sar eax, 8 - imul eax, eax - add eax, ebx - cmp eax, dist - jge @F - mov dist, eax - mov poolCalledPocket3D, edi -@@: - inc edi - cmp edi, 6 - jb pool_ai_pocket - mov edi, poolCalledPocket3D - mov eax, poolPocketX3D[edi*4] - sub eax, poolX3D[esi*4] - mov deltaX, eax - mov eax, poolPocketY3D[edi*4] - sub eax, poolY3D[esi*4] - mov deltaY, eax - invoke PoolSqrt3D,dist - test eax, eax - jnz @F - mov eax, 1 -@@: - mov dist, eax - mov eax, deltaX - imul eax, 10*256 - cdq - idiv dist - mov ebx, poolX3D[esi*4] - sub ebx, eax - mov targetX, ebx - mov eax, deltaY - imul eax, 10*256 - cdq - idiv dist - mov ebx, poolY3D[esi*4] - sub ebx, eax - mov targetY, ebx - invoke PoolAimPoint3D,targetX,targetY - mov poolPower3D, 65000 - ret -pool_ai_next: - inc esi - cmp esi, 16 - jb pool_ai_target - mov poolAngle3D, 0 - mov poolPower3D, 30000 - ret -PoolChooseAI3D ENDP - -HandlePool3D PROC uses ebx esi edi - xor esi, esi -pool_sink_tick: - mov eax, deltaTime3D - sub poolSinkTime3D[esi*4], eax - jnc @F - mov poolSinkTime3D[esi*4], 0 -@@: - inc esi - cmp esi, 16 - jb pool_sink_tick - mov eax, deltaTime3D - add poolTime3D, eax - cmp poolState3D, POOL_MOVING - jne pool_check_strike - add poolAccumulator3D, eax -pool_simulate: - cmp poolAccumulator3D, 2 - jb pool_handle_done - sub poolAccumulator3D, 2 - call PoolStep3D - cmp poolStill3D, 0 - je pool_simulate - call PoolFinishShot3D - ret -pool_check_strike: - cmp poolState3D, POOL_STRIKE - jne pool_check_result - cmp poolTime3D, 240 - jb pool_handle_done - mov ecx, poolAngle3D - mov eax, tableCos[ecx*4] - imul poolPower3D - shrd eax, edx, 16 - mov poolVX3D, eax - mov eax, tableSin[ecx*4] - imul poolPower3D - shrd eax, edx, 16 - mov poolVY3D, eax - mov poolState3D, POOL_MOVING - mov poolAccumulator3D, 0 - ret -pool_check_result: - cmp poolState3D, POOL_RESULT - jne pool_input - invoke Pressed3D,20h - test eax, eax - jz pool_handle_done - call InitPool3D - ret -pool_input: - cmp poolPlayer3D, 1 - jne pool_human - cmp poolAI3D, 0 - je pool_human - cmp poolTime3D, 850 - jb pool_handle_done - cmp poolState3D, POOL_HAND - jne pool_ai_shot - mov esi, 55 -pool_ai_place: - mov eax, esi - shl eax, 16 - invoke PoolPlaceCue3D,eax,115*FP_1 - test eax, eax - jnz @F - add esi, 8 - cmp esi, 280 - jb pool_ai_place - ret -@@: - mov poolState3D, POOL_AIM -pool_ai_shot: - call PoolChooseAI3D - call PoolShoot3D - ret -pool_human: - cmp mouseClick3D, 0 - je pool_key_input - cmp mouseY3D, 50 - jb pool_mouse_buttons - cmp mouseY3D, 180 - ja pool_mouse_buttons - mov eax, mouseX3D - shl eax, 16 - mov ebx, mouseY3D - shl ebx, 16 - cmp poolState3D, POOL_HAND - jne pool_mouse_aim - invoke PoolPlaceCue3D,eax,ebx - test eax, eax - jz pool_handle_done - mov poolState3D, POOL_AIM - ret -pool_mouse_aim: - invoke PoolAimPoint3D,eax,ebx - jmp pool_key_input -pool_mouse_buttons: - cmp mouseY3D, 193 - jb pool_key_input - cmp mouseY3D, 209 - ja pool_mouse_commands - cmp mouseX3D, 202 - jb pool_key_input - cmp mouseX3D, 308 - ja pool_key_input - mov eax, mouseX3D - sub eax, 202 - imul eax, 82000 - xor edx, edx - mov ecx, 106 - div ecx - add eax, 8000 - mov poolPower3D, eax - ret -pool_mouse_commands: - cmp mouseY3D, 211 - jb pool_key_input - cmp mouseY3D, 229 - ja pool_key_input - cmp mouseX3D, 90 - jb pool_cycle_ball - cmp mouseX3D, 200 - jb pool_cycle_pocket - call PoolShoot3D - ret -pool_key_input: - cmp poolState3D, POOL_AIM - jne pool_handle_done - cmp keys3D[25h], 0 - je @F - sub poolAngle3D, 1 -@@: - cmp keys3D[27h], 0 - je @F - add poolAngle3D, 1 -@@: - and poolAngle3D, 511 - mov eax, deltaTime3D - imul eax, 100 - cmp keys3D[26h], 0 - je @F - add poolPower3D, eax -@@: - cmp keys3D[28h], 0 - je @F - sub poolPower3D, eax -@@: - cmp poolPower3D, 8000 - jge @F - mov poolPower3D, 8000 -@@: - cmp poolPower3D, 90000 - jle @F - mov poolPower3D, 90000 -@@: - invoke Pressed3D,42h - test eax, eax - jnz pool_cycle_ball - invoke Pressed3D,50h - test eax, eax - jnz pool_cycle_pocket - invoke Pressed3D,20h - test eax, eax - jz pool_handle_done - call PoolShoot3D - ret -pool_cycle_ball: - inc poolCalled3D - cmp poolCalled3D, 15 - jbe pool_handle_done - mov poolCalled3D, 1 - ret -pool_cycle_pocket: - inc poolCalledPocket3D - cmp poolCalledPocket3D, 6 - jb pool_handle_done - mov poolCalledPocket3D, 0 -pool_handle_done: - ret -HandlePool3D ENDP - -RenderPool3D PROC uses ebx esi edi - local x:DWORD,y:DWORD,angle:DWORD - invoke DrawBox,0,0,320,240,00191E1Bh - invoke DrawBoxBorder,19,39,282,153,00573D26h,00AC8A4Dh,3 - invoke DrawBoxBorder,25,45,270,141,00254432h,009D9161h,2 - invoke DrawBox,30,50,260,130,0029744Eh - xor esi, esi -pool_render_pockets: - mov ebx, poolPocketX3D[esi*4] - sar ebx, 16 - mov edi, poolPocketY3D[esi*4] - sar edi, 16 - invoke DrawCircle,ebx,edi,8,000E1511h - cmp esi, poolCalledPocket3D - jne @F - invoke DrawCircle,ebx,edi,2,00D7BC6Ah -@@: - inc esi - cmp esi, 6 - jb pool_render_pockets - xor esi, esi -pool_render_balls: - cmp poolActive3D[esi*4], 0 - je pool_render_sunk_ball - mov ebx, poolX3D[esi*4] - sar ebx, 16 - mov edi, poolY3D[esi*4] - sar edi, 16 - invoke DrawCircle,ebx,edi,6,001D3024h - invoke DrawCircle,ebx,edi,5,poolColors3D[esi*4] - cmp esi, 9 - jb @F - lea eax, [ebx-3] - lea edx, [edi-2] - invoke DrawBox,eax,edx,7,3,00E9E3CFh -@@: - lea eax, [ebx-1] - lea edx, [edi-1] - invoke DrawPixel,eax,edx,00FFFFFFh - cmp esi, poolCalled3D - jne pool_render_next_ball - lea eax, [ebx-3] - lea edx, [edi-9] - invoke DrawNumber,eax,edx,esi,00F5E7BAh - jmp pool_render_next_ball -pool_render_sunk_ball: - cmp poolSinkTime3D[esi*4], 0 - je pool_render_tray_ball - mov ecx, poolPocket3D[esi*4] - mov ebx, poolPocketX3D[ecx*4] - sar ebx, 16 - mov edi, poolPocketY3D[ecx*4] - sar edi, 16 - mov eax, poolSinkTime3D[esi*4] - imul eax, 5 - xor edx, edx - mov ecx, 220 - div ecx - inc eax - invoke DrawCircle,ebx,edi,eax,poolColors3D[esi*4] - jmp pool_render_next_ball -pool_render_tray_ball: - ; Scratched cue is retained on the rack until ball-in-hand placement. - imul ebx, esi, 10 - add ebx, 20 - invoke DrawCircle,ebx,195,4,poolColors3D[esi*4] -pool_render_next_ball: - inc esi - cmp esi, 16 - jb pool_render_balls - cmp poolState3D, POOL_AIM - je pool_render_cue - cmp poolState3D, POOL_STRIKE - jne pool_render_header -pool_render_cue: - mov ecx, poolAngle3D - mov angle, ecx - mov esi, 8 - mov eax, poolPower3D - shr eax, 12 - add esi, eax - cmp poolState3D, POOL_STRIKE - jne pool_cue_line - mov eax, poolTime3D - shr eax, 3 - sub esi, eax - cmp esi, 5 - jge pool_cue_line - mov esi, 5 -pool_cue_line: - mov edi, 40 -pool_render_cue_pixel: - mov ecx, angle - mov eax, tableCos[ecx*4] - imul esi - neg eax - add eax, poolX3D - sar eax, 16 - mov ebx, eax - mov eax, tableSin[ecx*4] - imul esi - neg eax - add eax, poolY3D - sar eax, 16 - invoke DrawCircle,ebx,eax,1,00CFA872h - inc esi - dec edi - jnz pool_render_cue_pixel - cmp poolState3D, POOL_AIM - jne pool_render_header - mov esi, 16 -pool_aim_guide_pixel: - mov ecx, angle - mov eax, tableCos[ecx*4] - imul esi - add eax, poolX3D - sar eax, 16 - mov ebx, eax - mov eax, tableSin[ecx*4] - imul esi - add eax, poolY3D - sar eax, 16 - invoke DrawCircle,ebx,eax,1,008BCB87h - add esi, 4 - cmp esi, 76 - jb pool_aim_guide_pixel -pool_render_header: - invoke DrawString8x8,12,12,OFFSET poolTitle3D,00E6D09Dh - mov ebx, OFFSET poolPlayerText3D - mov eax, poolPlayer3D - cmp poolState3D, POOL_RESULT - jne @F - mov eax, poolWinner3D -@@: - test eax, eax - je @F - mov ebx, OFFSET poolDealerText3D -@@: - invoke DrawString8x8,100,12,ebx,00F1ECE0h - mov eax, poolPlayer3D - mov eax, poolGroups3D[eax*4] - invoke DrawString8x8,184,12,poolGroupTexts3D[eax*4],00CCBE94h - invoke DrawBoxBorder,12,211,74,18,0039412Fh,00AC9862h,1 - invoke DrawString8x8,18,216,OFFSET poolBallText3D,00FFFFFFh - invoke DrawNumber,62,216,poolCalled3D,00EAD19Bh - invoke DrawBoxBorder,92,211,104,18,0039412Fh,00AC9862h,1 - invoke DrawString8x8,98,216,OFFSET poolPocketText3D,00FFFFFFh - mov eax, poolCalledPocket3D - inc eax - invoke DrawNumber,167,216,eax,00EAD19Bh - invoke DrawBoxBorder,202,211,106,18,00425232h,00BBA76Fh,1 - mov ebx, OFFSET poolShotText3D - cmp poolState3D, POOL_RESULT - jne @F - mov ebx, OFFSET poolRackText3D -@@: - invoke DrawString8x8,226,216,ebx,00FFFFFFh - invoke DrawString8x8,202,187,OFFSET poolPowerText3D,00CCBE94h - mov eax, poolPower3D - xor edx, edx - mov ecx, 900 - div ecx - invoke DrawNumber,254,187,eax,00FFFFFFh - mov eax, poolPower3D - sub eax, 8000 - imul eax, 106 - xor edx, edx - mov ecx, 82000 - div ecx - mov x, eax - invoke DrawBox,202,201,106,5,00363D36h - invoke DrawBox,202,201,x,5,00D5BB73h - mov eax, x - add eax, 201 - invoke DrawBox,eax,199,2,9,00F4F0DDh - cmp poolState3D, POOL_HAND - jne @F - invoke DrawString8x8,84,30,OFFSET poolPlaceText3D,00E8B9A1h -@@: - cmp poolState3D, POOL_RESULT - jne pool_render_done - invoke DrawBoxBorder,102,91,116,39,00192720h,00D6B971h,2 - invoke DrawString8x8,130,103,OFFSET poolWinText3D,00FFFFFFh -pool_render_done: - ret -RenderPool3D ENDP +include src_graphics\pyramid_rules.inc +include src_graphics\pyramid_play.inc +include src_graphics\pyramid_render.inc diff --git a/src_graphics/billiards_data.inc b/src_graphics/billiards_data.inc index 0b2ee9c..fc8a04d 100644 --- a/src_graphics/billiards_data.inc +++ b/src_graphics/billiards_data.inc @@ -4,7 +4,10 @@ POOL_STRIKE equ 1 POOL_MOVING equ 2 POOL_HAND equ 3 POOL_RESULT equ 4 -POOL_RADIUS equ 5*FP_1 +POOL_RADIUS equ FP_1*5/2 +POOL_DIAMETER equ 5*FP_1 +POOL_PENALTY equ 5 +POOL_CHOICE equ 6 InitPool3D PROTO HandlePool3D PROTO RenderPool3D PROTO @@ -25,8 +28,10 @@ poolColors3D dd 00F0E8D3h,00D4B524h,00304EADh,00B72B36h,006A438Ch,00DD8030h,003B poolRackOrder3D dd 1,9,2,3,8,10,11,4,12,5,6,13,7,14,15 poolPocketX3D dd 30*FP_1,160*FP_1,290*FP_1,30*FP_1,160*FP_1,290*FP_1 poolPocketY3D dd 50*FP_1,50*FP_1,50*FP_1,180*FP_1,180*FP_1,180*FP_1 -poolJawX3D dd 42*FP_1,30*FP_1,145*FP_1,175*FP_1,290*FP_1,278*FP_1,42*FP_1,30*FP_1,145*FP_1,175*FP_1,290*FP_1,278*FP_1 -poolJawY3D dd 50*FP_1,62*FP_1,58*FP_1,58*FP_1,62*FP_1,50*FP_1,180*FP_1,168*FP_1,172*FP_1,172*FP_1,168*FP_1,180*FP_1 +poolJawX3D dd FP_1*137/4,30*FP_1,157*FP_1,163*FP_1,290*FP_1,FP_1*1143/4 + dd FP_1*137/4,30*FP_1,157*FP_1,163*FP_1,290*FP_1,FP_1*1143/4 +poolJawY3D dd 50*FP_1,FP_1*217/4,50*FP_1,50*FP_1,FP_1*217/4,50*FP_1 + dd 180*FP_1,FP_1*703/4,180*FP_1,180*FP_1,FP_1*703/4,180*FP_1 poolState3D dd POOL_AIM poolPlayer3D dd 0 poolAI3D dd 1 @@ -64,3 +69,4 @@ poolBallText3D db 216,192,208,0 poolPocketText3D db 203,211,199,192,0 poolGroupTexts3D dd OFFSET poolOpenText3D,OFFSET poolSolidsText3D,OFFSET poolStripesText3D .code +include src_graphics\pyramid_data.inc diff --git a/src_graphics/buckshot.inc b/src_graphics/buckshot.inc index 91bf956..e6ccca1 100644 --- a/src_graphics/buckshot.inc +++ b/src_graphics/buckshot.inc @@ -230,6 +230,7 @@ bs_finish_win: jbe @F mov bankroll, 1000000000 @@: + invoke NpcRecordRound3D,7,1 call SaveProgress3D ret bs_finish_lose: @@ -237,6 +238,7 @@ bs_finish_lose: mov bs3d_result, BS_LOSE mov bs3d_victim, 0 mov bs3d_timer, 800 + invoke NpcRecordRound3D,7,0 call SaveProgress3D bs_finish_done: ret diff --git a/src_graphics/card_table_assets.inc b/src_graphics/card_table_assets.inc index be36dcf..6c721fb 100644 --- a/src_graphics/card_table_assets.inc +++ b/src_graphics/card_table_assets.inc @@ -1,5 +1,6 @@ ; All runtime rendering/gameplay is native. Artwork and rank tables are binary assets. FreeCardTableAssets3D PROC + call FreeBJParty3D cmp cardTablePixels3D, 0 je @F invoke HeapFree, cardTableHeap3D, 0, cardTablePixels3D diff --git a/src_graphics/card_table_input.inc b/src_graphics/card_table_input.inc index bd97eb6..fd6fd25 100644 --- a/src_graphics/card_table_input.inc +++ b/src_graphics/card_table_input.inc @@ -119,8 +119,13 @@ LeaveCardTable3D PROC jmp card_leave_hall @@: cmp engineMode, MODE_DURAK - jne card_leave_hall + jne @F invoke NativeDurakSettle3D, 1 + jmp card_leave_hall +@@: + cmp engineMode,MODE_RUSSIAN + jne card_leave_hall + call AbortRussianRound3D card_leave_hall: mov cardExitActive3D, 0 mov paused3D, 0 @@ -146,6 +151,12 @@ RequestCardExit3D ENDP ; Called by the engine's Escape dispatch, before the generic pause branch. CardTableEscape3D PROC + cmp engineMode,MODE_NPC_DIALOG + jne @F + call CloseNpcDialog3D + mov eax,1 + ret +@@: cmp engineMode, MODE_COIN jne @F call CoinEscape3D @@ -163,12 +174,20 @@ CardTableEscape3D PROC call SlotEscape3D mov eax,1 ret +@@: + cmp engineMode, MODE_CLOVER + jne @F + call CloverEscape3D + mov eax,1 + ret @@: cmp engineMode, MODE_POKER je card_escape_handle cmp engineMode, MODE_BLACKJACK je card_escape_handle cmp engineMode, MODE_DURAK + je card_escape_handle + cmp engineMode, MODE_RUSSIAN jne card_escape_other card_escape_handle: cmp cardExitActive3D, 0 @@ -283,6 +302,8 @@ TableBusy3D PROC je table_busy_russian cmp eax, MODE_SLOTS je table_busy_slots + cmp eax, MODE_CLOVER + je table_busy_clover cmp eax, MODE_ROULETTE je table_busy_wheel cmp eax, MODE_COIN @@ -334,6 +355,10 @@ table_busy_slots: cmp slotSpinState, 1 je table_is_busy jmp table_not_busy +table_busy_clover: + cmp clpState3D,SLOT_SPIN + je table_is_busy + jmp table_not_busy table_busy_wheel: cmp roulState, 1 je table_is_busy diff --git a/src_graphics/card_tables_render.inc b/src_graphics/card_tables_render.inc index d395d16..3706d71 100644 --- a/src_graphics/card_tables_render.inc +++ b/src_graphics/card_tables_render.inc @@ -299,6 +299,11 @@ RenderNativePoker3D ENDP RenderNativeBlackjack3D PROC uses ebx esi edi local hand:DWORD,nCards:DWORD,y:DWORD,spacing:DWORD,startX:DWORD,hidden:DWORD,flipCard:DWORD + cmp cbBotCount3D, 0 + je @F + call RenderBJParty3D + ret +@@: call RenderCardTable3D invoke DrawTableHeader3D, OFFSET cbTitle3D, cbStake3D xor eax, eax @@ -461,6 +466,7 @@ bj_render_next_card: invoke DrawString8x8, 116, 135, cbResults3D[eax*4], 00EFD583h bj_render_buttons: call DrawQueuedTableHand3D + call DrawBJPartySelector3D cmp cbError3D, 0 je @F invoke DrawString8x8, 80, 135, OFFSET textNoCash3D, 00F89880h @@ -509,7 +515,12 @@ card_exit_dim: loop card_exit_dim invoke DrawBoxBorder, 20, 64, 280, 120, 00151D20h, 00D5C79Eh, 1 invoke DrawString8x8, 104, 78, OFFSET cardExitTitle3D, 00F2E4BCh - invoke DrawString8x8, 60, 104, OFFSET cardExitWarning3D, 00D8DFDDh + mov ecx,OFFSET cardExitWarning3D + cmp engineMode,MODE_RUSSIAN + jne @F + mov ecx,OFFSET rrPartyExitText3D +@@: + invoke DrawString8x8, 60, 104, ecx, 00D8DFDDh invoke DrawString8x8, 72, 120, OFFSET cardExitStake3D, 00F4B6A4h mov ebx, 00D5C79Eh mov esi, 00556555h diff --git a/src_graphics/city_arrival_data.inc b/src_graphics/city_arrival_data.inc index e0f3d2e..c0c2a59 100644 --- a/src_graphics/city_arrival_data.inc +++ b/src_graphics/city_arrival_data.inc @@ -152,11 +152,11 @@ cityEntryWoman3D LABEL BYTE cityObjectsEnd3D LABEL BYTE .errnz ((cityObjectsEnd3D-cityObjects3D)/SIZEOF CityProp3D)-CITY_PROP_COUNT cityWalkRoutes3D CityWalkRoute3D <(cityNearMan3D-cityObjects3D)/SIZEOF CityProp3D,10*FP_1,28*FP_1,FP_1*253/20,0,32000,0,140> - CityWalkRoute3D <(cityFarWoman3D-cityObjects3D)/SIZEOF CityProp3D,10*FP_1,28*FP_1,FP_1*169/10,32000,32000,16,160> + CityWalkRoute3D <(cityFarWoman3D-cityObjects3D)/SIZEOF CityProp3D,10*FP_1,28*FP_1,16*FP_1+FP_HALF,32000,32000,16,160> CityWalkRoute3D <(cityNearWoman3D-cityObjects3D)/SIZEOF CityProp3D,11*FP_1,27*FP_1,FP_1*63/5,21000,30000,16,155> - CityWalkRoute3D <(cityFarMan3D-cityObjects3D)/SIZEOF CityProp3D,10*FP_1,28*FP_1,FP_1*337/20,13000,34000,0,145> - CityWalkRoute3D <(cityEntryMan3D-cityObjects3D)/SIZEOF CityProp3D,20*FP_1+FP_1/5,21*FP_1+FP_1/5,9*FP_1,0,4000,0,140> - CityWalkRoute3D <(cityEntryWoman3D-cityObjects3D)/SIZEOF CityProp3D,23*FP_1+FP_1*4/5,24*FP_1+FP_1*4/5,9*FP_1,4000,5200,16,160> + CityWalkRoute3D <(cityFarMan3D-cityObjects3D)/SIZEOF CityProp3D,10*FP_1,28*FP_1,16*FP_1+FP_HALF,13000,34000,0,145> + CityWalkRoute3D <(cityEntryMan3D-cityObjects3D)/SIZEOF CityProp3D,11*FP_1,29*FP_1,FP_1*253/20,4000,31000,0,140> + CityWalkRoute3D <(cityEntryWoman3D-cityObjects3D)/SIZEOF CityProp3D,12*FP_1,30*FP_1,16*FP_1+FP_HALF,18000,30000,16,160> IFDEF CASINO_ACTION_TEST cityVisiblePixels3D dd CITY_PROP_COUNT dup(0) ENDIF diff --git a/src_graphics/hall_scene.inc b/src_graphics/hall_scene.inc index 6b83ac8..ffcf563 100644 --- a/src_graphics/hall_scene.inc +++ b/src_graphics/hall_scene.inc @@ -1,1291 +1,1306 @@ -; Room planes use independent ceiling/floor distances; the eye is not the room midpoint. -RenderCeilingAndFloor PROC uses ebx esi edi - local row:DWORD,distance:DWORD,sx:DWORD,sy:DWORD,wx:DWORD,wy:DWORD - local material:DWORD,shade:DWORD - mov row, 0 -hall_plane_row: - mov eax, row - cmp eax, viewHorizon3D - jge hall_plane_floor - cmp outdoorRender3D, 0 - jne hall_plane_next_row - mov ecx, viewHorizon3D - sub ecx, eax - mov eax, viewCeiling3D - sub eax, viewEye3D - mov material, 101 - cmp hallLevel3D, 0 - je @F - mov material, 93 -@@: - jmp hall_plane_distance -hall_plane_floor: - sub eax, viewHorizon3D - inc eax - mov ecx, eax - mov eax, viewEye3D - mov ebx, floorTexture3D - mov material, ebx -hall_plane_distance: - imul eax, SCREEN_H - cdq - idiv ecx - mov distance, eax - shr eax, 14 - neg eax - add eax, 256 - cmp eax, 55 - jge @F - mov eax, 55 -@@: - mov shade, eax - cmp hallLevel3D, 0 - je @F - mov eax, shade - imul eax, 7 - shr eax, 3 - mov shade, eax -@@: - mov eax, playerPlaneX - shl eax, 1 - imul distance - shrd eax, edx, 16 - cdq - mov ecx, SCREEN_W - idiv ecx - mov sx, eax - mov eax, playerPlaneY - shl eax, 1 - imul distance - shrd eax, edx, 16 - cdq - idiv ecx - mov sy, eax - mov eax, playerDirX - sub eax, playerPlaneX - imul distance - shrd eax, edx, 16 - add eax, playerX - mov wx, eax - mov eax, playerDirY - sub eax, playerPlaneY - imul distance - shrd eax, edx, 16 - add eax, playerY - mov wy, eax - mov eax, row - imul eax, SCREEN_W*4 - lea edi, screenBuffer[eax] - mov esi, SCREEN_W -hall_plane_pixel: - mov ebx, material - cmp outdoorRender3D, 0 - je hall_plane_sample - mov eax, wy - cmp eax, 13*FP_1 - jb hall_plane_crossroad - cmp eax, 16*FP_1 - jb hall_plane_sample -hall_plane_crossroad: - mov eax, wx - cmp eax, 29*FP_1 - jl hall_plane_sidewalk - cmp eax, 32*FP_1 - jl hall_plane_sample -hall_plane_sidewalk: - mov ebx, 72 -hall_plane_sample: - cmp outdoorRender3D, 0 - jne hall_plane_low_sample - mov eax, row - cmp eax, viewHorizon3D - jl hall_plane_choose_hd - cmp hallLevel3D, 0 - jne hall_plane_choose_hd - cmp wy, 23*FP_1 - jl hall_plane_choose_hd - cmp wx, 12*FP_1 - jl hall_plane_wood - cmp wx, 23*FP_1 - jl hall_plane_choose_hd -hall_plane_wood: - mov ebx, 85 -hall_plane_choose_hd: - cmp distance, 6*FP_1 - ja hall_plane_low_sample - mov ecx, hallRoomHD3D.pixels - cmp ebx, 80 - jb hall_plane_low_sample - cmp ebx, 103 - ja hall_plane_low_sample - cmp ebx, 92 - jb hall_plane_old_hd - mov ecx, hallArchitectureHD3D.pixels - sub ebx, 12 -hall_plane_old_hd: - test ecx, ecx - jz hall_plane_hd_fallback - sub ebx, 80 - shl ebx, 18 - add ecx, ebx - mov eax, wy - shr eax, 8 - and eax, 255 - shl eax, 8 - mov edx, wx - shr edx, 8 - and edx, 255 - add eax, edx - mov eax, [ecx+eax*4] - jmp hall_plane_shade -hall_plane_hd_fallback: - mov ebx, material -hall_plane_low_sample: - shl ebx, 16 - mov eax, wy - shr eax, 9 - and eax, 127 - shl eax, 7 - mov edx, wx - shr edx, 9 - and edx, 127 - add eax, edx - lea ebx, texturesBuffer[ebx] - mov eax, [ebx+eax*4] -hall_plane_shade: - cmp outdoorRender3D, 0 - je hall_plane_ambient - invoke ShadeCityGround3D, eax, wx, wy, shade - jmp hall_plane_store -hall_plane_ambient: - mov ebx, eax - and eax, 0000FF00h - imul eax, shade - shr eax, 8 - and eax, 0000FF00h - mov ecx, ebx - and ecx, 0FFh - imul ecx, shade - shr ecx, 8 - or eax, ecx - shr ebx, 16 - and ebx, 0FFh - imul ebx, shade - shr ebx, 8 - shl ebx, 16 - or eax, ebx -hall_plane_store: - stosd - mov eax, sx - add wx, eax - mov eax, sy - add wy, eax - dec esi - jnz hall_plane_pixel -hall_plane_next_row: - inc row - cmp row, SCREEN_H - jb hall_plane_row - ret -RenderCeilingAndFloor ENDP - -RenderSprites PROC uses ebx esi edi - cmp hallLevel3D, 0 - jne hall_sprites_done - xor esi, esi -hall_sprite_loop: - cmp esi, 14 - je hall_sprite_next - imul ebx, esi, SIZEOF SpriteObject - mov eax, casinoSprites[ebx].posX - mov hallSpriteTemp3D.posX, eax - mov eax, casinoSprites[ebx].posY - mov hallSpriteTemp3D.posY, eax - mov eax, hallSpriteWidths3D[esi*4] - mov hallSpriteTemp3D.worldW, eax - mov eax, hallSpriteHeights3D[esi*4] - mov hallSpriteTemp3D.worldH, eax - mov hallSpriteTemp3D.groundZ, 0 - cmp esi, 3 - jae @F - mov hallSpriteTemp3D.groundZ, FP_1/8 -@@: - mov ecx, casinoSprites[ebx].animSpeed - imul ecx, 40 - test ecx, ecx - jnz @F - mov ecx, 40 -@@: - mov eax, animationClock3D - cmp esi,3 - jae @F - mov edx,casinoSprites[ebx].curFrame - imul edx,ecx - add eax,edx -@@: - xor edx, edx - div ecx - mov ecx, casinoSprites[ebx].frameCount - test ecx, ecx - jnz @F - mov ecx, 1 -@@: - xor edx, edx - div ecx - add edx, casinoSprites[ebx].baseTexId - shl edx, 16 - add edx, OFFSET texturesBuffer - mov hallLegacyPack3D.pixels, edx - mov hallSpriteTemp3D.frame, 0 - mov hallSpriteTemp3D.asset, OFFSET hallLegacyPack3D - mov eax, hallStationPacks3D[esi*4] - test eax, eax - jz hall_sprite_draw - ; Missing dedicated art hides the station, never shows a contaminated atlas cell. - cmp [eax].AnimPack3D.pixels, 0 - je hall_sprite_next - mov hallSpriteTemp3D.asset, eax - cmp eax, OFFSET hallSlotFurniture3D - jne hall_sprite_draw - mov eax, animationClock3D - xor edx, edx - mov ecx, 320 - div ecx - add eax, esi - xor edx, edx - mov ecx, 3 - div ecx - mov hallSpriteTemp3D.frame, edx -hall_sprite_draw: - invoke DrawCityObject3D, OFFSET hallSpriteTemp3D, 0 -hall_sprite_next: - inc esi - cmp esi, NUM_SPRITES - jb hall_sprite_loop -hall_sprites_done: - ret -RenderSprites ENDP - -InitHall3D PROC uses esi edi - lea esi, hallLayout3D - lea edi, casinoMap - mov ecx, 256 - rep movsd - mov hallLevel3D, 0 - mov worldMap3D, OFFSET casinoMap - mov viewEye3D, FP_1*17/20 - mov viewCeiling3D, FP_1*5/2 - mov floorTexture3D, 100 - mov casinoSprites[14*SIZEOF SpriteObject].interactId, 0 - mov patronClock3D, 0 - ret -InitHall3D ENDP - -LoadHallAssets3D PROC - invoke LoadAnimPack3D, OFFSET hallCardFurniture3D, OFFSET hallCardFurniturePath3D - invoke LoadAnimPack3D, OFFSET hallWheelFurniture3D, OFFSET hallWheelFurniturePath3D - invoke LoadAnimPack3D, OFFSET hallBackFurniture3D, OFFSET hallBackFurniturePath3D - invoke LoadAnimPack3D, OFFSET hallSkillFurniture3D, OFFSET hallSkillFurniturePath3D - invoke LoadAnimPack3D, OFFSET hallChairFurniture3D, OFFSET hallChairFurniturePath3D - invoke LoadAnimPack3D, OFFSET hallLampFurniture3D, OFFSET hallLampFurniturePath3D - invoke LoadAnimPack3D, OFFSET hallRopeFurniture3D, OFFSET hallRopeFurniturePath3D - invoke LoadAnimPack3D, OFFSET hallSlotFurniture3D, OFFSET hallSlotFurniturePath3D - invoke LoadAnimPack3D, OFFSET hallBartender3D, OFFSET hallBartenderPath3D - invoke LoadAnimPack3D, OFFSET hallProps3D, OFFSET hallPropsPath3D - invoke LoadAnimPack3D, OFFSET hallDrink3D, OFFSET hallDrinkPath3D - invoke LoadAnimPack3D, OFFSET hallCityDetail3D, OFFSET hallCityDetailPath3D - invoke LoadAnimPack3D, OFFSET hallRoomMaterials3D, OFFSET hallRoomMaterialsPath3D - invoke LoadAnimPack3D, OFFSET hallPatrons3D, OFFSET hallPatronsPath3D - invoke LoadAnimPack3D, OFFSET hallStreetLife3D, OFFSET hallStreetLifePath3D - invoke LoadAnimPack3D, OFFSET hallRoomHD3D, OFFSET hallRoomHDPath3D - invoke LoadAnimPack3D, OFFSET hallArchitecture3D, OFFSET hallArchitecturePath3D - invoke LoadAnimPack3D, OFFSET hallArchitectureHD3D, OFFSET hallArchitectureHDPath3D - invoke LoadAnimPack3D, OFFSET hallDecorPack3D, OFFSET hallDecorPath3D - cmp hallArchitecture3D.pixels, 0 - je @F - push esi - push edi - mov esi, hallArchitecture3D.pixels - mov edi, OFFSET texturesBuffer+(92*128*128*4) - mov ecx, 12*128*128 - rep movsd - pop edi - pop esi -@@: - cmp hallRoomMaterials3D.pixels, 0 - je @F - push esi - push edi - mov esi, hallRoomMaterials3D.pixels - mov edi, OFFSET texturesBuffer+(80*128*128*4) - mov ecx, 12*128*128 - rep movsd - pop edi - pop esi -@@: - invoke LoadAnimPack3D, OFFSET materialsPack3D, OFFSET materialsPath3D - cmp materialsPack3D.pixels, 0 - je hall_load_sign - push ebx - push esi - push edi - xor ebx, ebx -hall_copy_material: - mov esi, materialsPack3D.pixels - mov eax, ebx - shl eax, 16 - add esi, eax - mov eax, hallMaterialSlots3D[ebx*4] - shl eax, 16 - lea edi, texturesBuffer[eax] - mov ecx, 128*128 - rep movsd - inc ebx - cmp ebx, 4 - jb hall_copy_material - pop edi - pop esi - pop ebx -hall_load_sign: - ret -LoadHallAssets3D ENDP - -FreeHallAssets3D PROC - call FreeNativeWheelArt3D - call FreeNativeCoinArt3D - invoke FreeAnimPack3D, OFFSET hallCardFurniture3D - invoke FreeAnimPack3D, OFFSET hallWheelFurniture3D - invoke FreeAnimPack3D, OFFSET hallBackFurniture3D - invoke FreeAnimPack3D, OFFSET hallSkillFurniture3D - invoke FreeAnimPack3D, OFFSET hallChairFurniture3D - invoke FreeAnimPack3D, OFFSET hallLampFurniture3D - invoke FreeAnimPack3D, OFFSET hallRopeFurniture3D - invoke FreeAnimPack3D, OFFSET hallSlotFurniture3D - invoke FreeAnimPack3D, OFFSET hallBartender3D - invoke FreeAnimPack3D, OFFSET hallProps3D - invoke FreeAnimPack3D, OFFSET hallDrink3D - invoke FreeAnimPack3D, OFFSET hallCityDetail3D - invoke FreeAnimPack3D, OFFSET hallRoomMaterials3D - invoke FreeAnimPack3D, OFFSET hallPatrons3D - invoke FreeAnimPack3D, OFFSET hallStreetLife3D - invoke FreeAnimPack3D, OFFSET hallRoomHD3D - invoke FreeAnimPack3D, OFFSET hallArchitecture3D - invoke FreeAnimPack3D, OFFSET hallArchitectureHD3D - invoke FreeAnimPack3D, OFFSET hallDecorPack3D - ret -FreeHallAssets3D ENDP - -; EAX=pixels, ECX=width, EDX=height; legacy materials keep their 128px fallback. -ResolveWorldSurface3D PROC uses esi material:DWORD - mov eax, material - cmp eax,110 +; Room planes use independent ceiling/floor distances; the eye is not the room midpoint. +RenderCeilingAndFloor PROC uses ebx esi edi + local row:DWORD,distance:DWORD,sx:DWORD,sy:DWORD,wx:DWORD,wy:DWORD + local material:DWORD,shade:DWORD + mov row, 0 +hall_plane_row: + mov eax, row + cmp eax, viewHorizon3D + jge hall_plane_floor + cmp outdoorRender3D, 0 + jne hall_plane_next_row + mov ecx, viewHorizon3D + sub ecx, eax + mov eax, viewCeiling3D + sub eax, viewEye3D + mov material, 101 + cmp hallLevel3D, 0 + je @F + mov material, 93 +@@: + jmp hall_plane_distance +hall_plane_floor: + sub eax, viewHorizon3D + inc eax + mov ecx, eax + mov eax, viewEye3D + mov ebx, floorTexture3D + mov material, ebx +hall_plane_distance: + imul eax, SCREEN_H + cdq + idiv ecx + mov distance, eax + shr eax, 14 + neg eax + add eax, 256 + cmp eax, 55 + jge @F + mov eax, 55 +@@: + mov shade, eax + cmp hallLevel3D, 0 + je @F + mov eax, shade + imul eax, 7 + shr eax, 3 + mov shade, eax +@@: + mov eax, playerPlaneX + shl eax, 1 + imul distance + shrd eax, edx, 16 + cdq + mov ecx, SCREEN_W + idiv ecx + mov sx, eax + mov eax, playerPlaneY + shl eax, 1 + imul distance + shrd eax, edx, 16 + cdq + idiv ecx + mov sy, eax + mov eax, playerDirX + sub eax, playerPlaneX + imul distance + shrd eax, edx, 16 + add eax, playerX + mov wx, eax + mov eax, playerDirY + sub eax, playerPlaneY + imul distance + shrd eax, edx, 16 + add eax, playerY + mov wy, eax + mov eax, row + imul eax, SCREEN_W*4 + lea edi, screenBuffer[eax] + mov esi, SCREEN_W +hall_plane_pixel: + mov ebx, material + cmp outdoorRender3D, 0 + je hall_plane_sample + mov eax, wy + cmp eax, 13*FP_1 + jb hall_plane_crossroad + cmp eax, 16*FP_1 + jb hall_plane_sample +hall_plane_crossroad: + mov eax, wx + cmp eax, 29*FP_1 + jl hall_plane_sidewalk + cmp eax, 32*FP_1 + jl hall_plane_sample +hall_plane_sidewalk: + mov ebx, 72 +hall_plane_sample: + cmp outdoorRender3D, 0 + jne hall_plane_low_sample + mov eax, row + cmp eax, viewHorizon3D + jl hall_plane_choose_hd + cmp hallLevel3D, 0 + jne hall_plane_choose_hd + cmp wy, 23*FP_1 + jl hall_plane_choose_hd + cmp wx, 12*FP_1 + jl hall_plane_wood + cmp wx, 23*FP_1 + jl hall_plane_choose_hd +hall_plane_wood: + mov ebx, 85 +hall_plane_choose_hd: + cmp distance, 6*FP_1 + ja hall_plane_low_sample + mov ecx, hallRoomHD3D.pixels + cmp ebx, 80 + jb hall_plane_low_sample + cmp ebx, 103 + ja hall_plane_low_sample + cmp ebx, 92 + jb hall_plane_old_hd + mov ecx, hallArchitectureHD3D.pixels + sub ebx, 12 +hall_plane_old_hd: + test ecx, ecx + jz hall_plane_hd_fallback + sub ebx, 80 + shl ebx, 18 + add ecx, ebx + mov eax, wy + shr eax, 8 + and eax, 255 + shl eax, 8 + mov edx, wx + shr edx, 8 + and edx, 255 + add eax, edx + mov eax, [ecx+eax*4] + jmp hall_plane_shade +hall_plane_hd_fallback: + mov ebx, material +hall_plane_low_sample: + shl ebx, 16 + mov eax, wy + shr eax, 9 + and eax, 127 + shl eax, 7 + mov edx, wx + shr edx, 9 + and edx, 127 + add eax, edx + lea ebx, texturesBuffer[ebx] + mov eax, [ebx+eax*4] +hall_plane_shade: + cmp outdoorRender3D, 0 + je hall_plane_ambient + invoke ShadeCityGround3D, eax, wx, wy, shade + jmp hall_plane_store +hall_plane_ambient: + mov ebx, eax + and eax, 0000FF00h + imul eax, shade + shr eax, 8 + and eax, 0000FF00h + mov ecx, ebx + and ecx, 0FFh + imul ecx, shade + shr ecx, 8 + or eax, ecx + shr ebx, 16 + and ebx, 0FFh + imul ebx, shade + shr ebx, 8 + shl ebx, 16 + or eax, ebx +hall_plane_store: + stosd + mov eax, sx + add wx, eax + mov eax, sy + add wy, eax + dec esi + jnz hall_plane_pixel +hall_plane_next_row: + inc row + cmp row, SCREEN_H + jb hall_plane_row + ret +RenderCeilingAndFloor ENDP + +RenderSprites PROC uses ebx esi edi + cmp hallLevel3D, 0 + jne hall_sprites_done + xor esi, esi +hall_sprite_loop: + cmp esi, 14 + je hall_sprite_next + imul ebx, esi, SIZEOF SpriteObject + mov eax, casinoSprites[ebx].posX + mov hallSpriteTemp3D.posX, eax + mov eax, casinoSprites[ebx].posY + mov hallSpriteTemp3D.posY, eax + mov eax, hallSpriteWidths3D[esi*4] + mov hallSpriteTemp3D.worldW, eax + mov eax, hallSpriteHeights3D[esi*4] + mov hallSpriteTemp3D.worldH, eax + mov hallSpriteTemp3D.groundZ, 0 + cmp esi, 3 + jae @F + mov hallSpriteTemp3D.groundZ, FP_1/8 +@@: + mov ecx, casinoSprites[ebx].animSpeed + imul ecx, 40 + test ecx, ecx + jnz @F + mov ecx, 40 +@@: + mov eax, animationClock3D + cmp esi,3 + jae @F + mov edx,casinoSprites[ebx].curFrame + imul edx,ecx + add eax,edx +@@: + xor edx, edx + div ecx + mov ecx, casinoSprites[ebx].frameCount + test ecx, ecx + jnz @F + mov ecx, 1 +@@: + xor edx, edx + div ecx + add edx, casinoSprites[ebx].baseTexId + shl edx, 16 + add edx, OFFSET texturesBuffer + mov hallLegacyPack3D.pixels, edx + mov hallSpriteTemp3D.frame, 0 + mov hallSpriteTemp3D.asset, OFFSET hallLegacyPack3D + mov eax, hallStationPacks3D[esi*4] + test eax, eax + jz hall_sprite_draw + ; Missing dedicated art hides the station, never shows a contaminated atlas cell. + cmp [eax].AnimPack3D.pixels, 0 + je hall_sprite_next + mov hallSpriteTemp3D.asset, eax + cmp eax, OFFSET hallSlotFurniture3D + jne hall_sprite_draw + mov eax, animationClock3D + xor edx, edx + mov ecx, 320 + div ecx + add eax, esi + xor edx, edx + mov ecx, 3 + div ecx + mov hallSpriteTemp3D.frame, edx +hall_sprite_draw: + invoke DrawCityObject3D, OFFSET hallSpriteTemp3D, 0 +hall_sprite_next: + inc esi + cmp esi, NUM_SPRITES + jb hall_sprite_loop +hall_sprites_done: + ret +RenderSprites ENDP + +InitHall3D PROC uses esi edi + lea esi, hallLayout3D + lea edi, casinoMap + mov ecx, 256 + rep movsd + mov hallLevel3D, 0 + mov worldMap3D, OFFSET casinoMap + mov viewEye3D, FP_1*17/20 + mov viewCeiling3D, FP_1*5/2 + mov floorTexture3D, 100 + mov casinoSprites[14*SIZEOF SpriteObject].interactId, 0 + mov patronClock3D, 0 + call InitCasinoNpcMind + call InitNpcLife3D + ret +InitHall3D ENDP + +LoadHallAssets3D PROC + invoke LoadAnimPack3D, OFFSET hallCardFurniture3D, OFFSET hallCardFurniturePath3D + invoke LoadAnimPack3D, OFFSET hallWheelFurniture3D, OFFSET hallWheelFurniturePath3D + invoke LoadAnimPack3D, OFFSET hallBackFurniture3D, OFFSET hallBackFurniturePath3D + invoke LoadAnimPack3D, OFFSET hallSkillFurniture3D, OFFSET hallSkillFurniturePath3D + invoke LoadAnimPack3D, OFFSET hallChairFurniture3D, OFFSET hallChairFurniturePath3D + invoke LoadAnimPack3D, OFFSET hallLampFurniture3D, OFFSET hallLampFurniturePath3D + invoke LoadAnimPack3D, OFFSET hallRopeFurniture3D, OFFSET hallRopeFurniturePath3D + invoke LoadAnimPack3D, OFFSET hallSlotFurniture3D, OFFSET hallSlotFurniturePath3D + invoke LoadAnimPack3D, OFFSET hallBartender3D, OFFSET hallBartenderPath3D + invoke LoadAnimPack3D, OFFSET hallProps3D, OFFSET hallPropsPath3D + invoke LoadAnimPack3D, OFFSET hallDrink3D, OFFSET hallDrinkPath3D + invoke LoadAnimPack3D, OFFSET hallCityDetail3D, OFFSET hallCityDetailPath3D + invoke LoadAnimPack3D, OFFSET hallRoomMaterials3D, OFFSET hallRoomMaterialsPath3D + invoke LoadAnimPack3D, OFFSET hallPatrons3D, OFFSET hallPatronsPath3D + invoke LoadAnimPack3D, OFFSET hallStreetLife3D, OFFSET hallStreetLifePath3D + invoke LoadAnimPack3D, OFFSET hallRoomHD3D, OFFSET hallRoomHDPath3D + invoke LoadAnimPack3D, OFFSET hallArchitecture3D, OFFSET hallArchitecturePath3D + invoke LoadAnimPack3D, OFFSET hallArchitectureHD3D, OFFSET hallArchitectureHDPath3D + invoke LoadAnimPack3D, OFFSET hallDecorPack3D, OFFSET hallDecorPath3D + cmp hallArchitecture3D.pixels, 0 + je @F + push esi + push edi + mov esi, hallArchitecture3D.pixels + mov edi, OFFSET texturesBuffer+(92*128*128*4) + mov ecx, 12*128*128 + rep movsd + pop edi + pop esi +@@: + cmp hallRoomMaterials3D.pixels, 0 + je @F + push esi + push edi + mov esi, hallRoomMaterials3D.pixels + mov edi, OFFSET texturesBuffer+(80*128*128*4) + mov ecx, 12*128*128 + rep movsd + pop edi + pop esi +@@: + invoke LoadAnimPack3D, OFFSET materialsPack3D, OFFSET materialsPath3D + cmp materialsPack3D.pixels, 0 + je hall_load_sign + push ebx + push esi + push edi + xor ebx, ebx +hall_copy_material: + mov esi, materialsPack3D.pixels + mov eax, ebx + shl eax, 16 + add esi, eax + mov eax, hallMaterialSlots3D[ebx*4] + shl eax, 16 + lea edi, texturesBuffer[eax] + mov ecx, 128*128 + rep movsd + inc ebx + cmp ebx, 4 + jb hall_copy_material + pop edi + pop esi + pop ebx +hall_load_sign: + ret +LoadHallAssets3D ENDP + +FreeHallAssets3D PROC + call FreeNativeWheelArt3D + call FreeNativeCoinArt3D + invoke FreeAnimPack3D, OFFSET hallCardFurniture3D + invoke FreeAnimPack3D, OFFSET hallWheelFurniture3D + invoke FreeAnimPack3D, OFFSET hallBackFurniture3D + invoke FreeAnimPack3D, OFFSET hallSkillFurniture3D + invoke FreeAnimPack3D, OFFSET hallChairFurniture3D + invoke FreeAnimPack3D, OFFSET hallLampFurniture3D + invoke FreeAnimPack3D, OFFSET hallRopeFurniture3D + invoke FreeAnimPack3D, OFFSET hallSlotFurniture3D + invoke FreeAnimPack3D, OFFSET hallBartender3D + invoke FreeAnimPack3D, OFFSET hallProps3D + invoke FreeAnimPack3D, OFFSET hallDrink3D + invoke FreeAnimPack3D, OFFSET hallCityDetail3D + invoke FreeAnimPack3D, OFFSET hallRoomMaterials3D + invoke FreeAnimPack3D, OFFSET hallPatrons3D + invoke FreeAnimPack3D, OFFSET hallStreetLife3D + invoke FreeAnimPack3D, OFFSET hallRoomHD3D + invoke FreeAnimPack3D, OFFSET hallArchitecture3D + invoke FreeAnimPack3D, OFFSET hallArchitectureHD3D + invoke FreeAnimPack3D, OFFSET hallDecorPack3D + ret +FreeHallAssets3D ENDP + +; EAX=pixels, ECX=width, EDX=height; legacy materials keep their 128px fallback. +ResolveWorldSurface3D PROC uses esi material:DWORD + mov eax, material + cmp eax,110 + jne @F + mov eax,OFFSET cityBenchMetal3D + mov ecx,32 + mov edx,32 + ret +@@: + cmp eax, 104 + jae surface_decor + cmp eax, 92 + jae surface_architecture + cmp eax, 80 + jae surface_room + cmp eax, 57 + jb surface_legacy + cmp eax, 72 + ja surface_legacy + mov esi, OFFSET hallCityDetail3D + sub eax, 57 + jmp surface_pack +surface_room: + mov esi, OFFSET hallRoomHD3D + sub eax, 80 + jmp surface_pack +surface_architecture: + mov esi, OFFSET hallArchitectureHD3D + sub eax, 92 + jmp surface_pack +surface_decor: + cmp eax, 109 + ja surface_missing + mov esi, OFFSET hallDecorPack3D + sub eax, 104 +surface_pack: + cmp [esi].AnimPack3D.pixels, 0 + je surface_legacy + cmp eax, [esi].AnimPack3D.frames + jae surface_missing + mov ecx, [esi].AnimPack3D.imageWidth + mov edx, [esi].AnimPack3D.height + imul eax, ecx + imul eax, edx + shl eax, 2 + add eax, [esi].AnimPack3D.pixels + ret +surface_legacy: + mov eax, material + cmp eax, 104 + jae surface_missing + shl eax, 16 + add eax, OFFSET texturesBuffer + mov ecx, 128 + mov edx, 128 + ret +surface_missing: + xor eax, eax + mov ecx, 128 + mov edx, 128 + ret +ResolveWorldSurface3D ENDP + +RenderHall3D PROC uses ebx esi + cmp hallLevel3D, 0 + jne hall_render_bunker + ; Fixed bar counter/stage are world geometry, with height and occlusion. + invoke DrawCityBoxSides3D, 3*FP_1,9*FP_1,23*FP_1,24*FP_1,0,FP_1*13/20,86 + invoke DrawCityHorizontal3D, 3*FP_1,9*FP_1,23*FP_1,24*FP_1,FP_1*13/20,85 + ; Three physical panels preserve detail instead of stretching one over the whole bar. + invoke DrawCityVertical3D,1,24*FP_1,3*FP_1,5*FP_1,0,FP_1*13/20,84 + invoke DrawCityVertical3D,1,24*FP_1,5*FP_1,7*FP_1,0,FP_1*13/20,84 + invoke DrawCityVertical3D,1,24*FP_1,7*FP_1,9*FP_1,0,FP_1*13/20,84 + invoke DrawCityBoxSides3D,3*FP_1,9*FP_1,21*FP_1,22*FP_1,0,FP_1*19/10,86 + invoke DrawCityVertical3D,1,22*FP_1,3*FP_1,5*FP_1,FP_1*3/5,FP_1*19/10,87 + invoke DrawCityVertical3D,1,22*FP_1,5*FP_1,7*FP_1,FP_1*3/5,FP_1*19/10,87 + invoke DrawCityVertical3D,1,22*FP_1,7*FP_1,9*FP_1,FP_1*3/5,FP_1*19/10,87 + invoke DrawCityBoxSides3D, 10*FP_1,22*FP_1,2*FP_1,5*FP_1,0,FP_1/8,2 + invoke DrawCityHorizontal3D, 10*FP_1,22*FP_1,2*FP_1,5*FP_1,FP_1/8,2 + ; Cabaret has a solid stage, side wings, stairs and lighting truss. + invoke DrawCityVertical3D,0,10*FP_1,2*FP_1,5*FP_1,FP_1/8,FP_1*23/10,2 + invoke DrawCityVertical3D,0,22*FP_1,2*FP_1,5*FP_1,FP_1/8,FP_1*23/10,2 + invoke DrawCityVertical3D,1,2*FP_1,10*FP_1,22*FP_1,FP_1/8,FP_1*23/10,2 + invoke DrawCityHorizontal3D,14*FP_1,18*FP_1,5*FP_1,FP_1*11/2,FP_1/12,85 + invoke DrawCityHorizontal3D,14*FP_1,18*FP_1,FP_1*11/2,6*FP_1,FP_1/24,85 + invoke DrawCityBoxSides3D,10*FP_1,22*FP_1,5*FP_1,FP_1*51/10,FP_1*11/5,FP_1*23/10,86 + ; Low room boundaries frame dining and billiards without closing their entrances. + invoke DrawCityBoxSides3D,FP_1*119/10,FP_1*121/10,24*FP_1,FP_1*51/2,0,FP_1*13/20,102 + invoke DrawCityHorizontal3D,FP_1*119/10,FP_1*121/10,24*FP_1,FP_1*51/2,FP_1*13/20,85 + invoke DrawCityBoxSides3D,FP_1*119/10,FP_1*121/10,FP_1*55/2,30*FP_1,0,FP_1*13/20,102 + invoke DrawCityBoxSides3D,23*FP_1,FP_1*116/5,23*FP_1,24*FP_1,0,FP_1*13/20,102 + invoke DrawCityBoxSides3D,23*FP_1,FP_1*116/5,26*FP_1,29*FP_1,0,FP_1*13/20,102 + invoke DrawCityVertical3D,1,6*FP_1,14*FP_1,18*FP_1,FP_1*17/10,FP_1*12/5,109 + invoke DrawCityBoxSides3D,1*FP_1,9*FP_1,FP_1,FP_1*6/5,FP_1*11/5,FP_1*5/2,103 + invoke DrawCityBoxSides3D,23*FP_1,31*FP_1,FP_1,FP_1*6/5,FP_1*11/5,FP_1*5/2,103 + mov eax, animationClock3D + xor edx, edx + mov ecx, 220 + div ecx + and eax, 1 + cmp engineMode, MODE_BAR + jne hall_bartender_pose + cmp barPhase3D, 1 + jne hall_bartender_pose + mov eax, barTime3D + xor edx, edx + mov ecx, 375 + div ecx + cmp eax, 7 + jbe hall_bartender_pose + mov eax, 7 + jmp hall_bartender_selected +hall_bartender_pose: + cmp engineMode, MODE_BAR + jne hall_bartender_store + cmp barPhase3D, 1 + je hall_bartender_selected + cmp barPhase3D, 2 + jne hall_bartender_store + mov eax,7 +hall_bartender_selected: + mov ecx, barSelection3D + shl ecx, 3 + add eax, ecx +hall_bartender_store: + mov hallObjects3D[4*SIZEOF CityProp3D].frame, eax + xor esi, esi +hall_render_props: + ; The former whole-stage billboard is replaced with world surfaces above. + cmp esi, 15 + je hall_render_next_prop + imul eax, esi, SIZEOF CityProp3D + add eax, OFFSET hallObjects3D + invoke DrawCityObject3D, eax, 0 +hall_render_next_prop: + inc esi + cmp esi, HALL_PROP_COUNT + jb hall_render_props + xor esi, esi +hall_render_lights: + imul eax, esi, SIZEOF CityProp3D + add eax, OFFSET hallLights3D + invoke DrawCityObject3D,eax,0 + inc esi + cmp esi, HALL_LIGHT_COUNT + jb hall_render_lights + xor esi, esi +hall_render_lounge: + imul eax, esi, SIZEOF CityProp3D + add eax, OFFSET hallLoungeDecor3D + invoke DrawCityObject3D,eax,0 + inc esi + cmp esi, HALL_DECOR_COUNT + jb hall_render_lounge + call RenderPatrons3D + ret +hall_render_bunker: + mov esi, 0 +hall_stair_step: + mov eax, esi + imul eax, FP_1/2 + add eax, 24*FP_1 + lea ebx, [eax+FP_1/2] + lea ecx, [esi+1] + imul ecx, FP_1/8 + invoke DrawCityHorizontal3D,15*FP_1,18*FP_1,eax,ebx,ecx,88 + mov eax, esi + imul eax, FP_1/2 + add eax, 24*FP_1 + mov ecx, esi + imul ecx, FP_1/8 + lea edx, [ecx+FP_1/8] + invoke DrawCityVertical3D,1,eax,15*FP_1,18*FP_1,ecx,edx,92 + inc esi + cmp esi, 8 + jb hall_stair_step + invoke DrawCityBoxSides3D, 14*FP_1,20*FP_1,14*FP_1,15*FP_1,0,FP_1/2,96 + invoke DrawCityHorizontal3D, 14*FP_1,20*FP_1,14*FP_1,15*FP_1,FP_1/2,97 + invoke DrawCityVertical3D,1,11*FP_1+FP_1/10,14*FP_1,16*FP_1,FP_1/4,FP_1*8/5,95 + invoke DrawCityVertical3D,1,11*FP_1+FP_1/10,17*FP_1,19*FP_1+FP_HALF,FP_1/4,FP_1*8/5,95 + invoke DrawCityVertical3D,0,19*FP_1+FP_1*9/10,17*FP_1,20*FP_1,0,FP_1*3/2,99 + ; A narrow, stepped vault is real geometry, not a square workshop ceiling. + invoke DrawCityHorizontal3D,14*FP_1,15*FP_1,11*FP_1,24*FP_1,FP_1*9/5,93 + invoke DrawCityVertical3D,0,15*FP_1,11*FP_1,24*FP_1,FP_1*9/5,FP_1*11/5,93 + invoke DrawCityHorizontal3D,15*FP_1,16*FP_1,11*FP_1,24*FP_1,FP_1*11/5,93 + invoke DrawCityVertical3D,0,16*FP_1,11*FP_1,24*FP_1,FP_1*11/5,FP_1*5/2,93 + invoke DrawCityHorizontal3D,18*FP_1,19*FP_1,11*FP_1,24*FP_1,FP_1*11/5,93 + invoke DrawCityVertical3D,0,18*FP_1,11*FP_1,24*FP_1,FP_1*11/5,FP_1*5/2,93 + invoke DrawCityHorizontal3D,19*FP_1,20*FP_1,11*FP_1,24*FP_1,FP_1*9/5,93 + invoke DrawCityVertical3D,0,19*FP_1,11*FP_1,24*FP_1,FP_1*9/5,FP_1*11/5,93 + mov eax, animationClock3D + xor edx, edx + mov ecx, 240 + div ecx + and eax, 7 + mov bunkerMerchant3D.frame, eax + invoke DrawCityObject3D, OFFSET bunkerMerchant3D, 0 + invoke DrawCityObject3D, OFFSET bunkerDisplay3D, 0 + invoke DrawCityObject3D, OFFSET bunkerDesk3D, 0 + invoke DrawCityObject3D, OFFSET bunkerDoor3D, 0 + ret +RenderHall3D ENDP + +; Extra rooms use the same distance and facing checks as the existing tables. +HallTarget3D PROC uses ebx wx:DWORD,wy:DWORD,id:DWORD,prompt:DWORD + mov eax, wx + sub eax, playerX + sar eax, 8 + mov ebx, eax + imul eax, eax + mov ecx, eax + mov eax, wy + sub eax, playerY + sar eax, 8 + mov edx, eax + imul eax, eax + add ecx, eax + cmp ecx, 262144 + jae hall_target_done + mov eax, playerDirX + sar eax, 8 + imul eax, ebx + mov ebx, playerDirY + sar ebx, 8 + imul ebx, edx + add eax, ebx + cmp eax, 18000 + jl hall_target_done + mov eax, id + mov interactTargetId, eax + mov eax, prompt + mov interactPromptPtr, eax +hall_target_done: + ret +HallTarget3D ENDP + +CheckHallInteractions3D PROC + cmp hallLevel3D, 0 + jne hall_check_bunker + cmp playerX, 3*FP_1 + jl hall_check_other + cmp playerX, 9*FP_1 + jg hall_check_other + cmp playerY, 24*FP_1+9830 + jl hall_check_other + ; A point on the serving edge remains in front even when standing close. + invoke HallTarget3D, playerX,23*FP_1+FP_HALF,INTERACT_BAR,OFFSET hallBarPrompt3D +hall_check_other: + invoke HallTarget3D, 28*FP_1+FP_HALF,10*FP_1+FP_HALF,INTERACT_BASEMENT,OFFSET hallBunkerPrompt3D + invoke HallTarget3D, 27*FP_1,25*FP_1,INTERACT_BILLIARDS,OFFSET hallPoolPrompt3D + call CheckNpcInteractions3D + ret +hall_check_bunker: + mov interactTargetId, 0 + mov interactPromptPtr, 0 + invoke HallTarget3D, 16*FP_1,14*FP_1+FP_HALF,INTERACT_SHOP,OFFSET promptShop + invoke HallTarget3D, 16*FP_1,27*FP_1,INTERACT_UPSTAIRS,OFFSET hallUpPrompt3D + ret +CheckHallInteractions3D ENDP + +TriggerHallInteraction3D PROC + cmp interactTargetId,INTERACT_NPC jne @F - mov eax,OFFSET cityBenchMetal3D - mov ecx,32 - mov edx,32 + call OpenNpcDialog3D ret @@: - cmp eax, 104 - jae surface_decor - cmp eax, 92 - jae surface_architecture - cmp eax, 80 - jae surface_room - cmp eax, 57 - jb surface_legacy - cmp eax, 72 - ja surface_legacy - mov esi, OFFSET hallCityDetail3D - sub eax, 57 - jmp surface_pack -surface_room: - mov esi, OFFSET hallRoomHD3D - sub eax, 80 - jmp surface_pack -surface_architecture: - mov esi, OFFSET hallArchitectureHD3D - sub eax, 92 - jmp surface_pack -surface_decor: - cmp eax, 109 - ja surface_missing - mov esi, OFFSET hallDecorPack3D - sub eax, 104 -surface_pack: - cmp [esi].AnimPack3D.pixels, 0 - je surface_legacy - cmp eax, [esi].AnimPack3D.frames - jae surface_missing - mov ecx, [esi].AnimPack3D.imageWidth - mov edx, [esi].AnimPack3D.height - imul eax, ecx - imul eax, edx - shl eax, 2 - add eax, [esi].AnimPack3D.pixels - ret -surface_legacy: - mov eax, material - cmp eax, 104 - jae surface_missing - shl eax, 16 - add eax, OFFSET texturesBuffer - mov ecx, 128 - mov edx, 128 - ret -surface_missing: - xor eax, eax - mov ecx, 128 - mov edx, 128 - ret -ResolveWorldSurface3D ENDP -RenderHall3D PROC uses ebx esi - cmp hallLevel3D, 0 - jne hall_render_bunker - ; Fixed bar counter/stage are world geometry, with height and occlusion. - invoke DrawCityBoxSides3D, 3*FP_1,9*FP_1,23*FP_1,24*FP_1,0,FP_1*13/20,86 - invoke DrawCityHorizontal3D, 3*FP_1,9*FP_1,23*FP_1,24*FP_1,FP_1*13/20,85 - ; Three physical panels preserve detail instead of stretching one over the whole bar. - invoke DrawCityVertical3D,1,24*FP_1,3*FP_1,5*FP_1,0,FP_1*13/20,84 - invoke DrawCityVertical3D,1,24*FP_1,5*FP_1,7*FP_1,0,FP_1*13/20,84 - invoke DrawCityVertical3D,1,24*FP_1,7*FP_1,9*FP_1,0,FP_1*13/20,84 - invoke DrawCityBoxSides3D,3*FP_1,9*FP_1,21*FP_1,22*FP_1,0,FP_1*19/10,86 - invoke DrawCityVertical3D,1,22*FP_1,3*FP_1,5*FP_1,FP_1*3/5,FP_1*19/10,87 - invoke DrawCityVertical3D,1,22*FP_1,5*FP_1,7*FP_1,FP_1*3/5,FP_1*19/10,87 - invoke DrawCityVertical3D,1,22*FP_1,7*FP_1,9*FP_1,FP_1*3/5,FP_1*19/10,87 - invoke DrawCityBoxSides3D, 10*FP_1,22*FP_1,2*FP_1,5*FP_1,0,FP_1/8,2 - invoke DrawCityHorizontal3D, 10*FP_1,22*FP_1,2*FP_1,5*FP_1,FP_1/8,2 - ; Cabaret has a solid stage, side wings, stairs and lighting truss. - invoke DrawCityVertical3D,0,10*FP_1,2*FP_1,5*FP_1,FP_1/8,FP_1*23/10,2 - invoke DrawCityVertical3D,0,22*FP_1,2*FP_1,5*FP_1,FP_1/8,FP_1*23/10,2 - invoke DrawCityVertical3D,1,2*FP_1,10*FP_1,22*FP_1,FP_1/8,FP_1*23/10,2 - invoke DrawCityHorizontal3D,14*FP_1,18*FP_1,5*FP_1,FP_1*11/2,FP_1/12,85 - invoke DrawCityHorizontal3D,14*FP_1,18*FP_1,FP_1*11/2,6*FP_1,FP_1/24,85 - invoke DrawCityBoxSides3D,10*FP_1,22*FP_1,5*FP_1,FP_1*51/10,FP_1*11/5,FP_1*23/10,86 - ; Low room boundaries frame dining and billiards without closing their entrances. - invoke DrawCityBoxSides3D,FP_1*119/10,FP_1*121/10,24*FP_1,FP_1*51/2,0,FP_1*13/20,102 - invoke DrawCityHorizontal3D,FP_1*119/10,FP_1*121/10,24*FP_1,FP_1*51/2,FP_1*13/20,85 - invoke DrawCityBoxSides3D,FP_1*119/10,FP_1*121/10,FP_1*55/2,30*FP_1,0,FP_1*13/20,102 - invoke DrawCityBoxSides3D,23*FP_1,FP_1*116/5,23*FP_1,24*FP_1,0,FP_1*13/20,102 - invoke DrawCityBoxSides3D,23*FP_1,FP_1*116/5,26*FP_1,29*FP_1,0,FP_1*13/20,102 - invoke DrawCityVertical3D,1,6*FP_1,14*FP_1,18*FP_1,FP_1*17/10,FP_1*12/5,109 - invoke DrawCityBoxSides3D,1*FP_1,9*FP_1,FP_1,FP_1*6/5,FP_1*11/5,FP_1*5/2,103 - invoke DrawCityBoxSides3D,23*FP_1,31*FP_1,FP_1,FP_1*6/5,FP_1*11/5,FP_1*5/2,103 - mov eax, animationClock3D - xor edx, edx - mov ecx, 220 - div ecx - and eax, 1 - cmp engineMode, MODE_BAR - jne hall_bartender_pose - cmp barPhase3D, 1 - jne hall_bartender_pose - mov eax, barTime3D - xor edx, edx - mov ecx, 375 - div ecx - cmp eax, 7 - jbe hall_bartender_pose - mov eax, 7 - jmp hall_bartender_selected -hall_bartender_pose: - cmp engineMode, MODE_BAR - jne hall_bartender_store - cmp barPhase3D, 1 - je hall_bartender_selected - cmp barPhase3D, 2 - jne hall_bartender_store - mov eax,7 -hall_bartender_selected: - mov ecx, barSelection3D - shl ecx, 3 - add eax, ecx -hall_bartender_store: - mov hallObjects3D[4*SIZEOF CityProp3D].frame, eax - xor esi, esi -hall_render_props: - ; The former whole-stage billboard is replaced with world surfaces above. - cmp esi, 15 - je hall_render_next_prop - imul eax, esi, SIZEOF CityProp3D - add eax, OFFSET hallObjects3D - invoke DrawCityObject3D, eax, 0 -hall_render_next_prop: - inc esi - cmp esi, HALL_PROP_COUNT - jb hall_render_props - xor esi, esi -hall_render_lights: - imul eax, esi, SIZEOF CityProp3D - add eax, OFFSET hallLights3D - invoke DrawCityObject3D,eax,0 - inc esi - cmp esi, HALL_LIGHT_COUNT - jb hall_render_lights - xor esi, esi -hall_render_lounge: - imul eax, esi, SIZEOF CityProp3D - add eax, OFFSET hallLoungeDecor3D - invoke DrawCityObject3D,eax,0 - inc esi - cmp esi, HALL_DECOR_COUNT - jb hall_render_lounge - call RenderPatrons3D + cmp interactTargetId, INTERACT_BAR + jne hall_trigger_stairs + call LoadHallAssets3D + mov engineMode, MODE_BAR + mov barPhase3D, 0 + mov barTime3D, 0 + call ClearKeys3D + mov eax, 1 + ret +hall_trigger_stairs: + cmp interactTargetId, INTERACT_BASEMENT + je hall_begin_stairs + cmp interactTargetId, INTERACT_UPSTAIRS + jne hall_trigger_none +hall_begin_stairs: + cmp hallLevel3D, 0 + jne @F + mov eax, playerX + mov stairsReturnX3D, eax + mov eax, playerY + mov stairsReturnY3D, eax + mov eax, playerAngle + mov stairsReturnAngle3D, eax +@@: + mov engineMode, MODE_STAIRS + mov stairsTime3D, 0 + call ClearKeys3D + mov eax, 1 + ret +hall_trigger_none: + cmp interactTargetId, INTERACT_BILLIARDS + jne @F + call InitPool3D + mov engineMode, MODE_POOL + call ClearKeys3D + mov eax, 1 + ret +@@: + xor eax, eax + ret +TriggerHallInteraction3D ENDP + +HandleStairs3D PROC + mov eax, deltaTime3D + add stairsTime3D, eax + cmp stairsTime3D, 1600 + jb stairs_handle_done + xor hallLevel3D, 1 + cmp hallLevel3D, 0 + je stairs_back_to_hall + mov worldMap3D, OFFSET bunkerMap3D + mov floorTexture3D, 94 + mov viewCeiling3D, FP_1*5/2 + mov playerX, 16*FP_1+FP_HALF + mov playerY, 23*FP_1+FP_HALF + mov playerAngle, 384 + jmp stairs_complete +stairs_back_to_hall: + mov worldMap3D, OFFSET casinoMap + mov floorTexture3D, 100 + mov viewCeiling3D, FP_1*5/2 + mov eax, stairsReturnX3D + mov playerX, eax + mov eax, stairsReturnY3D + mov playerY, eax + mov eax, stairsReturnAngle3D + mov playerAngle, eax +stairs_complete: + mov viewEye3D, FP_1*17/20 + mov engineMode, MODE_WALK + call ClearKeys3D +stairs_handle_done: + ret +HandleStairs3D ENDP + +RenderStairs3D PROC uses ebx esi + local oldX:DWORD,oldY:DWORD,oldAngle:DWORD,oldMap:DWORD,oldEye:DWORD,oldCeiling:DWORD,oldLevel:DWORD,oldFloor:DWORD + mov eax, playerX + mov oldX, eax + mov eax, playerY + mov oldY, eax + mov eax, playerAngle + mov oldAngle, eax + mov eax, worldMap3D + mov oldMap, eax + mov eax, viewEye3D + mov oldEye, eax + mov eax, viewCeiling3D + mov oldCeiling, eax + mov eax, hallLevel3D + mov oldLevel, eax + mov eax, floorTexture3D + mov oldFloor, eax + mov hallLevel3D, 1 + mov worldMap3D, OFFSET bunkerMap3D + mov floorTexture3D, 94 + mov viewCeiling3D, FP_1*5/2 + mov playerX, 16*FP_1+FP_HALF + mov playerAngle, 384 + mov eax, stairsTime3D + cmp eax, 1600 + jbe @F + mov eax, 1600 +@@: + cmp oldLevel, 0 + je @F + neg eax + add eax, 1600 +@@: + imul eax, 4*FP_1 + xor edx, edx + mov ecx, 1600 + div ecx + mov ebx, 27*FP_1+FP_HALF + sub ebx, eax + mov playerY, ebx + shr eax, 2 + neg eax + add eax, FP_1*37/20 + mov viewEye3D, eax + call UpdateCamera3D + call RenderCeilingAndFloor + call RenderWalls + call PrepareCityDepth3D + call RenderHall3D + mov eax, oldX + mov playerX, eax + mov eax, oldY + mov playerY, eax + mov eax, oldAngle + mov playerAngle, eax + mov eax, oldMap + mov worldMap3D, eax + mov eax, oldEye + mov viewEye3D, eax + mov eax, oldCeiling + mov viewCeiling3D, eax + mov eax, oldLevel + mov hallLevel3D, eax + mov eax, oldFloor + mov floorTexture3D, eax + call UpdateCamera3D + ret +RenderStairs3D ENDP + +BuyBarDrink3D PROC drink:DWORD + cmp barPhase3D, 0 + jne bar_buy_done + mov ecx, drink + cmp ecx, 2 + ja bar_buy_done + mov eax, barPrice3D[ecx*4] + cmp bankroll, eax + jb bar_buy_poor + sub bankroll, eax + mov barSelection3D, ecx + mov barPhase3D, 1 + mov barTime3D, 0 + call SaveProgress3D + ret +bar_buy_poor: + invoke CopyString3D, OFFSET barPoor3D, OFFSET flashMessage + mov flashTimer, 150 +bar_buy_done: + ret +BuyBarDrink3D ENDP + +HandleBar3D PROC uses ebx + cmp barPhase3D, 0 + jne bar_animate + mov ebx, 31h +bar_select_key: + invoke Pressed3D, ebx + test eax, eax + jz @F + mov eax, ebx + sub eax, 31h + invoke BuyBarDrink3D, eax + ret +@@: + inc ebx + cmp ebx, 33h + jbe bar_select_key + cmp mouseClick3D, 0 + je bar_handle_done + cmp mouseX3D, 170 + jb bar_handle_done + cmp mouseY3D, 98 + jb bar_handle_done + cmp mouseY3D, 155 + jae bar_handle_done + mov eax, mouseY3D + sub eax, 98 + xor edx, edx + mov ecx, 19 + div ecx + invoke BuyBarDrink3D, eax + ret +bar_animate: + mov eax, deltaTime3D + add barTime3D, eax + cmp barPhase3D, 1 + jne bar_after_drink + cmp barTime3D, 3000 + jb bar_handle_done + mov barPhase3D, 2 + mov barTime3D, 0 + ret +bar_after_drink: + cmp barTime3D, 2400 + jb bar_handle_done + mov ecx, barSelection3D + mov eax, barStrength3D[ecx*4] + test eax, eax + jnz @F + mov barIntoxication3D, 0 +@@: + add barIntoxication3D, eax + cmp barIntoxication3D, 60000 + jbe @F + mov barIntoxication3D, 60000 +@@: + mov barPhase3D, 0 + mov barTime3D, 0 +bar_handle_done: + ret +HandleBar3D ENDP + +RenderBar3D PROC uses ebx + local oldX:DWORD,oldY:DWORD,oldAngle:DWORD,oldHorizon:DWORD,oldEye:DWORD,oldMode:DWORD + mov eax, playerX + mov oldX, eax + mov eax, playerY + mov oldY, eax + mov eax, playerAngle + mov oldAngle, eax + mov eax, viewHorizon3D + mov oldHorizon, eax + mov eax, viewEye3D + mov oldEye, eax + mov eax, engineMode + mov oldMode, eax + mov engineMode, MODE_BAR + mov playerX, 6*FP_1 + mov playerY, 25*FP_1+FP_1/3 + mov playerAngle, 384 + mov viewHorizon3D, HALF_H + mov viewEye3D, FP_1*17/20 + call UpdateCamera3D + call RenderCeilingAndFloor + call RenderWalls + call PrepareCityDepth3D + call RenderHall3D + cmp barPhase3D, 0 + jne bar_active_scene + invoke DrawBoxBorder, 170,83,146,86,0017201Bh,00836D42h,1 + invoke DrawString8x8, 174,99,OFFSET barDrinks3D,00E4D9BDh + invoke DrawString8x8, 174,118,OFFSET barDrinks23D,00E4D9BDh + invoke DrawString8x8, 174,137,OFFSET barDrinks33D,00BCD7D0h + jmp bar_draw_title +bar_active_scene: + mov ebx, OFFSET barMixText3D + cmp barPhase3D, 2 + jne @F + mov ebx, OFFSET barDrinkText3D +@@: + invoke DrawBox,170,83,146,24,0017201Bh + invoke DrawString8x8,176,91,ebx,00E7CA88h +bar_draw_title: + invoke DrawBox,0,0,320,28,0014191Dh + invoke DrawString8x8, 18,15,OFFSET barName3D,00E7CA88h + cmp barPhase3D, 2 + jne bar_render_done + mov eax, barTime3D + xor edx, edx + mov ecx, 343 + div ecx + cmp eax, 6 + jbe @F + mov eax, 6 +@@: + mov ecx, barSelection3D + imul ecx, 7 + add eax, ecx + invoke DrawAnimSprite3D, OFFSET hallDrink3D,eax,272,170,360,360 +bar_render_done: + invoke DrawNumber,240,15,bankroll,00E5D6B0h + mov eax, oldX + mov playerX, eax + mov eax, oldY + mov playerY, eax + mov eax, oldAngle + mov playerAngle, eax + mov eax, oldHorizon + mov viewHorizon3D, eax + mov eax, oldEye + mov viewEye3D, eax + mov eax, oldMode + mov engineMode, eax + call UpdateCamera3D + ret +RenderBar3D ENDP + +RenderCityGuards3D PROC uses ebx + mov eax, cityClock3D + xor edx, edx + mov ecx, 180 + div ecx + and eax, 7 + mov cityGuardLeft3D.frame, eax + cmp arrivalState3D, ARRIVAL_WALK + je city_world_guard_right + mov cityGuardLeft3D.frame, 15 + cmp arrivalState3D, ARRIVAL_STOP + jne city_world_guard_invite + mov eax, arrivalTime3D + xor edx, edx + mov ecx, 90 + div ecx + cmp eax, 7 + jbe @F + mov eax, 7 +@@: + add eax, 8 + mov cityGuardLeft3D.frame, eax + jmp city_world_guard_right +city_world_guard_invite: + cmp arrivalState3D, ARRIVAL_ADMIT + jb city_world_guard_right + mov eax, arrivalTime3D + xor edx, edx + mov ecx, 120 + div ecx + add eax, 16 + cmp eax, 22 + jbe @F + mov eax, 22 +@@: + mov cityGuardLeft3D.frame, eax +city_world_guard_right: + mov eax, cityClock3D + add eax, 590 + xor edx, edx + mov ecx, 220 + div ecx + and eax, 7 + cmp arrivalState3D, ARRIVAL_PROFILE + jne @F + add eax, 24 +@@: + mov cityGuardRight3D.frame, eax + invoke DrawCityObject3D, OFFSET cityGuardLeft3D,0 + invoke DrawCityObject3D, OFFSET cityGuardRight3D,0 + ret +RenderCityGuards3D ENDP + +CanWalkHall3D PROC uses esi ebx px:DWORD,py:DWORD + cmp hallLevel3D, 0 + jne hall_collision_bunker + xor esi, esi +hall_collision_decor: + imul ebx, esi, SIZEOF CityProp3D + mov eax, px + sub eax, hallLoungeDecor3D[ebx].posX + test eax, eax + jns @F + neg eax +@@: + mov ecx, hallLoungeDecor3D[ebx].worldW + shr ecx, 1 + add ecx, 9830 + cmp eax, ecx + ja hall_collision_next_decor + mov eax, py + sub eax, hallLoungeDecor3D[ebx].posY + test eax, eax + jns @F + neg eax +@@: + cmp eax, FP_1*2/5 + jbe hall_collision_blocked +hall_collision_next_decor: + inc esi + cmp esi, HALL_DECOR_COUNT + jb hall_collision_decor + ; Stage and wings are solid: the audience stays in the cabaret's front aisle. + cmp px, 10*FP_1-9830 + jl hall_collision_stage_clear + cmp px, 22*FP_1+9830 + jg hall_collision_stage_clear + cmp py, 2*FP_1-9830 + jl hall_collision_stage_clear + cmp py, 5*FP_1+9830 + jle hall_collision_blocked +hall_collision_stage_clear: + cmp px, FP_1*47/4 + jl hall_collision_cabinets + cmp px, FP_1*49/4 + jg hall_collision_pool_divider + cmp py, 24*FP_1-9830 + jl hall_collision_cabinets + cmp py, FP_1*51/2+9830 + jle hall_collision_blocked + cmp py, FP_1*55/2-9830 + jl hall_collision_cabinets + cmp py, 30*FP_1+9830 + jle hall_collision_blocked +hall_collision_pool_divider: + cmp px, 23*FP_1-9830 + jl hall_collision_cabinets + cmp px, FP_1*116/5+9830 + jg hall_collision_cabinets + cmp py, 23*FP_1-9830 + jl hall_collision_cabinets + cmp py, 24*FP_1+9830 + jle hall_collision_blocked + cmp py, 26*FP_1-9830 + jl hall_collision_cabinets + cmp py, 29*FP_1+9830 + jle hall_collision_blocked +hall_collision_cabinets: + ; The work aisle is staff-only; player interaction is from the serving side. + cmp px, 3*FP_1-9830 + jl hall_collision_counter + cmp px, 9*FP_1+9830 + jg hall_collision_counter + cmp py, 21*FP_1-9830 + jl hall_collision_counter + cmp py, 24*FP_1+9830 + jle hall_collision_blocked +hall_collision_counter: + cmp px, 3*FP_1-9830 + jl hall_collision_dining + cmp px, 9*FP_1+9830 + jg hall_collision_pool + cmp py, 23*FP_1-9830 + jl hall_collision_clear + cmp py, 24*FP_1+9830 + jg hall_collision_dining + xor eax, eax + ret +hall_collision_pool: + cmp px, 26*FP_1-9830 + jl hall_collision_dining + cmp px, 28*FP_1+9830 + jg hall_collision_dining + cmp py, 24*FP_1-9830 + jl hall_collision_clear + cmp py, 26*FP_1+9830 + jg hall_collision_dining + xor eax, eax + ret +hall_collision_bunker: + cmp px, 14*FP_1-9830 + jl hall_collision_clear + cmp px, 20*FP_1+9830 + jg hall_collision_clear + cmp py, 14*FP_1-9830 + jl hall_collision_clear + cmp py, 15*FP_1+9830 + jg hall_collision_clear +hall_collision_blocked: + xor eax, eax + ret +hall_collision_clear: + mov eax, 1 + ret +hall_collision_dining: + cmp py, 26*FP_1+FP_1/3 + jl hall_collision_clear + cmp py, 29*FP_1+FP_HALF + jg hall_collision_clear + cmp px, 2*FP_1 + jl hall_collision_clear + cmp px, 5*FP_1 + jle hall_collision_blocked + cmp px, 8*FP_1 + jl hall_collision_clear + cmp px, 11*FP_1 + jle hall_collision_blocked + jmp hall_collision_clear +CanWalkHall3D ENDP + +RenderCityFacade3D PROC uses ebx esi + ; The original entrance artwork carries CASINO itself, mapped once across the doorway. + invoke DrawCityBoxSides3D,21*FP_1,24*FP_1,8*FP_1,8*FP_1+FP_1/5,0,FP_1*9/5,57 + invoke DrawCityVertical3D,1,8*FP_1+FP_1/5,21*FP_1,24*FP_1,0,FP_1*9/5,58 + invoke DrawCityBoxSides3D,FP_1*104/5,FP_1*106/5,8*FP_1,8*FP_1+FP_1*2/5,0,2*FP_1,103 + invoke DrawCityBoxSides3D,FP_1*119/5,FP_1*121/5,8*FP_1,8*FP_1+FP_1*2/5,0,2*FP_1,103 + invoke DrawCityBoxSides3D,FP_1*104/5,FP_1*121/5,8*FP_1,8*FP_1+FP_HALF,FP_1*9/5,2*FP_1,86 + invoke DrawCityHorizontal3D,FP_1*104/5,FP_1*121/5,8*FP_1,8*FP_1+FP_HALF,2*FP_1,85 + invoke DrawCityVertical3D,1,8*FP_1+FP_1*41/100,FP_1*101/5,FP_1*104/5,FP_1,FP_1*8/5,105 + invoke DrawCityVertical3D,1,8*FP_1+FP_1*41/100,FP_1*121/5,FP_1*124/5,FP_1,FP_1*8/5,105 + ; Recessed street windows, projecting bays and ledges are fixed world surfaces. + mov esi, 11 +hall_city_pilaster: + cmp esi, 20 + je hall_city_next_pilaster + cmp esi, 24 + je hall_city_next_pilaster + mov ebx, esi + shl ebx, 16 + lea eax, [ebx+FP_1/5] + invoke DrawCityBoxSides3D, ebx,eax,12*FP_1,12*FP_1+FP_1/6,0,5*FP_1,57 + lea eax, [ebx+FP_1/5] + invoke DrawCityBoxSides3D, ebx,eax,17*FP_1-FP_1/6,17*FP_1,0,5*FP_1,57 + lea eax, [ebx+FP_1/5] + lea edx, [ebx+FP_1*7/5] + invoke DrawCityBoxSides3D,eax,edx,FP_1*237/20,12*FP_1,FP_1/20,FP_1*13/10,57 + lea eax, [ebx+FP_1/5] + lea edx, [ebx+FP_1*7/5] + invoke DrawCityVertical3D,1,12*FP_1+FP_1/25,eax,edx,FP_1/20,FP_1*13/10,62 + lea eax, [ebx+FP_1/5] + lea edx, [ebx+FP_1*7/5] + invoke DrawCityBoxSides3D,eax,edx,12*FP_1,12*FP_1+FP_1/5,2*FP_1,FP_1*18/5,57 + lea eax, [ebx+FP_1/5] + lea edx, [ebx+FP_1*7/5] + invoke DrawCityVertical3D,1,12*FP_1+FP_1/5,eax,edx,2*FP_1,FP_1*18/5,106 + lea eax, [ebx+FP_1/5] + lea edx, [ebx+FP_1*7/5] + invoke DrawCityBoxSides3D,eax,edx,17*FP_1-FP_1/4,17*FP_1,2*FP_1,FP_1*18/5,57 + lea eax, [ebx+FP_1/5] + lea edx, [ebx+FP_1*7/5] + invoke DrawCityVertical3D,1,17*FP_1-FP_1/4,eax,edx,2*FP_1,FP_1*18/5,106 +hall_city_next_pilaster: + add esi, 4 + cmp esi, 29 + jb hall_city_pilaster + ret +RenderCityFacade3D ENDP + +UpdateHall3D PROC + call UpdatePatrons3D + mov viewHorizon3D, HALF_H + mov viewEye3D, FP_1*17/20 + cmp hallLevel3D, 0 + je @F + mov eax, playerY + sub eax, 24*FP_1 + jle @F + shr eax, 2 + cmp eax, FP_1 + jbe hall_step_eye + mov eax, FP_1 +hall_step_eye: + add viewEye3D, eax +@@: + cmp barIntoxication3D, 0 + je hall_update_done + mov eax, deltaTime3D + imul eax, 2 + sub barIntoxication3D, eax + jnc @F + mov barIntoxication3D, 0 +@@: + mov eax, animationClock3D + shr eax, 3 + and eax, 511 + mov eax, tableSin[eax*4] + imul barIntoxication3D + shrd eax, edx, 16 + sar eax, 14 + add viewHorizon3D, eax +hall_update_done: + ret +UpdateHall3D ENDP + +; Absolute route phase avoids accumulated movement drift and keeps walking FPS-independent. +UpdatePatrons3D PROC uses ebx esi edi + call UpdateNpcLife3D ret -hall_render_bunker: - mov esi, 0 -hall_stair_step: - mov eax, esi - imul eax, FP_1/2 - add eax, 24*FP_1 - lea ebx, [eax+FP_1/2] - lea ecx, [esi+1] - imul ecx, FP_1/8 - invoke DrawCityHorizontal3D,15*FP_1,18*FP_1,eax,ebx,ecx,88 - mov eax, esi - imul eax, FP_1/2 - add eax, 24*FP_1 - mov ecx, esi - imul ecx, FP_1/8 - lea edx, [ecx+FP_1/8] - invoke DrawCityVertical3D,1,eax,15*FP_1,18*FP_1,ecx,edx,92 - inc esi - cmp esi, 8 - jb hall_stair_step - invoke DrawCityBoxSides3D, 14*FP_1,20*FP_1,14*FP_1,15*FP_1,0,FP_1/2,96 - invoke DrawCityHorizontal3D, 14*FP_1,20*FP_1,14*FP_1,15*FP_1,FP_1/2,97 - invoke DrawCityVertical3D,1,11*FP_1+FP_1/10,14*FP_1,16*FP_1,FP_1/4,FP_1*8/5,95 - invoke DrawCityVertical3D,1,11*FP_1+FP_1/10,17*FP_1,19*FP_1+FP_HALF,FP_1/4,FP_1*8/5,95 - invoke DrawCityVertical3D,0,19*FP_1+FP_1*9/10,17*FP_1,20*FP_1,0,FP_1*3/2,99 - ; A narrow, stepped vault is real geometry, not a square workshop ceiling. - invoke DrawCityHorizontal3D,14*FP_1,15*FP_1,11*FP_1,24*FP_1,FP_1*9/5,93 - invoke DrawCityVertical3D,0,15*FP_1,11*FP_1,24*FP_1,FP_1*9/5,FP_1*11/5,93 - invoke DrawCityHorizontal3D,15*FP_1,16*FP_1,11*FP_1,24*FP_1,FP_1*11/5,93 - invoke DrawCityVertical3D,0,16*FP_1,11*FP_1,24*FP_1,FP_1*11/5,FP_1*5/2,93 - invoke DrawCityHorizontal3D,18*FP_1,19*FP_1,11*FP_1,24*FP_1,FP_1*11/5,93 - invoke DrawCityVertical3D,0,18*FP_1,11*FP_1,24*FP_1,FP_1*11/5,FP_1*5/2,93 - invoke DrawCityHorizontal3D,19*FP_1,20*FP_1,11*FP_1,24*FP_1,FP_1*9/5,93 - invoke DrawCityVertical3D,0,19*FP_1,11*FP_1,24*FP_1,FP_1*9/5,FP_1*11/5,93 - mov eax, animationClock3D - xor edx, edx - mov ecx, 240 - div ecx - and eax, 7 - mov bunkerMerchant3D.frame, eax - invoke DrawCityObject3D, OFFSET bunkerMerchant3D, 0 - invoke DrawCityObject3D, OFFSET bunkerDisplay3D, 0 - invoke DrawCityObject3D, OFFSET bunkerDesk3D, 0 - invoke DrawCityObject3D, OFFSET bunkerDoor3D, 0 - ret -RenderHall3D ENDP - -; Extra rooms use the same distance and facing checks as the existing tables. -HallTarget3D PROC uses ebx wx:DWORD,wy:DWORD,id:DWORD,prompt:DWORD - mov eax, wx - sub eax, playerX - sar eax, 8 - mov ebx, eax - imul eax, eax - mov ecx, eax - mov eax, wy - sub eax, playerY - sar eax, 8 - mov edx, eax - imul eax, eax - add ecx, eax - cmp ecx, 262144 - jae hall_target_done - mov eax, playerDirX - sar eax, 8 - imul eax, ebx - mov ebx, playerDirY - sar ebx, 8 - imul ebx, edx - add eax, ebx - cmp eax, 18000 - jl hall_target_done - mov eax, id - mov interactTargetId, eax - mov eax, prompt - mov interactPromptPtr, eax -hall_target_done: - ret -HallTarget3D ENDP - -CheckHallInteractions3D PROC - cmp hallLevel3D, 0 - jne hall_check_bunker - cmp playerX, 3*FP_1 - jl hall_check_other - cmp playerX, 9*FP_1 - jg hall_check_other - cmp playerY, 24*FP_1+9830 - jl hall_check_other - ; A point on the serving edge remains in front even when standing close. - invoke HallTarget3D, playerX,23*FP_1+FP_HALF,INTERACT_BAR,OFFSET hallBarPrompt3D -hall_check_other: - invoke HallTarget3D, 28*FP_1+FP_HALF,10*FP_1+FP_HALF,INTERACT_BASEMENT,OFFSET hallBunkerPrompt3D - invoke HallTarget3D, 27*FP_1,25*FP_1,INTERACT_BILLIARDS,OFFSET hallPoolPrompt3D - ret -hall_check_bunker: - mov interactTargetId, 0 - mov interactPromptPtr, 0 - invoke HallTarget3D, 16*FP_1,14*FP_1+FP_HALF,INTERACT_SHOP,OFFSET promptShop - invoke HallTarget3D, 16*FP_1,27*FP_1,INTERACT_UPSTAIRS,OFFSET hallUpPrompt3D - ret -CheckHallInteractions3D ENDP - -TriggerHallInteraction3D PROC - cmp interactTargetId, INTERACT_BAR - jne hall_trigger_stairs - call LoadHallAssets3D - mov engineMode, MODE_BAR - mov barPhase3D, 0 - mov barTime3D, 0 - call ClearKeys3D - mov eax, 1 - ret -hall_trigger_stairs: - cmp interactTargetId, INTERACT_BASEMENT - je hall_begin_stairs - cmp interactTargetId, INTERACT_UPSTAIRS - jne hall_trigger_none -hall_begin_stairs: - cmp hallLevel3D, 0 - jne @F - mov eax, playerX - mov stairsReturnX3D, eax - mov eax, playerY - mov stairsReturnY3D, eax - mov eax, playerAngle - mov stairsReturnAngle3D, eax -@@: - mov engineMode, MODE_STAIRS - mov stairsTime3D, 0 - call ClearKeys3D - mov eax, 1 - ret -hall_trigger_none: - cmp interactTargetId, INTERACT_BILLIARDS - jne @F - call InitPool3D - mov engineMode, MODE_POOL - call ClearKeys3D - mov eax, 1 - ret -@@: - xor eax, eax - ret -TriggerHallInteraction3D ENDP - -HandleStairs3D PROC - mov eax, deltaTime3D - add stairsTime3D, eax - cmp stairsTime3D, 1600 - jb stairs_handle_done - xor hallLevel3D, 1 - cmp hallLevel3D, 0 - je stairs_back_to_hall - mov worldMap3D, OFFSET bunkerMap3D - mov floorTexture3D, 94 - mov viewCeiling3D, FP_1*5/2 - mov playerX, 16*FP_1+FP_HALF - mov playerY, 23*FP_1+FP_HALF - mov playerAngle, 384 - jmp stairs_complete -stairs_back_to_hall: - mov worldMap3D, OFFSET casinoMap - mov floorTexture3D, 100 - mov viewCeiling3D, FP_1*5/2 - mov eax, stairsReturnX3D - mov playerX, eax - mov eax, stairsReturnY3D - mov playerY, eax - mov eax, stairsReturnAngle3D - mov playerAngle, eax -stairs_complete: - mov viewEye3D, FP_1*17/20 - mov engineMode, MODE_WALK - call ClearKeys3D -stairs_handle_done: - ret -HandleStairs3D ENDP - -RenderStairs3D PROC uses ebx esi - local oldX:DWORD,oldY:DWORD,oldAngle:DWORD,oldMap:DWORD,oldEye:DWORD,oldCeiling:DWORD,oldLevel:DWORD,oldFloor:DWORD - mov eax, playerX - mov oldX, eax - mov eax, playerY - mov oldY, eax - mov eax, playerAngle - mov oldAngle, eax - mov eax, worldMap3D - mov oldMap, eax - mov eax, viewEye3D - mov oldEye, eax - mov eax, viewCeiling3D - mov oldCeiling, eax - mov eax, hallLevel3D - mov oldLevel, eax - mov eax, floorTexture3D - mov oldFloor, eax - mov hallLevel3D, 1 - mov worldMap3D, OFFSET bunkerMap3D - mov floorTexture3D, 94 - mov viewCeiling3D, FP_1*5/2 - mov playerX, 16*FP_1+FP_HALF - mov playerAngle, 384 - mov eax, stairsTime3D - cmp eax, 1600 - jbe @F - mov eax, 1600 -@@: - cmp oldLevel, 0 - je @F - neg eax - add eax, 1600 -@@: - imul eax, 4*FP_1 - xor edx, edx - mov ecx, 1600 - div ecx - mov ebx, 27*FP_1+FP_HALF - sub ebx, eax - mov playerY, ebx - shr eax, 2 - neg eax - add eax, FP_1*37/20 - mov viewEye3D, eax - call UpdateCamera3D - call RenderCeilingAndFloor - call RenderWalls - call PrepareCityDepth3D - call RenderHall3D - mov eax, oldX - mov playerX, eax - mov eax, oldY - mov playerY, eax - mov eax, oldAngle - mov playerAngle, eax - mov eax, oldMap - mov worldMap3D, eax - mov eax, oldEye - mov viewEye3D, eax - mov eax, oldCeiling - mov viewCeiling3D, eax - mov eax, oldLevel - mov hallLevel3D, eax - mov eax, oldFloor - mov floorTexture3D, eax - call UpdateCamera3D - ret -RenderStairs3D ENDP - -BuyBarDrink3D PROC drink:DWORD - cmp barPhase3D, 0 - jne bar_buy_done - mov ecx, drink - cmp ecx, 2 - ja bar_buy_done - mov eax, barPrice3D[ecx*4] - cmp bankroll, eax - jb bar_buy_poor - sub bankroll, eax - mov barSelection3D, ecx - mov barPhase3D, 1 - mov barTime3D, 0 - call SaveProgress3D - ret -bar_buy_poor: - invoke CopyString3D, OFFSET barPoor3D, OFFSET flashMessage - mov flashTimer, 150 -bar_buy_done: - ret -BuyBarDrink3D ENDP - -HandleBar3D PROC uses ebx - cmp barPhase3D, 0 - jne bar_animate - mov ebx, 31h -bar_select_key: - invoke Pressed3D, ebx - test eax, eax - jz @F - mov eax, ebx - sub eax, 31h - invoke BuyBarDrink3D, eax - ret -@@: - inc ebx - cmp ebx, 33h - jbe bar_select_key - cmp mouseClick3D, 0 - je bar_handle_done - cmp mouseX3D, 170 - jb bar_handle_done - cmp mouseY3D, 98 - jb bar_handle_done - cmp mouseY3D, 155 - jae bar_handle_done - mov eax, mouseY3D - sub eax, 98 - xor edx, edx - mov ecx, 19 - div ecx - invoke BuyBarDrink3D, eax - ret -bar_animate: - mov eax, deltaTime3D - add barTime3D, eax - cmp barPhase3D, 1 - jne bar_after_drink - cmp barTime3D, 3000 - jb bar_handle_done - mov barPhase3D, 2 - mov barTime3D, 0 - ret -bar_after_drink: - cmp barTime3D, 2400 - jb bar_handle_done - mov ecx, barSelection3D - mov eax, barStrength3D[ecx*4] - test eax, eax - jnz @F - mov barIntoxication3D, 0 -@@: - add barIntoxication3D, eax - cmp barIntoxication3D, 60000 - jbe @F - mov barIntoxication3D, 60000 -@@: - mov barPhase3D, 0 - mov barTime3D, 0 -bar_handle_done: - ret -HandleBar3D ENDP - -RenderBar3D PROC uses ebx - local oldX:DWORD,oldY:DWORD,oldAngle:DWORD,oldHorizon:DWORD,oldEye:DWORD,oldMode:DWORD - mov eax, playerX - mov oldX, eax - mov eax, playerY - mov oldY, eax - mov eax, playerAngle - mov oldAngle, eax - mov eax, viewHorizon3D - mov oldHorizon, eax - mov eax, viewEye3D - mov oldEye, eax - mov eax, engineMode - mov oldMode, eax - mov engineMode, MODE_BAR - mov playerX, 6*FP_1 - mov playerY, 25*FP_1+FP_1/3 - mov playerAngle, 384 - mov viewHorizon3D, HALF_H - mov viewEye3D, FP_1*17/20 - call UpdateCamera3D - call RenderCeilingAndFloor - call RenderWalls - call PrepareCityDepth3D - call RenderHall3D - cmp barPhase3D, 0 - jne bar_active_scene - invoke DrawBoxBorder, 170,83,146,86,0017201Bh,00836D42h,1 - invoke DrawString8x8, 174,99,OFFSET barDrinks3D,00E4D9BDh - invoke DrawString8x8, 174,118,OFFSET barDrinks23D,00E4D9BDh - invoke DrawString8x8, 174,137,OFFSET barDrinks33D,00BCD7D0h - jmp bar_draw_title -bar_active_scene: - mov ebx, OFFSET barMixText3D - cmp barPhase3D, 2 - jne @F - mov ebx, OFFSET barDrinkText3D -@@: - invoke DrawBox,170,83,146,24,0017201Bh - invoke DrawString8x8,176,91,ebx,00E7CA88h -bar_draw_title: - invoke DrawBox,0,0,320,28,0014191Dh - invoke DrawString8x8, 18,15,OFFSET barName3D,00E7CA88h - cmp barPhase3D, 2 - jne bar_render_done - mov eax, barTime3D - xor edx, edx - mov ecx, 343 - div ecx - cmp eax, 6 - jbe @F - mov eax, 6 -@@: - mov ecx, barSelection3D - imul ecx, 7 - add eax, ecx - invoke DrawAnimSprite3D, OFFSET hallDrink3D,eax,272,170,360,360 -bar_render_done: - invoke DrawNumber,240,15,bankroll,00E5D6B0h - mov eax, oldX - mov playerX, eax - mov eax, oldY - mov playerY, eax - mov eax, oldAngle - mov playerAngle, eax - mov eax, oldHorizon - mov viewHorizon3D, eax - mov eax, oldEye - mov viewEye3D, eax - mov eax, oldMode - mov engineMode, eax - call UpdateCamera3D - ret -RenderBar3D ENDP - -RenderCityGuards3D PROC uses ebx - mov eax, cityClock3D - xor edx, edx - mov ecx, 180 - div ecx - and eax, 7 - mov cityGuardLeft3D.frame, eax - cmp arrivalState3D, ARRIVAL_WALK - je city_world_guard_right - mov cityGuardLeft3D.frame, 15 - cmp arrivalState3D, ARRIVAL_STOP - jne city_world_guard_invite - mov eax, arrivalTime3D - xor edx, edx - mov ecx, 90 - div ecx - cmp eax, 7 - jbe @F - mov eax, 7 -@@: - add eax, 8 - mov cityGuardLeft3D.frame, eax - jmp city_world_guard_right -city_world_guard_invite: - cmp arrivalState3D, ARRIVAL_ADMIT - jb city_world_guard_right - mov eax, arrivalTime3D - xor edx, edx - mov ecx, 120 - div ecx - add eax, 16 - cmp eax, 22 - jbe @F - mov eax, 22 -@@: - mov cityGuardLeft3D.frame, eax -city_world_guard_right: - mov eax, cityClock3D - add eax, 590 - xor edx, edx - mov ecx, 220 - div ecx - and eax, 7 - cmp arrivalState3D, ARRIVAL_PROFILE - jne @F - add eax, 24 -@@: - mov cityGuardRight3D.frame, eax - invoke DrawCityObject3D, OFFSET cityGuardLeft3D,0 - invoke DrawCityObject3D, OFFSET cityGuardRight3D,0 - ret -RenderCityGuards3D ENDP - -CanWalkHall3D PROC uses esi ebx px:DWORD,py:DWORD - cmp hallLevel3D, 0 - jne hall_collision_bunker - xor esi, esi -hall_collision_decor: - imul ebx, esi, SIZEOF CityProp3D - mov eax, px - sub eax, hallLoungeDecor3D[ebx].posX - test eax, eax - jns @F - neg eax -@@: - mov ecx, hallLoungeDecor3D[ebx].worldW - shr ecx, 1 - add ecx, 9830 - cmp eax, ecx - ja hall_collision_next_decor - mov eax, py - sub eax, hallLoungeDecor3D[ebx].posY - test eax, eax - jns @F - neg eax -@@: - cmp eax, FP_1*2/5 - jbe hall_collision_blocked -hall_collision_next_decor: - inc esi - cmp esi, HALL_DECOR_COUNT - jb hall_collision_decor - ; Stage and wings are solid: the audience stays in the cabaret's front aisle. - cmp px, 10*FP_1-9830 - jl hall_collision_stage_clear - cmp px, 22*FP_1+9830 - jg hall_collision_stage_clear - cmp py, 2*FP_1-9830 - jl hall_collision_stage_clear - cmp py, 5*FP_1+9830 - jle hall_collision_blocked -hall_collision_stage_clear: - cmp px, FP_1*47/4 - jl hall_collision_cabinets - cmp px, FP_1*49/4 - jg hall_collision_pool_divider - cmp py, 24*FP_1-9830 - jl hall_collision_cabinets - cmp py, FP_1*51/2+9830 - jle hall_collision_blocked - cmp py, FP_1*55/2-9830 - jl hall_collision_cabinets - cmp py, 30*FP_1+9830 - jle hall_collision_blocked -hall_collision_pool_divider: - cmp px, 23*FP_1-9830 - jl hall_collision_cabinets - cmp px, FP_1*116/5+9830 - jg hall_collision_cabinets - cmp py, 23*FP_1-9830 - jl hall_collision_cabinets - cmp py, 24*FP_1+9830 - jle hall_collision_blocked - cmp py, 26*FP_1-9830 - jl hall_collision_cabinets - cmp py, 29*FP_1+9830 - jle hall_collision_blocked -hall_collision_cabinets: - ; The work aisle is staff-only; player interaction is from the serving side. - cmp px, 3*FP_1-9830 - jl hall_collision_counter - cmp px, 9*FP_1+9830 - jg hall_collision_counter - cmp py, 21*FP_1-9830 - jl hall_collision_counter - cmp py, 24*FP_1+9830 - jle hall_collision_blocked -hall_collision_counter: - cmp px, 3*FP_1-9830 - jl hall_collision_dining - cmp px, 9*FP_1+9830 - jg hall_collision_pool - cmp py, 23*FP_1-9830 - jl hall_collision_clear - cmp py, 24*FP_1+9830 - jg hall_collision_dining - xor eax, eax - ret -hall_collision_pool: - cmp px, 26*FP_1-9830 - jl hall_collision_dining - cmp px, 28*FP_1+9830 - jg hall_collision_dining - cmp py, 24*FP_1-9830 - jl hall_collision_clear - cmp py, 26*FP_1+9830 - jg hall_collision_dining - xor eax, eax - ret -hall_collision_bunker: - cmp px, 14*FP_1-9830 - jl hall_collision_clear - cmp px, 20*FP_1+9830 - jg hall_collision_clear - cmp py, 14*FP_1-9830 - jl hall_collision_clear - cmp py, 15*FP_1+9830 - jg hall_collision_clear -hall_collision_blocked: - xor eax, eax - ret -hall_collision_clear: - mov eax, 1 - ret -hall_collision_dining: - cmp py, 26*FP_1+FP_1/3 - jl hall_collision_clear - cmp py, 29*FP_1+FP_HALF - jg hall_collision_clear - cmp px, 2*FP_1 - jl hall_collision_clear - cmp px, 5*FP_1 - jle hall_collision_blocked - cmp px, 8*FP_1 - jl hall_collision_clear - cmp px, 11*FP_1 - jle hall_collision_blocked - jmp hall_collision_clear -CanWalkHall3D ENDP - -RenderCityFacade3D PROC uses ebx esi - ; The original entrance artwork carries CASINO itself, mapped once across the doorway. - invoke DrawCityBoxSides3D,21*FP_1,24*FP_1,8*FP_1,8*FP_1+FP_1/5,0,FP_1*9/5,57 - invoke DrawCityVertical3D,1,8*FP_1+FP_1/5,21*FP_1,24*FP_1,0,FP_1*9/5,58 - invoke DrawCityBoxSides3D,FP_1*104/5,FP_1*106/5,8*FP_1,8*FP_1+FP_1*2/5,0,2*FP_1,103 - invoke DrawCityBoxSides3D,FP_1*119/5,FP_1*121/5,8*FP_1,8*FP_1+FP_1*2/5,0,2*FP_1,103 - invoke DrawCityBoxSides3D,FP_1*104/5,FP_1*121/5,8*FP_1,8*FP_1+FP_HALF,FP_1*9/5,2*FP_1,86 - invoke DrawCityHorizontal3D,FP_1*104/5,FP_1*121/5,8*FP_1,8*FP_1+FP_HALF,2*FP_1,85 - invoke DrawCityVertical3D,1,8*FP_1+FP_1*41/100,FP_1*101/5,FP_1*104/5,FP_1,FP_1*8/5,105 - invoke DrawCityVertical3D,1,8*FP_1+FP_1*41/100,FP_1*121/5,FP_1*124/5,FP_1,FP_1*8/5,105 - ; Recessed street windows, projecting bays and ledges are fixed world surfaces. - mov esi, 11 -hall_city_pilaster: - cmp esi, 20 - je hall_city_next_pilaster - cmp esi, 24 - je hall_city_next_pilaster - mov ebx, esi - shl ebx, 16 - lea eax, [ebx+FP_1/5] - invoke DrawCityBoxSides3D, ebx,eax,12*FP_1,12*FP_1+FP_1/6,0,5*FP_1,57 - lea eax, [ebx+FP_1/5] - invoke DrawCityBoxSides3D, ebx,eax,17*FP_1-FP_1/6,17*FP_1,0,5*FP_1,57 - lea eax, [ebx+FP_1/5] - lea edx, [ebx+FP_1*7/5] - invoke DrawCityBoxSides3D,eax,edx,FP_1*237/20,12*FP_1,FP_1/20,FP_1*13/10,57 - lea eax, [ebx+FP_1/5] - lea edx, [ebx+FP_1*7/5] - invoke DrawCityVertical3D,1,12*FP_1+FP_1/25,eax,edx,FP_1/20,FP_1*13/10,62 - lea eax, [ebx+FP_1/5] - lea edx, [ebx+FP_1*7/5] - invoke DrawCityBoxSides3D,eax,edx,12*FP_1,12*FP_1+FP_1/5,2*FP_1,FP_1*18/5,57 - lea eax, [ebx+FP_1/5] - lea edx, [ebx+FP_1*7/5] - invoke DrawCityVertical3D,1,12*FP_1+FP_1/5,eax,edx,2*FP_1,FP_1*18/5,106 - lea eax, [ebx+FP_1/5] - lea edx, [ebx+FP_1*7/5] - invoke DrawCityBoxSides3D,eax,edx,17*FP_1-FP_1/4,17*FP_1,2*FP_1,FP_1*18/5,57 - lea eax, [ebx+FP_1/5] - lea edx, [ebx+FP_1*7/5] - invoke DrawCityVertical3D,1,17*FP_1-FP_1/4,eax,edx,2*FP_1,FP_1*18/5,106 -hall_city_next_pilaster: - add esi, 4 - cmp esi, 29 - jb hall_city_pilaster - ret -RenderCityFacade3D ENDP - -UpdateHall3D PROC - call UpdatePatrons3D - mov viewHorizon3D, HALF_H - mov viewEye3D, FP_1*17/20 - cmp hallLevel3D, 0 - je @F - mov eax, playerY - sub eax, 24*FP_1 - jle @F - shr eax, 2 - cmp eax, FP_1 - jbe hall_step_eye - mov eax, FP_1 -hall_step_eye: - add viewEye3D, eax -@@: - cmp barIntoxication3D, 0 - je hall_update_done - mov eax, deltaTime3D - imul eax, 2 - sub barIntoxication3D, eax - jnc @F - mov barIntoxication3D, 0 -@@: - mov eax, animationClock3D - shr eax, 3 - and eax, 511 - mov eax, tableSin[eax*4] - imul barIntoxication3D - shrd eax, edx, 16 - sar eax, 14 - add viewHorizon3D, eax -hall_update_done: - ret -UpdateHall3D ENDP - -; Absolute route phase avoids accumulated movement drift and keeps walking FPS-independent. -UpdatePatrons3D PROC uses ebx esi edi - local wx:DWORD,wy:DWORD,phase:DWORD - cmp hallLevel3D, 0 - jne patron_update_done - mov eax, deltaTime3D - add eax, patronClock3D - xor edx, edx - mov ecx, 20000 - div ecx - mov patronClock3D, edx - xor esi, esi -patron_update_loop: - mov eax, esi - imul eax, 10000 - add eax, patronClock3D - xor edx, edx - mov ecx, 20000 - div ecx - mov eax, edx - xor edx, edx - mov ecx, 5000 - div ecx - mov phase, eax - mov eax, edx - imul eax, 4*FP_1 - xor edx, edx - div ecx - mov wx, 18*FP_1 - mov wy, 18*FP_1 - cmp phase, 0 - jne patron_route_south - add wx, eax - jmp patron_route_check -patron_route_south: - cmp phase, 1 - jne patron_route_west - mov wx, 22*FP_1 - shr eax, 1 - add wy, eax - jmp patron_route_check -patron_route_west: - mov wy, 20*FP_1 - cmp phase, 2 - jne patron_route_north - mov wx, 22*FP_1 - sub wx, eax - jmp patron_route_check -patron_route_north: - shr eax, 1 - sub wy, eax -patron_route_check: - invoke CanWalk3D,wx,wy - test eax, eax - jz patron_update_next - imul ebx, esi, SIZEOF CityProp3D - mov eax, wx - mov hallGuests3D[ebx].posX, eax - mov eax, wy - mov hallGuests3D[ebx].posY, eax - mov eax, patronClock3D - xor edx, edx - mov ecx, 220 - div ecx - and eax, 3 - lea eax, [eax+esi*4] - mov hallGuests3D[ebx].frame, eax -patron_update_next: - inc esi - cmp esi, 2 - jb patron_update_loop -patron_update_done: - ret -UpdatePatrons3D ENDP - -RenderPatrons3D PROC uses esi - xor esi, esi -patron_render_loop: - imul eax, esi, SIZEOF CityProp3D - add eax, OFFSET hallGuests3D - invoke DrawCityObject3D,eax,0 - inc esi - cmp esi, HALL_PATRON_COUNT - jb patron_render_loop - ret -RenderPatrons3D ENDP +IF 0 + local wx:DWORD,wy:DWORD,phase:DWORD + cmp hallLevel3D, 0 + jne patron_update_done + mov eax, deltaTime3D + add eax, patronClock3D + xor edx, edx + mov ecx, 20000 + div ecx + mov patronClock3D, edx + xor esi, esi +patron_update_loop: + mov eax, esi + imul eax, 10000 + add eax, patronClock3D + xor edx, edx + mov ecx, 20000 + div ecx + mov eax, edx + xor edx, edx + mov ecx, 5000 + div ecx + mov phase, eax + mov eax, edx + imul eax, 4*FP_1 + xor edx, edx + div ecx + mov wx, 18*FP_1 + mov wy, 18*FP_1 + cmp phase, 0 + jne patron_route_south + add wx, eax + jmp patron_route_check +patron_route_south: + cmp phase, 1 + jne patron_route_west + mov wx, 22*FP_1 + shr eax, 1 + add wy, eax + jmp patron_route_check +patron_route_west: + mov wy, 20*FP_1 + cmp phase, 2 + jne patron_route_north + mov wx, 22*FP_1 + sub wx, eax + jmp patron_route_check +patron_route_north: + shr eax, 1 + sub wy, eax +patron_route_check: + invoke CanWalk3D,wx,wy + test eax, eax + jz patron_update_next + imul ebx, esi, SIZEOF CityProp3D + mov eax, wx + mov hallGuests3D[ebx].posX, eax + mov eax, wy + mov hallGuests3D[ebx].posY, eax + mov eax, patronClock3D + xor edx, edx + mov ecx, 220 + div ecx + and eax, 3 + lea eax, [eax+esi*4] + mov hallGuests3D[ebx].frame, eax +patron_update_next: + inc esi + cmp esi, 2 + jb patron_update_loop +patron_update_done: + call UpdateCasinoNpcMind + ret +ENDIF +UpdatePatrons3D ENDP + +RenderPatrons3D PROC uses esi + call RenderNpcLife3D + mov esi,8 +patron_render_loop: + imul eax, esi, SIZEOF CityProp3D + add eax, OFFSET hallGuests3D + invoke DrawCityObject3D,eax,0 + inc esi + cmp esi,12 + jb patron_render_loop + ret +RenderPatrons3D ENDP diff --git a/src_graphics/native_blackjack.inc b/src_graphics/native_blackjack.inc index 2a0b640..4229edd 100644 --- a/src_graphics/native_blackjack.inc +++ b/src_graphics/native_blackjack.inc @@ -7,6 +7,7 @@ InitNativeBlackjack3D PROC mov cbDealerCount3D, 0 mov cbStake3D, 0 mov cbError3D, 0 + call InitBJParty3D call ClearKeys3D ret InitNativeBlackjack3D ENDP @@ -59,6 +60,8 @@ NativeBJSettle3D PROC result:DWORD mov cbVisible3D, 1 mov eax, result mov cbOutcome3D, eax + call ResolveBJParty3D + mov eax, result cmp eax, 1 je bj_settle_loss mov eax, cbStake3D @@ -78,6 +81,14 @@ bj_settle_loss: invoke PlayCasinoSound3D, OFFSET soundRoundLose, 0, 1 bj_settle_save: call ClearKeys3D + xor eax,eax + cmp cbOutcome3D,0 + sete al + cmp cbOutcome3D,3 + jne @F + mov eax,1 +@@: + invoke NpcRecordRound3D,1,eax call SaveProgress3D bj_settle_done: ret @@ -96,6 +107,9 @@ StartNativeBlackjack3D PROC mov cbStake3D, eax mov cbError3D, 0 mov cbDouble3D, 0 + mov cbEarlyOutcome3D, -1 + mov cbBotsSettled3D, 0 + mov cbInitialFlights3D, 4 mov cbVisible3D, 0 mov cbPlayerCount3D, 2 mov cbDealerCount3D, 2 @@ -109,6 +123,10 @@ StartNativeBlackjack3D PROC mov cbPlayer3D[4], eax mov eax, cbDeck3D[12] mov cbDealer3D[4], eax + cmp cbBotCount3D, 0 + je @F + call DealBJParty3D +@@: invoke NativeBJScore3D, OFFSET cbPlayer3D, 2 mov cbPlayerScore3D, eax invoke NativeBJScore3D, OFFSET cbDealer3D, 2 @@ -130,6 +148,8 @@ NativeBJHit3D PROC uses ebx jne bj_hit_done cmp cbPlayerCount3D, 12 jae bj_hit_done + cmp cbCursor3D, 52 + jae bj_hit_done mov ebx, cbCursor3D mov eax, cbDeck3D[ebx*4] mov cbCard3D, eax @@ -146,6 +166,7 @@ HandleNativeBlackjack3D PROC uses ebx call HandleCardExit3D test eax, eax jnz bj_input_done + call BJPartyInput3D invoke CardTableMouse3D, MODE_BLACKJACK cmp cardExitActive3D, 0 jne bj_input_done @@ -157,11 +178,18 @@ HandleNativeBlackjack3D PROC uses ebx je bj_ready_input cmp cbState3D, CB_PLAYER je bj_player_input + cmp cbState3D, CB_BOTS + jne @F + call UpdateBJParty3D + ret +@@: mov eax, deltaTime3D add cbTimer3D, eax cmp cbState3D, CB_DEAL jne bj_animate_hit - cmp cbTimer3D, TABLE_FLIGHT_MS*4 + mov eax, cbInitialFlights3D + imul eax, TABLE_FLIGHT_MS + cmp cbTimer3D, eax jb bj_input_done cmp cbDealerScore3D, 21 jne bj_player_natural @@ -175,7 +203,7 @@ HandleNativeBlackjack3D PROC uses ebx bj_player_natural: cmp cbPlayerScore3D, 21 jne bj_begin_player - invoke NativeBJSettle3D, 3 + invoke FinishBJPlayer3D, 3 ret bj_begin_player: mov cbState3D, CB_PLAYER @@ -199,7 +227,7 @@ bj_animate_hit: jne bj_begin_dealer jmp bj_begin_player bj_player_bust: - invoke NativeBJSettle3D, 1 + invoke FinishBJPlayer3D, 1 ret bj_animate_dealer: cmp cbTimer3D, 600 @@ -208,6 +236,8 @@ bj_animate_dealer: jae bj_compare_hands cmp cbDealerCount3D, 12 jae bj_compare_hands + cmp cbCursor3D, 52 + jae bj_compare_hands mov ebx, cbCursor3D mov eax, cbDeck3D[ebx*4] inc cbCursor3D @@ -220,6 +250,11 @@ bj_animate_dealer: invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1 ret bj_compare_hands: + cmp cbEarlyOutcome3D, -1 + je @F + invoke NativeBJSettle3D, cbEarlyOutcome3D + ret +@@: mov eax, cbDealerScore3D cmp eax, 21 ja bj_player_win @@ -260,10 +295,7 @@ bj_player_input: test eax, eax jz bj_input_done bj_begin_dealer: - mov cbVisible3D, 1 - mov cbState3D, CB_DEALER - mov cbTimer3D, 0 - call ClearKeys3D + invoke FinishBJPlayer3D, -1 ret bj_ready_input: invoke Pressed3D, 26h @@ -287,3 +319,4 @@ bj_ready_input: bj_input_done: ret HandleNativeBlackjack3D ENDP +include src_graphics\native_blackjack_party.inc diff --git a/src_graphics/native_blackjack_party.inc b/src_graphics/native_blackjack_party.inc new file mode 100644 index 0000000..d98e5d7 --- /dev/null +++ b/src_graphics/native_blackjack_party.inc @@ -0,0 +1,357 @@ +InitBJParty3D PROC uses edi + invoke LoadAnimPack3D,OFFSET cbPartyRoom3D,OFFSET cbPartyRoomPath3D + cmp cbPartyRoom3D.frames,1 + jne bj_party_invalid_room + cmp cbPartyRoom3D.imageWidth,SCREEN_W + jne bj_party_invalid_room + cmp cbPartyRoom3D.height,SCREEN_H + je bj_party_room_ready +bj_party_invalid_room: + invoke FreeAnimPack3D,OFFSET cbPartyRoom3D +bj_party_room_ready: + cmp cbBotCount3D,3 + jbe @F + mov cbBotCount3D,0 +@@: + mov cbEarlyOutcome3D,-1 + mov cbBotsSettled3D,0 + mov cbBotTurn3D,0 + mov cbBotTimer3D,0 + lea edi,cbBots3D + mov ecx,SIZEOF BJBot3D*3/4 + xor eax,eax + rep stosd + invoke LoadAnimPack3D,OFFSET cbPartyArt3D,OFFSET cbPartyArtPath3D + cmp cbPartyArt3D.frames,6 + jne bj_party_invalid_art + cmp cbPartyArt3D.imageWidth,160 + jne bj_party_invalid_art + cmp cbPartyArt3D.height,160 + jne bj_party_invalid_art + ret +bj_party_invalid_art: + call FreeBJParty3D + ret +InitBJParty3D ENDP + +FreeBJParty3D PROC + invoke FreeAnimPack3D,OFFSET cbPartyArt3D + invoke FreeAnimPack3D,OFFSET cbPartyRoom3D + ret +FreeBJParty3D ENDP + +; Round-robin: player, each guest, then dealer. Old solo order is unchanged. +DealBJParty3D PROC uses ebx esi edi + call InitBJParty3D + mov eax,cbBotCount3D + add eax,2 + shl eax,1 + mov cbInitialFlights3D,eax + mov cbCursor3D,0 + xor edi,edi +bj_party_deal_pass: + mov ecx,cbCursor3D + mov eax,cbDeck3D[ecx*4] + mov cbPlayer3D[edi*4],eax + inc cbCursor3D + xor ebx,ebx +bj_party_deal_guest: + cmp ebx,cbBotCount3D + jae bj_party_deal_dealer + mov esi,ebx + imul esi,SIZEOF BJBot3D + add esi,OFFSET cbBots3D + mov ecx,cbCursor3D + mov eax,cbDeck3D[ecx*4] + mov [esi+edi*4].BJBot3D.cards,eax + inc cbCursor3D + mov [esi].BJBot3D.count,2 + mov eax,cbBet3D + mov [esi].BJBot3D.stake,eax + inc ebx + jmp bj_party_deal_guest +bj_party_deal_dealer: + mov ecx,cbCursor3D + mov eax,cbDeck3D[ecx*4] + mov cbDealer3D[edi*4],eax + inc cbCursor3D + inc edi + cmp edi,2 + jb bj_party_deal_pass + xor ebx,ebx +bj_party_deal_score: + cmp ebx,cbBotCount3D + jae bj_party_deal_done + mov esi,ebx + imul esi,SIZEOF BJBot3D + add esi,OFFSET cbBots3D + invoke NativeBJScore3D,esi,2 + mov [esi].BJBot3D.score,eax + inc ebx + jmp bj_party_deal_score +bj_party_deal_done: + ret +DealBJParty3D ENDP + +BeginBJDealer3D PROC + mov cbVisible3D,1 + mov cbState3D,CB_DEALER + mov cbTimer3D,0 + call ClearKeys3D + ret +BeginBJDealer3D ENDP + +; Keep the table alive after a player bust/natural so other seats finish. +FinishBJPlayer3D PROC pending:DWORD + mov eax,pending + mov cbEarlyOutcome3D,eax + cmp cbBotCount3D,0 + je bj_party_solo_finish + mov cbBotTurn3D,0 + mov cbBotTimer3D,0 + mov cbState3D,CB_BOTS + call ClearKeys3D + ret +bj_party_solo_finish: + cmp pending,-1 + jne @F + call BeginBJDealer3D + ret +@@: + invoke NativeBJSettle3D,pending + ret +FinishBJPlayer3D ENDP + +; No hidden dealer card, other hands, future deck cards or RNG are consulted. +BJBotDecision3D PROC uses ebx esi slot:DWORD + cmp slot,3 + jae bj_bot_stand + mov esi,slot + imul esi,SIZEOF BJBot3D + add esi,OFFSET cbBots3D + cmp [esi].BJBot3D.count,12 + jae bj_bot_stand + mov eax,cbDealer3D + xor edx,edx + mov ecx,13 + div ecx + lea ebx,[edx+2] + cmp ebx,11 + jbe @F + mov ebx,10 +@@: + cmp edx,12 + jne @F + mov ebx,11 +@@: + mov eax,[esi].BJBot3D.score + cmp eax,21 + jae bj_bot_stand + cmp [esi].BJBot3D.count,2 + jne bj_bot_threshold + cmp eax,11 + jne bj_bot_threshold + cmp ebx,10 + jae bj_bot_threshold + mov eax,2 + ret +bj_bot_threshold: + mov ecx,17 + cmp slot,1 + jne @F + mov ecx,19 +@@: + cmp slot,2 + jne @F + cmp ebx,7 + jae @F + mov ecx,13 +@@: + cmp eax,ecx + jae bj_bot_stand + mov eax,1 + ret +bj_bot_stand: + xor eax,eax + ret +BJBotDecision3D ENDP + +UpdateBJParty3D PROC uses ebx esi + mov eax,deltaTime3D + cmp eax,250 + jbe @F + mov eax,250 +@@: + add cbBotTimer3D,eax + mov ebx,cbBotTurn3D + cmp ebx,cbBotCount3D + jae bj_bot_finish_table + mov esi,ebx + imul esi,SIZEOF BJBot3D + add esi,OFFSET cbBots3D + cmp [esi].BJBot3D.state,BJ_BOT_FLIGHT + je bj_bot_commit + cmp cbBotTimer3D,BJ_PARTY_MS + jb bj_bot_tick_done + invoke BJBotDecision3D,ebx + test eax,eax + jz bj_bot_finish_seat + cmp cbCursor3D,52 + jae bj_bot_finish_seat + cmp eax,2 + jne @F + shl [esi].BJBot3D.stake,1 +@@: + mov ecx,cbCursor3D + mov eax,cbDeck3D[ecx*4] + mov cbBotCard3D,eax + inc cbCursor3D + mov cbBotTimer3D,0 + mov [esi].BJBot3D.state,BJ_BOT_FLIGHT + invoke PlayCasinoSound3D,OFFSET soundCards,0,1 + ret +bj_bot_commit: + cmp cbBotTimer3D,TABLE_FLIGHT_MS + jb bj_bot_tick_done + mov ecx,[esi].BJBot3D.count + cmp ecx,12 + jae bj_bot_finish_seat + mov eax,cbBotCard3D + mov [esi+ecx*4].BJBot3D.cards,eax + inc [esi].BJBot3D.count + invoke NativeBJScore3D,esi,[esi].BJBot3D.count + mov [esi].BJBot3D.score,eax + cmp eax,21 + jae bj_bot_finish_seat + mov eax,cbBet3D + cmp [esi].BJBot3D.stake,eax + ja bj_bot_finish_seat + mov [esi].BJBot3D.state,BJ_BOT_WAIT + mov cbBotTimer3D,0 + ret +bj_bot_finish_seat: + mov [esi].BJBot3D.state,BJ_BOT_DONE + inc cbBotTurn3D + mov cbBotTimer3D,0 + ret +bj_bot_finish_table: + call BeginBJDealer3D +bj_bot_tick_done: + ret +UpdateBJParty3D ENDP + +ResolveBJParty3D PROC uses ebx esi + cmp cbBotsSettled3D,0 + jne bj_bot_resolve_done + mov cbBotsSettled3D,1 + xor ebx,ebx +bj_bot_resolve: + cmp ebx,cbBotCount3D + jae bj_bot_resolve_done + mov esi,ebx + imul esi,SIZEOF BJBot3D + add esi,OFFSET cbBots3D + mov [esi].BJBot3D.state,BJ_BOT_DONE + mov eax,1 + mov ecx,[esi].BJBot3D.score + cmp ecx,21 + ja bj_bot_result + cmp cbDealerScore3D,21 + jne bj_bot_no_dealer_natural + cmp cbDealerCount3D,2 + jne bj_bot_no_dealer_natural + cmp ecx,21 + jne bj_bot_result + cmp [esi].BJBot3D.count,2 + jne bj_bot_result + mov eax,2 + jmp bj_bot_result +bj_bot_no_dealer_natural: + cmp ecx,21 + jne bj_bot_compare + cmp [esi].BJBot3D.count,2 + jne bj_bot_compare + mov eax,3 + jmp bj_bot_result +bj_bot_compare: + cmp cbDealerScore3D,21 + ja bj_bot_won + cmp ecx,cbDealerScore3D + jb bj_bot_result + je bj_bot_pushed +bj_bot_won: + xor eax,eax + jmp bj_bot_result +bj_bot_pushed: + mov eax,2 +bj_bot_result: + mov [esi].BJBot3D.outcome,eax + inc ebx + jmp bj_bot_resolve +bj_bot_resolve_done: + ret +ResolveBJParty3D ENDP + +SetBJPartyCount3D PROC count:DWORD + cmp count,3 + ja bj_party_count_done + cmp cbState3D,CB_IDLE + je @F + cmp cbState3D,CB_RESULT + jne bj_party_count_done +@@: + mov eax,count + cmp eax,cbBotCount3D + je bj_party_count_done + mov cbBotCount3D,eax + mov cbState3D,CB_IDLE + mov cbPlayerCount3D,0 + mov cbDealerCount3D,0 + mov cbStake3D,0 + mov cbError3D,0 + call InitBJParty3D +bj_party_count_done: + ret +SetBJPartyCount3D ENDP + +BJPartyInput3D PROC uses ebx + cmp cbState3D,CB_IDLE + je @F + cmp cbState3D,CB_RESULT + jne bj_party_input_done +@@: + xor ebx,ebx +bj_party_key: + lea eax,[ebx+30h] + invoke Pressed3D,eax + test eax,eax + jz @F + invoke SetBJPartyCount3D,ebx + ret +@@: + inc ebx + cmp ebx,4 + jb bj_party_key + cmp mouseClick3D,0 + je bj_party_input_done + cmp mouseY3D,35 + jb bj_party_input_done + cmp mouseY3D,51 + jae bj_party_input_done + mov eax,mouseX3D + sub eax,212 + jc bj_party_input_done + cmp eax,100 + jae bj_party_input_done + xor edx,edx + mov ecx,25 + div ecx + cmp edx,22 + jae bj_party_input_done + invoke SetBJPartyCount3D,eax + mov mouseClick3D,0 +bj_party_input_done: + ret +BJPartyInput3D ENDP + +include src_graphics\native_blackjack_party_render.inc diff --git a/src_graphics/native_blackjack_party_data.inc b/src_graphics/native_blackjack_party_data.inc new file mode 100644 index 0000000..95f3475 --- /dev/null +++ b/src_graphics/native_blackjack_party_data.inc @@ -0,0 +1,60 @@ +; Independent blackjack seats share one deck, never the player's wallet. +CB_BOTS equ 6 +BJ_BOT_WAIT equ 0 +BJ_BOT_FLIGHT equ 1 +BJ_BOT_DONE equ 2 +BJ_PARTY_MS equ 550 +BJBot3D STRUCT + cards dd 12 dup(0) + count dd 0 + score dd 0 + stake dd 0 + outcome dd 0 + state dd 0 +BJBot3D ENDS +InitBJParty3D PROTO +FreeBJParty3D PROTO +DealBJParty3D PROTO +BeginBJDealer3D PROTO +FinishBJPlayer3D PROTO :DWORD +UpdateBJParty3D PROTO +BJBotDecision3D PROTO :DWORD +ResolveBJParty3D PROTO +BJPartyInput3D PROTO +SetBJPartyCount3D PROTO :DWORD +RenderBJParty3D PROTO +DrawBJPartySelector3D PROTO +DrawBJMiniCard3D PROTO :DWORD,:DWORD,:DWORD,:DWORD +DrawBJMiniFlight3D PROTO :DWORD,:DWORD,:DWORD,:DWORD +.data +cbBotCount3D dd 0 +cbBots3D BJBot3D 3 dup(<>) +cbBotTurn3D dd 0 +cbBotTimer3D dd 0 +cbBotCard3D dd 0 +cbEarlyOutcome3D dd -1 +cbBotsSettled3D dd 0 +cbInitialFlights3D dd 4 +cbPartyArt3D AnimPack3D <> +cbPartyArtPath3D db "assets\animations\tables\blackjack-guests-v1.bin",0 +cbPartyRoom3D AnimPack3D <> +cbPartyRoomPath3D db "assets\animations\tables\blackjack-room-v1.bin",0 +cbPartyNames3D dd OFFSET cbPartyName0,OFFSET cbPartyName1,OFFSET cbPartyName2 +cbPartyName0 db 210,206,203,223,0 +cbPartyName1 db 209,197,208,195,197,201,0 +cbPartyName2 db 192,203,200,209,192,0 +cbBotsLabel3D db 193,206,210,219,0 +cbBotWaitText3D db 198,196,168,210,0 +cbBotHitText3D db 202,192,208,210,192,0 +cbBotStandText3D db 213,194,192,210,200,210,0 +cbBotBustText3D db 207,197,208,197,193,206,208,0 +cbBotWinText3D db 207,206,193,197,196,192,0 +cbBotLoseText3D db 207,208,206,200,195,208,219,216,0 +cbBotPushText3D db 205,200,215,220,223,0 +cbBotNaturalText3D db 193,203,221,202,196,198,197,202,0 +cbBotResults3D dd OFFSET cbBotWinText3D,OFFSET cbBotLoseText3D,OFFSET cbBotPushText3D,OFFSET cbBotNaturalText3D +cbDealerLabel3D db 196,200,203,197,208,0 +cbPartyPlayerText3D db 194,219,0 +cbPartyDigit3D db "0",0,"1",0,"2",0,"3",0 +cbPartyX3D dd 8,120,232 +.code diff --git a/src_graphics/native_blackjack_party_render.inc b/src_graphics/native_blackjack_party_render.inc new file mode 100644 index 0000000..d3f7661 --- /dev/null +++ b/src_graphics/native_blackjack_party_render.inc @@ -0,0 +1,407 @@ +DrawBJPartySelector3D PROC uses ebx esi edi + xor edi,edi + cmp cbState3D,CB_IDLE + je @F + cmp cbState3D,CB_RESULT + jne bj_party_selector +@@: + mov edi,1 +bj_party_selector: + invoke DrawString8x8,176,39,OFFSET cbBotsLabel3D,00D4C5A4h + xor ebx,ebx +bj_party_selector_loop: + mov esi,ebx + imul esi,25 + add esi,212 + mov ecx,00454D48h + test edi,edi + jz @F + mov ecx,00D1B16Eh +@@: + mov eax,00202D26h + cmp ebx,cbBotCount3D + jne @F + mov eax,003B6C59h +@@: + invoke DrawBoxBorder,esi,35,22,16,eax,ecx,1 + lea edx,cbPartyDigit3D[ebx*2] + lea eax,[esi+7] + invoke DrawString8x8,eax,39,edx,00F2E9D3h + inc ebx + cmp ebx,4 + jb bj_party_selector_loop + ret +DrawBJPartySelector3D ENDP + +; Smaller guest cards retain an unambiguous rank and suit, never fake identities. +DrawBJMiniCard3D PROC uses ebx esi x:DWORD,y:DWORD,card:DWORD,hidden:DWORD + local ink:DWORD,rank:DWORD,suit:DWORD + mov ecx,00EEEDE2h + cmp hidden,0 + je @F + mov ecx,004A2941h +@@: + invoke DrawBoxBorder,x,y,20,30,ecx,00BCA878h,1 + cmp hidden,0 + jne bj_mini_back + mov eax,card + xor edx,edx + mov ecx,13 + div ecx + mov suit,eax + mov rank,edx + mov ink,00191F24h + cmp eax,1 + je @F + cmp eax,2 + jne bj_mini_face +@@: + mov ink,00BF263Ch +bj_mini_face: + lea edx,cardRankNames3D[edx*2] + mov eax,x + add eax,3 + mov ecx,y + add ecx,3 + invoke DrawString8x8,eax,ecx,edx,ink + mov eax,x + add eax,6 + mov edx,y + add edx,17 + invoke DrawNativeSuit3D,eax,edx,suit,ink + ret +bj_mini_back: + mov eax,x + add eax,4 + mov edx,y + add edx,4 + invoke DrawBoxBorder,eax,edx,12,22,004A2941h,00C9B589h,1 + ret +DrawBJMiniCard3D ENDP + +DrawBJMiniFlight3D PROC uses ebx x:DWORD,y:DWORD,card:DWORD,timeMs:DWORD + local px:DWORD,py:DWORD + mov ebx,timeMs + cmp ebx,TABLE_FLIGHT_MS + jbe @F + mov ebx,TABLE_FLIGHT_MS +@@: + mov eax,x + sub eax,170 + imul eax,ebx + cdq + mov ecx,TABLE_FLIGHT_MS + idiv ecx + add eax,170 + mov px,eax + mov eax,y + sub eax,24 + imul eax,ebx + cdq + idiv ecx + add eax,24 + mov py,eax + invoke QueueTableHand3D,px,py,timeMs,0 + invoke DrawBJMiniCard3D,px,py,card,0 + ret +DrawBJMiniFlight3D ENDP + +RenderBJParty3D PROC uses ebx esi edi + local guest:DWORD,stepX:DWORD,px:DWORD,pose:DWORD,shown:DWORD,slide:DWORD,cardId:DWORD,hide:DWORD + call RenderCardTable3D + cmp cbPartyRoom3D.pixels,0 + je @F + mov esi,cbPartyRoom3D.pixels + lea edi,screenBuffer + mov ecx,SCREEN_SIZE + rep movsd +@@: + invoke DrawBox,0,0,320,52,00151D20h + invoke DrawString8x8,8,6,OFFSET cbTitle3D,00E8D7ADh + invoke DrawString8x8,8,20,OFFSET cbDealerLabel3D,00D1B16Eh + invoke DrawString8x8,192,20,OFFSET textBank3D,00A8DDB9h + invoke FormatNumber,bankroll,OFFSET hudNumBuffer + invoke DrawString8x8,240,20,OFFSET hudNumBuffer,00F4F3E8h + call DrawBJPartySelector3D + xor edi,edi +bj_party_render_guest: + cmp edi,cbBotCount3D + jae bj_party_render_dealer + mov esi,edi + imul esi,SIZEOF BJBot3D + add esi,OFFSET cbBots3D + mov guest,esi + mov ebx,cbPartyX3D[edi*4] + invoke DrawString8x8,ebx,54,cbPartyNames3D[edi*4],00E8D7ADh + mov pose,edi + cmp cbState3D,CB_BOTS + jne @F + cmp edi,cbBotTurn3D + jne @F + add pose,3 +@@: + mov eax,ebx + add eax,4 + shl eax,1 + invoke DrawAnimSprite3D,OFFSET cbPartyArt3D,pose,eax,112,144,144 + cmp cbState3D,CB_IDLE + je bj_party_next_guest + cmp cbState3D,CB_DEAL + je @F + invoke FormatNumber,[esi].BJBot3D.score,OFFSET hudNumBuffer + lea eax,[ebx+64] + invoke DrawString8x8,eax,54,OFFSET hudNumBuffer,00EDDFB1h +@@: + mov eax,[esi].BJBot3D.count + mov shown,eax + cmp cbState3D,CB_BOTS + jne @F + cmp edi,cbBotTurn3D + jne @F + cmp [esi].BJBot3D.state,BJ_BOT_FLIGHT + jne @F + inc shown + inc eax +@@: + mov stepX,16 + cmp eax,4 + jbe @F + dec eax + mov ecx,eax + mov eax,60 + xor edx,edx + div ecx + mov stepX,eax +@@: + xor ebx,ebx +bj_party_guest_card: + mov eax,ebx + imul eax,stepX + add eax,cbPartyX3D[edi*4] + mov px,eax + cmp ebx,[esi].BJBot3D.count + jb bj_party_guest_existing + invoke DrawBJMiniFlight3D,px,124,cbBotCard3D,cbBotTimer3D + jmp bj_party_guest_next_card +bj_party_guest_existing: + mov edx,[esi+ebx*4].BJBot3D.cards + mov cardId,edx + cmp cbState3D,CB_DEAL + jne bj_party_guest_fixed + mov eax,cbBotCount3D + add eax,2 + imul eax,ebx + lea eax,[eax+edi+1] + imul eax,TABLE_FLIGHT_MS + mov ecx,cbTimer3D + sub ecx,eax + js bj_party_guest_next_card + invoke DrawBJMiniFlight3D,px,124,cardId,ecx + jmp bj_party_guest_next_card +bj_party_guest_fixed: + invoke DrawBJMiniCard3D,px,124,cardId,0 +bj_party_guest_next_card: + inc ebx + cmp ebx,shown + jb bj_party_guest_card + mov ecx,OFFSET cbBotWaitText3D + cmp cbState3D,CB_RESULT + jne bj_party_guest_live_status + mov eax,[esi].BJBot3D.outcome + mov ecx,cbBotResults3D[eax*4] + jmp bj_party_guest_status +bj_party_guest_live_status: + cmp [esi].BJBot3D.state,BJ_BOT_DONE + jne @F + mov ecx,OFFSET cbBotStandText3D +@@: + cmp [esi].BJBot3D.score,21 + jbe @F + mov ecx,OFFSET cbBotBustText3D +@@: + cmp cbState3D,CB_BOTS + jne bj_party_guest_status + cmp edi,cbBotTurn3D + jne bj_party_guest_status + mov ecx,OFFSET cbBotHitText3D +bj_party_guest_status: + mov eax,cbPartyX3D[edi*4] + invoke DrawString8x8,eax,158,ecx,00DCE7DBh +bj_party_next_guest: + inc edi + jmp bj_party_render_guest +bj_party_render_dealer: + cmp cbState3D,CB_IDLE + je bj_party_render_controls + mov stepX,22 + cmp cbDealerCount3D,5 + jbe @F + mov eax,cbDealerCount3D + dec eax + mov ecx,eax + mov eax,100 + xor edx,edx + div ecx + mov stepX,eax +@@: + xor ebx,ebx +bj_party_dealer_card: + mov eax,ebx + imul eax,stepX + add eax,64 + mov px,eax + mov edx,cbDealer3D[ebx*4] + mov cardId,edx + mov hide,0 + cmp ebx,1 + jne @F + cmp cbVisible3D,0 + jne @F + mov hide,1 +@@: + cmp cbState3D,CB_DEAL + jne bj_party_dealer_fixed + mov eax,cbBotCount3D + add eax,2 + imul eax,ebx + add eax,cbBotCount3D + inc eax + imul eax,TABLE_FLIGHT_MS + mov ecx,cbTimer3D + sub ecx,eax + js bj_party_dealer_next + ; Initial dealer cards stay inside the header, with the hole card hidden. +bj_party_dealer_fixed: + invoke DrawBJMiniCard3D,px,20,cardId,hide +bj_party_dealer_next: + inc ebx + cmp ebx,cbDealerCount3D + jb bj_party_dealer_card + xor ebx,ebx + mov shown,0 + cmp cbState3D,CB_HIT + jne @F + mov shown,1 +@@: + mov eax,cbPlayerCount3D + add shown,eax + mov stepX,40 + cmp shown,4 + jbe @F + mov eax,shown + dec eax + mov ecx,eax + mov eax,126 + xor edx,edx + div ecx + mov stepX,eax +@@: + mov eax,shown + dec eax + imul eax,stepX + add eax,34 + mov edx,320 + sub edx,eax + shr edx,1 + mov slide,edx +bj_party_player_card: + mov eax,ebx + imul eax,stepX + add eax,slide + mov px,eax + cmp ebx,cbPlayerCount3D + jb bj_party_player_existing + invoke DrawSlidingCard3D,px,168,cbCard3D,0,cbTimer3D + jmp bj_party_player_next +bj_party_player_existing: + mov edx,cbPlayer3D[ebx*4] + mov cardId,edx + cmp cbState3D,CB_DEAL + jne bj_party_player_fixed + mov eax,cbBotCount3D + add eax,2 + imul eax,ebx + imul eax,TABLE_FLIGHT_MS + mov ecx,cbTimer3D + sub ecx,eax + js bj_party_player_next + invoke DrawSlidingCard3D,px,168,cardId,0,ecx + jmp bj_party_player_next +bj_party_player_fixed: + invoke DrawNativeCard3D,px,168,cardId,0,34 +bj_party_player_next: + inc ebx + cmp ebx,shown + jb bj_party_player_card + invoke DrawString8x8,64,174,OFFSET cbPartyPlayerText3D,00E8D7ADh + invoke FormatNumber,cbPlayerScore3D,OFFSET hudNumBuffer + invoke DrawString8x8,64,188,OFFSET hudNumBuffer,00EDDFB1h +bj_party_render_controls: + call DrawQueuedTableHand3D + ; UI labels stay above animated hands instead of disappearing during a deal. + invoke DrawBox,0,52,320,10,00151D20h + xor edi,edi +bj_party_final_names: + cmp edi,cbBotCount3D + jae bj_party_final_names_done + mov ebx,cbPartyX3D[edi*4] + invoke DrawString8x8,ebx,54,cbPartyNames3D[edi*4],00E8D7ADh + cmp cbState3D,CB_IDLE + je bj_party_final_name_next + cmp cbState3D,CB_DEAL + je bj_party_final_name_next + mov esi,edi + imul esi,SIZEOF BJBot3D + add esi,OFFSET cbBots3D + invoke FormatNumber,[esi].BJBot3D.score,OFFSET hudNumBuffer + lea eax,[ebx+64] + invoke DrawString8x8,eax,54,OFFSET hudNumBuffer,00EDDFB1h +bj_party_final_name_next: + inc edi + jmp bj_party_final_names +bj_party_final_names_done: + invoke DrawString8x8,8,174,OFFSET textBet3D,00DDCFB1h + invoke FormatNumber,cbBet3D,OFFSET hudNumBuffer + invoke DrawString8x8,8,186,OFFSET hudNumBuffer,00F6F4DDh + xor edi,edi + cmp cbState3D,CB_IDLE + je bj_party_ready + cmp cbState3D,CB_RESULT + je bj_party_ready + invoke DrawStakeControls3D,0 + cmp cbState3D,CB_PLAYER + jne @F + mov edi,1 +@@: + invoke DrawTableButton3D,8,OFFSET cbHitText3D,edi + invoke DrawTableButton3D,86,OFFSET cbStandText3D,edi + cmp cbPlayerCount3D,2 + jne bj_party_no_double + mov eax,cbStake3D + cmp bankroll,eax + jae @F +bj_party_no_double: + xor edi,edi +@@: + invoke DrawTableButton3D,164,OFFSET cbDoubleText3D,edi + jmp bj_party_render_exit +bj_party_ready: + invoke DrawStakeControls3D,1 + invoke DrawTableButton3D,125,OFFSET pkDealText3D,1 + cmp cbState3D,CB_RESULT + jne bj_party_render_exit + mov eax,cbOutcome3D + mov ecx,OFFSET cbNaturalText3D + cmp eax,3 + je @F + mov ecx,cbResults3D[eax*4] +@@: + invoke DrawString8x8,8,226,ecx,00EFD583h +bj_party_render_exit: + cmp cbError3D,0 + je @F + invoke DrawString8x8,80,183,OFFSET textNoCash3D,00F89880h +@@: + call RenderCardExit3D + ret +RenderBJParty3D ENDP diff --git a/src_graphics/native_clover.inc b/src_graphics/native_clover.inc new file mode 100644 index 0000000..303b19c --- /dev/null +++ b/src_graphics/native_clover.inc @@ -0,0 +1,685 @@ +FreeNativeClover3D PROC + invoke FreeAnimPack3D,OFFSET clpCabinet3D + invoke FreeAnimPack3D,OFFSET clpSymbols3D + ret +FreeNativeClover3D ENDP + +InitNativeClover3D PROC + invoke LoadAnimPack3D,OFFSET clpCabinet3D,OFFSET clpCabinetPath3D + test eax,eax + jz clp_init_fail + cmp clpCabinet3D.imageWidth,640 + jne clp_init_fail + cmp clpCabinet3D.height,480 + jne clp_init_fail + cmp clpCabinet3D.frames,1 + jne clp_init_fail + invoke LoadAnimPack3D,OFFSET clpSymbols3D,OFFSET clpSymbolsPath3D + test eax,eax + jz clp_init_fail + cmp clpSymbols3D.imageWidth,CLP_CELL + jne clp_init_fail + cmp clpSymbols3D.height,CLP_CELL + jne clp_init_fail + cmp clpSymbols3D.frames,7 + jne clp_init_fail + mov clpState3D,SLOT_READY + mov clpTimer3D,0 + mov clpStake3D,0 + mov clpGross3D,0 + mov clpTotal3D,0 + mov clpCount3D,0 + mov clpWinMask3D,0 + mov clpSelected3D,0 + mov clpPaytable3D,0 + mov clpLeave3D,0 + mov clpError3D,0 + mov clpBet3D,50 + mov clpBetIndex3D,1 + mov paused3D,0 + mov cardExitActive3D,0 + call ClearKeys3D + mov eax,1 + ret +clp_init_fail: + call FreeNativeClover3D + xor eax,eax + ret +InitNativeClover3D ENDP + +; Tape contents and final board are frozen at the single stake debit. +StartNativeClover3D PROC uses ebx esi edi + cmp clpState3D,SLOT_SPIN + je clp_start_done + cmp clpPaytable3D,0 + jne clp_start_done + cmp clpCabinet3D.pixels,0 + je clp_start_done + cmp clpSymbols3D.pixels,0 + je clp_start_done + mov eax,clpBet3D + test eax,eax + jz clp_start_done + cmp eax,10000 + ja clp_start_done + cmp eax,bankroll + ja clp_start_money + sub bankroll,eax + mov clpStake3D,eax + mov clpState3D,SLOT_SPIN + mov clpTimer3D,0 + mov clpGross3D,0 + mov clpCount3D,0 + mov clpTotal3D,0 + mov clpWinMask3D,0 + mov clpSelected3D,0 + mov clpLeave3D,0 + mov clpError3D,0 + xor esi,esi +clp_start_column: + mov ebx,esi + shl ebx,8 + xor edi,edi +clp_start_tape: + invoke RandomRange3D,7 + mov clpTape3D[ebx+edi*4],eax + inc edi + cmp edi,64 + jb clp_start_tape + xor edi,edi +clp_start_rows: + mov ecx,edi + imul ecx,5 + add ecx,esi + mov eax,clpGrid3D[ecx*4] + mov clpTape3D[ebx+edi*4],eax + invoke RandomRange3D,7 + mov clpGrid3D[ecx*4],eax + mov edx,clpSteps3D[esi*4] + add edx,edi + mov clpTape3D[ebx+edx*4],eax + inc edi + cmp edi,3 + jb clp_start_rows + inc esi + cmp esi,5 + jb clp_start_column + call SaveProgress3D + invoke PlayCasinoSound3D,OFFSET soundSlotSpin,0,1 +clp_start_done: + ret +clp_start_money: + mov clpError3D,1 + ret +StartNativeClover3D ENDP + +; Reuse the original pure assembly evaluator, never the console game or payer. +CloverEvaluate3D PROC uses ebx esi edi + mov clpTotal3D,0 + mov clpCount3D,0 + mov clpWinMask3D,0 + mov clpJackpot3D,0 + xor esi,esi +clp_eval_validate: + cmp clpGrid3D[esi*4],6 + ja clp_eval_done + inc esi + cmp esi,15 + jb clp_eval_validate + lea esi,clpGrid3D + lea edi,slotGrid + mov ecx,15 + rep movsd + call EvaluateSlotCombos + mov eax,slotBestMultiplier + mov clpTotal3D,eax + mov eax,slotWinMask + mov clpWinMask3D,eax + mov eax,slotJackpotHit + mov clpJackpot3D,eax + mov eax,slotComboCount + mov clpCount3D,eax + lea esi,slotComboNames + lea edi,clpNames3D + mov ecx,eax + rep movsd + lea esi,slotComboMults + lea edi,clpMults3D + mov ecx,clpCount3D + rep movsd + lea esi,slotComboMasks + lea edi,clpMasks3D + mov ecx,clpCount3D + rep movsd +clp_eval_done: + xor eax,eax + ret +CloverEvaluate3D ENDP + +SettleNativeClover3D PROC + cmp clpState3D,SLOT_SPIN + jne clp_settle_done + call CloverEvaluate3D + mov eax,clpTotal3D + mul clpStake3D + mov ecx,1000000000 + sub ecx,bankroll + cmp eax,ecx + jbe @F + mov eax,ecx +@@: + mov clpGross3D,eax + add bankroll,eax + mov clpState3D,SLOT_RESULT + mov clpTimer3D,3400 + xor eax,eax + mov ecx,clpGross3D + cmp ecx,clpStake3D + seta al + invoke NpcRecordRound3D,4,eax + call SaveProgress3D + mov eax,clpGross3D + cmp eax,clpStake3D + jb clp_settle_loss + jne @F + invoke PlayCasinoSound3D,0,0,0 + jmp clp_settle_leave +@@: + invoke PlayCasinoSound3D,OFFSET soundRoundWin,0,1 + jmp clp_settle_leave +clp_settle_loss: + invoke PlayCasinoSound3D,OFFSET soundRoundLose,0,1 +clp_settle_leave: + cmp clpLeave3D,0 + je clp_settle_done + call CloverEscape3D +clp_settle_done: + ret +SettleNativeClover3D ENDP + +CloverEscape3D PROC + mov paused3D,0 + cmp clpPaytable3D,0 + je @F + mov clpPaytable3D,0 + call ClearKeys3D + ret +@@: + cmp clpState3D,SLOT_SPIN + jne clp_escape_hall + mov clpLeave3D,1 + call ClearKeys3D + ret +clp_escape_hall: + mov clpLeave3D,0 + mov engineMode,MODE_WALK + call ClearKeys3D + invoke PlayCasinoSound3D,0,0,0 + ret +CloverEscape3D ENDP + +CloverReelPosition3D PROC uses ebx index:DWORD + mov ebx,index + xor eax,eax + cmp ebx,4 + ja clp_pos_done + cmp clpState3D,SLOT_SPIN + jne clp_pos_end + mov eax,clpTimer3D + cmp eax,clpDurations3D[ebx*4] + jae clp_pos_end + shl eax,10 + xor edx,edx + div clpDurations3D[ebx*4] + mov ecx,2048 + sub ecx,eax + imul eax,ecx + mov ecx,clpSteps3D[ebx*4] + imul ecx,CLP_CELL + mul ecx + shrd eax,edx,20 + ret +clp_pos_end: + mov eax,clpSteps3D[ebx*4] + imul eax,CLP_CELL +clp_pos_done: + ret +CloverReelPosition3D ENDP + +HandleNativeClover3D PROC uses ebx + cmp mouseClick3D,0 + je clp_handle_tick + mov mouseClick3D,0 + mov eax,mouseY3D + cmp eax,3 + jb clp_handle_tick + cmp eax,17 + jae clp_handle_mouse_controls + cmp mouseX3D,252 + jb clp_handle_tick + cmp mouseX3D,312 + jae clp_handle_tick + call CloverEscape3D + cmp clpState3D,SLOT_SPIN + je clp_handle_tick + ret +clp_handle_mouse_controls: + cmp clpState3D,SLOT_SPIN + je clp_handle_tick + cmp clpPaytable3D,0 + je @F + cmp eax,202 + jb clp_handle_tick + cmp eax,220 + jae clp_handle_tick + cmp mouseX3D,112 + jb clp_handle_tick + cmp mouseX3D,208 + jae clp_handle_tick + mov clpPaytable3D,0 + ret +@@: + cmp eax,170 + jb clp_handle_tick + cmp eax,185 + jae clp_handle_mouse_footer + cmp mouseX3D,232 + jb clp_handle_tick + cmp mouseX3D,250 + jb clp_handle_previous + cmp mouseX3D,292 + jb clp_handle_tick + cmp mouseX3D,310 + jb clp_handle_next + jmp clp_handle_tick +clp_handle_mouse_footer: + cmp eax,222 + jb clp_handle_tick + cmp eax,238 + jae clp_handle_tick + mov eax,mouseX3D + cmp eax,11 + jb clp_handle_tick + cmp eax,29 + jb clp_handle_down + cmp eax,35 + jb clp_handle_tick + cmp eax,53 + jb clp_handle_up + cmp eax,120 + jb clp_handle_tick + cmp eax,190 + jb clp_handle_start + cmp eax,202 + jb clp_handle_tick + cmp eax,272 + jb clp_handle_paytable +clp_handle_tick: + cmp clpState3D,SLOT_SPIN + jne clp_handle_keys + mov eax,deltaTime3D + cmp eax,250 + jbe @F + mov eax,250 +@@: + add clpTimer3D,eax + cmp clpTimer3D,3400 + jb clp_handle_done + call SettleNativeClover3D + ret +clp_handle_keys: + invoke Pressed3D,50h + test eax,eax + jnz clp_handle_paytable + cmp clpPaytable3D,0 + je clp_handle_game_keys + invoke Pressed3D,20h + test eax,eax + jnz clp_handle_paytable + invoke Pressed3D,0Dh + test eax,eax + jnz clp_handle_paytable + ret +clp_handle_game_keys: + invoke Pressed3D,25h + test eax,eax + jnz clp_handle_previous + invoke Pressed3D,27h + test eax,eax + jnz clp_handle_next + invoke Pressed3D,57h + test eax,eax + jnz clp_handle_up + invoke Pressed3D,26h + test eax,eax + jnz clp_handle_up + invoke Pressed3D,53h + test eax,eax + jnz clp_handle_down + invoke Pressed3D,28h + test eax,eax + jnz clp_handle_down + invoke Pressed3D,20h + test eax,eax + jnz clp_handle_start + invoke Pressed3D,0Dh + test eax,eax + jz clp_handle_done +clp_handle_start: + call StartNativeClover3D + ret +clp_handle_paytable: + xor clpPaytable3D,1 + ret +clp_handle_previous: + cmp clpCount3D,0 + je clp_handle_done + cmp clpSelected3D,0 + jne @F + mov eax,clpCount3D + mov clpSelected3D,eax +@@: + dec clpSelected3D + ret +clp_handle_next: + cmp clpCount3D,0 + je clp_handle_done + inc clpSelected3D + mov eax,clpSelected3D + cmp eax,clpCount3D + jb clp_handle_done + mov clpSelected3D,0 + ret +clp_handle_up: + cmp clpBetIndex3D,6 + jae clp_handle_done + inc clpBetIndex3D + jmp clp_handle_bet +clp_handle_down: + cmp clpBetIndex3D,0 + je clp_handle_done + dec clpBetIndex3D +clp_handle_bet: + mov ecx,clpBetIndex3D + mov eax,slotBetValues3D[ecx*4] + mov clpBet3D,eax + mov clpError3D,0 +clp_handle_done: + ret +HandleNativeClover3D ENDP + +DrawCloverSymbol3D PROC uses ebx esi edi symbol:DWORD,x:DWORD,y:DWORD + local row:DWORD,lastRow:DWORD,source:DWORD + cmp symbol,6 + ja clp_symbol_done + mov eax,clpSymbols3D.pixels + test eax,eax + jz clp_symbol_done + mov ecx,symbol + imul ecx,CLP_CELL*CLP_CELL*4 + add eax,ecx + mov source,eax + mov eax,y + cmp eax,CLP_TOP + jge @F + mov eax,CLP_TOP +@@: + mov row,eax + mov eax,y + add eax,CLP_CELL + cmp eax,CLP_BOTTOM + jle @F + mov eax,CLP_BOTTOM +@@: + mov lastRow,eax +clp_symbol_row: + mov eax,row + cmp eax,lastRow + jge clp_symbol_done + mov ecx,eax + sub ecx,y + imul ecx,CLP_CELL*4 + mov esi,source + add esi,ecx + imul eax,640*4 + mov ecx,x + lea edi,screenBuffer[eax+ecx*4] + mov ecx,CLP_CELL +clp_symbol_column: + lodsd + test eax,0FF000000h + jz @F + and eax,00FFFFFFh + mov [edi],eax +@@: + add edi,4 + dec ecx + jnz clp_symbol_column + inc row + jmp clp_symbol_row +clp_symbol_done: + ret +DrawCloverSymbol3D ENDP + +DrawCloverReel3D PROC uses ebx esi edi index:DWORD + local symbolY:DWORD,baseStop:DWORD,columnX:DWORD + mov ebx,index + mov eax,clpColumns3D[ebx*4] + mov columnX,eax + cmp clpState3D,SLOT_SPIN + jne clp_reel_static + invoke CloverReelPosition3D,ebx + xor edx,edx + mov ecx,CLP_CELL + div ecx + mov baseStop,eax + mov eax,CLP_TOP + sub eax,edx + mov symbolY,eax + shl ebx,8 + xor esi,esi +clp_reel_tape: + mov ecx,baseStop + add ecx,esi + mov eax,clpTape3D[ebx+ecx*4] + invoke DrawCloverSymbol3D,eax,columnX,symbolY + add symbolY,CLP_CELL + inc esi + cmp esi,4 + jb clp_reel_tape + ret +clp_reel_static: + mov symbolY,CLP_TOP + xor esi,esi +clp_reel_rows: + mov ecx,esi + imul ecx,5 + add ecx,ebx + mov eax,clpGrid3D[ecx*4] + invoke DrawCloverSymbol3D,eax,columnX,symbolY + add symbolY,CLP_CELL + inc esi + cmp esi,3 + jb clp_reel_rows + ret +DrawCloverReel3D ENDP + +CloverComboText3D PROC index:DWORD + mov ecx,index + cmp ecx,clpCount3D + jae clp_combo_none + mov edx,clpNames3D[ecx*4] + xor ecx,ecx +clp_combo_lookup: + cmp edx,clpLegacyNames3D[ecx*4] + je clp_combo_found + inc ecx + cmp ecx,11 + jb clp_combo_lookup +clp_combo_none: + mov eax,OFFSET clpNoCombo3D + ret +clp_combo_found: + mov eax,clpShapeNames3D[ecx*4] + ret +CloverComboText3D ENDP + +RenderNativeClover3D PROC uses ebx esi edi + local cellX:DWORD,cellY:DWORD,selectedMask:DWORD + mov esi,clpCabinet3D.pixels + test esi,esi + jz clp_render_done + lea edi,screenBuffer + mov ecx,SCREEN_SIZE + rep movsd + xor esi,esi +clp_render_reels: + mov ebx,clpColumns3D[esi*4] + shr ebx,1 + invoke DrawBoxBorder,ebx,63,28,84,000D1816h,00405A46h,1 + invoke DrawCloverReel3D,esi + inc esi + cmp esi,5 + jb clp_render_reels + cmp clpState3D,SLOT_RESULT + jne clp_render_header + mov ecx,clpSelected3D + cmp ecx,clpCount3D + jae clp_render_header + mov eax,clpMasks3D[ecx*4] + mov selectedMask,eax + xor esi,esi +clp_render_highlight: + mov eax,1 + mov ecx,esi + shl eax,cl + test selectedMask,eax + jz clp_render_next_cell + mov eax,esi + xor edx,edx + mov ecx,5 + div ecx + imul eax,28 + add eax,63 + mov cellY,eax + mov ebx,clpColumns3D[edx*4] + shr ebx,1 + mov cellX,ebx + ; Border strips do not paint over the transparent symbol interior. + invoke DrawBox,ebx,cellY,28,1,00E9CE71h + mov eax,cellY + add eax,27 + invoke DrawBox,ebx,eax,28,1,00E9CE71h + invoke DrawBox,ebx,cellY,1,28,00E9CE71h + add ebx,27 + invoke DrawBox,ebx,cellY,1,28,00E9CE71h +clp_render_next_cell: + inc esi + cmp esi,15 + jb clp_render_highlight +clp_render_header: + invoke DrawBox,0,0,320,19,00151D20h + invoke DrawString8x8,8,6,OFFSET clpTitle3D,00E8D7ADh + invoke DrawString8x8,108,6,OFFSET textBank3D,00A8DDB9h + invoke FormatNumber,bankroll,OFFSET hudNumBuffer + invoke DrawString8x8,157,6,OFFSET hudNumBuffer,00F4F3E8h + invoke DrawBoxBorder,252,3,60,14,002C3637h,00687672h,1 + invoke DrawString8x8,258,6,OFFSET cardExitButton3D,00E9D8B0h + invoke DrawBox,63,160,194,26,00151D20h + mov ebx,OFFSET slotReadyText3D + cmp clpState3D,SLOT_SPIN + jne @F + mov ebx,OFFSET slotRollingText3D +@@: + cmp clpState3D,SLOT_RESULT + jne @F + mov ebx,OFFSET clpNoCombo3D + cmp clpCount3D,0 + je @F + mov ebx,OFFSET clpTotalText3D +@@: + cmp clpError3D,0 + je @F + mov ebx,OFFSET slotNoMoney3D +@@: + cmp clpLeave3D,0 + je @F + mov ebx,OFFSET slotExitText3D +@@: + invoke DrawString8x8,72,163,ebx,00E8D7ADh + cmp clpState3D,SLOT_RESULT + jne clp_render_footer + cmp clpCount3D,0 + je clp_render_footer + invoke DrawString8x8,208,163,OFFSET strMultiplier3D,00A8DDB9h + invoke FormatNumber,clpTotal3D,OFFSET hudNumBuffer + invoke DrawString8x8,216,163,OFFSET hudNumBuffer,00A8DDB9h + invoke CloverComboText3D,clpSelected3D + invoke DrawString8x8,72,175,eax,00F4F3E8h + mov ecx,clpSelected3D + invoke FormatNumber,clpMults3D[ecx*4],OFFSET hudNumBuffer + invoke DrawString8x8,208,175,OFFSET strMultiplier3D,00E9CE71h + invoke DrawString8x8,216,175,OFFSET hudNumBuffer,00E9CE71h + invoke DrawBoxBorder,232,170,18,15,0025372Ch,00E9CE71h,1 + invoke DrawBoxBorder,292,170,18,15,0025372Ch,00E9CE71h,1 + invoke DrawString8x8,237,174,OFFSET clpLeft3D,00E9CE71h + invoke DrawString8x8,297,174,OFFSET clpRight3D,00E9CE71h + mov eax,clpSelected3D + inc eax + invoke FormatNumber,eax,OFFSET hudNumBuffer + invoke DrawString8x8,252,174,OFFSET hudNumBuffer,00F4F3E8h + invoke DrawString8x8,268,174,OFFSET clpSlash3D,00F4F3E8h + invoke FormatNumber,clpCount3D,OFFSET hudNumBuffer + invoke DrawString8x8,276,174,OFFSET hudNumBuffer,00F4F3E8h +clp_render_footer: + invoke DrawBox,0,198,320,42,00151D20h + invoke DrawString8x8,11,201,OFFSET slotBetText3D,00E8D7ADh + invoke FormatNumber,clpBet3D,OFFSET hudNumBuffer + invoke DrawString8x8,75,201,OFFSET hudNumBuffer,00F4F3E8h + cmp clpState3D,SLOT_RESULT + jne @F + invoke DrawSlotTotals3D,clpGross3D,clpStake3D,120 +@@: + mov ebx,1 + cmp clpState3D,SLOT_SPIN + jne @F + xor ebx,ebx +@@: + invoke DrawBoxBorder,11,222,18,16,0025372Ch,00EEE5CDh,1 + invoke DrawBoxBorder,35,222,18,16,0025372Ch,00EEE5CDh,1 + invoke DrawString8x8,16,226,OFFSET tableMinusText3D,00EEE5CDh + invoke DrawString8x8,40,226,OFFSET tablePlusText3D,00EEE5CDh + invoke DrawTableButton3D,120,OFFSET slotSpinText3D,ebx + invoke DrawTableButton3D,202,OFFSET slotPayText3D,ebx + cmp clpPaytable3D,0 + je clp_render_done + invoke DrawBoxBorder,18,22,284,200,00151D20h,00D1B16Eh,1 + invoke DrawString8x8,76,29,OFFSET slotPayTitle3D,00E8D7ADh + invoke DrawString8x8,28,44,OFFSET clpSymbolsText3D,00A8DDB9h + invoke DrawString8x8,164,44,OFFSET clpShapesText3D,00A8DDB9h + xor esi,esi +clp_render_pay_row: + mov edi,esi + imul edi,11 + add edi,58 + mov eax,clpShapeNames3D[esi*4] + invoke DrawString8x8,156,edi,eax,00F4F3E8h + invoke FormatNumber,clpShapeFactors3D[esi*4],OFFSET hudNumBuffer + invoke DrawString8x8,280,edi,OFFSET hudNumBuffer,00E8D7ADh + cmp esi,7 + jae clp_render_pay_next + mov eax,clpSymbolNames3D[esi*4] + invoke DrawString8x8,28,edi,eax,00F4F3E8h + invoke FormatNumber,slotSymbolValues[esi*4],OFFSET hudNumBuffer + invoke DrawString8x8,132,edi,OFFSET hudNumBuffer,00E8D7ADh +clp_render_pay_next: + inc esi + cmp esi,11 + jb clp_render_pay_row + invoke DrawString8x8,28,181,OFFSET clpOverlapText3D,00A8DDB9h + invoke DrawString8x8,28,193,OFFSET slotPayNote3D,00A8DDB9h + invoke DrawBoxBorder,112,204,96,15,003B6C59h,00E9D8B0h,1 + invoke DrawString8x8,128,207,OFFSET slotCloseText3D,00E9D8B0h +clp_render_done: + ret +RenderNativeClover3D ENDP diff --git a/src_graphics/native_clover_data.inc b/src_graphics/native_clover_data.inc new file mode 100644 index 0000000..25f2b8e --- /dev/null +++ b/src_graphics/native_clover_data.inc @@ -0,0 +1,80 @@ +MODE_CLOVER equ 21 +CLP_CELL equ 56 +CLP_TOP equ 126 +CLP_BOTTOM equ 294 +InitNativeClover3D PROTO +FreeNativeClover3D PROTO +StartNativeClover3D PROTO +HandleNativeClover3D PROTO +RenderNativeClover3D PROTO +CloverEscape3D PROTO +SettleNativeClover3D PROTO +CloverEvaluate3D PROTO +CloverReelPosition3D PROTO :DWORD +DrawCloverSymbol3D PROTO :DWORD,:DWORD,:DWORD +DrawCloverReel3D PROTO :DWORD +CloverComboText3D PROTO :DWORD +.data +clpCabinet3D AnimPack3D <> +clpSymbols3D AnimPack3D <> +clpCabinetPath3D db "assets\animations\clover\cabinet-v1.bin",0 +clpSymbolsPath3D db "assets\animations\clover\symbols-v1.bin",0 +clpState3D dd 0 +clpTimer3D dd 0 +clpBet3D dd 50 +clpBetIndex3D dd 1 +clpStake3D dd 0 +clpGross3D dd 0 +clpTotal3D dd 0 +clpWinMask3D dd 0 +clpCount3D dd 0 +clpSelected3D dd 0 +clpJackpot3D dd 0 +clpPaytable3D dd 0 +clpLeave3D dd 0 +clpError3D dd 0 +clpGrid3D dd 0,1,2,3,4,5,6,0,1,2,3,4,5,6,0 +clpTape3D dd 320 dup(0) +clpNames3D dd 32 dup(0) +clpMults3D dd 32 dup(0) +clpMasks3D dd 32 dup(0) +clpDurations3D dd 1800,2200,2600,3000,3400 +clpSteps3D dd 28,32,36,40,44 +clpColumns3D dd 144,216,288,360,432 +clpTitle3D db 202,203,197,194,197,208,32,53,120,51,0 +clpTotalText3D db 204,205,206,198,200,210,197,203,220,0 +clpNoCombo3D db 205,197,210,32,202,206,204,193,200,205,192,214,200,201,0 +clpSymbolsText3D db 209,200,204,194,206,203,0 +clpShapesText3D db 212,200,195,211,208,192,0 +clpOverlapText3D db 212,200,195,211,208,192,32,120,32,209,200,204,194,206,203,59,32,209,211,204,204,192,0 +clpShape0 db 208,223,196,32,51,0 +clpShape1 db 208,223,196,32,52,0 +clpShape2 db 208,223,196,32,53,0 +clpShape3 db 194,197,208,210,200,202,192,203,220,0 +clpShape4 db 196,200,192,195,206,205,192,203,220,0 +clpShape5 db 209,210,208,197,203,202,192,32,194,194,197,208,213,0 +clpShape6 db 209,210,208,197,203,202,192,32,194,205,200,199,0 +clpShape7 db 194,197,208,213,205,200,201,32,208,223,196,0 +clpShape8 db 205,200,198,205,200,201,32,208,223,196,0 +clpShape9 db 195,203,192,199,0 +clpShape10 db 196,198,197,202,207,206,210,0 +clpSymbol0 db 202,203,197,194,197,208,0 +clpSymbol1 db 203,200,204,206,205,0 +clpSymbol2 db 194,200,216,205,223,0 +clpSymbol3 db 202,206,203,206,202,206,203,0 +clpSymbol4 db 192,203,204,192,199,0 +clpSymbol5 db 209,211,205,196,211,202,0 +clpSymbol6 db 209,197,204,220,0 +clpShapeNames3D dd OFFSET clpShape0,OFFSET clpShape1,OFFSET clpShape2 + dd OFFSET clpShape3,OFFSET clpShape4,OFFSET clpShape5,OFFSET clpShape6 + dd OFFSET clpShape7,OFFSET clpShape8,OFFSET clpShape9,OFFSET clpShape10 +clpLegacyNames3D dd OFFSET slotComboHorM,OFFSET slotComboHorL,OFFSET slotComboHorXL + dd OFFSET slotComboVertM,OFFSET slotComboDiagM,OFFSET slotComboUp,OFFSET slotComboDown + dd OFFSET slotComboSky,OFFSET slotComboEarth,OFFSET slotComboEye,OFFSET slotComboJackpot +clpShapeFactors3D dd 1,2,3,1,1,4,4,7,7,8,10 +clpSymbolNames3D dd OFFSET clpSymbol0,OFFSET clpSymbol1,OFFSET clpSymbol2,OFFSET clpSymbol3 + dd OFFSET clpSymbol4,OFFSET clpSymbol5,OFFSET clpSymbol6 +clpLeft3D db "<",0 +clpRight3D db ">",0 +clpSlash3D db "/",0 +.code diff --git a/src_graphics/native_coin.inc b/src_graphics/native_coin.inc index fbc4d8a..9742dad 100644 --- a/src_graphics/native_coin.inc +++ b/src_graphics/native_coin.inc @@ -98,6 +98,10 @@ coin_settle_loss: invoke PlayCasinoSound3D,OFFSET soundLose,0,1 coin_settle_save: mov coin3d_state,COIN_RESULT + xor eax,eax + cmp coin3d_win,0 + setne al + invoke NpcRecordRound3D,0,eax call SaveProgress3D coin_settle_done: ret diff --git a/src_graphics/native_durak.inc b/src_graphics/native_durak.inc index 1338857..0030bfd 100644 --- a/src_graphics/native_durak.inc +++ b/src_graphics/native_durak.inc @@ -133,6 +133,10 @@ dk_settle_loss: invoke PlayCasinoSound3D, OFFSET soundRoundLose, 0, 1 dk_settle_save: call ClearKeys3D + xor eax,eax + cmp dkOutcome3D,0 + sete al + invoke NpcRecordRound3D,5,eax call SaveProgress3D dk_settle_done: ret diff --git a/src_graphics/native_poker.inc b/src_graphics/native_poker.inc index bda384e..3e0d3cf 100644 --- a/src_graphics/native_poker.inc +++ b/src_graphics/native_poker.inc @@ -265,6 +265,10 @@ poker_fold_player: 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 @@ -362,6 +366,10 @@ poker_showdown_tie: 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 diff --git a/src_graphics/native_slots.inc b/src_graphics/native_slots.inc index 9e6f6ce..a16e6fa 100644 --- a/src_graphics/native_slots.inc +++ b/src_graphics/native_slots.inc @@ -135,6 +135,12 @@ SettleNativeSlots3D PROC uses esi jne slot_settle_done invoke SlotMultiplier3D,slotReel1,slotReel2,slotReel3 mul slotStake3D + mov ecx,1000000000 + sub ecx,bankroll + cmp eax,ecx + jbe @F + mov eax,ecx +@@: mov slotWinAmount,eax add bankroll,eax jc slot_settle_cap @@ -153,9 +159,19 @@ slot_settle_stops: mov slotSpinTimer,3000 mov slotSpinState,SLOT_RESULT mov slotEffects3D,0 + xor eax,eax + mov ecx,slotWinAmount + cmp ecx,slotStake3D + seta al + invoke NpcRecordRound3D,4,eax call SaveProgress3D - cmp slotWinAmount,0 - je slot_settle_loss + mov eax,slotWinAmount + cmp eax,slotStake3D + jb slot_settle_loss + jne @F + invoke PlayCasinoSound3D,0,0,0 + jmp slot_settle_exit +@@: invoke PlayCasinoSound3D,OFFSET soundRoundWin,0,1 jmp slot_settle_exit slot_settle_loss: @@ -476,8 +492,9 @@ slot_render_reels: invoke DrawBox,232,94,4,3,00E9CE71h cmp slotSpinState,SLOT_RESULT jne slot_render_header - cmp slotWinAmount,0 - je slot_render_header + mov eax,slotWinAmount + cmp eax,slotStake3D + jbe slot_render_header mov eax,slotEffects3D xor edx,edx mov ecx,200 @@ -501,7 +518,10 @@ slot_render_header: cmp slotSpinState,SLOT_RESULT jne @F mov ebx,OFFSET slotLoseText3D - cmp slotWinAmount,0 + mov eax,slotWinAmount + cmp eax,slotStake3D + jb @F + mov ebx,OFFSET slotRefundText3D je @F mov ebx,OFFSET slotWinText3D @@: @@ -518,15 +538,22 @@ slot_render_header: invoke DrawString8x8,104,149,ebx,00E8D7ADh cmp slotSpinState,SLOT_RESULT jne slot_render_controls - cmp slotWinAmount,0 - je slot_render_controls + cmp ebx,OFFSET slotWinText3D + je @F + cmp ebx,OFFSET slotRefundText3D + jne slot_render_controls +@@: invoke FormatNumber,slotWinAmount,OFFSET hudNumBuffer invoke DrawString8x8,164,149,OFFSET hudNumBuffer,00A8DDB9h slot_render_controls: - invoke DrawBox,0,202,320,38,00151D20h - invoke DrawString8x8,11,207,OFFSET slotBetText3D,00E8D7ADh + invoke DrawBox,0,198,320,42,00151D20h + invoke DrawString8x8,11,201,OFFSET slotBetText3D,00E8D7ADh invoke FormatNumber,slotBet,OFFSET hudNumBuffer - invoke DrawString8x8,83,207,OFFSET hudNumBuffer,00F4F3E8h + invoke DrawString8x8,75,201,OFFSET hudNumBuffer,00F4F3E8h + cmp slotSpinState,SLOT_RESULT + jne @F + invoke DrawSlotTotals3D,slotWinAmount,slotStake3D,120 +@@: mov ebx,1 cmp slotSpinState,SLOT_SPIN jne @F @@ -547,12 +574,12 @@ slot_render_controls: je slot_render_done invoke DrawBoxBorder,30,23,260,198,00151D20h,00D1B16Eh,1 invoke DrawString8x8,76,31,OFFSET slotPayTitle3D,00E8D7ADh - invoke DrawString8x8,66,48,OFFSET slotTripleText3D,00A8DDB9h + invoke DrawString8x8,42,48,OFFSET slotTripleText3D,00A8DDB9h xor esi,esi slot_render_pay_row: mov edi,esi - imul edi,14 - add edi,66 + imul edi,12 + add edi,62 mov eax,slotSymbolNames3D[esi*4] invoke DrawString8x8,62,edi,eax,00F4F3E8h invoke FormatNumber,slotTriple3D[esi*4],OFFSET hudNumBuffer @@ -561,10 +588,39 @@ slot_render_pay_row: inc esi cmp esi,8 jb slot_render_pay_row - invoke DrawString8x8,62,181,OFFSET slotPairText3D,00A8DDB9h - invoke DrawString8x8,62,192,OFFSET slotCherryPair3D,00A8DDB9h + invoke DrawString8x8,62,160,OFFSET slotPairText3D,00A8DDB9h + invoke DrawString8x8,62,173,OFFSET slotCherryPair3D,00A8DDB9h + invoke DrawString8x8,42,188,OFFSET slotPayNote3D,00A8DDB9h invoke DrawBoxBorder,112,204,96,15,003B6C59h,00E9D8B0h,1 invoke DrawString8x8,128,207,OFFSET slotCloseText3D,00E9D8B0h slot_render_done: ret RenderNativeSlots3D ENDP + +; Gross is the actual credited sum, including any returned stake. +DrawSlotTotals3D PROC uses ebx esi edi gross:DWORD,stake:DWORD,x:DWORD + mov ebx,x + lea edi,[ebx+72] + invoke DrawString8x8,ebx,201,OFFSET slotWinText3D,00E8D7ADh + invoke FormatNumber,gross,OFFSET hudNumBuffer + invoke DrawString8x8,edi,201,OFFSET hudNumBuffer,00F4F3E8h + invoke DrawString8x8,ebx,211,OFFSET slotNetText3D,00E8D7ADh + mov eax,gross + sub eax,stake + mov esi,00D0D4D0h + lea ebx,slotNetBuffer3D + test eax,eax + jz totals_format + mov BYTE PTR [ebx],'+' + mov esi,00A8DDB9h + jns @F + mov BYTE PTR [ebx],'-' + mov esi,00EE9988h + neg eax +@@: + inc ebx +totals_format: + invoke FormatNumber,eax,ebx + invoke DrawString8x8,edi,211,OFFSET slotNetBuffer3D,esi + ret +DrawSlotTotals3D ENDP diff --git a/src_graphics/native_slots_data.inc b/src_graphics/native_slots_data.inc index ce2863f..60a40c3 100644 --- a/src_graphics/native_slots_data.inc +++ b/src_graphics/native_slots_data.inc @@ -17,6 +17,7 @@ SlotExitMouse3D PROTO SlotReelPosition3D PROTO :DWORD DrawSlotReel3D PROTO :DWORD DrawSlotSymbol3D PROTO :DWORD,:DWORD,:DWORD +DrawSlotTotals3D PROTO :DWORD,:DWORD,:DWORD .data slotCabinetPack3D AnimPack3D <> slotSymbolsPack3D AnimPack3D <> @@ -38,6 +39,9 @@ slotLeaveAfter3D dd 0 slotPaytable3D dd 0 slotError3D dd 0 slotEffects3D dd 0 +slotNetBuffer3D db 16 dup(0) +slotRefundText3D db 194,206,199,194,208,192,210,0 +slotNetText3D db 200,210,206,195,0 slotTitle3D db "777",0 slotSpinText3D db 194,208,192,217,192,210,220,0 slotPayText3D db 194,219,207,203,192,210,219,0 @@ -50,7 +54,7 @@ slotRollingText3D db 194,208,192,217,197,205,200,197,0 slotExitText3D db 199,192,194,197,208,216,197,205,200,197,0 slotLoseText3D db 207,208,206,200,195,208,219,216,0 slotNoMoney3D db 205,197,210,32,196,197,205,197,195,0 -slotTripleText3D db 210,208,200,32,209,200,204,194,206,203,192,32,40,209,206,32,209,210,192,194,202,206,201,41,0 +slotTripleText3D db 214,197,205,210,208,58,32,210,208,200,32,206,196,200,205,192,202,206,194,219,213,0 strMultiplier3D db "x",0 slotPairText3D db 203,222,193,192,223,32,207,192,208,192,32,32,32,32,"x1",0 slotCherryPair3D db 207,192,208,192,32,194,200,216,197,205,32,32,32,32,"x2",0 diff --git a/src_graphics/native_wheel.inc b/src_graphics/native_wheel.inc index 468c8e2..049fb47 100644 --- a/src_graphics/native_wheel.inc +++ b/src_graphics/native_wheel.inc @@ -132,6 +132,11 @@ wheel_bank_cap: mov bankroll, 1000000000 @@: mov roulState, 2 + xor eax,eax + mov ecx,wheelReturn3D + cmp ecx,wheelStake3D + seta al + invoke NpcRecordRound3D,3,eax call SaveProgress3D wheel_settle_done: ret @@ -740,7 +745,7 @@ wheel_ball_place: cmp roulState,2 jne wheel_scene_done invoke DrawWheelLabels3D,centerX,centerY,radiusX,radiusY,wheelRotorAngle3D - invoke DrawBuckshotPanel3D,278,245,84,61,002D211Bh + invoke DrawWheelBox3D,278,245,84,61,002D211Bh invoke DrawBuckshotText3D,296,253,OFFSET wheelLandedText3D,00E5D29Eh mov ecx,00F4E7C8h cmp wheelResult3D,0 @@ -755,9 +760,56 @@ wheel_scene_done: ret RenderWheelScene3D ENDP +; Exact framebuffer rectangles avoid the two-pixel rounding of the logical UI grid. +DrawWheelBox3D PROC uses ebx esi edi x:DWORD,y:DWORD,w:DWORD,h:DWORD,ink:DWORD + local bottom:DWORD + mov esi,x + test esi,esi + jns @F + xor esi,esi +@@: + mov eax,x + add eax,w + cmp eax,SCREEN_W + jle @F + mov eax,SCREEN_W +@@: + sub eax,esi + jle wheel_box_done + mov ebx,eax + mov edx,y + test edx,edx + jns @F + xor edx,edx +@@: + mov eax,y + add eax,h + cmp eax,SCREEN_H + jle @F + mov eax,SCREEN_H +@@: + cmp eax,edx + jle wheel_box_done + mov bottom,eax +wheel_box_row: + imul edi,edx,SCREEN_W + add edi,esi + lea edi,screenBuffer[edi*4] + mov eax,ink + mov ecx,ebx + rep stosd + inc edx + cmp edx,bottom + jl wheel_box_row +wheel_box_done: + ret +DrawWheelBox3D ENDP + ; Upright screen-space digits retain their shape when the wheel is projected. DrawWheelDigit3D PROC uses ebx esi edi x:DWORD,y:DWORD,digit:DWORD,scale:DWORD,ink:DWORD local row:DWORD,column:DWORD,bits:DWORD,px:DWORD,py:DWORD + cmp scale,0 + je wheel_digit_done cmp digit,9 ja wheel_digit_done mov eax,digit @@ -780,7 +832,7 @@ wheel_digit_column: imul eax,scale add eax,y mov py,eax - invoke DrawBuckshotPanel3D,px,py,scale,scale,ink + invoke DrawWheelBox3D,px,py,scale,scale,ink wheel_digit_next: shl bits,1 inc column @@ -885,10 +937,10 @@ wheel_label_highlight: mov edi,wheelNumberY3D[esi*4] sub ebx,9 sub edi,6 - invoke DrawBuckshotPanel3D,ebx,edi,18,12,00E5C978h + invoke DrawWheelBox3D,ebx,edi,18,12,00E5C978h inc ebx inc edi - invoke DrawBuckshotPanel3D,ebx,edi,16,10,00121916h + invoke DrawWheelBox3D,ebx,edi,16,10,00121916h mov eax,wheelNumberY3D[esi*4] sub eax,5 invoke DrawWheelValue3D,wheelNumberX3D[esi*4],eax,wheelResult3D,2,00FFF8DEh diff --git a/src_graphics/native_wheel_data.inc b/src_graphics/native_wheel_data.inc index 972a678..6279b25 100644 --- a/src_graphics/native_wheel_data.inc +++ b/src_graphics/native_wheel_data.inc @@ -10,6 +10,7 @@ WheelTravel3D PROTO :DWORD,:DWORD,:DWORD DrawNativeWheelDisc3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD RenderWheelScene3D PROTO DrawWheelDigit3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD +DrawWheelBox3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD DrawWheelValue3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD DrawWheelLabels3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD .data diff --git a/src_graphics/npc_contracts.inc b/src_graphics/npc_contracts.inc new file mode 100644 index 0000000..be652d5 --- /dev/null +++ b/src_graphics/npc_contracts.inc @@ -0,0 +1,437 @@ +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,npcNames3D[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 diff --git a/src_graphics/npc_life.inc b/src_graphics/npc_life.inc new file mode 100644 index 0000000..8842209 --- /dev/null +++ b/src_graphics/npc_life.inc @@ -0,0 +1,581 @@ +; The visible people and the user's personality records share the same positions. +InitNpcLife3D PROC uses ebx esi edi + xor esi,esi + mov npcLifeClock3D,0 + mov npcSelected3D,-1 +npc_life_init: + imul ebx,esi,SIZEOF NpcLife3D + mov npcLife3D[ebx].identity,esi + mov npcLife3D[ebx].state,NPC_STAND + mov eax,esi + imul eax,900 + add eax,1800 + mov npcLife3D[ebx].remaining,eax + mov npcLife3D[ebx].routeStep,esi + mov npcLife3D[ebx].pathCount,0 + mov npcLife3D[ebx].remainder,0 + mov npcLife3D[ebx].poseClock,0 + mov eax,npcStartDest3D[esi*4] + mov npcLife3D[ebx].destination,eax + imul edi,esi,SIZEOF NpcMindEntity + mov ecx,npcDestX3D[eax*4] + mov casinoNpcs3D[edi].posX,ecx + mov ecx,npcDestY3D[eax*4] + mov casinoNpcs3D[edi].posY,ecx + cmp eax,7 + je @F + cmp eax,8 + jne npc_life_init_next +@@: + mov npcLife3D[ebx].state,NPC_SIT +npc_life_init_next: + inc esi + cmp esi,NPC_LIFE_COUNT + jb npc_life_init + mov npcLifeReady3D,1 + ret +InitNpcLife3D ENDP + +; BFS visits each tile at most once. Body clearance includes furniture and the stage. +NpcTryCell3D PROC uses ebx esi cell:DWORD,parent:DWORD + mov esi,cell + cmp esi,NPC_PATH_CAP + jae npc_cell_done + cmp npcParents3D[esi*4],-1 + jne npc_cell_done + mov eax,esi + and eax,31 + shl eax,16 + add eax,FP_HALF + mov edx,esi + shr edx,5 + shl edx,16 + add edx,FP_HALF + invoke CanWalk3D,eax,edx + test eax,eax + jz npc_cell_done + mov eax,parent + mov npcParents3D[esi*4],eax + mov ebx,npcSearchTail3D + cmp ebx,NPC_PATH_CAP + jae npc_cell_done + mov npcQueue3D[ebx*4],esi + inc npcSearchTail3D +npc_cell_done: + ret +NpcTryCell3D ENDP + +NpcPlanPath3D PROC uses ebx esi edi slot:DWORD,destination:DWORD + local firstCell:DWORD,currentCell:DWORD,pathBase:DWORD + cmp slot,NPC_LIFE_COUNT + jae npc_plan_fail + cmp destination,NPC_DEST_COUNT + jae npc_plan_fail + imul ebx,slot,SIZEOF NpcLife3D + mov npcLife3D[ebx].pathCount,0 + imul esi,slot,SIZEOF NpcMindEntity + mov eax,casinoNpcs3D[esi].posY + sar eax,16 + shl eax,5 + mov ecx,casinoNpcs3D[esi].posX + sar ecx,16 + add eax,ecx + cmp eax,NPC_PATH_CAP + jae npc_plan_fail + mov firstCell,eax + mov ecx,destination + mov eax,npcDestY3D[ecx*4] + sar eax,16 + shl eax,5 + mov edx,npcDestX3D[ecx*4] + sar edx,16 + add eax,edx + mov npcSearchGoal3D,eax + lea edi,npcParents3D + mov ecx,NPC_PATH_CAP + mov eax,-1 + rep stosd + mov eax,firstCell + mov npcParents3D[eax*4],eax + mov npcQueue3D,eax + mov npcSearchHead3D,0 + mov npcSearchTail3D,1 +npc_plan_search: + mov eax,npcSearchHead3D + cmp eax,npcSearchTail3D + jae npc_plan_fail + mov esi,npcQueue3D[eax*4] + inc npcSearchHead3D + cmp esi,npcSearchGoal3D + je npc_plan_found + mov eax,esi + and eax,31 + test eax,eax + jz @F + lea eax,[esi-1] + invoke NpcTryCell3D,eax,esi +@@: + mov eax,esi + and eax,31 + cmp eax,31 + je @F + lea eax,[esi+1] + invoke NpcTryCell3D,eax,esi +@@: + cmp esi,32 + jb @F + lea eax,[esi-32] + invoke NpcTryCell3D,eax,esi +@@: + cmp esi,NPC_PATH_CAP-32 + jae npc_plan_search + lea eax,[esi+32] + invoke NpcTryCell3D,eax,esi + jmp npc_plan_search +npc_plan_found: + mov eax,slot + imul eax,NPC_PATH_CAP*4 + add eax,OFFSET npcPaths3D + mov pathBase,eax + xor edi,edi +npc_plan_reverse: + cmp esi,firstCell + je npc_plan_success + cmp edi,NPC_PATH_CAP + jae npc_plan_fail + mov edx,pathBase + mov [edx+edi*4],esi + inc edi + mov esi,npcParents3D[esi*4] + jmp npc_plan_reverse +npc_plan_success: + mov npcLife3D[ebx].pathCount,edi + mov eax,destination + mov npcLife3D[ebx].destination,eax + mov eax,1 + ret +npc_plan_fail: + xor eax,eax + ret +NpcPlanPath3D ENDP + +NpcCanStep3D PROC uses ebx esi slot:DWORD,px:DWORD,py:DWORD + invoke CanWalk3D,px,py + test eax,eax + jz npc_space_done + mov eax,px + sub eax,playerX + jns @F + neg eax +@@: + cmp eax,FP_1*3/10 + jae npc_space_people + mov eax,py + sub eax,playerY + jns @F + neg eax +@@: + cmp eax,FP_1*3/10 + jb npc_space_blocked +npc_space_people: + xor esi,esi +npc_space_person: + cmp esi,slot + je npc_space_next + imul ebx,esi,SIZEOF NpcLife3D + cmp npcLife3D[ebx].state,NPC_AWAY + je npc_space_next + imul ebx,esi,SIZEOF NpcMindEntity + mov eax,px + sub eax,casinoNpcs3D[ebx].posX + jns @F + neg eax +@@: + cmp eax,FP_1*2/5 + jae npc_space_next + mov eax,py + sub eax,casinoNpcs3D[ebx].posY + jns @F + neg eax +@@: + cmp eax,FP_1*2/5 + jb npc_space_blocked +npc_space_next: + inc esi + cmp esi,NPC_LIFE_COUNT + jb npc_space_person + mov eax,1 + ret +npc_space_blocked: + xor eax,eax +npc_space_done: + ret +NpcCanStep3D ENDP + +; Millisecond movement, carrying the remainder and consuming whole route cells. +NpcMove3D PROC uses ebx esi edi slot:DWORD,milliseconds:DWORD + local budget:DWORD,wx:DWORD,wy:DWORD,mind:DWORD,pathBase:DWORD + imul ebx,slot,SIZEOF NpcLife3D + imul eax,slot,SIZEOF NpcMindEntity + lea esi,casinoNpcs3D[eax] + mov mind,esi + mov eax,slot + imul eax,NPC_PATH_CAP*4 + add eax,OFFSET npcPaths3D + mov pathBase,eax + mov eax,milliseconds + mov ecx,55000 + mul ecx + add eax,npcLife3D[ebx].remainder + adc edx,0 + mov ecx,1000 + div ecx + mov npcLife3D[ebx].remainder,edx + mov budget,eax +npc_move_cell: + mov eax,npcLife3D[ebx].pathCount + test eax,eax + jz npc_move_arrived + dec eax + mov edx,pathBase + mov edi,[edx+eax*4] + mov eax,edi + and eax,31 + shl eax,16 + add eax,FP_HALF + mov wx,eax + mov eax,edi + shr eax,5 + shl eax,16 + add eax,FP_HALF + mov wy,eax + mov esi,mind + mov eax,wx + sub eax,[esi].NpcMindEntity.posX + mov edi,1 + test eax,eax + jns @F + neg eax + mov edi,-1 +@@: + test eax,eax + jz npc_move_y + cmp eax,budget + jbe @F + mov eax,budget +@@: + sub budget,eax + imul eax,edi + add eax,[esi].NpcMindEntity.posX + mov wx,eax + invoke NpcCanStep3D,slot,wx,[esi].NpcMindEntity.posY + test eax,eax + jz npc_move_blocked + mov eax,wx + mov [esi].NpcMindEntity.posX,eax +npc_move_y: + mov eax,wy + sub eax,[esi].NpcMindEntity.posY + mov edi,1 + test eax,eax + jns @F + neg eax + mov edi,-1 +@@: + cmp eax,budget + jbe @F + mov eax,budget +@@: + sub budget,eax + imul eax,edi + add eax,[esi].NpcMindEntity.posY + mov wy,eax + invoke NpcCanStep3D,slot,[esi].NpcMindEntity.posX,wy + test eax,eax + jz npc_move_blocked + mov eax,wy + mov [esi].NpcMindEntity.posY,eax + mov edx,pathBase + mov eax,npcLife3D[ebx].pathCount + dec eax + mov edi,[edx+eax*4] + mov eax,[esi].NpcMindEntity.posX + sub eax,FP_HALF + sar eax,16 + mov edx,[esi].NpcMindEntity.posY + sub edx,FP_HALF + sar edx,16 + shl edx,5 + add eax,edx + cmp eax,edi + jne npc_move_done + ; Integer cell membership is insufficient: finish at the exact cell centre. + mov eax,edi + and eax,31 + shl eax,16 + add eax,FP_HALF + cmp eax,[esi].NpcMindEntity.posX + jne npc_move_done + mov eax,edi + shr eax,5 + shl eax,16 + add eax,FP_HALF + cmp eax,[esi].NpcMindEntity.posY + jne npc_move_done + dec npcLife3D[ebx].pathCount + cmp budget,0 + jne npc_move_cell + cmp npcLife3D[ebx].pathCount,0 + jne npc_move_done +npc_move_arrived: + mov eax,npcLife3D[ebx].destination + mov npcLife3D[ebx].state,NPC_STAND + mov npcLife3D[ebx].remaining,3500 + cmp eax,0 + jne @F + mov npcLife3D[ebx].state,NPC_AWAY + mov npcLife3D[ebx].remaining,4500 + jmp npc_move_done +@@: + cmp eax,7 + je @F + cmp eax,8 + jne npc_move_done +@@: + mov npcLife3D[ebx].state,NPC_SIT + mov npcLife3D[ebx].remaining,12000 + jmp npc_move_done +npc_move_blocked: + mov npcLife3D[ebx].state,NPC_STAND + mov npcLife3D[ebx].remaining,1000 + mov npcLife3D[ebx].pathCount,0 +npc_move_done: + ret +NpcMove3D ENDP + +UpdateNpcLife3D PROC uses ebx esi edi + local milliseconds:DWORD,destination:DWORD + cmp npcLifeReady3D,1 + jne npc_update_done + cmp hallLevel3D,0 + jne npc_update_done + mov eax,deltaTime3D + cmp eax,250 + jbe @F + mov eax,250 +@@: + mov milliseconds,eax + add npcLifeClock3D,eax + xor esi,esi +npc_update_person: + imul ebx,esi,SIZEOF NpcLife3D + mov eax,milliseconds + add npcLife3D[ebx].poseClock,eax + cmp npcLife3D[ebx].state,NPC_WALK + jne npc_update_wait + invoke NpcMove3D,esi,milliseconds + jmp npc_update_sync +npc_update_wait: + sub npcLife3D[ebx].remaining,eax + ja npc_update_sync + cmp npcLife3D[ebx].state,NPC_AWAY + jne npc_update_choose + mov eax,npcLife3D[ebx].identity + add eax,6 + cmp eax,NPC_IDENTITY_COUNT + jb @F + sub eax,NPC_IDENTITY_COUNT +@@: + mov npcLife3D[ebx].identity,eax + mov npcLife3D[ebx].state,NPC_STAND +npc_update_choose: + mov eax,npcLife3D[ebx].routeStep + xor edx,edx + mov ecx,NPC_DEST_COUNT + div ecx + mov eax,npcVisitRoute3D[edx*4] + mov destination,eax + inc npcLife3D[ebx].routeStep + invoke NpcPlanPath3D,esi,destination + test eax,eax + jz npc_update_retry + mov npcLife3D[ebx].state,NPC_WALK + jmp npc_update_sync +npc_update_retry: + mov npcLife3D[ebx].state,NPC_STAND + mov npcLife3D[ebx].remaining,1000 +npc_update_sync: + imul edi,esi,SIZEOF NpcMindEntity + mov eax,npcLife3D[ebx].state + mov casinoNpcs3D[edi].state,eax + mov eax,npcLife3D[ebx].remaining + mov casinoNpcs3D[edi].stateTimer,eax + ; Keep the old public position array coherent for existing world checks. + imul ecx,esi,SIZEOF CityProp3D + mov eax,casinoNpcs3D[edi].posX + mov hallGuests3D[ecx].posX,eax + mov eax,casinoNpcs3D[edi].posY + mov hallGuests3D[ecx].posY,eax + inc esi + cmp esi,NPC_LIFE_COUNT + jb npc_update_person +npc_update_done: + ret +UpdateNpcLife3D ENDP + +RenderNpcLife3D PROC uses ebx esi edi + cmp npcLifeReady3D,1 + jne npc_draw_done + xor esi,esi +npc_draw_depth: + imul ebx,esi,SIZEOF NpcMindEntity + invoke ProjectCityPoint3D,casinoNpcs3D[ebx].posX,casinoNpcs3D[ebx].posY + mov npcDrawDepth3D[esi*4],edx + mov npcDrawOrder3D[esi*4],esi + inc esi + cmp esi,NPC_LIFE_COUNT + jb npc_draw_depth + xor esi,esi +npc_draw_sort: + lea edi,[esi+1] +npc_draw_compare: + mov eax,npcDrawOrder3D[esi*4] + mov ebx,npcDrawDepth3D[eax*4] + mov ecx,npcDrawOrder3D[edi*4] + cmp ebx,npcDrawDepth3D[ecx*4] + jge @F + mov npcDrawOrder3D[esi*4],ecx + mov npcDrawOrder3D[edi*4],eax +@@: + inc edi + cmp edi,NPC_LIFE_COUNT + jb npc_draw_compare + inc esi + cmp esi,NPC_LIFE_COUNT-1 + jb npc_draw_sort + xor esi,esi +npc_draw_person: + mov eax,npcDrawOrder3D[esi*4] + imul ebx,eax,SIZEOF NpcLife3D + cmp npcLife3D[ebx].state,NPC_AWAY + je npc_draw_next + imul edi,eax,SIZEOF NpcMindEntity + mov eax,casinoNpcs3D[edi].posX + mov npcSprite3D.posX,eax + mov eax,casinoNpcs3D[edi].posY + mov npcSprite3D.posY,eax + mov npcSprite3D.worldW,FP_1*3/5 + mov npcSprite3D.worldH,FP_1*6/5 + mov npcSprite3D.frame,0 + cmp npcLife3D[ebx].identity,11 + jne @F + mov npcSprite3D.frame,4 +@@: + cmp npcLife3D[ebx].state,NPC_SIT + jne npc_draw_walk + mov npcSprite3D.frame,8 + cmp npcLife3D[ebx].identity,11 + jne @F + mov npcSprite3D.frame,10 +@@: + mov npcSprite3D.worldW,FP_1*4/5 + mov npcSprite3D.worldH,FP_1 + jmp npc_draw_sprite +npc_draw_walk: + cmp npcLife3D[ebx].state,NPC_WALK + jne npc_draw_sprite + mov eax,npcLife3D[ebx].poseClock + xor edx,edx + mov ecx,180 + div ecx + and eax,3 + add npcSprite3D.frame,eax +npc_draw_sprite: + invoke DrawCityObject3D,OFFSET npcSprite3D,0 +npc_draw_next: + inc esi + cmp esi,NPC_LIFE_COUNT + jb npc_draw_person +npc_draw_done: + ret +RenderNpcLife3D ENDP + +CheckNpcInteractions3D PROC uses ebx esi edi + local distance:DWORD,nearest:DWORD,deltaX:DWORD,deltaY:DWORD + cmp npcLifeReady3D,1 + jne npc_interact_done + cmp hallLevel3D,0 + jne npc_interact_done + cmp interactTargetId,0 + jne npc_interact_done + mov npcSelected3D,-1 + mov nearest,165000 + xor esi,esi +npc_interact_person: + imul ebx,esi,SIZEOF NpcLife3D + cmp npcLife3D[ebx].state,NPC_AWAY + je npc_interact_next + imul edi,esi,SIZEOF NpcMindEntity + mov eax,casinoNpcs3D[edi].posX + sub eax,playerX + sar eax,8 + mov deltaX,eax + imul eax,eax + mov distance,eax + mov eax,casinoNpcs3D[edi].posY + sub eax,playerY + sar eax,8 + mov deltaY,eax + imul eax,eax + add eax,distance + cmp eax,nearest + jae npc_interact_next + mov distance,eax + mov eax,playerDirX + sar eax,8 + imul eax,deltaX + mov edx,playerDirY + sar edx,8 + imul edx,deltaY + add eax,edx + cmp eax,6000 + jl npc_interact_next + ; Short, bounded line-of-sight test prevents talking through a wall. + mov ebx,1 +npc_interact_ray: + mov eax,deltaX + imul eax,ebx + shl eax,5 + add eax,playerX + sar eax,16 + mov edx,deltaY + imul edx,ebx + shl edx,5 + add edx,playerY + sar edx,16 + cmp eax,32 + jae npc_interact_next + cmp edx,32 + jae npc_interact_next + shl edx,5 + add edx,eax + mov ecx,worldMap3D + cmp BYTE PTR [ecx+edx],0 + jne npc_interact_next + inc ebx + cmp ebx,8 + jb npc_interact_ray + mov eax,distance + mov nearest,eax + mov npcSelected3D,esi +npc_interact_next: + inc esi + cmp esi,NPC_LIFE_COUNT + jb npc_interact_person + cmp npcSelected3D,-1 + je npc_interact_done + mov interactTargetId,INTERACT_NPC + mov interactPromptPtr,OFFSET npcTalkPrompt3D +npc_interact_done: + ret +CheckNpcInteractions3D ENDP diff --git a/src_graphics/npc_life_data.inc b/src_graphics/npc_life_data.inc new file mode 100644 index 0000000..7ea850d --- /dev/null +++ b/src_graphics/npc_life_data.inc @@ -0,0 +1,140 @@ +MODE_NPC_DIALOG equ 20 +IFDEF CASINO_ACTION_TEST +DeleteFileA PROTO :DWORD +ENDIF +INTERACT_NPC equ 40 +NPC_LIFE_COUNT equ 6 +NPC_IDENTITY_COUNT equ 12 +NPC_DEST_COUNT equ 10 +NPC_STAND equ 0 +NPC_WALK equ 1 +NPC_SIT equ 2 +NPC_AWAY equ 3 +NPC_PATH_CAP equ 1024 +InitNpcLife3D PROTO +UpdateNpcLife3D PROTO +RenderNpcLife3D PROTO +CheckNpcInteractions3D PROTO +OpenNpcDialog3D PROTO +HandleNpcDialog3D PROTO +RenderNpcDialog3D PROTO +CloseNpcDialog3D PROTO +NpcPlanPath3D PROTO :DWORD,:DWORD +NpcTryCell3D PROTO :DWORD,:DWORD +NpcMove3D PROTO :DWORD,:DWORD +NpcCanStep3D PROTO :DWORD,:DWORD,:DWORD +NpcRecordRound3D PROTO :DWORD,:DWORD +NpcEnsureJournal3D PROTO +NpcSaveJournal3D PROTO +NpcAcceptContract3D PROTO :DWORD +NpcClaimContract3D PROTO :DWORD +NpcContractType3D PROTO :DWORD +NpcDate3D PROTO +NpcNameText3D PROTO :DWORD +NpcLife3D STRUCT + identity dd ? + state dd ? + remaining dd ? + destination dd ? + routeStep dd ? + pathCount dd ? + remainder dd ? + poseClock dd ? +NpcLife3D ENDS +.data +npcLife3D NpcLife3D NPC_LIFE_COUNT dup(<>) +npcLifeReady3D dd 0 +npcLifeClock3D dd 0 +npcSelected3D dd -1 +npcDialogIdentity3D dd 0 +npcDialogError3D dd 0 +npcNameBuffer3D db 64 dup(0) +npcJournalIoError3D dd 0 +npcDestX3D dd 16*FP_1+FP_HALF,16*FP_1+FP_HALF,10*FP_1+FP_HALF,6*FP_1+FP_HALF,13*FP_1+FP_HALF + dd 21*FP_1+FP_HALF,7*FP_1+FP_HALF,6*FP_1+FP_HALF,16*FP_1+FP_HALF,16*FP_1+FP_HALF +npcDestY3D dd 28*FP_1+FP_HALF,17*FP_1+FP_HALF,13*FP_1+FP_HALF,14*FP_1+FP_HALF,9*FP_1+FP_HALF + dd 10*FP_1+FP_HALF,25*FP_1+FP_HALF,27*FP_1+FP_HALF,10*FP_1+FP_HALF,7*FP_1+FP_HALF +npcVisitRoute3D dd 1,5,8,2,3,6,7,9,1,0 +npcStartDest3D dd 1,2,3,6,8,7 +npcSprite3D CityProp3D <0,0,FP_1*3/5,FP_1*6/5,0,OFFSET hallPatrons3D> +npcDrawOrder3D dd NPC_LIFE_COUNT dup(0) +npcDrawDepth3D dd NPC_LIFE_COUNT dup(0) +npcJournalLoaded3D dd 0 +npcJournalPath3D db 260 dup(0) +npcJournalNextPath3D db 260 dup(0) +npcJournalSuffix3D db ".npc",0 +IFDEF CASINO_ACTION_TEST +npcJournalBasePtr3D dd OFFSET npcJournalTestBase3D +npcJournalTestBase3D db "build\arrival\fixtures\npc-default.dat",0 +ELSE +npcJournalBasePtr3D dd 0 +ENDIF +npcDateOverride3D dd 0 +npcSystemTime3D dw 8 dup(0) +; One bounded journal per profile; visitors 0..5 and 6..11 alternate at the entrance. +npcJournal3D LABEL DWORD +npcJournalMagic3D dd 3151504Eh +npcJournalDay3D dd 0 +npcAccepted3D dd 0 +npcClaimed3D dd 0 +npcProgress3D dd NPC_IDENTITY_COUNT dup(0) +npcJournalChecksum3D dd 0 +NPC_JOURNAL_SIZE equ $-npcJournal3D +npcJournalRead3D db NPC_JOURNAL_SIZE dup(0) +npcQuestGames3D dd -1,0,0,1,1,2,2,3,3,4,5,5 +npcQuestWins3D dd 0,0,1,0,1,0,1,0,1,0,0,1 +npcQuestGoals3D dd 3,3,1,2,1,2,1,3,1,3,1,1 +npcQuestRewards3D dd 150,150,350,250,500,350,700,250,500,150,300,700 +npcQuestTexts3D dd OFFSET npcQuest0,OFFSET npcQuest1,OFFSET npcQuest2,OFFSET npcQuest3 + dd OFFSET npcQuest4,OFFSET npcQuest5,OFFSET npcQuest6,OFFSET npcQuest7 + dd OFFSET npcQuest8,OFFSET npcQuest9,OFFSET npcQuest10,OFFSET npcQuest11 +npcNames3D dd OFFSET npcName0,OFFSET npcName1,OFFSET npcName2,OFFSET npcName3,OFFSET npcName4,OFFSET npcName5 + dd OFFSET npcName6,OFFSET npcName7,OFFSET npcName8,OFFSET npcName9,OFFSET npcName10,OFFSET npcName11 +npcGreetings3D dd OFFSET npcGreeting0,OFFSET npcGreeting1,OFFSET npcGreeting2 + dd OFFSET npcGreeting3,OFFSET npcGreeting4,OFFSET npcGreeting5 +npcName6 db 196,236,232,242,240,232,233,32,209,229,240,238,226,0 +npcName7 db 194,232,234,242,238,240,32,195,240,238,236,238,226,0 +npcName8 db 195,240,232,227,238,240,232,233,32,203,232,241,0 +npcName9 db 207,224,226,229,235,32,204,232,240,237,251,233,0 +npcName10 db 192,237,242,238,237,32,193,238,227,224,242,251,233,0 +npcName11 db 192,235,232,241,224,32,194,229,242,240,238,226,224,0 +npcGreeting0 db 207,240,238,226,229,240,232,236,32,242,226,238,254,32,226,251,228,229,240,230,234,243,63,0 +npcGreeting1 db 209,229,227,238,228,237,255,32,255,32,232,227,240,224,254,32,241,236,229,235,238,46,0 +npcGreeting2 db 211,228,224,247,224,32,235,254,225,232,242,32,242,229,240,239,229,235,232,226,251,245,46,0 +npcGreeting3 db 196,224,226,224,233,32,241,251,227,240,224,229,236,32,225,229,231,32,241,239,229,248,234,232,46,0 +npcGreeting4 db 197,241,242,252,32,228,229,235,238,32,241,32,237,224,227,240,224,228,238,233,46,0 +npcGreeting5 db 207,238,239,240,238,225,243,229,236,32,241,226,238,232,32,241,232,235,251,63,0 +npcQuest0 db 199,224,226,229,240,248,232,32,235,254,225,251,229,32,51,32,240,224,243,237,228,224,0 +npcQuest1 db 207,238,228,225,240,238,241,252,32,236,238,237,229,242,234,243,32,51,32,240,224,231,224,0 +npcQuest2 db 194,251,232,227,240,224,233,32,226,32,236,238,237,229,242,234,243,0 +npcQuest3 db 209,251,227,240,224,233,32,50,32,240,224,243,237,228,224,32,226,32,225,235,253,234,228,230,229,234,0 +npcQuest4 db 194,251,232,227,240,224,233,32,226,32,225,235,253,234,228,230,229,234,0 +npcQuest5 db 199,224,226,229,240,248,232,32,50,32,240,224,231,228,224,247,232,32,239,238,234,229,240,224,0 +npcQuest6 db 194,251,232,227,240,224,233,32,240,224,231,228,224,247,243,32,239,238,234,229,240,224,0 +npcQuest7 db 209,251,227,240,224,233,32,51,32,240,224,243,237,228,224,32,226,32,240,243,235,229,242,234,243,0 +npcQuest8 db 194,251,232,227,240,224,233,32,226,32,240,243,235,229,242,234,243,0 +npcQuest9 db 202,240,243,242,232,32,224,226,242,238,236,224,242,32,51,32,240,224,231,224,0 +npcQuest10 db 199,224,226,229,240,248,232,32,239,224,240,242,232,254,32,226,32,228,243,240,224,234,224,0 +npcQuest11 db 194,251,232,227,240,224,233,32,239,224,240,242,232,254,32,226,32,228,243,240,224,234,224,0 +npcTalkPrompt3D db 91,69,93,32,207,206,195,206,194,206,208,200,210,220,0 +npcContractTitle3D db 215,197,203,203,197,205,196,198,32,205,192,32,209,197,195,206,196,205,223,0 +npcProgressText3D db 207,240,238,227,240,229,241,241,0 +npcRewardText3D db 205,224,227,240,224,228,224,0 +npcAcceptText3D db 194,199,223,210,220,0 +npcClaimText3D db 205,192,195,208,192,196,192,0 +npcCloseText3D db 199,192,202,208,219,210,220,0 +npcAvailableText3D db 204,238,230,237,238,32,239,240,232,237,255,242,252,0 +npcActiveText3D db 194,251,239,238,235,237,255,229,242,241,255,0 +npcReadyText3D db 195,238,242,238,226,238,33,32,199,224,225,229,240,232,32,237,224,227,240,224,228,243,0 +npcDoneText3D db 205,224,227,240,224,228,224,32,243,230,229,32,239,238,235,243,247,229,237,224,0 +npcIoErrorText3D db 205,229,32,243,228,224,235,238,241,252,32,241,238,245,240,224,237,232,242,252,32,231,224,228,224,237,232,229,0 +npcSlashText3D db " / ",0 +.data? +npcPaths3D dd NPC_LIFE_COUNT*NPC_PATH_CAP dup(?) +npcParents3D dd NPC_PATH_CAP dup(?) +npcQueue3D dd NPC_PATH_CAP dup(?) +.data +npcSearchHead3D dd 0 +npcSearchTail3D dd 0 +npcSearchGoal3D dd 0 +.code diff --git a/src_graphics/npc_mind.inc b/src_graphics/npc_mind.inc new file mode 100644 index 0000000..1c8c3df --- /dev/null +++ b/src_graphics/npc_mind.inc @@ -0,0 +1,1005 @@ +; ============================================================================== +; NPC MIND CODE - MASM32 / CP1251 +; Logic, Pathfinding Steering, Personality Thinking & Multi-Seat Poker Engine +; ============================================================================== + +.code + +; ------------------------------------------------------------------------------ +; InitCasinoNpcMind: Èíèöèàëèçàöèÿ âñåõ 6 ïåðñîíàæåé è èõ ñòàðòîâûõ òî÷åê +; ------------------------------------------------------------------------------ +InitCasinoNpcMind PROC uses ebx esi edi + xor esi, esi +npc_init_loop: + mov eax, esi + imul eax, SIZEOF NpcMindEntity + lea edi, casinoNpcs3D[eax] + + ; Ïðèâÿçêà ê ïðîôèëþ (0..5) + mov [edi].NpcMindEntity.profileId, esi + + ; Çàäàåì ñòàðòîâûå êîîðäèíàòû ó ðàçíûõ âåéïîèíòîâ + ; NPC 0 (Àêóëà) -> ó ñòîëà ïîêåðà (óçåë 12) + ; NPC 1 (Ëóäîìàí) -> ó àâòîìàòîâ (óçåë 5) + ; NPC 2 (Ñêàëà) -> ó áëýêäæåêà (óçåë 10) + ; NPC 3 (Àâòîîòâåò÷èê) -> ó áàðà (óçåë 7) + ; NPC 4 (Ìàæîð) -> ó ñöåíû (óçåë 3) + ; NPC 5 (Íîâè÷îê) -> ó âõîäà (óçåë 0) + mov eax, esi + cmp eax, 0 + jne @F + mov ebx, 12 + jmp set_start_node +@@: + cmp eax, 1 + jne @F + mov ebx, 5 + jmp set_start_node +@@: + cmp eax, 2 + jne @F + mov ebx, 10 + jmp set_start_node +@@: + cmp eax, 3 + jne @F + mov ebx, 7 + jmp set_start_node +@@: + cmp eax, 4 + jne @F + mov ebx, 3 + jmp set_start_node +@@: + mov ebx, 0 + +set_start_node: + mov [edi].NpcMindEntity.currentNode, ebx + mov [edi].NpcMindEntity.targetNode, ebx + + imul ebx, SIZEOF NpcWaypoint + mov eax, casinoWaypoints3D[ebx].posX + mov [edi].NpcMindEntity.posX, eax + mov eax, casinoWaypoints3D[ebx].posY + mov [edi].NpcMindEntity.posY, eax + + mov [edi].NpcMindEntity.speed, (FP_1 / 18) ; Ñêîðîñòü õîäüáû + mov [edi].NpcMindEntity.state, NPCAI_STATE_IDLE + mov [edi].NpcMindEntity.currentTilt, 0 + + ; Ñòàðòîâûå ôèøêè èç ïðîôèëÿ + mov eax, esi + imul eax, SIZEOF NpcPersonality + mov ebx, casinoNpcProfiles[eax].defaultBank + mov [edi].NpcMindEntity.currentChips, ebx + + ; Ñòàðòîâûé òàéìåð è ìûñëè + invoke RandomRange, 60 + add eax, 40 + mov [edi].NpcMindEntity.stateTimer, eax + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thIdleBored + mov [edi].NpcMindEntity.reactionPtr, 0 + + inc esi + cmp esi, NPCAI_MAX_NPCS + jb npc_init_loop + ret +InitCasinoNpcMind ENDP + +; ------------------------------------------------------------------------------ +; UpdateCasinoNpcMind: Ïîêàäðîâîå îáíîâëåíèå ïîâåäåíèÿ è ïåðåìåùåíèÿ NPC â çàëå +; ------------------------------------------------------------------------------ +UpdateCasinoNpcMind PROC uses ebx esi edi + local nextX:DWORD, nextY:DWORD, dxFP:DWORD, dyFP:DWORD + + xor esi, esi +npc_update_loop: + mov eax, esi + imul eax, SIZEOF NpcMindEntity + lea edi, casinoNpcs3D[eax] + + ; 1. Ïëàâíîå îñòûâàíèå òèëüòà ñî âðåìåíåì + mov eax, [edi].NpcMindEntity.currentTilt + test eax, eax + jz @F + dec [edi].NpcMindEntity.currentTilt +@@: + + ; 2. Ìàøèíà ñîñòîÿíèé + mov eax, [edi].NpcMindEntity.state + cmp eax, NPCAI_STATE_IDLE + je npc_handle_idle + cmp eax, NPCAI_STATE_WALK + je npc_handle_walk + jmp npc_handle_activity + +npc_handle_idle: + dec [edi].NpcMindEntity.stateTimer + jnz npc_next_entity + + ; Âðåìÿ îæèäàíèÿ èñòåêëî -> âûáèðàåì íîâóþ öåëü + ; Åñëè ôèøåê ìàëî (< 500) -> èäåì ê áàíêîìàòó + cmp [edi].NpcMindEntity.currentChips, 500 + jge @F + mov [edi].NpcMindEntity.targetNode, 14 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkAtm + jmp start_walking +@@: + ; Èíà÷å âûáèðàåì ñëó÷àéíûé óçåë íàçíà÷åíèÿ + invoke RandomRange, NPCAI_WAYPOINT_COUNT + mov [edi].NpcMindEntity.targetNode, eax + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkWander + +start_walking: + mov [edi].NpcMindEntity.state, NPCAI_STATE_WALK + jmp npc_next_entity + +npc_handle_activity: + dec [edi].NpcMindEntity.stateTimer + jnz npc_next_entity + ; Àêòèâíîñòü çàêîí÷åíà (ïîèãðàë, âûïèë, ñíÿë äåíüãè) + mov [edi].NpcMindEntity.state, NPCAI_STATE_IDLE + invoke RandomRange, 50 + add eax, 40 + mov [edi].NpcMindEntity.stateTimer, eax + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thIdleBored + jmp npc_next_entity + +npc_handle_walk: + ; Ðàñ÷åò âåêòîðà ê öåëåâîìó âåéïîèíòó + mov ebx, [edi].NpcMindEntity.targetNode + imul ebx, SIZEOF NpcWaypoint + mov eax, casinoWaypoints3D[ebx].posX + sub eax, [edi].NpcMindEntity.posX + mov dxFP, eax + + mov eax, casinoWaypoints3D[ebx].posY + sub eax, [edi].NpcMindEntity.posY + mov dyFP, eax + + ; Ïðîâåðêà áëèçîñòè ê öåëåâîé òî÷êå (|dx| < FP_HALF è |dy| < FP_HALF) + mov eax, dxFP + test eax, eax + jns @F + neg eax +@@: + cmp eax, (FP_HALF / 2) + jae move_towards_target + + mov eax, dyFP + test eax, eax + jns @F + neg eax +@@: + cmp eax, (FP_HALF / 2) + jae move_towards_target + + ; Ïðèáûëè íà âåéïîèíò! + mov eax, [edi].NpcMindEntity.targetNode + mov [edi].NpcMindEntity.currentNode, eax + + ; Ïðîâåðÿåì òèï çîíû ýòîãî âåéïîèíòà + mov ebx, eax + imul ebx, SIZEOF NpcWaypoint + mov eax, casinoWaypoints3D[ebx].zoneType + + cmp eax, 1 ; Ïîêåð + je enter_gamble + cmp eax, 2 ; Áëýêäæåê + je enter_gamble + cmp eax, 5 ; Áàð + je enter_bar + cmp eax, 6 ; Áàíêîìàò + je enter_atm + cmp eax, 7 ; Ñöåíà + je enter_stage + + ; Îáû÷íûé êîðèäîð -> ïàóçà è âûáîð ñëåäóþùåãî + mov [edi].NpcMindEntity.state, NPCAI_STATE_IDLE + invoke RandomRange, 40 + add eax, 30 + mov [edi].NpcMindEntity.stateTimer, eax + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thIdleBored + jmp npc_next_entity + +enter_gamble: + mov [edi].NpcMindEntity.state, NPCAI_STATE_GAMBLE + mov [edi].NpcMindEntity.stateTimer, 120 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkTable + jmp npc_next_entity + +enter_bar: + mov [edi].NpcMindEntity.state, NPCAI_STATE_BAR + mov [edi].NpcMindEntity.stateTimer, 100 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkBar + jmp npc_next_entity + +enter_atm: + mov [edi].NpcMindEntity.state, NPCAI_STATE_ATM + mov [edi].NpcMindEntity.stateTimer, 80 + add [edi].NpcMindEntity.currentChips, 3000 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkAtm + jmp npc_next_entity + +enter_stage: + mov [edi].NpcMindEntity.state, NPCAI_STATE_STAGE + mov [edi].NpcMindEntity.stateTimer, 150 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkStage + jmp npc_next_entity + +move_towards_target: + ; Äåëàåì øàã â íàïðàâëåíèè öåëè + mov eax, [edi].NpcMindEntity.posX + cmp dxFP, 0 + jle move_left + add eax, [edi].NpcMindEntity.speed + jmp check_step_x +move_left: + sub eax, [edi].NpcMindEntity.speed +check_step_x: + mov nextX, eax + + mov eax, [edi].NpcMindEntity.posY + cmp dyFP, 0 + jle move_up + add eax, [edi].NpcMindEntity.speed + jmp check_step_y +move_up: + sub eax, [edi].NpcMindEntity.speed +check_step_y: + mov nextY, eax + + ; Ïðîâåðêà êîëëèçèé ÷åðåç CanWalk3D + invoke CanWalk3D, nextX, [edi].NpcMindEntity.posY + test eax, eax + jz @F + mov eax, nextX + mov [edi].NpcMindEntity.posX, eax +@@: + invoke CanWalk3D, [edi].NpcMindEntity.posX, nextY + test eax, eax + jz npc_next_entity + mov eax, nextY + mov [edi].NpcMindEntity.posY, eax + +npc_next_entity: + inc esi + cmp esi, NPCAI_MAX_NPCS + jb npc_update_loop + ret +UpdateCasinoNpcMind ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_InitTable: Ïîäãîòîâêà ñòîëà íà 4 ìåñòà (Èãðîê + 3 áîòà) +; ------------------------------------------------------------------------------ +MultiPoker_InitTable PROC uses ebx esi edi + lea edi, multiPokerTable + + mov [edi].MultiPokerTable.commCount, 0 + mov [edi].MultiPokerTable.mainPot, 0 + mov [edi].MultiPokerTable.currentHighBet, 0 + mov [edi].MultiPokerTable.minRaise, 100 + mov [edi].MultiPokerTable.smallBlind, 50 + mov [edi].MultiPokerTable.bigBlind, 100 + mov [edi].MultiPokerTable.dealerButton, 0 + mov [edi].MultiPokerTable.activeSeats, 4 + mov [edi].MultiPokerTable.stage, MPK_STAGE_PREFLOP + + ; Ìåñòî 0: Èãðîê + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].isHuman, 1 + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].profileId, 0 + mov eax, bankroll + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].chips, eax + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].seatStatus, MPK_SEAT_ACTIVE + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].lastAction, MPK_ACT_NONE + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].thoughtPtr, 0 + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].reactionPtr, 0 + + ; Ìåñòî 1: Âèêòîð «Àêóëà» (ïðîôèëü 0) + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].isHuman, 0 + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].profileId, 0 + mov eax, casinoNpcProfiles[0*SIZEOF NpcPersonality].defaultBank + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].chips, eax + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].seatStatus, MPK_SEAT_ACTIVE + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].lastAction, MPK_ACT_NONE + + ; Ìåñòî 2: Ñåðãåé «Ëóäîìàí» (ïðîôèëü 1) + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].isHuman, 0 + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].profileId, 1 + mov eax, casinoNpcProfiles[1*SIZEOF NpcPersonality].defaultBank + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].chips, eax + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].seatStatus, MPK_SEAT_ACTIVE + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].lastAction, MPK_ACT_NONE + + ; Ìåñòî 3: Äÿäÿ Òîëÿ «Ñêàëà» (ïðîôèëü 2) + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].isHuman, 0 + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].profileId, 2 + mov eax, casinoNpcProfiles[2*SIZEOF NpcPersonality].defaultBank + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].chips, eax + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].seatStatus, MPK_SEAT_ACTIVE + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].lastAction, MPK_ACT_NONE + ret +MultiPoker_InitTable ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_ShuffleDeck: Çàïîëíåíèå è òàñîâêà êîëîäû èç 52 êàðò +; ------------------------------------------------------------------------------ +MultiPoker_ShuffleDeck PROC uses ebx esi edi + ; Çàïîëíÿåì 0..51 + xor ecx, ecx +fill_deck: + mov multiDeck[ecx*4], ecx + inc ecx + cmp ecx, 52 + jb fill_deck + + ; Òàñîâêà Ôèøåðà-Éåòñà + mov ecx, 51 +shuffle_loop: + push ecx + inc ecx + invoke RandomRange, ecx + pop ecx + ; Îáìåí multiDeck[ecx*4] è multiDeck[eax*4] + mov edx, multiDeck[ecx*4] + mov ebx, multiDeck[eax*4] + mov multiDeck[ecx*4], ebx + mov multiDeck[eax*4], edx + dec ecx + jnz shuffle_loop + + mov multiDeckIndex, 0 + ret +MultiPoker_ShuffleDeck ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_StartHand: Ðàçäà÷à êàðò è ñáîð áëàéíäîâ +; ------------------------------------------------------------------------------ +MultiPoker_StartHand PROC uses ebx esi edi + lea edi, multiPokerTable + + call MultiPoker_ShuffleDeck + + mov [edi].MultiPokerTable.commCount, 0 + mov [edi].MultiPokerTable.mainPot, 0 + mov [edi].MultiPokerTable.currentHighBet, 0 + mov [edi].MultiPokerTable.stage, MPK_STAGE_PREFLOP + + ; Ïåðåäâèãàåì áàòòîí äèëåðà + mov eax, [edi].MultiPokerTable.dealerButton + inc eax + and eax, 3 + mov [edi].MultiPokerTable.dealerButton, eax + + ; Ðàçäàåì ïî 2 êàðòû êàæäîìó àêòèâíîìó ìåñòó + xor esi, esi +deal_seats_loop: + imul eax, esi, SIZEOF MpkSeat + lea ebx, [edi].MultiPokerTable.seats[eax] + + ; Åñëè íåò ôèøåê -> âûáûë + cmp [ebx].MpkSeat.chips, 50 + jae seat_can_play + mov [ebx].MpkSeat.seatStatus, MPK_SEAT_BUST + jmp next_deal_seat + +seat_can_play: + mov [ebx].MpkSeat.seatStatus, MPK_SEAT_ACTIVE + mov [ebx].MpkSeat.roundBet, 0 + mov [ebx].MpkSeat.totalBet, 0 + mov [ebx].MpkSeat.lastAction, MPK_ACT_NONE + + ; Êàðòà 1 + mov edx, multiDeckIndex + mov eax, multiDeck[edx*4] + mov [ebx].MpkSeat.card1, eax + inc multiDeckIndex + + ; Êàðòà 2 + mov edx, multiDeckIndex + mov eax, multiDeck[edx*4] + mov [ebx].MpkSeat.card2, eax + inc multiDeckIndex + +next_deal_seat: + inc esi + cmp esi, MPK_MAX_SEATS + jb deal_seats_loop + + ; Ðàçäàåì 5 îáùèõ êàðò íà ñòîë (ïîêà ñêðûòû) + xor esi, esi +deal_comm_loop: + mov edx, multiDeckIndex + mov eax, multiDeck[edx*4] + mov [edi].MultiPokerTable.commCards[esi*4], eax + inc multiDeckIndex + inc esi + cmp esi, 5 + jb deal_comm_loop + + ; Ñáîð Ìàëîãî Áëàéíäà + mov eax, [edi].MultiPokerTable.dealerButton + inc eax + and eax, 3 + imul eax, SIZEOF MpkSeat + mov ebx, [edi].MultiPokerTable.smallBlind + sub [edi].MultiPokerTable.seats[eax].chips, ebx + mov [edi].MultiPokerTable.seats[eax].roundBet, ebx + add [edi].MultiPokerTable.mainPot, ebx + + ; Ñáîð Áîëüøîãî Áëàéíäà + mov eax, [edi].MultiPokerTable.dealerButton + add eax, 2 + and eax, 3 + imul eax, SIZEOF MpkSeat + mov ebx, [edi].MultiPokerTable.bigBlind + sub [edi].MultiPokerTable.seats[eax].chips, ebx + mov [edi].MultiPokerTable.seats[eax].roundBet, ebx + add [edi].MultiPokerTable.mainPot, ebx + + mov eax, [edi].MultiPokerTable.bigBlind + mov [edi].MultiPokerTable.currentHighBet, eax + + ; Ïåðâûé õîä ïîñëå ÁÁ + mov eax, [edi].MultiPokerTable.dealerButton + add eax, 3 + and eax, 3 + mov [edi].MultiPokerTable.currentTurn, eax + ret +MultiPoker_StartHand ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_NpcDecideTurn: Ãëóáîêàÿ ëîãèêà ïðèíÿòèÿ ðåøåíèé ÈÈ áîòà +; Âõîä: seatIdx (0..3) +; ------------------------------------------------------------------------------ +MultiPoker_NpcDecideTurn PROC uses ebx esi edi, seatIdx:DWORD + local pSeat:DWORD, pProf:DWORD + local toCall:DWORD, handScore:DWORD, potOdds:DWORD + local aggro:DWORD, bluff:DWORD, courage:DWORD, tilt:DWORD + + ; 1. Ïîëó÷àåì óêàçàòåëè íà ñòóë è ïðîôèëü + mov eax, seatIdx + imul eax, SIZEOF MpkSeat + lea esi, multiPokerTable.seats[eax] + mov pSeat, esi + + mov eax, [esi].MpkSeat.profileId + imul eax, SIZEOF NpcPersonality + lea edi, casinoNpcProfiles[eax] + mov pProf, edi + + ; Ñóììà äëÿ êîëëà + mov eax, multiPokerTable.currentHighBet + sub eax, [esi].MpkSeat.roundBet + mov toCall, eax + + ; 2. Îöåíêà ñèëû ðóêè (0..100) + ; Êàðìàííûå êàðòû + mov eax, [esi].MpkSeat.card1 + mov multiEvalHand[0], eax + mov eax, [esi].MpkSeat.card2 + mov multiEvalHand[4], eax + + mov ecx, multiPokerTable.commCount + test ecx, ecx + jz eval_preflop_hand + + ; Ïîñòôëîï: êîïèðóåì îòêðûòûå êàðòû ñòîëà + xor edx, edx +copy_comm_eval: + mov eax, multiPokerTable.commCards[edx*4] + mov multiEvalHand[edx*4 + 8], eax + inc edx + cmp edx, ecx + jb copy_comm_eval + + lea eax, [ecx + 2] + invoke EvaluatePokerN, OFFSET multiEvalHand, eax + ; Score / 100 äàåò ïðèìåðíûé ïðîöåíò ñèëû + xor edx, edx + mov ecx, 80 + div ecx + mov handScore, eax + jmp apply_multi_opponent + +eval_preflop_hand: + ; Ïðåôëîï ýâðèñòèêà: ñòàðøèíñòâî è êàðìàííûå ïàðû + mov eax, [esi].MpkSeat.card1 + xor edx, edx + mov ecx, 13 + div ecx + mov ebx, edx ; ðàíã 1 (0..12) + + mov eax, [esi].MpkSeat.card2 + xor edx, edx + div ecx + mov ecx, edx ; ðàíã 2 (0..12) + + cmp ebx, ecx + jne preflop_ranks + ; Ïàðà! + lea eax, [ebx*4 + 40] + mov handScore, eax + jmp apply_multi_opponent + +preflop_ranks: + lea eax, [ebx + ecx] + imul eax, 3 + add eax, 15 + mov handScore, eax + +apply_multi_opponent: + ; Øòðàô çà èãðó ïðîòèâ íåñêîëüêèõ îïïîíåíòîâ + mov ecx, multiPokerTable.activeSeats + cmp ecx, 2 + jbe @F + imul ecx, 4 + sub handScore, ecx + jns @F + mov handScore, 5 +@@: + + ; 3. Ïñèõîëîãè÷åñêèå ìîäèôèêàòîðû + ÒÈËÜÒ + ; Íàõîäèì ñîîòâåòñòâóþùåãî NPC â casinoNpcs3D äëÿ ó÷åòà òåêóùåãî òèëüòà + mov eax, [esi].MpkSeat.profileId + imul eax, SIZEOF NpcMindEntity + mov eax, casinoNpcs3D[eax].currentTilt + mov tilt, eax + + mov eax, [edi].NpcPersonality.baseAggression + mov edx, tilt + shr edx, 1 + add eax, edx + mov aggro, eax + + mov eax, [edi].NpcPersonality.baseBluffRate + add eax, tilt + mov bluff, eax + + mov eax, [edi].NpcPersonality.baseCourage + mov courage, eax + + ; 4. Ðàñ÷åò øàíñîâ áàíêà (Pot Odds) + cmp toCall, 0 + je branch_free_check + + ; potOdds = (toCall * 100) / (mainPot + toCall) + mov eax, toCall + imul eax, 100 + mov ecx, multiPokerTable.mainPot + add ecx, toCall + test ecx, ecx + jnz @F + mov ecx, 1 +@@: + xor edx, edx + div ecx + mov potOdds, eax + + ; Ïðîâåðêà íà áëåô ñî ñëàáîé ðóêîé + cmp handScore, 30 + ja check_standard_call + invoke RandomRange, 100 + cmp eax, bluff + jbe decide_bluff_raise + +check_standard_call: + ; Ñðàâíåíèå ñèëû ðóêè è øàíñîâ áàíêà + mov eax, handScore + add eax, courage + shr eax, 1 + cmp eax, potOdds + jb decide_fold_action + + ; Ðóêà äîñòàòî÷íà äëÿ ïðîäîëæåíèÿ! Ïðîâåðÿåì æåëàíèå ðåéçèòü + mov eax, handScore + add eax, aggro + cmp eax, 120 + jae decide_value_raise + + ; Ñòàíäàðòíûé Êîëë + mov [esi].MpkSeat.lastAction, MPK_ACT_CALL + mov [esi].MpkSeat.thoughtPtr, OFFSET thActCall + mov eax, [edi].NpcPersonality.phraseWinPtr + mov [esi].MpkSeat.reactionPtr, eax + ret + +decide_value_raise: + mov [esi].MpkSeat.lastAction, MPK_ACT_RAISE + mov eax, multiPokerTable.minRaise + imul eax, 2 + mov [esi].MpkSeat.lastRaiseAmount, eax + mov [esi].MpkSeat.thoughtPtr, OFFSET thEvalGood + mov eax, [edi].NpcPersonality.phraseBluffPtr + mov [esi].MpkSeat.reactionPtr, eax + ret + +decide_bluff_raise: + mov [esi].MpkSeat.lastAction, MPK_ACT_RAISE + mov eax, multiPokerTable.minRaise + imul eax, 3 + mov [esi].MpkSeat.lastRaiseAmount, eax + mov [esi].MpkSeat.thoughtPtr, OFFSET thEvalBluffing + mov eax, [edi].NpcPersonality.phraseBluffPtr + mov [esi].MpkSeat.reactionPtr, eax + ret + +decide_fold_action: + mov [esi].MpkSeat.lastAction, MPK_ACT_FOLD + mov [esi].MpkSeat.seatStatus, MPK_SEAT_FOLDED + mov [esi].MpkSeat.thoughtPtr, OFFSET thActFold + mov eax, [edi].NpcPersonality.phraseLosePtr + mov [esi].MpkSeat.reactionPtr, eax + ret + +branch_free_check: + ; toCall == 0 -> ×åê èëè ëèäåðñêàÿ ñòàâêà + mov eax, handScore + add eax, aggro + cmp eax, 110 + jae lead_bet + mov [esi].MpkSeat.lastAction, MPK_ACT_CHECK + mov [esi].MpkSeat.thoughtPtr, OFFSET thActCheck + ret + +lead_bet: + mov [esi].MpkSeat.lastAction, MPK_ACT_RAISE + mov eax, multiPokerTable.minRaise + mov [esi].MpkSeat.lastRaiseAmount, eax + mov [esi].MpkSeat.thoughtPtr, OFFSET thEvalGood + mov eax, [edi].NpcPersonality.phraseBluffPtr + mov [esi].MpkSeat.reactionPtr, eax + ret +MultiPoker_NpcDecideTurn ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_ApplyAction: Ïðèìåíåíèå ñòàâêè, êîëëà èëè ïàñà ê ñîñòîÿíèþ ñòîëà +; ------------------------------------------------------------------------------ +MultiPoker_ApplyAction PROC uses ebx esi edi, seatIdx:DWORD, act:DWORD, amount:DWORD + mov eax, seatIdx + imul eax, SIZEOF MpkSeat + lea esi, multiPokerTable.seats[eax] + + cmp act, MPK_ACT_FOLD + je apply_fold + cmp act, MPK_ACT_CHECK + je apply_check + cmp act, MPK_ACT_CALL + je apply_call + cmp act, MPK_ACT_RAISE + je apply_raise + ret + +apply_fold: + mov [esi].MpkSeat.seatStatus, MPK_SEAT_FOLDED + dec multiPokerTable.activeSeats + ret + +apply_check: + ret + +apply_call: + mov eax, multiPokerTable.currentHighBet + sub eax, [esi].MpkSeat.roundBet + cmp eax, [esi].MpkSeat.chips + jbe @F + mov eax, [esi].MpkSeat.chips +@@: + sub [esi].MpkSeat.chips, eax + add [esi].MpkSeat.roundBet, eax + add [esi].MpkSeat.totalBet, eax + add multiPokerTable.mainPot, eax + ret + +apply_raise: + ; Äîñòàâêà äî currentHighBet + ðàçìåð ðåéçà + mov eax, multiPokerTable.currentHighBet + sub eax, [esi].MpkSeat.roundBet + add eax, amount + cmp eax, [esi].MpkSeat.chips + jbe @F + mov eax, [esi].MpkSeat.chips +@@: + sub [esi].MpkSeat.chips, eax + add [esi].MpkSeat.roundBet, eax + add [esi].MpkSeat.totalBet, eax + add multiPokerTable.mainPot, eax + + mov eax, [esi].MpkSeat.roundBet + mov multiPokerTable.currentHighBet, eax + ret +MultiPoker_ApplyAction ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_NextStreet: Ïåðåõîä íà ñëåäóþùóþ óëèöó òîðãîâ +; ------------------------------------------------------------------------------ +MultiPoker_NextStreet PROC uses ebx esi edi + ; Ñáðîñ roundBet äëÿ âñåõ ìåñò + xor ecx, ecx +reset_round_bets: + imul eax, ecx, SIZEOF MpkSeat + mov multiPokerTable.seats[eax].roundBet, 0 + inc ecx + cmp ecx, MPK_MAX_SEATS + jb reset_round_bets + + mov multiPokerTable.currentHighBet, 0 + + mov eax, multiPokerTable.stage + cmp eax, MPK_STAGE_PREFLOP + je go_flop + cmp eax, MPK_STAGE_FLOP + je go_turn + cmp eax, MPK_STAGE_TURN + je go_river + mov multiPokerTable.stage, MPK_STAGE_SHOWDOWN + ret + +go_flop: + mov multiPokerTable.commCount, 3 + mov multiPokerTable.stage, MPK_STAGE_FLOP + ret +go_turn: + mov multiPokerTable.commCount, 4 + mov multiPokerTable.stage, MPK_STAGE_TURN + ret +go_river: + mov multiPokerTable.commCount, 5 + mov multiPokerTable.stage, MPK_STAGE_RIVER + ret +MultiPoker_NextStreet ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_Showdown: Îïðåäåëåíèå ïîáåäèòåëÿ è ðàñ÷åò áàíêà +; ------------------------------------------------------------------------------ +MultiPoker_Showdown PROC uses ebx esi edi + local bestScore:DWORD, bestSeat:DWORD + + mov bestScore, 0 + mov bestSeat, 0 + + xor esi, esi +eval_showdown_seats: + imul eax, esi, SIZEOF MpkSeat + lea ebx, multiPokerTable.seats[eax] + + cmp [ebx].MpkSeat.seatStatus, MPK_SEAT_ACTIVE + jne next_showdown_seat + + ; Îöåíêà 7 êàðò (2 ñâîè + 5 ñòîëà) + mov eax, [ebx].MpkSeat.card1 + mov multiEvalHand[0], eax + mov eax, [ebx].MpkSeat.card2 + mov multiEvalHand[4], eax + + xor edx, edx +copy_7_cards: + mov eax, multiPokerTable.commCards[edx*4] + mov multiEvalHand[edx*4 + 8], eax + inc edx + cmp edx, 5 + jb copy_7_cards + + invoke EvaluatePokerN, OFFSET multiEvalHand, 7 + mov [ebx].MpkSeat.evalScore, eax + + cmp eax, bestScore + jb next_showdown_seat + mov bestScore, eax + mov bestSeat, esi + +next_showdown_seat: + inc esi + cmp esi, MPK_MAX_SEATS + jb eval_showdown_seats + + ; Íàãðàäà ïîáåäèòåëþ + mov eax, bestSeat + imul eax, SIZEOF MpkSeat + lea ebx, multiPokerTable.seats[eax] + mov edx, multiPokerTable.mainPot + add [ebx].MpkSeat.chips, edx + + ; Åñëè ïîáåäèë ÷åëîâåê -> îáíîâëÿåì bankroll + cmp bestSeat, 0 + jne @F + mov eax, [ebx].MpkSeat.chips + mov bankroll, eax +@@: + ret +MultiPoker_Showdown ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_PrintStatus: Òåêñòîâûé âûâîä ñîñòîÿíèÿ ñòîëà è ìûñëåé áîòîâ +; ------------------------------------------------------------------------------ +MultiPoker_PrintStatus PROC uses ebx esi edi + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET mpkTitleStr + call ResetColor + + invoke PrintStr, OFFSET mpkPotStr + invoke PrintUInt, multiPokerTable.mainPot + + invoke PrintStr, OFFSET mpkStreetStr + mov eax, multiPokerTable.stage + cmp eax, MPK_STAGE_PREFLOP + jne @F + invoke PrintStr, OFFSET strStagePreflop + jmp print_stage_done +@@: + cmp eax, MPK_STAGE_FLOP + jne @F + invoke PrintStr, OFFSET strStageFlop + jmp print_stage_done +@@: + cmp eax, MPK_STAGE_TURN + jne @F + invoke PrintStr, OFFSET strStageTurn + jmp print_stage_done +@@: + cmp eax, MPK_STAGE_RIVER + jne @F + invoke PrintStr, OFFSET strStageRiver + jmp print_stage_done +@@: + invoke PrintStr, OFFSET strStageShow +print_stage_done: + invoke PrintStr, OFFSET nl + + ; Âûâîä îáùèõ êàðò ñòîëà + invoke PrintStr, OFFSET mpkCommCardsStr + cmp multiPokerTable.commCount, 0 + jne print_table_cards + invoke PrintStr, OFFSET strStagePreflop + invoke PrintStr, OFFSET nl + jmp print_seats_info + +print_table_cards: + invoke PrintHandRow21, OFFSET multiPokerTable.commCards, multiPokerTable.commCount, 1 + +print_seats_info: + invoke PrintStr, OFFSET nl + + ; Âûâîä êàæäîãî èç 4 ìåñò + xor esi, esi +print_seats_loop: + imul eax, esi, SIZEOF MpkSeat + lea ebx, multiPokerTable.seats[eax] + + ; Èìÿ ìåñòà + cmp esi, 0 + jne print_npc_seat_header + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET promptPlayerTerminal + call ResetColor + jmp print_seat_details + +print_npc_seat_header: + mov eax, [ebx].MpkSeat.profileId + imul eax, SIZEOF NpcPersonality + invoke SetColor, COLOR_WARN + invoke PrintStr, casinoNpcProfiles[eax].namePtr + call ResetColor + +print_seat_details: + invoke PrintStr, OFFSET dotSpaceText + invoke PrintStr, OFFSET mpkChipsPrefix + invoke PrintUInt, [ebx].MpkSeat.chips + + ; Ñòàòóñ ìåñòà + cmp [ebx].MpkSeat.seatStatus, MPK_SEAT_FOLDED + jne @F + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET observerFold1Text + call ResetColor +@@: + invoke PrintStr, OFFSET nl + + ; Ìûñëè áîòà (åñëè åñòü) + cmp [ebx].MpkSeat.thoughtPtr, 0 + je print_reaction_check + invoke PrintStr, OFFSET mpkThoughtPrefix + invoke PrintStr, [ebx].MpkSeat.thoughtPtr + invoke PrintStr, OFFSET nl + +print_reaction_check: + cmp [ebx].MpkSeat.reactionPtr, 0 + je next_seat_print + invoke SetColor, COLOR_CARD + invoke PrintStr, [ebx].MpkSeat.reactionPtr + call ResetColor + invoke PrintStr, OFFSET nl + +next_seat_print: + inc esi + cmp esi, MPK_MAX_SEATS + jb print_seats_loop + ret +MultiPoker_PrintStatus ENDP + +; ------------------------------------------------------------------------------ +; GameMultiPoker: Ãëàâíàÿ òî÷êà âõîäà äëÿ êàðòî÷íîé èãðû ïðîòèâ 3 ïîñåòèòåëåé +; ------------------------------------------------------------------------------ +GameMultiPoker PROC uses ebx esi edi + call ClearView + call MultiPoker_InitTable + +multi_hand_loop: + call ClearView + call MultiPoker_StartHand + +multi_street_loop: + call ClearView + call MultiPoker_PrintStatus + + ; Ïðîâåðÿåì, îñòàëñÿ ëè â èãðå õîòÿ áû 1 îïïîíåíò + cmp multiPokerTable.activeSeats, 1 + jbe multi_hand_showdown + + ; Êðóã òîðãîâëè äëÿ êàæäîãî àêòèâíîãî ìåñòà + xor esi, esi +multi_turn_loop: + imul eax, esi, SIZEOF MpkSeat + lea ebx, multiPokerTable.seats[eax] + + cmp [ebx].MpkSeat.seatStatus, MPK_SEAT_ACTIVE + jne next_turn_player + + ; Õîä Èãðîêà (ìåñòî 0) + cmp esi, 0 + jne handle_bot_turn + + invoke PrintStr, OFFSET mpkPromptStr + call ReadKey + cmp al, '1' + je player_call + cmp al, '2' + je player_raise + cmp al, '0' + je player_fold + jmp player_call + +player_fold: + invoke MultiPoker_ApplyAction, 0, MPK_ACT_FOLD, 0 + jmp next_turn_player +player_call: + invoke MultiPoker_ApplyAction, 0, MPK_ACT_CALL, 0 + jmp next_turn_player +player_raise: + invoke MultiPoker_ApplyAction, 0, MPK_ACT_RAISE, 100 + jmp next_turn_player + +handle_bot_turn: + ; Õîä áîòà + invoke MultiPoker_NpcDecideTurn, esi + mov eax, [ebx].MpkSeat.lastAction + mov edx, [ebx].MpkSeat.lastRaiseAmount + invoke MultiPoker_ApplyAction, esi, eax, edx + invoke Sleep, 400 + +next_turn_player: + inc esi + cmp esi, MPK_MAX_SEATS + jb multi_turn_loop + + ; Ïåðåõîä íà ñëåäóþùóþ óëèöó + cmp multiPokerTable.stage, MPK_STAGE_RIVER + jae multi_hand_showdown + + call MultiPoker_NextStreet + jmp multi_street_loop + +multi_hand_showdown: + call ClearView + call MultiPoker_Showdown + call MultiPoker_PrintStatus + + invoke PrintStr, OFFSET mpkWaitNextStr + call ReadKey + cmp al, '0' + je multi_poker_exit + jmp multi_hand_loop + +multi_poker_exit: + ret +GameMultiPoker ENDP diff --git a/src_graphics/npc_mind_data.inc b/src_graphics/npc_mind_data.inc new file mode 100644 index 0000000..5301e20 --- /dev/null +++ b/src_graphics/npc_mind_data.inc @@ -0,0 +1,258 @@ +; ============================================================================== +; NPC MIND DATA - MASM32 / CP1251 +; Multi-agent AI: Open-space Navigation, Personalities & Multi-seat Poker +; ============================================================================== + +NPCAI_ARCHETYPE_SHARK equ 0 ; Àêóëà (Tight-Aggressive) +NPCAI_ARCHETYPE_MANIAC equ 1 ; Ëóäîìàí (Loose-Aggressive) +NPCAI_ARCHETYPE_ROCK equ 2 ; Ñêàëà (Tight-Passive) +NPCAI_ARCHETYPE_CALLING_STATION equ 3 ; Àâòîîòâåò÷èê (Loose-Passive) +NPCAI_ARCHETYPE_WHALE equ 4 ; Ìàæîð (Âûñîêèé áàíêðîëë, õàîñ) +NPCAI_ARCHETYPE_ROOKIE equ 5 ; Íîâè÷îê (Îøèáêè, íåóâåðåííîñòü) + +NPCAI_STATE_IDLE equ 0 ; Ñòîèò, îñìàòðèâàåòñÿ +NPCAI_STATE_WALK equ 1 ; Èäåò ïî âåéïîèíòàì +NPCAI_STATE_GAMBLE equ 2 ; Èãðàåò çà ñòîëîì +NPCAI_STATE_BAR equ 3 ; Ó áàðà +NPCAI_STATE_ATM equ 4 ; Ó áàíêîìàòà +NPCAI_STATE_STAGE equ 5 ; Ñìîòðèò øîó + +MPK_SEAT_EMPTY equ 0 +MPK_SEAT_ACTIVE equ 1 +MPK_SEAT_FOLDED equ 2 +MPK_SEAT_ALLIN equ 3 +MPK_SEAT_BUST equ 4 + +MPK_ACT_NONE equ 0 +MPK_ACT_FOLD equ 1 +MPK_ACT_CHECK equ 2 +MPK_ACT_CALL equ 3 +MPK_ACT_RAISE equ 4 +MPK_ACT_ALLIN equ 5 + +MPK_STAGE_PREFLOP equ 0 +MPK_STAGE_FLOP equ 1 +MPK_STAGE_TURN equ 2 +MPK_STAGE_RIVER equ 3 +MPK_STAGE_SHOWDOWN equ 4 + +NPCAI_MAX_NPCS equ 6 +MPK_MAX_SEATS equ 4 +NPCAI_WAYPOINT_COUNT equ 16 + +; ------------------------------------------------------------------------------ +; Ñòðóêòóðû äàííûõ +; ------------------------------------------------------------------------------ + +NpcPersonality STRUCT + namePtr dd ? + titlePtr dd ? + archetypeId dd ? + baseAggression dd ? ; 0..100 + baseTightness dd ? ; 0..100 + baseBluffRate dd ? ; 0..100 + baseCourage dd ? ; 0..100 + tiltSens dd ? ; 0..100 + defaultBank dd ? + phraseWinPtr dd ? + phraseLosePtr dd ? + phraseBluffPtr dd ? + phraseBustPtr dd ? +NpcPersonality ENDS + +NpcMindEntity STRUCT + posX dd ? ; 16.16 FP + posY dd ? ; 16.16 FP + dirX dd ? ; 16.16 FP + dirY dd ? ; 16.16 FP + speed dd ? ; 16.16 FP + state dd ? ; NPCAI_STATE_* + stateTimer dd ? + currentNode dd ? + targetNode dd ? + profileId dd ? + currentChips dd ? + currentTilt dd ? ; 0..100 + thoughtPtr dd ? + reactionPtr dd ? +NpcMindEntity ENDS + +MpkSeat STRUCT + isHuman dd ? ; 1=Player, 0=NPC + profileId dd ? ; Èíäåêñ NpcPersonality (0..5) + chips dd ? + roundBet dd ? + totalBet dd ? + card1 dd ? + card2 dd ? + evalScore dd ? + seatStatus dd ? ; MPK_SEAT_* + lastAction dd ? ; MPK_ACT_* + lastRaiseAmount dd ? + thoughtPtr dd ? + reactionPtr dd ? +MpkSeat ENDS + +MultiPokerTable STRUCT + seats MpkSeat MPK_MAX_SEATS dup(<>) + commCards dd 5 dup(?) + commCount dd ? + mainPot dd ? + currentHighBet dd ? + minRaise dd ? + dealerButton dd ? + currentTurn dd ? + activeSeats dd ? + smallBlind dd ? + bigBlind dd ? + stage dd ? +MultiPokerTable ENDS + +NpcWaypoint STRUCT + posX dd ? ; 16.16 FP + posY dd ? ; 16.16 FP + neighbor0 dd ? + neighbor1 dd ? + neighbor2 dd ? + neighbor3 dd ? + zoneType dd ? +NpcWaypoint ENDS + +; ------------------------------------------------------------------------------ +; Ñòðîêîâûå êîíñòàíòû è îïèñàíèÿ (CP1251) +; ------------------------------------------------------------------------------ + +.data + +; Èìåíà è òèòóëû 6 óíèêàëüíûõ ïåðñîíàæåé +npcName0 db "Âèêòîð «Àêóëà»",0 +npcTitle0 db "Ïðîôåññèîíàë (Tight-Aggressive)",0 + +npcName1 db "Ñåðãåé «Ëóäîìàí»",0 +npcTitle1 db "Ìàíüÿê (Loose-Aggressive, ÒÈËÜÒ)",0 + +npcName2 db "Äÿäÿ Òîëÿ «Ñêàëà»",0 +npcTitle2 db "Âåòåðàí (Tight-Passive)",0 + +npcName3 db "Ñòåïàí «Àâòîîòâåò÷èê»",0 +npcTitle3 db "Ëþáèòåëü (Calling Station)",0 + +npcName4 db "Ìàæîð Àðò¸ì",0 +npcTitle4 db "Õàéðîëëåð (Whale, Áåçóìíûå ñòàâêè)",0 + +npcName5 db "Âëàä «Íîâè÷îê»",0 +npcTitle5 db "Ñòóäåíò (Rookie, Íåîïûòíûé)",0 + +; Ôðàçû ïîáåäû +npcWin0 db "«Õîëîäíûé ðàñ÷åò è íèêàêîé ìàãèè. Áàíê ìîé.»",0 +npcWin1 db "«ÕÀ-ÕÀ! Êòî òóò êîðîëü êàçèíî?! Âñå ôèøêè ñþäà!»",0 +npcWin2 db "«Òèøå åäåøü — äàëüøå áóäåøü, ìîëîäåæü.»",0 +npcWin3 db "«Îïà, çàêðûëñÿ ñòðèò! À âû íå âåðèëè!»",0 +npcWin4 db "«Îôèöèàíò, âñåì øàìïàíñêîãî çà ìîé ñ÷åò!»",0 +npcWin5 db "«Îãî! Íåóæåëè ÿ ïðàâäà ïîáåäèë?! Âîò ýòî äà!»",0 + +; Ôðàçû ïîðàæåíèÿ / áýäáèòà +npcLose0 db "«Áûâàåò. Ìàòåìàòè÷åñêàÿ äèñïåðñèÿ íà äèñòàíöèè âåðíåò âñ¸.»",0 +npcLose1 db "«ÄÀ ÊÀÊ ÒÀÊ-ÒÎ?! Îïÿòü ðèâåðîì ïåðååõàëè, ñóêà!»",0 +npcLose2 db "«Çíàë âåäü, ÷òî íàäî áûëî ñáðàñûâàòü åùå íà ôëîïå...»",0 +npcLose3 db "«Ýõ, ÷óòêà íå õâàòèëî äî ôëåøà... â ñëåäóþùèé ðàç ïîâåçåò.»",0 +npcLose4 db "«Ïô-ô, êîïåéêè. Ñåé÷àñ ñíèìó åùå ïà÷êó â áàíêîìàòå.»",0 +npcLose5 db "«ß òàê è çíàë... Íàäî áûëî âíèìàòåëüíåå ÷èòàòü ïðàâèëà.»",0 + +; Ôðàçû áëåôà / ðåéçà +npcBluff0 db "«Òâîÿ ðóêà ñëàáåå. Ñýêîíîìü ôèøêè è ïàñóé.»",0 +npcBluff1 db "«Ñëàáàêè! Âàì íå ïî êàðìàíó ýòîò áàíê, äâèãàéòå ïàñ!»",0 +npcBluff2 db "«Ó ìåíÿ îòëè÷íàÿ êàðòà. Íå ñîâåòóþ ëåçòü ïîä êîëåñà.»",0 +npcBluff3 db "«À ÿ ïðîñòî õî÷ó ïîñìîòðåòü ñëåäóþùóþ êàðòó!»",0 +npcBluff4 db "«Âû ñòàâèòå êîïåéêè! Äàâàéòå èãðàòü ïî-âçðîñëîìó!»",0 +npcBluff5 db "«Ý-ý... êàæåòñÿ, ÿ ïîäíèìàþ ñòàâêó. Âû ñî ìíîé?»",0 + +; Ôðàçû áàíêðîòñòâà +npcBust0 db "«Ëèìèò íà ñåãîäíÿ èñ÷åðïàí. Ïîðà äåëàòü ïàóçó.»",0 +npcBust1 db "«Âñ¸ â íîëü! Áåãó ê áàíêîìàòó, ÿ îáÿçàí îòûãðàòüñÿ!»",0 +npcBust2 db "«Ïåíñèÿ êîí÷èëàñü... Ïîéäó ïîäûøó íà ñâåæåì âîçäóõå.»",0 +npcBust3 db "«Îé, ôèøêè êîí÷èëèñü... Ïîéäó â áàð çà ïèâîì.»",0 +npcBust4 db "«Îïÿòü îáíóëèëñÿ? Åðóíäà, ñåé÷àñ ñíèìó åùå $50,000.»",0 +npcBust5 db "«Êàæåòñÿ, íà ìåòðî ìíå óæå íå õâàòàåò...»",0 + +; Ìûñëè â ñâîáîäíîì ïåðåìåùåíèè ïî êàçèíî +thWalkWander db "Îñìàòðèâàåò èãðîâîé çàë â ïîèñêàõ èíòåðåñíîé èãðû",0 +thWalkTable db "Íàïðàâëÿåòñÿ ê ïîêåðíîìó ñòîëó èñïûòàòü óäà÷ó",0 +thWalkBar db "Ðåøèë çàãëÿíóòü â áàð çà íàïèòêîì",0 +thWalkAtm db "Çàêîí÷èëèñü ôèøêè, íàïðàâëÿåòñÿ ê áàíêîìàòó",0 +thWalkStage db "Ïîäõîäèò ê ñöåíå ïîñìîòðåòü íà òàíöîâùèö",0 +thIdleBored db "Ñòîèò ó êîëîííû, ïîäñ÷èòûâàåò îñòàâøèåñÿ äåíüãè",0 + +; Ìûñëè çà ïîêåðíûì ñòîëîì +thEvalStrong db "×óâñòâóåò íàòñ! Ãîòîâèò ëîâóøêó äëÿ îïïîíåíòîâ.",0 +thEvalGood db "Ðóêà ñèëüíàÿ, îòëè÷íûå øàíñû çàáðàòü ýòîò áàíê.",0 +thEvalDraw db "Ñ÷èòàåò àóòû: øàíñû áàíêà âûãîäíû äëÿ êîëëà.",0 +thEvalTrash db "Êàðòû — ìóñîð. Ñìûñëà ðèñêîâàòü ôèøêàìè íåò.",0 +thEvalTilted db "[ÒÈËÜÒ!] Çëèòñÿ ïîñëå ïðîèãðûøà è èäåò íà òàðàí!",0 +thEvalBluffing db "ÁËÅÔ! Èçîáðàæàåò ìîíñòðà è äàâèò ñòàâêîé!",0 + +; Îïèñàíèÿ äåéñòâèé +thActFold db "Ñáðàñûâàåò êàðòû â ïàñ",0 +thActCheck db "×åêàåò, ïðîïóñêàÿ õîä",0 +thActCall db "Êîëëèðóåò (óðàâíèâàåò) òåêóùóþ ñòàâêó",0 +thActRaise db "Ïîâûøàåò ñòàâêó (ðåéç!)",0 +thActAllIn db "Äâèãàåò âñå ôèøêè âïåðåä — ÂÀ-ÁÀÍÊ (ÎËË-ÈÍ)!",0 + +; Íàçâàíèÿ óëèö ïîêåðà +strStagePreflop db "Ïðåôëîï (Êàðìàííûå êàðòû)",0 +strStageFlop db "Ôëîï (3 êàðòû ñòîëà)",0 +strStageTurn db "Òåðí (4 êàðòû ñòîëà)",0 +strStageRiver db "Ðèâåð (5 êàðò ñòîëà)",0 +strStageShow db "Âñêðûòèå êàðò (Showdown)",0 + +; Òåêñòû èíòåðôåéñà ìóëüòè-ïîêåðà +mpkTitleStr db "=== ÒÅÕÀÑÑÊÈÉ ÕÎËÄÅÌ: ÑÒÎË ÍÀ 4 ÈÃÐÎÊÀ ===",13,10,0 +mpkPotStr db "Áàíê ñòîëà: $",0 +mpkStreetStr db " | Ðàóíä: ",0 +mpkCommCardsStr db "Îáùèå êàðòû íà ñòîëå: ",0 +mpkPromptStr db "Âàø õîä: [1] ×åê/Êîëë | [2] Ðåéç | [0] Ïàñ -> ",0 +mpkWaitNextStr db 13,10,"[Íàæìèòå ëþáóþ êëàâèøó äëÿ ñëåäóþùåé ðàçäà÷è, 0 äëÿ âûõîäà]...",0 +mpkChipsPrefix db " Ñòåê: $",0 +mpkThoughtPrefix db " [Ìûñëè]: ",0 +mpkGameOverStr db 13,10,"Ðàçäà÷à îêîí÷åíà. Ïîáåäèòåëü: ",0 +mpkWinChipsStr db " âûèãðàë áàíê $",0 + +ALIGN 4 + +; Áàçà ïðîôèëåé 6 óíèêàëüíûõ ëè÷íîñòåé +casinoNpcProfiles NpcPersonality + NpcPersonality + NpcPersonality + NpcPersonality + NpcPersonality + NpcPersonality + +; Ãðàô âåéïîèíòîâ êàçèíî (êîîðäèíàòû 16.16 FP è ñâÿçè) +casinoWaypoints3D NpcWaypoint <16*FP_1, 28*FP_1, 1, 4, 8, 0, 0> ; 0: Âõîä â êàçèíî + NpcWaypoint <16*FP_1, 20*FP_1, 0, 2, 4, 8, 0> ; 1: Öåíòð õîëëà (þã) + NpcWaypoint <16*FP_1, 14*FP_1, 1, 3, 10, 12, 0> ; 2: Öåíòð õîëëà (ñåâåð) + NpcWaypoint <16*FP_1, 6*FP_1, 2, 10, 12, 3, 7> ; 3: Ïåðåä ñöåíîé òàíöîâùèö + NpcWaypoint < 8*FP_1, 20*FP_1, 0, 1, 5, 7, 0> ; 4: Çàïàäíûé êîðèäîð + NpcWaypoint < 6*FP_1, 14*FP_1, 4, 6, 2, 5, 4> ; 5: Àâòîìàòû 777 + NpcWaypoint < 6*FP_1, 9*FP_1, 5, 10, 2, 6, 4> ; 6: Àâòîìàòû CloverPit + NpcWaypoint < 4*FP_1, 25*FP_1, 4, 0, 7, 7, 5> ; 7: Áàðíàÿ ñòîéêà + NpcWaypoint <24*FP_1, 20*FP_1, 0, 1, 9, 14, 0> ; 8: Âîñòî÷íûé êîðèäîð + NpcWaypoint <26*FP_1, 25*FP_1, 8, 0, 9, 9, 0> ; 9: Çîíà îòäûõà VIP + NpcWaypoint <12*FP_1, 9*FP_1, 2, 3, 6, 11, 2> ; 10: Ñòîë Áëýêäæåêà + NpcWaypoint <16*FP_1, 11*FP_1, 2, 10, 12, 11, 3> ; 11: Ñòîë Ðóëåòêè + NpcWaypoint <20*FP_1, 9*FP_1, 2, 3, 11, 13, 1> ; 12: Ñòîë Ïîêåðà (Õîëäåì) + NpcWaypoint <24*FP_1, 9*FP_1, 12, 8, 14, 13, 1> ; 13: Ñòîë Äóðàêà + NpcWaypoint <26*FP_1, 15*FP_1, 8, 13, 14, 14, 6> ; 14: Áàíêîìàò (ATM) + NpcWaypoint <10*FP_1, 15*FP_1, 2, 4, 5, 10, 0> ; 15: Çîíà êîñòåé/÷åðåïîâ + +; 6 àêòèâíûõ ïåðñîíàæåé, ãóëÿþùèõ ïî çàëó êàçèíî +casinoNpcs3D NpcMindEntity NPCAI_MAX_NPCS dup(<>) + +; Ýêçåìïëÿð ñòîëà ìóëüòè-ïîêåðà +multiPokerTable MultiPokerTable <> + +; Êîëîäà è ðàáî÷èé áóôåð äëÿ ìóëüòè-ïîêåðà +multiDeck dd 52 dup(0) +multiDeckIndex dd 0 +multiEvalHand dd 7 dup(0) +multiActionWait dd 0 diff --git a/src_graphics/platform_code.inc b/src_graphics/platform_code.inc index 663fef9..a4505e8 100644 --- a/src_graphics/platform_code.inc +++ b/src_graphics/platform_code.inc @@ -8,6 +8,12 @@ WindowEvents3D PROC uses ebx esi edi hwnd:DWORD, uMsg:DWORD, wp:DWORD, lp:DWORD @@: cmp uMsg, 201h je event_mouse_down + cmp uMsg,203h + jne @F + cmp engineMode,MODE_POOL + je event_mouse_down + jmp event_default +@@: cmp uMsg, 200h jne @F cmp engineMode, MODE_POOL @@ -61,9 +67,18 @@ event_mouse_down: mov mouseY3D, eax cmp uMsg,200h jne @F + cmp eax,50 + jb event_done cmp eax,211 jae event_done @@: + cmp uMsg,203h + je pyr_event_pick + mov pyrPickClick3D,0 + jmp pyr_event_pick_done +pyr_event_pick: + mov pyrPickClick3D,1 +pyr_event_pick_done: mov mouseClick3D, 1 jmp event_done event_key_down: diff --git a/src_graphics/pyramid_data.inc b/src_graphics/pyramid_data.inc new file mode 100644 index 0000000..a0305d8 --- /dev/null +++ b/src_graphics/pyramid_data.inc @@ -0,0 +1,71 @@ +InitPyramidState3D PROTO +PyramidContact3D PROTO :DWORD,:DWORD +PyramidContactEnd3D PROTO :DWORD,:DWORD +PyramidCross3D PROTO :DWORD +PyramidRail3D PROTO :DWORD,:DWORD +PyramidDistance3D PROTO :DWORD,:DWORD +PyramidDirection3D PROTO +PyramidSelect3D PROTO :DWORD +PyramidCanPlace3D PROTO :DWORD,:DWORD,:DWORD +PyramidRespot3D PROTO :DWORD +PyramidPenalty3D PROTO :DWORD +PyramidChoice3D PROTO :DWORD +PyramidRack3D PROTO +PyramidPick3D PROTO :DWORD,:DWORD +PyramidPathClear3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD +PyramidGuide3D PROTO +PyramidBall3D PROTO :DWORD,:DWORD,:DWORD,:DWORD +FreePyramidAssets3D PROTO +.data +pyrTablePack3D AnimPack3D <> +pyrBallsPack3D AnimPack3D <> +pyrTablePath3D db "assets\animations\pyramid\table-v2.bin",0 +pyrBallsPath3D db "assets\animations\pyramid\balls-v1.bin",0 +pyrCue3D dd 0 +pyrScore3D dd 0,0 +pyrOwner3D dd 16 dup(-1) +pyrRoll3D dd 16 dup(0) +pyrPreviousX3D dd 16 dup(0) +pyrHistoryRails3D dd 16 dup(0) +pyrHistoryCross3D dd 16 dup(0) +pyrRailHalf3D dd 16 dup(0) +pyrTouched3D dd 0 +pyrValidEnd3D dd 0 +pyrRailSide3D dd 0 +pyrFoulReason3D dd 0 +pyrIllegalBreak3D dd 0 +pyrFine3D dd 0 +pyrFineActive3D dd 0 +pyrAimCarry3D dd 0 +pyrPickClick3D dd 0 +pyrDirX3D dd FP_1 +pyrDirY3D dd 0 +pyrAimFactor3D REAL8 651.8986469044033 +pyrGuideOn3D dd 1 +pyrTarget3D dd -1 +pyrGuideX3D dd 0 +pyrGuideY3D dd 0 +pyrChoiceActor3D dd 0 +pyrFouler3D dd 0 +pyrSettled3D dd 0 +pyrExit3D db 194,32,213,206,203,203,0 +pyrTitle3D db 207,200,208,192,204,200,196,192,0 +pyrBreakText3D db 208,192,199,193,200,210,200,197,0 +pyrTurnText3D db 213,206,196,0 +pyrCueText3D db 193,200,210,206,202,0 +pyrGuideText3D db 207,208,200,214,197,203,0 +pyrPenaltyText3D db 216,210,208,192,212,205,206,201,32,216,192,208,0 +pyrChoiceText3D db 207,206,209,203,197,32,216,210,208,192,212,192,0 +pyrPlayText3D db 200,195,208,192,210,220,0 +pyrPassText3D db 207,197,208,197,196,192,210,220,0 +pyrRackText3D db 207,197,208,197,193,200,210,220,0 +pyrTheirBreakText3D db 197,195,206,32,211,196,192,208,0 +pyrNoContactText3D db 205,197,210,32,202,192,209,192,205,200,223,0 +pyrBadBreakText3D db 205,197,194,197,208,205,219,201,32,208,192,199,193,206,201,0 +pyrBadEndText3D db 205,197,194,197,208,205,219,201,32,211,196,192,208,0 +pyrPlayerName3D db 194,219,0 +pyrAIName3D db 200,200,0 +pyrSkipText3D db 207,208,206,207,211,209,202,0 +pyrScoreSep3D db ":",0 +pyrStatusNames3D dd OFFSET pyrTurnText3D,OFFSET pyrNoContactText3D,OFFSET pyrBadBreakText3D,OFFSET pyrBadEndText3D +.code diff --git a/src_graphics/pyramid_play.inc b/src_graphics/pyramid_play.inc new file mode 100644 index 0000000..f25d3d7 --- /dev/null +++ b/src_graphics/pyramid_play.inc @@ -0,0 +1,688 @@ +PyramidSelect3D PROC uses ebx ball:DWORD + cmp poolBreak3D,0 + je @F + mov pyrCue3D,0 + ret +@@: + mov ebx,ball + cmp ebx,15 + ja pyr_select_default + cmp poolActive3D[ebx*4],1 + jne pyr_select_default + mov pyrCue3D,ebx + mov poolCalled3D,ebx + ret +pyr_select_default: + mov ebx,pyrCue3D + cmp poolActive3D[ebx*4],1 + je pyr_select_done + xor ebx,ebx +pyr_select_scan: + cmp poolActive3D[ebx*4],1 + je pyr_select_found + inc ebx + cmp ebx,16 + jb pyr_select_scan + ret +pyr_select_found: + mov pyrCue3D,ebx + mov poolCalled3D,ebx +pyr_select_done: + ret +PyramidSelect3D ENDP + +PyramidPick3D PROC uses ebx esi px:DWORD,py:DWORD + xor esi,esi +pyr_pick_ball: + cmp poolActive3D[esi*4],1 + jne pyr_pick_next + mov eax,px + sub eax,poolX3D[esi*4] + sar eax,12 + imul eax,eax + mov ebx,eax + mov eax,py + sub eax,poolY3D[esi*4] + sar eax,12 + imul eax,eax + add eax,ebx + cmp eax,36*16*16 + ja pyr_pick_next + mov eax,esi + ret +pyr_pick_next: + inc esi + cmp esi,16 + jb pyr_pick_ball + mov eax,-1 + ret +PyramidPick3D ENDP + +PyramidDirection3D PROC uses ebx esi + mov ecx,poolAngle3D + and ecx,511 + cmp pyrFineActive3D,0 + jne pyr_direction_fine + mov eax,tableCos[ecx*4] + mov pyrDirX3D,eax + mov eax,tableSin[ecx*4] + mov pyrDirY3D,eax + ret +pyr_direction_fine: + mov ecx,pyrFine3D + and ecx,4095 + mov ebx,ecx + and ebx,7 + shr ecx,3 + lea esi,[ecx+1] + and esi,511 + mov eax,tableCos[esi*4] + sub eax,tableCos[ecx*4] + imul eax,ebx + sar eax,3 + add eax,tableCos[ecx*4] + mov pyrDirX3D,eax + mov eax,tableSin[esi*4] + sub eax,tableSin[ecx*4] + imul eax,ebx + sar eax,3 + add eax,tableSin[ecx*4] + mov pyrDirY3D,eax + ret +PyramidDirection3D ENDP + +PoolAimPoint3D PROC uses ebx px:DWORD,py:DWORD + local deltaX:DWORD,deltaY:DWORD,phase:DWORD + mov ebx,pyrCue3D + mov eax,px + sub eax,poolX3D[ebx*4] + mov deltaX,eax + mov ecx,py + sub ecx,poolY3D[ebx*4] + mov deltaY,ecx + or eax,ecx + jz pyr_aim_done + fild deltaY + fild deltaX + fpatan + fmul pyrAimFactor3D + fistp phase + mov eax,phase + and eax,4095 + mov pyrFine3D,eax + mov pyrFineActive3D,1 + call PyramidDirection3D +pyr_aim_done: + ret +PoolAimPoint3D ENDP + +PoolShoot3D PROC uses ebx esi + cmp poolState3D,POOL_AIM + jne pyr_shoot_done + mov ebx,pyrCue3D + cmp ebx,15 + ja pyr_shoot_done + cmp poolActive3D[ebx*4],1 + jne pyr_shoot_done + cmp pyrTablePack3D.pixels,0 + je pyr_shoot_done + cmp pyrBallsPack3D.pixels,0 + je pyr_shoot_done + cmp poolBreak3D,0 + je @F + test ebx,ebx + jnz pyr_shoot_done + cmp poolX3D,95*FP_1 + jge pyr_shoot_done +@@: + mov poolFirst3D,-1 + mov poolRail3D,0 + mov poolBreakRails3D,0 + mov poolPotted3D,0 + mov poolFoul3D,0 + mov pyrFoulReason3D,0 + mov pyrValidEnd3D,0 + mov pyrSettled3D,0 + mov poolAccumulator3D,0 + mov poolTime3D,0 + mov poolState3D,POOL_STRIKE + xor esi,esi +pyr_shoot_history: + mov pyrHistoryRails3D[esi*4],0 + mov pyrHistoryCross3D[esi*4],0 + mov pyrRailHalf3D[esi*4],0 + inc esi + cmp esi,16 + jb pyr_shoot_history + call PyramidDirection3D +pyr_shoot_done: + ret +PoolShoot3D ENDP + +; Obstruction checks use Q4 geometry with a 64-bit projection numerator. +PyramidPathClear3D PROC uses ebx esi edi sx:DWORD,sy:DWORD,ex:DWORD,ey:DWORD,skipA:DWORD,skipB:DWORD + local deltaX:DWORD,deltaY:DWORD,length2:DWORD,projection:DWORD,wx:DWORD,wy:DWORD + mov eax,ex + sub eax,sx + sar eax,12 + mov deltaX,eax + imul eax,eax + mov ebx,eax + mov eax,ey + sub eax,sy + sar eax,12 + mov deltaY,eax + imul eax,eax + add eax,ebx + mov length2,eax + test eax,eax + jz pyr_path_bad + xor esi,esi +pyr_path_ball: + cmp esi,skipA + je pyr_path_next + cmp esi,skipB + je pyr_path_next + cmp poolActive3D[esi*4],1 + jne pyr_path_next + mov eax,poolX3D[esi*4] + sub eax,sx + sar eax,12 + mov wx,eax + imul eax,deltaX + mov ebx,eax + mov eax,poolY3D[esi*4] + sub eax,sy + sar eax,12 + mov wy,eax + imul eax,deltaY + add eax,ebx + test eax,eax + jle pyr_path_next + cmp eax,length2 + jge pyr_path_next + mov ecx,FP_1 + imul ecx + idiv length2 + mov projection,eax + imul deltaX + shrd eax,edx,16 + sub eax,wx + imul eax,eax + mov ebx,eax + mov eax,projection + imul deltaY + shrd eax,edx,16 + sub eax,wy + imul eax,eax + add eax,ebx + cmp eax,25*16*16 + jb pyr_path_bad +pyr_path_next: + inc esi + cmp esi,16 + jb pyr_path_ball + mov eax,1 + ret +pyr_path_bad: + xor eax,eax + ret +PyramidPathClear3D ENDP + +; Search every cue/target/pocket triple; no hidden outcomes or teleported pots. +PoolChooseAI3D PROC uses ebx esi edi + local cue:DWORD,target:DWORD,pocket:DWORD,deltaX:DWORD,deltaY:DWORD,distance:DWORD + local gx:DWORD,gy:DWORD,best:DWORD,bestCue:DWORD,bestX:DWORD,bestY:DWORD,bestPower:DWORD + local shotLength:DWORD + cmp poolBreak3D,0 + je pyr_ai_search + mov pyrCue3D,0 + mov poolAngle3D,0 + mov pyrFineActive3D,0 + mov poolPower3D,85000 + ret +pyr_ai_search: + mov best,7FFFFFFFh + mov bestCue,-1 + mov cue,0 +pyr_ai_cue: + mov ecx,cue + cmp poolActive3D[ecx*4],1 + jne pyr_ai_next_cue + mov target,0 +pyr_ai_target: + mov esi,target + cmp esi,cue + je pyr_ai_next_target + cmp poolActive3D[esi*4],1 + jne pyr_ai_next_target + mov pocket,0 +pyr_ai_pocket: + mov edi,pocket + mov eax,poolPocketX3D[edi*4] + sub eax,poolX3D[esi*4] + mov deltaX,eax + mov eax,poolPocketY3D[edi*4] + sub eax,poolY3D[esi*4] + mov deltaY,eax + invoke PyramidDistance3D,deltaX,deltaY + test eax,eax + jz pyr_ai_next_pocket + mov distance,eax + mov eax,deltaX + mov ecx,POOL_DIAMETER + imul ecx + idiv distance + mov ebx,poolX3D[esi*4] + sub ebx,eax + mov gx,ebx + mov eax,deltaY + mov ecx,POOL_DIAMETER + imul ecx + idiv distance + mov ebx,poolY3D[esi*4] + sub ebx,eax + mov gy,ebx + cmp gx,30*FP_1+POOL_RADIUS + jl pyr_ai_next_pocket + cmp gx,290*FP_1-POOL_RADIUS + jg pyr_ai_next_pocket + cmp gy,50*FP_1+POOL_RADIUS + jl pyr_ai_next_pocket + cmp gy,180*FP_1-POOL_RADIUS + jg pyr_ai_next_pocket + mov ecx,cue + mov eax,gx + sub eax,poolX3D[ecx*4] + sar eax,12 + mov ebx,deltaX + sar ebx,12 + imul eax,ebx + mov ebx,eax + mov eax,gy + sub eax,poolY3D[ecx*4] + sar eax,12 + mov edx,deltaY + sar edx,12 + imul eax,edx + add eax,ebx + test eax,eax + jle pyr_ai_next_pocket + invoke PyramidPathClear3D,poolX3D[ecx*4],poolY3D[ecx*4],gx,gy,cue,target + test eax,eax + jz pyr_ai_next_pocket + mov edi,pocket + invoke PyramidPathClear3D,poolX3D[esi*4],poolY3D[esi*4],poolPocketX3D[edi*4],poolPocketY3D[edi*4],cue,target + test eax,eax + jz pyr_ai_next_pocket + mov ecx,cue + mov eax,gx + sub eax,poolX3D[ecx*4] + mov ebx,gy + sub ebx,poolY3D[ecx*4] + invoke PyramidDistance3D,eax,ebx + mov shotLength,eax + add eax,distance + cmp eax,best + jae pyr_ai_next_pocket + mov best,eax + mov ecx,cue + mov bestCue,ecx + mov ecx,gx + mov bestX,ecx + mov ecx,gy + mov bestY,ecx + ; v^2/(2*rolling loss) estimates the travel budget, with margin for a cut. + sar eax,16 + imul eax,220 + add eax,22000 + cmp eax,85000 + jbe @F + mov eax,85000 +@@: + mov bestPower,eax +pyr_ai_next_pocket: + inc pocket + cmp pocket,6 + jb pyr_ai_pocket +pyr_ai_next_target: + inc target + cmp target,16 + jb pyr_ai_target +pyr_ai_next_cue: + inc cue + cmp cue,16 + jb pyr_ai_cue + cmp bestCue,-1 + je pyr_ai_safety + mov eax,bestCue + mov pyrCue3D,eax + invoke PoolAimPoint3D,bestX,bestY + mov eax,bestPower + mov poolPower3D,eax + ret +pyr_ai_safety: + invoke PyramidSelect3D,-1 + mov esi,pyrCue3D + xor edi,edi +pyr_ai_safety_target: + cmp edi,esi + je @F + cmp poolActive3D[edi*4],1 + je pyr_ai_safety_found +@@: + inc edi + cmp edi,16 + jb pyr_ai_safety_target + ret +pyr_ai_safety_found: + invoke PoolAimPoint3D,poolX3D[edi*4],poolY3D[edi*4] + mov poolPower3D,65000 + ret +PoolChooseAI3D ENDP + +HandlePool3D PROC uses ebx esi edi + xor esi,esi +pyr_sink_tick: + mov eax,deltaTime3D + sub poolSinkTime3D[esi*4],eax + jnc @F + mov poolSinkTime3D[esi*4],0 +@@: + inc esi + cmp esi,16 + jb pyr_sink_tick + mov eax,deltaTime3D + add poolTime3D,eax + cmp mouseClick3D,0 + je pyr_update + cmp mouseY3D,3 + jb pyr_update + cmp mouseY3D,17 + jae pyr_update + cmp mouseX3D,252 + jb pyr_update + cmp mouseX3D,312 + jae pyr_update + mov engineMode,MODE_WALK + call ClearKeys3D + call SaveProgress3D + ret +pyr_update: + cmp poolState3D,POOL_MOVING + jne pyr_strike + add poolAccumulator3D,eax +pyr_fixed_tick: + cmp poolAccumulator3D,2 + jb pyr_handle_done + sub poolAccumulator3D,2 + call PoolStep3D + cmp poolStill3D,0 + je pyr_fixed_tick + call PoolFinishShot3D + ret +pyr_strike: + cmp poolState3D,POOL_STRIKE + jne pyr_idle + cmp poolTime3D,240 + jb pyr_handle_done + mov ebx,pyrCue3D + mov eax,pyrDirX3D + imul poolPower3D + shrd eax,edx,16 + mov poolVX3D[ebx*4],eax + mov eax,pyrDirY3D + imul poolPower3D + shrd eax,edx,16 + mov poolVY3D[ebx*4],eax + mov poolState3D,POOL_MOVING + mov poolAccumulator3D,0 + ret +pyr_idle: + cmp poolState3D,POOL_RESULT + jne pyr_actor + invoke Pressed3D,20h + test eax,eax + jnz pyr_restart + cmp mouseClick3D,0 + je pyr_handle_done + cmp mouseY3D,211 + jb pyr_handle_done + cmp mouseX3D,202 + jb pyr_handle_done +pyr_restart: + call InitPool3D + ret +pyr_actor: + cmp poolPlayer3D,1 + jne pyr_human + cmp poolAI3D,0 + je pyr_human + cmp poolTime3D,1000 + jb pyr_handle_done + cmp poolState3D,POOL_PENALTY + jne @F + xor esi,esi +pyr_ai_penalty: + cmp poolActive3D[esi*4],1 + je pyr_ai_penalty_pick + inc esi + cmp esi,16 + jb pyr_ai_penalty + ret +pyr_ai_penalty_pick: + invoke PyramidPenalty3D,esi + ret +@@: + cmp poolState3D,POOL_CHOICE + jne @F + invoke PyramidChoice3D,0 + ret +@@: + call PoolChooseAI3D + call PoolShoot3D + ret +pyr_human: + cmp poolState3D,POOL_CHOICE + jne pyr_human_penalty + mov esi,0 +pyr_choice_key: + lea eax,[esi+31h] + invoke Pressed3D,eax + test eax,eax + jnz pyr_choice_selected + inc esi + cmp esi,4 + jb pyr_choice_key + invoke Pressed3D,0Dh + test eax,eax + jz @F + xor esi,esi + jmp pyr_choice_selected +@@: + cmp mouseClick3D,0 + je pyr_handle_done + cmp mouseY3D,215 + jb pyr_handle_done + cmp mouseY3D,237 + jae pyr_handle_done + mov eax,mouseX3D + sub eax,8 + js pyr_handle_done + xor edx,edx + mov ecx,78 + div ecx + cmp edx,70 + jae pyr_handle_done + mov esi,eax +pyr_choice_selected: + invoke PyramidChoice3D,esi + ret +pyr_human_penalty: + cmp poolState3D,POOL_PENALTY + jne pyr_human_aim + invoke Pressed3D,0Dh + test eax,eax + jnz pyr_penalty_skip + cmp mouseClick3D,0 + je pyr_handle_done + cmp mouseY3D,215 + jb @F + cmp mouseY3D,238 + jae @F + cmp mouseX3D,202 + jae pyr_penalty_skip +@@: + mov eax,mouseX3D + shl eax,16 + mov ebx,mouseY3D + shl ebx,16 + invoke PyramidPick3D,eax,ebx + cmp eax,-1 + je pyr_handle_done + invoke PyramidPenalty3D,eax + ret +pyr_penalty_skip: + mov poolState3D,POOL_CHOICE + ret +pyr_human_aim: + cmp mouseClick3D,0 + je pyr_keys + mov mouseClick3D,0 + mov eax,mouseX3D + mov ebx,mouseY3D + cmp ebx,50 + jb pyr_keys + cmp ebx,180 + ja pyr_mouse_footer + shl eax,16 + shl ebx,16 + cmp pyrPickClick3D,0 + je @F + mov pyrPickClick3D,0 + invoke PyramidPick3D,eax,ebx + cmp eax,-1 + je pyr_handle_done + invoke PyramidSelect3D,eax + ret +@@: + cmp poolBreak3D,0 + je pyr_mouse_aim + cmp keys3D[10h],0 + je pyr_mouse_aim + cmp eax,95*FP_1 + jge pyr_handle_done + invoke PoolPlaceCue3D,eax,ebx + ret +pyr_mouse_aim: + invoke PoolAimPoint3D,eax,ebx + ret +pyr_mouse_footer: + cmp ebx,193 + jb pyr_keys + cmp ebx,209 + ja pyr_mouse_command + cmp eax,202 + jb pyr_keys + cmp eax,308 + ja pyr_keys + sub eax,202 + imul eax,82000 + xor edx,edx + mov ecx,106 + div ecx + add eax,8000 + mov poolPower3D,eax + ret +pyr_mouse_command: + cmp ebx,211 + jb pyr_keys + cmp ebx,238 + jae pyr_keys + cmp eax,86 + jb pyr_cycle_cue + cmp eax,196 + jb pyr_toggle_guide + call PoolShoot3D + ret +pyr_keys: + mov eax,deltaTime3D + imul eax,120 + cmp keys3D[10h],0 + je @F + mov eax,deltaTime3D + imul eax,30 +@@: + add eax,pyrAimCarry3D + xor edx,edx + mov ecx,1000 + div ecx + mov pyrAimCarry3D,edx + mov ebx,eax + cmp pyrFineActive3D,0 + jne @F + mov eax,poolAngle3D + shl eax,3 + mov pyrFine3D,eax +@@: + cmp keys3D[25h],0 + je @F + sub pyrFine3D,ebx + mov pyrFineActive3D,1 +@@: + cmp keys3D[27h],0 + je @F + add pyrFine3D,ebx + mov pyrFineActive3D,1 +@@: + and pyrFine3D,4095 + mov eax,deltaTime3D + imul eax,100 + cmp keys3D[26h],0 + je @F + add poolPower3D,eax +@@: + cmp keys3D[28h],0 + je @F + sub poolPower3D,eax +@@: + cmp poolPower3D,8000 + jge @F + mov poolPower3D,8000 +@@: + cmp poolPower3D,90000 + jle @F + mov poolPower3D,90000 +@@: + invoke Pressed3D,42h + test eax,eax + jnz pyr_cycle_cue + invoke Pressed3D,50h + test eax,eax + jnz pyr_toggle_guide + invoke Pressed3D,20h + test eax,eax + jz pyr_handle_done + call PoolShoot3D + ret +pyr_toggle_guide: + xor pyrGuideOn3D,1 + ret +pyr_cycle_cue: + cmp poolBreak3D,0 + jne pyr_handle_done + mov esi,pyrCue3D + mov edi,16 +pyr_cycle_scan: + inc esi + and esi,15 + cmp poolActive3D[esi*4],1 + je pyr_cycle_found + dec edi + jnz pyr_cycle_scan + ret +pyr_cycle_found: + invoke PyramidSelect3D,esi +pyr_handle_done: + ret +HandlePool3D ENDP diff --git a/src_graphics/pyramid_render.inc b/src_graphics/pyramid_render.inc new file mode 100644 index 0000000..6811600 --- /dev/null +++ b/src_graphics/pyramid_render.inc @@ -0,0 +1,378 @@ +PyramidBall3D PROC uses ebx esi ball:DWORD,x:DWORD,y:DWORD,sizePx:DWORD + mov ebx,ball + mov eax,pyrRoll3D[ebx*4] + shr eax,17 + and eax,3 + test ebx,ebx + jnz @F + add eax,4 +@@: + mov esi,eax + mov eax,sizePx + shr eax,1 + mov edx,x + sub edx,eax + mov ecx,y + sub ecx,eax + invoke DrawAnimSprite3D,OFFSET pyrBallsPack3D,esi,edx,ecx,sizePx,sizePx + cmp sizePx,12 + jne pyr_ball_done + test ebx,ebx + jz pyr_ball_done + mov esi,x + sub esi,1 + mov eax,y + sub eax,2 + cmp ebx,10 + jb @F + sub esi,2 + invoke DrawWheelDigit3D,esi,eax,1,1,003B3933h + add esi,4 + mov eax,y + sub eax,2 + sub ebx,10 +@@: + invoke DrawWheelDigit3D,esi,eax,ebx,1,003B3933h +pyr_ball_done: + ret +PyramidBall3D ENDP + +; A swept aim preview terminates on the first real ball or cushion. +PyramidGuide3D PROC uses ebx esi edi + local px:DWORD,py:DWORD,pointX:DWORD,pointY:DWORD + mov pyrTarget3D,-1 + mov ebx,pyrCue3D + mov eax,poolX3D[ebx*4] + mov px,eax + mov eax,poolY3D[ebx*4] + mov py,eax + mov esi,6 +pyr_guide_step: + mov eax,pyrDirX3D + imul esi + sar eax,1 + add eax,px + mov pointX,eax + mov eax,pyrDirY3D + imul esi + sar eax,1 + add eax,py + mov pointY,eax + cmp pointX,30*FP_1+POOL_RADIUS + jl pyr_guide_done + cmp pointX,290*FP_1-POOL_RADIUS + jg pyr_guide_done + cmp pointY,50*FP_1+POOL_RADIUS + jl pyr_guide_done + cmp pointY,180*FP_1-POOL_RADIUS + jg pyr_guide_done + xor edi,edi +pyr_guide_obstacle: + cmp edi,pyrCue3D + je pyr_guide_next_obstacle + cmp poolActive3D[edi*4],1 + jne pyr_guide_next_obstacle + mov eax,pointX + sub eax,poolX3D[edi*4] + sar eax,12 + imul eax,eax + mov ebx,eax + mov eax,pointY + sub eax,poolY3D[edi*4] + sar eax,12 + imul eax,eax + add eax,ebx + cmp eax,25*16*16 + jb pyr_guide_hit +pyr_guide_next_obstacle: + inc edi + cmp edi,16 + jb pyr_guide_obstacle + test esi,7 + jnz pyr_guide_next + mov eax,pointX + sar eax,16 + mov ebx,pointY + sar ebx,16 + invoke DrawPixel,eax,ebx,00B1D7CFh +pyr_guide_next: + inc esi + cmp esi,560 + jb pyr_guide_step +pyr_guide_done: + ret +pyr_guide_hit: + mov pyrTarget3D,edi + mov eax,pointX + mov pyrGuideX3D,eax + sar eax,16 + mov ebx,pointY + mov pyrGuideY3D,ebx + sar ebx,16 + invoke DrawCircle,eax,ebx,3,00B1D7CFh + mov eax,pointX + sar eax,16 + mov ebx,pointY + sar ebx,16 + invoke DrawCircle,eax,ebx,2,00295041h + ret +PyramidGuide3D ENDP + +RenderPool3D PROC uses ebx esi edi + local px:DWORD,py:DWORD,tip:DWORD,dirx:DWORD,diry:DWORD + mov esi,pyrTablePack3D.pixels + test esi,esi + jz pyr_render_missing + lea edi,screenBuffer + mov ecx,SCREEN_SIZE + rep movsd + xor esi,esi +pyr_render_mouths: + mov eax,poolPocketX3D[esi*4] + sar eax,16 + mov ebx,poolPocketY3D[esi*4] + sar ebx,16 + invoke DrawCircle,eax,ebx,3,000B1010h + inc esi + cmp esi,6 + jb pyr_render_mouths + invoke DrawPixel,95,115,00838C73h + invoke DrawPixel,160,115,00838C73h + invoke DrawPixel,225,115,00838C73h + cmp poolBreak3D,0 + je @F + invoke DrawBox,95,53,1,124,003C7261h +@@: + cmp poolState3D,POOL_AIM + jne pyr_render_objects + call PyramidDirection3D + cmp pyrGuideOn3D,0 + je pyr_render_objects + call PyramidGuide3D +pyr_render_objects: + xor esi,esi +pyr_render_ball: + cmp poolActive3D[esi*4],1 + jne pyr_render_sunk + mov eax,poolX3D[esi*4] + sar eax,15 + mov px,eax + mov eax,poolY3D[esi*4] + sar eax,15 + mov py,eax + cmp esi,pyrCue3D + jne @F + cmp poolState3D,POOL_AIM + jne @F + mov eax,px + sar eax,1 + mov ebx,py + sar ebx,1 + invoke DrawCircle,eax,ebx,4,007BAFACh +@@: + invoke PyramidBall3D,esi,px,py,12 + jmp pyr_render_next +pyr_render_sunk: + cmp poolSinkTime3D[esi*4],0 + je pyr_render_next + mov ecx,poolPocket3D[esi*4] + cmp ecx,5 + ja pyr_render_next + mov eax,poolPocketX3D[ecx*4] + sar eax,15 + mov px,eax + mov eax,poolPocketY3D[ecx*4] + sar eax,15 + mov py,eax + mov eax,poolSinkTime3D[esi*4] + imul eax,12 + xor edx,edx + mov ecx,220 + div ecx + test eax,eax + jz pyr_render_next + invoke PyramidBall3D,esi,px,py,eax +pyr_render_next: + inc esi + cmp esi,16 + jb pyr_render_ball + cmp poolState3D,POOL_AIM + je pyr_render_cue + cmp poolState3D,POOL_STRIKE + jne pyr_render_hud +pyr_render_cue: + mov ebx,pyrCue3D + mov eax,poolX3D[ebx*4] + mov px,eax + mov eax,poolY3D[ebx*4] + mov py,eax + mov eax,pyrDirX3D + mov dirx,eax + mov eax,pyrDirY3D + mov diry,eax + mov tip,5 + cmp poolState3D,POOL_STRIKE + jne @F + mov tip,3 + mov eax,240 + sub eax,poolTime3D + cmp eax,0 + jge pyr_cue_time + xor eax,eax +pyr_cue_time: + shr eax,4 + add tip,eax +@@: + mov esi,tip + mov edi,44 +pyr_cue_draw: + mov eax,dirx + imul esi + neg eax + add eax,px + sar eax,16 + mov ebx,eax + mov eax,diry + imul esi + neg eax + add eax,py + sar eax,16 + mov tip,eax + invoke DrawCircle,ebx,eax,1,003E2E23h + invoke DrawPixel,ebx,tip,00DCC59Ah + inc esi + dec edi + jnz pyr_cue_draw +pyr_render_hud: + invoke DrawBox,0,0,320,20,00151D20h + invoke DrawString8x8,8,6,OFFSET pyrTitle3D,00E8D7ADh + invoke DrawNumber,112,6,pyrScore3D,00F4F3E8h + invoke DrawString8x8,128,6,OFFSET pyrScoreSep3D,00E8D7ADh + invoke DrawNumber,144,6,pyrScore3D[4],00F4F3E8h + mov ebx,OFFSET pyrPlayerName3D + cmp poolPlayer3D,0 + je @F + mov ebx,OFFSET pyrAIName3D +@@: + invoke DrawString8x8,184,6,ebx,00A8DDB9h + invoke DrawBoxBorder,252,3,60,14,002C3637h,00687672h,1 + invoke DrawString8x8,258,6,OFFSET cardExitButton3D,00E9D8B0h + mov ebx,OFFSET pyrTurnText3D + cmp poolBreak3D,0 + je @F + mov ebx,OFFSET pyrBreakText3D +@@: + cmp poolState3D,POOL_PENALTY + jne @F + mov ebx,OFFSET pyrPenaltyText3D +@@: + cmp poolState3D,POOL_CHOICE + jne @F + mov ebx,OFFSET pyrChoiceText3D +@@: + cmp poolState3D,POOL_MOVING + jne @F + mov ebx,OFFSET poolMovingText3D +@@: + cmp poolState3D,POOL_STRIKE + jne @F + mov ebx,OFFSET poolShotText3D +@@: + invoke DrawBox,0,22,320,15,00151D20h + invoke DrawString8x8,8,26,ebx,00E8D7ADh + cmp poolState3D,POOL_PENALTY + je @F + cmp poolState3D,POOL_CHOICE + jne pyr_render_footer +@@: + mov ecx,pyrFoulReason3D + mov eax,pyrStatusNames3D[ecx*4] + invoke DrawString8x8,176,26,eax,00EAAD9Ah +pyr_render_footer: + invoke DrawBox,0,186,320,54,00151D20h + xor esi,esi + mov ebx,20 + mov edi,174 +pyr_render_shelves: + mov eax,pyrOwner3D[esi*4] + test eax,eax + js pyr_shelf_next + cmp eax,1 + jne pyr_shelf_player + invoke PyramidBall3D,esi,edi,381,10 + add edi,12 + jmp pyr_shelf_next +pyr_shelf_player: + invoke PyramidBall3D,esi,ebx,381,10 + add ebx,12 +pyr_shelf_next: + inc esi + cmp esi,16 + jb pyr_render_shelves + invoke DrawString8x8,202,187,OFFSET poolPowerText3D,00CCBE94h + mov eax,poolPower3D + sub eax,8000 + imul eax,100 + xor edx,edx + mov ecx,82000 + div ecx + invoke DrawNumber,254,187,eax,00FFFFFFh + mov eax,poolPower3D + sub eax,8000 + imul eax,106 + xor edx,edx + mov ecx,82000 + div ecx + mov tip,eax + invoke DrawBox,202,201,106,5,00363D36h + invoke DrawBox,202,201,tip,5,00D5BB73h + mov eax,tip + add eax,201 + invoke DrawBox,eax,199,2,9,00F4F0DDh + invoke DrawBoxBorder,12,215,74,22,0039412Fh,00AC9862h,1 + invoke DrawString8x8,18,222,OFFSET pyrCueText3D,00FFFFFFh + invoke DrawNumber,62,222,pyrCue3D,00EAD19Bh + invoke DrawBoxBorder,92,215,104,22,0039412Fh,00AC9862h,1 + invoke DrawString8x8,106,222,OFFSET pyrGuideText3D,00FFFFFFh + invoke DrawBoxBorder,202,215,106,22,00425232h,00BBA76Fh,1 + mov ebx,OFFSET poolShotText3D + cmp poolState3D,POOL_PENALTY + jne @F + mov ebx,OFFSET pyrSkipText3D +@@: + cmp poolState3D,POOL_RESULT + jne @F + mov ebx,OFFSET poolRackText3D +@@: + invoke DrawString8x8,226,222,ebx,00FFFFFFh + cmp poolState3D,POOL_CHOICE + jne pyr_render_result + invoke DrawBox,0,211,320,29,00151D20h + invoke DrawBoxBorder,8,215,70,22,0039412Fh,00AC9862h,1 + invoke DrawString8x8,19,222,OFFSET pyrPlayText3D,00FFFFFFh + invoke DrawBoxBorder,86,215,70,22,0039412Fh,00AC9862h,1 + invoke DrawString8x8,89,222,OFFSET pyrPassText3D,00FFFFFFh + cmp pyrIllegalBreak3D,0 + je pyr_render_result + invoke DrawBoxBorder,164,215,70,22,0039412Fh,00AC9862h,1 + invoke DrawString8x8,167,222,OFFSET pyrRackText3D,00FFFFFFh + invoke DrawBoxBorder,242,215,70,22,0039412Fh,00AC9862h,1 + invoke DrawString8x8,249,222,OFFSET pyrTheirBreakText3D,00FFFFFFh +pyr_render_result: + cmp poolState3D,POOL_RESULT + jne pyr_render_done + invoke DrawBoxBorder,76,88,168,43,00192720h,00D6B971h,2 + mov ebx,OFFSET pyrPlayerName3D + cmp poolWinner3D,0 + je @F + mov ebx,OFFSET pyrAIName3D +@@: + invoke DrawString8x8,92,100,ebx,00FFFFFFh + invoke DrawString8x8,92,115,OFFSET poolWinText3D,00E8D7ADh +pyr_render_done: + ret +pyr_render_missing: + invoke DrawBox,0,0,320,240,00151D20h + invoke DrawString8x8,56,108,OFFSET unavailableText3D,00E8D7ADh + ret +RenderPool3D ENDP diff --git a/src_graphics/pyramid_rules.inc b/src_graphics/pyramid_rules.inc new file mode 100644 index 0000000..00697db --- /dev/null +++ b/src_graphics/pyramid_rules.inc @@ -0,0 +1,571 @@ +InitPyramidState3D PROC uses esi edi + mov pyrCue3D,0 + mov poolFirst3D,-1 + mov pyrScore3D,0 + mov pyrScore3D[4],0 + mov pyrFine3D,0 + mov pyrFineActive3D,0 + mov pyrAimCarry3D,0 + mov pyrPickClick3D,0 + mov pyrSettled3D,0 + mov pyrFoulReason3D,0 + mov pyrIllegalBreak3D,0 + mov pyrValidEnd3D,0 + xor esi,esi +pyr_init_records: + mov pyrOwner3D[esi*4],-1 + mov pyrRoll3D[esi*4],0 + mov pyrHistoryRails3D[esi*4],0 + mov pyrHistoryCross3D[esi*4],0 + mov pyrRailHalf3D[esi*4],0 + inc esi + cmp esi,16 + jb pyr_init_records + invoke LoadAnimPack3D,OFFSET pyrTablePack3D,OFFSET pyrTablePath3D + invoke LoadAnimPack3D,OFFSET pyrBallsPack3D,OFFSET pyrBallsPath3D + ret +InitPyramidState3D ENDP + +FreePyramidAssets3D PROC + invoke FreeAnimPack3D,OFFSET pyrTablePack3D + invoke FreeAnimPack3D,OFFSET pyrBallsPack3D + ret +FreePyramidAssets3D ENDP + +; Q4 length calculation avoids the signed overflow of long Q8 table vectors. +PyramidDistance3D PROC uses ebx deltaX:DWORD,deltaY:DWORD + mov eax,deltaX + sar eax,12 + imul eax,eax + mov ebx,eax + mov eax,deltaY + sar eax,12 + imul eax,eax + add eax,ebx + invoke PoolSqrt3D,eax + shl eax,12 + ret +PyramidDistance3D ENDP + +PyramidContact3D PROC uses ebx esi edi a:DWORD,b:DWORD + mov esi,a + mov edi,b + cmp poolFirst3D,-1 + jne pyr_contact_events + cmp esi,pyrCue3D + jne @F + mov poolFirst3D,edi + jmp pyr_contact_events +@@: + cmp edi,pyrCue3D + jne pyr_contact_done + mov poolFirst3D,esi +pyr_contact_events: + ; Ordered cushion/crossing history follows impulse transfers, not all balls. + invoke PyramidContactEnd3D,esi,edi + invoke PyramidContactEnd3D,edi,esi + mov eax,pyrHistoryRails3D[esi*4] + or eax,pyrHistoryRails3D[edi*4] + mov pyrHistoryRails3D[esi*4],eax + mov pyrHistoryRails3D[edi*4],eax + mov eax,pyrHistoryCross3D[esi*4] + or eax,pyrHistoryCross3D[edi*4] + mov pyrHistoryCross3D[esi*4],eax + mov pyrHistoryCross3D[edi*4],eax + mov eax,pyrRailHalf3D[esi*4] + or eax,pyrRailHalf3D[edi*4] + mov pyrRailHalf3D[esi*4],eax + mov pyrRailHalf3D[edi*4],eax +pyr_contact_done: + ret +PyramidContact3D ENDP + +PyramidContactEnd3D PROC uses ebx esi edi moving:DWORD,other:DWORD + mov esi,moving + mov edi,other + test pyrRailHalf3D[esi*4],1 + jz @F + cmp poolX3D[edi*4],160*FP_1 + jge pyr_contact_valid +@@: + test pyrRailHalf3D[esi*4],2 + jz @F + cmp poolX3D[edi*4],160*FP_1 + jle pyr_contact_valid +@@: + ; A frozen-ball contact counts only against an eligible cushion history. + mov ebx,0 + cmp poolY3D[edi*4],50*FP_1+POOL_RADIUS+256 + jle pyr_contact_frozen + mov ebx,1 + cmp poolY3D[edi*4],180*FP_1-POOL_RADIUS-256 + jge pyr_contact_frozen + mov ebx,2 + cmp poolX3D[edi*4],30*FP_1+POOL_RADIUS+256 + jle pyr_contact_frozen + mov ebx,3 + cmp poolX3D[edi*4],290*FP_1-POOL_RADIUS-256 + jl pyr_contact_end_done +pyr_contact_frozen: + cmp pyrHistoryCross3D[esi*4],0 + jne pyr_contact_valid + mov eax,pyrHistoryRails3D[esi*4] + mov ecx,ebx + btr eax,ecx + test eax,eax + jz pyr_contact_end_done +pyr_contact_valid: + mov pyrValidEnd3D,1 +pyr_contact_end_done: + ret +PyramidContactEnd3D ENDP + +PyramidRail3D PROC uses ebx ball:DWORD,side:DWORD + cmp poolFirst3D,-1 + je pyr_rail_done + mov ebx,ball + mov eax,pyrHistoryRails3D[ebx*4] + mov ecx,side + btr eax,ecx + test eax,eax + jnz pyr_rail_valid + cmp pyrHistoryCross3D[ebx*4],0 + je @F +pyr_rail_valid: + mov pyrValidEnd3D,1 +@@: + mov ecx,side + bts pyrHistoryRails3D[ebx*4],ecx + mov eax,1 + cmp poolX3D[ebx*4],160*FP_1 + jl @F + mov eax,2 +@@: + or pyrRailHalf3D[ebx*4],eax +pyr_rail_done: + ret +PyramidRail3D ENDP + +PyramidCross3D PROC uses ebx ball:DWORD + cmp poolFirst3D,-1 + je pyr_cross_done + mov ebx,ball + mov eax,pyrPreviousX3D[ebx*4] + cmp eax,160*FP_1 + je pyr_cross_done + jl pyr_cross_from_left + cmp poolX3D[ebx*4],160*FP_1 + jge pyr_cross_done + jmp pyr_cross_record +pyr_cross_from_left: + cmp poolX3D[ebx*4],160*FP_1 + jle pyr_cross_done +pyr_cross_record: + mov pyrHistoryCross3D[ebx*4],1 + cmp pyrHistoryRails3D[ebx*4],0 + je pyr_cross_done + mov pyrValidEnd3D,1 +pyr_cross_done: + ret +PyramidCross3D ENDP + +PyramidCanPlace3D PROC uses ebx esi ball:DWORD,px:DWORD,py:DWORD + cmp px,30*FP_1+POOL_RADIUS + jl pyr_place_bad + cmp px,290*FP_1-POOL_RADIUS + jg pyr_place_bad + cmp py,50*FP_1+POOL_RADIUS + jl pyr_place_bad + cmp py,180*FP_1-POOL_RADIUS + jg pyr_place_bad + xor esi,esi +pyr_place_scan: + cmp esi,ball + je pyr_place_next + cmp poolActive3D[esi*4],0 + je pyr_place_next + mov eax,px + sub eax,poolX3D[esi*4] + sar eax,12 + imul eax,eax + mov ebx,eax + mov eax,py + sub eax,poolY3D[esi*4] + sar eax,12 + imul eax,eax + add eax,ebx + cmp eax,25*16*16 + jbe pyr_place_bad +pyr_place_next: + inc esi + cmp esi,16 + jb pyr_place_scan + mov eax,1 + ret +pyr_place_bad: + xor eax,eax + ret +PyramidCanPlace3D ENDP + +PyramidRespot3D PROC uses ebx esi ball:DWORD + mov ebx,225*FP_1 +pyr_respot_foot: + invoke PyramidCanPlace3D,ball,ebx,115*FP_1 + test eax,eax + jnz pyr_respot_found + add ebx,FP_1*501/100 + cmp ebx,287*FP_1 + jle pyr_respot_foot + mov ebx,225*FP_1-FP_1*501/100 +pyr_respot_front: + invoke PyramidCanPlace3D,ball,ebx,115*FP_1 + test eax,eax + jnz pyr_respot_found + sub ebx,FP_1*501/100 + cmp ebx,33*FP_1 + jge pyr_respot_front + ; Pathological layouts still keep every ball: bounded free-cloth fallback. + mov esi,55*FP_1 +pyr_respot_row: + mov ebx,35*FP_1 +pyr_respot_grid: + invoke PyramidCanPlace3D,ball,ebx,esi + test eax,eax + jnz pyr_respot_grid_found + add ebx,6*FP_1 + cmp ebx,285*FP_1 + jle pyr_respot_grid + add esi,6*FP_1 + cmp esi,175*FP_1 + jle pyr_respot_row + xor eax,eax + ret +pyr_respot_found: + mov esi,115*FP_1 +pyr_respot_grid_found: + mov ecx,ball + mov poolX3D[ecx*4],ebx + mov poolY3D[ecx*4],esi + mov poolVX3D[ecx*4],0 + mov poolVY3D[ecx*4],0 + mov poolActive3D[ecx*4],1 + mov poolPocket3D[ecx*4],-1 + mov poolSinkTime3D[ecx*4],0 + mov pyrOwner3D[ecx*4],-1 + mov eax,1 + ret +PyramidRespot3D ENDP + +PoolPlaceCue3D PROC px:DWORD,py:DWORD + invoke PyramidCanPlace3D,0,px,py + test eax,eax + jz @F + mov eax,px + mov poolX3D,eax + mov eax,py + mov poolY3D,eax + mov poolActive3D,1 + mov poolPocket3D,-1 + mov poolSinkTime3D,0 + mov poolVX3D,0 + mov poolVY3D,0 + mov eax,1 +@@: + ret +PoolPlaceCue3D ENDP + +PoolBallLegal3D PROC ball:DWORD + mov ecx,ball + xor eax,eax + cmp ecx,15 + ja @F + cmp ecx,pyrCue3D + je @F + cmp poolActive3D[ecx*4],1 + sete al +@@: + ret +PoolBallLegal3D ENDP + +PoolCountGroup3D PROC + mov poolAtStart3D,0 + ret +PoolCountGroup3D ENDP + +PoolFinishShot3D PROC uses ebx esi edi + cmp pyrSettled3D,0 + jne pyr_finish_done + mov pyrSettled3D,1 + mov poolFoul3D,0 + mov pyrFoulReason3D,0 + mov pyrIllegalBreak3D,0 + cmp poolFirst3D,-1 + jne pyr_finish_contact + mov pyrFoulReason3D,1 + jmp pyr_finish_foul +pyr_finish_contact: + cmp poolBreak3D,0 + je pyr_finish_normal + cmp poolPotted3D,0 + jne pyr_finish_score + mov eax,poolBreakRails3D + mov ecx,pyrCue3D + btr eax,ecx + xor ebx,ebx +pyr_finish_rail_count: + test eax,eax + jz @F + lea ecx,[eax-1] + and eax,ecx + inc ebx + jmp pyr_finish_rail_count +@@: + cmp ebx,3 + jae pyr_finish_turn + cmp ebx,2 + jb pyr_finish_bad_break + xor esi,esi +pyr_finish_break_cross: + cmp esi,pyrCue3D + je @F + cmp pyrHistoryCross3D[esi*4],0 + jne pyr_finish_turn +@@: + inc esi + cmp esi,16 + jb pyr_finish_break_cross +pyr_finish_bad_break: + mov pyrFoulReason3D,2 + jmp pyr_finish_foul +pyr_finish_normal: + cmp poolPotted3D,0 + jne pyr_finish_score + cmp pyrValidEnd3D,0 + jne pyr_finish_turn + mov pyrFoulReason3D,3 +pyr_finish_foul: + mov poolFoul3D,1 + mov eax,poolBreak3D + mov pyrIllegalBreak3D,eax + xor esi,esi +pyr_finish_restore: + bt poolPotted3D,esi + jnc @F + invoke PyramidRespot3D,esi +@@: + inc esi + cmp esi,16 + jb pyr_finish_restore + mov eax,poolPlayer3D + mov pyrFouler3D,eax + xor eax,1 + mov poolPlayer3D,eax + mov pyrChoiceActor3D,eax + mov poolState3D,POOL_PENALTY + mov poolTime3D,0 + mov poolBreak3D,0 + ret +pyr_finish_score: + mov ebx,poolPlayer3D + xor esi,esi +pyr_finish_credit: + bt poolPotted3D,esi + jnc @F + mov pyrOwner3D[esi*4],ebx + inc pyrScore3D[ebx*4] +@@: + inc esi + cmp esi,16 + jb pyr_finish_credit + cmp pyrScore3D[ebx*4],8 + jb pyr_finish_aim + mov poolWinner3D,ebx + mov poolState3D,POOL_RESULT + ret +pyr_finish_turn: + xor poolPlayer3D,1 +pyr_finish_aim: + mov poolBreak3D,0 + mov poolState3D,POOL_AIM + mov poolTime3D,0 + invoke PyramidSelect3D,-1 +pyr_finish_done: + ret +PoolFinishShot3D ENDP + +PyramidPenalty3D PROC uses ebx ball:DWORD + cmp poolState3D,POOL_PENALTY + jne pyr_penalty_done + mov ecx,ball + cmp ecx,15 + ja pyr_penalty_done + cmp poolActive3D[ecx*4],1 + jne pyr_penalty_done + mov ebx,poolPlayer3D + mov pyrOwner3D[ecx*4],ebx + mov poolActive3D[ecx*4],0 + mov poolPocket3D[ecx*4],-2 + mov poolSinkTime3D[ecx*4],0 + mov poolVX3D[ecx*4],0 + mov poolVY3D[ecx*4],0 + inc pyrScore3D[ebx*4] + cmp pyrScore3D[ebx*4],8 + jb @F + mov poolWinner3D,ebx + mov poolState3D,POOL_RESULT + ret +@@: + mov poolState3D,POOL_CHOICE + mov poolTime3D,0 +pyr_penalty_done: + ret +PyramidPenalty3D ENDP + +PyramidChoice3D PROC uses ebx esi edi choice:DWORD + cmp poolState3D,POOL_CHOICE + jne pyr_choice_done + cmp choice,3 + ja pyr_choice_done + cmp choice,2 + jb pyr_choice_actor + cmp pyrIllegalBreak3D,0 + je pyr_choice_done + ; The penalty score survives a partial re-rack. + cmp pyrOwner3D, -1 + je @F + mov esi,1 +pyr_rack_exchange: + cmp pyrOwner3D[esi*4],-1 + je pyr_rack_swap + inc esi + cmp esi,16 + jb pyr_rack_exchange + jmp pyr_choice_done +pyr_rack_swap: + mov eax,pyrOwner3D + mov pyrOwner3D[esi*4],eax + mov poolActive3D[esi*4],0 + mov poolPocket3D[esi*4],-2 + mov pyrOwner3D,-1 +@@: + mov poolActive3D,1 + mov poolPocket3D,-1 + mov poolX3D,82*FP_1 + mov poolY3D,115*FP_1 + mov poolVX3D,0 + mov poolVY3D,0 + mov poolBreak3D,1 + mov pyrCue3D,0 + call PyramidRack3D +pyr_choice_actor: + mov eax,pyrChoiceActor3D + test choice,1 + jz @F + xor eax,1 +@@: + mov poolPlayer3D,eax + mov poolState3D,POOL_AIM + mov poolTime3D,0 + mov pyrFineActive3D,0 + mov poolAngle3D,0 + invoke PyramidSelect3D,-1 +pyr_choice_done: + ret +PyramidChoice3D ENDP + +; Center a partial base; move the apex to the base if parity requires it. +PyramidRack3D PROC uses ebx esi edi + local remaining:DWORD,rowCount:DWORD,startSlot:DWORD,apex:DWORD + local apexX:DWORD,apexY:DWORD,moveApex:DWORD + mov remaining,0 + mov apex,-1 + mov moveApex,0 + mov esi,1 +pyr_rack_count: + cmp pyrOwner3D[esi*4],-1 + jne @F + inc remaining +@@: + inc esi + cmp esi,16 + jb pyr_rack_count + xor ebx,ebx + mov esi,1 +pyr_rack_row: + lea eax,[ebx+1] + cmp eax,remaining + jbe @F + mov eax,remaining +@@: + mov rowCount,eax + mov ecx,ebx + inc ecx + sub ecx,eax + test ecx,1 + jz pyr_rack_even + ; One apex ball joins the last row instead of creating an asymmetric base. + dec ecx + shr ecx,1 + mov startSlot,ecx + imul eax,ebx,FP_1*43302/10000 + add eax,225*FP_1 + mov apexX,eax + imul eax,ecx,5*FP_1 + imul edx,ebx,FP_1*5/2 + sub eax,edx + add eax,115*FP_1 + mov apexY,eax + mov moveApex,1 + inc startSlot + jmp pyr_rack_row_balls +pyr_rack_even: + shr ecx,1 + mov startSlot,ecx +pyr_rack_row_balls: + xor edi,edi +pyr_rack_find: + cmp pyrOwner3D[esi*4],-1 + je pyr_rack_place + inc esi + cmp esi,16 + jb pyr_rack_find + jmp pyr_rack_complete +pyr_rack_place: + cmp apex,-1 + jne @F + mov apex,esi +@@: + imul eax,ebx,FP_1*43302/10000 + add eax,225*FP_1 + mov poolX3D[esi*4],eax + mov eax,edi + add eax,startSlot + imul eax,5*FP_1 + imul ecx,ebx,FP_1*5/2 + sub eax,ecx + add eax,115*FP_1 + mov poolY3D[esi*4],eax + mov poolActive3D[esi*4],1 + mov poolPocket3D[esi*4],-1 + mov poolVX3D[esi*4],0 + mov poolVY3D[esi*4],0 + mov poolSinkTime3D[esi*4],0 + inc esi + inc edi + dec remaining + cmp edi,rowCount + jb pyr_rack_find + inc ebx + cmp remaining,0 + jne pyr_rack_row +pyr_rack_complete: + cmp moveApex,0 + je @F + mov ecx,apex + mov eax,apexX + mov poolX3D[ecx*4],eax + mov eax,apexY + mov poolY3D[ecx*4],eax +@@: + ret +PyramidRack3D ENDP diff --git a/src_graphics/russian_party.inc b/src_graphics/russian_party.inc new file mode 100644 index 0000000..673381b --- /dev/null +++ b/src_graphics/russian_party.inc @@ -0,0 +1,254 @@ +RRPartyReset3D PROC + cmp rrPartyCount3D,1 + jb rr_party_default + cmp rrPartyCount3D,3 + jbe @F +rr_party_default: + mov rrPartyCount3D,1 +@@: + mov ecx,rrPartyCount3D + inc ecx + mov rrPartySize3D,ecx + mov eax,1 + shl eax,cl + dec eax + mov rrPartyAlive3D,eax + mov rrPartyStake3D,0 + mov rrPartySettled3D,1 + mov rrPartyReloads3D,0 + ret +RRPartyReset3D ENDP + +RRPartyInit3D PROC + call RRPartyReset3D + invoke LoadAnimPack3D,OFFSET rrPartyArt3D,OFFSET rrPartyPath3D + cmp rrPartyArt3D.frames,6 + jne rr_party_bad_art + cmp rrPartyArt3D.imageWidth,192 + jne rr_party_bad_art + cmp rrPartyArt3D.height,192 + je rr_party_init_done +rr_party_bad_art: + invoke FreeAnimPack3D,OFFSET rrPartyArt3D +rr_party_init_done: + mov eax,1 + ret +RRPartyInit3D ENDP + +RRPartySetCount3D PROC count:DWORD + cmp count,1 + jb rr_party_count_done + cmp count,3 + ja rr_party_count_done + cmp rr3d_state,RR_READY + je @F + cmp rr3d_state,RR_WIN + jne rr_party_count_done +@@: + mov eax,count + mov rrPartyCount3D,eax + mov rr3d_state,RR_READY + mov rr3d_timer,0 + call RRPartyReset3D + call ClearKeys3D +rr_party_count_done: + ret +RRPartySetCount3D ENDP + +; Called once at the initial deal, and later only when all loaded rounds are spent. +RRLoadCylinder3D PROC uses esi + mov rr3d_mask,0 + xor esi,esi +rr_party_cartridge: + invoke RandomRange3D,6 + bt rr3d_mask,eax + jc rr_party_cartridge + bts rr3d_mask,eax + inc esi + cmp esi,rr3d_bullets + jb rr_party_cartridge + invoke RandomRange3D,6 + mov rr3d_chamber,eax + inc rrPartyReloads3D + ret +RRLoadCylinder3D ENDP + +RRPartyWin3D PROC + cmp rrPartySettled3D,0 + jne rr_party_win_done + mov rrPartySettled3D,1 + mov eax,rrPartyStake3D + imul eax,rrPartySize3D + mov rr3d_payout,eax + add bankroll,eax + mov rr3d_state,RR_WIN + invoke PlayCasinoSound3D,OFFSET soundRoundWin,0,20003h + invoke NpcRecordRound3D,6,1 + call SaveProgress3D +rr_party_win_done: + ret +RRPartyWin3D ENDP + +RRPartyLose3D PROC + cmp rrPartySettled3D,0 + jne rr_party_lose_done + mov rrPartySettled3D,1 + mov rr3d_state,RR_GLITCH + invoke NpcRecordRound3D,6,0 + call SaveProgress3D +rr_party_lose_done: + ret +RRPartyLose3D ENDP + +; No selectable target: every participant takes their own turn with the same cylinder. +RRPartyHit3D PROC + cmp rrPartySettled3D,0 + jne rr_party_hit_done + mov ecx,rr3d_chamber + btr rr3d_mask,ecx + mov ecx,rr3d_turn + cmp ecx,rrPartySize3D + jae rr_party_hit_done + btr rrPartyAlive3D,ecx + test ecx,ecx + jz rr_party_player_out + cmp rrPartyAlive3D,1 + je rr_party_last_player + mov rr3d_state,RR_DRY + ret +rr_party_player_out: + call RRPartyLose3D + ret +rr_party_last_player: + call RRPartyWin3D +rr_party_hit_done: + ret +RRPartyHit3D ENDP + +RRPartyNext3D PROC uses ebx + mov ebx,rrPartySize3D +rr_party_next_seat: + inc rr3d_turn + mov eax,rr3d_turn + cmp eax,rrPartySize3D + jb @F + mov rr3d_turn,0 + xor eax,eax +@@: + bt rrPartyAlive3D,eax + jc rr_party_next_found + dec ebx + jnz rr_party_next_seat + call RRPartyLose3D + ret +rr_party_next_found: + cmp rr3d_mask,0 + jne rr_party_same_cylinder + call RRLoadCylinder3D + mov rr3d_state,RR_LOAD + invoke PlayCasinoSound3D,OFFSET rrLoadSound3D,0,20003h + ret +rr_party_same_cylinder: + inc rr3d_chamber + cmp rr3d_chamber,6 + jb @F + mov rr3d_chamber,0 +@@: + mov rr3d_state,RR_PLAYER + cmp rr3d_turn,0 + je @F + mov rr3d_state,RR_RAISE +@@: + ret +RRPartyNext3D ENDP + +AbortRussianRound3D PROC + cmp rrPartySettled3D,0 + jne @F + mov rrPartySettled3D,1 + invoke NpcRecordRound3D,6,0 + call SaveProgress3D +@@: + mov rr3d_state,RR_READY + mov rr3d_timer,0 + ret +AbortRussianRound3D ENDP + +RRPartyInput3D PROC uses ebx + cmp rr3d_state,RR_READY + je rr_party_ready_keys + cmp rr3d_state,RR_WIN + je rr_party_mouse + cmp rr3d_state,RR_PLAYER + je rr_party_mouse + jmp rr_party_mouse_exit +rr_party_ready_keys: + invoke Pressed3D,25h + test eax,eax + jz @F + mov eax,rrPartyCount3D + dec eax + invoke RRPartySetCount3D,eax +@@: + invoke Pressed3D,27h + test eax,eax + jz rr_party_mouse + mov eax,rrPartyCount3D + inc eax + invoke RRPartySetCount3D,eax +rr_party_mouse: + cmp mouseClick3D,0 + je rr_party_input_done + cmp rr3d_state,RR_READY + jne rr_party_mouse_start + cmp mouseY3D,226 + jb rr_party_mouse_start + cmp mouseY3D,239 + jae rr_party_mouse_start + mov eax,mouseX3D + sub eax,188 + jc rr_party_mouse_start + cmp eax,58 + jae rr_party_mouse_start + xor edx,edx + mov ecx,20 + div ecx + cmp edx,18 + jae rr_party_mouse_start + inc eax + invoke RRPartySetCount3D,eax + mov mouseClick3D,0 + ret +rr_party_mouse_start: + cmp mouseY3D,225 + jb rr_party_mouse_exit + cmp mouseY3D,239 + jae rr_party_mouse_exit + cmp mouseX3D,8 + jb rr_party_mouse_exit + cmp mouseX3D,150 + jae rr_party_mouse_exit + mov pressedKeys3D[20h],1 + mov mouseClick3D,0 + ret +rr_party_mouse_exit: + cmp mouseClick3D,0 + je rr_party_input_done + cmp mouseY3D,3 + jb rr_party_clear_mouse + cmp mouseY3D,17 + jae rr_party_clear_mouse + cmp mouseX3D,252 + jb rr_party_clear_mouse + cmp mouseX3D,312 + jae rr_party_clear_mouse + mov mouseClick3D,0 + call RequestCardExit3D + ret +rr_party_clear_mouse: + mov mouseClick3D,0 +rr_party_input_done: + ret +RRPartyInput3D ENDP + +include src_graphics\russian_party_render.inc diff --git a/src_graphics/russian_party_data.inc b/src_graphics/russian_party_data.inc new file mode 100644 index 0000000..cc84c4f --- /dev/null +++ b/src_graphics/russian_party_data.inc @@ -0,0 +1,36 @@ +RRPartyInit3D PROTO +RRPartyReset3D PROTO +RRPartySetCount3D PROTO :DWORD +RRPartyInput3D PROTO +RRLoadCylinder3D PROTO +RRPartyHit3D PROTO +RRPartyNext3D PROTO +RRPartyWin3D PROTO +RRPartyLose3D PROTO +AbortRussianRound3D PROTO +RenderRRPartyCharacters3D PROTO +RenderRRPartyGun3D PROTO +RenderRRPartyControls3D PROTO +RenderRussianExit3D PROTO +.data +rrPartyCount3D dd 1 +rrPartySize3D dd 2 +rrPartyAlive3D dd 3 +rrPartyStake3D dd 0 +rrPartySettled3D dd 1 +rrPartyReloads3D dd 0 +rrPartyArt3D AnimPack3D <> +rrPartyPath3D db "assets\animations\roulette\participants-v1.bin",0 +rrPartyNames3D dd OFFSET rrPartyName0,OFFSET rrPartyName1,OFFSET rrPartyName2 +rrPartyName0 db 210,206,203,223,0 +rrPartyName1 db 209,197,208,195,197,201,0 +rrPartyName2 db 195,208,200,195,206,208,200,201,0 +rrPartyCountText3D db 209,206,207,197,208,205,200,202,200,0 +rrPartyOutText3D db 194,219,193,219,203,0 +rrPartyTurnText3D db 213,206,196,0 +rrPartyAliveText3D db 206,198,200,196,192,197,210,0 +rrPartyPoolText3D db 193,192,205,202,0 +rrPartyExitText3D db 208,224,243,237,228,32,229,249,184,32,237,229,32,231,224,234,238,237,247,229,237,46,0 +rrPartyDigits3D db "1",0,"2",0,"3",0 +rrPartyX3D dd 32,232,432 +.code diff --git a/src_graphics/russian_party_render.inc b/src_graphics/russian_party_render.inc new file mode 100644 index 0000000..3d03a3c --- /dev/null +++ b/src_graphics/russian_party_render.inc @@ -0,0 +1,173 @@ +RenderRRPartyCharacters3D PROC uses ebx esi edi + local px:DWORD,frame:DWORD,ink:DWORD + xor ebx,ebx +rr_party_draw_guest: + cmp ebx,rrPartyCount3D + jae rr_party_draw_done + mov esi,rrPartyX3D[ebx*4] + cmp rrPartyCount3D,2 + jne @F + imul esi,ebx,200 + add esi,132 +@@: + mov px,esi + mov frame,ebx + lea edi,[ebx+1] + mov ink,00D7C7A4h + bt rrPartyAlive3D,edi + jnc rr_party_inactive + cmp rr3d_turn,edi + jne rr_party_draw_body + cmp rr3d_state,RR_RAISE + je rr_party_active_body + cmp rr3d_state,RR_FIRE + je rr_party_active_body + cmp rr3d_state,RR_DRY + jne rr_party_draw_body +rr_party_active_body: + add frame,3 + mov ink,00FFE09Ah +rr_party_draw_body: + mov animOpacity3D,255 + jmp rr_party_body +rr_party_inactive: + mov ink,00697873h + cmp rr3d_turn,edi + jne rr_party_caption + cmp rr3d_state,RR_DRY + jne rr_party_caption + mov eax,700 + sub eax,rr3d_timer + jle rr_party_caption + imul eax,255 + xor edx,edx + mov ecx,700 + div ecx + mov animOpacity3D,eax +rr_party_body: + invoke DrawAnimSprite3D,OFFSET rrPartyArt3D,frame,px,48,176,176 +rr_party_caption: + mov animOpacity3D,255 + lea eax,[esi+16] + invoke DrawBuckshotText3D,eax,38,rrPartyNames3D[ebx*4],ink + mov ecx,OFFSET rrPartyOutText3D + bt rrPartyAlive3D,edi + jnc @F + mov ecx,OFFSET rrPartyAliveText3D + cmp rr3d_state,RR_READY + je @F + cmp rr3d_state,RR_WIN + je @F + cmp rr3d_turn,edi + jne @F + mov ecx,OFFSET rrPartyTurnText3D +@@: + lea eax,[esi+16] + invoke DrawBuckshotText3D,eax,230,ecx,ink + inc ebx + jmp rr_party_draw_guest +rr_party_draw_done: + mov animOpacity3D,255 + ret +RenderRRPartyCharacters3D ENDP + +; A shared tabletop revolver is passed to the highlighted seat; no extra arm layer. +RenderRRPartyGun3D PROC uses ebx + local target:DWORD,t:DWORD,px:DWORD,py:DWORD + mov ebx,rr3d_turn + dec ebx + cmp ebx,3 + jae rr_party_gun_done + mov eax,rrPartyX3D[ebx*4] + cmp rrPartyCount3D,2 + jne @F + imul eax,ebx,200 + add eax,132 +@@: + add eax,88 + shr eax,1 + mov target,eax + mov eax,750 + cmp rr3d_state,RR_RAISE + jne @F + mov eax,rr3d_timer + cmp eax,750 + jbe @F + mov eax,750 +@@: + mov t,eax + mov eax,target + sub eax,160 + imul eax,t + cdq + mov ecx,750 + idiv ecx + add eax,160 + mov px,eax + mov eax,19 + imul eax,t + xor edx,edx + div ecx + mov edx,151 + sub edx,eax + mov py,edx + invoke DrawRouletteSprite3D,0,px,py,98,52,0 +rr_party_gun_done: + ret +RenderRRPartyGun3D ENDP + +RenderRRPartyControls3D PROC uses ebx esi + cmp rrPartyCount3D,1 + jbe @F + invoke DrawBuckshotText3D,244,414,OFFSET rrPartyPoolText3D,00EBD5A0h + mov eax,rrPartyStake3D + test eax,eax + jnz rr_party_pool_locked + mov eax,rr3d_bet +rr_party_pool_locked: + imul eax,rrPartySize3D + invoke DrawBuckshotNumber3D,296,414,eax,00FFFFFFh +@@: + cmp rr3d_state,RR_READY + jne rr_party_controls_done + invoke DrawBuckshotText3D,280,462,OFFSET rrPartyCountText3D,00D7C7A4h + xor ebx,ebx +rr_party_control: + mov esi,ebx + imul esi,20 + add esi,188 + mov eax,0025352Dh + mov ecx,00766B51h + lea edx,[ebx+1] + cmp edx,rrPartyCount3D + jne @F + mov eax,003D6546h + mov ecx,00EBD5A0h +@@: + invoke DrawBoxBorder,esi,226,18,13,eax,ecx,1 + lea ecx,rrPartyDigits3D[ebx*2] + lea eax,[esi*2+14] + invoke DrawBuckshotText3D,eax,462,ecx,00EFE7D4h + inc ebx + cmp ebx,3 + jb rr_party_control +rr_party_controls_done: + ret +RenderRRPartyControls3D ENDP + +RenderRussianExit3D PROC + cmp engineMode,MODE_RUSSIAN + jne rr_party_exit_done + cmp cardExitActive3D,0 + jne rr_party_exit_show + cmp rr3d_state,RR_READY + je rr_party_exit_show + cmp rr3d_state,RR_WIN + je rr_party_exit_show + cmp rr3d_state,RR_PLAYER + jne rr_party_exit_done +rr_party_exit_show: + call RenderCardExit3D +rr_party_exit_done: + ret +RenderRussianExit3D ENDP diff --git a/src_graphics/russian_roulette.inc b/src_graphics/russian_roulette.inc index 2109fcd..8935046 100644 --- a/src_graphics/russian_roulette.inc +++ b/src_graphics/russian_roulette.inc @@ -1,6 +1,7 @@ ; Native roulette: one cylinder, one paid stake, cinematic states in the same window. .code FreeRussianAssets3D PROC + invoke FreeAnimPack3D,OFFSET rrPartyArt3D invoke FreeAnimPack3D,OFFSET rr3d_room invoke FreeAnimPack3D,OFFSET rr3d_dealer invoke FreeAnimPack3D,OFFSET rr3d_hands @@ -72,6 +73,8 @@ InitRussianGame3D PROC mov rr3d_timer, 0 mov rr3d_payout, 0 mov rr3d_error, 0 + mov cardExitActive3D,0 + call RRPartyInit3D @@: ret InitRussianGame3D ENDP @@ -84,22 +87,19 @@ StartRussianRound3D PROC uses ebx esi jle rr_start_empty cmp eax, bankroll ja rr_start_empty + cmp rr3d_bullets, 1 + jb rr_start_empty + cmp rr3d_bullets, 3 + ja rr_start_empty + call RRPartyReset3D + mov eax,rr3d_bet + mov rrPartyStake3D,eax + mov rrPartySettled3D,0 sub bankroll, eax - mov rr3d_mask, 0 mov rr3d_payout, 0 mov rr3d_error, 0 - xor esi, esi -rr_place_cartridge: - invoke RandomRange3D, 6 - bt rr3d_mask, eax - jc rr_place_cartridge - bts rr3d_mask, eax - inc esi - cmp esi, rr3d_bullets - jb rr_place_cartridge - invoke RandomRange3D, 6 - mov rr3d_chamber, eax - invoke RandomRange3D, 2 + call RRLoadCylinder3D + invoke RandomRange3D, rrPartySize3D mov rr3d_turn, eax mov rr3d_state, RR_LOAD mov rr3d_timer, 0 @@ -163,6 +163,11 @@ rr_next_outcome: mov rr3d_state, RR_DRY ret rr_live_round: + cmp rrPartyCount3D,1 + jbe @F + call RRPartyHit3D + ret +@@: cmp rr3d_turn, 0 je rr_player_lost mov eax, rr3d_bet @@ -170,14 +175,23 @@ rr_live_round: mov rr3d_payout, eax add bankroll, eax mov rr3d_state, RR_WIN + mov rrPartySettled3D,1 invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 20003h + invoke NpcRecordRound3D,6,1 call SaveProgress3D ret rr_player_lost: + mov rrPartySettled3D,1 mov rr3d_state, RR_GLITCH + invoke NpcRecordRound3D,6,0 call SaveProgress3D ret rr_next_chamber: + cmp rrPartyCount3D,1 + jbe @F + call RRPartyNext3D + ret +@@: inc rr3d_chamber cmp rr3d_chamber, 6 jb @F @@ -209,6 +223,14 @@ rr_next_casino: AdvanceRussianScene3D ENDP HandleRussianInput3D PROC uses ebx + call HandleCardExit3D + test eax,eax + jnz rr_input_done + call RRPartyInput3D + cmp cardExitActive3D,0 + jne rr_input_done + cmp engineMode,MODE_RUSSIAN + jne rr_input_done cmp rr3d_state, RR_READY je rr_input_ready cmp rr3d_state, RR_PLAYER @@ -295,6 +317,7 @@ rr_input_next: jz rr_input_done mov rr3d_state, RR_READY mov rr3d_timer, 0 + call RRPartyReset3D rr_input_done: ret HandleRussianInput3D ENDP @@ -542,6 +565,7 @@ RenderRussianGame3D PROC uses ebx esi edi cmp rr3d_state, RR_GMAN je rr_render_gman call RenderRussianTable3D + call RenderRussianExit3D ret invoke DrawBox, 0, 0, 320, 240, 00100D17h invoke DrawBoxBorder, 7, 7, 306, 226, 00192320h, 00BE994Ah, 2 @@ -717,5 +741,7 @@ rr_render_return: rr_render_hall: call RenderRussianHall3D rr_render_done: + call RenderRussianExit3D ret RenderRussianGame3D ENDP +include src_graphics\russian_party.inc diff --git a/src_graphics/russian_table.inc b/src_graphics/russian_table.inc index 2768dd6..7826ad8 100644 --- a/src_graphics/russian_table.inc +++ b/src_graphics/russian_table.inc @@ -9,6 +9,11 @@ RenderRussianTable3D PROC uses ebx esi edi lea edi,screenBuffer mov ecx,SCREEN_SIZE rep movsd + cmp rrPartyCount3D,1 + jbe rr_table_original_dealer + call RenderRRPartyCharacters3D + jmp rr_table_actions +rr_table_original_dealer: mov eax,0 cmp rr3d_turn,1 jne @F @@ -22,6 +27,7 @@ rr_table_dealer_active: mov eax,2 @@: invoke DrawAnimSprite3D,OFFSET rr3d_dealer,eax,192,2,256,224 +rr_table_actions: mov eax,rr3d_state cmp eax,RR_LOAD je rr_table_load @@ -92,6 +98,13 @@ rr_table_dry: mov pose,4 mov angle,128 rr_table_raised: + cmp rrPartyCount3D,1 + jbe @F + cmp rr3d_turn,0 + je @F + call RenderRRPartyGun3D + jmp rr_table_hud +@@: cmp rr3d_turn,1 je rr_table_dealer_gun ; Only the player's hands/gun are visible, never a portrait of the player. @@ -107,17 +120,45 @@ rr_table_glitch: rr_table_hud: invoke DrawBuckshotPanel3D,0,0,640,32,00111116h invoke DrawBuckshotText3D,14,12,OFFSET rrTitleText3D,00E9C47Ah - invoke DrawBuckshotText3D,488,12,OFFSET bs3d_textBank,00BCBCBCh - invoke DrawBuckshotNumber3D,540,12,bankroll,00F3E4BAh + invoke DrawBuckshotText3D,360,12,OFFSET bs3d_textBank,00BCBCBCh + invoke DrawBuckshotNumber3D,412,12,bankroll,00F3E4BAh invoke DrawBuckshotPanel3D,0,400,640,80,00111617h invoke DrawBuckshotText3D,16,414,OFFSET rrCartridgeText3D,00EBD5A0h - invoke DrawBuckshotNumber3D,160,414,rr3d_bullets,00FFFFFFh + mov ebx,rr3d_bullets + cmp rrPartyCount3D,1 + jbe @F + cmp rr3d_state,RR_READY + je @F + xor ebx,ebx + mov edx,rr3d_mask +rr_table_remaining_rounds: + shr edx,1 + adc ebx,0 + test edx,edx + jnz rr_table_remaining_rounds +@@: + invoke DrawBuckshotNumber3D,160,414,ebx,00FFFFFFh invoke DrawBuckshotText3D,456,414,OFFSET bs3d_textBet,00EBD5A0h - invoke DrawBuckshotNumber3D,528,414,rr3d_bet,00FFFFFFh + mov eax,rrPartyStake3D + cmp rr3d_state,RR_READY + je rr_table_selected_stake + test eax,eax + jnz rr_table_stake +rr_table_selected_stake: + mov eax,rr3d_bet +rr_table_stake: + invoke DrawBuckshotNumber3D,528,414,eax,00FFFFFFh mov ebx,OFFSET rrPlayerText3D cmp rr3d_turn,0 je @F mov ebx,OFFSET rrDealerText3D + cmp rrPartyCount3D,1 + jbe @F + mov eax,rr3d_turn + dec eax + cmp eax,3 + jae @F + mov ebx,rrPartyNames3D[eax*4] @@: cmp rr3d_state,RR_LOAD jne @F @@ -131,7 +172,10 @@ rr_table_hud: jne @F mov ebx,OFFSET rrClickText3D @@: + cmp rr3d_state,RR_READY + je @F invoke DrawBuckshotText3D,16,440,ebx,00E9C47Ah +@@: cmp rr3d_state,RR_READY jne rr_table_not_ready invoke DrawBuckshotText3D,16,440,OFFSET rrBulletKeys3D,00EBD5A0h @@ -154,15 +198,9 @@ rr_table_not_ready: invoke DrawBuckshotNumber3D,184,440,rr3d_payout,007FE395h invoke DrawBuckshotText3D,16,462,OFFSET rrRoundText3D,00FFFFFFh rr_table_exit_hint: - mov ebx,OFFSET bs3d_textPause - cmp rr3d_state,RR_READY - je rr_table_hall_hint - cmp rr3d_state,RR_WIN - jne @F -rr_table_hall_hint: mov ebx,OFFSET bs3d_textExit -@@: invoke DrawBuckshotText3D,530,462,ebx,00AFAFAFh + call RenderRRPartyControls3D ret rr_table_missing: invoke DrawBuckshotPanel3D,0,0,640,480,00111719h diff --git a/src_graphics/russian_view_data.inc b/src_graphics/russian_view_data.inc index f59985b..8c54ad1 100644 --- a/src_graphics/russian_view_data.inc +++ b/src_graphics/russian_view_data.inc @@ -3,3 +3,4 @@ rr3d_room AnimPack3D <> rr3d_dealer AnimPack3D <> rr3d_hands AnimPack3D <> rrHandsPath3D db "assets\animations\roulette\hands-v5.bin",0 +include src_graphics\russian_party_data.inc diff --git a/src_graphics/scene_animation_data.inc b/src_graphics/scene_animation_data.inc index a01d99c..d941b33 100644 --- a/src_graphics/scene_animation_data.inc +++ b/src_graphics/scene_animation_data.inc @@ -45,3 +45,4 @@ tableHandAnchorY3D dd 150,150,154,147,147,153,37,37 .data? tableProtectedRows3D dd (640*(88+36)) dup(?) .code +include src_graphics\native_blackjack_party_data.inc diff --git a/tools/generators/clover_cp1251.patch b/tools/generators/clover_cp1251.patch new file mode 100644 index 0000000..561b37c --- /dev/null +++ b/tools/generators/clover_cp1251.patch @@ -0,0 +1,36 @@ +diff --git a/poker.asm b/poker.asm +--- a/poker.asm ++++ b/poker.asm +@@ -165,1 +165,2 @@ + slotComboMults dd 32 dup(0) ++slotComboMasks dd 32 dup(0) +@@ -11292,1 +11293,3 @@ + mov slotComboMults[ebx * 4], edx ++ mov ecx,maskValue ++ mov slotComboMasks[ebx * 4],ecx +diff --git a/casino3d.inc b/casino3d.inc +--- a/casino3d.inc ++++ b/casino3d.inc +@@ -156,1 +156,2 @@ + include src_graphics\native_slots_data.inc ++include src_graphics\native_clover_data.inc +@@ -4730,1 +4731,4 @@ +- call BeginUnavailable3D ++ call InitNativeClover3D ++ test eax,eax ++ jz target_unported ++ mov engineMode,MODE_CLOVER +@@ -5131,1 +5135,2 @@ + include src_graphics\native_slots.inc ++include src_graphics\native_clover.inc +@@ -5255,1 +5260,7 @@ + check_slots_mode: ++ cmp engineMode,MODE_CLOVER ++ jne @F ++ call HandleNativeClover3D ++ call RenderNativeClover3D ++ jmp present_frame ++@@: +@@ -5485,1 +5496,2 @@ + call FreeNativeSlots3D ++ call FreeNativeClover3D diff --git a/tools/generators/generate_npc_mind.py b/tools/generators/generate_npc_mind.py new file mode 100644 index 0000000..2558c87 --- /dev/null +++ b/tools/generators/generate_npc_mind.py @@ -0,0 +1,1289 @@ +# -*- coding: utf-8 -*- +""" +Generator for NPC Mind AI system: +- src_graphics/npc_mind_data.inc +- src_graphics/npc_mind.inc +Both written in CP1251 encoding. +""" + +import os + +data_inc_path = r"src_graphics\npc_mind_data.inc" +code_inc_path = r"src_graphics\npc_mind.inc" + +DATA_CONTENT = r'''; ============================================================================== +; NPC MIND DATA - MASM32 / CP1251 +; Multi-agent AI: Open-space Navigation, Personalities & Multi-seat Poker +; ============================================================================== + +NPCAI_ARCHETYPE_SHARK equ 0 ; Ð�кула (Tight-Aggressive) +NPCAI_ARCHETYPE_MANIAC equ 1 ; Лудоман (Loose-Aggressive) +NPCAI_ARCHETYPE_ROCK equ 2 ; Скала (Tight-Passive) +NPCAI_ARCHETYPE_CALLING_STATION equ 3 ; Ð�втоответчик (Loose-Passive) +NPCAI_ARCHETYPE_WHALE equ 4 ; Мажор (Ð’Ñ‹Ñ�окий банкролл, хаоÑ�) +NPCAI_ARCHETYPE_ROOKIE equ 5 ; Ð�овичок (Ошибки, неуверенноÑ�ть) + +NPCAI_STATE_IDLE equ 0 ; Стоит, оÑ�матриваетÑ�Ñ� +NPCAI_STATE_WALK equ 1 ; Идет по вейпоинтам +NPCAI_STATE_GAMBLE equ 2 ; Играет за Ñ�толом +NPCAI_STATE_BAR equ 3 ; У бара +NPCAI_STATE_ATM equ 4 ; У банкомата +NPCAI_STATE_STAGE equ 5 ; Смотрит шоу + +MPK_SEAT_EMPTY equ 0 +MPK_SEAT_ACTIVE equ 1 +MPK_SEAT_FOLDED equ 2 +MPK_SEAT_ALLIN equ 3 +MPK_SEAT_BUST equ 4 + +MPK_ACT_NONE equ 0 +MPK_ACT_FOLD equ 1 +MPK_ACT_CHECK equ 2 +MPK_ACT_CALL equ 3 +MPK_ACT_RAISE equ 4 +MPK_ACT_ALLIN equ 5 + +MPK_STAGE_PREFLOP equ 0 +MPK_STAGE_FLOP equ 1 +MPK_STAGE_TURN equ 2 +MPK_STAGE_RIVER equ 3 +MPK_STAGE_SHOWDOWN equ 4 + +NPCAI_MAX_NPCS equ 6 +MPK_MAX_SEATS equ 4 +NPCAI_WAYPOINT_COUNT equ 16 + +; ------------------------------------------------------------------------------ +; Структуры данных +; ------------------------------------------------------------------------------ + +NpcPersonality STRUCT + namePtr dd ? + titlePtr dd ? + archetypeId dd ? + baseAggression dd ? ; 0..100 + baseTightness dd ? ; 0..100 + baseBluffRate dd ? ; 0..100 + baseCourage dd ? ; 0..100 + tiltSens dd ? ; 0..100 + defaultBank dd ? + phraseWinPtr dd ? + phraseLosePtr dd ? + phraseBluffPtr dd ? + phraseBustPtr dd ? +NpcPersonality ENDS + +NpcMindEntity STRUCT + posX dd ? ; 16.16 FP + posY dd ? ; 16.16 FP + dirX dd ? ; 16.16 FP + dirY dd ? ; 16.16 FP + speed dd ? ; 16.16 FP + state dd ? ; NPCAI_STATE_* + stateTimer dd ? + currentNode dd ? + targetNode dd ? + profileId dd ? + currentChips dd ? + currentTilt dd ? ; 0..100 + thoughtPtr dd ? + reactionPtr dd ? +NpcMindEntity ENDS + +MpkSeat STRUCT + isHuman dd ? ; 1=Player, 0=NPC + profileId dd ? ; ИндекÑ� NpcPersonality (0..5) + chips dd ? + roundBet dd ? + totalBet dd ? + card1 dd ? + card2 dd ? + evalScore dd ? + seatStatus dd ? ; MPK_SEAT_* + lastAction dd ? ; MPK_ACT_* + lastRaiseAmount dd ? + thoughtPtr dd ? + reactionPtr dd ? +MpkSeat ENDS + +MultiPokerTable STRUCT + seats MpkSeat MPK_MAX_SEATS dup(<>) + commCards dd 5 dup(?) + commCount dd ? + mainPot dd ? + currentHighBet dd ? + minRaise dd ? + dealerButton dd ? + currentTurn dd ? + activeSeats dd ? + smallBlind dd ? + bigBlind dd ? + stage dd ? +MultiPokerTable ENDS + +NpcWaypoint STRUCT + posX dd ? ; 16.16 FP + posY dd ? ; 16.16 FP + neighbor0 dd ? + neighbor1 dd ? + neighbor2 dd ? + neighbor3 dd ? + zoneType dd ? +NpcWaypoint ENDS + +; ------------------------------------------------------------------------------ +; Строковые конÑ�танты и опиÑ�аниÑ� (CP1251) +; ------------------------------------------------------------------------------ + +.data + +; Имена и титулы 6 уникальных перÑ�онажей +npcName0 db "Виктор «Ð�кула»",0 +npcTitle0 db "ПрофеÑ�Ñ�ионал (Tight-Aggressive)",0 + +npcName1 db "Сергей «Лудоман»",0 +npcTitle1 db "МаньÑ�к (Loose-Aggressive, ТИЛЬТ)",0 + +npcName2 db "ДÑ�дÑ� ТолÑ� «Скала»",0 +npcTitle2 db "Ветеран (Tight-Passive)",0 + +npcName3 db "Степан «Ð�втоответчик»",0 +npcTitle3 db "Любитель (Calling Station)",0 + +npcName4 db "Мажор Ð�ртём",0 +npcTitle4 db "Хайроллер (Whale, Безумные Ñ�тавки)",0 + +npcName5 db "Влад «Ð�овичок»",0 +npcTitle5 db "Студент (Rookie, Ð�еопытный)",0 + +; Фразы победы +npcWin0 db "«Холодный раÑ�чет и никакой магии. Банк мой.»",0 +npcWin1 db "«ХÐ�-Ð¥Ð�! Кто тут король казино?! Ð’Ñ�е фишки Ñ�юда!»",0 +npcWin2 db "«Тише едешь — дальше будешь, молодежь.»",0 +npcWin3 db "«Опа, закрылÑ�Ñ� Ñ�трит! Ð� вы не верили!»",0 +npcWin4 db "«Официант, вÑ�ем шампанÑ�кого за мой Ñ�чет!»",0 +npcWin5 db "«Ого! Ð�еужели Ñ� правда победил?! Вот Ñ�то да!»",0 + +; Фразы поражениÑ� / бÑ�дбита +npcLose0 db "«Бывает. МатематичеÑ�каÑ� диÑ�перÑ�иÑ� на диÑ�танции вернет вÑ�Ñ‘.»",0 +npcLose1 db "«ДÐ� КÐ�К ТÐ�К-ТО?! ОпÑ�ть ривером переехали, Ñ�ука!»",0 +npcLose2 db "«Знал ведь, что надо было Ñ�браÑ�ывать еще на флопе...»",0 +npcLose3 db "«Эх, чутка не хватило до флеша... в Ñ�ледующий раз повезет.»",0 +npcLose4 db "«Пф-Ñ„, копейки. СейчаÑ� Ñ�ниму еще пачку в банкомате.»",0 +npcLose5 db "«Я так и знал... Ð�адо было внимательнее читать правила.»",0 + +; Фразы блефа / рейза +npcBluff0 db "«ТвоÑ� рука Ñ�лабее. СÑ�кономь фишки и паÑ�уй.»",0 +npcBluff1 db "«Слабаки! Вам не по карману Ñ�тот банк, двигайте паÑ�!»",0 +npcBluff2 db "«У менÑ� отличнаÑ� карта. Ð�е Ñ�оветую лезть под колеÑ�а.»",0 +npcBluff3 db "«Ð� Ñ� проÑ�то хочу поÑ�мотреть Ñ�ледующую карту!»",0 +npcBluff4 db "«Вы Ñ�тавите копейки! Давайте играть по-взроÑ�лому!»",0 +npcBluff5 db "«Э-Ñ�... кажетÑ�Ñ�, Ñ� поднимаю Ñ�тавку. Ð’Ñ‹ Ñ�о мной?»",0 + +; Фразы банкротÑ�тва +npcBust0 db "«Лимит на Ñ�егоднÑ� иÑ�черпан. Пора делать паузу.»",0 +npcBust1 db "«ВÑ�Ñ‘ в ноль! Бегу к банкомату, Ñ� обÑ�зан отыгратьÑ�Ñ�!»",0 +npcBust2 db "«ПенÑ�иÑ� кончилаÑ�ÑŒ... Пойду подышу на Ñ�вежем воздухе.»",0 +npcBust3 db "«Ой, фишки кончилиÑ�ÑŒ... Пойду в бар за пивом.»",0 +npcBust4 db "«ОпÑ�ть обнулилÑ�Ñ�? Ерунда, Ñ�ейчаÑ� Ñ�ниму еще $50,000.»",0 +npcBust5 db "«КажетÑ�Ñ�, на метро мне уже не хватает...»",0 + +; МыÑ�ли в Ñ�вободном перемещении по казино +thWalkWander db "ОÑ�матривает игровой зал в поиÑ�ках интереÑ�ной игры",0 +thWalkTable db "Ð�аправлÑ�етÑ�Ñ� к покерному Ñ�толу иÑ�пытать удачу",0 +thWalkBar db "Решил заглÑ�нуть в бар за напитком",0 +thWalkAtm db "ЗакончилиÑ�ÑŒ фишки, направлÑ�етÑ�Ñ� к банкомату",0 +thWalkStage db "Подходит к Ñ�цене поÑ�мотреть на танцовщиц",0 +thIdleBored db "Стоит у колонны, подÑ�читывает оÑ�тавшиеÑ�Ñ� деньги",0 + +; МыÑ�ли за покерным Ñ�толом +thEvalStrong db "ЧувÑ�твует натÑ�! Готовит ловушку длÑ� оппонентов.",0 +thEvalGood db "Рука Ñ�ильнаÑ�, отличные шанÑ�Ñ‹ забрать Ñ�тот банк.",0 +thEvalDraw db "Считает ауты: шанÑ�Ñ‹ банка выгодны длÑ� колла.",0 +thEvalTrash db "Карты — муÑ�ор. СмыÑ�ла риÑ�ковать фишками нет.",0 +thEvalTilted db "[ТИЛЬТ!] ЗлитÑ�Ñ� поÑ�ле проигрыша и идет на таран!",0 +thEvalBluffing db "БЛЕФ! Изображает монÑ�тра и давит Ñ�тавкой!",0 + +; ОпиÑ�аниÑ� дейÑ�твий +thActFold db "СбраÑ�ывает карты в паÑ�",0 +thActCheck db "Чекает, пропуÑ�каÑ� ход",0 +thActCall db "Коллирует (уравнивает) текущую Ñ�тавку",0 +thActRaise db "Повышает Ñ�тавку (рейз!)",0 +thActAllIn db "Двигает вÑ�е фишки вперед — Ð’Ð�-БÐ�Ð�К (ОЛЛ-ИÐ�)!",0 + +; Ð�азваниÑ� улиц покера +strStagePreflop db "Префлоп (Карманные карты)",0 +strStageFlop db "Флоп (3 карты Ñ�тола)",0 +strStageTurn db "Терн (4 карты Ñ�тола)",0 +strStageRiver db "Ривер (5 карт Ñ�тола)",0 +strStageShow db "Ð’Ñ�крытие карт (Showdown)",0 + +; ТекÑ�ты интерфейÑ�а мульти-покера +mpkTitleStr db "=== ТЕХÐ�ССКИЙ ХОЛДЕМ: СТОЛ Ð�Ð� 4 ИГРОКÐ� ===",13,10,0 +mpkPotStr db "Банк Ñ�тола: $",0 +mpkStreetStr db " | Раунд: ",0 +mpkCommCardsStr db "Общие карты на Ñ�толе: ",0 +mpkPromptStr db "Ваш ход: [1] Чек/Колл | [2] Рейз | [0] ПаÑ� -> ",0 +mpkWaitNextStr db 13,10,"[Ð�ажмите любую клавишу длÑ� Ñ�ледующей раздачи, 0 длÑ� выхода]...",0 +mpkChipsPrefix db " Стек: $",0 +mpkThoughtPrefix db " [МыÑ�ли]: ",0 +mpkGameOverStr db 13,10,"Раздача окончена. Победитель: ",0 +mpkWinChipsStr db " выиграл банк $",0 + +ALIGN 4 + +; База профилей 6 уникальных личноÑ�тей +casinoNpcProfiles NpcPersonality + NpcPersonality + NpcPersonality + NpcPersonality + NpcPersonality + NpcPersonality + +; Граф вейпоинтов казино (координаты 16.16 FP и Ñ�вÑ�зи) +casinoWaypoints3D NpcWaypoint <16*FP_1, 28*FP_1, 1, 4, 8, 0, 0> ; 0: Вход в казино + NpcWaypoint <16*FP_1, 20*FP_1, 0, 2, 4, 8, 0> ; 1: Центр холла (юг) + NpcWaypoint <16*FP_1, 14*FP_1, 1, 3, 10, 12, 0> ; 2: Центр холла (Ñ�евер) + NpcWaypoint <16*FP_1, 6*FP_1, 2, 10, 12, 3, 7> ; 3: Перед Ñ�ценой танцовщиц + NpcWaypoint < 8*FP_1, 20*FP_1, 0, 1, 5, 7, 0> ; 4: Западный коридор + NpcWaypoint < 6*FP_1, 14*FP_1, 4, 6, 2, 5, 4> ; 5: Ð�втоматы 777 + NpcWaypoint < 6*FP_1, 9*FP_1, 5, 10, 2, 6, 4> ; 6: Ð�втоматы CloverPit + NpcWaypoint < 4*FP_1, 25*FP_1, 4, 0, 7, 7, 5> ; 7: БарнаÑ� Ñ�тойка + NpcWaypoint <24*FP_1, 20*FP_1, 0, 1, 9, 14, 0> ; 8: ВоÑ�точный коридор + NpcWaypoint <26*FP_1, 25*FP_1, 8, 0, 9, 9, 0> ; 9: Зона отдыха VIP + NpcWaypoint <12*FP_1, 9*FP_1, 2, 3, 6, 11, 2> ; 10: Стол БлÑ�кджека + NpcWaypoint <16*FP_1, 11*FP_1, 2, 10, 12, 11, 3> ; 11: Стол Рулетки + NpcWaypoint <20*FP_1, 9*FP_1, 2, 3, 11, 13, 1> ; 12: Стол Покера (Холдем) + NpcWaypoint <24*FP_1, 9*FP_1, 12, 8, 14, 13, 1> ; 13: Стол Дурака + NpcWaypoint <26*FP_1, 15*FP_1, 8, 13, 14, 14, 6> ; 14: Банкомат (ATM) + NpcWaypoint <10*FP_1, 15*FP_1, 2, 4, 5, 10, 0> ; 15: Зона коÑ�тей/черепов + +; 6 активных перÑ�онажей, гулÑ�ющих по залу казино +casinoNpcs3D NpcMindEntity NPCAI_MAX_NPCS dup(<>) + +; ЭкземплÑ�Ñ€ Ñ�тола мульти-покера +multiPokerTable MultiPokerTable <> + +; Колода и рабочий буфер длÑ� мульти-покера +multiDeck dd 52 dup(0) +multiDeckIndex dd 0 +multiEvalHand dd 7 dup(0) +multiActionWait dd 0 +'''.strip() + +CODE_CONTENT = r'''; ============================================================================== +; NPC MIND CODE - MASM32 / CP1251 +; Logic, Pathfinding Steering, Personality Thinking & Multi-Seat Poker Engine +; ============================================================================== + +.code + +; ------------------------------------------------------------------------------ +; InitCasinoNpcMind: ИнициализациÑ� вÑ�ех 6 перÑ�онажей и их Ñ�тартовых точек +; ------------------------------------------------------------------------------ +InitCasinoNpcMind PROC uses ebx esi edi + xor esi, esi +npc_init_loop: + mov eax, esi + imul eax, SIZEOF NpcMindEntity + lea edi, casinoNpcs3D[eax] + + ; ПривÑ�зка к профилю (0..5) + mov [edi].NpcMindEntity.profileId, esi + + ; Задаем Ñ�тартовые координаты у разных вейпоинтов + ; NPC 0 (Ð�кула) -> у Ñ�тола покера (узел 12) + ; NPC 1 (Лудоман) -> у автоматов (узел 5) + ; NPC 2 (Скала) -> у блÑ�кджека (узел 10) + ; NPC 3 (Ð�втоответчик) -> у бара (узел 7) + ; NPC 4 (Мажор) -> у Ñ�цены (узел 3) + ; NPC 5 (Ð�овичок) -> у входа (узел 0) + mov eax, esi + cmp eax, 0 + jne @F + mov ebx, 12 + jmp set_start_node +@@: + cmp eax, 1 + jne @F + mov ebx, 5 + jmp set_start_node +@@: + cmp eax, 2 + jne @F + mov ebx, 10 + jmp set_start_node +@@: + cmp eax, 3 + jne @F + mov ebx, 7 + jmp set_start_node +@@: + cmp eax, 4 + jne @F + mov ebx, 3 + jmp set_start_node +@@: + mov ebx, 0 + +set_start_node: + mov [edi].NpcMindEntity.currentNode, ebx + mov [edi].NpcMindEntity.targetNode, ebx + + imul ebx, SIZEOF NpcWaypoint + mov eax, casinoWaypoints3D[ebx].posX + mov [edi].NpcMindEntity.posX, eax + mov eax, casinoWaypoints3D[ebx].posY + mov [edi].NpcMindEntity.posY, eax + + mov [edi].NpcMindEntity.speed, (FP_1 / 18) ; СкороÑ�ть ходьбы + mov [edi].NpcMindEntity.state, NPCAI_STATE_IDLE + mov [edi].NpcMindEntity.currentTilt, 0 + + ; Стартовые фишки из профилÑ� + mov eax, esi + imul eax, SIZEOF NpcPersonality + mov ebx, casinoNpcProfiles[eax].defaultBank + mov [edi].NpcMindEntity.currentChips, ebx + + ; Стартовый таймер и мыÑ�ли + invoke RandomRange, 60 + add eax, 40 + mov [edi].NpcMindEntity.stateTimer, eax + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thIdleBored + mov [edi].NpcMindEntity.reactionPtr, 0 + + inc esi + cmp esi, NPCAI_MAX_NPCS + jb npc_init_loop + ret +InitCasinoNpcMind ENDP + +; ------------------------------------------------------------------------------ +; UpdateCasinoNpcMind: Покадровое обновление поведениÑ� и перемещениÑ� NPC в зале +; ------------------------------------------------------------------------------ +UpdateCasinoNpcMind PROC uses ebx esi edi + local nextX:DWORD, nextY:DWORD, dxFP:DWORD, dyFP:DWORD + + xor esi, esi +npc_update_loop: + mov eax, esi + imul eax, SIZEOF NpcMindEntity + lea edi, casinoNpcs3D[eax] + + ; 1. Плавное оÑ�тывание тильта Ñ�о временем + mov eax, [edi].NpcMindEntity.currentTilt + test eax, eax + jz @F + dec [edi].NpcMindEntity.currentTilt +@@: + + ; 2. Машина Ñ�оÑ�тоÑ�ний + mov eax, [edi].NpcMindEntity.state + cmp eax, NPCAI_STATE_IDLE + je npc_handle_idle + cmp eax, NPCAI_STATE_WALK + je npc_handle_walk + jmp npc_handle_activity + +npc_handle_idle: + dec [edi].NpcMindEntity.stateTimer + jnz npc_next_entity + + ; ВремÑ� ожиданиÑ� иÑ�текло -> выбираем новую цель + ; ЕÑ�ли фишек мало (< 500) -> идем к банкомату + cmp [edi].NpcMindEntity.currentChips, 500 + jge @F + mov [edi].NpcMindEntity.targetNode, 14 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkAtm + jmp start_walking +@@: + ; Иначе выбираем Ñ�лучайный узел назначениÑ� + invoke RandomRange, NPCAI_WAYPOINT_COUNT + mov [edi].NpcMindEntity.targetNode, eax + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkWander + +start_walking: + mov [edi].NpcMindEntity.state, NPCAI_STATE_WALK + jmp npc_next_entity + +npc_handle_activity: + dec [edi].NpcMindEntity.stateTimer + jnz npc_next_entity + ; Ð�ктивноÑ�ть закончена (поиграл, выпил, Ñ�нÑ�л деньги) + mov [edi].NpcMindEntity.state, NPCAI_STATE_IDLE + invoke RandomRange, 50 + add eax, 40 + mov [edi].NpcMindEntity.stateTimer, eax + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thIdleBored + jmp npc_next_entity + +npc_handle_walk: + ; РаÑ�чет вектора к целевому вейпоинту + mov ebx, [edi].NpcMindEntity.targetNode + imul ebx, SIZEOF NpcWaypoint + mov eax, casinoWaypoints3D[ebx].posX + sub eax, [edi].NpcMindEntity.posX + mov dxFP, eax + + mov eax, casinoWaypoints3D[ebx].posY + sub eax, [edi].NpcMindEntity.posY + mov dyFP, eax + + ; Проверка близоÑ�ти к целевой точке (|dx| < FP_HALF и |dy| < FP_HALF) + mov eax, dxFP + test eax, eax + jns @F + neg eax +@@: + cmp eax, (FP_HALF / 2) + jae move_towards_target + + mov eax, dyFP + test eax, eax + jns @F + neg eax +@@: + cmp eax, (FP_HALF / 2) + jae move_towards_target + + ; Прибыли на вейпоинт! + mov eax, [edi].NpcMindEntity.targetNode + mov [edi].NpcMindEntity.currentNode, eax + + ; ПроверÑ�ем тип зоны Ñ�того вейпоинта + mov ebx, eax + imul ebx, SIZEOF NpcWaypoint + mov eax, casinoWaypoints3D[ebx].zoneType + + cmp eax, 1 ; Покер + je enter_gamble + cmp eax, 2 ; БлÑ�кджек + je enter_gamble + cmp eax, 5 ; Бар + je enter_bar + cmp eax, 6 ; Банкомат + je enter_atm + cmp eax, 7 ; Сцена + je enter_stage + + ; Обычный коридор -> пауза и выбор Ñ�ледующего + mov [edi].NpcMindEntity.state, NPCAI_STATE_IDLE + invoke RandomRange, 40 + add eax, 30 + mov [edi].NpcMindEntity.stateTimer, eax + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thIdleBored + jmp npc_next_entity + +enter_gamble: + mov [edi].NpcMindEntity.state, NPCAI_STATE_GAMBLE + mov [edi].NpcMindEntity.stateTimer, 120 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkTable + jmp npc_next_entity + +enter_bar: + mov [edi].NpcMindEntity.state, NPCAI_STATE_BAR + mov [edi].NpcMindEntity.stateTimer, 100 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkBar + jmp npc_next_entity + +enter_atm: + mov [edi].NpcMindEntity.state, NPCAI_STATE_ATM + mov [edi].NpcMindEntity.stateTimer, 80 + add [edi].NpcMindEntity.currentChips, 3000 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkAtm + jmp npc_next_entity + +enter_stage: + mov [edi].NpcMindEntity.state, NPCAI_STATE_STAGE + mov [edi].NpcMindEntity.stateTimer, 150 + mov [edi].NpcMindEntity.thoughtPtr, OFFSET thWalkStage + jmp npc_next_entity + +move_towards_target: + ; Делаем шаг в направлении цели + mov eax, [edi].NpcMindEntity.posX + cmp dxFP, 0 + jle move_left + add eax, [edi].NpcMindEntity.speed + jmp check_step_x +move_left: + sub eax, [edi].NpcMindEntity.speed +check_step_x: + mov nextX, eax + + mov eax, [edi].NpcMindEntity.posY + cmp dyFP, 0 + jle move_up + add eax, [edi].NpcMindEntity.speed + jmp check_step_y +move_up: + sub eax, [edi].NpcMindEntity.speed +check_step_y: + mov nextY, eax + + ; Проверка коллизий через CanWalk3D + invoke CanWalk3D, nextX, [edi].NpcMindEntity.posY + test eax, eax + jz @F + mov eax, nextX + mov [edi].NpcMindEntity.posX, eax +@@: + invoke CanWalk3D, [edi].NpcMindEntity.posX, nextY + test eax, eax + jz npc_next_entity + mov eax, nextY + mov [edi].NpcMindEntity.posY, eax + +npc_next_entity: + inc esi + cmp esi, NPCAI_MAX_NPCS + jb npc_update_loop + ret +UpdateCasinoNpcMind ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_InitTable: Подготовка Ñ�тола на 4 меÑ�та (Игрок + 3 бота) +; ------------------------------------------------------------------------------ +MultiPoker_InitTable PROC uses ebx esi edi + lea edi, multiPokerTable + + mov [edi].MultiPokerTable.commCount, 0 + mov [edi].MultiPokerTable.mainPot, 0 + mov [edi].MultiPokerTable.currentHighBet, 0 + mov [edi].MultiPokerTable.minRaise, 100 + mov [edi].MultiPokerTable.smallBlind, 50 + mov [edi].MultiPokerTable.bigBlind, 100 + mov [edi].MultiPokerTable.dealerButton, 0 + mov [edi].MultiPokerTable.activeSeats, 4 + mov [edi].MultiPokerTable.stage, MPK_STAGE_PREFLOP + + ; МеÑ�то 0: Игрок + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].isHuman, 1 + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].profileId, 0 + mov eax, bankroll + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].chips, eax + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].seatStatus, MPK_SEAT_ACTIVE + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].lastAction, MPK_ACT_NONE + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].thoughtPtr, 0 + mov [edi].MultiPokerTable.seats[0*SIZEOF MpkSeat].reactionPtr, 0 + + ; МеÑ�то 1: Виктор «Ð�кула» (профиль 0) + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].isHuman, 0 + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].profileId, 0 + mov eax, casinoNpcProfiles[0*SIZEOF NpcPersonality].defaultBank + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].chips, eax + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].seatStatus, MPK_SEAT_ACTIVE + mov [edi].MultiPokerTable.seats[1*SIZEOF MpkSeat].lastAction, MPK_ACT_NONE + + ; МеÑ�то 2: Сергей «Лудоман» (профиль 1) + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].isHuman, 0 + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].profileId, 1 + mov eax, casinoNpcProfiles[1*SIZEOF NpcPersonality].defaultBank + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].chips, eax + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].seatStatus, MPK_SEAT_ACTIVE + mov [edi].MultiPokerTable.seats[2*SIZEOF MpkSeat].lastAction, MPK_ACT_NONE + + ; МеÑ�то 3: ДÑ�дÑ� ТолÑ� «Скала» (профиль 2) + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].isHuman, 0 + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].profileId, 2 + mov eax, casinoNpcProfiles[2*SIZEOF NpcPersonality].defaultBank + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].chips, eax + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].seatStatus, MPK_SEAT_ACTIVE + mov [edi].MultiPokerTable.seats[3*SIZEOF MpkSeat].lastAction, MPK_ACT_NONE + ret +MultiPoker_InitTable ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_ShuffleDeck: Заполнение и таÑ�овка колоды из 52 карт +; ------------------------------------------------------------------------------ +MultiPoker_ShuffleDeck PROC uses ebx esi edi + ; ЗаполнÑ�ем 0..51 + xor ecx, ecx +fill_deck: + mov multiDeck[ecx*4], ecx + inc ecx + cmp ecx, 52 + jb fill_deck + + ; ТаÑ�овка Фишера-ЙетÑ�а + mov ecx, 51 +shuffle_loop: + push ecx + inc ecx + invoke RandomRange, ecx + pop ecx + ; Обмен multiDeck[ecx*4] и multiDeck[eax*4] + mov edx, multiDeck[ecx*4] + mov ebx, multiDeck[eax*4] + mov multiDeck[ecx*4], ebx + mov multiDeck[eax*4], edx + dec ecx + jnz shuffle_loop + + mov multiDeckIndex, 0 + ret +MultiPoker_ShuffleDeck ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_StartHand: Раздача карт и Ñ�бор блайндов +; ------------------------------------------------------------------------------ +MultiPoker_StartHand PROC uses ebx esi edi + lea edi, multiPokerTable + + call MultiPoker_ShuffleDeck + + mov [edi].MultiPokerTable.commCount, 0 + mov [edi].MultiPokerTable.mainPot, 0 + mov [edi].MultiPokerTable.currentHighBet, 0 + mov [edi].MultiPokerTable.stage, MPK_STAGE_PREFLOP + + ; Передвигаем баттон дилера + mov eax, [edi].MultiPokerTable.dealerButton + inc eax + and eax, 3 + mov [edi].MultiPokerTable.dealerButton, eax + + ; Раздаем по 2 карты каждому активному меÑ�ту + xor esi, esi +deal_seats_loop: + imul eax, esi, SIZEOF MpkSeat + lea ebx, [edi].MultiPokerTable.seats[eax] + + ; ЕÑ�ли нет фишек -> выбыл + cmp [ebx].MpkSeat.chips, 50 + jae seat_can_play + mov [ebx].MpkSeat.seatStatus, MPK_SEAT_BUST + jmp next_deal_seat + +seat_can_play: + mov [ebx].MpkSeat.seatStatus, MPK_SEAT_ACTIVE + mov [ebx].MpkSeat.roundBet, 0 + mov [ebx].MpkSeat.totalBet, 0 + mov [ebx].MpkSeat.lastAction, MPK_ACT_NONE + + ; Карта 1 + mov edx, multiDeckIndex + mov eax, multiDeck[edx*4] + mov [ebx].MpkSeat.card1, eax + inc multiDeckIndex + + ; Карта 2 + mov edx, multiDeckIndex + mov eax, multiDeck[edx*4] + mov [ebx].MpkSeat.card2, eax + inc multiDeckIndex + +next_deal_seat: + inc esi + cmp esi, MPK_MAX_SEATS + jb deal_seats_loop + + ; Раздаем 5 общих карт на Ñ�тол (пока Ñ�крыты) + xor esi, esi +deal_comm_loop: + mov edx, multiDeckIndex + mov eax, multiDeck[edx*4] + mov [edi].MultiPokerTable.commCards[esi*4], eax + inc multiDeckIndex + inc esi + cmp esi, 5 + jb deal_comm_loop + + ; Сбор Малого Блайнда + mov eax, [edi].MultiPokerTable.dealerButton + inc eax + and eax, 3 + imul eax, SIZEOF MpkSeat + mov ebx, [edi].MultiPokerTable.smallBlind + sub [edi].MultiPokerTable.seats[eax].chips, ebx + mov [edi].MultiPokerTable.seats[eax].roundBet, ebx + add [edi].MultiPokerTable.mainPot, ebx + + ; Сбор Большого Блайнда + mov eax, [edi].MultiPokerTable.dealerButton + add eax, 2 + and eax, 3 + imul eax, SIZEOF MpkSeat + mov ebx, [edi].MultiPokerTable.bigBlind + sub [edi].MultiPokerTable.seats[eax].chips, ebx + mov [edi].MultiPokerTable.seats[eax].roundBet, ebx + add [edi].MultiPokerTable.mainPot, ebx + + mov eax, [edi].MultiPokerTable.bigBlind + mov [edi].MultiPokerTable.currentHighBet, eax + + ; Первый ход поÑ�ле ББ + mov eax, [edi].MultiPokerTable.dealerButton + add eax, 3 + and eax, 3 + mov [edi].MultiPokerTable.currentTurn, eax + ret +MultiPoker_StartHand ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_NpcDecideTurn: ГлубокаÑ� логика принÑ�тиÑ� решений ИИ бота +; Вход: seatIdx (0..3) +; ------------------------------------------------------------------------------ +MultiPoker_NpcDecideTurn PROC uses ebx esi edi, seatIdx:DWORD + local pSeat:DWORD, pProf:DWORD + local toCall:DWORD, handScore:DWORD, potOdds:DWORD + local aggro:DWORD, bluff:DWORD, courage:DWORD, tilt:DWORD + + ; 1. Получаем указатели на Ñ�тул и профиль + mov eax, seatIdx + imul eax, SIZEOF MpkSeat + lea esi, multiPokerTable.seats[eax] + mov pSeat, esi + + mov eax, [esi].MpkSeat.profileId + imul eax, SIZEOF NpcPersonality + lea edi, casinoNpcProfiles[eax] + mov pProf, edi + + ; Сумма длÑ� колла + mov eax, multiPokerTable.currentHighBet + sub eax, [esi].MpkSeat.roundBet + mov toCall, eax + + ; 2. Оценка Ñ�илы руки (0..100) + ; Карманные карты + mov eax, [esi].MpkSeat.card1 + mov multiEvalHand[0], eax + mov eax, [esi].MpkSeat.card2 + mov multiEvalHand[4], eax + + mov ecx, multiPokerTable.commCount + test ecx, ecx + jz eval_preflop_hand + + ; ПоÑ�тфлоп: копируем открытые карты Ñ�тола + xor edx, edx +copy_comm_eval: + mov eax, multiPokerTable.commCards[edx*4] + mov multiEvalHand[edx*4 + 8], eax + inc edx + cmp edx, ecx + jb copy_comm_eval + + lea eax, [ecx + 2] + invoke EvaluatePokerN, OFFSET multiEvalHand, eax + ; Score / 100 дает примерный процент Ñ�илы + xor edx, edx + mov ecx, 80 + div ecx + mov handScore, eax + jmp apply_multi_opponent + +eval_preflop_hand: + ; Префлоп Ñ�вриÑ�тика: Ñ�таршинÑ�тво и карманные пары + mov eax, [esi].MpkSeat.card1 + xor edx, edx + mov ecx, 13 + div ecx + mov ebx, edx ; ранг 1 (0..12) + + mov eax, [esi].MpkSeat.card2 + xor edx, edx + div ecx + mov ecx, edx ; ранг 2 (0..12) + + cmp ebx, ecx + jne preflop_ranks + ; Пара! + lea eax, [ebx*4 + 40] + mov handScore, eax + jmp apply_multi_opponent + +preflop_ranks: + lea eax, [ebx + ecx] + imul eax, 3 + add eax, 15 + mov handScore, eax + +apply_multi_opponent: + ; Штраф за игру против неÑ�кольких оппонентов + mov ecx, multiPokerTable.activeSeats + cmp ecx, 2 + jbe @F + imul ecx, 4 + sub handScore, ecx + jns @F + mov handScore, 5 +@@: + + ; 3. ПÑ�ихологичеÑ�кие модификаторы + ТИЛЬТ + ; Ð�аходим Ñ�оответÑ�твующего NPC в casinoNpcs3D длÑ� учета текущего тильта + mov eax, [esi].MpkSeat.profileId + imul eax, SIZEOF NpcMindEntity + mov eax, casinoNpcs3D[eax].currentTilt + mov tilt, eax + + mov eax, [edi].NpcPersonality.baseAggression + mov edx, tilt + shr edx, 1 + add eax, edx + mov aggro, eax + + mov eax, [edi].NpcPersonality.baseBluffRate + add eax, tilt + mov bluff, eax + + mov eax, [edi].NpcPersonality.baseCourage + mov courage, eax + + ; 4. РаÑ�чет шанÑ�ов банка (Pot Odds) + cmp toCall, 0 + je branch_free_check + + ; potOdds = (toCall * 100) / (mainPot + toCall) + mov eax, toCall + imul eax, 100 + mov ecx, multiPokerTable.mainPot + add ecx, toCall + test ecx, ecx + jnz @F + mov ecx, 1 +@@: + xor edx, edx + div ecx + mov potOdds, eax + + ; Проверка на блеф Ñ�о Ñ�лабой рукой + cmp handScore, 30 + ja check_standard_call + invoke RandomRange, 100 + cmp eax, bluff + jbe decide_bluff_raise + +check_standard_call: + ; Сравнение Ñ�илы руки и шанÑ�ов банка + mov eax, handScore + add eax, courage + shr eax, 1 + cmp eax, potOdds + jb decide_fold_action + + ; Рука доÑ�таточна длÑ� продолжениÑ�! ПроверÑ�ем желание рейзить + mov eax, handScore + add eax, aggro + cmp eax, 120 + jae decide_value_raise + + ; Стандартный Колл + mov [esi].MpkSeat.lastAction, MPK_ACT_CALL + mov [esi].MpkSeat.thoughtPtr, OFFSET thActCall + mov eax, [edi].NpcPersonality.phraseWinPtr + mov [esi].MpkSeat.reactionPtr, eax + ret + +decide_value_raise: + mov [esi].MpkSeat.lastAction, MPK_ACT_RAISE + mov eax, multiPokerTable.minRaise + imul eax, 2 + mov [esi].MpkSeat.lastRaiseAmount, eax + mov [esi].MpkSeat.thoughtPtr, OFFSET thEvalGood + mov eax, [edi].NpcPersonality.phraseBluffPtr + mov [esi].MpkSeat.reactionPtr, eax + ret + +decide_bluff_raise: + mov [esi].MpkSeat.lastAction, MPK_ACT_RAISE + mov eax, multiPokerTable.minRaise + imul eax, 3 + mov [esi].MpkSeat.lastRaiseAmount, eax + mov [esi].MpkSeat.thoughtPtr, OFFSET thEvalBluffing + mov eax, [edi].NpcPersonality.phraseBluffPtr + mov [esi].MpkSeat.reactionPtr, eax + ret + +decide_fold_action: + mov [esi].MpkSeat.lastAction, MPK_ACT_FOLD + mov [esi].MpkSeat.seatStatus, MPK_SEAT_FOLDED + mov [esi].MpkSeat.thoughtPtr, OFFSET thActFold + mov eax, [edi].NpcPersonality.phraseLosePtr + mov [esi].MpkSeat.reactionPtr, eax + ret + +branch_free_check: + ; toCall == 0 -> Чек или лидерÑ�каÑ� Ñ�тавка + mov eax, handScore + add eax, aggro + cmp eax, 110 + jae lead_bet + mov [esi].MpkSeat.lastAction, MPK_ACT_CHECK + mov [esi].MpkSeat.thoughtPtr, OFFSET thActCheck + ret + +lead_bet: + mov [esi].MpkSeat.lastAction, MPK_ACT_RAISE + mov eax, multiPokerTable.minRaise + mov [esi].MpkSeat.lastRaiseAmount, eax + mov [esi].MpkSeat.thoughtPtr, OFFSET thEvalGood + mov eax, [edi].NpcPersonality.phraseBluffPtr + mov [esi].MpkSeat.reactionPtr, eax + ret +MultiPoker_NpcDecideTurn ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_ApplyAction: Применение Ñ�тавки, колла или паÑ�а к Ñ�оÑ�тоÑ�нию Ñ�тола +; ------------------------------------------------------------------------------ +MultiPoker_ApplyAction PROC uses ebx esi edi, seatIdx:DWORD, act:DWORD, amount:DWORD + mov eax, seatIdx + imul eax, SIZEOF MpkSeat + lea esi, multiPokerTable.seats[eax] + + cmp act, MPK_ACT_FOLD + je apply_fold + cmp act, MPK_ACT_CHECK + je apply_check + cmp act, MPK_ACT_CALL + je apply_call + cmp act, MPK_ACT_RAISE + je apply_raise + ret + +apply_fold: + mov [esi].MpkSeat.seatStatus, MPK_SEAT_FOLDED + dec multiPokerTable.activeSeats + ret + +apply_check: + ret + +apply_call: + mov eax, multiPokerTable.currentHighBet + sub eax, [esi].MpkSeat.roundBet + cmp eax, [esi].MpkSeat.chips + jbe @F + mov eax, [esi].MpkSeat.chips +@@: + sub [esi].MpkSeat.chips, eax + add [esi].MpkSeat.roundBet, eax + add [esi].MpkSeat.totalBet, eax + add multiPokerTable.mainPot, eax + ret + +apply_raise: + ; ДоÑ�тавка до currentHighBet + размер рейза + mov eax, multiPokerTable.currentHighBet + sub eax, [esi].MpkSeat.roundBet + add eax, amount + cmp eax, [esi].MpkSeat.chips + jbe @F + mov eax, [esi].MpkSeat.chips +@@: + sub [esi].MpkSeat.chips, eax + add [esi].MpkSeat.roundBet, eax + add [esi].MpkSeat.totalBet, eax + add multiPokerTable.mainPot, eax + + mov eax, [esi].MpkSeat.roundBet + mov multiPokerTable.currentHighBet, eax + ret +MultiPoker_ApplyAction ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_NextStreet: Переход на Ñ�ледующую улицу торгов +; ------------------------------------------------------------------------------ +MultiPoker_NextStreet PROC uses ebx esi edi + ; СброÑ� roundBet длÑ� вÑ�ех меÑ�Ñ‚ + xor ecx, ecx +reset_round_bets: + imul eax, ecx, SIZEOF MpkSeat + mov multiPokerTable.seats[eax].roundBet, 0 + inc ecx + cmp ecx, MPK_MAX_SEATS + jb reset_round_bets + + mov multiPokerTable.currentHighBet, 0 + + mov eax, multiPokerTable.stage + cmp eax, MPK_STAGE_PREFLOP + je go_flop + cmp eax, MPK_STAGE_FLOP + je go_turn + cmp eax, MPK_STAGE_TURN + je go_river + mov multiPokerTable.stage, MPK_STAGE_SHOWDOWN + ret + +go_flop: + mov multiPokerTable.commCount, 3 + mov multiPokerTable.stage, MPK_STAGE_FLOP + ret +go_turn: + mov multiPokerTable.commCount, 4 + mov multiPokerTable.stage, MPK_STAGE_TURN + ret +go_river: + mov multiPokerTable.commCount, 5 + mov multiPokerTable.stage, MPK_STAGE_RIVER + ret +MultiPoker_NextStreet ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_Showdown: Определение победителÑ� и раÑ�чет банка +; ------------------------------------------------------------------------------ +MultiPoker_Showdown PROC uses ebx esi edi + local bestScore:DWORD, bestSeat:DWORD + + mov bestScore, 0 + mov bestSeat, 0 + + xor esi, esi +eval_showdown_seats: + imul eax, esi, SIZEOF MpkSeat + lea ebx, multiPokerTable.seats[eax] + + cmp [ebx].MpkSeat.seatStatus, MPK_SEAT_ACTIVE + jne next_showdown_seat + + ; Оценка 7 карт (2 Ñ�вои + 5 Ñ�тола) + mov eax, [ebx].MpkSeat.card1 + mov multiEvalHand[0], eax + mov eax, [ebx].MpkSeat.card2 + mov multiEvalHand[4], eax + + xor edx, edx +copy_7_cards: + mov eax, multiPokerTable.commCards[edx*4] + mov multiEvalHand[edx*4 + 8], eax + inc edx + cmp edx, 5 + jb copy_7_cards + + invoke EvaluatePokerN, OFFSET multiEvalHand, 7 + mov [ebx].MpkSeat.evalScore, eax + + cmp eax, bestScore + jb next_showdown_seat + mov bestScore, eax + mov bestSeat, esi + +next_showdown_seat: + inc esi + cmp esi, MPK_MAX_SEATS + jb eval_showdown_seats + + ; Ð�аграда победителю + mov eax, bestSeat + imul eax, SIZEOF MpkSeat + lea ebx, multiPokerTable.seats[eax] + mov edx, multiPokerTable.mainPot + add [ebx].MpkSeat.chips, edx + + ; ЕÑ�ли победил человек -> обновлÑ�ем bankroll + cmp bestSeat, 0 + jne @F + mov eax, [ebx].MpkSeat.chips + mov bankroll, eax +@@: + ret +MultiPoker_Showdown ENDP + +; ------------------------------------------------------------------------------ +; MultiPoker_PrintStatus: ТекÑ�товый вывод Ñ�оÑ�тоÑ�ниÑ� Ñ�тола и мыÑ�лей ботов +; ------------------------------------------------------------------------------ +MultiPoker_PrintStatus PROC uses ebx esi edi + invoke SetColor, COLOR_TITLE + invoke PrintStr, OFFSET mpkTitleStr + call ResetColor + + invoke PrintStr, OFFSET mpkPotStr + invoke PrintUInt, multiPokerTable.mainPot + + invoke PrintStr, OFFSET mpkStreetStr + mov eax, multiPokerTable.stage + cmp eax, MPK_STAGE_PREFLOP + jne @F + invoke PrintStr, OFFSET strStagePreflop + jmp print_stage_done +@@: + cmp eax, MPK_STAGE_FLOP + jne @F + invoke PrintStr, OFFSET strStageFlop + jmp print_stage_done +@@: + cmp eax, MPK_STAGE_TURN + jne @F + invoke PrintStr, OFFSET strStageTurn + jmp print_stage_done +@@: + cmp eax, MPK_STAGE_RIVER + jne @F + invoke PrintStr, OFFSET strStageRiver + jmp print_stage_done +@@: + invoke PrintStr, OFFSET strStageShow +print_stage_done: + invoke PrintStr, OFFSET nl + + ; Вывод общих карт Ñ�тола + invoke PrintStr, OFFSET mpkCommCardsStr + cmp multiPokerTable.commCount, 0 + jne print_table_cards + invoke PrintStr, OFFSET strStagePreflop + invoke PrintStr, OFFSET nl + jmp print_seats_info + +print_table_cards: + invoke PrintHandRow21, OFFSET multiPokerTable.commCards, multiPokerTable.commCount, 1 + +print_seats_info: + invoke PrintStr, OFFSET nl + + ; Вывод каждого из 4 меÑ�Ñ‚ + xor esi, esi +print_seats_loop: + imul eax, esi, SIZEOF MpkSeat + lea ebx, multiPokerTable.seats[eax] + + ; ИмÑ� меÑ�та + cmp esi, 0 + jne print_npc_seat_header + invoke SetColor, COLOR_MONEY + invoke PrintStr, OFFSET promptPlayerTerminal + call ResetColor + jmp print_seat_details + +print_npc_seat_header: + mov eax, [ebx].MpkSeat.profileId + imul eax, SIZEOF NpcPersonality + invoke SetColor, COLOR_WARN + invoke PrintStr, casinoNpcProfiles[eax].namePtr + call ResetColor + +print_seat_details: + invoke PrintStr, OFFSET dotSpaceText + invoke PrintStr, OFFSET mpkChipsPrefix + invoke PrintUInt, [ebx].MpkSeat.chips + + ; СтатуÑ� меÑ�та + cmp [ebx].MpkSeat.seatStatus, MPK_SEAT_FOLDED + jne @F + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET observerFold1Text + call ResetColor +@@: + invoke PrintStr, OFFSET nl + + ; МыÑ�ли бота (еÑ�ли еÑ�ть) + cmp [ebx].MpkSeat.thoughtPtr, 0 + je print_reaction_check + invoke PrintStr, OFFSET mpkThoughtPrefix + invoke PrintStr, [ebx].MpkSeat.thoughtPtr + invoke PrintStr, OFFSET nl + +print_reaction_check: + cmp [ebx].MpkSeat.reactionPtr, 0 + je next_seat_print + invoke SetColor, COLOR_CARD + invoke PrintStr, [ebx].MpkSeat.reactionPtr + call ResetColor + invoke PrintStr, OFFSET nl + +next_seat_print: + inc esi + cmp esi, MPK_MAX_SEATS + jb print_seats_loop + ret +MultiPoker_PrintStatus ENDP + +; ------------------------------------------------------------------------------ +; GameMultiPoker: ГлавнаÑ� точка входа длÑ� карточной игры против 3 поÑ�етителей +; ------------------------------------------------------------------------------ +GameMultiPoker PROC uses ebx esi edi + call ClearView + call MultiPoker_InitTable + +multi_hand_loop: + call ClearView + call MultiPoker_StartHand + +multi_street_loop: + call ClearView + call MultiPoker_PrintStatus + + ; ПроверÑ�ем, оÑ�талÑ�Ñ� ли в игре хотÑ� бы 1 оппонент + cmp multiPokerTable.activeSeats, 1 + jbe multi_hand_showdown + + ; Круг торговли длÑ� каждого активного меÑ�та + xor esi, esi +multi_turn_loop: + imul eax, esi, SIZEOF MpkSeat + lea ebx, multiPokerTable.seats[eax] + + cmp [ebx].MpkSeat.seatStatus, MPK_SEAT_ACTIVE + jne next_turn_player + + ; Ход Игрока (меÑ�то 0) + cmp esi, 0 + jne handle_bot_turn + + invoke PrintStr, OFFSET mpkPromptStr + call ReadKey + cmp al, '1' + je player_call + cmp al, '2' + je player_raise + cmp al, '0' + je player_fold + jmp player_call + +player_fold: + invoke MultiPoker_ApplyAction, 0, MPK_ACT_FOLD, 0 + jmp next_turn_player +player_call: + invoke MultiPoker_ApplyAction, 0, MPK_ACT_CALL, 0 + jmp next_turn_player +player_raise: + invoke MultiPoker_ApplyAction, 0, MPK_ACT_RAISE, 100 + jmp next_turn_player + +handle_bot_turn: + ; Ход бота + invoke MultiPoker_NpcDecideTurn, esi + mov eax, [ebx].MpkSeat.lastAction + mov edx, [ebx].MpkSeat.lastRaiseAmount + invoke MultiPoker_ApplyAction, esi, eax, edx + invoke Sleep, 400 + +next_turn_player: + inc esi + cmp esi, MPK_MAX_SEATS + jb multi_turn_loop + + ; Переход на Ñ�ледующую улицу + cmp multiPokerTable.stage, MPK_STAGE_RIVER + jae multi_hand_showdown + + call MultiPoker_NextStreet + jmp multi_street_loop + +multi_hand_showdown: + call ClearView + call MultiPoker_Showdown + call MultiPoker_PrintStatus + + invoke PrintStr, OFFSET mpkWaitNextStr + call ReadKey + cmp al, '0' + je multi_poker_exit + jmp multi_hand_loop + +multi_poker_exit: + ret +GameMultiPoker ENDP +'''.strip() + +print("Writing npc_mind_data.inc in CP1251...") +with open(data_inc_path, "w", encoding="cp1251", errors="replace") as f: + f.write(DATA_CONTENT + "\n") + +print("Writing npc_mind.inc in CP1251...") +with open(code_inc_path, "w", encoding="cp1251", errors="replace") as f: + f.write(CODE_CONTENT + "\n") + +print("Done generating NPC mind modules.") diff --git a/tools/generators/npc_life_cp1251.patch b/tools/generators/npc_life_cp1251.patch new file mode 100644 index 0000000..7f1b04a --- /dev/null +++ b/tools/generators/npc_life_cp1251.patch @@ -0,0 +1,52 @@ +diff --git a/casino3d.inc b/casino3d.inc +--- a/casino3d.inc ++++ b/casino3d.inc +@@ -149,1 +149,2 @@ + include src_graphics\npc_mind_data.inc ++include src_graphics\npc_life_data.inc +@@ -5124,1 +5125,3 @@ + include src_graphics\npc_mind.inc ++include src_graphics\npc_life.inc ++include src_graphics\npc_contracts.inc +@@ -5240,1 +5243,7 @@ + check_slots_mode: ++ cmp engineMode,MODE_NPC_DIALOG ++ jne @F ++ call HandleNpcDialog3D ++ call RenderNpcDialog3D ++ jmp present_frame ++@@: +diff --git a/src_graphics/hall_scene.inc b/src_graphics/hall_scene.inc +--- a/src_graphics/hall_scene.inc ++++ b/src_graphics/hall_scene.inc +@@ -281,1 +281,2 @@ + call InitCasinoNpcMind ++ call InitNpcLife3D +@@ -624,2 +625,3 @@ + invoke HallTarget3D, 27*FP_1,25*FP_1,INTERACT_BILLIARDS,OFFSET hallPoolPrompt3D ++ call CheckNpcInteractions3D + ret +@@ -640,1 +642,7 @@ + TriggerHallInteraction3D PROC ++ cmp interactTargetId,INTERACT_NPC ++ jne @F ++ call OpenNpcDialog3D ++ ret ++@@: ++ +@@ -1207,1 +1215,4 @@ + UpdatePatrons3D PROC uses ebx esi edi ++ call UpdateNpcLife3D ++ ret ++IF 0 +@@ -1281,1 +1292,2 @@ ++ENDIF + UpdatePatrons3D ENDP +@@ -1284,2 +1296,3 @@ + RenderPatrons3D PROC uses esi +- xor esi, esi ++ call RenderNpcLife3D ++ mov esi,8 +@@ -1291,1 +1304,1 @@ +- cmp esi, HALL_PATRON_COUNT ++ cmp esi,12 diff --git a/tools/generators/npc_rounds_cp1251.patch b/tools/generators/npc_rounds_cp1251.patch new file mode 100644 index 0000000..59be47c --- /dev/null +++ b/tools/generators/npc_rounds_cp1251.patch @@ -0,0 +1,37 @@ +diff --git a/casino3d.inc b/casino3d.inc +--- a/casino3d.inc ++++ b/casino3d.inc +@@ -3128,2 +3128,3 @@ + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 ++ invoke NpcRecordRound3D,8,1 + call SaveProgress3D +@@ -3135,2 +3136,3 @@ + invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 ++ invoke NpcRecordRound3D,8,0 + call SaveProgress3D +@@ -3413,1 +3415,3 @@ + FinalizeSkullsGuess PROC uses ebx ++ cmp skulls3d_state,3 ++ jne skulls_guess_done +@@ -3423,2 +3427,4 @@ + mov skulls3d_state, 4 + invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 ++ invoke NpcRecordRound3D,9,1 ++ call SaveProgress3D +@@ -3430,3 +3436,6 @@ + mov skulls3d_state, 4 + invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 ++ invoke NpcRecordRound3D,9,0 ++ call SaveProgress3D ++skulls_guess_done: + ret +@@ -4160,1 +4169,3 @@ + mov skill3d_win_amount, eax ++ invoke NpcRecordRound3D,10,1 ++ call SaveProgress3D +@@ -4168,3 +4179,5 @@ + mov skill3d_state, 5 + mov skill3d_timer, 0 ++ invoke NpcRecordRound3D,10,0 ++ call SaveProgress3D + invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1 diff --git a/tools/generators/pack_blackjack_guests.py b/tools/generators/pack_blackjack_guests.py new file mode 100644 index 0000000..0a843d1 --- /dev/null +++ b/tools/generators/pack_blackjack_guests.py @@ -0,0 +1,36 @@ +"""Offline sprite-sheet normalization; runtime rendering remains MASM.""" +import json +import struct +from pathlib import Path + +from PIL import Image + +ROOT = Path(__file__).resolve().parents[2] + + +def main(): + source = ROOT / "assets/sprites/tables/blackjack-guests-v1.png" + image = Image.open(source).convert("RGBA") + assert image.size == (1536, 1024) + frames = [] + for row in range(2): + for column in range(3): + frame = image.crop((column * 512, row * 512, (column + 1) * 512, (row + 1) * 512)) + frame = frame.resize((160, 160), Image.Resampling.NEAREST) + assert frame.getpixel((0, 0))[3] == 0 + assert sum(alpha >= 240 for alpha in frame.getchannel("A").get_flattened_data()) > 6000 + frames.append(frame.tobytes("raw", "BGRA")) + data = b"".join(frames) + path = ROOT / "assets/animations/tables/blackjack-guests-v1.bin" + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(struct.pack("<4sIIII", b"ANM1", 160, 160, 6, len(data)) + data) + room = Image.open(ROOT / "assets/sprites/tables/blackjack-room-v1.png").convert("RGBA") + room = room.resize((640, 480), Image.Resampling.NEAREST) + data = room.tobytes("raw", "BGRA") + room_path = ROOT / "assets/animations/tables/blackjack-room-v1.bin" + room_path.write_bytes(struct.pack("<4sIIII", b"ANM1", 640, 480, 1, len(data)) + data) + print(json.dumps({"guest_frames": 6, "size": [160, 160], "path": str(path), "room": str(room_path)})) + + +if __name__ == "__main__": + main() diff --git a/tools/generators/pack_clover_assets.py b/tools/generators/pack_clover_assets.py new file mode 100644 index 0000000..5ad57c8 --- /dev/null +++ b/tools/generators/pack_clover_assets.py @@ -0,0 +1,48 @@ +"""Offline normalization of generated art; the game animates reels in MASM.""" +import json +import struct +from pathlib import Path +from PIL import Image + +ROOT = Path(__file__).resolve().parents[2] +SOURCE = ROOT / "assets/sprites/clover" +OUTPUT = ROOT / "assets/animations/clover" + + +def pack(name, frames): + width, height = frames[0].size + pixels = b"".join(frame.tobytes("raw", "BGRA") for frame in frames) + (OUTPUT / name).write_bytes(struct.pack("<4s4I", b"ANM1", width, height, + len(frames), len(pixels)) + pixels) + + +def main(): + OUTPUT.mkdir(parents=True, exist_ok=True) + cabinet = Image.open(SOURCE / "cabinet-v1.png").convert("RGBA") + cabinet = cabinet.resize((640, 480), Image.Resampling.NEAREST) + cabinet.putalpha(255) + pack("cabinet-v1.bin", [cabinet]) + sheet = Image.open(SOURCE / "symbols-v1.png").convert("RGBA") + assert 1.8 < sheet.width / sheet.height < 2.2 + frames = [] + for index in range(7): + column, row = index % 4, index // 4 + cell = sheet.crop((round(column * sheet.width / 4), round(row * sheet.height / 2), + round((column + 1) * sheet.width / 4), round((row + 1) * sheet.height / 2))) + bounds = cell.getchannel("A").getbbox() + assert bounds, f"Empty symbol {index}" + cell = cell.crop(bounds) + cell.thumbnail((46, 46), Image.Resampling.NEAREST) + frame = Image.new("RGBA", (56, 56)) + frame.paste(cell, ((56 - cell.width) // 2, (56 - cell.height) // 2)) + frame.putalpha(frame.getchannel("A").point(lambda value: 255 if value >= 128 else 0)) + frames.append(frame) + pack("symbols-v1.bin", frames) + (OUTPUT / "manifest.json").write_text(json.dumps({"symbols": ["clover", "lemon", "cherries", + "bell", "diamond", "chest", "seven"], "cabinet": [640, 480], "symbol": [56, 56], + "runtime": "MASM; five reels, three complete rows, legacy additive combos"}, indent=2) + "\n") + print("Packed Clover 5x3 cabinet and seven alpha-tested symbols") + + +if __name__ == "__main__": + main() diff --git a/tools/generators/pack_pyramid_assets.py b/tools/generators/pack_pyramid_assets.py new file mode 100644 index 0000000..5a4c92d --- /dev/null +++ b/tools/generators/pack_pyramid_assets.py @@ -0,0 +1,56 @@ +"""Offline art normalization to the exact assembly table and ball anchors.""" +from pathlib import Path +import struct +from PIL import Image + +ROOT = Path(__file__).resolve().parents[2] +SOURCE = ROOT / "assets/sprites/pyramid" +OUT = ROOT / "assets/animations/pyramid" + + +def pack(name, frames): + w, h = frames[0].size + payload = b"".join(frame.tobytes("raw", "BGRA") for frame in frames) + (OUT / name).write_bytes(struct.pack("<4s4I", b"ANM1", w, h, len(frames), len(payload)) + payload) + + +def main(): + OUT.mkdir(parents=True, exist_ok=True) + source = Image.open(SOURCE / "table-v2.png").convert("RGBA") + # Nine-slice-style normalization keeps the mouths and cushion noses aligned + # with the shared logical cloth rectangle, rather than scaling the whole art. + source_x = [0, 128, 160, 723, 1290, 1320, 1448] + source_y = [0, 197, 220, 733, 747, 1086] + target_x = [0, 60, 61, 320, 579, 580, 640] + target_y = [0, 100, 101, 359, 360, 480] + frame = Image.new("RGBA", (640, 480)) + for row in range(len(target_y) - 1): + for col in range(len(target_x) - 1): + cell = source.crop((round(source_x[col] * source.width / 1448), + round(source_y[row] * source.height / 1086), + round(source_x[col + 1] * source.width / 1448), + round(source_y[row + 1] * source.height / 1086))) + cell = cell.resize((target_x[col + 1] - target_x[col], + target_y[row + 1] - target_y[row]), Image.Resampling.NEAREST) + frame.paste(cell, (target_x[col], target_y[row])) + frame.putalpha(255) + pack("table-v2.bin", [frame]) + sheet = Image.open(SOURCE / "balls-v1.png").convert("RGBA") + frames = [] + for i in range(8): + col, row = i % 4, i // 4 + cell = sheet.crop((round(col * sheet.width / 4), round(row * sheet.height / 2), + round((col + 1) * sheet.width / 4), round((row + 1) * sheet.height / 2))) + # Ignore faint generator fringe outside the actual circular ball. + cell.putalpha(cell.getchannel("A").point(lambda a: 255 if a >= 192 else 0)) + cell = cell.crop(cell.getchannel("A").getbbox()) + cell.thumbnail((10, 10), Image.Resampling.LANCZOS) + frame = Image.new("RGBA", (12, 12)) + frame.paste(cell, ((12 - cell.width) // 2, (12 - cell.height) // 2)) + frames.append(frame) + pack("balls-v1.bin", frames) + print("Packed anchored 640x480 table and eight 12x12 Russian ball poses") + + +if __name__ == "__main__": + main() diff --git a/tools/generators/pack_russian_party.py b/tools/generators/pack_russian_party.py new file mode 100644 index 0000000..2b80e09 --- /dev/null +++ b/tools/generators/pack_russian_party.py @@ -0,0 +1,28 @@ +"""Offline packing of neutral seated guest artwork, not game logic.""" +import struct +from pathlib import Path + +from PIL import Image + +ROOT = Path(__file__).resolve().parents[2] + + +def main(): + image = Image.open(ROOT / "assets/sprites/roulette/participants-v1.png").convert("RGBA") + assert image.size == (1536, 1024) + frames = [] + for row in range(2): + for col in range(3): + frame = image.crop((col * 512, row * 512, (col + 1) * 512, (row + 1) * 512)) + frame = frame.resize((192, 192), Image.Resampling.NEAREST) + assert frame.getpixel((0, 0))[3] == 0 + assert sum(a >= 240 for a in frame.getchannel("A").get_flattened_data()) > 8000 + frames.append(frame.tobytes("raw", "BGRA")) + data = b"".join(frames) + output = ROOT / "assets/animations/roulette/participants-v1.bin" + output.write_bytes(struct.pack("<4sIIII", b"ANM1", 192, 192, 6, len(data)) + data) + print("Packed six neutral seated guest frames for native Russian roulette") + + +if __name__ == "__main__": + main() diff --git a/tools/generators/patch_gen.py b/tools/generators/patch_gen.py new file mode 100644 index 0000000..13d096c --- /dev/null +++ b/tools/generators/patch_gen.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +import sys + +with open('tools/generators/generate_npc_mind.py', 'r', encoding='utf-8') as f: + c = f.read() + +c = c.replace('invoke PrintStr, OFFSET chipText', 'invoke PrintStr, OFFSET mpkChipsPrefix') +c = c.replace('invoke PrintStr, OFFSET cheatCodePrompt', 'invoke PrintStr, OFFSET mpkThoughtPrefix') + +old_str = 'mpkWaitNextStr db 13,10,"[Ð�ажмите любую клавишу длÑ� Ñ�ледующей раздачи, 0 длÑ� выхода]...",0\n' +new_str = old_str + 'mpkChipsPrefix db " Стек: $",0\nmpkThoughtPrefix db " [МыÑ�ли]: ",0\n' + +if old_str in c: + c = c.replace(old_str, new_str) + print("Added prefix strings") +else: + print("Target string not found in c") + +with open('tools/generators/generate_npc_mind.py', 'w', encoding='utf-8') as f: + f.write(c) + +print("Saved generate_npc_mind.py") diff --git a/tools/generators/patch_poker_asm.py b/tools/generators/patch_poker_asm.py index 77a5a7e..9227363 100644 --- a/tools/generators/patch_poker_asm.py +++ b/tools/generators/patch_poker_asm.py @@ -1,92 +1,46 @@ -from pathlib import Path -REPO_ROOT = Path(__file__).resolve().parents[2] -with open(REPO_ROOT / 'poker.asm', 'r', encoding='cp1251') as f: +# -*- coding: utf-8 -*- +with open('poker.asm', 'r', encoding='cp1251') as f: text = f.read() -# 1. Add defaultPlayerSave -if 'defaultPlayerSave' not in text: - target = 'saveFileName db 64 dup(0)' - replacement = 'saveFileName db 64 dup(0)\r\ndefaultPlayerSave db "Player.dat",0' - text = text.replace(target, replacement, 1) +target_str = 'pokerTitle db 13,10,"--- Poker ---",13,10,0\n' +new_str = target_str + '''pokerModeMenuText db "1. КлаÑ�Ñ�ичеÑ�кий покер 1 на 1 (против Дилера)",13,10 + db "2. Стол на 4 перÑ�оны (Ð’Ñ‹ против поÑ�етителей казино)",13,10 + db "0. Выход в главное меню",13,10 + db "Выбор: ",0 +''' -# 2. Remove include casino3d.inc from old position -old_inc = 'include casino3d.inc' -if old_inc in text: - text = text.replace(old_inc, '; include casino3d.inc moved below', 1) +target_proc = 'GamePoker PROC\nstart_poker:\n' +new_proc = '''GamePoker PROC +poker_choose_mode: + call ClearView + invoke PrintTitleColor, OFFSET pokerTitle + invoke PrintStr, OFFSET pokerModeMenuText + call ReadKey + cmp al, '1' + je start_poker + cmp al, '2' + je poker_launch_multitable + cmp al, '0' + je poker_mode_exit + jmp poker_choose_mode -# 3. Update run_casino_3d in MainMenu -old_run_3d = """run_casino_3d: - - call StartCasino3D - - jmp menu_loop""" - -new_run_3d = """run_casino_3d: - invoke ShowWindow, hCasinoConsole, SW_HIDE - call StartCasino3D - invoke ShowWindow, hCasinoConsole, SW_SHOW - invoke SetForegroundWindow, hCasinoConsole - jmp menu_loop""" - -if old_run_3d in text: - text = text.replace(old_run_3d, new_run_3d, 1) -else: - print('Notice: old_run_3d pattern not exact, searching line-by-line') - -# 4. Insert include casino3d.inc after MainMenu ENDP and replace main PROC -pos = text.find('exit_menu:') -if pos != -1: - end_main_pos = text.find('END main') - if end_main_pos != -1: - new_main_block = """exit_menu: +poker_launch_multitable: + call GameMultiPoker ret -MainMenu ENDP -include casino3d.inc +poker_mode_exit: + ret -; --- main: Unified Entry Point --- -main PROC - invoke SetConsoleOutputCP, 65001 - invoke SetConsoleCP, 65001 - invoke GetStdHandle, STD_OUTPUT_HANDLE - mov hOut, eax - call ConfigureConsoleSize - call EnableAnsi - invoke CreateDirectoryA, OFFSET runtimeDir, 0 - invoke GetStdHandle, STD_INPUT_HANDLE - mov hIn, eax - invoke GetTickCount - mov seed, eax - call InitSounds - call InitPaths3D - call AutoLoadAccountFast - cmp accountCount, 0 - jne @F - call ResetProfileDefaults - invoke CopyCString, OFFSET saveFileName, OFFSET defaultPlayerSave - call SaveGame - call CollectAccounts -@@: - call ApplySoundVolume - invoke GetConsoleWindow - mov hCasinoConsole, eax - invoke ShowWindow, hCasinoConsole, SW_HIDE - call StartCasino3D - cmp mutex3D, 0 - je @F - invoke CloseHandle, mutex3D -@@: - invoke ExitProcess, 0 -main ENDP -""" - text = text[:pos] + new_main_block + '\r\nEND main\r\n' - print('Successfully replaced main block!') - else: - print('Error: END main not found') +start_poker: +''' + +if target_str not in text: + print("ERROR: target_str not found") +elif target_proc not in text: + print("ERROR: target_proc not found") else: - print('Error: exit_menu: not found') - -with open(REPO_ROOT / 'poker.asm', 'wb') as f: - f.write(text.encode('cp1251')) - -print('poker.asm updated in CP1251!') + text = text.replace(target_str, new_str, 1) + text = text.replace(target_proc, new_proc, 1) + with open('poker.asm', 'w', encoding='cp1251') as f: + f.write(text) + print("poker.asm patched successfully") diff --git a/tools/generators/pyramid_cleanup_cp1251.patch b/tools/generators/pyramid_cleanup_cp1251.patch new file mode 100644 index 0000000..af2350d --- /dev/null +++ b/tools/generators/pyramid_cleanup_cp1251.patch @@ -0,0 +1,6 @@ +diff --git a/casino3d.inc b/casino3d.inc +--- a/casino3d.inc ++++ b/casino3d.inc +@@ -5498,1 +5498,2 @@ + call FreeNativeClover3D ++ call FreePyramidAssets3D diff --git a/tools/tests/blackjack_party_probe.asm b/tools/tests/blackjack_party_probe.asm new file mode 100644 index 0000000..3b6a309 --- /dev/null +++ b/tools/tests/blackjack_party_probe.asm @@ -0,0 +1,16 @@ +.386 +.model flat,stdcall +option casemap:none +include F:\MASM32\masm32\include\windows.inc +include F:\MASM32\masm32\include\kernel32.inc +InitPaths3D PROTO +LoadArrivalAssets3D PROTO +RunBJPartyTest3D PROTO +.code +RunBJPartyProbe PROC + call InitPaths3D + call LoadArrivalAssets3D + call RunBJPartyTest3D + invoke ExitProcess,eax +RunBJPartyProbe ENDP +END diff --git a/tools/tests/blackjack_party_test.inc b/tools/tests/blackjack_party_test.inc new file mode 100644 index 0000000..6c35ad7 --- /dev/null +++ b/tools/tests/blackjack_party_test.inc @@ -0,0 +1,364 @@ +; Native state-machine regression. Tests never write the real player's profile. +.data +bjPartySeenLo dd 0 +bjPartySeenHi dd 0 +bjPartySeenCount dd 0 +bjPartyShot1 db "build\actions\blackjack-party-1.bmp",0 +bjPartyShot2 db "build\actions\blackjack-party-2.bmp",0 +bjPartyShot3 db "build\actions\blackjack-party-3.bmp",0 +bjPartyShots dd OFFSET bjPartyShot1,OFFSET bjPartyShot2,OFFSET bjPartyShot3 +bjPartyFlightShot db "build\actions\blackjack-party-flight.bmp",0 +bjPartyResultShot db "build\actions\blackjack-party-result.bmp",0 +bjPartyExitShot db "build\actions\blackjack-party-exit.bmp",0 +.code +CheckBJPartyHand3D PROC uses ebx esi hand:DWORD,count:DWORD + mov esi,hand + cmp count,2 + jb bj_party_hand_bad + cmp count,12 + ja bj_party_hand_bad + xor ebx,ebx +bj_party_hand_card: + mov eax,[esi+ebx*4] + cmp eax,52 + jae bj_party_hand_bad + cmp eax,32 + jb bj_party_hand_low + sub eax,32 + bts bjPartySeenHi,eax + jc bj_party_hand_bad + jmp bj_party_hand_next +bj_party_hand_low: + bts bjPartySeenLo,eax + jc bj_party_hand_bad +bj_party_hand_next: + inc bjPartySeenCount + inc ebx + cmp ebx,count + jb bj_party_hand_card + xor eax,eax + ret +bj_party_hand_bad: + mov eax,8104 + ret +CheckBJPartyHand3D ENDP + +RunBJPartyTest3D PROC uses ebx esi edi + local rounds:DWORD,ticks:DWORD,savedBank:DWORD,savedSeed:DWORD,savedCursor:DWORD,fixtureSeed:DWORD + mov engineMode,MODE_BLACKJACK + mov cbBet3D,100 + mov cbBotCount3D,0 + call InitNativeBlackjack3D + cmp cbPartyArt3D.pixels,0 + je bj_party_fail_art + cmp cbPartyRoom3D.pixels,0 + je bj_party_fail_art + ; Real mouse selection; changing seats resets the displayed hand, not money. + mov bankroll,10000 + mov mouseClick3D,1 + mov mouseX3D,270 + mov mouseY3D,40 + call BJPartyInput3D + cmp cbBotCount3D,2 + jne bj_party_fail_input + cmp mouseClick3D,0 + jne bj_party_fail_input + cmp bankroll,10000 + jne bj_party_fail_input + call StartNativeBlackjack3D + invoke SetBJPartyCount3D,3 + cmp cbBotCount3D,2 + jne bj_party_fail_input + cmp cbCursor3D,8 + jne bj_party_fail_deck + cmp bankroll,9900 + jne bj_party_fail_wallet + ; A bot decision may see its own total and the dealer's upcard, nothing else. + mov cbBots3D.score,16 + mov cbBots3D.count,2 + mov cbDealer3D,4 + invoke BJBotDecision3D,0 + mov savedCursor,eax + mov cbDealer3D[4],12 + mov cbPlayer3D,51 + mov cbDeck3D[120],33 + invoke BJBotDecision3D,0 + cmp eax,savedCursor + jne bj_party_fail_hidden + mov cbBots3D[SIZEOF BJBot3D].score,18 + mov cbBots3D[SIZEOF BJBot3D].count,2 + invoke BJBotDecision3D,1 + cmp eax,1 + jne bj_party_fail_hidden + mov cbBots3D[SIZEOF BJBot3D*2].score,13 + mov cbBots3D[SIZEOF BJBot3D*2].count,2 + invoke BJBotDecision3D,2 + test eax,eax + jnz bj_party_fail_hidden + ; Natural beats a drawn 21, but a dealer natural beats a drawn guest 21. + mov cbBotCount3D,3 + mov cbBotsSettled3D,0 + mov cbDealerScore3D,21 + mov cbDealerCount3D,2 + mov cbBots3D.score,21 + mov cbBots3D.count,2 + mov cbBots3D[SIZEOF BJBot3D].score,21 + mov cbBots3D[SIZEOF BJBot3D].count,3 + mov cbBots3D[SIZEOF BJBot3D*2].score,22 + call ResolveBJParty3D + cmp cbBots3D.outcome,2 + jne bj_party_fail_wallet + cmp cbBots3D[SIZEOF BJBot3D].outcome,1 + jne bj_party_fail_wallet + cmp cbBots3D[SIZEOF BJBot3D*2].outcome,1 + jne bj_party_fail_wallet + mov cbDealerCount3D,3 + mov cbBotsSettled3D,0 + call ResolveBJParty3D + cmp cbBots3D.outcome,3 + jne bj_party_fail_wallet + ; Run 200 full rounds with each party size, alternating hits and doubles. + mov edi,1 +bj_party_test_size: + mov cbBotCount3D,edi + mov rounds,200 +bj_party_test_round: + mov eax,rounds + imul eax,2137 + add eax,edi + mov rngSeed3D,eax + mov bankroll,10000 + mov cbState3D,CB_IDLE + mov engineMode,MODE_BLACKJACK + call StartNativeBlackjack3D + mov eax,edi + add eax,2 + shl eax,1 + cmp cbCursor3D,eax + jne bj_party_fail_deck + mov ticks,0 + mov deltaTime3D,50 +bj_party_test_tick: + cmp cbState3D,CB_RESULT + je bj_party_test_result + cmp cbState3D,CB_PLAYER + jne bj_party_test_handle + mov pressedKeys3D[53h],1 + cmp cbPlayerScore3D,16 + jae @F + mov pressedKeys3D[53h],0 + mov pressedKeys3D[48h],1 +@@: + cmp cbPlayerCount3D,2 + jne bj_party_test_handle + test rounds,1 + jz bj_party_test_handle + mov pressedKeys3D[44h],1 +bj_party_test_handle: + call HandleNativeBlackjack3D + call ClearKeys3D + cmp cbBotCount3D,edi + jne bj_party_fail_input + cmp cbCursor3D,52 + ja bj_party_fail_deck + inc ticks + cmp ticks,2000 + jae bj_party_fail_stuck + jmp bj_party_test_tick +bj_party_test_result: + mov eax,10000 + sub eax,cbStake3D + cmp cbOutcome3D,1 + je bj_party_expected + add eax,cbStake3D + cmp cbOutcome3D,2 + je bj_party_expected + add eax,cbStake3D + cmp cbOutcome3D,3 + jne bj_party_expected + mov edx,cbStake3D + shr edx,1 + add eax,edx +bj_party_expected: + cmp bankroll,eax + jne bj_party_fail_wallet + mov savedBank,eax + invoke NativeBJSettle3D,cbOutcome3D + mov eax,savedBank + cmp bankroll,eax + jne bj_party_fail_wallet + mov bjPartySeenLo,0 + mov bjPartySeenHi,0 + mov bjPartySeenCount,0 + invoke CheckBJPartyHand3D,OFFSET cbPlayer3D,cbPlayerCount3D + test eax,eax + jnz bj_party_test_done + invoke CheckBJPartyHand3D,OFFSET cbDealer3D,cbDealerCount3D + test eax,eax + jnz bj_party_test_done + xor ebx,ebx +bj_party_check_guests: + mov esi,ebx + imul esi,SIZEOF BJBot3D + add esi,OFFSET cbBots3D + cmp [esi].BJBot3D.state,BJ_BOT_DONE + jne bj_party_fail_stuck + cmp [esi].BJBot3D.outcome,3 + ja bj_party_fail_wallet + invoke CheckBJPartyHand3D,esi,[esi].BJBot3D.count + test eax,eax + jnz bj_party_test_done + inc ebx + cmp ebx,edi + jb bj_party_check_guests + mov eax,bjPartySeenCount + cmp cbCursor3D,eax + jne bj_party_fail_deck + xor ebx,ebx +bj_party_check_prefix: + mov eax,cbDeck3D[ebx*4] + cmp eax,32 + jb @F + sub eax,32 + bt bjPartySeenHi,eax + jnc bj_party_fail_deck + jmp bj_party_prefix_next +@@: + bt bjPartySeenLo,eax + jnc bj_party_fail_deck +bj_party_prefix_next: + inc ebx + cmp ebx,cbCursor3D + jb bj_party_check_prefix + dec rounds + jnz bj_party_test_round + cmp edi,3 + jne @F + call RenderNativeBlackjack3D + invoke WriteActionSnapshot3D,OFFSET bjPartyResultShot +@@: + ; Actual framebuffer for each seat count, then repeat without state changes. + mov cbState3D,CB_IDLE + mov bankroll,10000 + call StartNativeBlackjack3D + mov cbState3D,CB_PLAYER + mov eax,cbInitialFlights3D + imul eax,TABLE_FLIGHT_MS + mov cbTimer3D,eax + mov eax,rngSeed3D + mov savedSeed,eax + mov eax,cbCursor3D + mov savedCursor,eax + mov eax,bankroll + mov savedBank,eax + call RenderNativeBlackjack3D + mov eax,edi + dec eax + invoke WriteActionSnapshot3D,bjPartyShots[eax*4] + mov ebx,8 +bj_party_render_repeat: + call RenderNativeBlackjack3D + dec ebx + jnz bj_party_render_repeat + mov eax,savedSeed + cmp rngSeed3D,eax + jne bj_party_fail_render + mov eax,savedCursor + cmp cbCursor3D,eax + jne bj_party_fail_render + mov eax,savedBank + cmp bankroll,eax + jne bj_party_fail_render + inc edi + cmp edi,4 + jb bj_party_test_size + ; Player bust does not prematurely end or hide the other guests' turns. + invoke FinishBJPlayer3D,1 + cmp cbState3D,CB_BOTS + jne bj_party_fail_stuck + ; Choose a genuine deal that needs a guest card for the animation capture. + mov fixtureSeed,1001 +bj_party_find_flight: + mov eax,fixtureSeed + mov rngSeed3D,eax + mov cbState3D,CB_IDLE + mov bankroll,10000 + call StartNativeBlackjack3D + cmp cbPlayerScore3D,21 + je bj_party_next_fixture + cmp cbDealerScore3D,21 + je bj_party_next_fixture + cmp cbBots3D.score,17 + jb bj_party_flight_found +bj_party_next_fixture: + inc fixtureSeed + cmp fixtureSeed,1101 + jae bj_party_fail_stuck + jmp bj_party_find_flight +bj_party_flight_found: + invoke FinishBJPlayer3D,-1 + mov deltaTime3D,50 + mov cbBotTimer3D,BJ_PARTY_MS + call UpdateBJParty3D + cmp cbBots3D.state,BJ_BOT_FLIGHT + jne bj_party_fail_stuck + mov cbBotTimer3D,180 + call RenderNativeBlackjack3D + invoke WriteActionSnapshot3D,OFFSET bjPartyFlightShot + ; Confirmation pauses bot timers; leaving counts once as player's loss. + call RequestCardExit3D + cmp cardExitActive3D,1 + jne bj_party_fail_input + mov savedCursor,180 + call HandleNativeBlackjack3D + cmp cbBotTimer3D,180 + jne bj_party_fail_input + call RenderNativeBlackjack3D + invoke WriteActionSnapshot3D,OFFSET bjPartyExitShot + mov eax,bankroll + mov savedBank,eax + mov pressedKeys3D[59h],1 + call HandleNativeBlackjack3D + cmp engineMode,MODE_WALK + jne bj_party_fail_input + mov eax,savedBank + cmp bankroll,eax + jne bj_party_fail_wallet + mov engineMode,MODE_BLACKJACK + ; A result table can return to solo by keyboard, without another settlement. + mov pressedKeys3D[30h],1 + call BJPartyInput3D + cmp cbBotCount3D,0 + jne bj_party_fail_input + cmp cbState3D,CB_IDLE + jne bj_party_fail_input + cmp cbPlayerCount3D,0 + jne bj_party_fail_input + mov eax,savedBank + cmp bankroll,eax + jne bj_party_fail_wallet + xor eax,eax + ret +bj_party_fail_art: + mov eax,8101 + ret +bj_party_fail_input: + mov eax,8102 + ret +bj_party_fail_wallet: + mov eax,8103 + ret +bj_party_fail_deck: + mov eax,8104 + ret +bj_party_fail_hidden: + mov eax,8105 + ret +bj_party_fail_stuck: + mov eax,8106 + ret +bj_party_fail_render: + mov eax,8107 +bj_party_test_done: + ret +RunBJPartyTest3D ENDP diff --git a/tools/tests/card_tables_test.inc b/tools/tests/card_tables_test.inc index 9591c0f..62613bd 100644 --- a/tools/tests/card_tables_test.inc +++ b/tools/tests/card_tables_test.inc @@ -527,9 +527,14 @@ table_bj_expected: mov eax, savedBank cmp bankroll, eax jne table_fail_25 + call RunBJPartyTest3D + test eax,eax + jnz table_bj_party_failed call FreeCardTableAssets3D xor eax, eax ret +table_bj_party_failed: + ret table_fail_20: mov eax, 20 ret @@ -573,3 +578,4 @@ table_fail_33: mov eax, 33 ret RunCardTablesTest3D ENDP +include tools\tests\blackjack_party_test.inc diff --git a/tools/tests/casino_actions_test.inc b/tools/tests/casino_actions_test.inc index c069a9a..bc1bb3a 100644 --- a/tools/tests/casino_actions_test.inc +++ b/tools/tests/casino_actions_test.inc @@ -93,8 +93,11 @@ include tools\tests\card_exit_test.inc include tools\tests\city_lighting_test.inc include tools\tests\durak_test.inc include tools\tests\slots_test.inc +include tools\tests\clover_test.inc +include tools\tests\pyramid_test.inc include tools\tests\coin_detail_test.inc include tools\tests\coin_test.inc +include tools\tests\russian_party_test.inc RunCasinoActionsTest3D PROC uses ebx esi edi local savedSeed:DWORD,iterations:DWORD,chamberMask:DWORD,value1:DWORD,value2:DWORD,count:DWORD @@ -473,6 +476,11 @@ action_round_done: jne action_fail_12 cmp bankroll, 0 jne action_fail_12 + call RunRRPartyTest3D + test eax,eax + jz @F + ret +@@: call RunUnavailableTest3D test eax,eax jz @F @@ -512,6 +520,11 @@ action_round_done: test eax,eax jz @F ret +@@: + call RunCloverTest3D + test eax,eax + jz @F + ret @@: call RunCoinTest3D test eax,eax diff --git a/tools/tests/check_blackjack_party.py b/tools/tests/check_blackjack_party.py new file mode 100644 index 0000000..05d640b --- /dev/null +++ b/tools/tests/check_blackjack_party.py @@ -0,0 +1,61 @@ +"""Inspect native party table captures and compare tested/shipping MASM.""" +import argparse +import hashlib +from pathlib import Path + +from PIL import Image, ImageChops, ImageDraw, ImageStat +from check_card_exit_build import Coff + +ROOT = Path(__file__).resolve().parents[2] + + +def frames(): + names = ["1", "2", "3", "flight", "result", "exit"] + sheet = Image.new("RGB", (1280, 3 * 504), (20, 25, 29)) + draw = ImageDraw.Draw(sheet) + signatures = [] + captured = {} + for i, name in enumerate(names): + path = ROOT / "build/actions" / f"blackjack-party-{name}.bmp" + image = Image.open(path).convert("RGB") + captured[name] = image + assert image.size == (640, 480) + assert len(image.getcolors(640 * 480)) > 1000, name + assert sum(ImageStat.Stat(image.crop((0, 444, 640, 476))).stddev) > 10, name + signatures.append(hashlib.sha256(image.tobytes()).digest()) + image.save(path.with_suffix(".png")) + x, y = (i % 2) * 640, (i // 2) * 504 + sheet.paste(image, (x, y + 24)) + draw.text((x + 8, y + 6), f"Native blackjack: {name}", fill="white") + assert len(set(signatures)) == len(names) + for number, box in (("2", (248, 132, 392, 240)), ("3", (472, 132, 616, 240))): + difference = ImageChops.difference(captured[number].crop(box), captured["1"].crop(box)) + assert sum(ImageStat.Stat(difference).mean) > 15, f"Guest {number} did not render" + sheet.save(ROOT / "build/actions/blackjack-party-contact.png") + print("PASS: six distinct native party-table captures, visible portraits, cards, controls and exit modal") + + +def parity(): + tested = Coff(ROOT / "build/actions/actions-test.obj") + shipping = Coff(ROOT / "build/graphics/poker.obj") + for name, size in (("InitBJParty3D", 0), ("FreeBJParty3D", 0), ("DealBJParty3D", 0), + ("FinishBJPlayer3D", 4), ("BeginBJDealer3D", 0), + ("BJBotDecision3D", 4), ("UpdateBJParty3D", 0), + ("ResolveBJParty3D", 0), ("BJPartyInput3D", 0), + ("SetBJPartyCount3D", 4), ("RenderBJParty3D", 0), + ("DrawBJPartySelector3D", 0), ("DrawBJMiniCard3D", 16), + ("DrawBJMiniFlight3D", 16), ("NativeBJSettle3D", 4), + ("StartNativeBlackjack3D", 0), ("HandleNativeBlackjack3D", 0), + ("RenderNativeBlackjack3D", 0)): + symbol = f"_{name}@{size}" + assert tested.signature(symbol) == shipping.signature(symbol), name + print("PASS: shipping party dealing, AI, settlement, animation and input match native-tested MASM") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--parity", action="store_true") + args = parser.parse_args() + frames() + if args.parity: + parity() diff --git a/tools/tests/check_clover.py b/tools/tests/check_clover.py new file mode 100644 index 0000000..14fe0d7 --- /dev/null +++ b/tools/tests/check_clover.py @@ -0,0 +1,82 @@ +"""Verify real MASM Clover framebuffer captures and shipping-code parity.""" +import argparse +import hashlib +import struct +from pathlib import Path +from PIL import Image, ImageChops +from check_card_exit_build import Coff +from check_coin_detail import font, text_matches + +ROOT = Path(__file__).resolve().parents[2] +OUT = ROOT / "build/actions" +NAMES = ["clover-ready", "clover-spin", "clover-stopped", "clover-win", "clover-next", "clover-paytable"] +FUNCTIONS = {"InitNativeClover3D": 0, "FreeNativeClover3D": 0, "StartNativeClover3D": 0, + "CloverEvaluate3D": 0, "SettleNativeClover3D": 0, "CloverEscape3D": 0, + "CloverReelPosition3D": 4, "HandleNativeClover3D": 0, + "DrawCloverSymbol3D": 12, "DrawCloverReel3D": 4, "RenderNativeClover3D": 0, + "CloverComboText3D": 4, "DrawSlotTotals3D": 12, "EvaluateSlotCombos": 0, + "SlotApplyWin": 12, "CardTableEscape3D": 0, "TableBusy3D": 0} + + +def main(parity=False): + packs = ROOT / "assets/animations/clover" + raw = (packs / "cabinet-v1.bin").read_bytes() + assert struct.unpack_from("<4s4I", raw) == (b"ANM1", 640, 480, 1, 640 * 480 * 4) + assert set(raw[23::4]) == {255} + cabinet = Image.frombytes("RGBA", (640, 480), raw[20:], "raw", "BGRA").convert("RGB") + raw = (packs / "symbols-v1.bin").read_bytes() + stride = 56 * 56 * 4 + assert struct.unpack_from("<4s4I", raw) == (b"ANM1", 56, 56, 7, stride * 7) + assert len(raw) == 20 + stride * 7 + assert set(raw[23::4]) == {0, 255} + assert len({hashlib.sha256(raw[20 + i * stride:20 + (i + 1) * stride]).digest() + for i in range(7)}) == 7 + frames = {} + for name in NAMES: + frame = Image.open(OUT / (name + ".bmp")).convert("RGB") + assert frame.size == (640, 480) + assert len(frame.getcolors(640 * 480)) > 2000, name + frames[name] = frame + frame.save(OUT / (name + ".png")) + if name == "clover-paytable": + continue + difference = ImageChops.difference(frame, cabinet) + for y in range(80, 318): + for x in range(110, 530): + in_reel = 126 <= y < 294 and any(left <= x < left + 56 for left in (144, 216, 288, 360, 432)) + if not in_reel: + assert difference.getpixel((x, y)) == (0, 0, 0), (name, x, y) + assert len({hashlib.sha256(frame.tobytes()).digest() for frame in frames.values()}) == len(NAMES) + # Every complete cell contains a symbol, not a truncated or empty partial row. + for col in (144, 216, 288, 360, 432): + for top in (126, 182, 238): + cell = frames["clover-ready"].crop((col + 4, top + 4, col + 52, top + 52)) + assert len(cell.getcolors(48 * 48)) > 20, (col, top) + selected = ImageChops.difference(frames["clover-win"], frames["clover-next"]) + assert selected.crop((144, 126, 488, 294)).getbbox(), "Changing the paid combo must change the highlighted cells" + contact = Image.new("RGB", (1920, 960)) + for i, name in enumerate(NAMES): + contact.paste(frames[name], ((i % 3) * 640, (i // 3) * 480)) + contact.save(OUT / "clover-contact.png") + glyphs = font() + text_matches(frames["clover-ready"], "КЛЕВЕР 5x3", 16, 12, 2, (232, 215, 173), glyphs) + text_matches(frames["clover-win"], "27300", 384, 402, 2, (244, 243, 232), glyphs) + text_matches(frames["clover-win"], "+27200", 384, 422, 2, (168, 221, 185), glyphs) + text_matches(frames["clover-win"], "ДЖЕКПОТ", 144, 350, 2, (244, 243, 232), glyphs) + text_matches(frames["clover-next"], "ГЛÐ�З", 144, 350, 2, (244, 243, 232), glyphs) + source = (ROOT / "src_graphics/native_clover.inc").read_text(encoding="ascii") + assert "call EvaluateSlotCombos" in source + assert "call GameSlot" not in source and "call PaySlotMultiplier" not in source + if parity: + tested = Coff(ROOT / "build/actions/actions-test.obj") + shipped = Coff(ROOT / "build/graphics/poker.obj") + for name, size in FUNCTIONS.items(): + assert tested.signature(f"_{name}@{size}") == shipped.signature(f"_{name}@{size}"), name + print("PASS: 5x3 complete cells, 7 real sprites, clipping, six distinct native frames, paid-mask selection" + + (", tested/shipping ASM parity" if parity else "")) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--parity", action="store_true") + main(parser.parse_args().parity) diff --git a/tools/tests/check_european_wheel.py b/tools/tests/check_european_wheel.py index 282be24..5da7aa8 100644 --- a/tools/tests/check_european_wheel.py +++ b/tools/tests/check_european_wheel.py @@ -4,6 +4,7 @@ import hashlib import json import re import struct +from functools import lru_cache from pathlib import Path from PIL import Image, ImageDraw @@ -14,12 +15,93 @@ ORDER = [0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26] RED = {1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36} +DIGITS = ((7, 5, 5, 5, 7), (2, 6, 2, 2, 7), (7, 1, 7, 4, 7), + (7, 1, 7, 1, 7), (5, 5, 7, 1, 1), (7, 4, 7, 1, 7), + (7, 4, 7, 5, 7), (7, 1, 2, 2, 2), (7, 5, 7, 5, 7), + (7, 5, 7, 1, 7)) +LABEL_INK = (255, 248, 222) + + +@lru_cache(maxsize=2) +def lookup_table(name): + lines = (ROOT / "casino3d_data.inc").read_text(encoding="cp1251").splitlines() + start = next(i for i, line in enumerate(lines) if line.startswith(name + " dd ")) + values = [] + for i, line in enumerate(lines[start:]): + if i and not line.strip().startswith("dd "): + break + for value in re.findall(r"([0-9A-F]+)h", line): + number = int(value, 16) + values.append(number if number < 2**31 else number - 2**32) + assert len(values) == 512, name + return values + + +def divide_signed(number, denominator): + return number // denominator if number >= 0 else -((-number) // denominator) + + +def label_positions(center_x, center_y, radius_x, radius_y, angle): + cosine, sine = lookup_table("tableCos"), lookup_table("tableSin") + return [(center_x + divide_signed((cosine[(i * 512 // 37 + angle) % 512] * 195 >> 16) + * radius_x, 224), + center_y + divide_signed((sine[(i * 512 // 37 + angle) % 512] * 195 >> 16) + * radius_y, 224)) for i in range(37)] + + +def value_pixels(center_x, y, number, scale): + text = str(number) + x = center_x - ((len(text) * 4 - 1) * scale // 2) + return {(x + (digit_index * 4 + column) * scale + dx, y + row * scale + dy) + for digit_index, digit in enumerate(text) + for row, bits in enumerate(DIGITS[int(digit)]) + for column in range(3) if bits & (4 >> column) + for dx in range(scale) for dy in range(scale)} + + +def readable_labels(): + # Independent pixel masks check the actual assembly framebuffer, not a mock renderer. + for angle in range(512): + for geometry, scale in (((206, 170, 142, 46, angle), 1), + ((320, 278, 205, 88, angle), 2)): + occupied = set() + for number, (x, y) in zip(ORDER, label_positions(*geometry)): + pixels = value_pixels(x, y - 5 * scale // 2, number, scale) + assert not occupied.intersection(pixels), (angle, scale, number, "overlap") + occupied.update(pixels) + for name, geometry, scale in ( + ("small", (206, 170, 142, 46, 0), 1), + ("rotated", (320, 278, 205, 88, 113), 2)): + frame = Image.open(ROOT / "build/actions" / f"wheel-label-{name}.bmp").convert("RGB") + expected = set() + for number, (x, y) in zip(ORDER, label_positions(*geometry)): + glyph = value_pixels(x, y - 5 * scale // 2, number, scale) + assert not expected.intersection(glyph), (name, number, "overlapping digits") + expected.update(glyph) + actual = {(x, y) for y in range(480) for x in range(640) + if frame.getpixel((x, y)) == LABEL_INK} + assert actual == expected, (name, "missing or distorted digit pixels", + len(expected - actual), len(actual - expected)) + + positions = label_positions(320, 278, 205, 88, 0) + for result in range(37): + frame = Image.open(ROOT / "build/actions" / f"wheel-label-{result:02}.bmp").convert("RGB") + for number, (x, y) in zip(ORDER, positions): + pixels = value_pixels(x, y - 5, number, 2) + missing = [point for point in pixels if frame.getpixel(point) != LABEL_INK] + assert not missing, (result, number, "ball/highlight obscures label", missing[:5]) + ink = (244, 231, 200) if result not in RED else (255, 180, 173) + assert all(frame.getpixel(point) == ink + for point in value_pixels(320, 268, result, 6)), (result, "central result") + print("PASS: all 37 native results retain every upright pocket digit and large central result;") + print(" exact 1x/2x native glyphs and no overlap at any of 512 rotation angles") def assets(): manifest = json.loads((ROOT / "assets/animations/wheel/manifest-v1.json").read_text()) assert manifest == {"order": ORDER, "zero_pockets": 1} source = (ROOT / "src_graphics/native_wheel_data.inc").read_text(encoding="ascii") + assert 'wheelRotorPath3D db "assets\\animations\\wheel\\rotor-v2.bin",0' in source order = re.search(r"wheelOrder3D dd ([0-9,]+)", source).group(1) assert [int(value) for value in order.split(",")] == ORDER low, high = re.search(r"wheelRedMask3D dd ([0-9A-F]+)h,([0-9A-F]+)h", source).groups() @@ -33,6 +115,9 @@ def assets(): assert len(data) == 20 + size[0] * size[1] * 4, name alpha = set(data[23::4]) assert alpha == ({0, 255} if name == "rotor" else {255}), name + if name == "rotor": + assert not any(data[i + 2] > 245 and data[i + 1] > 225 and data[i] > 185 + for i in range(20, len(data), 4)), "Baked-in numbers returned" print("PASS: three valid packs; exact European order, one zero and correct red/black colors") @@ -65,7 +150,8 @@ def parity(): ("WheelEscape3D", 0), ("WheelTravel3D", 12), ("DrawNativeWheelDisc3D", 20), ("RenderWheelScene3D", 0), ("LoadNativeWheelArt3D", 0), ("FreeNativeWheelArt3D", 0), - ("DrawWheelDigit3D", 20), ("DrawWheelValue3D", 20), ("DrawWheelLabels3D", 20), + ("DrawWheelBox3D", 20), ("DrawWheelDigit3D", 20), + ("DrawWheelValue3D", 20), ("DrawWheelLabels3D", 20), ("AnimateCityPedestrians3D", 0), ("HandleArrival3D", 0)) for name, arguments in functions: symbol = f"_{name}@{arguments}" @@ -81,5 +167,6 @@ if __name__ == "__main__": assets() if not options.assets_only: captures() + readable_labels() if options.parity: parity() diff --git a/tools/tests/check_npc_life.py b/tools/tests/check_npc_life.py new file mode 100644 index 0000000..b206022 --- /dev/null +++ b/tools/tests/check_npc_life.py @@ -0,0 +1,55 @@ +"""Inspect actual MASM dialog frames and compare tested/shipping NPC procedures.""" +import argparse +import hashlib +from pathlib import Path + +from PIL import Image, ImageDraw +from check_card_exit_build import Coff + +ROOT = Path(__file__).resolve().parents[2] + + +def captures(): + sheet = Image.new("RGB", (640, 3 * 504), (20, 25, 29)) + draw = ImageDraw.Draw(sheet) + hashes = [] + for index, name in enumerate(("open", "ready", "done")): + path = ROOT / "build/actions" / f"npc-dialog-{name}.bmp" + frame = Image.open(path).convert("RGB") + assert frame.size == (640, 480) + assert len(frame.getcolors(640 * 480)) > 1000, name + assert frame.getpixel((60, 96)) == (186, 153, 85), "dialog border" + hashes.append(hashlib.sha256(frame.crop((60, 96, 580, 398)).tobytes()).digest()) + frame.save(path.with_suffix(".png")) + sheet.paste(frame, (0, index * 504 + 24)) + draw.text((8, index * 504 + 6), name, fill="white") + assert len(set(hashes)) == 3, "Contract status/reward must visibly change" + sheet.save(ROOT / "build/actions/npc-dialog-contact.png") + print("PASS: three distinct native NPC dialog frames, bounded modal and changing contract status") + + +def parity(): + tested = Coff(ROOT / "build/actions/actions-test.obj") + shipped = Coff(ROOT / "build/graphics/poker.obj") + procedures = (("InitNpcLife3D", 0), ("UpdateNpcLife3D", 0), ("RenderNpcLife3D", 0), + ("NpcPlanPath3D", 8), ("NpcTryCell3D", 8), ("NpcMove3D", 8), + ("NpcCanStep3D", 12), ("CheckNpcInteractions3D", 0), + ("OpenNpcDialog3D", 0), ("HandleNpcDialog3D", 0), + ("RenderNpcDialog3D", 0), ("CloseNpcDialog3D", 0), + ("NpcContractType3D", 4), ("NpcAcceptContract3D", 4), + ("NpcClaimContract3D", 4), ("NpcRecordRound3D", 8), + ("NpcSaveJournal3D", 0), ("NpcNameText3D", 4), + ("AnimateCityPedestrians3D", 0), ("FinalizeSkullsGuess", 0)) + for name, size in procedures: + symbol = f"_{name}@{size}" + assert tested.signature(symbol) == shipped.signature(symbol), name + print("PASS: shipping NPC navigation, poses, dialogs, rewards and street movement match tested MASM") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--parity", action="store_true") + args = parser.parse_args() + captures() + if args.parity: + parity() diff --git a/tools/tests/check_russian_party.py b/tools/tests/check_russian_party.py new file mode 100644 index 0000000..029b907 --- /dev/null +++ b/tools/tests/check_russian_party.py @@ -0,0 +1,56 @@ +"""Check actual native Russian-roulette party frames and shipping code parity.""" +import argparse +import hashlib +from pathlib import Path + +from PIL import Image, ImageDraw, ImageStat +from check_card_exit_build import Coff + +ROOT = Path(__file__).resolve().parents[2] + + +def frames(): + names = ["ready", "turn", "out", "win", "exit"] + sheet = Image.new("RGB", (1280, 3 * 504), (20, 25, 29)) + draw = ImageDraw.Draw(sheet) + signatures = [] + for i, name in enumerate(names): + path = ROOT / "build/actions" / f"rr-party-{name}.bmp" + image = Image.open(path).convert("RGB") + assert image.size == (640, 480) + assert len(image.getcolors(640 * 480)) > 1000, name + assert sum(ImageStat.Stat(image.crop((0, 400, 640, 480))).stddev) > 5, name + signatures.append(hashlib.sha256(image.tobytes()).digest()) + image.save(path.with_suffix(".png")) + x, y = (i % 2) * 640, (i // 2) * 504 + sheet.paste(image, (x, y + 24)) + draw.text((x + 8, y + 6), f"Native Russian party: {name}", fill="white") + assert len(set(signatures)) == len(names) + sheet.save(ROOT / "build/actions/rr-party-contact.png") + print("PASS: five distinct native party frames: setup, active seat, elimination, win and exit dialog") + + +def parity(): + tested = Coff(ROOT / "build/actions/actions-test.obj") + shipping = Coff(ROOT / "build/graphics/poker.obj") + procedures = (("RRPartyInit3D", 0), ("RRPartyReset3D", 0), ("RRPartySetCount3D", 4), + ("RRPartyInput3D", 0), ("RRLoadCylinder3D", 0), ("RRPartyHit3D", 0), + ("RRPartyNext3D", 0), ("RRPartyWin3D", 0), ("RRPartyLose3D", 0), + ("AbortRussianRound3D", 0), ("RenderRRPartyCharacters3D", 0), + ("RenderRRPartyGun3D", 0), ("RenderRRPartyControls3D", 0), + ("RenderRussianExit3D", 0), ("StartRussianRound3D", 0), + ("AdvanceRussianScene3D", 0), ("HandleRussianInput3D", 0), + ("RenderRussianGame3D", 0), ("RenderRussianTable3D", 0)) + for name, size in procedures: + symbol = f"_{name}@{size}" + assert tested.signature(symbol) == shipping.signature(symbol), name + print("PASS: shipping party turns, payouts, reloading, animation and exit match native-tested MASM") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--parity", action="store_true") + args = parser.parse_args() + frames() + if args.parity: + parity() diff --git a/tools/tests/check_scene_hardening.py b/tools/tests/check_scene_hardening.py index 7bad83c..0e6cafa 100644 --- a/tools/tests/check_scene_hardening.py +++ b/tools/tests/check_scene_hardening.py @@ -13,7 +13,7 @@ def main(): source = (ROOT / 'casino3d.inc').read_text(encoding='cp1251') interaction = source.split('Trigger3DInteraction PROC', 1)[1].split('Trigger3DInteraction ENDP', 1)[0] assert 'LaunchClassicGame' not in interaction - assert interaction.count('call BeginUnavailable3D') == 7 + assert interaction.count('call BeginUnavailable3D') == 6 assert 'call InitNativeDurak3D' in interaction assert 'call InitNativeSlots3D' in interaction panel = Image.open(OUTPUT / 'unavailable.bmp').convert('RGB') diff --git a/tools/tests/check_slot_build.py b/tools/tests/check_slot_build.py index 2e44b3e..f67d437 100644 --- a/tools/tests/check_slot_build.py +++ b/tools/tests/check_slot_build.py @@ -14,7 +14,7 @@ def main(): "RenderNativeSlots3D": 0, "SlotMultiplier3D": 12, "SettleNativeSlots3D": 0, "SlotEscape3D": 0, "SlotExitMouse3D": 0, "SlotReelPosition3D": 4, "DrawSlotReel3D": 4, - "DrawSlotSymbol3D": 12, "Trigger3DInteraction": 0, + "DrawSlotSymbol3D": 12, "DrawSlotTotals3D": 12, "Trigger3DInteraction": 0, "StartCasino3D": 0, "CardTableEscape3D": 0} for name, size in functions.items(): symbol = f"_{name}@{size}" diff --git a/tools/tests/check_slot_frames.py b/tools/tests/check_slot_frames.py index 592c560..52450ef 100644 --- a/tools/tests/check_slot_frames.py +++ b/tools/tests/check_slot_frames.py @@ -4,6 +4,7 @@ import struct from pathlib import Path from PIL import Image, ImageChops +from check_coin_detail import font, text_matches ROOT = Path(__file__).resolve().parents[2] OUTPUT = ROOT / "build/actions" @@ -58,7 +59,18 @@ def main(): for index, name in enumerate(NAMES): contact.paste(frames[name], ((index % 4) * 640, (index // 4) * 480)) contact.save(OUTPUT / "slots-contact.png") + glyphs = font() + for name, gross, net, status, ink in ( + ("slots-refund", "100", "0", "ВОЗВРÐ�Т", (208, 212, 208)), + ("slots-net-win", "200", "+100", "ВЫПЛÐ�ТÐ�", (168, 221, 185)), + ("slots-loss", "0", "-100", "ПРОИГРЫШ", (238, 153, 136))): + frame = Image.open(OUTPUT / (name + ".bmp")).convert("RGB") + text_matches(frame, gross, 384, 402, 2, (244, 243, 232), glyphs) + text_matches(frame, net, 384, 422, 2, ink, glyphs) + text_matches(frame, status, 208, 298, 2, (232, 215, 173), glyphs) + frame.save(OUTPUT / (name + ".png")) print("PASS: 8 distinct native slot frames; pixel-accurate reel clipping; sequential stops; opaque cabinet and 8 real symbol sprites") + print("PASS: exact native gross/net/refund/loss Russian glyphs; refund is not a net win") if __name__ == "__main__": diff --git a/tools/tests/clover_fixtures.inc b/tools/tests/clover_fixtures.inc new file mode 100644 index 0000000..587f6f2 --- /dev/null +++ b/tools/tests/clover_fixtures.inc @@ -0,0 +1,558 @@ +; Mechanically generated offline reference vectors. +.data +clpFixtureCount3D equ 553 +clpFixtures3D label DWORD + dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,117,6,32767,1 + dd 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,78,6,32767,1 + dd 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,78,6,32767,1 + dd 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,117,6,32767,1 + dd 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,195,6,32767,1 + dd 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,195,6,32767,1 + dd 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,273,6,32767,1 + dd 6,3,6,2,6,2,5,6,4,0,6,0,3,6,6,56,1,17553,0 + dd 6,6,6,6,6,2,5,1,4,0,4,0,3,6,2,49,1,31,0 + dd 0,3,6,2,5,2,5,1,4,0,6,6,6,6,6,49,1,31744,0 + dd 0,3,6,2,5,2,6,1,6,0,6,0,3,6,6,28,1,17732,0 + dd 6,3,6,2,6,2,6,1,6,0,4,0,6,6,2,28,1,4433,0 + dd 6,6,6,6,6,2,5,1,4,0,4,0,3,6,2,49,1,31,0 + dd 0,3,6,2,5,6,6,6,6,6,4,0,3,6,2,21,1,992,0 + dd 0,3,6,2,5,2,5,1,4,0,6,6,6,6,6,49,1,31744,0 + dd 6,6,6,6,5,2,5,1,4,0,4,0,3,6,2,14,1,15,0 + dd 0,6,6,6,6,2,5,1,4,0,4,0,3,6,2,14,1,30,0 + dd 0,3,6,2,5,6,6,6,6,0,4,0,3,6,2,14,1,480,0 + dd 0,3,6,2,5,2,6,6,6,6,4,0,3,6,2,14,1,960,0 + dd 0,3,6,2,5,2,5,1,4,0,6,6,6,6,2,14,1,15360,0 + dd 0,3,6,2,5,2,5,1,4,0,4,6,6,6,6,14,1,30720,0 + dd 6,3,6,2,5,6,5,1,4,0,6,0,3,6,2,7,1,1057,0 + dd 0,6,6,2,5,2,6,1,4,0,4,6,3,6,2,7,1,2114,0 + dd 0,3,6,2,5,2,5,6,4,0,4,0,6,6,2,7,1,4228,0 + dd 0,3,6,6,5,2,5,1,6,0,4,0,3,6,2,7,1,8456,0 + dd 0,3,6,2,6,2,5,1,4,6,4,0,3,6,6,7,1,16912,0 + dd 6,3,6,2,5,2,6,1,4,0,4,0,6,6,2,7,1,4161,0 + dd 0,6,6,2,5,2,5,6,4,0,4,0,3,6,2,7,1,8322,0 + dd 0,3,6,2,5,2,5,1,6,0,4,0,3,6,6,7,1,16644,0 + dd 0,3,6,2,5,2,6,1,4,0,6,0,3,6,2,7,1,1092,0 + dd 0,3,6,6,5,2,5,6,4,0,4,6,3,6,2,7,1,2184,0 + dd 0,3,6,2,6,2,5,1,6,0,4,0,6,6,2,7,1,4368,0 + dd 6,6,6,2,5,2,5,1,4,0,4,0,3,6,2,7,1,7,0 + dd 0,6,6,6,5,2,5,1,4,0,4,0,3,6,2,7,1,14,0 + dd 0,3,6,6,6,2,5,1,4,0,4,0,3,6,2,7,1,28,0 + dd 0,3,6,2,5,6,6,6,4,0,4,0,3,6,2,7,1,224,0 + dd 0,3,6,2,5,2,6,6,6,0,4,0,3,6,2,7,1,448,0 + dd 0,3,6,2,5,2,5,6,6,6,4,0,3,6,2,7,1,896,0 + dd 0,3,6,2,5,2,5,1,4,0,6,6,6,6,2,14,1,15360,0 + dd 0,3,6,2,5,2,5,1,4,0,4,6,6,6,2,7,1,14336,0 + dd 0,3,6,2,5,2,5,1,4,0,4,0,6,6,6,7,1,28672,0 + dd 6,3,3,0,1,2,0,3,5,5,6,6,0,0,2,0,0,0,0 + dd 2,6,3,6,2,6,2,4,4,5,3,2,4,6,2,0,0,0,0 + dd 1,3,6,2,6,6,5,0,6,1,4,6,0,4,4,0,0,0,0 + dd 3,3,0,0,1,0,3,3,5,2,3,2,0,6,1,0,0,0,0 + dd 3,6,0,3,0,4,1,5,6,0,6,2,2,0,2,0,0,0,0 + dd 3,2,6,0,5,0,5,5,5,1,2,6,4,4,6,5,1,448,0 + dd 6,0,0,3,4,1,0,6,3,0,3,0,5,4,0,3,1,2114,0 + dd 5,5,4,2,1,4,4,6,3,1,6,6,1,1,1,4,2,29200,0 + dd 6,5,0,5,5,0,6,0,3,6,5,5,3,0,6,0,0,0,0 + dd 4,0,4,6,5,3,1,3,4,3,5,1,3,3,6,0,0,0,0 + dd 3,6,6,2,2,3,4,1,6,0,6,3,2,2,4,0,0,0,0 + dd 5,0,1,2,6,6,2,2,6,2,5,6,6,1,6,7,1,4368,0 + dd 4,3,1,6,3,6,6,5,5,4,1,3,3,6,2,0,0,0,0 + dd 1,3,1,2,6,3,6,4,6,6,2,2,2,5,6,9,2,24080,0 + dd 0,3,6,2,2,5,6,6,4,0,2,0,5,4,1,0,0,0,0 + dd 4,5,3,0,1,5,4,0,2,6,6,3,4,2,0,5,1,4161,0 + dd 0,1,3,1,4,3,3,3,2,6,0,0,4,6,1,3,1,224,0 + dd 3,5,6,1,4,0,2,0,2,5,6,1,3,6,4,0,0,0,0 + dd 6,1,6,6,5,6,4,0,5,4,4,3,4,5,3,0,0,0,0 + dd 2,3,2,2,4,2,0,2,6,1,1,0,3,4,3,0,0,0,0 + dd 4,3,6,6,2,3,2,6,5,3,0,2,6,2,3,7,1,4228,0 + dd 1,3,0,4,5,3,2,1,5,1,2,1,4,4,4,5,1,28672,0 + dd 1,1,3,0,1,6,5,4,1,3,0,3,0,1,2,0,0,0,0 + dd 4,5,1,2,0,2,4,0,0,5,6,0,2,0,0,0,0,0,0 + dd 6,0,2,1,5,4,0,2,0,0,1,5,5,4,0,0,0,0,0 + dd 1,6,6,6,5,6,6,2,2,0,0,2,5,3,2,7,1,14,0 + dd 6,6,6,1,6,0,5,1,3,5,3,4,5,4,5,7,1,7,0 + dd 2,6,2,0,5,1,6,6,0,4,5,0,1,1,4,0,0,0,0 + dd 1,2,5,2,0,2,3,1,2,5,6,6,1,2,4,2,1,8456,0 + dd 3,0,2,4,0,4,3,0,1,3,1,3,6,2,1,0,0,0,0 + dd 5,2,1,1,3,5,0,0,6,0,4,6,4,5,1,0,0,0,0 + dd 5,3,5,4,6,3,4,2,6,4,4,1,6,4,4,7,1,4368,0 + dd 4,4,3,6,5,3,5,0,5,0,2,0,4,6,3,0,0,0,0 + dd 3,1,2,4,2,2,4,0,5,2,4,6,0,1,1,0,0,0,0 + dd 1,4,4,4,3,4,5,2,6,4,3,6,2,5,2,5,1,14,0 + dd 0,0,6,3,3,3,6,4,2,3,0,6,6,5,1,0,0,0,0 + dd 4,2,4,0,4,4,6,0,0,1,5,4,5,2,6,0,0,0,0 + dd 0,0,4,6,4,1,3,0,0,5,2,2,1,6,1,0,0,0,0 + dd 4,6,0,2,1,6,3,3,4,1,4,4,4,2,0,5,1,7168,0 + dd 5,1,6,0,6,2,6,5,6,1,4,3,1,6,0,0,0,0,0 + dd 2,2,6,4,2,5,2,3,6,0,2,6,3,6,0,0,0,0,0 + dd 3,1,3,5,1,5,3,5,4,4,0,5,5,5,3,10,2,14472,0 + dd 0,0,6,6,4,3,2,0,6,5,2,4,3,2,4,0,0,0,0 + dd 4,1,4,3,0,1,4,4,0,6,0,4,6,1,1,0,0,0,0 + dd 5,6,0,5,2,3,2,1,3,2,4,4,5,2,4,0,0,0,0 + dd 2,4,2,6,6,1,4,2,0,5,6,5,2,4,0,2,1,4228,0 + dd 0,3,6,2,3,2,1,6,1,1,2,4,5,2,1,0,0,0,0 + dd 3,3,5,3,6,0,6,5,4,2,3,2,5,4,5,5,1,4228,0 + dd 6,6,5,1,4,4,5,6,2,2,2,4,6,4,6,0,0,0,0 + dd 6,5,5,4,6,2,4,5,4,0,2,2,1,3,5,0,0,0,0 + dd 3,2,2,4,3,2,0,1,1,5,2,1,4,6,2,0,0,0,0 + dd 6,0,1,4,3,3,4,2,0,2,1,3,4,5,0,0,0,0,0 + dd 0,2,1,4,3,4,1,5,6,1,3,2,4,3,1,0,0,0,0 + dd 6,1,2,5,0,0,0,0,3,0,3,6,3,1,4,3,1,224,0 + dd 5,0,0,5,0,1,3,6,5,3,3,3,5,6,3,0,0,0,0 + dd 1,0,1,1,4,3,3,4,6,6,0,5,1,3,6,0,0,0,0 + dd 0,1,0,4,2,3,5,5,1,2,4,3,4,2,6,0,0,0,0 + dd 4,4,1,4,4,6,1,3,4,1,5,1,2,2,2,2,1,28672,0 + dd 6,2,2,3,4,0,1,2,2,5,3,2,5,6,0,0,0,0,0 + dd 5,3,0,4,1,5,1,0,0,1,4,1,6,2,4,0,0,0,0 + dd 6,1,6,0,0,0,6,5,5,6,4,1,1,0,2,0,0,0,0 + dd 2,6,0,3,1,3,6,0,2,2,5,1,5,1,0,0,0,0,0 + dd 2,4,3,0,5,0,5,5,6,5,4,4,3,3,5,5,1,16912,0 + dd 5,3,1,3,5,6,0,1,2,2,4,2,4,4,3,0,0,0,0 + dd 4,1,1,4,4,4,0,0,6,3,5,4,1,4,0,0,0,0,0 + dd 2,0,5,3,3,5,1,1,3,5,1,3,6,5,2,0,0,0,0 + dd 3,5,5,6,4,6,6,1,1,0,5,2,2,2,1,2,1,14336,0 + dd 1,1,5,0,5,0,0,3,6,1,5,2,5,6,1,0,0,0,0 + dd 2,6,2,0,3,1,4,4,0,2,5,6,3,4,5,0,0,0,0 + dd 0,4,6,6,4,4,2,1,4,6,5,5,5,1,2,5,1,7168,0 + dd 2,5,4,2,1,2,2,6,2,4,0,0,1,4,5,0,0,0,0 + dd 3,5,2,0,3,2,2,3,2,3,0,0,0,4,2,5,2,23812,0 + dd 2,4,3,3,0,0,6,2,1,5,1,6,6,4,1,0,0,0,0 + dd 2,0,6,6,6,4,4,3,2,0,0,4,1,4,2,7,1,28,0 + dd 1,3,5,2,6,2,3,4,4,5,1,3,2,3,0,3,1,2114,0 + dd 4,3,1,2,5,0,0,5,6,5,2,3,1,3,1,0,0,0,0 + dd 0,4,2,5,1,0,2,6,0,2,1,6,2,4,5,0,0,0,0 + dd 2,0,5,6,3,3,3,6,2,1,1,4,0,2,3,0,0,0,0 + dd 3,5,5,3,5,2,0,3,2,0,2,3,2,2,2,5,2,30856,0 + dd 3,0,5,4,5,3,2,1,2,1,4,3,1,4,4,0,0,0,0 + dd 2,3,5,6,1,6,6,1,4,3,1,0,4,3,6,0,0,0,0 + dd 1,6,0,5,3,5,0,2,3,3,3,1,0,2,5,0,0,0,0 + dd 2,0,3,4,4,0,1,6,6,1,3,5,2,1,4,0,0,0,0 + dd 4,4,1,3,4,2,0,6,0,1,6,3,4,1,3,0,0,0,0 + dd 6,4,5,3,0,1,0,1,6,3,4,4,0,0,2,0,0,0,0 + dd 1,1,3,6,0,6,4,0,4,3,5,0,0,2,5,0,0,0,0 + dd 1,5,4,0,4,5,3,6,4,2,6,4,5,5,1,0,0,0,0 + dd 0,4,0,1,0,5,5,3,0,2,3,4,2,4,5,0,0,0,0 + dd 0,5,6,2,5,1,3,3,1,1,1,6,4,2,4,0,0,0,0 + dd 6,0,4,6,2,4,4,3,5,4,2,0,5,4,2,0,0,0,0 + dd 5,3,1,1,3,5,4,4,2,2,6,0,1,3,6,0,0,0,0 + dd 6,4,3,3,0,4,4,2,1,6,1,4,0,4,5,5,1,2114,0 + dd 4,4,3,0,4,0,2,1,2,5,5,5,5,2,4,5,1,7168,0 + dd 2,3,6,6,2,1,1,6,0,4,4,5,2,1,4,0,0,0,0 + dd 2,4,3,6,0,5,4,3,1,5,6,2,5,5,0,0,0,0,0 + dd 0,0,6,0,0,2,0,0,5,2,5,1,4,5,3,0,0,0,0 + dd 4,4,6,0,5,0,4,4,1,2,6,5,4,3,2,5,1,4161,0 + dd 0,5,0,4,1,5,0,3,2,3,2,3,1,0,1,0,0,0,0 + dd 6,3,3,2,3,4,1,4,1,4,1,6,0,5,0,0,0,0,0 + dd 5,0,2,2,4,2,1,1,3,3,6,6,6,4,3,7,1,7168,0 + dd 3,0,2,6,0,0,6,3,5,2,3,3,3,3,0,6,1,15360,0 + dd 5,0,0,6,3,5,0,5,4,6,3,6,0,1,6,0,0,0,0 + dd 2,5,2,5,1,1,4,4,3,4,1,1,2,2,1,0,0,0,0 + dd 5,5,1,2,4,4,3,0,4,1,4,6,3,3,0,0,0,0,0 + dd 3,2,0,2,0,0,6,6,1,5,4,2,6,5,4,0,0,0,0 + dd 6,3,0,6,6,1,5,3,0,1,3,2,6,5,1,0,0,0,0 + dd 2,1,6,0,6,3,6,1,5,4,5,3,1,6,6,0,0,0,0 + dd 4,0,0,3,1,1,6,4,5,0,4,1,6,0,6,0,0,0,0 + dd 2,4,2,3,6,0,6,0,5,3,3,1,2,0,5,0,0,0,0 + dd 1,6,1,2,2,1,4,2,6,4,1,1,2,0,2,2,1,1057,0 + dd 3,3,0,6,2,5,0,5,5,4,2,4,0,1,6,0,0,0,0 + dd 5,0,4,4,3,4,3,3,6,1,1,0,0,0,6,3,1,14336,0 + dd 5,5,4,6,2,4,0,1,6,0,3,6,0,0,5,0,0,0,0 + dd 1,6,0,4,6,2,6,2,1,0,6,1,4,6,1,0,0,0,0 + dd 3,3,6,1,2,1,3,1,5,5,0,2,2,6,0,0,0,0,0 + dd 1,0,1,1,3,4,3,3,4,2,2,1,3,2,5,0,0,0,0 + dd 0,1,4,6,1,5,4,3,4,1,1,5,3,4,3,0,0,0,0 + dd 6,5,3,0,6,4,3,1,1,3,3,6,5,6,0,3,1,1092,0 + dd 4,2,5,4,6,6,6,3,2,2,1,3,2,4,0,0,0,0,0 + dd 2,1,5,5,4,5,0,2,4,3,6,2,3,2,2,0,0,0,0 + dd 1,3,0,4,2,0,1,4,4,5,6,4,5,6,4,5,1,2184,0 + dd 3,3,4,5,4,1,0,4,5,1,3,4,3,6,0,0,0,0,0 + dd 1,6,4,6,2,1,1,2,0,0,0,6,0,3,4,0,0,0,0 + dd 0,4,5,3,4,1,1,6,2,0,6,6,2,6,6,0,0,0,0 + dd 1,5,2,1,5,1,6,4,1,0,6,4,0,6,4,0,0,0,0 + dd 0,3,6,3,0,2,1,6,1,2,6,0,3,1,1,0,0,0,0 + dd 4,0,2,3,0,2,6,4,1,3,0,6,1,4,3,0,0,0,0 + dd 0,0,5,5,4,5,1,5,2,5,2,3,6,5,2,0,0,0,0 + dd 5,5,4,1,5,5,2,5,4,6,3,1,4,6,5,0,0,0,0 + dd 6,3,3,5,1,4,6,4,0,0,2,4,0,2,4,0,0,0,0 + dd 1,2,6,2,4,5,0,4,3,0,3,0,1,3,2,0,0,0,0 + dd 0,0,5,0,3,6,5,2,4,6,1,3,4,5,0,0,0,0,0 + dd 0,4,3,4,0,0,1,5,3,5,3,2,6,5,6,0,0,0,0 + dd 5,4,6,6,2,1,3,3,1,6,1,4,5,2,0,0,0,0,0 + dd 4,4,2,1,3,5,1,4,6,6,1,2,1,5,2,0,0,0,0 + dd 0,3,1,1,5,0,2,4,4,3,0,2,0,6,5,3,1,1057,0 + dd 6,2,3,2,3,0,5,1,4,2,1,5,2,5,2,0,0,0,0 + dd 2,6,4,1,6,4,5,1,4,0,6,5,5,2,1,0,0,0,0 + dd 5,2,0,1,6,3,6,0,6,2,0,0,3,4,1,0,0,0,0 + dd 5,0,3,0,3,0,2,4,6,0,2,6,1,6,6,0,0,0,0 + dd 6,5,1,3,2,6,1,4,4,6,5,0,1,2,3,0,0,0,0 + dd 2,4,6,0,4,3,0,6,3,1,4,2,4,2,4,0,0,0,0 + dd 1,6,5,1,3,6,3,1,5,6,2,3,0,6,6,0,0,0,0 + dd 5,6,6,5,6,1,0,5,6,0,6,0,0,1,0,0,0,0,0 + dd 2,5,2,4,4,4,1,4,5,3,5,2,5,4,1,0,0,0,0 + dd 4,3,5,1,4,6,5,5,5,6,5,6,0,2,1,10,2,1476,0 + dd 5,3,6,1,6,5,2,0,6,1,0,4,6,4,1,7,1,4368,0 + dd 6,3,4,1,1,1,0,5,3,1,5,5,3,1,1,2,1,16912,0 + dd 0,3,5,5,3,6,3,1,5,4,2,5,4,3,5,5,1,16644,0 + dd 6,1,1,1,6,4,3,5,1,5,3,1,4,3,0,2,1,14,0 + dd 6,4,2,5,6,0,4,2,1,1,1,2,3,0,4,0,0,0,0 + dd 6,6,3,6,2,4,2,0,0,0,3,0,0,3,4,3,1,896,0 + dd 6,6,6,4,5,2,5,5,5,4,6,5,1,0,2,12,2,455,0 + dd 2,1,0,1,6,4,0,5,1,0,2,0,1,1,4,2,1,8456,0 + dd 5,6,4,5,2,5,5,2,1,0,0,3,5,1,0,5,1,4161,0 + dd 0,6,4,5,5,3,5,0,1,5,3,2,1,0,5,5,1,16912,0 + dd 6,2,0,0,6,6,1,6,6,2,1,2,2,4,6,0,0,0,0 + dd 0,6,3,1,3,1,5,4,1,1,6,2,4,0,4,0,0,0,0 + dd 1,1,1,1,6,2,6,0,4,1,2,3,5,5,2,4,1,15,0 + dd 4,5,1,5,0,6,6,4,6,1,0,1,4,5,5,0,0,0,0 + dd 6,3,3,4,6,6,1,6,0,2,5,2,2,5,1,0,0,0,0 + dd 6,3,5,0,1,2,1,6,6,6,0,5,0,6,6,7,1,896,0 + dd 0,2,5,1,2,4,5,0,1,0,3,2,2,2,5,2,1,14336,0 + dd 0,5,1,5,5,1,1,0,3,3,6,1,5,1,2,0,0,0,0 + dd 4,6,4,4,4,0,1,4,3,3,5,5,6,2,1,5,1,28,0 + dd 2,2,2,3,0,3,3,1,2,0,0,6,4,4,2,4,2,16647,0 + dd 2,6,5,2,0,2,6,6,4,0,5,0,5,3,5,0,0,0,0 + dd 2,4,1,2,2,5,0,4,0,4,4,5,1,5,5,0,0,0,0 + dd 0,0,3,2,4,5,5,5,4,5,0,2,4,1,5,10,2,4592,0 + dd 2,2,3,6,3,4,0,2,4,2,5,4,6,6,4,0,0,0,0 + dd 2,6,0,2,2,0,0,1,1,4,0,1,3,5,2,3,1,1092,0 + dd 2,5,4,3,1,2,4,5,0,1,6,3,2,6,5,0,0,0,0 + dd 3,3,4,1,4,4,5,5,0,0,2,3,4,4,6,0,0,0,0 + dd 3,3,0,0,2,0,5,1,0,4,0,3,1,5,4,0,0,0,0 + dd 6,2,2,3,5,4,1,3,0,0,0,0,2,5,1,0,0,0,0 + dd 1,6,2,6,4,1,0,6,6,1,1,1,0,3,3,2,1,1057,0 + dd 5,3,5,6,5,2,2,1,6,3,1,2,2,5,1,0,0,0,0 + dd 6,1,3,5,4,5,0,5,3,3,3,6,1,6,0,0,0,0,0 + dd 4,2,0,3,0,3,5,0,4,6,3,4,0,4,1,3,1,4228,0 + dd 3,5,1,5,6,3,2,1,3,4,2,5,2,6,5,0,0,0,0 + dd 0,1,0,5,5,6,0,5,0,6,4,2,0,6,1,3,1,4161,0 + dd 5,0,2,0,0,3,4,3,6,1,5,5,3,5,0,0,0,0,0 + dd 3,0,5,5,4,3,4,6,3,4,5,1,4,5,6,0,0,0,0 + dd 3,4,3,4,0,0,0,0,1,3,0,1,2,0,2,3,1,224,0 + dd 2,2,1,0,0,1,4,5,6,1,4,6,0,4,2,0,0,0,0 + dd 1,1,5,2,0,2,2,6,1,1,0,5,0,2,4,0,0,0,0 + dd 0,2,6,2,4,2,4,6,5,6,1,4,6,3,4,7,1,4228,0 + dd 6,0,3,0,3,0,2,1,0,2,0,1,6,4,4,0,0,0,0 + dd 1,2,1,4,3,6,1,4,4,5,5,6,0,3,0,0,0,0,0 + dd 6,2,3,3,3,6,0,5,1,3,4,1,5,6,3,6,2,16924,0 + dd 6,5,1,1,6,5,1,2,5,0,3,6,0,5,4,0,0,0,0 + dd 4,4,2,3,5,0,3,0,1,2,1,6,6,3,3,0,0,0,0 + dd 6,1,6,2,4,5,6,0,5,1,1,2,6,5,4,7,1,4161,0 + dd 1,3,4,0,4,6,2,5,1,5,5,2,5,2,5,0,0,0,0 + dd 1,1,4,1,6,4,2,5,1,5,4,5,6,5,6,0,0,0,0 + dd 1,5,6,2,3,1,3,3,5,2,1,1,3,2,6,2,1,1057,0 + dd 0,1,5,0,1,0,1,5,3,6,0,2,1,4,6,3,1,1057,0 + dd 0,2,1,4,1,0,0,2,6,1,1,6,4,1,2,0,0,0,0 + dd 0,4,6,0,3,6,6,4,0,6,0,3,5,3,1,0,0,0,0 + dd 2,2,5,3,1,1,1,3,3,5,2,6,6,3,6,3,1,8456,0 + dd 6,2,6,2,2,0,2,5,5,5,6,2,3,2,4,7,2,3010,0 + dd 1,6,2,3,3,1,1,5,4,0,6,0,6,1,5,0,0,0,0 + dd 2,5,4,1,4,4,2,1,3,0,5,6,4,1,3,0,0,0,0 + dd 3,5,5,6,5,1,6,5,6,4,3,0,2,4,4,0,0,0,0 + dd 5,2,0,2,3,2,0,2,5,1,4,2,5,2,6,4,2,10378,0 + dd 4,5,5,6,1,1,3,2,4,5,5,3,0,3,5,0,0,0,0 + dd 0,5,3,1,2,6,6,1,1,2,5,6,3,5,3,0,0,0,0 + dd 5,5,2,6,5,1,2,0,6,4,1,4,6,2,3,0,0,0,0 + dd 5,1,6,5,1,1,0,2,3,0,0,3,3,5,4,0,0,0,0 + dd 1,1,2,0,5,0,2,1,5,6,4,4,1,0,0,0,0,0,0 + dd 4,0,5,5,0,4,3,6,1,2,2,0,5,4,6,0,0,0,0 + dd 5,0,6,3,1,5,3,6,1,5,4,2,5,1,0,0,0,0,0 + dd 0,2,3,4,1,5,0,2,4,5,1,2,6,5,5,0,0,0,0 + dd 1,2,6,2,3,6,2,5,0,6,5,0,0,2,1,0,0,0,0 + dd 0,0,3,6,3,6,0,3,0,6,2,0,3,2,2,6,2,6342,0 + dd 6,6,6,3,2,3,6,6,3,5,3,3,5,4,2,7,1,7,0 + dd 4,2,1,6,5,4,0,3,5,5,5,0,4,6,0,0,0,0,0 + dd 1,4,0,3,2,4,6,4,6,4,4,6,1,4,0,5,1,8322,0 + dd 4,2,1,3,6,2,5,4,5,1,0,6,3,6,5,0,0,0,0 + dd 2,5,4,3,3,3,3,5,5,4,1,0,0,5,1,5,1,8322,0 + dd 1,6,0,3,6,4,0,2,5,6,5,2,3,3,6,7,1,16912,0 + dd 4,2,3,6,6,0,1,2,5,2,4,6,4,4,0,0,0,0,0 + dd 5,1,4,6,0,5,5,2,5,6,0,0,0,3,0,3,1,7168,0 + dd 4,1,3,3,5,1,4,3,1,3,6,5,4,1,5,5,1,4161,0 + dd 4,2,1,0,0,3,4,4,4,4,5,5,1,6,5,10,1,960,0 + dd 0,2,1,3,0,3,0,0,1,1,4,5,0,2,0,3,1,4161,0 + dd 6,5,1,6,3,4,4,3,5,3,0,3,4,6,6,0,0,0,0 + dd 2,3,0,1,1,5,6,4,5,4,0,5,3,1,5,0,0,0,0 + dd 6,3,6,1,1,4,3,6,2,0,2,2,1,0,2,0,0,0,0 + dd 2,3,3,0,4,3,5,3,1,3,3,0,5,2,1,0,0,0,0 + dd 2,1,0,6,1,0,4,1,3,3,5,5,3,2,2,0,0,0,0 + dd 3,2,4,0,0,2,5,3,4,1,4,3,5,3,5,0,0,0,0 + dd 1,4,6,1,5,5,3,0,2,2,6,0,4,6,6,0,0,0,0 + dd 6,5,2,6,3,4,3,1,4,4,3,1,6,3,0,0,0,0,0 + dd 1,4,3,6,0,2,2,3,6,2,3,3,0,0,5,0,0,0,0 + dd 0,2,4,1,5,6,6,2,4,5,4,1,4,6,0,0,0,0,0 + dd 1,2,1,3,0,0,3,0,5,2,2,5,6,5,6,0,0,0,0 + dd 6,6,2,0,3,0,0,0,6,1,6,3,6,4,6,3,1,224,0 + dd 0,6,5,0,3,6,4,0,4,3,0,5,0,3,0,0,0,0,0 + dd 1,3,6,6,0,3,2,4,2,6,3,6,2,2,3,0,0,0,0 + dd 5,4,1,2,6,0,1,3,0,2,3,1,4,2,6,0,0,0,0 + dd 5,1,5,3,0,2,1,5,5,2,5,3,2,5,5,5,1,16644,0 + dd 5,0,5,4,2,4,3,4,0,6,2,1,3,0,0,0,0,0,0 + dd 6,3,2,4,1,6,6,4,5,0,2,4,4,1,1,5,1,2184,0 + dd 3,1,3,4,3,2,3,2,0,0,0,3,2,5,3,0,0,0,0 + dd 5,2,2,4,5,6,6,0,1,4,3,1,6,2,5,0,0,0,0 + dd 1,4,0,6,2,4,1,6,0,4,6,5,2,3,5,0,0,0,0 + dd 5,5,3,5,1,5,4,0,4,4,4,2,6,2,5,0,0,0,0 + dd 6,3,2,2,1,2,6,6,3,1,3,1,4,4,0,0,0,0,0 + dd 0,0,0,2,4,1,6,5,0,0,6,4,6,6,5,3,1,7,0 + dd 5,3,2,1,4,1,5,6,1,0,1,1,5,2,6,5,1,4161,0 + dd 4,5,2,1,6,5,2,0,2,4,1,5,6,5,0,0,0,0,0 + dd 4,0,0,1,2,6,1,3,2,0,5,3,3,2,0,0,0,0,0 + dd 6,2,5,4,2,5,2,1,5,3,0,0,4,2,5,5,1,16644,0 + dd 4,6,2,0,5,1,1,1,0,3,1,5,3,0,4,5,2,8680,0 + dd 6,6,4,1,6,1,5,0,5,3,6,1,2,4,6,0,0,0,0 + dd 1,2,6,3,3,0,0,6,0,2,1,4,4,5,2,0,0,0,0 + dd 0,1,0,3,6,0,5,3,3,4,2,0,0,3,0,3,1,8456,0 + dd 3,2,2,2,0,5,4,1,3,5,4,1,4,0,6,2,1,14,0 + dd 1,2,6,1,6,4,6,6,3,6,0,0,3,0,6,7,1,16912,0 + dd 6,4,6,0,0,0,1,3,2,3,4,2,5,0,3,0,0,0,0 + dd 2,4,3,4,4,0,6,1,6,0,2,5,6,6,4,0,0,0,0 + dd 0,0,4,4,1,0,1,4,6,1,1,2,4,3,3,5,1,4228,0 + dd 4,6,6,4,2,0,0,2,5,0,1,6,4,5,3,0,0,0,0 + dd 3,0,4,3,4,4,3,3,1,3,1,0,4,6,1,0,0,0,0 + dd 5,6,0,2,6,4,3,5,0,3,4,6,4,5,1,0,0,0,0 + dd 1,1,6,2,5,0,6,1,6,5,2,3,6,4,2,0,0,0,0 + dd 0,2,6,0,0,3,1,4,2,0,1,5,5,5,3,5,1,14336,0 + dd 4,5,0,3,6,0,5,2,6,2,3,4,5,4,3,0,0,0,0 + dd 1,3,5,3,4,2,2,2,0,0,5,3,6,1,3,2,1,224,0 + dd 5,1,5,5,1,6,1,4,5,6,1,3,4,5,3,5,1,8456,0 + dd 0,2,1,3,2,4,3,5,2,0,3,4,4,0,1,0,0,0,0 + dd 3,2,4,6,5,4,3,2,0,0,4,4,2,1,0,0,0,0,0 + dd 2,4,3,0,6,1,2,3,3,4,6,1,3,1,2,3,1,4228,0 + dd 1,1,1,1,2,0,3,2,1,1,4,0,4,1,3,6,2,8463,0 + dd 3,3,6,2,2,4,3,0,6,6,4,2,0,4,5,0,0,0,0 + dd 3,3,3,4,2,5,6,0,0,3,1,1,5,3,3,3,1,7,0 + dd 2,5,6,4,1,3,1,5,6,5,1,1,6,6,4,0,0,0,0 + dd 3,6,4,3,5,6,0,0,5,4,6,2,0,5,3,0,0,0,0 + dd 2,2,6,3,4,0,0,6,0,2,2,1,5,4,6,0,0,0,0 + dd 4,2,0,3,6,3,6,6,5,1,6,6,0,4,3,0,0,0,0 + dd 4,1,2,2,2,4,3,1,2,4,1,0,4,5,2,4,2,16668,0 + dd 4,4,3,3,6,3,0,3,5,4,1,5,3,5,3,3,1,4228,0 + dd 4,1,3,6,4,1,3,4,5,4,5,5,5,2,0,5,1,7168,0 + dd 3,5,4,2,5,2,0,1,5,3,5,3,1,6,1,0,0,0,0 + dd 1,5,4,3,6,3,3,3,3,0,5,4,5,1,5,6,1,480,0 + dd 4,0,2,4,1,4,3,0,4,0,5,1,4,0,1,3,1,8322,0 + dd 6,3,2,3,5,5,6,4,0,0,0,2,6,0,1,7,1,4161,0 + dd 5,5,1,0,0,5,5,1,3,5,0,1,6,4,6,0,0,0,0 + dd 5,0,1,1,6,1,4,5,5,6,5,5,6,1,0,0,0,0,0 + dd 4,6,0,5,3,5,4,5,1,5,4,0,5,6,0,0,0,0,0 + dd 5,3,5,4,0,6,3,1,1,3,2,1,5,3,2,0,0,0,0 + dd 3,6,3,6,0,2,0,6,0,1,0,4,2,3,4,0,0,0,0 + dd 1,0,6,3,2,1,5,1,6,4,2,1,3,2,4,0,0,0,0 + dd 5,4,6,6,2,4,6,0,6,6,5,2,4,0,1,0,0,0,0 + dd 6,6,6,1,4,0,2,3,0,6,3,3,4,6,3,7,1,7,0 + dd 0,1,0,5,4,0,6,5,0,5,5,2,2,1,1,0,0,0,0 + dd 0,4,1,6,1,5,4,3,5,0,1,6,5,2,3,0,0,0,0 + dd 1,6,6,6,6,2,1,5,3,3,4,1,2,4,1,14,1,30,0 + dd 5,2,5,3,1,6,3,2,6,5,2,4,1,4,1,0,0,0,0 + dd 4,0,3,0,0,0,0,5,0,6,6,5,0,6,6,3,1,4368,0 + dd 1,2,3,1,5,0,2,6,3,5,6,4,2,0,0,0,0,0,0 + dd 6,6,6,6,5,3,1,3,2,4,1,5,5,6,3,14,1,15,0 + dd 3,0,0,1,6,1,0,2,2,2,5,5,6,4,2,2,1,896,0 + dd 4,3,0,2,3,4,1,5,6,1,0,6,3,3,6,0,0,0,0 + dd 5,0,0,4,6,1,3,0,0,1,5,0,4,6,6,0,0,0,0 + dd 5,4,2,2,3,6,3,4,4,0,4,0,3,6,2,0,0,0,0 + dd 6,4,5,3,5,2,5,0,5,6,1,3,5,4,1,5,1,4368,0 + dd 1,4,1,5,4,6,2,6,2,4,1,2,4,5,1,0,0,0,0 + dd 0,1,0,6,5,1,2,4,5,2,3,1,5,3,5,5,1,4368,0 + dd 2,4,1,6,1,3,1,6,1,3,0,2,0,4,5,0,0,0,0 + dd 5,6,0,5,5,4,0,0,1,3,5,6,6,1,3,0,0,0,0 + dd 1,2,3,3,4,5,4,5,0,5,0,2,6,6,6,7,1,28672,0 + dd 1,0,3,2,5,6,5,3,1,3,1,5,0,5,1,0,0,0,0 + dd 6,0,4,6,3,3,0,1,4,5,6,1,3,1,1,0,0,0,0 + dd 4,3,1,4,1,1,5,6,1,4,4,0,0,4,6,0,0,0,0 + dd 1,1,1,5,1,2,0,6,0,0,6,4,1,4,1,2,1,7,0 + dd 4,2,0,2,0,4,4,4,4,3,0,3,4,3,0,15,2,4577,0 + dd 6,5,3,5,3,1,2,3,4,2,1,2,3,2,1,3,1,4228,0 + dd 1,6,4,6,3,6,1,1,1,3,4,2,4,3,6,2,1,448,0 + dd 0,2,2,4,3,4,4,6,3,5,4,6,3,2,2,3,1,4368,0 + dd 5,3,3,5,0,4,1,1,3,0,1,0,5,4,4,0,0,0,0 + dd 3,2,5,6,6,5,6,0,5,6,5,6,6,2,0,0,0,0,0 + dd 6,1,2,6,4,2,3,3,2,5,6,6,4,6,4,0,0,0,0 + dd 0,4,0,2,0,0,4,5,1,1,4,5,0,1,5,0,0,0,0 + dd 1,3,5,0,2,4,2,3,0,6,2,2,6,6,5,0,0,0,0 + dd 0,1,4,3,2,2,1,1,1,0,4,5,5,0,6,2,1,448,0 + dd 2,2,3,5,4,4,5,4,5,3,2,1,2,2,1,0,0,0,0 + dd 2,1,3,2,4,5,6,3,2,6,0,2,2,3,5,0,0,0,0 + dd 3,0,0,5,0,2,0,6,4,4,0,1,1,3,4,3,1,1092,0 + dd 2,3,6,0,0,2,2,0,6,6,3,5,6,4,0,0,0,0,0 + dd 4,2,5,3,0,5,5,5,0,2,4,2,4,2,4,5,1,224,0 + dd 3,4,5,5,0,3,3,3,0,4,4,4,1,4,2,3,1,224,0 + dd 5,1,3,3,1,0,6,3,3,3,2,4,5,3,4,6,2,9096,0 + dd 1,2,0,2,0,5,1,5,6,6,1,6,4,0,2,0,0,0,0 + dd 4,0,6,4,4,6,1,5,0,6,1,2,3,6,0,0,0,0,0 + dd 3,6,1,2,4,5,6,6,1,5,0,0,3,3,4,0,0,0,0 + dd 1,4,2,4,4,5,2,2,6,2,5,2,2,2,1,4,2,14468,0 + dd 6,3,2,0,6,1,3,1,6,1,6,1,4,0,2,0,0,0,0 + dd 4,2,6,3,2,6,5,1,0,0,6,5,0,4,4,0,0,0,0 + dd 2,2,5,1,2,6,3,0,0,1,1,1,0,3,4,0,0,0,0 + dd 4,5,0,2,2,0,5,6,4,2,0,5,6,6,4,5,1,2114,0 + dd 3,5,4,6,1,6,0,2,6,0,3,0,0,5,0,0,0,0,0 + dd 3,0,6,0,1,2,3,2,1,0,5,2,4,6,3,0,0,0,0 + dd 6,3,1,4,6,4,0,4,6,0,2,4,6,0,3,12,2,6552,0 + dd 1,6,0,1,1,5,1,2,1,0,0,2,1,1,6,10,2,12633,0 + dd 1,0,4,5,6,0,3,0,2,6,3,3,4,0,0,3,1,8322,0 + dd 6,0,2,6,0,5,5,3,1,2,1,0,2,4,0,0,0,0,0 + dd 1,6,0,4,5,6,2,3,0,3,2,6,5,4,0,3,1,16644,0 + dd 0,2,4,5,3,3,2,0,5,3,5,3,0,2,6,0,0,0,0 + dd 6,6,2,2,1,3,3,5,5,2,4,4,3,4,2,0,0,0,0 + dd 6,2,2,5,2,2,6,2,0,1,4,3,6,5,3,7,1,4161,0 + dd 3,2,2,2,0,4,0,1,0,3,5,4,3,4,4,2,1,14,0 + dd 3,2,6,2,1,4,4,0,1,4,1,1,2,6,6,0,0,0,0 + dd 2,2,5,6,3,0,3,1,1,1,1,2,4,4,3,2,1,896,0 + dd 6,0,0,0,2,4,4,1,5,4,3,6,5,1,2,3,1,14,0 + dd 2,2,4,3,6,0,3,4,0,5,1,3,4,5,1,5,1,4228,0 + dd 6,0,1,2,0,2,2,0,5,2,2,6,5,6,5,0,0,0,0 + dd 6,2,6,5,5,6,6,3,4,4,6,4,5,0,6,14,2,1125,0 + dd 3,6,6,4,2,1,5,3,5,5,4,0,5,1,2,0,0,0,0 + dd 1,4,2,0,2,2,4,1,1,4,6,0,6,2,0,0,0,0,0 + dd 2,3,1,3,5,4,4,5,1,6,6,5,5,4,1,2,1,16644,0 + dd 6,6,5,6,6,6,2,6,2,6,0,3,1,4,0,0,0,0,0 + dd 1,4,4,5,2,2,0,6,3,6,6,2,5,2,3,0,0,0,0 + dd 1,1,4,6,5,6,0,6,3,2,4,5,6,2,6,0,0,0,0 + dd 4,1,2,2,2,6,1,3,1,2,6,5,4,3,4,2,1,28,0 + dd 0,2,5,4,3,6,5,5,4,3,5,1,1,3,4,5,1,1092,0 + dd 2,0,3,1,0,5,0,1,2,2,4,1,4,5,4,2,1,2184,0 + dd 2,5,3,0,4,2,2,1,2,6,1,2,4,1,1,0,0,0,0 + dd 6,1,4,6,5,5,0,6,3,5,0,5,3,6,4,0,0,0,0 + dd 1,1,2,5,5,5,1,3,1,2,3,5,1,2,2,2,1,4161,0 + dd 6,4,1,0,6,4,5,1,6,0,0,6,6,2,5,7,1,4368,0 + dd 0,2,6,1,2,5,4,5,5,3,4,2,4,2,5,0,0,0,0 + dd 5,3,0,6,3,0,2,4,6,4,2,4,6,4,3,0,0,0,0 + dd 4,0,6,6,0,1,5,5,5,1,5,6,6,6,0,12,2,14784,0 + dd 4,4,0,3,3,2,1,0,6,1,1,4,5,5,6,0,0,0,0 + dd 4,3,3,5,6,1,4,5,3,5,3,5,6,5,4,5,1,2184,0 + dd 5,3,2,2,1,0,3,5,5,5,5,4,0,6,1,5,1,896,0 + dd 6,3,5,3,4,0,0,0,1,3,3,2,4,3,6,3,1,224,0 + dd 0,6,1,1,4,1,4,3,2,1,4,3,4,3,4,0,0,0,0 + dd 3,4,6,6,6,1,2,3,1,2,5,0,2,1,5,7,1,28,0 + dd 2,2,1,5,5,2,2,3,3,1,0,6,6,6,5,7,1,14336,0 + dd 2,2,1,6,5,5,4,4,5,6,5,5,6,4,4,0,0,0,0 + dd 5,4,1,6,5,0,0,2,0,5,2,3,3,4,4,0,0,0,0 + dd 3,2,2,2,0,0,4,0,5,3,2,1,1,6,6,2,1,14,0 + dd 3,4,1,4,6,5,2,2,6,5,5,6,4,0,5,0,0,0,0 + dd 6,6,2,4,0,1,3,1,6,5,4,3,2,6,2,0,0,0,0 + dd 0,6,0,5,1,6,5,2,0,2,2,5,6,0,4,0,0,0,0 + dd 6,5,5,4,5,4,0,5,5,5,1,0,0,6,0,5,1,896,0 + dd 2,3,0,1,6,4,0,0,1,0,1,1,0,5,5,3,1,4228,0 + dd 5,5,3,6,3,5,5,3,0,5,6,4,0,0,1,0,0,0,0 + dd 4,2,2,0,5,2,3,6,3,3,4,3,3,2,1,0,0,0,0 + dd 0,0,0,0,2,0,4,1,1,2,2,3,4,4,6,6,1,15,0 + dd 6,1,0,3,0,2,3,6,1,5,5,0,2,2,3,0,0,0,0 + dd 3,6,5,3,6,4,6,6,5,4,6,1,6,1,4,0,0,0,0 + dd 0,2,3,2,5,5,1,2,1,5,4,3,5,0,1,0,0,0,0 + dd 4,0,2,5,3,6,3,3,6,4,3,3,0,4,5,0,0,0,0 + dd 2,1,3,1,0,5,3,4,2,0,1,3,3,5,5,0,0,0,0 + dd 1,2,1,6,2,5,0,2,2,0,0,5,5,1,3,0,0,0,0 + dd 2,3,2,0,3,3,3,2,1,0,6,5,4,2,6,0,0,0,0 + dd 3,0,1,6,6,5,4,0,4,2,0,4,2,6,4,0,0,0,0 + dd 4,6,5,6,6,0,1,2,1,1,2,1,1,2,0,0,0,0,0 + dd 2,2,4,6,5,4,6,5,6,5,3,1,2,6,6,7,1,8456,0 + dd 2,1,1,3,1,0,3,5,6,6,0,3,4,2,6,0,0,0,0 + dd 0,0,5,2,4,2,3,4,2,5,3,2,6,5,4,0,0,0,0 + dd 1,5,1,0,5,3,1,0,3,0,2,6,2,1,6,0,0,0,0 + dd 2,1,2,4,2,5,3,0,4,0,2,4,2,1,5,0,0,0,0 + dd 0,4,3,6,0,3,2,3,5,4,3,6,1,3,3,0,0,0,0 + dd 0,4,2,5,5,0,2,6,4,4,2,1,6,3,5,2,1,1092,0 + dd 3,0,1,1,3,1,0,5,0,1,5,1,3,5,0,0,0,0,0 + dd 6,0,0,1,6,1,5,1,6,3,4,0,0,6,5,0,0,0,0 + dd 6,0,6,6,1,0,0,5,6,6,2,0,4,6,0,10,2,10570,0 + dd 3,6,5,1,3,3,5,6,0,6,6,6,6,1,6,7,1,7168,0 + dd 3,5,2,4,3,0,3,1,5,0,0,3,2,5,3,0,0,0,0 + dd 0,4,2,4,2,3,3,1,4,4,0,1,6,2,3,0,0,0,0 + dd 6,6,6,4,4,6,3,0,4,6,2,5,4,6,2,12,2,4375,0 + dd 2,6,1,4,5,1,0,3,6,6,2,2,0,3,3,0,0,0,0 + dd 0,5,4,1,0,0,5,2,4,4,2,0,0,0,6,3,1,14336,0 + dd 2,1,6,3,2,4,6,2,6,5,1,0,6,6,3,0,0,0,0 + dd 2,2,3,0,1,2,0,6,6,3,3,0,2,4,2,0,0,0,0 + dd 0,3,1,3,0,3,4,4,4,4,6,3,6,4,1,10,1,960,0 + dd 1,6,2,4,4,4,2,2,1,5,1,3,2,0,1,2,1,4228,0 + dd 4,4,3,3,4,5,6,5,0,6,2,2,2,6,0,2,1,7168,0 + dd 2,4,4,3,6,2,4,4,5,3,6,4,3,5,2,5,1,2114,0 + dd 0,6,6,5,1,2,3,5,5,3,1,6,6,2,5,0,0,0,0 + dd 3,4,2,2,6,2,5,0,1,3,6,3,2,1,0,0,0,0,0 + dd 5,0,3,2,2,0,0,2,2,5,2,3,3,1,0,0,0,0,0 + dd 4,1,1,3,2,1,5,6,3,5,1,2,1,4,6,0,0,0,0 + dd 5,6,2,5,4,5,6,3,1,2,6,4,2,2,2,2,1,28672,0 + dd 5,6,4,1,6,1,3,0,6,5,3,3,3,1,1,3,1,7168,0 + dd 3,6,6,6,2,4,0,1,3,3,6,2,3,2,2,7,1,14,0 + dd 2,0,0,1,6,6,3,2,0,1,0,1,3,0,3,0,0,0,0 + dd 4,1,2,1,1,6,4,3,1,5,2,3,0,5,0,0,0,0,0 + dd 0,1,0,0,1,0,1,1,5,3,1,2,0,1,2,2,1,8322,0 + dd 3,6,4,5,5,6,4,6,0,3,6,5,4,6,6,7,1,8322,0 + dd 5,5,4,1,4,3,2,5,0,1,5,1,6,0,6,0,0,0,0 + dd 2,1,5,2,6,1,0,5,6,6,5,6,6,2,4,7,1,4368,0 + dd 0,1,3,3,3,5,1,2,2,1,0,2,0,1,5,3,1,28,0 + dd 2,4,2,3,3,0,6,3,0,2,6,5,6,6,3,0,0,0,0 + dd 5,5,6,6,1,0,0,4,0,6,4,1,2,2,5,0,0,0,0 + dd 4,4,4,0,6,3,1,6,1,1,4,2,3,5,6,5,1,7,0 + dd 4,6,6,4,1,4,6,0,3,1,0,6,2,3,2,7,1,2114,0 + dd 2,4,6,2,2,5,2,0,5,1,0,5,5,3,4,0,0,0,0 + dd 0,5,1,0,4,1,0,3,0,3,0,4,1,5,6,0,0,0,0 + dd 5,6,4,1,6,6,6,3,4,5,3,3,1,1,3,0,0,0,0 + dd 2,1,1,6,3,1,3,6,2,4,4,3,1,4,2,0,0,0,0 + dd 3,2,0,3,1,5,0,4,3,4,2,5,0,4,3,0,0,0,0 + dd 1,3,1,1,6,0,5,0,0,1,2,2,2,0,0,2,1,7168,0 + dd 4,2,5,5,2,4,2,6,6,2,5,4,6,2,5,0,0,0,0 + dd 2,2,6,1,2,3,5,6,6,3,6,0,6,1,2,7,1,4228,0 + dd 0,2,3,1,6,4,2,1,4,3,3,0,3,2,1,0,0,0,0 + dd 5,0,6,3,4,3,6,3,4,4,5,6,5,4,0,0,0,0,0 + dd 2,0,6,6,3,6,5,6,0,2,6,6,5,1,5,7,1,2184,0 + dd 0,4,3,4,4,5,4,1,0,3,6,0,0,5,6,0,0,0,0 + dd 5,6,1,2,3,4,1,3,1,4,2,2,0,5,0,0,0,0,0 + dd 6,1,4,1,3,5,6,6,4,6,2,5,4,3,1,0,0,0,0 + dd 2,1,3,0,5,2,3,1,2,4,2,3,2,2,6,2,1,1057,0 + dd 5,4,1,3,4,1,6,2,0,5,3,5,2,3,5,0,0,0,0 + dd 0,5,5,4,5,4,4,5,4,4,4,2,3,0,6,0,0,0,0 + dd 1,0,1,1,3,1,4,6,3,3,4,3,3,1,0,3,1,4368,0 + dd 3,5,5,6,1,5,1,5,6,5,2,0,0,4,1,0,0,0,0 + dd 4,3,4,5,2,2,2,1,4,2,5,0,5,2,3,0,0,0,0 + dd 1,1,6,4,6,1,1,3,2,2,3,0,4,2,0,0,0,0,0 + dd 1,1,1,6,2,1,1,3,3,3,5,6,5,0,2,5,2,903,0 + dd 5,0,0,4,6,6,3,5,6,3,1,6,6,2,1,7,1,4368,0 + dd 0,4,0,3,4,2,4,5,0,1,0,4,6,2,6,5,1,2114,0 + dd 5,6,2,6,6,2,6,3,5,2,2,5,3,2,3,0,0,0,0 + dd 5,0,5,0,3,3,1,1,4,4,5,0,6,5,5,0,0,0,0 + dd 4,4,1,3,0,4,6,2,4,3,3,1,1,4,3,0,0,0,0 + dd 5,2,3,3,3,3,5,4,3,4,4,3,3,5,4,6,2,4380,0 + dd 4,2,1,4,0,2,2,0,5,3,4,6,5,2,3,0,0,0,0 + dd 1,2,1,5,4,3,2,1,5,3,1,0,4,3,2,0,0,0,0 + dd 4,1,4,6,3,4,3,1,0,2,5,4,6,5,1,0,0,0,0 + dd 4,0,3,6,2,3,6,0,3,5,0,3,2,0,2,3,1,8322,0 + dd 6,1,2,3,4,2,4,4,1,1,0,2,2,2,4,2,1,14336,0 + dd 6,6,3,0,6,5,2,5,4,5,1,6,5,4,6,0,0,0,0 + dd 5,1,0,1,2,4,0,4,5,4,2,5,3,0,3,0,0,0,0 + dd 5,3,2,2,1,1,3,6,0,6,0,2,3,2,4,0,0,0,0 + dd 5,1,1,6,5,6,6,6,6,4,3,1,4,4,2,14,1,480,0 + dd 0,1,5,6,3,0,6,1,4,4,2,5,1,5,2,0,0,0,0 + dd 4,5,3,2,1,5,0,4,0,5,0,4,4,5,2,0,0,0,0 + dd 4,6,1,1,4,5,4,4,5,6,6,0,6,3,5,0,0,0,0 + dd 2,5,5,6,5,1,0,0,4,3,3,5,6,5,4,0,0,0,0 + dd 5,0,2,2,4,4,1,6,0,0,1,0,5,5,2,0,0,0,0 + dd 1,0,5,6,6,0,0,5,1,3,6,1,2,3,4,0,0,0,0 + dd 5,6,3,2,1,2,1,0,0,2,6,2,2,6,5,0,0,0,0 + dd 0,5,5,5,5,6,2,0,1,1,4,5,0,5,5,10,1,30,0 + dd 3,5,6,1,4,4,1,4,3,0,5,5,1,1,6,0,0,0,0 + dd 6,1,2,4,1,4,6,1,1,0,6,2,0,6,2,0,0,0,0 + dd 1,2,5,2,3,6,1,1,3,0,3,0,3,3,1,3,1,4368,0 + dd 0,6,5,6,3,6,0,5,2,0,0,2,2,5,4,0,0,0,0 + dd 2,5,4,4,3,0,6,5,6,0,0,2,6,6,0,0,0,0,0 + dd 6,4,1,0,1,1,1,3,2,6,2,1,2,2,6,0,0,0,0 + dd 5,0,1,5,6,4,0,6,4,1,0,3,2,3,0,0,0,0,0 + dd 2,6,4,6,1,0,0,3,5,5,5,5,4,5,5,0,0,0,0 + dd 0,2,6,4,3,5,1,6,3,0,3,1,5,5,6,0,0,0,0 + dd 5,0,1,2,1,3,3,4,6,6,5,2,6,6,2,0,0,0,0 + dd 1,3,3,5,4,3,4,5,4,2,0,3,6,4,2,0,0,0,0 + dd 5,6,6,6,5,2,0,5,6,5,5,2,0,1,3,7,1,14,0 + dd 0,0,5,6,5,6,5,4,0,2,3,1,0,6,1,0,0,0,0 + dd 6,3,3,2,3,0,5,2,0,1,2,4,6,3,1,0,0,0,0 + dd 6,3,2,4,4,4,4,2,1,2,1,1,3,6,1,0,0,0,0 + dd 4,4,1,5,3,1,4,6,4,2,2,2,4,2,1,5,1,4161,0 + dd 6,2,0,5,6,2,5,6,4,2,5,0,0,4,2,0,0,0,0 + dd 6,5,3,1,5,2,3,4,5,5,1,0,0,1,6,0,0,0,0 + dd 4,3,6,3,5,3,4,5,2,4,0,5,1,0,1,0,0,0,0 + dd 1,1,4,6,3,6,5,2,0,0,0,5,0,6,5,0,0,0,0 + dd 0,6,0,4,6,6,5,5,0,4,1,6,3,4,2,0,0,0,0 + dd 1,6,0,1,5,5,3,6,5,3,0,1,6,4,3,0,0,0,0 + dd 4,1,5,6,5,4,4,5,6,2,3,1,6,3,6,0,0,0,0 + dd 1,3,1,0,6,3,0,4,5,4,0,3,6,6,3,0,0,0,0 + dd 0,6,3,5,3,2,6,2,1,2,5,2,3,4,4,0,0,0,0 +.code diff --git a/tools/tests/clover_test.inc b/tools/tests/clover_test.inc new file mode 100644 index 0000000..a293ed9 --- /dev/null +++ b/tools/tests/clover_test.inc @@ -0,0 +1,273 @@ +include tools\tests\clover_fixtures.inc +.data +clpTestStage3D dd 0 +clpTestReady db "build\actions\clover-ready.bmp",0 +clpTestSpin db "build\actions\clover-spin.bmp",0 +clpTestStopped db "build\actions\clover-stopped.bmp",0 +clpTestWin db "build\actions\clover-win.bmp",0 +clpTestNext db "build\actions\clover-next.bmp",0 +clpTestPay db "build\actions\clover-paytable.bmp",0 +.code +RunCloverTest3D PROC uses ebx esi edi + local oldBank:DWORD,oldMode:DWORD,oldSeed:DWORD,iterations:DWORD + local fixture:DWORD,expected:DWORD,rngSnapshot:DWORD,previous:DWORD,ticks:DWORD + mov eax,bankroll + mov oldBank,eax + mov eax,engineMode + mov oldMode,eax + mov eax,rngSeed3D + mov oldSeed,eax + mov clpTestStage3D,1 + mov engineMode,MODE_WALK + mov interactTargetId,INTERACT_SLOTS_CLOVER + call Trigger3DInteraction + cmp engineMode,MODE_CLOVER + jne clp_test_fail + call TableBusy3D + test eax,eax + jnz clp_test_fail + call RenderNativeClover3D + invoke WriteActionSnapshot3D,OFFSET clpTestReady + test eax,eax + jz clp_test_fail + mov clpTestStage3D,2 + lea ebx,clpFixtures3D + mov iterations,clpFixtureCount3D +clp_test_fixture: + mov fixture,ebx + mov esi,ebx + lea edi,clpGrid3D + mov ecx,15 + rep movsd + call CloverEvaluate3D + mov ebx,fixture + mov eax,[ebx+60] + cmp clpTotal3D,eax + jne clp_test_fail + mov eax,[ebx+64] + cmp clpCount3D,eax + jne clp_test_fail + mov eax,[ebx+68] + cmp clpWinMask3D,eax + jne clp_test_fail + mov eax,[ebx+72] + cmp clpJackpot3D,eax + jne clp_test_fail + xor esi,esi + xor edi,edi +clp_test_combo_sum: + cmp esi,clpCount3D + jae @F + add edi,clpMults3D[esi*4] + mov eax,clpMasks3D[esi*4] + test eax,eax + jz clp_test_fail + and eax,clpWinMask3D + cmp eax,clpMasks3D[esi*4] + jne clp_test_fail + inc esi + jmp clp_test_combo_sum +@@: + cmp edi,clpTotal3D + jne clp_test_fail + add ebx,76 + dec iterations + jnz clp_test_fixture + mov clpGrid3D,7 + call CloverEvaluate3D + cmp clpTotal3D,0 + jne clp_test_fail + cmp clpCount3D,0 + jne clp_test_fail + mov clpGrid3D,0 + mov clpTestStage3D,3 + mov clpBet3D,50 + mov bankroll,49 + mov clpState3D,SLOT_READY + mov eax,rngSeed3D + mov rngSnapshot,eax + call StartNativeClover3D + cmp bankroll,49 + jne clp_test_fail + mov eax,rngSnapshot + cmp rngSeed3D,eax + jne clp_test_fail + mov iterations,500 +clp_test_round: + call ClearKeys3D + mov engineMode,MODE_CLOVER + mov clpState3D,SLOT_READY + mov clpBet3D,100 + mov bankroll,100000 + call StartNativeClover3D + cmp bankroll,99900 + jne clp_test_fail + cmp clpState3D,SLOT_SPIN + jne clp_test_fail + mov eax,rngSeed3D + mov rngSnapshot,eax + call CloverEvaluate3D + mov eax,clpTotal3D + imul eax,100 + add eax,99900 + mov expected,eax + mov clpCount3D,0 + mov clpTotal3D,0 + call StartNativeClover3D + cmp bankroll,99900 + jne clp_test_fail + mov eax,iterations + and eax,3 + mov eax,slotsTestRates[eax*4] + mov deltaTime3D,eax + mov ticks,0 + ; Queue exit for half the rounds, without cancelling or repaying. + test iterations,1 + jz @F + call CardTableEscape3D +@@: +clp_test_round_tick: + mov pressedKeys3D[57h],1 + mov pressedKeys3D[20h],1 + call HandleNativeClover3D + call ClearKeys3D + cmp clpBet3D,100 + jne clp_test_fail + mov eax,rngSnapshot + cmp rngSeed3D,eax + jne clp_test_fail + inc ticks + cmp ticks,220 + ja clp_test_fail + cmp clpState3D,SLOT_SPIN + je clp_test_round_tick + mov eax,expected + cmp bankroll,eax + jne clp_test_fail + call SettleNativeClover3D + mov eax,expected + cmp bankroll,eax + jne clp_test_fail + test iterations,1 + jz @F + cmp engineMode,MODE_WALK + jne clp_test_fail +@@: + xor esi,esi +clp_test_final_column: + mov ebx,esi + shl ebx,8 + mov ecx,clpSteps3D[esi*4] + lea ebx,clpTape3D[ebx+ecx*4] + xor edi,edi +clp_test_final_row: + mov ecx,edi + imul ecx,5 + add ecx,esi + mov eax,[ebx+edi*4] + cmp eax,clpGrid3D[ecx*4] + jne clp_test_fail + inc edi + cmp edi,3 + jb clp_test_final_row + inc esi + cmp esi,5 + jb clp_test_final_column + dec iterations + jnz clp_test_round + mov clpTestStage3D,4 + mov clpState3D,SLOT_SPIN + xor esi,esi +clp_test_monotonic_column: + mov clpTimer3D,0 + mov previous,0 +clp_test_monotonic_tick: + invoke CloverReelPosition3D,esi + cmp eax,previous + jb clp_test_fail + mov previous,eax + inc clpTimer3D + cmp clpTimer3D,3400 + jbe clp_test_monotonic_tick + mov eax,clpSteps3D[esi*4] + imul eax,CLP_CELL + cmp eax,previous + jne clp_test_fail + inc esi + cmp esi,5 + jb clp_test_monotonic_column + mov clpTestStage3D,5 + mov clpState3D,SLOT_READY + mov bankroll,100000 + call StartNativeClover3D + mov clpTimer3D,900 + mov eax,rngSeed3D + mov rngSnapshot,eax + call RenderNativeClover3D + mov eax,rngSnapshot + cmp rngSeed3D,eax + jne clp_test_fail + cmp bankroll,99900 + jne clp_test_fail + invoke WriteActionSnapshot3D,OFFSET clpTestSpin + mov clpTimer3D,2200 + call RenderNativeClover3D + invoke WriteActionSnapshot3D,OFFSET clpTestStopped + ; Force an all-seven jackpot and inspect distinct paid masks. + lea edi,clpGrid3D + mov eax,6 + mov ecx,15 + rep stosd + mov clpLeave3D,0 + mov engineMode,MODE_CLOVER + call SettleNativeClover3D + cmp clpJackpot3D,1 + jne clp_test_fail + cmp clpCount3D,2 + jb clp_test_fail + call RenderNativeClover3D + invoke WriteActionSnapshot3D,OFFSET clpTestWin + mov pressedKeys3D[27h],1 + call HandleNativeClover3D + cmp clpSelected3D,1 + jne clp_test_fail + call RenderNativeClover3D + invoke WriteActionSnapshot3D,OFFSET clpTestNext + mov clpPaytable3D,1 + call RenderNativeClover3D + invoke WriteActionSnapshot3D,OFFSET clpTestPay + call CardTableEscape3D + cmp engineMode,MODE_CLOVER + jne clp_test_fail + cmp clpPaytable3D,0 + jne clp_test_fail + call CardTableEscape3D + cmp engineMode,MODE_WALK + jne clp_test_fail + mov clpTestStage3D,6 + mov clpState3D,SLOT_SPIN + mov clpStake3D,10000 + mov bankroll,999999999 + call SettleNativeClover3D + cmp bankroll,1000000000 + jne clp_test_fail + cmp clpGross3D,1 + jne clp_test_fail + call SettleNativeClover3D + cmp bankroll,1000000000 + jne clp_test_fail + mov eax,oldBank + mov bankroll,eax + mov eax,oldMode + mov engineMode,eax + mov eax,oldSeed + mov rngSeed3D,eax + call ClearKeys3D + call FreeNativeClover3D + xor eax,eax + ret +clp_test_fail: + mov eax,clpTestStage3D + add eax,860 + ret +RunCloverTest3D ENDP diff --git a/tools/tests/hall_test.inc b/tools/tests/hall_test.inc index d56b44a..00ec84a 100644 --- a/tools/tests/hall_test.inc +++ b/tools/tests/hall_test.inc @@ -90,6 +90,8 @@ include tools\tests\world_regression.inc include tools\tests\hall_furniture_test.inc include tools\tests\wheel_scene_test.inc +include tools\tests\npc_life_test.inc + RunHallTest3D PROC uses ebx esi edi local oldBank:DWORD,oldSeed:DWORD,endX:DWORD,endV:DWORD mov eax, bankroll @@ -122,19 +124,12 @@ RunHallTest3D PROC uses ebx esi edi call TestHallSurface3D cmp eax, 1 jne hall_test_fail - ; Sample the entire walking route; every accepted position must stay navigable. + ; Visible people use the same personality positions as the new simulation. mov patronClock3D, 0 mov deltaTime3D, 50 mov ebx, 400 hall_test_patron_route: call UpdatePatrons3D - cmp ebx, 201 - jne @F - cmp hallGuests3D.posX,22*FP_1 - jne hall_test_fail - cmp hallGuests3D.posY,20*FP_1 - jne hall_test_fail -@@: invoke CanWalk3D,hallGuests3D.posX,hallGuests3D.posY cmp eax, 1 jne hall_test_fail @@ -145,10 +140,6 @@ hall_test_patron_route: jnz hall_test_patron_route cmp patronClock3D, 0 jne hall_test_fail - cmp hallGuests3D.posX,18*FP_1 - jne hall_test_fail - cmp hallGuests3D.posY,18*FP_1 - jne hall_test_fail invoke CanWalk3D,4*FP_1,27*FP_1 test eax, eax jnz hall_test_fail @@ -297,7 +288,7 @@ hall_test_two_balls: jb hall_test_two_balls mov poolX3D, 100*FP_1 mov poolY3D, 115*FP_1 - mov poolX3D[4], 105*FP_1+FP_1*4/5 + mov poolX3D[4], 102*FP_1+FP_1*4/5 mov poolY3D[4], 115*FP_1 mov poolVX3D, FP_1 invoke PoolCollide3D,0,1 @@ -324,7 +315,7 @@ hall_test_fast_contact: cmp poolVX3D[4], 0 jle hall_test_fail mov poolActive3D[4], 0 - mov poolX3D, 33*FP_1 + mov poolX3D, 31*FP_1 mov poolVX3D, -30000 call PoolStep3D cmp poolVX3D, 0 @@ -334,7 +325,7 @@ hall_test_fast_contact: mov hallTestStage3D, 75 mov poolActive3D[4], 0 mov poolX3D, 160*FP_1 - mov poolY3D, 52*FP_1 + mov poolY3D, 51*FP_1+FP_1/2 invoke PoolPocketBall3D,0 cmp poolActive3D, 0 jne hall_test_fail @@ -342,8 +333,8 @@ hall_test_fast_contact: jne hall_test_fail ; Near a middle pocket, the jaw must rebound an off-center approach. mov poolActive3D, 1 - mov poolX3D, 145*FP_1 - mov poolY3D, 64*FP_1 + mov poolX3D, 157*FP_1 + mov poolY3D, 52*FP_1 mov poolVX3D, 0 mov poolVY3D, -20000 invoke PoolJawContact3D,0 @@ -397,16 +388,15 @@ hall_test_friction: mov poolRail3D, 1 mov poolActive3D[8*4], 0 mov poolPotted3D, 100h + mov pyrScore3D,7 call PoolFinishShot3D cmp poolState3D, POOL_RESULT jne hall_test_fail - cmp poolWinner3D, 1 + cmp poolWinner3D, 0 jne hall_test_fail call InitPool3D - mov poolGroups3D, 1 - mov poolAtStart3D, 0 mov poolBreak3D, 0 - mov poolFirst3D, 8 + mov poolFirst3D, -1 mov poolRail3D, 1 mov poolActive3D[8*4], 0 mov poolPotted3D, 100h @@ -414,7 +404,12 @@ hall_test_friction: mov poolCalledPocket3D, 0 mov poolPocket3D[8*4], 0 call PoolFinishShot3D - cmp poolWinner3D, 0 + cmp poolState3D,POOL_PENALTY + jne hall_test_fail + cmp poolActive3D[8*4],1 + jne hall_test_fail + invoke PyramidPenalty3D,1 + cmp pyrScore3D[4],1 jne hall_test_fail call InitPool3D call RenderPool3D @@ -431,6 +426,12 @@ hall_test_friction: call RunWorldRegression3D test eax, eax jz hall_test_fail + call RunPyramidTest3D + test eax,eax + jnz hall_test_fail + call RunNpcLifeTest3D + test eax,eax + jnz hall_test_fail mov eax, oldSeed cmp eax, rngSeed3D jne hall_test_fail diff --git a/tools/tests/npc_life_probe.asm b/tools/tests/npc_life_probe.asm new file mode 100644 index 0000000..e343033 --- /dev/null +++ b/tools/tests/npc_life_probe.asm @@ -0,0 +1,20 @@ +.386 +.model flat,stdcall +option casemap:none +include F:\MASM32\masm32\include\windows.inc +include F:\MASM32\masm32\include\kernel32.inc +InitPaths3D PROTO +LoadTextures3D PROTO +InitializeCasinoSprites3D PROTO +LoadHallAssets3D PROTO +RunNpcLifeTest3D PROTO +.code +RunNpcLifeProbe PROC + call InitPaths3D + call LoadTextures3D + call InitializeCasinoSprites3D + call LoadHallAssets3D + call RunNpcLifeTest3D + invoke ExitProcess,eax +RunNpcLifeProbe ENDP +END diff --git a/tools/tests/npc_life_test.inc b/tools/tests/npc_life_test.inc new file mode 100644 index 0000000..4793086 --- /dev/null +++ b/tools/tests/npc_life_test.inc @@ -0,0 +1,227 @@ +.data +npcTestBase1 db "build\arrival\fixtures\npc-one.dat",0 +npcTestBase2 db "build\arrival\fixtures\npc-two.dat",0 +npcTestJournal1 db "build\arrival\fixtures\npc-one.dat.npc",0 +npcTestJournal2 db "build\arrival\fixtures\npc-two.dat.npc",0 +npcTestOpenShot db "build\actions\npc-dialog-open.bmp",0 +npcTestReadyShot db "build\actions\npc-dialog-ready.bmp",0 +npcTestDoneShot db "build\actions\npc-dialog-done.bmp",0 +.code +RunNpcLifeTest3D PROC uses ebx esi edi + local oldBank:DWORD,steps:DWORD,identity:DWORD,firstX:DWORD,firstY:DWORD,claimBank:DWORD + mov eax,bankroll + mov oldBank,eax + mov hallTestStage3D,7901 + call InitHall3D + xor esi,esi +npc_test_destinations: + invoke NpcPlanPath3D,0,esi + cmp eax,1 + jne npc_test_fail + inc esi + cmp esi,NPC_DEST_COUNT + jb npc_test_destinations + mov esi,20 +npc_test_rate: + call InitNpcLife3D + mov playerX,30*FP_1+FP_HALF + mov playerY,30*FP_1+FP_HALF + mov edi,1 +npc_test_rate_clear_crowd: + imul ebx,edi,SIZEOF NpcLife3D + mov npcLife3D[ebx].state,NPC_AWAY + inc edi + cmp edi,NPC_LIFE_COUNT + jb npc_test_rate_clear_crowd + invoke NpcPlanPath3D,0,5 + cmp eax,1 + jne npc_test_fail + mov eax,2000 + xor edx,edx + div esi + mov steps,eax +npc_test_rate_step: + invoke NpcMove3D,0,esi + dec steps + jnz npc_test_rate_step + mov eax,casinoNpcs3D.posX + mov edx,casinoNpcs3D.posY + cmp esi,20 + jne npc_test_rate_compare + mov firstX,eax + mov firstY,edx + mov esi,50 + jmp npc_test_rate +npc_test_rate_compare: + cmp eax,firstX + jne npc_test_fail + cmp edx,firstY + jne npc_test_fail + cmp esi,100 + je npc_test_routes + mov esi,100 + jmp npc_test_rate +npc_test_routes: + mov hallTestStage3D,7902 + call InitNpcLife3D + mov deltaTime3D,50 + mov steps,2400 +npc_test_simulate: + call UpdateNpcLife3D + xor esi,esi +npc_test_person_bounds: + imul ebx,esi,SIZEOF NpcMindEntity + invoke CanWalk3D,casinoNpcs3D[ebx].posX,casinoNpcs3D[ebx].posY + cmp eax,1 + jne npc_test_fail + imul edi,esi,SIZEOF NpcLife3D + cmp npcLife3D[edi].state,NPC_AWAY + ja npc_test_fail + cmp npcLife3D[edi].identity,NPC_IDENTITY_COUNT + jae npc_test_fail + cmp npcLife3D[edi].pathCount,NPC_PATH_CAP + ja npc_test_fail + inc esi + cmp esi,NPC_LIFE_COUNT + jb npc_test_person_bounds + dec steps + jnz npc_test_simulate + cmp npcLifeClock3D,120000 + jne npc_test_fail + mov hallTestStage3D,7903 + invoke DeleteFileA,OFFSET npcTestJournal1 + invoke DeleteFileA,OFFSET npcTestJournal2 + mov npcJournalBasePtr3D,OFFSET npcTestBase1 + mov npcDateOverride3D,20261012 + mov npcJournalLoaded3D,0 + call NpcEnsureJournal3D + cmp eax,1 + jne npc_test_fail + xor esi,esi +npc_test_find_any: + invoke NpcContractType3D,esi + test eax,eax + jz npc_test_accept + inc esi + cmp esi,NPC_IDENTITY_COUNT + jb npc_test_find_any + jmp npc_test_fail +npc_test_accept: + mov identity,esi + invoke NpcRecordRound3D,0,1 + cmp npcProgress3D[esi*4],0 + jne npc_test_fail + invoke NpcAcceptContract3D,esi + cmp eax,1 + jne npc_test_fail + invoke NpcClaimContract3D,esi + test eax,eax + jnz npc_test_fail + ; A real legacy graphical settlement contributes once, including repeat protection. + mov skulls3d_state,3 + mov skulls3d_choice,0 + mov skulls3d_ballPos,0 + mov skulls3d_bet,50 + call FinalizeSkullsGuess + cmp npcProgress3D[esi*4],1 + jne npc_test_fail + mov eax,bankroll + mov claimBank,eax + call FinalizeSkullsGuess + mov eax,claimBank + cmp bankroll,eax + jne npc_test_fail + cmp npcProgress3D[esi*4],1 + jne npc_test_fail + invoke NpcRecordRound3D,1,1 + invoke NpcRecordRound3D,2,0 + invoke NpcRecordRound3D,3,1 + cmp npcProgress3D[esi*4],3 + jne npc_test_fail + invoke NpcClaimContract3D,esi + cmp eax,1 + jne npc_test_fail + mov eax,claimBank + add eax,150 + cmp bankroll,eax + jne npc_test_fail + mov npcJournalLoaded3D,0 + call NpcEnsureJournal3D + invoke NpcClaimContract3D,identity + test eax,eax + jnz npc_test_fail + mov hallTestStage3D,7904 + mov npcJournalBasePtr3D,OFFSET npcTestBase2 + call NpcEnsureJournal3D + cmp npcAccepted3D,0 + jne npc_test_fail + cmp npcClaimed3D,0 + jne npc_test_fail + call InitNpcLife3D + mov playerX,16*FP_1+FP_HALF + mov playerY,18*FP_1+FP_HALF + mov playerAngle,384 + call UpdateCamera3D + mov interactTargetId,0 + call CheckNpcInteractions3D + cmp interactTargetId,INTERACT_NPC + jne npc_test_fail + cmp npcSelected3D,0 + jne npc_test_fail + call TriggerHallInteraction3D + cmp engineMode,MODE_NPC_DIALOG + jne npc_test_fail + call RenderNpcDialog3D + invoke WriteActionSnapshot3D,OFFSET npcTestOpenShot + mov mouseClick3D,1 + mov mouseX3D,60 + mov mouseY3D,175 + call HandleNpcDialog3D + bt npcAccepted3D,0 + jnc npc_test_fail + mov ebx,3 +npc_test_finish_dialog: + xor esi,esi +npc_test_finish_games: + invoke NpcRecordRound3D,esi,1 + inc esi + cmp esi,6 + jb npc_test_finish_games + dec ebx + jnz npc_test_finish_dialog + call RenderNpcDialog3D + invoke WriteActionSnapshot3D,OFFSET npcTestReadyShot + mov mouseClick3D,1 + mov mouseX3D,145 + mov mouseY3D,175 + call HandleNpcDialog3D + bt npcClaimed3D,0 + jnc npc_test_fail + call RenderNpcDialog3D + invoke WriteActionSnapshot3D,OFFSET npcTestDoneShot + call CardTableEscape3D + cmp eax,1 + jne npc_test_fail + cmp engineMode,MODE_WALK + jne npc_test_fail + mov npcDateOverride3D,20261013 + call NpcEnsureJournal3D + cmp npcAccepted3D,0 + jne npc_test_fail + cmp npcClaimed3D,0 + jne npc_test_fail + mov npcAccepted3D,0 + mov npcClaimed3D,0 + mov npcJournalLoaded3D,0 + mov npcDateOverride3D,0 + mov npcJournalBasePtr3D,OFFSET npcJournalTestBase3D + mov deltaTime3D,16 + mov eax,oldBank + mov bankroll,eax + call ClearKeys3D + xor eax,eax + ret +npc_test_fail: + mov eax,hallTestStage3D + ret +RunNpcLifeTest3D ENDP diff --git a/tools/tests/prepare_clover_fixtures.py b/tools/tests/prepare_clover_fixtures.py new file mode 100644 index 0000000..6d4d3d9 --- /dev/null +++ b/tools/tests/prepare_clover_fixtures.py @@ -0,0 +1,55 @@ +"""Independent offline oracle for the original Clover combo contract.""" +from pathlib import Path +from random import Random + +ROOT = Path(__file__).resolve().parents[2] +VALUES = [3, 2, 2, 3, 5, 5, 7] +PATTERNS = [([0, 4, 7, 10, 14], 8), + ([0, 1, 2, 3, 4], 7), ([10, 11, 12, 13, 14], 7), + ([10, 6, 2, 8, 14], 4), ([0, 6, 12, 8, 4], 4)] +PATTERNS += [(list(range(row * 5, row * 5 + 5)), 3) for row in range(3)] +PATTERNS += [(list(range(row * 5 + col, row * 5 + col + 4)), 2) + for row in range(3) for col in range(2)] +PATTERNS += [([col, col + 5, col + 10], 1) for col in range(5)] +PATTERNS += [([0, 6, 12], 1), ([1, 7, 13], 1), ([2, 8, 14], 1), + ([10, 6, 2], 1), ([11, 7, 3], 1), ([12, 8, 4], 1)] +PATTERNS += [(list(range(row * 5 + col, row * 5 + col + 3)), 1) + for row in range(3) for col in range(3)] + + +def evaluate(board): + blocked = win = total = count = 0 + jackpot = int(len(set(board)) == 1) + if jackpot: + total, count, win = VALUES[board[0]] * 10, 1, 32767 + for cells, factor in PATTERNS: + bits = sum(1 << cell for cell in cells) + if len({board[cell] for cell in cells}) != 1 or blocked & bits == bits: + continue + blocked |= bits + win |= bits + total += VALUES[board[cells[0]]] * factor + count += 1 + return total, count, win, jackpot + + +def main(): + rng = Random(5315) + boards = [[symbol] * 15 for symbol in range(7)] + for cells, _ in PATTERNS: + board = [(i * 3 + i // 5) % 7 for i in range(15)] + for cell in cells: + board[cell] = 6 + boards.append(board) + boards += [[rng.randrange(7) for _ in range(15)] for _ in range(512)] + lines = ["; Mechanically generated offline reference vectors.", ".data", + f"clpFixtureCount3D equ {len(boards)}", "clpFixtures3D label DWORD"] + for board in boards: + lines.append(" dd " + ",".join(map(str, [*board, *evaluate(board)]))) + lines.append(".code") + (ROOT / "tools/tests/clover_fixtures.inc").write_text("\n".join(lines) + "\n", encoding="ascii") + print(f"Prepared {len(boards)} independent Clover boards") + + +if __name__ == "__main__": + main() diff --git a/tools/tests/pyramid_syntax_probe.asm b/tools/tests/pyramid_syntax_probe.asm new file mode 100644 index 0000000..4d207ee --- /dev/null +++ b/tools/tests/pyramid_syntax_probe.asm @@ -0,0 +1,37 @@ +; Compile-only probe for the actual MASM billiards modules; not a game runtime. +.386 +.model flat,stdcall +option casemap:none +FP_1 equ 65536 +SCREEN_SIZE equ 640*480 +MODE_WALK equ 0 +AnimPack3D STRUCT + magic dd ? + imageWidth dd ? + height dd ? + frames dd ? + bytes dd ? + pixels dd ? +AnimPack3D ENDS +LoadAnimPack3D PROTO :DWORD,:DWORD +FreeAnimPack3D PROTO :DWORD +DrawAnimSprite3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD +DrawWheelDigit3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD +DrawBox PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD +DrawBoxBorder PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD +DrawCircle PROTO :DWORD,:DWORD,:DWORD,:DWORD +DrawPixel PROTO :DWORD,:DWORD,:DWORD +DrawString8x8 PROTO :DWORD,:DWORD,:DWORD,:DWORD +DrawNumber PROTO :DWORD,:DWORD,:DWORD,:DWORD +Pressed3D PROTO :DWORD +ClearKeys3D PROTO +SaveProgress3D PROTO +WriteActionSnapshot3D PROTO :DWORD +EXTERN bankroll:DWORD,rngSeed3D:DWORD,deltaTime3D:DWORD,engineMode:DWORD +EXTERN tableSin:DWORD,tableCos:DWORD,screenBuffer:DWORD +EXTERN mouseX3D:DWORD,mouseY3D:DWORD,mouseClick3D:DWORD +EXTERN keys3D:BYTE,pressedKeys3D:BYTE,cardExitButton3D:BYTE,unavailableText3D:BYTE +include src_graphics\billiards_data.inc +include src_graphics\billiards.inc +include tools\tests\pyramid_test.inc +END diff --git a/tools/tests/pyramid_test.inc b/tools/tests/pyramid_test.inc new file mode 100644 index 0000000..17674af --- /dev/null +++ b/tools/tests/pyramid_test.inc @@ -0,0 +1,309 @@ +.data +pyrTestStage3D dd 0 +pyrTestRack db "build\actions\pyramid-rack.bmp",0 +pyrTestAim db "build\actions\pyramid-aim.bmp",0 +pyrTestStrike db "build\actions\pyramid-strike.bmp",0 +pyrTestPenalty db "build\actions\pyramid-penalty.bmp",0 +pyrTestChoice db "build\actions\pyramid-choice.bmp",0 +pyrTestWin db "build\actions\pyramid-win.bmp",0 +.code +PyramidTestLedger3D PROC uses ebx esi edi + xor esi,esi + xor ebx,ebx + xor edi,edi +pyr_test_ledger_ball: + cmp poolActive3D[esi*4],1 + jne @F + inc ebx + cmp pyrOwner3D[esi*4],-1 + jne pyr_test_ledger_bad + jmp pyr_test_ledger_next +@@: + cmp pyrOwner3D[esi*4],0 + jl pyr_test_ledger_bad + cmp pyrOwner3D[esi*4],1 + ja pyr_test_ledger_bad + inc edi +pyr_test_ledger_next: + inc esi + cmp esi,16 + jb pyr_test_ledger_ball + add ebx,edi + cmp ebx,16 + jne pyr_test_ledger_bad + mov eax,pyrScore3D + add eax,pyrScore3D[4] + cmp eax,edi + jne pyr_test_ledger_bad + xor eax,eax + ret +pyr_test_ledger_bad: + mov eax,1 + ret +PyramidTestLedger3D ENDP + +RunPyramidTest3D PROC uses ebx esi edi + local oldBank:DWORD,oldSeed:DWORD,oldAI:DWORD,oldMode:DWORD,ticks:DWORD,value:DWORD + mov eax,bankroll + mov oldBank,eax + mov eax,rngSeed3D + mov oldSeed,eax + mov eax,poolAI3D + mov oldAI,eax + mov eax,engineMode + mov oldMode,eax + mov engineMode,MODE_POOL + mov poolAI3D,0 + call ClearKeys3D + mov pyrTestStage3D,1 + call InitPool3D + call PyramidTestLedger3D + test eax,eax + jnz pyr_test_fail + call RenderPool3D + invoke WriteActionSnapshot3D,OFFSET pyrTestRack + ; Old Q8 squares wrapped at 256 pixels and potted a distant ball. + mov poolX3D,286*FP_1 + mov poolY3D,50*FP_1 + invoke PoolPocketBall3D,0 + cmp poolActive3D,1 + jne pyr_test_fail + mov poolX3D,34*FP_1 + mov poolY3D,180*FP_1 + invoke PoolPocketBall3D,0 + cmp poolActive3D,1 + jne pyr_test_fail + mov pyrTestStage3D,2 + call InitPool3D + mov poolBreak3D,0 + invoke PoolAimPoint3D,250*FP_1,115*FP_1+FP_1/2 + test pyrFine3D,7 + jz pyr_test_fail + mov poolX3D[12*4],100*FP_1 + mov poolY3D[12*4],90*FP_1 + mov poolX3D[4],160*FP_1 + mov poolY3D[4],90*FP_1 + invoke PyramidSelect3D,12 + cmp pyrCue3D,12 + jne pyr_test_fail + invoke PoolAimPoint3D,200*FP_1,90*FP_1 + call RenderPool3D + cmp pyrTarget3D,-1 + je pyr_test_fail + invoke WriteActionSnapshot3D,OFFSET pyrTestAim + call PoolShoot3D + cmp poolState3D,POOL_STRIKE + jne pyr_test_fail + mov poolTime3D,120 + call RenderPool3D + invoke WriteActionSnapshot3D,OFFSET pyrTestStrike + mov deltaTime3D,120 + call HandlePool3D + cmp poolVX3D[12*4],0 + jle pyr_test_fail + cmp poolVX3D,0 + jne pyr_test_fail + mov pyrTestStage3D,3 + call InitPool3D + mov poolBreak3D,0 + mov poolFirst3D,1 + mov poolActive3D,0 + mov poolPocket3D,1 + mov poolPotted3D,1 + call PoolFinishShot3D + cmp poolFoul3D,0 + jne pyr_test_fail + cmp pyrScore3D,1 + jne pyr_test_fail + cmp poolPlayer3D,0 + jne pyr_test_fail + cmp pyrCue3D,0 + je pyr_test_fail + call PoolFinishShot3D + cmp pyrScore3D,1 + jne pyr_test_fail + call PyramidTestLedger3D + test eax,eax + jnz pyr_test_fail + mov pyrTestStage3D,4 + call InitPool3D + mov poolBreak3D,0 + mov poolFirst3D,-1 + mov poolActive3D[3*4],0 + mov poolActive3D[9*4],0 + mov poolPotted3D,208h + call PoolFinishShot3D + cmp poolState3D,POOL_PENALTY + jne pyr_test_fail + cmp poolActive3D[3*4],1 + jne pyr_test_fail + cmp poolActive3D[9*4],1 + jne pyr_test_fail + cmp poolPlayer3D,1 + jne pyr_test_fail + call RenderPool3D + invoke WriteActionSnapshot3D,OFFSET pyrTestPenalty + invoke PyramidPenalty3D,4 + invoke PyramidPenalty3D,5 + cmp pyrScore3D[4],1 + jne pyr_test_fail + cmp poolActive3D[5*4],1 + jne pyr_test_fail + call RenderPool3D + invoke WriteActionSnapshot3D,OFFSET pyrTestChoice + invoke PyramidChoice3D,1 + cmp poolPlayer3D,0 + jne pyr_test_fail + call PyramidTestLedger3D + test eax,eax + jnz pyr_test_fail + ; Invalid break has partial-rack choices; the penalty is not erased. + call InitPool3D + mov poolFirst3D,1 + mov poolBreakRails3D,6 + call PoolFinishShot3D + cmp pyrIllegalBreak3D,1 + jne pyr_test_fail + invoke PyramidPenalty3D,0 + invoke PyramidChoice3D,2 + cmp poolBreak3D,1 + jne pyr_test_fail + cmp poolActive3D,1 + jne pyr_test_fail + cmp pyrScore3D[4],1 + jne pyr_test_fail + call PyramidTestLedger3D + test eax,eax + jnz pyr_test_fail + mov pyrTestStage3D,5 + ; Three object cushions, or two plus an object crossing, is a legal break. + call InitPool3D + mov poolFirst3D,1 + mov poolBreakRails3D,0Eh + call PoolFinishShot3D + cmp poolFoul3D,0 + jne pyr_test_fail + call InitPool3D + mov poolFirst3D,1 + mov poolBreakRails3D,6 + mov pyrHistoryCross3D[4],1 + call PoolFinishShot3D + cmp poolFoul3D,0 + jne pyr_test_fail + mov pyrTestStage3D,6 + ; Legal completion needs ordered events along the same transfer chain. + call InitPool3D + mov poolBreak3D,0 + mov poolFirst3D,1 + invoke PyramidRail3D,1,0 + invoke PyramidRail3D,1,0 + cmp pyrValidEnd3D,0 + jne pyr_test_fail + invoke PyramidRail3D,1,1 + cmp pyrValidEnd3D,1 + jne pyr_test_fail + call InitPool3D + mov poolFirst3D,1 + mov pyrPreviousX3D[4],159*FP_1 + mov poolX3D[4],161*FP_1 + invoke PyramidCross3D,1 + invoke PyramidRail3D,2,0 + cmp pyrValidEnd3D,0 + jne pyr_test_fail + invoke PyramidRail3D,1,0 + cmp pyrValidEnd3D,1 + jne pyr_test_fail + call InitPool3D + mov poolFirst3D,1 + invoke PyramidRail3D,1,0 + mov pyrPreviousX3D[4],159*FP_1 + mov poolX3D[4],161*FP_1 + invoke PyramidCross3D,1 + cmp pyrValidEnd3D,1 + jne pyr_test_fail + call InitPool3D + mov poolFirst3D,1 + invoke PyramidRail3D,1,0 + mov poolX3D[4],80*FP_1 + mov poolX3D[8],90*FP_1 + invoke PyramidContact3D,1,2 + invoke PyramidRail3D,2,1 + cmp pyrValidEnd3D,1 + jne pyr_test_fail + mov pyrTestStage3D,7 + ; The real bot must pot through geometry, not inject a pocket result. + call InitPool3D + mov poolBreak3D,0 + mov poolPlayer3D,1 + mov poolAI3D,0 + mov esi,2 +pyr_test_ai_clear: + mov poolActive3D[esi*4],0 + inc esi + cmp esi,16 + jb pyr_test_ai_clear + mov poolX3D,160*FP_1 + mov poolY3D,115*FP_1 + mov poolX3D[4],160*FP_1 + mov poolY3D[4],70*FP_1 + call PoolChooseAI3D + cmp pyrCue3D,0 + jne pyr_test_fail + call PoolShoot3D + mov deltaTime3D,240 + call HandlePool3D + mov deltaTime3D,16 + mov ticks,0 +pyr_test_ai_tick: + call HandlePool3D + inc ticks + cmp ticks,1000 + ja pyr_test_fail + cmp poolState3D,POOL_MOVING + je pyr_test_ai_tick + cmp pyrScore3D[4],1 + jb pyr_test_fail + cmp poolPocket3D[4],1 + jne pyr_test_fail + mov pyrTestStage3D,8 + call InitPool3D + mov poolBreak3D,0 + mov poolFirst3D,9 + mov poolPotted3D,01FEh + mov esi,1 +pyr_test_winning_balls: + mov poolActive3D[esi*4],0 + mov poolPocket3D[esi*4],1 + inc esi + cmp esi,9 + jb pyr_test_winning_balls + call PoolFinishShot3D + cmp pyrScore3D,8 + jne pyr_test_fail + cmp poolWinner3D,0 + jne pyr_test_fail + cmp poolState3D,POOL_RESULT + jne pyr_test_fail + call PyramidTestLedger3D + test eax,eax + jnz pyr_test_fail + call RenderPool3D + invoke WriteActionSnapshot3D,OFFSET pyrTestWin + mov eax,oldBank + cmp bankroll,eax + jne pyr_test_fail + mov eax,oldSeed + cmp rngSeed3D,eax + jne pyr_test_fail + mov eax,oldAI + mov poolAI3D,eax + mov eax,oldMode + mov engineMode,eax + call ClearKeys3D + xor eax,eax + ret +pyr_test_fail: + mov eax,pyrTestStage3D + add eax,920 + ret +RunPyramidTest3D ENDP diff --git a/tools/tests/russian_party_probe.asm b/tools/tests/russian_party_probe.asm new file mode 100644 index 0000000..1706335 --- /dev/null +++ b/tools/tests/russian_party_probe.asm @@ -0,0 +1,22 @@ +.386 +.model flat,stdcall +option casemap:none +include F:\MASM32\masm32\include\windows.inc +include F:\MASM32\masm32\include\kernel32.inc +InitPaths3D PROTO +LoadTextures3D PROTO +InitializeCasinoSprites3D PROTO +LoadArrivalAssets3D PROTO +InitHall3D PROTO +RunRRPartyTest3D PROTO +.code +RunRRPartyProbe PROC + call InitPaths3D + call LoadTextures3D + call InitializeCasinoSprites3D + call LoadArrivalAssets3D + call InitHall3D + call RunRRPartyTest3D + invoke ExitProcess,eax +RunRRPartyProbe ENDP +END diff --git a/tools/tests/russian_party_test.inc b/tools/tests/russian_party_test.inc new file mode 100644 index 0000000..7026cf6 --- /dev/null +++ b/tools/tests/russian_party_test.inc @@ -0,0 +1,321 @@ +.data +rrPartyShotReady db "build\actions\rr-party-ready.bmp",0 +rrPartyShotTurn db "build\actions\rr-party-turn.bmp",0 +rrPartyShotOut db "build\actions\rr-party-out.bmp",0 +rrPartyShotWin db "build\actions\rr-party-win.bmp",0 +rrPartyShotExit db "build\actions\rr-party-exit.bmp",0 +.code +RunRRPartyTest3D PROC uses ebx esi edi + local rounds:DWORD,ticks:DWORD,bank:DWORD,savedSeed:DWORD,savedMask:DWORD,savedAlive:DWORD,phase:DWORD + mov engineMode,MODE_RUSSIAN + call InitRussianGame3D + test eax,eax + jz rr_party_test_art_fail + cmp rrPartyArt3D.pixels,0 + je rr_party_test_art_fail + mov rr3d_bet,50 + mov rr3d_bullets,1 + mov bankroll,10000 + mov mouseClick3D,1 + mov mouseX3D,230 + mov mouseY3D,232 + call RRPartyInput3D + cmp rrPartyCount3D,3 + jne rr_party_test_input_fail + cmp mouseClick3D,0 + jne rr_party_test_input_fail + call RenderRussianGame3D + invoke WriteActionSnapshot3D,OFFSET rrPartyShotReady + mov rr3d_bullets,2 + call StartRussianRound3D + cmp rrPartyAlive3D,15 + jne rr_party_test_rules_fail + cmp rrPartySize3D,4 + jne rr_party_test_rules_fail + cmp rrPartyStake3D,50 + jne rr_party_test_money_fail + cmp rrPartyReloads3D,1 + jne rr_party_test_rules_fail + cmp bankroll,9950 + jne rr_party_test_money_fail + invoke RRPartySetCount3D,2 + cmp rrPartyCount3D,3 + jne rr_party_test_input_fail + ; Elimination removes one seat and consumes one round, not the entire match. + mov rr3d_turn,2 + mov rr3d_chamber,0 + mov rr3d_mask,5 + mov rr3d_shot,1 + mov rr3d_state,RR_FIRE + call AdvanceRussianScene3D + cmp rrPartyAlive3D,11 + jne rr_party_test_rules_fail + cmp rr3d_mask,4 + jne rr_party_test_rules_fail + cmp rr3d_state,RR_DRY + jne rr_party_test_rules_fail + cmp bankroll,9950 + jne rr_party_test_money_fail + mov rr3d_timer,350 + call RenderRussianGame3D + invoke WriteActionSnapshot3D,OFFSET rrPartyShotOut + call AdvanceRussianScene3D + cmp rr3d_turn,3 + jne rr_party_test_rules_fail + cmp rr3d_chamber,1 + jne rr_party_test_rules_fail + cmp rr3d_mask,4 + jne rr_party_test_rules_fail + ; The cursor wraps and skips a previously eliminated seat. + mov rr3d_turn,1 + mov rr3d_state,RR_DRY + call AdvanceRussianScene3D + cmp rr3d_turn,3 + jne rr_party_test_rules_fail + ; Consuming the last loaded round reloads without taking another stake. + mov rr3d_mask,0 + mov rr3d_state,RR_DRY + call AdvanceRussianScene3D + cmp rr3d_state,RR_LOAD + jne rr_party_test_rules_fail + cmp rr3d_turn,0 + jne rr_party_test_rules_fail + cmp rrPartyReloads3D,2 + jne rr_party_test_rules_fail + cmp bankroll,9950 + jne rr_party_test_money_fail + ; The final surviving player receives the locked, not subsequently edited, pool. + mov rrPartyAlive3D,3 + mov rr3d_turn,1 + mov rr3d_chamber,2 + mov rr3d_mask,4 + mov rr3d_shot,1 + mov rr3d_state,RR_FIRE + mov rr3d_bet,999 + call AdvanceRussianScene3D + cmp rr3d_state,RR_WIN + jne rr_party_test_rules_fail + cmp rrPartyAlive3D,1 + jne rr_party_test_rules_fail + cmp rr3d_payout,200 + jne rr_party_test_money_fail + cmp bankroll,10150 + jne rr_party_test_money_fail + call RRPartyWin3D + call AdvanceRussianScene3D + cmp bankroll,10150 + jne rr_party_test_money_fail + mov rr3d_bet,50 + call RenderRussianGame3D + invoke WriteActionSnapshot3D,OFFSET rrPartyShotWin + ; 600 full matches, 2/3 guests, 1..3 rounds loaded, 16/50/250 ms updates. + mov edi,2 +rr_party_test_size: + mov rr3d_state,RR_READY + invoke RRPartySetCount3D,edi + mov rounds,300 +rr_party_test_match: + mov engineMode,MODE_RUSSIAN + mov rr3d_state,RR_READY + mov bankroll,10000 + mov rr3d_bet,50 + mov eax,rounds + imul eax,5231 + add eax,edi + mov rngSeed3D,eax + mov eax,rounds + xor edx,edx + mov ecx,3 + div ecx + inc edx + mov rr3d_bullets,edx + mov eax,16 + cmp edx,1 + je @F + mov eax,50 + cmp edx,2 + je @F + mov eax,250 +@@: + mov deltaTime3D,eax + call StartRussianRound3D + mov ticks,0 +rr_party_test_tick: + cmp rrPartySettled3D,0 + jne rr_party_test_ending + mov eax,rrPartyAlive3D + test eax,1 + jz rr_party_test_rules_fail + mov eax,rr3d_mask + cmp eax,63 + ja rr_party_test_rules_fail + mov eax,rr3d_turn + cmp eax,rrPartySize3D + jae rr_party_test_rules_fail + cmp rr3d_state,RR_DRY + je @F ; the outgoing seat may already be eliminated during its fade + bt rrPartyAlive3D,eax + jnc rr_party_test_rules_fail +@@: + cmp bankroll,9950 + jne rr_party_test_money_fail + cmp rr3d_state,RR_PLAYER + jne rr_party_test_ending + mov pressedKeys3D[20h],1 +rr_party_test_ending: + call HandleRussianInput3D + call ClearKeys3D + inc ticks + cmp ticks,20000 + jae rr_party_test_stuck_fail + cmp rr3d_state,RR_WIN + je rr_party_test_won + cmp engineMode,MODE_WALK + jne rr_party_test_tick + cmp bankroll,9950 + jne rr_party_test_money_fail + cmp rrPartySettled3D,1 + jne rr_party_test_money_fail + jmp rr_party_test_next +rr_party_test_won: + mov eax,edi + inc eax + imul eax,50 + cmp rr3d_payout,eax + jne rr_party_test_money_fail + add eax,9950 + cmp bankroll,eax + jne rr_party_test_money_fail + mov bank,eax + call RRPartyWin3D + mov eax,bank + cmp bankroll,eax + jne rr_party_test_money_fail +rr_party_test_next: + dec rounds + jnz rr_party_test_match + inc edi + cmp edi,4 + jb rr_party_test_size + ; Native rendering is pure; the active guest and empty seats must be readable. + mov rr3d_state,RR_READY + mov bankroll,10000 + mov engineMode,MODE_RUSSIAN + call StartRussianRound3D + mov rr3d_state,RR_RAISE + mov rr3d_turn,2 + mov rr3d_timer,400 + mov eax,rngSeed3D + mov savedSeed,eax + mov eax,rr3d_mask + mov savedMask,eax + mov eax,rrPartyAlive3D + mov savedAlive,eax + mov ebx,8 +rr_party_test_repeat_render: + call RenderRussianGame3D + dec ebx + jnz rr_party_test_repeat_render + mov eax,savedSeed + cmp rngSeed3D,eax + jne rr_party_test_render_fail + mov eax,savedMask + cmp rr3d_mask,eax + jne rr_party_test_render_fail + mov eax,savedAlive + cmp rrPartyAlive3D,eax + jne rr_party_test_render_fail + cmp rr3d_timer,400 + jne rr_party_test_render_fail + cmp bankroll,9950 + jne rr_party_test_money_fail + invoke WriteActionSnapshot3D,OFFSET rrPartyShotTurn + ; Escape modal freezes every animation phase, not just the player's input. + mov phase,RR_LOAD +rr_party_test_exit_phase: + mov rr3d_state,RR_READY + mov bankroll,10000 + mov engineMode,MODE_RUSSIAN + call StartRussianRound3D + mov eax,phase + mov rr3d_state,eax + mov rr3d_timer,37 + mov eax,rngSeed3D + mov savedSeed,eax + mov eax,rr3d_mask + mov savedMask,eax + call CardTableEscape3D + cmp cardExitActive3D,1 + jne rr_party_test_input_fail + call HandleRussianInput3D + cmp rr3d_timer,37 + jne rr_party_test_input_fail + mov eax,savedSeed + cmp rngSeed3D,eax + jne rr_party_test_input_fail + mov eax,savedMask + cmp rr3d_mask,eax + jne rr_party_test_input_fail + mov pressedKeys3D[4Eh],1 + call HandleRussianInput3D + cmp cardExitActive3D,0 + jne rr_party_test_input_fail + cmp rr3d_timer,37 + jne rr_party_test_input_fail + call RequestCardExit3D + cmp phase,RR_RAISE + jne @F + call RenderRussianGame3D + invoke WriteActionSnapshot3D,OFFSET rrPartyShotExit +@@: + mov pressedKeys3D[59h],1 + call HandleRussianInput3D + cmp engineMode,MODE_WALK + jne rr_party_test_input_fail + cmp bankroll,9950 + jne rr_party_test_money_fail + call AbortRussianRound3D + cmp bankroll,9950 + jne rr_party_test_money_fail + inc phase + cmp phase,RR_WIN + jb rr_party_test_exit_phase + ; Zero bank and invalid bullet counts cannot create a paid or stuck match. + mov engineMode,MODE_RUSSIAN + mov rr3d_state,RR_READY + mov bankroll,0 + call StartRussianRound3D + cmp rr3d_state,RR_READY + jne rr_party_test_money_fail + mov bankroll,10000 + mov rr3d_bullets,0 + call StartRussianRound3D + cmp rr3d_state,RR_READY + jne rr_party_test_money_fail + cmp bankroll,10000 + jne rr_party_test_money_fail + mov rr3d_bullets,1 + invoke RRPartySetCount3D,1 + mov cardExitActive3D,0 + call ClearKeys3D + xor eax,eax + ret +rr_party_test_art_fail: + mov eax,8201 + ret +rr_party_test_input_fail: + mov eax,8202 + ret +rr_party_test_rules_fail: + mov eax,8203 + ret +rr_party_test_money_fail: + mov eax,8204 + ret +rr_party_test_stuck_fail: + mov eax,8205 + ret +rr_party_test_render_fail: + mov eax,8206 + ret +RunRRPartyTest3D ENDP diff --git a/tools/tests/slots_test.inc b/tools/tests/slots_test.inc index 0fd37f9..399823b 100644 --- a/tools/tests/slots_test.inc +++ b/tools/tests/slots_test.inc @@ -11,6 +11,9 @@ slotsTest7 db "build\actions\slots-exit.bmp",0 slotsTestTimes dd 600,1799,1800,2400 slotsTestPaths dd OFFSET slotsTest1,OFFSET slotsTest2,OFFSET slotsTest3,OFFSET slotsTest4 slotsTestRates dd 16,33,50,250 +slotsRefundPath3D db "build\actions\slots-refund.bmp",0 +slotsNetWinPath3D db "build\actions\slots-net-win.bmp",0 +slotsLossPath3D db "build\actions\slots-loss.bmp",0 .code RunSlotsTest3D PROC uses ebx esi edi local oldBank:DWORD,oldMode:DWORD,oldSeed:DWORD,oldX:DWORD,oldY:DWORD,oldAngle:DWORD @@ -406,6 +409,68 @@ slots_test_exit_tick: call SettleNativeSlots3D cmp bankroll,1000000000 jne slots_test_fail + cmp slotWinAmount,1 + jne slots_test_fail + mov slotsTestStage3D,8 + mov engineMode,MODE_SLOTS + mov slotBet,100 + mov slotStake3D,100 + mov slotError3D,0 + mov slotLeaveAfter3D,0 + mov slotPaytable3D,0 + mov bankroll,99900 + mov slotReel1,2 + mov slotReel2,2 + mov slotReel3,4 + mov slotTargets3D,1 + mov slotTargets3D[4],6 + mov slotTargets3D[8],5 + mov slotSpinState,SLOT_SPIN + call SettleNativeSlots3D + cmp bankroll,100000 + jne slots_test_fail + cmp slotWinAmount,100 + jne slots_test_fail + call RenderNativeSlots3D + cmp BYTE PTR slotNetBuffer3D,'0' + jne slots_test_fail + cmp BYTE PTR slotNetBuffer3D[1],0 + jne slots_test_fail + invoke WriteActionSnapshot3D,OFFSET slotsRefundPath3D + mov bankroll,99900 + mov slotReel1,1 + mov slotReel2,1 + mov slotReel3,2 + mov slotTargets3D,0 + mov slotTargets3D[4],4 + mov slotTargets3D[8],6 + mov slotSpinState,SLOT_SPIN + call SettleNativeSlots3D + cmp bankroll,100100 + jne slots_test_fail + cmp slotWinAmount,200 + jne slots_test_fail + call RenderNativeSlots3D + cmp DWORD PTR slotNetBuffer3D,3030312Bh + jne slots_test_fail + invoke WriteActionSnapshot3D,OFFSET slotsNetWinPath3D + mov bankroll,99900 + mov slotReel1,1 + mov slotReel2,2 + mov slotReel3,5 + mov slotTargets3D,0 + mov slotTargets3D[4],6 + mov slotTargets3D[8],2 + mov slotSpinState,SLOT_SPIN + call SettleNativeSlots3D + cmp bankroll,99900 + jne slots_test_fail + cmp slotWinAmount,0 + jne slots_test_fail + call RenderNativeSlots3D + cmp DWORD PTR slotNetBuffer3D,3030312Dh + jne slots_test_fail + invoke WriteActionSnapshot3D,OFFSET slotsLossPath3D mov eax,oldBank mov bankroll,eax mov eax,oldSeed diff --git a/tools/tests/street_asset_probe.asm b/tools/tests/street_asset_probe.asm index 02292c8..d998e20 100644 --- a/tools/tests/street_asset_probe.asm +++ b/tools/tests/street_asset_probe.asm @@ -8,6 +8,10 @@ LoadAnimPack3D PROTO :DWORD,:DWORD FreeAnimPack3D PROTO :DWORD InitNativeSlots3D PROTO FreeNativeSlots3D PROTO +InitNativeClover3D PROTO +FreeNativeClover3D PROTO +InitPool3D PROTO +FreePyramidAssets3D PROTO LoadNativeWheelArt3D PROTO FreeNativeWheelArt3D PROTO LoadNativeCoinArt3D PROTO @@ -52,6 +56,12 @@ RunStreetAssetProbe PROC cmp eax,1 jne probe_failed call FreeNativeSlots3D + call InitNativeClover3D + cmp eax,1 + jne probe_failed + call FreeNativeClover3D + call InitPool3D + call FreePyramidAssets3D call LoadNativeWheelArt3D cmp eax,1 jne probe_failed diff --git a/tools/tests/street_population_test.inc b/tools/tests/street_population_test.inc index d53b117..ca6c710 100644 --- a/tools/tests/street_population_test.inc +++ b/tools/tests/street_population_test.inc @@ -89,10 +89,48 @@ street_test_person: sar eax,16 mov ecx,cityObjects3D[edi].posY sar ecx,16 + cmp eax,32 + jae street_test_extended_cell shl ecx,5 add eax,ecx cmp cityMap3D[eax],0 jne street_test_fail + jmp street_test_cell_clear +street_test_extended_cell: + ; The continuation district is world-space geometry, not another 32x32 tile row. + cmp ecx,12 + jb street_test_fail + cmp ecx,17 + jae street_test_fail + cmp eax,96 + jae street_test_fail + push ebx + push esi + mov eax,cityObjects3D[edi].posX + mov ecx,cityObjects3D[edi].posY + xor esi,esi +street_test_backdrop_clear: + imul ebx,esi,SIZEOF CityBuilding3D + cmp eax,citySkyline3D[ebx].minX + jl street_test_backdrop_next + cmp eax,citySkyline3D[ebx].maxX + jge street_test_backdrop_next + cmp ecx,citySkyline3D[ebx].minY + jl street_test_backdrop_next + cmp ecx,citySkyline3D[ebx].maxY + jl street_test_backdrop_blocked +street_test_backdrop_next: + inc esi + cmp esi,CITY_DISTANT_BUILDINGS + jb street_test_backdrop_clear + pop esi + pop ebx + jmp street_test_cell_clear +street_test_backdrop_blocked: + pop esi + pop ebx + jmp street_test_fail +street_test_cell_clear: cmp cityObjects3D[edi].worldH,FP_1*7/5 ja street_test_fail mov eax,cityObjects3D[edi].frame diff --git a/tools/tests/test_blackjack_party.ps1 b/tools/tests/test_blackjack_party.ps1 new file mode 100644 index 0000000..87fab5d --- /dev/null +++ b/tools/tests/test_blackjack_party.ps1 @@ -0,0 +1,21 @@ +param([string]$MasmRoot = 'F:\MASM32\masm32') +$ErrorActionPreference = 'Stop' +$root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path +Push-Location $root +try { + & "$MasmRoot\bin\ml.exe" /c /coff /Cp /nologo /Fobuild\actions\blackjack-party-probe.obj tools\tests\blackjack_party_probe.asm + if ($LASTEXITCODE -ne 0) { throw 'Blackjack probe assembly failed' } + $sdkRoot = Join-Path ${env:ProgramFiles(x86)} 'Windows Kits\10\Lib' + $sdk = Get-ChildItem -LiteralPath $sdkRoot -Directory | + Sort-Object Name -Descending | + Where-Object { Test-Path -LiteralPath (Join-Path $_.FullName 'um\x86\kernel32.lib') } | + Select-Object -First 1 + $libraries = @() + $libraries += '/LIBPATH:' + (Join-Path $sdk.FullName 'um\x86') + $libraries += "/LIBPATH:$MasmRoot\lib" + & "$MasmRoot\bin\link.exe" /nologo /SUBSYSTEM:CONSOLE /ENTRY:RunBJPartyProbe@0 @libraries /OUT:build\actions\blackjack-party-probe.exe build\actions\blackjack-party-probe.obj build\actions\actions-test.obj kernel32.lib winmm.lib user32.lib ws2_32.lib gdi32.lib + if ($LASTEXITCODE -ne 0) { throw 'Blackjack probe link failed' } + & .\build\actions\blackjack-party-probe.exe + if ($LASTEXITCODE -ne 0) { throw "Blackjack party assertion failed: $LASTEXITCODE" } + Write-Output 'PASS: 600 native party rounds, shared deck, private wallet, no hidden-card peeking, controls and safe exit' +} finally { Pop-Location } diff --git a/tools/tests/test_casino_actions.ps1 b/tools/tests/test_casino_actions.ps1 index 1672cd5..bf5489b 100644 --- a/tools/tests/test_casino_actions.ps1 +++ b/tools/tests/test_casino_actions.ps1 @@ -6,6 +6,8 @@ try { New-Item -ItemType Directory -Path 'build\actions' -Force | Out-Null & 'C:\Python314\python.exe' tools\tests\prepare_arrival_fixtures.py if ($LASTEXITCODE -ne 0) { throw 'Profile test fixture preparation failed' } + & 'C:\Python314\python.exe' tools\tests\prepare_clover_fixtures.py + if ($LASTEXITCODE -ne 0) { throw 'Clover fixture preparation failed' } & "$MasmRoot\bin\ml.exe" /c /coff /Cp /nologo /I. /DCASINO_ACTION_TEST=1 /Fobuild\actions\actions-test.obj poker.asm if ($LASTEXITCODE -ne 0) { throw 'Action test assembly failed' } $sdkRoot = Join-Path ${env:ProgramFiles(x86)} 'Windows Kits\10\Lib' diff --git a/tools/tests/test_npc_life.ps1 b/tools/tests/test_npc_life.ps1 new file mode 100644 index 0000000..5f17437 --- /dev/null +++ b/tools/tests/test_npc_life.ps1 @@ -0,0 +1,21 @@ +param([string]$MasmRoot = 'F:\MASM32\masm32') +$ErrorActionPreference = 'Stop' +$root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path +Push-Location $root +try { + & "$MasmRoot\bin\ml.exe" /c /coff /Cp /nologo /Fobuild\actions\npc-life-probe.obj tools\tests\npc_life_probe.asm + if ($LASTEXITCODE -ne 0) { throw 'NPC probe assembly failed' } + $sdkRoot = Join-Path ${env:ProgramFiles(x86)} 'Windows Kits\10\Lib' + $sdk = Get-ChildItem -LiteralPath $sdkRoot -Directory | + Sort-Object Name -Descending | + Where-Object { Test-Path -LiteralPath (Join-Path $_.FullName 'um\x86\kernel32.lib') } | + Select-Object -First 1 + $libraries = @() + $libraries += '/LIBPATH:' + (Join-Path $sdk.FullName 'um\x86') + $libraries += "/LIBPATH:$MasmRoot\lib" + & "$MasmRoot\bin\link.exe" /nologo /SUBSYSTEM:CONSOLE /ENTRY:RunNpcLifeProbe@0 @libraries /OUT:build\actions\npc-life-probe.exe build\actions\npc-life-probe.obj build\actions\actions-test.obj kernel32.lib winmm.lib user32.lib ws2_32.lib gdi32.lib + if ($LASTEXITCODE -ne 0) { throw 'NPC probe link failed' } + & .\build\actions\npc-life-probe.exe + if ($LASTEXITCODE -ne 0) { throw "NPC assertion failed: $LASTEXITCODE" } + Write-Output 'PASS: native NPC navigation, rate invariance, profiles, progress, rewards and graphical dialog controls' +} finally { Pop-Location } diff --git a/tools/tests/test_russian_party.ps1 b/tools/tests/test_russian_party.ps1 new file mode 100644 index 0000000..530bb6f --- /dev/null +++ b/tools/tests/test_russian_party.ps1 @@ -0,0 +1,21 @@ +param([string]$MasmRoot = 'F:\MASM32\masm32') +$ErrorActionPreference = 'Stop' +$root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path +Push-Location $root +try { + & "$MasmRoot\bin\ml.exe" /c /coff /Cp /nologo /Fobuild\actions\russian-party-probe.obj tools\tests\russian_party_probe.asm + if ($LASTEXITCODE -ne 0) { throw 'Russian party probe assembly failed' } + $sdkRoot = Join-Path ${env:ProgramFiles(x86)} 'Windows Kits\10\Lib' + $sdk = Get-ChildItem -LiteralPath $sdkRoot -Directory | + Sort-Object Name -Descending | + Where-Object { Test-Path -LiteralPath (Join-Path $_.FullName 'um\x86\kernel32.lib') } | + Select-Object -First 1 + $libraries = @() + $libraries += '/LIBPATH:' + (Join-Path $sdk.FullName 'um\x86') + $libraries += "/LIBPATH:$MasmRoot\lib" + & "$MasmRoot\bin\link.exe" /nologo /SUBSYSTEM:CONSOLE /ENTRY:RunRRPartyProbe@0 @libraries /OUT:build\actions\russian-party-probe.exe build\actions\russian-party-probe.obj build\actions\actions-test.obj kernel32.lib winmm.lib user32.lib ws2_32.lib gdi32.lib + if ($LASTEXITCODE -ne 0) { throw 'Russian party probe link failed' } + & .\build\actions\russian-party-probe.exe + if ($LASTEXITCODE -ne 0) { throw "Russian party assertion failed: $LASTEXITCODE" } + Write-Output 'PASS: 600 native party matches, elimination/order, locked pool, reloading, render purity and safe exit' +} finally { Pop-Location } diff --git a/tools/tests/test_street_asset_paths.ps1 b/tools/tests/test_street_asset_paths.ps1 index fd950cd..de2cb69 100644 --- a/tools/tests/test_street_asset_paths.ps1 +++ b/tools/tests/test_street_asset_paths.ps1 @@ -26,5 +26,5 @@ try { if ($LASTEXITCODE -ne 0) { throw "Street pack failed to load from $directory" } } finally { Pop-Location } } - Write-Output 'PASS: shipping MASM loader loads street, roulette, coin, native 777 and eight hall furniture packs from root/TEMP and clears failed headers' + Write-Output 'PASS: shipping MASM loader loads street, roulette, coin, native 777/Clover 5x3 and eight hall furniture packs from root/TEMP and clears failed headers' } finally { Pop-Location } diff --git a/tools/tests/unavailable_test.inc b/tools/tests/unavailable_test.inc index 198ca77..b0f17ef 100644 --- a/tools/tests/unavailable_test.inc +++ b/tools/tests/unavailable_test.inc @@ -1,6 +1,5 @@ .data -unavailableTestIds3D dd INTERACT_SLOTS_CLOVER - dd INTERACT_ONLINE_RR,INTERACT_UMAMUSUME,INTERACT_HELL_TOWER,INTERACT_TERMINAL,INTERACT_OBSERVER +unavailableTestIds3D dd INTERACT_ONLINE_RR,INTERACT_UMAMUSUME,INTERACT_HELL_TOWER,INTERACT_TERMINAL,INTERACT_OBSERVER unavailableTestPath3D db "build\actions\unavailable.bmp",0 .code RunUnavailableTest3D PROC uses ebx esi edi @@ -73,7 +72,7 @@ unavailable_test_close: cmp playerAngle,eax jne unavailable_test_fail inc esi - cmp esi,6 + cmp esi,5 jb unavailable_test_next mov eax,oldMode mov engineMode,eax diff --git a/tools/tests/wheel_scene_test.inc b/tools/tests/wheel_scene_test.inc index 0061f6f..e848b05 100644 --- a/tools/tests/wheel_scene_test.inc +++ b/tools/tests/wheel_scene_test.inc @@ -10,6 +10,8 @@ wheelResultShot3D db "build\actions\wheel-result-v1.bmp",0 wheelTestTimes3D dd 0,0,1200,3000,4100,4200 wheelLabelPrefix3D db "build\actions\wheel-label-" wheelLabelDigits3D db "00.bmp",0 +wheelSmallLabelsShot3D db "build\actions\wheel-label-small.bmp",0 +wheelRotatedLabelsShot3D db "build\actions\wheel-label-rotated.bmp",0 .code RunWheelSceneTest3D PROC uses ebx esi edi local oldBank:DWORD,oldSeed:DWORD,result:DWORD,selectedSeed:DWORD,savedBank:DWORD @@ -86,6 +88,25 @@ wheel_test_all_bets: cmp result,37 jb wheel_test_all_outcomes mov hallTestStage3D,7802 + lea edi,screenBuffer + mov ecx,SCREEN_SIZE + xor eax,eax + rep stosd + invoke DrawWheelBox3D,-2,-2,4,4,00123456h + cmp screenBuffer,00123456h + jne wheel_test_failed + cmp screenBuffer[(SCREEN_W+1)*4],00123456h + jne wheel_test_failed + cmp screenBuffer[2*4],0 + jne wheel_test_failed + cmp screenBuffer[(SCREEN_W*2)*4],0 + jne wheel_test_failed + invoke DrawWheelBox3D,SCREEN_W-1,SCREEN_H-1,4,4,00654321h + cmp screenBuffer[(SCREEN_SIZE-1)*4],00654321h + jne wheel_test_failed + invoke DrawWheelBox3D,0,0,0,4,0 + cmp screenBuffer,00123456h + jne wheel_test_failed mov previous,0 mov time,0 wheel_test_easing: @@ -120,6 +141,24 @@ wheel_test_label_bounds: inc time cmp time,512 jb wheel_test_label_angles + lea edi,screenBuffer + mov ecx,SCREEN_SIZE + xor eax,eax + rep stosd + invoke DrawWheelLabels3D,206,170,142,46,0 + cmp wheelNumberScale3D,1 + jne wheel_test_failed + invoke WriteActionSnapshot3D,OFFSET wheelSmallLabelsShot3D + test eax,eax + jz wheel_test_failed + lea edi,screenBuffer + mov ecx,SCREEN_SIZE + xor eax,eax + rep stosd + invoke DrawWheelLabels3D,320,278,205,88,113 + invoke WriteActionSnapshot3D,OFFSET wheelRotatedLabelsShot3D + test eax,eax + jz wheel_test_failed ; Standard felt rows are 3/2/1; each displayed number's click adds that number. mov engineMode,MODE_ROULETTE call InitNativeWheel3D diff --git a/tools/tests/world_regression.inc b/tools/tests/world_regression.inc index b9e9ae0..9ef8c42 100644 --- a/tools/tests/world_regression.inc +++ b/tools/tests/world_regression.inc @@ -239,7 +239,7 @@ world_pocket_tick: cmp esi,6 jb world_pocket_motion call PoolFinishShot3D - cmp poolState3D,POOL_HAND + cmp poolState3D,POOL_PENALTY jne world_test_fail call RenderPool3D invoke WriteActionSnapshot3D,OFFSET hallTestScratch3D