From a1f08995ef4a01480d61a93db8ceecca6f72d3cb Mon Sep 17 00:00:00 2001 From: ricardoofnl Date: Thu, 3 Sep 2026 00:42:26 +0700 Subject: [PATCH] [saco] Add `sub_10075330`; the nametag pass was absent, 15 register bytes off an edi/ebp swap --- saco/d3dhook/IDirect3DDevice9Hook.cpp | 79 ++++++++++++++++++++++++++- saco/game/entity.h | 1 + saco/game/playerped.h | 2 + saco/game/scripting.h | 1 + saco/net/netgame.h | 8 ++- saco/net/playerpool.h | 4 ++ saco/net/remoteplayer.h | 1 + 7 files changed, 93 insertions(+), 3 deletions(-) diff --git a/saco/d3dhook/IDirect3DDevice9Hook.cpp b/saco/d3dhook/IDirect3DDevice9Hook.cpp index 04307ad..67758e2 100644 --- a/saco/d3dhook/IDirect3DDevice9Hook.cpp +++ b/saco/d3dhook/IDirect3DDevice9Hook.cpp @@ -24,6 +24,7 @@ int dword_101516D8; extern CGame *pGame; extern CChatWindow *pChatWindow; +extern CNewPlayerTags *pNewPlayerTags; extern GAME_SETTINGS tSettings; int dword_1012DE64; @@ -45,6 +46,11 @@ int dword_1026EB8C; int dword_1026EC24; int dword_1026EC2C; char byte_1026EBB8; +MATRIX4X4 stru_10140CF8; +MATRIX4X4 stru_10140AF8; +VECTOR vec_10140D3C; +VECTOR vec_10140D64; +char byte_10140C78[128]; void sub_1009D8B0(); // .text:1009D8B0 void sub_100C3F50(); // .text:100C3F50 @@ -54,7 +60,7 @@ int sub_100C3E20(int a1, int a2); // .text:100C3E20 int sub_10062270(std::string *pstrFileName); // .text:10062270 void sub_10074480(); // .text:10074480 void sub_10074210(); // .text:10074210 -void sub_10075330(); // .text:10075330 +int sub_100B7E00(); // .text:100B7E00 void sub_1009E490(); // .text:1009E490 // samp keeps this gta helper in a data slot, so the call goes through a pointer float (*dword_10102BF4)(float a1, float a2) = (float (*)(float, float))0x568FE0; @@ -85,6 +91,77 @@ public: //------------------------------------------- +// per-frame nametag pass: walks the player pool and draws a tag over every visible remote ped +void sub_10075330() +{ + if(!pNetGame) + return; + if(!pNetGame->GetSettings()->field_38) + return; + + pNewPlayerTags->FUNC_1006CD80(); + + CPlayerPool *pPlayerPool = pNetGame->GetPlayerPool(); + pGame->FindPlayerPed()->GetMatrix(&stru_10140CF8); + + int iHighestId = pPlayerPool->field_2F3A; + for(int i = 0; i <= iHighestId; i++) + { + if(pPlayerPool->GetSlotState((PLAYERID)i) != 1) + continue; + CRemotePlayer *pRemotePlayer = pPlayerPool->GetAt((PLAYERID)i); + if(!pRemotePlayer) + continue; + CPlayerPed *pPlayerPed = pRemotePlayer->m_pPlayerPed; + if(!pPlayerPed) + continue; + if(!pRemotePlayer->field_10A) + continue; + if(!pRemotePlayer->field_4) + continue; + + float fDistance = pPlayerPed->FUNC_1009F190(); + if(fDistance <= pNetGame->GetSettings()->field_27) + { + if(pRemotePlayer->field_10A == 19 && pRemotePlayer->field_1E1 && sub_100B7E00()) + { + ((CEntity *)pRemotePlayer->field_1E1)->GetMatrix(&stru_10140AF8); + vec_10140D3C = stru_10140AF8.pos; + } + else + { + if(!pPlayerPed->IsAdded()) + continue; + memset(&vec_10140D3C, 0, sizeof(VECTOR)); + pPlayerPed->FUNC_100AE480(8, &vec_10140D3C); + } + + vec_10140D64 = vec_10140D3C; + + CAMERA_AIM *pAim = GameGetInternalAim(); + int iLineOfSight = 0; + if(pNetGame->GetSettings()->field_2F) + iLineOfSight = ScriptCommand(&is_line_of_sight_clear, + vec_10140D64.X, vec_10140D64.Y, vec_10140D64.Z, + pAim->pos1x, pAim->pos1y, pAim->pos1z, 1, 0, 0, 1, 0); + if(!pNetGame->GetSettings()->field_2F || iLineOfSight) + { + sprintf(byte_10140C78, "%s (%d)", pPlayerPool->FUNC_100175C0(i), i); + if(!pRemotePlayer->field_10C) + { + pNewPlayerTags->Draw((D3DXVECTOR3 *)&vec_10140D64, byte_10140C78, + pRemotePlayer->GetPlayerColorAsARGB(), pPlayerPed->FUNC_1009F190(), + pNetGame->field_234, pRemotePlayer->FUNC_10016330()); + } + } + } + } + + pNewPlayerTags->FUNC_1006CD90(); +} + +//------------------------------------------- + // screenshot grab: reached from Present when the F8 handler raises dword_1012DE64 void sub_100755C0() { diff --git a/saco/game/entity.h b/saco/game/entity.h index 3df72a1..0ce2aa9 100644 --- a/saco/game/entity.h +++ b/saco/game/entity.h @@ -56,6 +56,7 @@ public: BOOL IsAdded(); float FUNC_1009F0C0(); // .text:1009F0C0 + float FUNC_1009F190(); // .text:1009F190 BYTE FUNC_100B8340(); // .text:100B8340 float FUNC_100B72A0(); // .text:100B72A0 int FUNC_100B7390(); // .text:100B7390 diff --git a/saco/game/playerped.h b/saco/game/playerped.h index a30a0ba..247f8fe 100644 --- a/saco/game/playerped.h +++ b/saco/game/playerped.h @@ -118,6 +118,8 @@ public: void FUNC_100ADFB0(int iLevel); // .text:100ADFB0 int FUNC_100ADC90(); // .text:100ADC90 + void FUNC_100AE480(int a1, PVECTOR pVec); // .text:100AE480 + void ProcessVehicleHorn(); void StartDancing(int iStyle); diff --git a/saco/game/scripting.h b/saco/game/scripting.h index ee86e36..fb34848 100644 --- a/saco/game/scripting.h +++ b/saco/game/scripting.h @@ -158,6 +158,7 @@ const SCRIPT_COMMAND is_wav_loaded = { 0x3D0, "i" }; const SCRIPT_COMMAND play_wav = { 0x3D1, "i" }; const SCRIPT_COMMAND unload_wav = { 0x40D, "i" }; const SCRIPT_COMMAND set_wav_at_location = { 0x3D7, "ifff" }; +const SCRIPT_COMMAND is_line_of_sight_clear = { 0x06BD, "ffffffiiiii" }; const SCRIPT_COMMAND set_widescreen = { 0x02A3, "i" }; // the fifth argument is declared "i" but samp passes a float diff --git a/saco/net/netgame.h b/saco/net/netgame.h index e4b7cce..9e77255 100644 --- a/saco/net/netgame.h +++ b/saco/net/netgame.h @@ -28,7 +28,9 @@ struct struc_41 BYTE field_2D; char field_2E; char field_2F; - char _gap30[10]; + char _gap30[8]; + BYTE field_38; + char _gap39; }; typedef struct _NETGAME_POOLS { @@ -56,7 +58,9 @@ private: char m_szHostName[257]; char field_232; char field_233; - char field_234; +public: + BYTE field_234; +private: int m_iPort; int field_239; DWORD m_dwMapIcon[100]; diff --git a/saco/net/playerpool.h b/saco/net/playerpool.h index 621c199..736fc7b 100644 --- a/saco/net/playerpool.h +++ b/saco/net/playerpool.h @@ -50,6 +50,10 @@ public: PLAYERID GetLocalPlayerID() { return m_LocalPlayerID; }; + int GetSlotState(PLAYERID playerId) { if(playerId >= MAX_PLAYERS) return 0; return field_2A[playerId]; } + + PCHAR FUNC_100175C0(int iPlayerId); // .text:100175C0 + class CObject *FUNC_10013B70(ENTITY_TYPE *pEntity); // todo: implement void sub_10013C90(); // todo: implement diff --git a/saco/net/remoteplayer.h b/saco/net/remoteplayer.h index da6f243..1b17012 100644 --- a/saco/net/remoteplayer.h +++ b/saco/net/remoteplayer.h @@ -84,6 +84,7 @@ public: float FUNC_10016120(); // .text:10016120 void FUNC_10017530(); // .text:10017530 void FUNC_10017570(); // .text:10017570 + int FUNC_10016330(); // .text:10016330 }; //----------------------------------------------------