Created
September 2, 2021 16:14
-
-
Save The-Musaigen/64b31b8ac0b1c1f95a77128968d2c31c to your computer and use it in GitHub Desktop.
GTA:SAMP modification that allows to see players identifiers on the radar.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <main.h> | |
IniFile gIniFile{ ".\\BlipsEnchancedByMusaigen.ini" }; | |
CD3DFont* gFont{ nullptr }; | |
Hook* hkPoolInstantiate{ nullptr }; | |
Hook* hkProcess{ nullptr }; | |
Hook* hkPresent{ nullptr }; | |
Hook* hkReset{ nullptr }; | |
CPlayerPool* gPool{ nullptr }; | |
Bool gRenderReady{ false }; | |
String gFontFace; | |
Int gFontSize; | |
Int gFontFlags; | |
Bool gRenderLocal; | |
Bool gRenderShadow; | |
Float gOffsetX; | |
Float gOffsetY; | |
using std::to_string; | |
HRESULT WINAPI OnPresent(IDirect3DDevice9* device, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) | |
{ | |
if (!gRenderReady) | |
{ | |
gFont->Initialize(device); | |
gRenderReady = true; | |
} | |
if (BlipsEnchanced::CanRender()) | |
{ | |
auto scissor { BlipsEnchanced::BeginScissor(device) }; | |
auto index { 0 }; | |
for (; index < SAMP_MAX_PLAYERS; index++) | |
{ | |
CPed* ped { nullptr }; | |
if (index == gPool->m_nId && gRenderLocal) | |
ped = FindPlayerPed(); | |
else | |
{ | |
auto info{ gPool->m_pPlayerInfo[index] }; | |
if (!gPool->m_bNotEmpty[index] || | |
!info || | |
!info->m_pPlayer || | |
!info->m_pPlayer->m_pPed || | |
!info->m_pPlayer->m_pPed->m_pGamePed) | |
continue; | |
ped = info->m_pPlayer->m_pPed->m_pGamePed; | |
} | |
if (!ped) | |
continue; | |
CVector& position = ped->GetPosition(); | |
CVector2D radar; | |
CVector2D screen; | |
BlipsEnchanced::TransformRealWorldPointToRadarSpace(&radar, &CVector2D(position.x, position.y)); | |
BlipsEnchanced::TransformRadarPointToScreenSpace(&screen, &radar); | |
gFont->PrintShadow(screen.x + gOffsetX, screen.y + gOffsetY, -1, to_string(index).c_str()); | |
} | |
if (scissor) | |
BlipsEnchanced::EndScissor(device); | |
} | |
return hkPresent->Call<HRESULT, CT_STDCALL>(device, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); | |
} | |
HRESULT WINAPI OnReset(IDirect3DDevice9* device, D3DPRESENT_PARAMETERS* pParameters) | |
{ | |
if (gRenderReady) | |
{ | |
gFont->Invalidate(); | |
gRenderReady = false; | |
} | |
return hkReset->Call<HRESULT, CT_STDCALL>(device, pParameters); | |
} | |
Void OnProcess() | |
{ | |
STATIC Bool initialized { false }; | |
if (!initialized) | |
{ | |
IDirect3DDevice9* device { MemoryWrapper::ReadMemory<IDirect3DDevice9*>(0xC97C28) }; | |
if (device != nullptr) | |
{ | |
Void** vtable { *reinterpret_cast<Void***>(device) }; | |
hkReset = new Hook(vtable[16], OnReset); | |
hkReset->Install(); | |
hkPresent = new Hook(vtable[17], OnPresent); | |
hkPresent->Install(); | |
initialized = true; | |
} | |
} | |
return hkProcess->Call(); | |
} | |
Void METHOD OnPoolInstantiate(CPlayerPool* pPlayerPool, Void* edx86) | |
{ | |
gPool = pPlayerPool; | |
return hkPoolInstantiate->Call<Void, CT_THISCALL>(pPlayerPool); | |
} | |
BlipsEnchanced::BlipsEnchanced() | |
{ | |
UInt32 constructor = MemoryWrapper::SearchPattern("samp.dll", "\x6A\xFF\x68\x00\x00\x00\x00\x64\xA1\x00\x00\x00\x00\x50\x64\x89\x25\x00\x00\x00\x00\x83\xEC\x08\x53\x56", "xxx????xx????xxxx????xxxxx"); | |
gFontFace = gIniFile.ReadString("Main", "FontFace", "Arial"); | |
gFontSize = gIniFile.ReadInteger("Main", "FontSize", 8); | |
gFontFlags = gIniFile.ReadInteger("Main", "FontFlags", FCR_BORDER); | |
gRenderLocal = gIniFile.ReadBoolean("Flags", "RenderLocal", true); | |
gRenderShadow = gIniFile.ReadBoolean("Flags", "RenderShadow", true); | |
gOffsetX = gIniFile.ReadFloat("Offsets", "OffsetX", .0F); | |
gOffsetY = gIniFile.ReadFloat("Offsets", "OffsetY", .0F); | |
gFont = new CD3DFont(gFontFace.c_str(), gFontSize, gFontFlags); | |
hkProcess = new Hook(0x53BEE0, OnProcess); | |
hkProcess->Install(); | |
if (constructor > 0) | |
{ | |
hkPoolInstantiate = new Hook(constructor, OnPoolInstantiate); | |
hkPoolInstantiate->Install(); | |
} | |
} | |
BlipsEnchanced::~BlipsEnchanced() | |
{ | |
if (hkPoolInstantiate) | |
delete hkPoolInstantiate; | |
delete hkProcess; | |
delete hkPresent; | |
delete hkReset; | |
delete gFont; | |
} | |
Void BlipsEnchanced::TransformRealWorldPointToRadarSpace(CVector2D* out, CVector2D* in) | |
{ | |
CallWrapper::Call<Void>(0x583530, out, in); | |
} | |
Void BlipsEnchanced::TransformRadarPointToScreenSpace(CVector2D* out, CVector2D* in) | |
{ | |
CallWrapper::Call<Void>(0x583480, out, in); | |
} | |
CONST D3DCAPS9* BlipsEnchanced::GetCaps() | |
{ | |
return CallWrapper::Call<CONST D3DCAPS9*>(0x7FAD20); | |
} | |
Bool BlipsEnchanced::CanRender() | |
{ | |
auto radarMode { MemoryWrapper::ReadMemory<Int>(0xBA676C) }; | |
return (gFont != nullptr && gPool != nullptr && gRenderReady && !IsMenuOpened() && radarMode != 2); | |
} | |
Bool BlipsEnchanced::BeginScissor(IDirect3DDevice9* device) | |
{ | |
auto caps { GetCaps() }; | |
auto drawRadarOrMap { MemoryWrapper::ReadMemory<Bool>(0xBA67A1) }; | |
if (!drawRadarOrMap && caps->RasterCaps & D3DPRASTERCAPS_SCISSORTEST) | |
{ | |
// Taken from plugin-sdk: https://github.com/DK22Pac/plugin-sdk/blob/bb15c327c5fcab9bca766b76c5d6e2817b6cbe36/examples/GPS/Main.cpp#L86 | |
RECT rect; | |
CVector2D posn; | |
BlipsEnchanced::TransformRadarPointToScreenSpace(&posn, &CVector2D(-1.0f, -1.0f)); | |
rect.left = static_cast<LONG>(posn.x + 2.0f); | |
rect.bottom = static_cast<LONG>(posn.y - 2.0f); | |
BlipsEnchanced::TransformRadarPointToScreenSpace(&posn, &CVector2D(1.0f, 1.0f)); | |
rect.right = static_cast<LONG>(posn.x - 2.0f); | |
rect.top = static_cast<LONG>(posn.y + 2.0f); | |
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); | |
device->SetScissorRect(&rect); | |
return true; | |
} | |
return false; | |
} | |
Void BlipsEnchanced::EndScissor(IDirect3DDevice9* device) | |
{ | |
device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment