- Status
- Offline
- Joined
- Mar 3, 2026
- Messages
- 692
- Reaction score
- 457
Since every generic P2C provider is suddenly flexing a "Permanent Advanced UAV" feature, it's time to pull back the curtain. This isn't some complex memory write or exploit—it's just basic coordinate projection. By reading specific structures and rebuilding the game's internal math, you can draw a perfect radar overlay directly on the tac-map without touching a single byte of game memory. This is ideal for external builds or DMA setups where you want to stay strictly read-only.
Initial Data Gathering
First, you need the cg_t (client_info) data. We specifically need three vec2_t variables: compassMapUpperLeft, compassMapWorldSize, and compassNorth. These only need to be cached once at the start of each match.
To find these, look for LUI_LuaCall_Game_GetMapSizeData (which contains map metadata strings) and CG_CompassFullToWorld.
The Compass System Structure
You'll need to interface with CgCompassSystem. This is handled through the ms_compassSystemArray pointer.
Rebuilding WorldPosToCompass
This is the core logic. You are essentially recreating the game's internal function to map 3D world coordinates (x, y, z) onto the 2D plane of the tac-map. The following logic handles the scaling and zoom levels so your dots stay pinned to the right location even when you zoom in on the map.
Technical Implementation Notes
This method is completely read-only, meaning no write-access is required, keeping your attack surface minimal. Just cache the map data per session and loop your entity list.
Anyone found the exact array size for the LUI elements in this build? Drop your findings below.
Initial Data Gathering
First, you need the cg_t (client_info) data. We specifically need three vec2_t variables: compassMapUpperLeft, compassMapWorldSize, and compassNorth. These only need to be cached once at the start of each match.
To find these, look for LUI_LuaCall_Game_GetMapSizeData (which contains map metadata strings) and CG_CompassFullToWorld.
LUI_LuaCall_Game_GetMapSizeData
CG_CompassFullToWorld
Static Offsets:
Code:
33 D2 41 B8 ? ? ? ? 48 8B CF E8 ? ? ? ? C5 FA 10 8B
CG_CompassFullToWorld
Code:
C5 FA 10 81 ? ? ? ? C5 FA 59 1A C5 FA 10 89 ? ? ? ? C5 F2 59 62
Static Offsets:
Code:
Steam:
compassMapUpperLeft = 0x1D7E20;
compassMapWorldSize = 0x1711BC;
compassNorth = 0x48EC0;
Bnet:
compassMapUpperLeft = 0x15B9A4;
compassMapWorldSize = 0x189D40;
compassNorth = 0x175628;
Xbox:
compassMapUpperLeft = 0x1D35B0;
compassMapWorldSize = 0xCD030;
compassNorth = 0x1B6EFC;
The Compass System Structure
You'll need to interface with CgCompassSystem. This is handled through the ms_compassSystemArray pointer.
Code:
// ms_compassSystemArray base addresses
// Xbox: 0xC728AD8
// Steam: 0xC782B88
// Bnet: 0xCC30870
// Signature: 48 8D 05 ?? ?? ?? ?? 48 8B 0C C8 E8 ?? ?? ?? ?? 33 C0 48 8B 4C 24
struct CgCompassSystem
{
uint64_t __vftable; // 0x00
char pad[0x1];
bool m_compassMirrorLeftRight; // 0x9
bool m_isUsingTabletMode; // 0xA
bool m_PreventZoom; // 0xB
float m_compassPlayerYaw; // 0xC
vec2_t m_compassPlayerForward; // 0x10
int m_currentCompassType; // 0x18
char pad2[0x8];
int m_currentDisplayType; // 0x24
char pad3[0x5AC];
vec2_t m_tacmapMapCenter; // 0x5D4
char pad4[0x4B1C];
float m_currentZoomLevel; // 0x50F8
};
Rebuilding WorldPosToCompass
This is the core logic. You are essentially recreating the game's internal function to map 3D world coordinates (x, y, z) onto the 2D plane of the tac-map. The following logic handles the scaling and zoom levels so your dots stay pinned to the right location even when you zoom in on the map.
Code:
// Rebuilt logic for Tac-map projection
float zoom = 1.0f / compassSystem.m_currentZoomLevel;
vec2_t tacmapCenter = compassSystem.m_tacmapMapCenter;
vec2_t relativePos = {
worldPos.x - compassMapUpperLeft.x,
worldPos.y - compassMapUpperLeft.y
};
vec2_t translatedPos = {
(((relativePos.x * north.y - relativePos.y * north.x) / worldSize.x) - tacmapCenter.x) * zoom * mapRect.w,
((-(relativePos.x * north.x + relativePos.y * north.y) / worldSize.y) - tacmapCenter.y) * zoom * mapRect.h
};
vec2_t screenPos = {
(0.5f * mapRect.w) + mapRect.x + translatedPos.x,
(0.5f * mapRect.h) + mapRect.y + translatedPos.y
};
Technical Implementation Notes
- Resolution Scaling: The tac-map position is static relative to the UI, but you must scale your rectDef_s based on the current screen resolution (e.g., scaling from 1080p base).
- UI Issues: Reading the LUIElement directly via memory can be unstable for external cheats. Hardcoding the map boundaries and scaling based on delta works more reliably.
- Drawing: If you're using ImGui, a simple AddCircleFilled on the background draw list is enough once you have the screenPos.
This method is completely read-only, meaning no write-access is required, keeping your attack surface minimal. Just cache the map data per session and loop your entity list.
Anyone found the exact array size for the LUI elements in this build? Drop your findings below.