Исходник Адреса памяти элементов худа GTA:SA

ya_noob

Участник
57
7
C++:
class HUD {
public:
  void setHUD() {
        HealthHeight = 9;
        HealthWidth = 100; // 109
        HealthX = 161; //141
        HealthY = 77;

        ArmorX = 114; // 94
        ArmorY = 48; // 48

        MoneyX = 52; // 32
        MoneyY = 89; // 89
        MoneyXScale = 0.55; // 0.55
        MoneyYScale = 1; // 1.1
    }
private:
    float& HealthWidth = *(float*)0x866BB8;
    float& HealthHeight = *(float*)0x85EED4;
    float& HealthX = *(float*)0x86535C;
    float& HealthY = *(float*)0x866CA8;

    float& ArmorX = *(float*)0x866B78;
    float& ArmorY = *(float*)0x862D38;

    float& MoneyX = *(float*)0x85950C;
    float& MoneyY = *(float*)0x866C88;
    float& MoneyXScale = *(float*)0x866CAC;
    float& MoneyYScale = *(float*)0x858F14;
};
MoneyXScale = 0.55 // вносится не как 0.55, а как 0.5, из-за чего цифры слипаются, я знаю что можно просто не трогать этот адрес, но мне важно понять как внести значение с плавающей точкой по адресу памяти.
Обращаюсь к памяти с указателем на float, но само значение с плавающей точкой записать в эту память не получается, значение просто округляется, как решить эту проблему?


НЕ АКТУАЛЬНО. На самом деле число не округлялось, проблема была не в MoneyXScale, а в MoneyX, при его изменении от стандартного значения цифры слипаются, а когда поставил на 96, радар сплюснулся и игра начала лагать дико

Наоборот, я тебе дал из какого-то репозитория, который уже удален

