.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