Гайд API SF | Урок 6 - ESP(рисуем на игроках)

Статус
В этой теме нельзя размещать новые ответы.

CleanLegend

Известный
Автор темы
Всефорумный модератор
476
928
Введение
В этом уроке покажу как можно рисовать на игроках

Начало работы
Для начала нужно зарегистрировать callback present, в нем мы будем рисовать.

C++:
bool CALLBACK Present ( CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride,
                                 CONST RGNDATA *pDirtyRegion )
{
   if( SUCCEEDED( SF->getRender()->BeginRender() ) ) // если рендер готов к рисованию
   {
       // рисуем
       SF->getRender()->EndRender(); // завершаем рисование
   };

   return true; // возвращаем положительный результат
};
в mainloop:
C++:
SF->getRender()->registerD3DCallback(eDirect3DDeviceMethods::D3DMETHOD_PRESENT, Present);

Создаем функцию для удобства и в ней начинаем с цикла:
C++:
void ESP()
{
for (int i = 0; i < SAMP_MAX_PLAYERS; i++) // перебираем всех игроков и проверяем их на вилидность
{
if (SF->getSAMP()->getPlayers()->iIsListed[i] != 1) continue;
if (SF->getSAMP()->getPlayers()->pRemotePlayer[i] == NULL) continue;
if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData == NULL) continue;
if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor == NULL) continue;
if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped == NULL) continue;
        // Если игрок не существует или не в зоне стрима, то пропускаем
}
}
Можно сделать проверку на зону стрима вызовом одной функции:
C++:
if (SF->getSAMP()->getPlayers()->IsPlayerDefined(i, true))
{
// Игрок в стриме
}
Теперь нужно получить координаты игрока, перевести их в экранные и проверить есть ли игрок на экране:

C++:
// Получаем координаты игрока
enpos[0] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[0]; // X
enpos[1] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[1]; // Y
enpos[2] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[2]; // Z
// Переводим игровые координаты в экранные
SF->getGame()->convert3DCoordsToScreen(enpos[0], enpos[1], enpos[2], &screen[0], &screen[1]);
// Получаем CPed
CPed* Ped = GAME->GetPools()->GetPed((DWORD*)SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped);
 // Проверяем есть ли игрок на экране
if (Ped->IsOnScreen())
{
            // игрок на экране
}
Перейдем к рисованию, сначала с квадрата.
Для этого нужно вызвать функцию для рисования квадрата и указать экранные координаты:
C++:
SF->getRender()->DrawBox(screen[0], screen[1], 35, 35, 0xFF00FF00);
получаем:
3bP8eMd.png
Рисуем линии:
C++:
SF->getRender()->DrawLine(640, 900, screen[0], screen[1], 5,0xFF00FF00);
получаем:
ltcertH.png
Рисуем текст:
C++:
char buf[255];
// Заполняем буфер ником и id
sprintf_s(buf, "%s[%d]", SF->getSAMP()->getPlayers()->GetPlayerName(i),i);
 // Рисуем текст
 pFont->Print(buf, 0xFF00FF00, screen[0], screen[1], false);