AutoHotKey:
aInterface["HealthX"] := Object("ADDRESSES", [0x58EE87], "DEFAULT_POINTER", 0x86535C, "DEFAULT_VALUE", 141.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["HealthY"] := Object("ADDRESSES", [0x58EE68], "DEFAULT_POINTER", 0x866CA8, "DEFAULT_VALUE", 77.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["HealthWidth"] := Object("ADDRESSES", [0x5892D8], "DEFAULT_POINTER", 0x866BB8, "DEFAULT_VALUE", 109.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["HealthHeight"] := Object("ADDRESSES", [0x589358], "DEFAULT_POINTER", 0x85EED4, "DEFAULT_VALUE", 9.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["HealthColor"] := Object("ADDRESSES", [0x58932A], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 0, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["HealthBorder"] := Object("ADDRESSES", [0x589353], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 1, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["HealthPercentage"] := Object("ADDRESSES", [0x589355], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 0, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["ArmorX"] := Object("ADDRESSES", [0x58EF59], "DEFAULT_POINTER", 0x866B78, "DEFAULT_VALUE", 94.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["ArmorY"] := Object("ADDRESSES", [0x58EF3A], "DEFAULT_POINTER", 0x862D38, "DEFAULT_VALUE", 48.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["ArmorWidth"] := Object("ADDRESSES", [0x58915D], "DEFAULT_POINTER", 0x86503C, "DEFAULT_VALUE", 62.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["ArmorHeight"] := Object("ADDRESSES", [0x589146], "DEFAULT_POINTER", 0x85EED4, "DEFAULT_VALUE", 9.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["ArmorColor"] := Object("ADDRESSES", [0x5890F5], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 4, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["ArmorBorder"] := Object("ADDRESSES", [0x589123], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 1, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["ArmorPercentage"] := Object("ADDRESSES", [0x589125], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 0, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["BreathX"] := Object("ADDRESSES", [0x58F11F], "DEFAULT_POINTER", 0x866B78, "DEFAULT_VALUE", 94.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["BreathY"] := Object("ADDRESSES", [0x58F100], "DEFAULT_POINTER", 0x86503C, "DEFAULT_VALUE", 62.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["BreathWidth"] := Object("ADDRESSES", [0x589235], "DEFAULT_POINTER", 0x86503C, "DEFAULT_VALUE", 62.0 ,"VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["BreathHeight"] := Object("ADDRESSES", [0x58921E], "DEFAULT_POINTER", 0x85EED4, "DEFAULT_VALUE", 9.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["BreathColor"] := Object("ADDRESSES", [0x5891E4], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 3, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["BreathBorder"] := Object("ADDRESSES", [0x589207], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 1, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["BreathPercentage"] := Object("ADDRESSES", [0x589209], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 0, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["MoneyX"] := Object("ADDRESSES", [0x58F5FC], "DEFAULT_POINTER", 0x85950C, "DEFAULT_VALUE", 32.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["MoneyY"] := Object("ADDRESSES", [0x58F5DC], "DEFAULT_POINTER", 0x866C88, "DEFAULT_VALUE", 89.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["MoneyXScale"] := Object("ADDRESSES", [0x58F564], "DEFAULT_POINTER", 0x866CAC, "DEFAULT_VALUE", 0.55 ,"VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["MoneyYScale"] := Object("ADDRESSES", [0x58F54E], "DEFAULT_POINTER", 0x858F14, "DEFAULT_VALUE", 1.1, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["MoneyColor"] := Object("ADDRESSES", [0x58F492], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 1, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["MoneyColorDebt"] := Object("ADDRESSES", [0x58F4D4], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 0, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["WeaponX"] := Object("ADDRESSES", [0x58F92F], "DEFAULT_POINTER", 0x866C84, "DEFAULT_VALUE", 0.17343046, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WeaponIconX"] := Object("ADDRESSES", [0x58F927], "DEFAULT_POINTER", 0x85950C, "DEFAULT_VALUE", 32.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WeaponIconY"] := Object("ADDRESSES", [0x58F913], "DEFAULT_POINTER", 0x858BA4, "DEFAULT_VALUE", 20.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WeaponAmmoY"] := Object("ADDRESSES", [0x58F9DC], "DEFAULT_POINTER", 0x858BA4, "DEFAULT_VALUE", 20.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WeaponAmmoX"] := Object("ADDRESSES", [0x58F9F7], "DEFAULT_POINTER", 0x866C84, "DEFAULT_VALUE", 0.17343046, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WeaponIconWidth"] := Object("ADDRESSES", [0x58FAAB], "DEFAULT_POINTER", 0x866C4C, "DEFAULT_VALUE", 47.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WeaponAmmoHeight"] := Object("ADDRESSES", [0x5894B7], "DEFAULT_POINTER", 0x858CB0, "DEFAULT_VALUE", 0.7, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WeaponAmmoWidth"] := Object("ADDRESSES", [0x5894CD], "DEFAULT_POINTER", 0x858C24, "DEFAULT_VALUE", 0.3, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WantedX"] := Object("ADDRESSES", [0x58DD0F], "DEFAULT_POINTER", 0x863210, "DEFAULT_VALUE", 29.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WantedY"] := Object("ADDRESSES", [0x58DDFC], "DEFAULT_POINTER", 0x866C5C, "DEFAULT_VALUE", 114.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WantedEmptyY"] := Object("ADDRESSES", [0x58DE27], "DEFAULT_POINTER", 0x858CCC, "DEFAULT_VALUE", 12.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WantedXScale"] := Object("ADDRESSES", [0x58DCC0], "DEFAULT_POINTER", 0x866C60, "DEFAULT_VALUE", 0.605, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WantedYScale"] := Object("ADDRESSES", [0x58DCAA], "DEFAULT_POINTER", 0x866C64, "DEFAULT_VALUE", 1.21, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["WantedColor"] := Object("ADDRESSES", [0x58DDC9], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 6, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["RadioY"] := Object("ADDRESSES", [0x4E9FD8], "DEFAULT_POINTER", 0x858F8C, "DEFAULT_VALUE", 22.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["RadioXScale"] := Object("ADDRESSES", [0x4E9F38], "DEFAULT_POINTER", 0x858CC8, "DEFAULT_VALUE", 0.6, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["RadioYScale"] := Object("ADDRESSES", [0x4E9F22], "DEFAULT_POINTER", 0x858C20, "DEFAULT_VALUE", 0.9, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["RadioColor"] := Object("ADDRESSES", [0x4E9F91], "DEFAULT_POINTER", null, "DEFAULT_VALUE", 6, "VALUE_TYPE", "Byte", "DETOUR_ADDRESS", null)
aInterface["RadarX"] := Object("ADDRESSES", [0x58A79B, 0x5834D4, 0x58A836, 0x58A8E9, 0x58A98A, 0x58A469, 0x58A5E2, 0x58A6E6], "DEFAULT_POINTER", 0x858A10, "DEFAULT_VALUE", 40.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["RadarY"] := Object("ADDRESSES", [0x58A7C7, 0x58A868, 0x58A913, 0x58A9C7, 0x583500, 0x58A499, 0x58A60E, 0x58A71E], "DEFAULT_POINTER", 0x866B70, "DEFAULT_VALUE", 104.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["RadarHeight"] := Object("ADDRESSES", [0x58A47D, 0x58A632, 0x58A6AB, 0x58A70E, 0x58A801, 0x58A8AB, 0x58A921, 0x58A9D5, 0x5834F6], "DEFAULT_POINTER", 0x866B74, "DEFAULT_VALUE", 76.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["RadarWidth"] := Object("ADDRESSES", [0x5834C2, 0x58A449, 0x58A7E9, 0x58A840, 0x58A943, 0x58A99D], "DEFAULT_POINTER", 0x866B78, "DEFAULT_VALUE", 94.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["RadarScaleWidth"] := Object("ADDRESSES", [0x5834EE, 0x58A475, 0x58A602, 0x58A706, 0x58A7BB, 0x58A85C, 0x58A90B, 0x58A9BF],
"DEFAULT_POINTER", 0x859524, "DEFAULT_VALUE", 0.002232143, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["RadarScaleHeight"] := Object("ADDRESSES", [0x5834BC, 0x58A443, 0x58A5DA, 0x58A6E0, 0x58A793, 0x58A830, 0x58A8E1, 0x58A984], "DEFAULT_POINTER", 0x859520, "DEFAULT_VALUE", 0.0015625, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["Radar-Tilt-XPos"] := Object("ADDRESSES", [0x58A469], "DEFAULT_POINTER", 0x858A10, "DEFAULT_VALUE", 40.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["Radar-Tilt-YPos"] := Object("ADDRESSES", [0x58A499], "DEFAULT_POINTER", 0x866B70, "DEFAULT_VALUE", 104.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["Radar-Height-XPos"] := Object("ADDRESSES", [0x58A5E2, 0x58A6E6], "DEFAULT_POINTER", 0x858A10, "DEFAULT_VALUE", 40.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
aInterface["Radar-Height-YPos"] := Object("ADDRESSES", [0x58A60E, 0x58A71E], "DEFAULT_POINTER", 0x866B70, "DEFAULT_VALUE", 104.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
получается через указатель на float обращаться только через второй адрес памяти, например aInterface["MoneyX"] := Object("ADDRESSES", [0x58F5FC], "DEFAULT_POINTER", 0x85950C, "DEFAULT_VALUE", 32.0, "VALUE_TYPE", "Float", "DETOUR_ADDRESS", null)
к 0x58F5FC получается обращаться только через указатель на один байт, иначе краш. а к 0x85950C через указатель на float. Как в 0x58F5FC записать значение float, если сам тип данных для указателя этого адреса обрезает в 1 байт. Это для .asi, на lua я не понимаю зачем сначала считывают значение mem.getuint32(0x58F5FC), а потом mem.setfloat, в чем смысл считывать значение с адреса памяти? - Почему сразу нельзя вписать нужное значение?
 
Последнее редактирование:

ya_noob

Участник
57
7
Получаешь сперва указатель на этот адрес, а потом цже в него записываешь значение.
конкретнее? Ну вот указатель на float: "float*". а если полностью: "float* a = (float*)0x1231231321321". но таким образом крашит.

Получаешь сперва указатель на этот адрес, а потом цже в него записываешь значение.
Как ты сделал? Можешь написать на примере HealthX?

Получаешь сперва указатель на этот адрес, а потом цже в него записываешь значение.
C++:
struct Hud {
    Hud() {
        VirtualProtect(&HealthX, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
        VirtualProtect(&HealthY, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);

        HealthX = 120;
        HealthY = 70;
       
    }
    DWORD oldProtect;
   float& HealthX = *(float*)0x58EE87; //141
   float& HealthY = *(float*)0x58EE68; //77
} hud;

ЧТО НЕ ТАК?

Получаешь сперва указатель на этот адрес, а потом цже в него записываешь значение.
C++:
struct Hud {
    Hud() {
        VirtualProtect(&HealthX, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
        VirtualProtect(&HealthY, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
        VirtualProtect(&pHealthX, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
        VirtualProtect(&pHealthY, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);

        pHealthX = 120;
        pHealthY = 60;
        
        *(float*)0x58EE87 = *(float*)0x86535C;
        *(float*)0x58EE68 = *(float*)0x866CA8;
    }
    DWORD oldProtect;
    float& HealthX = *(float*)0x58EE87;
    float& HealthY = *(float*)0x58EE68;
    float& pHealthX = *(float*)0x86535C;//141
    float& pHealthY = *(float*)0x866CA8;//77
} hud;


Так тоже крашит. Так что значит в адрес нужно вписывать указатель на float?
 
Последнее редактирование:

ARMOR

kjor32 is legend
Модератор
4,846
6,071
конкретнее? Ну вот указатель на float: "float*". а если полностью: "float* a = (float*)0x1231231321321". но таким образом крашит.


Как ты сделал? Можешь написать на примере HealthX?


C++:
struct Hud {
    Hud() {
        VirtualProtect(&HealthX, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
        VirtualProtect(&HealthY, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);

        HealthX = 120;
        HealthY = 70;
      
    }
    DWORD oldProtect;
   float& HealthX = *(float*)0x58EE87; //141
   float& HealthY = *(float*)0x58EE68; //77
} hud;

ЧТО НЕ ТАК?


C++:
struct Hud {
    Hud() {
        VirtualProtect(&HealthX, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
        VirtualProtect(&HealthY, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
        VirtualProtect(&pHealthX, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
        VirtualProtect(&pHealthY, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);

        pHealthX = 120;
        pHealthY = 60;
       
        *(float*)0x58EE87 = *(float*)0x86535C;
        *(float*)0x58EE68 = *(float*)0x866CA8;
    }
    DWORD oldProtect;
    float& HealthX = *(float*)0x58EE87;
    float& HealthY = *(float*)0x58EE68;
    float& pHealthX = *(float*)0x86535C;//141
    float& pHealthY = *(float*)0x866CA8;//77
} hud;


Так тоже крашит. Так что значит в адрес нужно вписывать указатель на float?
Как вариант юзать такое говно ( Не ебу насколько это правильно ):
C++:
float& pHealth = **(float**)(0x58EE87);
pHealth = 120.f;
 

ya_noob

Участник
57
7
Как вариант юзать такое говно ( Не ебу насколько это правильно ):
C++:
float& pHealth = **(float**)(0x58EE87);
pHealth = 120.f;
Получилось, но не умею понятия как именно это работает. Почему через "float& pHealth = *(float*)(0x58EE87)" крашит, а через "float& pHealth = **(float**)(0x58EE87)" - нет, ведь в обоих случая изменяя значение по указателю, оно все равно изменится в переменной на который этот указатель указывает
 

kin4stat

mq-team
Всефорумный модератор
2,730
4,710
Как вариант юзать такое говно ( Не ебу насколько это правильно ):
C++:
float& pHealth = **(float**)(0x58EE87);
pHealth = 120.f;
Некоторые константы могут использоваться в других местах кода. Поэтому изменять саму константы стоит только в случаях, когда есть полная уверенность что константа используется только в одном месте.

Например, если изменить саму константу дистанции прорисовки текста от /dl, то сломаются хпбары над игроками. Поэтому в этом случае нужно менять именно указатель на значение, а не само значение.

Получилось, но не умею понятия как именно это работает. Почему через "float& pHealth = *(float*)(0x58EE87)" крашит, а через "float& pHealth = **(float**)(0x58EE87)" - нет, ведь в обоих случая изменяя значение по указателю, оно все равно изменится в переменной на который этот указатель указывает
Потому что (float*)0x1337
Это получение указателя с адресом 0x1337.
(float**)0x1337 это получение указателя, которое лежит по адресу 0x1337
 

ya_noob

Участник
57
7
Некоторые константы могут использоваться в других местах кода. Поэтому изменять саму константы стоит только в случаях, когда есть полная уверенность что константа используется только в одном месте.

Например, если изменить саму константу дистанции прорисовки текста от /dl, то сломаются хпбары над игроками. Поэтому в этом случае нужно менять именно указатель на значение, а не само значение.


Потому что (float*)0x1337
Это получение указателя с адресом 0x1337.
(float**)0x1337 это получение указателя, которое лежит по адресу 0x1337
[float** a = float* b (константа) + какое-то значение] - то есть вот так примерно схематично высчитывается позиция ХПбара? Или нет? В любом случае спасибо
 

Vintik

Мечтатель
Проверенный
1,463
913
Health PosX - 0x58EE87
Health PosY - 0x58EE68
Health Width - 0x5892D8
Health Height - 0x589358
game координаты или window?
в любом случае (и так, и так проверил) хп бар выводится слева сверху, а он справа...

C++:
static const float radarX1 = **(float**)0x58EE87;
static const float radarY1 = **(float**)0x58EE68;
static const float radarWidth = **(float**)0x5892D8;
static const float radarHeight = **(float**)0x589358;
SF->getRender()->DrawBox(radarX1, radarY1, radarWidth, radarHeight, D3DCOLOR_ARGB(120, 0, 255, 0));
SF->getRender()->EndRender();
где ошибка?
1691446427628.png


upd: вопрос решил, может кому-то будет полезно решение. координаты там игровые (game), их надо переводить в экранные. и еще почему-это конкретно с радаром вертикальные координаты (ось Y) считаются снизу вверх. низ экрана - 0 координата, верх - 448. размер игрового экрана 640 x 448 (Ш x В). вот код:
C++:
float radarX1 = **(float**)0x58A79B;
float radarY1 = 448 - **(float**)0x58A7C7;
float radarWidth = **(float**)0x5834C2;
float radarHeight = **(float**)0x58A47D;
SF->getGame()->convertGameCoordsToWindow(radarX1, radarY1, &radarX1, &radarY1);
SF->getGame()->convertGameCoordsToWindow(radarWidth, radarHeight, &radarWidth, &radarHeight);
SF->getRender()->DrawBox(radarX1, radarY1, radarWidth, radarHeight, D3DCOLOR_ARGB(120, 0, 255, 0));
1691494987499.png
 
Последнее редактирование: