From f6a0e664faaaad3843ffdc1ab0a727bee48b8641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A4=D0=B5=D0=B4=D0=BE?= =?UTF-8?q?=D1=81=D0=B5=D0=B5=D0=B2?= Date: Wed, 30 Sep 2026 21:27:18 +0300 Subject: [PATCH] chore: track all project backups, docs, runtime assets, and graphify output --- .gitignore | 30 - ...ino3d_before_enginefix_20260924_220800.inc | 2975 +++ backups/casino3d_before_full_fix.inc | 5228 ++++++ backups/casino3d_before_rich_ui.inc | 4756 +++++ backups/poker_backup_broken.exe | Bin 0 -> 184832 bytes ...poker_before_enginefix_20260924_220800.asm | 15144 ++++++++++++++++ ...poker_before_enginefix_20260924_220800.exe | Bin 0 -> 559616 bytes docs/previews_minigames/font_test.png | Bin 0 -> 2925 bytes docs/render_view.png | Bin 0 -> 67099 bytes graphify-out/.graphify_labels.json | 1 + graphify-out/.graphify_python | 1 + graphify-out/.graphify_root | 1 + graphify-out/.graphify_semantic_new.json | 1790 ++ graphify-out/.graphify_transcripts.json | 1 + graphify-out/.graphify_uncached.txt | 35 + graphify-out/.vocab.txt | 260 + graphify-out/GRAPH_REPORT.md | 127 + ...d79f38b69415391a8513cdb928bd7c13476d9.json | 1 + ...46b04fa951fe188d0fda9be8c78bd42a8bcbc.json | 1 + ...3d21f3a33a18ca102faa52fb8cac0b644be35.json | 1 + ...e44d32b433568a6007f81701b2f9ee3ce0455.json | 1 + ...8a3678043ddd3ae85cdaa79f1c27f00d6fdcf.json | 1 + ...9e48f9b4a7f701ce3500521befbc805a35c9a.json | 1 + ...d460dcd78bb98289e988d575ab8e9e01ad54c.json | 1 + ...a9e2112319bdaf8c89ea20b4c49ac55520a2a.json | 1 + ...9b7d8b349dafb88ee476878ac7d8e4e95fcdb.json | 1 + ...27d86319cf01167962564fddb4ef445029606.json | 1 + ...47b45b06443907eb422c671c5f4ccbcf71968.json | 1 + ...c012aeb99180bbc671d58513b58b454e7452d.json | 1 + ...8a27bf2d7320e67804d80b42835798ca957c5.json | 1 + ...8d8bf6242e0a79147b3c96085a23c99422493.json | 1 + ...d1e5ab22f7b02fc200f7450304d888b68bbf1.json | 1 + ...2acd593e9c8627cbd6520c573c8c5d9435d93.json | 1 + ...5141be58d38619b85c57183a0c5a9ea69d3a3.json | 1 + ...2a0249ea08f2b4ee51dba135bb416c69e8d9f.json | 1 + ...931630d1435baf8235432b0402eb26a5089c4.json | 1 + ...9edd6ba5dec55e03222df428abb5a36330150.json | 1 + ...40a304b7e571cea3e36fc5357728eafb44cf3.json | 1 + ...d98f496a43319d6bb108033c4fab1175c67b6.json | 1 + ...3cc0f57af765057576eede971308c4eebf950.json | 1 + ...17f63989558728f1d1ddb12bc251985032513.json | 1 + ...ce6664af577eef41c272ca17c98528dbfa4ff.json | 1 + ...7f9c63556fbf5d66abdb340c52a51daaf1dcd.json | 1 + ...079fedb9c7dde4980ae686ffde08217b223a3.json | 1 + ...469f080f92cc10e4a047b77d4cd4516c24449.json | 1 + ...f26f39ba9662936b01d78c78b37a5b3eadbdb.json | 1 + ...4950faec5ec673bc22f7584d657b45618cff7.json | 1 + ...b51b8910eed6f43487aa98564ddcb759a1b97.json | 1 + ...3db0504b0c82ff76e03016f9f8988fe7e8301.json | 1 + ...905e62cc34419f654a6239e777b23263be11c.json | 1 + ...d643f24a92a601310c76eb33e44407af6eef3.json | 1 + ...dac85e95983acd32ae7ca8480a439b7865620.json | 1 + ...48a430bd4ee753dc803cef82fab9552bf2873.json | 1 + ...808736da317b48391a68184cbdfd372d693fe.json | 1 + ...57cd6f46cf7fff6c1b66c6136769cd15a7ace.json | 1 + ...0d905ae3604a239c8daa6e3ae2d0f8845eb78.json | 1 + ...15cdb60c4936ca9ffcbf1b4df48885a1e33d1.json | 1 + ...5ea2050aee241bea354ce2990721134a845f3.json | 1 + ...48f66279808d60a4271f637362898bfb5a0ee.json | 1 + ...56f842168108d8dffa02f074752d8d53ad2fa.json | 1 + ...d438a63891019df6c1f9fd1465631fed7e4c7.json | 1 + ...948a6964cfa315825377918a162d62760a952.json | 1 + ...b0495433172e7266523a3d26ac2b42c5a49ae.json | 1 + ...ad6691c764ca162aeb960c04bdb9516d76b3e.json | 1 + ...151607479313f68fa78c77fd13f3cc3ee0618.json | 1 + ...3266c40fb1641b1829a4fe3a1fa95758f29aa.json | 1 + ...e98276db2181fd67ce5951d8f4682cbcd0769.json | 1 + ...631d481899c6440bd5e1fa769ff4f161259b7.json | 1 + ...27a0a2ec44bc43e522f43e3abea7569328164.json | 1 + ...cea6c667a4f1f1a35230d4cb692d88249fd43.json | 1 + ...68055ceede785e6e40404caaa242a808f25bc.json | 1 + ...598a37eeed28b7862705c59ff22692de7f38e.json | 1 + ...0574587a9a920b8b6d96b1695a526eb4fdc5d.json | 1 + ...69f2be981e14c8d4055f8d3fc8aef3573e2e2.json | 1 + ...64211ee06a6c55f801f948fcbac7b152f7050.json | 1 + ...088c822b61bd8fd638c06e211b9dfd97d4645.json | 1 + graphify-out/cache/stat-index.json | 1 + .../variables_documentation_3fc6d2dc.md | 965 + graphify-out/cost.json | 12 + graphify-out/graph.html | 320 + graphify-out/graph.json | 4030 ++++ graphify-out/manifest.json | 402 + poker.obj | Bin 0 -> 316722 bytes runtime/casino3d-progress.dat | Bin 0 -> 16 bytes .../__pycache__/build_all_3d.cpython-314.pyc | Bin 0 -> 75518 bytes .../build_casino_assets.cpython-314.pyc | Bin 0 -> 12727 bytes .../__pycache__/build_engine.cpython-314.pyc | Bin 0 -> 216 bytes .../build_graphics_assets.cpython-314.pyc | Bin 0 -> 6425 bytes .../generate_casino3d.cpython-314.pyc | Bin 0 -> 201 bytes .../__pycache__/generate_font.cpython-314.pyc | Bin 0 -> 2584 bytes .../generate_math_and_map.cpython-314.pyc | Bin 0 -> 4648 bytes .../generate_unified_casino3d.cpython-314.pyc | Bin 0 -> 59359 bytes .../__pycache__/make_casino3d.cpython-314.pyc | Bin 0 -> 147 bytes .../patch_poker_asm.cpython-314.pyc | Bin 0 -> 3177 bytes .../preview_dbd_hook.cpython-314.pyc | Bin 0 -> 3504 bytes .../preview_hakari.cpython-314.pyc | Bin 0 -> 3111 bytes .../__pycache__/preview_intro.cpython-314.pyc | Bin 0 -> 3567 bytes .../simulate_render.cpython-314.pyc | Bin 0 -> 13042 bytes .../test_minigames_render.cpython-314.pyc | Bin 0 -> 21762 bytes 99 files changed, 36108 insertions(+), 30 deletions(-) delete mode 100644 .gitignore create mode 100644 backups/casino3d_before_enginefix_20260924_220800.inc create mode 100644 backups/casino3d_before_full_fix.inc create mode 100644 backups/casino3d_before_rich_ui.inc create mode 100644 backups/poker_backup_broken.exe create mode 100644 backups/poker_before_enginefix_20260924_220800.asm create mode 100644 backups/poker_before_enginefix_20260924_220800.exe create mode 100644 docs/previews_minigames/font_test.png create mode 100644 docs/render_view.png create mode 100644 graphify-out/.graphify_labels.json create mode 100644 graphify-out/.graphify_python create mode 100644 graphify-out/.graphify_root create mode 100644 graphify-out/.graphify_semantic_new.json create mode 100644 graphify-out/.graphify_transcripts.json create mode 100644 graphify-out/.graphify_uncached.txt create mode 100644 graphify-out/.vocab.txt create mode 100644 graphify-out/GRAPH_REPORT.md create mode 100644 graphify-out/cache/ast/v0.9.18/0d8891501bfba3c351f82dabe23d79f38b69415391a8513cdb928bd7c13476d9.json create mode 100644 graphify-out/cache/ast/v0.9.18/0e20ce5f0da50b080a252db92e146b04fa951fe188d0fda9be8c78bd42a8bcbc.json create mode 100644 graphify-out/cache/ast/v0.9.18/138dda071059ae037e9972bdbc63d21f3a33a18ca102faa52fb8cac0b644be35.json create mode 100644 graphify-out/cache/ast/v0.9.18/17cce3e69a6245d4d8d4d48847de44d32b433568a6007f81701b2f9ee3ce0455.json create mode 100644 graphify-out/cache/ast/v0.9.18/1ad632faebe559e783b0064c2338a3678043ddd3ae85cdaa79f1c27f00d6fdcf.json create mode 100644 graphify-out/cache/ast/v0.9.18/260c7d561bd484ebf4a0b7f05ce9e48f9b4a7f701ce3500521befbc805a35c9a.json create mode 100644 graphify-out/cache/ast/v0.9.18/47fa3293a06711be74c2f14c52bd460dcd78bb98289e988d575ab8e9e01ad54c.json create mode 100644 graphify-out/cache/ast/v0.9.18/4bf4afc73df542d7e831d4468cda9e2112319bdaf8c89ea20b4c49ac55520a2a.json create mode 100644 graphify-out/cache/ast/v0.9.18/4ededd1f62dfbf46792345c3be39b7d8b349dafb88ee476878ac7d8e4e95fcdb.json create mode 100644 graphify-out/cache/ast/v0.9.18/531a442e9e0c8f0c7c6ac0060e327d86319cf01167962564fddb4ef445029606.json create mode 100644 graphify-out/cache/ast/v0.9.18/5f3f8a091f85d4da2b6a9052a2747b45b06443907eb422c671c5f4ccbcf71968.json create mode 100644 graphify-out/cache/ast/v0.9.18/60e4e6059cb5be35a945d8b9587c012aeb99180bbc671d58513b58b454e7452d.json create mode 100644 graphify-out/cache/ast/v0.9.18/75c60a1a5818b18c7cfa072c4708a27bf2d7320e67804d80b42835798ca957c5.json create mode 100644 graphify-out/cache/ast/v0.9.18/7627c17a45c6dc182aa6d5405eb8d8bf6242e0a79147b3c96085a23c99422493.json create mode 100644 graphify-out/cache/ast/v0.9.18/7b7850caf79296f29325be3bb73d1e5ab22f7b02fc200f7450304d888b68bbf1.json create mode 100644 graphify-out/cache/ast/v0.9.18/7f720d61b49719534794328d3012acd593e9c8627cbd6520c573c8c5d9435d93.json create mode 100644 graphify-out/cache/ast/v0.9.18/96a2e9b3fe3a64c41bfd8ced2675141be58d38619b85c57183a0c5a9ea69d3a3.json create mode 100644 graphify-out/cache/ast/v0.9.18/af3c3463623a9dc11fb58dc537a2a0249ea08f2b4ee51dba135bb416c69e8d9f.json create mode 100644 graphify-out/cache/ast/v0.9.18/b70c30af76f1f519b55093958a9931630d1435baf8235432b0402eb26a5089c4.json create mode 100644 graphify-out/cache/ast/v0.9.18/c24892bb1085007fd9e480f1f4c9edd6ba5dec55e03222df428abb5a36330150.json create mode 100644 graphify-out/cache/ast/v0.9.18/d31fe1e6e7ffc320f0f384a1d9140a304b7e571cea3e36fc5357728eafb44cf3.json create mode 100644 graphify-out/cache/ast/v0.9.18/e0ca915f66cb272addb0bca6b7dd98f496a43319d6bb108033c4fab1175c67b6.json create mode 100644 graphify-out/cache/ast/v0.9.18/e92dd483b153ada4a22fb3ccbb73cc0f57af765057576eede971308c4eebf950.json create mode 100644 graphify-out/cache/ast/v0.9.18/f27d1ca5e032eebb68a1df01fd317f63989558728f1d1ddb12bc251985032513.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/016158cc8adad8160340452b77cce6664af577eef41c272ca17c98528dbfa4ff.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/09dd028822ba46a04b140cfe2d87f9c63556fbf5d66abdb340c52a51daaf1dcd.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/0d6f574242f0d2d03be537ebfd0079fedb9c7dde4980ae686ffde08217b223a3.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/139008ef7748309e83aeac704e3469f080f92cc10e4a047b77d4cd4516c24449.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/26a929e4e6f254f9aba76895b9ef26f39ba9662936b01d78c78b37a5b3eadbdb.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/32f81bd8f45e0773c6c1d53140f4950faec5ec673bc22f7584d657b45618cff7.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/3e3c7eff3b45033cc98ee546129b51b8910eed6f43487aa98564ddcb759a1b97.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/3f5cdf31d62662cddb0759ad99c3db0504b0c82ff76e03016f9f8988fe7e8301.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/4d8f0de181aedda11b2d4ce04f8905e62cc34419f654a6239e777b23263be11c.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/5019c39ae53c46f65590fb3377ed643f24a92a601310c76eb33e44407af6eef3.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/50bb900fa5771366b25d5e61fd7dac85e95983acd32ae7ca8480a439b7865620.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/5c39c43551141a3f7beb37ef54848a430bd4ee753dc803cef82fab9552bf2873.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/5cd86e06c67bdf06ccb0adf9b42808736da317b48391a68184cbdfd372d693fe.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/5d012f24010a6eb1de1cdd1742257cd6f46cf7fff6c1b66c6136769cd15a7ace.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/6502c037ea8cfb065a14ef126fb0d905ae3604a239c8daa6e3ae2d0f8845eb78.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/66785c4ded4380a94ff1a92dcea15cdb60c4936ca9ffcbf1b4df48885a1e33d1.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/686d95276641b50cad94586d23f5ea2050aee241bea354ce2990721134a845f3.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/697d2c4eb527e73f383c161bac448f66279808d60a4271f637362898bfb5a0ee.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/82e133215be02a2cd9dd8a3a25756f842168108d8dffa02f074752d8d53ad2fa.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/8937c5c15aa61e292c07e5b448fd438a63891019df6c1f9fd1465631fed7e4c7.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/a113431c0e76e7daa8d56c7d69a948a6964cfa315825377918a162d62760a952.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/a9a271207ed30f453f832cb69b4b0495433172e7266523a3d26ac2b42c5a49ae.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/af01a2f906052efca92f2cfc486ad6691c764ca162aeb960c04bdb9516d76b3e.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/b5eb0b056a9964e494760f4ce3f151607479313f68fa78c77fd13f3cc3ee0618.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/b732ac4170f7a74ce6a57e220b33266c40fb1641b1829a4fe3a1fa95758f29aa.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/c1326bcfdd650879a2a436c99d0e98276db2181fd67ce5951d8f4682cbcd0769.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/c4178347ffe8fa44f006bd04ff7631d481899c6440bd5e1fa769ff4f161259b7.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/c8bbcc1e907856de0c3dc438bb527a0a2ec44bc43e522f43e3abea7569328164.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/ca15a08a45d16237e0e2d624843cea6c667a4f1f1a35230d4cb692d88249fd43.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/d676872e69d4aeeb49265d3988c68055ceede785e6e40404caaa242a808f25bc.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/d98a4f99254061be7b91bbbb70f598a37eeed28b7862705c59ff22692de7f38e.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/d9fd6ae71610254ca4c206a20100574587a9a920b8b6d96b1695a526eb4fdc5d.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/ddb0f204117b91048fa027ed12269f2be981e14c8d4055f8d3fc8aef3573e2e2.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/f2fdf00fc3204cd407be451fbc264211ee06a6c55f801f948fcbac7b152f7050.json create mode 100644 graphify-out/cache/semantic/pd5fd89c46bb5/f70c4f274cf8e4c4cf5b2788263088c822b61bd8fd638c06e211b9dfd97d4645.json create mode 100644 graphify-out/cache/stat-index.json create mode 100644 graphify-out/converted/variables_documentation_3fc6d2dc.md create mode 100644 graphify-out/cost.json create mode 100644 graphify-out/graph.html create mode 100644 graphify-out/graph.json create mode 100644 graphify-out/manifest.json create mode 100644 poker.obj create mode 100644 runtime/casino3d-progress.dat create mode 100644 tools/generators/__pycache__/build_all_3d.cpython-314.pyc create mode 100644 tools/generators/__pycache__/build_casino_assets.cpython-314.pyc create mode 100644 tools/generators/__pycache__/build_engine.cpython-314.pyc create mode 100644 tools/generators/__pycache__/build_graphics_assets.cpython-314.pyc create mode 100644 tools/generators/__pycache__/generate_casino3d.cpython-314.pyc create mode 100644 tools/generators/__pycache__/generate_font.cpython-314.pyc create mode 100644 tools/generators/__pycache__/generate_math_and_map.cpython-314.pyc create mode 100644 tools/generators/__pycache__/generate_unified_casino3d.cpython-314.pyc create mode 100644 tools/generators/__pycache__/make_casino3d.cpython-314.pyc create mode 100644 tools/generators/__pycache__/patch_poker_asm.cpython-314.pyc create mode 100644 tools/previews/__pycache__/preview_dbd_hook.cpython-314.pyc create mode 100644 tools/previews/__pycache__/preview_hakari.cpython-314.pyc create mode 100644 tools/previews/__pycache__/preview_intro.cpython-314.pyc create mode 100644 tools/tests/__pycache__/simulate_render.cpython-314.pyc create mode 100644 tools/tests/__pycache__/test_minigames_render.cpython-314.pyc diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c98a93d..0000000 --- a/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# Build intermediate files -*.obj -*.pdb -*.ilk -*.tmp -*.res - -# Large zip archives & installer payloads (>100MB) -*.zip -PokerGameSetup.exe -PokerGameSetup_*.exe - -# Legacy backups folder (kept locally) -backups/ - -# Generated frames & temporary video tools (270MB) -tools/generated_frames/ -__pycache__/ -*.pyc - -# Local debug / test captures -*_test*.png -debug_render.png -render_view.png -*.log - -# Tool and runtime generated outputs -graphify-out/ -runtime/*.dat -runtime/*.stop diff --git a/backups/casino3d_before_enginefix_20260924_220800.inc b/backups/casino3d_before_enginefix_20260924_220800.inc new file mode 100644 index 0000000..80abf4c --- /dev/null +++ b/backups/casino3d_before_enginefix_20260924_220800.inc @@ -0,0 +1,2975 @@ + +; ============================================================================== +; 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 +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 + +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 + +.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 "Assembler Casino - 2.5D",0 +szTexturesRelPath db "assets\textures\casino3d-hd.bin",0 +szTexturesFullPath db 260 dup(0) + +soundCoin db "assets\audio\Çâîí ïàäàþùåé ìîíåòû.wav",0 +soundCards db "assets\audio\playing_cards_deck_flick_through_001_20485.wav",0 +soundRoulette db "assets\audio\roulette-wheel-throw-2.wav",0 +soundJackpot db "assets\audio\Äæåêïîò.wav",0 +soundClick db "assets\audio\b05e1ac8be34248.wav",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] CABARET - TIP $100",0 +promptSlot1 db "[E] SLOTS 777",0 +promptSlot2 db "[E] SLOTS 777",0 +promptBlackjack db "[E] BLACKJACK / 21",0 +promptPoker db "POKER - UNDER CONSTRUCTION",0 +promptRoulette db "[E] ROULETTE",0 +promptShop db "[E] BOUTIQUE",0 +promptATM db "[E] CASHIER",0 +promptBackroom db "BACKROOM - UNDER CONSTRUCTION",0 +promptDurak db "DURAK - UNDER CONSTRUCTION",0 +promptHell db "TOWER - UNDER CONSTRUCTION",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 13 +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) + +shopMsg db 128 dup(0) +atmMsg db 128 dup(0) + +strWin db "ÏÎÁÅÄÀ! +$",0 +strLose db "ÏÐÎÈÃÐÛØ",0 +strJackpot db "ÄÆÅÊÏÎÒ! +$",0 +strPush db "ÍÈ×Üß (PUSH)",0 +strDealerBust db "ÄÈËÅÐ ÏÅÐÅÁÐÀË! ÏÎÁÅÄÀ! +$",0 +strPlayerBust db "ÏÅÐÅÁÎÐ (>21)! ÏÐÎÈÃÐÛØ",0 + +sym7 db " 777 ",0 +symBar db " BAR ",0 +symBell db " BELL",0 +symCherry db "CHERRY",0 +symClover db "CLOVER",0 +symGem db " GEM ",0 +symCrown db "CROWN",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 (48 * 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 --- +RenderCeilingAndFloor PROC uses ebx esi edi + local floorRow:DWORD + local pDist:DWORD + local fStepX:DWORD + local fStepY:DWORD + local fX:DWORD + local fY:DWORD + local shade:DWORD + local cShade:DWORD + + ; Horizon line: row 120 + mov edi, HALF_H +floor_scanlines: + cmp edi, SCREEN_H + jge floor_done + mov floorRow, edi + + ; Distance = (HALF_H * FP_1) / (y - HALF_H) + mov eax, edi + sub eax, HALF_H + inc eax + mov ecx, eax + mov eax, HALF_H * FP_1 + cdq + idiv ecx + mov pDist, eax + + ; Distance shading (closer is brighter, far horizon is dark) + mov edx, pDist + shr edx, 13 + mov eax, 255 + sub eax, edx + cmp eax, 35 + jge @F + mov eax, 35 +@@: + mov shade, eax + mov edx, eax + sub edx, 25 + cmp edx, 20 + jge @F + mov edx, 20 +@@: + mov cShade, edx + + ; Step along scanline: (2 * playerPlane) * pDist / SCREEN_W + mov eax, playerPlaneX + shl eax, 1 + imul pDist + shrd eax, edx, 16 + cdq + mov ecx, SCREEN_W + idiv ecx + mov fStepX, eax + + mov eax, playerPlaneY + shl eax, 1 + imul pDist + shrd eax, edx, 16 + cdq + mov ecx, SCREEN_W + idiv ecx + mov fStepY, eax + + ; Starting floor coordinates at x=0: + ; player + pDist * (playerDir - playerPlane) + mov eax, playerDirX + sub eax, playerPlaneX + imul pDist + shrd eax, edx, 16 + add eax, playerX + mov fX, eax + + mov eax, playerDirY + sub eax, playerPlaneY + imul pDist + shrd eax, edx, 16 + add eax, playerY + mov fY, eax + + ; Fill scanline for floor (y) and ceiling (SCREEN_H - 1 - y) + xor esi, esi +col_floor_loop: + cmp esi, SCREEN_W + jge next_floor_row + + ; Carpet Texture (Slot 3: 3 * 4096 * 4 = 49152 bytes) + mov eax, fX + shr eax, 9 + and eax, 127 + mov edx, fY + shr edx, 9 + and edx, 127 + shl edx, 7 + add edx, eax + + mov eax, [texturesBuffer + (3 * 128 * 128 * 4) + edx*4] + + ; Shade Floor RGB + mov ebx, shade + movzx ecx, al + imul ecx, ebx + shr ecx, 8 + push ecx + + movzx ecx, ah + imul ecx, ebx + shr ecx, 8 + shl ecx, 8 + + shr eax, 16 + movzx eax, al + imul eax, ebx + shr eax, 8 + shl eax, 16 + or eax, ecx + pop ecx + or eax, ecx + + ; Store to Floor pixel + mov ecx, floorRow + imul ecx, SCREEN_W + add ecx, esi + mov [screenBuffer + ecx*4], eax + + ; Ceiling Spotlight Texture (Slot 5: 5 * 4096 * 4 = 81920 bytes) + mov eax, [texturesBuffer + (5 * 128 * 128 * 4) + edx*4] + mov ebx, cShade + movzx ecx, al + imul ecx, ebx + shr ecx, 8 + push ecx + + movzx ecx, ah + imul ecx, ebx + shr ecx, 8 + shl ecx, 8 + + shr eax, 16 + movzx eax, al + imul eax, ebx + shr eax, 8 + shl eax, 16 + or eax, ecx + pop ecx + or eax, ecx + + ; Store to Ceiling pixel: (SCREEN_H - 1 - floorRow) + mov ecx, SCREEN_H - 1 + sub ecx, floorRow + imul ecx, SCREEN_W + add ecx, esi + mov [screenBuffer + ecx*4], eax + + mov eax, fStepX + add fX, eax + mov eax, fStepY + add fY, eax + inc esi + jmp col_floor_loop + +next_floor_row: + inc edi + jmp floor_scanlines + +floor_done: + ret +RenderCeilingAndFloor ENDP + +; --- DDA Raycasting Walls --- +RenderWalls PROC + local col: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 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 + ; 2^32 needs the full EDX:EAX dividend, not a truncated multiply. + xor eax, eax + mov edx, 1 + idiv ebx + mov deltaDistX, eax + +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 + ; 2^32 needs the full EDX:EAX dividend, not a truncated multiply. + xor eax, eax + mov edx, 1 + idiv ebx + mov deltaDistY, eax + +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 hit_wall + + 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 hit_wall + cmp mapX, MAP_WIDTH + jge hit_wall + cmp mapY, 0 + jl hit_wall + cmp mapY, MAP_HEIGHT + jge hit_wall + + mov eax, mapY + shl eax, 5 + add eax, mapX + movzx eax, BYTE PTR [casinoMap + eax] + test eax, eax + jnz hit_wall + jmp dda_step_loop + +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 + + ; High casino ceiling: lineH = (SCREEN_H * FP_1 * 180 / 240) / perpWallDist + mov eax, SCREEN_H + imul eax, FP_1 + cdq + idiv perpWallDist + mov lineH, eax + + mov eax, lineH + shr eax, 1 + mov ecx, HALF_H + sub ecx, eax + mov drawStart, ecx + + mov eax, lineH + shr eax, 1 + mov ecx, HALF_H + add ecx, eax + mov drawEnd, ecx + + 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 + 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 +@@: + cmp side, 1 + jne select_tex + cmp rayDirY, 0 + jge select_tex + mov eax, 127 + sub eax, texX + mov texX, eax + +select_tex: + mov eax, mapY + shl eax, 5 + add eax, mapX + movzx eax, BYTE PTR [casinoMap + 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, 128 * FP_1 + cdq + idiv lineH + mov esi, eax ; stepY + + mov eax, lineH + shr eax, 1 + add eax, drawStart + sub eax, HALF_H + 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 + shl eax, 7 + add eax, texX + + mov edx, texId + shl edx, 14 + add eax, edx + mov eax, [texturesBuffer + eax*4] + + ; Shade wall pixel + mov ebx, shade + 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 --- +RenderSprites PROC + local sprIdx:DWORD + local relX:DWORD + local relY:DWORD + local invDet:DWORD + local transX:DWORD + local transY:DWORD + local sprScreenX:DWORD + local sprH:DWORD + local sprW:DWORD + local drawStartY:DWORD + local drawEndY:DWORD + local drawStartX:DWORD + local drawEndX:DWORD + local stripe:DWORD + local texX:DWORD + local texY:DWORD + local shade:DWORD + local texSlot:DWORD + + push ebx + push esi + push edi + + xor esi, esi +calc_dist_loop: + cmp esi, NUM_SPRITES + jge sort_sprites + mov eax, esi + imul eax, SIZEOF SpriteObject + + mov edx, [casinoSprites + eax].posX + sub edx, playerX + sar edx, 8 + imul edx, edx + mov ebx, edx + + mov edx, [casinoSprites + eax].posY + sub edx, playerY + sar edx, 8 + imul edx, edx + add ebx, edx + + mov [casinoSprites + eax].distSq, ebx + mov [sortedSprites + esi*4], esi + inc esi + jmp calc_dist_loop + +sort_sprites: + xor esi, esi +sort_outer: + cmp esi, NUM_SPRITES - 1 + jge render_sorted_sprites + mov edi, esi + inc edi +sort_inner: + cmp edi, NUM_SPRITES + jge next_sort_outer + + mov eax, [sortedSprites + esi*4] + imul eax, SIZEOF SpriteObject + mov eax, [casinoSprites + eax].distSq + + mov ebx, [sortedSprites + edi*4] + imul ebx, SIZEOF SpriteObject + mov ebx, [casinoSprites + ebx].distSq + + cmp eax, ebx + jge @F + mov ecx, [sortedSprites + esi*4] + mov edx, [sortedSprites + edi*4] + mov [sortedSprites + esi*4], edx + mov [sortedSprites + edi*4], ecx +@@: + inc edi + jmp sort_inner +next_sort_outer: + inc esi + jmp sort_outer + +render_sorted_sprites: + xor esi, esi +draw_spr_loop: + cmp esi, NUM_SPRITES + jge sprites_rendered + + mov eax, [sortedSprites + esi*4] + mov sprIdx, eax + imul eax, SIZEOF SpriteObject + + ; Sample animation by elapsed time. Pausing freezes the clock. + push eax + mov ecx, [casinoSprites + eax].animSpeed + imul ecx, 40 + mov eax, animationClock3D + xor edx, edx + div ecx + pop ebx + xor edx, edx + div [casinoSprites + ebx].frameCount + mov [casinoSprites + ebx].curFrame, edx + mov eax, ebx + + cmp [casinoSprites + eax].distSq, 16 + jle next_spr + + mov edx, [casinoSprites + eax].posX + sub edx, playerX + mov relX, edx + + mov edx, [casinoSprites + eax].posY + sub edx, playerY + mov relY, edx + + mov eax, playerPlaneX + imul playerDirY + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerDirX + imul playerPlaneY + shrd eax, edx, 16 + sub ebx, eax + test ebx, ebx + jz next_spr + + ; 2^32 needs the full EDX:EAX dividend, not a truncated multiply. + xor eax, eax + mov edx, 1 + idiv ebx + mov invDet, eax + + mov eax, playerDirY + imul relX + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerDirX + imul relY + shrd eax, edx, 16 + sub ebx, eax + + mov eax, ebx + imul invDet + shrd eax, edx, 16 + mov transX, eax + + mov eax, playerPlaneY + neg eax + imul relX + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerPlaneX + imul relY + shrd eax, edx, 16 + add ebx, eax + + mov eax, ebx + imul invDet + shrd eax, edx, 16 + mov transY, eax + + cmp transY, 4096 + jle next_spr + + mov eax, transX + imul eax, HALF_W + cdq + idiv transY + add eax, HALF_W + mov sprScreenX, eax + + mov eax, SCREEN_H + imul eax, FP_1 + cdq + idiv transY + test eax, eax + jns @F + neg eax +@@: + cmp eax, SCREEN_H * 2 + jle @F + mov eax, SCREEN_H * 2 +@@: + mov sprH, eax + mov sprW, eax + + mov eax, HALF_H + mov ebx, sprH + shr ebx, 1 + sub eax, ebx + mov drawStartY, eax + add eax, sprH + mov drawEndY, eax + + mov eax, sprScreenX + mov ebx, sprW + shr ebx, 1 + sub eax, ebx + mov drawStartX, eax + add eax, sprW + mov drawEndX, eax + + cmp drawStartY, 0 + jge @F + mov drawStartY, 0 +@@: + cmp drawEndY, SCREEN_H + jl @F + mov drawEndY, SCREEN_H - 1 +@@: + + mov eax, transY + shr eax, 13 + mov edx, 256 + sub edx, eax + cmp edx, 110 + jge @F + mov edx, 110 +@@: + mov shade, edx + + mov eax, sprIdx + imul eax, SIZEOF SpriteObject + mov edx, [casinoSprites + eax].baseTexId + add edx, [casinoSprites + eax].curFrame + mov texSlot, edx + + mov eax, drawStartX + mov stripe, eax + +spr_stripe_loop: + mov eax, stripe + cmp eax, drawEndX + jge next_spr + + cmp eax, 0 + jl next_spr_stripe + cmp eax, SCREEN_W + jge next_spr + + mov edx, transY + cmp edx, [zBuffer + eax*4] + jge next_spr_stripe + + mov eax, stripe + sub eax, sprScreenX + mov ebx, sprW + shr ebx, 1 + add eax, ebx + shl eax, 7 + cdq + idiv sprW + cmp eax, 0 + jl next_spr_stripe + cmp eax, 128 + jge next_spr_stripe + mov texX, eax + + mov edi, drawStartY +spr_pix_y_loop: + cmp edi, drawEndY + jg next_spr_stripe + + mov eax, edi + sub eax, HALF_H + mov ebx, sprH + shr ebx, 1 + add eax, ebx + shl eax, 7 + cdq + idiv sprH + cmp eax, 0 + jl next_spr_y + cmp eax, 128 + jge next_spr_y + mov texY, eax + + shl eax, 7 + add eax, texX + mov edx, texSlot + shl edx, 14 + add eax, edx + mov eax, [texturesBuffer + eax*4] + + ; Chromakey magenta filter + cmp eax, CHROMA_KEY + je next_spr_y +do_draw_sprite_pix: + mov ebx, shade + 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 ecx, edi + imul ecx, SCREEN_W + add ecx, stripe + mov [screenBuffer + ecx*4], eax + +next_spr_y: + inc edi + jmp spr_pix_y_loop + +next_spr_stripe: + inc stripe + jmp spr_stripe_loop + +next_spr: + inc esi + jmp draw_spr_loop + +sprites_rendered: + pop edi + pop esi + pop ebx + ret +RenderSprites ENDP + +; --- 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, 0000D7FFh, 1 + + ; Draw Sprites on 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, 000000FFh + 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 PlaySoundA, OFFSET soundClick, 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, 0000D7FFh, 3 + + ; Illuminated Top Marquee + invoke DrawBoxBorder, 25, 20, 270, 32, 000A0505h, 0000FFFFh, 2 + invoke DrawString8x8, 55, 32, OFFSET textSlots3D, 0000D7FFh + + ; 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 PlaySoundA, 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 PlaySoundA, OFFSET soundJackpot, 0, 1 + jmp draw_reels +@@: + mov eax, slotBet + imul eax, 10 + mov slotWinAmount, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000D7FFh, 1 + + invoke DrawString8x8, 28, 172, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 175, 172, OFFSET textBet3D, 0000D7FFh + 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, 0000FFFFh + invoke FormatNumber, slotWinAmount, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 187, OFFSET hudNumBuffer, 0000FFFFh + +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, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + ret +DrawReelSymbolAt1 ENDP + +DrawReelSymbolAt2 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 135, 105, OFFSET sym7, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + ret +DrawReelSymbolAt2 ENDP + +DrawReelSymbolAt3 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 218, 105, OFFSET sym7, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + 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 PlaySoundA, 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 PlaySoundA, OFFSET soundJackpot, 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 PlaySoundA, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000D7FFh, 3 + + ; Dealer Area Top + invoke DrawString8x8, 25, 20, OFFSET textBJ3D, 0000D7FFh + invoke DrawString8x8, 25, 35, OFFSET textDealer3D, 00FFFFFFh + invoke FormatNumber, bjDealerScore, OFFSET hudNumBuffer + invoke DrawString8x8, 120, 35, OFFSET hudNumBuffer, 0000FFFFh + + ; 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, 0000D7FFh, 1 + cmp BYTE PTR [bjOutcomeMsg], 0 + je draw_bj_controls + invoke DrawString8x8, 28, 188, OFFSET bjOutcomeMsg, 0000FFFFh + 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 PlaySoundA, 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, 0000D7FFh, 3 + + ; 2.5D Rotating Wheel on Left + invoke DrawCircle, 85, 110, 65, 00102550h + invoke DrawCircle, 85, 110, 60, 0000D7FFh + invoke DrawCircle, 85, 110, 52, 00101010h + invoke DrawCircle, 85, 110, 22, 0000D7FFh ; 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000FFFFh, 2 +@@: + cmp roulBetType, 2 + jne @F + invoke DrawBoxBorder, 173, 58, 129, 32, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 3 + jne @F + invoke DrawBoxBorder, 173, 93, 129, 32, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 4 + jne @F + invoke DrawBoxBorder, 173, 128, 64, 30, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 5 + jne draw_ro_footer + invoke DrawBoxBorder, 238, 128, 64, 30, 0, 0000FFFFh, 2 + +draw_ro_footer: + invoke DrawBoxBorder, 20, 180, 280, 42, 00101015h, 0000D7FFh, 1 + + cmp roulState, 2 + jne @F + invoke DrawString8x8, 28, 186, OFFSET textResult3D, 0000D7FFh + invoke FormatNumber, roulWinningNum, OFFSET hudNumBuffer + invoke DrawString8x8, 85, 186, OFFSET hudNumBuffer, 0000FFFFh + 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, 0000D7FFh, 3 + invoke DrawString8x8, 25, 20, OFFSET textShop3D, 0000D7FFh + + invoke DrawBoxBorder, 20, 40, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 46, OFFSET textItem1_3D, 0000FFFFh + invoke DrawString8x8, 28, 58, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 80, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 86, OFFSET textItem2_3D, 0000FFFFh + invoke DrawString8x8, 28, 98, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 120, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 126, OFFSET textItem3_3D, 0000FFFFh + invoke DrawString8x8, 28, 138, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 165, 280, 55, 00100A0Ah, 0000D7FFh, 1 + invoke DrawString8x8, 28, 172, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 0000FFFFh + + 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 + +; --- Player Input & Movement Physics --- +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: + ret +CheckInteractions ENDP + +Trigger3DInteraction PROC + mov eax, interactTargetId + test eax, eax + jz @F + + cmp eax, 8 ; DANCER + jne check_target_slots + cmp bankroll, 100 + jl dancer_no_cash + sub bankroll, 100 + inc dancerLuckBuff + ; Tips are cosmetic and must not silently change game odds. + invoke CopyString3D, OFFSET textTips3D, OFFSET flashMessage + mov flashTimer, 100 + invoke PlaySoundA, OFFSET soundJackpot, 0, 1 + ret +dancer_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + ret + +check_target_slots: + cmp eax, 3 ; SLOTS + jne check_target_bj + mov engineMode, MODE_SLOTS + invoke PlaySoundA, OFFSET soundClick, 0, 1 + ret + +check_target_bj: + cmp eax, 1 ; BLACKJACK + jne check_target_roulette + mov engineMode, MODE_BLACKJACK + mov bjState, 0 + ret + +check_target_roulette: + cmp eax, 4 ; ROULETTE + jne check_target_shop + mov engineMode, MODE_ROULETTE + mov roulState, 0 + ret + +check_target_shop: + cmp eax, 6 ; SHOP + jne check_target_atm + mov engineMode, MODE_SHOP + ret + +check_target_atm: + cmp eax, 7 ; ATM + jne target_unported + mov engineMode, MODE_ATM + ret +target_unported: + invoke CopyString3D, OFFSET textUnavailable3D, OFFSET flashMessage + mov flashTimer, 150 +@@: + 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 Create3DWindow + test eax, eax + jz init_failed + call LoadTextures3D + test eax, eax + jz init_failed + +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, 8 + 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, 8 + 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, 8 + mov casinoSprites[2*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer + + ; Sprite 3: Blackjack Table with Dealer (Front Center Left) + mov casinoSprites[3*SIZEOF SpriteObject].posX, (12 * FP_1 + FP_HALF) + mov casinoSprites[3*SIZEOF SpriteObject].posY, (10 * 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, 1 + mov casinoSprites[3*SIZEOF SpriteObject].promptPtr, OFFSET promptBlackjack + + ; Sprite 4: 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, 4 + mov casinoSprites[4*SIZEOF SpriteObject].promptPtr, OFFSET promptRoulette + + ; Sprite 5: Poker Table (Front Center Right) + mov casinoSprites[5*SIZEOF SpriteObject].posX, (21 * FP_1) + mov casinoSprites[5*SIZEOF SpriteObject].posY, (10 * 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, 1 + mov casinoSprites[5*SIZEOF SpriteObject].promptPtr, OFFSET promptPoker + + ; Sprite 6: Slot Machine 1 (West Arcade) + mov casinoSprites[6*SIZEOF SpriteObject].posX, (6 * FP_1) + mov casinoSprites[6*SIZEOF SpriteObject].posY, (8 * FP_1) + mov casinoSprites[6*SIZEOF SpriteObject].baseTexId, 24 + mov casinoSprites[6*SIZEOF SpriteObject].frameCount, 3 + mov casinoSprites[6*SIZEOF SpriteObject].curFrame, 0 + mov casinoSprites[6*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[6*SIZEOF SpriteObject].animSpeed, 8 + mov casinoSprites[6*SIZEOF SpriteObject].interactId, 3 + mov casinoSprites[6*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot1 + + ; Sprite 7: Slot Machine 2 (CloverPit) + mov casinoSprites[7*SIZEOF SpriteObject].posX, (6 * FP_1) + mov casinoSprites[7*SIZEOF SpriteObject].posY, (11 * FP_1) + mov casinoSprites[7*SIZEOF SpriteObject].baseTexId, 24 + mov casinoSprites[7*SIZEOF SpriteObject].frameCount, 3 + mov casinoSprites[7*SIZEOF SpriteObject].curFrame, 1 + mov casinoSprites[7*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[7*SIZEOF SpriteObject].animSpeed, 8 + mov casinoSprites[7*SIZEOF SpriteObject].interactId, 3 + mov casinoSprites[7*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot2 + + ; Sprite 8: Slot Machine 3 + mov casinoSprites[8*SIZEOF SpriteObject].posX, (6 * FP_1) + mov casinoSprites[8*SIZEOF SpriteObject].posY, (14 * FP_1) + mov casinoSprites[8*SIZEOF SpriteObject].baseTexId, 24 + mov casinoSprites[8*SIZEOF SpriteObject].frameCount, 3 + mov casinoSprites[8*SIZEOF SpriteObject].curFrame, 2 + mov casinoSprites[8*SIZEOF SpriteObject].animTimer, 0 + mov casinoSprites[8*SIZEOF SpriteObject].animSpeed, 8 + mov casinoSprites[8*SIZEOF SpriteObject].interactId, 3 + mov casinoSprites[8*SIZEOF SpriteObject].promptPtr, OFFSET promptSlot1 + + ; Sprite 9: Bartender / Bar Counter (East Wing) + mov casinoSprites[9*SIZEOF SpriteObject].posX, (26 * FP_1) + mov casinoSprites[9*SIZEOF SpriteObject].posY, (12 * FP_1) + mov casinoSprites[9*SIZEOF SpriteObject].baseTexId, 32 + 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, 6 + mov casinoSprites[9*SIZEOF SpriteObject].promptPtr, OFFSET promptShop + + ; Sprite 10: ATM Bank Terminal (East Wing) + mov casinoSprites[10*SIZEOF SpriteObject].posX, (26 * FP_1) + mov casinoSprites[10*SIZEOF SpriteObject].posY, (16 * FP_1) + mov casinoSprites[10*SIZEOF SpriteObject].baseTexId, 33 + 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, 7 + mov casinoSprites[10*SIZEOF SpriteObject].promptPtr, OFFSET promptATM + + ; Sprite 11: Underground Table (South Wing) + mov casinoSprites[11*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF) + mov casinoSprites[11*SIZEOF SpriteObject].posY, (24 * FP_1) + mov casinoSprites[11*SIZEOF SpriteObject].baseTexId, 34 + 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, 5 + mov casinoSprites[11*SIZEOF SpriteObject].promptPtr, OFFSET promptBackroom + + ; Sprite 12: Secret Demon Portal (South Wing) + mov casinoSprites[12*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF) + mov casinoSprites[12*SIZEOF SpriteObject].posY, (29 * FP_1) + mov casinoSprites[12*SIZEOF SpriteObject].baseTexId, 4 + 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, 9 + mov casinoSprites[12*SIZEOF SpriteObject].promptPtr, OFFSET promptHell + + mov eax, 1 + jmp init_return +init_failed: + xor eax, eax +init_return: + pop edi + pop esi + pop ebx + ret +Init3DEngine ENDP + +; --- 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_WALK + jne leave_table + xor paused3D, 1 + jmp engine_tick +leave_table: + ; An already paid round cannot be skipped or settled twice. + cmp slotSpinState, 1 + je engine_tick + cmp roulState, 1 + je engine_tick + mov engineMode, MODE_WALK +engine_tick: + cmp paused3D, 0 + jne draw_pause + mov eax, deltaTime3D + add animationClock3D, eax + cmp engineMode, MODE_WALK + jne check_slots_mode + call UpdateCamera3D + call CheckInteractions + call HandlePlayerInput + call UpdateCamera3D + call RenderCeilingAndFloor + call RenderWalls + call RenderSprites + call RenderHUD + call RenderMinimap + jmp present_frame +check_slots_mode: + cmp engineMode, MODE_SLOTS + jne check_bj_mode + call HandleSlotsInput + call RenderSlotsGame + jmp present_frame +check_bj_mode: + cmp engineMode, MODE_BLACKJACK + jne check_roul_mode + call HandleBlackjackInput + call RenderBlackjackGame + jmp present_frame +check_roul_mode: + cmp engineMode, MODE_ROULETTE + jne check_shop_mode + call HandleRouletteInput + call RenderRouletteGame + jmp present_frame +check_shop_mode: + cmp engineMode, MODE_SHOP + jne check_atm_mode + call HandleShopInput + call RenderShopGame + jmp present_frame +check_atm_mode: + call HandleATMInput + call RenderATMGame + jmp present_frame +draw_pause: + invoke DrawBoxBorder, 65, 75, 190, 85, 00151C21h, 00D8BC6Ah, 2 + invoke DrawString8x8, 86, 88, OFFSET textPause3D, 00FFFFFFh + invoke DrawString8x8, 78, 111, OFFSET textResume3D, 00D8BC6Ah + invoke DrawString8x8, 78, 131, OFFSET textQuit3D, 00BBBBBBh + invoke Pressed3D, 51h + test eax, eax + jnz engine_shutdown +present_frame: + call Present3D + lea edi, pressedKeys3D + xor eax, eax + mov ecx, 64 + rep stosd + invoke GetTickCount + sub eax, frameStart3D + cmp eax, 16 + jae engine_loop + mov ecx, 16 + sub ecx, eax + invoke Sleep, ecx + jmp engine_loop +engine_idle: + invoke Sleep, 50 + jmp engine_loop +engine_shutdown: + call SaveProgress3D + 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 diff --git a/backups/casino3d_before_full_fix.inc b/backups/casino3d_before_full_fix.inc new file mode 100644 index 0000000..549c02a --- /dev/null +++ b/backups/casino3d_before_full_fix.inc @@ -0,0 +1,5228 @@ + +; ============================================================================== +; 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 +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 + +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 + +.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 "Assembler Casino - 2.5D",0 +szTexturesRelPath db "assets\textures\casino3d-hd.bin",0 +szTexturesFullPath db 260 dup(0) + +soundCoin db "assets\audio\Çâóê ìîíåòû áðîøåííîé â âîçäóõ è óïàâøåé íà ïîâåðõíîñòü.wav",0 +soundCoinDing db "assets\audio\Çâóê ìîíåòû â èãðå Ultrakill.wav",0 +soundCards db "assets\audio\playing_cards_deck_flick_through_001_20485.wav",0 +soundRoulette db "assets\audio\roulette-wheel-throw-2.wav",0 +soundJackpot db "assets\audio\Äæýê ïîò.wav",0 +soundVictory db "assets\audio\victory-tf2.wav",0 +soundClick db "assets\audio\revolverdryfirec.wav",0 +soundShuffle db "assets\audio\moving-stone.wav",0 +soundLose db "assets\audio\Ïðîèãðûø.wav",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 "[E] ÏÎÊÅÐ (TEXAS HOLD'EM)",0 +promptDurak db "[E] ÊÀÐÒÛ: ÏÎÄÊÈÄÍÎÉ ÄÓÐÀÊ",0 +promptCasinoRoulette db "[E] ÅÂÐÎÏÅÉÑÊÀß ÐÓËÅÒÊÀ",0 +promptClassicSlot db "[E] ÊËÀÑÑÈ×ÅÑÊÈÅ ÑËÎÒÛ 777",0 +promptCloverSlot db "[E] ÑËÎÒÛ CLOVERPIT (5x3)",0 +promptDice db "[E] ÈÃÐÀ  ÊÎÑÒÈ (CRAPS)",0 +promptSkulls db "[E] ÍÀϨÐÑÒÊÈ (×ÅÐÅÏÀ)",0 +promptCoin db "[E] ÌÎÍÅÒÊÀ (ÎШË/ÐÅØÊÀ)",0 +promptSkillCheck db "[E] ÒÐÅÍÈÐÎÂÊÀ ÐÅÀÊÖÈÈ",0 +promptBuckshot db "[E] BUCKSHOT ROULETTE",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 "[KAZIK 3D CASINO] - ÁËÝÊÄÆÅÊ (21)",0 +szTitlePoker db "[KAZIK 3D CASINO] - ÏÎÊÅÐ (TEXAS HOLD'EM)",0 +szTitleDurak db "[KAZIK 3D CASINO] - ÏÎÄÊÈÄÍÎÉ ÄÓÐÀÊ",0 +szTitleCasinoRoulette db "[KAZIK 3D CASINO] - ÅÂÐÎÏÅÉÑÊÀß ÐÓËÅÒÊÀ",0 +szTitleClassicSlot db "[KAZIK 3D CASINO] - ÊËÀÑÑÈ×ÅÑÊÈÅ ÑËÎÒÛ 777",0 +szTitleCloverSlot db "[KAZIK 3D CASINO] - ÑËÎÒ-ÌÀØÈÍÀ CLOVERPIT (5x3)",0 +szTitleDice db "[KAZIK 3D CASINO] - ÈÃÐÀ  ÊÎÑÒÈ (CRAPS)",0 +szTitleSkulls db "[KAZIK 3D CASINO] - ÍÀϨÐÑÒÊÈ",0 +szTitleCoin db "[KAZIK 3D CASINO] - ÌÎÍÅÒÊÀ (ÎШË/ÐÅØÊÀ)",0 +szTitleSkillCheck db "[KAZIK 3D CASINO] - ÏÐÎÂÅÐÊÀ ÐÅÀÊÖÈÈ",0 +szTitleBuckshot db "[KAZIK 3D CASINO] - BUCKSHOT ROULETTE",0 +szTitleRussianRoulette db "[KAZIK 3D CASINO] - ÐÓÑÑÊÀß ÐÓËÅÒÊÀ",0 +szTitleOnlineRR db "[KAZIK 3D CASINO] - ÑÅÒÅÂÀß ÐÓÑÑÊÀß ÐÓËÅÒÊÀ",0 +szTitleUmamusume db "[KAZIK 3D CASINO] - ÑÊÀ×ÊÈ ÓÌÀÌÓÑÓÌÝ",0 +szTitleHellTower db "[KAZIK 3D CASINO] - ÁÀØÍß ÀÄÀ (ÒÓÐÍÈÐ)",0 +szTitleShop db "[KAZIK 3D CASINO] - ÁÓÒÈÊ È ÒÀËÈÑÌÀÍÛ",0 +szTitleATM db "[KAZIK 3D CASINO] - ÁÀÍÊÎÌÀÒ",0 +szTitleTerminal db "[KAZIK 3D CASINO] - ÒÅÐÌÈÍÀË ÈÃÐÎÊÀ",0 +szTitleObserver db "[KAZIK 3D CASINO] - ÐÅÆÈÌ ÍÀÁËÞÄÀÒÅËß (ÈÈ)",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) + +; --- Native 2.5D Coin Flip Game --- +coin3d_bet dd 50 +coin3d_side 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 + +coinRxAnimTable db 26, 22, 16, 6, 16, 22, 26, 22, 16, 6 + +; --- Native 2.5D Coin Flip --- +textCoinTitle db "* * * Ç Î Ë Î Ò À ß Ì Î Í Å Ò À * * *",0 +textCoinHeads db "ÎШË",0 +textCoinTails db "ÐÅØÊÀ",0 +textCoinStreak db "ÑÅÐÈß: ",0 +textCoinSide1 db "[1] ÎШË",0 +textCoinSide2 db "[2] ÐÅØÊÀ",0 +textCoinFlipping db "ÌÎÍÅÒÀ  ÏÎ˨ÒÅ...",0 +textCoinWin db "ÂÛÈÃÐÛØ: +$",0 +textCoinLose db "ÍÅ ÓÃÀÄÀË!",0 +textCoinKey1 db "1:ÎШË",0 +textCoinKey2 db "2:ÐÅØÊÀ",0 +textCoinKeySpace db "ÏÐÎÁÅË:ÁÐÎÑÎÊ",0 +textCoinStreakFmt db "ÑÅÐÈß: [X] [X] [X] [ ] [ ] x4!",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 "=== G R A N D C R A P S ===",0 +textDiceSubtitle db "[ PASS LINE ] [ ANY CRAPS ]",0 +textDiceEven db "[1] רÒ",0 +textDiceOdd db "[2] ÍÅ×ÅÒ",0 +textDiceEvenNums db "2 4 6 8 10",0 +textDiceOddNums db "3 5 7 9 11",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 "ÏÐÎÁÅË:ÁÐÎÑÎÊ",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 + +textSkullsTitle db "+ + + Í À Ï ¨ Ð Ñ Ò Ê È + + +",0 +textSkullsPhase0 db "ÄÅËÀÉ ÑÒÀÂÊÓ È ÆÌÈ [ÏÐÎÁÅË]",0 +textSkullsPhase1 db "ÑÌÎÒÐÈ, ÃÄÅ ÇÎËÎÒÎÉ ØÀÐ...",0 +textSkullsPhase2 db "ÊÐÓ×Ó, ÂÅÐ×Ó, ÇÀÏÓÒÀÒÜ ÕÎ×Ó...",0 +textSkullsPhase3 db "ÃÄÅ ØÀÐ? ÂÛÁÈÐÀÉ: [1], [2] ÈËÈ [3]!",0 +textSkullsWin db "ÂÅÐÍÎ! ÂÛÏËÀÒÀ x3! +$",0 +textSkullsLose db "ÌÈÌÎ! ØÀÐ ÁÛË Â ÄÐÓÃÎÌ ÌÅÑÒÅ!",0 +textSkullsAgain db "[ÏÐÎÁÅË] - ÑÛÃÐÀÒÜ Å٨ ÐÀÇ",0 +textSkullsKey1 db "1:ÊÓÁÎÊ",0 +textSkullsKey2 db "2:ÊÓÁÎÊ",0 +textSkullsKey3 db "3:ÊÓÁÎÊ",0 +textSkullsKeySpace 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 "ÍÈ×Üß (PUSH)",0 +strDealerBust db "ÄÈËÅÐ ÏÅÐÅÁÐÀË! ÏÎÁÅÄÀ! +$",0 +strPlayerBust db "ÏÅÐÅÁÎÐ (>21)! ÏÐÎÈÃÐÛØ",0 + +sym7 db " 777 ",0 +symBar db " BAR ",0 +symBell db " BELL",0 +symCherry db "CHERRY",0 +symClover db "CLOVER",0 +symGem db " GEM ",0 +symCrown db "CROWN",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 (48 * 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 --- +RenderCeilingAndFloor PROC uses ebx esi edi + local floorRow:DWORD + local pDist:DWORD + local fStepX:DWORD + local fStepY:DWORD + local fX:DWORD + local fY:DWORD + local shade:DWORD + local cShade:DWORD + + ; Horizon line: row 120 + mov edi, HALF_H +floor_scanlines: + cmp edi, SCREEN_H + jge floor_done + mov floorRow, edi + + ; Distance = (HALF_H * FP_1) / (y - HALF_H) + mov eax, edi + sub eax, HALF_H + inc eax + mov ecx, eax + mov eax, HALF_H * FP_1 + cdq + idiv ecx + mov pDist, eax + + ; Distance shading (closer is brighter, far horizon is dark) + mov edx, pDist + shr edx, 13 + mov eax, 255 + sub eax, edx + cmp eax, 35 + jge @F + mov eax, 35 +@@: + mov shade, eax + mov edx, eax + sub edx, 25 + cmp edx, 20 + jge @F + mov edx, 20 +@@: + mov cShade, edx + + ; Step along scanline: (2 * playerPlane) * pDist / SCREEN_W + mov eax, playerPlaneX + shl eax, 1 + imul pDist + shrd eax, edx, 16 + cdq + mov ecx, SCREEN_W + idiv ecx + mov fStepX, eax + + mov eax, playerPlaneY + shl eax, 1 + imul pDist + shrd eax, edx, 16 + cdq + mov ecx, SCREEN_W + idiv ecx + mov fStepY, eax + + ; Starting floor coordinates at x=0: + ; player + pDist * (playerDir - playerPlane) + mov eax, playerDirX + sub eax, playerPlaneX + imul pDist + shrd eax, edx, 16 + add eax, playerX + mov fX, eax + + mov eax, playerDirY + sub eax, playerPlaneY + imul pDist + shrd eax, edx, 16 + add eax, playerY + mov fY, eax + + ; Fill scanline for floor (y) and ceiling (SCREEN_H - 1 - y) + xor esi, esi +col_floor_loop: + cmp esi, SCREEN_W + jge next_floor_row + + ; Carpet Texture (Slot 3: 3 * 4096 * 4 = 49152 bytes) + mov eax, fX + shr eax, 9 + and eax, 127 + mov edx, fY + shr edx, 9 + and edx, 127 + shl edx, 7 + add edx, eax + + mov eax, [texturesBuffer + (3 * 128 * 128 * 4) + edx*4] + + ; Shade Floor RGB + mov ebx, shade + movzx ecx, al + imul ecx, ebx + shr ecx, 8 + push ecx + + movzx ecx, ah + imul ecx, ebx + shr ecx, 8 + shl ecx, 8 + + shr eax, 16 + movzx eax, al + imul eax, ebx + shr eax, 8 + shl eax, 16 + or eax, ecx + pop ecx + or eax, ecx + + ; Store to Floor pixel + mov ecx, floorRow + imul ecx, SCREEN_W + add ecx, esi + mov [screenBuffer + ecx*4], eax + + ; Ceiling Spotlight Texture (Slot 5: 5 * 4096 * 4 = 81920 bytes) + mov eax, [texturesBuffer + (5 * 128 * 128 * 4) + edx*4] + mov ebx, cShade + movzx ecx, al + imul ecx, ebx + shr ecx, 8 + push ecx + + movzx ecx, ah + imul ecx, ebx + shr ecx, 8 + shl ecx, 8 + + shr eax, 16 + movzx eax, al + imul eax, ebx + shr eax, 8 + shl eax, 16 + or eax, ecx + pop ecx + or eax, ecx + + ; Store to Ceiling pixel: (SCREEN_H - 1 - floorRow) + mov ecx, SCREEN_H - 1 + sub ecx, floorRow + imul ecx, SCREEN_W + add ecx, esi + mov [screenBuffer + ecx*4], eax + + mov eax, fStepX + add fX, eax + mov eax, fStepY + add fY, eax + inc esi + jmp col_floor_loop + +next_floor_row: + inc edi + jmp floor_scanlines + +floor_done: + ret +RenderCeilingAndFloor ENDP + +; --- DDA Raycasting Walls --- +RenderWalls PROC + local col: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 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 hit_wall + + 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 hit_wall + cmp mapX, MAP_WIDTH + jge hit_wall + cmp mapY, 0 + jl hit_wall + cmp mapY, MAP_HEIGHT + jge hit_wall + + mov eax, mapY + shl eax, 5 + add eax, mapX + movzx eax, BYTE PTR [casinoMap + eax] + test eax, eax + jnz hit_wall + jmp dda_step_loop + +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 + + ; High casino ceiling: lineH = (SCREEN_H * FP_1 * 180 / 240) / perpWallDist + mov eax, SCREEN_H + imul eax, FP_1 + cdq + idiv perpWallDist + mov lineH, eax + + mov eax, lineH + shr eax, 1 + mov ecx, HALF_H + sub ecx, eax + mov drawStart, ecx + + mov eax, lineH + shr eax, 1 + mov ecx, HALF_H + add ecx, eax + mov drawEnd, ecx + + 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 + 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 +@@: + cmp side, 1 + jne select_tex + cmp rayDirY, 0 + jge select_tex + mov eax, 127 + sub eax, texX + mov texX, eax + +select_tex: + mov eax, mapY + shl eax, 5 + add eax, mapX + movzx eax, BYTE PTR [casinoMap + 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, lineH + shr eax, 1 + add eax, drawStart + sub eax, HALF_H + 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 + shl eax, 7 + add eax, texX + + mov edx, texId + shl edx, 14 + add eax, edx + mov eax, [texturesBuffer + eax*4] + + ; Shade wall pixel + mov ebx, shade + 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 --- +RenderSprites PROC + local sprIdx:DWORD + local relX:DWORD + local relY:DWORD + local invDet:DWORD + local transX:DWORD + local transY:DWORD + local sprScreenX:DWORD + local sprH:DWORD + local sprW:DWORD + local drawStartY:DWORD + local drawEndY:DWORD + local drawStartX:DWORD + local drawEndX:DWORD + local stripe:DWORD + local texX:DWORD + local texY:DWORD + local shade:DWORD + local texSlot:DWORD + + push ebx + push esi + push edi + + xor esi, esi +calc_dist_loop: + cmp esi, NUM_SPRITES + jge sort_sprites + mov eax, esi + imul eax, SIZEOF SpriteObject + + mov edx, [casinoSprites + eax].posX + sub edx, playerX + sar edx, 8 + imul edx, edx + mov ebx, edx + + mov edx, [casinoSprites + eax].posY + sub edx, playerY + sar edx, 8 + imul edx, edx + add ebx, edx + + mov [casinoSprites + eax].distSq, ebx + mov [sortedSprites + esi*4], esi + inc esi + jmp calc_dist_loop + +sort_sprites: + xor esi, esi +sort_outer: + cmp esi, NUM_SPRITES - 1 + jge render_sorted_sprites + mov edi, esi + inc edi +sort_inner: + cmp edi, NUM_SPRITES + jge next_sort_outer + + mov eax, [sortedSprites + esi*4] + imul eax, SIZEOF SpriteObject + mov eax, [casinoSprites + eax].distSq + + mov ebx, [sortedSprites + edi*4] + imul ebx, SIZEOF SpriteObject + mov ebx, [casinoSprites + ebx].distSq + + cmp eax, ebx + jge @F + mov ecx, [sortedSprites + esi*4] + mov edx, [sortedSprites + edi*4] + mov [sortedSprites + esi*4], edx + mov [sortedSprites + edi*4], ecx +@@: + inc edi + jmp sort_inner +next_sort_outer: + inc esi + jmp sort_outer + +render_sorted_sprites: + xor esi, esi +draw_spr_loop: + cmp esi, NUM_SPRITES + jge sprites_rendered + + mov eax, [sortedSprites + esi*4] + mov sprIdx, eax + imul eax, SIZEOF SpriteObject + + ; Sample animation by elapsed time. Pausing freezes the clock. + push eax + mov ecx, [casinoSprites + eax].animSpeed + cmp ecx, 0 + jg @F + mov ecx, 1 +@@: + imul ecx, 40 + mov eax, animationClock3D + xor edx, edx + div ecx + pop ebx + mov ecx, [casinoSprites + ebx].frameCount + cmp ecx, 0 + jg @F + mov ecx, 1 +@@: + xor edx, edx + div ecx + mov [casinoSprites + ebx].curFrame, edx + mov eax, ebx + + cmp [casinoSprites + eax].distSq, 16 + jle next_spr + + mov edx, [casinoSprites + eax].posX + sub edx, playerX + mov relX, edx + + mov edx, [casinoSprites + eax].posY + sub edx, playerY + mov relY, edx + + mov eax, playerPlaneX + imul playerDirY + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerDirX + imul playerPlaneY + shrd eax, edx, 16 + sub ebx, eax + + mov eax, ebx + test eax, eax + jns @F + neg eax +@@: + cmp eax, 4 + jbe next_spr + + ; 2^32 needs the full EDX:EAX dividend, not a truncated multiply. + xor eax, eax + mov edx, 1 + idiv ebx + mov invDet, eax + + mov eax, playerDirY + imul relX + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerDirX + imul relY + shrd eax, edx, 16 + sub ebx, eax + + mov eax, ebx + imul invDet + shrd eax, edx, 16 + mov transX, eax + + mov eax, playerPlaneY + neg eax + imul relX + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerPlaneX + imul relY + shrd eax, edx, 16 + add ebx, eax + + mov eax, ebx + imul invDet + shrd eax, edx, 16 + mov transY, eax + + cmp transY, 4096 + jle next_spr + + mov eax, transX + imul eax, HALF_W + cdq + idiv transY + add eax, HALF_W + mov sprScreenX, eax + + mov eax, SCREEN_H + imul eax, FP_1 + cdq + idiv transY + test eax, eax + jns @F + neg eax +@@: + cmp eax, 1 + jge @F + jmp next_spr +@@: + cmp eax, SCREEN_H * 2 + jle @F + mov eax, SCREEN_H * 2 +@@: + mov sprH, eax + mov sprW, eax + + mov eax, HALF_H + mov ebx, sprH + shr ebx, 1 + sub eax, ebx + mov drawStartY, eax + add eax, sprH + mov drawEndY, eax + + mov eax, sprScreenX + mov ebx, sprW + shr ebx, 1 + sub eax, ebx + mov drawStartX, eax + add eax, sprW + mov drawEndX, eax + + cmp drawStartY, 0 + jge @F + mov drawStartY, 0 +@@: + cmp drawEndY, SCREEN_H + jl @F + mov drawEndY, SCREEN_H - 1 +@@: + + mov eax, transY + shr eax, 13 + mov edx, 256 + sub edx, eax + cmp edx, 110 + jge @F + mov edx, 110 +@@: + mov shade, edx + + mov eax, sprIdx + imul eax, SIZEOF SpriteObject + mov edx, [casinoSprites + eax].baseTexId + add edx, [casinoSprites + eax].curFrame + mov texSlot, edx + + mov eax, drawStartX + mov stripe, eax + +spr_stripe_loop: + mov eax, stripe + cmp eax, drawEndX + jge next_spr + + cmp eax, 0 + jl next_spr_stripe + cmp eax, SCREEN_W + jge next_spr + + mov edx, transY + cmp edx, [zBuffer + eax*4] + jge next_spr_stripe + + mov eax, stripe + sub eax, sprScreenX + mov ebx, sprW + shr ebx, 1 + add eax, ebx + shl eax, 7 + cdq + idiv sprW + cmp eax, 0 + jl next_spr_stripe + cmp eax, 128 + jge next_spr_stripe + mov texX, eax + + mov edi, drawStartY +spr_pix_y_loop: + cmp edi, drawEndY + jg next_spr_stripe + + mov eax, edi + sub eax, HALF_H + mov ebx, sprH + shr ebx, 1 + add eax, ebx + shl eax, 7 + cdq + idiv sprH + cmp eax, 0 + jl next_spr_y + cmp eax, 128 + jge next_spr_y + mov texY, eax + + shl eax, 7 + add eax, texX + mov edx, texSlot + shl edx, 14 + add eax, edx + mov eax, [texturesBuffer + eax*4] + + ; Chromakey magenta filter + cmp eax, CHROMA_KEY + je next_spr_y +do_draw_sprite_pix: + mov ebx, shade + 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 ecx, edi + imul ecx, SCREEN_W + add ecx, stripe + mov [screenBuffer + ecx*4], eax + +next_spr_y: + inc edi + jmp spr_pix_y_loop + +next_spr_stripe: + inc stripe + jmp spr_stripe_loop + +next_spr: + inc esi + jmp draw_spr_loop + +sprites_rendered: + pop edi + pop esi + pop ebx + ret +RenderSprites ENDP + +; --- 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, 0000D7FFh, 1 + + ; Draw Sprites on 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, 000000FFh + 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 PlaySoundA, OFFSET soundClick, 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, 0000D7FFh, 3 + + ; Illuminated Top Marquee + invoke DrawBoxBorder, 25, 20, 270, 32, 000A0505h, 0000FFFFh, 2 + invoke DrawString8x8, 55, 32, OFFSET textSlots3D, 0000D7FFh + + ; 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 PlaySoundA, 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 PlaySoundA, OFFSET soundJackpot, 0, 1 + jmp draw_reels +@@: + mov eax, slotBet + imul eax, 10 + mov slotWinAmount, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000D7FFh, 1 + + invoke DrawString8x8, 28, 172, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 175, 172, OFFSET textBet3D, 0000D7FFh + 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, 0000FFFFh + invoke FormatNumber, slotWinAmount, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 187, OFFSET hudNumBuffer, 0000FFFFh + +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, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + ret +DrawReelSymbolAt1 ENDP + +DrawReelSymbolAt2 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 135, 105, OFFSET sym7, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + ret +DrawReelSymbolAt2 ENDP + +DrawReelSymbolAt3 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 218, 105, OFFSET sym7, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + 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 PlaySoundA, 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 PlaySoundA, OFFSET soundJackpot, 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 PlaySoundA, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000D7FFh, 3 + + ; Dealer Area Top + invoke DrawString8x8, 25, 20, OFFSET textBJ3D, 0000D7FFh + invoke DrawString8x8, 25, 35, OFFSET textDealer3D, 00FFFFFFh + invoke FormatNumber, bjDealerScore, OFFSET hudNumBuffer + invoke DrawString8x8, 120, 35, OFFSET hudNumBuffer, 0000FFFFh + + ; 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, 0000D7FFh, 1 + cmp BYTE PTR [bjOutcomeMsg], 0 + je draw_bj_controls + invoke DrawString8x8, 28, 188, OFFSET bjOutcomeMsg, 0000FFFFh + 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 PlaySoundA, 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, 0000D7FFh, 3 + + ; 2.5D Rotating Wheel on Left + invoke DrawCircle, 85, 110, 65, 00102550h + invoke DrawCircle, 85, 110, 60, 0000D7FFh + invoke DrawCircle, 85, 110, 52, 00101010h + invoke DrawCircle, 85, 110, 22, 0000D7FFh ; 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000FFFFh, 2 +@@: + cmp roulBetType, 2 + jne @F + invoke DrawBoxBorder, 173, 58, 129, 32, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 3 + jne @F + invoke DrawBoxBorder, 173, 93, 129, 32, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 4 + jne @F + invoke DrawBoxBorder, 173, 128, 64, 30, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 5 + jne draw_ro_footer + invoke DrawBoxBorder, 238, 128, 64, 30, 0, 0000FFFFh, 2 + +draw_ro_footer: + invoke DrawBoxBorder, 20, 180, 280, 42, 00101015h, 0000D7FFh, 1 + + cmp roulState, 2 + jne @F + invoke DrawString8x8, 28, 186, OFFSET textResult3D, 0000D7FFh + invoke FormatNumber, roulWinningNum, OFFSET hudNumBuffer + invoke DrawString8x8, 85, 186, OFFSET hudNumBuffer, 0000FFFFh + 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, 0000D7FFh, 3 + invoke DrawString8x8, 25, 20, OFFSET textShop3D, 0000D7FFh + + invoke DrawBoxBorder, 20, 40, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 46, OFFSET textItem1_3D, 0000FFFFh + invoke DrawString8x8, 28, 58, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 80, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 86, OFFSET textItem2_3D, 0000FFFFh + invoke DrawString8x8, 28, 98, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 120, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 126, OFFSET textItem3_3D, 0000FFFFh + invoke DrawString8x8, 28, 138, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 165, 280, 55, 00100A0Ah, 0000D7FFh, 1 + invoke DrawString8x8, 28, 172, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 0000FFFFh + + 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 capW:DWORD + ; Compute string length + mov esi, strPtr + xor ecx, ecx +@@: + mov al, [esi+ecx] + test al, al + jz @F + inc ecx + jmp @B +@@: + shl ecx, 3 ; length * 8 + add ecx, 8 ; padding 8px + mov capW, ecx + + ; Drop shadow + mov eax, x + mov edx, y + add edx, 2 + invoke DrawBox, eax, edx, capW, 13, 0008080Ch + + ; Body & Border + mov eax, 00606870h ; default border + mov edx, 001A1C22h ; default fill + cmp isActive, 0 + je @F + mov eax, 0000FFFFh ; active gold border + mov edx, 001B4B22h ; active dark green fill +@@: + invoke DrawBoxBorder, x, y, capW, 13, edx, eax, 1 + + ; String text + mov eax, 00D0D8E0h + cmp isActive, 0 + je @F + mov eax, 0000FFFFh +@@: + mov edx, x + add edx, 4 + mov ecx, y + add ecx, 3 + invoke DrawString8x8, edx, ecx, strPtr, eax + mov eax, capW + ret +DrawKeycap3D ENDP + +DrawChipStack PROC uses ebx esi edi, x:DWORD, y:DWORD, chipCount:DWORD + xor esi, esi +chip_loop: + cmp esi, chipCount + jge chip_done + mov eax, esi + shl eax, 2 ; esi * 4 + mov edx, y + sub edx, eax ; cy = y - esi*4 + + ; Shadow + mov eax, x + add eax, 2 + mov ecx, edx + add ecx, 5 + invoke DrawBox, eax, ecx, 20, 2, 00041006h + + ; Chip body + invoke DrawBoxBorder, x, edx, 24, 6, 001515B8h, 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 + invoke DrawBox, eax, ecx, 3, 4, 00FFFFFFh + + inc esi + jmp chip_loop +chip_done: + ret +DrawChipStack ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: COIN FLIP (ÌÎÍÅÒÊÀ) +; ============================================================================== +DrawDetailedCoin PROC uses ebx esi edi, cxVal:DWORD, cyVal:DWORD, rxVal:DWORD, ryVal:DWORD, outerColor:DWORD, innerColor:DWORD, reliefType:DWORD + LOCAL curDY:DWORD, curDX:DWORD, rxSq:DWORD, rySq:DWORD, rxRySq:DWORD, threshSq:DWORD + cmp rxVal, 0 + jle coin_draw_ret + cmp ryVal, 0 + jle coin_draw_ret + + mov eax, rxVal + imul eax, eax + mov rxSq, eax + + mov eax, ryVal + imul eax, eax + mov rySq, eax + + mov eax, rxSq + imul eax, rySq + mov rxRySq, eax + + mov eax, rxRySq + shr eax, 2 + imul eax, 3 + mov threshSq, eax + + mov eax, ryVal + neg eax + mov curDY, eax + +coin_y_loop: + mov eax, curDY + cmp eax, ryVal + jg check_coin_relief + + mov eax, rxVal + neg eax + mov curDX, eax + +coin_x_loop: + mov eax, curDX + cmp eax, rxVal + jg next_coin_y + + mov eax, curDX + imul eax, eax + imul eax, rySq + mov ebx, curDY + imul ebx, ebx + imul ebx, rxSq + add eax, ebx + cmp eax, rxRySq + jg next_coin_x + + mov ecx, innerColor + cmp eax, threshSq + jb @F + mov ecx, outerColor +@@: + mov eax, cxVal + add eax, curDX + mov edx, cyVal + add edx, curDY + invoke DrawPixel, eax, edx, ecx + +next_coin_x: + inc curDX + jmp coin_x_loop + +next_coin_y: + inc curDY + jmp coin_y_loop + +check_coin_relief: + cmp rxVal, 14 + jl coin_draw_ret + cmp reliefType, 1 + je draw_eagle_relief + cmp reliefType, 2 + je draw_wreath_relief + jmp coin_draw_ret + +draw_eagle_relief: + ; Crown + mov eax, cxVal + sub eax, 3 + mov edx, cyVal + sub edx, 14 + invoke DrawBox, eax, edx, 7, 2, 00007A9Ah + mov eax, cxVal + sub eax, 4 + mov edx, cyVal + sub edx, 12 + invoke DrawBox, eax, edx, 9, 2, 00007A9Ah + + ; Body & Head + mov eax, cxVal + sub eax, 2 + mov edx, cyVal + sub edx, 9 + invoke DrawBox, eax, edx, 5, 12, 00007A9Ah + mov eax, cxVal + dec eax + mov edx, cyVal + sub edx, 8 + invoke DrawBox, eax, edx, 3, 10, 0000D7FFh + + ; Wings + mov eax, cxVal + sub eax, 10 + mov edx, cyVal + sub edx, 8 + invoke DrawBox, eax, edx, 7, 3, 00007A9Ah + mov eax, cxVal + sub eax, 13 + mov edx, cyVal + sub edx, 5 + invoke DrawBox, eax, edx, 10, 3, 00007A9Ah + mov eax, cxVal + sub eax, 11 + mov edx, cyVal + sub edx, 2 + invoke DrawBox, eax, edx, 7, 3, 00007A9Ah + + mov eax, cxVal + add eax, 4 + mov edx, cyVal + sub edx, 8 + invoke DrawBox, eax, edx, 7, 3, 00007A9Ah + mov eax, cxVal + add eax, 4 + mov edx, cyVal + sub edx, 5 + invoke DrawBox, eax, edx, 10, 3, 00007A9Ah + mov eax, cxVal + add eax, 5 + mov edx, cyVal + sub edx, 2 + invoke DrawBox, eax, edx, 7, 3, 00007A9Ah + + ; Tail + mov eax, cxVal + sub eax, 4 + mov edx, cyVal + add edx, 4 + invoke DrawBox, eax, edx, 9, 3, 00007A9Ah + mov eax, cxVal + sub eax, 3 + mov edx, cyVal + add edx, 7 + invoke DrawBox, eax, edx, 7, 3, 00007A9Ah + jmp coin_draw_ret + +draw_wreath_relief: + ; Roman numeral 'I' + mov eax, cxVal + sub eax, 5 + mov edx, cyVal + sub edx, 10 + invoke DrawBox, eax, edx, 11, 3, 00007A9Ah + mov eax, cxVal + sub eax, 2 + mov edx, cyVal + sub edx, 7 + invoke DrawBox, eax, edx, 5, 14, 00007A9Ah + mov eax, cxVal + dec eax + mov edx, cyVal + sub edx, 6 + invoke DrawBox, eax, edx, 3, 12, 0000D7FFh + mov eax, cxVal + sub eax, 6 + mov edx, cyVal + add edx, 7 + invoke DrawBox, eax, edx, 13, 3, 00007A9Ah + + ; Laurel dots left & right + mov eax, cxVal + sub eax, 12 + mov edx, cyVal + sub edx, 10 + invoke DrawBox, eax, edx, 2, 2, 00007A9Ah + mov eax, cxVal + add eax, 11 + mov edx, cyVal + sub edx, 10 + invoke DrawBox, eax, edx, 2, 2, 00007A9Ah + + mov eax, cxVal + sub eax, 12 + mov edx, cyVal + sub edx, 5 + invoke DrawBox, eax, edx, 2, 2, 00007A9Ah + mov eax, cxVal + add eax, 11 + mov edx, cyVal + sub edx, 5 + invoke DrawBox, eax, edx, 2, 2, 00007A9Ah + + mov eax, cxVal + sub eax, 12 + mov edx, cyVal + invoke DrawBox, eax, edx, 2, 2, 00007A9Ah + mov eax, cxVal + add eax, 11 + mov edx, cyVal + invoke DrawBox, eax, edx, 2, 2, 00007A9Ah + + mov eax, cxVal + sub eax, 12 + mov edx, cyVal + add edx, 5 + invoke DrawBox, eax, edx, 2, 2, 00007A9Ah + mov eax, cxVal + add eax, 11 + mov edx, cyVal + add edx, 5 + invoke DrawBox, eax, edx, 2, 2, 00007A9Ah + +coin_draw_ret: + ret +DrawDetailedCoin ENDP + +InitCoinGame PROC + mov coin3d_state, 0 + mov coin3d_timer, 0 + mov coin3d_win, 0 + cmp coin3d_bet, 10 + jge @F + mov coin3d_bet, 50 +@@: + ret +InitCoinGame ENDP + +HandleCoinInput PROC + cmp coin3d_state, 1 + je coin_input_done + + invoke Pressed3D, 20h ; SPACE -> Flip! + test eax, eax + jz check_coin_side + mov eax, bankroll + cmp eax, coin3d_bet + jl coin_no_cash + sub eax, coin3d_bet + mov bankroll, eax + mov coin3d_state, 1 + mov coin3d_timer, 0 + mov coin3d_win, 0 + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp coin_input_done + +coin_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp coin_input_done + +check_coin_side: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov coin3d_side, 1 + invoke PlaySoundA, OFFSET soundClick, 0, 1 +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz check_coin_bet_adjust + mov coin3d_side, 2 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + +check_coin_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz coin_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_coin_bet_down +coin_inc_bet: + invoke PlaySoundA, OFFSET soundClick, 0, 1 + cmp coin3d_bet, 500 + jge coin_input_done + cmp coin3d_bet, 250 + jge coin_set_500 + cmp coin3d_bet, 100 + jge coin_set_250 + cmp coin3d_bet, 50 + jge coin_set_100 + cmp coin3d_bet, 25 + jge coin_set_50 + jmp coin_set_25 +coin_set_500: + mov coin3d_bet, 500 + jmp coin_input_done +coin_set_250: + mov coin3d_bet, 250 + jmp coin_input_done +coin_set_100: + mov coin3d_bet, 100 + jmp coin_input_done +coin_set_50: + mov coin3d_bet, 50 + jmp coin_input_done +coin_set_25: + mov coin3d_bet, 25 + jmp coin_input_done + +check_coin_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz coin_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz coin_input_done +coin_dec_bet: + invoke PlaySoundA, OFFSET soundClick, 0, 1 + cmp coin3d_bet, 25 + jle coin_set_10 + cmp coin3d_bet, 50 + jle coin_set_25 + cmp coin3d_bet, 100 + jle coin_set_50 + cmp coin3d_bet, 250 + jle coin_set_100 + mov coin3d_bet, 250 + jmp coin_input_done +coin_set_10: + mov coin3d_bet, 10 + +coin_input_done: + ret +HandleCoinInput ENDP + +RenderCoinGame PROC uses ebx esi edi + LOCAL cyVal:DWORD, rxVal:DWORD, curX:DWORD + + ; Cabinet Bezel (Mahogany wood & leather) + invoke DrawBox, 0, 0, 320, 240, 00060914h + invoke DrawBoxBorder, 6, 6, 308, 228, 000F1522h, 001B2E48h, 3 + + ; Corner Brass Rivets + invoke DrawBox, 12, 12, 3, 3, 0000D7FFh + invoke DrawPixel, 13, 13, 00FFFFFFh + invoke DrawBox, 306, 12, 3, 3, 0000D7FFh + invoke DrawPixel, 307, 13, 00FFFFFFh + invoke DrawBox, 12, 226, 3, 3, 0000D7FFh + invoke DrawPixel, 13, 227, 00FFFFFFh + invoke DrawBox, 306, 226, 3, 3, 0000D7FFh + invoke DrawPixel, 307, 227, 00FFFFFFh + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 24, 12, 272, 26, 000A101Ch, 0000D7FFh, 2 + invoke DrawString8x8, 48, 21, OFFSET textCoinTitle, 0000FFFFh + + ; Bulb lights on marquee border + mov curX, 28 +coin_bulbs: + cmp curX, 292 + jge coin_meters + invoke DrawPixel, curX, 13, 0000FFFFh + invoke DrawPixel, curX, 36, 0000D7FFh + add curX, 12 + jmp coin_bulbs + +coin_meters: + ; Status Meters: Bank & Bet + invoke DrawBoxBorder, 20, 44, 114, 18, 000A1A0Eh, 001A4B22h, 1 + invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 0050FF50h + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawBoxBorder, 186, 44, 114, 18, 001A100Ah, 003A2814h, 1 + invoke DrawString8x8, 190, 49, OFFSET textBetPrompt, 0000D7FFh + invoke FormatNumber, coin3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 0000D7FFh + invoke DrawString8x8, 278, 49, OFFSET textBetHint, 00808080h + + ; Center Velvet Platter + invoke DrawCircle, 160, 110, 46, 000090C0h + invoke DrawCircle, 160, 110, 44, 0000D7FFh + invoke DrawCircle, 160, 110, 41, 00180824h + + ; Selection Podiums: [1] ÎШË + mov eax, 00121620h + mov edx, 00404855h + mov ecx, 0090A0B0h + cmp coin3d_side, 1 + jne @F + mov eax, 001C3822h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 20, 72, 76, 52, eax, edx, 2 + pop ecx + invoke DrawString8x8, 28, 78, OFFSET textCoinSide1, ecx + invoke DrawDetailedCoin, 58, 106, 12, 12, 0000A0D0h, 0000D7FFh, 1 + + ; Selection Podiums: [2] ÐÅØÊÀ + mov eax, 00121620h + mov edx, 00404855h + mov ecx, 0090A0B0h + cmp coin3d_side, 2 + jne @F + mov eax, 001C3822h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 224, 72, 76, 52, eax, edx, 2 + pop ecx + invoke DrawString8x8, 232, 78, OFFSET textCoinSide2, ecx + invoke DrawDetailedCoin, 262, 106, 12, 12, 000080A0h, 0000B0D0h, 2 + + ; Flipping animation logic + cmp coin3d_state, 1 + jne coin_at_rest + + inc coin3d_timer + + ; Parabolic toss: cy = 110 - (t * (40 - t)) / 14 + mov eax, coin3d_timer + mov ecx, 40 + sub ecx, eax + imul eax, ecx + xor edx, edx + mov ecx, 14 + div ecx + mov edx, 110 + sub edx, eax + mov cyVal, edx + + ; Width rx from lookup table: (t % 10) + mov eax, coin3d_timer + xor edx, edx + mov ecx, 10 + div ecx + movzx eax, BYTE PTR [coinRxAnimTable + edx] + mov rxVal, eax + + invoke DrawDetailedCoin, 160, cyVal, rxVal, 26, 0000A0D0h, 0000D7FFh, 0 + invoke DrawString8x8, 88, 160, OFFSET textCoinFlipping, 0000FFFFh + + cmp coin3d_timer, 40 + jl coin_draw_controls + + ; Flip complete! + mov coin3d_state, 2 + invoke RandomRange3D, 2 + inc eax + mov coin3d_result, eax + + mov eax, coin3d_result + cmp eax, coin3d_side + jne coin_flip_lost + + ; Won! + mov eax, coin3d_bet + shl eax, 1 + mov coin3d_win, eax + add bankroll, eax + inc coin3d_streak + cmp coin3d_streak, 3 + jl @F + invoke PlaySoundA, OFFSET soundVictory, 0, 1 + jmp coin_draw_controls +@@: + invoke PlaySoundA, OFFSET soundCoinDing, 0, 1 + jmp coin_draw_controls + +coin_flip_lost: + mov coin3d_streak, 0 + mov coin3d_win, 0 + invoke PlaySoundA, OFFSET soundLose, 0, 1 + jmp coin_draw_controls + +coin_at_rest: + ; Draw coin resting in velvet dish + mov edx, coin3d_side + cmp coin3d_state, 2 + jne @F + mov edx, coin3d_result +@@: + invoke DrawDetailedCoin, 160, 110, 26, 26, 0000A0D0h, 0000D7FFh, edx + + ; Outcome / Streak Display + cmp coin3d_state, 2 + jne coin_show_streak + + cmp coin3d_win, 0 + je coin_show_lose + invoke DrawBoxBorder, 44, 154, 232, 20, 000E141Eh, 0050FF50h, 1 + invoke DrawString8x8, 64, 160, OFFSET textCoinWin, 0050FF50h + invoke FormatNumber, coin3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 152, 160, OFFSET hudNumBuffer, 0050FF50h + jmp coin_draw_controls + +coin_show_lose: + invoke DrawBoxBorder, 44, 154, 232, 20, 000E141Eh, 000000FFh, 1 + invoke DrawString8x8, 114, 160, OFFSET textCoinLose, 008080FFh + jmp coin_draw_controls + +coin_show_streak: + invoke DrawBoxBorder, 44, 154, 232, 20, 000E141Eh, 0000D7FFh, 1 + invoke DrawString8x8, 52, 160, OFFSET textCoinStreakFmt, 0000FFFFh + +coin_draw_controls: + ; Keycaps Control Bar + invoke DrawBox, 16, 194, 288, 1, 001E2E40h + + mov eax, 0 + cmp coin3d_side, 1 + sete al + invoke DrawKeycap3D, 22, 202, OFFSET textCoinKey1, eax + + mov eax, 0 + cmp coin3d_side, 2 + sete al + invoke DrawKeycap3D, 88, 202, OFFSET textCoinKey2, eax + + invoke DrawKeycap3D, 160, 202, OFFSET textCoinKeySpace, 1 + invoke DrawKeycap3D, 274, 202, OFFSET textKeyEsc, 0 + ret +RenderCoinGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: DICE / CRAPS (ÊÎÑÒÈ) +; ============================================================================== +DrawCrapsDie PROC uses ebx esi edi, x:DWORD, y:DWORD, sizeVal:DWORD, valNum:DWORD + ; Drop shadow on green felt + mov eax, x + add eax, 3 + mov edx, y + add edx, sizeVal + invoke DrawBox, eax, edx, sizeVal, 3, 00031408h + mov eax, x + add eax, sizeVal + mov edx, y + add edx, 3 + invoke DrawBox, eax, edx, 3, sizeVal, 00031408h + + ; Ivory body & dark border + invoke DrawBoxBorder, x, y, sizeVal, sizeVal, 00F0F4FAh, 00353540h, 1 + + ; Bevel highlight top & left + mov eax, sizeVal + sub eax, 2 + mov edx, x + inc edx + mov ecx, y + inc ecx + invoke DrawBox, edx, ecx, eax, 1, 00FFFFFFh + invoke DrawBox, edx, ecx, 1, eax, 00FFFFFFh + + ; Bevel shadow bottom & right + mov edx, x + inc edx + mov ecx, y + add ecx, sizeVal + sub ecx, 2 + invoke DrawBox, edx, ecx, eax, 1, 00C0C6D0h + mov edx, x + add edx, sizeVal + sub edx, 2 + mov ecx, y + inc ecx + invoke DrawBox, edx, ecx, 1, eax, 00C0C6D0h + + ; Casino Ruby Red circular pips (radius 3) + cmp valNum, 1 + je draw_die_c + cmp valNum, 3 + je draw_die_c + cmp valNum, 5 + je draw_die_c + jmp check_die_pips_corners + +draw_die_c: + mov eax, x + add eax, 18 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 3, 001515C8h + dec eax + dec edx + invoke DrawPixel, eax, edx, 00FFFFFFh + +check_die_pips_corners: + cmp valNum, 2 + jl die_pips_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 3, 001515C8h + mov eax, x + add eax, sizeVal + sub eax, 10 + mov edx, y + add edx, sizeVal + sub edx, 10 + invoke DrawCircle, eax, edx, 3, 001515C8h + + cmp valNum, 4 + jl die_pips_done + mov eax, x + add eax, sizeVal + sub eax, 10 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 3, 001515C8h + mov eax, x + add eax, 9 + mov edx, y + add edx, sizeVal + sub edx, 10 + invoke DrawCircle, eax, edx, 3, 001515C8h + + cmp valNum, 6 + jl die_pips_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 3, 001515C8h + mov eax, x + add eax, sizeVal + sub eax, 10 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 3, 001515C8h + +die_pips_done: + ret +DrawCrapsDie ENDP + +InitDiceGame PROC + mov dice3d_state, 0 + mov dice3d_timer, 0 + mov dice3d_win, 0 + cmp dice3d_bet, 10 + jge @F + mov dice3d_bet, 50 +@@: + ret +InitDiceGame ENDP + +HandleDiceInput PROC + cmp dice3d_state, 1 + je dice_input_done + + invoke Pressed3D, 20h ; SPACE -> Roll! + test eax, eax + jz check_dice_choice + mov eax, bankroll + cmp eax, dice3d_bet + jl dice_no_cash + sub eax, dice3d_bet + mov bankroll, eax + mov dice3d_state, 1 + mov dice3d_timer, 0 + mov dice3d_win, 0 + invoke PlaySoundA, OFFSET soundCards, 0, 1 + jmp dice_input_done + +dice_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp dice_input_done + +check_dice_choice: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov dice3d_choice, 1 + invoke PlaySoundA, OFFSET soundClick, 0, 1 +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz check_dice_bet_adjust + mov dice3d_choice, 2 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + +check_dice_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz dice_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_dice_bet_down +dice_inc_bet: + invoke PlaySoundA, OFFSET soundClick, 0, 1 + cmp dice3d_bet, 500 + jge dice_input_done + cmp dice3d_bet, 250 + jge dice_set_500 + cmp dice3d_bet, 100 + jge dice_set_250 + cmp dice3d_bet, 50 + jge dice_set_100 + cmp dice3d_bet, 25 + jge dice_set_50 + jmp dice_set_25 +dice_set_500: + mov dice3d_bet, 500 + jmp dice_input_done +dice_set_250: + mov dice3d_bet, 250 + jmp dice_input_done +dice_set_100: + mov dice3d_bet, 100 + jmp dice_input_done +dice_set_50: + mov dice3d_bet, 50 + jmp dice_input_done +dice_set_25: + mov dice3d_bet, 25 + jmp dice_input_done + +check_dice_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz dice_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz dice_input_done +dice_dec_bet: + invoke PlaySoundA, OFFSET soundClick, 0, 1 + cmp dice3d_bet, 25 + jle dice_set_10 + cmp dice3d_bet, 50 + jle dice_set_25 + cmp dice3d_bet, 100 + jle dice_set_50 + cmp dice3d_bet, 250 + jle dice_set_100 + mov dice3d_bet, 250 + jmp dice_input_done +dice_set_10: + mov dice3d_bet, 10 + +dice_input_done: + ret +HandleDiceInput ENDP + +RenderDiceGame PROC uses ebx esi edi + LOCAL d1X:DWORD, d1Y:DWORD, d2X:DWORD, d2Y:DWORD, bxX:DWORD + + ; Craps Emerald Felt & Oak Armrest + invoke DrawBox, 0, 0, 320, 240, 00082E12h + invoke DrawBoxBorder, 4, 4, 312, 232, 00093816h, 00122244h, 3 + invoke DrawBoxBorder, 8, 8, 304, 224, 000A3F19h, 0005140Ah, 2 + + ; Pyramidal diamond craps backboard texture + mov bxX, 12 +craps_bumper: + cmp bxX, 308 + jge craps_felt_markings + mov eax, bxX + add eax, 4 + invoke DrawBox, eax, 11, 4, 4, 00041006h + mov eax, bxX + add eax, 5 + invoke DrawPixel, eax, 12, 000F4820h + add bxX, 12 + jmp craps_bumper + +craps_felt_markings: + ; Table Markings printed in gold directly on felt + invoke DrawString8x8, 72, 20, OFFSET textDiceTitle, 0000D7FFh + invoke DrawString8x8, 68, 32, OFFSET textDiceSubtitle, 0000B0A0h + + ; Meters: Bank & Bet + invoke DrawBoxBorder, 16, 46, 108, 16, 0006240Eh, 000E5022h, 1 + invoke DrawString8x8, 20, 50, OFFSET textBankPrompt, 0050FF50h + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 68, 50, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawBoxBorder, 196, 46, 108, 16, 0006240Eh, 000E5022h, 1 + invoke DrawString8x8, 200, 50, OFFSET textBetPrompt, 0000D7FFh + invoke FormatNumber, dice3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 264, 50, OFFSET hudNumBuffer, 0000D7FFh + + ; Betting Zone Left: [1] רÒ + mov eax, 00073014h + mov edx, 001A602Ah + mov ecx, 0080B090h + cmp dice3d_choice, 1 + jne @F + mov eax, 000B441Dh + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 16, 68, 88, 54, eax, edx, 2 + pop ecx + invoke DrawString8x8, 24, 74, OFFSET textDiceEven, ecx + invoke DrawString8x8, 20, 86, OFFSET textDiceEvenNums, 0000D7FFh + cmp dice3d_choice, 1 + jne @F + invoke DrawChipStack, 48, 110, 4 +@@: + + ; Betting Zone Right: [2] ÍÅ×ÅÒ + mov eax, 00073014h + mov edx, 001A602Ah + mov ecx, 0080B090h + cmp dice3d_choice, 2 + jne @F + mov eax, 000B441Dh + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 216, 68, 88, 54, eax, edx, 2 + pop ecx + invoke DrawString8x8, 224, 74, OFFSET textDiceOdd, ecx + invoke DrawString8x8, 224, 86, OFFSET textDiceOddNums, 00508060h + cmp dice3d_choice, 2 + jne @F + invoke DrawChipStack, 248, 110, 4 +@@: + + ; Center Dice Field + invoke DrawBoxBorder, 112, 68, 96, 54, 00072E13h, 00145826h, 1 + + ; Rolling Animation Logic + cmp dice3d_state, 1 + jne dice_at_rest + + inc dice3d_timer + + ; Tumbling jitter offsets + mov eax, dice3d_timer + and eax, 3 + sub eax, 1 + + mov edx, 120 + add edx, eax + mov d1X, edx + mov edx, 76 + sub edx, eax + mov d1Y, edx + + mov edx, 164 + sub edx, eax + mov d2X, edx + mov edx, 78 + add edx, eax + mov d2Y, edx + + test dice3d_timer, 1 + jz @F + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax +@@: + invoke DrawCrapsDie, d1X, d1Y, 36, dice3d_val1 + invoke DrawCrapsDie, d2X, d2Y, 36, dice3d_val2 + invoke DrawString8x8, 76, 138, OFFSET textDiceRolling, 0000FFFFh + + cmp dice3d_timer, 36 + jl dice_draw_controls + + ; Settle dice! + mov dice3d_state, 2 + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax + + mov eax, dice3d_val1 + add eax, dice3d_val2 + mov dice3d_sum, eax + + ; Check choice vs sum parity + mov eax, dice3d_sum + test eax, 1 + jz dice_sum_is_even + + ; Odd + cmp dice3d_choice, 2 + je dice_roll_won + jmp dice_roll_lost + +dice_sum_is_even: + cmp dice3d_choice, 1 + je dice_roll_won + +dice_roll_lost: + mov dice3d_win, 0 + invoke PlaySoundA, OFFSET soundLose, 0, 1 + jmp dice_draw_controls + +dice_roll_won: + mov eax, dice3d_bet + shl eax, 1 + mov dice3d_win, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundVictory, 0, 1 + jmp dice_draw_controls + +dice_at_rest: + invoke DrawCrapsDie, 120, 76, 36, dice3d_val1 + invoke DrawCrapsDie, 164, 76, 36, dice3d_val2 + + cmp dice3d_state, 2 + jne dice_draw_controls + + ; Scoreboard Plaque + invoke DrawBoxBorder, 36, 130, 248, 30, 00051D0Ch, 0000D7FFh, 1 + invoke DrawString8x8, 44, 135, OFFSET textDiceSumHdr, 0000D7FFh + invoke FormatNumber, dice3d_val1, OFFSET hudNumBuffer + invoke DrawString8x8, 100, 135, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 110, 135, OFFSET textDicePlus, 0000D7FFh + invoke FormatNumber, dice3d_val2, OFFSET hudNumBuffer + invoke DrawString8x8, 134, 135, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 144, 135, OFFSET textDiceEqual, 0000D7FFh + invoke FormatNumber, dice3d_sum, OFFSET hudNumBuffer + invoke DrawString8x8, 168, 135, OFFSET hudNumBuffer, 0000FFFFh + + mov eax, dice3d_sum + test eax, 1 + jnz @F + invoke DrawString8x8, 186, 135, OFFSET textDiceEvenResult, 0080FF80h + jmp dice_show_win_msg +@@: + invoke DrawString8x8, 186, 135, OFFSET textDiceOddResult, 00FF8080h + +dice_show_win_msg: + cmp dice3d_win, 0 + je dice_show_loss + invoke DrawString8x8, 68, 147, OFFSET textDiceWin, 0050FF50h + invoke FormatNumber, dice3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 156, 147, OFFSET hudNumBuffer, 0050FF50h + invoke DrawString8x8, 188, 147, OFFSET textDiceWinMult, 0050FF50h + jmp dice_draw_controls + +dice_show_loss: + invoke DrawString8x8, 116, 147, OFFSET textDiceLose, 008080FFh + +dice_draw_controls: + invoke DrawBox, 16, 188, 288, 1, 00104820h + + mov eax, 0 + cmp dice3d_choice, 1 + sete al + invoke DrawKeycap3D, 20, 198, OFFSET textDiceKey1, eax + + mov eax, 0 + cmp dice3d_choice, 2 + sete al + invoke DrawKeycap3D, 82, 198, OFFSET textDiceKey2, eax + + invoke DrawKeycap3D, 160, 198, OFFSET textDiceKeySpace, 1 + invoke DrawKeycap3D, 274, 198, 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, 00081E2Eh + invoke DrawCircle, cxVal, cyVal, 11, 00103A58h + invoke DrawCircle, cxVal, cyVal, 8, 001A588Ah + invoke DrawCircle, cxVal, cyVal, 6, 0000B0E0h + invoke DrawCircle, cxVal, cyVal, 4, 0000E0FFh + mov eax, cxVal + dec eax + mov edx, cyVal + dec edx + invoke DrawCircle, eax, edx, 2, 00A0FFFFh + mov eax, cxVal + sub eax, 2 + mov edx, cyVal + sub edx, 2 + 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, 28 +@@: + mov liftY, eax + + ; Drop shadow on purple velvet + cmp isLifted, 0 + jne @F + mov eax, x + add eax, 6 + mov edx, y + add edx, 42 + invoke DrawBox, eax, edx, 36, 4, 000A0410h + jmp draw_cup_body +@@: + mov eax, x + add eax, 10 + mov edx, y + add edx, 42 + invoke DrawBox, eax, edx, 28, 2, 0012061Ah + + ; Draw orb if lifted and has ball + cmp hasBall, 0 + je draw_cup_body + mov eax, x + add eax, 24 + mov edx, y + add edx, 26 + invoke DrawGlowingOrb, eax, edx + +draw_cup_body: + ; Base + mov eax, x + add eax, 6 + mov edx, liftY + add edx, 36 + invoke DrawBoxBorder, eax, edx, 36, 6, 00221A30h, 0000B0D0h, 1 + + ; Stem + mov eax, x + add eax, 18 + mov edx, liftY + add edx, 28 + invoke DrawBox, eax, edx, 12, 8, 00332545h + mov eax, x + add eax, 22 + mov edx, liftY + add edx, 28 + invoke DrawBox, eax, edx, 4, 8, 0055406Eh + + ; Bowl + mov eax, x + add eax, 8 + mov edx, liftY + add edx, 8 + invoke DrawBoxBorder, eax, edx, 32, 20, 002D1E40h, 0000D7FFh, 1 + mov eax, x + add eax, 14 + mov edx, liftY + add edx, 10 + invoke DrawBox, eax, edx, 6, 16, 00503570h + mov eax, x + add eax, 17 + mov edx, liftY + add edx, 10 + invoke DrawBox, eax, edx, 3, 16, 007850A0h + + ; Flared Rim + mov eax, x + add eax, 4 + mov edx, liftY + add edx, 2 + invoke DrawBoxBorder, eax, edx, 40, 7, 00150A20h, 0000FFFFh, 1 + mov eax, x + add eax, 12 + mov edx, liftY + add edx, 4 + invoke DrawBox, eax, edx, 16, 2, 0000FFFFh + + ; Skull Insignia on Bowl + mov eax, x + add eax, 21 + mov edx, liftY + add edx, 12 + invoke DrawBox, eax, edx, 6, 5, 0000D7FFh + mov eax, x + add eax, 22 + mov edx, liftY + add edx, 17 + invoke DrawBox, eax, edx, 4, 3, 0000D7FFh + mov eax, x + add eax, 22 + mov edx, liftY + add edx, 14 + invoke DrawPixel, eax, edx, 00150A20h + mov eax, x + add eax, 24 + mov edx, liftY + add edx, 14 + invoke DrawPixel, eax, edx, 00150A20h + + ; Cup ID Badge + mov eax, x + add eax, 21 + mov edx, liftY + add edx, 24 + mov ecx, cupId + add ecx, '0' + invoke DrawChar8x8, eax, edx, ecx, 0000FFFFh + ret +DrawGothicCup ENDP + +InitSkullsGame PROC + mov skulls3d_state, 0 + mov skulls3d_timer, 0 + mov skulls3d_win, 0 + cmp skulls3d_bet, 10 + jge @F + mov skulls3d_bet, 50 +@@: + invoke RandomRange3D, 3 + mov skulls3d_ballPos, eax + ret +InitSkullsGame ENDP + +FinalizeSkullsGuess PROC uses ebx + mov skulls3d_state, 4 + mov eax, skulls3d_choice + cmp eax, skulls3d_ballPos + jne skulls_guess_lost + + ; Won 3x! + mov eax, skulls3d_bet + imul eax, 3 + mov skulls3d_win, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundVictory, 0, 1 + ret + +skulls_guess_lost: + mov skulls3d_win, 0 + invoke PlaySoundA, OFFSET soundLose, 0, 1 + ret +FinalizeSkullsGuess ENDP + +HandleSkullsInput PROC + cmp skulls3d_state, 1 + je skulls_input_done + cmp skulls3d_state, 2 + je skulls_input_done + + cmp skulls3d_state, 3 + je check_skulls_pick + + ; State 0 or 4: Can start new round or adjust bet + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_skulls_bet_adjust + + mov eax, bankroll + cmp eax, skulls3d_bet + jl skulls_no_cash + sub eax, skulls3d_bet + mov bankroll, eax + + invoke RandomRange3D, 3 + mov skulls3d_ballPos, eax + + 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 + mov skulls3d_win, 0 + invoke PlaySoundA, OFFSET soundShuffle, 0, 1 + jmp skulls_input_done + +skulls_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp skulls_input_done + +check_skulls_pick: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov skulls3d_choice, 0 + call FinalizeSkullsGuess + jmp skulls_input_done +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz @F + mov skulls3d_choice, 1 + call FinalizeSkullsGuess + jmp skulls_input_done +@@: + invoke Pressed3D, 33h ; '3' + test eax, eax + jz skulls_input_done + mov skulls3d_choice, 2 + call FinalizeSkullsGuess + jmp skulls_input_done + +check_skulls_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz skulls_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_skulls_bet_down +skulls_inc_bet: + invoke PlaySoundA, OFFSET soundClick, 0, 1 + cmp skulls3d_bet, 500 + jge skulls_input_done + cmp skulls3d_bet, 250 + jge skulls_set_500 + cmp skulls3d_bet, 100 + jge skulls_set_250 + cmp skulls3d_bet, 50 + jge skulls_set_100 + cmp skulls3d_bet, 25 + jge skulls_set_50 + jmp skulls_set_25 +skulls_set_500: + mov skulls3d_bet, 500 + jmp skulls_input_done +skulls_set_250: + mov skulls3d_bet, 250 + jmp skulls_input_done +skulls_set_100: + mov skulls3d_bet, 100 + jmp skulls_input_done +skulls_set_50: + mov skulls3d_bet, 50 + jmp skulls_input_done +skulls_set_25: + mov skulls3d_bet, 25 + jmp skulls_input_done + +check_skulls_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz skulls_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz skulls_input_done +skulls_dec_bet: + invoke PlaySoundA, OFFSET soundClick, 0, 1 + cmp skulls3d_bet, 25 + jle skulls_set_10 + cmp skulls3d_bet, 50 + jle skulls_set_25 + cmp skulls3d_bet, 100 + jle skulls_set_50 + cmp skulls3d_bet, 250 + jle skulls_set_100 + mov skulls3d_bet, 250 + jmp skulls_input_done +skulls_set_10: + mov skulls3d_bet, 10 + +skulls_input_done: + ret +HandleSkullsInput ENDP + +RenderSkullsGame PROC uses ebx esi edi + 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 + + ; Dark Gothic Tavern Table with Royal Velvet + invoke DrawBox, 0, 0, 320, 240, 000D0612h + invoke DrawBoxBorder, 4, 4, 312, 232, 00160B20h, 00321845h, 3 + invoke DrawBoxBorder, 8, 8, 304, 224, 00220F30h, 0000D7FFh, 1 + + ; Header + invoke DrawBoxBorder, 24, 12, 272, 24, 0012081Ah, 0000D7FFh, 2 + invoke DrawString8x8, 64, 20, OFFSET textSkullsTitle, 0000FFFFh + + ; Meters: Bank & Bet + invoke DrawBoxBorder, 20, 42, 114, 16, 000D0616h, 00401858h, 1 + invoke DrawString8x8, 24, 46, OFFSET textBankPrompt, 0050FF50h + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 72, 46, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawBoxBorder, 186, 42, 114, 16, 000D0616h, 00401858h, 1 + invoke DrawString8x8, 190, 46, OFFSET textBetPrompt, 0000D7FFh + invoke FormatNumber, skulls3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 254, 46, OFFSET hudNumBuffer, 0000D7FFh + + ; Velvet Table Runner + invoke DrawBoxBorder, 16, 64, 288, 120, 001A0B25h, 00452060h, 1 + + ; Dispatch based on phase + cmp skulls3d_state, 1 + je skulls_render_phase1 + cmp skulls3d_state, 2 + je skulls_render_phase2 + cmp skulls3d_state, 3 + je skulls_render_phase3 + cmp skulls3d_state, 4 + je skulls_render_phase4 + + ; Phase 0: Idle / Betting + invoke DrawString8x8, 56, 70, OFFSET textSkullsPhase0, 0000D7FFh + invoke DrawGothicCup, 48, 108, 1, 0, 0 + invoke DrawGothicCup, 136, 108, 2, 0, 0 + invoke DrawGothicCup, 224, 108, 3, 0, 0 + jmp skulls_draw_controls + +skulls_render_phase1: + inc skulls3d_timer + invoke DrawString8x8, 56, 70, OFFSET textSkullsPhase1, 0000FFFFh + + ; Draw cups with ballPos cup lifted + mov eax, 0 + cmp skulls3d_ballPos, 0 + sete al + invoke DrawGothicCup, 48, 108, 1, eax, eax + + mov eax, 0 + cmp skulls3d_ballPos, 1 + sete al + invoke DrawGothicCup, 136, 108, 2, eax, eax + + mov eax, 0 + cmp skulls3d_ballPos, 2 + sete al + invoke DrawGothicCup, 224, 108, 3, eax, eax + + cmp skulls3d_timer, 40 + jl skulls_draw_controls + + ; Start Phase 2 (Shuffle) + mov skulls3d_state, 2 + mov skulls3d_timer, 0 + invoke PlaySoundA, OFFSET soundShuffle, 0, 1 + jmp skulls_draw_controls + +skulls_render_phase2: + inc skulls3d_timer + + 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_pair + +pass_0: + dec eax + mov passTick, eax + mov eax, skulls3d_swapPair0 + mov curPair, eax + jmp setup_pass_pair + +pass_1: + sub eax, 21 + mov passTick, eax + mov eax, skulls3d_swapPair1 + mov curPair, eax + +setup_pass_pair: + cmp curPair, 1 + je pair_1 + cmp curPair, 2 + je pair_2 + mov swapSlotA, 0 + mov swapSlotB, 1 + mov xA, 48 + mov xB, 136 + jmp calc_swap_coords +pair_1: + mov swapSlotA, 1 + mov swapSlotB, 2 + mov xA, 136 + mov xB, 224 + jmp calc_swap_coords +pair_2: + mov swapSlotA, 0 + mov swapSlotB, 2 + mov xA, 48 + mov xB, 224 + +calc_swap_coords: + mov eax, xB + sub eax, xA + mov distX, eax + + mov eax, distX + imul eax, passTick + xor edx, edx + mov ecx, 20 + div ecx + mov dxVal, eax + + mov eax, xA + add eax, dxVal + mov curXA, eax + + mov eax, xB + sub eax, dxVal + mov curXB, eax + + ; Arch height: archY = (t * (20 - t)) / 25 + mov eax, passTick + mov ecx, 20 + sub ecx, eax + imul eax, ecx + xor edx, edx + mov ecx, 25 + div ecx + mov archY, eax + + mov edx, 108 + sub edx, archY + mov curYA, edx ; upper arc + + mov edx, 108 + add edx, archY + mov curYB, edx ; lower arc + + invoke DrawString8x8, 56, 70, OFFSET textSkullsPhase2, 0000FFFFh + + ; Depth sorted rendering: Background cup (upper arc) draws FIRST, Foreground cup (lower arc) draws OVER it! + invoke DrawGothicCup, curXA, curYA, 1, 0, 0 + invoke DrawGothicCup, curXB, curYB, 2, 0, 0 + + ; Draw remaining static cup + cmp curPair, 1 + je draw_stat_0 + cmp curPair, 2 + je draw_stat_1 + invoke DrawGothicCup, 224, 108, 3, 0, 0 + jmp check_pass_finish +draw_stat_0: + invoke DrawGothicCup, 48, 108, 1, 0, 0 + jmp check_pass_finish +draw_stat_1: + invoke DrawGothicCup, 136, 108, 2, 0, 0 + +check_pass_finish: + cmp skulls3d_timer, 20 + je do_pass_swap + cmp skulls3d_timer, 40 + je do_pass_swap + cmp skulls3d_timer, 60 + je do_pass_swap + jmp skulls_draw_controls + +do_pass_swap: + ; Update ballPos if involved in swap + mov eax, skulls3d_ballPos + cmp eax, swapSlotA + jne check_swap_b + mov eax, swapSlotB + mov skulls3d_ballPos, eax + jmp ball_swap_done +check_swap_b: + cmp eax, swapSlotB + jne ball_swap_done + mov eax, swapSlotA + mov skulls3d_ballPos, eax + +ball_swap_done: + invoke PlaySoundA, OFFSET soundShuffle, 0, 1 + + cmp skulls3d_timer, 60 + jl skulls_draw_controls + + ; Shuffle complete -> Move to Pick phase + mov skulls3d_state, 3 + mov skulls3d_timer, 0 + jmp skulls_draw_controls + +skulls_render_phase3: + invoke DrawString8x8, 40, 70, OFFSET textSkullsPhase3, 0000FFFFh + invoke DrawGothicCup, 48, 108, 1, 0, 0 + invoke DrawGothicCup, 136, 108, 2, 0, 0 + invoke DrawGothicCup, 224, 108, 3, 0, 0 + jmp skulls_draw_controls + +skulls_render_phase4: + ; Reveal phase + cmp skulls3d_win, 0 + je skulls_show_loss + invoke DrawString8x8, 48, 70, OFFSET textSkullsWin, 0050FF50h + invoke FormatNumber, skulls3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 216, 70, OFFSET hudNumBuffer, 0050FF50h + jmp skulls_p4_cups + +skulls_show_loss: + invoke DrawString8x8, 40, 70, OFFSET textSkullsLose, 008080FFh + +skulls_p4_cups: + ; Draw chosen cup lifted + mov eax, 0 + cmp skulls3d_choice, 0 + sete al + mov edx, 0 + cmp skulls3d_ballPos, 0 + sete dl + invoke DrawGothicCup, 48, 108, 1, eax, edx + + mov eax, 0 + cmp skulls3d_choice, 1 + sete al + mov edx, 0 + cmp skulls3d_ballPos, 1 + sete dl + invoke DrawGothicCup, 136, 108, 2, eax, edx + + mov eax, 0 + cmp skulls3d_choice, 2 + sete al + mov edx, 0 + cmp skulls3d_ballPos, 2 + sete dl + invoke DrawGothicCup, 224, 108, 3, eax, edx + + invoke DrawString8x8, 64, 168, OFFSET textSkullsAgain, 0000D7FFh + +skulls_draw_controls: + invoke DrawBox, 16, 190, 288, 1, 003A1850h + + mov eax, 0 + cmp skulls3d_choice, 0 + sete al + invoke DrawKeycap3D, 18, 200, OFFSET textSkullsKey1, eax + + mov eax, 0 + cmp skulls3d_choice, 1 + sete al + invoke DrawKeycap3D, 82, 200, OFFSET textSkullsKey2, eax + + mov eax, 0 + cmp skulls3d_choice, 2 + sete al + invoke DrawKeycap3D, 146, 200, OFFSET textSkullsKey3, eax + + invoke DrawKeycap3D, 212, 200, OFFSET textSkullsKeySpace, 1 + invoke DrawKeycap3D, 274, 200, OFFSET textKeyEsc, 0 + ret +RenderSkullsGame 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: + 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: + ; Çàïóñê îðèãèíàëüíîé èãðû! + call pGameProc + + ; Çàêðûâàåì êîíñîëü + 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 + 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 PlaySoundA, OFFSET soundJackpot, 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 + invoke LaunchClassicGame, OFFSET Game21, 1, OFFSET szTitleBlackjack + ret + +check_target_poker: + cmp eax, INTERACT_POKER + jne check_target_durak + invoke LaunchClassicGame, OFFSET GamePoker, 2, OFFSET szTitlePoker + ret + +check_target_durak: + cmp eax, INTERACT_DURAK + jne check_target_slots777 + invoke LaunchClassicGame, OFFSET GameDurak, 10, OFFSET szTitleDurak + ret + +check_target_slots777: + cmp eax, INTERACT_SLOTS_777 + jne check_target_slots_clover + invoke LaunchClassicGame, OFFSET GameClassicSlot, 9, OFFSET szTitleClassicSlot + ret + +check_target_slots_clover: + cmp eax, INTERACT_SLOTS_CLOVER + jne check_target_roulette + invoke LaunchClassicGame, OFFSET GameSlot, 3, OFFSET szTitleCloverSlot + ret + +check_target_roulette: + cmp eax, INTERACT_ROULETTE + jne check_target_dice + invoke LaunchClassicGame, OFFSET GameCasinoRoulette, 8, OFFSET szTitleCasinoRoulette + 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 + invoke LaunchClassicGame, OFFSET GameSkillCheck, 11, OFFSET szTitleSkillCheck + ret + +check_target_buckshot: + cmp eax, INTERACT_BUCKSHOT + jne check_target_rr + invoke LaunchClassicGame, OFFSET GameBuckshot, 13, OFFSET szTitleBuckshot + ret + +check_target_rr: + cmp eax, INTERACT_RUSSIAN_ROULETTE + jne check_target_online_rr + invoke LaunchClassicGame, OFFSET GameRoulette, 4, OFFSET szTitleRussianRoulette + ret + +check_target_online_rr: + cmp eax, INTERACT_ONLINE_RR + jne check_target_umamusume + invoke LaunchClassicGame, OFFSET GameOnlineCasino, 20, OFFSET szTitleOnlineRR + ret + +check_target_umamusume: + cmp eax, INTERACT_UMAMUSUME + jne check_target_hell + invoke LaunchClassicGame, OFFSET GameUmamusume, 21, OFFSET szTitleUmamusume + ret + +check_target_hell: + cmp eax, INTERACT_HELL_TOWER + jne check_target_shop + invoke LaunchClassicGame, OFFSET GameTournament, 666, OFFSET szTitleHellTower + ret + +check_target_shop: + cmp eax, INTERACT_SHOP + jne check_target_atm + invoke LaunchClassicGame, OFFSET GameShop, 0, OFFSET szTitleShop + 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 + invoke LaunchClassicGame, OFFSET GamePlayerTerminal, 0, OFFSET szTitleTerminal + ret + +check_target_observer: + cmp eax, INTERACT_OBSERVER + jne target_unported + invoke LaunchClassicGame, OFFSET GameObserver, 14, OFFSET szTitleObserver + ret + +target_unported: + invoke CopyString3D, OFFSET textUnavailable3D, OFFSET flashMessage + mov flashTimer, 150 +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 Create3DWindow + test eax, eax + jz init_failed + call LoadTextures3D + test eax, eax + jz init_failed + +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 + + mov eax, 1 + jmp init_return +init_failed: + xor eax, eax +init_return: + pop edi + pop esi + pop ebx + ret +Init3DEngine ENDP + +; --- 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_WALK + jne leave_table + xor paused3D, 1 + jmp engine_tick +leave_table: + ; An already paid round cannot be skipped or settled twice. + cmp slotSpinState, 1 + je engine_tick + cmp roulState, 1 + je engine_tick + cmp coin3d_state, 1 + je engine_tick + cmp dice3d_state, 1 + je engine_tick + cmp skulls3d_state, 1 + je engine_tick + cmp skulls3d_state, 2 + je engine_tick + mov engineMode, MODE_WALK +engine_tick: + cmp paused3D, 0 + jne draw_pause + mov eax, deltaTime3D + add animationClock3D, eax + cmp engineMode, MODE_WALK + jne check_slots_mode + call UpdateCamera3D + call CheckInteractions + call HandlePlayerInput + call UpdateCamera3D + call RenderCeilingAndFloor + call RenderWalls + call RenderSprites + call RenderHUD + call RenderMinimap + jmp present_frame +check_slots_mode: + cmp engineMode, MODE_SLOTS + jne check_bj_mode + call HandleSlotsInput + call RenderSlotsGame + jmp present_frame +check_bj_mode: + cmp engineMode, MODE_BLACKJACK + jne check_roul_mode + call HandleBlackjackInput + call RenderBlackjackGame + jmp present_frame +check_roul_mode: + cmp engineMode, MODE_ROULETTE + jne check_shop_mode + call HandleRouletteInput + call RenderRouletteGame + jmp present_frame +check_shop_mode: + cmp engineMode, MODE_SHOP + jne check_atm_mode + call HandleShopInput + call RenderShopGame + 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 present_frame + call HandleSkullsInput + call RenderSkullsGame + jmp present_frame +draw_pause: + invoke DrawBoxBorder, 65, 75, 190, 85, 00151C21h, 00D8BC6Ah, 2 + invoke DrawString8x8, 86, 88, OFFSET textPause3D, 00FFFFFFh + invoke DrawString8x8, 78, 111, OFFSET textResume3D, 00D8BC6Ah + invoke DrawString8x8, 78, 131, OFFSET textQuit3D, 00BBBBBBh + invoke Pressed3D, 51h + test eax, eax + jnz engine_shutdown +present_frame: + call Present3D + lea edi, pressedKeys3D + xor eax, eax + mov ecx, 64 + rep stosd + invoke GetTickCount + sub eax, frameStart3D + cmp eax, 16 + jae engine_loop + mov ecx, 16 + sub ecx, eax + invoke Sleep, ecx + jmp engine_loop +engine_idle: + invoke Sleep, 50 + jmp engine_loop +engine_shutdown: + call SaveProgress3D + 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 diff --git a/backups/casino3d_before_rich_ui.inc b/backups/casino3d_before_rich_ui.inc new file mode 100644 index 0000000..96f7064 --- /dev/null +++ b/backups/casino3d_before_rich_ui.inc @@ -0,0 +1,4756 @@ + +; ============================================================================== +; 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 +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 + +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 + +.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 "Assembler Casino - 2.5D",0 +szTexturesRelPath db "assets\textures\casino3d-hd.bin",0 +szTexturesFullPath db 260 dup(0) + +soundCoin db "assets\audio\Çâîí ïàäàþùåé ìîíåòû.wav",0 +soundCards db "assets\audio\playing_cards_deck_flick_through_001_20485.wav",0 +soundRoulette db "assets\audio\roulette-wheel-throw-2.wav",0 +soundJackpot db "assets\audio\Äæåêïîò.wav",0 +soundClick db "assets\audio\b05e1ac8be34248.wav",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 "[E] ÏÎÊÅÐ (TEXAS HOLD'EM)",0 +promptDurak db "[E] ÊÀÐÒÛ: ÏÎÄÊÈÄÍÎÉ ÄÓÐÀÊ",0 +promptCasinoRoulette db "[E] ÅÂÐÎÏÅÉÑÊÀß ÐÓËÅÒÊÀ",0 +promptClassicSlot db "[E] ÊËÀÑÑÈ×ÅÑÊÈÅ ÑËÎÒÛ 777",0 +promptCloverSlot db "[E] ÑËÎÒÛ CLOVERPIT (5x3)",0 +promptDice db "[E] ÈÃÐÀ  ÊÎÑÒÈ (CRAPS)",0 +promptSkulls db "[E] ÍÀϨÐÑÒÊÈ (×ÅÐÅÏÀ)",0 +promptCoin db "[E] ÌÎÍÅÒÊÀ (ÎШË/ÐÅØÊÀ)",0 +promptSkillCheck db "[E] ÒÐÅÍÈÐÎÂÊÀ ÐÅÀÊÖÈÈ",0 +promptBuckshot db "[E] BUCKSHOT ROULETTE",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 "[KAZIK 3D CASINO] - ÁËÝÊÄÆÅÊ (21)",0 +szTitlePoker db "[KAZIK 3D CASINO] - ÏÎÊÅÐ (TEXAS HOLD'EM)",0 +szTitleDurak db "[KAZIK 3D CASINO] - ÏÎÄÊÈÄÍÎÉ ÄÓÐÀÊ",0 +szTitleCasinoRoulette db "[KAZIK 3D CASINO] - ÅÂÐÎÏÅÉÑÊÀß ÐÓËÅÒÊÀ",0 +szTitleClassicSlot db "[KAZIK 3D CASINO] - ÊËÀÑÑÈ×ÅÑÊÈÅ ÑËÎÒÛ 777",0 +szTitleCloverSlot db "[KAZIK 3D CASINO] - ÑËÎÒ-ÌÀØÈÍÀ CLOVERPIT (5x3)",0 +szTitleDice db "[KAZIK 3D CASINO] - ÈÃÐÀ  ÊÎÑÒÈ (CRAPS)",0 +szTitleSkulls db "[KAZIK 3D CASINO] - ÍÀϨÐÑÒÊÈ",0 +szTitleCoin db "[KAZIK 3D CASINO] - ÌÎÍÅÒÊÀ (ÎШË/ÐÅØÊÀ)",0 +szTitleSkillCheck db "[KAZIK 3D CASINO] - ÏÐÎÂÅÐÊÀ ÐÅÀÊÖÈÈ",0 +szTitleBuckshot db "[KAZIK 3D CASINO] - BUCKSHOT ROULETTE",0 +szTitleRussianRoulette db "[KAZIK 3D CASINO] - ÐÓÑÑÊÀß ÐÓËÅÒÊÀ",0 +szTitleOnlineRR db "[KAZIK 3D CASINO] - ÑÅÒÅÂÀß ÐÓÑÑÊÀß ÐÓËÅÒÊÀ",0 +szTitleUmamusume db "[KAZIK 3D CASINO] - ÑÊÀ×ÊÈ ÓÌÀÌÓÑÓÌÝ",0 +szTitleHellTower db "[KAZIK 3D CASINO] - ÁÀØÍß ÀÄÀ (ÒÓÐÍÈÐ)",0 +szTitleShop db "[KAZIK 3D CASINO] - ÁÓÒÈÊ È ÒÀËÈÑÌÀÍÛ",0 +szTitleATM db "[KAZIK 3D CASINO] - ÁÀÍÊÎÌÀÒ",0 +szTitleTerminal db "[KAZIK 3D CASINO] - ÒÅÐÌÈÍÀË ÈÃÐÎÊÀ",0 +szTitleObserver db "[KAZIK 3D CASINO] - ÐÅÆÈÌ ÍÀÁËÞÄÀÒÅËß (ÈÈ)",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) + +; --- Native 2.5D Coin Flip Game --- +coin3d_bet dd 50 +coin3d_side 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 + +coinRxAnimTable db 22, 18, 12, 4, 12, 18, 22, 18, 12, 4 + +textCoinTitle db "ÌÎÍÅÒÊÀ (ÎШË / ÐÅØÊÀ)",0 +textCoinHeads db "ÎШË",0 +textCoinTails db "ÐÅØÊÀ",0 +textCoinStreak db "ÑÅÐÈß: ",0 +textCoinSide1 db "[1] ÎШË",0 +textCoinSide2 db "[2] ÐÅØÊÀ",0 +textCoinFlipping db "ÌÎÍÅÒÀ  ÂÎÇÄÓÕÅ...",0 +textCoinWin db "ÂÛÈÃÐÛØ! +$",0 +textCoinLose db "ÏÐÎÈÃÐÛØ!",0 +textCoinControls1 db "[1/2] ÑÒÎÐÎÍÀ [ÏÐÎÁÅË] ÁÐÎÑÎÊ",0 +textCoinControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",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 3 +dice3d_val2 dd 4 +dice3d_sum dd 7 +dice3d_win dd 0 + +textDiceTitle db "ÊÎÑÒÈ (CRAPS) - רÒ / ÍÅ×ÅÒ",0 +textDiceEven db "[1] רÒ",0 +textDiceOdd db "[2] ÍÅ×ÅÒ",0 +textDiceTally db "ÊÎÑÒÈ: ",0 +textDicePlus db " + ",0 +textDiceEqual db " = ",0 +textDiceEvenResult db " (רÒ)",0 +textDiceOddResult db " (ÍÅ×ÅÒ)",0 +textDiceRolling db "ÁÐÎÑÎÊ ÊÎÑÒÅÉ...",0 +textDiceWin db "ÂÛÈÃÐÛØ! +$",0 +textDiceLose db "ÏÐÎÈÃÐÛØ!",0 +textDiceControls1 db "[1] רÒ [2] ÍÅ×ÅÒ [ÏÐÎÁÅË] ÁÐÎÑÎÊ",0 +textDiceControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",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 0 ; 0, 1, 2 +skulls3d_choice dd 0 ; 0, 1, 2 +skulls3d_win dd 0 +skulls3d_swapPair0 dd 0 +skulls3d_swapPair1 dd 1 +skulls3d_swapPair2 dd 2 + +textSkullsTitle db "ÍÀϨÐÑÒÊÈ (×ÅÐÅÏÀ È ÊÓÁÊÈ)",0 +textSkullsPhase0 db "ÂÛÁÅÐÈÒÅ ÑÒÀÂÊÓ È ÍÀÆÌÈÒÅ [ÏÐÎÁÅË]",0 +textSkullsPhase1 db "ÇÀÏÎÌÍÈÒÅ, ÃÄÅ ØÀÐÈÊ!",0 +textSkullsPhase2 db "ÊÐÓ×Ó, ÂÅÐ×Ó, ÇÀÏÓÒÀÒÜ ÕÎ×Ó...",0 +textSkullsPhase3 db "ÃÄÅ ØÀÐÈÊ? ÍÀÆÌÈÒÅ [1], [2] ÈËÈ [3]!",0 +textSkullsWin db "ÂÛ ÓÃÀÄÀËÈ! ÄÆÅÊÏÎÒ x3! +$",0 +textSkullsLose db "ÍÅ ÓÃÀÄÀËÈ! ØÀÐÈÊ ÁÛË ÍÅ ÇÄÅÑÜ!",0 +textSkullsAgain db "[ÏÐÎÁÅË] - ÑÛÃÐÀÒÜ Å٨ ÐÀÇ",0 +textSkullsControls1 db "[1/2/3] ÂÛÁÎÐ ÊÓÁÊÀ [ÏÐÎÁÅË] ÑÒÀÐÒ",0 +textSkullsControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",0 + +shopMsg db 128 dup(0) +atmMsg db 128 dup(0) + +strWin db "ÏÎÁÅÄÀ! +$",0 +strLose db "ÏÐÎÈÃÐÛØ",0 +strJackpot db "ÄÆÅÊÏÎÒ! +$",0 +strPush db "ÍÈ×Üß (PUSH)",0 +strDealerBust db "ÄÈËÅÐ ÏÅÐÅÁÐÀË! ÏÎÁÅÄÀ! +$",0 +strPlayerBust db "ÏÅÐÅÁÎÐ (>21)! ÏÐÎÈÃÐÛØ",0 + +sym7 db " 777 ",0 +symBar db " BAR ",0 +symBell db " BELL",0 +symCherry db "CHERRY",0 +symClover db "CLOVER",0 +symGem db " GEM ",0 +symCrown db "CROWN",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 (48 * 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 --- +RenderCeilingAndFloor PROC uses ebx esi edi + local floorRow:DWORD + local pDist:DWORD + local fStepX:DWORD + local fStepY:DWORD + local fX:DWORD + local fY:DWORD + local shade:DWORD + local cShade:DWORD + + ; Horizon line: row 120 + mov edi, HALF_H +floor_scanlines: + cmp edi, SCREEN_H + jge floor_done + mov floorRow, edi + + ; Distance = (HALF_H * FP_1) / (y - HALF_H) + mov eax, edi + sub eax, HALF_H + inc eax + mov ecx, eax + mov eax, HALF_H * FP_1 + cdq + idiv ecx + mov pDist, eax + + ; Distance shading (closer is brighter, far horizon is dark) + mov edx, pDist + shr edx, 13 + mov eax, 255 + sub eax, edx + cmp eax, 35 + jge @F + mov eax, 35 +@@: + mov shade, eax + mov edx, eax + sub edx, 25 + cmp edx, 20 + jge @F + mov edx, 20 +@@: + mov cShade, edx + + ; Step along scanline: (2 * playerPlane) * pDist / SCREEN_W + mov eax, playerPlaneX + shl eax, 1 + imul pDist + shrd eax, edx, 16 + cdq + mov ecx, SCREEN_W + idiv ecx + mov fStepX, eax + + mov eax, playerPlaneY + shl eax, 1 + imul pDist + shrd eax, edx, 16 + cdq + mov ecx, SCREEN_W + idiv ecx + mov fStepY, eax + + ; Starting floor coordinates at x=0: + ; player + pDist * (playerDir - playerPlane) + mov eax, playerDirX + sub eax, playerPlaneX + imul pDist + shrd eax, edx, 16 + add eax, playerX + mov fX, eax + + mov eax, playerDirY + sub eax, playerPlaneY + imul pDist + shrd eax, edx, 16 + add eax, playerY + mov fY, eax + + ; Fill scanline for floor (y) and ceiling (SCREEN_H - 1 - y) + xor esi, esi +col_floor_loop: + cmp esi, SCREEN_W + jge next_floor_row + + ; Carpet Texture (Slot 3: 3 * 4096 * 4 = 49152 bytes) + mov eax, fX + shr eax, 9 + and eax, 127 + mov edx, fY + shr edx, 9 + and edx, 127 + shl edx, 7 + add edx, eax + + mov eax, [texturesBuffer + (3 * 128 * 128 * 4) + edx*4] + + ; Shade Floor RGB + mov ebx, shade + movzx ecx, al + imul ecx, ebx + shr ecx, 8 + push ecx + + movzx ecx, ah + imul ecx, ebx + shr ecx, 8 + shl ecx, 8 + + shr eax, 16 + movzx eax, al + imul eax, ebx + shr eax, 8 + shl eax, 16 + or eax, ecx + pop ecx + or eax, ecx + + ; Store to Floor pixel + mov ecx, floorRow + imul ecx, SCREEN_W + add ecx, esi + mov [screenBuffer + ecx*4], eax + + ; Ceiling Spotlight Texture (Slot 5: 5 * 4096 * 4 = 81920 bytes) + mov eax, [texturesBuffer + (5 * 128 * 128 * 4) + edx*4] + mov ebx, cShade + movzx ecx, al + imul ecx, ebx + shr ecx, 8 + push ecx + + movzx ecx, ah + imul ecx, ebx + shr ecx, 8 + shl ecx, 8 + + shr eax, 16 + movzx eax, al + imul eax, ebx + shr eax, 8 + shl eax, 16 + or eax, ecx + pop ecx + or eax, ecx + + ; Store to Ceiling pixel: (SCREEN_H - 1 - floorRow) + mov ecx, SCREEN_H - 1 + sub ecx, floorRow + imul ecx, SCREEN_W + add ecx, esi + mov [screenBuffer + ecx*4], eax + + mov eax, fStepX + add fX, eax + mov eax, fStepY + add fY, eax + inc esi + jmp col_floor_loop + +next_floor_row: + inc edi + jmp floor_scanlines + +floor_done: + ret +RenderCeilingAndFloor ENDP + +; --- DDA Raycasting Walls --- +RenderWalls PROC + local col: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 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 hit_wall + + 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 hit_wall + cmp mapX, MAP_WIDTH + jge hit_wall + cmp mapY, 0 + jl hit_wall + cmp mapY, MAP_HEIGHT + jge hit_wall + + mov eax, mapY + shl eax, 5 + add eax, mapX + movzx eax, BYTE PTR [casinoMap + eax] + test eax, eax + jnz hit_wall + jmp dda_step_loop + +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 + + ; High casino ceiling: lineH = (SCREEN_H * FP_1 * 180 / 240) / perpWallDist + mov eax, SCREEN_H + imul eax, FP_1 + cdq + idiv perpWallDist + mov lineH, eax + + mov eax, lineH + shr eax, 1 + mov ecx, HALF_H + sub ecx, eax + mov drawStart, ecx + + mov eax, lineH + shr eax, 1 + mov ecx, HALF_H + add ecx, eax + mov drawEnd, ecx + + 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 + 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 +@@: + cmp side, 1 + jne select_tex + cmp rayDirY, 0 + jge select_tex + mov eax, 127 + sub eax, texX + mov texX, eax + +select_tex: + mov eax, mapY + shl eax, 5 + add eax, mapX + movzx eax, BYTE PTR [casinoMap + 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, lineH + shr eax, 1 + add eax, drawStart + sub eax, HALF_H + 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 + shl eax, 7 + add eax, texX + + mov edx, texId + shl edx, 14 + add eax, edx + mov eax, [texturesBuffer + eax*4] + + ; Shade wall pixel + mov ebx, shade + 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 --- +RenderSprites PROC + local sprIdx:DWORD + local relX:DWORD + local relY:DWORD + local invDet:DWORD + local transX:DWORD + local transY:DWORD + local sprScreenX:DWORD + local sprH:DWORD + local sprW:DWORD + local drawStartY:DWORD + local drawEndY:DWORD + local drawStartX:DWORD + local drawEndX:DWORD + local stripe:DWORD + local texX:DWORD + local texY:DWORD + local shade:DWORD + local texSlot:DWORD + + push ebx + push esi + push edi + + xor esi, esi +calc_dist_loop: + cmp esi, NUM_SPRITES + jge sort_sprites + mov eax, esi + imul eax, SIZEOF SpriteObject + + mov edx, [casinoSprites + eax].posX + sub edx, playerX + sar edx, 8 + imul edx, edx + mov ebx, edx + + mov edx, [casinoSprites + eax].posY + sub edx, playerY + sar edx, 8 + imul edx, edx + add ebx, edx + + mov [casinoSprites + eax].distSq, ebx + mov [sortedSprites + esi*4], esi + inc esi + jmp calc_dist_loop + +sort_sprites: + xor esi, esi +sort_outer: + cmp esi, NUM_SPRITES - 1 + jge render_sorted_sprites + mov edi, esi + inc edi +sort_inner: + cmp edi, NUM_SPRITES + jge next_sort_outer + + mov eax, [sortedSprites + esi*4] + imul eax, SIZEOF SpriteObject + mov eax, [casinoSprites + eax].distSq + + mov ebx, [sortedSprites + edi*4] + imul ebx, SIZEOF SpriteObject + mov ebx, [casinoSprites + ebx].distSq + + cmp eax, ebx + jge @F + mov ecx, [sortedSprites + esi*4] + mov edx, [sortedSprites + edi*4] + mov [sortedSprites + esi*4], edx + mov [sortedSprites + edi*4], ecx +@@: + inc edi + jmp sort_inner +next_sort_outer: + inc esi + jmp sort_outer + +render_sorted_sprites: + xor esi, esi +draw_spr_loop: + cmp esi, NUM_SPRITES + jge sprites_rendered + + mov eax, [sortedSprites + esi*4] + mov sprIdx, eax + imul eax, SIZEOF SpriteObject + + ; Sample animation by elapsed time. Pausing freezes the clock. + push eax + mov ecx, [casinoSprites + eax].animSpeed + cmp ecx, 0 + jg @F + mov ecx, 1 +@@: + imul ecx, 40 + mov eax, animationClock3D + xor edx, edx + div ecx + pop ebx + mov ecx, [casinoSprites + ebx].frameCount + cmp ecx, 0 + jg @F + mov ecx, 1 +@@: + xor edx, edx + div ecx + mov [casinoSprites + ebx].curFrame, edx + mov eax, ebx + + cmp [casinoSprites + eax].distSq, 16 + jle next_spr + + mov edx, [casinoSprites + eax].posX + sub edx, playerX + mov relX, edx + + mov edx, [casinoSprites + eax].posY + sub edx, playerY + mov relY, edx + + mov eax, playerPlaneX + imul playerDirY + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerDirX + imul playerPlaneY + shrd eax, edx, 16 + sub ebx, eax + + mov eax, ebx + test eax, eax + jns @F + neg eax +@@: + cmp eax, 4 + jbe next_spr + + ; 2^32 needs the full EDX:EAX dividend, not a truncated multiply. + xor eax, eax + mov edx, 1 + idiv ebx + mov invDet, eax + + mov eax, playerDirY + imul relX + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerDirX + imul relY + shrd eax, edx, 16 + sub ebx, eax + + mov eax, ebx + imul invDet + shrd eax, edx, 16 + mov transX, eax + + mov eax, playerPlaneY + neg eax + imul relX + shrd eax, edx, 16 + mov ebx, eax + + mov eax, playerPlaneX + imul relY + shrd eax, edx, 16 + add ebx, eax + + mov eax, ebx + imul invDet + shrd eax, edx, 16 + mov transY, eax + + cmp transY, 4096 + jle next_spr + + mov eax, transX + imul eax, HALF_W + cdq + idiv transY + add eax, HALF_W + mov sprScreenX, eax + + mov eax, SCREEN_H + imul eax, FP_1 + cdq + idiv transY + test eax, eax + jns @F + neg eax +@@: + cmp eax, 1 + jge @F + jmp next_spr +@@: + cmp eax, SCREEN_H * 2 + jle @F + mov eax, SCREEN_H * 2 +@@: + mov sprH, eax + mov sprW, eax + + mov eax, HALF_H + mov ebx, sprH + shr ebx, 1 + sub eax, ebx + mov drawStartY, eax + add eax, sprH + mov drawEndY, eax + + mov eax, sprScreenX + mov ebx, sprW + shr ebx, 1 + sub eax, ebx + mov drawStartX, eax + add eax, sprW + mov drawEndX, eax + + cmp drawStartY, 0 + jge @F + mov drawStartY, 0 +@@: + cmp drawEndY, SCREEN_H + jl @F + mov drawEndY, SCREEN_H - 1 +@@: + + mov eax, transY + shr eax, 13 + mov edx, 256 + sub edx, eax + cmp edx, 110 + jge @F + mov edx, 110 +@@: + mov shade, edx + + mov eax, sprIdx + imul eax, SIZEOF SpriteObject + mov edx, [casinoSprites + eax].baseTexId + add edx, [casinoSprites + eax].curFrame + mov texSlot, edx + + mov eax, drawStartX + mov stripe, eax + +spr_stripe_loop: + mov eax, stripe + cmp eax, drawEndX + jge next_spr + + cmp eax, 0 + jl next_spr_stripe + cmp eax, SCREEN_W + jge next_spr + + mov edx, transY + cmp edx, [zBuffer + eax*4] + jge next_spr_stripe + + mov eax, stripe + sub eax, sprScreenX + mov ebx, sprW + shr ebx, 1 + add eax, ebx + shl eax, 7 + cdq + idiv sprW + cmp eax, 0 + jl next_spr_stripe + cmp eax, 128 + jge next_spr_stripe + mov texX, eax + + mov edi, drawStartY +spr_pix_y_loop: + cmp edi, drawEndY + jg next_spr_stripe + + mov eax, edi + sub eax, HALF_H + mov ebx, sprH + shr ebx, 1 + add eax, ebx + shl eax, 7 + cdq + idiv sprH + cmp eax, 0 + jl next_spr_y + cmp eax, 128 + jge next_spr_y + mov texY, eax + + shl eax, 7 + add eax, texX + mov edx, texSlot + shl edx, 14 + add eax, edx + mov eax, [texturesBuffer + eax*4] + + ; Chromakey magenta filter + cmp eax, CHROMA_KEY + je next_spr_y +do_draw_sprite_pix: + mov ebx, shade + 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 ecx, edi + imul ecx, SCREEN_W + add ecx, stripe + mov [screenBuffer + ecx*4], eax + +next_spr_y: + inc edi + jmp spr_pix_y_loop + +next_spr_stripe: + inc stripe + jmp spr_stripe_loop + +next_spr: + inc esi + jmp draw_spr_loop + +sprites_rendered: + pop edi + pop esi + pop ebx + ret +RenderSprites ENDP + +; --- 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, 0000D7FFh, 1 + + ; Draw Sprites on 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, 000000FFh + 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 PlaySoundA, OFFSET soundClick, 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, 0000D7FFh, 3 + + ; Illuminated Top Marquee + invoke DrawBoxBorder, 25, 20, 270, 32, 000A0505h, 0000FFFFh, 2 + invoke DrawString8x8, 55, 32, OFFSET textSlots3D, 0000D7FFh + + ; 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 PlaySoundA, 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 PlaySoundA, OFFSET soundJackpot, 0, 1 + jmp draw_reels +@@: + mov eax, slotBet + imul eax, 10 + mov slotWinAmount, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000D7FFh, 1 + + invoke DrawString8x8, 28, 172, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 175, 172, OFFSET textBet3D, 0000D7FFh + 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, 0000FFFFh + invoke FormatNumber, slotWinAmount, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 187, OFFSET hudNumBuffer, 0000FFFFh + +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, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + ret +DrawReelSymbolAt1 ENDP + +DrawReelSymbolAt2 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 135, 105, OFFSET sym7, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + ret +DrawReelSymbolAt2 ENDP + +DrawReelSymbolAt3 PROC + cmp eax, 0 + jne @F + invoke DrawString8x8, 218, 105, OFFSET sym7, 000000FFh + 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, 0000D7FFh + 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, 0000D7FFh + 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 PlaySoundA, 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 PlaySoundA, OFFSET soundJackpot, 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 PlaySoundA, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000D7FFh, 3 + + ; Dealer Area Top + invoke DrawString8x8, 25, 20, OFFSET textBJ3D, 0000D7FFh + invoke DrawString8x8, 25, 35, OFFSET textDealer3D, 00FFFFFFh + invoke FormatNumber, bjDealerScore, OFFSET hudNumBuffer + invoke DrawString8x8, 120, 35, OFFSET hudNumBuffer, 0000FFFFh + + ; 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, 0000D7FFh, 1 + cmp BYTE PTR [bjOutcomeMsg], 0 + je draw_bj_controls + invoke DrawString8x8, 28, 188, OFFSET bjOutcomeMsg, 0000FFFFh + 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 PlaySoundA, 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, 0000D7FFh, 3 + + ; 2.5D Rotating Wheel on Left + invoke DrawCircle, 85, 110, 65, 00102550h + invoke DrawCircle, 85, 110, 60, 0000D7FFh + invoke DrawCircle, 85, 110, 52, 00101010h + invoke DrawCircle, 85, 110, 22, 0000D7FFh ; 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, 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 PlaySoundA, OFFSET soundCoin, 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 PlaySoundA, OFFSET soundCoin, 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, 0000FFFFh, 2 +@@: + cmp roulBetType, 2 + jne @F + invoke DrawBoxBorder, 173, 58, 129, 32, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 3 + jne @F + invoke DrawBoxBorder, 173, 93, 129, 32, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 4 + jne @F + invoke DrawBoxBorder, 173, 128, 64, 30, 0, 0000FFFFh, 2 +@@: + cmp roulBetType, 5 + jne draw_ro_footer + invoke DrawBoxBorder, 238, 128, 64, 30, 0, 0000FFFFh, 2 + +draw_ro_footer: + invoke DrawBoxBorder, 20, 180, 280, 42, 00101015h, 0000D7FFh, 1 + + cmp roulState, 2 + jne @F + invoke DrawString8x8, 28, 186, OFFSET textResult3D, 0000D7FFh + invoke FormatNumber, roulWinningNum, OFFSET hudNumBuffer + invoke DrawString8x8, 85, 186, OFFSET hudNumBuffer, 0000FFFFh + 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, 0000D7FFh, 3 + invoke DrawString8x8, 25, 20, OFFSET textShop3D, 0000D7FFh + + invoke DrawBoxBorder, 20, 40, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 46, OFFSET textItem1_3D, 0000FFFFh + invoke DrawString8x8, 28, 58, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 80, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 86, OFFSET textItem2_3D, 0000FFFFh + invoke DrawString8x8, 28, 98, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 120, 280, 32, 001A1010h, 00FFFFFFh, 1 + invoke DrawString8x8, 28, 126, OFFSET textItem3_3D, 0000FFFFh + invoke DrawString8x8, 28, 138, OFFSET textShopHint3D, 00A0A0A0h + + invoke DrawBoxBorder, 20, 165, 280, 55, 00100A0Ah, 0000D7FFh, 1 + invoke DrawString8x8, 28, 172, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 0000FFFFh + + 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 + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: COIN FLIP (ÌÎÍÅÒÊÀ) +; ============================================================================== +DrawCoinEllipse PROC uses ebx esi edi cxVal:DWORD, cyVal:DWORD, rxVal:DWORD, ryVal:DWORD, outerColor:DWORD, innerColor:DWORD + local curDY:DWORD, curDX:DWORD, rxSq:DWORD, rySq:DWORD, rxRySq:DWORD, threshSq:DWORD + cmp rxVal, 0 + jle ellipse_done + cmp ryVal, 0 + jle ellipse_done + + mov eax, rxVal + imul eax, eax + mov rxSq, eax + + mov eax, ryVal + imul eax, eax + mov rySq, eax + + mov eax, rxSq + imul eax, rySq + mov rxRySq, eax + + mov eax, rxRySq + shr eax, 2 + imul eax, 3 + mov threshSq, eax + + mov eax, ryVal + neg eax + mov curDY, eax + +ellipse_y_loop: + mov eax, curDY + cmp eax, ryVal + jg ellipse_done + + mov eax, rxVal + neg eax + mov curDX, eax + +ellipse_x_loop: + mov eax, curDX + cmp eax, rxVal + jg next_ellipse_y + + mov eax, curDX + imul eax, eax + imul eax, rySq + mov ebx, curDY + imul ebx, ebx + imul ebx, rxSq + add eax, ebx + cmp eax, rxRySq + jg next_ellipse_x + + mov ecx, innerColor + cmp eax, threshSq + jb @F + mov ecx, outerColor +@@: + mov eax, cxVal + add eax, curDX + mov edx, cyVal + add edx, curDY + invoke DrawPixel, eax, edx, ecx + +next_ellipse_x: + inc curDX + jmp ellipse_x_loop + +next_ellipse_y: + inc curDY + jmp ellipse_y_loop + +ellipse_done: + ret +DrawCoinEllipse ENDP + +InitCoinGame PROC + mov coin3d_state, 0 + mov coin3d_timer, 0 + mov coin3d_win, 0 + cmp coin3d_bet, 10 + jge @F + mov coin3d_bet, 50 +@@: + ret +InitCoinGame ENDP + +HandleCoinInput PROC + cmp coin3d_state, 1 + je coin_input_done + + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_coin_side + mov eax, bankroll + cmp eax, coin3d_bet + jl coin_no_cash + sub eax, coin3d_bet + mov bankroll, eax + mov coin3d_state, 1 + mov coin3d_timer, 0 + mov coin3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp coin_input_done +coin_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp coin_input_done + +check_coin_side: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov coin3d_side, 1 +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz check_coin_bet_adjust + mov coin3d_side, 2 + +check_coin_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz coin_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_coin_bet_down +coin_inc_bet: + cmp coin3d_bet, 500 + jge coin_input_done + cmp coin3d_bet, 250 + jge coin_set_500 + cmp coin3d_bet, 100 + jge coin_set_250 + cmp coin3d_bet, 50 + jge coin_set_100 + cmp coin3d_bet, 25 + jge coin_set_50 + jmp coin_set_25 + +check_coin_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz coin_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz coin_input_done +coin_dec_bet: + cmp coin3d_bet, 25 + jle coin_set_10 + cmp coin3d_bet, 50 + jle coin_set_25 + cmp coin3d_bet, 100 + jle coin_set_50 + cmp coin3d_bet, 250 + jle coin_set_100 + jmp coin_set_250 + +coin_set_500: + mov coin3d_bet, 500 + jmp coin_input_done +coin_set_250: + mov coin3d_bet, 250 + jmp coin_input_done +coin_set_100: + mov coin3d_bet, 100 + jmp coin_input_done +coin_set_50: + mov coin3d_bet, 50 + jmp coin_input_done +coin_set_25: + mov coin3d_bet, 25 + jmp coin_input_done +coin_set_10: + mov coin3d_bet, 10 + jmp coin_input_done + +coin_input_done: + ret +HandleCoinInput ENDP + +RenderCoinGame PROC uses ebx esi edi + local cyVal:DWORD, rxVal:DWORD + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00140D18h + invoke DrawBoxBorder, 10, 10, 300, 220, 0022142Ah, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000D0812h, 0000FFFFh, 2 + invoke DrawString8x8, 72, 27, OFFSET textCoinTitle, 0000D7FFh + + ; Streak Display + invoke DrawString8x8, 28, 50, OFFSET textCoinStreak, 0000D7FFh + invoke FormatNumber, coin3d_streak, OFFSET hudNumBuffer + invoke DrawString8x8, 84, 50, OFFSET hudNumBuffer, 0050FF50h + + ; Side Panel: [1] ÎШË + mov eax, 00120D16h + mov edx, 00505050h + mov ecx, 00808080h + cmp coin3d_side, 1 + jne @F + mov eax, 001E3520h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 24, 70, 68, 38, eax, edx, 2 + pop ecx + invoke DrawString8x8, 28, 85, OFFSET textCoinSide1, ecx + + ; Side Panel: [2] ÐÅØÊÀ + mov eax, 00120D16h + mov edx, 00505050h + mov ecx, 00808080h + cmp coin3d_side, 2 + jne @F + mov eax, 001E3520h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 228, 70, 68, 38, eax, edx, 2 + pop ecx + invoke DrawString8x8, 232, 85, OFFSET textCoinSide2, ecx + + ; Center coin pedestal arena + invoke DrawBoxBorder, 102, 54, 116, 84, 000F0A12h, 00504030h, 1 + + ; Flipping animation logic + cmp coin3d_state, 1 + jne coin_at_rest + + inc coin3d_timer + + ; Parabolic toss: cy = 96 - (t * (40 - t)) / 16 + mov eax, coin3d_timer + mov ecx, 40 + sub ecx, eax + imul eax, ecx + shr eax, 4 + mov edx, 96 + sub edx, eax + mov cyVal, edx + + ; Width rx from lookup table: (t % 10) + mov eax, coin3d_timer + xor edx, edx + mov ecx, 10 + div ecx + movzx eax, BYTE PTR [coinRxAnimTable + edx] + mov rxVal, eax + + invoke DrawCoinEllipse, 160, cyVal, rxVal, 22, 0000D7FFh, 0000B0E0h + invoke DrawString8x8, 84, 142, OFFSET textCoinFlipping, 0000FFFFh + + cmp coin3d_timer, 40 + jl coin_draw_controls + + ; Flip complete! + mov coin3d_state, 2 + invoke RandomRange3D, 2 + inc eax + mov coin3d_result, eax + + mov eax, coin3d_result + cmp eax, coin3d_side + jne coin_flip_lost + + ; Won! + mov eax, coin3d_bet + shl eax, 1 + mov coin3d_win, eax + add bankroll, eax + inc coin3d_streak + cmp coin3d_streak, 3 + jl @F + invoke PlaySoundA, OFFSET soundJackpot, 0, 1 + jmp coin_draw_controls +@@: + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp coin_draw_controls + +coin_flip_lost: + mov coin3d_streak, 0 + mov coin3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp coin_draw_controls + +coin_at_rest: + ; Draw coin resting at (160, 96) + invoke DrawCoinEllipse, 160, 96, 24, 24, 0000D7FFh, 0000B0E0h + invoke DrawCoinEllipse, 160, 96, 20, 20, 0000FFFFh, 000090D0h + + ; Draw side text inside coin + cmp coin3d_state, 2 + jne coin_show_picked_side + cmp coin3d_result, 1 + jne @F + invoke DrawString8x8, 144, 92, OFFSET textCoinHeads, 00000030h + jmp coin_show_splash +@@: + invoke DrawString8x8, 140, 92, OFFSET textCoinTails, 00000030h + jmp coin_show_splash + +coin_show_picked_side: + cmp coin3d_side, 1 + jne @F + invoke DrawString8x8, 144, 92, OFFSET textCoinHeads, 00000030h + jmp coin_draw_controls +@@: + invoke DrawString8x8, 140, 92, OFFSET textCoinTails, 00000030h + jmp coin_draw_controls + +coin_show_splash: + cmp coin3d_win, 0 + je coin_show_loss + invoke DrawString8x8, 90, 142, OFFSET textCoinWin, 0000FFFFh + invoke FormatNumber, coin3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 178, 142, OFFSET hudNumBuffer, 0000FFFFh + jmp coin_draw_controls + +coin_show_loss: + invoke DrawString8x8, 126, 142, OFFSET textCoinLose, 000000FFh + +coin_draw_controls: + ; Bottom Control Panel + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, coin3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 28, 186, OFFSET textCoinControls1, 00FFFFFFh + invoke DrawString8x8, 28, 202, OFFSET textCoinControls2, 00A0A0A0h + ret +RenderCoinGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: DICE / CRAPS (ÊÎÑÒÈ) +; ============================================================================== +DrawDieCube PROC uses ebx esi edi x:DWORD, y:DWORD, cubeSize:DWORD, valNum:DWORD + local pipColor:DWORD + mov pipColor, 001515C0h + + invoke DrawBoxBorder, x, y, cubeSize, cubeSize, 00F4F6F8h, 00303038h, 2 + + mov eax, x + add eax, cubeSize + mov edx, y + add edx, 2 + invoke DrawBox, eax, edx, 2, cubeSize, 0008140Ah + mov eax, x + add eax, 2 + mov edx, y + add edx, cubeSize + invoke DrawBox, eax, edx, cubeSize, 2, 0008140Ah + + cmp valNum, 1 + je draw_die_center + cmp valNum, 3 + je draw_die_center + cmp valNum, 5 + je draw_die_center + jmp check_die_corners +draw_die_center: + mov eax, x + add eax, 18 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + +check_die_corners: + cmp valNum, 2 + jl die_render_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 27 + mov edx, y + add edx, 27 + invoke DrawCircle, eax, edx, 2, pipColor + + cmp valNum, 4 + jl die_render_done + mov eax, x + add eax, 27 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 9 + mov edx, y + add edx, 27 + invoke DrawCircle, eax, edx, 2, pipColor + + cmp valNum, 6 + jl die_render_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 27 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + +die_render_done: + ret +DrawDieCube ENDP + +InitDiceGame PROC + mov dice3d_state, 0 + mov dice3d_timer, 0 + mov dice3d_win, 0 + cmp dice3d_bet, 10 + jge @F + mov dice3d_bet, 50 +@@: + ret +InitDiceGame ENDP + +HandleDiceInput PROC + cmp dice3d_state, 1 + je dice_input_done + + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_dice_choice + mov eax, bankroll + cmp eax, dice3d_bet + jl dice_no_cash + sub eax, dice3d_bet + mov bankroll, eax + mov dice3d_state, 1 + mov dice3d_timer, 0 + mov dice3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp dice_input_done +dice_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp dice_input_done + +check_dice_choice: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov dice3d_choice, 1 +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz check_dice_bet_adjust + mov dice3d_choice, 2 + +check_dice_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz dice_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_dice_bet_down +dice_inc_bet: + cmp dice3d_bet, 500 + jge dice_input_done + cmp dice3d_bet, 250 + jge dice_set_500 + cmp dice3d_bet, 100 + jge dice_set_250 + cmp dice3d_bet, 50 + jge dice_set_100 + cmp dice3d_bet, 25 + jge dice_set_50 + jmp dice_set_25 + +check_dice_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz dice_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz dice_input_done +dice_dec_bet: + cmp dice3d_bet, 25 + jle dice_set_10 + cmp dice3d_bet, 50 + jle dice_set_25 + cmp dice3d_bet, 100 + jle dice_set_50 + cmp dice3d_bet, 250 + jle dice_set_100 + jmp dice_set_250 + +dice_set_500: + mov dice3d_bet, 500 + jmp dice_input_done +dice_set_250: + mov dice3d_bet, 250 + jmp dice_input_done +dice_set_100: + mov dice3d_bet, 100 + jmp dice_input_done +dice_set_50: + mov dice3d_bet, 50 + jmp dice_input_done +dice_set_25: + mov dice3d_bet, 25 + jmp dice_input_done +dice_set_10: + mov dice3d_bet, 10 + jmp dice_input_done + +dice_input_done: + ret +HandleDiceInput ENDP + +RenderDiceGame PROC uses ebx esi edi + local d1X:DWORD, d1Y:DWORD, d2X:DWORD, d2Y:DWORD + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 000C2612h + invoke DrawBoxBorder, 10, 10, 300, 220, 0014381Ah, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000A1F0Eh, 0000FFFFh, 2 + invoke DrawString8x8, 52, 27, OFFSET textDiceTitle, 0000D7FFh + + ; Choice Panels + mov eax, 000E2614h + mov edx, 00505050h + mov ecx, 00808080h + cmp dice3d_choice, 1 + jne @F + mov eax, 001C4824h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 24, 55, 76, 36, eax, edx, 2 + pop ecx + invoke DrawString8x8, 34, 68, OFFSET textDiceEven, ecx + + mov eax, 000E2614h + mov edx, 00505050h + mov ecx, 00808080h + cmp dice3d_choice, 2 + jne @F + mov eax, 001C4824h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 220, 55, 76, 36, eax, edx, 2 + pop ecx + invoke DrawString8x8, 226, 68, OFFSET textDiceOdd, ecx + + ; Dice Table Box + invoke DrawBoxBorder, 104, 52, 112, 54, 0009200Dh, 00305030h, 1 + + ; Rolling animation logic + cmp dice3d_state, 1 + jne dice_at_rest + + inc dice3d_timer + + ; Tumbling jitter offsets + mov eax, dice3d_timer + and eax, 3 + sub eax, 1 + + mov edx, 112 + add edx, eax + mov d1X, edx + + mov edx, 60 + sub edx, eax + mov d1Y, edx + + mov edx, 172 + sub edx, eax + mov d2X, edx + + mov edx, 62 + add edx, eax + mov d2Y, edx + + test dice3d_timer, 1 + jz @F + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax +@@: + invoke DrawDieCube, d1X, d1Y, 36, dice3d_val1 + invoke DrawDieCube, d2X, d2Y, 36, dice3d_val2 + + invoke DrawString8x8, 96, 132, OFFSET textDiceRolling, 0000FFFFh + + cmp dice3d_timer, 36 + jl dice_draw_controls + + ; Roll completed! + mov dice3d_state, 2 + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax + + mov eax, dice3d_val1 + add eax, dice3d_val2 + mov dice3d_sum, eax + + test eax, 1 + jz dice_sum_is_even + mov ecx, 2 ; Odd + jmp check_dice_win +dice_sum_is_even: + mov ecx, 1 ; Even + +check_dice_win: + cmp ecx, dice3d_choice + jne dice_roll_lost + + mov eax, dice3d_bet + shl eax, 1 + mov dice3d_win, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp dice_draw_controls + +dice_roll_lost: + mov dice3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp dice_draw_controls + +dice_at_rest: + invoke DrawDieCube, 112, 60, 36, dice3d_val1 + invoke DrawDieCube, 172, 60, 36, dice3d_val2 + + cmp dice3d_state, 2 + jne dice_draw_controls + + ; Score Tally + invoke DrawString8x8, 80, 112, OFFSET textDiceTally, 0000D7FFh + invoke FormatNumber, dice3d_val1, OFFSET hudNumBuffer + invoke DrawString8x8, 136, 112, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 146, 112, OFFSET textDicePlus, 0000D7FFh + invoke FormatNumber, dice3d_val2, OFFSET hudNumBuffer + invoke DrawString8x8, 170, 112, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 180, 112, OFFSET textDiceEqual, 0000D7FFh + invoke FormatNumber, dice3d_sum, OFFSET hudNumBuffer + invoke DrawString8x8, 204, 112, OFFSET hudNumBuffer, 0000FFFFh + + mov eax, dice3d_sum + test eax, 1 + jz @F + invoke DrawString8x8, 222, 112, OFFSET textDiceOddResult, 00FF8080h + jmp dice_show_outcome +@@: + invoke DrawString8x8, 222, 112, OFFSET textDiceEvenResult, 0080FF80h + +dice_show_outcome: + cmp dice3d_win, 0 + je dice_show_loss + invoke DrawString8x8, 90, 132, OFFSET textDiceWin, 0000FFFFh + invoke FormatNumber, dice3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 178, 132, OFFSET hudNumBuffer, 0000FFFFh + jmp dice_draw_controls +dice_show_loss: + invoke DrawString8x8, 126, 132, OFFSET textDiceLose, 000000FFh + +dice_draw_controls: + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, dice3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 28, 186, OFFSET textDiceControls1, 00FFFFFFh + invoke DrawString8x8, 28, 202, OFFSET textDiceControls2, 00A0A0A0h + ret +RenderDiceGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: SKULLS & CUPS (ÍÀϨÐÑÒÊÈ) +; ============================================================================== +DrawCup PROC uses ebx esi edi x:DWORD, y:DWORD, cupNumChar:DWORD + invoke DrawBox, x + 14, y, 16, 4, 0000C8E8h + invoke DrawBoxBorder, x + 8, y + 4, 28, 12, 00221A30h, 0000D7FFh, 2 + invoke DrawBoxBorder, x + 4, y + 16, 36, 16, 00221A30h, 0000D7FFh, 2 + invoke DrawBoxBorder, x + 2, y + 32, 40, 8, 002A2038h, 0000FFFFh, 2 + + mov eax, x + add eax, 18 + mov edx, y + add edx, 18 + invoke DrawChar8x8, eax, edx, cupNumChar, 0000FFFFh + ret +DrawCup ENDP + +DrawGoldenBall PROC uses ebx esi edi x:DWORD, y:DWORD + invoke DrawCircle, x, y, 7, 0000A5D8h + invoke DrawCircle, x, y, 6, 0000D7FFh + invoke DrawCircle, x, y, 4, 0000FFFFh + mov eax, x + sub eax, 2 + mov edx, y + sub edx, 2 + invoke DrawCircle, eax, edx, 1, 00FFFFFFh + ret +DrawGoldenBall ENDP + +InitSkullsGame PROC + mov skulls3d_state, 0 + mov skulls3d_timer, 0 + mov skulls3d_win, 0 + cmp skulls3d_bet, 10 + jge @F + mov skulls3d_bet, 50 +@@: + ret +InitSkullsGame ENDP + +FinalizeSkullsGuess PROC + mov skulls3d_state, 4 + mov eax, skulls3d_choice + cmp eax, skulls3d_ballPos + jne skulls_guess_lost + + mov eax, skulls3d_bet + imul eax, 3 + mov skulls3d_win, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundJackpot, 0, 1 + ret + +skulls_guess_lost: + mov skulls3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + ret +FinalizeSkullsGuess ENDP + +HandleSkullsInput PROC + cmp skulls3d_state, 1 + je skulls_input_done + cmp skulls3d_state, 2 + je skulls_input_done + + cmp skulls3d_state, 0 + jne check_skulls_in_phase3 + + ; Phase 0: Idle / betting + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_skulls_bet_adjust + + mov eax, bankroll + cmp eax, skulls3d_bet + jl skulls_no_cash + sub eax, skulls3d_bet + mov bankroll, eax + + invoke RandomRange3D, 3 + mov skulls3d_ballPos, eax + mov skulls3d_state, 1 + mov skulls3d_timer, 0 + mov skulls3d_win, 0 + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp skulls_input_done + +skulls_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp skulls_input_done + +check_skulls_in_phase3: + cmp skulls3d_state, 3 + jne check_skulls_in_phase4 + + ; Phase 3: Pick cup + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov skulls3d_choice, 0 + call FinalizeSkullsGuess + jmp skulls_input_done +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz @F + mov skulls3d_choice, 1 + call FinalizeSkullsGuess + jmp skulls_input_done +@@: + invoke Pressed3D, 33h ; '3' + test eax, eax + jz skulls_input_done + mov skulls3d_choice, 2 + call FinalizeSkullsGuess + jmp skulls_input_done + +check_skulls_in_phase4: + ; Phase 4: Play again or adjust bet + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_skulls_bet_adjust + mov skulls3d_state, 0 + jmp skulls_input_done + +check_skulls_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz skulls_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_skulls_bet_down +skulls_inc_bet: + cmp skulls3d_bet, 500 + jge skulls_input_done + cmp skulls3d_bet, 250 + jge skulls_set_500 + cmp skulls3d_bet, 100 + jge skulls_set_250 + cmp skulls3d_bet, 50 + jge skulls_set_100 + cmp skulls3d_bet, 25 + jge skulls_set_50 + jmp skulls_set_25 + +check_skulls_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz skulls_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz skulls_input_done +skulls_dec_bet: + cmp skulls3d_bet, 25 + jle skulls_set_10 + cmp skulls3d_bet, 50 + jle skulls_set_25 + cmp skulls3d_bet, 100 + jle skulls_set_50 + cmp skulls3d_bet, 250 + jle skulls_set_100 + jmp skulls_set_250 + +skulls_set_500: + mov skulls3d_bet, 500 + jmp skulls_input_done +skulls_set_250: + mov skulls3d_bet, 250 + jmp skulls_input_done +skulls_set_100: + mov skulls3d_bet, 100 + jmp skulls_input_done +skulls_set_50: + mov skulls3d_bet, 50 + jmp skulls_input_done +skulls_set_25: + mov skulls3d_bet, 25 + jmp skulls_input_done +skulls_set_10: + mov skulls3d_bet, 10 + jmp skulls_input_done + +skulls_input_done: + ret +HandleSkullsInput ENDP + +RenderSkullsGame PROC uses ebx esi edi + 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 + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00100E18h + invoke DrawBoxBorder, 10, 10, 300, 220, 001A1828h, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000C0A14h, 0000FFFFh, 2 + invoke DrawString8x8, 56, 27, OFFSET textSkullsTitle, 0000D7FFh + + ; Dispatch based on phase + cmp skulls3d_state, 1 + je skulls_render_phase1 + cmp skulls3d_state, 2 + je skulls_render_phase2 + cmp skulls3d_state, 3 + je skulls_render_phase3 + cmp skulls3d_state, 4 + je skulls_render_phase4 + + ; Phase 0: Idle / Betting + invoke DrawCup, 50, 105, '1' + invoke DrawCup, 138, 105, '2' + invoke DrawCup, 226, 105, '3' + invoke DrawString8x8, 24, 48, OFFSET textSkullsPhase0, 0000D7FFh + jmp skulls_draw_controls + +skulls_render_phase1: + inc skulls3d_timer + + ; Draw golden ball under starting cup + mov eax, skulls3d_ballPos + cmp eax, 0 + je p1_ball_0 + cmp eax, 1 + je p1_ball_1 + invoke DrawGoldenBall, 248, 120 + jmp p1_draw_cups +p1_ball_0: + invoke DrawGoldenBall, 72, 120 + jmp p1_draw_cups +p1_ball_1: + invoke DrawGoldenBall, 160, 120 + +p1_draw_cups: + mov edx, 105 + cmp skulls3d_ballPos, 0 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 50, edx, '1' + + mov edx, 105 + cmp skulls3d_ballPos, 1 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 138, edx, '2' + + mov edx, 105 + cmp skulls3d_ballPos, 2 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 226, edx, '3' + + invoke DrawString8x8, 76, 48, OFFSET textSkullsPhase1, 0000FFFFh + + cmp skulls3d_timer, 40 + jl skulls_draw_controls + + ; Start Phase 2 (Shuffle) + mov skulls3d_state, 2 + mov skulls3d_timer, 0 + invoke RandomRange3D, 3 + mov skulls3d_swapPair0, eax + invoke RandomRange3D, 3 + mov skulls3d_swapPair1, eax + invoke RandomRange3D, 3 + mov skulls3d_swapPair2, eax + jmp skulls_draw_controls + +skulls_render_phase2: + inc skulls3d_timer + + 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_pair + +pass_0: + dec eax + mov passTick, eax + mov eax, skulls3d_swapPair0 + mov curPair, eax + jmp setup_pass_pair + +pass_1: + sub eax, 21 + mov passTick, eax + mov eax, skulls3d_swapPair1 + mov curPair, eax + +setup_pass_pair: + cmp curPair, 1 + je pair_1 + cmp curPair, 2 + je pair_2 + mov swapSlotA, 0 + mov swapSlotB, 1 + mov xA, 50 + mov xB, 138 + jmp calc_swap_coords +pair_1: + mov swapSlotA, 1 + mov swapSlotB, 2 + mov xA, 138 + mov xB, 226 + jmp calc_swap_coords +pair_2: + mov swapSlotA, 0 + mov swapSlotB, 2 + mov xA, 50 + mov xB, 226 + +calc_swap_coords: + mov eax, xB + sub eax, xA + mov distX, eax + + mov eax, distX + imul eax, passTick + xor edx, edx + mov ecx, 20 + div ecx + mov dxVal, eax + + mov eax, xA + add eax, dxVal + mov curXA, eax + + mov eax, xB + sub eax, dxVal + mov curXB, eax + + mov eax, passTick + mov ecx, 20 + sub ecx, eax + imul eax, ecx + xor edx, edx + mov ecx, 25 + div ecx + mov archY, eax + + mov eax, 105 + sub eax, archY + mov curYA, eax + + mov eax, 105 + add eax, archY + mov curYB, eax + + cmp passTick, 19 + jne @F + mov eax, skulls3d_ballPos + cmp eax, swapSlotA + jne check_ball_b + mov eax, swapSlotB + mov skulls3d_ballPos, eax + jmp ball_swap_done +check_ball_b: + cmp eax, swapSlotB + jne ball_swap_done + mov eax, swapSlotA + mov skulls3d_ballPos, eax +ball_swap_done: + invoke PlaySoundA, OFFSET soundClick, 0, 1 +@@: + cmp curPair, 1 + je draw_stat_0 + cmp curPair, 2 + je draw_stat_1 + invoke DrawCup, 226, 105, '3' + jmp draw_moving_cups +draw_stat_0: + invoke DrawCup, 50, 105, '1' + jmp draw_moving_cups +draw_stat_1: + invoke DrawCup, 138, 105, '2' + +draw_moving_cups: + mov edx, '1' + add edx, swapSlotA + invoke DrawCup, curXA, curYA, edx + + mov edx, '1' + add edx, swapSlotB + invoke DrawCup, curXB, curYB, edx + + invoke DrawString8x8, 40, 48, OFFSET textSkullsPhase2, 0000FFFFh + + cmp skulls3d_timer, 60 + jl skulls_draw_controls + mov skulls3d_state, 3 + mov skulls3d_timer, 0 + jmp skulls_draw_controls + +skulls_render_phase3: + invoke DrawCup, 50, 105, '1' + invoke DrawCup, 138, 105, '2' + invoke DrawCup, 226, 105, '3' + invoke DrawString8x8, 16, 48, OFFSET textSkullsPhase3, 0000FFFFh + jmp skulls_draw_controls + +skulls_render_phase4: + mov eax, skulls3d_ballPos + cmp eax, 0 + je p4_ball_0 + cmp eax, 1 + je p4_ball_1 + invoke DrawGoldenBall, 248, 120 + jmp p4_draw_cups +p4_ball_0: + invoke DrawGoldenBall, 72, 120 + jmp p4_draw_cups +p4_ball_1: + invoke DrawGoldenBall, 160, 120 + +p4_draw_cups: + mov edx, 105 + cmp skulls3d_choice, 0 + je @F + cmp skulls3d_ballPos, 0 + jne draw_cup0 +@@: + mov edx, 70 +draw_cup0: + invoke DrawCup, 50, edx, '1' + + mov edx, 105 + cmp skulls3d_choice, 1 + je @F + cmp skulls3d_ballPos, 1 + jne draw_cup1 +@@: + mov edx, 70 +draw_cup1: + invoke DrawCup, 138, edx, '2' + + mov edx, 105 + cmp skulls3d_choice, 2 + je @F + cmp skulls3d_ballPos, 2 + jne draw_cup2 +@@: + mov edx, 70 +draw_cup2: + invoke DrawCup, 226, edx, '3' + + cmp skulls3d_win, 0 + je p4_splash_lose + invoke DrawString8x8, 24, 48, OFFSET textSkullsWin, 0000FFFFh + invoke FormatNumber, skulls3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 48, OFFSET hudNumBuffer, 0000FFFFh + jmp p4_again_hint +p4_splash_lose: + invoke DrawString8x8, 36, 48, OFFSET textSkullsLose, 000000FFh +p4_again_hint: + invoke DrawString8x8, 56, 138, OFFSET textSkullsAgain, 0000D7FFh + +skulls_draw_controls: + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, skulls3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 24, 186, OFFSET textSkullsControls1, 00FFFFFFh + invoke DrawString8x8, 24, 202, OFFSET textSkullsControls2, 00A0A0A0h + ret +RenderSkullsGame ENDP + +; --- Player Input & Movement Physics --- +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: + 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: + ; Çàïóñê îðèãèíàëüíîé èãðû! + call pGameProc + + ; Çàêðûâàåì êîíñîëü + 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 + 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 PlaySoundA, OFFSET soundJackpot, 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 + invoke LaunchClassicGame, OFFSET Game21, 1, OFFSET szTitleBlackjack + ret + +check_target_poker: + cmp eax, INTERACT_POKER + jne check_target_durak + invoke LaunchClassicGame, OFFSET GamePoker, 2, OFFSET szTitlePoker + ret + +check_target_durak: + cmp eax, INTERACT_DURAK + jne check_target_slots777 + invoke LaunchClassicGame, OFFSET GameDurak, 10, OFFSET szTitleDurak + ret + +check_target_slots777: + cmp eax, INTERACT_SLOTS_777 + jne check_target_slots_clover + invoke LaunchClassicGame, OFFSET GameClassicSlot, 9, OFFSET szTitleClassicSlot + ret + +check_target_slots_clover: + cmp eax, INTERACT_SLOTS_CLOVER + jne check_target_roulette + invoke LaunchClassicGame, OFFSET GameSlot, 3, OFFSET szTitleCloverSlot + ret + +check_target_roulette: + cmp eax, INTERACT_ROULETTE + jne check_target_dice + invoke LaunchClassicGame, OFFSET GameCasinoRoulette, 8, OFFSET szTitleCasinoRoulette + 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 + invoke LaunchClassicGame, OFFSET GameSkillCheck, 11, OFFSET szTitleSkillCheck + ret + +check_target_buckshot: + cmp eax, INTERACT_BUCKSHOT + jne check_target_rr + invoke LaunchClassicGame, OFFSET GameBuckshot, 13, OFFSET szTitleBuckshot + ret + +check_target_rr: + cmp eax, INTERACT_RUSSIAN_ROULETTE + jne check_target_online_rr + invoke LaunchClassicGame, OFFSET GameRoulette, 4, OFFSET szTitleRussianRoulette + ret + +check_target_online_rr: + cmp eax, INTERACT_ONLINE_RR + jne check_target_umamusume + invoke LaunchClassicGame, OFFSET GameOnlineCasino, 20, OFFSET szTitleOnlineRR + ret + +check_target_umamusume: + cmp eax, INTERACT_UMAMUSUME + jne check_target_hell + invoke LaunchClassicGame, OFFSET GameUmamusume, 21, OFFSET szTitleUmamusume + ret + +check_target_hell: + cmp eax, INTERACT_HELL_TOWER + jne check_target_shop + invoke LaunchClassicGame, OFFSET GameTournament, 666, OFFSET szTitleHellTower + ret + +check_target_shop: + cmp eax, INTERACT_SHOP + jne check_target_atm + invoke LaunchClassicGame, OFFSET GameShop, 0, OFFSET szTitleShop + 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 + invoke LaunchClassicGame, OFFSET GamePlayerTerminal, 0, OFFSET szTitleTerminal + ret + +check_target_observer: + cmp eax, INTERACT_OBSERVER + jne target_unported + invoke LaunchClassicGame, OFFSET GameObserver, 14, OFFSET szTitleObserver + ret + +target_unported: + invoke CopyString3D, OFFSET textUnavailable3D, OFFSET flashMessage + mov flashTimer, 150 +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 Create3DWindow + test eax, eax + jz init_failed + call LoadTextures3D + test eax, eax + jz init_failed + +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 + + mov eax, 1 + jmp init_return +init_failed: + xor eax, eax +init_return: + pop edi + pop esi + pop ebx + ret +Init3DEngine ENDP + +; --- 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_WALK + jne leave_table + xor paused3D, 1 + jmp engine_tick +leave_table: + ; An already paid round cannot be skipped or settled twice. + cmp slotSpinState, 1 + je engine_tick + cmp roulState, 1 + je engine_tick + cmp coin3d_state, 1 + je engine_tick + cmp dice3d_state, 1 + je engine_tick + cmp skulls3d_state, 1 + je engine_tick + cmp skulls3d_state, 2 + je engine_tick + mov engineMode, MODE_WALK +engine_tick: + cmp paused3D, 0 + jne draw_pause + mov eax, deltaTime3D + add animationClock3D, eax + cmp engineMode, MODE_WALK + jne check_slots_mode + call UpdateCamera3D + call CheckInteractions + call HandlePlayerInput + call UpdateCamera3D + call RenderCeilingAndFloor + call RenderWalls + call RenderSprites + call RenderHUD + call RenderMinimap + jmp present_frame +check_slots_mode: + cmp engineMode, MODE_SLOTS + jne check_bj_mode + call HandleSlotsInput + call RenderSlotsGame + jmp present_frame +check_bj_mode: + cmp engineMode, MODE_BLACKJACK + jne check_roul_mode + call HandleBlackjackInput + call RenderBlackjackGame + jmp present_frame +check_roul_mode: + cmp engineMode, MODE_ROULETTE + jne check_shop_mode + call HandleRouletteInput + call RenderRouletteGame + jmp present_frame +check_shop_mode: + cmp engineMode, MODE_SHOP + jne check_atm_mode + call HandleShopInput + call RenderShopGame + 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 present_frame + call HandleSkullsInput + call RenderSkullsGame + jmp present_frame +draw_pause: + invoke DrawBoxBorder, 65, 75, 190, 85, 00151C21h, 00D8BC6Ah, 2 + invoke DrawString8x8, 86, 88, OFFSET textPause3D, 00FFFFFFh + invoke DrawString8x8, 78, 111, OFFSET textResume3D, 00D8BC6Ah + invoke DrawString8x8, 78, 131, OFFSET textQuit3D, 00BBBBBBh + invoke Pressed3D, 51h + test eax, eax + jnz engine_shutdown +present_frame: + call Present3D + lea edi, pressedKeys3D + xor eax, eax + mov ecx, 64 + rep stosd + invoke GetTickCount + sub eax, frameStart3D + cmp eax, 16 + jae engine_loop + mov ecx, 16 + sub ecx, eax + invoke Sleep, ecx + jmp engine_loop +engine_idle: + invoke Sleep, 50 + jmp engine_loop +engine_shutdown: + call SaveProgress3D + 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 diff --git a/backups/poker_backup_broken.exe b/backups/poker_backup_broken.exe new file mode 100644 index 0000000000000000000000000000000000000000..cef22cb42c39cc4f2e0ed639e7807494cb6da4c1 GIT binary patch literal 184832 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 | |",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\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\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: ââîä ïîëüçîâàòåëÿ è ðàçáîð ââåäåííûõ äàííûõ --- +Pause PROC + invoke PrintStr, OFFSET pauseText + call ReadAnyKey + ret +Pause 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 --- +BuildAppDataDir PROC uses eax + mov appDataReady, 0 + 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 Pause + 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 Pause + 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 Pause + 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 + 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 Pause + 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 Pause +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 Pause + 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 Pause + 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 Pause + 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 Pause + ret +cheat_swap21_none: + invoke PrintStr, OFFSET cheatNoTargetText + call Pause + 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 Pause + 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 Pause + ret +cheat_swap_poker_none: + invoke PrintStr, OFFSET cheatNoTargetText + call Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + xor eax, eax + ret +online_join_connect_error: + call PrintOnlineError + call OnlineCleanup + call Pause + 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 Pause + ret +online_casino_protocol_error: + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET OnlineProtocolText + call ResetColor + call OnlineCleanup + call Pause + ret +online_casino_session_error: + call PrintOnlineError + call OnlineCleanup + call Pause +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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + 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 Pause + jmp shop_charms_menu + +shop_blue: + invoke ShopBuyBack, 1, 3000, 2 + call Pause + jmp shop_backs_menu +shop_red: + invoke ShopBuyBack, 2, 3000, 4 + call Pause + jmp shop_backs_menu +shop_gold: + invoke ShopBuyBack, 3, 10000, 8 + call Pause + jmp shop_backs_menu +shop_skull: + invoke ShopBuyBack, 4, 12000, 10h + call Pause + jmp shop_backs_menu +shop_clover_back: + invoke ShopBuyBack, 5, 15000, 20h + call Pause + jmp shop_backs_menu +shop_arcane: + invoke ShopBuyBack, 6, 17000, 40h + call Pause + jmp shop_backs_menu +shop_noir: + invoke ShopBuyBack, 7, 18000, 80h + call Pause + jmp shop_backs_menu +shop_diamond_back: + invoke ShopBuyBack, 8, 20000, 100h + call Pause + jmp shop_backs_menu +shop_rider: + invoke ShopBuyBack, 9, 22000, 200h + call Pause + jmp shop_backs_menu +shop_bee: + invoke ShopBuyBack, 10, 22000, 400h + call Pause + jmp shop_backs_menu +shop_fan: + invoke ShopBuyBack, 11, 23000, 800h + call Pause + jmp shop_backs_menu +shop_web: + invoke ShopBuyBack, 12, 24000, 1000h + call Pause + jmp shop_backs_menu + +buy_charm_clover: + invoke ShopBuyCharm, 1, 12000 + call Pause + jmp shop_charms_menu +buy_charm_bell: + invoke ShopBuyCharm, 2, 18000 + call Pause + jmp shop_charms_menu +buy_charm_diamond: + invoke ShopBuyCharm, 3, 25000 + call Pause + jmp shop_charms_menu +buy_charm_skull: + invoke ShopBuyCharm, 4, 32000 + call Pause + jmp shop_charms_menu +buy_charm_web: + invoke ShopBuyCharm, 5, 40000 + call Pause + jmp shop_charms_menu +buy_charm_bee_item: + invoke ShopBuyCharm, 6, 30000 + call Pause + jmp shop_charms_menu +buy_charm_moon: + invoke ShopBuyCharm, 7, 36000 + call Pause + jmp shop_charms_menu +buy_charm_crown: + invoke ShopBuyCharm, 8, 52000 + call Pause + jmp shop_charms_menu +buy_charm_mirror: + invoke ShopBuyCharm, 9, 42000 + call Pause + jmp shop_charms_menu +buy_charm_dice: + invoke ShopBuyCharm, 10, 35000 + call Pause + jmp shop_charms_menu +buy_charm_blood: + invoke ShopBuyCharm, 11, 65000 + call Pause + jmp shop_charms_menu +buy_charm_hourglass: + invoke ShopBuyCharm, 12, 48000 + call Pause + jmp shop_charms_menu +buy_charm_horseshoe: + invoke ShopBuyCharm, 13, 39000 + call Pause + jmp shop_charms_menu +buy_charm_joker: + invoke ShopBuyCharm, 14, 70000 + call Pause + jmp shop_charms_menu +buy_charm_phoenix: + invoke ShopBuyCharm, 15, 56000 + call Pause + jmp shop_charms_menu +buy_charm_compass: + invoke ShopBuyCharm, 16, 44000 + call Pause + jmp shop_charms_menu +buy_charm_tooth: + invoke ShopBuyCharm, 17, 47000 + call Pause + jmp shop_charms_menu +buy_charm_eye: + invoke ShopBuyCharm, 18, 60000 + call Pause + jmp shop_charms_menu +buy_charm_key: + invoke ShopBuyCharm, 19, 41000 + call Pause + jmp shop_charms_menu +buy_charm_candle: + invoke ShopBuyCharm, 20, 76000 + call Pause + jmp shop_charms_menu +buy_charm_chip: + invoke ShopBuyCharm, 21, 50000 + call Pause + jmp shop_charms_menu +buy_charm_snake: + invoke ShopBuyCharm, 22, 62000 + call Pause + jmp shop_charms_menu +buy_charm_ace: + invoke ShopBuyCharm, 23, 53000 + call Pause + jmp shop_charms_menu +buy_charm_devil: + invoke ShopBuyCharm, 24, 100000 + call Pause + 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 Pause + 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 Pause + ret +GameAchievements ENDP +; --- GameTraining: ñëóæåáíûé áëîê èãðîâîé ëîãèêè --- +GameTraining PROC + call ClearView + invoke PrintTitleColor, OFFSET trainingTitle + invoke PrintStr, OFFSET trainingText + call Pause + 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 Pause + 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 Pause + ret + +tournament_failed: + call StopTowerMusic ; tower failed + invoke SetColor, COLOR_BAD + invoke PrintStr, OFFSET tournamentFailText + call ResetColor + mov tournamentMode, 0 + call Pause + 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 Pause +uma_exit: + ret +GameUmamusume 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 Pause + 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 + 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 +main ENDP + +END main diff --git a/backups/poker_before_enginefix_20260924_220800.exe b/backups/poker_before_enginefix_20260924_220800.exe new file mode 100644 index 0000000000000000000000000000000000000000..897135467b0edbcd1afe39cbc4668b957cdc70a1 GIT binary patch literal 559616 zcmeFacX(9A8#cTtn}m?Cq1V7trT0il7Aew1Fc74Q5NU@^ zAOe9X!46jJh^Q0R4oU!Jzx#gXoU=>w_x|zy^Iq2*E_RYVlev$4fQdYq>G*!uMK^H|7<&7Z)y?TbRGVJu`pd!bM*9 zWwYIdzJ>023*F~ml;>WsXx8km>FKF$Ow&It{q@OEv(jqof0u;YtE+)e&$+F79lmEZ zSt;M+=FK!HV|kQ2)Zw@=F41w-%`X*Lw0#a&T+KLVnxj^n!!h^*A;&iboB_~{Z{~_{ zyw0x^AoDGMi$@8vu%rgr_=6y2?Qat$34h~T#yPGeP(IY*ew>#6fBJ);CNXm9Nod+ ziT}+`lPm99SX4L@x{_Dq*|8pZ-mgo_GD&+D{QtiH?B9N{ohOeL^YuN8KMnuO*<&?gokf9~nK&0p%t1l2NoWf~ zMXr${#VYx1q0{v?@~4xU7|DuZrhqxA0{IUNP4QR9c{BXg3Er9oE_GKV5)s2`Dqw;^ z&tHR3d2!zJ{MGT^!IT{8uTJ!i@K-y%qx{uL-ZB2_Wbasib&7Yqzq*EZqQ5%TJH=mJ z(>u*yo#vfUkfP3mt%`!0s*il9sc!OJOPyolE#x~@HI(m~$|c_}m2BdX6V$Jzj+o!S z$#+fllYG0>xBNzSEMHw^<)}jV>nf{yuVrMgc8->oZRK^kOVPTgMYi(hL#Ohnva$?CQb~fYt zDYX9|)AM!2KDMwIi0!nn9mFnw5VReX2wXjyi zMw{5#j4!89drM_7u_hKaj#!$7T}JH0aWjvF#C|uivl;(}Lho2Aw-MW7Ve5!JYhkYt z3tHIQ#BMjSvl;LDD1;VTD!)=?hJ~FVHqOFoQSy8XYfkK36FZynYbjLQQW-!j!NSH6 z`|Frl5SJ4B$-)*A``pCNX8e5$y=1A}MC>sOdyv>Y7WNFW>n&_6v1?51Y{r{E2BC?T z$~ROQX<@$-%eJr+#JX5mE$X!}v9lRpNTFj#&8&AN_OpczAoh)gjUl$%!Y(DY!^F;J zd@F_4S}NBPyV=5SBDT!J9wb&|Vb2hoZDMCLUh8oP4YX9=r%F!?`-WH>3;UH=0}DGr zEXBkM64bjWA$FR%7+2Kqpd-OZ?-jq${CCxnhsd2wryr*97;IEL@UKCJmWm4lwS#Y%Hwd98gDg& zsls?pa8TU6%BM)4LT#W2>9p?niZk5!ie!RnUQU-Il63fG^%=&@s2|}+{2mHByiT%2nnQyVyl#FE%h2I%7s(=^zRhtsLM+f2@i@it8@Wos95GEbv=HM__OhPJ* z=ZRdX*1&Rwv4zO_>KY<&!vDtJ+`O^lCQS5u<}o=}*(x|`))*+4bts!vF$1vYkwZLi`q?zeQ-D2>rcg=)SG2gwg>`eHWBo z8#mQ=e(AOGJ$*GxuT8kX*Vn%@F?;}o5k9AXXF~XMfam#If!EX5tn}K%EMJ4tYn}7S zObWja(9q!X*C(OIlThRF;e=t~b(KT+vRX<9IK1-$C$3MM&AQ=J)!^6K_-*9KL zBk*nMF^9L&kn0m{)tVYP3bDV|O#3P@bZ^4YeJq3Q9oM^h>8qMmwy~HB_m~4fIMWlum%o5cK0VA?TN4V}U{6iH!k5 z@lS#H9EjQoG)*IfbTSp8e3W!F@k(a~aQ;DmHbA?rP)@ykg0Vn4V+K;Xy`*_Z2I|v) zv#r#!+6rlCD_i;@YRWKkDo9gv+BqD#>Mj@(-E}Mhoj#(+5niqSY0F&1`I@PfR2!|; zx{2C!s8wBtD2{qul?PN!rD!XNMzX}wDX`#zps!1*XRZKkDxC}H5z4;Oc?BT;MN3yY zuZmvf70QpYAd8M%PqbwH`B~f-dTM5OURP|2P~KQ4?k$`#mXCbFCPR zv~;36sc52B=;_KCD2}irs1L|0pqP%{#{yb|#2E8U|D#4viSdGT^)$5RY;csiR@|v= zpC0OOABSNb>fYg2nD_aQFki3sq9;CMP~RwHLU^Sr#hk&6&`-s_l)Y;O`+r^htcWVE z-%PP*A!cMU_-_0im#X_fvl~U}6sMuWM*PJFML&@x@*g=Y2e45yLR?vW`*lonSo+j3T_0TXX z<|3Yan%FZW|Bk(AGpBbF-v|8U0;y)HzZDhROMKI5V!5omby2at#BV!I>_d{Tj*4w2 ze)(x)7c-IZQ85qk^G_4ImNnibDmIsRrYUA->mkx=L}hLwe)I@B(OmU8I)Z{kwYMjG zIfu6yd*BY-EjiazZu|m---U3vw@KMa_18#gWm4Kd56XH{GEB<#q}&CHi9bu7mB3|J z3o{R6E$t2qML>!a_3yMV2zK=QTJhM&ASw98JRrGhplO4C&;%ZbCBtWLafX@pZ_?uj~l zbuZeP+y0K0I=$bVv7#RyU;B9~0F+6(f>|f&Qd5T4Hw;y$6+K zt7MQa|J2hJrtvrx0SvH(wPTr@O!(uUP&4@5{rbk@U>-*+j}slhWE#u?uD&#`js^A z+}-uc?m)%m<*5lf0(*yt-}6Tt-i$znOwN(;$=@jI2@~`15FxNM?fRtaTlC%QtB1u& z;;`Z2-({jUb^4`T6(V~YfC8Fh90TIlx@ZB#KOq9pP8Z@^;h*ePL&$iu{$M_DQ1>w+ ztK(c{>(Sti4@_#AMcqp3rzUlwMg5r6Z%pbWi@J~0A5H3Di~2LEznRp|7PS@jjg7-5 zwSh(LOX>-eil?U9vyr4a8)$zIB96u1i%G3zQa`q+`J~o2scf1eyMWY8le*rbE+MtO zNxjXY-b`vQlX{IseT>v>lRC$uzDnx(CN=3n{yrvcF&hTYZeuv`tnzJtxd8j-uE@6ypy4DH70es1B5Pi4u>T zE&&fPg`vbdlvsYU#6MOs{eb7h#y(2Sh?UUQa?9=nhpM1N0-|0GfP`v`q}BYEF+K-b z0&$W*br*$eQMfjRt5I3%yjWpf4j?;J0cA5O`vX>M>Rk}+TvbMEK=O9S%VSS}@C>MQ9KAa5Msg#{_x-0}Rg`>n3 zl;941jJ1(WFOuv~k5gg|C0fNwNbkJK4IA4AqTB6Ne&`AG)qh8OYiqwxdh0)aiT3eV zTLVM7cL@6D`RJeDLH}HtlV6yWb5%)vXSe@Ei=w2}D`|HaI%nTg=(=m8>rO|r^_snEg+svxg0RZhE?@ zCZxB04XhH;hESfTmIs|ZWE8bE`hY5Y z6+|5)EGes+LQETB!A+`A8^FZW62fu5uG(J4%MiQ>bYlc<2s(}E?w2fd4A6=gyd`l( zp;K%%dKI=3s4TVw<(${(K+}T8Q#S_x1TkNs%!#r1)lK`=Y$I&F3a+*#DCfM9tRTwT z5d38-#}ZbNkUMtbrh&-sHs%2H)8YG%RXUfNQ6a=LHruzWqTR$oz5kQ$?T=0(-|wMz z&!S!E3KDbr6*tKlgzqWEbo92r+p?Anrd*yExRLb(TP91eCUl((h72 zXV<87G7bKzqyM6In1rs{mzE_^3{p=ol*~eii2#SyGIW6JH%;0h74^!s>4H#oYWX1>d-tIK@E}bl)ROzI2-h?4NWX=*=0ZdQg9wo%lB(#PQN0ZQv zggBanZY9LgBy=YsjwYdd32`(DttG_KBorjXaUiroXoQ|7#OX)qc|z>{LoXBJh!EOD zh~q$L0Zauwgsvboh>(xaP(n)xjU=>`5XYp@GC~}aLMsSy`#-dX5cjo1HxlCBe&|*} zn>wR}wsH{Jwgt36(wbzH42P1#>J@ZKp*z8n2l(g~N+DYi^Qb}k+~G1LD4~r#U3JRveB;E>C}2D}nolmUfkW03j>GTtT0f;ogum zGkhnNlZO-XAfay~DL)IK>%`vYg;PM7`J< z4`&%ra|9WkA;xKt(HUZ#1{s|p#%Ykz8Dg9U8J!`fPfAuWaDs1mNLTqzd1W#UI4c&<&$d(skpa$9U zLJZU(TV9BPs-;;CuI0B3on!579_A9PgU|V(z<9Qk~!FwT(M0Vzp$nHE1*@|Z%aVoGi4q;Ze z<=%HYZ!LfIIo=xf+HfPPK=w5@a{bNCkc~(|1Dw5+VkMI19pJBS?(OHVZsqOmuWrM$ zhV8s9{nhPhI<*j{n-$mDxEp$6h?^$@yn$7{01qQ$1i0BLV@IzKH@8PBM-B~MU7wL@ z5$Vj4L;mvGQGx4s^mkIkmvW*!r$b@rn05~*? z^Za1p&?x(59DH?^WeR{pqxA&9q0z^J-b%yfj=AY-{JFw zMzv)s4iCqx`NUcAa22d0Rm2 z3c+yv_7Y+<1w(O;A$GA~DAR$&h6{#*?MbYkV0hZzoq&hVB7ufB0{b|_Y;sW2I9uST zVwdVa9`9PgF56bxZzE9p#73aBi%K7m0`FJsv{`WXX&Zq@58DW;`*s^al}llXcQw3A ztIEha9`CzOr=8#}&_EK`T+BkUcajEDyccPphId#v7s>lZX*>~?E22(s7Y)?(wh4Eo z)ee>f)*m$H^wzW_;=^gurJy0{{c{sw-^a}*_0T_&$X0mg@SjL1I@k5eN;Uf9i6rXtTB;RnFZ2A4iNNZ*7>Ak^IMqz>HHj^}Fu5Q}@g(D3arn5yJI3|Ot=hrs(8Fi%F7yP3rqz&1VxHOqlHOU&#ev1Qc4HB-xhDFQ z0Uw|<&sDX#O)Kk*E+D9_;Oi$lDHueM-GVqAWm`hmIaTTFu{W$!3zj;AFbA#27#ijRP}`W&d0 zNtDUULcwf&>~r!9;th{WR!w`2}Gle>?Z(8fjM8O|2%aP0 zGJ?$nypdpS0jCp80;rxuHY#$*$s&s5Y%(S?=tq<0mEYSKmAiZU{*0PCatk6V?Q;xe zlPboJi^w4~Sz)n_VVsWhHVX1|P_GZAyFT)V|5%*2A3^HciPD*P~6l;a=SKLkV10<)ByjIAms+8mq$$z~A@=B6%$_!g^@Qi=aGIuS% zjW`?oG7p^*Uz%uG97>jF@!_=17yvOEZI-#l_nT({>h}QebbAqB&y#Obr zgHYh?LAYoku6!*itFhk7Z7bDkpzc_ zAHF5B5^u}r0v>+&4DIy5!7fMPC3-g(;|m_6{|1{+)&^AP8w6}El}|^?>By&V13F#{ z(7S{VLtf4Q6wPIc3$%@(sgV@!N0ALg|Hea1Z0B48bH;Htizjg^z*wFJXbt!{p~_rM z!lt&)m6vvJBD;X<@n|W=(?q8N)e+*roY0J!?(nVxGu--lwwEUVhXaN_BO)vyaIB5Bj;Oi)M9NQRgELPiu6j-ClURI z=teOh3vn^f!8Y(91-n@WYTE`@lHQPLA39V5)M!Lg3&=PJrGjvAmGKN5n@@WlEWy+` z!8?$z;Y{Fke1_hM%Avv9T1;RMu1mP>`R{Hi_9SIklq@zO$e zMbUUE@jVLVQlxtsvx9L;2V?dvY3e2>a19ekKmxhyv#)_mw{mDF(khb#F#@Yk!m^Yw zuHpFe8F?cyJj>RSv5vF~&>~sff>F2GMxFuDc#iBxgw1^!Rb;boCVL~#!gJE>j9=64Zw_Rv5ng^t~?>826%t#gq>KyP* z@D6}DM*KU~E(9F&T4tW~&N#?}qgqKkr<3BSSs`0KYUV){C|(Om~ zzQv>K4tswzfb5AkAbT}- zp8Xzqfags$);9+IN6`Hq*-!*2Owvab?aobV^)Ege0IE<+ZJY11`ya*9e}aPVW8VZ@ z=Bd~+uancu+a&yP^oc&(Iww6=TbBtC8iC5Mf=!ISM#r_Va~bUDeuT4Y=|9Syn5Ur0 zaG@9CnJ|4;43p=eVAaVbozOv+)I~u(f}9&8X{a#_h1;NY-Ad8`l9EWOjUM1yl6sMJ zr~)OHPBY;R>Kc$`WX+Qe6(f-ndmy15qUT4x&sFz+0c~kLFN0^)rPPzOlf`+0y2@tX z1tNN~JoOs~yz!LtgQPqtCiZ88LZeyBnN&;In=L(NN#`|!8-)}fA2r+BHhUh3GNqVW zVcbcnt|0IXl|&BaF?@>3?p54I5FPnm64FZvW7@+|IlhCDlA_-G+{#N8D8^id$G7BV z(KYpq&3-#d9E$P4xB)?jRYh|~MFz5`(h*+%r75X}X~whUC8~Jx2Eq@NDd%@KY(}DtD4#knkM|Q&brUk#w5&d-&<_J)kZ@nrt7cCpuKs zjuU+>$kla!#9ScX-&YJIWg<(G^3oglOnHWs+pJ<8=uo|bLg3kF@qzY zwAC6kmd!Wo*70K=vY=Vww6gNx{M(Xt%ABrcAoVoAuIeTOeYpVC346VflPT)z>O%` z<-tZ!8Rp*Dk->h>X98g7X|Dj-bi!f{EbQ)lApmxEGz+^rS_>O_9}5dRMIQ=)jlA6g zU?UIB5bEhJRy%-NuCliUaOrI&|M3i0nd~SXuk9*(Ls)fOWjh3@>nbZ3pq{IYyE6Xc z_3>J|01aGauL;l)Z=(y)$W`_V0G&tK(5re9_$Ewf992O=^$Fcgs2QOf3AHBVCzOVd z@HLz2@XNQU5x*90;&bfqT-gZ>&)CF0;PB*44fr)q?-GvM)RNfwo0{;;vk60s1AC3w zK;~W}mPg!cOy^h2P3`#AWD~XpxYwA;ue43I`Q_Zy6JMBq?M=k=YkQ$tg=m&t5CTT| zK*ZjDM}&o{l1;$l zs46Xk8qzYTAuWR%dR&B2L*EO48qzYT7#$6$51kh3L)$@pApRXy+}lN;J?<~e_3IE$ zQNsu)5w55D6UHkMq<1C!D`Cub3GXMIq#6)ruwg}>N|+&3&|IBBtF78fI92^g_yxjg z>PNzl5w4@YAbcO;4D~+Yn+PYX9fX$?ZmeDbycs2ry3(udmYZdJxJf~4bsu?LI)u~k z;?oVp;(9hL4(w&FTczLF16*CkTHVg^;0N|NZq*Lmy47^? z%t@Lwy+n!7($lnbH#OT+^V)s*IEe8;#bJhKZiuk$%ZV#reZNPJW%}a7?V{(g5LTbQ z4qK1%fZZtC`U}YFUpp&cOXh?{Xr$#j7;}C7m zM+y-Ym@-|1cL)mNuoZ!syn6XfjC&6|I$QWdz&SN*Xq3f@-K5FBl9RPdsC`3JJKxs6 zAyzxr)b4k(c0X!g8P#rWYS%IDh}EtGGLFZa4p+Yc3==*78wYa7skf2Gm{)%ffyrUE zmT@J9Y}H^B#%sK~iWhnh;?38ekL<^5z50Df94|jm;5Kc(4>dV!PGQ)_k2z>W#?QHsg1^s4VBXaK3J0L2vZ} zVoIn9)i_A!`((q$o`gQ@NluX39njdj(NTpTLm?}9XDc$fd^?aZ7h%1 zz(%%c6J#u!AbSK2itDG_#&s}h-g>fp&~kYH!_6E8lf$7CCk z`VFA4+lWx%!x)J_Ux7q2C0?iOm*l@-L+c5(BKJW+dFp|!z&jGZiJVs{T?WX0n1W~L zFLF2GpMSC2zt`BsZReYjM4r4;pQru>J)@*-msx}O$f6szlQ>;MVTs-3C&?bnIz%enl|`~IEi4kMNwLy z=%3t#$re$PAbO#Q5`idJS<&~FWC@x*G^MDS(VOK`%<{Z~Wj`N~e!nODg${z1FPjhH z&uU@V({yjUcJHT` z#Jvyz>im?sdsAIb^Eb7Js+Km}-LqDBK`%h0?eohU=oBUI~x%eOdu@qlh-5|b)LAZp= zK%`ALfExL9>}^2db9I~8da}@$FG6TCg&w6)ZS@BH#Iu|^a9oWCtm}9+nC3fNvjOQ0 zJOthUlMMVvQA(5Rq+QBY?KsfQqce@PGkxfcQ+xeG{AeaAj(9WXRO*W?1+G6T98>B`jD9}znP~Y0|A2o#C>Y{1c&Ru9UMLh$FE4%eWkP84hhNTDk6cgIu6FnK;Hn!1Rsoo zw@1O%QE;h%DQW`Lxm62m>iWNt?CTuAKS%#%c-a_VeHM_5w5I_f!AKT|2z4zGBa`$y zLFZJHgN)IJyyAb5*C1k1&lS8>)N_R)SQ+SSOb3w@A2p9#46E6bFQG{ua8o~HJ#92+ z^3vf5Z7*qENgHd+y+PUl(mXcpInXMd93JD~fqLaH7?nIZ*(b9%HO66LrB*`@gLCYN z%NETXB&7!7(W-FMfJarCAM~~`e{Oy&|J$9fz#Q+OR3~*@8Q$NC$I2qPs4EQ}V zlKWDPgPa+Rcn0oDaSs3#$s$vixIrVTDV9XK*qeiYau)dt;jsB z5*x$1?7s)mOxN4O7|u%EEpjqpd&rjC45CbO-#dKrBzHOr&S;PXy?Y=cFN_EF;`j+l z2#do*TqkwHI#Ruh$AD5udWz!ko~w4jl%Ac8GN&i11dYV#Lu(hn8rI1#(7-`{1hfHT z61kn3))LEPAd|f=b`}boYgf|2=DwpNpyx8V>J}7uxS{6$_7u`hT+0qRSCxPPM=xL! z%lXmTv}*Zzj&j4#5G!7L_8ipVStAPP^5YNe#^U*%ICeXjYM&5t^Crkcgi7ab=<=`9 z`LPY16d(TT-bH=3azRm=)7{}~6A{5k7KPMnhgeLkkA%J0YAQ~Oh(W98yA-9WzWkH# zmNP;m(qBM_6J$+mJ%4rml9o^{shwR>l3v(AO<*_O@DEg}>Ot_=Fu`5~Ct+6+b5FKl z?J^@*Lo8$sNt^RNp4KP-pc z6xM8!{YNWBjH{f<6*}lgKFM%BHR#(_BS4;b03px;e03kN1$B!T33408E4G~0&enGjzC zADtFR!hum)*B&}i$|O%Lrz3m~&w#3q&o}oxSOfPA>ASS4~o;9xw%=onHo4X zGHUNt#neEK@=V*wz2D2 zIKoW8n}dT~r5m-q?l#oUhML(>ov2CePdH&z_(juV#5>`7Kds~>`cl?pvb4g3auR&4 z{2nPU5($Jm&~peLtxwnZ#n4;(`|@Bxy)3Zb&JTW27wmeB^kVeeFfPjXZ9A8dKY^ zw~_l5r5y_&S5Y>~I)`Y$yx|O}j+Q-NyF4uEZjVVu)G8t3vaM+Xt)<6hY^Kk|LHlMmZU+*Vfl zSXsFM?tG16;}&BsPZ@a-n{nQ@7XMsK;J0YLw|lrfviGcswF)xG{ zDSni(Yvl#-Kd?*6DkjR}U4D6%hVB0WW+q%KT0qn)RM(2y!0_~>JKUh56>;RUR$+$Y z!I48%@-)w^L3GV5i+Jx4)Y5UB$Doot3bd3sSAo*4_(CP`HAPlz0B(tByWuNfVxwhZ zO$=X~2xFs7hfRi+Xlt<$?hD21w4zTRY=X0 zKCm6m7uOAqML^532RpFzGe@p#Mk2HP^Lq$6i}KYI$_lij8&H31xZLZ;uH?fY`VUIs zfV8ZD&m;A9P}M#xh;x?Uw990~To1etQb#%AV<3~_W~@adt?*rD%<10lT+E_k>NBxu zcBON)>C)-Wp`DSLP;{QQY|i2B;4FQOqi>wAky?dJ*r_vsBVyL{;aQ19j23D-<;>05 zKOg2!>oWMAr(OqLFXPZ%`7p2M&UeK56h75g;F)J*+*)0>YhM)g!J@uY)HyLX)wwOM z-UO9X@^A6&*PHAmZOpy&l9ny&Z@_mbsYe7@{kiM#gU{^Kx(TyK`6t6z|(b8x|jVCbkwS1Uh0^WS%K`t+=9)jri zJa+IcAeDe6F)G!K3T}o9ZiM4ZNjbf}HNrhrQ_ShZkElWXT5IhvH&r*miSUiaSo-?_ zO=KRxvr9HJb)oIX{TP*1>!=&9RrgCAvefX@oKHQi_R-&JA33_T(h3IzDV8l8;YD-Q zlW-u&wUpg&b2(KqI@~}jWE7@{2Wqf(VSG5t+TreO9A}2BA4Gih^u#lPW$N%=kf7-v`(zex2>P*-20v&&iHD$B=!lQY>>HW}ZzdjP|!?zNx7 zK&;;T8Xuo>W%v@zs06IvR6{fYRm_j>w(xZnc9DAYkBKkqK1cMV4 ze65Y}S|o8VxfhBWo=~a3K7-A>P!d&H%*t+x6x#+Gz(CbOxU4Ntvl;)chwdU22QAk# zuA%eifvZN*6gAYt7(K*M)S|=K&ao^L5|J$Sfa+&1@#J}E3XOhA_K62zpcPiP2=HbI z@J0ymdPZy7{+_H^-@!IRQF_`0Ck>egbeiguIj=)ZE4)C3UQh_nkTW{QF{bbUsOFRA z%WVf%QR#J-;W@~aS+zwij0c!-0hwhOLsTl5dX-%D?Y}Vo6sknMh86ND0oa!*Ujpl_ z_SKMNweyDvWd9ITViXErT8!gMi}82|4F{?5W?>>P>~nhSV3VT+C4yV|Qq@8Njqz-I zHh~PVE+LSNOIq>(z!qlJp7n6E;(jDL9yB@8#)&m1-)Y`B-%{ zj$`nmY1u)Zs}>_!7){Bzk&Fkyu=1j= zL46xPO#%6xb%2Vd0@`pNWc5>pbU+bbJv>-Y@d7rBV01cyzCmtEQSEW)fUY<5(;qB9nPIBw+M-NttJVzb%jNMKJBO(AXJDE%jy`4 zBo??K-$0V_kdRQ&3>NX`7SipkB^p4&Ed=Hn0KKAj2uKi4wpxv>h!Kj>HU4r3UizU< zoq`m2@~M_c5khi7GsVkMXiW&PtX=}4LI=WN6rG0p+E7O2F zFA+E`v;=v;g)ZjIFi0TVNutXyM*=;<@@51{8_`cBy>-J4RLv*h!Al$*wyeYEk5e6c zf&r`CG>k$?W}$QsUt*V%5Nh#=Hp>mJJHptXBFsOP_YZo*DW-HB)#JUkG^gQ~G&R-L zltx~`n8-#$@&vRQg|z_k2Xt>rAnA(!*U|bGE?W;X{=xx zajF~B_H1#(D~O0~zb16MK-Z%h*OzGdi;N^V7!6 zMAF;ScZ`{LAfp^JZ@@Pro8uqKj&c0e9gtf9gw4h8S;MUOY8qerVf#afR2c8h2gpdT zPz%3=gX=E=zU2X^y$7N(Y#PwJU?q~Z49aRYBT~AbWgtpB>SL>|gc?)5lA8I{yaYl8 z7puray8T2`GYYR@Iux8=0tjUtF*aNaXagZ}@F7A!Uk@5`8!_753MfG6vpWGTBP8CJ z5E6R}2#LL!gv8!tLSpYCLSkL+_S7)l{@nP9YGgh-C#$gzQ%vQp~0PBwBM;zY7gC;)eUdp<`pT2{Kh0SdphqoO7vR1-p>6+jU~5rj;LwJmGKvEyE&av+`D zkM;*edx!7j*E%Cka{V5DCUIAr0RONKz=R%isSH%6ap|SVz>3?D$p#Dn)ekA@pjpik z>cUH)80X}JA1uu!n|UQP55biOQYKV84P|-gFWs=;k(rBC;+ytRI1%CNSb>5 z0k$jb=yHrOO7kJUjgIri0i*FupwHRpi?e_RfmY~i?gq^P4r9PY`{TL5*{JZV3Gr$x z(jOT58omR09!Tgr4L>T3A2f0g8C4p-K^VViWNrFApNIzD z=M{h&eW;OXYizMKr2cW@@=^4qAx4trNSg5(vr~103^Z>N{u;0qZk<%Ue^6`%55tL{ z$Sem_E#g!~mg`fIf-I3ZbNl=_cyl0%0BX$2I8Ke5pb^Pp5UOe1WtaM0LNlq536fzs z)2yG9aZrMz?EL0mxK#&%!%g}*893zeTX;C;F2VFId^GqNM!kbqN7Pm559tqo&o9I% zHPj5VGLePcn4s0g`L_oF>##u z2C_q78!kfkQg92F$CxH|!8EZSrinwb19fRm7Pc$ke9pP9GOQ0Adg@p}@mDbhg`cl< zGFbShc$+*J&mr#jFlMncg|zXG77pVLjFC3BZR z|D@hRcVWyLEE)`Khxfurxnt*O5qO1qAEu30SwzLQUIVcG9_g@r&HWyZ1`coiNIC)IGn%>p zvZ^x-XfbZ;h`hs_9%R>$Ej@Sqg@7}nsQ(HzXE$s~FZeRXN8<=b;oG62-o>7ej#-{n z*O9Fut0_mj=x9@pb_4jC3|QIz06s1tbc`Q8j!6yqQq{Rcf5eC1BkjW5*YAzB=lW>K)0Ln%w^YrIxG}Z*Q{Y}v8sh*@iM*0_^tEundWBb#zeA3?U z7BatkNY6nM5g?p{@ER)4L9hUi!y5>*M#IV-5R?^n0kM@PrgA<&GS6KIQh+1F4np&2 za~)O`s=3WwU~@;2yPm_Pi=Og_7K*u_h(B^ylLug z%oo(_?;xkC>RQ6tm8aEGLs(MTFf1FSCv+{9;=3X}wM&;S?u!=ApSN(fdq{rKyoHP0 z?Z@TMS}<>62RB&hsg539-6IwidEJGJ7A;6m?b+3R!6N*YxyHJ8bq~&;c{!wp&nuqo zUb4tn=+@fqk-5da-T4b=xfd@g^tyZY>E0vD?Omir<`mAGy>M37^wf#@^StvG&UMdO zROns=4;IhQUoyL}Yge!wl4y*v{%*&RMGF_so=FWYV&b!D$}yRV7cQDVAA-Xq0Sg1i zT>_uI{B?Gn_WUL81^M2Y1{FEe{L9WHoMAx{=pJ|uB`vTtgFmg& zpujP40#_&3ist1nbdOu)n?Kv@H5t)X zI}UByy+A@Xs^^HIp4osSSK4Wj+XoM3&6_i4cH!)WUdxxog^Rq4W-glVE}mUjG;h(u zBD-~ZeT56Vx^tybF6%SJu}}o*YJv;^B3jMnmx-s)5u?N8NHQ6eTBv7B&82viYLpsOY)1P zb1c%*^U>wfH}xJSNh``-Wmu?V9Kyw7@oEH~$l;ZGJ$Vd`XTIfXa~4X zhk9F}r~54R09;T*Iqg4&k%pIZ*D+n^*$_3(PBng13Y zsF~TRCULH~qWVEPNOq__K8&YnrZ1hhGB3U504O2zy|j~!Y$wr{Zom$OF_CR4j;Y@U z6u&fwkMm8h<))*hr1aDjjQ)S@2knD$!BqZCG z=Mj?qP^PB$Lpu?Y{m_<#WPi0GA=w5^CnWX~2#LL;Re;3aZ-m6&4}@fY^-DrxZx0|2 z5e|IWxvgbCihll z80!GE(#dS|PYr}$*xK=7@+(CF+S#0&E5^O&z^Covj4r#{idE^)VuZz2jfkA{R>31Ulv zzq`Gn+&czAE@jmdvL~1I9xc&1>HyN_?L}5lq*-}d6q_gY_zt8mga6+cZjDy#V?Mqb z(7pUgfVTmuU$K9R6-UpUp02XPa4n}hHk{!jBBv9IUoS!)reqJIa=0dY6{>8V8fja< zht@aU0PDrJ_4(AfMO$x$&4P}!Tmbj9$Fhi%cS)&ZQoE`3$)ISMtO2rH{4BIEvD5UY1O6EolU|+NEbESS^ahx*dzB~ z)`RkWhedEMof}A@JuEO@6rubSQ1y|t+Dg2LIQlem85-o;G94{06NonBzP}^hvOl+>Iu;yoyTz0 z&=vTN3`w#R#kgN?Tt*0eHtwV(gb2ZQ0ihy7buR!kkI)5#rW3lB(8YwFB{YiA_k;!! zYBCB?A3}2pbs_XTq1J?|2{k4(n3-?^s!$c%fJ<)cUdv@(ED}9X0v#VveQ@6O%02yY){Pe$H$w~#r(7B3 zUZ>n>TMj$koyfb1yobr_Ve?`WtAWJg!3j5uv0MX|e}S(!Zsbx2m}`u7S=bm=KLd%L z;5U}i`e0ax>v)CrF`&7)F`+2cSWZrRaBwRy_ganXNN7j`V~{Qcd!Xdx_QAF|wyfHQ z|ISs9K~x86ja+VX-fIPTOvq?dJ8;lXAj6+iKnLcey20mA7t}m{Aw6*|BPP@V z7|OCfIR5exp)8=Ge)zzF*1%vw?2?bLu)d{%NQT^ zVdHT|n7O;qixSDA>*}e0kYx$@K2c&v5Q8nng*fjOIG*Av!xLIKguAky5dhaMZ4&_3 zEqyFNlB=vr0NlIuj{vxL$%T#!SCP2NS_y!=vUpq*=b2q)*#h7Krm+Ixt}NdFUd7*< z3(~V}XIp%_Ry+fOamiqw7fnIw{DbXNBat<>3jI9V(1hpoNorAw_5-f6Jepf^Zjy87%Cj(Wyr(e>;AnaPsU)?}mxmIo=?*u+f z9xn3#T}q;nYh{qU{ZSsSq|@cr#=R2OV%DF`$$~j*B`iw5; z7@5Vk%<(JGdXmwdG0cnxtR5aGRP$cZBz5mbn3LAdm#>W*+3t5zB7*8uSKHjTZSHz< zotWwx84THbiRP_AE90?*Qsh~}lIM~oEH?>&uzXzrgr$y8gyjyQAS~Y$0AaaH0EFc` z0w65k7XV?oM*xJSt{sHsXQ1eLV}1H?8G7WZ3($TloopefdxR%FJhB+v=h0E)_Yq1` zLyX?4N6Ec{+|S8vN8MVsE=TgJ<@nI1@VLzpF4i!gXM_th>?C}thH(H3Zy#zHFTFX! z!!(Sh;RyHFa1Fv;HJnNqR|M15nuPIyoiJaG7N1x2GU#>95h=5}=7(qROAb!N7abRc$erOug)4;CQ?_}@t&aB}i7EZ5p?!z}r z3nDd~yC{+*BD}4HoyNepaG~WF<0CY{gwX+Vf<0MaZ z0dT5DZ)%!==?t$@(LeP(IxRc#M*ecOuTkLQjO@fa1&;YO1n!9bZ{;>I%8dfk>Sb&5 zz8FIpmZ1zz4_G8;@}hf;p*Asw8U;o-vOJA3TF)|C&yhDaNZ;l3k^i_0?-Zs<7PGhe zY7PniBE^BXpnH|;8+Gy`J{}UrsbM)wE9ViAo>?v-mV5M`lD?==6l5c$CSS}z#OIEh z_znX9ZQ`$g#Y8i0qM4LI1TUJ$S~>7Ptvsu(xV05Gngzpzf4IuSh8Q54_OT5yBs7gt z#y|D8nOsvTILWfX>$WgSV5q9WNDN1#c@{bm`|`J*FUzl$WDVeaArU8%@k0;T&uf7h z$kn9F6scB0dO=!2O_*_91C?Z>l&qRmsfDx3@z`-oHO?OjR-&<(EWSqxYbnr5LPBF} z3#*tc{vPB>2_+Z?>03yz0Tul8MS;`Uhn}IpWUV9X6dz31DzYr6T?O$*K5cQfZ>Q1R zqBbJcwjT%krg((KVkT{rGhvhQBN=wqbE1s*bU_Nsa9kN>yhH{L;3Cs4(VrE>8Dr_t zG?Hs_W6~ImZp$JMBRLH@jyKA1w96uQBRL(eCKxF#qvS>;*Mg&oM#kVMIZhj4ISsCE5t%hsj<*H)d)JjH+4|?INwtYHMcEvPmOyAnl(U%~(%7O>eu{(O2>M1Gu_Wb;A9VQZV8M}EBOYx7aH*i^Ck zy~s~cjch(=3~Jv}%YI$*6BT!*b^4q|$Y!hF4L?+biIayvOpG7Lt#lILpWNZPjYCak zGUpod`@m`q&B_JSuR~4EI>wTge%M#rNMns0n~S2l8uLM%j(-=8P`}i6fYcPYc&78w zc!fvaDZ2KpUL1G8wgzli0f6%G);;J6uod4(XJGIilS{y(J>SiN}ZEM z6DS&@=+QZ{U{ud>eUdRAl*mFrLpA{V8ocObRQkI01eZUE^2KBcC4c#s3HT*R)CYp_iHrWaI8ORE}G3**`&sN9`gb0?@UW6NK##qJ5I;o0SNwz1kjqCLgUXh zB}HlWj*Cna?bmFr>n>sZWQM*<5;LfY*wuERZ!by3>HxnFj(Hl+Zn3y9#yD^xW)R^P z*lSz#A4@Du(-&kO=PylX>5J&i+wFbt_xjR*yf@zZtvIVj!jSM+rU6{8X(o>gank7r ze#TsTAWp%9s8>=zk_$ZU!!PW<&R4nAEG&I+@RU17c8b_H*ntX?i}NZWkf-jQ9~I-o zYb>ulY3x7V9#cH*OO4K0lXeeCkvKiq6%kyuVqQMs3QWt${=6tNkoe%pH7-D@f$cBflTV*;_aeF2s6=2TuV8sM#LyCXNa~X^ZqO<;rgq+{v0igyTc?3_n#OG*Ea8Ax9`b*tvT!5qriNUNWKXVp3FBu4OwE!rNne2VA7_D2Pc#!-M?Jb~1BC*ivDSz(2FE5%*hL?vGV} zp5pXg(`ns#V9c_HG5lg9O*(vd!GJ~_zWVaJu4Y?sU^^im$>=+1*vE`jzdy>L6D@G? zE)dlOVr91xXe}VlEi0XWm|XegZS`6;_No~&x#}K*?6ajaR$MTs_W0O;7+vmI$u54h zwCI{_NubE9O3jB*waOD^)S#LRbzL5H zAf?_#cgXUX%kmg$md79~e)^tTFuUO+3#P?s1=E#TNCvxVIEp}*&2yJnWs_^5Y`TJ> zo`jtC4Vl662TsGS|Hw2is8K_8x~{U;#6s*i?qW{IAO)48^I-m*1-G$Zf@z%>*Q)h^ zPtJx~2_KMY-^j5lB4C_vfP_vziJIabr{ym92-4{QSz|dv>9eUo+n}!Hu2L3j0eFGE zn;1bshD;!BncWv$3}qHt%hSvr{o8KARZhFumcY6Wsm60rY(KNpV#CqH*cN(G?_zi{ z7IHB~=|vf-o0mv=s%jJw!>mbcnDMGoH51-c-9wvgX(WwVX#iSGz;vXgp{AuLf)JHX z{ODyM^G$Qrg)#V>B!L}l{o}uQ7||b1a8_b%X3Raf8mNx}#QVxk2vE$UH0(U5SB z7a&T2;Uc$4xTz?_Bzh7;!kbJ0Em1H~rIFUQ+ShxD*uJ*4)wWjg(l%T)6j2GgTc|J$Hm8wS8E)G2nM9y&d`Gw{H1uq>uM-bFIhLr75LHBJtkycMEk z#QmRnm|T7#9MgF!F%oa$298TGJwsQf8=0#qHI`C4DfLR!QhBw(`nD|kn9#ECV<6Nq z5695_n-P}UZY+kwwk3bo7l?dfE}o|5c@L@^k))V25hg1 z?lHtK!fZDOtk*(QPIPkyZKwL=CkQM9yDQN-u%70ivk%$RpTKSWa^Pf^;Hlj3EWzQ$ zEFh67OlOwhFRfsfcd1u^8M6dWwUN`ACHOt*K{N(xHt8|yK8Ma0LOt%#Q%H|hw>fl~ zB`70ZcFiS#9vCRrHZ^;UnNA| zt=kBZFy2FC;zlkKRuLTUAuVy^>p)nSOFmNEO+SRG?!=stbv6f`?<@i&B_Sp5a#z|cn1nwyC zsOt&L$3(~o0yAxGshsbUC{3|bCyg47fkx`pr@?AQNq-p9ts$g;19aHCj(e-**q&Gh zxDq3M7MKGlx-2j}Xn&`Ae+x(+Od;)5Ed<94_$Ugfwe=Fn`r=MNmt6|z4+|j`-KlEy zH1vUh&usK4=Hs#h`NbUk-yFWzf4N=oX|^r8z-w z0dl8`ceJ<_TBwKdc;-V{_d+gmPH%@%!=Q_j7U^n2BXHB@^rzV@XU`z2b4&ZG7~lg3 z?W2kz4P2=4KOp{mtCI=b zNI2d)kNo!nR_|g-cxTk%i1W~Ck3Io0>zC*V@$|x|(+E=|JaQo72=e&Bvs2ZhAXqyo zeasz@zVqiyGs=Q`k_ngd5@QjqeKcb=I?MXJ#FqI)Qil2^kU0HNz7j3xCSo;wbrQ-W zWutWK1xNd&IZfFUru><;iQ1;~^}3STD0sitw6Y8pvK5Hi8LDMDPMf@U7%XK7-)xOKo-Z(T^hd5?gSh7JMv=dzNvI zqV*k0X~3iOX^DA?n2(5Ic>+dlM60OH`|<5CY8+&#gBblpP8x=vLK5V4qQR&=ssIH^ zzg{*L%7l+RN>)z;PY01fS25j^6Ob%KrFr{-SD%0s_=CC%ti2Af)CKE$@P`Z5aKd)M zG6Aa<|AB0jG5=}f0XD@L&e+}H=;6!{gIcTqZaAavI!Z=-6_cZuAEWH>0i%{k|HT7Q z;Ze)Je>rNA;mPTv7SZyGu$H%|2@+*wsCC+?Mcz@T9_VvN^eAtEF&07@e4a(UgND!g zg4JUn`VM-e+I9hD16k?Kc6mXYf7R+#)plEo3e3aIC}^6}>o;hks> zw7dI}%@FB5_`tAJ)k*_61G{7Sr%&k9rxBWo4?T_or&fUjMI>=U9-dH45;v?606SXB zNS}_Bg}Ydu#x0Oy_p%ZT?i{LkgBbYyg8KjYs41SWBoot$k8r#|4M(a4EjZE@<{+% zy+S2_j#R5GN8YL1A@7lYhV_f2=vgF2_m4+8`q7eVzN6m`gl**Nql$Cn{hIR5arA?o zFk+;B_mS^2M5G<{=W|hFOtpsy@z(DVk*MAvLfrkEK&ZY&%*!Iw0IQS5>JMyOFJgya z+1t2z-@@(hZ!({_4;ru7>a#2EM_6scOQ_G|;FX-l-d?<)fZ%$=`XaJPuj=G&Ap8hy zr=MLh+L5)NOf$4B99!`Q`te#$q9f;JvdnbkF!_z}WZ2FQob_uuyt+A((1}F+g@{@p z)FmsJ(2b7+xt0_a(R-Zi#EYENXJcn0a@%dh=6-9rGbRJ&b_-&}FS=g(LVtIlrcYFmF^k8ik zZX}6fDI?3qF0iD5WoK17&a|VZ1=Mt{jAy|?vXNLgT zk+V+#?8y0t0N9b!EC6=od?f&O9RWd zUPSa`L=P2oqUuNV9YmKCeGbu8@{vorxlhGvaC6#@aC6+4hSHO`AqjRwPddCQ5BV`x zFvyRo0w6yY3xND65CHkHRsiJ3_XI$GY!LuEq<$*^KB2fv0DMC6uL9r`ib?={Lh&mB z@Cn5MC~OrS_{ilY0^nPUDFWcQ&ItnGqlz;Hz(*Bt696Ao%m-icbP)EizD-gNNyqTmcq2*u)kh>%kTjhn=1SugBn?p8NZLeF3Q2z? zsUJy+>RFP$PttiLZ6&D%2|`>ClJuV>oxB;Ohe_H`Qh#+1Nzan>IY}!>dR>Q_Mbh&m zZ6|3SNzag!s78_WbCP~W(sd-Q*8}I{ z4M__~I*iB0ktD^dcS!mRN#jU*kEB6b;4et}J4u(4^a@F=iAeJINeYnEhor|z`huiH zs~brgMAGj_nnKd|w7@G!x{{*Dtky?Boh(`(7%pgxONGyZ=2#;DbrYe$%Zy^zPkyR4$3FbH@ zS7gOSr-6dC%kub^V_UHA?uw3ceAyKp=lPaYbPV(@s_3}TH;--Jt@x~=Z$3Xgh$b-6 zcXLI@`93e&5Z^3*>TntclD6N(ziFGP~mt_W&qa|Um|b1JPc4j!GpCS1;&1y z=r``LH_%T-AnO4Z(Z|^mY#~%ij+8s??n4(6B|V`-P*(c9Apy`Ba2vBU2JtY0GzJ$4 zfW}~m0B8(G34q4nMgh@#^8Mc&=`Cw02+fM0-!PA@DKT!xFJT8gT~+-0J;lQ;YE7)p^GP{q!h$k zM@C>;@uxJ_3+Mtheu7)UIo4exfo&%Cd&Kg!JnZ87l-S9sz^)-WUQLb#kE)5wK$$h~|tu=9xJTwxo ziA}T;(tw>o>@oC(8#y|Kgi2z!5c>~e&n0$%)k*9LV)@0d#!lQIx8z!2Z-H>d&+;@j z5F2lW#sT{UNa`74KO}a5b=P=c)2{>eJH)d44GEtT`y*mk61$byMC;ZGz#b;{Hexqx z-Vcer@p@pV5X*%k=sPtX*vE-YB{rMbMC&)ihKS{Ey~dfu4zN;g1a|Tbz{V1rMr^$G z6tO=bwwayEOEvb~n}BU1_OHaAO>BQ_9kDkefvTF=cHAI0NbF<8{({)Q>{$13J z=dJ?sKhQ#`Tj`R!*bTpVG9LS&vo8JY6x4F|UU{-{c$;_}<^-$ws^X<&EySE};1!wj z4*Xobw+V8lnjn6YVq+=xAwITG!sD-Q6S2PaQun?u#TR0q699GZR|23T_O<}%h`lEO z>YgtBsC$iqLEY;V0Cg`xNKLZ?aP#N*RAOmT9HuuCAb-78NT&(k#~B8gR2-lDM%+=@{B)oON`NfiQOcvBIz8G zB%Lv8u%w^ZEyRk-vFa>hZzlG;#J-pf32`b!31f-%iSTk@`>0Qey@c31iJkZiupYIG z*nY%LCw3&ZY{E*vCbsPkU`G?X{VU|K- zUm-RGe_(BU7}$8Vkl3e){ghaR#t_DsNbCk;cM-epEno+zYltl(_SeKNMmMb>K@B8! zF|kh&yYk!^c8pJ*0Cp0w4-#9AF<3#OQp64?mLDpy{J#V?N$n^0d}0?8`vg`>@Gjol z#2Uo%yFAviCScD~KO?qj39x)I%Nn)?*l(yuiT#*Zo+xMehe3yd>ONxsNbIRjU^91u zcaX{@_C;b9u_N1nJzvcs_J_poC$`^*z+RxPCw48dZxg%aJCJ*!x}4a%iTxR{(tXAG zHkIZ5aQw_0H=#Fy6KYa@@elW%fHRh+POA&y+toayhP!KUVor@`^T`ZwamDEe4)nMK zJ!wO4oDY^i{S;3%e7!~QKYfF1Wq!noIsh*hS{DLg ztp}nzjc9c>IBoE|43thTGx5P1#9c+c^sI%GN9h%|^+Kcs>;WD0IMSy^puHNuLys!D zJ+yAsMg$r!*|2KRR_2D*$)a85D7dQ4!olnT2Y+mibQn>3Emc1d4rUuT_+xXFlY@r> zXjM4pP+~@=%Jm-1{-p`ZdkSXNo1L1FiRvK2sK;So%y2>+|EdU#_mm;3(r<3}pXC|x zCf>7T7OIsJn)JZm^uAOc$B#`3iPk?aL~i)T+ns85qVK_j)lKvrfViP?#5`bPFJk)_ zW<)Wvw~B3COTuUdI?O=B0NEuhswj<>!ZlB=gG4JtKBG6E6r!=omN@Q`EyB@ zk7S9hfY4ToStg9kO-u6eUD#0bOeN1Y@=OpO=BFh&$!T8Ab2)ix$#Wr~Gv(-;k|(ll zvI(`ahc)YOKv$M zzQUA>l0z9Ob48SVf_PCff%xZ$r;_W47bTBh3;cJ8x0S31;xr{c1X3&c4xs-hq<Xwi?Jh+FuJ)83{cLj#ykGcuZ8!l?zfet3|qf<_T6+b3mW>34}%gXrElU^mPNci zUj~#!kJa#e21FIZ!M98SqvEViI5jn%a}kDrI(kA?tTvSgwjYX(+xb=s5XlFsQh?g- zk4?r`bI&XFymcP1n=T#-q}tO76A$P@ZRTU9dT1ghgm{)O>-1&nMe&%7q#~X7H6{Ba zG0|y#1_u7-ejAx4?&5b70ExT!!C1)NQ;OU7(0bH(s2KlhJgmAJy3B?YPl#0&h`5S& zlY?*lrK?LD^hH#so&TcMQVa;Y4;%R5(u~rm!#(%K_V; zze2|=UR_GY`3(0M!wtnFa`DcUz`i5%Z73nCeg#N*i&3nvQI9Y%H%TIebx_fIkbxI5 zFb};@AFami2JrUU{gp;nkfIp11(90M z5{^}m5q_C4PU|3CO}L+0OW2-~l^r|{#G5LY_%8`hREr5mUb36P$H=a!aeRz?F)Nvm zkuPBl=40f1gakfD4#+=Mh{woAx}$uI%mDlO7@4!IY#}_E6f=oXm(>ZDmv8C}~+DWGQeC!7= zr|tw3oZbzv61|ej0lzlnZ?8wl0cs#wH!xY781kEZe3pj3kB>E&2Ub5rx@tT$w1_B1 z@zsmGoV~^|BOvfk-Sj%kKOZsQa}i?KfdF7N$O*(jSX7`NV0(@es2&mMK$vI2X`oIZ zPtQQ#eljZ1%T6H9vMX+ti!4(|#dPQQqXOOM1fpp5v=fNhMg^*UG%AqS3B;7EyPZIc zI4V%}Gf{!KHmcLal&eurpng3ACI2BR&}TxU$;qX<;Q4i$xM&^~Q^QA5fqv!$;&~0K z#tGEFXP^^bI)Qv;S~ZGQKXwA(DLR&&FGK=NQL8x9mxyGbaQ<}!ip!5#%x9(o`#B!< z4y$2(Vz3}u1l$!_#IXSKPnFGLRT&K#D186P;7b^M0E0g(!5!9{$(prrkyTs`j;0g} zgD*lgPW&EAiuE+{`+>It+X3w+hl%M^)bX_##Caa*yLHh{yp=IPPuaZ)dSK6(>aCN3 z+&Yc7nY_*AEep3A&+WML&sqb0)oP0VCq=ISgbAqiJ{*A+<6(IClv4dfL7?UFsUn>c z&s!CT*Ct~;gfYD|6OWf$^2XChMicVwIxs{!Z ztPAjmok+@nl`N1JGXq-I`JHrDyG%+bF7H!bS$ZqI?i~Ri3pW{fVjD zuE#EtYv3#~|Abi&SWZV=IZ&b+|Iz)P%1<}n8zX|6Hl@=D)^{m?735deOvhPPTEV*+ zv-I+p0IH&K$BWI%ZnU;AfR_Ohh@T;!CPWk?@R0cOj?7FIi)n8i`Vz1$R#z7yzwR1~ zOc`kHW9Ys>tA|(Ob}O*zX0)65v^8gj^vCM#SI**x^K?i#7Ncrn+ax2udc~Y~Gdwqp zM8A;F+f~v~p35+1|4DpMdxw3%R`?Ca@1FH=-wo9`^>|v~7>_QN^)i$)z8hISU}N>Y zXT94uW!lLDZ?R4kP)Pf_9V6%A*wSN*5zg~)-)VspG8H9nx`}d0c>g}e){efwek-yz zuU~E6fZDvI+Pr~`p?m-)7vj7F$9I%x;B@7+H>~gWBR9&&^4&{szc_Ew_)z(fic`kg z!Rt@0gC{D#pz_1~KNE`kpmM>5n+9%Pc6^dCHL!nL;PM}t-^Zb zwa7Co7YvA7VB($6u~oC5{0{{@Fx%l-8f}Xd#Kyn zRZ-s6Z|#9;72W;T)N2|twh z6PGHr#S=Hv|8FYqs;o&Nc4Fmj)Sr;?bZl=**hYnU#MTw%o^4kE-sG*X z+*i?bQN>pS%RO%nBxZrXs(Tb{C%(LMyXuE8V)oyDYya()v%A72 zY*Qa8ULxf-Nb&#sQr`Fi_Dnuql=oPSx4F_Ait(zcjp*2QPm_&&%tcn~id`=uW2(B5 z#-ZJiP&s(xGPsLP7t=<3c#jXXO6AVw)qi~Qja(%DPg76t+be3oYt3j zF%J?qFGLrj(%V(*PvLWZwSnGCB!4<2;~Xn9zHp{FNXEO#8>(XNZ0|^71~E4TRF&Ri za0zGEc2Lc1(IAT$E4veXO6A3X+cCxs5Lz>6`wLJcc@?%E1S>yd2EZq`S<$~tz zbxFxPPOhkDncC$2IB*H*l!|S~?0u!NEl!rvd0g*u+SuV5;zm~C&G7e}NO3NVM z$rWMxm_Nh)Pb|N)();mv@4j+W$NCuW$CZfJ+g#(_i^y?UT&33^`L#xWUn9K`tsfE>y-Dc@d|*ft6Z>q)4+|(e!sxjMmK3^;mPvdo4mU!y}N4F8?3v@ zyEo0Qjy%TU@ok9)N!WdIMTqH-^XO`{jY$CVm`3Vqx2@8_59<7dD9Kz3yf>NkACc7NYE@2iyyUfEuEPTUT(-OK*80JZt0#MkyEzWmYlrhfAh zU;9`?+v`sA2|I4&RF+_zz@U{@Jj~r};d7XZhgD0m4%`P)M5w%G0I+@-!{5ZEE0G zqFCbQDkQ`fxXIfEnVFRjPk@l+e;!uVbr6lw{*$e@)=tYAtbKe_B7!jx>zP3 zsN886TY4O63=Tv%b-SSpa5Se{kII(>$M?NopuoUUM#YwrG8_hudz9whv;b9bAAA7n=6LVk#LWtv?Bzeg7Yft0 zJO3CUyxMr}5E3`P&1dg!_z}@7ZYPR868pJ?`-z0ZEphW>xYJ*h9~fW$apLzkGMH}k zC5hp1euP__m%a|<@;f(qtECd{s$8%wx)P;#8~7&1O_g`N{XeKn;SSvF-FEvrO+IAa z?cLot0RDPv<3bFjq)MSOSr=b45No*>bBybP>b2wOGZ(ylz_3z}aL|G2ALArY%l@jK$0OyuuN2cKLONRuf1qkmr5w>6{Jhm5GxU!BN142z#@)$6d>HO;IW)KkGFxm^Foqn7h$_;rkl?A^2?WAsU}$_6x{rGK7=lU~uL2n#hK^TX zLK@7byAj7=J9GeKtnKY!->k-a48sIWsaf49MOMC8ty7MxDE?V45sxE z?E8pYa-83b!K_N+h6|ZcQ_V6BzBi6$#|5H zLnOzd&>)P*6A$xR=a4oK2lm#0rUTy2`e7Dar+$H~3}?qi?o;d*1M_=7lZ^Arag3aL zq!ly%)A6X0Lj<{+$XN~&_5tTzL}o^iiI04Ngy_rzU{q1ccn^b>-9O$#&azeTKxJ1} zG1befFWSmHjqxzgC0GBzT)pgSf1bT4rXZ zVI2>JjDmRu83j|Yf|3D(M53lMV@_kS)*-3tTjZi%iv7(qaP248@esJEs>);euxtIG zL4%Bfae5~NRO4=zyrl!76V$8vYOUM(_$GeqOYbY7#(Se11(BrtAaB3YFZ!4jA*TCuV|Www20zb=3}Hq z>#ot|I!JHzu{#UL187=r^@ZluwBG6q?P^Wyt^QvrGeOgOt1qj1)F8V7dI21XkMspYvWKwU2<>A){MC4j_At~B z5cs&OA*UHrp_Lbt3wx(t#80<}4-H;{Bw7W6@IhYM;Z~V-6R)vb68ED-~6TwwS|S^I{xMpQudi+&3G>2CJ(Xjuxb0P2TC>CpybQy(f} zL8&AXENfITSZEAML@E2sDHYWhVFSgfn6l)Gba4!2msjmn7+Lq(Sc4yS72s+!3&s{) zSuiq7T?bVH*J7Aq_YiEf2{eZ8w8`}4)p462y&mlckEHBZV9YC+lBte^VQOHbR{7^t zxd5_^M;vg2yekv7~2K|eu2K_={*`R|T&FSw* zvH4FyoaWyZ#jk)RKOFlkcls66+oXllLTT%D}PTcJzl{WwWlXGj@Ys4 z)t=Zs#HOj|dSX4qn(AR2yVPz%<|E3rHza%bYd0UF9=P!dBp^AGsPR~U_$Q9#ak}&| zm-KSD*B$QZa5-KciXL9CaX|&x!o_~*AhUO|e-C6Ub13pC14Uthiamm7b|wlY$a5R% zNlBoOmFGG>3;ld~-jC<7g*UzqV|FJn6&0Svxc93_S%RN)@FgpzC-M6~21AX92^Iqn zRnr%8LJGT5k?Zl1An#ND9mjhfaGj#y9F; zh91x(bmO-WI?)nCN;}bV2%`mNRP?ID^3Sf>-kDUfb3qgZvrX@z@38-x?O!ET>?o3| zSP(ZaOYLO@+KXA$EG&Zy$_p;iqk(+Tbfpc^C0$|t5hhSGn0a;x8J94`1Rdf!C&USc zn5siu5EUY6nH|Sc9m3;;IK>e8Iz$7t!q|rn!!$>7qGW>gAY#{n_95At=z$ZqDoNlH zwEET8h6|DWgcELn6YeV#$`CGGjt5KPP>tXOto5K4Twwi*Ot&F)xQL$4G)^<6IZSc* zk`v7oE$I%;l;kk=iDtS4Z^5iXOqwZB7mm(zMy4QjdKXM#e?5rVXZ!0{L4?2lFOea& zwrqiJBd=k~Spnd$@25R<1H3Jr+VTnp4z}HaE@r|qKNb;rewbqe*Ar+@t4dTmY z7x*r#=(vc7Uw;c97w@>lcV0z@=}V~SxZH=Mv4{8~yNA*FI5Bne)RCF$uL<&1&VCiA z;!0YeLE_f5KS8mQA#Z&SpUzg?^A^twy5V9@N0eN1wfrXjQn)syv0b-bf*q`v0I45f zu}ggqjR2c2L7$KAg}M)DV&YGq$k`84*kKPEblODDH^sUf?Tvzb>8Jb?sBk$?O8O>C zoXnsNL*4}-O=m_1*;A2UA5elA{1KwY0mUpklY~r2__-tDHnJ}S`y)Li+y&IVUn5}+ zB;4ajD5Zq^!G3cO3D$RYrjNCSFm>_qD2Lben5?)|eO_xK-4Z9EVCWVMi9**imya4RZotAmo1$fzu1=g8}PGKZ65&a31 zbO~PISxph*Yh-SEDp0vZMX6Tx4?O?&(@nZ&6ih8xrZUK~efR5lnUsP`5h~R|bpT~O zLfc%ZE+kfB6b<)jY%H*mIp3-dtl;EV?*0WYV*2;vR%baT$g^eAIP$^ z*QF;A@SSzFhYQZ@(uarfi5edx`1M0cL~JvL6SL>}u-BhX#ep|TMRnndgX>DbDJGtN<`5m3_{%CW8F zF7T>rFuVY>NBtT}hP$wr(YeV&7Qp+Uw{Zccc==c3kvVxldZPQ@<)?;K{AnU4vkhNC zQJ6V=XiN%Uxb=>apv%5-fkc0t;?E{svB)`2A@TYM* z)A`Qc+KV>L?y7u;9qykd|4~n8y#Iv8Hpb_4^FI!xZ&hnePHmxE>fNsyF zV9`VDDRdfK71u*-P7q5UMLHH2Vun9@D1NcSHvxPy33O47=Nk})Y}DaoTAY1enFkxB zsj;9&#)Y8tDYGf;`09Qe0ERiMtiKM!&M%((hM(E(wRO1>HA(&8v#`!TCPj8RG$VV| z(SFh&+we0;P#h-G7Ej^<-+E`BtV;ky^BV?pk?Uh%0>p*M0RnNgjDIzr>m7(|nbe`i zL*pY3K(zgTA@xWB`PL-?$`mLL(0o8z@?t<*@)AI?5_TE+1j+@ZC0l^B|V;A|v8oLRJU<24*0}?amfR&&hBb~-144ZOX=*al;&FI3R7^kq+NjKz|g;6NHbFCkoUb&=f#g@^nCU zEdZqT%M?DwF&~hYyx8Ge0%)&D&J{jNwgfr{P$3{Kc_kn%*#{_A(y>PPD0wX)EqR^8 zw*ipW`4Qp!Cior|h^6E)K&D7}0+8198KF|%76*F4p}q)+TX<_cF98}PIrysZQSvr{ zSZCe_beZr~1JaUr36)`YJJ4Q-x(`ra3Gp$Y%SH0%;OQzbS44Pk_QTvk}q_i!4A~~#2v%%LxApq z-$S?V zG{Wlp5?A8J=YcA?Po0B8C2iwD&USc+G-^YO=@0J`RHxE(@Uq(-5a zqV7WHu5qu3l%}XGQT4~bLJdbxzmX#iEixAPVg-B}X1N=maqw}#kHk#98i?8d#tja> z58gYy2`k9z72E>FYBtu-)ePJMIT$!ehv~AxSoc~WW5R-&1sUp-zo086J++L($gsr) z3)P!{4fn1xi7GCbqyCGix88couM+wtN6ieE3fd@jw|3;iL$The5>~49x!?+iKs0_N)-tREiz7>%YW+ z565YLANP}9bV!Vei5nlp&%5gtdZ97+fsJAUB@XZEdo&53UbF+0El_DNXJ8HtiZC$f zItXb0WguN@pdFd@B4~X7_;n}{HkwC;Vo{yKq~}4xM~u*A0-)=y-uqfPyWf~)xPFcu!3$hka#;kNcxBlSZdu^{GQyFw}$6JMpD&P9vi7)OXLq7TdEYEGdhvJT*1Y zirvq`sS3eoB{rcdT7dZ0dc4&KWk+SGFbS~|&^j2e#^VFT6Ls!JCk9}Q0pLF3KwF1jqxw9?8;5u+Llr7B zeHn~|%~JfqcmwZiDafwus8DOTZ5r5q1sbb43X@~6--BRM=g#I=uV@_7#yPrY-w4v z&=N5xfwh==Xx@pI6lT78D{G8hg*=F1E9+N5oUVAP7MKE$P5u-?Z167;@GF2$nbi5( zl?9)V@&h?gBE|x=P8WuuVCD;+X_W^GjLqIIes*9ahky%=EcHBUKK8)$1NU|ge#V9DYBHO^sPf6;CLo84x~bX#+gmFm7P%8PE{L_wvl$Q8IuJ9}!vNWezd(Lm zj~0Y%rqQ5OJp!g=&j#EpFMgEp#Si0NU}iyOLfvVkF~uxSst>}{c&GxrtN3Eb{4mLp z`42S1Rck26L)|JbUQ765A7zM4LfvVkIWk{C7%dYbMP}C5Z4bxB*7x8b`l4ekC`&M?7FH^0Mm^Oa8 zf8y5NrDttQ;QSm`g%D9+P}Ee2uJME=$|B8H3aw)3t&}D!bz3PWT*0w02M`%D(MqI@ zDO3;o4?bQ0*WvE6)YV|XdEE8qqp3gpTbz*P;Ty)Pfi<3c0kFKNKYbI#2QI;Mj#@bc z;QPbT{gC&rx=)_M5qB|&D8T?>9;K|{4WBf}d-)`MPL?O*0PP2)t{H?lpwRCtI{xW< z1+%A#8@LNq4&VA5k;(C~M+CshQ*8p^PpuXJ9pVQCz{yja1wcRK2?22O z)K&p5!Y9!Iq(23z;j_H}Gy$hyWc%U-k~|zqZrp*!EAq0V`u0NLe(m589)~L|2JR^b z$JR)lbvBH-a5D(&9RkM|>hfj4t#ELtjA+`+fxFegq0-|>;1$5}#i^25xE`bgM{bXv5dP zJ59uV2NEC`%*NjCp^un2d1vSbxv!J^bh#(VeW2Vgl>1=0n{po__hE7$F87ggA1n9k zk7G4o!6ykai*AH<$kLzt*`*0n=Rfp>ouE9fMjIp@p z;3~v*GjNaM_t&`I#KQ@XpC_=uCcgg;kpY~39fMnmx}9t@R<1J-v_|g z;W~z^9}eaECa&voO~f?|*AiSSac#i$V_ZMO^){}3xcs<6xMHu0G0wv^4A)p(lW@(! zwFFlIu2s0ci|ZL&zr{5SVfgnb;(Q+0Yq6b#`$sVknA| zq%l7;V8KFL#N0C9$}%5qm!0FwE5XTmc8Y1`4C4x8a$#|4-t_FET;#`Z5V8pNFDdnD zvhk*1=0HP@_?0|M7-KZ8iYUtpB{%0}uYf>fYy_*N0+&S`3qVG0ZV3y4u}ZWqD=9&4 zMBDxXa!OQTgOnot&9=_7VW2g59!9QN*`+>jNl9^uVJy!pDatDxGdeZ5u+T7WGFIf| zXXO>;X2GUK_kjP;#_H@_t2Vm#?CLvE-EcVFdJzYKQgA| zm#)nA(K`fe%9_l4OuLz_}xN%6gQbQjR#Q;SRT?kQoKZR})PGV5L>WX0?} zm@5Z)(|pA&(~9uex6k<_8lL=Kn?g+$;IAreJ5r{>5QD>qWm1g zcr0dCadxh*OBu!!@IXHN#t!Yr}ttnGI2>vQtZn zSJ_m4RF@@s+JKjC1)k z8F^F0r&6P|IA?ht^q6nlg?fV5e2qeu0eFEdBReN2ZzX684J4z8b}KeYQ3wsA(134Q zWf%*L9M&~k$lXSMQJ!yUHfjXcLJ$vBj}+_|OlGzZ4~B71Zhko6nHo43=UTwEfNKHQ0#Y9^3I+#%RA4UoRKwS&fJ9fe;FWOnP(uJrp@t43u1_`h1Y6rwLi`PY7-KNS;T|(G$Pe+OpxBwN3t$5(4^+nUb=nx@PzLADF|Y%$++M)?ZXyc=wno z=Dh5CbFxc)c_rrP)U+vAo43#LF1jNj9+7z0FdK{=od<)Vai;NpLz~&=Zwej?nn&AP zn%exSI$L)H8{3pwXZo9({Ov7mlD)OTBd|(W1ZV81Yp7Rk4W?@D4rBdh09I&GCmI?d zem4m9!NB2`pxGL%ZwMV`_~XI0Zu4NL8LV$3}k&B zqLHNfkv63Aq-qTWo6Up4KvzeDIg-(TWY+mxsf*d#26R)O}~>4HU?{Gm3<;QgI2 zg6M^E;RFb12IeFffMzfo$wzpHCVyS9nQ5zSXgn#VJlVjKE4~e0}bsG z*3f9qHjly)*6Y|LQ3>&XN6aX69WBg>*@&<;(0-~ot%!XFfk~U}-0|7FyWcZ+nAN*#_k8eYb9?oH_usiJs@xn5wzRjRh9E;nj+E%^ zcG64@1J{HBs1pX|_w=STOm@PqbuiIkmo8munj=s=mzXBtDAEW#E-}}d^Kl6rQ3-00 zGD1tV!E2nbs14@)xr^AY&+=x>^G-2Q{%tCPjzCbv#y=a31O@KD*J#wpo*G>P1D){- zYcyoY5YwDGW1e@>+<7yzOcT!}eN8AcVqB<+|7)qJIU+0#I9O)s+NH1xkjPxqjPAIY zH)l+qnK^g9nKkp)9t1}Ki~xnBE=?iI?h2Wcr)SL0oH2I}Q4#a>2o$D7$Njai=t)0y zde^{qPJ2)_;JupsfrgfPe~6w8jRl=3`#xq}=Rw5^2A^wpDNJ?594pPtE`J-{zH~HD zSwCzK*iUGY!GSV<2u&~Qdgnp35cJzn2R1cK^hi)`>rusr7-7v&KU*{weirVip#|jR zAz;4Ueh#8%!AG>Uq2LL$CJjVrKkRgI!isCxiyqB>)q#E#I%hjW!RC_y(IJDUIi}F- zLfg{pKcO0>_xK^)WK-bONj4#>1sx{oMMh(%Oq!AsY+{>*)V=RV(&3lw4i2R^p{4GE zB}T$G9&9*b9;ri1GTel#PcfVQO|7cAU7FEeu_HwAVCPAg9?5A9_zxlvKHLL%H?;sY z952ASrT_?ao$@mo-MAImzWkh?@-uR?SNif-=ZAqAWys2f3GwTEJq}1{_v_z#b7S6~_fopA}8#5-A6c^o> z$0+j)(HRFYt++53KU4CvR}>c!+7oP6t*r_ziQNMkf=v9{BHW7*u1$7-^uv9-Yu>MZ z?*nuHJKMi7Yj=FGd++~57JC4#K@`t`7@*$iX%9zR+kO1kJD0E2BN$qTDXqB!S zd$PmLlWjrsv<3>@8gv(7m0fHe*sdOKIM~8&Z$KSGbqThi^{DfoLPNnK1W5-2>SR*` zJE?y2SO|q`oH>2&f-J9@IVvaIn^iWw!Il$2b^t|;?nJ{M$X_Z-yyNvxe+b)+ zJ`HZscH$#UWM1S!C=TZmI6U||E&fao$V(9I3^IE+MrP)`84EM!d(Ek{=FXiLW^<&Q zIoTz-r3hb&5fy(+?7NQ&tvRo-Fu7hJI{82+WH2JSh~y> zb+YS}Ba~edMiOi@hop@hITCVvqs%rGBs^>G(M%C!L{f+&Xms23n7BQfy*DWm=%kFqqj_yige4e4mr9SqdkF1;kFe9zs%U{4 z5ycQabnhWiI~{va-yUUy=#hQ2=pOh;4D}rLN0oy*)5b(tq9y`*2#m}RIMI)WGYqu_ z(Fma5$)f3$x4JL|BQsDMoFKXko9*=&EJWCKX+!@Sy#C`hHLTKT^uqnEXNp7c;TVP` zO){>-<;9hS>n>a+xE{pyLtI;Ny^d=SuEV&#!qxZONyZ>tLvdY;>t{V0$1PjCK)EKaky^5m5=K_T#w*-9@iVV_Ty^C74wZr#-+Hf#Wi`lH)Fn; zF?qiDmnmp<78ETnDqdY==2&^zJ~O8{H;)ZdvQ#N{s*{IYhd%&Cd24)TVR31xc~@Re z@rt}sb9H_Z@I>K3BZ-6aG49UJFELjZX5VX;g+GV`UfJ1O4-hU?-TH*)@Ca9Ph33GG@#%vb+nubFz#@Gv>_kE}m~p zn>%Ip+$mmTYQ~ItY!!jXm}SiKW_jmN%9u0Lpg}Wc7}|sYXf*uT9dcv(jA_&7&7FlA zM`Oy|1(_t~O z6-l+tJH$rVgL+t>{Y4IHY9kY&3jHh0`*ns>rn~=if)EHRq4Cy0BtB`0CBpp;P3>Q* z#_)t4XND5u-_!D1F?WK#Uu#3uTpt-Yq1kFr1V(}e>zIYL{$_OHWkwDzRZs32+w}w; zB*{#YR;U*;qMQ?dc!rm8>U4BQC!`w>DTX=BxY`(EIP>C$Zr>vfc&~|XL(h#HockUj zGvDZxvqjw#-E8`e9!;Oja~r2kaT{k{G|5Q9bv`Z=*GOE~;hKbNI<7^ya&Z;lLhmNf zz~Ng*fPLaRbwr_4Y?sEm&U%z(6i<|L&efnjBxFyHhJ9&x_7&4am_5U+8-}Zx1;@mX zI)d>E9>Np%C_*9-Go)>&Nn}3#l{4=wWf;^1>l$DH-Mz05N)b!`@B5nR>B$N4m?&`m zcD?(~o)16RZ@!CR$!-S=U~NMDzbg-#>50jf?m(16_B<;msahIBb?8UJ&mb8(&p6$t z=dLgUkvi1?T0(q{p9A>DaCJf-s~t0m3L_VPtCE?;f9-LQSDbB@K{01^;d^QW4fXA( zzQlOs1PrLF;~tr*Lt)%w%QZh%GHj}EZ$l@%&abCaF&%BP0&rTOyAJt=K~J5(1Jjh4 zsSX8OsI&1GKpm)4=-Gsj$6|u^C=Y2T_=u#8)sS<_;=A6*{CfLIhJ_ZGr>qxeSJ!~< zrrGdigLxP!mMK5294!I&+lpyVC?-o1a49mrf=oJbT9uRORO@}!gb^PmAzSO~R0}3M zSTIvfI5vMnvx$<1p)&dQ1(C2+b2}yg#P49%KOn8acfU2s_%B@V<7&axcQ7got{J#; zaXo@78{H6J>5|-RU-pvRyzIiflBFxHl5F%%QhjTDa7&nF!DP84S&2`;)Y*t7n9b9F zQPb)`fa1_v{6|CG^tGH12-9q8NVPWgzzV*#Ayj_?vjV|DuuZ`jQ5<%Zb@jpHdhRwn z3v>F4mOamuF(YLZ3Lkz(OV{*No0*0M3@l7x9wCIaAJjlJVQ^ubIbr&OO|)i0{5}#* z^r0Xih$Sf$GLaI2M`7N{o~9B>3@0q7quI!GV_xHMeY<(MA<%H7$=|GWJbF2f1~RcU z(SivmS>C`DQZMf*vq_Gx?X?DJuLhnzL8L7dUgsMZS;Vvr)SE6Y{A*|u$=A?&DeG|U zfj{k}{YUBc&3PWpXR$8)X=eu~`=oeDjS@4S0bd)$ssiWCgKel@+7W3X9OgpAv0$Ly z$%kIJ9n5yDx^lY3A3!Z*?3k64A$EXIqZ#x}Y?#N3VjD#^$sj#R!!eZP&VGMDwKn@( zIwg0u)3sv}xDnGW8Xv4X(;S}80(+%-oHO-9sg4=h?{GN6;yP_IRH?<13>TQG5L-3| zHHWajEsD`Sw!m|qnE_LiHLPuCV6dA%EF15$WlI}Q;iE>2bga|PE4wSZ)LNb$SqT?9 z#|5(f?a(tya*Ltfu2qzu?(?%4?`nTn9tBjjjX!Qo~HS5XldJ$b$^nWjU+D>EL=ivr^CzSqu3Mp4nRj-tuE zlQ;&8T8IQC#|gNH4LyR6rd=axOdd75mx5_JaVSzw*qVkARw^)p7&(aph9 zj!M4f^bF6X01I_5>u8>@X2_qY57 zQ;cosXEE+W0oJfFtYJ>>B#-J{{HQe(j54(Eu%Dv|uJ9mY8mdPb7)u8W7Y+Y`I!G7Y z%7zV5u!K8N=mG#cM-_lEy>sz8Z7lAmsYS-O1r$rvF?5J&Y8I$)jbYugXKhBKxYRT^ zV9`ywTwNzn%16_%(b>|wm|v@l`Dm1v4_et#Ycku~xr8u^9xlqV$=CHNq-l1OghI3n zL$SIbhUaE|S9cwRU>if)8Hzn{QK=r=JJr%c!Gx!K;2!O2c(kWS=rqy)$rdx*m^wpc z@#s#28Sx$ey5Wd+jC;=5aEM%|8Fl2Isih#R-84iur)O@nd$gx#YP9LqoCfo2TJ0W< z>Y1BulrTrinVM~sBZq#bW;?of@^3ZUGAR@32%*zoMKxcp{FQb8kI- zv6FhZSEIMPG@@J}6?L4P(c4QIJspt|?OTk~-310|>=vJ?n{9WDN&Z0AxEnNvO|4WZ z-7D5Mls>B13@#gPL>g>>k=F1uSFU5;*HGVtVVk%VFiTd*=1!VkI;FPV5x#e;3{?=0)B~Ha5kaNTO`b!jEjm zvL9t%0OF1|M|gJ_qA6yS6b1`>MF}JTDBR_VV0t?5@(4Z+M{J8M3+EU!KD@bL_T0I1 zbP$M2MJ6*2*yO4(^HoT@<8pfr-@u{^BDOzb-T{LoS-Uue5{Rys;$$JJkmno-=mnWFE&9K8m)U(?4^o?nHjlkLg9m$hi+4WoHMdc0@<& zf-Rg&tP3>A9!Ndojdi3RgGo*{wubx%{cYGH(xPNu>P#I3C)QSMVq#~Q36R*)pXXGg z9ji2f*zOqM?479>D-dUNCmGDT%|d50dd%rWQP zNn1O$Jx931^@s`kYE%moDa{J{#XW|$PGrrpMdxVnXlGjxTYHY%Gtd}p$TSkCsp|tu z$`GRE%$OaiHVby=V}%a0!0njR3Iz|T<54qBjQtFQWhd@~{s6O&lDGvz#_Lk%>?i{5 zGT6d!q)k>d@YBJ)(CFo#mX+apXD+=nys0zwDtHa;Ud_q#<}R9JSG1)g)-GMUB+Mmy zJ)vk=0DY@dRY%a(rt00BvuDhkH`jL2Yq3Xi!i~5&9?85aCFQD!1H}`bqr@f?k%Bc7 zR&Z{yEXF@^c2j0d)-FZRz&b+1T;V{D3`be2=O_z@KLr2aJ>aIW^Jt1WdF~85(TwVv zYp#isy<{mCc_RMGG;>SxS4JtkL=<-XnYjeh-SAQP!zQhH(`I4QQ&=x}tkejjIbw-J z;67T&JmbWNQw&;zSi$@kmAOeekl0a%VI=nZ>uv2U13gCD5Et%aqOeC#k~k4z7aK;3 zd@BI%@Su2*{^79jye=wkI)ta z5!E=O8Z1T4b)=`J+kTuQ@E#_qP>$O&Cvk6B!`GpbK2ZlQ?Rvt?)>RCajov0!FV(ebAf3KKlSn< z;z}b93W*hWB`SMw)!7As!_1MUiLR(E6fx6#qLUPsE6$Xt9>xt9h91V9>BR;k=rs&j z>W3e^-$e+2Ytd~?Pj?=H;geGepoBvkMup^Wa>kq~vm6JVnsS9xP|UUH{5qC^@Lpw# z4isfrq-fWyoip~-WNP$UxNGdr!aXcziMa3~PSV8`y;2@YxGq!@LDrm%nO<`qw)2Q+ zP>_E7mnYVhCHNo7DJ#E}`@C%JbiUXR2%2G+D(p1#npt`$7GptXnRoKnW?h2D6IWP@ zWLuO}6zoVH=uu~^2W=S%1CtXIngZTphL6|PYv{%9CrN9nYuH02@D&z zr5A&qZ7a6VD=vk9jk^tZW#PA)WEr%_Bt*}dW+&Pn-BJ45AeIO17m7}APr@x(TZ11h z3p%ox@a#Ed4Z%I8JK$!c=c%1|!`(G@q0oX(O<+3;c2Z%Zi%c6w^;PjcBU+Uv3<#L$ z(_3)NhqV2F?0pGf71g=_*thxGTB#xslECD0W0ITXCL|<;2qXa_K_J8cih|}M34$z1 zfncmusY~l?ZA)8gt@gdr-R{2HzS`{-x7NC&UG#Me2ohzHr7Hbnd;Y)QndQ#RotZoL zW+BKOn9QBCFW+{)^PO+pmE>lPHcra51q^2ngJEJE4@hB>#t3>xafT7qq3=hJQU7d6 zPnLu%8;oAvD3dweezOb`JQ+jAKU%=L0D%(4Iq@z*vD;ThoA6Xc@feXn7ru>_JUNE}Nop6C?%tO`QRr)~4W ztj!Lwed?Q(Gxc+;(u&zwLvfGBf-JVZ3wAD118Lu|Fl*GLJ_$dTMY5?Bu&&Ux$@JOc zV8y?~p(GOyA$x}v9j*`UhJNdrLpU;mCF<@IR3acLvltr;+94}2)Y1Fg@&ugV9JR^V5OGR;F=~8!P<(5jMn$UvP%J5dF1Jx&pr0b zN1uA^QT6HP9)I=^&pi!RW52+1m{Lih;H5oRsLE0mf1se|Mw@QGiIVgHgH#~ok(c+r z3Pl2l?<-htAVAtda?eegUoj8IQac*|s2i zJTq|!2J0HPhxa1z z2^j7Irwn^3*+ejef1oW#4jtZ2vlyh>(7k@s>UABg?+7ie9yx=3@X5XqX*d3Uokv=Fn@sdtfREle>Lbi5w&YqDh|G z(%5=oW>4Ux!i930Mfz)dwvI!Iw!q zr2+0)@6-uap870KSnvoSRmmDzmB|39C`YTBJ8u7Y6~{6Tlj%y4Pl~ZfAPX@kaGG(InRzea(rK4)~|`}|9i_F_n} zPfTA9*knFIDVv`iaKtcQL`2QxH$#4w^ar3}|6A-qJy$&-wc*c1pRa$_O zG*WO7#~+TO2~^DEnAF~*IPw4y50qv+j}PPBxiSklvL?cOQmz_$%0Dkd|x^o@=4olp^H`X!7;F!CrbUf)O|mqTocTH5{b)1Sz>r zK0({1lOw6Xz)G~IvZ_QoPlwG<=+;RBvCj+b271<`*@OexwLImemDMn6z`LyI5M*z< z4|)@I@HagN$qrTFha4&0rGs89heLNh6)%s0knib3j6P>DTe_PiCgI_HbQfocDyuoT zFVOoK_+c-q;kd&joIK+I&s9J%g&9yEJ4y>YtWLBz$jah?^frV>fTF`s5{(fLzb@(g zS?|Lgte6S*P$#|Jwvo4EiMZny}^B>Y{dlwKEZFyx0QuyPq zGOZ*CybI(m0dp@i-2a4oEN*{R`b%m7e%t%XVXpoUqno;*UXmmv8#%DR@zYGF2-bT#9cz^h=ho7oPj1l#Qi3Eoh{o z>Ulk}bSh>fkb-INeu}}8`N`D!n>DjMd_|f#V=YdZ^XR%JIg=Nf=c#liq6x}oLR)C! z(Wto62W81oVwu+CtF{8H=cgV&wC}`WvONx&3Kb1>?|ZnWk?+T};gIuU8A9qRBnM?e zxB#NB7mhFNKd{Nt3;!@&(fl43Avk#bRvq|3sk)m`fY9f9Uj?Vx|JFV%5cI6{tOoNW zSpvrgGfJX;;LuB8CM*Fo9t)3sI1g$~!#I+Eh8^M&YUE?x$0Wb!RM>JLK+nNCksJ_NL%8d80!@4>l@vFr9S8n!`mUa zZLNxZ5eqM%+@N^W(+{m}faO_)@q)Vr{oX)(1tn<_I)?JPR94 z0;dVF9|64+9pquJfbA?XHMJ+OoO%i8P^nKfmA?*)Fcbc2iA?%bvmrF{)Ug4R7(ZMK zz(BOF=Yo$$Y*g%){`sT@mITpS*aNZESdp3@amuh(x(Fz1mfiu%c;p|s_rT4OIKoWi;vU4&GARkdso+0e?mLKS(?wQ{sU!~vU#0z;mAU}5pa#vhjycg-hccJ zCeFaUmoQ_*V?>cG0ChM^@FdX(yEUGkd}-oi^7T890% z6MM^E2VCKVJw*6E96ttOJ4WsBUij5K$`Qky$`j~3ERGi`(sJgt^R`mQUrS_?{%_^k zU{C-a0)`Vt7}9Z?Xp;vj!)-3oSN^1rQkD{Tj*F_0*6@t0`DOrNz!;hCWs#mr`a|?Q zw^ToZc?FuiuN3=(Ah~-X$R9@6Fw0~L)JZ)~#6|PSIBAd%V`sn&(HXp4I(q9n$^{-t z1m+-5{Vhu3gvjki*i!+uwS&Y)Sq2SYiO?@7uus5&fx}1P5N%)YaZ*R9m0s(^(ej-f zWxx%N`oHxLwq2vH8vdfY5@&T9%R~7RWo00|mx8x&NknBlrW{%%Y~1z8bG17;c9<7B zzmt}(Xunp}5zXD{zCC-7$X!IeCP`N5v`kB;$sKx}v?T*)BUo9Mln)yur4DDO%0K|i z)JlxfLtJ*{sV~Si(ZSwVfX(dJlYIwpVqOc~bz(ot+9SP<_8BBcdJnM2YqaP9#!tVb z4i`EL(+~qN+FMJ3~0)K?gX92hHEwKm4EK3ED5d$!4#9Y~G4YFU9TYKQHIBh6xUmo1?TPe+= z50uNm0r&2M?_)!~D;;W3HloK&f-~j=MDN6YO?t*Oyxg}R28_qRzJTTulMUq5v$4*s+CG5QG(S6b{jEWf2%=J)8=M-TMW`3#3h(PudIlU#jC?^nszN!i;7U8@d^|&eg=Amm zaGM!P)Y6(8?3xdEa`xh*PdttT?*^`D`T~Qw@MOpge%=B<48Tftc67LmmyiD`d>6un0))~@C^Tip5=Xx!biqPQSK z?wQ%GIUt=39zfo&G_}<7+X-BgLV(4RlyW0Xq+*DduR|<*8e*Yz zYzYUrI$klY;Zso)?rJTfC-OKWfBD!$PygB_T$5rCy@IG`bcI4KJiI~VgyE$WE#(vP zB%X2c5un49*;1^9{IAKc*aWnN@mo7kp;3U<+`mIo)jYmKK9wiYpEBgpxR-Y-SL7!t zq`*yq*XXmxZhuJ!bGpclMw=qEHVO!liezo&BH#4&h~(9VzbmZ&X+47Yc!(wf8!Ho| zT&CgTM8yULzg8oqaejzqpH;GEs%I#N<2Vwm^5r^_oC?FCdGdqZy7Y`^XlJZeFwdYz z1|vf}_B@#%x<#YoazDfvDJ(=_82KtJX`ro(5{|IGgeVW|6H4-I$)C8{iD0Q8GQXI^ zC9JMILh+bdxz~wMspvs&Z3LwTavwp!h)-Nd$OVR6S0X!4V9A9E*1l2|YeEUzg7qjC zMSA1mEjhmO-~v@|FiP=CWOfQ^sG`H34A;22`6G&uN^Pn|r11};WGZ}=1V%?X9N8@; z(Wvh3a15WSz=PkbXo<)-{N`I-1ZNxd>#TQ%Yprh~+nd^KjpNCZc)lcWMncqwl;)+q zwYF*jE^%7gdhIJ4UiG10^2kd(9wFd%-9!Ov!@_Ee!Qlv;8za1@2Lr+(LGtc3Q9SFk zaJ<)a$6_&tS4TtPIxQUWNW*Ymu~5hs4${fsx$>#%Rfoe(2s5Ivq01!U=8amzaG*mY^+})|FRoxiUVkt)y zMCx0kF^oYZQXdM%y1P5OF`Tj3;^Ms6S?@$(B!baJQu35YYioB;I24QJ=d)puMS7Ye zk^Fr8#6WdN+fhe%emLAIhXsM5=H^&Fv_UE>kG9J>VjD3b+Q1@BO-+4tU8uIUwlxw8 z^~hMaKPzO7?0ZKj6sm2mM^?Nv$2io9*K{K}(}kKbz-UEX9fmD2EkcasEEE@DBLw*J zyd253OrEKorEAGU?hQ|DjFudKue{Q=3fIQSOreNN2JhtPcO)T)UvgOqhN>9V=oyh* zk-?Z8{Tc9KOt3_)fO(iKK6%~D8ayY`8Z%=IQ^3qx^6A>pNNR{%ns~1L$8}9q=*SoF4)Ok+L8owMJ`y(Q*uy3^Q7w z=Z_$~PGzl#juaTVQK*rSza;OGtuaeQ{_c5^2okbZNs9B@d7d8OB*~Tws9A>tGM4J` z(yew!)HP957*<1g0f8hDL%6eQq+o7agSypNceTp&tyK zabyAemi!oz$Px`tjzwC*EC@mRcqFcO!##jfSsrIO1fYRYQYfs-FieD_S?syI$Y#L` z>j`B9H3_L#UTN>U))SPT58wj~MF2B^E8OUUOHw%;;DOO-M1I2yGm2kcDZ_PW0JtsK zBA8gWW87uk_(L3wV$33HeyCQ>Pw0)5E*EnytpxWVU(hZtHzb#FNeGz*lor$&bi1>&wVS!R6Dy8H)>Mb*&RqgH zLC;%3!$J8Hl0gD8*%s2FXnck;u~H1OmW-X89FsJ6P;Q5ejHgUUqUX7yl1_ENNHGf}L&xw(ey$dXEzth&4F>YA|fZpNJU^n_5b zTPgsUyz0O|DO?ymk(ejP2QrDCqP3MNv^S5x^=Jxk0i!ANCj60gbhp&S0oRcPJl15M z(+!}X4hcj~_4MhoUhOx99zB8ywEu|G(l8-q)fIY_87)gN{zzi1XJraQsxjjEjOk#e z#mmG-!;GAaGGNh~HI5aQl<`1fuyN^?a5$tGtFXxD|~oKxC&TC|Mg7Td<{0 zqs4Lxm=@F#53}%)Tz0UO5V?#g#)0faB6<0eh{n1>tF(f!5-Dg`ix;b)gRHntCmqdo zb)e)bRV&f%c0{NVqY6+Cz&Z$k8g2)1U?Q!o=tfd?QdOv6AOa%_^wnr^Gel{&6k`I3 zI@+q%Yf2b&1fkvP7Rt|^hzqL#M5%dVAJKKtUq+#12GrIX4Z%xT%C#&Y#yH@*Q5|Jt zgpk~YCxZm2QJ{E7y%EhdBGRM#$Qy!$n6Jj_@nXi4Tt(F-h=zkXO2(092$6d9CKMWq z&7DiE2hECtf&lSDHF`9Ml8ZOlFBZcg>oJOkq6ws!7n=;C0aTZ|EcuFoj&OYSSk3_y zP!^B^8A7EoB-Ut7U3)7LSkJ7^!@`q`EE%olqn}t$Sh8!A5R0(_tPr>iF}zaBA~eX1 z$@b}uGT}HjbN^38}%=1{yA+6rJovP;+sJxDuy>dP6bYE}@7dJ|?7=nXUxwaF0PW zF~l>H{r8FNj-ZVm%^@&?c>!FzyYriYJeXXs!a}iT4jPg)*8(*=SnUeEzlo0?D0f?- zUk$B`*4G#)CWjEHp)+Xa>TU$p~9tyR$t5Ug%cCf2V$_p}QLgH|3K_02F9ATs_kRz?Cpy)1% z!*x`}ck`USlnj{|*(qu#lw4a!qKMScCDhh(zS$g)#AjA}7`GLa=Q>5hA1q({?3Kt^1EVEj#zI2?*rqkl|{Etu|boIs&0 z`^A!?YnT`p_Hh6L-p$w)fl$re4JMYCLC)-jYHxrL33NtUkQUDlYB}av@F8hpW-*Em zn7BS^o3(aWO7@u)Gp*hXZonn!AhQ^49=yZ>M?-7KU?w)jp!iTF{4$0EYGoIi=a)Q{ z!G<0&&btx{H3N*s#KIBX1)>?{_5;Z!#K!P2mk@3VwJ@EOxzS&HCctS86nmh($@|!$ z)<9^6mN1$W_8=&NTR@WVOBqv}L!ouCW{APjc2Ec3wE1dnC?A@4$lnyzywiqa-QbpB zZQv`U{2XYH)F9Fka5rk^A-9sz$qfPb)X;{Lj8i>~QGhTA`CM)SBqk4O8+hRHRNAYd zdbESgLZ5SIhFFA{N>wnZDaxgun@m@Rg;gh&G`H?pAUJtzBsLk$P-Z|mb=0#vdMt}a z4H!KxMOx*8N9T8_g;KN)IZ1Z4|5z6xzP%gVmjRNKp=C9i+-<2Q6w`aBKcbKaG-ViC z37!o8pv9mVa{!8sO7!X={`a6CYz_a%(A;m{;U$v&;yWz-hv`B;)( zn)V9|87!2TF{*+)$~BjsqLnGMe8zsKS*x1AI2wzDDF{dwESDgNt=Cf^YqP$Xv{Wf; z#-!#IQ!r2|8K^O}8XHMm>ctbHJ^E(9H583wdPrBy3rHkntsyqZnKMgZZW14}vGPZh znSr?N6n7X>haG9?D!2l&CB+Mgky)H<7a@^Xr~uU?3hO~Eg|sCm!%-e?`9LIylT9vW z3SOwOE|lMl)gB}a)UJi%uWX_IC&n>1v>mL}HMTfhmExn+aQya0@5 ziBFag{ioS-IoZ1Y#Zqlz4ois9at%(jW?Q2De{$3eIz#-(ih}Y ztcgJMt*@5fFrjHNnx_XteQHTy`Pp1s3xVHgk`_^4Z;X!X)0Q{_YZJl*uO5m15-9W< z;(8GofL62{i6LytOIHcX-)70+YoVT=STx!U>AHyqAwG%g!!^y#(1(Mj%Vb7kEsOTo zELrWS2g?F)(G%BLQ)#~~qY(nJAR|)qWRy$E*2L?$&N8qg7L!@*Luobx>p}83lq@ej zvAr#3V$2b?Pr-)*B#z}vLk1L2G2OU~qQG6rFR}MuV2l;UAs!2!4@xx|+4PZ&#bd$U zs3?yYN*$Q-l@_pI5Va^wrjWOG33Nu)YvKz?kg8CqyR{QWP3TG#Qh-#pvO6R#;T|p$ zwazi6l#0zd6siGQ5iRmcMq&b>sm2m~=QktRObw!t2a+8L z<O%lEOT0QvmhHuCH=9*#=EaNo8-&B_ zcf4WVX}t1!g&SMP(_t#4unP&7lQcG%300~zJ+9k*ZZcz~b$ZA~Un#qI6+}tuU zTwW&hTdS2BnZhlznN{XbEF8fyr>wyltyOCNO^l}W!lvPNM6ywaO^c&l_9odgTKZxu z5{P3q13xU4k&w$0>urr-5aFLqi`Os9FbT9-43j|8kfJ67wN~gA#^jSD53MtkNl_eP zrmO+sP!7|!0*ZE&15pbRuvs}YAO!J-EZ$Hwg9VznLeh@lZ? z%ffY}z}V%>&jSy&09Xids6&nt#bV2Ho`E`u#cM%w<1*WY3P8sZ!$?a~5_kQwA~vgJ zNnx6O29#48%+kq>c* zfg=YxjWPTl_S7Y~O$EbN2@v}8xL<2m%| z%6^BHr;oxb4cbOW8gOC=Cu6o*M;|#(N8w=r$<3jNCd>v-9>M#g&D7j^Ov> zy@&T2DN6sU#p9UGQFsy2J@4p)y;N1;s9yd>`bRWp^z`sxK~~*kB0~*d4L$hsES)If zL*DZm=a8K( zGPprGipL{;y)Q-Q!)0ZO3`Y?tjwzO~G@Lr4)5o%h4&t;`&!iIdDR^Wn`_@y-PsKe{*t!I8eDdHSd}|ASc;E^~F}+UWyA1JARk3UJH%C&$n#g)K6MQ`vpT?Yr;T>ivHk8n^q7JG>Jh z?_Dy@O`uQOwfl~n^bjQ>1OYNIp2j7>o+L>FlQ$13Y>ngl?mIu}`TvfanBs;TBHDla z=KGQ*#oB-U9h_79r@wFM+?QeL0L9oLUbnhJQ!-&&W4ni}o+g z_+`tcO^ZyMR#v9xFOzP8;Z?^dUoEV!uP;)KHX;6o8*Yflm*Gob*8H8urRVQlvSdjQ z?#}o-Tx8hZ?eUKM*Gmy268?amKT>ujSpSt}5&b=^PDT5stH$_5HuL*aWt)w7XZ~oL z{4iHrRL@^lQi#tJ7L_d1->LPL-+j{Gm*KNi)A+eV{rv`fR*U~{(BF$YDMaC~{@#fh zyi3Kz;jhu>u**DZ>9*L?Im?OyhWO8HYg^k5_}6B(wXJMf8N9w5a|4I;2*EcW^|s(6 zRp9veq?Z0(SO}*^Wo1Q0`a6AxqQA?G@=8k!CqyO`m6q!9bb*AU?Ivs#7M7LWuxy!` zf9mw95H6-qoo? zS4-s^ygq6;KDDqAE3TpC+*5GVO)TBh^5$>4o#p*+xF;)cgQJ9% zh%x~^>qhEpabJ)71GsO*{XyK1@9)K@*51TNH*w6Gt^w&Iklxwobn`gBY)ik50M0x{0J*V;28mh_;n)rQXQt5>y^mrrb~ zD4$eQ6}@)(W_-8ix~>itzdB@gb@|%W%QsqTU~%zRb>)W6b!xe?aZ_hkJXCMi#^*u!ed*9K^`*Zb*oA3%DM{^GL1yjpHKBGbkv2hevD@V{7>~UCcYYn? zs87ANB4pLp5L@lm2)+BOmakd9VYT;U$mq8A#j?N+2)AH*MBkg*WDH zTRCw<_lm0Z?LKX^)*_o|39z-$5^grI-Dil5b|KBm)f+neXvu~RWl8vj8s3o-`52yiqZUZX+vH?Cga2^zk(W7DP%Pk=EJ zlwP~4qhoC;ss6R4ez3D*d1AS;X)Y1ACc4Dy!v*%R-n)hCIyZwsmC8guLuDyMHYfgW zYehU*uY6PIwH+JQb#Gj~LSs{wcUeySUER>p)q&5m*|@08xlATnhVS{#ZftIw*|fNI zW>Z^f8&p{xYt}B`yn0jH#>P&Q9SI5P$3VQSch(EpK1F zrenj(&W(BvQzrJehK}p5?pWV8b5-|-6|2yPMIGxquG-Mi*4nvoV`tmK*QprM$n*aSZ9A)oYh; z1heYYhP1k-qB>X&E^?DYhT5V`SEfoyn(7Bd*FoHQ%kDdGv;4n>qPA37?AD{Us`A$@ zcx;skWfBFidOnEg@~82{n=Bz7x|LD#53@KT%?6-cBMTd+|2Aqx&aFn6EJ2p3C9?lT zMS21=y;-gi0af!v(|sS4FRie@R#NxO?@{5wcvxCN+Jyise-}pZ0gMPfu_WKH{}Z9* zxT3w;|5~%zV;qIpBmIiBr}VDCp3b*Ads3rvtS&NFW&|=LkQspi8-Zv$L=2eF;cr7r z%dCb)4a%|xtk~CGwYFo!OeuUR%ZxA1D#luV{pxkgH?8hmzj2wixY8GE%hzvoNuo(& zZE^`3bx+cMReKvhJt?E@pRt`aW0u;4DB~NpT@a{OcU;?MX5lAnjW6Pwfsnhp%+Td% zZd=!e&XudzcE}IqmQSouvX_>x%U)VnQMD?2X~jj^OPdC4NHYaxMj$f+nGwj0!09yt zXT1}fQR?FP4f7W-Ts*%~ZE0;>gpYyGYHXcxnOeB>@g2W^{IMbxX|ObTNPg1jD83HW zdmNt!+q?VCLkC|yR=WSt@!mbJ9)l$gT-7e@>R7RQ`C9eTj*d0R|JvR+`e1JHeBY}@ zD)t2)KlJy%Mxpjc%r1OA>)??-e2xwVD!l^hpbF#$vx5RvUD*Bp?lsGis`nLqz5R%~ z^Vpt!$6oC%iWgC-7CyUoAHOsSo1Mc)ksUh`i#pdVU#%|cSly`>J_p~iuc*)c{gp!p zQFT0Hm0I{4>{1**$gHm&lUXN4)!ChE+tr1uR(Gj|55ovaeWC9)X5(cxyGAX1YA@Zr z(!}Z5-UGcN5A{~TxS->j)f+n1`718&?!fLr;gf&gvkyH}pX`10)nk3A-z=gUeZuF4 z_8vw?<)Pl={CdQp!)oEg(kgyQPy0s3bI%TX8qzeh=+@&ZN_A1K%{#j8<|D-5){6SHUzNjcoFDS~L zzf+Vy{03i(d|pxJ?^KlcKcgsLcuG-z_JpGB{I#O|`B#dv=TSx3{jj3E@Svjn>KBUg zy`L+}Cw{6ZtA4B~wLij^-wze#*WXu^58a3QzN;wvzlA!!p(xc~SCr?zf^=U}lsCVi zC|my%1A7micj5gr2>&$3Ya7b=xT4(sQAK&pA25qlWlp_-r<&RO!Q?a6at58w4<)e;}qFgdw zQEGB9Hd$!zd5ZE|d@l3;vk{NaWUj?0G@Ae!VL}S7KfWcz1Ai0ZjyHtpIwr*Y!$K4v z6yo1s6{7EDAs%~4h;Q}^ar>VT|9?U({=E=WecUhdRD3#6#Z@;_0sm@#ilKab&v?Xa1KE6YddW#$7^m zd#3gjo1tA-3Hj#Lf>2G3G`g+P4VtgX@HN=e0tt+$6*=-zP*# zrx16oMSHIiV(ZmH{JkB|tMDE}_!Zc9T`I)mON3Z^i4f;465^4Ig?Rr0Atuj9+b=>H zO-Og45bv8M#Kkj&m{Ko9;dCL!O%)=iR)|oI5M|Xu%$g*`@(Lk7RF3{cF*YSa*dLcDRF5I-C##0SpB zc%LIg!Fz>x*9alre2)+Z&l2LmyM_4cyM*{x+JHr{z zbWG2D%+GRI9?NCR5_;Q>%-W+$1Kj(q-!Fl2QaGp3{oHx!N=aKWtdFA|ao;lx~ zcg{cIfbc-LAbb!`2rq;i!Vlqy@Fd~tY7Nc^Z-hI-AK{SjNVp_?jsct!UJ18^U&1lr znQ%?`CY%%A3HOA5;sNo2ctQLio)BM%H^d*}5%Gz5Mf@V35#NY+#6RL8@sW5*{3M}$QQ^T z$S24z$T!G8$VbRe$XCc;$Y;oJ$alzp$cM;}$d|~U$fwA!F6`C#7x@_Z8TlId8~Ggh z9r+&lANe5pA^9TtBl#rxCHW@#C;2G(Dfue-EBP$>E%`3_FZnR}vE<8t*Z4H~HTgFA zH~BdEIr%#IJNZ2MJ^4Pb%>19u^PiFbGV-6s4>Iy!M*hplf2WuHcSf>H6A|$D9hS=s zJmU=G=R1rae3~!8V0G>_dO-)D_+qUiSh+YL30`Xsaq5`%F`H>R;aIvlR zNIzmkmx5<`(*qAYaPQVGwWXz{tA*ut$@03k;zGH-+i>-w@%3Hx^>~+0R?dNDFuyGL}Pi+r!?sjtCb6*Z`QKfLYm*29NodbD>0 zdyf3_i4mx;Z;|~+s0>F>?!EV3=0o{NFJ~;qC+m|Vz!@CDcfR2n8^Z~!M-{R?$i{b$ zfXe4>_i?`P>|+15aCHYpQqDs;#sLk*L%U)a2K37&-X^7`KTUKH5dTeIUW=pcHxKXC884=}k}k3y8~+tF{l8}QJ} z@kReR-M3-%ksSd#Ff*50kH6^6_U+oUMSG%!U2HclISP0lmv8!?K3OMUVm-uDlmrCf z6Ai$-sx0XuJRa8Tm*d3_=od$oRd>npRd>jFLxmXKmM)C1F+S`)ZWVaYRC8tz!V!aX zU8J9UZapmVMrqo%4b}1LIa7Pe<|Cc4d~{*24?s8_=)Q8w1}_ ztDFxNwQ-sZJZE!SFruIam?A|1Qr&wm#!Y*ksqE1Ef%@*d?^)ur)~~KJdnEmQ;NCt7 zkHG4#7CAy1-pA0Oa)nn+aFaR=LIi??1(-QW-OMfaloXL@s<+pU* zcbiOy8u*M!I;M>P-w}+e40;2w1^_S|{Z!Q*@J7P{K!^p;B}6r$LrkajUwblOhYnI0 zfWwTh*WbH(&g|m*eHa)%4{z&|?c;CntI#_t6O$Q%K^uV)gI02;;LHeQM&MK$foRk) z12&$^G<)RA_EMMxU%jDY<3?%yJhO6E#fSoX*Jd^>oYTAjXR2Eo7B6g68W+xl`B7^l zt-F+q@pECrC5>uB^DMP-$(%*X%;oFXcWzSGb}nyMHACsLO&vX(x=}@$S?8+u=vAxN z!@qDxN0+*3RfnEZT?wP9jt%O1WKcJC%9yKh#wn`I>s+yXtE76} zp|T>{zILs$uwzrphRzk}(5#j@4cFo{m~v^^!di9y0<==iVjEjX<8d)v*tBo4wdG`^JkzP`h3q=uz1m& zix)S-(bnt*^JbyRt+TZDm&&0jM;(px8(SL?C%Z+%w(!I%3|gf+vvtn=g$tUU5i=HF zrY>ln*+^gl1T9n>W;bAph7OEdXNQ%lyMClBxvoTMs<@l2 zY?_1C&S;p|z!EV#1jJb=UjxL2jV%qW4T~DpifGj=R(Hvq#!K;BaN(SJ=qu)|v3bGb z*-a`Yu4SQubNtG@1q&A{EsGa6DHRjZL^*;NaTFI}TIQ;lAoaopt?HttMil^J$C8u! zrX5kJoYmTaThU4xB4#A@E1dqfTBbkm%2YX)cE%CAa1+YCDn2!Ob^8VIBa@%p{P zWrP#kv9$3DkQg}g07)z*dTI2R!6dK?=`&18d^2$r_*yYhX<0D0u@(6jH^bmqow=ZS z;iA^XGZ)QS&@A(|E?7Jd=E#lm#UyZA)do44Ik$Deg8A-c%vy{ixb9Jl7F_C8GwfG2 z-*PZt1y50r_8xrW(C)wWy|Fh>eg2Uhzu%$mc>KA?9(wHArytt!)Q&tjAK7yVM#x7G zy$Q#Fd-fjO`w|>4yb2!-a5%U(PkC_1Q;$FU^b=3e)u5{W?$IaysQr>f)vCqHr40*b zmBAU@-u-ZAsQ&iQp0{@O!lMn?(j$9cIdXJ2ybj`x?C8n82VvckxiTY=8G+0QxQ{^3 zC6msn(4)vp-r=6CU!gEx9Q4cNgZ-?DGP`jUq&TcR^X$`)J^bt+UQizS z<)e>3^Yn9haOS8y_1N$K_!qU1B6^YX$YW1D`mFlQqt8D2;IliP$TQE8Ff#+6epW4< zUNNxZ+#D*F+B0GT>mN;Tu{qzC7y4? zlj$KhZvAIGci{Oic)oz=zv6iqPdqHw88ZKwXC#LII|@(}knjwJ;pHCT^&a6Z9^o;M z@Gg(=tq9-tV53r~q7nM_z^*w;Av$1Oy{}xP6wWZ-u^fq@JRWMCiz z0~r{|z(58DGBA*Vfm0U-&WlbFW2VeD@3GUHMM1|6w!7?uUldiJ`jMFU;cwW&nQq*i zWoBNZoD4jiy6}*hySLZe5hrtIE|Pd_;BmtP`^3!uJv1bD^=E%>(v9)WS4moN*67@f zE-9l=%fP?@!N56%6~f@#C7VAjd3F8$y+eZE>CzF>Aj%Y^NroITy0Sh469WVj89x5@ z;^Wr&JUcfm$V;PJ?h(_!^Ww0^^Hk{r=@!=+6E5!(q-)lGXMVqZVLCIn-g8TNnKC?i z`vqTm;%$ZR$>;;=8|fVB-FrjD8G4YB4^9ghpgdo+=2pS=b21z`o#ILVNC!y|GkOGX zo{{0Fr{365S4Unq+}G~IiQaInz&(g}pEK&T;0qbNKK1b0Z_c>JC7+*q?{gVG-;X^B z(oE7$(onzg&cwaF@aI&VPwMZe-#Xpa@~i z!RJ$@AvK?WMC2{HMv&$X7g)%&EfQrw{I(Ogfvv z`=PNfOow(+XGpu}lL;T0y5F93i2Q|o=2YSLlRxuAVZE!ieODB(x!!i4zig!#KXazY zzqHL3&UBR@`hqP#%bM}yp|dYe2mg&c89MOx#KDt6TMfK7U~9NM>wnNI@w5E;PfFa) zn>|P5)JziRX8rr1-(xFFCEX}m*)5`*KO);P?HfCXo&JM5nasXHh8CnlHz-HahW%vY zJ9)0byC+<{MB?4ZaU%vD$J3=F^qVBsV-;SB*5i)cjLkEJ;0j}>UKb}my zuld~1B>qq~PZtk|Q$ETih0E88Ngw_CNnJyb4rIkPJ$3ljG8{d=>imvV!lkfcDNujf}GtSr;XXt=I2Phj3wapHBVYqdP7#$uh zMgrGQ=UauGQ}MyO1a%riC3n%Tkaime3}l|CA3dO~Ka^|yn!A4{3ZQcz6B&0}l=u62Pq@Fs#KJ2xJi(f4(7bk zCqZUS@b;tur0uld8C3WIeC97{8&td?j?ZkrQsUzKzWsfPr$KOfu+osuupOigv#(hx zX+v(|m_Zu@>PQD$Z^$)4#-8}?LkGCN8%+HkWz-4HErSB{wU;zYetyG_Unk|;>EQS$ z{?I4L@6*ZamxpC8|J0{N-4&OJ!Jr4~teJyK2e>w*FOrO2@YJRQJR>$(HoGR?=U`nw zKzGGObz;$tA4r+66OYM@iF3?feevvsJFg5fd%$)UO)F2xzvR|iM8{qC$a+|xAO1Vz zNWZv-sJ*l~a2tZOHTQx^V$$t{r!S;lAmfAN)T05E_Xo?4hw`V|ICDVYm^e9i!#eT4 z?|fg})%RvnoRac3(h?WB4j`Tf!IQyC!}`hN*`9S@`=+D~LHj{Em0w*rAnhMaI*?fp zoLcx#9p7O1-5Dsn9}{}7Tq|$B|0hZD-6lsDVO<@Nf1k{B>>v3&`Tfnm+?lkGOhX!& zihSbLKklv=Nkfm4G942BI~-S=M9*7yCyJ>tYQ+rQ+?=WqW_uS`SUJ`nie zg(pK9o(sA~8G&nuWV!~*LDVCXhV-Y6&eQ#zxFg)o1<^6&7!NapRr5kS& z=Y>Xyk-1por*W4yP8J=XyGQt~mnqZFUb9lO)`WA?s(XCH)B(3A%-9Q^JUYO!AISAxbmPrp3~X1<8wcD^@orkXQn)I|&xy)p32+h4nu+6pGhsH+MIo4CZ`h=MHflrDFEf=RfZeD#PjU=sfTQ@Om$%k$g zy;tNfzAUY= zbsP5}bbx8x^7@65o(_~>L)w>TY=s7w1`L!9KhNk;ZuNr=x46jka&hB>iMF`?;YDus zkUy38Y!~(4-5nVJrfuINs=9wGCN6(k;&nmEPep#{fqviT7yMY3M|wfpKzb6C{!&j? z@xi+_eL;$ADz|ZAn3v4Ob-@LfEl7Dzb0(Jxu4RJu$uAxEpfWUI;AsHIbfC`aQ%)UQ z3H{Z0tn&lj<4Ur`6(74jLC!bv9`QlT@=KRpGEY=oOWoapr0`hx)t4n-C;uKOTn|bw zNE4#-e5d;x7;%$6@=cLD1-ehtfq>)gm(Gh0Z2rMd#Q9T-QmSKA_`Ray=7Cuc z@O)|JEb+k60OI~Y?d?Z5-JB9!5dNsUbJIhS9*{2h!Dx`U(c=n*TK;}fwe^{#cwhg$ zSEOuSbis~(^Yx&(9wc31^)E!_nw^3)$-sB7=cNDmrpTK)2lhSh?)TVneCKXlFPvwa zsef6t^#dX+A8UdXXw5*a2YB8rbB3`0G=Ow;AkOPk-sd_x6xF;jm1S!yfoSK1I56}iZLj%&M0p$C%weo|ZAaRuUv!c*R2ZRCg z4C3PO03o>ptQ+PhRuq z4Ch)PqYp@p4h)2zpZc6sV5ly3X#&hp*B_k?omD?z(V91MO}FQM6Zt*yK3!gG&DT8d zQL!TSr1;b)|0urm?LFeL#}10)$Nw&ZUQGYfpS&XTcdg$k>4dfXbbpf$Ouff@Pov_- z{}iLgha?>snRPb!^}Es@`%q<`xaNyrw#jgmNy=g5(d9W^CDbPoB^9J@@VUBj+z(_?Wo; zBQJ^vAKaf3o(H7|M!IL7eofr<*+2K29+1v?=?5qal;9!nUWVV}0OxEv`@8&!;_K<^1}9!*{TT^OW#}y#9B;J$h1b zJJm{Gef7Aw_2%D;lA@mk?jzSev{81OTl!hdt|~}>ZX9zud2!-;fO?(@ldv9eq;-2A zUsoljf3ttS$TMe#;`ra+GrZi}=bX6Bl{1XE@7&Xu@_sYq{Qz^HkOn+{$p$- zRn1-h>k7-XpG}27Qnudn(i^Fw;IK$fIzXL7Dr*DU7`vT0Aim|+mZmpHF7rxUcdiEr z2L%@t1*(JesJ}MDnX|)Z%kQ!F=lnkR&x69n_-Izb-msMS5uSk8E-;gj#=-N+_s4__ zMeTn*nt=P1_e&Zd35@&X_oph}JBbh1Dx?EJ=^phVZtH_2S?Ag3%zIrpb?E||truwk*9bxKQx53Q zT7c)HPFEYj{_OD+4#HUPj|N>&b{994C!E!t-@QI*KG$*~@1HmNoWQtG{eBSK=USOO zGL=30{?Z7_7u@In(;xrZ-=b2=PyJ=kHG!K>AeFgyokJIxnS}M9^$Y>^K@H0<4Fn@9 z)}G`=Zn}#gVW*>QK!1Jr8`5Ep3(ZF9H>mx}H^NIRLv zurVS%7>J9q4)q*C>ZiSslLnCI=3Y>0&gafzVO1{noO*e!I~CuDx@r3q;oVsV455G+^xQVoY9E z%5$!kWhI;exhxXy>3TZ2Khm)0ap?Mp|K-X6)^*(j}q~|H)K6FIq zjY-t=8M^-bg&hfSNIict+$W6pM}8)r1YI`|B@JL*lnF=&($!&74;kbvqMJ^zYU^)Z z@n53>+aVuJP8|lYc3ATz`}v`u`hfEHr+;qn?Whaj9tY(cC+!aMJ`KLv#uUC+jGh2} zpU+)9v)rcZBi|2K=lSMwEf4cP(nZH_;C^;lwX{#Sw!I!_c9ZG(3ESz)%hcr!SG;%9 zncB&}kb1{-N(Iqt4_eleIKHWKo$Sv;S$GvzEt%Bq?x3h zetmG;6Y$donEHSaXh4cEB4y0q#=rGq%9u&YArA|R^UieCnVrgK1=IE0JMC*&^A};w z?=!a9kwhJB!wRg;eDb)*@eGf*u8+7+yMCwsf_`k0>HDa!OXVVt3>Uq=AKs-CNBu>r z`VZ31WHJ!b@$D+xL#(1Y+~=$Mkg9C?|ujX~b|UE5RD zZxD4DLHg)SLwRZ3)F^Q7UB35B}6%v3JYP`~=zbOFiM0R|1o3XM-0W~y2mZ07~8|Jg%H%gBNb zfjrF#>p|X6#r*)%taQK0U3f(->3BA*SYpHd%m3rnq8A}#gnBYlWCaj9(O&^2S=ce!HKEEF!qin6~!1E>$ouL&hBXVOQuC%}{w#@yad6Nnf7$#`%YSu%36T5)o;xB?NjS~ z@pt~@9|fQRUln6R&^h_Yoo;c&cjCQ41Eek>Nf|kl)U?(CTu%@8?+B!Ot~ZF>?_Bd= z{DI9W&zE%$M~BYBS$=O@pGf=lHdrEW@$=h9o0Xs!&+R1J+j8Q`+x4CJoC@7cc3#No zJ1D3OkehXn$O@+}OH%GP@Sjhqi%LQRBCFQhV9QCfyxxbiE|9b-9i3m@eJ={q#4+b% z-S2T1)w!(sJ<@uW;Tj%>y`Rh8AJ_eL-?i^6`RV*9_Xj=4OF1^EADp)<&O7^+>bl8q z9YA|5C;kMJ0dQU@=Vrhl^noeD*5w~@(FORFkyU(-xZsNqC$!VqZnyX0stZh4=U3Fe z%6GhTN?g|bm7vo;{r37(IscYSkLART)8#!Cy(xVi z_>D`tG5~b}+2h;Ng01U+ZqWt&QP&0d!03c|vurTthU;!&6F>ZoVYe4>c5XN=ogZmn zGF+vcZ^&12&EJYOzt6a)8)xhVrpo(iryBH1wvXip)2BmRD*L9~Kkyn8rwkBuFM#;Z zJ1bn2GK@)G0Px;`)iq!Ka?&!=wF??~N9+(&haVw|vxhY&bsazws@Tp56jG zf4{LDsJNQX+V?N~Z2W`rey;g5`o1`h`_Vh%bkIH2RAhkq@Ae75vq1*$H=fz*C27H% z6J~Qt&-E=QvN}Co;Bb)v(mCHponJQ2?qmVSz3%C4b{nf|$o*bv2P%AAZDGQi%1DoSk_(!7+cPhkynoGCzU-TRpzuGsVT%p_dB(>Jo~f@2a`6m{pPcGd z{$Pgx1a=L^HJJ7Er|h7#)lUX++5}eL`uh~{ANIjHA5IJIi1UUXfI2JE1V0#^&@{~k zch>c%-|v$x15CKQE9G`y@TG@ERw4Ml&wcqv^>~cuf_QJq#vj_=NS#!lX$^! zQ1~2<=lM8fU z{(jOjs<(aJ)>c2fH{wpF4A3v$?}N*chKNn)C*>!f^j^519hwK4dtTCUH}X%IW2eFL zjGxDMI)lPyvVAHqxE<{9Qvv@u20?8D{d|ScH=BVke3mZ#WnlczQQH7NBLc&a0ZV*V zFKjSn0LlW>V=cbrcKeqH7-*F(VG-M~zQ0tfm{XKTVG;NN@ zZWr0=<$>rxd5`^D-Sjc%g@^Rr9poC0yq|qKRq#LP8jJQ9UUTL28C?6BKPSci+??A* zb~u_A>{(%y>sAAnc~*sTfi>Rw`&5wu(&hcd&~-ZdY<-{6VL#VP8fuLX`kV7-=yB!K zpaVX%oa+)R&E>afyoSlC)sX z4K}%M<@(j20m)?9bYuXYwc{S#Q2Gf^&ko1Uak-GM%OD?20T0jCk+)(~obE%TF)mMOTI@{8Zup91r>t4RZO}RXW!I zZvKI&>l<4DeZK`R2I6IjAkpHr>pRKkDuEy&pl$_ZZM zKpPIL3{cVabX-29Y)D;E8n6~55AmINZ^{6m2Y&e`Tx8cnS=;UPn=-&qoedmaS#KLl zuQpl3<$gbS|5%K%*S*DJKfU6vJ3P~Qa@Gl)$f z*8pC1IPHO_eqooy|J>XUi0p!~X~CKw96I9`I%I%xpb5@2)_3Px)QU@9zw;JdGbC$( zbZmV~)~pv}Bfx!+yJEoAb{_+`aT)BepldF#bAhzqcH&KLX=_?A<_CXXapTJEGQh&E zn|_0@lef>%}*CK*my#mB`)#uvkh0AG|26}w9}u~ zS$RLlhwpyl;uSY8_vZMT&SlN-#CzktaIRhU_p|v6^4-ppCHrr^@pm@d<%<{oTJhhC zFQf&e1J28Df8CmYFnEk+p&)1dPKMr}>wCA0eBZ4vUifdMb)x~4AB^~u@eFd- zifc2kwmE%+Ro?VTU${&c&;9bHDg#h$w0_|^c^zrtf9|**G4Y0v+Q!(=&ktq$WS7?()C(^A8=ed=$kUy5B*TB^ zajpf}Z)5%7EN>{@gX&(qz9Af)|0~-(*Z$|v(tF;@ZK6u z{rq6ifOLHO6RX??>Lxa;JZ5rwuN=&ie+jL*ZG!p~MO5=8|313pm>p1pmF{ijye=1UV1jxBjAT z*GdEY;M0V;qIZkY!1+;Q?cazSo%`Oj;FWN1wF#_U*5q5xw6CZ3-JrqvW*GH~)^Q8+ zyXyAszWtiJ>1q@AZ+jN!0#c>LdV22Rrp5cuuN2wk=OpyYi7Uo?5S#y@*8Nd$pX?$Z zH~L^agW$hc*>3d2D0i@*LF@p&_EqmQ+s-`z@>f^5^T2tlkI3^zjYQseyXQ{=%d5U{ zj|uzy?b-&tjMA>n2{4)r|EQ-Q$TdK?ttaI+oWFRk7+Zq1zsJ4hf8+iVFa7Whp6R^u zGd#O!d|J4ln+@F$@{gZx_xC|NQ7;${qWd3e|9)JjC%fG6H37nQMR`{sH~= z0H*xMA8c?OzIc`icUjnn9y0;5{aCv%SS!vue~$@c4d4Oae&MxO#QlU(78qB7y+Dt0 z#?`8}HYdY<##2u}koaHo`A1S}gWU6nHfAOq{XIif^7@iZlBrW{U z3Af1locK@v;D!G|eEd>I@X9|};Z|IB!&kSxJ8K@Vc3IO{%RQO+ALKlspFaTSw}Pd9 zO2R0<{~q9bP|h@?a?5(XzQDw-G31K6E|G*!moh}=X%`h z;=Z6;JyzUyi>J=e>!QBVEzeMd1<}F!;lI-#Pz3sE1HPQ=dnc~Dzn_czXPIRfWd(W0 zKK(Hh2dD@4%fogC#XTe4m?^Ud1pm{~`-kUG6WOJ}e~+8%eFOjJbzkk7&MUtRFBz2< z@6S~?nf2wjp8EJtydw?ZUcYe>N8RLp14q5^pX&+c^Se$a|7ZJyTt+{gPp2<{vToS_ z>oA%XPX0YuHyXfvMj5F*%jQ;?I6yu4gel-j9{7@j^+BrN4j!m|fasQcQldT7S9 z;gzkmwtkPV9O;|htE`;-*=gZ_PT?f8zM?BHxAo2M`+n5zC%aA+AHP=or=E}e-phu_ z*=H}CA}6j5*1NMkZtq@o`{6%zc_T-9e-F+L_Zc<{`v6`rnk;IJ>>yuHp^M)x)m4urnTmC{vL;O z+o|sRk!D!SDPFb8M%(=GKM33nC;TT*Pi7mG4Ad5Kb?Ys zpM(7ja{juq{AaE*3T?ZsFkEpX^wbu3$c~|qt?8}56W0Hm zq5reM1AmXovD^6>a=zb_d7R}0eV?~EZU?vV`}g~nQ-=0>;htMK*Y5q%0o32$n^Jux z>mXk{#?$(~=YPxNJ3Z5R9UX`2)O>%ZsiL$<$XPpoh}(7*em?_*xd_oN|QLkt&x zUv6U*n$7pn}LzYu#>E^sj_Hw_&C?EqZL3KC}30dS4%mnT&n0M7%aga4`e z`Y6TPKL`Eyy2J6XXmQ(|EOo@|_j`Ll>60!bMg(I)JQmT+2!Z&x|jb9oGTS z7ErAk=~>qKpjp;F1o?eVVMR(bARU{3IhN(Xf0sKvHNN)0>yrbF1b)5Je9WQ)m>QeoSr*&OwYIY_ ze($N;0i^2Zv+mo^dA67RZF*nK4*Pbdv<>K@8g|HSuv;4I`gqwVKIB`D6K1XO>-L+vyj0czsoMS2eD=G(?OkWlZzSuR+t}E`3TBAh z@KP~u9Q^$Tv;oYGL_OO#amy_>{O2B#7aRt$0rc`e-+{tGMG(A2bf*_9#1&4!LW;rJZp_zKkk>_3A1iEZw*V;4k*=c zd{k`xsBgb-+ZjLa=O^3v_1QBH`vEycQ#6{uwL$i06Xb)OviEwnuVl5|2H4LAD2V*& zxBd(Q=jo*J(*Jqs@4fKf%jbucCZyB8fyi@h_w&|fxc>Ir`>R}I_w$wvX3xWVKAFt# zjL#}aAOE=~=GxfMkx3nZ3!NYyL^|wtt5#fh`(1ha_fq2jsoMROT(e5#OoZ&?aohS; zjdhYox&aF>f3L_bo+NVfF9BVM`PP@;Vz&YC^8v#By=2$P`0lUQ**!13^TPii`-om; z4t98u{a3&5fIIj8O4mbQ?E{CS)7S%`{~*6Ilf_y2s&jo|F)KfHe<1V+)*rZC z{+YN>pd}xx)iG6oXA{mKgZ-5)={ z-%h)~($3DLaF|n?`Z<76*^ntb@E}O|l%)-(ti1Kn$9>DH{`htq%v#~s?KgdR2jTyz z+Wk-d^u50Aq|9&VG#jqI*f(vEF&d0C8T$YR4Y2wG zGi?X32~5j)x3L(CupoMW_L25kUhQf4!G7D^=Fgv;6b^IB zQnvvZHD+Yea{b^pe|p?bj%NY=(ndF?_FaIWdw?nL{e9pT-**0oW$&+iL4|Kxzy1zH zTuxP%XZ=$?Z$DSz_Z`3>-=QIm7;0M}EBq6mt$1$GfuK+3Wf|5oPsZ;cei!^?|I#_X zwBbJ2&0esi!3Vx42OfSh@SpW=`%|CEFNh001}Nw_^V{IgejD%3eZQ)Y+-=S|@jd&3Ng{g&z6a5? zM#4uok#DiS@tB zUEUJ+aZEYDEzMAc<sx?alLoN`WE!S5U~#xSt#n|x zw8^alucvHdTGj3SJ)a+XLkDGX#cUSYy% zIyS)lh26!s#`nvX-}y1KEpFvHbyn8Cy8Rw%{BOQ4zMrw~-mm!f#jStNFn()g?D-=E z&u3ci(eS@!y{+GJ$t^!i);o4~yE*quZu^F4z3Ho>=<-|5FyepF=C9b`#m^rAZG3|0 z0hwl~?SY*5?tCBa_)nQB$oCdVU;jUQUmj*farOOv|9x-Vm1UMY`##LR?=!3e!?3Ti zBeKgP$N(aXvIz`=EXt;ULR4^z7>sC)5;aEA#9d5G)NCduG0B_lec$JM&R4&_oSy2s z-F>_7+@H=JPoiuFSak}Nm^HTn8 zLSC-bWTtn*b>e&9Mp=X0VV%DmFjt_;YM|F{FoS(}W;nOXb8;4#+qFOOC8F=Q2%|PE z(QTQj_inK)XZ3qEzgM*Tb6GU}3;({{-#`21-{_@3{*M+;y#HHTbLursA7oFxTg(F( zeZ}w}srcb*r#66HAH~lKXWZHG-@5%GpzZh1ZkGUHyQ0_GJVE|LEh*#$0xJ zp1i9muDWgPUorn)1K(K>a6J2UBmOaWY=upyHUI>?+XIZm%WQ zaLF<|`sF{`@*OrI_Yt0kezv%?llk`E8??A>%)IK{Ioo*l+g#E((|M1oGY|Gj`hwt@{ci;a5|MJ*>`}6PF z$^qqP0*8HI_B*RQ*dKPZfc?V# zf9=gpwq@;}!}kKhe{rFXe}7|tmIK6YYyjZX>0C8*Kxdp2>_{EsbblXchcy*;^C{{# zzMS;^%y%CjKnLJIuepzonXZ8U1VJOKAmhJI;NPm8)BKoJ_j|IVtA^_M_c!)uIY4Y? z1LO>R)zap4dNu%L7=N9~AJ~!DhriFso@y`Ei0tb0)=>x|j!Z2f<*53Krnv;6X1$875-ul>&#dd;paPVPmgy8kv) zbpP2p{+*2dWqD9-0IUgyeQAXktV4DB2bu5a?*&@5BV76LhdQ0-2VMQ0udc53ZT!JE z^vqZPwjKA&{8oJc38mMyTV|cewOWR4X2j|}`MRU=Una&M31y=Hw+OIbxGnj^1pY0` zIn9sFc8C9-QL#GqF}LGn>@Um1(J%hxqYv%&1pzls&In{3(V6B1!i9N$5B#8RXazlC zH-7@#Ozoqbj{9Yv%RYcO;RA3go53u{n9=ZWgPFWrm-w_S30qk zV4KOZ4%^M2&tK*@?)J~~Ysd;oQuea@1Ok3CEYiQ?>ep%dbB>nNcpJ?J{YDgN_Y zRvP5e4D)gx_V(ND0f-+m#ntmF_C0Fb_RVj#ee$&mufqwpIf<2n*TAyV<{jY$q51t!*08OIr zkABQo2SlAR=0%^>bV9In0r&klH(Qo{HC=dnaQ%O-=l>o!O9|y-{BIG~zS1`TS2tVu z|1HY7$?xsC!I2Hn-m$-of260q@mGTmfXrF#4`w~!W=@-R1?IN9;~JqrXn}K9n3iTS ze6i{`{a~xP@%gEI#=!$$FX<+*k6{7Q@{B)!JjPC6|!eH9{`zka&{$SpW~mr z^Np>q%M1&hH4nPX$$3fKc8);wnkG3krRr)11u#1Y_*a^1v}_H5i~Y|527Bx;%LwL_ zAZs!$;0wqb_9NS|D(nC^`&(pOU_UI@76DhC1>;ur!1?G-&PJ2l$7#$7`fDSwuYSu1 z<1&oTWInYw?b-*BC*}fz;NOz*zv8=RY@Zoy{9|rFmTM>J#EPrPDooqkhJU23%DK(= zcMeFf$Ns7;J^bare0%}ukL>mdGhPDmgE2nfJBJ?VZ1w2p?$JKzMt|dde3wm~ z=ZB02vd%~4se0|!2as6m35t9-F1=Cj|1o~H!$!@?AG*S;lWzbuocY|vYcHT&F)1f+wTJm#n@k!4>Ml?_MKUMH-Pbv82eq^&V#WIKn!~Tenq>p zujKcIDvfnZ2k!qxyKs-Tz-I7QNBCK*4}9Sxo533MtNeB41Bg8qG})Fhv*5%L+vkSj z{2#aHf2Iz}vaF-r7Js_T4ChvP9zQ;SP>uan89~3J+DNcXo#+6p5puKkUBcJ~AJh zcYYYS4!~H~$@c_h%-E%&PhdwcUHop)#t6VW<{{9}2kOH#t26Y66P*Q{-wgY6F8nQ^ z^}S|1w90ep14zgj95mU6oy`8f@mp8gK3DB~{9W6v{o{M3d!F;@)9jv`J+;}gjyXe& zdl}v0+^)Qp4a}*C>ZDdVvMcZ z;~VT~jGMh5b_B)`{`~t)8|>v(=l6kqticXPzt6mN;sZ#?oE$WnhWxYbkJt_mc}wQI z!YRJ%#~8PZ-R=RbJouDtJ#T&bwBDwnD`(o4wQH|>4|^ec^fc}T2=~~Zcl&}B9?^`oqghGV=h^OMv5d;p1s z`9YIu^!JQ^*a51{%h$yl+^zlhxA%{A0?r6$nmdW%gOux~rf)j9Q*YCxd)C{QRe$U6 zIx5My7oa1?{?CcE0PFUCLFrL1>7i({`F9zxU%=m<94yF4?ye%_9vrm?l<1rHut~c>>1l-jy<8@# zPOJf_5Ql^V*_|WA*jHot&(ODaCYt~@KIR;q zj_@Z8rOrUUGJ0EvaAL6zqPC)@VRjNZ7^_StT~{psY} ze>?_o`wj4%Sz{mV-+)Df+m=};#>3pkvCw9LqvvT^xXaAte6CYU87Uv2&*+b++AD|4@6!4lJ_z%!$V_lD3Ksf}g z6>2Zm<$7YQgR>G~^O(t0-zWc|+xs%jYs4!?;Rd~;CF`m@44 z=VOjfmPt2hjAL;Qc~;8_>ie9zUjW#E9%!#UAY-p1)9CN*aF6z)&&N2)j+U^wm07m-}w!?Ml| z^V-fdzd)gu?LaA-5kg{|8C@I{A4j+m*)E1q%lv(^^6_8-t;UHnZDTX=I?Bg zj>NXzyW!I}JD*E#-$>!(%PxA&5k0pa`%Q=8AMzpl01_$&1zms=lV0Yoy2ax0}h^MPZcz&5n}+8kk+>+;Ve^bA8Z}7a)IV0H00~J3iOTMOK?{D(~EP4EdWjU+g z+vR&2r|P(B&pH22Wy`A1YHGS*E63==tnkn8#&;{6=mGEob^&Z`tS1U&ErAn!t7WiG z4`UM8BhW>5GQsz7UK;oJ+)g#N)2kgh|IhU_`T&*%RemRIZ(H}%BF6r9vR=Bm)e+5^ z_7z87b&Y-K1-JVE-~&h%wux2UYiG5s1KRn?7nbF$es7(Boxs#>IP zZo%^~XJ>ZymRUVG58qCMUBhki7hBQK-|xb8U-khc)h7o{hJktR|6vuqk7Ze_XBhK4X6&!Zg`4YO;$M9)^Z~}(jXO?K(fS9de4qFh zvCH$EW!zUh^e&a&{~EQt`A2OG0^g+SyI1Sb-LDNkfCk|Mu#k19`P<%aJMX9Y_L;WN ztAEmbU%AXPIgNF^X1I2m7sxt*oH@b=P$zr<7U9k}+SUS(+#tpP7Ui7eceb&=6WI?X z{`vh)H%>MEMq*q^EhW|uwG0VW1GL}aIm6Z+*T+?`d->Uydu;Fl3=lqmcF3=6`=dWh z@88q%dFjL5kNpFg_g8g;+r5Bg+xJ+u0koR1qiwEZ-4D;(mi0&5_<@~o?C%dB;lTgQ zmbIq%=WnCh#n2sSL(9ombo@i+{k7|Ix$olxXb1l19&bDASF` ztOwlg1?qeDb4uyg!xGnd!&41w0gJ|pc>tSs+uidF4)45wFl0O&_&@T>g@EzD{nWD> z){nmPrH+5tyuoODcX)=64WW0S?mW8V*rbA`}fm`u_gIYq?E3zi#wG*KQ^wt? z*B5f%9q=2BHW+*WeT5IeLeA~-2P_?>V;_3Ju588_cl-T;L8s?^sd!hfVMAaZLG~;7 zOIP0isBL?i*UZ%0uFZJ_K)-~3oon9Tsa%B%|7XAa#$uj7NL`|6`yB^Vr7+ z5P<{zueXIpcADTib^;esQi~+q2 zYaaS8Y%(op^?T&U5A3h^O`T=lpXI|Y4j2AW2jJPRznAZ+*vIc9J^*w48+-tRC%Bef z$iKWFu5w1T?K9l^{jqn)3d@1yyFCv8x}ad$eA_lHeB=S$23YdM3EQ$}dcZSynvVZ) ztogUYw3~b3#J^J=V1|ACHsS*?$G_?WFq2QayiptG>#~peKfAKolj~jey}+K^{r>)R z0>%Jt=aFlKzaphU^#2y2?=5X-0zemL4D4lD*7q6L3+#t~&A%I*Ta^tr{!tH%1u(Xk z`+KBwi%T^d!K$vvkN5!0b%4PK&@b7A>|Rale)vNj|5Ns?xBYF|j=iq&e|=_AQ2T%A z2e+Kd5Vt{W}u>jB~6F7(Z{3Bkbch5g&j#{(XD^7Iv=OZz0|Cy|%r6NUQhd>)g5S z*WU)q?{B6L>YljhN*BRzA-6|O1Ml)2=-91GZOilTyXx4#GvJ@~fYUhQ12D(Gj}O2B z{?)!8*DTX!G3L?y_4n$1e80yGyTQnF`)yFvEqiJ`rSuhk0E-~o09)P``of}ITYlFa z`*%hBqs|c@fVmDZ_yGC~AAld(_38U<%BKzSklSy3IQ_2c%O?)#x?}&YivNfYz#RWRJ^&j$L(X}ui@5S8(f8YwFI>6QHP&!uPoUU# z`a8F00zf}xjw`fn>)eOi)>Q@)ak2S>!s4WTW#Cx#s=uhWB;y-|A-I39REH(01N!Pk#FdQK>B{n&pE|# zd&&j!ePC@p;Bc`Xu%GY)SOi%=YBqprxvo9-@2dDmy(2yVa~)vt0Spj6028@&CfiQ@0ST1AXU)DDin-1`T?4RA3!ae)WygCT^auoAAmXj z4L*QDwLUWIM6P8yFI?q*+>d!Vw-|0u`9RJEf(?)%Yyi2fYI>gH2gq#fWhkG}*mdXq zf&H$G|A-I39RCI%z>oP_qI03md>9 z6yKO*mFWc7UDS<6i9}?#|oB7`r3-e%1-0umM1~?H{zAiO6(I8W`Mp zf1E4N-|kS)=$8BIV5d83{eLjp5%B?-I~oea-%O*9{_Atd4In;jy1Cb0_pn${k9L|HyCjs zHbD8#z2aM8LJ!&mgWp8hQE^Q(^u2Sz-0yGoEkDSj8yRp~wkzX5)II=wQ;oly7EYVY zDetVxsXl;~=iB!9U<{BsMEJ37WW8{;d!Ikn`-F0>zf;{1$k`wmw`5PQu%$`C*ft${ z;P?MavBOsB_z&hc{_uSn$XreN>-smk%=nCNcm=~g=*sv9T|(^x0Pee@4v>8Sn||_J zecWF+zrU@VXN*j7y~kI>kN7r^Q;deP9DI*%_XVQ;TyZaMQP6)#P^RQzvZY8?s+;UW8E%>-;nz!HHJQb4Qu!N zu8#ju`v91BvJU7>-vH$Lsj=(>=(ql1ZC`t#uwm`wJ9pL~*O&puI>Wf1v5z=V8vtjU zWR6Oqw1L77un6@F`cu_yhjjc0bL`JNWK8q5Rm@`r75BJ?ZD97jPxV<{9si;B0m$@X z9e{6vhRPo!zpp)M*$0p$&P^Y;UG!}hGL8K7Aw2_{@9S)RKkI=&ZGg)C$8G79Ht>3i z9UhvoKl2;71&00gGyF|j75{E*)UJ+y&@9wG0OkwguA~EGA3(~WWLvo|x;-$PxwG~C zjDN&|%mu)n$(uXOl2*x$!JYS)WsB3Y-x*^8=mXV`XB$DqzT3H~?tuSr_yCwUT}cPX zK7ho*wU#mso7e5x9>59wZ1^UpjJeK~#y1Dt`T$VA{`6av-qe%Q28nTi5)y`le$7Ao zoPmAV@$dyO&XH$@edNn>>LlGA@ElDpQK(#z8no;Cl#JNkW=CyWIkbMWc0E|6o41-Pu6xI5rKoIU`V zwmkpRS#^Ny1Bh-~W-8CHbpydZzQfyIY=-0auulS+4+KqeZyu!3EPQMJfoEV{mN%r) z|I4`Nw3{)%{LJovf3zo@J^-11om~eQd;pEY2O!zA8N)r)@YH**@eiM0Fu&&&YCRC> znxKX=7sVc7k5032jQv@*fO7=CM$CRe#yrQc3*>Tc(%l9B;r0Q@G-e&J_1JF$=7apa zV5WV1022PI4!S?j7yV*q_W4=q61U$BWSa;yN^2B;01?75_GjKR*7;iY2{P^xo7o8b z8z*sh!GA~i0A%{I4rq@qmY)}_w2u$qk}Mak3C!Q$QTuzXaP2f7X9dGeqzl}_`dPS{XJqUpPxD>D9fVLba%l&+8YWV0LEZW`gHJuZ8qp< zxAU-0`4vbx*$0p|G)tS`a?}5D*-)S7A8LJpb%E6ny%mrSD7&w1&2K2y{HuKBwSC;D zaG%eyJU5{J*3ETy!ha}y0GLxXv$GiQR{mJia(*Fxa~KtB%pLkBd1Qy}Xxobt_0IoSu0zVyL>c$m6T-JW&G5Y8!AIzckAG#rGQRzb?|++> z$M-?;JgYWvekgnZ@UN)2_IC}w0sFxipK;sT6U#n;*wGtY%Rc7%JK{{gQ0W)61#NPw z1Nxo&nqo$*(eWS5{r+}*H5>N_dt4bR{G(lF{kc^izG!o+DfXc&>}aIk3xyBBN)NLh zV7!Aj?e)j1?FrVk>;tHN^b^Oj-*D!0x-Pj-x9R&?r=U$}n-d*Sar~z`_QNsuXP(Rc zB**#}VAdd`vD0~MKB>pkxuW4-Z!9VhFPp+rabSQiPPT$>`%enOdbhk0Tm0s{S zC)iPA|8U7tN8;bgKj_5QXGfn<_yFwQ*H!L0^#OF(F~5}#uv;70QDgsb$y7(-fBUIt zefoWj1KYas`T)AZzFsRV2b!NWc7f?QprgkA;gXk*z(4wTvoU|m zy$9Qkeb6lwK7erXBb4uP;sXfRce?|{X()eJxb-m~9njHZ|4_;Uo*i!do8caLnBxyt zTO&RI^X~%r^8sLOY5PaEz+4Ad`2aBH z?+)vG-C|xXk97exk9yBUkjMU6lQz@AH{74EWhI}TB|qH#Kd=9hbwGRleP*;HJ&59R^d^B%L`-g4x5UC!b6GAq;F^MH5wLZAy}dx&|Cy#T;I_QV7mLtXuOINvCJ z$q`+Km}Y9+)%Ahgo?zp_AO7(^o(BlF4%qkVMV)uBd4t`y&iFikc$ayNbo`{P-Fkgr zdv#D$Wh2#`x=6))UZJd&CpCJhG*qv1I7p9V9T>p{Nug676|r0uv{kP9cUjitG}g9W&TIREsT-V* z1!Vf0r5m1pk8*ArNGZ+5l+ZkkVu#KRyFLg7{@vg+)MY!;2M`F}` zKlqd*o8C;esIU0;loQ$US0-!W=Ag@dF#FQ3{4C532Kr4Am2cHYpQ5a>ag;es=m9CD4-2h6 z=!Lbe$>p{)d*U7X+I<|SCu=7Sya&sA_4-&k;1^k(>vepTD5dR4!OPf~^l^84a~9-cipFmJdM2yS%nYrlFiR z;Jw*n%h&9QsZ{gOb3y6zAybjHJ)y>RPrS zU-=W`Y5eY0bj#DP(U`r@QsII@EPj&TKND1!TZo{r)l03KcX2&_E7mvxdHJd zYqa?O#Fljde}mIZmVkZOp_dchI%8XLhDiRM$AhNR!Rvm{eNLr!t)i^q*9H`F$MmMj z`&QHT4?m@Szy233Klh=jJ_t1qJM#Im4*=hAa58>J{|>w_c=`hExcFzf_m{t?IS=om zlBwwd@d5mUO$Xb~48wuu;jCWRpPdm8musEie+kyy0Lw-F;}y z@t`KlNB&F(d!Qrn8R~b-J^&u?sB!VltrXq7N~a0vbKv*?rdyvmNki6*X&2r52pbNz z9P=_*ab$ike11N+x(w$j1^T^VJNc;Gf0+7AN~Nq3!X9Wx7`9=uF6+QTs4>`)&zF4w zjC)_%T+c--~{lsmR}yJ(y}rWciNTqSJ%uY!tw*!z)lJ324+ zSyy1qWlqc9pzsd@DJRVZCS7R zY-BzKD;?Rl-}$j_rH|pGar50_w=#oqfm=Nw%lqYsceTwjJ>1|Q-<=o_!(3 zJ;sZXb-W#m(@^S3_y(~@BiQqVvJODH@3Wt3eUzC^5W&0=^D;eD{O3%|(R}&!Ph1G8 z{RW<4&u*m8@4ncV^$Pp~u<=yfhTZ`&_|KjYPsOWeQO(1_ z+nZy@SA2geGS0s|a4+isq%lVj%zZ?5a)x^~$DXF*+hRR8 z;6ov`?`8hL){pGhy*zO*>jBt&q4p2Ta)&g0S5?Ai2wjjnJ%_S|9=O~>AF)@WNMOEV z*G_G`q|zvq*H|wena_`4U)BTI%Mr@CLOXeG5Mu=Rwu)P(P|oDkZmA3U2%D#H$#AOJ zv4v{C{Zd%QUMkJu|BbBSi{M_yy_!xMyFmXQsVYC=x~_ZdRjpq{|JY|-FUlS*?1L^C z3Kld_`Q7WO_C$Eb@>cx87!PMiM$Y4mU|+?%)ivgU_`Aebauu$8^q24*081D%6f7Ft zsq_Ns16_ssVGIwvhjM=2DcvKukKo-3-%j)6hfE3j83Rt`*Izkc3|OnW@34lw!llDC z-Jt1*8{>m!GvIj~fN_jf@LtSw`m19{+=t$V9T(~EBlvfUbARP9SAe;qj*#bIy%U)A z7dk_~9cX)j`^fs82ju8970+rFo@BSQg+CeWza38^advNXcx6lLl#!Cdx z!N;>xnnDjp&fbjR-Ys^6Ssv>LFxKp-xkIN|=`Q6khlh1Lk@L4AxDO_dgYhiLB=(DU zmU)Bjf_eDyai&Y;yv+#agMrgio#_V!2f}<4{Z8~&pv|p z&WO9tTqk_f0Ba2}uaLcTr?&Q}v-uR^*T7sn&d@IRHq`~b`W zd%z%vVCe|PHa{1AIo=2R9eOD;W{=>!J7DQ@Xan%-FGTPh!Sm&Sg-9DCavqU^hzvwz zAR+@18HmV0LL!0FV*vfse>V$IAuwNP{2XO}NfHk>3+J-z@wx0E|O#;|y7u7o8yu z{eZJ@BKvHED;GE?1?Qs#>)eA-%L-%@G74FZ*qwpP0{Ypm{#`!EY~=gY?qmQuG??F6 zs5$W_mF#$g`Yc>y2x$|hQ$qj#lrn0fAs^)mHyogfgD(cHkAWOuToJJwt!1ITd~bO6 zbDhuNtEZxbZixQRc8BP^bWKjO=B&`RJwPRyge2%S{g8i*w_jsS`RkciCMOU64*aVg=7#grXt!R6lh* zP29A}QRsj3G%6d}=;|F@pWbP`DP!s!g3aMnt}$M~InkHHxDl9llkcI=?r&%Hve?|)85{!Hx(yMFeS_N6;`mp|~i(b6j@H}@wxki6r zQ^hxUJ$C(CDjU^EX=Ryyd1EJAxCj2?StC}hpj)4KhW38(7sERtBMXi_L{$@p`+XPW zz-hk#yP!La5zq#w`aXZvcIurWY`Qpsc_l=pTt`EfEuyXOd}5$~>j$4}m@XSF`fKGk z>UCUA2_+8dPpM-kQqH0^S^zF{m*1tO({7xu-B0LSZTqa;f#sS!tb6&#K6RPWx`UDm zL?2;Om+W~f9E};EE4y-kfWF>||E}`zixgi|NVLcd8@Vg`kuj!m;={|HzrvJ8;5&FM_rbTnaGvU?PcSXdd`}Yi&R-?w3Qm3E z)8AAd_<|5BHhoGZOW)T*?vU51c;UNRx_td7+I^Ji_xzs>zem4Rbk{*j89B=G{pCUj z!OmbgK#Xh12-i=I@jQS21K0#zNd};^{Eh8E&xC#gR|x|1N*KFgtpV@Lo_vOing!OC za`JW3pb=Dg=*I@0H9Ylu0#EZszd>oq-*X*u2EIyVw|`9aCx2^rZrx+=3EO^*Wqr~s zvuMHbhYfNtb!RI@r(JLQo0#GZf)12*k69Z2(avrcLQWyCX7%U1vOP~yl(4I0{vlmH zrcw0o7j?R|JbRAv237c!lYbXqTS^u8w(%W22hYH}KzMHTo2=@WH9gUAs;zAm2VbJ3 z0fQ{-ms})t*rCIEdtk3>`pZI&^KRQ{OE=K3Gs^&Q?~nI|>+YqVi30Odh)%!WmrgT; zo|np~>FE3fD%yBZrx)}!bb3b43zmE@E_jiq-1w#zTDM=MJ@@{co_PG%^z516YH3{a z{i^aGSU#t4<~syAV|gyweu`pC3cYe*Qs<&!4YdB1Hd_&L9iJO*+P?J3(?#FYCS&{# zIqr-yfd1Z}&d*(P2lW#4kwZpR7H#~IckGV79(poH$b(!)O(*uRG4z?x@tK9+H{}=j zxbBV*>6KT$CbxedefT$moHP#nq0h4+XOK6x6Z$>>6{U`tPCcWqpDh_q6K$BJ8__ylBJywz5}f zeDBet2j$MitZC- z(H<`y)b__@2%RU<2kE$~TrrNZo@<7_?P&i1*1V~*DPN~exY4IwY#T%0k6hE@bD!zZ zGyY2I(d!1m{}?LU^&R~^ptX!aq|tA`@y4J0vK_L4az`KhT*EVX30;A{9|8A%^3FGY zpY!Wq{Zo@QxgHox_I>sbT0Lt{zD2R68J2BB8*3(yAogLR4>ZF7WWa8G2))};enR-E zWnQc4teJDEck;LN5Sw{DwS4!ShI{b7RT2zYuF8tix+f zCzOl$8lU!N)@13vqq{{Ph-;Y+NGCRw+S&uaV7SMHShHbg>*p@L!_bbz{Ak_IL!VzT zq{47tZ?nKfD)zJvGKH?Prn4?C+*!+D*~;1lQ$``zjf_uTNDd9TLk^PwC5{qO&0 z`YOnmY!|>bWS>FlJ)$p2sG<0%Q{;)+N>Rx@eA=B_nxxYPenc}FNF8Qx6JkC+TrvQC zV`uLbZ#rmbBXG~-AFK9x`7iqV-fg^388T7VFRBj*__Wf~u=R&Gzh;mXm8XGRCuAVrhYp|>%K-X<#DZv_G6lD9*PqEW z=NNW)sMnBSO*X$zjbW#F$}^~Us^I;lu<&889~3%26TFx1$!U!3pzjf2@6|o_zV@D~ zdwyZyCv?7OO|0AUoJ=-P&F_3{2A9^GfihlA9 zuRjEFZ1(krGErIA5iq9Gp06>_9;$u-vSqh^BW>(xib}mg57Tye$9VhD-#1n2`EnVg zd&Rc#UhebJhpJ;dGyMxb$TWA#!(f!dI70n{e9AT<`v=N*h&7+W4$wpNF^W#k@}Wyw zc`~(r=$%ho{?s!*_v6YlMc-n+<`n%vsJ_LGHEJwpYFxNx2Sud`-d_rp69?<#``T$E z^?bh1aWBucI_|;ysMJhd??ZpeJc1uj{X<_bm+6SKnG8Tqxi0V#v7a!l{JA#%3t5PR z9!R^^hdx<#+4|UU)Y=xG`@ovY1HQ)Ekznfp*cMjye(ks4qG+L~n5StK$$H%tc3+(so?H%K>?q?s5s`sJWRr?!#a7W>udCRexe;K|gzK=O6@TdCVFAed2uKl`gP$b9w4GU&d8O z@!IOWsz2%vfB3g<3&NIV9gxxQ1z#EPY&4}=Rzo(yhQ@lLzOyG9%0%Z}Pw0QS@0a6X z=m4zQmY*r7a~8KywBRv^?9ZBUL4`gc&x-zT^6}se z>pu$0v-rL65vg{HtOGD-3>p@HdR>d&55(o(U?`J5-r5#yuMV)9 z->HB4BE{rhPtloz|047gatZl_Uq8JnSl}U1pe1Q_8VXR#~h>B&d&~r%heaI2d>8rXQcAoqfO#fb}_zxYR z{>i>6UPC621wEdvV%>{5HkeLjWBTeC%WW*w>4*EF&;eF{UiAC1MbQ+UC9p5T==EOR z1o`AVvp6n(l|kk)_Ki($ri>|5G&#e%TN%^fwfqNJknguQjb{g2|8t#GAEn#}V7(Hs zRIo^_1B*H-bpCi-y2-R$c*5&XU2^KQ&u^@B0Oo4kjs-EtV>R9{T)Tr}vairWd_f!b z`_G-I=ktAzV>7Z0yytNb;*!lzX!KD1{Hh*BU%>PYB%U|t9Xj>cujrS*{D&-7+Vzn` zzob#aedm?~c@KUAe#?K52Ywdju)+W8<8M%GdY&cCn09iUQIo9e0Hh7~CR*D8n6Gss z1DH>g^*yJ7{rHMR{k=n%&(-P!?8|jg({b^)nerdwp6Z9ZeWJRSOC3+k{uHLAlXzhN zAL={@|G5tVe}I472mkSRPOL48#?=VzMPKDiqZ6(jCoFbQbrPNNywMF zc2}jJ>{EBj2k=(@ll49Ft{-%*yJz)FA7v7-f%k@FplQi2D`&!>u&`Wz4 z@F4S4wV^PMmhU@F?`-{4X1|7S{;kS?=zso`<$}w*ja3_f^$wl`TL-jFX|6TUEjr^W z>YZ?nwgv|4U{qT2HS2&0Th|%N#8-O#C@SA@?bIi1wO3ag^W_NaUkXc3pVs(4=FS#9 zkMHSmpPts(7jgmlN8Nx2nZBwoO&&wZ<@}|=NBIx>oqvOTna?u+p#!*Fps_l3#d$%FXlkST1TD-;W#GiDpT6l&+=mL?w^WrxWp5r%lCW7(y9!=o_Asc zSo!-3Z{I|*qOJ%j6|ve_ALIRux)eR1?{nOs3Njk(Lm_cfHsnl?$Jsmg!Y^Zxn(*!}A7_&Q}sImPA*{);f;4zHho`7>wqJiaH# zp5)1<{Eth#P5T|!6?kCUAXevk+iUyF&*n6kgFgSZW$zL2F8>7s|LPb(o)hMEAsVIx zJ);thYakf^y<)Dnr0>m#ymLeIjvg_T@f6))IWGi%uAL6Bn(L{1{5``vHoW?#ruzrX zpJ>RJd5?5_+(uLWd(xV<-}RX{Pm?!w&Ih_u{=*(E=3AgK^t+02`5kgv)(e5Y4||8? zKa6MjS=d7cT$S8?NTWk^2G%=!*FPC!*i~N4skAK~U8V70-LEhTpzOBymWcOW%J+@0v+nz|v$fx4PWFyj)%kwa_al#=nTBp+ zw(VtpSfzty|EvBB$OG4z=K=Ct)?T8Y*x%I4jQ>5vzG2Y^SkQRWn_i#rfCU1FQkk4Z zOHBEQah)Cht@{4#n`h|HZ*K99`8C}yy;FWa(wOTSAUUaQp;d%2i4h%r`@ z|FEu3zV9ZjjsfK7s%exB#`quggU*uw~>&b$xk9WVL-3p!7}XN!hK z^aXMm^wlzcIc;YH;Jgklr^bnWGbuJ-;9rDW9yy`CbIe^U^*p{O$DY*jrn)~aakc(C zJQwd$?SJ@6b<_-HD4oWWdmSOsmga;*NeX2Qy}nsDeU~{3+j}ZQHI~~JDF}At8+i_3Gh9qF?cHff!|dX-sd2n`+3<%D31}HzQ?Sb zT7P*CsP@>eHCm?*E!SxQ{F?C}c`{w)bYf`_I`Dh%Ic2Fev4(Qxd(3SBoI`BZ2UzXr zD!b>H{@k3wZGFF753_V!b_vC$&Y-yXyA5&>my@kO55I$aK?c;hKXu&)#sp?`_LnE~ zpLvhp$oyCBLd+HTd#>I6abw<)UrUe$*?-CFKoV+`479Ma0U#S@G)CSXKk)7w8L)7o zp-kQ~b6=p9FWAcVE4*V9c?!k*MHswnhKBvy&YaQn_?~TCa2g zSNHa*_H&>%AdmmS5SeE(|K&1rzFgi-S{?h#<5&2(A@BXpiS<*L=*n@=XmdY6Y|d3a zW%)N#c6n`p8T)q{%4AM8pAWLK0kLkFb+H_0&zwYYqMisd#XB(1KXLmyJ&*4N8W#!q z!u#M8k!h^Xp}+>KuwZk8VbHt2}u;34agU1>if zRNT# zcP-ETCe|nEH1L#0Yw4&Y<9-;{0nzE!{0H6H22^>#wiWY|WA)q!t2saLC9YUt|5D)h zBvtg#^Z1_g_*#k{dK*O#Sw=AfCQxi$4V7#?q{%4!A~LPf2LM0vU!XcbelF7ZWBXsd z7w9$CD5!t(x&`cG1`n!^{eWV{d8D!ZMpDe+g@PWdD6Tw-qEgKHk9<4&ZhFh>2Pzm@ zWGGj@*L)11jsdOsU-#%+6fby>kT=w8`$Nxgo>lD0y_%v$oe|)_= zT}`olL=d*06`eVM>66}mdC;PXhO(vGy|`lBbF7{rX0^_{>d0A&FA@9~p>%@R-@Nwa z^LifNQ)5pbb6*C0T%Lx0TH8n8b&}RU^<$cN_hXblYX|jx&byaI9S4}Lsg~zbRK7aB z4mST`H8rA?)Wd{ujDGKozAJb4!U$9&ensakutKmQ)R^vD0vL(7|g)aq)c z1Jtn~=q%gROyiDUH;7bz2ov5Th|+YZ^eIg9uWF~>nF!$g8vDE_XxvppQrJEvCuV~XBV^WD#tyO zbG3F>%)i%%2B5>;AOBse2gZWx-hVTU!4{DHs?3vc#gI$YPidx`c+9ur-TyLeH~K)> z0iOCAN3>PxKJ{L&4+yb*FZY)DrhHX>fL7~$HU5_g{);f`&ZTYqzm$i3tDx@fh8*-R z7^Jmx=ALIv=>Q!t=2fo_FgxeX%)W*Ubc7y&+^O~+cn{y7EPuS-yYUC#&@*58Vjpr3 zI|%%bsar=0iR&mna{?vg=UdWNrTNr7m-sJY`CiWanWp^5_eo_RkS+c%@p$+e3I8^H z=l5gnii~}vqiUyX?Ns}I(164JpZ!y-bKhsbHa*`{^$CFH=nKMW4?y13`5n|l?epcc zz*fKicfF0=R*rQWVDKG=xsv$klbSpvlwNP(E7O=`EB@!*YQ7EtzJ8hiR_lH$_B~1o z1OI#WrsyW~zMtv9@tg~P)B6E+T{y6%uB`;^@rQ9iFvf;5 ze&sauJ#10c*2BBe56FH#{Ep{&q0`R({=Y5xk9O-eK+Gso$9EeYwrL4Uo6b!2g8QC4T8W=fVA2 z-#l*XN<-P=_1?J^*``BU-4|@N*Rx9SKe6H}E!5AsH2!<#yq?GR%;Gp@4Ct@#muZ3Y zlfV6M0_{*=?3pv;8SDWwEP_Yi6?}z(tQ+8Wfv4zK%=&qj19@E+|BmN)Q1`>X_@^!I zx!t-AP-C1gPskbUm)?toPR6|4h&$#P%9gb{^Z!`+|LUK3Pk&zV*kbJ+YaQ}Gv0RJ+ zd$!GII_dkF791b_;$H;233OC_!%S<83)Jx!^M+&SX2^n*u>$19$=R>aGqP`&>w|Nv zcz+khGu#$`v6T&wD9*+(!2~>doQ6-@%+BC5UQk!7v7XvK z`P#<@h&|?r)~jE5LE}yTg`*7Rp}$cVHK_i7*n(EyZ%7%GOo^4E4-jGBue|4wWDfA? zd3?_-j?MPYXSnJ6WqNQLGQfHOYemg$Lf{WP!T8InPhkE98pFOf(;<*a-q#IU+u8cu zCbL+z0TNPHJEHT>kG*U1a+*>N<@=sBUjqnzFWdh}Tdw_`)~rAC&L6$0$yxP`etMo6 z-#IU#)awUy+xM%qc}nQfhrj%nZV$jeq|Ozy{zVKO4t;OeZ#$I%tU&vMC%x_+7r;M&eKcnM zfy^Js0)GR>iH_&K0sV;;&-wZJ6W-F#bQ*E~FPe-x<+WKkgAE|Y{)y#6&-$Tr`IKsn zCz~(4YbcvJq0W^5Sm$HLf2;F7OE$GqlBfg1q+RQ^cg;GuQ_tgjRBp zy1ioDC-}~xru=n!PUrxP4Tpc%yM7w-jJ1^Nxk1bys~G(R)&$AHOs`x09zH!@!;3o9 z9Q-xi{lr%R<6dqz+W_%>Ryd+@^QxH|Pi}qsw4r?7LUZ4r)%OCde1MgQo}#2`!G943 zFS}8D*V^;v^*p|36(`hZYCbzqMU&stWpu@s&)O{mYy-sC4|7E0Imf(Xe_&JQLCKxwV}I56$GQM# zgrH4ofDMsUBls^uR-<q}wS@0i0ejn%A#hym<`F`fN8l#_AX)0esK6uRp zV*DQSMw>qRyFm^h59k|Umt#IzJzvI32jJTc(C?5T{*DLB7VJCN_L#?kZ6eo;(~rLW z*LLw=w*i`#=`^>ZZ?=TTbb&`Mm(tKfTVKxgmSc78ALAdf)wwSPE0$1lt>C{1bB}xV z&Gh|S^gO=j8($}MzcZh|EC)?Z7ffjj8l#-bfBCoY8G%PUk0`gD)3Dd!SC#|cQ)B3s zWk3Bd!n~CH9;DeeW!|ISYMDT;*#<~zNVcW%;M=_Y@jB5T%e2p)Hb~cpa(ghwm-(%x zthv^CqDia$#YS0 zCAE}TKU5FfUU^?ziw9W+?fG|3W0nEPt<&Gwm17&g(>TGBzUlpY((Ye)&)uxOxu2n2 z^-=S_U!C`1zH6Z?%($QMFS7gnvzX*KlGcK z-;a6EvDKNsWjppza=p+2A`DpST?@GR?RWJ&zSkB9*7rN1w_E;iKlQ9F{}*j;)p(vV z?oLexKz}Fo2xS@F2IwnnfJ=0j^j{xYSYx&_AFI)?}j(fc|w-k5HCj8z5mo zt%0tfai69*ea}zvxE#a%x>M$7Kw6Fa8TTC9jRW%*PNtLw!DkWXKI9z-Am%(djvv%t zqovbvzZ+Tx!vB*OJ~8D#bOXN|>+u7%0r(lgigg=c@B|4 z>_hk4jr*AQ9AkYT+rx5Pb@(a$eU&r4erMQ$`6JWxe3k*v;At8y?biAQN~=Klk9R=^ zY8sn#IoNylWu5o9-(DLa(Ds=9PPPGeIhhpe2W@gBB6^8s<{z@F6bjCUWcj9H}B{T?d6&91ReTzw9%EAM|)e{bbYULAnC zWDM%1=O+#bUEdF$wTJ&^JeTu2r42Ap*Z`L>$Jn3Px=PQ(y~35&-{Z#m9y1=>f&r4_wUEd#S{&z|nV8{fGwoMZDGaGy9^iCUOjeUPUA1fJv z%vj9_RO~(^#sY%>A~daP(?#*)safZH_gIfCJ36Y1sU+nJ}<0y5HpR8xwlMbc+N4+|u z4bXh&D!t#&94xSZiT`Ph*4Qt*|NE}>zAOW_I$+;%N*y3{fCy#NO7!t)`J8bY@16Mk zdEUgWEQFf>ozVuEcI-us|4pkW>2wF}i`JU^d(cm->wIP2I!#;Y06af;)*wm~bwHSL zaI03o(Yqhj`0sSw&vSaR44CD~_e0J9Kx_bib(ZVzCe40;e(N8m+h2M?r#EPxIWom^ zo)_ymo$}bOoYmTJ@W1wvS1El+Pf8njHDxvRqI)iWK~=XM()jOm+;2rU9zm zVgp#!Rjs?*YxV;qjoU!w(@Qj3gWd>L2hGoS2^RKQF6?wb(d|q1I`v!JOmQRcaMkyl z@tpfGwCg zE}PN@T}{c2?#KO1Gqc!=F5%#Rpf&)v!>aCqIpIC%77qRgVgtxLmD?rf2a;wRAX=;m%)4c* zCGRoE3tb&3fBpRqz62|uP``6uQ_QfHuKIq^g6ZUx_xO!d{;TUeWZK)^<8p!60Q_6T z+%`Ec&@|fsRS&&w$^T%C_x#BK<`RH+HB=n`sm6OJ<9?L}Zg`L1I^{pgGN0vln&rv& zIqk*>L@!#pVUv59s zOU|=P2g-jpyvO_9*Z^+ZVAnpgdu#*5j^1FPd#LPvmFMcUYzt_8|A;lN`+l=_I>`%! z|89BD^=PjRz|RRr%r-#vquy_b1Akbrr}8FT*SuD+J$-*5bP0t2cn@U2?fcx=0B)b{ zw!CTsgtO1Lk|~Tgx$noBzHZwTNclkdk9WD10XH^4AZ>B;n_I;k5av~31K@id;q3FR z_>cUA3Ep+ns9U`7{|;XL0HLl2-)R4SSTp*xhyQM6z>N)HR@e6Aop}GZwC2=n1YBiJ z+N|*&G>#p)mSBU~@g$u0u1zVW)H(N1;?(VW9Z}Cv$wPbj?^XuFWdm68n`s$0ej}wV zyq|8!A4FGNeM6_=KV%K^h&jjlGrywJ`(C5$+aC>?JUHb)+k6}|7WtZE&bNv~WdlIB zpnt*hWqiy0&RBk&igvw3HIM&X+neQN4^KF;FTaarKpq!{LLQv*--@4Z^Mhpr$oyuV z!n{Tde9Qcn>4^Ea_N?WS`4q}DWWefMVrUP`L;Adp6x%#6p#CD<{14Oy@W=1i=7p3p zbvYI7{=SB9ncs36zLw66dsUubms;&1k=s@G=&NEsK@p`i7gIv>Fp3>I*GC?Ji~h?G zYChk6uU^!~7vbhV^abM;ei$qL;e_7_&7&x}xr{PKXHwOH;|5=jOdC$4PYq=Kw#t)^ zxVBqE&h5kcfs(scQP${QlsWtwN*^9gDZ`4X&(t}THEolrJmgKkTg!(WSn(p*`DQkN zKYk~TX%TWQ_&uzQ(uaAp_MweMt8SvcXUz9kFkKL1zO^&i`GLp~d_-1rhH_i$AHP5a zi-uFy@M{gBWnfv-eplT(HL=58>oL+W>V-_G|VU>jSy}&YrQ28gAc5<>K7^ zjA3zxcA#B(v#O}}!U-JOXI(Cri7S$T+%=PaxDU~Yj+3ASy zIDY|aZDjg&hcxt<*}S33f4;6d@DSzQTxCknf|)mko&V@hFt-gKEau{12e2KIG;Dxr zJt4>7d%tsEIpRIm>xW|PR%enQoI&EGKVUh4KFFIbdA3Z@!0`+oi^^mAZ?*_a|?Val0|1N*i3)e)}aVUOkJlC&X*?mi2H) zr@{a1F}<|<)f{`;5!Shlu7&N|UigX%H}0Xd>2owW0PUTG zv@t`e;HH~wL&mrfj-DmIFKx;Utv;xiT35Sk^z;7CW9p7PSK9=g=VY8{Ma$ZUpQG}v z>&4h%FlCRrHsm3HP8F4IxK*=L`#ooVzPeRiIUi?jchxby%D-S;gC5vt;>I>$ddhL_ ziRY;5zQa_0_j)Q^I-K(7R#En7Ar~$~?yMqBrb;)7^9y(FBs@1zesld`|8@l*Zm@V7 z$a7c@tj?ihS_Tq>hyFr)d2CiM_(Hq8T^|Uq?S6ytBGwwK>kQ54+Zpp9zwqI7CBMBL zKRWUr>|@X}6gnZ;vV*?8JNj=rlK=c}*ovSnXzX^}5Ntm4^I)%FEQ@p1ySlHQ>D*Of z*isln!LDkr-N^iO5@TKlXJucmIw8U_&sblJP*DKv+t&L zR$4^rb&Zct4K_G<6l62<@Gub(%P|L;iq5B~G+K6ipSFRYV=p8-Ax1T$YZd|Z4VbLQ}UbyeD6 ztd02{tbcLhbF(XhwWXLl?(F^<_^-h;H*;F`PhO4xb4G=v`U*Xs8(XD*_`4F{;PYz5HYCJYAftEeGV|KFSSUx`>kU5-Cy8 zEWc$t)tq?K=RKf#IL?Jq`v}k-K3KDMXU|OS<=MOs_-e(@JtaP%RnpE{n( zMmAE>kb3G7`=34m`M8gAvkx4mT|fIuqsNGqD=4ijlTyb_q&gG4KyQW%6VT@>&-*?9 zJIY_VoqDJDrnsyqnz?5$wSMrq)&{hthexzEz)&`-QGecoV-Hb!bslBTTI7Qb$U>-n zoRD|b=U%+^D8&?IP;~0`Gi3}4^r8dx2gVA+qb=0 zhU!jTr1IV8C}Z+Miq6lbo}Mc%{g$8cEgF2w9NPNMMVh&HFC~_wQ{M881{p*j8mjqO z%mJ$NP+2!G7Wn=am5*uE+C6n=E5+wTYk9~=@bno)Wg9-yzE@na@l(p5@D|}a#OgPS zk%w=bm#=$I(C3#_vHv{9mDNzs*sBfCi%z?qKwrog=#f0M$wwB@N2r)>&oy)m^9eEZ zTXJ)g!1=dm=xvLs<=JzTT%4p`Bd=$|m0CLQw(X)VpHsn<3x@Vix$#ZfbMMc!@WvZ| zq67E;LQBt|`;J}?-)XKn`Y9E!|2FlC6*P_WK2v+Xct?D0G%Yy(FwNYzmpqlZRCCgJ zW@@l#02@r^JKhr~-q%aiVa}n$T8K%%Uc2scX6wKi3i z|A3x&{MYo?zy2@T{r&sj|Bs$M^IIC;{F?T=f+;^1XF{V@MbnxW&QtS>#ndZF)CocGyhpDaC^{=&tdIYZ z_%64%{*ZI<8tvl0&wl=QI{M(}TK=pV7pQgnMJ@f&hkxTDS`0cA7raP)8qQPI;ddyu zG=q94^`NMPnzr|fcQ?$Opw$QUD%^-lg4wS4y+)lMFv zrE%RmQMA2h55fBw!K=5l`l8*aJLH@HzJ2mbY8?1OUB*=%fNRJJXv6gS^{@V^$pZ94 z_2HjTLiT=&k2*!s@q^mlFX~V*q=MGJ@?(lGN+9rw>ka+|(l@H>cGJd;qTVUrqMP>b zrBQdZXlYz?+i~7P+4i$K-_dr|9e;oL!@p_Vm^WToIay=ek1d+HgAtI0L!MDWp#{!=lZb4v?FrCve9T9(kTP`Gm9Mq7L)O7lwS7*mbF$76KL@k~O$%qfO{Htz*V?biK~im7eMFtc zZ(K*ycC}LKh@rX+Ko;ECiSk~q^1V+|RN56(IdL$p6mswBbAxt`JcM4JYc#p9f9&U! zS@?aeotrm)thF6{Yp8oAptdu8Km(Qo;0O6N$G)Jn^5--f#6=$#wnmJhPKzHqO@kIp zr@}QmbQ(B4M-es-V+V0!|1$FA+(7Hk|CkDzD=8{nv|9=J%XezJ9(6-~A@BH;`!jBj z9HWeUZIwn}!1@5`ywPt^#f}ek8Hn?&HPk7sBAM>~$wf+S$Rp@2ZjX~a3G$e|@Qxi6 zopA+?Ue`ji?%$`SaUGMEO0g-$`gOxopZoA0JhN&K=R0jb%0nmO4}B=E8=m?#C1pOX z(ZJ)`D(ccxua8{kKJypr?T77Zrwe5}2Xu=oOQg8G8>sce&ndksnW8hV(1Is^zE}1< z8!4r6tk^H`iQZP$_e&SQtLJfhIo2AY{KxmKV&DjWz!b`qZ+efiC-0)z#PNE)xPFMa z-Wm0oRR46_esnv#NZz-Vf7=}tlYIq^*&uj-V4s%8b!=vgX!}WB_6k?tN5u=hb{q5) z{vfNsfmvI$0^&d1!ym_-Hv0|dL6_nW_9HM*zWW)yUZ|TIxb9gqXBcF_tS`WrR<`rv zD-$Wc(98Rb+GL99Bc3mUCuz3c_V~Ds!cKo)v)fTe^l|w6$vfYewq0#2%Bp$XR~OPj7#0dM%+2=$BDn$UOdFx0%&n&C?1?|Ec%YYuJhS!*~IGO~ccl3!V$x zOZ30qAnZ@b!KJz)o_F*x4PUc_iZ|Y?%K&__YWw9gP4ZW)rP$mn#cz+$h&z^OXM^^+^NsDK_s)+Wm9!?azi3EsbkWW^G&hZ zIQM%?{wvM4EN4asj3e-e827dIi#qg9x>j$0uej^<`l5abB|Wruq}C@J`a*f_KE?># zN7g<59>wNgN!8Pb&>cTGucdK~;7J>$w?8grhL%_L;EyP0;Hz4F&^P1HuJ6+di2qQ3 z{Bg`_vvzYHaD~5>E8f>=4%(w$F@3Jm+ut+#dPALY|CUEiP;<*%F*a)ZrjUHLEXIl4 z{?cuS$Ww47P1&_Y3rMRWF1v){aWAu^9WeAY6sImj;+daKKeZTp$|k};mmiaWYYn?Ub+tKd4rzE zbsl)jM7r(F8OokHNpC;&9k(Ag0rNk1$r6eyx{{VYahirKpP{93&B2p=BHz{M>K)s#vm{1g^|M&> zrf;OU@+3ojx!!q0vuWo?Ur_SEOuhZ^3o!p>e|GwqI*Kp3igted1?3Ixqor|;&|A=! zF9 zYSasVG{}HF2KF}&w4w><$YV*iDPU_fpZ%K7{{Fx9ccTtCn?JQ#oJp0Juh*CBjaX~H zi2HuGZB7ky8K8me<4b82?Jv8Ew!M3iipGeu+eDf}OzL$y|5Jv}(ca1JKl;VLXyA$8 z7TfgmRwC%&c8`_RK;Cr-j!`4wk;zqr`T-Z+R7%CDleubij4*-cs+*9fsW*XZq!8@Af#8@PA<^lwzZ`BMW8 zSPno3@DkUMX}PVOhMx#B&VDoe20jmNd-?o#>6TZ&@o78rAa81`828OI)EV{8AKpj9 zb5cXB-geBPvixJu71Jbl!Awf5xQZ5^Iw5S|d0HCRS}4C-_&IM7^D-HfH+7R~J?4q} zl`neF&_2j9kBiYJ{GlI19tYN$-n*pHK*mj>81GFH7(4g1QSQ0zh^MwbEqs4tjCB@u zub&ud`s~N=mG}if%f%lP2A>UQ6SeL+?1@>(6O0U|+7onJ@mS z@ko^e@EE!fm|#qETRDcj!+wB$$1;H!^ql)m1cU*LsZxNXsFv;2KIDKHGqOZvTPjzNVV;*Jg?H_sUTXEl`lvI5cl}sq6ZSP&w(zupGoOp-&{p(}r|Ez!06yFO$eI6Ed zt~~mo)&?FUaNF$Stm>Dk_O4H<`P?6A?ekx2&jnqd`q)?R$?ZovU-Zd|b;*YMu72?a z8n9>-mE5^WZ@)YS##o5?5B-?Z(1Vg|L?0m9Uplc^OXC_LNsOcL4)wj@Ie#Yw@uP2h z`)8cr1N&g?3xA?P&;5~VxBg6<4}@IE0ds`qcYH*R&;EgipZgPS{@}l~cdXm{h5lUi zoo3flcb=yB{xy1?vl~6M`xjqPdf%Q@eY|b026)c$k68A5_Lo^ ze~0HST=l6>KHryP=zz3Qv-SFpTtAPNJbpr)QJJOl7`BhPb_VjmGEjccAxf^hifV7} zM|ZyQrk2Jv0-o*WJ3w;#xt=py*6RHz?8))-7HMtc^VhgsATjFzuJ5w%oTlbAGbw-B ze7$|L?qeB{{r(NlT%?rxtF^G@?f0m1MzwxzhJCwwnzet?=2p}8;tTM z==+q?SIB?}nhe}jtv%BU`&RWbYd@Dg^2!CDwxa!Z=MeL6?PB0FbHYL|?+5jw(!1Nf zDT=Y4+-5l~`@x_K^5&1F)c#jfzr{_o?p0y4j&X;5)X}c}W^D+T4oDocjz(>qPZ?vf z4K}~3_vQ8@E&D?74fIs;Ep~*K=g&~Ws5ORuAG#j>zF9js&u#mIr2|Um?GoetWU4&S z=JPZ2`>O57m{6VvDQuaqeV00SOevMjy~og2*ktIJ5Q7%ztGV9~wEbo}0MB2sB70Y3Ez{GZGAI-TjjA|9M8bB%--YAHdWh?J`XnE_EXQ&-m@=j=?xD)VtBTh z4gkK!PkvX!n?Ie)^_;f*JCwd?pJTZ+_%3VH+T-;6@BV41C%?xoR@;xV+2r{rR`0|$_Mwtdxhndtzz47ay(zW2LaIScO7zSW2CHA3IvtQ0eO z4m1yTfjmZrPON$8IWZnAq@7lkC?FR3G|C1L!A&iBd z`1n^oa-iw}Zg0b~`!)V%j1&7KhBs2d`Zn7Zbwa=8w4ZlN3t&O^mEwK))M*E3w+5o64wJ~Sr;x7bhvb$dCHijTK&<6Km(qEc31A%r_-C?2S2`(b$xEz=cGL7 z4Ou`PxIP@?tj(%}4^dIe6w00$Pg&ypUbg|~{^ERA$QD0WjxkmXhrIiv1?G|Daid&E zPRnQ4;@nxZO%A1Z-m0Bz3m*GBj~4zbxAv^RHU#57`bq2y?8TSQ5@Gr7%5~I# z_B7h~`n$C7#G_QcdaKS4$W$=;ddLgxCCDjwoiwOFm5=uB%f`NR>`&+Y=$`Ui%3r>h zs*io_Gp?vT`2iKI+)W96#olXu|GIGxI`&?VylbPr=NPtWd*li2=P?xa7sr%jX#1*f z7kg~6&zbi;BfoU(IjTGPYq96%U8)%+)NV`Ulu;2K-z#YAb6-%AQ#a&GaRRhE~ zQ$Eo4q4U~w)C=p-uwTn;9TL_XV!bB+VQpUZ?hh!d`Fj-WnXf;e_uXPY@T^0J^nJ(h z#rV@d=udf`F?Hlns+~5HmOuTBzQ43rf;jg;?5D0h@v*kof!9ETwoca+V?P$Jr34?U z4}15Gdg2xv_KRX4EB5t{+PqQk^Ze}_=kb2ou1B=}q1YpceV4p9v{%e^lz-cPDw=aa z+yBdJ{?xU7X7rcycuyI4F?Q95V&CT{+8&gc#F6^D@J{SeMIEZQ+^5L|>?tcA$h1!y zQ0BA06ZYWqC9L_ZIriD5y}Kv1eWZ972kbMQ{lEkI zenl%=gU_BR+x-Z|Hge-zUY(Qj(geHVQNFXeMfI$odG!P)H0wPvG1W`H=R9so42v}thMaEWZ z7e}Z6oSxr#oafEs%L3!rnYNjEx$k}7_ue^oIp^Mc&iS3!RIG*C4PAqy9r#Ml71VXT z^l$XCL!v9S{}uOP@(SMd&-~oex$4^-o*&#BPTqu-RP5w~g%cSsw8NGIr#{6T0i82& z59fkld|mm8Hz|5}qMUmL3=`hHy{edog^NvLl6OrCCq zf5k3Bme79Pf-THa$9p>1SUu&V^yqOK%DA#%6K5f$f3+ySWM$Lt+U6Fu2C_s z;aKMG z;5VY5uw+2>sLHOp?x5g=D&9Ur{f4`3%n-0$UZHKt|G`llFS(xQOV-uQzhW3r55*!V z@8Ai4p7_?!uqMJE#$fbZUIUhMEc&SVG^BJRxzY+5Q{K+z0hp!0_--P@kqfN+4eH-e zoMQA!9_KeOI>C(5!Fjh}3j^AjF*@BdW=Ra)0~|-J*j&|rnnOZ)17CXXsZ{yL{O#tr z?ECgzr)`(MwEdO7!%E1fe+S_KeCUCFXjoCPj2FckLKk8DL_fYxFe<=Ug$?a3=UyQe zwxpBGmjXvve(@(S{F9Q`^16ci0CJ#nP;+ZHvkuTXdJpt)KM%O6OJM=O)RyPb6bQSQm8a6HCL&H`?uk*k;85VC|#)pgqBp z$*-PcPow>X{=vE$Sb((sUl3xbO&=lN-R_q>z7gi7_X7cf-wH1&6aKMI###t+jQYgY zzbY7!qJ#VC{uv`}ya@1vzKM^>JD`;Y=z%WiYd@I0p+1UXL8!^Y{YS-7#XH^Ovx4!MvaOCX7tOHo9$j2_ zlV7?u_LYCcWM$=jK!f*OxBCJ0fJ{3vH{cn6kaM&-WF6T4q#f62%ZE+JzCZ^2+#PH_ zlBZ?RoFhj#zTJvFG-DCKKMq%X2O2WR!lfv-!YA6x9{b8aVtx=?*2{H_M!fPR#Xk8x z-W>IC;z$%*1-S=?;=bLVQ&7kWi5t>qI?LpltI0P$%*ITNTgTWR#=j_Dz}yR{Kc~-Q zS%N93x%#z~z()8a_G>iuK?ku~S_j0h1?JTWt^@rMG2xW-iHU;%t~Y7JCzQgv3m6E* zQ#KV_r}cmgbWa&(V;+Fph#CK&v@`4q=6+Ir_Zs7`@$rb44@e)~Xzc6r%~Inzp851U zDth$E=5!Sh`bnkM3o3 z4o*DCIY5&;QcBT{_;ilfcV#vn`z8%NSN`=HaVXGRI1r1DxJkrK>G!QIAp`yi9Vw@J zK8>q;g5ow=xx+l=U{gC)$fRsLzPw*3AsR!^uBBM;x8T5+Ux<|Dgr9%>SU7 zHPkCTUfMo5Gg!tB_UGo<(LPYT*nk}zAD#4TN-Z8mSt~c(H1?Hev-HHj`902KCRdAI zbbj94HDqAm%w_cOirExXW8oQ_vO}Owx(5rL!ZGd~-#w_T)*kzawQOq4wub+)tM(E2 zQGOx!dfrqC83>=Sf-%(t?Y4LBy|n#NY9Ay#f0hDMI+B0(Y#TR#cwEqd?m>LANwYQl zJ7oYdo~@|^;^Sj#whRB*XPNvu&(Q~JHw>S*sL|L*d?#q$ZalRo8Nl<*cJOpQsQ77$ zu6s z`@uD$oRW&`XzuRUXxsbOZsJ9skJ8CM+8*^Ve}i+U3^>2nYs4ucRx@+SF6x<6LB0?E z?w0v)+r>qFN;Xqi=}rpFT}}bR=Tk~at;hP9{6p_+93@KS38g0)z~?r<3+t)p$Z`r8 zy+ryywBq;F-W7VwylY=Tp4BcFzyB(Q&Z?ju*&|sm&E)#bqqGHEr9LMACcmD}Ap__K zv~PCBcIuP6l>L9D6qubuL6h@oz#hvN1{;am7?hveEp?BEHEQC1&ObYQ9OFN_aNK1i zg^$Z`G=4nsY<`A#WW;cGXDrgdf_&;Z)SF|zIBsy)_j&PK(v!DS59lS;t=4|w9f~O8 zIJ_**QGXlph`6V3UK-uI)mqcwnV3IyUvfJnRMj3#1uxBjHBKhQy9!K zh0Prig%6Q?&H6^~cE@@cYhX|7n%3}itG@vqj487}P!~NAFY0`6xqfGsSTlm}A8MT6 zYCZ6K%!#NA4m@!Du z-LU1|j_wBUrVe&*YM`j8g_KcNMw9DarLoICphp&+qq0L^NIcQ>t$S(u_B~dd&cvw{ zU2Xa2!87J0(BO7LTI z$rT<&4==2w={t5)_~_Ag%nA19o@@(FUZ8t5w!~fEKnvhEi8qU+8DdQ-za+9t9)wkfJi)+kPI)5WC z`_S11l+STY_jKvVYq)6=qk>!~u-U;kpte)^df;n@?G$!A_iFYT=@2Z|H^SIwjtnGE>uFA7}^k1;#_@q?g!lA4J|Emft=6u}7sJFuqkk=)M@d zji_8mxz+5`^UD?AWaR84V)sOy;Ga+$T4to(oG%D|0<@Fl{9U<^I=eXEt#^A8U-h=F z9II%_rnZ6lcq5C;#gBwMxZYi@ytVGS_oVG%tB0RK>4x!`$93Jh%jDz%Z3UY+d;str z!cPEuVducM(zgBc^P~;bSF2+_b$$sI?%Pk@dUxYKt0wqoHD9dwlZ?FZpj$rwyc{nd zzE0prc|(aml+X{I_?<%HYw6xja?}o6P;Bc-+dj&9-WvH=;oD@tu;wd~}YH?#C;Y$Ms*(a@xb>S}Z>76Xk2K|ufR(>1RJMg{04-lChDZZu7zMQu^ zy+mvT$e}j$&|e6;7h@hgK+k{fxCAm)RVeP7VtYgX>H*a_KHbTQ|EK4J{U)jcVG9Pux) ze?)DvpbtDb+99g?b@7cw&3Iq*3)&fa2G_`6mdd`bCz(%kUk^-Tk6|;#U!*>)d$%_T zUFcukAEi9LnC3Mc7r%x-`!~?{=5ufkdkB0f3pl4?+V1l*?+>a!MafS$Nd7SA?{O_- zAbk!$_b!6}CcUCiXk(rSecQ*glE)zDz6#|wf`7u(vrK!8<|WFVStdS&=J4*Zla_Pt z`%rm)?80)Puf7`9LFj`a6$LbM?Ph|1p(XnG9++U1z`dfKaqh`>IJx#kN+_zJoHdIG z`I^w@=2}GKI+6b*Wzoh)eGl6{?7=9_`kVa0c7p?-!Jg~n0ldZLucoNdnL-=$t^Jxd95v7Gd(ea(SMzx_MIX;c8)*GuLsh#zK11L5W|VT>Kf0;z$_LiUi7#=i z4deFBy1_QB_I#5*Y|-!|0iV6=EaOVqj|4iXJLu~@`mBhFD+zdW>?4$>vkWQSK)pG4 z0O-U`TPbb2@)fI(@f?#rY_XuNc5rhH;J39WKaza62?hMlr}ViLJaIKeuQ}SRO$6&Q zmB;=Y`Q2M%r&9lEPY7N2l&YKPt4$R=p#KLKuc!DKD+S9PHDv|$9y3{JCcVtL4td?z zoR3D^0z8+`3YaDQ_)t4V!kv8K z_;dD2z?j(-zx558_QFwG{LV!i(^GloV=6fO8YOK$PC?TuJdV4FO4jkKw$PkI$0>I1 z0b?Ki8AY%kW#FS@Uq%AV2OM`9oQ@QO=J?ZT7Cs%9-&ZYdF+#kE?1T8sziDM7@Q)JOb z?xQQRPePoRt|PIwyszd@G@$YT$5vKRuVgQ(x%xM`Kdfv$6&^i7A;YK8o8q6@_t8J>^#JA|?5|we^J(ve zukE?B@1sj7pWA-GGvDV9?i8CwartXxZpQo!9SVOU{BejQS@OaenLDA=$5g*S5p$m= zpVSD=Lx)_{;8$))MIqHeJ}3+W&3-m zeGfNvADU0yhcA@-F^6Ft1z%{lv=W&s`%GI)T?dVAHXjb!qkC3qqj|tJVu9$%AKLHW zPzSehc}JU{%U#eiz5MQEZBt%u>6~7_xTDQa+9V|0xZ<~-|FlhC2D##wI~m)0XB$7i a8&|BVe%7Wv|HpTeSWj8cln4J;|NA!^FuI8V literal 0 HcmV?d00001 diff --git a/docs/previews_minigames/font_test.png b/docs/previews_minigames/font_test.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0e6218c039821df31aa0b8448062e255c2c10f GIT binary patch literal 2925 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

~t86&GMXQ7_3%~o>+tCRZ7O0pL}PAWvY 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 literal 0 HcmV?d00001 diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json new file mode 100644 index 0000000..4a05256 --- /dev/null +++ b/graphify-out/.graphify_labels.json @@ -0,0 +1 @@ +{"0": "Account & Cloud Sync System", "1": "Portable Build & Networking", "2": "Architecture Constraints & Roadmap", "3": "Core Project & MASM Instructions", "4": "3D Asset Generation Pipeline", "5": "Visual FX & Variables Spec", "6": "Casino Sprite Atlas & Props", "7": "Renderer Texture Slot Packer", "8": "Cabaret Dancer Animation Sequence", "9": "3D Raycaster Environment Textures", "10": "Release Verification Smoke Tests", "11": "Dead by Daylight Helper Tool", "12": "Hakari Dance Animation Previewer", "13": "Skill Check Minigame & Reference", "14": "3D Engine Assembly Generator", "15": "Fixed-Point Math & Map Generator", "16": "Casino Intro Preview Utility", "17": "Raycasting Render Simulator", "18": "Casino 2.5D Engine Core Include", "19": "Casino 2.5D Data Constants", "20": "Bitmap 8x8 Font Module", "21": "Repository Overview & License", "22": "GDI Platform Event Loop", "23": "Platform Window State & Config", "24": "Software Raycaster Renderer", "25": "Engine Build Helper Script", "26": "Graphics Assembler Build Script", "27": "Casino 3D Builder Script", "28": "Font Generator Tool", "29": "Unified 3D Engine Generator", "30": "Casino 3D Make Script", "31": "ASM Hotpatching Utility"} \ No newline at end of file diff --git a/graphify-out/.graphify_python b/graphify-out/.graphify_python new file mode 100644 index 0000000..4350d36 --- /dev/null +++ b/graphify-out/.graphify_python @@ -0,0 +1 @@ +C:\Users\IKER\AppData\Roaming\uv\tools\graphifyy\Scripts\python.exe \ No newline at end of file diff --git a/graphify-out/.graphify_root b/graphify-out/.graphify_root new file mode 100644 index 0000000..9361e63 --- /dev/null +++ b/graphify-out/.graphify_root @@ -0,0 +1 @@ +E:\DEPAI IN 3D\KAZIK \ No newline at end of file diff --git a/graphify-out/.graphify_semantic_new.json b/graphify-out/.graphify_semantic_new.json new file mode 100644 index 0000000..f3c85c6 --- /dev/null +++ b/graphify-out/.graphify_semantic_new.json @@ -0,0 +1,1790 @@ +{ + "nodes": [ + { + "id": "agents", + "label": "AGENTS.md Project Instructions", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "agents_masm32_build", + "label": "MASM32 Build Pipeline", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Single-file x86 assembly Windows console casino game assembled with ml.exe /c /coff /Cp /nologo and linked with link.exe /SUBSYSTEM:CONSOLE against kernel32, winmm, user32, ws2_32, gdi32." + }, + { + "id": "agents_cp1251_encoding", + "label": "CP1251 Console Encoding Standard", + "file_type": "rationale", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Source strings and dealer_phrases.txt must remain in Windows-1251 (CP1251) for Windows console rendering; do not re-save as UTF-8." + }, + { + "id": "agents_cheat_codes", + "label": "Console Cheat Codes System", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "agents_games_catalog", + "label": "Casino Games Catalog", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "agents_animation_assets", + "label": "ANSI Animation Assets Spec", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "casino_intro.ans and hakari_dance.ans use ANSI escape codes and CP1251 with form-feed frame separators for high-performance terminal animations." + }, + { + "id": "cmakelists", + "label": "CMake Portable Build Configuration", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\CMakeLists.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "cmakelists_poker_portable", + "label": "poker_portable Target", + "file_type": "code", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\CMakeLists.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "cmakelists_winsock_dependency", + "label": "Win32 Winsock ws2_32 Dependency", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\CMakeLists.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "readme", + "label": "KAZIK Project Readme", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\README.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_data_dealer_phrases", + "label": "Dealer Dialogue Phrases", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\data\\dealer_phrases.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_data_dealer_phrases_outcome_prefixes", + "label": "Win Loss Draw Outcome Prefixes", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\data\\dealer_phrases.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Lines prefixed with W|, L|, and D| categorize dealer reactions to player outcomes for runtime dynamic selection." + }, + { + "id": "docs_known_limitations", + "label": "Known Limitations Specification", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_known_limitations_windows_platform_lock", + "label": "Windows Platform Dependency", + "file_type": "rationale", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Officially Windows-only due to tight coupling to MASM32, WinAPI, WinMM, MCI, and Windows console API." + }, + { + "id": "docs_known_limitations_wine_support", + "label": "Wine and CrossOver POSIX Support", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Enables non-Windows execution on Linux and macOS via Wine translation layers without rewriting the assembly core." + }, + { + "id": "docs_known_limitations_ansi_console_speed", + "label": "ANSI Animation Console Bottleneck", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Console throughput limits animation smoothness on older PCs, requiring frame-skip rendering profiles." + }, + { + "id": "docs_known_limitations_durak_logic_risk", + "label": "Durak Card Logic Complexity Risk", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Durak is the most complex game logic in the suite due to card defense, tossing (podkidnoy), transferring (perevodnoy), and table clearing." + }, + { + "id": "docs_online_radmin", + "label": "Online Radmin VPN Guide", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ONLINE_RADMIN.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_online_radmin_host_authoritative", + "label": "Host Authoritative Network Model", + "file_type": "rationale", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ONLINE_RADMIN.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Host owns hidden chamber state in Russian roulette and dice seeds; client sends only inputs so both peers remain in sync without a dedicated server." + }, + { + "id": "docs_online_radmin_p2p_socket", + "label": "Winsock TCP Port 27015 LAN Protocol", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ONLINE_RADMIN.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Built-in 1v1 match on TCP port 27015 directly inside poker.exe without installing separate servers or services." + }, + { + "id": "docs_readme_release", + "label": "Release Notes and User Guide", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\README_RELEASE.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_readme_release_rendering_profiles", + "label": "Animation Rendering Profiles", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\README_RELEASE.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Cinematic, Adaptive, and Stable profiles control frame-skipping to eliminate flicker and stutter without omitting entire scenes." + }, + { + "id": "docs_readme_release_package_architecture", + "label": "Release Package Architecture", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\README_RELEASE.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Bundles launcher Assembler Casino.exe, core bin/poker.exe, and assets into an installer for clean user experience." + }, + { + "id": "docs_release_checklist", + "label": "Release QA Checklist", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_release_checklist_smoke_check", + "label": "Automated Release Smoke Check", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "tools/release_smoke_check.ps1 automates pre-release verification of builds, installer, and payload integrity." + }, + { + "id": "docs_release_checklist_installer_validation", + "label": "Installer & Uninstaller Verification", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Validates installation directory selection, desktop shortcuts, registry entry under Add/Remove Programs, and clean uninstallation." + }, + { + "id": "docs_release_checklist_game_verification", + "label": "Casino Games QA Verification", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Comprehensive verification steps covering all 12 casino games, account persistence, bankruptcy handling, and win goals." + }, + { + "id": "docs_roadmap", + "label": "Development Roadmap", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_roadmap_online_command_protocol", + "label": "Multiplayer Command Protocol", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Client-server text command set (BET, HIT, STAND, FOLD, RAISE, PLAY_CARD, READY, CHAT) sent over TCP sockets." + }, + { + "id": "docs_roadmap_security_milestones", + "label": "Security & Signing Roadmap", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Planned addition of Authenticode code-signing, release manifests, and stronger save checksum validation." + }, + { + "id": "docs_roadmap_future_expansions", + "label": "Future Casino Expansions", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Planned expansions including casino tax, VIP tier benefits, charm bestiary, secret ending, and casino tower tournament." + }, + { + "id": "docs_security_notes", + "label": "Security Architecture Notes", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_security_notes_sha256_payload_check", + "label": "SHA-256 Binary Integrity Verification", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Installer verifies embedded archive hash and launcher validates bin/poker.exe hash to prevent payload tampering." + }, + { + "id": "docs_security_notes_save_tamper_signature", + "label": "Save File Salted Signature", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Save files write a hash signature computed over the first 276 bytes with a hardcoded salt to catch manual progress hex editing." + }, + { + "id": "docs_security_notes_path_traversal_guard", + "label": "Installer Path Traversal Guard", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Installer rejects archive entries containing ../ to guarantee unpacked files cannot escape the installation directory." + }, + { + "id": "docs_casino_intro_preview", + "label": "Casino Intro ASCII Preview", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\casino_intro_preview.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "ASCII art banner preview for the main casino entry screen." + }, + { + "id": "docs_dbd_hook_static", + "label": "Dead by Daylight Hook Reference Graphic", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\dbd_hook_static.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_dbd_hook_static_skill_check", + "label": "Skill Check Hook Escape Minigame", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\dbd_hook_static.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Timed QTE skill check minigame inspired by Dead by Daylight requiring player to press SPACE or ENTER at the exact moment." + }, + { + "id": "docs_revolver_small_preview", + "label": "Revolver ASCII Preview", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\revolver_small_preview.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_revolver_small_preview_russian_roulette_visuals", + "label": "Russian Roulette Revolver ASCII Graphics", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\revolver_small_preview.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Detailed multi-angle ASCII art gun animations showing cylinder spin and hammer cocking for Russian Roulette." + }, + { + "id": "docs_читкоды", + "label": "Secret Cheat Codes Reference", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ЧИТКОДЫ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_читкоды_menu_codes", + "label": "Menu Cheat Code Definitions", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ЧИТКОДЫ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Keyboard cheat commands entered at the main menu including MONEYRAIN, SEVENS, WINNEXT, GODMODE, FAIRPLAY, GOAL, RESETBANK, AI difficulty, and ACHIEVER." + }, + { + "id": "docs_новый_текстовый_документ", + "label": "Intro Glitch Prototype Snippet", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\Новый текстовый документ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_новый_текстовый_документ_showintro", + "label": "ShowIntro Procedure Prototype", + "file_type": "code", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\Новый текстовый документ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "docs_новый_текстовый_документ_glitch_fx", + "label": "Terminal Glitch and Screen Shake FX", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\Новый текстовый документ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Uses rdtsc CPU cycle counter to dynamically trigger screen shakes, ANSI 256-color flicker flashes, and character corruption." + }, + { + "id": "graphify_out_converted_variables_documentation_3fc6d2dc", + "label": "poker.asm Variables Reference", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\graphify-out\\converted\\variables_documentation_3fc6d2dc.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", + "label": "SAVE_MAGIC Constant 31435653h", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\graphify-out\\converted\\variables_documentation_3fc6d2dc.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Magic header constant used to validate Assembler Casino save game integrity upon loading." + }, + { + "id": "graphify_out_converted_variables_documentation_3fc6d2dc_color_constants", + "label": "Console Color Attributes Constants", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\graphify-out\\converted\\variables_documentation_3fc6d2dc.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Defines standard color attribute constants for cards, table, wood, money, warnings, and titles in WinAPI console." + }, + { + "id": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles", + "label": "Standard Console Handles", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\graphify-out\\converted\\variables_documentation_3fc6d2dc.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Constants for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and INVALID_HANDLE_VALUE for Windows console I/O." + }, + { + "id": "runtime_achievement", + "label": "Runtime Achievement Storage File", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\runtime\\achievement.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Local file storing unlocked player achievements." + }, + { + "id": "runtime_achievement_tracking", + "label": "Runtime Achievement Tracker", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\runtime\\achievement.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "идеи", + "label": "Feature Backlog and Game Ideas", + "file_type": "document", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "идеи_appdata_saves", + "label": "AppData Save Migration Idea", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Moving player save data to %AppData% prevents accidental deletion when reinstalling or updating the casino." + }, + { + "id": "идеи_shop_and_charms", + "label": "Casino Shop and Charms Mechanic", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Allows spending winnings on charms, custom card decks, shirts, and lucky talismans with gameplay effects." + }, + { + "id": "идеи_pulse_stress", + "label": "Heart Rate Stress Visualization", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Visualizes player character pulse and anxiety level during high-stakes gambling decisions." + }, + { + "id": "идеи_durak_expansion", + "label": "Durak Card Game Expansion", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Addition of Russian card game Durak with podkidnoy and perevodnoy variants to broaden casino offerings." + }, + { + "id": "идеи_buckshot_roulette", + "label": "Buckshot Roulette Game Mode Idea", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Adaptation of shotgun-based Russian Roulette gameplay with items and bluffing mechanics." + }, + { + "id": "идеи_casino_tower", + "label": "Casino Tower Tournament Idea", + "file_type": "concept", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Multi-floor casino tower progression where players face escalating AI opponents with special modifiers." + }, + { + "id": "assets_icons_casino_preview_image", + "label": "Casino Preview Icon", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\icons\\casino_preview.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_sprites_cabaret_loop_v1_image", + "label": "Cabaret Loop Sprite Sheet", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\cabaret-loop-v1.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_sprites_casino_atlas_v1_image", + "label": "Casino Atlas Sprite Sheet", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\casino-atlas-v1.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_bartender_shop_image", + "label": "Bartender Shop Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_bartender_shop.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_blackjack_table_image", + "label": "Blackjack Table Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_blackjack_table.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_dancer_frame_0_image", + "label": "Dancer Animation Frame 0 Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_0.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_dancer_frame_1_image", + "label": "Dancer Animation Frame 1 Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_1.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_dancer_frame_2_image", + "label": "Dancer Animation Frame 2 Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_2.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_dancer_frame_3_image", + "label": "Dancer Animation Frame 3 Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_3.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_roulette_table_image", + "label": "Roulette Table Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_roulette_table.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_slot_frame_0_image", + "label": "Slot Machine Frame 0 Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_0.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_slot_frame_1_image", + "label": "Slot Machine Frame 1 Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_1.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_sprite_slot_frame_2_image", + "label": "Slot Machine Frame 2 Sprite", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_2.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_tex_floor_carpet_image", + "label": "Casino Carpet Floor Texture", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_floor_carpet.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_tex_wall_hell_image", + "label": "Hell Wall Texture", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_hell.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_tex_wall_stripclub_image", + "label": "Neon Strip Club Wall Texture", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_stripclub.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + }, + { + "id": "assets_textures_tex_wall_velvet_image", + "label": "Velvet Wall Texture", + "file_type": "image", + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_velvet.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null + } + ], + "edges": [ + { + "source": "agents", + "target": "agents_masm32_build", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "agents", + "target": "agents_cp1251_encoding", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "agents", + "target": "agents_cheat_codes", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "agents", + "target": "agents_games_catalog", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "agents", + "target": "agents_animation_assets", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "agents_cheat_codes", + "target": "docs_читкоды_menu_codes", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "agents_cp1251_encoding", + "target": "assets_data_dealer_phrases", + "relation": "rationale_for", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "agents_games_catalog", + "target": "docs_release_checklist_game_verification", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "cmakelists", + "target": "cmakelists_poker_portable", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\CMakeLists.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "cmakelists", + "target": "cmakelists_winsock_dependency", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\CMakeLists.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "cmakelists_winsock_dependency", + "target": "docs_online_radmin_p2p_socket", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\CMakeLists.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_data_dealer_phrases", + "target": "assets_data_dealer_phrases_outcome_prefixes", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\data\\dealer_phrases.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_known_limitations", + "target": "docs_known_limitations_windows_platform_lock", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_known_limitations", + "target": "docs_known_limitations_wine_support", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_known_limitations", + "target": "docs_known_limitations_ansi_console_speed", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_known_limitations", + "target": "docs_known_limitations_durak_logic_risk", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_known_limitations_windows_platform_lock", + "target": "agents_masm32_build", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_known_limitations_ansi_console_speed", + "target": "docs_readme_release_rendering_profiles", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_known_limitations_durak_logic_risk", + "target": "идеи_durak_expansion", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_online_radmin", + "target": "docs_online_radmin_host_authoritative", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ONLINE_RADMIN.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_online_radmin", + "target": "docs_online_radmin_p2p_socket", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ONLINE_RADMIN.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_online_radmin_host_authoritative", + "target": "docs_roadmap_online_command_protocol", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ONLINE_RADMIN.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_readme_release", + "target": "docs_readme_release_rendering_profiles", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\README_RELEASE.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_readme_release", + "target": "docs_readme_release_package_architecture", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\README_RELEASE.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_readme_release_package_architecture", + "target": "docs_release_checklist_installer_validation", + "relation": "references", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\README_RELEASE.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_release_checklist", + "target": "docs_release_checklist_smoke_check", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_release_checklist", + "target": "docs_release_checklist_installer_validation", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_release_checklist", + "target": "docs_release_checklist_game_verification", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_release_checklist_smoke_check", + "target": "docs_security_notes_sha256_payload_check", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_roadmap", + "target": "docs_roadmap_online_command_protocol", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_roadmap", + "target": "docs_roadmap_security_milestones", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_roadmap", + "target": "docs_roadmap_future_expansions", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_roadmap_security_milestones", + "target": "docs_security_notes", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_security_notes", + "target": "docs_security_notes_sha256_payload_check", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_security_notes", + "target": "docs_security_notes_save_tamper_signature", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_security_notes", + "target": "docs_security_notes_path_traversal_guard", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_security_notes_save_tamper_signature", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", + "relation": "shares_data_with", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_security_notes_save_tamper_signature", + "target": "идеи_appdata_saves", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_casino_intro_preview", + "target": "agents_animation_assets", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\casino_intro_preview.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_dbd_hook_static", + "target": "docs_dbd_hook_static_skill_check", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\dbd_hook_static.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_revolver_small_preview", + "target": "docs_revolver_small_preview_russian_roulette_visuals", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\revolver_small_preview.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_revolver_small_preview_russian_roulette_visuals", + "target": "идеи_buckshot_roulette", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\revolver_small_preview.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_читкоды", + "target": "docs_читкоды_menu_codes", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ЧИТКОДЫ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_новый_текстовый_документ", + "target": "docs_новый_текстовый_документ_showintro", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\Новый текстовый документ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_новый_текстовый_документ_showintro", + "target": "docs_новый_текстовый_документ_glitch_fx", + "relation": "implements", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\Новый текстовый документ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_новый_текстовый_документ_showintro", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles", + "relation": "calls", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\Новый текстовый документ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "docs_новый_текстовый_документ_glitch_fx", + "target": "docs_casino_intro_preview", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\Новый текстовый документ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "graphify_out_converted_variables_documentation_3fc6d2dc", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\graphify-out\\converted\\variables_documentation_3fc6d2dc.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "graphify_out_converted_variables_documentation_3fc6d2dc", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_color_constants", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\graphify-out\\converted\\variables_documentation_3fc6d2dc.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "graphify_out_converted_variables_documentation_3fc6d2dc", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\graphify-out\\converted\\variables_documentation_3fc6d2dc.md", + "source_location": null, + "weight": 1.0 + }, + { + "source": "runtime_achievement", + "target": "runtime_achievement_tracking", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\runtime\\achievement.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "runtime_achievement_tracking", + "target": "docs_читкоды_menu_codes", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\runtime\\achievement.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "идеи", + "target": "идеи_appdata_saves", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "идеи", + "target": "идеи_shop_and_charms", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "идеи", + "target": "идеи_pulse_stress", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "идеи", + "target": "идеи_durak_expansion", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "идеи", + "target": "идеи_buckshot_roulette", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "идеи", + "target": "идеи_casino_tower", + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "идеи_shop_and_charms", + "target": "docs_roadmap_future_expansions", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "идеи_casino_tower", + "target": "docs_roadmap_future_expansions", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\ИДЕИ.txt", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_sprites_cabaret_loop_v1_image", + "target": "assets_textures_sprite_dancer_frame_0_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\cabaret-loop-v1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_sprites_cabaret_loop_v1_image", + "target": "assets_textures_sprite_dancer_frame_1_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\cabaret-loop-v1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_sprites_cabaret_loop_v1_image", + "target": "assets_textures_sprite_dancer_frame_2_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\cabaret-loop-v1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_sprites_cabaret_loop_v1_image", + "target": "assets_textures_sprite_dancer_frame_3_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\cabaret-loop-v1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_dancer_frame_0_image", + "target": "assets_textures_sprite_dancer_frame_1_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_0.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_dancer_frame_1_image", + "target": "assets_textures_sprite_dancer_frame_2_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_dancer_frame_2_image", + "target": "assets_textures_sprite_dancer_frame_3_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_2.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_dancer_frame_3_image", + "target": "assets_textures_sprite_dancer_frame_0_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_3.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_slot_frame_0_image", + "target": "assets_textures_sprite_slot_frame_1_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_0.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_slot_frame_1_image", + "target": "assets_textures_sprite_slot_frame_2_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_slot_frame_2_image", + "target": "assets_textures_sprite_slot_frame_0_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_2.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_sprites_casino_atlas_v1_image", + "target": "assets_textures_sprite_blackjack_table_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\casino-atlas-v1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_sprites_casino_atlas_v1_image", + "target": "assets_textures_sprite_roulette_table_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\casino-atlas-v1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_sprites_casino_atlas_v1_image", + "target": "assets_textures_sprite_bartender_shop_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\casino-atlas-v1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_sprites_casino_atlas_v1_image", + "target": "assets_textures_sprite_slot_frame_0_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\casino-atlas-v1.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_blackjack_table_image", + "target": "assets_textures_sprite_roulette_table_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_blackjack_table.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_roulette_table_image", + "target": "assets_textures_sprite_blackjack_table_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_roulette_table.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_sprite_bartender_shop_image", + "target": "assets_textures_sprite_blackjack_table_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_bartender_shop.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_tex_wall_velvet_image", + "target": "assets_textures_tex_wall_stripclub_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_velvet.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_tex_wall_stripclub_image", + "target": "assets_textures_tex_wall_hell_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_stripclub.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_tex_wall_velvet_image", + "target": "assets_textures_tex_wall_hell_image", + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_velvet.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_tex_floor_carpet_image", + "target": "assets_textures_tex_wall_velvet_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_floor_carpet.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_textures_tex_floor_carpet_image", + "target": "assets_textures_tex_wall_stripclub_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_floor_carpet.png", + "source_location": null, + "weight": 1.0 + }, + { + "source": "assets_icons_casino_preview_image", + "target": "assets_sprites_casino_atlas_v1_image", + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\icons\\casino_preview.png", + "source_location": null, + "weight": 1.0 + } + ], + "hyperedges": [ + { + "id": "he_p2p_multiplayer_architecture", + "label": "P2P Multiplayer Architecture", + "nodes": [ + "docs_online_radmin_host_authoritative", + "docs_online_radmin_p2p_socket", + "docs_roadmap_online_command_protocol" + ], + "relation": "implement", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\ONLINE_RADMIN.txt" + }, + { + "id": "he_save_integrity_protection", + "label": "Save File Integrity & Persistence Architecture", + "nodes": [ + "docs_security_notes_save_tamper_signature", + "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", + "идеи_appdata_saves" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt" + }, + { + "id": "he_release_packaging_verification", + "label": "Release Packaging & Verification Flow", + "nodes": [ + "docs_release_checklist_smoke_check", + "docs_release_checklist_installer_validation", + "docs_security_notes_sha256_payload_check" + ], + "relation": "implement", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt" + }, + { + "id": "cabaret_dancer_animation_set", + "label": "Cabaret Dancer Animation Sequence", + "nodes": [ + "assets_textures_sprite_dancer_frame_0_image", + "assets_textures_sprite_dancer_frame_1_image", + "assets_textures_sprite_dancer_frame_2_image", + "assets_textures_sprite_dancer_frame_3_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\cabaret-loop-v1.png" + }, + { + "id": "slot_machine_animation_set", + "label": "Slot Machine Reel Animation Sequence", + "nodes": [ + "assets_textures_sprite_slot_frame_0_image", + "assets_textures_sprite_slot_frame_1_image", + "assets_textures_sprite_slot_frame_2_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_0.png" + }, + { + "id": "casino_wall_textures_set", + "label": "Casino Wall Textures Set", + "nodes": [ + "assets_textures_tex_wall_velvet_image", + "assets_textures_tex_wall_stripclub_image", + "assets_textures_tex_wall_hell_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_velvet.png" + } + ], + "input_tokens": 0, + "output_tokens": 0 +} \ No newline at end of file diff --git a/graphify-out/.graphify_transcripts.json b/graphify-out/.graphify_transcripts.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/graphify-out/.graphify_transcripts.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/graphify-out/.graphify_uncached.txt b/graphify-out/.graphify_uncached.txt new file mode 100644 index 0000000..7faa2d8 --- /dev/null +++ b/graphify-out/.graphify_uncached.txt @@ -0,0 +1,35 @@ +E:\DEPAI IN 3D\KAZIK\AGENTS.md +E:\DEPAI IN 3D\KAZIK\CMakeLists.txt +E:\DEPAI IN 3D\KAZIK\README.md +E:\DEPAI IN 3D\KAZIK\assets\data\dealer_phrases.txt +E:\DEPAI IN 3D\KAZIK\docs\KNOWN_LIMITATIONS.txt +E:\DEPAI IN 3D\KAZIK\docs\ONLINE_RADMIN.txt +E:\DEPAI IN 3D\KAZIK\docs\README_RELEASE.txt +E:\DEPAI IN 3D\KAZIK\docs\RELEASE_CHECKLIST.txt +E:\DEPAI IN 3D\KAZIK\docs\ROADMAP.txt +E:\DEPAI IN 3D\KAZIK\docs\SECURITY_NOTES.txt +E:\DEPAI IN 3D\KAZIK\docs\casino_intro_preview.txt +E:\DEPAI IN 3D\KAZIK\docs\dbd_hook_static.txt +E:\DEPAI IN 3D\KAZIK\docs\revolver_small_preview.txt +E:\DEPAI IN 3D\KAZIK\docs\Новый текстовый документ.txt +E:\DEPAI IN 3D\KAZIK\docs\ЧИТКОДЫ.txt +E:\DEPAI IN 3D\KAZIK\graphify-out\converted\variables_documentation_3fc6d2dc.md +E:\DEPAI IN 3D\KAZIK\runtime\achievement.txt +E:\DEPAI IN 3D\KAZIK\ИДЕИ.txt +E:\DEPAI IN 3D\KAZIK\assets\icons\casino_preview.png +E:\DEPAI IN 3D\KAZIK\assets\sprites\cabaret-loop-v1.png +E:\DEPAI IN 3D\KAZIK\assets\sprites\casino-atlas-v1.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_bartender_shop.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_blackjack_table.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_dancer_frame_0.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_dancer_frame_1.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_dancer_frame_2.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_dancer_frame_3.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_roulette_table.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_slot_frame_0.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_slot_frame_1.png +E:\DEPAI IN 3D\KAZIK\assets\textures\sprite_slot_frame_2.png +E:\DEPAI IN 3D\KAZIK\assets\textures\tex_floor_carpet.png +E:\DEPAI IN 3D\KAZIK\assets\textures\tex_wall_hell.png +E:\DEPAI IN 3D\KAZIK\assets\textures\tex_wall_stripclub.png +E:\DEPAI IN 3D\KAZIK\assets\textures\tex_wall_velvet.png \ No newline at end of file diff --git a/graphify-out/.vocab.txt b/graphify-out/.vocab.txt new file mode 100644 index 0000000..cd61bd3 --- /dev/null +++ b/graphify-out/.vocab.txt @@ -0,0 +1,260 @@ +account +achievement +agents +all +and +animation +ansi +app +architecture +art +ascii +asm +assets +atlas +atm +attributes +authoritative +automated +backlog +backroom +bartender +bgra +binary +black +blackjack +blend +bottleneck +browser +buckshot +build +cabaret +calc +card +carpet +casino +catalog +ceiling +cells +charms +cheat +check +checklist +chromakey +clean +cleanup +clear +cloud +club +code +codes +color +command +complexity +configuration +console +constant +constants +cross +dancer +data +daylight +dbd +dead +dealer +definitions +dependency +development +dialogue +download +draw +durak +dwords +enable +encoding +engine +escape +expansion +expansions +fail +feature +file +float +floor +flow +font +frame +future +game +games +generate +get +glitch +graphic +graphics +guard +guide +hakari +handles +hash +heart +hell +hook +host +icon +idea +ideas +image +img +import +inc +init +installer +instructions +integrity +into +intro +kazik +key +known +lan +limitations +lobby +local +logic +login +loop +loss +machine +magic +main +make +map +masked +masm +math +mechanic +menu +migration +minigame +mode +model +multiplayer +nearest +neon +net +network +never +notes +online +outcome +over +pack +package +pass +password +patch +path +peer +phrases +pipeline +pixel +pixels +place +platform +play +poker +port +portable +posix +prefixes +preview +procedure +profiles +project +protocol +prototype +pyth +radmin +rate +raw +read +readme +reference +register +release +render +renderer +rendering +require +resize +revolver +risk +roadmap +room +roulette +runtime +russian +salted +save +screen +secret +security +set +sha +shake +sheet +shop +show +signature +signing +simulate +skill +slot +slots +smoke +snippet +source +spec +specification +sprite +standard +storage +stress +strip +support +sync +system +table +target +tcp +terminal +tex +text +texture +the +tournament +tower +tracker +transfer +traversal +umamusume +unified +uninstaller +upload +user +variables +velvet +verification +verify +visualization +vpn +wall +white +win +window +windows +wine +winsock +with +wood \ No newline at end of file diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md new file mode 100644 index 0000000..0269271 --- /dev/null +++ b/graphify-out/GRAPH_REPORT.md @@ -0,0 +1,127 @@ +# Graph Report - . (2026-09-24) + +## Corpus Check +- 80 files · ~187,102 words +- Verdict: corpus is large enough that graph structure adds value. + +## Summary +- 147 nodes · 195 edges · 32 communities (28 shown, 4 thin omitted) +- Extraction: 78% EXTRACTED · 22% INFERRED · 0% AMBIGUOUS · INFERRED: 43 edges (avg confidence: 0.88) +- Token cost: 0 input · 0 output + +## Community Hubs (Navigation) +- Account & Cloud Sync System +- Portable Build & Networking +- Architecture Constraints & Roadmap +- Core Project & MASM Instructions +- 3D Asset Generation Pipeline +- Visual FX & Variables Spec +- Casino Sprite Atlas & Props +- Renderer Texture Slot Packer +- Cabaret Dancer Animation Sequence +- 3D Raycaster Environment Textures +- Release Verification Smoke Tests +- Dead by Daylight Helper Tool +- Hakari Dance Animation Previewer +- Skill Check Minigame & Reference +- Repository Overview & License + +## God Nodes (most connected - your core abstractions) +1. `net_lobby_menu()` - 10 edges +2. `main()` - 10 edges +3. `main()` - 9 edges +4. `account_register()` - 8 edges +5. `account_login()` - 8 edges +6. `calc_account_signature()` - 7 edges +7. `account_save()` - 7 edges +8. `account_import_transfer_key()` - 7 edges +9. `clear_screen()` - 6 edges +10. `account_cloud_sync_download()` - 6 edges + +## Surprising Connections (you probably didn't know these) +- `Console Cheat Codes System` --semantically_similar_to--> `Menu Cheat Code Definitions` [INFERRED] [semantically similar] + AGENTS.md → docs/ЧИТКОДЫ.txt +- `Win32 Winsock ws2_32 Dependency` --semantically_similar_to--> `Winsock TCP Port 27015 LAN Protocol` [INFERRED] [semantically similar] + CMakeLists.txt → docs/ONLINE_RADMIN.txt +- `Casino Games Catalog` --conceptually_related_to--> `Casino Games QA Verification` [INFERRED] + AGENTS.md → docs/RELEASE_CHECKLIST.txt +- `Windows Platform Dependency` --conceptually_related_to--> `MASM32 Build Pipeline` [INFERRED] + docs/KNOWN_LIMITATIONS.txt → AGENTS.md +- `CP1251 Console Encoding Standard` --rationale_for--> `Dealer Dialogue Phrases` [INFERRED] + AGENTS.md → assets/data/dealer_phrases.txt + +## Import Cycles +- None detected. + +## Hyperedges (group relationships) +- **P2P Multiplayer Architecture** — docs_online_radmin_host_authoritative, docs_online_radmin_p2p_socket, docs_roadmap_online_command_protocol [INFERRED 0.85] +- **Save File Integrity & Persistence Architecture** — docs_security_notes_save_tamper_signature, graphify_out_converted_variables_documentation_3fc6d2dc_save_magic, идеи_appdata_saves [INFERRED 0.85] +- **Release Packaging & Verification Flow** — docs_release_checklist_smoke_check, docs_release_checklist_installer_validation, docs_security_notes_sha256_payload_check [INFERRED 0.85] +- **Cabaret Dancer Animation Sequence** — assets_textures_sprite_dancer_frame_0_image, assets_textures_sprite_dancer_frame_1_image, assets_textures_sprite_dancer_frame_2_image, assets_textures_sprite_dancer_frame_3_image [INFERRED 0.95] +- **Slot Machine Reel Animation Sequence** — assets_textures_sprite_slot_frame_0_image, assets_textures_sprite_slot_frame_1_image, assets_textures_sprite_slot_frame_2_image [INFERRED 0.95] +- **Casino Wall Textures Set** — assets_textures_tex_wall_velvet_image, assets_textures_tex_wall_stripclub_image, assets_textures_tex_wall_hell_image [INFERRED 0.85] + +## Communities (32 total, 4 thin omitted) + +### Community 0 - "Account & Cloud Sync System" +Cohesion: 0.27 +Nodes (20): AccountData, account_cloud_sync_download(), account_cloud_sync_upload(), account_generate_transfer_key(), account_import_transfer_key(), account_login(), account_register(), account_save() (+12 more) + +### Community 1 - "Portable Build & Networking" +Cohesion: 0.11 +Nodes (18): CMake Portable Build Configuration, poker_portable Target, Win32 Winsock ws2_32 Dependency, Online Radmin VPN Guide, Host Authoritative Network Model, Winsock TCP Port 27015 LAN Protocol, Release Notes and User Guide, Release Package Architecture (+10 more) + +### Community 2 - "Architecture Constraints & Roadmap" +Cohesion: 0.15 +Nodes (14): Known Limitations Specification, ANSI Animation Console Bottleneck, Durak Card Logic Complexity Risk, Wine and CrossOver POSIX Support, Animation Rendering Profiles, Revolver ASCII Preview, Russian Roulette Revolver ASCII Graphics, Future Casino Expansions (+6 more) + +### Community 3 - "Core Project & MASM Instructions" +Cohesion: 0.17 +Nodes (12): AGENTS.md Project Instructions, Console Cheat Codes System, CP1251 Console Encoding Standard, Casino Games Catalog, MASM32 Build Pipeline, Dealer Dialogue Phrases, Win Loss Draw Outcome Prefixes, Windows Platform Dependency (+4 more) + +### Community 4 - "3D Asset Generation Pipeline" +Cohesion: 0.32 +Nodes (11): Image, clean_chromakey_black(), clean_chromakey_white(), img_to_raw_dwords(), main(), make_atm(), make_backroom_table(), make_carpet_floor() (+3 more) + +### Community 5 - "Visual FX & Variables Spec" +Cohesion: 0.18 +Nodes (11): ANSI Animation Assets Spec, Casino Intro ASCII Preview, Save File Salted Signature, Intro Glitch Prototype Snippet, Terminal Glitch and Screen Shake FX, ShowIntro Procedure Prototype, poker.asm Variables Reference, Console Color Attributes Constants (+3 more) + +### Community 6 - "Casino Sprite Atlas & Props" +Cohesion: 0.36 +Nodes (8): Casino Preview Icon, Casino Atlas Sprite Sheet, Bartender Shop Sprite, Blackjack Table Sprite, Roulette Table Sprite, Slot Machine Frame 0 Sprite, Slot Machine Frame 1 Sprite, Slot Machine Frame 2 Sprite + +### Community 7 - "Renderer Texture Slot Packer" +Cohesion: 0.53 +Nodes (5): cells(), main(), pack(), Pack project-local source art into the MASM renderer's 128px BGRA slots. Pyth, sprite() + +### Community 8 - "Cabaret Dancer Animation Sequence" +Cohesion: 0.80 +Nodes (5): Cabaret Loop Sprite Sheet, Dancer Animation Frame 0 Sprite, Dancer Animation Frame 1 Sprite, Dancer Animation Frame 2 Sprite, Dancer Animation Frame 3 Sprite + +### Community 9 - "3D Raycaster Environment Textures" +Cohesion: 0.83 +Nodes (4): Casino Carpet Floor Texture, Hell Wall Texture, Neon Strip Club Wall Texture, Velvet Wall Texture + +### Community 10 - "Release Verification Smoke Tests" +Cohesion: 0.83 +Nodes (3): Fail(), Pass(), Require-File() + +## Knowledge Gaps +- **14 isolated node(s):** `poker_portable Target`, `KAZIK Project Readme`, `Win Loss Draw Outcome Prefixes`, `Wine and CrossOver POSIX Support`, `Installer Path Traversal Guard` (+9 more) + These have ≤1 connection - possible missing edges or undocumented components. +- **4 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. + +## Suggested Questions +_Questions this graph is uniquely positioned to answer:_ + +- **Why does `AGENTS.md Project Instructions` connect `Core Project & MASM Instructions` to `Visual FX & Variables Spec`?** + _High betweenness centrality (0.049) - this node is a cross-community bridge._ +- **Why does `Feature Backlog and Game Ideas` connect `Architecture Constraints & Roadmap` to `Visual FX & Variables Spec`?** + _High betweenness centrality (0.042) - this node is a cross-community bridge._ +- **Why does `Security Architecture Notes` connect `Portable Build & Networking` to `Visual FX & Variables Spec`?** + _High betweenness centrality (0.039) - this node is a cross-community bridge._ +- **What connects `poker_portable Target`, `KAZIK Project Readme`, `Win Loss Draw Outcome Prefixes` to the rest of the system?** + _14 weakly-connected nodes found - possible documentation gaps or missing edges._ +- **Should `Portable Build & Networking` be split into smaller, more focused modules?** + _Cohesion score 0.1111111111111111 - nodes in this community are weakly interconnected._ \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/0d8891501bfba3c351f82dabe23d79f38b69415391a8513cdb928bd7c13476d9.json b/graphify-out/cache/ast/v0.9.18/0d8891501bfba3c351f82dabe23d79f38b69415391a8513cdb928bd7c13476d9.json new file mode 100644 index 0000000..a5cfc75 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/0d8891501bfba3c351f82dabe23d79f38b69415391a8513cdb928bd7c13476d9.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "label": "casino_portable.c", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "label": "platform_init()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L14", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_cleanup", "label": "platform_cleanup()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L26", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "label": "clear_screen()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L32", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_set_text_color", "label": "set_text_color()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L37", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "label": "read_masked_password()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L42", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_hash_password", "label": "hash_password()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L76", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_calc_account_signature", "label": "calc_account_signature()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L89", "_callable": true}, {"id": "accountdata", "label": "AccountData", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "E:\\DEPAI IN 3D\\KAZIK\\src_portable\\casino_portable.c"}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "label": "account_save()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L101", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "label": "account_register()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L114", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "label": "account_login()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L141", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_account_generate_transfer_key", "label": "account_generate_transfer_key()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L204", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "label": "account_import_transfer_key()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L211", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_upload", "label": "account_cloud_sync_upload()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L237", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "label": "account_cloud_sync_download()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L248", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_verify_peer_account_signature", "label": "verify_peer_account_signature()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L272", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "label": "render_lobby_browser()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L278", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "label": "host_room_flow()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L309", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "label": "net_lobby_menu()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L341", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "label": "play_umamusume()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L419", "_callable": true}, {"id": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "label": "main()", "file_type": "code", "source_file": "src_portable/casino_portable.c", "source_location": "L482", "_callable": true}], "edges": [{"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L7", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L14", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_cleanup", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L26", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L32", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_set_text_color", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L37", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L42", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_hash_password", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L76", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_calc_account_signature", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L89", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_calc_account_signature", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L89", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L101", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L101", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L114", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L114", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L141", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L141", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_generate_transfer_key", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L204", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_generate_transfer_key", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L204", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L211", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L211", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_upload", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L237", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_upload", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L237", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L248", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L248", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_verify_peer_account_signature", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L272", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L278", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L309", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L309", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L341", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L341", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L419", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "target": "accountdata", "relation": "references", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L419", "weight": 1.0, "context": "parameter_type"}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_c", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L482", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_calc_account_signature", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L108", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L115", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L122", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_hash_password", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L126", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_calc_account_signature", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L130", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L132", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L142", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L159", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L160", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_calc_account_signature", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L176", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_hash_password", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L188", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_hash_password", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L224", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_calc_account_signature", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L227", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L229", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_hash_password", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L258", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_calc_account_signature", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L262", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L264", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L279", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L344", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L349", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_verify_peer_account_signature", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L370", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_upload", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L387", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_generate_transfer_key", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L393", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L406", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L407", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L420", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L476", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L483", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L499", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L501", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L508", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L509", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_cleanup", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L511", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L518", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L529", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "target": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.c", "source_location": "L531", "weight": 1.0}], "raw_calls": [{"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "callee": "WSAStartup", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L17", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "callee": "MAKEWORD", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L17", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "callee": "GetStdHandle", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L18", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "callee": "GetConsoleMode", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L20", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "callee": "SetConsoleMode", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L21", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "callee": "srand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L23", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_init", "callee": "time", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L23", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_platform_cleanup", "callee": "WSACleanup", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L28", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L33", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_clear_screen", "callee": "fflush", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L34", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_set_text_color", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L38", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_set_text_color", "callee": "fflush", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L39", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "_getch", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L47", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "tcgetattr", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L50", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "tcsetattr", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L53", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L54", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "tcsetattr", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L55", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L62", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "fflush", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L63", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L67", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "fflush", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L68", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_read_masked_password", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L72", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "callee": "snprintf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L103", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "callee": "fopen", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L104", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "callee": "fwrite", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L109", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_save", "callee": "fclose", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L110", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L116", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L117", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L118", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L121", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "rand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L125", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L133", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L134", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L135", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_register", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L135", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L143", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L145", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L146", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "snprintf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L149", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "fopen", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L150", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L152", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L153", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L155", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L158", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "fread", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L166", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "fclose", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L167", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L170", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L171", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L171", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L178", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L179", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L180", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L180", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L185", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L190", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L191", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L192", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L197", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L198", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_login", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L199", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_generate_transfer_key", "callee": "snprintf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L208", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "callee": "sscanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L213", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L214", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L218", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L219", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "callee": "rand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L223", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_import_transfer_key", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L230", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_upload", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L238", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_upload", "callee": "Sleep", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L240", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_upload", "callee": "usleep", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L242", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_upload", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L244", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L249", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "callee": "Sleep", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L251", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "callee": "usleep", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L253", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "callee": "strncpy", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L256", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L265", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L266", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_account_cloud_sync_download", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L267", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L280", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L281", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L282", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L283", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L284", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L286", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L289", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L299", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L300", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L301", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L302", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L303", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L304", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L305", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_render_lobby_browser", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L306", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L311", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "memset", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L315", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "strncpy", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L317", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L319", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L320", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L321", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L323", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L326", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L328", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L331", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L332", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L336", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L337", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L338", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_host_room_flow", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L338", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L345", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L352", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L354", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L359", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L360", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "strcmp", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L361", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L362", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L363", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L363", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "rand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L368", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L369", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L371", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L372", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L372", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L377", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L378", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L379", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L379", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L381", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L382", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L382", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L388", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L389", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L389", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L394", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L395", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L396", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L397", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L397", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L403", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L404", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L405", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L408", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_net_lobby_menu", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L409", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L421", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L422", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L423", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L424", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L425", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L426", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L427", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L428", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L430", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L432", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L434", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L436", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L444", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "rand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L445", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "rand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L446", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "rand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L447", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "rand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L448", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "rand", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L449", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L453", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L454", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L455", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "Sleep", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L459", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "usleep", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L461", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L465", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L470", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L474", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L477", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L478", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_play_umamusume", "callee": "getchar", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L478", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L485", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L486", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L487", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L491", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L492", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L493", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L494", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L495", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L496", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L505", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L506", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L507", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L519", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L520", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L521", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L522", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L523", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L524", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "printf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L525", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_src_portable_casino_portable_main", "callee": "scanf", "is_member_call": false, "source_file": "src_portable/casino_portable.c", "source_location": "L526", "receiver": null}]} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/0e20ce5f0da50b080a252db92e146b04fa951fe188d0fda9be8c78bd42a8bcbc.json b/graphify-out/cache/ast/v0.9.18/0e20ce5f0da50b080a252db92e146b04fa951fe188d0fda9be8c78bd42a8bcbc.json new file mode 100644 index 0000000..fe77afc --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/0e20ce5f0da50b080a252db92e146b04fa951fe188d0fda9be8c78bd42a8bcbc.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_release_smoke_check_ps1", "label": "release_smoke_check.ps1", "file_type": "code", "source_file": "tools/release_smoke_check.ps1", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_release_smoke_check_pass", "label": "Pass()", "file_type": "code", "source_file": "tools/release_smoke_check.ps1", "source_location": "L7"}, {"id": "e_depai_in_3d_kazik_tools_release_smoke_check_fail", "label": "Fail()", "file_type": "code", "source_file": "tools/release_smoke_check.ps1", "source_location": "L11"}, {"id": "e_depai_in_3d_kazik_tools_release_smoke_check_require_file", "label": "Require-File()", "file_type": "code", "source_file": "tools/release_smoke_check.ps1", "source_location": "L15"}], "edges": [{"source": "e_depai_in_3d_kazik_tools_release_smoke_check_ps1", "target": "e_depai_in_3d_kazik_tools_release_smoke_check_pass", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/release_smoke_check.ps1", "source_location": "L7", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_release_smoke_check_ps1", "target": "e_depai_in_3d_kazik_tools_release_smoke_check_fail", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/release_smoke_check.ps1", "source_location": "L11", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_release_smoke_check_ps1", "target": "e_depai_in_3d_kazik_tools_release_smoke_check_require_file", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/release_smoke_check.ps1", "source_location": "L15", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_release_smoke_check_require_file", "target": "e_depai_in_3d_kazik_tools_release_smoke_check_fail", "relation": "calls", "confidence": "EXTRACTED", "source_file": "tools/release_smoke_check.ps1", "source_location": "L18", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_release_smoke_check_require_file", "target": "e_depai_in_3d_kazik_tools_release_smoke_check_pass", "relation": "calls", "confidence": "EXTRACTED", "source_file": "tools/release_smoke_check.ps1", "source_location": "L20", "weight": 1.0}], "raw_calls": [{"caller_nid": "e_depai_in_3d_kazik_tools_release_smoke_check_pass", "callee": "Write-Host", "is_member_call": false, "source_file": "tools/release_smoke_check.ps1", "source_location": "L8"}, {"caller_nid": "e_depai_in_3d_kazik_tools_release_smoke_check_require_file", "callee": "Join-Path", "is_member_call": false, "source_file": "tools/release_smoke_check.ps1", "source_location": "L16"}, {"caller_nid": "e_depai_in_3d_kazik_tools_release_smoke_check_require_file", "callee": "Test-Path", "is_member_call": false, "source_file": "tools/release_smoke_check.ps1", "source_location": "L17"}]} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/138dda071059ae037e9972bdbc63d21f3a33a18ca102faa52fb8cac0b644be35.json b/graphify-out/cache/ast/v0.9.18/138dda071059ae037e9972bdbc63d21f3a33a18ca102faa52fb8cac0b644be35.json new file mode 100644 index 0000000..91c60a9 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/138dda071059ae037e9972bdbc63d21f3a33a18ca102faa52fb8cac0b644be35.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "label": "platform_code.inc", "file_type": "code", "source_file": "src_graphics/platform_code.inc", "source_location": "L1"}], "edges": [{"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "dword", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "umsg", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "event_key_down", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "cmp", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "event_fullscreen", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "event_key_up", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "event_focus_lost", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "event_erase", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "event_paint", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wm_close", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wm_destroy", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "hwnd", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wp", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "ecx", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "event_done", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "mov", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "edi", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "keys3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "eax", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "beginpaint", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "paint3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "endpaint", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "getmodulefilenamea", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "directory3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "esi", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "test", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "path_found", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "path_scan", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "setcurrentdirectorya", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "sztexturesrelpath", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "path_done", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "getmodulehandlea", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "user32name3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "dpiname3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "h3dinst", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wc3d_hinstance", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "loadicona", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wc3d_hicon", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wc3d_hiconsm", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "loadcursora", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wc3d_hcursor", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wc3d_cbsize", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "c3d_wndclassex_mov_wc3d_style", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "wc3d_lpfnwndproc", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "casino3dwndproc_mov_wc3d_lpszclassname", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "sz3dclassname", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "bmi3d_bmiheader_bisize", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "c3d_bitmapinfoheader_mov_bmi3d_bmiheader_biwidth", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "screen_w_mov_bmi3d_bmiheader_biheight", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "bmi3d_bmiheader_biplanes", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "bmi3d_bmiheader_bibitcount", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "bmi3d_bmiheader_bisizeimage", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "getsystemmetrics", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "widthpx", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "heightpx", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "edx", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "adjustwindowrectex", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "clientrect3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "ws_overlappedwindow", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L109", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "createfilea", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "assets_failed", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "readfile", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "ebx", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "texturesbuffer", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "count", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "closehandle", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "messageboxa", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "h3dwnd", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "textmissing3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "sz3dwindowtitle", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "getclientrect", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L193", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "fullscreen3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L268", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "restore_window", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L268", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "savedrect3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L268", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "getmonitorinfoa", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L268", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "monitor3d", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L268", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "setwindowlonga", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L268", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "playerangle", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L296", "weight": 1.0, "context": "import"}, {"source": "e_depai_in_3d_kazik_src_graphics_platform_code_inc", "target": "tablecos", "relation": "imports", "confidence": "EXTRACTED", "source_file": "src_graphics/platform_code.inc", "source_location": "L296", "weight": 1.0, "context": "import"}], "input_tokens": 0, "output_tokens": 0, "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/17cce3e69a6245d4d8d4d48847de44d32b433568a6007f81701b2f9ee3ce0455.json b/graphify-out/cache/ast/v0.9.18/17cce3e69a6245d4d8d4d48847de44d32b433568a6007f81701b2f9ee3ce0455.json new file mode 100644 index 0000000..d116e6e --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/17cce3e69a6245d4d8d4d48847de44d32b433568a6007f81701b2f9ee3ce0455.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_casino3d_inc", "label": "casino3d.inc", "file_type": "code", "source_file": "casino3d.inc", "source_location": "L1"}], "edges": [], "input_tokens": 0, "output_tokens": 0, "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/1ad632faebe559e783b0064c2338a3678043ddd3ae85cdaa79f1c27f00d6fdcf.json b/graphify-out/cache/ast/v0.9.18/1ad632faebe559e783b0064c2338a3678043ddd3ae85cdaa79f1c27f00d6fdcf.json new file mode 100644 index 0000000..c4371b0 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/1ad632faebe559e783b0064c2338a3678043ddd3ae85cdaa79f1c27f00d6fdcf.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_build_all_3d_py", "label": "build_all_3d.py", "file_type": "code", "source_file": "tools/build_all_3d.py", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_build_all_3d_a", "label": "a()", "file_type": "code", "source_file": "tools/build_all_3d.py", "source_location": "L7", "_callable": true}], "edges": [{"source": "e_depai_in_3d_kazik_tools_build_all_3d_py", "target": "sys", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/build_all_3d.py", "source_location": "L2", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_all_3d_py", "target": "e_depai_in_3d_kazik_tools_build_all_3d_a", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_all_3d.py", "source_location": "L7", "weight": 1.0}], "raw_calls": [{"caller_nid": "e_depai_in_3d_kazik_tools_build_all_3d_a", "callee": "append", "is_member_call": true, "source_file": "tools/build_all_3d.py", "source_location": "L8", "receiver": "code_chunks"}]} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/260c7d561bd484ebf4a0b7f05ce9e48f9b4a7f701ce3500521befbc805a35c9a.json b/graphify-out/cache/ast/v0.9.18/260c7d561bd484ebf4a0b7f05ce9e48f9b4a7f701ce3500521befbc805a35c9a.json new file mode 100644 index 0000000..abfa4bd --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/260c7d561bd484ebf4a0b7f05ce9e48f9b4a7f701ce3500521befbc805a35c9a.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_font8x8_inc", "label": "font8x8.inc", "file_type": "code", "source_file": "font8x8.inc", "source_location": "L1"}], "edges": [], "input_tokens": 0, "output_tokens": 0, "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/47fa3293a06711be74c2f14c52bd460dcd78bb98289e988d575ab8e9e01ad54c.json b/graphify-out/cache/ast/v0.9.18/47fa3293a06711be74c2f14c52bd460dcd78bb98289e988d575ab8e9e01ad54c.json new file mode 100644 index 0000000..ccd4c2b --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/47fa3293a06711be74c2f14c52bd460dcd78bb98289e988d575ab8e9e01ad54c.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_generate_math_and_map_py", "label": "generate_math_and_map.py", "file_type": "code", "source_file": "tools/generate_math_and_map.py", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_generate_math_and_map_float_to_fp", "label": "float_to_fp()", "file_type": "code", "source_file": "tools/generate_math_and_map.py", "source_location": "L7", "_callable": true}], "edges": [{"source": "e_depai_in_3d_kazik_tools_generate_math_and_map_py", "target": "math", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/generate_math_and_map.py", "source_location": "L1", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_generate_math_and_map_py", "target": "e_depai_in_3d_kazik_tools_generate_math_and_map_float_to_fp", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/generate_math_and_map.py", "source_location": "L7", "weight": 1.0}], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/4bf4afc73df542d7e831d4468cda9e2112319bdaf8c89ea20b4c49ac55520a2a.json b/graphify-out/cache/ast/v0.9.18/4bf4afc73df542d7e831d4468cda9e2112319bdaf8c89ea20b4c49ac55520a2a.json new file mode 100644 index 0000000..4ad242b --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/4bf4afc73df542d7e831d4468cda9e2112319bdaf8c89ea20b4c49ac55520a2a.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_src_graphics_renderer_inc", "label": "renderer.inc", "file_type": "code", "source_file": "src_graphics/renderer.inc", "source_location": "L1"}], "edges": [], "input_tokens": 0, "output_tokens": 0, "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/4ededd1f62dfbf46792345c3be39b7d8b349dafb88ee476878ac7d8e4e95fcdb.json b/graphify-out/cache/ast/v0.9.18/4ededd1f62dfbf46792345c3be39b7d8b349dafb88ee476878ac7d8e4e95fcdb.json new file mode 100644 index 0000000..e4b1a9f --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/4ededd1f62dfbf46792345c3be39b7d8b349dafb88ee476878ac7d8e4e95fcdb.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_casino3d_data_inc", "label": "casino3d_data.inc", "file_type": "code", "source_file": "casino3d_data.inc", "source_location": "L1"}], "edges": [], "input_tokens": 0, "output_tokens": 0, "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/531a442e9e0c8f0c7c6ac0060e327d86319cf01167962564fddb4ef445029606.json b/graphify-out/cache/ast/v0.9.18/531a442e9e0c8f0c7c6ac0060e327d86319cf01167962564fddb4ef445029606.json new file mode 100644 index 0000000..5b19e10 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/531a442e9e0c8f0c7c6ac0060e327d86319cf01167962564fddb4ef445029606.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "label": "build_casino_assets.py", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "label": "clean_chromakey_black()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L14", "_callable": true}, {"id": "image", "label": "Image", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "E:\\DEPAI IN 3D\\KAZIK\\tools\\build_casino_assets.py"}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "label": "clean_chromakey_white()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L25", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "label": "img_to_raw_dwords()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L35", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_make_wood_wall", "label": "make_wood_wall()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L46", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_make_carpet_floor", "label": "make_carpet_floor()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L60", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_make_ceiling_tex", "label": "make_ceiling_tex()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L80", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_make_atm", "label": "make_atm()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L101", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "label": "make_backroom_table()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L120", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "label": "main()", "file_type": "code", "source_file": "tools/build_casino_assets.py", "source_location": "L140", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_casino_assets_rationale_15", "label": "Resize with NEAREST so pixels never blend with chromakey!", "file_type": "rationale", "source_file": "tools/build_casino_assets.py", "source_location": "L15"}], "edges": [{"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "os", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L1", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "pathlib", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L2", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "pil", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L3", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L14", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "target": "image", "relation": "references", "context": "parameter_type", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L14", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "target": "image", "relation": "references", "context": "return_type", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L14", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L25", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "target": "image", "relation": "references", "context": "parameter_type", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L25", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "target": "image", "relation": "references", "context": "return_type", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L25", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L35", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "target": "image", "relation": "references", "context": "parameter_type", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L35", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_wood_wall", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L46", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_carpet_floor", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L60", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_ceiling_tex", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L80", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_atm", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L101", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L120", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_py", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L140", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L148", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_wood_wall", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L150", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_carpet_floor", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L166", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_ceiling_tex", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L177", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L190", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L208", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_atm", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L223", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L226", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_casino_assets_rationale_15", "target": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "tools/build_casino_assets.py", "source_location": "L15", "weight": 1.0}], "raw_calls": [{"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "callee": "convert", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L16", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "callee": "resize", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L16", "receiver": "img"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_casino_assets.py", "source_location": "L16"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_casino_assets.py", "source_location": "L16"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "callee": "load", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L17", "receiver": "img"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L18"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L19"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_black", "callee": "CHROMAKEY", "is_member_call": false, "indirect": true, "context": "assignment", "source_file": "tools/build_casino_assets.py", "source_location": "L22"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "callee": "convert", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L26", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "callee": "resize", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L26", "receiver": "img"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_casino_assets.py", "source_location": "L26"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_casino_assets.py", "source_location": "L26"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "callee": "load", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L27", "receiver": "img"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L28"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L29"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_clean_chromakey_white", "callee": "CHROMAKEY", "is_member_call": false, "indirect": true, "context": "assignment", "source_file": "tools/build_casino_assets.py", "source_location": "L32"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "convert", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L36", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "resize", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L36", "receiver": "img"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_casino_assets.py", "source_location": "L36"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_casino_assets.py", "source_location": "L36"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "bytearray", "is_member_call": false, "source_file": "tools/build_casino_assets.py", "source_location": "L37", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "load", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L38", "receiver": "img"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L39"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L40"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_img_to_raw_dwords", "callee": "extend", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L43", "receiver": "data"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_wood_wall", "callee": "bytearray", "is_member_call": false, "source_file": "tools/build_casino_assets.py", "source_location": "L47", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_wood_wall", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L48"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_wood_wall", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L49"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_wood_wall", "callee": "extend", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L57", "receiver": "data"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_carpet_floor", "callee": "bytearray", "is_member_call": false, "source_file": "tools/build_casino_assets.py", "source_location": "L61", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_carpet_floor", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L62"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_carpet_floor", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L63"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_carpet_floor", "callee": "extend", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L77", "receiver": "data"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_ceiling_tex", "callee": "bytearray", "is_member_call": false, "source_file": "tools/build_casino_assets.py", "source_location": "L81", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_ceiling_tex", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L82"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_ceiling_tex", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L83"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_ceiling_tex", "callee": "extend", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L98", "receiver": "data"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_atm", "callee": "bytearray", "is_member_call": false, "source_file": "tools/build_casino_assets.py", "source_location": "L102", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_atm", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L103"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_atm", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L104"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_atm", "callee": "CHROMAKEY", "is_member_call": false, "indirect": true, "context": "assignment", "source_file": "tools/build_casino_assets.py", "source_location": "L106"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_atm", "callee": "extend", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L117", "receiver": "data"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "callee": "bytearray", "is_member_call": false, "source_file": "tools/build_casino_assets.py", "source_location": "L121", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L122"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "callee": "TEX_SIZE", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L123"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "callee": "CHROMAKEY", "is_member_call": false, "indirect": true, "context": "assignment", "source_file": "tools/build_casino_assets.py", "source_location": "L125"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "callee": "CHROMAKEY", "is_member_call": false, "indirect": true, "context": "assignment", "source_file": "tools/build_casino_assets.py", "source_location": "L136"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_make_backroom_table", "callee": "extend", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L137", "receiver": "data"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "mkdir", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L141", "receiver": "OUT_DIR"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L146", "receiver": "velvet_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L154", "receiver": "neon_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L162", "receiver": "carpet_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L170", "receiver": "hell_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L184", "receiver": "dancer_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "convert", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L185", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "crop", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L189", "receiver": "sheet"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L195", "receiver": "slot_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "convert", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L196", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "crop", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L200", "receiver": "sheet"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L206", "receiver": "bj_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L212", "receiver": "roul_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "exists", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L218", "receiver": "shop_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "OUT_BIN", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L230"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "TOTAL_SLOTS", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_casino_assets.py", "source_location": "L231"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "get", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L232", "receiver": "atlas"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "get", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L232", "receiver": "atlas"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "ljust", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L234", "receiver": "data"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "write", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L235", "receiver": "f"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_casino_assets_main", "callee": "stat", "is_member_call": true, "source_file": "tools/build_casino_assets.py", "source_location": "L237", "receiver": "OUT_BIN"}]} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/5f3f8a091f85d4da2b6a9052a2747b45b06443907eb422c671c5f4ccbcf71968.json b/graphify-out/cache/ast/v0.9.18/5f3f8a091f85d4da2b6a9052a2747b45b06443907eb422c671c5f4ccbcf71968.json new file mode 100644 index 0000000..6835fe7 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/5f3f8a091f85d4da2b6a9052a2747b45b06443907eb422c671c5f4ccbcf71968.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_generate_unified_casino3d_py", "label": "generate_unified_casino3d.py", "file_type": "code", "source_file": "tools/generate_unified_casino3d.py", "source_location": "L1"}], "edges": [{"source": "e_depai_in_3d_kazik_tools_generate_unified_casino3d_py", "target": "sys", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/generate_unified_casino3d.py", "source_location": "L3", "weight": 1.0}], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/60e4e6059cb5be35a945d8b9587c012aeb99180bbc671d58513b58b454e7452d.json b/graphify-out/cache/ast/v0.9.18/60e4e6059cb5be35a945d8b9587c012aeb99180bbc671d58513b58b454e7452d.json new file mode 100644 index 0000000..6d2864e --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/60e4e6059cb5be35a945d8b9587c012aeb99180bbc671d58513b58b454e7452d.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_build_graphics_assets_py", "label": "build_graphics_assets.py", "file_type": "code", "source_file": "tools/build_graphics_assets.py", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_build_graphics_assets_cells", "label": "cells()", "file_type": "code", "source_file": "tools/build_graphics_assets.py", "source_location": "L15", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_graphics_assets_sprite", "label": "sprite()", "file_type": "code", "source_file": "tools/build_graphics_assets.py", "source_location": "L22", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_graphics_assets_pack", "label": "pack()", "file_type": "code", "source_file": "tools/build_graphics_assets.py", "source_location": "L32", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "label": "main()", "file_type": "code", "source_file": "tools/build_graphics_assets.py", "source_location": "L41", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_build_graphics_assets_rationale_1", "label": "Pack project-local source art into the MASM renderer's 128px BGRA slots. Pyth", "file_type": "rationale", "source_file": "tools/build_graphics_assets.py", "source_location": "L1"}], "edges": [{"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_py", "target": "pathlib", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L6", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_py", "target": "pil", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L7", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_py", "target": "e_depai_in_3d_kazik_tools_build_graphics_assets_cells", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L15", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_py", "target": "e_depai_in_3d_kazik_tools_build_graphics_assets_sprite", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L22", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_py", "target": "e_depai_in_3d_kazik_tools_build_graphics_assets_pack", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L32", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_py", "target": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L41", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "target": "e_depai_in_3d_kazik_tools_build_graphics_assets_cells", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L50", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "target": "e_depai_in_3d_kazik_tools_build_graphics_assets_sprite", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L54", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "target": "e_depai_in_3d_kazik_tools_build_graphics_assets_pack", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L62", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_build_graphics_assets_rationale_1", "target": "e_depai_in_3d_kazik_tools_build_graphics_assets_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "tools/build_graphics_assets.py", "source_location": "L1", "weight": 1.0}], "raw_calls": [{"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_cells", "callee": "convert", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L16", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_cells", "callee": "crop", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L17", "receiver": "image"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_sprite", "callee": "resize", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L25", "receiver": "cell"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_sprite", "callee": "new", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L27", "receiver": "Image"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_sprite", "callee": "SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_graphics_assets.py", "source_location": "L27"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_sprite", "callee": "SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_graphics_assets.py", "source_location": "L27"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_sprite", "callee": "alpha_composite", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L28", "receiver": "out"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_pack", "callee": "bytearray", "is_member_call": false, "source_file": "tools/build_graphics_assets.py", "source_location": "L33", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_pack", "callee": "getdata", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L34", "receiver": "image"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_pack", "callee": "CHROMA", "is_member_call": false, "indirect": true, "context": "assignment", "source_file": "tools/build_graphics_assets.py", "source_location": "L36"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_pack", "callee": "extend", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L37", "receiver": "result"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "read_bytes", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L42", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "SLOTS", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/build_graphics_assets.py", "source_location": "L45"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "frombytes", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L46", "receiver": "Image"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "putalpha", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L48", "receiver": "tile"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "append", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L49", "receiver": "textures"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "resize", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L49", "receiver": "tile"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_graphics_assets.py", "source_location": "L49"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "SIZE", "is_member_call": false, "indirect": true, "context": "collection", "source_file": "tools/build_graphics_assets.py", "source_location": "L49"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "items", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L55", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "putalpha", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L59", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "items", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L60", "receiver": "sprites"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "join", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L62", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "write_bytes", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L65", "receiver": "target"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "new", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L66", "receiver": "Image"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "alpha_composite", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L68", "receiver": "preview"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "save", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L69", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "convert", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L69", "receiver": "preview"}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "resize", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L70", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_build_graphics_assets_main", "callee": "save", "is_member_call": true, "source_file": "tools/build_graphics_assets.py", "source_location": "L72", "receiver": null}]} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/75c60a1a5818b18c7cfa072c4708a27bf2d7320e67804d80b42835798ca957c5.json b/graphify-out/cache/ast/v0.9.18/75c60a1a5818b18c7cfa072c4708a27bf2d7320e67804d80b42835798ca957c5.json new file mode 100644 index 0000000..4ab020f --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/75c60a1a5818b18c7cfa072c4708a27bf2d7320e67804d80b42835798ca957c5.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_simulate_render_py", "label": "simulate_render.py", "file_type": "code", "source_file": "tools/simulate_render.py", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_simulate_render_get_tex_pixel", "label": "get_tex_pixel()", "file_type": "code", "source_file": "tools/simulate_render.py", "source_location": "L40", "_callable": true}], "edges": [{"source": "e_depai_in_3d_kazik_tools_simulate_render_py", "target": "math", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/simulate_render.py", "source_location": "L2", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_simulate_render_py", "target": "struct", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/simulate_render.py", "source_location": "L3", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_simulate_render_py", "target": "pil", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/simulate_render.py", "source_location": "L4", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_simulate_render_py", "target": "re", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/simulate_render.py", "source_location": "L19", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_simulate_render_py", "target": "e_depai_in_3d_kazik_tools_simulate_render_get_tex_pixel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/simulate_render.py", "source_location": "L40", "weight": 1.0}], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/7627c17a45c6dc182aa6d5405eb8d8bf6242e0a79147b3c96085a23c99422493.json b/graphify-out/cache/ast/v0.9.18/7627c17a45c6dc182aa6d5405eb8d8bf6242e0a79147b3c96085a23c99422493.json new file mode 100644 index 0000000..588b74a --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/7627c17a45c6dc182aa6d5405eb8d8bf6242e0a79147b3c96085a23c99422493.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_preview_dbd_hook_py", "label": "preview_dbd_hook.py", "file_type": "code", "source_file": "tools/preview_dbd_hook.py", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_preview_dbd_hook_place_window", "label": "place_window()", "file_type": "code", "source_file": "tools/preview_dbd_hook.py", "source_location": "L12", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "label": "main()", "file_type": "code", "source_file": "tools/preview_dbd_hook.py", "source_location": "L27", "_callable": true}], "edges": [{"source": "e_depai_in_3d_kazik_tools_preview_dbd_hook_py", "target": "pathlib", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_dbd_hook.py", "source_location": "L1", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_dbd_hook_py", "target": "ctypes", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_dbd_hook.py", "source_location": "L2", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_dbd_hook_py", "target": "os", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_dbd_hook.py", "source_location": "L3", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_dbd_hook_py", "target": "sys", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_dbd_hook.py", "source_location": "L4", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_dbd_hook_py", "target": "time", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_dbd_hook.py", "source_location": "L5", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_dbd_hook_py", "target": "e_depai_in_3d_kazik_tools_preview_dbd_hook_place_window", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/preview_dbd_hook.py", "source_location": "L12", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_dbd_hook_py", "target": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/preview_dbd_hook.py", "source_location": "L27", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "target": "e_depai_in_3d_kazik_tools_preview_dbd_hook_place_window", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/preview_dbd_hook.py", "source_location": "L39", "weight": 1.0}], "raw_calls": [{"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_place_window", "callee": "GetConsoleWindow", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L15", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_place_window", "callee": "GetSystemMetrics", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L17", "receiver": "user32"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_place_window", "callee": "SetWindowPos", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L22", "receiver": "user32"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "resolve", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L28", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "Path", "is_member_call": false, "source_file": "tools/preview_dbd_hook.py", "source_location": "L28", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "__file__", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/preview_dbd_hook.py", "source_location": "L28"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "exists", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L31", "receiver": "path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "exists", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L35", "receiver": "stop_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "unlink", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L36", "receiver": "stop_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "system", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L38", "receiver": "os"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "split", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L40", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "FRAME_SEPARATOR", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/preview_dbd_hook.py", "source_location": "L40"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "read_text", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L40", "receiver": "path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "exists", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L42", "receiver": "stop_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "exists", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L44", "receiver": "stop_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "system", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L46", "receiver": "os"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "write", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L47", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "flush", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L48", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "sleep", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L49", "receiver": "time"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "FRAME_DELAY", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/preview_dbd_hook.py", "source_location": "L49"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "write", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L51", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "flush", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L52", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "exists", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L53", "receiver": "stop_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_dbd_hook_main", "callee": "unlink", "is_member_call": true, "source_file": "tools/preview_dbd_hook.py", "source_location": "L54", "receiver": "stop_path"}]} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/7b7850caf79296f29325be3bb73d1e5ab22f7b02fc200f7450304d888b68bbf1.json b/graphify-out/cache/ast/v0.9.18/7b7850caf79296f29325be3bb73d1e5ab22f7b02fc200f7450304d888b68bbf1.json new file mode 100644 index 0000000..0516580 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/7b7850caf79296f29325be3bb73d1e5ab22f7b02fc200f7450304d888b68bbf1.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_make_casino3d_py", "label": "make_casino3d.py", "file_type": "code", "source_file": "tools/make_casino3d.py", "source_location": "L1"}], "edges": [], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/7f720d61b49719534794328d3012acd593e9c8627cbd6520c573c8c5d9435d93.json b/graphify-out/cache/ast/v0.9.18/7f720d61b49719534794328d3012acd593e9c8627cbd6520c573c8c5d9435d93.json new file mode 100644 index 0000000..5178571 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/7f720d61b49719534794328d3012acd593e9c8627cbd6520c573c8c5d9435d93.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_src_graphics_platform_data_inc", "label": "platform_data.inc", "file_type": "code", "source_file": "src_graphics/platform_data.inc", "source_location": "L1"}], "edges": [], "input_tokens": 0, "output_tokens": 0, "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/96a2e9b3fe3a64c41bfd8ced2675141be58d38619b85c57183a0c5a9ea69d3a3.json b/graphify-out/cache/ast/v0.9.18/96a2e9b3fe3a64c41bfd8ced2675141be58d38619b85c57183a0c5a9ea69d3a3.json new file mode 100644 index 0000000..a1d6673 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/96a2e9b3fe3a64c41bfd8ced2675141be58d38619b85c57183a0c5a9ea69d3a3.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_build_engine_py", "label": "build_engine.py", "file_type": "code", "source_file": "tools/build_engine.py", "source_location": "L1"}], "edges": [{"source": "e_depai_in_3d_kazik_tools_build_engine_py", "target": "sys", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/build_engine.py", "source_location": "L2", "weight": 1.0}], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/af3c3463623a9dc11fb58dc537a2a0249ea08f2b4ee51dba135bb416c69e8d9f.json b/graphify-out/cache/ast/v0.9.18/af3c3463623a9dc11fb58dc537a2a0249ea08f2b4ee51dba135bb416c69e8d9f.json new file mode 100644 index 0000000..3df1774 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/af3c3463623a9dc11fb58dc537a2a0249ea08f2b4ee51dba135bb416c69e8d9f.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_generate_casino3d_py", "label": "generate_casino3d.py", "file_type": "code", "source_file": "tools/generate_casino3d.py", "source_location": "L1"}], "edges": [], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/b70c30af76f1f519b55093958a9931630d1435baf8235432b0402eb26a5089c4.json b/graphify-out/cache/ast/v0.9.18/b70c30af76f1f519b55093958a9931630d1435baf8235432b0402eb26a5089c4.json new file mode 100644 index 0000000..9ec1a71 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/b70c30af76f1f519b55093958a9931630d1435baf8235432b0402eb26a5089c4.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_preview_intro_py", "label": "preview_intro.py", "file_type": "code", "source_file": "tools/preview_intro.py", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_preview_intro_main", "label": "main()", "file_type": "code", "source_file": "tools/preview_intro.py", "source_location": "L12", "_callable": true}], "edges": [{"source": "e_depai_in_3d_kazik_tools_preview_intro_py", "target": "pathlib", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_intro.py", "source_location": "L1", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_intro_py", "target": "os", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_intro.py", "source_location": "L2", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_intro_py", "target": "sys", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_intro.py", "source_location": "L3", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_intro_py", "target": "msvcrt", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_intro.py", "source_location": "L4", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_intro_py", "target": "time", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_intro.py", "source_location": "L5", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_intro_py", "target": "e_depai_in_3d_kazik_tools_preview_intro_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/preview_intro.py", "source_location": "L12", "weight": 1.0}], "raw_calls": [{"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "resolve", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L13", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "Path", "is_member_call": false, "source_file": "tools/preview_intro.py", "source_location": "L13", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "__file__", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/preview_intro.py", "source_location": "L13"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "exists", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L15", "receiver": "intro_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "system", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L19", "receiver": "os"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "split", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L20", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "FRAME_SEPARATOR", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/preview_intro.py", "source_location": "L20"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "read_text", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L20", "receiver": "intro_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "replace", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L24", "receiver": "frame"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "replace", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L29", "receiver": "frame"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "write", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L31", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "flush", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L32", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "time", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L33", "receiver": "time"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "time", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L34", "receiver": "time"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "kbhit", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L35", "receiver": "msvcrt"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "getwch", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L36", "receiver": "msvcrt"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "sleep", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L39", "receiver": "time"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "write", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L43", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "flush", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L44", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "time", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L45", "receiver": "time"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "time", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L46", "receiver": "time"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "kbhit", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L47", "receiver": "msvcrt"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "getwch", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L48", "receiver": "msvcrt"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "sleep", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L51", "receiver": "time"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "write", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L53", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_intro_main", "callee": "flush", "is_member_call": true, "source_file": "tools/preview_intro.py", "source_location": "L54", "receiver": null}]} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/c24892bb1085007fd9e480f1f4c9edd6ba5dec55e03222df428abb5a36330150.json b/graphify-out/cache/ast/v0.9.18/c24892bb1085007fd9e480f1f4c9edd6ba5dec55e03222df428abb5a36330150.json new file mode 100644 index 0000000..a2b0441 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/c24892bb1085007fd9e480f1f4c9edd6ba5dec55e03222df428abb5a36330150.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_generate_font_py", "label": "generate_font.py", "file_type": "code", "source_file": "tools/generate_font.py", "source_location": "L1"}], "edges": [{"source": "e_depai_in_3d_kazik_tools_generate_font_py", "target": "pil", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/generate_font.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/d31fe1e6e7ffc320f0f384a1d9140a304b7e571cea3e36fc5357728eafb44cf3.json b/graphify-out/cache/ast/v0.9.18/d31fe1e6e7ffc320f0f384a1d9140a304b7e571cea3e36fc5357728eafb44cf3.json new file mode 100644 index 0000000..f4bde6c --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/d31fe1e6e7ffc320f0f384a1d9140a304b7e571cea3e36fc5357728eafb44cf3.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_preview_hakari_py", "label": "preview_hakari.py", "file_type": "code", "source_file": "tools/preview_hakari.py", "source_location": "L1"}, {"id": "e_depai_in_3d_kazik_tools_preview_hakari_enable_ansi", "label": "enable_ansi()", "file_type": "code", "source_file": "tools/preview_hakari.py", "source_location": "L12", "_callable": true}, {"id": "e_depai_in_3d_kazik_tools_preview_hakari_main", "label": "main()", "file_type": "code", "source_file": "tools/preview_hakari.py", "source_location": "L18", "_callable": true}], "edges": [{"source": "e_depai_in_3d_kazik_tools_preview_hakari_py", "target": "pathlib", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_hakari.py", "source_location": "L1", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_hakari_py", "target": "os", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_hakari.py", "source_location": "L2", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_hakari_py", "target": "sys", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_hakari.py", "source_location": "L3", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_hakari_py", "target": "time", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_hakari.py", "source_location": "L4", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_hakari_py", "target": "winsound", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "tools/preview_hakari.py", "source_location": "L5", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_hakari_py", "target": "e_depai_in_3d_kazik_tools_preview_hakari_enable_ansi", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/preview_hakari.py", "source_location": "L12", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_hakari_py", "target": "e_depai_in_3d_kazik_tools_preview_hakari_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tools/preview_hakari.py", "source_location": "L18", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_tools_preview_hakari_main", "target": "e_depai_in_3d_kazik_tools_preview_hakari_enable_ansi", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "tools/preview_hakari.py", "source_location": "L29", "weight": 1.0}], "raw_calls": [{"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_enable_ansi", "callee": "system", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L15", "receiver": "os"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "resolve", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L19", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "Path", "is_member_call": false, "source_file": "tools/preview_hakari.py", "source_location": "L19", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "__file__", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/preview_hakari.py", "source_location": "L19"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "exists", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L23", "receiver": "dance_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "split", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L27", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "FRAME_SEPARATOR", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/preview_hakari.py", "source_location": "L27"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "read_text", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L27", "receiver": "dance_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "exists", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L30", "receiver": "sound_path"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "PlaySound", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L31", "receiver": "winsound"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "system", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L35", "receiver": "os"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "write", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L36", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "flush", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L37", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "sleep", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L38", "receiver": "time"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "FRAME_DELAY", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "tools/preview_hakari.py", "source_location": "L38"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "PlaySound", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L40", "receiver": "winsound"}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "write", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L41", "receiver": null}, {"caller_nid": "e_depai_in_3d_kazik_tools_preview_hakari_main", "callee": "flush", "is_member_call": true, "source_file": "tools/preview_hakari.py", "source_location": "L42", "receiver": null}]} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/e0ca915f66cb272addb0bca6b7dd98f496a43319d6bb108033c4fab1175c67b6.json b/graphify-out/cache/ast/v0.9.18/e0ca915f66cb272addb0bca6b7dd98f496a43319d6bb108033c4fab1175c67b6.json new file mode 100644 index 0000000..7a2a4d7 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/e0ca915f66cb272addb0bca6b7dd98f496a43319d6bb108033c4fab1175c67b6.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_patch_poker_asm_py", "label": "patch_poker_asm.py", "file_type": "code", "source_file": "tools/patch_poker_asm.py", "source_location": "L1"}], "edges": [], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/e92dd483b153ada4a22fb3ccbb73cc0f57af765057576eede971308c4eebf950.json b/graphify-out/cache/ast/v0.9.18/e92dd483b153ada4a22fb3ccbb73cc0f57af765057576eede971308c4eebf950.json new file mode 100644 index 0000000..a64ac59 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/e92dd483b153ada4a22fb3ccbb73cc0f57af765057576eede971308c4eebf950.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_tools_build_graphics_ps1", "label": "build_graphics.ps1", "file_type": "code", "source_file": "tools/build_graphics.ps1", "source_location": "L1"}], "edges": [], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/ast/v0.9.18/f27d1ca5e032eebb68a1df01fd317f63989558728f1d1ddb12bc251985032513.json b/graphify-out/cache/ast/v0.9.18/f27d1ca5e032eebb68a1df01fd317f63989558728f1d1ddb12bc251985032513.json new file mode 100644 index 0000000..3f35991 --- /dev/null +++ b/graphify-out/cache/ast/v0.9.18/f27d1ca5e032eebb68a1df01fd317f63989558728f1d1ddb12bc251985032513.json @@ -0,0 +1 @@ +{"nodes": [{"id": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "label": "casino_portable.h", "file_type": "code", "source_file": "src_portable/casino_portable.h", "source_location": "L1"}], "edges": [{"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "stdio", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L9", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "stdlib", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L10", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "string", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L11", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "stdint", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L12", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "stdbool", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L13", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "time", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L14", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "winsock2", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L17", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "ws2tcpip", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L18", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "windows", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L19", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "conio", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L20", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "unistd", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L26", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "types", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L27", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "socket", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L28", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "in", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L29", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "inet", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L30", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "netdb", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L31", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "termios", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L32", "weight": 1.0}, {"source": "e_depai_in_3d_kazik_src_portable_casino_portable_h", "target": "select", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src_portable/casino_portable.h", "source_location": "L33", "weight": 1.0}], "raw_calls": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/016158cc8adad8160340452b77cce6664af577eef41c272ca17c98528dbfa4ff.json b/graphify-out/cache/semantic/pd5fd89c46bb5/016158cc8adad8160340452b77cce6664af577eef41c272ca17c98528dbfa4ff.json new file mode 100644 index 0000000..a4a268e --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/016158cc8adad8160340452b77cce6664af577eef41c272ca17c98528dbfa4ff.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_sprites_cabaret_loop_v1_image", "label": "Cabaret Loop Sprite Sheet", "file_type": "image", "source_file": "assets/sprites/cabaret-loop-v1.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_sprites_cabaret_loop_v1_image", "target": "assets_textures_sprite_dancer_frame_0_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/cabaret-loop-v1.png", "source_location": null, "weight": 1.0}, {"source": "assets_sprites_cabaret_loop_v1_image", "target": "assets_textures_sprite_dancer_frame_1_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/cabaret-loop-v1.png", "source_location": null, "weight": 1.0}, {"source": "assets_sprites_cabaret_loop_v1_image", "target": "assets_textures_sprite_dancer_frame_2_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/cabaret-loop-v1.png", "source_location": null, "weight": 1.0}, {"source": "assets_sprites_cabaret_loop_v1_image", "target": "assets_textures_sprite_dancer_frame_3_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/cabaret-loop-v1.png", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "cabaret_dancer_animation_set", "label": "Cabaret Dancer Animation Sequence", "nodes": ["assets_textures_sprite_dancer_frame_0_image", "assets_textures_sprite_dancer_frame_1_image", "assets_textures_sprite_dancer_frame_2_image", "assets_textures_sprite_dancer_frame_3_image"], "relation": "form", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/cabaret-loop-v1.png"}]} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/09dd028822ba46a04b140cfe2d87f9c63556fbf5d66abdb340c52a51daaf1dcd.json b/graphify-out/cache/semantic/pd5fd89c46bb5/09dd028822ba46a04b140cfe2d87f9c63556fbf5d66abdb340c52a51daaf1dcd.json new file mode 100644 index 0000000..40529ac --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/09dd028822ba46a04b140cfe2d87f9c63556fbf5d66abdb340c52a51daaf1dcd.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_dbd_hook_static", "label": "Dead by Daylight Hook Reference Graphic", "file_type": "document", "source_file": "docs/dbd_hook_static.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_dbd_hook_static_skill_check", "label": "Skill Check Hook Escape Minigame", "file_type": "concept", "source_file": "docs/dbd_hook_static.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Timed QTE skill check minigame inspired by Dead by Daylight requiring player to press SPACE or ENTER at the exact moment."}], "edges": [{"source": "docs_dbd_hook_static", "target": "docs_dbd_hook_static_skill_check", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/dbd_hook_static.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/0d6f574242f0d2d03be537ebfd0079fedb9c7dde4980ae686ffde08217b223a3.json b/graphify-out/cache/semantic/pd5fd89c46bb5/0d6f574242f0d2d03be537ebfd0079fedb9c7dde4980ae686ffde08217b223a3.json new file mode 100644 index 0000000..e61f22c --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/0d6f574242f0d2d03be537ebfd0079fedb9c7dde4980ae686ffde08217b223a3.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_dancer_frame_1_image", "label": "Dancer Animation Frame 1 Sprite", "file_type": "image", "source_file": "assets/textures/sprite_dancer_frame_1.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_dancer_frame_1_image", "target": "assets_textures_sprite_dancer_frame_2_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/textures/sprite_dancer_frame_1.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/139008ef7748309e83aeac704e3469f080f92cc10e4a047b77d4cd4516c24449.json b/graphify-out/cache/semantic/pd5fd89c46bb5/139008ef7748309e83aeac704e3469f080f92cc10e4a047b77d4cd4516c24449.json new file mode 100644 index 0000000..298ea74 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/139008ef7748309e83aeac704e3469f080f92cc10e4a047b77d4cd4516c24449.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_data_dealer_phrases", "label": "Dealer Dialogue Phrases", "file_type": "document", "source_file": "assets/data/dealer_phrases.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "assets_data_dealer_phrases_outcome_prefixes", "label": "Win Loss Draw Outcome Prefixes", "file_type": "concept", "source_file": "assets/data/dealer_phrases.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Lines prefixed with W|, L|, and D| categorize dealer reactions to player outcomes for runtime dynamic selection."}], "edges": [{"source": "assets_data_dealer_phrases", "target": "assets_data_dealer_phrases_outcome_prefixes", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "assets/data/dealer_phrases.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/26a929e4e6f254f9aba76895b9ef26f39ba9662936b01d78c78b37a5b3eadbdb.json b/graphify-out/cache/semantic/pd5fd89c46bb5/26a929e4e6f254f9aba76895b9ef26f39ba9662936b01d78c78b37a5b3eadbdb.json new file mode 100644 index 0000000..f18b6da --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/26a929e4e6f254f9aba76895b9ef26f39ba9662936b01d78c78b37a5b3eadbdb.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_release_checklist", "label": "Release QA Checklist", "file_type": "document", "source_file": "docs/RELEASE_CHECKLIST.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_release_checklist_smoke_check", "label": "Automated Release Smoke Check", "file_type": "concept", "source_file": "docs/RELEASE_CHECKLIST.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "tools/release_smoke_check.ps1 automates pre-release verification of builds, installer, and payload integrity."}, {"id": "docs_release_checklist_installer_validation", "label": "Installer & Uninstaller Verification", "file_type": "concept", "source_file": "docs/RELEASE_CHECKLIST.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Validates installation directory selection, desktop shortcuts, registry entry under Add/Remove Programs, and clean uninstallation."}, {"id": "docs_release_checklist_game_verification", "label": "Casino Games QA Verification", "file_type": "concept", "source_file": "docs/RELEASE_CHECKLIST.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Comprehensive verification steps covering all 12 casino games, account persistence, bankruptcy handling, and win goals."}], "edges": [{"source": "docs_release_checklist", "target": "docs_release_checklist_smoke_check", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/RELEASE_CHECKLIST.txt", "source_location": null, "weight": 1.0}, {"source": "docs_release_checklist", "target": "docs_release_checklist_installer_validation", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/RELEASE_CHECKLIST.txt", "source_location": null, "weight": 1.0}, {"source": "docs_release_checklist", "target": "docs_release_checklist_game_verification", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/RELEASE_CHECKLIST.txt", "source_location": null, "weight": 1.0}, {"source": "docs_release_checklist_smoke_check", "target": "docs_security_notes_sha256_payload_check", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/RELEASE_CHECKLIST.txt", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "he_release_packaging_verification", "label": "Release Packaging & Verification Flow", "nodes": ["docs_release_checklist_smoke_check", "docs_release_checklist_installer_validation", "docs_security_notes_sha256_payload_check"], "relation": "implement", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/RELEASE_CHECKLIST.txt"}]} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/32f81bd8f45e0773c6c1d53140f4950faec5ec673bc22f7584d657b45618cff7.json b/graphify-out/cache/semantic/pd5fd89c46bb5/32f81bd8f45e0773c6c1d53140f4950faec5ec673bc22f7584d657b45618cff7.json new file mode 100644 index 0000000..1405c1b --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/32f81bd8f45e0773c6c1d53140f4950faec5ec673bc22f7584d657b45618cff7.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_slot_frame_0_image", "label": "Slot Machine Frame 0 Sprite", "file_type": "image", "source_file": "assets/textures/sprite_slot_frame_0.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_slot_frame_0_image", "target": "assets_textures_sprite_slot_frame_1_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/textures/sprite_slot_frame_0.png", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "slot_machine_animation_set", "label": "Slot Machine Reel Animation Sequence", "nodes": ["assets_textures_sprite_slot_frame_0_image", "assets_textures_sprite_slot_frame_1_image", "assets_textures_sprite_slot_frame_2_image"], "relation": "form", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/textures/sprite_slot_frame_0.png"}]} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/3e3c7eff3b45033cc98ee546129b51b8910eed6f43487aa98564ddcb759a1b97.json b/graphify-out/cache/semantic/pd5fd89c46bb5/3e3c7eff3b45033cc98ee546129b51b8910eed6f43487aa98564ddcb759a1b97.json new file mode 100644 index 0000000..5ba68d8 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/3e3c7eff3b45033cc98ee546129b51b8910eed6f43487aa98564ddcb759a1b97.json @@ -0,0 +1 @@ +{"nodes": [{"id": "graphify_out_converted_variables_documentation_3fc6d2dc", "label": "poker.asm Variables Reference", "file_type": "document", "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", "label": "SAVE_MAGIC Constant 31435653h", "file_type": "concept", "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Magic header constant used to validate Assembler Casino save game integrity upon loading."}, {"id": "graphify_out_converted_variables_documentation_3fc6d2dc_color_constants", "label": "Console Color Attributes Constants", "file_type": "concept", "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Defines standard color attribute constants for cards, table, wood, money, warnings, and titles in WinAPI console."}, {"id": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles", "label": "Standard Console Handles", "file_type": "concept", "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Constants for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and INVALID_HANDLE_VALUE for Windows console I/O."}], "edges": [{"source": "graphify_out_converted_variables_documentation_3fc6d2dc", "target": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", "source_location": null, "weight": 1.0}, {"source": "graphify_out_converted_variables_documentation_3fc6d2dc", "target": "graphify_out_converted_variables_documentation_3fc6d2dc_color_constants", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", "source_location": null, "weight": 1.0}, {"source": "graphify_out_converted_variables_documentation_3fc6d2dc", "target": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/3f5cdf31d62662cddb0759ad99c3db0504b0c82ff76e03016f9f8988fe7e8301.json b/graphify-out/cache/semantic/pd5fd89c46bb5/3f5cdf31d62662cddb0759ad99c3db0504b0c82ff76e03016f9f8988fe7e8301.json new file mode 100644 index 0000000..9014966 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/3f5cdf31d62662cddb0759ad99c3db0504b0c82ff76e03016f9f8988fe7e8301.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b", "label": "Secret Cheat Codes Reference", "file_type": "document", "source_file": "docs/\u0427\u0418\u0422\u041a\u041e\u0414\u042b.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b_menu_codes", "label": "Menu Cheat Code Definitions", "file_type": "concept", "source_file": "docs/\u0427\u0418\u0422\u041a\u041e\u0414\u042b.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Keyboard cheat commands entered at the main menu including MONEYRAIN, SEVENS, WINNEXT, GODMODE, FAIRPLAY, GOAL, RESETBANK, AI difficulty, and ACHIEVER."}], "edges": [{"source": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b", "target": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b_menu_codes", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/\u0427\u0418\u0422\u041a\u041e\u0414\u042b.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/4d8f0de181aedda11b2d4ce04f8905e62cc34419f654a6239e777b23263be11c.json b/graphify-out/cache/semantic/pd5fd89c46bb5/4d8f0de181aedda11b2d4ce04f8905e62cc34419f654a6239e777b23263be11c.json new file mode 100644 index 0000000..509b8b7 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/4d8f0de181aedda11b2d4ce04f8905e62cc34419f654a6239e777b23263be11c.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_online_radmin", "label": "Online Radmin VPN Guide", "file_type": "document", "source_file": "docs/ONLINE_RADMIN.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_online_radmin_host_authoritative", "label": "Host Authoritative Network Model", "file_type": "rationale", "source_file": "docs/ONLINE_RADMIN.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Host owns hidden chamber state in Russian roulette and dice seeds; client sends only inputs so both peers remain in sync without a dedicated server."}, {"id": "docs_online_radmin_p2p_socket", "label": "Winsock TCP Port 27015 LAN Protocol", "file_type": "concept", "source_file": "docs/ONLINE_RADMIN.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Built-in 1v1 match on TCP port 27015 directly inside poker.exe without installing separate servers or services."}], "edges": [{"source": "docs_online_radmin", "target": "docs_online_radmin_host_authoritative", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/ONLINE_RADMIN.txt", "source_location": null, "weight": 1.0}, {"source": "docs_online_radmin", "target": "docs_online_radmin_p2p_socket", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/ONLINE_RADMIN.txt", "source_location": null, "weight": 1.0}, {"source": "docs_online_radmin_host_authoritative", "target": "docs_roadmap_online_command_protocol", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/ONLINE_RADMIN.txt", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "he_p2p_multiplayer_architecture", "label": "P2P Multiplayer Architecture", "nodes": ["docs_online_radmin_host_authoritative", "docs_online_radmin_p2p_socket", "docs_roadmap_online_command_protocol"], "relation": "implement", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/ONLINE_RADMIN.txt"}]} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/5019c39ae53c46f65590fb3377ed643f24a92a601310c76eb33e44407af6eef3.json b/graphify-out/cache/semantic/pd5fd89c46bb5/5019c39ae53c46f65590fb3377ed643f24a92a601310c76eb33e44407af6eef3.json new file mode 100644 index 0000000..364fdb8 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/5019c39ae53c46f65590fb3377ed643f24a92a601310c76eb33e44407af6eef3.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_slot_frame_1_image", "label": "Slot Machine Frame 1 Sprite", "file_type": "image", "source_file": "assets/textures/sprite_slot_frame_1.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_slot_frame_1_image", "target": "assets_textures_sprite_slot_frame_2_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/textures/sprite_slot_frame_1.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/50bb900fa5771366b25d5e61fd7dac85e95983acd32ae7ca8480a439b7865620.json b/graphify-out/cache/semantic/pd5fd89c46bb5/50bb900fa5771366b25d5e61fd7dac85e95983acd32ae7ca8480a439b7865620.json new file mode 100644 index 0000000..d3cefdc --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/50bb900fa5771366b25d5e61fd7dac85e95983acd32ae7ca8480a439b7865620.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442", "label": "Intro Glitch Prototype Snippet", "file_type": "document", "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_showintro", "label": "ShowIntro Procedure Prototype", "file_type": "code", "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_glitch_fx", "label": "Terminal Glitch and Screen Shake FX", "file_type": "concept", "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Uses rdtsc CPU cycle counter to dynamically trigger screen shakes, ANSI 256-color flicker flashes, and character corruption."}], "edges": [{"source": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442", "target": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_showintro", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", "source_location": null, "weight": 1.0}, {"source": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_showintro", "target": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_glitch_fx", "relation": "implements", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", "source_location": null, "weight": 1.0}, {"source": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_showintro", "target": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles", "relation": "calls", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", "source_location": null, "weight": 1.0}, {"source": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_glitch_fx", "target": "docs_casino_intro_preview", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/5c39c43551141a3f7beb37ef54848a430bd4ee753dc803cef82fab9552bf2873.json b/graphify-out/cache/semantic/pd5fd89c46bb5/5c39c43551141a3f7beb37ef54848a430bd4ee753dc803cef82fab9552bf2873.json new file mode 100644 index 0000000..9a3e7bc --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/5c39c43551141a3f7beb37ef54848a430bd4ee753dc803cef82fab9552bf2873.json @@ -0,0 +1 @@ +{"nodes": [{"id": "readme", "label": "KAZIK Project Readme", "file_type": "document", "source_file": "README.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/5cd86e06c67bdf06ccb0adf9b42808736da317b48391a68184cbdfd372d693fe.json b/graphify-out/cache/semantic/pd5fd89c46bb5/5cd86e06c67bdf06ccb0adf9b42808736da317b48391a68184cbdfd372d693fe.json new file mode 100644 index 0000000..1caadf4 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/5cd86e06c67bdf06ccb0adf9b42808736da317b48391a68184cbdfd372d693fe.json @@ -0,0 +1 @@ +{"nodes": [{"id": "cmakelists", "label": "CMake Portable Build Configuration", "file_type": "document", "source_file": "CMakeLists.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "cmakelists_poker_portable", "label": "poker_portable Target", "file_type": "code", "source_file": "CMakeLists.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "cmakelists_winsock_dependency", "label": "Win32 Winsock ws2_32 Dependency", "file_type": "concept", "source_file": "CMakeLists.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "cmakelists", "target": "cmakelists_poker_portable", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "CMakeLists.txt", "source_location": null, "weight": 1.0}, {"source": "cmakelists", "target": "cmakelists_winsock_dependency", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "CMakeLists.txt", "source_location": null, "weight": 1.0}, {"source": "cmakelists_winsock_dependency", "target": "docs_online_radmin_p2p_socket", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "CMakeLists.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/5d012f24010a6eb1de1cdd1742257cd6f46cf7fff6c1b66c6136769cd15a7ace.json b/graphify-out/cache/semantic/pd5fd89c46bb5/5d012f24010a6eb1de1cdd1742257cd6f46cf7fff6c1b66c6136769cd15a7ace.json new file mode 100644 index 0000000..c74e863 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/5d012f24010a6eb1de1cdd1742257cd6f46cf7fff6c1b66c6136769cd15a7ace.json @@ -0,0 +1 @@ +{"nodes": [{"id": "agents", "label": "AGENTS.md Project Instructions", "file_type": "document", "source_file": "AGENTS.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_masm32_build", "label": "MASM32 Build Pipeline", "file_type": "concept", "source_file": "AGENTS.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Single-file x86 assembly Windows console casino game assembled with ml.exe /c /coff /Cp /nologo and linked with link.exe /SUBSYSTEM:CONSOLE against kernel32, winmm, user32, ws2_32, gdi32."}, {"id": "agents_cp1251_encoding", "label": "CP1251 Console Encoding Standard", "file_type": "rationale", "source_file": "AGENTS.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Source strings and dealer_phrases.txt must remain in Windows-1251 (CP1251) for Windows console rendering; do not re-save as UTF-8."}, {"id": "agents_cheat_codes", "label": "Console Cheat Codes System", "file_type": "concept", "source_file": "AGENTS.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_games_catalog", "label": "Casino Games Catalog", "file_type": "concept", "source_file": "AGENTS.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_animation_assets", "label": "ANSI Animation Assets Spec", "file_type": "concept", "source_file": "AGENTS.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "casino_intro.ans and hakari_dance.ans use ANSI escape codes and CP1251 with form-feed frame separators for high-performance terminal animations."}], "edges": [{"source": "agents", "target": "agents_masm32_build", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents", "target": "agents_cp1251_encoding", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents", "target": "agents_cheat_codes", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents", "target": "agents_games_catalog", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents", "target": "agents_animation_assets", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_cheat_codes", "target": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b_menu_codes", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_cp1251_encoding", "target": "assets_data_dealer_phrases", "relation": "rationale_for", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_games_catalog", "target": "docs_release_checklist_game_verification", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/6502c037ea8cfb065a14ef126fb0d905ae3604a239c8daa6e3ae2d0f8845eb78.json b/graphify-out/cache/semantic/pd5fd89c46bb5/6502c037ea8cfb065a14ef126fb0d905ae3604a239c8daa6e3ae2d0f8845eb78.json new file mode 100644 index 0000000..eacc1e9 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/6502c037ea8cfb065a14ef126fb0d905ae3604a239c8daa6e3ae2d0f8845eb78.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_known_limitations", "label": "Known Limitations Specification", "file_type": "document", "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_known_limitations_windows_platform_lock", "label": "Windows Platform Dependency", "file_type": "rationale", "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Officially Windows-only due to tight coupling to MASM32, WinAPI, WinMM, MCI, and Windows console API."}, {"id": "docs_known_limitations_wine_support", "label": "Wine and CrossOver POSIX Support", "file_type": "concept", "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Enables non-Windows execution on Linux and macOS via Wine translation layers without rewriting the assembly core."}, {"id": "docs_known_limitations_ansi_console_speed", "label": "ANSI Animation Console Bottleneck", "file_type": "concept", "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Console throughput limits animation smoothness on older PCs, requiring frame-skip rendering profiles."}, {"id": "docs_known_limitations_durak_logic_risk", "label": "Durak Card Logic Complexity Risk", "file_type": "concept", "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Durak is the most complex game logic in the suite due to card defense, tossing (podkidnoy), transferring (perevodnoy), and table clearing."}], "edges": [{"source": "docs_known_limitations", "target": "docs_known_limitations_windows_platform_lock", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "weight": 1.0}, {"source": "docs_known_limitations", "target": "docs_known_limitations_wine_support", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "weight": 1.0}, {"source": "docs_known_limitations", "target": "docs_known_limitations_ansi_console_speed", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "weight": 1.0}, {"source": "docs_known_limitations", "target": "docs_known_limitations_durak_logic_risk", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "weight": 1.0}, {"source": "docs_known_limitations_windows_platform_lock", "target": "agents_masm32_build", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "weight": 1.0}, {"source": "docs_known_limitations_ansi_console_speed", "target": "docs_readme_release_rendering_profiles", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "weight": 1.0}, {"source": "docs_known_limitations_durak_logic_risk", "target": "\u0438\u0434\u0435\u0438_durak_expansion", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/KNOWN_LIMITATIONS.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/66785c4ded4380a94ff1a92dcea15cdb60c4936ca9ffcbf1b4df48885a1e33d1.json b/graphify-out/cache/semantic/pd5fd89c46bb5/66785c4ded4380a94ff1a92dcea15cdb60c4936ca9ffcbf1b4df48885a1e33d1.json new file mode 100644 index 0000000..c13e08b --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/66785c4ded4380a94ff1a92dcea15cdb60c4936ca9ffcbf1b4df48885a1e33d1.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_blackjack_table_image", "label": "Blackjack Table Sprite", "file_type": "image", "source_file": "assets/textures/sprite_blackjack_table.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_blackjack_table_image", "target": "assets_textures_sprite_roulette_table_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "assets/textures/sprite_blackjack_table.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/686d95276641b50cad94586d23f5ea2050aee241bea354ce2990721134a845f3.json b/graphify-out/cache/semantic/pd5fd89c46bb5/686d95276641b50cad94586d23f5ea2050aee241bea354ce2990721134a845f3.json new file mode 100644 index 0000000..05a4432 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/686d95276641b50cad94586d23f5ea2050aee241bea354ce2990721134a845f3.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_slot_frame_2_image", "label": "Slot Machine Frame 2 Sprite", "file_type": "image", "source_file": "assets/textures/sprite_slot_frame_2.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_slot_frame_2_image", "target": "assets_textures_sprite_slot_frame_0_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/textures/sprite_slot_frame_2.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/697d2c4eb527e73f383c161bac448f66279808d60a4271f637362898bfb5a0ee.json b/graphify-out/cache/semantic/pd5fd89c46bb5/697d2c4eb527e73f383c161bac448f66279808d60a4271f637362898bfb5a0ee.json new file mode 100644 index 0000000..6f97646 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/697d2c4eb527e73f383c161bac448f66279808d60a4271f637362898bfb5a0ee.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_casino_intro_preview", "label": "Casino Intro ASCII Preview", "file_type": "document", "source_file": "docs/casino_intro_preview.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "ASCII art banner preview for the main casino entry screen."}], "edges": [{"source": "docs_casino_intro_preview", "target": "agents_animation_assets", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/casino_intro_preview.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/82e133215be02a2cd9dd8a3a25756f842168108d8dffa02f074752d8d53ad2fa.json b/graphify-out/cache/semantic/pd5fd89c46bb5/82e133215be02a2cd9dd8a3a25756f842168108d8dffa02f074752d8d53ad2fa.json new file mode 100644 index 0000000..a8761b3 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/82e133215be02a2cd9dd8a3a25756f842168108d8dffa02f074752d8d53ad2fa.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_bartender_shop_image", "label": "Bartender Shop Sprite", "file_type": "image", "source_file": "assets/textures/sprite_bartender_shop.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_bartender_shop_image", "target": "assets_textures_sprite_blackjack_table_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "assets/textures/sprite_bartender_shop.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/8937c5c15aa61e292c07e5b448fd438a63891019df6c1f9fd1465631fed7e4c7.json b/graphify-out/cache/semantic/pd5fd89c46bb5/8937c5c15aa61e292c07e5b448fd438a63891019df6c1f9fd1465631fed7e4c7.json new file mode 100644 index 0000000..2cc4dbe --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/8937c5c15aa61e292c07e5b448fd438a63891019df6c1f9fd1465631fed7e4c7.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_tex_wall_hell_image", "label": "Hell Wall Texture", "file_type": "image", "source_file": "assets/textures/tex_wall_hell.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/a113431c0e76e7daa8d56c7d69a948a6964cfa315825377918a162d62760a952.json b/graphify-out/cache/semantic/pd5fd89c46bb5/a113431c0e76e7daa8d56c7d69a948a6964cfa315825377918a162d62760a952.json new file mode 100644 index 0000000..94bd222 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/a113431c0e76e7daa8d56c7d69a948a6964cfa315825377918a162d62760a952.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_dancer_frame_2_image", "label": "Dancer Animation Frame 2 Sprite", "file_type": "image", "source_file": "assets/textures/sprite_dancer_frame_2.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_dancer_frame_2_image", "target": "assets_textures_sprite_dancer_frame_3_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/textures/sprite_dancer_frame_2.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/a9a271207ed30f453f832cb69b4b0495433172e7266523a3d26ac2b42c5a49ae.json b/graphify-out/cache/semantic/pd5fd89c46bb5/a9a271207ed30f453f832cb69b4b0495433172e7266523a3d26ac2b42c5a49ae.json new file mode 100644 index 0000000..b4b1d0b --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/a9a271207ed30f453f832cb69b4b0495433172e7266523a3d26ac2b42c5a49ae.json @@ -0,0 +1 @@ +{"nodes": [{"id": "runtime_achievement", "label": "Runtime Achievement Storage File", "file_type": "document", "source_file": "runtime/achievement.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Local file storing unlocked player achievements."}, {"id": "runtime_achievement_tracking", "label": "Runtime Achievement Tracker", "file_type": "concept", "source_file": "runtime/achievement.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "runtime_achievement", "target": "runtime_achievement_tracking", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "runtime/achievement.txt", "source_location": null, "weight": 1.0}, {"source": "runtime_achievement_tracking", "target": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b_menu_codes", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "runtime/achievement.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/af01a2f906052efca92f2cfc486ad6691c764ca162aeb960c04bdb9516d76b3e.json b/graphify-out/cache/semantic/pd5fd89c46bb5/af01a2f906052efca92f2cfc486ad6691c764ca162aeb960c04bdb9516d76b3e.json new file mode 100644 index 0000000..122f8b3 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/af01a2f906052efca92f2cfc486ad6691c764ca162aeb960c04bdb9516d76b3e.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_tex_floor_carpet_image", "label": "Casino Carpet Floor Texture", "file_type": "image", "source_file": "assets/textures/tex_floor_carpet.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_tex_floor_carpet_image", "target": "assets_textures_tex_wall_velvet_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "assets/textures/tex_floor_carpet.png", "source_location": null, "weight": 1.0}, {"source": "assets_textures_tex_floor_carpet_image", "target": "assets_textures_tex_wall_stripclub_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "assets/textures/tex_floor_carpet.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/b5eb0b056a9964e494760f4ce3f151607479313f68fa78c77fd13f3cc3ee0618.json b/graphify-out/cache/semantic/pd5fd89c46bb5/b5eb0b056a9964e494760f4ce3f151607479313f68fa78c77fd13f3cc3ee0618.json new file mode 100644 index 0000000..2e358c4 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/b5eb0b056a9964e494760f4ce3f151607479313f68fa78c77fd13f3cc3ee0618.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_sprites_casino_atlas_v1_image", "label": "Casino Atlas Sprite Sheet", "file_type": "image", "source_file": "assets/sprites/casino-atlas-v1.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_sprites_casino_atlas_v1_image", "target": "assets_textures_sprite_blackjack_table_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/casino-atlas-v1.png", "source_location": null, "weight": 1.0}, {"source": "assets_sprites_casino_atlas_v1_image", "target": "assets_textures_sprite_roulette_table_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/casino-atlas-v1.png", "source_location": null, "weight": 1.0}, {"source": "assets_sprites_casino_atlas_v1_image", "target": "assets_textures_sprite_bartender_shop_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/casino-atlas-v1.png", "source_location": null, "weight": 1.0}, {"source": "assets_sprites_casino_atlas_v1_image", "target": "assets_textures_sprite_slot_frame_0_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/sprites/casino-atlas-v1.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/b732ac4170f7a74ce6a57e220b33266c40fb1641b1829a4fe3a1fa95758f29aa.json b/graphify-out/cache/semantic/pd5fd89c46bb5/b732ac4170f7a74ce6a57e220b33266c40fb1641b1829a4fe3a1fa95758f29aa.json new file mode 100644 index 0000000..21851a2 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/b732ac4170f7a74ce6a57e220b33266c40fb1641b1829a4fe3a1fa95758f29aa.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_tex_wall_stripclub_image", "label": "Neon Strip Club Wall Texture", "file_type": "image", "source_file": "assets/textures/tex_wall_stripclub.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_tex_wall_stripclub_image", "target": "assets_textures_tex_wall_hell_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "assets/textures/tex_wall_stripclub.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/c1326bcfdd650879a2a436c99d0e98276db2181fd67ce5951d8f4682cbcd0769.json b/graphify-out/cache/semantic/pd5fd89c46bb5/c1326bcfdd650879a2a436c99d0e98276db2181fd67ce5951d8f4682cbcd0769.json new file mode 100644 index 0000000..87fb7fc --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/c1326bcfdd650879a2a436c99d0e98276db2181fd67ce5951d8f4682cbcd0769.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_tex_wall_velvet_image", "label": "Velvet Wall Texture", "file_type": "image", "source_file": "assets/textures/tex_wall_velvet.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_tex_wall_velvet_image", "target": "assets_textures_tex_wall_stripclub_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "assets/textures/tex_wall_velvet.png", "source_location": null, "weight": 1.0}, {"source": "assets_textures_tex_wall_velvet_image", "target": "assets_textures_tex_wall_hell_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "assets/textures/tex_wall_velvet.png", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "casino_wall_textures_set", "label": "Casino Wall Textures Set", "nodes": ["assets_textures_tex_wall_velvet_image", "assets_textures_tex_wall_stripclub_image", "assets_textures_tex_wall_hell_image"], "relation": "form", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "assets/textures/tex_wall_velvet.png"}]} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/c4178347ffe8fa44f006bd04ff7631d481899c6440bd5e1fa769ff4f161259b7.json b/graphify-out/cache/semantic/pd5fd89c46bb5/c4178347ffe8fa44f006bd04ff7631d481899c6440bd5e1fa769ff4f161259b7.json new file mode 100644 index 0000000..47eaf22 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/c4178347ffe8fa44f006bd04ff7631d481899c6440bd5e1fa769ff4f161259b7.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_roulette_table_image", "label": "Roulette Table Sprite", "file_type": "image", "source_file": "assets/textures/sprite_roulette_table.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_roulette_table_image", "target": "assets_textures_sprite_blackjack_table_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "assets/textures/sprite_roulette_table.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/c8bbcc1e907856de0c3dc438bb527a0a2ec44bc43e522f43e3abea7569328164.json b/graphify-out/cache/semantic/pd5fd89c46bb5/c8bbcc1e907856de0c3dc438bb527a0a2ec44bc43e522f43e3abea7569328164.json new file mode 100644 index 0000000..3abe1e6 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/c8bbcc1e907856de0c3dc438bb527a0a2ec44bc43e522f43e3abea7569328164.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_security_notes", "label": "Security Architecture Notes", "file_type": "document", "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_security_notes_sha256_payload_check", "label": "SHA-256 Binary Integrity Verification", "file_type": "concept", "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Installer verifies embedded archive hash and launcher validates bin/poker.exe hash to prevent payload tampering."}, {"id": "docs_security_notes_save_tamper_signature", "label": "Save File Salted Signature", "file_type": "concept", "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Save files write a hash signature computed over the first 276 bytes with a hardcoded salt to catch manual progress hex editing."}, {"id": "docs_security_notes_path_traversal_guard", "label": "Installer Path Traversal Guard", "file_type": "concept", "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Installer rejects archive entries containing ../ to guarantee unpacked files cannot escape the installation directory."}], "edges": [{"source": "docs_security_notes", "target": "docs_security_notes_sha256_payload_check", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "weight": 1.0}, {"source": "docs_security_notes", "target": "docs_security_notes_save_tamper_signature", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "weight": 1.0}, {"source": "docs_security_notes", "target": "docs_security_notes_path_traversal_guard", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "weight": 1.0}, {"source": "docs_security_notes_save_tamper_signature", "target": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", "relation": "shares_data_with", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "weight": 1.0}, {"source": "docs_security_notes_save_tamper_signature", "target": "\u0438\u0434\u0435\u0438_appdata_saves", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "docs/SECURITY_NOTES.txt", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "he_save_integrity_protection", "label": "Save File Integrity & Persistence Architecture", "nodes": ["docs_security_notes_save_tamper_signature", "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", "\u0438\u0434\u0435\u0438_appdata_saves"], "relation": "form", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/SECURITY_NOTES.txt"}]} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/ca15a08a45d16237e0e2d624843cea6c667a4f1f1a35230d4cb692d88249fd43.json b/graphify-out/cache/semantic/pd5fd89c46bb5/ca15a08a45d16237e0e2d624843cea6c667a4f1f1a35230d4cb692d88249fd43.json new file mode 100644 index 0000000..6d9b343 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/ca15a08a45d16237e0e2d624843cea6c667a4f1f1a35230d4cb692d88249fd43.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_dancer_frame_0_image", "label": "Dancer Animation Frame 0 Sprite", "file_type": "image", "source_file": "assets/textures/sprite_dancer_frame_0.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_dancer_frame_0_image", "target": "assets_textures_sprite_dancer_frame_1_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/textures/sprite_dancer_frame_0.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/d676872e69d4aeeb49265d3988c68055ceede785e6e40404caaa242a808f25bc.json b/graphify-out/cache/semantic/pd5fd89c46bb5/d676872e69d4aeeb49265d3988c68055ceede785e6e40404caaa242a808f25bc.json new file mode 100644 index 0000000..71dc0c8 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/d676872e69d4aeeb49265d3988c68055ceede785e6e40404caaa242a808f25bc.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_icons_casino_preview_image", "label": "Casino Preview Icon", "file_type": "image", "source_file": "assets/icons/casino_preview.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_icons_casino_preview_image", "target": "assets_sprites_casino_atlas_v1_image", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "assets/icons/casino_preview.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/d98a4f99254061be7b91bbbb70f598a37eeed28b7862705c59ff22692de7f38e.json b/graphify-out/cache/semantic/pd5fd89c46bb5/d98a4f99254061be7b91bbbb70f598a37eeed28b7862705c59ff22692de7f38e.json new file mode 100644 index 0000000..130272f --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/d98a4f99254061be7b91bbbb70f598a37eeed28b7862705c59ff22692de7f38e.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_revolver_small_preview", "label": "Revolver ASCII Preview", "file_type": "document", "source_file": "docs/revolver_small_preview.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_revolver_small_preview_russian_roulette_visuals", "label": "Russian Roulette Revolver ASCII Graphics", "file_type": "concept", "source_file": "docs/revolver_small_preview.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Detailed multi-angle ASCII art gun animations showing cylinder spin and hammer cocking for Russian Roulette."}], "edges": [{"source": "docs_revolver_small_preview", "target": "docs_revolver_small_preview_russian_roulette_visuals", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/revolver_small_preview.txt", "source_location": null, "weight": 1.0}, {"source": "docs_revolver_small_preview_russian_roulette_visuals", "target": "\u0438\u0434\u0435\u0438_buckshot_roulette", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "docs/revolver_small_preview.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/d9fd6ae71610254ca4c206a20100574587a9a920b8b6d96b1695a526eb4fdc5d.json b/graphify-out/cache/semantic/pd5fd89c46bb5/d9fd6ae71610254ca4c206a20100574587a9a920b8b6d96b1695a526eb4fdc5d.json new file mode 100644 index 0000000..f907bd8 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/d9fd6ae71610254ca4c206a20100574587a9a920b8b6d96b1695a526eb4fdc5d.json @@ -0,0 +1 @@ +{"nodes": [{"id": "assets_textures_sprite_dancer_frame_3_image", "label": "Dancer Animation Frame 3 Sprite", "file_type": "image", "source_file": "assets/textures/sprite_dancer_frame_3.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "assets_textures_sprite_dancer_frame_3_image", "target": "assets_textures_sprite_dancer_frame_0_image", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "assets/textures/sprite_dancer_frame_3.png", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/ddb0f204117b91048fa027ed12269f2be981e14c8d4055f8d3fc8aef3573e2e2.json b/graphify-out/cache/semantic/pd5fd89c46bb5/ddb0f204117b91048fa027ed12269f2be981e14c8d4055f8d3fc8aef3573e2e2.json new file mode 100644 index 0000000..1f5ffea --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/ddb0f204117b91048fa027ed12269f2be981e14c8d4055f8d3fc8aef3573e2e2.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_readme_release", "label": "Release Notes and User Guide", "file_type": "document", "source_file": "docs/README_RELEASE.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_readme_release_rendering_profiles", "label": "Animation Rendering Profiles", "file_type": "concept", "source_file": "docs/README_RELEASE.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Cinematic, Adaptive, and Stable profiles control frame-skipping to eliminate flicker and stutter without omitting entire scenes."}, {"id": "docs_readme_release_package_architecture", "label": "Release Package Architecture", "file_type": "concept", "source_file": "docs/README_RELEASE.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Bundles launcher Assembler Casino.exe, core bin/poker.exe, and assets into an installer for clean user experience."}], "edges": [{"source": "docs_readme_release", "target": "docs_readme_release_rendering_profiles", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/README_RELEASE.txt", "source_location": null, "weight": 1.0}, {"source": "docs_readme_release", "target": "docs_readme_release_package_architecture", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/README_RELEASE.txt", "source_location": null, "weight": 1.0}, {"source": "docs_readme_release_package_architecture", "target": "docs_release_checklist_installer_validation", "relation": "references", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "docs/README_RELEASE.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/f2fdf00fc3204cd407be451fbc264211ee06a6c55f801f948fcbac7b152f7050.json b/graphify-out/cache/semantic/pd5fd89c46bb5/f2fdf00fc3204cd407be451fbc264211ee06a6c55f801f948fcbac7b152f7050.json new file mode 100644 index 0000000..ab540d5 --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/f2fdf00fc3204cd407be451fbc264211ee06a6c55f801f948fcbac7b152f7050.json @@ -0,0 +1 @@ +{"nodes": [{"id": "\u0438\u0434\u0435\u0438", "label": "Feature Backlog and Game Ideas", "file_type": "document", "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "\u0438\u0434\u0435\u0438_appdata_saves", "label": "AppData Save Migration Idea", "file_type": "concept", "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Moving player save data to %AppData% prevents accidental deletion when reinstalling or updating the casino."}, {"id": "\u0438\u0434\u0435\u0438_shop_and_charms", "label": "Casino Shop and Charms Mechanic", "file_type": "concept", "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Allows spending winnings on charms, custom card decks, shirts, and lucky talismans with gameplay effects."}, {"id": "\u0438\u0434\u0435\u0438_pulse_stress", "label": "Heart Rate Stress Visualization", "file_type": "concept", "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Visualizes player character pulse and anxiety level during high-stakes gambling decisions."}, {"id": "\u0438\u0434\u0435\u0438_durak_expansion", "label": "Durak Card Game Expansion", "file_type": "concept", "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Addition of Russian card game Durak with podkidnoy and perevodnoy variants to broaden casino offerings."}, {"id": "\u0438\u0434\u0435\u0438_buckshot_roulette", "label": "Buckshot Roulette Game Mode Idea", "file_type": "concept", "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Adaptation of shotgun-based Russian Roulette gameplay with items and bluffing mechanics."}, {"id": "\u0438\u0434\u0435\u0438_casino_tower", "label": "Casino Tower Tournament Idea", "file_type": "concept", "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Multi-floor casino tower progression where players face escalating AI opponents with special modifiers."}], "edges": [{"source": "\u0438\u0434\u0435\u0438", "target": "\u0438\u0434\u0435\u0438_appdata_saves", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "weight": 1.0}, {"source": "\u0438\u0434\u0435\u0438", "target": "\u0438\u0434\u0435\u0438_shop_and_charms", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "weight": 1.0}, {"source": "\u0438\u0434\u0435\u0438", "target": "\u0438\u0434\u0435\u0438_pulse_stress", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "weight": 1.0}, {"source": "\u0438\u0434\u0435\u0438", "target": "\u0438\u0434\u0435\u0438_durak_expansion", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "weight": 1.0}, {"source": "\u0438\u0434\u0435\u0438", "target": "\u0438\u0434\u0435\u0438_buckshot_roulette", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "weight": 1.0}, {"source": "\u0438\u0434\u0435\u0438", "target": "\u0438\u0434\u0435\u0438_casino_tower", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "weight": 1.0}, {"source": "\u0438\u0434\u0435\u0438_shop_and_charms", "target": "docs_roadmap_future_expansions", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "weight": 1.0}, {"source": "\u0438\u0434\u0435\u0438_casino_tower", "target": "docs_roadmap_future_expansions", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": "\u0418\u0414\u0415\u0418.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/semantic/pd5fd89c46bb5/f70c4f274cf8e4c4cf5b2788263088c822b61bd8fd638c06e211b9dfd97d4645.json b/graphify-out/cache/semantic/pd5fd89c46bb5/f70c4f274cf8e4c4cf5b2788263088c822b61bd8fd638c06e211b9dfd97d4645.json new file mode 100644 index 0000000..fc7d39b --- /dev/null +++ b/graphify-out/cache/semantic/pd5fd89c46bb5/f70c4f274cf8e4c4cf5b2788263088c822b61bd8fd638c06e211b9dfd97d4645.json @@ -0,0 +1 @@ +{"nodes": [{"id": "docs_roadmap", "label": "Development Roadmap", "file_type": "document", "source_file": "docs/ROADMAP.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "docs_roadmap_online_command_protocol", "label": "Multiplayer Command Protocol", "file_type": "concept", "source_file": "docs/ROADMAP.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Client-server text command set (BET, HIT, STAND, FOLD, RAISE, PLAY_CARD, READY, CHAT) sent over TCP sockets."}, {"id": "docs_roadmap_security_milestones", "label": "Security & Signing Roadmap", "file_type": "concept", "source_file": "docs/ROADMAP.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Planned addition of Authenticode code-signing, release manifests, and stronger save checksum validation."}, {"id": "docs_roadmap_future_expansions", "label": "Future Casino Expansions", "file_type": "concept", "source_file": "docs/ROADMAP.txt", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null, "rationale": "Planned expansions including casino tax, VIP tier benefits, charm bestiary, secret ending, and casino tower tournament."}], "edges": [{"source": "docs_roadmap", "target": "docs_roadmap_online_command_protocol", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/ROADMAP.txt", "source_location": null, "weight": 1.0}, {"source": "docs_roadmap", "target": "docs_roadmap_security_milestones", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/ROADMAP.txt", "source_location": null, "weight": 1.0}, {"source": "docs_roadmap", "target": "docs_roadmap_future_expansions", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "docs/ROADMAP.txt", "source_location": null, "weight": 1.0}, {"source": "docs_roadmap_security_milestones", "target": "docs_security_notes", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "docs/ROADMAP.txt", "source_location": null, "weight": 1.0}], "hyperedges": []} \ No newline at end of file diff --git a/graphify-out/cache/stat-index.json b/graphify-out/cache/stat-index.json new file mode 100644 index 0000000..ad8001d --- /dev/null +++ b/graphify-out/cache/stat-index.json @@ -0,0 +1 @@ +{"E:\\DEPAI IN 3D\\KAZIK\\AGENTS.md":{"size":2055,"mtime_ns":1790270822393003200,"word_count":239,"hash":"5d012f24010a6eb1de1cdd1742257cd6f46cf7fff6c1b66c6136769cd15a7ace"},"E:\\DEPAI IN 3D\\KAZIK\\CMakeLists.txt":{"size":273,"mtime_ns":1790270822393003200,"word_count":14,"hash":"5cd86e06c67bdf06ccb0adf9b42808736da317b48391a68184cbdfd372d693fe"},"E:\\DEPAI IN 3D\\KAZIK\\README.md":{"size":70,"mtime_ns":1790270822393003200,"word_count":12,"hash":"5c39c43551141a3f7beb37ef54848a430bd4ee753dc803cef82fab9552bf2873"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\data\\dealer_phrases.txt":{"size":575,"mtime_ns":1790270822489428100,"word_count":40,"hash":"139008ef7748309e83aeac704e3469f080f92cc10e4a047b77d4cd4516c24449"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\icons\\casino_preview.png":{"size":21380,"mtime_ns":1790270822489428100,"word_count":812,"hash":"d676872e69d4aeeb49265d3988c68055ceede785e6e40404caaa242a808f25bc"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\cabaret-loop-v1.png":{"size":1428593,"mtime_ns":1790270823119320500,"word_count":48413,"hash":"016158cc8adad8160340452b77cce6664af577eef41c272ca17c98528dbfa4ff"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\sprites\\casino-atlas-v1.png":{"size":1884304,"mtime_ns":1790270823124529400,"word_count":63811,"hash":"b5eb0b056a9964e494760f4ce3f151607479313f68fa78c77fd13f3cc3ee0618"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_bartender_shop.png":{"size":6103,"mtime_ns":1790270823142275300,"word_count":205,"hash":"82e133215be02a2cd9dd8a3a25756f842168108d8dffa02f074752d8d53ad2fa"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_blackjack_table.png":{"size":5817,"mtime_ns":1790270823142275300,"word_count":233,"hash":"66785c4ded4380a94ff1a92dcea15cdb60c4936ca9ffcbf1b4df48885a1e33d1"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_0.png":{"size":1975,"mtime_ns":1790270823142275300,"word_count":78,"hash":"ca15a08a45d16237e0e2d624843cea6c667a4f1f1a35230d4cb692d88249fd43"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_1.png":{"size":2161,"mtime_ns":1790270823142275300,"word_count":77,"hash":"0d6f574242f0d2d03be537ebfd0079fedb9c7dde4980ae686ffde08217b223a3"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_2.png":{"size":1862,"mtime_ns":1790270823142275300,"word_count":67,"hash":"a113431c0e76e7daa8d56c7d69a948a6964cfa315825377918a162d62760a952"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_dancer_frame_3.png":{"size":1983,"mtime_ns":1790270823142275300,"word_count":78,"hash":"d9fd6ae71610254ca4c206a20100574587a9a920b8b6d96b1695a526eb4fdc5d"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_roulette_table.png":{"size":6040,"mtime_ns":1790270823142275300,"word_count":209,"hash":"c4178347ffe8fa44f006bd04ff7631d481899c6440bd5e1fa769ff4f161259b7"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_0.png":{"size":4322,"mtime_ns":1790270823142275300,"word_count":131,"hash":"32f81bd8f45e0773c6c1d53140f4950faec5ec673bc22f7584d657b45618cff7"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_1.png":{"size":4434,"mtime_ns":1790270823142275300,"word_count":142,"hash":"5019c39ae53c46f65590fb3377ed643f24a92a601310c76eb33e44407af6eef3"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\sprite_slot_frame_2.png":{"size":4421,"mtime_ns":1790270823142275300,"word_count":149,"hash":"686d95276641b50cad94586d23f5ea2050aee241bea354ce2990721134a845f3"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_floor_carpet.png":{"size":10055,"mtime_ns":1790270823142275300,"word_count":404,"hash":"af01a2f906052efca92f2cfc486ad6691c764ca162aeb960c04bdb9516d76b3e"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_hell.png":{"size":8095,"mtime_ns":1790270823142275300,"word_count":274,"hash":"8937c5c15aa61e292c07e5b448fd438a63891019df6c1f9fd1465631fed7e4c7"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_stripclub.png":{"size":9402,"mtime_ns":1790270823142275300,"word_count":336,"hash":"b732ac4170f7a74ce6a57e220b33266c40fb1641b1829a4fe3a1fa95758f29aa"},"E:\\DEPAI IN 3D\\KAZIK\\assets\\textures\\tex_wall_velvet.png":{"size":8652,"mtime_ns":1790270823142275300,"word_count":319,"hash":"c1326bcfdd650879a2a436c99d0e98276db2181fd67ce5951d8f4682cbcd0769"},"E:\\DEPAI IN 3D\\KAZIK\\casino3d.inc":{"size":72176,"mtime_ns":1790270823149606600,"word_count":8467,"hash":"17cce3e69a6245d4d8d4d48847de44d32b433568a6007f81701b2f9ee3ce0455"},"E:\\DEPAI IN 3D\\KAZIK\\casino3d_data.inc":{"size":15600,"mtime_ns":1790270823149606600,"word_count":350,"hash":"4ededd1f62dfbf46792345c3be39b7d8b349dafb88ee476878ac7d8e4e95fcdb"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\KNOWN_LIMITATIONS.txt":{"size":1274,"mtime_ns":1790270823149606600,"word_count":105,"hash":"6502c037ea8cfb065a14ef126fb0d905ae3604a239c8daa6e3ae2d0f8845eb78"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\ONLINE_RADMIN.txt":{"size":1060,"mtime_ns":1790270823149606600,"word_count":170,"hash":"4d8f0de181aedda11b2d4ce04f8905e62cc34419f654a6239e777b23263be11c"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\README_RELEASE.txt":{"size":2751,"mtime_ns":1790270823149606600,"word_count":232,"hash":"ddb0f204117b91048fa027ed12269f2be981e14c8d4055f8d3fc8aef3573e2e2"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\RELEASE_CHECKLIST.txt":{"size":3876,"mtime_ns":1790270823149606600,"word_count":364,"hash":"26a929e4e6f254f9aba76895b9ef26f39ba9662936b01d78c78b37a5b3eadbdb"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\ROADMAP.txt":{"size":3358,"mtime_ns":1790270823149606600,"word_count":304,"hash":"f70c4f274cf8e4c4cf5b2788263088c822b61bd8fd638c06e211b9dfd97d4645"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\SECURITY_NOTES.txt":{"size":3499,"mtime_ns":1790270823149606600,"word_count":261,"hash":"c8bbcc1e907856de0c3dc438bb527a0a2ec44bc43e522f43e3abea7569328164"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\casino_intro_preview.txt":{"size":2539,"mtime_ns":1790270823149606600,"word_count":103,"hash":"697d2c4eb527e73f383c161bac448f66279808d60a4271f637362898bfb5a0ee"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\dbd_hook_static.txt":{"size":1393,"mtime_ns":1790270823149606600,"word_count":116,"hash":"09dd028822ba46a04b140cfe2d87f9c63556fbf5d66abdb340c52a51daaf1dcd"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\revolver_small_preview.txt":{"size":12238,"mtime_ns":1790270823149606600,"word_count":1154,"hash":"d98a4f99254061be7b91bbbb70f598a37eeed28b7862705c59ff22692de7f38e"},"E:\\DEPAI IN 3D\\KAZIK\\graphify-out\\converted\\variables_documentation_3fc6d2dc.md":{"size":235799,"mtime_ns":1790274665270484400,"word_count":23232,"hash":"3e3c7eff3b45033cc98ee546129b51b8910eed6f43487aa98564ddcb759a1b97"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt":{"size":15541,"mtime_ns":1790270823149606600,"word_count":1445,"hash":"50bb900fa5771366b25d5e61fd7dac85e95983acd32ae7ca8480a439b7865620"},"E:\\DEPAI IN 3D\\KAZIK\\docs\\\u0427\u0418\u0422\u041a\u041e\u0414\u042b.txt":{"size":750,"mtime_ns":1790270823149606600,"word_count":60,"hash":"3f5cdf31d62662cddb0759ad99c3db0504b0c82ff76e03016f9f8988fe7e8301"},"E:\\DEPAI IN 3D\\KAZIK\\font8x8.inc":{"size":16214,"mtime_ns":1790270823149606600,"word_count":3087,"hash":"260c7d561bd484ebf4a0b7f05ce9e48f9b4a7f701ce3500521befbc805a35c9a"},"E:\\DEPAI IN 3D\\KAZIK\\runtime\\achievement.txt":{"size":0,"mtime_ns":1790270823159343700,"word_count":0,"hash":"a9a271207ed30f453f832cb69b4b0495433172e7266523a3d26ac2b42c5a49ae"},"E:\\DEPAI IN 3D\\KAZIK\\src_graphics\\platform_code.inc":{"size":9961,"mtime_ns":1790270823159343700,"word_count":1209,"hash":"138dda071059ae037e9972bdbc63d21f3a33a18ca102faa52fb8cac0b644be35"},"E:\\DEPAI IN 3D\\KAZIK\\src_graphics\\platform_data.inc":{"size":3455,"mtime_ns":1790270823159343700,"word_count":412,"hash":"7f720d61b49719534794328d3012acd593e9c8627cbd6520c573c8c5d9435d93"},"E:\\DEPAI IN 3D\\KAZIK\\src_graphics\\renderer.inc":{"size":57722,"mtime_ns":1790270823159343700,"word_count":6764,"hash":"4bf4afc73df542d7e831d4468cda9e2112319bdaf8c89ea20b4c49ac55520a2a"},"E:\\DEPAI IN 3D\\KAZIK\\src_portable\\casino_portable.c":{"size":18932,"mtime_ns":1790270823159343700,"word_count":1802,"hash":"0d8891501bfba3c351f82dabe23d79f38b69415391a8513cdb928bd7c13476d9"},"E:\\DEPAI IN 3D\\KAZIK\\src_portable\\casino_portable.h":{"size":3513,"mtime_ns":1790270823159343700,"word_count":327,"hash":"f27d1ca5e032eebb68a1df01fd317f63989558728f1d1ddb12bc251985032513"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\build_all_3d.py":{"size":78230,"mtime_ns":1790270823159343700,"word_count":9195,"hash":"1ad632faebe559e783b0064c2338a3678043ddd3ae85cdaa79f1c27f00d6fdcf"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\build_casino_assets.py":{"size":8394,"mtime_ns":1790270823159343700,"word_count":1025,"hash":"531a442e9e0c8f0c7c6ac0060e327d86319cf01167962564fddb4ef445029606"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\build_engine.py":{"size":83,"mtime_ns":1790270823159343700,"word_count":11,"hash":"96a2e9b3fe3a64c41bfd8ced2675141be58d38619b85c57183a0c5a9ea69d3a3"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\build_graphics.ps1":{"size":717,"mtime_ns":1790270823159343700,"word_count":70,"hash":"e92dd483b153ada4a22fb3ccbb73cc0f57af765057576eede971308c4eebf950"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\build_graphics_assets.py":{"size":3324,"mtime_ns":1790270823159343700,"word_count":394,"hash":"60e4e6059cb5be35a945d8b9587c012aeb99180bbc671d58513b58b454e7452d"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\generate_casino3d.py":{"size":85,"mtime_ns":1790270823159343700,"word_count":9,"hash":"af3c3463623a9dc11fb58dc537a2a0249ea08f2b4ee51dba135bb416c69e8d9f"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\generate_font.py":{"size":1182,"mtime_ns":1790270823159343700,"word_count":123,"hash":"c24892bb1085007fd9e480f1f4c9edd6ba5dec55e03222df428abb5a36330150"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\generate_math_and_map.py":{"size":2819,"mtime_ns":1790270823159343700,"word_count":443,"hash":"47fa3293a06711be74c2f14c52bd460dcd78bb98289e988d575ab8e9e01ad54c"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\generate_unified_casino3d.py":{"size":61170,"mtime_ns":1790270823159343700,"word_count":6784,"hash":"5f3f8a091f85d4da2b6a9052a2747b45b06443907eb422c671c5f4ccbcf71968"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\make_casino3d.py":{"size":80,"mtime_ns":1790270823159343700,"word_count":14,"hash":"7b7850caf79296f29325be3bb73d1e5ab22f7b02fc200f7450304d888b68bbf1"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\patch_poker_asm.py":{"size":2607,"mtime_ns":1790270823159343700,"word_count":276,"hash":"e0ca915f66cb272addb0bca6b7dd98f496a43319d6bb108033c4fab1175c67b6"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\preview_dbd_hook.py":{"size":1673,"mtime_ns":1790270823159343700,"word_count":152,"hash":"7627c17a45c6dc182aa6d5405eb8d8bf6242e0a79147b3c96085a23c99422493"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\preview_hakari.py":{"size":1210,"mtime_ns":1790270823159343700,"word_count":101,"hash":"d31fe1e6e7ffc320f0f384a1d9140a304b7e571cea3e36fc5357728eafb44cf3"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\preview_intro.py":{"size":1814,"mtime_ns":1790270823159343700,"word_count":148,"hash":"b70c30af76f1f519b55093958a9931630d1435baf8235432b0402eb26a5089c4"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\release_smoke_check.ps1":{"size":8092,"mtime_ns":1790270823159343700,"word_count":684,"hash":"0e20ce5f0da50b080a252db92e146b04fa951fe188d0fda9be8c78bd42a8bcbc"},"E:\\DEPAI IN 3D\\KAZIK\\tools\\simulate_render.py":{"size":9470,"mtime_ns":1790270823159343700,"word_count":1578,"hash":"75c60a1a5818b18c7cfa072c4708a27bf2d7320e67804d80b42835798ca957c5"},"E:\\DEPAI IN 3D\\KAZIK\\\u0418\u0414\u0415\u0418.txt":{"size":1118,"mtime_ns":1790270823159343700,"word_count":88,"hash":"f2fdf00fc3204cd407be451fbc264211ee06a6c55f801f948fcbac7b152f7050"}} \ No newline at end of file diff --git a/graphify-out/converted/variables_documentation_3fc6d2dc.md b/graphify-out/converted/variables_documentation_3fc6d2dc.md new file mode 100644 index 0000000..a93b795 --- /dev/null +++ b/graphify-out/converted/variables_documentation_3fc6d2dc.md @@ -0,0 +1,965 @@ + + +Assembler Casino: справочник переменных +Файл: F:\покер\poker.asm +Сгенерировано: 27.05.2026 01:34 +Констант: 24. Переменных/строк в .data: 929. +Константы EQU +Переменные и строки .data +| Имя | Тип | Значение | Блок | Назначение | +| --- | --- | --- | --- | --- | +| STD_INPUT_HANDLE | equ | -10 | WinAPI-константы | Значение/код для работы с дескрипторами Windows. | +| STD_OUTPUT_HANDLE | equ | -11 | WinAPI-константы | Значение/код для работы с дескрипторами Windows. | +| VK_RETURN | equ | 0Dh | Константы | Числовая константа, используемая в коде. | +| VK_SPACE | equ | 20h | Константы | Числовая константа, используемая в коде. | +| 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 | WinAPI-константы | Значение/код для работы с дескрипторами Windows. | +| SAVE_MAGIC | equ | 31435653h | Сохранения | Магическое число для проверки файла сохранения. | +| ENABLE_VIRTUAL_TERMINAL_PROCESSING | equ | 0004h | Константы | Числовая константа, используемая в коде. | +| COLOR_DEFAULT | equ | 07h | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_TITLE | equ | 0Bh | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_MONEY | equ | 0Ah | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_WARN | equ | 0Eh | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_BAD | equ | 0Ch | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_CARD | equ | 0Fh | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_RED_CARD | equ | 0Ch | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_BACK_CARD | equ | 08h | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_TABLE | equ | 02h | Константы цветов | Цветовой атрибут консоли Windows. | +| COLOR_WOOD | equ | 06h | Константы цветов | Цветовой атрибут консоли Windows. | +| Имя | Тип | Начальное значение | Блок | Назначение | +| --- | --- | --- | --- | --- | +| hOut | dd | 0 | Консоль | Дескриптор стандартного ввода/вывода консоли. | +| hIn | dd | 0 | Консоль | Дескриптор стандартного ввода/вывода консоли. | +| charsWritten | dd | 0 | Служебные WinAPI | Служебное значение для WinAPI, консоли или генератора случайных чисел. | +| charsRead | dd | 0 | Служебные WinAPI | Служебное значение для WinAPI, консоли или генератора случайных чисел. | +| consoleMode | dd | 0 | Служебные WinAPI | Служебное значение для WinAPI, консоли или генератора случайных чисел. | +| printLen | dd | 0 | Служебные WinAPI | Служебное значение для WinAPI, консоли или генератора случайных чисел. | +| wideLen | dd | 0 | Служебные WinAPI | Служебное значение для WinAPI, консоли или генератора случайных чисел. | +| seed | dd | 0 | Служебные WinAPI | Служебное значение для WinAPI, консоли или генератора случайных чисел. | +| 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) | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Объявлено как массив/буфер. | +| playerTotal | dd | 0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. | +| dealerTotal | dd | 0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| playerAces | dd | 0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. | +| dealerAces | dd | 0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| playerCards | dd | 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. | +| 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 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. | +| 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 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. | +| dealerFileHandle | dd | 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. | +| dealerLineLen | dd | 0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| dealerPhraseCount | dd | 0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| dealerPhrasePick | dd | 0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| dealerScanMode | dd | 0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| dealerWantedTag | db | 0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| 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 | 64 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 | Экономика | Банк игрока, цель, ставка или текст денежных операций. | +| 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 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| bsShells | dd | 8 dup(0) | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Объявлено как массив/буфер. | +| bsShellIndex | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsShellCount | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsLiveCount | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsBlankCount | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsPlayerHP | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsAIHP | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsTurn | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsDamage | dd | 1 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsKnownShell | dd | 0FFFFFFFFh | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsSkipPlayer | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsSkipAI | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsPlayerGlass | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsPlayerSaw | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsPlayerBeer | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsPlayerCuffs | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsAIGlass | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsAISaw | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsAIBeer | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsAICuffs | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsTarget | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsShell | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsAction | dd | 0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| 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 | 20 dup(0) | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Объявлено как массив/буфер. | +| durakAIHand | dd | 20 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) | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Объявлено как массив/буфер. | +| skillNeedle | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillDir | dd | 1 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillSuccessStart | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillSuccessEnd | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillPerfectPos | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillGaugeIndex | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillFrameCount | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillHits | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillMisses | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillResult | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillPerfects | dd | 0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillDelay | dd | 45 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| casinoSuspicion | dd | 0 | Подозрение казино | Уровень подозрения казино и связанные сообщения/штрафы. | +| stressLevel | dd | 0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. | +| lastGameResult | dd | 0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. | +| tournamentStage | dd | 0 | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. | +| tournamentMode | dd | 0 | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. | +| pulseCycles | dd | 0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. | +| rankCounts | db | 13 dup(0) | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Объявлено как массив/буфер. | +| suitCounts | db | 4 dup(0) | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Объявлено как массив/буфер. | +| nl | db | 13,10,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. | +| dotSpaceText | db | ". ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| clearLines | db | 13,10,13,10,13,10,13,10,13,10,13,10,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. | +| titleText | db | "==============================",13,10 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| menuText | db | "1. Магазин",13,10 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| choiceText | db | "Выбор: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| badChoiceText | db | "Нет такого пункта.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| accountMenuText | db | "1. Войти в аккаунт",13,10 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| accountPromptText | db | "Введите имя аккаунта латиницей: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| accountBadText | db | "Имя должно содержать хотя бы одну букву или цифру.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| accountLoginText | db | "Аккаунт загружен: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| accountCreateText | db | "Аккаунт создан: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| accountListTitle | db | "Выберите аккаунт:",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| accountNoFilesText | db | "Сохраненных аккаунтов пока нет.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| accountSelectText | db | "Номер аккаунта: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| pauseText | db | 13,10,"Нажмите любую клавишу...",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| bankText | db | "Ваш банк: $",0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| betText | db | "Введите ставку: $",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| betChosenText | db | "Вы поставили $",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| badBetText | db | "Ставка должна быть числом больше 0.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| tooBigBetText | db | "У вас нет столько денег.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| suspicionText | db | "Подозрение казино: ",0 | Подозрение казино | Уровень подозрения казино и связанные сообщения/штрафы. Это строка или фрагмент ASCII-графики. | +| suspicionCalmText | db | "тихо",13,10,0 | Подозрение казино | Уровень подозрения казино и связанные сообщения/штрафы. Это строка или фрагмент ASCII-графики. | +| suspicionWatchText | db | "за тобой смотрят",13,10,0 | Подозрение казино | Уровень подозрения казино и связанные сообщения/штрафы. Это строка или фрагмент ASCII-графики. | +| suspicionHuntText | db | "охрана рядом",13,10,0 | Подозрение казино | Уровень подозрения казино и связанные сообщения/штрафы. Это строка или фрагмент ASCII-графики. | +| suspicionUpText | db | "Подозрение выросло.",13,10,0 | Подозрение казино | Уровень подозрения казино и связанные сообщения/штрафы. Это строка или фрагмент ASCII-графики. | +| suspicionFineText | db | "Охрана заметила мутную игру. Штраф: $",0 | Подозрение казино | Уровень подозрения казино и связанные сообщения/штрафы. Это строка или фрагмент ASCII-графики. | +| stressText | db | "Стресс ставки: ",0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| stressLowText | db | "спокойно",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| stressMidText | db | "пульс растет",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| stressHighText | db | "руки дрожат",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| stressMaxText | db | "паника",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| cheatMoveText | db | "Шулерство: 3 - подсмотреть, 4 - подменить карту.",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatPeekText | db | "Ты незаметно подсмотрел карту:",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatSwapText | db | "Ты подменил карту под рукавом.",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatNoTargetText | db | "Сейчас нечего подменять.",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| tournamentTitle | db | 13,10,"--- Турнир-башня ---",13,10,0 | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| tournamentIntro | db | "Башня казино: 10 этапов подряд. Проиграл этап - начинаешь заново.",13 | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| tournamentStageText | db | 13,10,"Этап башни: ",0 | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| tournamentFailText | db | 13,10,"Башня обрушилась. Турнир начинается заново.",13,10,0 | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| tournamentWinText | db | 13,10,"ТЫ ВЗЯЛ БАШНЮ КАЗИНО! Финальный бонус: $50000",13,10,0 | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| tournamentFire1 | db | 13,10," . * .",13,10," ASSEMBLER CASI | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| tournamentFire2 | db | 13,10," * \ | / \ | / *",13,10," -- TOWER CLEARED - | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| tournamentFire3 | db | 13,10," * . * . * . * . * . * . *",13,10," $$$ FIREWORKS $$$", | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| tournamentFire4 | db | 13,10," ============ JACKPOT SKY ============",13,10," * * | Турнир-башня | Этап башни, режим турнира или финальная анимация победы. Это строка или фрагмент ASCII-графики. | +| cheatAppliedText | db | "CHEAT ACTIVATED: ",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatBadText | db | "Unknown cheat code.",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatMoneyText | db | "+$50000",13,10,0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| cheatSevenText | db | "+$7777",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatWinText | db | "next loss becomes win",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatGodText | db | "losses become wins",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatFairText | db | "fair play restored",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatGoalText | db | "bank moved to current goal",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatResetText | db | "bank reset to $10000",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatEasyText | db | "AI difficulty EASY",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatNormalText | db | "AI difficulty NORMAL",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatHardText | db | "AI difficulty HARD",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatJackpotText | db | "next slot spin is forced jackpot",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| cheatRichText | db | "+$250000",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatDoubleText | db | "bank doubled",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatPoorText | db | "bank set to $1",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatShopText | db | "+$30000 for shop",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatBacksText | db | "all card backs unlocked",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCharmText | db | "luck talisman maxed",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatNoCharmText | db | "luck talisman removed",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatAchText | db | "all achievements unlocked",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatSavedText | db | "CHEAT: loss changed into win.",13,10,0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeMoney | db | "MONEYRAIN",0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| cheatCodeSeven | db | "SEVENS",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeWin | db | "WINNEXT",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeGod | db | "GODMODE",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeFair | db | "FAIRPLAY",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeGoal | db | "GOAL",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeReset | db | "RESETBANK",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeEasy | db | "EASYAI",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeNormal | db | "NORMALAI",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeHard | db | "HARDAI",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeJackpot | db | "JACKPOT",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| cheatCodeRich | db | "HIGHROLLER",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeDouble | db | "DOUBLECASH",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodePoor | db | "ONEBUCK",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeShop | db | "SHOPPING",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeBacks | db | "ALLBACKS",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeCharm | db | "MAXCHARM",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeNoCharm | db | "NOCHARM",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| cheatCodeAch | db | "ACHIEVER",0 | Чит-коды | Буфер, флаг или текст чит-кода. Это строка или фрагмент ASCII-графики. | +| moneyWinText | db | "Выигрыш: +$",0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| moneyLoseText | db | "Проигрыш: -$",0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| moneyDrawText | db | "Ставка возвращается.",13,10,0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| casinoKickText | db | 13,10,"У вас не осталось денег. Вас выводят из казино.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| casinoExitText | db | "Нажмите любую клавишу, чтобы выйти...",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| welcomeText | db | 13,10,"Добро пожаловать в ASSEMBLER CASINO!",13,10,"Удача любит смелых | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| difficultyText | db | 13,10,"Сложность AI: 1 - Easy, 2 - Normal, 3 - Hard: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| difficultyNowText | db | "Сложность AI: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| easyName | db | "Easy",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| normalName | db | "Normal",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| hardName | db | "Hard",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| statsGamesText | db | "Игр сыграно: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| statsWinsText | db | "Побед: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| statsLossText | db | "Поражений: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| statsDrawText | db | "Ничьих: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| statsBestWinText | db | "Макс. выигрыш: $",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| statsBestLossText | db | "Макс. проигрыш: $",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| statsByGameTitle | db | 13,10,"--- Статистика и лидеры казино ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| statsLinePlayed | db | " игр: ",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsLineWins | db | " побед: ",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsLineLoss | db | " поражений: ",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsLineDraw | db | " ничьих: ",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| leaderCurrentTitle | db | "Текущий аккаунт:",13,10,0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderTitle | db | 13,10,"Лидеры среди всех аккаунтов:",13,10,0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderNoDataText | db | "Нет сохранений аккаунтов.",13,10,0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderBankText | db | "Самый большой банк: ",0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| leaderWinsText | db | "Больше всего побед: ",0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderLossText | db | "Больше всего поражений: ",0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderGameTitle | db | 13,10,"Лидеры по играм:",13,10,0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderGameWinText | db | " победы: ",0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderGameLossText | db | " поражения: ",0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderDashText | db | "-",0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderOpenText | db | " (",0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderCloseText | db | ")",0 | Лидеры | Данные таблицы лидеров по аккаунтам и играм. Это строка или фрагмент ASCII-графики. | +| leaderMoneyPrefix | db | "$",0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| statsGame21 | db | "21 / Очко",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGamePoker | db | "Poker",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameClover | db | "CloverPit",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameRR | db | "Русская рулетка",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameSkulls | db | "Черепа",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameCoin | db | "Орел/решка",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameDice | db | "Кости",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameCasinoRoulette | db | "Казино-рулетка",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| statsGameClassicSlot | db | "Slot machine",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameDurak | db | "Дурак",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameSkillCheck | db | "Крюк: Skill Check",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| statsGameNames | dd | OFFSET statsGame21, OFFSET statsGamePoker, OFFSET statsGameClover, OFF | Прочее | Служебная переменная или строка, используемая внутри игровой логики. | +| bankRecoveredText | db | "После прошлого визита казино выдало новый стартовый банк: $10000",13, | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| goalText | db | "Цель игры: довести банк до $",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| victoryText | db | 13,10,"+====================================+",13,10 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| victoryReachedText | db | "Ты поднял банк до $",0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| victoryTailText | db | "Охрана уже нервничает.",13,10 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| victoryExitText | db | "Нажмите любую клавишу, чтобы продолжить игру...",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| nextGoalText | db | "Следующая цель: $",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| croupierPrefix | db | 13,10,"Крупье: ",0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierWin1 | db | "Красиво. Фишки идут к вам.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierWin2 | db | "Стол сегодня явно на вашей стороне.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierWin3 | db | "Хороший удар по банку казино.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierLose1 | db | "Казино забирает ставку.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierLose2 | db | "Не лучший расклад, но вечер еще живой.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierLose3 | db | "Фишки уходят со стола.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierDraw1 | db | "Ставка остается при вас.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierDraw2 | db | "Никто не сдвинул банк. Играем дальше.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierDraw3 | db | "Ровно. Без победителя.",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| croupierWinList | dd | OFFSET croupierWin1, OFFSET croupierWin2, OFFSET croupierWin3 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| croupierLoseList | dd | OFFSET croupierLose1, OFFSET croupierLose2, OFFSET croupierLose3 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| croupierDrawList | dd | OFFSET croupierDraw1, OFFSET croupierDraw2, OFFSET croupierDraw3 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. | +| dealerFileName | db | "dealer_phrases.txt",0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| pulseTitleText | db | 13,10,"Пульс ставки:",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| pulseFrame1 | db | " _/\_ спокойно",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| pulseFrame2 | db | " _/\/\_ напряжение",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| pulseFrame3 | db | " _/\/\/\_ риск",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| pulseFrame4 | db | " _/\/\/\/\_ сердце колотится",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| pulseFrame5 | db | " _/\/\_/\_ вдох...",13,10,0 | Стресс ставки | Уровень стресса и кадры ЭКГ-пульса при рискованной ставке. Это строка или фрагмент ASCII-графики. | +| observerTitle | db | 13,10,"--- Наблюдатель AI vs AI ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerIntro | db | "AI-1 и AI-2 играют 5 быстрых раундов в 21 без ставок.",13,10,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| observerRoundText | db | 13,10,"Раунд ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerAI1Text | db | "AI-1 очки: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerAI2Text | db | "AI-2 очки: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerWin1Text | db | "AI-1 забирает раунд.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerWin2Text | db | "AI-2 забирает раунд.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerDrawText | db | "Ничья между железками.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerDoneText | db | 13,10,"Наблюдение окончено.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerMenuText | db | "1. Русская рулетка",13,10 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observer21Title | db | 13,10,"--- AI vs AI: 21 / Очко ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerPokerTitle | db | 13,10,"--- AI vs AI: Poker ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerDurakTitle | db | 13,10,"--- AI vs AI: Дурак ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerRRTitle | db | 13,10,"--- AI vs AI: Русская рулетка ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerAI1CardsText | db | 13,10,"Карты AI-1:",13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| observerAI2CardsText | db | 13,10,"Карты AI-2:",13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| observerAI1RaiseText | db | "AI-1 повышает ставку.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerAI2RaiseText | db | "AI-2 повышает ставку.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerCallText | db | "Соперник отвечает.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerFold1Text | db | "AI-1 делает фолд.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerFold2Text | db | "AI-2 делает фолд.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerShotAI1Text | db | "Выстрел достался AI-1. Победил AI-2.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| observerShotAI2Text | db | "Выстрел достался AI-2. Победил AI-1.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| shopMainMenuText | db | "1. Рубашки карт",13,10 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackTitle | db | 13,10,"--- Магазин: рубашки карт ---",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmTitle | db | 13,10,"--- Магазин: талисманы ---",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackMenuText | db | "1. Синяя рубашка карт - $3000",13,10 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmMenuText | db | "1. Талисман Клевер: 7%, 3 заряда - $12000",13,10 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopTitle | db | 13,10,"--- Магазин казино ---",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopMenuText | db | "1. Синяя рубашка карт - $3000",13,10 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackText | db | "Текущая рубашка: ",0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackGray | db | "Серая",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackBlue | db | "Синяя волна",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackRed | db | "Красный крест",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackGold | db | "Золотой блеск",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackSkull | db | "Череп",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackClover | db | "CloverPit",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackArcane | db | "Arcane",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackNoir | db | "Noir",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackDiamond | db | "Diamond",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackRider | db | "Rider",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackBee | db | "Bee",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackFan | db | "Fan",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBackWeb | db | "Web",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmText | db | "Талисман: ",0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmNone | db | "нет",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmClover | db | "Клевер",0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmBell | db | "Колокол",0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmDiamond | db | "Алмаз",0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmUsesText | db | ", зарядов: ",0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopBoughtText | db | "Покупка выполнена.",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopSelectedText | db | "Рубашка выбрана.",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmBurnText | db | "Талисман сгорел.",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| shopCharmSaveText | db | 13,10,"Талисман вспыхнул и спас ставку!",13,10,0 | Магазин | Рубашки карт, талисманы, цены, названия и состояние покупок. Это строка или фрагмент ASCII-графики. | +| achMenuTitle | db | 13,10,"--- Достижения ---",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achPopupTop | db | 13,10,"+--------------------------------------+",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achPopupTitle | db | "| ДОСТИЖЕНИЕ ОТКРЫТО |",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achPopupLeft | db | "| ",0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achPopupBottom | db | "+--------------------------------------+",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achDoneText | db | "[x] ",0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achTodoText | db | "[ ] ",0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achFirstWinName | db | "Первый выигрыш",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achFirstLossName | db | "Первый проигрыш",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achJackpotName | db | "Джекпот пойман",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| achHighRollerName | db | "Большая ставка",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achShopperName | db | "Покупатель казино",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achCharmName | db | "Талисман сработал",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achGoalName | db | "Цель достигнута",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achCloverPitName | db | "CloverPit разогрелся",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achClassicSlotName | db | "Старый автомат платит",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achPokerRaiseName | db | "Ставка повышена",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achPokerBluffName | db | "Блеф сработал",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achRouletteWinName | db | "Колесо судьбы",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| achRussianWinName | db | "Сухой щелчок",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achDurakWinName | db | "Не дурак",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achBackCollectorName | db | "Коллекционер рубашек",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achCharmBuyerName | db | "Талисман в кармане",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achObserverName | db | "Ложа наблюдателя",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achSkillCheckName | db | "С крюка сорвался",13,10,0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achievementFileName | db | "achievement.txt",0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| achievementCmd | db | "cmd /c start ""Achievement"" achievement_popup.bat",0 | Достижения | Файл, команда, маска или название достижения. Это строка или фрагмент ASCII-графики. | +| skillTitle | db | 13,10,"--- Крюк: Skill Check ---",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillIntro | db | "Попадай по зеленой зоне. PERFECT дает двойной прогресс.",13,10 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillHookArt | db | 13,10 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. | +| skillStateText | db | "Состояние: ",0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillStateGood | db | "держишься",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillStateWarn | db | "цепь скрипит",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillStateBad | db | "тьма рядом",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillProgressText | db | "Прогресс побега: ",0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillMissText | db | "Промахи: ",0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillGaugeHint | db | 13,10,"Шкала:",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillGaugeLeft | db | "[",0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillGaugeRight | db | "]",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillGaugeEmpty | db | "-",0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillGaugeSuccess | db | "#",0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillGaugePerfect | db | "@",0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillGaugeNeedle | db | "|",0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillSuccessText | db | 13,10,"Успех. Ты удержался на крюке.",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillPerfectText | db | 13,10,"PERFECT! Рывок почти сорвал крюк.",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillFailText | db | 13,10,"Промах. Крюк дернул сильнее.",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillEscapeText | db | 13,10,"Ты сорвался с крюка и вырвался из тумана!",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| skillDarkText | db | 13,10,"Тьма забрала тебя. Ставка сгорела.",13,10,0 | Skill Check | Положение указателя, зеленая зона, промахи, попадания и скорость шкалы. Это строка или фрагмент ASCII-графики. | +| coinTitle | db | 13,10,"--- Орел и решка ---",13,10,0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinIntroText | db | "Угадай сторону монеты. Победа дает выигрыш размером со ставку.",13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinChoiceText | db | "1 - Орел, 2 - Решка: ",0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinSpinText | db | "Монета летит...",13,10,0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinFrame1 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame2 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame3 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame4 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame5 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame6 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame7 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame8 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame9 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame10 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame11 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame12 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame13 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinFrame14 | db | 13,10 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. | +| coinPickText | db | "Ты выбрал: ",0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinResultText | db | "Выпало: ",0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinHeadsText | db | "Орел",13,10,0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinTailsText | db | "Решка",13,10,0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| diceTitle | db | 13,10,"--- Кости ---",13,10,0 | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| diceIntroText | db | "Угадай четность суммы двух костей. Победа дает выигрыш размером со ст | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| diceChoiceText | db | "1 - чет, 2 - нечет: ",0 | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| diceRollText | db | "Кости летят по столу...",13,10,0 | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| diceFirstText | db | "Первая кость: ",0 | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| diceSecondText | db | "Вторая кость: ",0 | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| diceSumText | db | "Сумма: ",0 | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| diceEvenText | db | "Чет",13,10,0 | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| diceOddText | db | "Нечет",13,10,0 | Кости | Броски костей, сумма или выбранная четность. Это строка или фрагмент ASCII-графики. | +| casinoRouletteTitle | db | 13,10,"--- Казино-рулетка ---",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteIntro | db | "Европейское колесо: 0 зеленый, половина чисел красные, половина черны | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteBetMenu | db | "1 - число 0-36",13,10 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteNumberAsk | db | "Введите число 0-36: ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteBadNumber | db | "В рулетке есть только числа от 0 до 36.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteSpinText | db | "Шарик скачет по карманам колеса... Итоговый карман прямо под стрелкой | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteResultText | db | 13,10,"Шарик остановился на: ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteWinText | db | "Ставка сыграла.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteLoseText | db | "Ставка не сыграла.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteWheelTop | db | " =============================================================", | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteWheelBottom | db | " =============================================================", | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRoulettePad | db | " ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteBigSidePad | db | " ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteBigSideGap1 | db | " .-------------------------------------------------. ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteBigSideGap2 | db | " / .-------------------------------------. \ ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteBigSideGap3 | db | " | / . . . . . . . . . . . . . . \ | ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteBigSideGap4 | db | " | | \\ | // ( O ) \\ | | ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteBigSideGap5 | db | " | | // | \\ --+-- // | | ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteBigSideGap6 | db | " | \ . . . . . . . . . . . . \ | | ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| roulettePocketLeft | db | "[",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| roulettePocketRight | db | "] ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteNumSpace | db | " ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteRedName | db | "красное",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteBlackName | db | "черное",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteGreenName | db | "зеленый ноль",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rouletteWheel | dd | 0,32,15,19,4,21,2,25,17,34,6,27,13,36,11,30,8,23,10 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| rouletteColors | db | 0,1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| bankLevelText | db | "Уровень банка: ",0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| bankLevelNewbie | db | "Новичок",13,10,0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| bankLevelPlayer | db | "Игрок",13,10,0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| bankLevelHigh | db | "Хайроллер",13,10,0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| bankLevelLegend | db | "Легенда казино",13,10,0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| hitText | db | "Взять карту? (y/n): ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| againText | db | "Сыграть еще? (y/n): ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| yourCardText | db | 13,10,"Твоя карта:",13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| dealerCardText | db | 13,10,"Карта дилера:",13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| aiThinkText | db | 13,10,"AI думает...",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| aiMoveText | db | 13,10,"AI берет карту!",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| aiCardsText | db | 13,10,"Карты AI:",13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| playerCardsText | db | 13,10,"Твои карты:",13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| yourScoreText | db | "Твои очки: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| dealerScoreText | db | "Очки дилера: ",0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| aiScoreText | db | "Очки AI: ",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| bustText | db | "Перебор. Ты проиграл.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| dealerBustText | db | "У дилера перебор. Ты выиграл!",13,10,0 | Крупье | Фразы крупье, чтение dealer_phrases.txt или выбор реплики. Это строка или фрагмент ASCII-графики. | +| winText | db | "Ты выиграл!",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| loseText | db | "Ты проиграл.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| drawText | db | "Ничья.",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| blackjackText | db | "Blackjack!",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| twentyOneTitle | db | 13,10,"--- 21 / Очко ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| blackjackTitle | db | 13,10,"--- Blackjack ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| pokerTitle | db | 13,10,"--- Poker ---",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| slotTitle | db | 13,10,"--- CloverPit ---",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlotTitle | db | 13,10,"--- Slot machine ---",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| durakTitle | db | 13,10,"--- Дурак ---",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakInfoText | db | "Козырь: ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakDeckText | db | "Карт в колоде: ",0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| durakAICardsText | db | "Карт у AI: ",0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| durakYourHandText | db | 13,10,"Твои карты:",13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| durakTableText | db | 13,10,"На столе: ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakAttackAsk | db | "Выбери карту для атаки: ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakDefendAsk | db | "Чем бить? 0 - взять: ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakBadMoveText | db | "Так нельзя. Выбери другую карту.",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakAITakeText | db | "AI не смог отбиться и взял карту.",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakAIDefendText | db | "AI отбился картой: ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakAIAttackText | db | "AI атакует: ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakPlayerTakeText | db | "Ты взял карту.",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakPlayerDefendText | db | "Ты отбился.",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakWinText | db | "Ты вышел из игры без карт. Победа!",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakLoseText | db | "AI избавился от карт раньше тебя. Ты проиграл.",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| trainingTitle | db | 13,10,"--- Обучение ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| trainingText | db | "Главное: сначала выбери ставку. Если банк упадет до 0, казино выведет | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| durakDeckVisualText | db | "Колода: [рубашка], из-под нее торчит козырь ",0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| durakAIFaceText | db | 13,10,"Карты AI:",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakThrowAsk | db | "Подкинуть карту? 0 - бито: ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakTransferText | db | "Перевод! Ход переходит обратно.",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakTablePairsText | db | 13,10,"Карты на столе:",13,10,0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakSlashText | db | " / ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| durakUnbeatenText | db | " _ ",0 | Дурак | Карты, козырь, стол атаки/защиты, ход и временные руки в игре Дурак. Это строка или фрагмент ASCII-графики. | +| skullsTitle | db | 13,10,"--- Черепа и шарик ---",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsIntroText | db | "Следи за шариком. Выплата за победу: x2.",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsShowText | db | "Смотри внимательно: шарик сейчас здесь.",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsHideText | db | "Черепа закрывают шарик...",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsShuffleText | db | "Черепа скользят по столу...",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsGuessText | db | "Где шарик? 1 / 2 / 3: ",0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsWinText | db | "Верно! Шарик найден.",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsLoseText | db | "Мимо. Шарик был под другим черепом.",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsBallText | db | "Шарик был под черепом ",0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsSwap12Text | db | " \\______/",13,10," / \",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsSwap23Text | db | " \\______/",13,10," / | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullsSwap13Text | db | " \\____________________/",13,10," / | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| rouletteTitle | db | 13,10,"--- Русская рулетка ---",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrIntroText | db | "Барабан на 6 камер. Easy: 1 опасная, Normal: 2, Hard: 3.",13,10,"AI и | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrDangerText | db | "Опасных камер в барабане: ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrSpinText | db | "Барабан вращается... ",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrSpin1 | db | "|",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrSpin2 | db | "/",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrSpin3 | db | "-",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrSpin4 | db | "\\",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrStartsPlayerText | db | "Револьвер остановился на тебе. Ты стреляешь первым.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrStartsAIText | db | "Револьвер остановился на AI. Он стреляет первым.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrPlayerTurnText | db | "Твой ход. Нажми любую клавишу, чтобы нажать на спуск...",0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrAITurnText | db | "Ход AI. Он поднимает револьвер...",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrClickText | db | "Щелчок. Пусто.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrBangText | db | "БАХ!",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrPlayerLoseText | db | "Тебе не повезло. Ставка уходит казино.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrAIShotText | db | "AI выбыл. Ты пережил эту партию.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrPayoutText | db | "Выплата рулетки зависит от сложности.",13,10,0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| buckshotTitle | db | 13,10,"--- Buckshot Roulette ---",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| buckshotIntro | db | "Дробовик заряжен живыми и холостыми патронами в неизвестном порядке." | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| bsShotgunArt | db | 13,10 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsShotgunLoad1 | db | 13,10 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsShotgunLoad2 | db | 13,10 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsShotgunLoad3 | db | 13,10 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsShotgunFire | db | 13,10 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsShotgunDry | db | 13,10 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. | +| bsHPText | db | "HP: ты ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsAIHPText | db | " / AI ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsShellInfoText | db | "Патроны в раунде: ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsLiveText | db | " живых, ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsBlankText | db | " холостых",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsLeftText | db | "Осталось в дробовике: ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsKnownUnknownText | db | "Текущий патрон: неизвестно",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsKnownLiveText | db | "Текущий патрон: ЖИВОЙ",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsKnownBlankText | db | "Текущий патрон: холостой",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsItemsText | db | "Предметы: лупа ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsSawText | db | ", пила ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsBeerText | db | ", пиво ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsCuffsText | db | ", наручники ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsMenuText | db | 13,10,"1. Стрелять в себя",13,10 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsLoadText | db | 13,10,"Крупье заряжает дробовик...",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsLiveLoadedText | db | "Живой патрон",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsBlankLoadedText | db | "Холостой патрон",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsPlayerTurnText | db | 13,10,"Твой ход.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsAITurnText | db | 13,10,"Ход AI...",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsShootPlayerText | db | "Выстрел в тебя.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsShootAIText | db | "Выстрел в AI.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsDryText | db | "Щелчок. Холостой.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsHitText | db | "БАХ! Урон: ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsGlassUseText | db | "Лупа показывает патрон.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsSawUseText | db | "Пила надрезает ствол. Следующий живой выстрел сильнее.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsBeerUseText | db | "Пиво. Патрон вылетает из дробовика: ",0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsCuffsUseText | db | "Наручники защелкнулись. AI пропустит ход.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsNoItemText | db | "Этого предмета нет.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsAISawText | db | "AI использует пилу.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsAIGlassText | db | "AI смотрит патрон через лупу.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsAIBeerText | db | "AI выбрасывает патрон пивом.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsAICuffsText | db | "AI надевает на тебя наручники.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsSkipPlayerText | db | "Ты в наручниках и пропускаешь ход.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsSkipAIText | db | "AI в наручниках и пропускает ход.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsWinText | db | "AI падает. Ты забираешь банк стола.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| bsLoseText | db | "Ты падаешь. Крупье забирает ставку.",13,10,0 | Buckshot Roulette | Состояние дробовика: патроны, здоровье, предметы, цель и текущий ход. Это строка или фрагмент ASCII-графики. | +| rrGunUp | db | 117,117,36,96,36,36,36,117,117,36,36,36,13,10 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| 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,3 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| 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,3 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| rrGunDownLeft | db | 32,32,32,32,32,32,62,36,13,10 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| rrGunDown | db | 62,36,36,36,36,36,36,42,36,36,36,43,34,96,96,13,10 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| 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,3 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| 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,3 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| 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, | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. | +| pokerReplaceText | db | "Поменять карту ",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerReplaceTail | db | "? (y/n): ",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerAIExchangeText | db | 13,10,"AI думает над обменом...",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerRevealText | db | 13,10,"AI вскрывает покерную руку...",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerYourComboText | db | "Твоя комбинация: ",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerAIComboText | db | "Комбинация AI: ",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerTableText | db | 13,10,"Карты на столе:",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerHintText | db | "Подсказка: сейчас у тебя ",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerDecisionText | db | "1 - играть, 2 - повысить ставку, 0 - фолд: ",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerPotText | db | "Банк раунда: $",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerBetText | db | "Твоя текущая ставка: $",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerChipTitle | db | "Фишки:",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerChipHigh | db | " [###]",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerChipMid | db | " [===]",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerChipLow | db | " [___]",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerRaiseAskText | db | "На сколько повысить ставку: $",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerRaisedText | db | "Ты повысил ставку. Новая ставка: $",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerBadRaiseText | db | "Повышение должно быть больше 0 и не больше твоего банка.",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerAICallRaiseText | db | 13,10,"AI отвечает на ставку.",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerAIFoldRaiseText | db | 13,10,"AI не принимает повышение и делает фолд. Ты выиграл!",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerHardIntroText | db | "Hard Poker: один раз можно заменить одну карманную карту.",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerHardExchangeText | db | "Заменить карту? 1 - первую, 2 - вторую, 0 - не менять: ",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerHardAIExchangeText | db | 13,10,"AI пересматривает карманные карты...",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerAIRaiseText | db | 13,10,"AI повышает ставку на $",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerCallRaiseText | db | "Ответить? 1 - колл, 0 - фолд: ",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerPlayerCallText | db | "Ты ответил на повышение. Новая ставка: $",0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerFoldToRaiseText | db | 13,10,"Ты сбросил карты после повышения AI.",13,10,"Ты проиграл.",13,1 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerFoldText | db | 13,10,"Ты сделал фолд.",13,10,"Ты проиграл.",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerAIFoldText | db | 13,10,"AI сделал фолд. Ты выиграл!",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerNextCardText | db | 13,10,"Открывается следующая карта...",13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| pokerHighName | db | "Старшая карта",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerPairName | db | "Пара",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerTwoPairName | db | "Две пары",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerTripsName | db | "Тройка",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerStraightName | db | "Стрит",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerFlushName | db | "Флеш",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerFullHouseName | db | "Фулл хаус",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerFourName | db | "Каре",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| pokerStraightFlushName | db | "Стрит-флеш",13,10,0 | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. Это строка или фрагмент ASCII-графики. | +| slotPullText | db | "Крутим барабаны...",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotLeft | db | "[ ",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotMid | db | " ] [ ",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotRight | db | " ]",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotJackpot | db | "Джекпот!",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotPair | db | "Комбинация сыграла!",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotPayoutText | db | "Выплата x",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotPayTableText | db | "Символы: LEM/CHR x2, CLV/BEL x3, DIA/BOX x5, 777 x7.",13,10 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotEmpty | db | "Не повезло.",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboText | db | "Комбинация: ",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotMultiplierText | db | "Множитель: x",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotTotalMultiplierText | db | "Итоговый множитель: x",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboHorM | db | "Гор. M",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboVertM | db | "Верт. M",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboDiagM | db | "Диаг. M",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboHorL | db | "Гор. L",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboHorXL | db | "Гор. XL",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboUp | db | "Вверх",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboDown | db | "Вниз",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboSky | db | "Небо",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboEarth | db | "Земля",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboEye | db | "Глаз",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotComboJackpot | db | "Джекпот",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| cardTop | db | 0E2h, 094h, 08Ch, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. | +| cardBottom | db | 0E2h, 094h, 094h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. | +| cardEmpty | db | 0E2h, 094h, 082h, " ", 0E2h, 094h, 082h, 13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardSuitLeft | db | 0E2h, 094h, 082h, " ", 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardSuitRight | db | " ", 0E2h, 094h, 082h, 13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardRankOneL | db | 0E2h, 094h, 082h, " ", 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardRankOneR | db | " ", 0E2h, 094h, 082h, 13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardRankTenL | db | 0E2h, 094h, 082h, " ", 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardRankTenR | db | " ", 0E2h, 094h, 082h, 13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardCenterL | db | 0E2h, 094h, 082h, " ", 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardCenterR | db | " ", 0E2h, 094h, 082h, 13,10,0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardTopSeg | db | 0E2h, 094h, 08Ch, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. | +| cardBottomSeg | db | 0E2h, 094h, 094h, 0E2h, 094h, 080h, 0E2h, 094h, 080h, 0E2h, 094h, 080h | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. | +| cardEmptySeg | db | 0E2h, 094h, 082h, " ", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardBackSeg | db | 0E2h, 094h, 082h, 0E2h, 096h, 091h, 0E2h, 096h, 091h, 0E2h, 096h, 091h | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. | +| cardBackBlueSeg | db | 0E2h, 094h, 082h, "~~*~~*~~*", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardBackRedSeg | db | 0E2h, 094h, 082h, "XX+XX+XX+", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardBackGoldSeg | db | 0E2h, 094h, 082h, "$*$*$*$*$", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardBackSkullSeg | db | 0E2h, 094h, 082h, "|o",0E2h,098h,0A0h," v ",0E2h,098h,0A0h,"o|", 0E2h, | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardBackCloverSeg | db | 0E2h, 094h, 082h, "$+ ",0E2h,099h,0A3h,"$",0E2h,099h,0A3h," +$", 0E2h, | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| backGray1 | db | 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGray2 | db | 0E2h,094h,082h,"|#|#|#|#|",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGray3 | db | 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGray4 | db | 0E2h,094h,082h,"|#|#|#|#|",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGray5 | db | 0E2h,094h,082h,"+-+-+-+-+",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBlue1 | db | 0E2h,094h,082h,"\\==*==//",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBlue2 | db | 0E2h,094h,082h,"/ ___ /",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBlue3 | db | 0E2h,094h,082h,"| (@@@) |",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBlue4 | db | 0E2h,094h,082h,"/ ~~~ /",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBlue5 | db | 0E2h,094h,082h,"//==*==//",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRed1 | db | 0E2h,094h,082h,"ooooooooo",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRed2 | db | 0E2h,094h,082h,"oXXXxXXXo",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRed3 | db | 0E2h,094h,082h,"oXX---XXo",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRed4 | db | 0E2h,094h,082h,"oXXXxXXXo",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRed5 | db | 0E2h,094h,082h,"ooooooooo",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGold1 | db | 0E2h,094h,082h,"{$*$$$*$}",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGold2 | db | 0E2h,094h,082h,"*/^ $ ^/*",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGold3 | db | 0E2h,094h,082h,"$ <@@@> $",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGold4 | db | 0E2h,094h,082h,"*v/ $ /v*",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backGold5 | db | 0E2h,094h,082h,"{$*$$$*$}",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backSkull1 | db | 0E2h,094h,082h,"._.---._.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backSkull2 | db | 0E2h,094h,082h,"/,(o o),\",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backSkull3 | db | 0E2h,094h,082h,"| ^ |",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backSkull4 | db | 0E2h,094h,082h,"\ '-=-' /",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backSkull5 | db | 0E2h,094h,082h,"~|==|==|~",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backClover1 | db | 0E2h,094h,082h,"+o+$$$+o+",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backClover2 | db | 0E2h,094h,082h,"o ",0E2h,098h,098h," + ",0E2h,098h,098h," o",0E2h,094h | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backClover3 | db | 0E2h,094h,082h,"$+ ",0E2h,099h,0A3h,"$",0E2h,099h,0A3h," +$",0E2h,094h | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backClover4 | db | 0E2h,094h,082h,"o ",0E2h,098h,098h," | ",0E2h,098h,098h," o",0E2h,094h | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backClover5 | db | 0E2h,094h,082h,"+o+$$$+o+",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backArcane1 | db | 0E2h,094h,082h,".~*~*~*~.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backArcane2 | db | 0E2h,094h,082h,"/__~_~__\",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backArcane3 | db | 0E2h,094h,082h,"|_/\/\_ |",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backArcane4 | db | 0E2h,094h,082h,"| \_/\_/|",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backArcane5 | db | 0E2h,094h,082h,"'--===--'",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backNoir1 | db | 0E2h,094h,082h,"((\\_//))",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backNoir2 | db | 0E2h,094h,082h,"// | \\",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backNoir3 | db | 0E2h,094h,082h,"--(#*#)--",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backNoir4 | db | 0E2h,094h,082h,"\\__|__//",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backNoir5 | db | 0E2h,094h,082h,"((//~\\))",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backDiamond1 | db | 0E2h,094h,082h,"<><###><>",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backDiamond2 | db | 0E2h,094h,082h,"/\ /\",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backDiamond3 | db | 0E2h,094h,082h,"*$*",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backDiamond4 | db | 0E2h,094h,082h,"\/ \/",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backDiamond5 | db | 0E2h,094h,082h,"<><###><>",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRider1 | db | 0E2h,094h,082h,".oO===Oo.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRider2 | db | 0E2h,094h,082h,"(/ .-. /)",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRider3 | db | 0E2h,094h,082h,"o-( @ )-o",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRider4 | db | 0E2h,094h,082h,"(/ '-' /)",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backRider5 | db | 0E2h,094h,082h,"'oO===Oo'",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBee1 | db | 0E2h,094h,082h,"<>.<>.<>.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBee2 | db | 0E2h,094h,082h,".<>.<><>.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBee3 | db | 0E2h,094h,082h,"<> BEE <>",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBee4 | db | 0E2h,094h,082h,".<>.<><>.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backBee5 | db | 0E2h,094h,082h,"<>.<>.<>.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backFan1 | db | 0E2h,094h,082h,"\\|/\\|//",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backFan2 | db | 0E2h,094h,082h," -\\|//- ",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backFan3 | db | 0E2h,094h,082h,"<(( o ))>",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backFan4 | db | 0E2h,094h,082h," -//|\\- ",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backFan5 | db | 0E2h,094h,082h,"//|/|/|\\",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backWeb1 | db | 0E2h,094h,082h,"\\..|..//",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backWeb2 | db | 0E2h,094h,082h,".\\.|.//.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backWeb3 | db | 0E2h,094h,082h,"--(o-o)--",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backWeb4 | db | 0E2h,094h,082h,".//|.|\\.",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| backWeb5 | db | 0E2h,094h,082h,"//''-''\\",0E2h,094h,082h,0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| cardFlipLeft | db | 0E2h, 094h, 082h, " \ ", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardFlipMid | db | 0E2h, 094h, 082h, " | ", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardFlipRight | db | 0E2h, 094h, 082h, " / ", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardSuitRightSeg | db | " ", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardRankOneRSeg | db | " ", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardRankTenRSeg | db | " ", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardCenterRSeg | db | " ", 0E2h, 094h, 082h, 0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardGap | db | " ",0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| revealText | db | 13,10,"AI вскрывает карты...",13,10,0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| rank2 | db | "2",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rank3 | db | "3",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rank4 | db | "4",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rank5 | db | "5",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rank6 | db | "6",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rank7 | db | "7",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rank8 | db | "8",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rank9 | db | "9",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rank10 | db | "10",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rankJ | db | "J",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rankQ | db | "Q",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rankK | db | "K",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| rankA | db | "A",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| 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 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. | +| suits | dd | OFFSET suitSpades, OFFSET suitHearts, OFFSET suitClubs, OFFSET suitDia | Прочее | Служебная переменная или строка, используемая внутри игровой логики. | +| pokerNames | dd | OFFSET pokerHighName, OFFSET pokerPairName, OFFSET pokerTwoPairName | Покер | Временное состояние покера: оценка комбинаций, ставки, обмен карт или счетчики рангов/мастей. | +| slot0 | db | "CLV",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slot1 | db | "LEM",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slot2 | db | "CHR",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slot3 | db | "BEL",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slot4 | db | "DIA",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slot5 | db | "BOX",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slot6 | db | "777",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotSymbols | dd | OFFSET slot0, OFFSET slot1, OFFSET slot2 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. | +| slotSymbolValues | dd | 3, 2, 2, 3, 5, 5, 7 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. | +| classicSlot0 | db | "7",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlot1 | db | "BAR",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlot2 | db | "$",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlot3 | db | "*",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlot4 | db | "#",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlot5 | db | "A",0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlotSymbols | dd | OFFSET classicSlot0, OFFSET classicSlot1, OFFSET classicSlot2 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. | +| classicSlotPayTableText | db | "Классический слот 3x3. Выигрышная линия - средняя.",13,10 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlotJackpot | db | "Джекпот! Три одинаковых.",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlotPair | db | "Пара на линии!",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlotEmpty | db | "Не повезло.",13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlotBorder | db | '+-----+-----+-----+',13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| classicSlotPayline | db | '----- WIN LINE -----',13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| cardSoundClose | db | 'close cardsound',0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardSoundOpen | db | 'open "playing_cards_deck_flick_through_001_20485.wav" type waveaudio | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardSoundPlay | db | 'play cardsound from 0',0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| cardSoundStop | db | 'stop cardsound',0 | Карты | Состояние колоды, карт на руках, карт на столе или отображения карт. Это строка или фрагмент ASCII-графики. | +| slotSoundClose | db | 'close slotsound',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotSoundOpen | db | 'open "hKhoJArfEGAxxMewx0UQiddakTdBjFc.wav" type waveaudio alias slots | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotSoundPlay | db | 'play slotsound from 0',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotSoundStop | db | 'stop slotsound',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotIntroClose | db | 'close slotintro',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotIntroOpen | db | 'open "Летс гоу гэмблинг.wav" type waveaudio alias slotintro',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotIntroPlay | db | 'play slotintro from 0',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotIntroStop | db | 'stop slotintro',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| jackpotClose | db | 'close jackpotsound',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| jackpotOpen | db | 'open "Джэк пот.wav" type waveaudio alias jackpotsound',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| jackpotPlay | db | 'play jackpotsound from 0',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| jackpotStop | db | 'stop jackpotsound',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| hakariSoundClose | db | 'close hakarisound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| hakariSoundOpen | db | 'open "hakari_dance.wav" type waveaudio alias hakarisound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| hakariSoundPlay | db | 'play hakarisound from 0',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| hakariSoundStop | db | 'stop hakarisound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| coinSoundClose | db | 'close coinsound',0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinSoundOpen | db | 'open "Звук монеты брошенной в воздух и упавшей на поверхность.wav" ty | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinSoundPlay | db | 'play coinsound from 0',0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| coinSoundStop | db | 'stop coinsound',0 | Орел и решка | Выбор игрока, результат или кадр анимации монеты. Это строка или фрагмент ASCII-графики. | +| bankruptClose | db | 'close bankruptsound',0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| bankruptOpen | db | 'open "Проигрыш.wav" type waveaudio alias bankruptsound',0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| bankruptPlay | db | 'play bankruptsound from 0',0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| bankruptStop | db | 'stop bankruptsound',0 | Экономика | Банк игрока, цель, ставка или текст денежных операций. Это строка или фрагмент ASCII-графики. | +| victoryClose | db | 'close victorysound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| victoryOpen | db | 'open "victory-tf2.wav" type waveaudio alias victorysound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| victoryPlay | db | 'play victorysound from 0',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| victoryStop | db | 'stop victorysound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| rrSpinClose | db | 'close rrspinsound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrSpinOpen | db | 'open "toy-gun-revolver-close-chamber-spin_f1ruc5nd.wav" type waveaudi | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrSpinPlay | db | 'play rrspinsound from 0',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrSpinStop | db | 'stop rrspinsound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrDryClose | db | 'close rrdrysound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrDryOpen | db | 'open "revolverdryfirec.wav" type waveaudio alias rrdrysound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrDryPlay | db | 'play rrdrysound from 0',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrDryStop | db | 'stop rrdrysound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrShotClose | db | 'close rrshotsound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrShotOpen | db | 'open "b05e1ac8be34248.wav" type waveaudio alias rrshotsound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrShotPlay | db | 'play rrshotsound from 0',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| rrShotStop | db | 'stop rrshotsound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteSoundClose | db | 'close casinoroulettesound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteSoundOpen | db | 'open "roulette-wheel-throw-2.wav" type waveaudio alias casinoroulette | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteSoundPlay | db | 'play casinoroulettesound from 0',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| casinoRouletteSoundStop | db | 'stop casinoroulettesound',0 | Рулетка | Состояние русской или казино-рулетки: барабан, пули, колесо, ставка, результат. Это строка или фрагмент ASCII-графики. | +| stoneSoundClose | db | 'close stonesound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| stoneSoundOpen | db | 'open "moving-stone.wav" type waveaudio alias stonesound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| stoneSoundPlay | db | 'play stonesound from 0',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| stoneSoundStop | db | 'stop stonesound',0 | Звуки | MCI-команда или имя звукового ресурса. Это строка или фрагмент ASCII-графики. | +| slotBorder | db | '+-----+-----+-----+-----+-----+',13,10,0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotWall | db | '|',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotWinLeft | db | '>',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotWinRight | db | '<',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotCellBlank | db | ' ',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotPadTwo | db | ' ',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| slotPadOne | db | ' ',0 | Слоты | Состояние слот-машины: символы, видимые барабаны, выигрышные линии, множители и джекпот. Это строка или фрагмент ASCII-графики. | +| skullSeg1 | db | 020h, 020h, 020h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 088h, 0E2h, 096h | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullSeg2 | db | 020h, 020h, 0E2h, 096h, 084h, 0E2h, 096h, 088h, 0E2h, 096h, 080h, 020h | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullSeg3 | db | 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullSeg4 | db | 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 080h | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullSeg5 | db | 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h, 0E2h, 096h, 084h | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullSeg6 | db | 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 0E2h, 096h, 080h | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullSeg7 | db | 020h, 020h, 020h, 0E2h, 096h, 080h, 0E2h, 096h, 088h, 0E2h, 096h, 088h | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullSeg8 | db | 020h, 020h, 020h, 020h, 0E2h, 096h, 088h, 0E2h, 096h, 088h, 020h, 020h | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullNums | db | " [1] [2] [3]",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullBlankBall | db | 13,10,13,10,13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. | +| skullBall1 | db | " .***.",13,10," (* O *)",13,10," `***'",13,10,0 | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullBall2 | db | " .***.",13,10," (* O *)",13,10," | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| skullBall3 | db | " .***.",13,10," | Черепа и шарик | Позиция шарика, выбор игрока или параметры перемешивания черепов. Это строка или фрагмент ASCII-графики. | +| saveFileName | db | 64 dup(0) | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Объявлено как массив/буфер. | +| saveExt | db | '.dat',0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| accountPattern | db | "*.dat",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| danceFileName | db | "hakari_dance.ans",0 | Тексты интерфейса | Строка, которая выводится пользователю в меню, игре или результате. Это строка или фрагмент ASCII-графики. | +| casinoIntroFile | db | "casino_intro.ans",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| ansiExitIntro | db | 1Bh,"[0m",1Bh,"[?25h",1Bh,"[2J",1Bh,"[H",0 | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Это строка или фрагмент ASCII-графики. | +| accountList | db | 20 dup(64 dup(0)) | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Объявлено как массив/буфер. | +| findData | db | 320 dup(0) | Прочее | Служебная переменная или строка, используемая внутри игровой логики. Объявлено как массив/буфер. | \ No newline at end of file diff --git a/graphify-out/cost.json b/graphify-out/cost.json new file mode 100644 index 0000000..e5b4093 --- /dev/null +++ b/graphify-out/cost.json @@ -0,0 +1,12 @@ +{ + "runs": [ + { + "date": "2026-09-24T18:38:37.106144+00:00", + "input_tokens": 0, + "output_tokens": 0, + "files": 80 + } + ], + "total_input_tokens": 0, + "total_output_tokens": 0 +} \ No newline at end of file diff --git a/graphify-out/graph.html b/graphify-out/graph.html new file mode 100644 index 0000000..b546e5d --- /dev/null +++ b/graphify-out/graph.html @@ -0,0 +1,320 @@ + + + + +graphify - graphify-out/graph.html + + + + +

+ + + + + \ No newline at end of file diff --git a/graphify-out/graph.json b/graphify-out/graph.json new file mode 100644 index 0000000..8c99b64 --- /dev/null +++ b/graphify-out/graph.json @@ -0,0 +1,4030 @@ +{ + "directed": false, + "multigraph": false, + "graph": { + "hyperedges": [ + { + "id": "he_p2p_multiplayer_architecture", + "label": "P2P Multiplayer Architecture", + "nodes": [ + "docs_online_radmin_host_authoritative", + "docs_online_radmin_p2p_socket", + "docs_roadmap_online_command_protocol" + ], + "relation": "implement", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/ONLINE_RADMIN.txt" + }, + { + "id": "he_save_integrity_protection", + "label": "Save File Integrity & Persistence Architecture", + "nodes": [ + "docs_security_notes_save_tamper_signature", + "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", + "\u0438\u0434\u0435\u0438_appdata_saves" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/SECURITY_NOTES.txt" + }, + { + "id": "he_release_packaging_verification", + "label": "Release Packaging & Verification Flow", + "nodes": [ + "docs_release_checklist_smoke_check", + "docs_release_checklist_installer_validation", + "docs_security_notes_sha256_payload_check" + ], + "relation": "implement", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/RELEASE_CHECKLIST.txt" + }, + { + "id": "cabaret_dancer_animation_set", + "label": "Cabaret Dancer Animation Sequence", + "nodes": [ + "assets_textures_sprite_dancer_frame_0_image", + "assets_textures_sprite_dancer_frame_1_image", + "assets_textures_sprite_dancer_frame_2_image", + "assets_textures_sprite_dancer_frame_3_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/cabaret-loop-v1.png" + }, + { + "id": "slot_machine_animation_set", + "label": "Slot Machine Reel Animation Sequence", + "nodes": [ + "assets_textures_sprite_slot_frame_0_image", + "assets_textures_sprite_slot_frame_1_image", + "assets_textures_sprite_slot_frame_2_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_slot_frame_0.png" + }, + { + "id": "casino_wall_textures_set", + "label": "Casino Wall Textures Set", + "nodes": [ + "assets_textures_tex_wall_velvet_image", + "assets_textures_tex_wall_stripclub_image", + "assets_textures_tex_wall_hell_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "assets/textures/tex_wall_velvet.png" + } + ] + }, + "nodes": [ + { + "label": "casino3d.inc", + "file_type": "code", + "source_file": "casino3d.inc", + "source_location": "L1", + "_origin": "ast", + "id": "casino3d", + "community": 18, + "norm_label": "casino3d.inc" + }, + { + "label": "casino3d_data.inc", + "file_type": "code", + "source_file": "casino3d_data.inc", + "source_location": "L1", + "_origin": "ast", + "id": "casino3d_data", + "community": 19, + "norm_label": "casino3d_data.inc" + }, + { + "label": "font8x8.inc", + "file_type": "code", + "source_file": "font8x8.inc", + "source_location": "L1", + "_origin": "ast", + "id": "font8x8", + "community": 20, + "norm_label": "font8x8.inc" + }, + { + "label": "platform_code.inc", + "file_type": "code", + "source_file": "src_graphics/platform_code.inc", + "source_location": "L1", + "_origin": "ast", + "id": "src_graphics_platform_code", + "community": 22, + "norm_label": "platform_code.inc" + }, + { + "label": "platform_data.inc", + "file_type": "code", + "source_file": "src_graphics/platform_data.inc", + "source_location": "L1", + "_origin": "ast", + "id": "src_graphics_platform_data", + "community": 23, + "norm_label": "platform_data.inc" + }, + { + "label": "renderer.inc", + "file_type": "code", + "source_file": "src_graphics/renderer.inc", + "source_location": "L1", + "_origin": "ast", + "id": "src_graphics_renderer", + "community": 24, + "norm_label": "renderer.inc" + }, + { + "label": "casino_portable.c", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L1", + "_origin": "ast", + "id": "src_portable_casino_portable_c_src_portable_casino_portable", + "community": 0, + "norm_label": "casino_portable.c" + }, + { + "label": "platform_init()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L14", + "_origin": "ast", + "id": "src_portable_casino_portable_platform_init", + "community": 0, + "norm_label": "platform_init()" + }, + { + "label": "platform_cleanup()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L26", + "_origin": "ast", + "id": "src_portable_casino_portable_platform_cleanup", + "community": 0, + "norm_label": "platform_cleanup()" + }, + { + "label": "clear_screen()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L32", + "_origin": "ast", + "id": "src_portable_casino_portable_clear_screen", + "community": 0, + "norm_label": "clear_screen()" + }, + { + "label": "set_text_color()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L37", + "_origin": "ast", + "id": "src_portable_casino_portable_set_text_color", + "community": 0, + "norm_label": "set_text_color()" + }, + { + "label": "read_masked_password()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L42", + "_origin": "ast", + "id": "src_portable_casino_portable_read_masked_password", + "community": 0, + "norm_label": "read_masked_password()" + }, + { + "label": "hash_password()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L76", + "_origin": "ast", + "id": "src_portable_casino_portable_hash_password", + "community": 0, + "norm_label": "hash_password()" + }, + { + "label": "calc_account_signature()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L89", + "_origin": "ast", + "id": "src_portable_casino_portable_calc_account_signature", + "community": 0, + "norm_label": "calc_account_signature()" + }, + { + "label": "AccountData", + "file_type": "code", + "source_file": "", + "source_location": "", + "_origin": "ast", + "id": "accountdata", + "community": 0, + "norm_label": "accountdata" + }, + { + "label": "account_save()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L101", + "_origin": "ast", + "id": "src_portable_casino_portable_account_save", + "community": 0, + "norm_label": "account_save()" + }, + { + "label": "account_register()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L114", + "_origin": "ast", + "id": "src_portable_casino_portable_account_register", + "community": 0, + "norm_label": "account_register()" + }, + { + "label": "account_login()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L141", + "_origin": "ast", + "id": "src_portable_casino_portable_account_login", + "community": 0, + "norm_label": "account_login()" + }, + { + "label": "account_generate_transfer_key()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L204", + "_origin": "ast", + "id": "src_portable_casino_portable_account_generate_transfer_key", + "community": 0, + "norm_label": "account_generate_transfer_key()" + }, + { + "label": "account_import_transfer_key()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L211", + "_origin": "ast", + "id": "src_portable_casino_portable_account_import_transfer_key", + "community": 0, + "norm_label": "account_import_transfer_key()" + }, + { + "label": "account_cloud_sync_upload()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L237", + "_origin": "ast", + "id": "src_portable_casino_portable_account_cloud_sync_upload", + "community": 0, + "norm_label": "account_cloud_sync_upload()" + }, + { + "label": "account_cloud_sync_download()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L248", + "_origin": "ast", + "id": "src_portable_casino_portable_account_cloud_sync_download", + "community": 0, + "norm_label": "account_cloud_sync_download()" + }, + { + "label": "verify_peer_account_signature()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L272", + "_origin": "ast", + "id": "src_portable_casino_portable_verify_peer_account_signature", + "community": 0, + "norm_label": "verify_peer_account_signature()" + }, + { + "label": "render_lobby_browser()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L278", + "_origin": "ast", + "id": "src_portable_casino_portable_render_lobby_browser", + "community": 0, + "norm_label": "render_lobby_browser()" + }, + { + "label": "host_room_flow()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L309", + "_origin": "ast", + "id": "src_portable_casino_portable_host_room_flow", + "community": 0, + "norm_label": "host_room_flow()" + }, + { + "label": "net_lobby_menu()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L341", + "_origin": "ast", + "id": "src_portable_casino_portable_net_lobby_menu", + "community": 0, + "norm_label": "net_lobby_menu()" + }, + { + "label": "play_umamusume()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L419", + "_origin": "ast", + "id": "src_portable_casino_portable_play_umamusume", + "community": 0, + "norm_label": "play_umamusume()" + }, + { + "label": "main()", + "file_type": "code", + "source_file": "src_portable/casino_portable.c", + "source_location": "L482", + "_origin": "ast", + "id": "src_portable_casino_portable_main", + "community": 0, + "norm_label": "main()" + }, + { + "label": "casino_portable.h", + "file_type": "code", + "source_file": "src_portable/casino_portable.h", + "source_location": "L1", + "_origin": "ast", + "id": "src_portable_casino_portable_h_src_portable_casino_portable", + "community": 0, + "norm_label": "casino_portable.h" + }, + { + "label": "build_all_3d.py", + "file_type": "code", + "source_file": "tools/build_all_3d.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_build_all_3d", + "community": 14, + "norm_label": "build_all_3d.py" + }, + { + "label": "a()", + "file_type": "code", + "source_file": "tools/build_all_3d.py", + "source_location": "L7", + "_origin": "ast", + "id": "tools_build_all_3d_a", + "community": 14, + "norm_label": "a()" + }, + { + "label": "build_casino_assets.py", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_build_casino_assets", + "community": 4, + "norm_label": "build_casino_assets.py" + }, + { + "label": "clean_chromakey_black()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L14", + "_origin": "ast", + "id": "tools_build_casino_assets_clean_chromakey_black", + "community": 4, + "norm_label": "clean_chromakey_black()" + }, + { + "label": "Image", + "file_type": "code", + "source_file": "", + "source_location": "", + "_origin": "ast", + "id": "image", + "community": 4, + "norm_label": "image" + }, + { + "label": "clean_chromakey_white()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L25", + "_origin": "ast", + "id": "tools_build_casino_assets_clean_chromakey_white", + "community": 4, + "norm_label": "clean_chromakey_white()" + }, + { + "label": "img_to_raw_dwords()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L35", + "_origin": "ast", + "id": "tools_build_casino_assets_img_to_raw_dwords", + "community": 4, + "norm_label": "img_to_raw_dwords()" + }, + { + "label": "make_wood_wall()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L46", + "_origin": "ast", + "id": "tools_build_casino_assets_make_wood_wall", + "community": 4, + "norm_label": "make_wood_wall()" + }, + { + "label": "make_carpet_floor()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L60", + "_origin": "ast", + "id": "tools_build_casino_assets_make_carpet_floor", + "community": 4, + "norm_label": "make_carpet_floor()" + }, + { + "label": "make_ceiling_tex()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L80", + "_origin": "ast", + "id": "tools_build_casino_assets_make_ceiling_tex", + "community": 4, + "norm_label": "make_ceiling_tex()" + }, + { + "label": "make_atm()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L101", + "_origin": "ast", + "id": "tools_build_casino_assets_make_atm", + "community": 4, + "norm_label": "make_atm()" + }, + { + "label": "make_backroom_table()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L120", + "_origin": "ast", + "id": "tools_build_casino_assets_make_backroom_table", + "community": 4, + "norm_label": "make_backroom_table()" + }, + { + "label": "main()", + "file_type": "code", + "source_file": "tools/build_casino_assets.py", + "source_location": "L140", + "_origin": "ast", + "id": "tools_build_casino_assets_main", + "community": 4, + "norm_label": "main()" + }, + { + "label": "Resize with NEAREST so pixels never blend with chromakey!", + "file_type": "rationale", + "source_file": "tools/build_casino_assets.py", + "source_location": "L15", + "_origin": "ast", + "id": "tools_build_casino_assets_rationale_15", + "community": 4, + "norm_label": "resize with nearest so pixels never blend with chromakey!" + }, + { + "label": "build_engine.py", + "file_type": "code", + "source_file": "tools/build_engine.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_build_engine", + "community": 25, + "norm_label": "build_engine.py" + }, + { + "label": "build_graphics.ps1", + "file_type": "code", + "source_file": "tools/build_graphics.ps1", + "source_location": "L1", + "_origin": "ast", + "id": "tools_build_graphics", + "community": 26, + "norm_label": "build_graphics.ps1" + }, + { + "label": "build_graphics_assets.py", + "file_type": "code", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_build_graphics_assets", + "community": 7, + "norm_label": "build_graphics_assets.py" + }, + { + "label": "cells()", + "file_type": "code", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L15", + "_origin": "ast", + "id": "tools_build_graphics_assets_cells", + "community": 7, + "norm_label": "cells()" + }, + { + "label": "sprite()", + "file_type": "code", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L22", + "_origin": "ast", + "id": "tools_build_graphics_assets_sprite", + "community": 7, + "norm_label": "sprite()" + }, + { + "label": "pack()", + "file_type": "code", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L32", + "_origin": "ast", + "id": "tools_build_graphics_assets_pack", + "community": 7, + "norm_label": "pack()" + }, + { + "label": "main()", + "file_type": "code", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L41", + "_origin": "ast", + "id": "tools_build_graphics_assets_main", + "community": 7, + "norm_label": "main()" + }, + { + "label": "Pack project-local source art into the MASM renderer's 128px BGRA slots. Pyth", + "file_type": "rationale", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_build_graphics_assets_rationale_1", + "community": 7, + "norm_label": "pack project-local source art into the masm renderer's 128px bgra slots. pyth" + }, + { + "label": "generate_casino3d.py", + "file_type": "code", + "source_file": "tools/generate_casino3d.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_generate_casino3d", + "community": 27, + "norm_label": "generate_casino3d.py" + }, + { + "label": "generate_font.py", + "file_type": "code", + "source_file": "tools/generate_font.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_generate_font", + "community": 28, + "norm_label": "generate_font.py" + }, + { + "label": "generate_math_and_map.py", + "file_type": "code", + "source_file": "tools/generate_math_and_map.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_generate_math_and_map", + "community": 15, + "norm_label": "generate_math_and_map.py" + }, + { + "label": "float_to_fp()", + "file_type": "code", + "source_file": "tools/generate_math_and_map.py", + "source_location": "L7", + "_origin": "ast", + "id": "tools_generate_math_and_map_float_to_fp", + "community": 15, + "norm_label": "float_to_fp()" + }, + { + "label": "generate_unified_casino3d.py", + "file_type": "code", + "source_file": "tools/generate_unified_casino3d.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_generate_unified_casino3d", + "community": 29, + "norm_label": "generate_unified_casino3d.py" + }, + { + "label": "make_casino3d.py", + "file_type": "code", + "source_file": "tools/make_casino3d.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_make_casino3d", + "community": 30, + "norm_label": "make_casino3d.py" + }, + { + "label": "patch_poker_asm.py", + "file_type": "code", + "source_file": "tools/patch_poker_asm.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_patch_poker_asm", + "community": 31, + "norm_label": "patch_poker_asm.py" + }, + { + "label": "preview_dbd_hook.py", + "file_type": "code", + "source_file": "tools/preview_dbd_hook.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_preview_dbd_hook", + "community": 11, + "norm_label": "preview_dbd_hook.py" + }, + { + "label": "place_window()", + "file_type": "code", + "source_file": "tools/preview_dbd_hook.py", + "source_location": "L12", + "_origin": "ast", + "id": "tools_preview_dbd_hook_place_window", + "community": 11, + "norm_label": "place_window()" + }, + { + "label": "main()", + "file_type": "code", + "source_file": "tools/preview_dbd_hook.py", + "source_location": "L27", + "_origin": "ast", + "id": "tools_preview_dbd_hook_main", + "community": 11, + "norm_label": "main()" + }, + { + "label": "preview_hakari.py", + "file_type": "code", + "source_file": "tools/preview_hakari.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_preview_hakari", + "community": 12, + "norm_label": "preview_hakari.py" + }, + { + "label": "enable_ansi()", + "file_type": "code", + "source_file": "tools/preview_hakari.py", + "source_location": "L12", + "_origin": "ast", + "id": "tools_preview_hakari_enable_ansi", + "community": 12, + "norm_label": "enable_ansi()" + }, + { + "label": "main()", + "file_type": "code", + "source_file": "tools/preview_hakari.py", + "source_location": "L18", + "_origin": "ast", + "id": "tools_preview_hakari_main", + "community": 12, + "norm_label": "main()" + }, + { + "label": "preview_intro.py", + "file_type": "code", + "source_file": "tools/preview_intro.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_preview_intro", + "community": 16, + "norm_label": "preview_intro.py" + }, + { + "label": "main()", + "file_type": "code", + "source_file": "tools/preview_intro.py", + "source_location": "L12", + "_origin": "ast", + "id": "tools_preview_intro_main", + "community": 16, + "norm_label": "main()" + }, + { + "label": "release_smoke_check.ps1", + "file_type": "code", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L1", + "_origin": "ast", + "id": "tools_release_smoke_check", + "community": 10, + "norm_label": "release_smoke_check.ps1" + }, + { + "label": "Pass()", + "file_type": "code", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L7", + "_origin": "ast", + "id": "tools_release_smoke_check_pass", + "community": 10, + "norm_label": "pass()" + }, + { + "label": "Fail()", + "file_type": "code", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L11", + "_origin": "ast", + "id": "tools_release_smoke_check_fail", + "community": 10, + "norm_label": "fail()" + }, + { + "label": "Require-File()", + "file_type": "code", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L15", + "_origin": "ast", + "id": "tools_release_smoke_check_require_file", + "community": 10, + "norm_label": "require-file()" + }, + { + "label": "simulate_render.py", + "file_type": "code", + "source_file": "tools/simulate_render.py", + "source_location": "L1", + "_origin": "ast", + "id": "tools_simulate_render", + "community": 17, + "norm_label": "simulate_render.py" + }, + { + "label": "get_tex_pixel()", + "file_type": "code", + "source_file": "tools/simulate_render.py", + "source_location": "L40", + "_origin": "ast", + "id": "tools_simulate_render_get_tex_pixel", + "community": 17, + "norm_label": "get_tex_pixel()" + }, + { + "label": "AGENTS.md Project Instructions", + "file_type": "document", + "source_file": "AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "agents", + "community": 3, + "norm_label": "agents.md project instructions" + }, + { + "label": "MASM32 Build Pipeline", + "file_type": "concept", + "source_file": "AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Single-file x86 assembly Windows console casino game assembled with ml.exe /c /coff /Cp /nologo and linked with link.exe /SUBSYSTEM:CONSOLE against kernel32, winmm, user32, ws2_32, gdi32.", + "id": "agents_masm32_build", + "community": 3, + "norm_label": "masm32 build pipeline" + }, + { + "label": "CP1251 Console Encoding Standard", + "file_type": "rationale", + "source_file": "AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Source strings and dealer_phrases.txt must remain in Windows-1251 (CP1251) for Windows console rendering; do not re-save as UTF-8.", + "id": "agents_cp1251_encoding", + "community": 3, + "norm_label": "cp1251 console encoding standard" + }, + { + "label": "Console Cheat Codes System", + "file_type": "concept", + "source_file": "AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "agents_cheat_codes", + "community": 3, + "norm_label": "console cheat codes system" + }, + { + "label": "Casino Games Catalog", + "file_type": "concept", + "source_file": "AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "agents_games_catalog", + "community": 3, + "norm_label": "casino games catalog" + }, + { + "label": "ANSI Animation Assets Spec", + "file_type": "concept", + "source_file": "AGENTS.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "casino_intro.ans and hakari_dance.ans use ANSI escape codes and CP1251 with form-feed frame separators for high-performance terminal animations.", + "id": "agents_animation_assets", + "community": 5, + "norm_label": "ansi animation assets spec" + }, + { + "label": "CMake Portable Build Configuration", + "file_type": "document", + "source_file": "CMakeLists.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "cmakelists", + "community": 1, + "norm_label": "cmake portable build configuration" + }, + { + "label": "poker_portable Target", + "file_type": "code", + "source_file": "CMakeLists.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "cmakelists_poker_portable", + "community": 1, + "norm_label": "poker_portable target" + }, + { + "label": "Win32 Winsock ws2_32 Dependency", + "file_type": "concept", + "source_file": "CMakeLists.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "cmakelists_winsock_dependency", + "community": 1, + "norm_label": "win32 winsock ws2_32 dependency" + }, + { + "label": "KAZIK Project Readme", + "file_type": "document", + "source_file": "README.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "readme", + "community": 21, + "norm_label": "kazik project readme" + }, + { + "label": "Dealer Dialogue Phrases", + "file_type": "document", + "source_file": "assets/data/dealer_phrases.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_data_dealer_phrases", + "community": 3, + "norm_label": "dealer dialogue phrases" + }, + { + "label": "Win Loss Draw Outcome Prefixes", + "file_type": "concept", + "source_file": "assets/data/dealer_phrases.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Lines prefixed with W|, L|, and D| categorize dealer reactions to player outcomes for runtime dynamic selection.", + "id": "assets_data_dealer_phrases_outcome_prefixes", + "community": 3, + "norm_label": "win loss draw outcome prefixes" + }, + { + "label": "Known Limitations Specification", + "file_type": "document", + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_known_limitations", + "community": 2, + "norm_label": "known limitations specification" + }, + { + "label": "Windows Platform Dependency", + "file_type": "rationale", + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Officially Windows-only due to tight coupling to MASM32, WinAPI, WinMM, MCI, and Windows console API.", + "id": "docs_known_limitations_windows_platform_lock", + "community": 3, + "norm_label": "windows platform dependency" + }, + { + "label": "Wine and CrossOver POSIX Support", + "file_type": "concept", + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Enables non-Windows execution on Linux and macOS via Wine translation layers without rewriting the assembly core.", + "id": "docs_known_limitations_wine_support", + "community": 2, + "norm_label": "wine and crossover posix support" + }, + { + "label": "ANSI Animation Console Bottleneck", + "file_type": "concept", + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Console throughput limits animation smoothness on older PCs, requiring frame-skip rendering profiles.", + "id": "docs_known_limitations_ansi_console_speed", + "community": 2, + "norm_label": "ansi animation console bottleneck" + }, + { + "label": "Durak Card Logic Complexity Risk", + "file_type": "concept", + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Durak is the most complex game logic in the suite due to card defense, tossing (podkidnoy), transferring (perevodnoy), and table clearing.", + "id": "docs_known_limitations_durak_logic_risk", + "community": 2, + "norm_label": "durak card logic complexity risk" + }, + { + "label": "Online Radmin VPN Guide", + "file_type": "document", + "source_file": "docs/ONLINE_RADMIN.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_online_radmin", + "community": 1, + "norm_label": "online radmin vpn guide" + }, + { + "label": "Host Authoritative Network Model", + "file_type": "rationale", + "source_file": "docs/ONLINE_RADMIN.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Host owns hidden chamber state in Russian roulette and dice seeds; client sends only inputs so both peers remain in sync without a dedicated server.", + "id": "docs_online_radmin_host_authoritative", + "community": 1, + "norm_label": "host authoritative network model" + }, + { + "label": "Winsock TCP Port 27015 LAN Protocol", + "file_type": "concept", + "source_file": "docs/ONLINE_RADMIN.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Built-in 1v1 match on TCP port 27015 directly inside poker.exe without installing separate servers or services.", + "id": "docs_online_radmin_p2p_socket", + "community": 1, + "norm_label": "winsock tcp port 27015 lan protocol" + }, + { + "label": "Release Notes and User Guide", + "file_type": "document", + "source_file": "docs/README_RELEASE.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_readme_release", + "community": 1, + "norm_label": "release notes and user guide" + }, + { + "label": "Animation Rendering Profiles", + "file_type": "concept", + "source_file": "docs/README_RELEASE.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Cinematic, Adaptive, and Stable profiles control frame-skipping to eliminate flicker and stutter without omitting entire scenes.", + "id": "docs_readme_release_rendering_profiles", + "community": 2, + "norm_label": "animation rendering profiles" + }, + { + "label": "Release Package Architecture", + "file_type": "concept", + "source_file": "docs/README_RELEASE.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Bundles launcher Assembler Casino.exe, core bin/poker.exe, and assets into an installer for clean user experience.", + "id": "docs_readme_release_package_architecture", + "community": 1, + "norm_label": "release package architecture" + }, + { + "label": "Release QA Checklist", + "file_type": "document", + "source_file": "docs/RELEASE_CHECKLIST.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_release_checklist", + "community": 1, + "norm_label": "release qa checklist" + }, + { + "label": "Automated Release Smoke Check", + "file_type": "concept", + "source_file": "docs/RELEASE_CHECKLIST.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "tools/release_smoke_check.ps1 automates pre-release verification of builds, installer, and payload integrity.", + "id": "docs_release_checklist_smoke_check", + "community": 1, + "norm_label": "automated release smoke check" + }, + { + "label": "Installer & Uninstaller Verification", + "file_type": "concept", + "source_file": "docs/RELEASE_CHECKLIST.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Validates installation directory selection, desktop shortcuts, registry entry under Add/Remove Programs, and clean uninstallation.", + "id": "docs_release_checklist_installer_validation", + "community": 1, + "norm_label": "installer & uninstaller verification" + }, + { + "label": "Casino Games QA Verification", + "file_type": "concept", + "source_file": "docs/RELEASE_CHECKLIST.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Comprehensive verification steps covering all 12 casino games, account persistence, bankruptcy handling, and win goals.", + "id": "docs_release_checklist_game_verification", + "community": 1, + "norm_label": "casino games qa verification" + }, + { + "label": "Development Roadmap", + "file_type": "document", + "source_file": "docs/ROADMAP.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_roadmap", + "community": 1, + "norm_label": "development roadmap" + }, + { + "label": "Multiplayer Command Protocol", + "file_type": "concept", + "source_file": "docs/ROADMAP.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Client-server text command set (BET, HIT, STAND, FOLD, RAISE, PLAY_CARD, READY, CHAT) sent over TCP sockets.", + "id": "docs_roadmap_online_command_protocol", + "community": 1, + "norm_label": "multiplayer command protocol" + }, + { + "label": "Security & Signing Roadmap", + "file_type": "concept", + "source_file": "docs/ROADMAP.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Planned addition of Authenticode code-signing, release manifests, and stronger save checksum validation.", + "id": "docs_roadmap_security_milestones", + "community": 1, + "norm_label": "security & signing roadmap" + }, + { + "label": "Future Casino Expansions", + "file_type": "concept", + "source_file": "docs/ROADMAP.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Planned expansions including casino tax, VIP tier benefits, charm bestiary, secret ending, and casino tower tournament.", + "id": "docs_roadmap_future_expansions", + "community": 2, + "norm_label": "future casino expansions" + }, + { + "label": "Security Architecture Notes", + "file_type": "document", + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_security_notes", + "community": 1, + "norm_label": "security architecture notes" + }, + { + "label": "SHA-256 Binary Integrity Verification", + "file_type": "concept", + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Installer verifies embedded archive hash and launcher validates bin/poker.exe hash to prevent payload tampering.", + "id": "docs_security_notes_sha256_payload_check", + "community": 1, + "norm_label": "sha-256 binary integrity verification" + }, + { + "label": "Save File Salted Signature", + "file_type": "concept", + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Save files write a hash signature computed over the first 276 bytes with a hardcoded salt to catch manual progress hex editing.", + "id": "docs_security_notes_save_tamper_signature", + "community": 5, + "norm_label": "save file salted signature" + }, + { + "label": "Installer Path Traversal Guard", + "file_type": "concept", + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Installer rejects archive entries containing ../ to guarantee unpacked files cannot escape the installation directory.", + "id": "docs_security_notes_path_traversal_guard", + "community": 1, + "norm_label": "installer path traversal guard" + }, + { + "label": "Casino Intro ASCII Preview", + "file_type": "document", + "source_file": "docs/casino_intro_preview.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "ASCII art banner preview for the main casino entry screen.", + "id": "docs_casino_intro_preview", + "community": 5, + "norm_label": "casino intro ascii preview" + }, + { + "label": "Dead by Daylight Hook Reference Graphic", + "file_type": "document", + "source_file": "docs/dbd_hook_static.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_dbd_hook_static", + "community": 13, + "norm_label": "dead by daylight hook reference graphic" + }, + { + "label": "Skill Check Hook Escape Minigame", + "file_type": "concept", + "source_file": "docs/dbd_hook_static.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Timed QTE skill check minigame inspired by Dead by Daylight requiring player to press SPACE or ENTER at the exact moment.", + "id": "docs_dbd_hook_static_skill_check", + "community": 13, + "norm_label": "skill check hook escape minigame" + }, + { + "label": "Revolver ASCII Preview", + "file_type": "document", + "source_file": "docs/revolver_small_preview.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_revolver_small_preview", + "community": 2, + "norm_label": "revolver ascii preview" + }, + { + "label": "Russian Roulette Revolver ASCII Graphics", + "file_type": "concept", + "source_file": "docs/revolver_small_preview.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Detailed multi-angle ASCII art gun animations showing cylinder spin and hammer cocking for Russian Roulette.", + "id": "docs_revolver_small_preview_russian_roulette_visuals", + "community": 2, + "norm_label": "russian roulette revolver ascii graphics" + }, + { + "label": "Secret Cheat Codes Reference", + "file_type": "document", + "source_file": "docs/\u0427\u0418\u0422\u041a\u041e\u0414\u042b.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b", + "community": 3, + "norm_label": "secret cheat codes reference" + }, + { + "label": "Menu Cheat Code Definitions", + "file_type": "concept", + "source_file": "docs/\u0427\u0418\u0422\u041a\u041e\u0414\u042b.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Keyboard cheat commands entered at the main menu including MONEYRAIN, SEVENS, WINNEXT, GODMODE, FAIRPLAY, GOAL, RESETBANK, AI difficulty, and ACHIEVER.", + "id": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b_menu_codes", + "community": 3, + "norm_label": "menu cheat code definitions" + }, + { + "label": "Intro Glitch Prototype Snippet", + "file_type": "document", + "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442", + "community": 5, + "norm_label": "intro glitch prototype snippet" + }, + { + "label": "ShowIntro Procedure Prototype", + "file_type": "code", + "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_showintro", + "community": 5, + "norm_label": "showintro procedure prototype" + }, + { + "label": "Terminal Glitch and Screen Shake FX", + "file_type": "concept", + "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Uses rdtsc CPU cycle counter to dynamically trigger screen shakes, ANSI 256-color flicker flashes, and character corruption.", + "id": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_glitch_fx", + "community": 5, + "norm_label": "terminal glitch and screen shake fx" + }, + { + "label": "poker.asm Variables Reference", + "file_type": "document", + "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "graphify_out_converted_variables_documentation_3fc6d2dc", + "community": 5, + "norm_label": "poker.asm variables reference" + }, + { + "label": "SAVE_MAGIC Constant 31435653h", + "file_type": "concept", + "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Magic header constant used to validate Assembler Casino save game integrity upon loading.", + "id": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", + "community": 5, + "norm_label": "save_magic constant 31435653h" + }, + { + "label": "Console Color Attributes Constants", + "file_type": "concept", + "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Defines standard color attribute constants for cards, table, wood, money, warnings, and titles in WinAPI console.", + "id": "graphify_out_converted_variables_documentation_3fc6d2dc_color_constants", + "community": 5, + "norm_label": "console color attributes constants" + }, + { + "label": "Standard Console Handles", + "file_type": "concept", + "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Constants for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and INVALID_HANDLE_VALUE for Windows console I/O.", + "id": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles", + "community": 5, + "norm_label": "standard console handles" + }, + { + "label": "Runtime Achievement Storage File", + "file_type": "document", + "source_file": "runtime/achievement.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Local file storing unlocked player achievements.", + "id": "runtime_achievement", + "community": 3, + "norm_label": "runtime achievement storage file" + }, + { + "label": "Runtime Achievement Tracker", + "file_type": "concept", + "source_file": "runtime/achievement.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "runtime_achievement_tracking", + "community": 3, + "norm_label": "runtime achievement tracker" + }, + { + "label": "Feature Backlog and Game Ideas", + "file_type": "document", + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "\u0438\u0434\u0435\u0438", + "community": 2, + "norm_label": "feature backlog and game ideas" + }, + { + "label": "AppData Save Migration Idea", + "file_type": "concept", + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Moving player save data to %AppData% prevents accidental deletion when reinstalling or updating the casino.", + "id": "\u0438\u0434\u0435\u0438_appdata_saves", + "community": 5, + "norm_label": "appdata save migration idea" + }, + { + "label": "Casino Shop and Charms Mechanic", + "file_type": "concept", + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Allows spending winnings on charms, custom card decks, shirts, and lucky talismans with gameplay effects.", + "id": "\u0438\u0434\u0435\u0438_shop_and_charms", + "community": 2, + "norm_label": "casino shop and charms mechanic" + }, + { + "label": "Heart Rate Stress Visualization", + "file_type": "concept", + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Visualizes player character pulse and anxiety level during high-stakes gambling decisions.", + "id": "\u0438\u0434\u0435\u0438_pulse_stress", + "community": 2, + "norm_label": "heart rate stress visualization" + }, + { + "label": "Durak Card Game Expansion", + "file_type": "concept", + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Addition of Russian card game Durak with podkidnoy and perevodnoy variants to broaden casino offerings.", + "id": "\u0438\u0434\u0435\u0438_durak_expansion", + "community": 2, + "norm_label": "durak card game expansion" + }, + { + "label": "Buckshot Roulette Game Mode Idea", + "file_type": "concept", + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Adaptation of shotgun-based Russian Roulette gameplay with items and bluffing mechanics.", + "id": "\u0438\u0434\u0435\u0438_buckshot_roulette", + "community": 2, + "norm_label": "buckshot roulette game mode idea" + }, + { + "label": "Casino Tower Tournament Idea", + "file_type": "concept", + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "rationale": "Multi-floor casino tower progression where players face escalating AI opponents with special modifiers.", + "id": "\u0438\u0434\u0435\u0438_casino_tower", + "community": 2, + "norm_label": "casino tower tournament idea" + }, + { + "label": "Casino Preview Icon", + "file_type": "image", + "source_file": "assets/icons/casino_preview.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_icons_casino_preview_image", + "community": 6, + "norm_label": "casino preview icon" + }, + { + "label": "Cabaret Loop Sprite Sheet", + "file_type": "image", + "source_file": "assets/sprites/cabaret-loop-v1.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_sprites_cabaret_loop_v1_image", + "community": 8, + "norm_label": "cabaret loop sprite sheet" + }, + { + "label": "Casino Atlas Sprite Sheet", + "file_type": "image", + "source_file": "assets/sprites/casino-atlas-v1.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_sprites_casino_atlas_v1_image", + "community": 6, + "norm_label": "casino atlas sprite sheet" + }, + { + "label": "Bartender Shop Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_bartender_shop.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_bartender_shop_image", + "community": 6, + "norm_label": "bartender shop sprite" + }, + { + "label": "Blackjack Table Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_blackjack_table.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_blackjack_table_image", + "community": 6, + "norm_label": "blackjack table sprite" + }, + { + "label": "Dancer Animation Frame 0 Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_dancer_frame_0.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_dancer_frame_0_image", + "community": 8, + "norm_label": "dancer animation frame 0 sprite" + }, + { + "label": "Dancer Animation Frame 1 Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_dancer_frame_1.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_dancer_frame_1_image", + "community": 8, + "norm_label": "dancer animation frame 1 sprite" + }, + { + "label": "Dancer Animation Frame 2 Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_dancer_frame_2.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_dancer_frame_2_image", + "community": 8, + "norm_label": "dancer animation frame 2 sprite" + }, + { + "label": "Dancer Animation Frame 3 Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_dancer_frame_3.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_dancer_frame_3_image", + "community": 8, + "norm_label": "dancer animation frame 3 sprite" + }, + { + "label": "Roulette Table Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_roulette_table.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_roulette_table_image", + "community": 6, + "norm_label": "roulette table sprite" + }, + { + "label": "Slot Machine Frame 0 Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_slot_frame_0.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_slot_frame_0_image", + "community": 6, + "norm_label": "slot machine frame 0 sprite" + }, + { + "label": "Slot Machine Frame 1 Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_slot_frame_1.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_slot_frame_1_image", + "community": 6, + "norm_label": "slot machine frame 1 sprite" + }, + { + "label": "Slot Machine Frame 2 Sprite", + "file_type": "image", + "source_file": "assets/textures/sprite_slot_frame_2.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_sprite_slot_frame_2_image", + "community": 6, + "norm_label": "slot machine frame 2 sprite" + }, + { + "label": "Casino Carpet Floor Texture", + "file_type": "image", + "source_file": "assets/textures/tex_floor_carpet.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_tex_floor_carpet_image", + "community": 9, + "norm_label": "casino carpet floor texture" + }, + { + "label": "Hell Wall Texture", + "file_type": "image", + "source_file": "assets/textures/tex_wall_hell.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_tex_wall_hell_image", + "community": 9, + "norm_label": "hell wall texture" + }, + { + "label": "Neon Strip Club Wall Texture", + "file_type": "image", + "source_file": "assets/textures/tex_wall_stripclub.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_tex_wall_stripclub_image", + "community": 9, + "norm_label": "neon strip club wall texture" + }, + { + "label": "Velvet Wall Texture", + "file_type": "image", + "source_file": "assets/textures/tex_wall_velvet.png", + "source_location": null, + "source_url": null, + "captured_at": null, + "author": null, + "contributor": null, + "id": "assets_textures_tex_wall_velvet_image", + "community": 9, + "norm_label": "velvet wall texture" + } + ], + "links": [ + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L248", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_account_cloud_sync_download", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L237", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_account_cloud_sync_upload", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L204", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_account_generate_transfer_key", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L211", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_account_import_transfer_key", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L141", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_account_login", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L114", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_account_register", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L101", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_account_save", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L89", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_calc_account_signature", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L32", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_clear_screen", + "confidence_score": 1.0 + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L7", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_h_src_portable_casino_portable", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L76", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_hash_password", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L309", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_host_room_flow", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L482", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_main", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L341", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_net_lobby_menu", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L26", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_platform_cleanup", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L14", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_platform_init", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L419", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_play_umamusume", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L42", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_read_masked_password", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L278", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_render_lobby_browser", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L37", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_set_text_color", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L272", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_c_src_portable_casino_portable", + "target": "src_portable_casino_portable_verify_peer_account_signature", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L483", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_platform_init", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L511", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_platform_cleanup", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L142", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_login", + "target": "src_portable_casino_portable_clear_screen", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L115", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_register", + "target": "src_portable_casino_portable_clear_screen", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L518", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_clear_screen", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L420", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_play_umamusume", + "target": "src_portable_casino_portable_clear_screen", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L279", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_render_lobby_browser", + "target": "src_portable_casino_portable_clear_screen", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L159", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_login", + "target": "src_portable_casino_portable_read_masked_password", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L122", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_register", + "target": "src_portable_casino_portable_read_masked_password", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L508", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_read_masked_password", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L406", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_net_lobby_menu", + "target": "src_portable_casino_portable_read_masked_password", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L258", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_cloud_sync_download", + "target": "src_portable_casino_portable_hash_password", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L224", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_import_transfer_key", + "target": "src_portable_casino_portable_hash_password", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L188", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_login", + "target": "src_portable_casino_portable_hash_password", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L126", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_register", + "target": "src_portable_casino_portable_hash_password", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L262", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_cloud_sync_download", + "target": "src_portable_casino_portable_calc_account_signature", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L227", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_import_transfer_key", + "target": "src_portable_casino_portable_calc_account_signature", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L176", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_login", + "target": "src_portable_casino_portable_calc_account_signature", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L130", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_register", + "target": "src_portable_casino_portable_calc_account_signature", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L108", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_save", + "target": "src_portable_casino_portable_calc_account_signature", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L89", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_calc_account_signature", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L248", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_account_cloud_sync_download", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L237", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_account_cloud_sync_upload", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L204", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_account_generate_transfer_key", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L211", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_account_import_transfer_key", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L141", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_account_login", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L114", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_account_register", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L101", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_account_save", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L309", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_host_room_flow", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L341", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_net_lobby_menu", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L419", + "weight": 1.0, + "context": "parameter_type", + "_origin": "ast", + "source": "src_portable_casino_portable_play_umamusume", + "target": "accountdata", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L264", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_cloud_sync_download", + "target": "src_portable_casino_portable_account_save", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L229", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_import_transfer_key", + "target": "src_portable_casino_portable_account_save", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L132", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_register", + "target": "src_portable_casino_portable_account_save", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L476", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_play_umamusume", + "target": "src_portable_casino_portable_account_save", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L501", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_account_register", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L160", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_account_login", + "target": "src_portable_casino_portable_account_cloud_sync_download", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L499", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_account_login", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L393", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_net_lobby_menu", + "target": "src_portable_casino_portable_account_generate_transfer_key", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L509", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_account_import_transfer_key", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L407", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_net_lobby_menu", + "target": "src_portable_casino_portable_account_import_transfer_key", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L387", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_net_lobby_menu", + "target": "src_portable_casino_portable_account_cloud_sync_upload", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L370", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_net_lobby_menu", + "target": "src_portable_casino_portable_verify_peer_account_signature", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L344", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_net_lobby_menu", + "target": "src_portable_casino_portable_render_lobby_browser", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L349", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_net_lobby_menu", + "target": "src_portable_casino_portable_host_room_flow", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L531", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_net_lobby_menu", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "src_portable/casino_portable.c", + "source_location": "L529", + "weight": 1.0, + "_origin": "ast", + "source": "src_portable_casino_portable_main", + "target": "src_portable_casino_portable_play_umamusume", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_all_3d.py", + "source_location": "L7", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_all_3d", + "target": "tools_build_all_3d_a", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L14", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_clean_chromakey_black", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L25", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_clean_chromakey_white", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L35", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_img_to_raw_dwords", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L140", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_main", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L101", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_make_atm", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L120", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_make_backroom_table", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L60", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_make_carpet_floor", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L80", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_make_ceiling_tex", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L46", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets", + "target": "tools_build_casino_assets_make_wood_wall", + "confidence_score": 1.0 + }, + { + "relation": "references", + "context": "return_type", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L14", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_clean_chromakey_black", + "target": "image", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L190", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_main", + "target": "tools_build_casino_assets_clean_chromakey_black", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L15", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_rationale_15", + "target": "tools_build_casino_assets_clean_chromakey_black", + "confidence_score": 1.0 + }, + { + "relation": "references", + "context": "return_type", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L25", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_clean_chromakey_white", + "target": "image", + "confidence_score": 1.0 + }, + { + "relation": "references", + "context": "parameter_type", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L35", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_img_to_raw_dwords", + "target": "image", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L208", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_main", + "target": "tools_build_casino_assets_clean_chromakey_white", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L148", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_main", + "target": "tools_build_casino_assets_img_to_raw_dwords", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L150", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_main", + "target": "tools_build_casino_assets_make_wood_wall", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L166", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_main", + "target": "tools_build_casino_assets_make_carpet_floor", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L177", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_main", + "target": "tools_build_casino_assets_make_ceiling_tex", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L223", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_main", + "target": "tools_build_casino_assets_make_atm", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_casino_assets.py", + "source_location": "L226", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_casino_assets_main", + "target": "tools_build_casino_assets_make_backroom_table", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L15", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_graphics_assets", + "target": "tools_build_graphics_assets_cells", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L41", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_graphics_assets", + "target": "tools_build_graphics_assets_main", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L32", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_graphics_assets", + "target": "tools_build_graphics_assets_pack", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L22", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_graphics_assets", + "target": "tools_build_graphics_assets_sprite", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L1", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_graphics_assets_rationale_1", + "target": "tools_build_graphics_assets", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L50", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_graphics_assets_main", + "target": "tools_build_graphics_assets_cells", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L54", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_graphics_assets_main", + "target": "tools_build_graphics_assets_sprite", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/build_graphics_assets.py", + "source_location": "L62", + "weight": 1.0, + "_origin": "ast", + "source": "tools_build_graphics_assets_main", + "target": "tools_build_graphics_assets_pack", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/generate_math_and_map.py", + "source_location": "L7", + "weight": 1.0, + "_origin": "ast", + "source": "tools_generate_math_and_map", + "target": "tools_generate_math_and_map_float_to_fp", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/preview_dbd_hook.py", + "source_location": "L27", + "weight": 1.0, + "_origin": "ast", + "source": "tools_preview_dbd_hook", + "target": "tools_preview_dbd_hook_main", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/preview_dbd_hook.py", + "source_location": "L12", + "weight": 1.0, + "_origin": "ast", + "source": "tools_preview_dbd_hook", + "target": "tools_preview_dbd_hook_place_window", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/preview_dbd_hook.py", + "source_location": "L39", + "weight": 1.0, + "_origin": "ast", + "source": "tools_preview_dbd_hook_main", + "target": "tools_preview_dbd_hook_place_window", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/preview_hakari.py", + "source_location": "L12", + "weight": 1.0, + "_origin": "ast", + "source": "tools_preview_hakari", + "target": "tools_preview_hakari_enable_ansi", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/preview_hakari.py", + "source_location": "L18", + "weight": 1.0, + "_origin": "ast", + "source": "tools_preview_hakari", + "target": "tools_preview_hakari_main", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "tools/preview_hakari.py", + "source_location": "L29", + "weight": 1.0, + "_origin": "ast", + "source": "tools_preview_hakari_main", + "target": "tools_preview_hakari_enable_ansi", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/preview_intro.py", + "source_location": "L12", + "weight": 1.0, + "_origin": "ast", + "source": "tools_preview_intro", + "target": "tools_preview_intro_main", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L11", + "weight": 1.0, + "_origin": "ast", + "source": "tools_release_smoke_check", + "target": "tools_release_smoke_check_fail", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L7", + "weight": 1.0, + "_origin": "ast", + "source": "tools_release_smoke_check", + "target": "tools_release_smoke_check_pass", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L15", + "weight": 1.0, + "_origin": "ast", + "source": "tools_release_smoke_check", + "target": "tools_release_smoke_check_require_file", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "confidence": "EXTRACTED", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L20", + "weight": 1.0, + "_origin": "ast", + "source": "tools_release_smoke_check_require_file", + "target": "tools_release_smoke_check_pass", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "confidence": "EXTRACTED", + "source_file": "tools/release_smoke_check.ps1", + "source_location": "L18", + "weight": 1.0, + "_origin": "ast", + "source": "tools_release_smoke_check_require_file", + "target": "tools_release_smoke_check_fail", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "tools/simulate_render.py", + "source_location": "L40", + "weight": 1.0, + "_origin": "ast", + "source": "tools_simulate_render", + "target": "tools_simulate_render_get_tex_pixel", + "confidence_score": 1.0 + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "AGENTS.md", + "source_location": null, + "weight": 1.0, + "source": "agents", + "target": "agents_animation_assets" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "AGENTS.md", + "source_location": null, + "weight": 1.0, + "source": "agents", + "target": "agents_cheat_codes" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "AGENTS.md", + "source_location": null, + "weight": 1.0, + "source": "agents", + "target": "agents_cp1251_encoding" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "AGENTS.md", + "source_location": null, + "weight": 1.0, + "source": "agents", + "target": "agents_games_catalog" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "AGENTS.md", + "source_location": null, + "weight": 1.0, + "source": "agents", + "target": "agents_masm32_build" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_known_limitations_windows_platform_lock", + "target": "agents_masm32_build" + }, + { + "relation": "rationale_for", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "AGENTS.md", + "source_location": null, + "weight": 1.0, + "source": "agents_cp1251_encoding", + "target": "assets_data_dealer_phrases" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "AGENTS.md", + "source_location": null, + "weight": 1.0, + "source": "agents_cheat_codes", + "target": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b_menu_codes" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "AGENTS.md", + "source_location": null, + "weight": 1.0, + "source": "agents_games_catalog", + "target": "docs_release_checklist_game_verification" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/casino_intro_preview.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_casino_intro_preview", + "target": "agents_animation_assets" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CMakeLists.txt", + "source_location": null, + "weight": 1.0, + "source": "cmakelists", + "target": "cmakelists_poker_portable" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "CMakeLists.txt", + "source_location": null, + "weight": 1.0, + "source": "cmakelists", + "target": "cmakelists_winsock_dependency" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "CMakeLists.txt", + "source_location": null, + "weight": 1.0, + "source": "cmakelists_winsock_dependency", + "target": "docs_online_radmin_p2p_socket" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "assets/data/dealer_phrases.txt", + "source_location": null, + "weight": 1.0, + "source": "assets_data_dealer_phrases", + "target": "assets_data_dealer_phrases_outcome_prefixes" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_known_limitations", + "target": "docs_known_limitations_ansi_console_speed" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_known_limitations", + "target": "docs_known_limitations_durak_logic_risk" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_known_limitations", + "target": "docs_known_limitations_windows_platform_lock" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_known_limitations", + "target": "docs_known_limitations_wine_support" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_known_limitations_ansi_console_speed", + "target": "docs_readme_release_rendering_profiles" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/KNOWN_LIMITATIONS.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_known_limitations_durak_logic_risk", + "target": "\u0438\u0434\u0435\u0438_durak_expansion" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/ONLINE_RADMIN.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_online_radmin", + "target": "docs_online_radmin_host_authoritative" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/ONLINE_RADMIN.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_online_radmin", + "target": "docs_online_radmin_p2p_socket" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/ONLINE_RADMIN.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_online_radmin_host_authoritative", + "target": "docs_roadmap_online_command_protocol" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/README_RELEASE.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_readme_release", + "target": "docs_readme_release_package_architecture" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/README_RELEASE.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_readme_release", + "target": "docs_readme_release_rendering_profiles" + }, + { + "relation": "references", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/README_RELEASE.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_readme_release_package_architecture", + "target": "docs_release_checklist_installer_validation" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/RELEASE_CHECKLIST.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_release_checklist", + "target": "docs_release_checklist_game_verification" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/RELEASE_CHECKLIST.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_release_checklist", + "target": "docs_release_checklist_installer_validation" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/RELEASE_CHECKLIST.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_release_checklist", + "target": "docs_release_checklist_smoke_check" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/RELEASE_CHECKLIST.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_release_checklist_smoke_check", + "target": "docs_security_notes_sha256_payload_check" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/ROADMAP.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_roadmap", + "target": "docs_roadmap_future_expansions" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/ROADMAP.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_roadmap", + "target": "docs_roadmap_online_command_protocol" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/ROADMAP.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_roadmap", + "target": "docs_roadmap_security_milestones" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "docs/ROADMAP.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_roadmap_security_milestones", + "target": "docs_security_notes" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "weight": 1.0, + "source": "\u0438\u0434\u0435\u0438_casino_tower", + "target": "docs_roadmap_future_expansions" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "weight": 1.0, + "source": "\u0438\u0434\u0435\u0438_shop_and_charms", + "target": "docs_roadmap_future_expansions" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_security_notes", + "target": "docs_security_notes_path_traversal_guard" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_security_notes", + "target": "docs_security_notes_save_tamper_signature" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_security_notes", + "target": "docs_security_notes_sha256_payload_check" + }, + { + "relation": "shares_data_with", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_security_notes_save_tamper_signature", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "docs/SECURITY_NOTES.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_security_notes_save_tamper_signature", + "target": "\u0438\u0434\u0435\u0438_appdata_saves" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_glitch_fx", + "target": "docs_casino_intro_preview" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/dbd_hook_static.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_dbd_hook_static", + "target": "docs_dbd_hook_static_skill_check" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/revolver_small_preview.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_revolver_small_preview", + "target": "docs_revolver_small_preview_russian_roulette_visuals" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "docs/revolver_small_preview.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_revolver_small_preview_russian_roulette_visuals", + "target": "\u0438\u0434\u0435\u0438_buckshot_roulette" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/\u0427\u0418\u0422\u041a\u041e\u0414\u042b.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b", + "target": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b_menu_codes" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "runtime/achievement.txt", + "source_location": null, + "weight": 1.0, + "source": "runtime_achievement_tracking", + "target": "docs_\u0447\u0438\u0442\u043a\u043e\u0434\u044b_menu_codes" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442", + "target": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_showintro" + }, + { + "relation": "implements", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_showintro", + "target": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_glitch_fx" + }, + { + "relation": "calls", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt", + "source_location": null, + "weight": 1.0, + "source": "docs_\u043d\u043e\u0432\u044b\u0439_\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442_showintro", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", + "source_location": null, + "weight": 1.0, + "source": "graphify_out_converted_variables_documentation_3fc6d2dc", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_color_constants" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", + "source_location": null, + "weight": 1.0, + "source": "graphify_out_converted_variables_documentation_3fc6d2dc", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "graphify-out/converted/variables_documentation_3fc6d2dc.md", + "source_location": null, + "weight": 1.0, + "source": "graphify_out_converted_variables_documentation_3fc6d2dc", + "target": "graphify_out_converted_variables_documentation_3fc6d2dc_winapi_handles" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "runtime/achievement.txt", + "source_location": null, + "weight": 1.0, + "source": "runtime_achievement", + "target": "runtime_achievement_tracking" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "weight": 1.0, + "source": "\u0438\u0434\u0435\u0438", + "target": "\u0438\u0434\u0435\u0438_appdata_saves" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "weight": 1.0, + "source": "\u0438\u0434\u0435\u0438", + "target": "\u0438\u0434\u0435\u0438_buckshot_roulette" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "weight": 1.0, + "source": "\u0438\u0434\u0435\u0438", + "target": "\u0438\u0434\u0435\u0438_casino_tower" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "weight": 1.0, + "source": "\u0438\u0434\u0435\u0438", + "target": "\u0438\u0434\u0435\u0438_durak_expansion" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "weight": 1.0, + "source": "\u0438\u0434\u0435\u0438", + "target": "\u0438\u0434\u0435\u0438_pulse_stress" + }, + { + "relation": "references", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "\u0418\u0414\u0415\u0418.txt", + "source_location": null, + "weight": 1.0, + "source": "\u0438\u0434\u0435\u0438", + "target": "\u0438\u0434\u0435\u0438_shop_and_charms" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "assets/icons/casino_preview.png", + "source_location": null, + "weight": 1.0, + "source": "assets_icons_casino_preview_image", + "target": "assets_sprites_casino_atlas_v1_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/cabaret-loop-v1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_sprites_cabaret_loop_v1_image", + "target": "assets_textures_sprite_dancer_frame_0_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/cabaret-loop-v1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_sprites_cabaret_loop_v1_image", + "target": "assets_textures_sprite_dancer_frame_1_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/cabaret-loop-v1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_sprites_cabaret_loop_v1_image", + "target": "assets_textures_sprite_dancer_frame_2_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/cabaret-loop-v1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_sprites_cabaret_loop_v1_image", + "target": "assets_textures_sprite_dancer_frame_3_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/casino-atlas-v1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_sprites_casino_atlas_v1_image", + "target": "assets_textures_sprite_bartender_shop_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/casino-atlas-v1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_sprites_casino_atlas_v1_image", + "target": "assets_textures_sprite_blackjack_table_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/casino-atlas-v1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_sprites_casino_atlas_v1_image", + "target": "assets_textures_sprite_roulette_table_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/casino-atlas-v1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_sprites_casino_atlas_v1_image", + "target": "assets_textures_sprite_slot_frame_0_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "assets/textures/sprite_bartender_shop.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_bartender_shop_image", + "target": "assets_textures_sprite_blackjack_table_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "assets/textures/sprite_blackjack_table.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_blackjack_table_image", + "target": "assets_textures_sprite_roulette_table_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_dancer_frame_0.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_dancer_frame_0_image", + "target": "assets_textures_sprite_dancer_frame_1_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_dancer_frame_3.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_dancer_frame_3_image", + "target": "assets_textures_sprite_dancer_frame_0_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_dancer_frame_1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_dancer_frame_1_image", + "target": "assets_textures_sprite_dancer_frame_2_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_dancer_frame_2.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_dancer_frame_2_image", + "target": "assets_textures_sprite_dancer_frame_3_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_slot_frame_0.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_slot_frame_0_image", + "target": "assets_textures_sprite_slot_frame_1_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_slot_frame_2.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_slot_frame_2_image", + "target": "assets_textures_sprite_slot_frame_0_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_slot_frame_1.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_sprite_slot_frame_1_image", + "target": "assets_textures_sprite_slot_frame_2_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "assets/textures/tex_floor_carpet.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_tex_floor_carpet_image", + "target": "assets_textures_tex_wall_stripclub_image" + }, + { + "relation": "conceptually_related_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "assets/textures/tex_floor_carpet.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_tex_floor_carpet_image", + "target": "assets_textures_tex_wall_velvet_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "assets/textures/tex_wall_stripclub.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_tex_wall_stripclub_image", + "target": "assets_textures_tex_wall_hell_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.75, + "source_file": "assets/textures/tex_wall_velvet.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_tex_wall_velvet_image", + "target": "assets_textures_tex_wall_hell_image" + }, + { + "relation": "semantically_similar_to", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "assets/textures/tex_wall_velvet.png", + "source_location": null, + "weight": 1.0, + "source": "assets_textures_tex_wall_velvet_image", + "target": "assets_textures_tex_wall_stripclub_image" + } + ], + "hyperedges": [ + { + "id": "he_p2p_multiplayer_architecture", + "label": "P2P Multiplayer Architecture", + "nodes": [ + "docs_online_radmin_host_authoritative", + "docs_online_radmin_p2p_socket", + "docs_roadmap_online_command_protocol" + ], + "relation": "implement", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/ONLINE_RADMIN.txt" + }, + { + "id": "he_save_integrity_protection", + "label": "Save File Integrity & Persistence Architecture", + "nodes": [ + "docs_security_notes_save_tamper_signature", + "graphify_out_converted_variables_documentation_3fc6d2dc_save_magic", + "\u0438\u0434\u0435\u0438_appdata_saves" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/SECURITY_NOTES.txt" + }, + { + "id": "he_release_packaging_verification", + "label": "Release Packaging & Verification Flow", + "nodes": [ + "docs_release_checklist_smoke_check", + "docs_release_checklist_installer_validation", + "docs_security_notes_sha256_payload_check" + ], + "relation": "implement", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "docs/RELEASE_CHECKLIST.txt" + }, + { + "id": "cabaret_dancer_animation_set", + "label": "Cabaret Dancer Animation Sequence", + "nodes": [ + "assets_textures_sprite_dancer_frame_0_image", + "assets_textures_sprite_dancer_frame_1_image", + "assets_textures_sprite_dancer_frame_2_image", + "assets_textures_sprite_dancer_frame_3_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/sprites/cabaret-loop-v1.png" + }, + { + "id": "slot_machine_animation_set", + "label": "Slot Machine Reel Animation Sequence", + "nodes": [ + "assets_textures_sprite_slot_frame_0_image", + "assets_textures_sprite_slot_frame_1_image", + "assets_textures_sprite_slot_frame_2_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "assets/textures/sprite_slot_frame_0.png" + }, + { + "id": "casino_wall_textures_set", + "label": "Casino Wall Textures Set", + "nodes": [ + "assets_textures_tex_wall_velvet_image", + "assets_textures_tex_wall_stripclub_image", + "assets_textures_tex_wall_hell_image" + ], + "relation": "form", + "confidence": "INFERRED", + "confidence_score": 0.85, + "source_file": "assets/textures/tex_wall_velvet.png" + } + ], + "built_at_commit": "fe4e38140d00c9f5b515491f4ecea5da8a091e20" +} \ No newline at end of file diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json new file mode 100644 index 0000000..769d6fa --- /dev/null +++ b/graphify-out/manifest.json @@ -0,0 +1,402 @@ +{ + "casino3d.inc": { + "mtime": 1790270823.1496067, + "ast_hash": "f9805043552d04b9a22d41301d6b3cf7", + "semantic_hash": "f9805043552d04b9a22d41301d6b3cf7" + }, + "casino3d_data.inc": { + "mtime": 1790270823.1496067, + "ast_hash": "c963346468c7960b6e879fb4d6528d36", + "semantic_hash": "c963346468c7960b6e879fb4d6528d36" + }, + "font8x8.inc": { + "mtime": 1790270823.1496067, + "ast_hash": "a70f89b1a80b10b5fb066945ef2eb417", + "semantic_hash": "a70f89b1a80b10b5fb066945ef2eb417" + }, + "src_graphics/platform_code.inc": { + "mtime": 1790270823.1593437, + "ast_hash": "6deacf4986280e0a0666cb311909a5eb", + "semantic_hash": "6deacf4986280e0a0666cb311909a5eb" + }, + "src_graphics/platform_data.inc": { + "mtime": 1790270823.1593437, + "ast_hash": "cd0f48032c02304efeb00df62647506d", + "semantic_hash": "cd0f48032c02304efeb00df62647506d" + }, + "src_graphics/renderer.inc": { + "mtime": 1790270823.1593437, + "ast_hash": "6166ca49fc7663f8657f16abad957e7d", + "semantic_hash": "6166ca49fc7663f8657f16abad957e7d" + }, + "src_portable/casino_portable.c": { + "mtime": 1790270823.1593437, + "ast_hash": "8792e5b57cbea01b6de4d414f8fb82f4", + "semantic_hash": "8792e5b57cbea01b6de4d414f8fb82f4" + }, + "src_portable/casino_portable.h": { + "mtime": 1790270823.1593437, + "ast_hash": "0fc31c1800373092e986f6f8a90e73d0", + "semantic_hash": "0fc31c1800373092e986f6f8a90e73d0" + }, + "tools/build_all_3d.py": { + "mtime": 1790270823.1593437, + "ast_hash": "b9310099dc9462538747bd814aebb511", + "semantic_hash": "b9310099dc9462538747bd814aebb511" + }, + "tools/build_casino_assets.py": { + "mtime": 1790270823.1593437, + "ast_hash": "950d40f9da724225e975c5cf7978f417", + "semantic_hash": "950d40f9da724225e975c5cf7978f417" + }, + "tools/build_engine.py": { + "mtime": 1790270823.1593437, + "ast_hash": "213dac8f3e761814847d3ed0da8b35af", + "semantic_hash": "213dac8f3e761814847d3ed0da8b35af" + }, + "tools/build_graphics.ps1": { + "mtime": 1790270823.1593437, + "ast_hash": "c7500c5a66fb43ff87a1dad6e36226a3", + "semantic_hash": "c7500c5a66fb43ff87a1dad6e36226a3" + }, + "tools/build_graphics_assets.py": { + "mtime": 1790270823.1593437, + "ast_hash": "3f620d3d643a897dd6508564838f30da", + "semantic_hash": "3f620d3d643a897dd6508564838f30da" + }, + "tools/generate_casino3d.py": { + "mtime": 1790270823.1593437, + "ast_hash": "7cfee82adb3c170b6d084bcc18d6f0d8", + "semantic_hash": "7cfee82adb3c170b6d084bcc18d6f0d8" + }, + "tools/generate_font.py": { + "mtime": 1790270823.1593437, + "ast_hash": "9f79c4567a80d4174eeee514c0b956dc", + "semantic_hash": "9f79c4567a80d4174eeee514c0b956dc" + }, + "tools/generate_math_and_map.py": { + "mtime": 1790270823.1593437, + "ast_hash": "a7d6f6abe8e93427c7476b1520be204f", + "semantic_hash": "a7d6f6abe8e93427c7476b1520be204f" + }, + "tools/generate_unified_casino3d.py": { + "mtime": 1790270823.1593437, + "ast_hash": "91f98b357fea1672295b848c162cb933", + "semantic_hash": "91f98b357fea1672295b848c162cb933" + }, + "tools/make_casino3d.py": { + "mtime": 1790270823.1593437, + "ast_hash": "037efa7839edb47f5a80ce8f95a03066", + "semantic_hash": "037efa7839edb47f5a80ce8f95a03066" + }, + "tools/patch_poker_asm.py": { + "mtime": 1790270823.1593437, + "ast_hash": "f9da4aa8ffcf6b1d9c42a28298f546ed", + "semantic_hash": "f9da4aa8ffcf6b1d9c42a28298f546ed" + }, + "tools/preview_dbd_hook.py": { + "mtime": 1790270823.1593437, + "ast_hash": "f110a82383960bb7d22bfef5e82b2f37", + "semantic_hash": "f110a82383960bb7d22bfef5e82b2f37" + }, + "tools/preview_hakari.py": { + "mtime": 1790270823.1593437, + "ast_hash": "b168b5435bace7cf4ea2ab51d3691138", + "semantic_hash": "b168b5435bace7cf4ea2ab51d3691138" + }, + "tools/preview_intro.py": { + "mtime": 1790270823.1593437, + "ast_hash": "54093a40f57a5c68a5ff1044a60e4ebb", + "semantic_hash": "54093a40f57a5c68a5ff1044a60e4ebb" + }, + "tools/release_smoke_check.ps1": { + "mtime": 1790270823.1593437, + "ast_hash": "0f7a033512d7c0b050dd2a2f7fbccc69", + "semantic_hash": "0f7a033512d7c0b050dd2a2f7fbccc69" + }, + "tools/simulate_render.py": { + "mtime": 1790270823.1593437, + "ast_hash": "84098cde25e5391156a33c8457d214de", + "semantic_hash": "84098cde25e5391156a33c8457d214de" + }, + "AGENTS.md": { + "mtime": 1790270822.3930032, + "ast_hash": "97ba65f5cc00efbfe83c482a89793cbb", + "semantic_hash": "97ba65f5cc00efbfe83c482a89793cbb" + }, + "CMakeLists.txt": { + "mtime": 1790270822.3930032, + "ast_hash": "64868d02077ea41fa9952bbde3d7fbd5", + "semantic_hash": "64868d02077ea41fa9952bbde3d7fbd5" + }, + "README.md": { + "mtime": 1790270822.3930032, + "ast_hash": "5f0539fc91819e1483b3cde1696bb9c8", + "semantic_hash": "5f0539fc91819e1483b3cde1696bb9c8" + }, + "assets/data/dealer_phrases.txt": { + "mtime": 1790270822.489428, + "ast_hash": "6bd4e117e2e1c58abffb3ca11173c717", + "semantic_hash": "6bd4e117e2e1c58abffb3ca11173c717" + }, + "docs/KNOWN_LIMITATIONS.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "5e7a9ed6b3705a3fdbbaadb26f1cee17", + "semantic_hash": "5e7a9ed6b3705a3fdbbaadb26f1cee17" + }, + "docs/ONLINE_RADMIN.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "abf23bd8a4072d6069604658b6edf3d4", + "semantic_hash": "abf23bd8a4072d6069604658b6edf3d4" + }, + "docs/README_RELEASE.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "2e6d833ba134cfba0f3c0eec97d2e4a2", + "semantic_hash": "2e6d833ba134cfba0f3c0eec97d2e4a2" + }, + "docs/RELEASE_CHECKLIST.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "3f678030b73c6871ee8d66109b3c9d5c", + "semantic_hash": "3f678030b73c6871ee8d66109b3c9d5c" + }, + "docs/ROADMAP.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "65fe0c7e313e5fd5c6f8423ce5bf8544", + "semantic_hash": "65fe0c7e313e5fd5c6f8423ce5bf8544" + }, + "docs/SECURITY_NOTES.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "51eca3baccd270cb1c8ea8e79bae88d0", + "semantic_hash": "51eca3baccd270cb1c8ea8e79bae88d0" + }, + "docs/casino_intro_preview.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "881b205041909b342c2cb795b3cd3415", + "semantic_hash": "881b205041909b342c2cb795b3cd3415" + }, + "docs/dbd_hook_static.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "076285d4f360ee261903bed5829dd153", + "semantic_hash": "076285d4f360ee261903bed5829dd153" + }, + "docs/revolver_small_preview.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "f95cc9165dfd7e9bf9a9b5b6c49be2b6", + "semantic_hash": "f95cc9165dfd7e9bf9a9b5b6c49be2b6" + }, + "docs/\u041d\u043e\u0432\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "5bd25dc621e2acf6a783c59c7db1da1b", + "semantic_hash": "5bd25dc621e2acf6a783c59c7db1da1b" + }, + "docs/\u0427\u0418\u0422\u041a\u041e\u0414\u042b.txt": { + "mtime": 1790270823.1496067, + "ast_hash": "02af0d595853a44aa8101ccfe0866d6a", + "semantic_hash": "02af0d595853a44aa8101ccfe0866d6a" + }, + "graphify-out/converted/variables_documentation_3fc6d2dc.md": { + "mtime": 1790274665.2704844, + "ast_hash": "a3d861ece24cb2d853f8c370625ee1ed", + "semantic_hash": "a3d861ece24cb2d853f8c370625ee1ed" + }, + "runtime/achievement.txt": { + "mtime": 1790270823.1593437, + "ast_hash": "d41d8cd98f00b204e9800998ecf8427e", + "semantic_hash": "d41d8cd98f00b204e9800998ecf8427e" + }, + "\u0418\u0414\u0415\u0418.txt": { + "mtime": 1790270823.1593437, + "ast_hash": "435c7897beeb02828af0d67980459582", + "semantic_hash": "435c7897beeb02828af0d67980459582" + }, + "assets/icons/casino_preview.png": { + "mtime": 1790270822.489428, + "ast_hash": "136c227375ee02994cc1d3293948c4b8", + "semantic_hash": "136c227375ee02994cc1d3293948c4b8" + }, + "assets/sprites/cabaret-loop-v1.png": { + "mtime": 1790270823.1193204, + "ast_hash": "8b565300f5f6ecc28d69d1bebc174a9f", + "semantic_hash": "8b565300f5f6ecc28d69d1bebc174a9f" + }, + "assets/sprites/casino-atlas-v1.png": { + "mtime": 1790270823.1245294, + "ast_hash": "a499f3325fa8dfe21c8c559fde628a5c", + "semantic_hash": "a499f3325fa8dfe21c8c559fde628a5c" + }, + "assets/textures/sprite_bartender_shop.png": { + "mtime": 1790270823.1422753, + "ast_hash": "5873e10361abc4a38eb1464d87337d92", + "semantic_hash": "5873e10361abc4a38eb1464d87337d92" + }, + "assets/textures/sprite_blackjack_table.png": { + "mtime": 1790270823.1422753, + "ast_hash": "1c18b20ee2aeede4b0bac4e73a92b20a", + "semantic_hash": "1c18b20ee2aeede4b0bac4e73a92b20a" + }, + "assets/textures/sprite_dancer_frame_0.png": { + "mtime": 1790270823.1422753, + "ast_hash": "2e6f3e753f73e90a5f4e4895e2007e7f", + "semantic_hash": "2e6f3e753f73e90a5f4e4895e2007e7f" + }, + "assets/textures/sprite_dancer_frame_1.png": { + "mtime": 1790270823.1422753, + "ast_hash": "2e94c2c5ddb1b6ac9e794bb5f7094ea5", + "semantic_hash": "2e94c2c5ddb1b6ac9e794bb5f7094ea5" + }, + "assets/textures/sprite_dancer_frame_2.png": { + "mtime": 1790270823.1422753, + "ast_hash": "54fd34f18738278ebe030e3a9b7568cd", + "semantic_hash": "54fd34f18738278ebe030e3a9b7568cd" + }, + "assets/textures/sprite_dancer_frame_3.png": { + "mtime": 1790270823.1422753, + "ast_hash": "d0529cd063152c1ab05e38dcf6eb6f82", + "semantic_hash": "d0529cd063152c1ab05e38dcf6eb6f82" + }, + "assets/textures/sprite_roulette_table.png": { + "mtime": 1790270823.1422753, + "ast_hash": "496e68eeb97fe1ac462cd9eb98f68046", + "semantic_hash": "496e68eeb97fe1ac462cd9eb98f68046" + }, + "assets/textures/sprite_slot_frame_0.png": { + "mtime": 1790270823.1422753, + "ast_hash": "837d6eed96011c0c0d948766b49db377", + "semantic_hash": "837d6eed96011c0c0d948766b49db377" + }, + "assets/textures/sprite_slot_frame_1.png": { + "mtime": 1790270823.1422753, + "ast_hash": "39a327461204bf64717a36a1953a0c77", + "semantic_hash": "39a327461204bf64717a36a1953a0c77" + }, + "assets/textures/sprite_slot_frame_2.png": { + "mtime": 1790270823.1422753, + "ast_hash": "668a9eb8b19e4fb661bbd9c7698c8365", + "semantic_hash": "668a9eb8b19e4fb661bbd9c7698c8365" + }, + "assets/textures/tex_floor_carpet.png": { + "mtime": 1790270823.1422753, + "ast_hash": "87cbe6cd48079db418b029b0959390d4", + "semantic_hash": "87cbe6cd48079db418b029b0959390d4" + }, + "assets/textures/tex_wall_hell.png": { + "mtime": 1790270823.1422753, + "ast_hash": "2a0d78005ef9ea1c6aa1641100142b5a", + "semantic_hash": "2a0d78005ef9ea1c6aa1641100142b5a" + }, + "assets/textures/tex_wall_stripclub.png": { + "mtime": 1790270823.1422753, + "ast_hash": "bbdfda9487a2f1a606779506e45b8651", + "semantic_hash": "bbdfda9487a2f1a606779506e45b8651" + }, + "assets/textures/tex_wall_velvet.png": { + "mtime": 1790270823.1422753, + "ast_hash": "3f46d6b191209be7c50889447c071876", + "semantic_hash": "3f46d6b191209be7c50889447c071876" + }, + "assets/audio/b05e1ac8be34248.wav": { + "mtime": 1790270822.414604, + "ast_hash": "2ffb76db56a87df737232df08fab4bab", + "semantic_hash": "2ffb76db56a87df737232df08fab4bab" + }, + "assets/audio/hKhoJArfEGAxxMewx0UQiddakTdBjFc.wav": { + "mtime": 1790270822.414604, + "ast_hash": "1e0f4def573ba11d6813bd33a3d02d7d", + "semantic_hash": "1e0f4def573ba11d6813bd33a3d02d7d" + }, + "assets/audio/hakari_dance.wav": { + "mtime": 1790270822.4302027, + "ast_hash": "d509663313eb3dc91d655b7af00491dc", + "semantic_hash": "d509663313eb3dc91d655b7af00491dc" + }, + "assets/audio/moving-stone.wav": { + "mtime": 1790270822.439434, + "ast_hash": "5d70b6f793ec13833a80604bb573c3b3", + "semantic_hash": "5d70b6f793ec13833a80604bb573c3b3" + }, + "assets/audio/playing_cards_deck_flick_through_001_20485.wav": { + "mtime": 1790270822.439434, + "ast_hash": "2f81256093ebf7b7d54f39eff0cee761", + "semantic_hash": "2f81256093ebf7b7d54f39eff0cee761" + }, + "assets/audio/revolverdryfirec.wav": { + "mtime": 1790270822.439434, + "ast_hash": "6ba327b092caf04b859c470a695d3a0f", + "semantic_hash": "6ba327b092caf04b859c470a695d3a0f" + }, + "assets/audio/roulette-wheel-throw-2.wav": { + "mtime": 1790270822.4598324, + "ast_hash": "6c057032512ab790c99589ab7b974c15", + "semantic_hash": "6c057032512ab790c99589ab7b974c15" + }, + "assets/audio/toy-gun-revolver-close-chamber-spin_f1ruc5nd.wav": { + "mtime": 1790270822.4598324, + "ast_hash": "ba5316144397cef3b42045fec10fa7fc", + "semantic_hash": "ba5316144397cef3b42045fec10fa7fc" + }, + "assets/audio/victory-tf2.wav": { + "mtime": 1790270822.469207, + "ast_hash": "e5634376184480460a4146725d89cf8a", + "semantic_hash": "e5634376184480460a4146725d89cf8a" + }, + "assets/audio/\u0414\u0436\u044d\u043a \u043f\u043e\u0442.wav": { + "mtime": 1790270822.4821348, + "ast_hash": "b7e9958169fd1b859c6c90d4328ff413", + "semantic_hash": "b7e9958169fd1b859c6c90d4328ff413" + }, + "assets/audio/\u0417\u0432\u0443\u043a \u043c\u043e\u043d\u0435\u0442\u044b \u0431\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0439 \u0432 \u0432\u043e\u0437\u0434\u0443\u0445 \u0438 \u0443\u043f\u0430\u0432\u0448\u0435\u0439 \u043d\u0430 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c.wav": { + "mtime": 1790270822.4821348, + "ast_hash": "55f6f3e750d19b3a17c3ddaea26ef9d7", + "semantic_hash": "55f6f3e750d19b3a17c3ddaea26ef9d7" + }, + "assets/audio/\u0417\u0432\u0443\u043a \u043c\u043e\u043d\u0435\u0442\u044b \u0432 \u0438\u0433\u0440\u0435 Ultrakill.wav": { + "mtime": 1790270822.4821348, + "ast_hash": "884aa1749acdc0cbb0f7feb17e6628e7", + "semantic_hash": "884aa1749acdc0cbb0f7feb17e6628e7" + }, + "assets/audio/\u041b\u0435\u0442\u0441 \u0433\u043e\u0443 \u0433\u044d\u043c\u0431\u043b\u0438\u043d\u0433.wav": { + "mtime": 1790270822.489428, + "ast_hash": "9babfd7362b8f65dc961be5d49d1f2b9", + "semantic_hash": "9babfd7362b8f65dc961be5d49d1f2b9" + }, + "assets/audio/\u041f\u0440\u043e\u0438\u0433\u0440\u044b\u0448.wav": { + "mtime": 1790270822.489428, + "ast_hash": "4375c277c7c905c4967a9a6d38d9fd9f", + "semantic_hash": "4375c277c7c905c4967a9a6d38d9fd9f" + }, + "assets/music/tower/KEYGEN_CHURCH_-_Hareklavit_75543927.mp3": { + "mtime": 1790270822.5744476, + "ast_hash": "3868ac1ad89190c469cf170c7b12e6a6", + "semantic_hash": "3868ac1ad89190c469cf170c7b12e6a6" + }, + "assets/music/tower/KEYGEN_CHURCH_-_Ladikerfos_75543991.mp3": { + "mtime": 1790270822.6715348, + "ast_hash": "e0e2cc83261d29f85ec0507ec0e8073c", + "semantic_hash": "e0e2cc83261d29f85ec0507ec0e8073c" + }, + "assets/music/tower/KEYGEN_CHURCH_-_Tilaskarot_75546826.mp3": { + "mtime": 1790270822.738438, + "ast_hash": "9b193980b0c62bce505f7c5af3e910ef", + "semantic_hash": "9b193980b0c62bce505f7c5af3e910ef" + }, + "assets/music/tower/Keygen_Church_-_Tenebre_Rosso_Sangue_ULTRAKILL_Original_Game_Soundtrack_79610890.mp3": { + "mtime": 1790270822.7995152, + "ast_hash": "1d04fb66ce356d3e1da34ad2a30795d2", + "semantic_hash": "1d04fb66ce356d3e1da34ad2a30795d2" + }, + "assets/music/tower/Mick_Gordon_-_BFG_Division_48126042.mp3": { + "mtime": 1790270822.9346032, + "ast_hash": "443414f37f655f905fc07d31d3031cd2", + "semantic_hash": "443414f37f655f905fc07d31d3031cd2" + }, + "assets/music/tower/Mick_Gordon_-_Rip_Tear_48126019.mp3": { + "mtime": 1790270823.0045426, + "ast_hash": "54377250e2e0f4193b6be504fa6f1bc7", + "semantic_hash": "54377250e2e0f4193b6be504fa6f1bc7" + }, + "assets/music/tower/Mick_Gordon_-_The_Only_Thing_They_Fear_Is_You_OST_DOOM_Eternal_72020713.mp3": { + "mtime": 1790270823.113895, + "ast_hash": "7198bbb632c4208dbe718afbf0c5f8f6", + "semantic_hash": "7198bbb632c4208dbe718afbf0c5f8f6" + } +} \ No newline at end of file diff --git a/poker.obj b/poker.obj new file mode 100644 index 0000000000000000000000000000000000000000..b5408bdb18259fd75308e11fbfa7c211af95d465 GIT binary patch literal 316722 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

+GO_q`U+$82-r4*9&`|d1e{|lhUJ;}?60qyPqs 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 P_tbwp_uk_7Kl}dxU1Uu2 literal 0 HcmV?d00001 diff --git a/tools/generators/__pycache__/build_casino_assets.cpython-314.pyc b/tools/generators/__pycache__/build_casino_assets.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eeafbdb3aaa56ed610e935a3bb6bb0a42b062f95 GIT binary patch literal 12727 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 literal 0 HcmV?d00001 diff --git a/tools/generators/__pycache__/build_engine.cpython-314.pyc b/tools/generators/__pycache__/build_engine.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cb89464c904b8910c33e3b6d763dd7b5946364a GIT binary patch literal 216 zcmdPqIUu8fA&w!4(UYNsA(l~*A&AL@5h5!O6jf%> zWPSV!Z literal 0 HcmV?d00001 diff --git a/tools/generators/__pycache__/build_graphics_assets.cpython-314.pyc b/tools/generators/__pycache__/build_graphics_assets.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9eb0812a324e1fa7a113c2ebeb6612ccf4559cc3 GIT binary patch literal 6425 zcmb6-YfKzTdet*M59Z1HF@8(~w((#d29IsbdC7te#seK@*^{XF|dy$XXEqLGLgL=)$U zZjGpM;<4tuwwn}5C;C8Bi9XP|iS!DORoNow7wbb2KO3Ti$Q1AAD3%wgU|5V$;si%sY#+Qx@mx5-@f=?xP)*G((HW}a z9NkU{p@=9nm`t8);zT4&1qF%?Q<1T;P%z9syMOj|za^IB^o&6itju@1$UX8LQAAOtrwr)z>fTlEEA0recRZv6@s_QS| zpU$iG4qVzb3Fnj599qldykNGH(5s)Ow;E#l_ za=a+%K#s;aiS+Z4sHB??2E++TKfwjZCq$QCBBLM}7&tUF85Sgxk4y`aE{LT>B6x}L z3wqe|(4j*VMM*9!$->Au7v^|YjPSyUEa1Lzo{dff{eq7b1P-(zdQH;#xll;pi(s)G z9^pQ8F|=hVSh#TG!lJll*}GvmkhC0F@~&CxVx4dFsB}-p?vKJ9ed9d>-`zq1vfwl%e1U5wIE@jE!lq~S&3tebt-xBA`dCA z+}72ZbJMR`iD|#1saLu)XGRG)Wfx5u$)2)17N938tx=?I+p1kK*nQP8%}7?tceCW4 z{2dp8X%>I=+QPTtD#5qpsFWKW)6g1s#+F63pr<8ouk~tj@LtWXyijoq{7sgR2<28X z<^*;!3NB_`GW53how?LMC~3pov}Bh(h0hYkS-e zxYe`2==piiGuanhH(ZNdcZTk{ zSDRef@`JyrG27vdxK;mqTje{1-chSZQoZ4QM03ij6s?{X6+aIi*#Cf~W=*BqK<8wbGRT`KYTIp=qEO@8-Q; zq9y|nD8S)`SI@*+fQ0E_Vk5^f5gH!yY8jL>_D<9T$6;gd)qubd&tm`! z{L34?CUPv#v)3fUI41^Jk(Kmky6OIl?UJ6G5g}>-%a4t$lou3yX(q~IGZhkftaTDG zE)k;=!3r1+*_10h2lMa0%pZl%6g)yVbYP{er8nP?b#0dJ`QhY8lOIRsO>@K?`#W=S zydXY!r);ajIe%fUeX(-WXj`z(TNkgy2bPG%&=X_zO9Lu9^umZNg|UnL0ocqBPqvlA z2ow4B|AO|gHg&8)Beh-oI#xu{NY-ZMVv&)oJ~HpBZQ70*ss4xK!*Rf8FB(7-L<5Qv zBUu}o+fT8IAOdp`lW0b=)?&A)0$VD&WEkv{`XsMrdqlAPFM((+O}aC;lI%awD+Sxm#dW-_bmnQ#+bs&vIDw+(?V-$Q}hW7dz5A zH9r}WA+vUx+!bEG174ej*EOPuZDgNvhBuo_07oDz%I>y21nf;7`aWY1RVoXdGlgCsuX6686VGc4@<`83JY8ZQ?#Z#%A zk$bBQL`4RdnH(;|-RkTmhnLqNV*+%O)tz7})o`9a!u>(pAHf8qSfggqdCeBoY*gq4 zRfpnC)~1PSAZII|-J4F98b$EoQxKLl`dJ|ujvNa#j0VGUpcq8&g7en$?6gGUTElEr zW=Yz|D=X?*F~kb>SDPB5;qhHyMxlm)iyM(>1}5#9vzZIr4&U_{Jg?6}cbcd|P6z{r zP#470vLz|Zg-pYhgW6L7rTBvx6w^WIQkJnWs2UyD1_>9@=OW~|0wNeq!%>L{r$ZD& z26rX)jHP4GywfZ390&yi$4V zY`kP?_%q8!aebn=eywfbD|zql?W2fU=l@6J`U#oLk`@x@*~4-c+o)u*3P&<@jq=>p zAU7=&w`K>VpH&f80UQsG4YfYU)9-=0O3Xb~ZF?z-1{Y6U}O=8A>8%W;Lx;pG))nUD%WFfDTd!?4qAzulSt8-5;O> z2n5IS=kT~3iUR%pLz0Q-*nkhmkbe?CF+MVx1~5jaL^*?y z^l4mq@M?(1XYts}ONPGAcDi$LNKWjfJT5#niAw?Lqyg#%A~y*|gbyQ-$e5>bHjzG= z$B6R#afd@tiNrLKbdYa^MVFn2*cwSjMG^QDGKd(2d_^bAwxkcRVL!)9x-lLqXRsWK zZajARX`v$1L9xj45Fks23?n34dX+CT=TE`{0XtVnc~tG)vNIJ$`j*W~FGgSB$*lv4ig!|l@2p;VRJmq38|%afxD$@HR8bq8*tBNtgoxgjA3L{Iye~fX zr1;>x5s-6GOC>+5pEE3K76)$YZ`xmKQOTjFWfk$J_~=sQ61`lo+_6HeG_PD)ty&%3 z%>1ZY8eOhh9$l$g8O5I;RY6sytc&$Jgi0bL3{l{>9>(Ho&F4=Be4X z&@$h$UPONpd~95A8(1r%*UWV6EM|gu^VA*PJ@T&Qo|q~>vdpH+8`sT^39>O^ZrrjK zB#MuxtjFQnq-ldJO_HUH;ySr^%T}}yyb+A+?-ef-e_MXvy;AvkOM-GIPMlk_b*Jew z@uav0(`VCY-!M9pM(2`ldEoPs2M0d4tro1Z4@-aTerQkBbU!hk#}qsKlr;Z!|6lYk zcCL|*4bqt;o%hH@%|MD8SSRUcz+?K(HQ;h-?Qfljh}EPo3X5HIO_t@T8OmPyo~wy+E+;DOtGKlp;$uNJo-%+;JzWdQy9O65dOj zhfl2Vsl%<01|MHZyg!0h?0JI-C}BP$^XAUo>Rdb-uf7wAdzYH-4J~y6+q}!&3DfZ> zwCZ^S$Z%1Z*<~+KVB;u|-0l>i~)?*#eJK%(Ox2!6U3|vN4g%4zkCPbr7Qx z23`00eu89wl~z*Y>B&f7D#W$%AHqUxV})_(K>i5grG_NP|1u$>;@?rpmj?4(_xJvM z!>})D*tceIZWwBkhMHv}WvGpjn+6kfMpI0;nO70hztWRL>nodqu)itR6NRq|D~XdY Zx(P&D=4RKm6~85o-|qr8lMWe?{{zPq*KPm+ literal 0 HcmV?d00001 diff --git a/tools/generators/__pycache__/generate_casino3d.cpython-314.pyc b/tools/generators/__pycache__/generate_casino3d.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c13e070786f7913cbf6c01e59a025ed0952f3f3 GIT binary patch literal 201 zcmdPqF(9LXA(larA&9|*5h5zj5X7j=pvhFFEzq$#{#kpeQr1WF^CAkoH@uCHeU| z#W8S2aAs;e+?0aKTO2mI`6;D2sdhzdKwTi4i}`@W2WCb_#)k~77ud9}F=!XD0EGZ7 C3NhIL literal 0 HcmV?d00001 diff --git a/tools/generators/__pycache__/generate_font.cpython-314.pyc b/tools/generators/__pycache__/generate_font.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3e015b4da4faeb5e4e9750d40db5267a99ae850 GIT binary patch literal 2584 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 literal 0 HcmV?d00001 diff --git a/tools/generators/__pycache__/generate_unified_casino3d.cpython-314.pyc b/tools/generators/__pycache__/generate_unified_casino3d.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2152a8ab3a796131c54cde34cdacdda6900a7b26 GIT binary patch literal 59359 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 literal 0 HcmV?d00001 diff --git a/tools/generators/__pycache__/make_casino3d.cpython-314.pyc b/tools/generators/__pycache__/make_casino3d.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ae868b16fde3994bc7ba7566cc5e89116f2ce0f GIT binary patch literal 147 zcmdPqXyO-4UW##^ifiA5#FD;Yk6 z6x~uR$iP9Vh*Axh99d?=R;q-!)YN+ z{E1rbr~Ys7OY^_aZa-DKCKB%|t`LkBl+NtlNxXM{A8s zmp{5hv~i@>bXn2X7VRDxtxA@PE2^}KjH>hiHQzPKe_2t{qEtr^LU{#VnS`>{7#<&K z&b&pL=8l0;=OGt+OqTFaZoJvAXf@T65v)n3qUjUz7!fpwrr}9)Sl1sQ8Ll8z-)K%5 zmL|Gh;)I;%IFcMeQB_#Ql7R~@UeT4`t2baBX_lz!dZYR6Yp&E&(H;*RQ$s%U6*Wpk9?n;d$mV3Bf?Z^lcD zMOc>EL^DM;FXWY$1k01bfWqO!c{EKNt*1O)N)Z=y1iVvy)4en zE*2NuGb7al*GY&RMAAbC+bI_kdsSJp4CEzIRhlT!mNaQaMYEczbY@d9kc3fDF;ETb z#^!7eE|tsG(lR9HfR#GcUJKIm%7eHrE4BLtQXSZVq#H32k^@U; zBlDVqtF(m7Abl#M-EU451L3TN^#xs$XKOWzS(Z!}w??`|a%E01e+&0C1ZT>DKaWg= zD~7&G#zN7Z7;Z=};ey`SEL5>UitdP*&Pj13JT@VM7ZY^#PjuDt+yef*qjh`B@p6jcwFdXg!f(s}Zx&EC>lQ{2CyGZz9`WcirRpZ~ ztJX6<+L&ikB8^JOt|8N;I8F;Web`K;Ilpt$Tr*p>YSd`eQq@gppoS{dNDDglE2>_* zpKYEg8HR4;X&bw8Iww|X$u!^fR6+MUL&QIf36KK-Qg$jL(WPkWC zxkgUgF*1PGRb|DXUpjVN6lsZwq8&33nV}C5H87BdO*_GtDoY~2w6tuqdIM=Tvud-X zt7MxclwmtchWHx7cGBAjnN*mfAbmoyUWOKprvpEfIc!SW6G)VPfn_VTd+zvN% z(@r5x7AYAbeacW<=gFbQj%*kTMt0PB7oxAhkMz}PpU1kcnxCy94H*(?bn`Q^zuG!M zAa7EUyh+Czn|AzKU6(Bt{m!5tIP^2r{3H243^NS#Z!qv8)xACN<>K?y(08e!z0`Zp zQ@QU_xo00Aq&{pVUPKaGBir{6xa`x3Zw8)6@&}RppQUy(_2kOqD_>r16<>uxboww3 z*wZ`met4*zzR)VSdp~L2Y$v;(Tzh92p-OU_dRHgl@Q9i}4AEd$uhcK?3(lyAyC{rxx0Uh?vz;!8HM%gybx^8_=N{6cx8 zY^V03=UU-*IJ!0T`Bb~_^q;1_n%envuWz`u(2n(O8~d>{hoRwj*saVV&w%d!?c#QI ztGTmy&~;&V^!h>9^)2>AJiVK_bP&J%k}gIL;uoAaAMCTkF9RMXpGSuGBg4;T+ic{E z8;@>m6`$OEd~+whm&)$5LzIt^|3m>3-HpEYPw?wkW{40(h}(_ie|n{ohY{lclS#g- d!QbLNrCj9OscacU{+>&gew+9QNS3=3KLeP&Q!4-f literal 0 HcmV?d00001 diff --git a/tools/previews/__pycache__/preview_dbd_hook.cpython-314.pyc b/tools/previews/__pycache__/preview_dbd_hook.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af891126856f51c038fec9bcd8f02d074d8f59cb GIT binary patch literal 3504 zcmc&%U2Gd!6~6Q1@z^ttCw8)KnjhOq)2!8QX}8&KME~T{w2exGnN}_sJ^5zWD32Ho+IL<&HHXL8jpM zqz_mbrBRj~`vBGeT_5@;0kgq;Um;*d>N9L>GrDBX>dNFV@Z`*ts?X$21J5>S51Oi4 zGBTPjy(>#|O(9o&yO^6+)mulj1)I<1@`|FGc~i>ebPmSx@H4`|%IIH+CjyT#yIpje zC!j_J%v|z;;P^WUYnD+j%D7)p3j5baDY{JoUF~IK;7r>oh1YE(H}V>hCPsF?6))kq zrBMp+tc|kBJtK`wlOi$pJ2%cEc_owyxaK02CbQ(>UAr0Gku@s&sz$@?LD#m`rim=N zKAMFr%MzpBhCYf!ddT_3P)2ZV8C3LOFQcg6`6i>2R6ml5gh$8g$aVNCKLAnw8N_%p z;j@{7xu8jg&CJP4u~f2|Swqr~zizX)Bwdk8APE;G^J}VNs3qw-*r;=k=IVlBN;6j^ zQdP0i%zZT_lcHY`%AVf)7C3zBBassf8+2W@(KPAS@~QP3qx$<5isyiF_^;1P;p z(lPREUMuAbQVx5g&gs3Na+2sS2xYWQa-KlFGjgy0PQTSTT*Xzr4C0UZ4I${5LZj zubp2?)`ZYfa+^Vcu*F9!d~}sw&98N?y|W%)Pk+jvdK^H!@Ws;(#CJbMgePFL{5A#c zmqrh`^?uTKt{eT4PkNyFxSKn7fckid0RDV19&mQ@JTSJ>-2o-3<7CzGc>^3NSuqoY zj&rpENhe$m${dCx)r49fh8nPs3QnWr5IzGn9CQb2zXcGLQO3P8P^OuhZbGN9Z5z4p zNIeHmkly=S<{AJ-Bo6O_j7UDyqjvWIZjiRSHKJ#C55Psd2(B(vZ#vg#rn#!fxVwR? z8ZNvvxtCdroetp1R1?0feYp{cq71Cnpi~ovt_Gnv61}apGx#oas5KsT)a`0pt;mW# z(f{VoX`~{pFRql?=SuGU8r8eUo!taD!Bs{H=)y8wn)Dvy0l9*&mdoJ$OLxt=UO|MK z`H;eusEtz5HU)Ik^qxn@|8sOJwwXcqYYM}zjp8VC&{eh8yZj+SJ~V(X{~X~G^k4ff z@~ydEGWvzS@9|9bl%rWRgrH3P-}Z8CZ+Hvg`~uq-;!Q@)q84y&NSnzUhGZJHKd;E} zVu6ZdEb`5VNnSB*uRg1o@{F_?XsQiU)fQiAcEKtJPnXz~I;#{HgN5mW7CZ6A(WA#= zXO!8}qG#5edTk8mk(~0BAZ=Ds3TjbSZrY5b>#7bluuw7<>E3T2ok?`*_;R(`Ty9D( z!D9#yg!=ieWP7!|E-BzFBhAYOv>r`|n;puoQj(QhHVKuJF`U}!6hGUiOZj5Xl;%y_ zV`wGWw1XGKG>IW5O^AGTY08u^0K0zhTS;@=O<7&%Bao- zf6RV(#^T}?F22DHS=^xtcW5oS$sH-5uW`ZKum14t{mdqpSexABz6vU#>-NH?5L-RF zDZE~u0E?BA%O_V(|KN0;4Ls;LSY<~Z1%_*_M6&SAs#{Z;l1k&XT+ho8Kt%Z86 z&|oDrXoU_u3?10&iQe|q!hKeFs1hEs!ov^4!**9sT?pOt-Syoct_rcb5WeTXGs={Dh=(^{>>;LJ=Plb^u0kl81O`-7c(-89UEB`FceR8n-;&JrJ zsdJss{P}qD;6x9F6BD0fE|=hOMw-(l`E4gW) z4jx~@aG9%xUMUAZXW(DL=L7J5**=44erd5v^*r)--MRLo^oGCh0p0hQLiB!Toqq!n C$ZdfD literal 0 HcmV?d00001 diff --git a/tools/previews/__pycache__/preview_hakari.cpython-314.pyc b/tools/previews/__pycache__/preview_hakari.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e07eeca8acfc8a8b62fb326e001c9fa6228d4da8 GIT binary patch literal 3111 zcmdrOOKcNIbk@7J*Y-NLX#$DkCU!z8h7?i~2>po4Z5-kN!QFrhs)@DO8?vplYt60+ zq!+6~DxgZCf(W)0eL#>qPloCC|Na`!{T{KoZTQ&)53=W zmiFW>>Rc)%$g-jdnwUyq7f5mNsV~4#Kz|~d3ayjj+6eg9*e_!`pp86j0J! zM{(j?6NC_t%&c_7IY11SIZt{zoeLh=-{1dg@Q|F(j)yI}MNxH|dQsKH8O(wbOq{~x zjCGeN3um(;c&$p<3oC}dJ|GI{p$%E>pTs_nEw*&uVSk$|^wqP5u zVml0wU0Ra0Fohj3t7h2n$w-?qY#|$F?z$-VI)dTTw1KML0K*0l%|`CFK+Qt#%nCrs zjog{piUUV8m~|E>dYWL;(&w))<)Dgqs*jv*4S36@8QnO`Q3)zeLTm!l-pjT1b8sF3 zqPbbR*%s5Nowqj5a+ZYUxokB{Kbxn<|C!u~pSPKLg*yPM5aM+=1q)N&&a=E@sCE`{ z&%Zg6r2Y&r_2uX!IsWQe4R@nwi!n1y@|kR{iJ|ybld9toN_LpDgvGSlAk%Q_CSSuY zxl)>-kCb)|25Yf)qfV5dy=WwdP>xAQrNNTR}SM*ZO7^^{+j9aIW$@A_UXWD4)*Oarp*yfBWKx=V zLDQ{jE-PueXM~R&i>4-`@dzI|ahx}rn9j~hvPyi?9r3Jial#;JRl_Y6z2CNvEMzLci29N*>J2Vo4Kq>r^(cPV0;&&A>#>iegT8RZR~^ zk48>cHN{WzhofODaWki+u%c+X)5vKm2agopX}DCSZBtm75h1WDCJiY_pxTz189|cq zepobm;J47r3TV~adgIjfmWp>r(Ys^GyR+i$FM9jG@s+&;h1jyszi_JTd+8=u_6;r$ z#mc@|VQkseR&fQ2u0X}rb=%do+}5=i8Ys67Ty}1-+snSai~EMlzTqda-`lKcm31$+ z>?*Ol?|QuV+}kSdP|+Q_IrQCYi|){pJ6drcDY}pRa(v01ER6iYcrG1Vw)-mf_M*ML zV)x&+`&U_Sh4tTN{a*|$%zggWt8$Y^R10t?NMLf~;$AY4TNaZhV3f5{5JZCv zr31fcq!KH}h+we~iJ81C|1iSD@TZ2j!S^~91hu*d|~X~g)A$Jak0+Z+D? literal 0 HcmV?d00001 diff --git a/tools/previews/__pycache__/preview_intro.cpython-314.pyc b/tools/previews/__pycache__/preview_intro.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d1edcae0acb59651f4825fd0357f6dc5f2339ee GIT binary patch literal 3567 zcmeGfTWlLy^^PB7d&Z8(u45;*>qnckbzhs^v?OKQrYX3rlTB-8iz$j55bSd+;h+4-s5xcJwDRqpb)^bp>_aT+Lj^{$UbV57;VTH`yATSZt5g(SwMNm2 zc90XqHZx1GhW#jJ{S*&lglbA=mD!6kRO2V&8S1AaDq+uI&9*i&0B?lvvpzs<NR6 z;qOBXkOk4#3GhawVP+d%BfzuaQ*5J>5~s{dC5T|;O9~KjT9AraMaG`@sbNJB3UXSM zxNAIjeTT__t|S~6Z>si8CR-{AN><@A8HolXJACCmfXe7Ibc}F3#ps7QjXVP}%3-8~ z85nKhen@*6rS%P=G+v$tdPhDNJND50F#Vc$BYj|N~e10Sn zDI#gpH9J&~cd#v*fwBo=&;OpaRs!jrHL)gruTWa>Bc*XJHAsTyZiph*+|h^ix^`Hh&#FN~si??A0|ol%-hu zL_1>2h)aD&E5q>+LMihUakQffF~VrVU_&7kKq&)*;>3mh2#MsYdd{10{=;B5L8W(o z?PTz|5N$RY{=6(j>bnY~msm$XZ>`q?*zVJ3lRKO)L8x=MMa!#drYuLb3u)U+x=;5u z?B2;{6`}M2U7kFoa~;}=t5<9OD$dq(R);&0-Ij**w$4gbZu=h2(Sy@)4bjD%k}mCVXAr^qUmE%ES5 z^Fm2pU~*ZRFA428ISUg1Zb<}Q=*YA%U&=2ybF(=y@}-jl1FuKUmgWl!=6PlM*syAm zII)n;aWR8x*1IgXsWuRtJ zf_6eR2q2Pg$_iIhZ4#HwXB6&+qMBu~z$>cr0y{bp&%6^)jN+oCz{X4_!fTE;hfWCtWXR87S!Uy|^XqV-Q1ct6Xi#dz*sS?+2u2iBMa>&&4B zGqA=C{KB=t43-m3m%nyp!`1)LzTrBtI+WOOCCXz>y1PLK*XUq_4*ii1HM>Kr(ZP-G z!9{A~@)d}`GZU3bJAj`20e z_$Qav9qICgraM#~Z@S#&v6eTyLT-8wE>VldCe7SFvvj8BUGc2b2Ob{Tq)#?`gSGGe z*taTYuJNp z_F(NBb^HDoBz1eJ<>{#=Dv9Os#dyo@t;Q;`zRhP7wS+Oyg_T(_QTS?P{w)9T*}BUg8o zs!+9)n@sen4|#*1^`PU!ccyETYu?z$sYSZk0w-Vp*#y%R~^bWOrd#mqP-miX8`Jff*dr-Vryf4&@ z%|K|S??-Po_xEj)ud-eX>h7(MRmN)bo1XryJ;>kx_bum|8LL#T9OgG)$vh!~w{MUH$Z33C>iwkvQ?<30d U;pOGjIu%?s1)my`$*;xuCt3(=xc~qF literal 0 HcmV?d00001 diff --git a/tools/tests/__pycache__/simulate_render.cpython-314.pyc b/tools/tests/__pycache__/simulate_render.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d2df8cb48fe3f5e5544547507353653a93df3a8 GIT binary patch literal 13042 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 H*=+g$Q({GU literal 0 HcmV?d00001