Цвет объекта

ChаtGPT

Известный
Автор темы
420
103
Версия MoonLoader
.026-beta
Здравствуйте! Нужна помощь с функцией getObjectMaterialColor(objectHandle, slot).
Я разрабатываю универсальный скрипт рендера по пресетам. Цель - отрисовывать объекты не только по их модели, но и по другим параметрам: текстуре, цвету и тексту. Сам скрипт почти готов, но когда дело дошло до реализации функций для получения этих параметров столкнулся с проблемами.


К сожалению, я слабо разбираюсь в работе со структурами, FFI и указателями, и просто не понимаю, как правильно считать данные.
Я подключил структуру CObject и попробовал получить текст материала через соответствующее поле, но на выходе получаю непонятные значения вроде 8388620, 2 или 12. Причём такие же значения выводятся и у объектов, у которых материал явно не установлен.


Можно ли как-то реализовать корректное считывание этих данных именно через структуру, без реверса и жёсткой привязки к адресам для конкретных версий SAMP-клиента? Очень хочется добиться максимальной совместимости, чтобы скрипт работал на разных клиентах SAMP.


П.с. Простите, если написал какой-то бред я реально не понимаю, что делаю не так.

Сразу прикрепляю скрин “будущего скрипта” может это поможет лучше понять, чего я хочу добиться.
photo_2025-04-29_12-52-45.jpg


Lua:
local ffi = require("ffi")

ffi.cdef[[
    typedef uint32_t D3DCOLOR;
    typedef int BOOL;
    typedef unsigned short ID;
    typedef struct RwTexture {
        char name[32];
        char mask[32];
        unsigned filterAddressing;
        int refCount;
    } RwTexture;
    struct CSprite2d {
        RwTexture *m_pTexture;
    };
    typedef struct MaterialText {
        char m_nMaterialIndex;
        char pad_0[137];
        char m_nMaterialSize;
        char m_szFont[65];
        char m_nFontSize;
        bool m_bBold;
        D3DCOLOR m_fontColor;
        D3DCOLOR m_backgroundColor;
        char m_align;
    } MaterialText;
    typedef struct ObjectMaterial {
        struct CSprite2d *m_pSprite[16];
        D3DCOLOR m_color[16];
        char pad_6[68];
        int m_nType[16];
        BOOL m_bTextureWasCreated[16];
        MaterialText m_textInfo[16];
        const char *m_szText[16];
        void *m_pBackgroundTexture[16];
        void *m_pTexture[16];
    } ObjectMaterial;
    typedef struct CObject {
        ObjectMaterial m_material;
        BOOL m_bHasCustomMaterial;
    } CObject;
]]



local function getObjectMaterialColor(objectHandle, slot)
    local ptr = getObjectPointer(objectHandle)
    if ptr == 0 then return nil end
    local cobj = ffi.cast("CObject*", ptr)
    local color = cobj.m_material.m_color[slot]
    return color
end

local font = renderCreateFont('Arial', 10, 0x1 + 0x4 + 0x8)
function onD3DPresent()
    if isSampAvailable() and not isPauseMenuActive() then
        for _, handle in pairs(getAllObjects()) do
            if isObjectOnScreen(handle) then
                local _, x, y, z = getObjectCoordinates(handle)
                local sx, sy = convert3DCoordsToScreen(x, y, z)

                local id = sampGetObjectSampIdByHandle(handle)
                local color = getObjectMaterialColor(handle, 0)

                renderFontDrawText(font, color, sx, sy, 0xFFFF9900)
            end
        end
    end
end

Получилось с помощью sampapi:


Lua:
local sampapi = require("sampapi")
local CNetGame = sampapi.require('CNetGame', true)

function getObjectColor(handle, slot)
    local objectId = sampGetObjectSampIdByHandle(handle)

    local netGame = CNetGame.RefNetGame()
    local objectPool = netGame:GetObjectPool()
    local object = objectPool:Get(objectId)

    if object == ffi.NULL then return nil end

    return object.m_material.m_color[slot]
end
 
Последнее редактирование: