Facebook
From Chartreuse Parrot, 5 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 339
  1. #include "plugin.h"
  2. #include "game_sa\RenderWare.h"
  3. #include "game_sa\common.h"
  4. #include "game_sa\CMenuManager.h"
  5. #include "game_sa\CRadar.h"
  6. #include "game_sa\CWorld.h"
  7. #include "game_sa\RenderWare.h"
  8. #include "game_sa\CFont.h"
  9. #include "d3d9.h"
  10.  
  11. #include <Psapi.h>
  12.  
  13. #pragma comment( lib, "psapi.lib" )
  14.  
  15. #define MAX_NODE_POINTS 2000
  16. #define GPS_LINE_WIDTH  4.0f
  17. #define GPS_LINE_R  180
  18. #define GPS_LINE_G  24
  19. #define GPS_LINE_B  24
  20. #define GPS_LINE_A  255
  21. #define MAX_TARGET_DISTANCE 20.0f
  22.  
  23. #define E_ADDR_GAMEPROCESS      0x53E981
  24.  
  25. using namespace plugin;
  26.  
  27. #pragma pack(push, 1)
  28. typedef struct stOpcodeRelCall
  29. {
  30.         BYTE bOpcode;
  31.         DWORD dwRelAddr;
  32. } OpcodeRelCall;
  33. #pragma pack(pop)
  34.  
  35. class GPS {
  36. private:
  37.         HANDLE hThread = NULL;
  38.  
  39. public:
  40.         GPS() {
  41.                 hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GPS::init, (LPVOID)this, 0, (LPDWORD)NULL);
  42.         }
  43.  
  44.         ~GPS() {
  45.                 // Check if thread still running on process
  46.                 if (hThread != NULL)
  47.                         TerminateThread(hThread, 0);
  48.         }
  49.  
  50.         static LPVOID WINAPI init(LPVOID *lpParam) {
  51.                 MODULEINFO miSampDll;
  52.                 DWORD dwSampDllBaseAddr, dwSampDllEndAddr, dwCallAddr;
  53.  
  54.                 GPS *sender = (GPS *)lpParam;
  55.  
  56.                 stOpcodeRelCall *fnGameProc = (stOpcodeRelCall *)E_ADDR_GAMEPROCESS;
  57.  
  58.                 // Check if E_ADDR_GAMEPROCESS opcode is a relative call (0xE8)
  59.                 while (fnGameProc->bOpcode != 0xE8)
  60.                         Sleep(100);
  61.  
  62.                 while (true) {
  63.                         Sleep(100);
  64.  
  65.                         // Get samp.dll module information to get base address and end address
  66.                         if (!GetModuleInformation(GetCurrentProcess(), GetModuleHandle("samp.dll"), &miSampDll, sizeof(MODULEINFO))) {
  67.                                 continue;
  68.                         }
  69.  
  70.                         // Some stupid calculation
  71.                         dwSampDllBaseAddr = (DWORD)miSampDll.lpBaseOfDll;
  72.                         dwSampDllEndAddr = dwSampDllBaseAddr + miSampDll.SizeOfImage;
  73.  
  74.                         // Calculate destination address by offset and relative call opcode size
  75.                         dwCallAddr = fnGameProc->dwRelAddr + E_ADDR_GAMEPROCESS + 5;
  76.  
  77.                         // Check if dwCallAddr is a samp.dll's hook address,
  78.                         // to make sure this plugin hook (Events::gameProcessEvent) not replaced by samp.dll
  79.                         if (dwCallAddr >= dwSampDllBaseAddr && dwCallAddr <= dwSampDllEndAddr)
  80.                                 break;
  81.                 }
  82.  
  83.                 // Just wait a few secs for the game loaded fully to avoid any conflicts and crashes
  84.                 // I don't know what the elegant way is :)
  85.                 while (!FindPlayerPed(0))
  86.                         Sleep(5000);
  87.  
  88.                 // Run the plugin
  89.                 sender->run();
  90.  
  91.                 // Reset the thread handle
  92.                 sender->hThread = NULL;
  93.  
  94.                 return NULL;
  95.         }
  96.  
  97.         void run() {
  98.                 static bool gpsShown;
  99.                 static float gpsDistance;
  100.                 static CNodeAddress resultNodes[MAX_NODE_POINTS];
  101.                 static CVector2D nodePoints[MAX_NODE_POINTS];
  102.                 static RwIm2DVertex lineVerts[MAX_NODE_POINTS * 4];
  103.  
  104.                 Events::gameProcessEvent += []() {
  105.                         if (FrontEndMenuManager.m_nTargetBlipIndex
  106.                                 && CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)].m_nCounter == HIWORD(FrontEndMenuManager.m_nTargetBlipIndex)
  107.                                 && CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)].m_nBlipDisplayFlag
  108.                                 && FindPlayerPed()
  109.                                 && DistanceBetweenPoints(CVector2D(FindPlayerCoors(0)),
  110.                                         CVector2D(CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)].m_vPosition)) < MAX_TARGET_DISTANCE)
  111.                         {
  112.                                 CRadar::ClearBlip(FrontEndMenuManager.m_nTargetBlipIndex);
  113.                                 FrontEndMenuManager.m_nTargetBlipIndex = 0;
  114.                         }
  115.                 };
  116.  
  117.                 Events::drawRadarOverlayEvent += []() {
  118.                         gpsShown = false;
  119.                         CPed *playa = FindPlayerPed(0);
  120.                         if (playa
  121.                                 && playa->m_pVehicle
  122.                                 && playa->m_nPedFlags.bInVehicle
  123.                                 && playa->m_pVehicle->m_nVehicleSubClass != VEHICLE_PLANE
  124.                                 && playa->m_pVehicle->m_nVehicleSubClass != VEHICLE_HELI
  125.                                 && playa->m_pVehicle->m_nVehicleSubClass != VEHICLE_BMX
  126.                                 && FrontEndMenuManager.m_nTargetBlipIndex
  127.                                 && CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)].m_nCounter == HIWORD(FrontEndMenuManager.m_nTargetBlipIndex)
  128.                                 && CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)].m_nBlipDisplayFlag)
  129.                         {
  130.                                 CVector destPosn = CRadar::ms_RadarTrace[LOWORD(FrontEndMenuManager.m_nTargetBlipIndex)].m_vPosition;
  131.                                 destPosn.z = CWorld::FindGroundZForCoord(destPosn.x, destPosn.y);
  132.  
  133.                                 short nodesCount = 0;
  134.  
  135.                                 ThePaths.DoPathSearch(0, FindPlayerCoors(0), CNodeAddress(), destPosn, resultNodes, &nodesCount, MAX_NODE_POINTS, &gpsDistance,
  136.                                         999999.0f, NULL, 999999.0f, false, CNodeAddress(), false, playa->m_pVehicle->m_nVehicleSubClass == VEHICLE_BOAT);
  137.  
  138.                                 if (nodesCount > 0) {
  139.                                         for (short i = 0; i < nodesCount; i++) {
  140.                                                 CVector nodePosn = ThePaths.GetPathNode(resultNodes[i])->GetNodeCoors();
  141.                                                 CVector2D tmpPoint;
  142.                                                 CRadar::TransformRealWorldPointToRadarSpace(tmpPoint, CVector2D(nodePosn.x, nodePosn.y));
  143.                                                 if (!FrontEndMenuManager.drawRadarOrMap)
  144.                                                         CRadar::TransformRadarPointToScreenSpace(nodePoints[i], tmpPoint);
  145.                                                 else {
  146.                                                         CRadar::LimitRadarPoint(tmpPoint);
  147.                                                         CRadar::TransformRadarPointToScreenSpace(nodePoints[i], tmpPoint);
  148.                                                         nodePoints[i].x *= static_cast<float>(RsGlobal.maximumWidth) / 640.0f;
  149.                                                         nodePoints[i].y *= static_cast<float>(RsGlobal.maximumHeight) / 448.0f;
  150.                                                         CRadar::LimitToMap(&nodePoints[i].x, &nodePoints[i].y);
  151.                                                 }
  152.                                         }
  153.  
  154.                                         if (!FrontEndMenuManager.drawRadarOrMap
  155.                                                 && reinterpret_cast<D3DCAPS9 const*>(RwD3D9GetCaps())->RasterCaps & D3DPRASTERCAPS_SCISSORTEST)
  156.                                         {
  157.                                                 RECT rect;
  158.                                                 CVector2D posn;
  159.                                                 CRadar::TransformRadarPointToScreenSpace(posn, CVector2D(-1.0f, -1.0f));
  160.                                                 rect.left = posn.x + 2.0f; rect.bottom = posn.y - 2.0f;
  161.                                                 CRadar::TransformRadarPointToScreenSpace(posn, CVector2D(1.0f, 1.0f));
  162.                                                 rect.right = posn.x - 2.0f; rect.top = posn.y + 2.0f;
  163.                                                 GetD3DDevice()->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
  164.                                                 GetD3DDevice()->SetScissorRect(&rect);
  165.                                         }
  166.  
  167.                                         RwRenderStateSet(rwRENDERSTATETEXTURERASTER, NULL);
  168.  
  169.                                         unsigned int vertIndex = 0;
  170.                                         for (short i = 0; i < (nodesCount - 1); i++) {
  171.                                                 CVector2D point[4], shift[2];
  172.                                                 CVector2D dir = nodePoints[i + 1] - nodePoints[i];
  173.                                                 float angle = atan2(dir.y, dir.x);
  174.                                                 if (!FrontEndMenuManager.drawRadarOrMap) {
  175.                                                         shift[0].x = cosf(angle - 1.5707963f) * GPS_LINE_WIDTH;
  176.                                                         shift[0].y = sinf(angle - 1.5707963f) * GPS_LINE_WIDTH;
  177.                                                         shift[1].x = cosf(angle + 1.5707963f) * GPS_LINE_WIDTH;
  178.                                                         shift[1].y = sinf(angle + 1.5707963f) * GPS_LINE_WIDTH;
  179.                                                 }
  180.                                                 else {
  181.                                                         float mp = FrontEndMenuManager.m_fMapZoom - 140.0f;
  182.                                                         if (mp < 140.0f)
  183.                                                                 mp = 140.0f;
  184.                                                         else if (mp > 960.0f)
  185.                                                                 mp = 960.0f;
  186.                                                         mp = mp / 960.0f + 0.4f;
  187.                                                         shift[0].x = cosf(angle - 1.5707963f) * GPS_LINE_WIDTH * mp;
  188.                                                         shift[0].y = sinf(angle - 1.5707963f) * GPS_LINE_WIDTH * mp;
  189.                                                         shift[1].x = cosf(angle + 1.5707963f) * GPS_LINE_WIDTH * mp;
  190.                                                         shift[1].y = sinf(angle + 1.5707963f) * GPS_LINE_WIDTH * mp;
  191.                                                 }
  192.                                                 Setup2dVertex(lineVerts[vertIndex + 0], nodePoints[i].x + shift[0].x, nodePoints[i].y + shift[0].y);
  193.                                                 Setup2dVertex(lineVerts[vertIndex + 1], nodePoints[i + 1].x + shift[0].x, nodePoints[i + 1].y + shift[0].y);
  194.                                                 Setup2dVertex(lineVerts[vertIndex + 2], nodePoints[i].x + shift[1].x, nodePoints[i].y + shift[1].y);
  195.                                                 Setup2dVertex(lineVerts[vertIndex + 3], nodePoints[i + 1].x + shift[1].x, nodePoints[i + 1].y + shift[1].y);
  196.                                                 vertIndex += 4;
  197.                                         }
  198.  
  199.                                         RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, lineVerts, 4 * (nodesCount - 1));
  200.  
  201.                                         if (!FrontEndMenuManager.drawRadarOrMap
  202.                                                 && reinterpret_cast<D3DCAPS9 const*>(RwD3D9GetCaps())->RasterCaps & D3DPRASTERCAPS_SCISSORTEST)
  203.                                         {
  204.                                                 GetD3DDevice()->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
  205.                                         }
  206.  
  207.                                         gpsDistance += DistanceBetweenPoints(FindPlayerCoors(0), ThePaths.GetPathNode(resultNodes[0])->GetNodeCoors());
  208.                                         gpsShown = true;
  209.                                 }
  210.                         }
  211.                 };
  212.  
  213.                 Events::drawHudEvent += [] {
  214.                         if (gpsShown) {
  215.                                 //CFont::SetAlignment(ALIGN_CENTER);
  216.                                 CFont::SetColor(CRGBA(200, 200, 200, 255));
  217.                                 CFont::SetBackground(false, false);
  218.                                 CFont::SetWrapx(500.0f);
  219.                                 CFont::SetScale(0.4f * static_cast<float>(RsGlobal.maximumWidth) / 640.0f,
  220.                                         0.8f * static_cast<float>(RsGlobal.maximumHeight) / 448.0f);
  221.                                 CFont::SetFontStyle(FONT_SUBTITLES);
  222.                                 //CFont::SetProp(true);
  223.                                 CFont::SetDropShadowPosition(1);
  224.                                 CFont::SetDropColor(CRGBA(0, 0, 0, 255));
  225.                                 CVector2D radarBottom;
  226.                                 CRadar::TransformRadarPointToScreenSpace(radarBottom, CVector2D(0.0f, -1.0f));
  227.                                 char text[16];
  228.                                 if (gpsDistance > 1000.0f)
  229.                                         sprintf(text, "%.2fkm", gpsDistance / 1000.0f);
  230.                                 else
  231.                                         sprintf(text, "%dm", static_cast<int>(gpsDistance));
  232.                                 CFont::PrintString(radarBottom.x, radarBottom.y + 8.0f * static_cast<float>(RsGlobal.maximumHeight) / 448.0f, text);
  233.                         }
  234.                 };
  235.         }
  236.  
  237.         static void Setup2dVertex(RwIm2DVertex &vertex, float x, float y) {
  238.                 vertex.x = x;
  239.                 vertex.y = y;
  240.                 vertex.u = vertex.v = 0.0f;
  241.                 vertex.z = CSprite2d::NearScreenZ + 0.0001f;
  242.                 vertex.rhw = CSprite2d::RecipNearClip;
  243.                 vertex.emissiveColor = RWRGBALONG(GPS_LINE_R, GPS_LINE_G, GPS_LINE_B, GPS_LINE_A);
  244.         }
  245.  
  246. } gps;