- Align tower progression and cursor coordinates strictly to the 6 floors: Coin, Dice, Cards, Russian Roulette, Roulette, Buckshot - Recalibrate tower cursor Y positions for each tier (205, 174, 143, 112, 81, 50) - Reformat UI text, labels, and action buttons to strictly fit within card and sub-card boundaries without clipping - Remove redundant 'КАЗИНО 3D' prefix from header banner, keeping bold centered 'АДСКАЯ БАШНЯ' - Rebuild shipping binaries and verify complete 6-floor test suite
574 lines
14 KiB
PHP
574 lines
14 KiB
PHP
; --- hell_tower.inc: Implementation of Hell Tower (6-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, 6
|
||
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_BLACKJACK
|
||
jne @F
|
||
call InitNativeBlackjack3D
|
||
mov engineMode, MODE_BLACKJACK
|
||
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_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, 6
|
||
jae report_champion
|
||
|
||
mov towerFloorState, TOWER_STATE_CLEAR
|
||
mov towerCalloutAnim, 0
|
||
mov eax, towerStage
|
||
dec eax
|
||
cmp eax, 6
|
||
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, 6
|
||
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 = 16, height = 208
|
||
mov cardH, 208
|
||
mov cardY, 16
|
||
|
||
; 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: "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>" (Centered, NO "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3D")
|
||
mov eax, cardX
|
||
add eax, 6
|
||
mov ecx, cardW
|
||
sub ecx, 12
|
||
invoke DrawBoxBorder, eax, 22, ecx, 18, 00220404h, 00FF4444h, 1
|
||
mov eax, cardX
|
||
add eax, 55
|
||
invoke DrawString8x8, eax, 27, OFFSET towerHeader, 00FFDD66h
|
||
|
||
; Floor indicator: "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> N / 6" and Prize prompt
|
||
mov eax, cardX
|
||
add eax, 12
|
||
invoke DrawString8x8, eax, 46, OFFSET towerFloorPrefix, 00FF6666h
|
||
invoke FormatNumber, towerStage, OFFSET hudNumBuffer
|
||
mov eax, cardX
|
||
add eax, 52
|
||
invoke DrawString8x8, eax, 46, OFFSET hudNumBuffer, 00FFFFFFh
|
||
mov eax, cardX
|
||
add eax, 60
|
||
invoke DrawString8x8, eax, 46, OFFSET towerOfTen, 00AAAAAAh
|
||
|
||
mov eax, cardX
|
||
add eax, 105
|
||
invoke DrawString8x8, eax, 46, OFFSET towerPrizePrompt, 00FFAA55h
|
||
invoke FormatNumber, towerPrizeAmount, OFFSET hudNumBuffer
|
||
mov eax, cardX
|
||
add eax, 149
|
||
invoke DrawString8x8, eax, 46, OFFSET hudNumBuffer, 00FFDD44h
|
||
|
||
; 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 (Y = 60 to 130)
|
||
mov eax, cardX
|
||
add eax, 6
|
||
mov ecx, cardW
|
||
sub ecx, 12
|
||
invoke DrawBoxBorder, eax, 60, ecx, 70, 001E0404h, 00881818h, 1
|
||
|
||
mov eax, cardX
|
||
add eax, 12
|
||
invoke DrawString8x8, eax, 66, OFFSET towerEnemyLabel, 00FFAA55h
|
||
mov eax, towerStage
|
||
dec eax
|
||
mov edx, towerBossNames[eax*4]
|
||
mov eax, cardX
|
||
add eax, 60
|
||
invoke DrawString8x8, eax, 66, edx, 00FFFFFFh
|
||
|
||
mov eax, cardX
|
||
add eax, 12
|
||
invoke DrawString8x8, eax, 80, OFFSET towerGameLabel, 00FFAA55h
|
||
mov eax, towerStage
|
||
dec eax
|
||
mov edx, towerGameNames[eax*4]
|
||
mov eax, cardX
|
||
add eax, 60
|
||
invoke DrawString8x8, eax, 80, edx, 00FFDD66h
|
||
|
||
mov eax, towerStage
|
||
dec eax
|
||
mov edx, towerDescriptions[eax*4]
|
||
mov eax, cardX
|
||
add eax, 12
|
||
invoke DrawString8x8, eax, 98, edx, 00CCCCCCh
|
||
|
||
; Rules & warning box (Y = 134 to 166)
|
||
mov eax, cardX
|
||
add eax, 6
|
||
mov ecx, cardW
|
||
sub ecx, 12
|
||
invoke DrawBoxBorder, eax, 134, ecx, 32, 00180303h, 00661111h, 1
|
||
mov eax, cardX
|
||
add eax, 12
|
||
invoke DrawString8x8, eax, 139, OFFSET towerRuleText, 00FFAA33h
|
||
mov eax, cardX
|
||
add eax, 12
|
||
invoke DrawString8x8, eax, 151, OFFSET towerLossWarning, 00FF5555h
|
||
|
||
; Bankroll & Prize (Y = 172)
|
||
mov eax, cardX
|
||
add eax, 12
|
||
invoke DrawString8x8, eax, 172, OFFSET textBank3D, 00AAAAAAh
|
||
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
|
||
mov eax, cardX
|
||
add eax, 60
|
||
invoke DrawString8x8, eax, 172, OFFSET hudNumBuffer, 0066FF66h
|
||
|
||
; Action Buttons (Y = 188 to 212)
|
||
mov eax, cardX
|
||
add eax, 6
|
||
invoke DrawBoxBorder, eax, 188, 93, 24, 003D0C0Ch, 00FF4444h, 1
|
||
mov eax, cardX
|
||
add eax, 12
|
||
invoke DrawString8x8, eax, 196, OFFSET towerStartBtn, 00FFFFFFh
|
||
|
||
mov eax, cardX
|
||
add eax, 107
|
||
invoke DrawBoxBorder, eax, 188, 93, 24, 00220606h, 00882222h, 1
|
||
mov eax, cardX
|
||
add eax, 113
|
||
invoke DrawString8x8, eax, 196, OFFSET towerEscBtn, 00AAAAAAh
|
||
jmp render_tower_done
|
||
|
||
render_card_clear:
|
||
mov eax, cardX
|
||
add eax, 6
|
||
mov ecx, cardW
|
||
sub ecx, 12
|
||
invoke DrawBoxBorder, eax, 62, ecx, 80, 00082208h, 0033CC33h, 2
|
||
mov eax, cardX
|
||
add eax, 51
|
||
invoke DrawString8x8, eax, 76, OFFSET towerClearTitle, 0066FF66h
|
||
mov eax, cardX
|
||
add eax, 47
|
||
invoke DrawString8x8, eax, 96, OFFSET towerClearDesc, 00FFFFFFh
|
||
|
||
mov eax, cardX
|
||
add eax, 18
|
||
invoke DrawBoxBorder, eax, 176, 170, 26, 00114411h, 0044FF44h, 1
|
||
mov eax, cardX
|
||
add eax, 47
|
||
invoke DrawString8x8, eax, 184, OFFSET towerNextBtn, 00FFFFFFh
|
||
jmp render_tower_done
|
||
|
||
render_card_defeat:
|
||
mov eax, cardX
|
||
add eax, 6
|
||
mov ecx, cardW
|
||
sub ecx, 12
|
||
invoke DrawBoxBorder, eax, 62, ecx, 80, 002A0404h, 00FF2222h, 2
|
||
mov eax, cardX
|
||
add eax, 31
|
||
invoke DrawString8x8, eax, 76, OFFSET towerDefeatTitle, 00FF4444h
|
||
mov eax, cardX
|
||
add eax, 27
|
||
invoke DrawString8x8, eax, 98, OFFSET towerDefeatDesc, 00FFFFFFh
|
||
|
||
mov eax, cardX
|
||
add eax, 18
|
||
invoke DrawBoxBorder, eax, 176, 170, 26, 00441010h, 00FF4444h, 1
|
||
mov eax, cardX
|
||
add eax, 31
|
||
invoke DrawString8x8, eax, 184, OFFSET towerReturnBtn, 00FFFFFFh
|
||
jmp render_tower_done
|
||
|
||
render_card_champion:
|
||
mov eax, cardX
|
||
add eax, 6
|
||
mov ecx, cardW
|
||
sub ecx, 12
|
||
invoke DrawBoxBorder, eax, 58, ecx, 92, 00332200h, 00FFD700h, 2
|
||
mov eax, cardX
|
||
add eax, 43
|
||
invoke DrawString8x8, eax, 70, OFFSET towerChampTitle, 00FFE066h
|
||
mov eax, cardX
|
||
add eax, 27
|
||
invoke DrawString8x8, eax, 90, OFFSET towerChampSubtitle, 00FFFFFFh
|
||
mov eax, cardX
|
||
add eax, 19
|
||
invoke DrawString8x8, eax, 114, OFFSET towerPrizeText, 0066FF66h
|
||
|
||
mov eax, cardX
|
||
add eax, 18
|
||
invoke DrawBoxBorder, eax, 176, 170, 26, 00443300h, 00FFCC00h, 1
|
||
mov eax, cardX
|
||
add eax, 31
|
||
invoke DrawString8x8, eax, 184, 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, 88, 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
|