.data nvTestPath db 'build\hall-expansion\npc-visits.bin',0 nvTestOrder db 'build\hall-expansion\npc-visit-order.bmp',0 nvTestDrink db 'build\hall-expansion\npc-visit-drink.bmp',0 nvTestSeat db 'build\hall-expansion\npc-visit-seat.bmp',0 nvTestWin db 'build\hall-expansion\npc-visit-win.bmp',0 nvTestLoss db 'build\hall-expansion\npc-visit-loss.bmp',0 ; slot, identity, cast, activities, destinations, walking ticks, journeys, chips. nvTestRecords dd NPC_LIFE_COUNT*8 dup(0) .code NpcVisitsNativeTests PROC uses ebx esi edi local ticks:DWORD,bank:DWORD,rng:DWORD,handle:DWORD,count:DWORD,bits:DWORD local savedClock:DWORD,seenResults:DWORD mov expansionStage,200 mov hallLevel3D,0 mov engineMode,MODE_WALK mov worldMap3D,OFFSET casinoMap mov playerX,FP_1*305/10 mov playerY,FP_1*305/10 mov eax,bankroll mov bank,eax mov eax,seed mov rng,eax call NpcChairMotionNativeTests call InitNpcLife3D mov bits,0 xor esi,esi nv_test_identity: imul ebx,esi,SIZEOF NpcLife3D imul edi,esi,32 mov nvTestRecords[edi],esi mov eax,npcLife3D[ebx].identity mov nvTestRecords[edi+4],eax mov eax,npcGuestAppearance3D[eax*4] mov nvTestRecords[edi+8],eax bts bits,eax jc nv_test_fail inc esi cmp esi,NPC_LIFE_COUNT jb nv_test_identity cmp bits,1023 jne nv_test_fail xor esi,esi nv_test_paths: invoke NpcPlanPath3D,0,esi cmp eax,1 jne nv_test_fail inc esi cmp esi,NPC_DEST_COUNT jb nv_test_paths call InitNpcLife3D mov expansionStage,201 mov deltaTime3D,50 mov ticks,9600 nv_test_tick: call UpdateNpcLife3D xor esi,esi nv_test_person: imul ebx,esi,SIZEOF NpcLife3D imul edi,esi,32 mov eax,npcLife3D[ebx].identity cmp eax,nvTestRecords[edi+4] jne nv_test_fail cmp npcVisitChips3D[esi*4],0 jl nv_test_fail cmp npcVisitChips3D[esi*4],100000 ja nv_test_fail mov eax,npcVisitActivity3D[esi*4] cmp eax,NV_YIELD ja nv_test_fail bts nvTestRecords[edi+12],eax mov eax,npcLife3D[ebx].destination cmp eax,NPC_DEST_COUNT jae nv_test_fail cmp npcLife3D[ebx].state,NPC_WALK jne @F inc nvTestRecords[edi+20] jmp nv_test_bounds @@: cmp npcVisitActivity3D[esi*4],NV_IDLE je nv_test_bounds cmp npcVisitActivity3D[esi*4],NV_YIELD je nv_test_bounds bts nvTestRecords[edi+16],eax nv_test_bounds: invoke NpcEntity3D,esi mov ebx,eax invoke CanWalk3D,[ebx].NpcMindEntity.posX,[ebx].NpcMindEntity.posY cmp eax,1 jne nv_test_fail inc esi cmp esi,NPC_LIFE_COUNT jb nv_test_person xor esi,esi mov bits,0 nv_test_station: mov eax,npcStationOwner3D[esi*4] cmp eax,-1 je nv_test_station_next cmp eax,NPC_LIFE_COUNT jae nv_test_fail bts bits,eax jc nv_test_fail imul ebx,eax,SIZEOF NpcLife3D cmp npcLife3D[ebx].destination,esi jne nv_test_fail cmp npcLife3D[ebx].state,NPC_AWAY je nv_test_fail nv_test_station_next: inc esi cmp esi,NPC_DEST_COUNT jb nv_test_station dec ticks jnz nv_test_tick mov expansionStage,202 xor esi,esi nv_test_record: imul edi,esi,32 imul ebx,esi,SIZEOF NpcLife3D mov eax,npcLife3D[ebx].routeStep mov nvTestRecords[edi+24],eax mov eax,npcVisitChips3D[esi*4] mov nvTestRecords[edi+28],eax cmp nvTestRecords[edi+20],50 jb nv_test_fail inc esi cmp esi,NPC_LIFE_COUNT jb nv_test_record invoke CreateFileA,OFFSET nvTestPath,40000000h,0,0,2,80h,0 mov handle,eax invoke WriteFile,handle,OFFSET nvTestRecords,SIZEOF nvTestRecords,ADDR count,0 invoke CloseHandle,handle mov eax,bankroll cmp eax,bank jne nv_test_fail mov eax,seed cmp eax,rng jne nv_test_fail mov eax,npcLifeClock3D mov savedClock,eax mov engineMode,MODE_NPC_DIALOG call UpdateNpcLife3D mov eax,savedClock cmp npcLifeClock3D,eax jne nv_test_fail mov engineMode,MODE_WALK mov hallLevel3D,HALL_ROOF call UpdateNpcLife3D mov eax,savedClock cmp npcLifeClock3D,eax jne nv_test_fail mov hallLevel3D,0 mov expansionStage,204 call InitNpcLife3D mov esi,1 nv_test_yield_clear: imul ebx,esi,SIZEOF NpcLife3D mov npcLife3D[ebx].state,NPC_AWAY inc esi cmp esi,NPC_LIFE_COUNT jb nv_test_yield_clear invoke NpcReleaseStation3D,0 invoke NpcPlanPath3D,0,5 cmp eax,1 jne nv_test_fail mov npcStationOwner3D[5*4],0 mov npcLife3D.state,NPC_WALK mov eax,casinoNpcs3D.posX mov playerX,eax mov eax,casinoNpcs3D.posY mov playerY,eax invoke NpcMove3D,0,16 cmp npcVisitActivity3D,NV_YIELD jne nv_test_fail cmp npcLife3D.pathCount,0 je nv_test_fail mov ticks,7 nv_test_yield_retry: invoke NpcAdvanceVisit3D,0 invoke NpcMove3D,0,16 dec ticks jnz nv_test_yield_retry cmp npcLife3D.pathCount,0 jne nv_test_fail cmp npcStationOwner3D[5*4],-1 jne nv_test_fail cmp npcWalkDistance3D,0 jne nv_test_fail mov expansionStage,203 call InitNpcLife3D xor esi,esi nv_test_hide: imul ebx,esi,SIZEOF NpcLife3D mov npcLife3D[ebx].state,NPC_AWAY inc esi cmp esi,NPC_LIFE_COUNT jb nv_test_hide mov npcLife3D.destination,10 mov casinoNpcs3D.posX,FP_1*65/10 mov casinoNpcs3D.posY,FP_1*255/10 invoke NpcArrive3D,0 mov playerX,FP_1*65/10 mov playerY,FP_1*282/10 mov playerAngle,384 call UpdateInteriorEye3D call ExpansionFrame invoke ExpansionSnapshot,OFFSET nvTestOrder invoke NpcAdvanceVisit3D,0 cmp npcVisitActivity3D,NV_DRINK jne nv_test_fail mov npcLife3D.poseClock,360 call ExpansionFrame invoke ExpansionSnapshot,OFFSET nvTestDrink mov npcLife3D.destination,7 mov casinoNpcs3D.posX,FP_1*135/10 mov casinoNpcs3D.posY,FP_1*195/10 invoke NpcArrive3D,0 mov npcLife3D.poseClock,1200 mov npcSitTime3D,800 mov playerX,13*FP_1 mov playerY,FP_1*215/10 call ExpansionFrame invoke ExpansionSnapshot,OFFSET nvTestSeat mov npcSprite3D.posX,FP_1*135/10 mov npcSprite3D.posY,FP_1*195/10 invoke NpcResolveVisitPose3D,0 cmp eax,CAST_SEAT jne nv_test_fail cmp npcSprite3D.posX,13*FP_1 jne nv_test_fail cmp npcSprite3D.posY,FP_1*195/10-FP_1*35/100 jne nv_test_fail mov seenResults,0 mov ticks,32 mov npcLife3D.destination,2 mov casinoNpcs3D.posX,FP_1*105/10 mov casinoNpcs3D.posY,FP_1*135/10 mov playerX,FP_1*105/10 mov playerY,16*FP_1 nv_test_result: invoke NpcArrive3D,0 invoke NpcAdvanceVisit3D,0 mov npcLife3D.poseClock,360 call ExpansionFrame cmp npcVisitActivity3D,NV_WIN jne nv_test_loss invoke ExpansionSnapshot,OFFSET nvTestWin or seenResults,1 jmp nv_test_result_next nv_test_loss: cmp npcVisitActivity3D,NV_LOSS jne nv_test_fail invoke ExpansionSnapshot,OFFSET nvTestLoss or seenResults,2 nv_test_result_next: cmp seenResults,3 je nv_test_done dec ticks jnz nv_test_result jmp nv_test_fail nv_test_done: call InitNpcLife3D ret nv_test_fail: invoke ExitProcess,expansionStage ret NpcVisitsNativeTests ENDP include tools/tests/npc_chair_motion_test.inc