- Bowling feel: impulse contact solver, string pinsetter cycle, in-world lengthwise return rack and visible ball return lift - Ball weights: 4/5/6/7 kg selection with equal launch work physics, momentum balance, and projected picking - Audio: dedicated MCI channels with 7 synthesized waveaudio cues (release, rolling, impacts, applause, pinsetter, return) - First-person animations: 33-frame player underarm throw/follow-through sequence (player-underarm-v2) - Visitors: 10 persistent shared cast identities with exclusive reservations, activity transitions, and chair sit/rise animations - Tests & verification: comprehensive native regression test suites and updated documentation - Synchronize binaries and update launcher hash to 536E23BED4055562BC63871826FF44FFED037923A9BE8E0F591131DB4FBD104B
240 lines
6.6 KiB
PHP
240 lines
6.6 KiB
PHP
.data
|
|
ncTestSit0 db 'build\hall-expansion\npc-chair-sit-0.bmp',0
|
|
ncTestSit1 db 'build\hall-expansion\npc-chair-sit-1.bmp',0
|
|
ncTestSit2 db 'build\hall-expansion\npc-chair-sit-2.bmp',0
|
|
ncTestSit3 db 'build\hall-expansion\npc-chair-sit-3.bmp',0
|
|
ncTestSit4 db 'build\hall-expansion\npc-chair-sit-4.bmp',0
|
|
ncTestSit5 db 'build\hall-expansion\npc-chair-sit-5.bmp',0
|
|
ncTestSit6 db 'build\hall-expansion\npc-chair-sit-6.bmp',0
|
|
ncTestSit7 db 'build\hall-expansion\npc-chair-sit-7.bmp',0
|
|
ncTestSit8 db 'build\hall-expansion\npc-chair-sit-8.bmp',0
|
|
ncTestSit9 db 'build\hall-expansion\npc-chair-sit-9.bmp',0
|
|
ncTestChat db 'build\hall-expansion\npc-chair-chat.bmp',0
|
|
ncTestRise0 db 'build\hall-expansion\npc-chair-rise-0.bmp',0
|
|
ncTestRise1 db 'build\hall-expansion\npc-chair-rise-1.bmp',0
|
|
ncTestRise2 db 'build\hall-expansion\npc-chair-rise-2.bmp',0
|
|
ncTestRise3 db 'build\hall-expansion\npc-chair-rise-3.bmp',0
|
|
ncTestRise4 db 'build\hall-expansion\npc-chair-rise-4.bmp',0
|
|
ncTestRise5 db 'build\hall-expansion\npc-chair-rise-5.bmp',0
|
|
ncTestRise6 db 'build\hall-expansion\npc-chair-rise-6.bmp',0
|
|
ncTestRise7 db 'build\hall-expansion\npc-chair-rise-7.bmp',0
|
|
ncTestRise8 db 'build\hall-expansion\npc-chair-rise-8.bmp',0
|
|
ncTestSitPaths dd OFFSET ncTestSit0,OFFSET ncTestSit1,OFFSET ncTestSit2,OFFSET ncTestSit3,OFFSET ncTestSit4
|
|
dd OFFSET ncTestSit5,OFFSET ncTestSit6,OFFSET ncTestSit7,OFFSET ncTestSit8,OFFSET ncTestSit9
|
|
ncTestRisePaths dd OFFSET ncTestRise0,OFFSET ncTestRise1,OFFSET ncTestRise2,OFFSET ncTestRise3,OFFSET ncTestRise4
|
|
dd OFFSET ncTestRise5,OFFSET ncTestRise6,OFFSET ncTestRise7,OFFSET ncTestRise8
|
|
.code
|
|
NpcChairMotionNativeTests PROC uses ebx esi edi
|
|
local startX:DWORD,startY:DWORD,endX:DWORD,endY:DWORD,px:DWORD,py:DWORD
|
|
local ticks:DWORD,lastX:DWORD,lastY:DWORD
|
|
mov expansionStage,210
|
|
call InitNpcLife3D
|
|
mov playerX,FP_1*305/10
|
|
mov playerY,FP_1*305/10
|
|
invoke NpcPlanPath3D,0,7
|
|
cmp eax,1
|
|
jne nc_test_fail
|
|
mov eax,casinoNpcs3D.posX
|
|
mov startX,eax
|
|
mov eax,casinoNpcs3D.posY
|
|
mov startY,eax
|
|
mov esi,npcLife3D.pathCount
|
|
nc_test_edge:
|
|
dec esi
|
|
mov eax,npcPaths3D[esi*4]
|
|
mov edx,eax
|
|
and eax,31
|
|
shl eax,16
|
|
add eax,FP_HALF
|
|
mov endX,eax
|
|
shr edx,5
|
|
shl edx,16
|
|
add edx,FP_HALF
|
|
mov endY,edx
|
|
mov edi,1
|
|
nc_test_edge_sample:
|
|
mov eax,endX
|
|
sub eax,startX
|
|
imul eax,edi
|
|
sar eax,2
|
|
add eax,startX
|
|
mov px,eax
|
|
mov eax,endY
|
|
sub eax,startY
|
|
imul eax,edi
|
|
sar eax,2
|
|
add eax,startY
|
|
mov py,eax
|
|
invoke CanWalk3D,px,py
|
|
cmp eax,1
|
|
jne nc_test_fail
|
|
inc edi
|
|
cmp edi,4
|
|
jbe nc_test_edge_sample
|
|
mov eax,endX
|
|
mov startX,eax
|
|
mov eax,endY
|
|
mov startY,eax
|
|
test esi,esi
|
|
jnz nc_test_edge
|
|
mov expansionStage,211
|
|
mov npcLife3D.destination,7
|
|
mov casinoNpcs3D.posX,FP_1*135/10
|
|
mov casinoNpcs3D.posY,FP_1*195/10
|
|
invoke NpcArrive3D,0
|
|
mov npcSprite3D.posX,FP_1*135/10
|
|
mov npcSprite3D.posY,FP_1*195/10
|
|
invoke NpcResolveVisitPose3D,0
|
|
cmp npcSprite3D.posX,FP_1*135/10
|
|
jne nc_test_fail
|
|
cmp npcSprite3D.posY,FP_1*195/10
|
|
jne nc_test_fail
|
|
mov expansionStage,212
|
|
call InitNpcLife3D
|
|
mov esi,1
|
|
nc_test_hide:
|
|
imul ebx,esi,SIZEOF NpcLife3D
|
|
mov npcLife3D[ebx].state,NPC_AWAY
|
|
mov npcLife3D[ebx].remaining,1000000
|
|
invoke NpcReleaseStation3D,esi
|
|
inc esi
|
|
cmp esi,NPC_LIFE_COUNT
|
|
jb nc_test_hide
|
|
; The guest from the reported screenshot approaches the chair through gameplay.
|
|
mov npcLife3D.identity,3
|
|
invoke NpcReleaseStation3D,0
|
|
invoke NpcPlanPath3D,0,7
|
|
cmp eax,1
|
|
jne nc_test_fail
|
|
mov npcStationOwner3D[7*4],0
|
|
mov npcLife3D.state,NPC_WALK
|
|
mov npcVisitActivity3D,NV_IDLE
|
|
mov deltaTime3D,16
|
|
mov ticks,1500
|
|
nc_test_real_approach:
|
|
call UpdateNpcLife3D
|
|
cmp npcLife3D.state,NPC_SIT
|
|
je nc_test_sit_begin
|
|
cmp npcLife3D.state,NPC_WALK
|
|
jne nc_test_fail
|
|
dec ticks
|
|
jnz nc_test_real_approach
|
|
jmp nc_test_fail
|
|
nc_test_sit_begin:
|
|
cmp npcSitTime3D,0
|
|
jne nc_test_fail
|
|
mov playerX,14*FP_1
|
|
mov playerY,FP_1*222/10
|
|
mov playerAngle,384
|
|
call UpdateInteriorEye3D
|
|
xor esi,esi
|
|
mov deltaTime3D,0
|
|
nc_test_sit_frames:
|
|
call UpdateNpcLife3D
|
|
call ExpansionFrame
|
|
invoke ExpansionSnapshot,ncTestSitPaths[esi*4]
|
|
mov eax,npcSprite3D.frame
|
|
xor edx,edx
|
|
mov ecx,CAST_STRIDE
|
|
div ecx
|
|
mov ebx,edx
|
|
cmp esi,8
|
|
jae nc_test_sit_hold
|
|
lea eax,[esi+56]
|
|
cmp ebx,eax
|
|
jne nc_test_fail
|
|
jmp nc_test_sit_anchor
|
|
nc_test_sit_hold:
|
|
cmp ebx,12
|
|
jb nc_test_fail
|
|
cmp ebx,15
|
|
ja nc_test_fail
|
|
nc_test_sit_anchor:
|
|
mov eax,npcSprite3D.posX
|
|
test esi,esi
|
|
jz nc_test_sit_save
|
|
mov edx,lastX
|
|
sub edx,eax
|
|
cmp edx,0
|
|
jl nc_test_fail
|
|
cmp edx,FP_1/10
|
|
jg nc_test_fail
|
|
nc_test_sit_save:
|
|
mov lastX,eax
|
|
mov eax,npcSprite3D.posY
|
|
mov lastY,eax
|
|
mov deltaTime3D,100
|
|
inc esi
|
|
cmp esi,10
|
|
jb nc_test_sit_frames
|
|
mov expansionStage,213
|
|
; Changing from resting to conversation must not restart the sit-down strip.
|
|
invoke NpcEntity3D,1
|
|
mov [eax].NpcMindEntity.posX,FP_1*155/10
|
|
mov [eax].NpcMindEntity.posY,FP_1*195/10
|
|
mov npcLife3D[SIZEOF NpcLife3D].state,NPC_SIT
|
|
invoke NpcAdvanceVisit3D,0
|
|
cmp npcVisitActivity3D,NV_CHAT
|
|
jne nc_test_fail
|
|
cmp npcLife3D.poseClock,0
|
|
jne nc_test_fail
|
|
mov npcLife3D[SIZEOF NpcLife3D].state,NPC_AWAY
|
|
call ExpansionFrame
|
|
mov eax,npcSprite3D.frame
|
|
xor edx,edx
|
|
mov ecx,CAST_STRIDE
|
|
div ecx
|
|
cmp edx,16
|
|
jne nc_test_fail
|
|
mov eax,npcSprite3D.posX
|
|
cmp eax,lastX
|
|
jne nc_test_fail
|
|
mov eax,npcSprite3D.posY
|
|
cmp eax,lastY
|
|
jne nc_test_fail
|
|
invoke ExpansionSnapshot,OFFSET ncTestChat
|
|
invoke NpcChooseVisit3D,0
|
|
cmp eax,1
|
|
jne nc_test_fail
|
|
cmp npcRise3D,800
|
|
jne nc_test_fail
|
|
mov deltaTime3D,0
|
|
xor esi,esi
|
|
nc_test_rise_frames:
|
|
call UpdateNpcLife3D
|
|
call ExpansionFrame
|
|
invoke ExpansionSnapshot,ncTestRisePaths[esi*4]
|
|
mov eax,npcSprite3D.frame
|
|
xor edx,edx
|
|
mov ecx,CAST_STRIDE
|
|
div ecx
|
|
mov ebx,edx
|
|
test esi,esi
|
|
jnz nc_test_rise_anchor
|
|
mov eax,npcSprite3D.posX
|
|
cmp eax,lastX
|
|
jne nc_test_fail
|
|
mov eax,npcSprite3D.posY
|
|
cmp eax,lastY
|
|
jne nc_test_fail
|
|
nc_test_rise_anchor:
|
|
cmp esi,8
|
|
jae nc_test_rise_end
|
|
mov eax,63
|
|
sub eax,esi
|
|
cmp ebx,eax
|
|
jne nc_test_fail
|
|
jmp nc_test_rise_next
|
|
nc_test_rise_end:
|
|
cmp ebx,3
|
|
ja nc_test_fail
|
|
nc_test_rise_next:
|
|
mov deltaTime3D,100
|
|
inc esi
|
|
cmp esi,9
|
|
jb nc_test_rise_frames
|
|
ret
|
|
nc_test_fail:
|
|
invoke ExitProcess,expansionStage
|
|
ret
|
|
NpcChairMotionNativeTests ENDP
|