для использования pFont нужно объявить и инициализировать его:
C++:
stFontInfo *pFont;
//Затем один раз инициализируем шрифт:
pFont = SF->getRender()->CreateNewFont("Tahoma", 12, FCR_BORDER );
получаем:
VCHsMSA.png
По такому принципу можно рисовать всё что угодно.
весь код функции:
C++:
void ESP()
{
    float enpos[3]; // для координат игрока
    float screen[2]; // для экранных координат
    char buf[255]; // для текста
    for (int i = 0; i < SAMP_MAX_PLAYERS; i++) // перебор всех игроков
    {
        // проверяем каждого игрока на валидность, зону стрима
        if (SF->getSAMP()->getPlayers()->iIsListed[i] != 1) continue;
        if (SF->getSAMP()->getPlayers()->pRemotePlayer[i] == NULL) continue;
        if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData == NULL) continue;
        if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor == NULL) continue;
        if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped == NULL) continue;
        // Если игрок не существует или не в зоне стрима, то пропускаем

        // Можно сделать это одной функцией
        /*if (SF->getSAMP()->getPlayers()->IsPlayerDefined(i, true))
        {
         // рисуем
        }*/
        // Тут подойдут два варианта, это уже как вам будет удобнее
       
        // Получаем координаты игрока
        enpos[0] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[0]; // X
        enpos[1] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[1]; // Y
        enpos[2] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[2]; // Z
        // Переводим игровые координаты в экранные
        SF->getGame()->convert3DCoordsToScreen(enpos[0], enpos[1], enpos[2], &screen[0], &screen[1]);
        // Получаем CPed
        CPed* Ped = GAME->GetPools()->GetPed((DWORD*)SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped);
        // Проверяем есть ли игрок на экране
        if (Ped->IsOnScreen())
        {
            // начинаем рисовать

            // Рисуем квадрат на игроках
            //    SF->getRender()->DrawBox(screen[0], screen[1], 35, 35, 0xFF00FF00);
            // Рисуем линии
            //SF->getRender()->DrawLine(640, 900, screen[0], screen[1], 5,0xFF00FF00);
           
            // Заполняем буфер ником и id
            sprintf_s(buf, "%s[%d]", SF->getSAMP()->getPlayers()->GetPlayerName(i),i);
            // Рисуем текст
            pFont->Print(buf, 0xFF00FF00, screen[0], screen[1], false);

        }

    }
}
 

Livarka

Известный
156
65
Введение
В этом уроке покажу как можно рисовать на игроках

Начало работы
Для начала нужно зарегистрировать callback present, в нем мы будем рисовать.

C++:
bool CALLBACK Present ( CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride,
                                 CONST RGNDATA *pDirtyRegion )
{
   if( SUCCEEDED( SF->getRender()->BeginRender() ) ) // если рендер готов к рисованию
   {
       // рисуем
       SF->getRender()->EndRender(); // завершаем рисование
   };

   return true; // возвращаем положительный результат
};
в mainloop:
C++:
SF->getRender()->registerD3DCallback(eDirect3DDeviceMethods::D3DMETHOD_PRESENT, Present);

Создаем функцию для удобства и в ней начинаем с цикла:
C++:
void ESP()
{
for (int i = 0; i < SAMP_MAX_PLAYERS; i++) // перебираем всех игроков и проверяем их на вилидность
{
if (SF->getSAMP()->getPlayers()->iIsListed[i] != 1) continue;
if (SF->getSAMP()->getPlayers()->pRemotePlayer[i] == NULL) continue;
if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData == NULL) continue;
if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor == NULL) continue;
if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped == NULL) continue;
        // Если игрок не существует или не в зоне стрима, то пропускаем
}
}
Можно сделать проверку на зону стрима вызовом одной функции:
C++:
if (SF->getSAMP()->getPlayers()->IsPlayerDefined(i, true))
{
// Игрок в стриме
}
Теперь нужно получить координаты игрока, перевести их в экранные и проверить есть ли игрок на экране:

C++:
// Получаем координаты игрока
enpos[0] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[0]; // X
enpos[1] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[1]; // Y
enpos[2] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[2]; // Z
// Переводим игровые координаты в экранные
SF->getGame()->convert3DCoordsToScreen(enpos[0], enpos[1], enpos[2], &screen[0], &screen[1]);
// Получаем CPed
CPed* Ped = GAME->GetPools()->GetPed((DWORD*)SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped);
 // Проверяем есть ли игрок на экране
if (Ped->IsOnScreen())
{
            // игрок на экране
}
Перейдем к рисованию, сначала с квадрата.
Для этого нужно вызвать функцию для рисования квадрата и указать экранные координаты:
C++:
SF->getRender()->DrawBox(screen[0], screen[1], 35, 35, 0xFF00FF00);
получаем:
3bP8eMd.png
Рисуем линии:
C++:
SF->getRender()->DrawLine(640, 900, screen[0], screen[1], 5,0xFF00FF00);
получаем:
ltcertH.png
Рисуем текст:
C++:
char buf[255];
// Заполняем буфер ником и id
sprintf_s(buf, "%s[%d]", SF->getSAMP()->getPlayers()->GetPlayerName(i),i);
 // Рисуем текст
 pFont->Print(buf, 0xFF00FF00, screen[0], screen[1], false);
для использования pFont нужно объявить и инициализировать его:
C++:
stFontInfo *pFont;
//Затем один раз инициализируем шрифт:
pFont = SF->getRender()->CreateNewFont("Tahoma", 12, FCR_BORDER );
получаем:
VCHsMSA.png
По такому принципу можно рисовать всё что угодно.
весь код функции:
C++:
void ESP()
{
    float enpos[3]; // для координат игрока
    float screen[2]; // для экранных координат
    char buf[255]; // для текста
    for (int i = 0; i < SAMP_MAX_PLAYERS; i++) // перебор всех игроков
    {
        // проверяем каждого игрока на валидность, зону стрима
        if (SF->getSAMP()->getPlayers()->iIsListed[i] != 1) continue;
        if (SF->getSAMP()->getPlayers()->pRemotePlayer[i] == NULL) continue;
        if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData == NULL) continue;
        if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor == NULL) continue;
        if (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped == NULL) continue;
        // Если игрок не существует или не в зоне стрима, то пропускаем

        // Можно сделать это одной функцией
        /*if (SF->getSAMP()->getPlayers()->IsPlayerDefined(i, true))
        {
         // рисуем
        }*/
        // Тут подойдут два варианта, это уже как вам будет удобнее
      
        // Получаем координаты игрока
        enpos[0] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[0]; // X
        enpos[1] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[1]; // Y
        enpos[2] = SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->fOnFootPos[2]; // Z
        // Переводим игровые координаты в экранные
        SF->getGame()->convert3DCoordsToScreen(enpos[0], enpos[1], enpos[2], &screen[0], &screen[1]);
        // Получаем CPed
        CPed* Ped = GAME->GetPools()->GetPed((DWORD*)SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped);
        // Проверяем есть ли игрок на экране
        if (Ped->IsOnScreen())
        {
            // начинаем рисовать

            // Рисуем квадрат на игроках
            //    SF->getRender()->DrawBox(screen[0], screen[1], 35, 35, 0xFF00FF00);
            // Рисуем линии
            //SF->getRender()->DrawLine(640, 900, screen[0], screen[1], 5,0xFF00FF00);
          
            // Заполняем буфер ником и id
            sprintf_s(buf, "%s[%d]", SF->getSAMP()->getPlayers()->GetPlayerName(i),i);
            // Рисуем текст
            pFont->Print(buf, 0xFF00FF00, screen[0], screen[1], false);

        }

    }
}
Дополни как рендер ника сделать чтобы он был равен цвету самого ника. Думаю у людей будет такой вопрос
 

клешь рояль

Известный
1,255
551
А нельзя это сделать с "if and" как в клео ?
C++:
void ESP()
{
for (int i = 0; i < SAMP_MAX_PLAYERS; i++) // перебираем всех игроков и проверяем их на вилидность
{
if and
(SF->getSAMP()->getPlayers()->iIsListed[i] != 1) continue;
 (SF->getSAMP()->getPlayers()->pRemotePlayer[i] == NULL) continue;
 (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData == NULL) continue;
 (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor == NULL) continue;
 (SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData->pSAMP_Actor->pGTA_Ped == NULL) continue;
        // Если игрок не существует или не в зоне стрима, то пропускаем
}
}
 

CleanLegend

Известный
Автор темы
Всефорумный модератор
476
928
Дополни как рендер ника сделать чтобы он был равен цвету самого ника. Думаю у людей будет такой вопрос
C++:
pFont->Print(buf, SF->getSAMP()->getPlayers()->GetPlayerColor(i), screen[0], screen[1], false);
А нельзя это сделать с "if and" как в клео ?
Всё можно упростить, но для понимания посчитал нужным сделать так.
Будет выглядеть примерно так:
C++:
if (SF->getSAMP()->getPlayers()->iIsListed[i] != 1 || SF->getSAMP()->getPlayers()->pRemotePlayer[i] == NULL || SF->getSAMP()->getPlayers()->pRemotePlayer[i]->pPlayerData == NULL)
            continue;
 
  • Нравится
Реакции: клешь рояль
Статус
В этой теме нельзя размещать новые ответы.