.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