KAZIK/src_graphics/darts.inc
Artvasil09 23dc40ee5c feat: implement native darts mini-game, AI observer mode, and fortune session assets
- Darts: native 500-point match against Max with sway/fatigue mouse aim, parabolic throw camera, raster arm animations, and 16 camera-relative flying dart views

- AI Observer: autonomous spectator mode for Hold'em, Blackjack, Durak, and Billiards with profile isolation and playback controls

- Fortune Session: raster sprite packs, mist/orb animations, tarot divination spreads, and pack tools

- Hall Integration: wall dartboard in lounge, observer terminal dispatch, and bot turn hooks

- Packaging & Verification: updated installer streaming hash, synchronized launcher, passing check suites and release smoke checks
2026-10-24 22:10:25 +03:00

890 lines
17 KiB
PHP

; One immutable hit point drives scoring, dart geometry and the follow camera.
.code
LoadDarts3D PROC
invoke LoadAnimPack3D,OFFSET dtBoard3D,OFFSET dtBoardPath
test eax,eax
jz dt_load_fail
cmp dtBoard3D.imageWidth,512
jne dt_load_fail
cmp dtBoard3D.height,512
jne dt_load_fail
cmp dtBoard3D.frames,1
jne dt_load_fail
invoke LoadAnimPack3D,OFFSET dtHands3D,OFFSET dtHandsPath
test eax,eax
jz dt_load_fail
cmp dtHands3D.imageWidth,256
jne dt_load_fail
cmp dtHands3D.height,256
jne dt_load_fail
cmp dtHands3D.frames,16
jne dt_load_fail
invoke LoadAnimPack3D,OFFSET dtDart3D,OFFSET dtDartPath
test eax,eax
jz dt_load_fail
cmp dtDart3D.imageWidth,256
jne dt_load_fail
cmp dtDart3D.height,256
jne dt_load_fail
cmp dtDart3D.frames,16
jne dt_load_fail
invoke LoadAnimPack3D,OFFSET dtWall3D,OFFSET dtWallPath
test eax,eax
jz dt_load_fail
cmp dtWall3D.imageWidth,512
jne dt_load_fail
cmp dtWall3D.height,512
jne dt_load_fail
cmp dtWall3D.frames,1
jne dt_load_fail
invoke LoadAnimPack3D,OFFSET dtChair3D,OFFSET dtChairPath
test eax,eax
jz dt_load_fail
invoke LoadAnimPack3D,OFFSET dtTable3D,OFFSET dtTablePath
test eax,eax
jz dt_load_fail
invoke LoadAnimPack3D,OFFSET dtRoom3D,OFFSET dtRoomPath
test eax,eax
jz dt_load_fail
cmp dtRoom3D.imageWidth,256
jne dt_load_fail
cmp dtRoom3D.height,256
jne dt_load_fail
cmp dtRoom3D.frames,12
jne dt_load_fail
mov eax,1
ret
dt_load_fail:
call FreeDarts3D
xor eax,eax
ret
LoadDarts3D ENDP
FreeDarts3D PROC
invoke FreeAnimPack3D,OFFSET dtBoard3D
invoke FreeAnimPack3D,OFFSET dtHands3D
invoke FreeAnimPack3D,OFFSET dtDart3D
invoke FreeAnimPack3D,OFFSET dtWall3D
invoke FreeAnimPack3D,OFFSET dtChair3D
invoke FreeAnimPack3D,OFFSET dtTable3D
invoke FreeAnimPack3D,OFFSET dtRoom3D
ret
FreeDarts3D ENDP
ResetDarts3D PROC
mov dtState3D,DT_AIM
mov dtTimer3D,0
mov dtRemaining3D,500
mov dtVisitStart3D,500
mov dtScores3D,500
mov dtScores3D[4],500
mov dtActor3D,0
mov dtWinner3D,0
mov dtBotTimer3D,0
mov dtBotPrepared3D,0
mov dtScoreOpen3D,0
mov dtHistoryRows3D,1
mov dtHistory3D,500
mov dtHistory3D[4],500
mov dtWallDirty3D,1
mov dtCount3D,0
mov dtThrows3D,0
mov dtVisit3D,1
mov dtLast3D,0
mov dtBust3D,0
mov dtHolding3D,0
mov dtMouseReleased3D,0
mov dtHoldTime3D,0
mov dtCamX3D,0
mov dtCamY3D,0
mov dtCamZ3D,0
mov dtLens3D,DT_FOCAL
mov dtLookX3D,0
mov dtLookY3D,0
ret
ResetDarts3D ENDP
BeginDarts3D PROC
call LoadDarts3D
xor eax,1
mov dtError3D,eax
call ResetDarts3D
mov engineMode,MODE_DARTS
mov paused3D,0
mov mouseX3D,160
mov mouseY3D,107
mov dtCursorX3D,320*256
mov dtCursorY3D,214*256
call ClearKeys3D
mov mouseClick3D,0
ret
BeginDarts3D ENDP
DartsAim3D PROC uses ebx
local amplitude:DWORD,phase:DWORD,secondary:DWORD
; Smooth mixed phases and gradual hold fatigue; never scatter after release.
mov amplitude,10
cmp dtHolding3D,0
je dt_aim_phase
mov eax,dtHoldTime3D
sub eax,1200
jle dt_aim_phase
xor edx,edx
mov ecx,350
div ecx
cmp eax,8
jbe @F
mov eax,8
@@:
add amplitude,eax
dt_aim_phase:
mov eax,dtClock3D
xor edx,edx
mov ecx,3
div ecx
and eax,511
mov phase,eax
mov ebx,tableSin[eax*4]
imul ebx,amplitude
sar ebx,16
mov eax,dtClock3D
xor edx,edx
mov ecx,5
div ecx
add eax,91
and eax,511
mov secondary,eax
mov eax,tableSin[eax*4]
imul eax,3
sar eax,16
add ebx,eax
mov eax,dtCursorX3D
sub eax,320*256
imul eax,DT_WALL
cdq
mov ecx,DT_FOCAL*256
idiv ecx
cmp dtActor3D,0
je @F
mov eax,dtBotAimX3D
@@:
add eax,ebx
cmp eax,-290
jge @F
mov eax,-290
@@:
cmp eax,290
jle @F
mov eax,290
@@:
mov dtAimX3D,eax
mov eax,phase
mov ebx,tableCos[eax*4]
mov ecx,amplitude
sub ecx,2
imul ebx,ecx
sar ebx,16
mov eax,secondary
sub eax,58
and eax,511
mov eax,tableSin[eax*4]
imul eax,3
sar eax,16
add ebx,eax
mov eax,dtCursorY3D
mov edx,214*256
sub edx,eax
imul eax,edx,DT_WALL
cdq
mov ecx,DT_FOCAL*256
idiv ecx
cmp dtActor3D,0
je @F
mov eax,dtBotAimY3D
@@:
add eax,ebx
cmp eax,-245
jge @F
mov eax,-245
@@:
cmp eax,245
jle @F
mov eax,245
@@:
mov dtAimY3D,eax
ret
DartsAim3D ENDP
; Select a target from the visible score, then commit imperfect aim before release.
DartsBotAim3D PROC uses ebx esi
local ring:DWORD,target:DWORD
mov target,20
mov ring,103
mov eax,dtRemaining3D
cmp eax,20
ja dt_bot_double
mov target,eax
mov ring,53
jmp dt_bot_sector
dt_bot_double:
cmp eax,40
ja dt_bot_special
test eax,1
jnz dt_bot_special
shr eax,1
mov target,eax
mov ring,166
jmp dt_bot_sector
dt_bot_special:
cmp eax,50
jne @F
mov dtBotDesired3D,50
mov dtBotAimX3D,0
mov dtBotAimY3D,0
jmp dt_bot_scatter
@@:
cmp eax,25
jne @F
mov dtBotDesired3D,25
mov dtBotAimX3D,0
mov dtBotAimY3D,11
jmp dt_bot_scatter
@@:
cmp eax,60
ja dt_bot_sector
xor edx,edx
mov ecx,3
div ecx
test edx,edx
jnz dt_bot_single20
mov target,eax
jmp dt_bot_sector
dt_bot_single20:
mov ring,53
dt_bot_sector:
mov eax,target
cmp ring,103
jne @F
imul eax,3
@@:
cmp ring,166
jne @F
shl eax,1
@@:
mov dtBotDesired3D,eax
xor ebx,ebx
@@:
mov eax,dtSector3D[ebx*4]
cmp eax,target
je dt_bot_direction
inc ebx
cmp ebx,20
jb @B
xor ebx,ebx
dt_bot_direction:
imul eax,ebx,512
xor edx,edx
mov ecx,20
div ecx
mov esi,eax
mov eax,tableSin[esi*4]
imul eax,ring
sar eax,16
mov dtBotAimX3D,eax
mov eax,tableCos[esi*4]
imul eax,ring
sar eax,16
mov dtBotAimY3D,eax
dt_bot_scatter:
invoke RandomRange3D,17
sub eax,8
add dtBotAimX3D,eax
invoke RandomRange3D,17
sub eax,8
add dtBotAimY3D,eax
mov dtBotPrepared3D,1
ret
DartsBotAim3D ENDP
ThrowDarts3D PROC
cmp dtState3D,DT_AIM
jne dt_throw_done
cmp dtError3D,0
jne dt_throw_done
mov eax,dtAimX3D
mov dtHitX3D,eax
mov eax,dtAimY3D
mov dtHitY3D,eax
mov dtState3D,DT_RELEASE
mov dtTimer3D,0
mov dtHolding3D,0
mov dtMouseReleased3D,0
inc dtThrows3D
dt_throw_done:
ret
ThrowDarts3D ENDP
; Board units are millimetres: 6.35/15.9 bull, 99..107 triple, 162..170 double.
DartsScore3D PROC uses ebx x:SDWORD,y:SDWORD
local angle:DWORD,oldControl:WORD,truncate:WORD
cmp x,-170
jl dt_score_miss
cmp x,170
jg dt_score_miss
cmp y,-170
jl dt_score_miss
cmp y,170
jg dt_score_miss
mov eax,x
imul eax,eax
mov ebx,y
imul ebx,ebx
add ebx,eax
cmp ebx,170*170
ja dt_score_miss
cmp ebx,40
jbe dt_score_bull
cmp ebx,253
jbe dt_score_outer_bull
fnstcw oldControl
mov ax,oldControl
or ax,0C00h
mov truncate,ax
fldcw truncate
fild x
fild y
fpatan
fmul dtAngleFactor3D
fistp angle
fldcw oldControl
mov eax,angle
add eax,65536+1638
and eax,65535
imul eax,20
shr eax,16
mov eax,dtSector3D[eax*4]
mov edx,1
cmp ebx,162*162
jae dt_score_double
cmp ebx,99*99
jb dt_score_done
cmp ebx,107*107
ja dt_score_done
mov edx,3
imul eax,3
ret
dt_score_double:
mov edx,2
shl eax,1
ret
dt_score_bull:
mov eax,50
mov edx,2
ret
dt_score_outer_bull:
mov eax,25
mov edx,1
ret
dt_score_miss:
xor eax,eax
xor edx,edx
dt_score_done:
ret
DartsScore3D ENDP
SettleDarts3D PROC uses ebx
cmp dtState3D,DT_FLIGHT
jne dt_settle_done
invoke DartsScore3D,dtHitX3D,dtHitY3D
mov dtLast3D,eax
mov dtMultiplier3D,edx
mov ebx,dtCount3D
cmp ebx,3
jae dt_settle_done
mov dtMarkScore3D[ebx*4],eax
mov ecx,dtHitX3D
mov dtMarkX3D[ebx*4],ecx
mov ecx,dtHitY3D
mov dtMarkY3D[ebx*4],ecx
inc dtCount3D
mov ecx,dtRemaining3D
sub ecx,eax
js dt_bust
dt_score_accept:
mov dtRemaining3D,ecx
jmp dt_begin_impact
dt_bust:
mov eax,dtVisitStart3D
mov dtRemaining3D,eax
mov dtBust3D,1
dt_begin_impact:
mov ebx,dtActor3D
mov eax,dtRemaining3D
mov dtScores3D[ebx*4],eax
mov dtWallDirty3D,1
test eax,eax
jnz @F
mov dtWinner3D,ebx
@@:
cmp dtRemaining3D,0
je dt_record_visit
cmp dtCount3D,3
je dt_record_visit
cmp dtBust3D,0
je dt_no_record
dt_record_visit:
call DartsRecordScore3D
dt_no_record:
mov dtState3D,DT_IMPACT
mov dtTimer3D,0
invoke PlayCasinoSound3D,OFFSET soundClick,0,1
dt_settle_done:
ret
SettleDarts3D ENDP
DartsRecordScore3D PROC uses ebx esi edi
mov ebx,dtHistoryRows3D
cmp ebx,32
jb @F
lea esi,dtHistory3D[8]
lea edi,dtHistory3D
mov ecx,62
cld
rep movsd
mov ebx,31
@@:
mov eax,dtScores3D
mov dtHistory3D[ebx*8],eax
mov eax,dtScores3D[4]
mov dtHistory3D[ebx*8+4],eax
inc ebx
mov dtHistoryRows3D,ebx
mov dtWallDirty3D,1
ret
DartsRecordScore3D ENDP
HandleDarts3D PROC
invoke Pressed3D,9
test eax,eax
jz @F
xor dtScoreOpen3D,1
mov dtHolding3D,0
mov dtMouseReleased3D,0
@@:
cmp dtScoreOpen3D,0
jne dt_handle_done
invoke Pressed3D,52h
test eax,eax
jz @F
call ResetDarts3D
@@:
cmp mouseClick3D,0
je dt_handle_game
cmp mouseY3D,218
jb dt_handle_game
cmp mouseX3D,230
jb dt_handle_game
call ResetDarts3D
mov mouseClick3D,0
dt_handle_game:
cmp dtError3D,0
jne dt_handle_done
mov eax,deltaTime3D
add dtClock3D,eax
cmp dtState3D,DT_AIM
jne dt_animate
cmp dtActor3D,0
je dt_player_aim
cmp dtBotPrepared3D,0
jne @F
call DartsBotAim3D
@@:
call DartsAim3D
mov eax,deltaTime3D
add dtBotTimer3D,eax
cmp dtBotTimer3D,900
jb dt_handle_done
mov dtHolding3D,1
mov eax,dtBotTimer3D
sub eax,900
cmp eax,280
jbe @F
mov eax,280
@@:
mov dtHoldTime3D,eax
cmp dtBotTimer3D,1220
jb dt_handle_done
invoke DartsScore3D,dtAimX3D,dtAimY3D
cmp eax,dtBotDesired3D
je dt_bot_commit
cmp dtBotTimer3D,1600
jb dt_handle_done
dt_bot_commit:
call ThrowDarts3D
jmp dt_handle_done
dt_player_aim:
cmp mouseClick3D,0
je @F
mov dtHolding3D,1
mov dtHoldTime3D,0
@@:
cmp dtHolding3D,0
je dt_player_hover
mov eax,deltaTime3D
add dtHoldTime3D,eax
cmp dtHoldTime3D,4000
jbe @F
mov dtHoldTime3D,4000
@@:
dt_player_hover:
call DartsAim3D
cmp dtHolding3D,0
jne dt_player_release
mov dtMouseReleased3D,0
jmp dt_handle_done
dt_player_release:
cmp dtMouseReleased3D,0
je dt_handle_done
call ThrowDarts3D
jmp dt_handle_done
dt_animate:
mov eax,deltaTime3D
add dtTimer3D,eax
cmp dtState3D,DT_RELEASE
jne dt_animate_flight
cmp dtTimer3D,200
jb dt_handle_done
sub dtTimer3D,200
mov dtState3D,DT_FLIGHT
jmp dt_handle_done
dt_animate_flight:
cmp dtState3D,DT_FLIGHT
jne dt_animate_impact
cmp dtTimer3D,DT_THROW_MS
jb dt_handle_done
call SettleDarts3D
jmp dt_handle_done
dt_animate_impact:
cmp dtState3D,DT_IMPACT
jne dt_animate_return
cmp dtTimer3D,1300
jb dt_handle_done
mov dtState3D,DT_WIN
cmp dtRemaining3D,0
je dt_handle_done
mov dtState3D,DT_RETURN
mov dtTimer3D,0
jmp dt_handle_done
dt_animate_return:
cmp dtState3D,DT_RETURN
jne dt_handle_done
cmp dtTimer3D,750
jb dt_handle_done
cmp dtBust3D,0
jne dt_next_visit
cmp dtCount3D,3
jb dt_return_aim
dt_next_visit:
mov dtBust3D,0
mov dtCount3D,0
inc dtVisit3D
xor dtActor3D,1
mov eax,dtActor3D
mov eax,dtScores3D[eax*4]
mov dtRemaining3D,eax
mov dtVisitStart3D,eax
dt_return_aim:
mov dtState3D,DT_AIM
mov dtTimer3D,0
mov dtMouseReleased3D,0
mov dtHolding3D,0
mov dtHoldTime3D,0
mov dtBotPrepared3D,0
mov dtBotTimer3D,0
dt_handle_done:
mov mouseClick3D,0
ret
HandleDarts3D ENDP
DartsPath3D PROC uses ebx esi timeMs:DWORD
local progress:DWORD,pathX:DWORD,pathY:DWORD,pathZ:DWORD
mov eax,timeMs
cmp eax,DT_THROW_MS
jbe @F
mov eax,DT_THROW_MS
@@:
shl eax,16
xor edx,edx
mov ecx,DT_THROW_MS
div ecx
mov progress,eax
mov ebx,eax
imul eax,DT_WALL
sar eax,16
mov pathZ,eax
mov eax,dtHitX3D
sub eax,70
imul eax,ebx
sar eax,16
add eax,70
mov pathX,eax
mov eax,65536
sub eax,ebx
imul ebx
shrd eax,edx,16
imul eax,280
sar eax,16
mov esi,eax
mov eax,dtHitY3D
add eax,35
imul eax,ebx
sar eax,16
sub eax,35
add eax,esi
mov edx,eax
mov eax,pathX
mov ecx,pathZ
ret
DartsPath3D ENDP
; Real orbit: behind -> alongside the dart -> behind the impact, with one camera basis.
DartsCamera3D PROC uses ebx esi
local progress:DWORD,weight:DWORD,timeMs:DWORD,factor:DWORD
local length2:DWORD,span:DWORD,targetZ:DWORD,deltaX:DWORD,deltaZ:DWORD
mov timeMs,0
cmp dtState3D,DT_FLIGHT
jne @F
mov eax,dtTimer3D
mov timeMs,eax
jmp dt_camera_path
@@:
cmp dtState3D,DT_IMPACT
je dt_camera_end
cmp dtState3D,DT_WIN
je dt_camera_end
cmp dtState3D,DT_RETURN
jne dt_camera_path
dt_camera_end:
mov timeMs,DT_THROW_MS
dt_camera_path:
invoke DartsPath3D,timeMs
mov dtShotX3D,eax
mov dtShotY3D,edx
mov dtShotZ3D,ecx
mov eax,timeMs
cmp eax,DT_THROW_MS
jbe @F
mov eax,DT_THROW_MS
@@:
shl eax,16
xor edx,edx
mov ecx,DT_THROW_MS
div ecx
mov progress,eax
mov ebx,eax
shr eax,8
mov eax,tableSin[eax*4]
imul eax
shrd eax,edx,16
mov weight,eax
imul eax,260
sar eax,16
mov ecx,420
sub ecx,eax
mov eax,dtShotZ3D
sub eax,ecx
jns @F
xor eax,eax
@@:
mov dtCamZ3D,eax
mov eax,weight
imul eax,300
sar eax,16
mov ecx,dtShotX3D
sub ecx,70
sub ecx,eax
mov dtCamX3D,ecx
mov eax,weight
imul eax,80
sar eax,16
add eax,dtShotY3D
add eax,35
mov dtCamY3D,eax
mov eax,dtHitX3D
imul eax,ebx
sar eax,17
mov esi,eax
mov ecx,dtShotX3D
sub ecx,eax
imul ecx,weight
sar ecx,16
add ecx,esi
mov dtLookX3D,ecx
mov eax,dtHitY3D
imul eax,ebx
sar eax,17
mov esi,eax
mov ecx,dtShotY3D
sub ecx,eax
imul ecx,weight
sar ecx,16
add ecx,esi
mov dtLookY3D,ecx
mov eax,dtShotZ3D
sub eax,DT_WALL
imul eax,weight
sar eax,16
add eax,DT_WALL
mov targetZ,eax
cmp dtState3D,DT_RETURN
jne dt_camera_basis
mov eax,dtTimer3D
cmp eax,750
jbe @F
mov eax,750
@@:
mov ecx,750
sub ecx,eax
imul eax,ecx,65536
xor edx,edx
mov ecx,750
div ecx
mov ebx,eax
mov eax,dtCamX3D
imul eax,ebx
sar eax,16
mov dtCamX3D,eax
mov eax,dtCamY3D
imul eax,ebx
sar eax,16
mov dtCamY3D,eax
mov eax,dtCamZ3D
imul eax,ebx
sar eax,16
mov dtCamZ3D,eax
mov eax,dtLookX3D
imul eax,ebx
sar eax,16
mov dtLookX3D,eax
mov eax,dtLookY3D
imul eax,ebx
sar eax,16
mov dtLookY3D,eax
dt_camera_basis:
mov eax,dtCamZ3D
imul eax,550
xor edx,edx
mov ecx,DT_WALL-420
div ecx
mov ecx,DT_FOCAL
sub ecx,eax
mov eax,weight
imul eax,160
sar eax,16
sub ecx,eax
cmp ecx,350
jge @F
mov ecx,350
@@:
mov dtLens3D,ecx
mov eax,dtLookX3D
sub eax,dtCamX3D
mov deltaX,eax
imul eax,eax
mov ebx,targetZ
sub ebx,dtCamZ3D
mov deltaZ,ebx
imul ebx,ebx
add eax,ebx
mov length2,eax
fild length2
fsqrt
fistp span
cmp span,1
jge @F
mov span,1
@@:
mov eax,deltaX
shl eax,16
cdq
idiv span
mov dtYawSin3D,eax
mov eax,deltaZ
shl eax,16
cdq
idiv span
mov dtYawCos3D,eax
mov eax,dtLookY3D
sub eax,dtCamY3D
imul eax,dtLens3D
cdq
idiv span
add eax,214
mov dtScreenY3D,eax
mov dtScreenX3D,320
ret
DartsCamera3D ENDP
DartsProject3D PROC uses ebx x:SDWORD,y:SDWORD,z:SDWORD
local deltaX:DWORD,deltaZ:DWORD,depth:DWORD,side:DWORD
mov eax,x
sub eax,dtCamX3D
mov deltaX,eax
mov ebx,z
sub ebx,dtCamZ3D
mov deltaZ,ebx
imul eax,dtYawCos3D
imul ebx,dtYawSin3D
sub eax,ebx
sar eax,16
mov side,eax
mov eax,deltaX
imul eax,dtYawSin3D
mov ebx,deltaZ
imul ebx,dtYawCos3D
add eax,ebx
sar eax,16
mov depth,eax
cmp eax,16
jg @F
mov eax,16
@@:
mov ecx,eax
mov eax,side
imul eax,dtLens3D
cdq
idiv ecx
add eax,320
push eax
mov eax,y
sub eax,dtCamY3D
imul eax,dtLens3D
cdq
idiv ecx
mov edx,dtScreenY3D
sub edx,eax
pop eax
mov ecx,depth
ret
DartsProject3D ENDP
ResolveDartsSurface3D PROC
cmp dtBoard3D.pixels,0
jne @F
invoke LoadAnimPack3D,OFFSET dtBoard3D,OFFSET dtBoardPath
@@:
mov eax,dtBoard3D.pixels
mov ecx,512
mov edx,512
ret
ResolveDartsSurface3D ENDP
DrawHallDarts3D PROC
cmp hallLevel3D,0
jne @F
invoke DrawCityVertical3D,0,FP_1*3098/100,FP_1*275/10,FP_1*285/10,FP_1*115/100,FP_1*215/100,160
@@:
ret
DrawHallDarts3D ENDP
include src_graphics\darts_render.inc