- Billiards: add native Russian Pyramid & American Eight-Ball pool with physics prediction, controls, and regression tests - Scratch Tickets: add dedicated counter, mat presentation, elliptical coin scraping, 4 ticket types, and payout effects - First-Person Dice: add native dice scene, hand anchor frames, throwing animation, and table perspective - City Wake & Weather: add arrival cutscene, alley geometry, weather/rain effects, and lighter/rocker animation - World Dressing: add hall paintings, furniture packs, hall lighting, and scene regression tests - Build & Tooling: update build.bat for modern MSVC toolchain, update launcher hash, and refresh shipping binaries
348 lines
9 KiB
PHP
348 lines
9 KiB
PHP
.data
|
|
eightRegressionStage3D dd 0
|
|
eightRegressionShotBmp3D db "build\actions\eight-human-shot.bmp",0
|
|
eightRegressionGroupBmp3D db "build\actions\eight-group-credit.bmp",0
|
|
.code
|
|
EightRegressionPot3D PROC uses ebx
|
|
mov pressedKeys3D[20h],1
|
|
mov deltaTime3D,16
|
|
call HandlePool3D
|
|
cmp poolState3D,POOL_STRIKE
|
|
jne eight_regression_pot_failed
|
|
call RenderPool3D
|
|
mov deltaTime3D,240
|
|
call HandlePool3D
|
|
mov ebx,2000
|
|
eight_regression_motion:
|
|
mov deltaTime3D,16
|
|
call HandlePool3D
|
|
call RenderPool3D
|
|
cmp poolState3D,POOL_MOVING
|
|
jne eight_regression_pot_done
|
|
dec ebx
|
|
jnz eight_regression_motion
|
|
eight_regression_pot_failed:
|
|
xor eax,eax
|
|
ret
|
|
eight_regression_pot_done:
|
|
mov eax,1
|
|
ret
|
|
EightRegressionPot3D ENDP
|
|
|
|
RunEightRegression3D PROC uses ebx esi edi
|
|
local actor:DWORD,guide:DWORD,oldBank:DWORD,oldSeed:DWORD
|
|
mov eax,bankroll
|
|
mov oldBank,eax
|
|
mov eax,rngSeed3D
|
|
mov oldSeed,eax
|
|
mov eightRegressionStage3D,10
|
|
invoke StartBilliards3D,1
|
|
mov poolBreak3D,0
|
|
mov poolGroups3D,1
|
|
mov poolGroups3D[4],2
|
|
mov esi,1
|
|
eight_regression_clear:
|
|
mov poolActive3D[esi*4],0
|
|
inc esi
|
|
cmp esi,16
|
|
jb eight_regression_clear
|
|
mov poolActive3D[5*4],1
|
|
mov poolActive3D[6*4],1
|
|
mov poolActive3D[9*4],1
|
|
mov poolX3D,160*FP_1
|
|
mov poolY3D,100*FP_1
|
|
mov poolX3D[5*4],160*FP_1
|
|
mov poolY3D[5*4],70*FP_1
|
|
mov poolX3D[6*4],220*FP_1
|
|
mov poolY3D[6*4],120*FP_1
|
|
mov poolX3D[9*4],240*FP_1
|
|
mov poolY3D[9*4],140*FP_1
|
|
mov poolPower3D,45000
|
|
invoke PoolAimPoint3D,160*FP_1,70*FP_1
|
|
; Ordinary aim/Space/render path, with the stale default call still present.
|
|
call EightRegressionPot3D
|
|
test eax,eax
|
|
jz eight_regression_failed
|
|
mov eightRegressionStage3D,11
|
|
cmp poolActive3D[5*4],0
|
|
jne eight_regression_failed
|
|
mov eightRegressionStage3D,12
|
|
cmp poolPlayer3D,0
|
|
jne eight_regression_failed
|
|
cmp poolState3D,POOL_AIM
|
|
jne eight_regression_failed
|
|
cmp pyrOwner3D[5*4],0
|
|
jne eight_regression_failed
|
|
cmp pyrScore3D,6
|
|
jne eight_regression_failed
|
|
cmp pyrScore3D[4],6
|
|
jne eight_regression_failed
|
|
invoke WriteActionSnapshot3D,OFFSET eightRegressionShotBmp3D
|
|
mov eightRegressionStage3D,13
|
|
mov deltaTime3D,1200
|
|
call HandlePool3D
|
|
cmp poolState3D,POOL_AIM
|
|
jne eight_regression_failed
|
|
; The same human must be able to make a second normal shot immediately.
|
|
mov poolX3D,160*FP_1
|
|
mov poolY3D,100*FP_1
|
|
mov poolX3D[6*4],160*FP_1
|
|
mov poolY3D[6*4],70*FP_1
|
|
invoke PoolAimPoint3D,160*FP_1,70*FP_1
|
|
call EightRegressionPot3D
|
|
cmp eax,1
|
|
jne eight_regression_failed
|
|
cmp poolPlayer3D,0
|
|
jne eight_regression_failed
|
|
cmp pyrScore3D,7
|
|
jne eight_regression_failed
|
|
cmp pyrOwner3D[6*4],0
|
|
jne eight_regression_failed
|
|
; The same ordinary-shot path works for either actor with guides on or off.
|
|
mov actor,0
|
|
eight_regression_actor:
|
|
mov guide,0
|
|
eight_regression_guide:
|
|
mov eightRegressionStage3D,14
|
|
invoke StartBilliards3D,1
|
|
mov eax,actor
|
|
mov poolPlayer3D,eax
|
|
mov poolAI3D,0
|
|
mov eax,guide
|
|
mov pyrGuideOn3D,eax
|
|
mov poolBreak3D,0
|
|
mov esi,1
|
|
eight_regression_actor_clear:
|
|
mov poolActive3D[esi*4],0
|
|
inc esi
|
|
cmp esi,16
|
|
jb eight_regression_actor_clear
|
|
mov poolActive3D[5*4],1
|
|
mov poolActive3D[9*4],1
|
|
mov poolX3D,160*FP_1
|
|
mov poolY3D,100*FP_1
|
|
mov poolX3D[5*4],160*FP_1
|
|
mov poolY3D[5*4],70*FP_1
|
|
mov poolX3D[9*4],240*FP_1
|
|
mov poolY3D[9*4],140*FP_1
|
|
mov poolPower3D,45000
|
|
invoke PoolAimPoint3D,160*FP_1,70*FP_1
|
|
call RenderPool3D
|
|
cmp poolCalled3D,5
|
|
jne eight_regression_failed
|
|
cmp poolCalledPocket3D,1
|
|
jne eight_regression_failed
|
|
call EightRegressionPot3D
|
|
cmp eax,1
|
|
jne eight_regression_failed
|
|
mov ebx,actor
|
|
cmp poolPlayer3D,ebx
|
|
jne eight_regression_failed
|
|
cmp poolGroups3D[ebx*4],1
|
|
jne eight_regression_failed
|
|
cmp pyrOwner3D[5*4],ebx
|
|
jne eight_regression_failed
|
|
inc guide
|
|
cmp guide,2
|
|
jb eight_regression_guide
|
|
inc actor
|
|
cmp actor,2
|
|
jb eight_regression_actor
|
|
mov poolAI3D,1
|
|
mov pyrGuideOn3D,1
|
|
; Each independent manual override remains binding across real input/render.
|
|
mov guide,0
|
|
eight_regression_manual:
|
|
mov eightRegressionStage3D,15
|
|
invoke StartBilliards3D,1
|
|
mov poolBreak3D,0
|
|
mov poolGroups3D,1
|
|
mov poolGroups3D[4],2
|
|
mov esi,1
|
|
eight_regression_manual_clear:
|
|
mov poolActive3D[esi*4],0
|
|
inc esi
|
|
cmp esi,16
|
|
jb eight_regression_manual_clear
|
|
mov poolActive3D[5*4],1
|
|
mov poolActive3D[2*4],1
|
|
mov poolActive3D[9*4],1
|
|
mov poolX3D,160*FP_1
|
|
mov poolY3D,100*FP_1
|
|
mov poolX3D[5*4],160*FP_1
|
|
mov poolY3D[5*4],70*FP_1
|
|
mov poolX3D[2*4],220*FP_1
|
|
mov poolY3D[2*4],120*FP_1
|
|
mov poolX3D[9*4],240*FP_1
|
|
mov poolY3D[9*4],140*FP_1
|
|
mov poolPower3D,45000
|
|
invoke PoolAimPoint3D,160*FP_1,70*FP_1
|
|
mov eax,guide
|
|
mov poolCallManual3D,eax
|
|
mov poolCalled3D,2
|
|
mov poolCalledPocket3D,4
|
|
call RenderPool3D
|
|
test guide,1
|
|
jz eight_regression_auto_ball
|
|
cmp poolCalled3D,2
|
|
jne eight_regression_failed
|
|
jmp eight_regression_manual_pocket
|
|
eight_regression_auto_ball:
|
|
cmp poolCalled3D,5
|
|
jne eight_regression_failed
|
|
eight_regression_manual_pocket:
|
|
test guide,2
|
|
jz eight_regression_auto_pocket
|
|
cmp poolCalledPocket3D,4
|
|
jne eight_regression_failed
|
|
jmp eight_regression_manual_shoot
|
|
eight_regression_auto_pocket:
|
|
mov eax,1
|
|
test guide,1
|
|
jz @F
|
|
mov eax,-1
|
|
@@:
|
|
cmp poolCalledPocket3D,eax
|
|
jne eight_regression_failed
|
|
eight_regression_manual_shoot:
|
|
call EightRegressionPot3D
|
|
cmp eax,1
|
|
jne eight_regression_failed
|
|
cmp poolActive3D[5*4],0
|
|
jne eight_regression_failed
|
|
xor eax,eax
|
|
cmp guide,0
|
|
je @F
|
|
inc eax
|
|
@@:
|
|
cmp poolPlayer3D,eax
|
|
jne eight_regression_failed
|
|
cmp poolCallManual3D,0
|
|
jne eight_regression_failed
|
|
inc guide
|
|
cmp guide,4
|
|
jb eight_regression_manual
|
|
; Exhaustive group credit is independent of the shooter and a foul.
|
|
mov actor,0
|
|
eight_regression_credit_actor:
|
|
mov guide,0
|
|
eight_regression_credit_foul:
|
|
mov eightRegressionStage3D,16
|
|
invoke StartBilliards3D,1
|
|
mov eax,actor
|
|
mov poolPlayer3D,eax
|
|
mov poolGroups3D,1
|
|
mov poolGroups3D[4],2
|
|
mov poolBreak3D,0
|
|
mov poolFirst3D,1
|
|
cmp actor,0
|
|
je @F
|
|
mov poolFirst3D,9
|
|
@@:
|
|
mov poolRail3D,1
|
|
mov poolCalled3D,1
|
|
mov poolCalledPocket3D,1
|
|
mov poolPotted3D,202h
|
|
mov poolActive3D[4],0
|
|
mov poolActive3D[9*4],0
|
|
mov poolPocket3D[4],1
|
|
mov poolPocket3D[9*4],1
|
|
cmp guide,0
|
|
je @F
|
|
mov poolActive3D,0
|
|
or poolPotted3D,1
|
|
@@:
|
|
call PoolFinishShot3D
|
|
cmp pyrScore3D,1
|
|
jne eight_regression_failed
|
|
cmp pyrScore3D[4],1
|
|
jne eight_regression_failed
|
|
cmp pyrOwner3D[4],0
|
|
jne eight_regression_failed
|
|
cmp pyrOwner3D[9*4],1
|
|
jne eight_regression_failed
|
|
call PoolFinishShot3D
|
|
cmp pyrScore3D,1
|
|
jne eight_regression_failed
|
|
cmp pyrScore3D[4],1
|
|
jne eight_regression_failed
|
|
inc guide
|
|
cmp guide,2
|
|
jb eight_regression_credit_foul
|
|
inc actor
|
|
cmp actor,2
|
|
jb eight_regression_credit_actor
|
|
call RenderPool3D
|
|
invoke WriteActionSnapshot3D,OFFSET eightRegressionGroupBmp3D
|
|
; Real AI scheduling retains a legal pot but stops after a miss.
|
|
mov eightRegressionStage3D,17
|
|
invoke StartBilliards3D,1
|
|
mov poolPlayer3D,1
|
|
mov poolAI3D,1
|
|
mov poolGroups3D,2
|
|
mov poolGroups3D[4],1
|
|
mov poolBreak3D,0
|
|
mov esi,1
|
|
eight_regression_ai_clear:
|
|
mov poolActive3D[esi*4],0
|
|
inc esi
|
|
cmp esi,16
|
|
jb eight_regression_ai_clear
|
|
mov poolActive3D[5*4],1
|
|
mov poolActive3D[6*4],1
|
|
mov poolActive3D[9*4],1
|
|
mov poolX3D,160*FP_1
|
|
mov poolY3D,100*FP_1
|
|
mov poolX3D[5*4],160*FP_1
|
|
mov poolY3D[5*4],70*FP_1
|
|
mov poolX3D[6*4],220*FP_1
|
|
mov poolY3D[6*4],120*FP_1
|
|
mov poolX3D[9*4],240*FP_1
|
|
mov poolY3D[9*4],140*FP_1
|
|
mov deltaTime3D,1200
|
|
call HandlePool3D
|
|
cmp poolState3D,POOL_STRIKE
|
|
jne eight_regression_failed
|
|
call RenderPool3D
|
|
mov deltaTime3D,240
|
|
call HandlePool3D
|
|
mov ebx,2000
|
|
eight_regression_ai_motion:
|
|
mov deltaTime3D,16
|
|
call HandlePool3D
|
|
call RenderPool3D
|
|
cmp poolState3D,POOL_MOVING
|
|
jne eight_regression_ai_finished
|
|
dec ebx
|
|
jnz eight_regression_ai_motion
|
|
jmp eight_regression_failed
|
|
eight_regression_ai_finished:
|
|
cmp poolActive3D[5*4],0
|
|
jne eight_regression_failed
|
|
cmp poolPlayer3D,1
|
|
jne eight_regression_failed
|
|
cmp pyrOwner3D[5*4],1
|
|
jne eight_regression_failed
|
|
mov pyrSettled3D,0
|
|
mov poolFirst3D,6
|
|
mov poolRail3D,1
|
|
mov poolPotted3D,0
|
|
call PoolFinishShot3D
|
|
cmp poolPlayer3D,0
|
|
jne eight_regression_failed
|
|
mov deltaTime3D,1200
|
|
call HandlePool3D
|
|
cmp poolState3D,POOL_AIM
|
|
jne eight_regression_failed
|
|
mov eax,oldBank
|
|
cmp bankroll,eax
|
|
jne eight_regression_failed
|
|
mov eax,oldSeed
|
|
cmp rngSeed3D,eax
|
|
jne eight_regression_failed
|
|
xor eax,eax
|
|
ret
|
|
eight_regression_failed:
|
|
mov eax,eightRegressionStage3D
|
|
ret
|
|
RunEightRegression3D ENDP
|