; --- hell_tower.inc: Implementation of Hell Tower (10-floor Boss Rush) --- .code FreeTowerMinigameAssets PROC call FreeBuckshotAssets3D call FreeRussianAssets3D call FreeCardTableAssets3D call FreeNativeCoinArt3D call FreeNativeWheelArt3D ret FreeTowerMinigameAssets ENDP InitHellTower3D PROC call FreeTowerMinigameAssets mov tournamentMode, 1 mov towerStage, 1 mov towerFloorState, TOWER_STATE_BRIEFING mov towerAnimClock, 0 mov towerCalloutAnim, 0 mov eax, towerFloorY[0] mov towerCursorY, eax mov towerCursorTargetY, eax invoke LoadAnimPack3D, OFFSET hellTowerMenuArt3D, OFFSET hellTowerMenuPath3D call StopTowerMusic mov engineMode, MODE_HELL_TOWER call ClearKeys3D ret InitHellTower3D ENDP TowerExitToHall PROC call StopTowerMusic call FreeTowerMinigameAssets mov tournamentMode, 0 mov engineMode, MODE_WALK call ClearKeys3D ret TowerExitToHall ENDP TowerLaunchCurrentFloor PROC uses ebx esi edi mov eax, towerStage dec eax cmp eax, 10 jae @F jmp launch_valid @@: xor eax, eax launch_valid: mov edx, towerFloorModes[eax*4] mov towerCurrentGame, edx mov towerFloorState, TOWER_STATE_IN_GAME ; Launch corresponding game cmp edx, MODE_COIN jne @F call InitCoinGame mov engineMode, MODE_COIN jmp launch_done @@: cmp edx, MODE_DICE jne @F call InitDiceGame mov engineMode, MODE_DICE jmp launch_done @@: cmp edx, MODE_SKULLS jne @F call InitSkullsGame mov engineMode, MODE_SKULLS jmp launch_done @@: cmp edx, MODE_BLACKJACK jne @F call InitNativeBlackjack3D mov engineMode, MODE_BLACKJACK jmp launch_done @@: cmp edx, MODE_POKER jne @F call InitNativePoker3D mov engineMode, MODE_POKER jmp launch_done @@: cmp edx, MODE_RUSSIAN jne @F call InitRussianGame3D mov engineMode, MODE_RUSSIAN jmp launch_done @@: cmp edx, MODE_ROULETTE jne @F call InitNativeWheel3D mov engineMode, MODE_ROULETTE jmp launch_done @@: cmp edx, MODE_DURAK jne @F call InitNativeDurak3D mov engineMode, MODE_DURAK jmp launch_done @@: cmp edx, MODE_SKILL jne @F call InitSkillGame mov engineMode, MODE_SKILL jmp launch_done @@: cmp edx, MODE_BUCKSHOT jne launch_done call InitBuckshot3D mov engineMode, MODE_BUCKSHOT launch_done: call ClearKeys3D ret TowerLaunchCurrentFloor ENDP TowerReportRoundOutcome PROC uses eax outcome:DWORD cmp tournamentMode, 1 jne report_exit mov eax, outcome cmp eax, 1 jne report_loss ; --- Victory --- cmp towerStage, 10 jae report_champion mov towerFloorState, TOWER_STATE_CLEAR mov towerCalloutAnim, 0 mov eax, towerStage dec eax cmp eax, 10 jae @F mov edx, towerFloorY[eax*4] mov towerCursorTargetY, edx @@: invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 mov engineMode, MODE_HELL_TOWER call ClearKeys3D ret report_champion: mov towerFloorState, TOWER_STATE_CHAMPION mov eax, towerPrizeAmount add bankroll, eax invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1 call SaveProgress3D mov engineMode, MODE_HELL_TOWER call ClearKeys3D ret report_loss: invoke TriggerCharmLossProtection, 0 test eax, eax jz @F mov towerFloorState, TOWER_STATE_BRIEFING invoke CopyString3D, OFFSET msgCharmTowerSave, OFFSET flashMessage mov flashTimer, 140 mov engineMode, MODE_HELL_TOWER call ClearKeys3D ret @@: mov towerFloorState, TOWER_STATE_DEFEAT call StopTowerMusic invoke PlayCasinoSound3D, OFFSET soundRoundLose, 0, 1 mov engineMode, MODE_HELL_TOWER call ClearKeys3D ret report_exit: ret TowerReportRoundOutcome ENDP HandleHellTowerInput PROC mov eax, towerFloorState cmp eax, TOWER_STATE_BRIEFING je input_briefing cmp eax, TOWER_STATE_CLEAR je input_clear cmp eax, TOWER_STATE_DEFEAT je input_defeat cmp eax, TOWER_STATE_CHAMPION je input_champion ret input_briefing: invoke Pressed3D, 1Bh ; ESC test eax, eax jz @F call TowerExitToHall ret @@: invoke Pressed3D, 20h ; SPACE test eax, eax jnz start_stage invoke Pressed3D, 0Dh ; ENTER test eax, eax jnz start_stage ret start_stage: call TowerLaunchCurrentFloor ret input_clear: invoke Pressed3D, 1Bh ; ESC test eax, eax jz @F call TowerExitToHall ret @@: invoke Pressed3D, 20h ; SPACE test eax, eax jnz advance_stage invoke Pressed3D, 0Dh ; ENTER test eax, eax jnz advance_stage ret advance_stage: inc towerStage mov towerFloorState, TOWER_STATE_BRIEFING mov towerCalloutAnim, 0 mov eax, towerStage dec eax cmp eax, 10 jae @F mov edx, towerFloorY[eax*4] mov towerCursorTargetY, edx @@: call ClearKeys3D ret input_defeat: invoke Pressed3D, 1Bh ; ESC test eax, eax jnz exit_to_hall invoke Pressed3D, 20h ; SPACE test eax, eax jnz exit_to_hall invoke Pressed3D, 0Dh ; ENTER test eax, eax jnz exit_to_hall ret input_champion: invoke Pressed3D, 1Bh ; ESC test eax, eax jnz exit_to_hall invoke Pressed3D, 20h ; SPACE test eax, eax jnz exit_to_hall invoke Pressed3D, 0Dh ; ENTER test eax, eax jnz exit_to_hall ret exit_to_hall: call TowerExitToHall ret HandleHellTowerInput ENDP RenderHellTower3D PROC uses ebx esi edi local cardX:DWORD, cardY:DWORD, cardW:DWORD, cardH:DWORD local currY:DWORD, tgtY:DWORD ; 1. Background: draw HellTower menu art if loaded, else fallback to maroon cmp hellTowerMenuArt3D.pixels, 0 je fallback_clear cmp hellTowerMenuArt3D.imageWidth, SCREEN_W jne fallback_sprite cmp hellTowerMenuArt3D.height, SCREEN_H jne fallback_sprite mov esi, hellTowerMenuArt3D.pixels lea edi, screenBuffer mov ecx, SCREEN_SIZE rep movsd jmp bg_done fallback_sprite: invoke DrawAnimSprite3D, OFFSET hellTowerMenuArt3D, 0, 0, 0, SCREEN_W, SCREEN_H jmp bg_done fallback_clear: lea edi, screenBuffer mov ecx, SCREEN_SIZE mov eax, 00100202h rep stosd bg_done: ; 2. Update towerAnimClock inc towerAnimClock ; 3. Smooth cursor Y movement towards towerCursorTargetY (exponential damping) mov eax, towerCursorTargetY cmp eax, towerCursorY je cursor_update_done jg cursor_move_down ; Moving UP towards tower peak (target < current) mov ecx, towerCursorY sub ecx, eax shr ecx, 2 inc ecx sub towerCursorY, ecx mov eax, towerCursorTargetY cmp towerCursorY, eax jge cursor_update_done mov towerCursorY, eax jmp cursor_update_done cursor_move_down: ; Moving DOWN towards tower base (target > current) mov ecx, eax sub ecx, towerCursorY shr ecx, 2 inc ecx add towerCursorY, ecx mov eax, towerCursorTargetY cmp towerCursorY, eax jle cursor_update_done mov towerCursorY, eax cursor_update_done: ; 4. Update sliding callout animation (0 to 100%) cmp towerCalloutAnim, 100 jge callout_step_done add towerCalloutAnim, 10 cmp towerCalloutAnim, 100 jle callout_step_done mov towerCalloutAnim, 100 callout_step_done: ; 5. Calculate sliding callout card dimensions occupying free left space: ; Max width = 206, fixed right bound = 214, top = 20, height = 208 mov cardH, 208 mov cardY, 20 ; cardW = 206 * towerCalloutAnim / 100 mov eax, 206 imul eax, towerCalloutAnim xor edx, edx mov ecx, 100 div ecx cmp eax, 10 jae @F mov eax, 10 @@: mov cardW, eax ; cardX = 214 - cardW mov edx, 214 sub edx, cardW mov cardX, edx ; 6. Draw glowing cursor & indicator on the tower (Right side) ; Indicator line from card right edge (214) to cursor on tower (X=224) mov eax, towerCursorY invoke DrawBox, 214, eax, 10, 2, 00FF4444h ; Cursor chevron/diamond at X=224 mov eax, towerCursorY sub eax, 3 invoke DrawBoxBorder, 224, eax, 7, 7, 00FF3300h, 00FFDD44h, 1 ; Pulsing flame pip on the tower floor at X=234 mov eax, towerAnimClock and eax, 8 jz pip_bright mov edx, 00EE3300h jmp pip_draw pip_bright: mov edx, 00FFAA22h pip_draw: mov eax, towerCursorY sub eax, 2 invoke DrawBox, 234, eax, 5, 5, edx ; 7. Draw Callout Box (outer and inner border with deep infernal tint) invoke DrawBoxBorder, cardX, cardY, cardW, cardH, 00120202h, 00CC2222h, 2 mov eax, cardX add eax, 2 mov edx, cardY add edx, 2 mov ecx, cardW sub ecx, 4 mov ebx, cardH sub ebx, 4 invoke DrawBoxBorder, eax, edx, ecx, ebx, 000C0202h, 00551111h, 1 ; Only render full content once card has slid out sufficiently (cardW >= 120) cmp cardW, 120 jb render_tower_done ; Header Banner: "ÊÀÇÈÍÎ 3D - ÀÄÑÊÀß ÁÀØÍß" mov eax, cardX add eax, 6 mov ecx, cardW sub ecx, 12 invoke DrawBoxBorder, eax, 26, ecx, 18, 00220404h, 00FF4444h, 1 mov eax, cardX add eax, 12 invoke DrawString8x8, eax, 31, OFFSET towerHeader, 00FFDD66h ; Floor indicator: "ÝÒÀÆ N / 10" mov eax, cardX add eax, 10 invoke DrawString8x8, eax, 50, OFFSET towerFloorPrefix, 00FF6666h invoke FormatNumber, towerStage, OFFSET hudNumBuffer mov eax, cardX add eax, 50 invoke DrawString8x8, eax, 50, OFFSET hudNumBuffer, 00FFFFFFh mov eax, cardX add eax, 58 invoke DrawString8x8, eax, 50, OFFSET towerOfTen, 00AAAAAAh ; Specific state content inside the card mov eax, towerFloorState cmp eax, TOWER_STATE_BRIEFING je render_card_briefing cmp eax, TOWER_STATE_CLEAR je render_card_clear cmp eax, TOWER_STATE_DEFEAT je render_card_defeat cmp eax, TOWER_STATE_CHAMPION je render_card_champion jmp render_tower_done render_card_briefing: ; Boss & Game sub-card mov eax, cardX add eax, 6 mov ecx, cardW sub ecx, 12 invoke DrawBoxBorder, eax, 64, ecx, 62, 001E0404h, 00881818h, 1 mov eax, cardX add eax, 10 invoke DrawString8x8, eax, 70, OFFSET towerEnemyLabel, 00FFAA55h mov eax, towerStage dec eax mov edx, towerBossNames[eax*4] mov eax, cardX add eax, 56 invoke DrawString8x8, eax, 70, edx, 00FFFFFFh mov eax, cardX add eax, 10 invoke DrawString8x8, eax, 84, OFFSET towerGameLabel, 00FFAA55h mov eax, towerStage dec eax mov edx, towerGameNames[eax*4] mov eax, cardX add eax, 56 invoke DrawString8x8, eax, 84, edx, 00FFDD66h mov eax, towerStage dec eax mov edx, towerDescriptions[eax*4] mov eax, cardX add eax, 10 invoke DrawString8x8, eax, 100, edx, 00CCCCCCh ; Rules & warning mov eax, cardX add eax, 10 invoke DrawString8x8, eax, 134, OFFSET towerRuleText, 00FFAA33h mov eax, cardX add eax, 10 invoke DrawString8x8, eax, 148, OFFSET towerLossWarning, 00EE4444h ; Bankroll & Prize mov eax, cardX add eax, 10 invoke DrawString8x8, eax, 164, OFFSET textBank3D, 00AAAAAAh invoke FormatNumber, bankroll, OFFSET hudNumBuffer mov eax, cardX add eax, 56 invoke DrawString8x8, eax, 164, OFFSET hudNumBuffer, 0066FF66h mov eax, cardX add eax, 110 invoke DrawString8x8, eax, 164, OFFSET towerPrizePrompt, 00FFAA55h invoke FormatNumber, towerPrizeAmount, OFFSET hudNumBuffer mov eax, cardX add eax, 154 invoke DrawString8x8, eax, 164, OFFSET hudNumBuffer, 00FFDD44h ; Action Buttons (Start & Escape) mov eax, cardX add eax, 8 invoke DrawBoxBorder, eax, 186, 92, 22, 003D0C0Ch, 00FF4444h, 1 mov eax, cardX add eax, 14 invoke DrawString8x8, eax, 193, OFFSET towerStartBtn, 00FFFFFFh mov eax, cardX add eax, 106 invoke DrawBoxBorder, eax, 186, 92, 22, 00220606h, 00882222h, 1 mov eax, cardX add eax, 114 invoke DrawString8x8, eax, 193, OFFSET towerEscBtn, 00AAAAAAh jmp render_tower_done render_card_clear: mov eax, cardX add eax, 8 mov ecx, cardW sub ecx, 16 invoke DrawBoxBorder, eax, 74, ecx, 60, 00082208h, 0033CC33h, 2 mov eax, cardX add eax, 14 invoke DrawString8x8, eax, 86, OFFSET towerClearTitle, 0066FF66h mov eax, cardX add eax, 14 invoke DrawString8x8, eax, 108, OFFSET towerClearDesc, 00FFFFFFh mov eax, cardX add eax, 18 mov ecx, cardW sub ecx, 36 invoke DrawBoxBorder, eax, 186, ecx, 22, 00114411h, 0044FF44h, 1 mov eax, cardX add eax, 42 invoke DrawString8x8, eax, 193, OFFSET towerNextBtn, 00FFFFFFh jmp render_tower_done render_card_defeat: mov eax, cardX add eax, 8 mov ecx, cardW sub ecx, 16 invoke DrawBoxBorder, eax, 74, ecx, 60, 002A0404h, 00FF2222h, 2 mov eax, cardX add eax, 14 invoke DrawString8x8, eax, 86, OFFSET towerDefeatTitle, 00FF4444h mov eax, cardX add eax, 14 invoke DrawString8x8, eax, 108, OFFSET towerDefeatDesc, 00FFFFFFh mov eax, cardX add eax, 16 mov ecx, cardW sub ecx, 32 invoke DrawBoxBorder, eax, 186, ecx, 22, 00441010h, 00FF4444h, 1 mov eax, cardX add eax, 22 invoke DrawString8x8, eax, 193, OFFSET towerReturnBtn, 00FFFFFFh jmp render_tower_done render_card_champion: mov eax, cardX add eax, 8 mov ecx, cardW sub ecx, 16 invoke DrawBoxBorder, eax, 68, ecx, 72, 00332200h, 00FFD700h, 2 mov eax, cardX add eax, 12 invoke DrawString8x8, eax, 78, OFFSET towerChampTitle, 00FFE066h mov eax, cardX add eax, 16 invoke DrawString8x8, eax, 96, OFFSET towerChampSubtitle, 00FFFFFFh mov eax, cardX add eax, 14 invoke DrawString8x8, eax, 116, OFFSET towerPrizeText, 0066FF66h mov eax, cardX add eax, 16 mov ecx, cardW sub ecx, 32 invoke DrawBoxBorder, eax, 186, ecx, 22, 00443300h, 00FFCC00h, 1 mov eax, cardX add eax, 22 invoke DrawString8x8, eax, 193, OFFSET towerReturnBtn, 00FFFFFFh render_tower_done: ret RenderHellTower3D ENDP RenderTowerInGameBadge PROC cmp tournamentMode, 1 jne badge_done cmp engineMode, MODE_HELL_TOWER je badge_done cmp engineMode, MODE_WALK je badge_done invoke DrawBoxBorder, 4, 4, 96, 16, 00220404h, 00FF3333h, 1 invoke DrawString8x8, 8, 8, OFFSET towerHudBadge, 00FFAA55h invoke FormatNumber, towerStage, OFFSET hudNumBuffer invoke DrawString8x8, 64, 8, OFFSET hudNumBuffer, 00FFFFFFh invoke DrawString8x8, 72, 8, OFFSET towerHudOfTen, 00AAAAAAh badge_done: ret RenderTowerInGameBadge ENDP