- 420
- 103
- Версия MoonLoader
- .026-beta
Здравствуйте! Нужна помощь с функцией
Я разрабатываю универсальный скрипт рендера по пресетам. Цель - отрисовывать объекты не только по их модели, но и по другим параметрам: текстуре, цвету и тексту. Сам скрипт почти готов, но когда дело дошло до реализации функций для получения этих параметров столкнулся с проблемами.
К сожалению, я слабо разбираюсь в работе со структурами, FFI и указателями, и просто не понимаю, как правильно считать данные.
Я подключил структуру CObject и попробовал получить текст материала через соответствующее поле, но на выходе получаю непонятные значения вроде
Можно ли как-то реализовать корректное считывание этих данных именно через структуру, без реверса и жёсткой привязки к адресам для конкретных версий SAMP-клиента? Очень хочется добиться максимальной совместимости, чтобы скрипт работал на разных клиентах SAMP.
П.с. Простите, если написал какой-то бред я реально не понимаю, что делаю не так.
Сразу прикрепляю скрин “будущего скрипта” может это поможет лучше понять, чего я хочу добиться.
Получилось с помощью sampapi:
getObjectMaterialColor(objectHandle, slot)
.Я разрабатываю универсальный скрипт рендера по пресетам. Цель - отрисовывать объекты не только по их модели, но и по другим параметрам: текстуре, цвету и тексту. Сам скрипт почти готов, но когда дело дошло до реализации функций для получения этих параметров столкнулся с проблемами.
К сожалению, я слабо разбираюсь в работе со структурами, FFI и указателями, и просто не понимаю, как правильно считать данные.
Я подключил структуру CObject и попробовал получить текст материала через соответствующее поле, но на выходе получаю непонятные значения вроде
8388620
, 2
или 12
. Причём такие же значения выводятся и у объектов, у которых материал явно не установлен.Можно ли как-то реализовать корректное считывание этих данных именно через структуру, без реверса и жёсткой привязки к адресам для конкретных версий SAMP-клиента? Очень хочется добиться максимальной совместимости, чтобы скрипт работал на разных клиентах SAMP.
П.с. Простите, если написал какой-то бред я реально не понимаю, что делаю не так.
Сразу прикрепляю скрин “будущего скрипта” может это поможет лучше понять, чего я хочу добиться.
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
Последнее редактирование: