Полезные сниппеты и функции

Cosmo

Известный
Друг
659
2,775
Описание: Быстрый бег в любом месте. Например в интерьерах, где это ранее было запрещено (один из таких - завод около фермы)
Lua:
memory.hex2bin("B800000000C20400", 0x55E870, 8) -- ON
memory.hex2bin("8B4424048D04408B", 0x55E870, 8) -- OFF (default)
thanks @ARMOR

Описание: Снятие ограничение скорости транспорта в некоторых местах на карте. Например, одно из таких: мост SF-LV
Lua:
-- ON
memory.setuint8(0x72DDD0, 0x33, true)
memory.setuint8(0x72DDD1, 0xC0, true)
memory.setuint8(0x72DDD2, 0xC3, true)

-- OFF (default)
memory.setuint8(0x72DDD0, 0xA1, true)
memory.setuint8(0x72DDD1, 0xB8, true)
memory.setuint8(0x72DDD2, 0x7A, true)
thanks @ARMOR

Описание: Снятие ограничение скорости транспорта на железнодорожных рельсах (взято из SAP)
Lua:
memory.setfloat(0x8D34AC, 0.0, true) -- ON
memory.setfloat(0x8D34AC, 0.003, true) -- OFF (default)
 
Последнее редактирование:

Орк

Известный
307
206
Описание: Возвращает режим камеры. Код пару раз встречался на форуме, но сюда никто не занес.
Описание есть тут: https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_sa/game_sa/eCamMode.h
Или под спойлером
Lua:
local memory = require("memory")
eCamMode = memory.getint16(0xB6F1A8)
--or
eCamMode = readMemory(0xB6F1A8, 2, false)
Lua:
    -- MODE_NONE = 0,
    -- MODE_TOPDOWN = 1,
    -- MODE_GTACLASSIC = 2,
    -- MODE_BEHINDCAR = 3,
    -- MODE_FOLLOWPED = 4,
    -- MODE_AIMING = 5,
    -- MODE_DEBUG = 6,
    -- MODE_SNIPER = 7,
    -- MODE_ROCKETLAUNCHER = 8,
    -- MODE_MODELVIEW = 9,
    -- MODE_BILL = 10,
    -- MODE_SYPHON = 11,
    -- MODE_CIRCLE = 12,
    -- MODE_CHEESYZOOM = 13,
    -- MODE_WHEELCAM = 14,
    -- MODE_FIXED = 15,
    -- MODE_1STPERSON = 16,
    -- MODE_FLYBY = 17,
    -- MODE_CAM_ON_A_STRING = 18,
    -- MODE_REACTION = 19,
    -- MODE_FOLLOW_PED_WITH_BIND = 20,
    -- MODE_CHRIS = 21,
    -- MODE_BEHINDBOAT = 22,
    -- MODE_PLAYER_FALLEN_WATER = 23,
    -- MODE_CAM_ON_TRAIN_ROOF = 24,
    -- MODE_CAM_RUNNING_SIDE_TRAIN = 25,
    -- MODE_BLOOD_ON_THE_TRACKS = 26,
    -- MODE_IM_THE_PASSENGER_WOOWOO = 27,
    -- MODE_SYPHON_CRIM_IN_FRONT = 28,
    -- MODE_PED_DEAD_BABY = 29,
    -- MODE_PILLOWS_PAPS = 30,
    -- MODE_LOOK_AT_CARS = 31,
    -- MODE_ARRESTCAM_ONE = 32,
    -- MODE_ARRESTCAM_TWO = 33,
    -- MODE_M16_1STPERSON = 34,
    -- MODE_SPECIAL_FIXED_FOR_SYPHON = 35,
    -- MODE_FIGHT_CAM = 36,
    -- MODE_TOP_DOWN_PED = 37,
    -- MODE_LIGHTHOUSE = 38,
    -- MODE_SNIPER_RUNABOUT = 39,
    -- MODE_ROCKETLAUNCHER_RUNABOUT = 40,
    -- MODE_1STPERSON_RUNABOUT = 41,
    -- MODE_M16_1STPERSON_RUNABOUT = 42,
    -- MODE_FIGHT_CAM_RUNABOUT = 43,
    -- MODE_EDITOR = 44,
    -- MODE_HELICANNON_1STPERSON = 45,
    -- MODE_CAMERA = 46,
    -- MODE_ATTACHCAM = 47,
    -- MODE_TWOPLAYER = 48,
    -- MODE_TWOPLAYER_IN_CAR_AND_SHOOTING = 49,
    -- MODE_TWOPLAYER_SEPARATE_CARS = 50,
    -- MODE_ROCKETLAUNCHER_HS = 51,
    -- MODE_ROCKETLAUNCHER_RUNABOUT_HS = 52,
    -- MODE_AIMWEAPON = 53,
    -- MODE_TWOPLAYER_SEPARATE_CARS_TOPDOWN = 54,
    -- MODE_AIMWEAPON_FROMCAR = 55,
    -- MODE_DW_HELI_CHASE = 56,
    -- MODE_DW_CAM_MAN = 57,
    -- MODE_DW_BIRDY = 58,
    -- MODE_DW_PLANE_SPOTTER = 59,
    -- MODE_DW_DOG_FIGHT = 60,
    -- MODE_DW_FISH = 61,
    -- MODE_DW_PLANECAM1 = 62,
    -- MODE_DW_PLANECAM2 = 63,
    -- MODE_DW_PLANECAM3 = 64,
    -- MODE_AIMWEAPON_ATTACHED = 65

Пример:
Lua:
eCamMode = readMemory(0xB6F1A8, 2, false)
if eCamMode == 15 then print('Камера отсоединена от персонажа') end
if eCamMode == 53 then print('Вы целитесь из оружия') end
if eCamMode == 46 then print('Вы целитесь через камеру') end
 

ARMOR

Go Robot
Модератор
4,994
6,992
Описание: Меняет текстуру модели по указателю на неё ( скины, объекты и т.д )
ВНИМАНИЕ: Меняет текстуру всем игрокам с такой же моделью. Так же нельзя перезапускать скрипт ведь старая текстура удалится и вас крашнет нахуй, разве что сохраняйте старые текстуры моделей в таблице и при выгрузке скрипта устанавливайте старые текстурки

Lua:
local ffi = require("ffi")

ffi.cdef[[
    typedef void*(__cdecl *CallBack)(void* pMaterial, void* pData);
]]

local RpClumpForAllAtomics = ffi.cast("void*(__cdecl*)(void*, void*(__cdecl*)(void*, void*), void*)", 0x749B70)
local RpGeometryForAllMaterials = ffi.cast("void*(__cdecl*)(void*, void*(__cdecl*)(void*, void*), void*)", 0x74C790)

function materialTextureCB(pMaterial, pData)
    local pGeometry = ffi.cast("uintptr_t*", ffi.cast("uintptr_t", pMaterial) + 0x18)[0]
    ffi.cast("int*", pGeometry + 0x8)[0] = bit.bor(ffi.cast("int*", pGeometry + 0x8)[0], 0x40)
    RpGeometryForAllMaterials(ffi.cast("void*", pGeometry), ffi.cast("CallBack", atomicTextureCB), ffi.cast("void*", pData))
    return pMaterial
end

function atomicTextureCB(pAtomic, pData)
    local pTexture = ffi.cast("uintptr_t*", ffi.cast("uintptr_t", pAtomic) + 0x00)[0]
    local pRaster = ffi.cast("uintptr_t*", pTexture + 0x00)[0]
    ffi.cast("void**", pRaster + 0x34)[0] = pData
    return pAtomic
end

function setEntityModelTexture(pEntity, DxTexture)
    local pTexture = ffi.cast("void*", renderGetTextureStruct(DxTexture));
    local pRwObject = ffi.cast("uintptr_t*", pEntity + 0x18)[0];
    if (ffi.cast("unsigned char*", pRwObject)[0] == 1) then
        local pGeometry = ffi.cast("uintptr_t*", pRwObject + 0x18)[0]
        ffi.cast("int*", pGeometry + 0x8)[0] = bit.bor(ffi.cast("int*", pGeometry + 0x8)[0], 0x40)
        RpGeometryForAllMaterials(ffi.cast("void*", pGeometry), ffi.cast("CallBack", atomicTextureCB), ffi.cast("void*", pData))
    elseif ffi.cast("unsigned char*", pRwObject)[0] == 2 then
        RpClumpForAllAtomics(ffi.cast("void*", pRwObject), ffi.cast("CallBack", materialTextureCB), ffi.cast("void*", pTexture))
    end
end

Пример использования:
Lua:
function main()
    local myTexture = renderLoadTextureFromFile(".\\moonloader\\obama.png")
    while true do
        wait(0)
        if wasKeyPressed(49) then
            local pPed = getCharPointer(PLAYER_PED)
            setEntityModelTexture(pPed, myTexture)
        end
    end
end

Скриншот:
1730687765657.jpeg
 
Последнее редактирование:

hihihehe

Потрачен
7
31
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Описание: генерирует билд версии скрипта в стиле GoldSrc (ссылка)
Пример использования:
example:
function generateBuildVersion(date)
    local day, month, year = date:match("(%d+).(%d+).(%d+)")
    local time = os.time({ day = tonumber(day), month = tonumber(month), year = tonumber(year), hour = 0 })
    local baseTime = os.time({ day = 1, month = 1, year = 1900, hour = 0 })

    return math.floor(os.difftime(time, baseTime) / (24 * 60 * 60) + 0.5)
end

local releaseDate = "24.10.1996"
local updateDate = "06.11.2024"
print(generateBuildVersion(updateDate) - generateBuildVersion(releaseDate)) -- output: 10240
Код:
code:
function generateBuildVersion(date)
    local day, month, year = date:match("(%d+).(%d+).(%d+)")
    local time = os.time({ day = tonumber(day), month = tonumber(month), year = tonumber(year), hour = 0 })
    local baseTime = os.time({ day = 1, month = 1, year = 1900, hour = 0 })

    return math.floor(os.difftime(time, baseTime) / (24 * 60 * 60) + 0.5)
end
 
Последнее редактирование:

Naito

Активный
157
35
Description: Add an expiration date.


code:
local function isModExpired()
    local currentTime = os.date("*t")
    if currentTime.year > endYear or
       (currentTime.year == endYear and currentTime.month > endMonth) or
       (currentTime.year == endYear and currentTime.month == endMonth and currentTime.day > endDay) or
       (currentTime.year == endYear and currentTime.month == endMonth and currentTime.day == endDay and currentTime.hour >= endHour and currentTime.min >= endMinute) then
        return true
    end
    return false
end

local endYear = 2025
local endMonth = 7
local endDay = 1
local endHour = 20
local endMinute = 30

-- Function to check if the current date is greater than or equal to the deactivation date
local function isModExpired()
    local currentTime = os.date("*t")
    if currentTime.year > endYear or
       (currentTime.year == endYear and currentTime.month > endMonth) or
       (currentTime.year == endYear and currentTime.month == endMonth and currentTime.day > endDay) or
       (currentTime.year == endYear and currentTime.month == endMonth and currentTime.day == endDay and currentTime.hour >= endHour and currentTime.min >= endMinute) then
        return true
    end
    return false
end

local function isModExpired()
    local currentTime = os.date("*t")
    if currentTime.year > endYear or
       (currentTime.year == endYear and currentTime.month > endMonth) or
       (currentTime.year == endYear and currentTime.month == endMonth and currentTime.day > endDay) or
       (currentTime.year == endYear and currentTime.month == endMonth and currentTime.day == endDay and currentTime.hour >= endHour and currentTime.min >= endMinute) then
        return true
    end
    return false
end

-- Function to calculate the remaining time until deactivation
local function getTimeRemaining()
    local currentTime = os.time()
    local endTime = os.time{year = endYear, month = endMonth, day = endDay, hour = endHour, min = endMinute}

    local remaining = endTime - currentTime

    if remaining <= 0 then
        return "MOD EXPIRED!"
    end

    local days = math.floor(remaining / 86400)
    remaining = remaining % 86400

    local hours = math.floor(remaining / 3600)
    remaining = remaining % 3600

    local minutes = math.floor(remaining / 60)
    local seconds = remaining % 60

    return string.format("TIME LEFT UNTIL EXPIRATION: %d days, %02d:%02d:%02d", days, hours, minutes, seconds)
end
 

1NEXPL1CA

Известный
759
377
Описание: рисует текст с чёрной обводкой mimgui (т.к в mimgui вроде нельзя поменять флаг шрифта)
Думаю реализация не из лучших, посоветуйте свои варианты!
Код:

Lua:
function imgui.TextWithOutline(DRAW_LIST, X, Y, COLOR, TEXT, OFFSET)
    local OFFSETS = {
        {-OFFSET, 0}, {OFFSET, 0}, {0, -OFFSET}, {0, OFFSET},{-OFFSET, -OFFSET}, {-OFFSET, OFFSET}, {OFFSET, -OFFSET}, {OFFSET, OFFSET}
    }
    for _, OFFSET in ipairs(OFFSETS) do
        DRAW_LIST:AddText(imgui.ImVec2(X - OFFSET[1], Y - OFFSET[2]), 0xFF000000, TEXT)
    end
    DRAW_LIST:AddText(imgui.ImVec2(X, Y), COLOR, TEXT)
end
 

ARMOR

Go Robot
Модератор
4,994
6,992
Описание: Подгружаем кастомные модели с помощью SAMP. ( Калькор добавил эту возможность ещё в R3, но подгрузку моделей серверами только в DL )

РАБОТАЕТ ТОЛЬКО НА Р3

Lua:
local ffi = require("ffi")
local samp = getModuleHandle("samp.dll")

local loadSampCustomSkin = ffi.cast("int(__cdecl*)(int, int, const char*, const char*, const char*)", samp + 0xA7340)
local loadSampCustomModel = ffi.cast("int(__cdecl*)(int, int, const char*, const char*, const char*)", samp + 0xA73A0)
local initCustomModelsArray = ffi.cast("void(__cdecl*)()", samp + 0xA7170)

Пример использования:
Lua:
local ffi = require("ffi")
local samp = getModuleHandle("samp.dll")

local loadSampCustomSkin = ffi.cast("int(__cdecl*)(int, int, const char*, const char*, const char*)", samp + 0xA7340)
local loadSampCustomModel = ffi.cast("int(__cdecl*)(int, int, const char*, const char*, const char*)", samp + 0xA73A0)
local initCustomModelsArray = ffi.cast("void(__cdecl*)()", samp + 0xA7170)

function setModelIndex(handle, id)
    local pPed = getCharPointer(handle)
    ffi.cast("void(__thiscall*)(void*, int)", 0x005E4880)(ffi.cast("void*", pPed), id)
end

function main()
    while not isSampAvailable() do wait(0) end

    -- Объязательно используйте эту функцию. Без неё будет крашить при подгрузке моделей
    initCustomModelsArray()

    -- loadSampCustomSkin: Подгружает модель для скина
    -- loadSampCustomModel: Подгружает модель для объектов
    -- Первый аргумент - это ID стандартной модели с которой будет браться основная информация. Например 0 ид скин сиджея. С него будут браться анимации и т.д
    -- Второй аргумент - это кастомный ID модели, начинайте от 20000
    -- Третий аргумент - это название txdSlot. Указывайте туда что хотите. Например название скрипта
    -- Четвертный аргумент - это путь к .dff файлу модели
    -- Пятый аргумент - это путь к .txd файлу модели
    loadSampCustomSkin(0, 20001, "nullGirl", ".\\customModels\\myModel.dff" , ".\\customModels\\myModel.txd")
    loadSampCustomModel(2387, 20002, "nullGirl", ".\\customModels\\myModel.dff" , ".\\customModels\\myModel.txd")

    while true do
        wait(0)
        if wasKeyPressed(49) then
            setModelIndex(playerPed, 20001)
        end
        if wasKeyPressed(50) then
            local x, y, z = getCharCoordinates(playerPed)
            createObject(20002, x + 15, y, z)
        end
    end
end

Скриншот:
1732765299308.jpeg


Предыстория:
258284

123.jpg

 

UBP

Известный
360
223
Изменяем максимальную скорость транспорта без краша при торможении. * Краш вызывается, если изменять максимальную скорость авто через адрес
0xC2B9DC + VehicleHeader * 224 + 0x84.
Пример файла-библиотеки. Если нужно интегрировать внутрь скрипта, убрать везде public.
Lua:
local mem = require 'memory' -- Подключаем библиотеку для работы с памятью игры
local ffi = require 'ffi' -- Подключаем ffi
-- Таблица для хранения значений
public = {}
public.originalGearSpeeds = {}

-- Получаем заголовок машины
function public.GetVehicleHeader()
    local value = 0
    local car = storeCarCharIsInNoSave(playerPed)
    if car then
        value = getCarModel(car)
        value = mem.getint32(value * 0x4 + 0xA9B0C8, false)
        value = mem.getint16(value + 0x4A, false)
    end
    return value
end

-- Функция для сохранения оригинальных значений скоростей передач
-- @param vehicle - указатель на объект CVehicle
-- @param gearNum - номер передачи
function public.saveOriginalGearSpeed(vehicle, gearNum)
    if not public.originalGearSpeeds[gearNum] then
        for i = 0, gearNum do
            public.originalGearSpeeds[i] = vehicle.pHandlingData.transmissionData.aGears[i].fMaxVelocity
        end
    end
end

-- Функция для установки новой скорости
--@param car - указатель на объект CVehicle
--@param newSpeed - новая скорость
function public.setNewGearSpeed(car, newSpeed)
    local CarPointer = getCarPointer(car)
    if CarPointer ~= 0 then
        local vehicle = ffi.cast("CVehicle*", CarPointer)
        if vehicle.pHandlingData ~= nil then
            local Gears = mem.getint8(0xC2B9DC + public.GetVehicleHeader() * 224 + 0x76, false)
            public.saveOriginalGearSpeed(vehicle, Gears)
            for i = 0, Gears do
                vehicle.pHandlingData.transmissionData.aGears[i].fMaxVelocity = newSpeed
            end
        else
            print("Ошибка: pHandlingData является нулевым указателем")
        end
    end
end

-- Функция для восстановления оригинальной скорости
--@param car - указатель на объект CVehicle
--@param a - car pointer
function public.restoreOriginalGearSpeed(car)
    local CarPointer = getCarPointer(car)
    if CarPointer ~= 0 then
        local vehicle = ffi.cast("CVehicle*", CarPointer)
        if vehicle.pHandlingData ~= nil then
            local Gears = mem.getint8(0xC2B9DC + public.GetVehicleHeader() * 224 + 0x76, false)
            if public.originalGearSpeeds[Gears] then
                for i = 0, Gears do
                    vehicle.pHandlingData.transmissionData.aGears[i].fMaxVelocity = public.originalGearSpeeds[Gears]
                end
            end
        else
            print("Ошибка: pHandlingData является нулевым указателем")
        end
    end
end

return public

Пример:
Lua:
local CarUtils = require('lib.CarUtils') -- Вместо CarUtils название вашего файла-библиотеки
local car = storeCarCharIsInNoSave(playerPed)
CarUtils.setNewGearSpeed(car, 0.852)

function onScriptTerminate(script, quitGame) -- При краше или выходе сбрасываем значения
    if script == thisScript() then
        if isCharInAnyCar(playerPed) then
            local car = storeCarCharIsInNoSave(playerPed)
            CarUtils.restoreOriginalGearSpeed(car)
        end
    end
end
 
Последнее редактирование:

Moorell

Участник
58
12
Описание:
Рекурсивное деление текста, функции, которые я видел - не подходят для моих целей, поэтому я написал что-то подобное. На русском языке не проверялось

Function:
function split(text,limit,massive)
    if #text > limit then
        local w = text:sub(1,limit)
        massive[#massive + 1] = w
        if(#text:gsub(w,'') > limit) then
            split(text:gsub(w,''),limit,massive)
        else
            massive[#massive + 1] = text:gsub(w,'')
        end
        return massive
    else
        return {text}
    end

end

Использование:

Example:
local text = [[Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.]]
local result = split(text,50,{})
print(unpack(result))

Результат:

Result:
Lorem Ipsum is simply dummy text of the printing a    nd typesetting industry. Lorem Ipsum has been the     industry's standard dummy text ever since the 1500    s, when an unknown printer took a galley of type a    nd scrambled it to make a type specimen book. It h    as survived not only five centuries, but also the     leap into electronic typesetting, remaining essent    ially unchanged. It was popularised in the 1960s w    ith the release of Letraset sheets containing Lore    m Ipsum passages, and more recently with desktop p    ublishing software like Aldus PageMaker including     versions of Lorem Ipsum.
Крашит если в тексте будет какой либо спец символ (+, -, * и т д)
 
  • Эм
Реакции: XRLM

Gorskin

🖕
Проверенный
1,347
1,193
Описание: Просто ограничитель кадров, много кто у меня просил вырезать саму реализацию. Не требует хуков и прочей фигни.


Lua:
local ffi = require("ffi")


local TARGET_FRAMERATE = 60 -- значение фпс

------------------------------------------ [FFI cdef] ---------------------------
ffi.cdef [[   
    typedef unsigned int UINT;
    typedef unsigned long DWORD;
    typedef void* HANDLE;
    typedef DWORD HRESULT;
    typedef long LONG;
    typedef int BOOL;
    typedef enum _D3DFORMAT { __D3DFORMAT } D3DFORMAT;
    typedef enum _D3DMULTISAMPLE_TYPE { __D3DMULTISAMPLE_TYPE } D3DMULTISAMPLE_TYPE;
    typedef enum _D3DSWAPEFFECT { __D3DSWAPEFFECT } D3DSWAPEFFECT;
    typedef struct _HWND* HWND;
    typedef struct _IDirect3DDevice9 IDirect3DDevice9;
    
    void Sleep(unsigned long dwMilliseconds);

    typedef struct _D3DPRESENT_PARAMETERS {
        UINT                BackBufferWidth;
        UINT                BackBufferHeight;
        D3DFORMAT           BackBufferFormat;
        UINT                BackBufferCount;
        D3DMULTISAMPLE_TYPE MultiSampleType;
        DWORD               MultiSampleQuality;
        D3DSWAPEFFECT       SwapEffect;
        HWND                hDeviceWindow;
        BOOL                Windowed;
        BOOL                EnableAutoDepthStencil;
        D3DFORMAT           AutoDepthStencilFormat;
        DWORD               Flags;
        UINT                FullScreen_RefreshRateInHz;
        UINT                PresentationInterval;
    } D3DPRESENT_PARAMETERS;

    typedef union _LARGE_INTEGER {
        struct {
        long LowPart;
        long HighPart;
        };
        long long QuadPart;
    } LARGE_INTEGER;

    //kernel32
    int __stdcall QueryPerformanceCounter(LARGE_INTEGER* performanceCount);
    int __stdcall QueryPerformanceFrequency(LARGE_INTEGER* frequency);

    //winmm
    DWORD __stdcall timeGetTime(void);

    typedef unsigned int uint16;
    typedef unsigned int uint8;
]]

local kernel32 = ffi.load("Kernel32.dll")

local frequency_large = ffi.new("LARGE_INTEGER")
kernel32.QueryPerformanceFrequency(frequency_large)
local performance_frequency = tonumber(frequency_large.QuadPart)

local function get_current_ms()
    local ticks_large = ffi.new("LARGE_INTEGER")
    kernel32.QueryPerformanceCounter(ticks_large)
    return tonumber(ticks_large.QuadPart) * (1000 / performance_frequency)
end

local winmm = ffi.load("winmm.dll")

local _last_frame_time = 0

perfect_sleep = function(ms)
    local target = get_current_ms() + ms

    while get_current_ms() < target do end
end

function onD3DPresent()
    if TARGET_FRAMERATE >= 4 and TARGET_FRAMERATE <= 299 then
        if _last_frame_time ~= 0 then
            local time_lost_to_swap =  (winmm.timeGetTime() - _last_frame_time)
            local time_to_swap = (1000 / TARGET_FRAMERATE )
            if time_lost_to_swap < time_to_swap then
                perfect_sleep(time_to_swap - time_lost_to_swap)
            end
        end
        _last_frame_time = winmm.timeGetTime()
    end
end
 
  • Нравится
  • Эм
Реакции: 1NS, #Northn и kyrtion

Cloud.

Активный
358
52
Описание: Показывает радар и худ во время слежки.
Lua:
function radarAndHudPatch(bool)
    if bool then
        memory.write(sampGetBase() + 643864, 37008, 2, true)
    else
        memory.write(sampGetBase() + 643864, 3956, 2, true)
    end
end
Пример использования:
Lua:
local memory = require "memory"
function main()
    sampRegisterChatCommand("radarpatch", function()
        radarAndHudPatch(true)
        sampAddChatMessage("Патч включён", -1)
    end)
    wait(-1)
end
извиняюсь за оффтоп, но худ тут не нужен, т.к сервер не отображает худ игрока за каким следит админ
 

Орк

Известный
307
206
Требования: https://github.com/lipp/lua-websockets , https://github.com/obsproject/obs-websocket/releases (плагин для obs)
1735795464048.png

Описание: Вебсокет, который начинает/останавливает запись и сохраняет повтор буфера в OBS. При написании активно использовался ChatGPТ.
Меня раздражало, что постоянно нужно нажимать/эмулировать кнопки для начала записи. Иногда промахивался и не попадал в кнопку, а эмуляция может не сработать. Теперь нашел решение!
Все/большинство названий команд можно посмотреть тут https://gist.github.com/lee-brown/70e6014a903dfea9e2dfe7e35fc8ab88#startstoprecording
Lua:
local websocket = require("websocket")

local host = "localhost"
local port = 4444
local url = "ws://" .. host .. ":" .. port

local StartRecording = [[ { "request-type": "StartRecording", "message-id": "1" } ]]
local StopRecording = [[ { "request-type": "StopRecording", "message-id": "1" } ]]
local SaveReplayBuffer = [[ { "request-type": "SaveReplayBuffer", "message-id": "1" } ]]

function sendcmd(cmd)

    local client = websocket.client.sync()

    local success, err = pcall(function()
        client:connect(url)
    end)

    if not success then
        print("Ошибка подключения: " .. err)
        return
    end
    client:send(cmd)

    -- Ожидаем ответа от OBS (необязательно, но полезно для проверки)
    -- local response = client:receive()
    -- print("Ответ от OBS: " .. response)


    client:close()
end
Пример:
Lua:
sendcmd(StartRecording)

Если поможете оптимизировать/отказаться от вебсокетов/использовать другую библиотеку, то буду только рад. А если подскажите, как правильно оформить по стандарту синтаксиса, будет вообще замечательно.
 

chromiusj

$IWishYouSweetDreams
Модератор
5,720
4,015
Описание:
Сама функция:
imgui.Poll = (function()
    local pollStates = {}
    ---@param title string Название голосования (должно быть уникальным)
    ---@param options table Таблица с опциями голосования (каждая опция - это таблица с ключами: title (название), percent (процент прогресса, по умолчанию 0))
    ---@param settings table Настройки голосования (например, {type = "multiple" или "single", animationDuration = <длительность анимации в секундах>, width = <ширина пункта>})
    return function(title, options, settings)
        local pollState = pollStates[title]
        if not pollState then
            pollState = {
                options = {},
                settings = settings,
                animStartTime = 0,
                animating = false,
                voteCompleted = false,
            }

            for _, option in ipairs(options) do
                table.insert(pollState.options, {
                    title = option.title,
                    percent = option.percent or 0,
                    targetPercent = option.percent or 0,
                    circleFill = 0,
                    selected = false,
                    initialPercent = 0,
                    initialCircleFill = 0,
                })
            end
            pollStates[title] = pollState
        end
        local function interpolate(t)
            return 1 - (1 - t) ^ 3
        end
        local function updateAnimation()
            if pollState.animating then
                local elapsed = os.clock() - pollState.animStartTime
                local duration = pollState.settings.animationDuration or 1
                if elapsed >= duration then
                    pollState.animating = false
                    for _, option in ipairs(pollState.options) do
                        option.percent = option.targetPercent
                        option.circleFill = option.selected and 100 or 0
                    end
                else
                    local t = elapsed / duration
                    t = interpolate(t)
                    for _, option in ipairs(pollState.options) do
                        option.percent = option.initialPercent + (option.targetPercent - option.initialPercent) * t
                        option.circleFill = option.initialCircleFill + ((option.selected and 100 or 0) - option.initialCircleFill) * t
                        option.percent = math.max(0, math.min(100, option.percent))
                        option.circleFill = math.max(0, math.min(100, option.circleFill))
                    end
                end
            end
        end
        updateAnimation()
        local fixedWidth = settings.width or 400
        local boxHeight, padding = 60, 15
        local windowPos = imgui.GetWindowPos()
        local contentRegionMin = imgui.GetWindowContentRegionMin()
        imgui.SetCursorScreenPos(imgui.ImVec2(windowPos.x + contentRegionMin.x, imgui.GetCursorScreenPos().y))
        imgui.Text(title)
        local p = imgui.GetCursorScreenPos()
        local dl = imgui.GetWindowDrawList()
        local circleRadius = 12
        local barHeight, barPadding = 10, 20
        local circleSegments = 64
        for i, option in ipairs(pollState.options) do
            local boxMin = imgui.ImVec2(p.x, p.y + (i - 1) * (boxHeight + padding))
            local boxMax = imgui.ImVec2(boxMin.x + fixedWidth, boxMin.y + boxHeight)
            imgui.SetCursorScreenPos(boxMin)
            imgui.InvisibleButton("option" .. i .. "_" .. title, imgui.ImVec2(fixedWidth, boxHeight))
            local isHovered, isClicked = imgui.IsItemHovered(), imgui.IsItemClicked()
            if isClicked and not pollState.voteCompleted then
                if pollState.settings.type == "single" then
                    for _, opt in ipairs(pollState.options) do opt.selected = false end
                    option.selected = true
                elseif pollState.settings.type == "multiple" then
                    option.selected = not option.selected
                end
                local totalVotes = 0
                for _, opt in ipairs(pollState.options) do
                    if opt.selected then totalVotes = totalVotes + 1 end
                end
                for _, opt in ipairs(pollState.options) do
                    if totalVotes > 0 then
                        opt.targetPercent = opt.selected and math.floor(100 / totalVotes) or 0
                    else
                        opt.targetPercent = 0
                    end
                end
                for _, opt in ipairs(pollState.options) do
                    opt.initialPercent = opt.percent
                    opt.initialCircleFill = opt.circleFill
                end
                pollState.animStartTime = os.clock()
                pollState.animating = true
            end
            local borderColor = imgui.GetColorU32(
                option.selected and imgui.Col.ButtonActive or (isHovered and imgui.Col.ButtonHovered or imgui.Col.Border)
            )
            dl:AddRect(boxMin, boxMax, borderColor, 10, 7, 2)
            local circlePos = imgui.ImVec2(boxMin.x + circleRadius + 10, boxMin.y + boxHeight / 2)
            dl:AddCircle(circlePos, circleRadius, imgui.GetColorU32(imgui.Col.Border), circleSegments, 2)
            local circleFillColor = imgui.GetColorU32(imgui.Col.ButtonHovered)
            local fillRadius = circleRadius * option.circleFill / 100
            dl:AddCircleFilled(circlePos, fillRadius, circleFillColor, circleSegments)
            local barMin = imgui.ImVec2(boxMin.x + circleRadius * 2 + 20, boxMax.y - barHeight - 15)
            local barMax = imgui.ImVec2(boxMin.x + fixedWidth - barPadding, boxMax.y - 15)
            local radius = barHeight / 2
            dl:AddRectFilled(barMin, barMax, imgui.GetColorU32(imgui.Col.FrameBg), radius, ImDrawCornerFlags_All)
            if option.percent > 0 then
                local activeBarMax = imgui.ImVec2(barMin.x + (barMax.x - barMin.x) * option.percent / 100, barMax.y)
                local cornerFlags = ImDrawCornerFlags_Left
                if option.percent == 100 then
                    cornerFlags = ImDrawCornerFlags_All
                end
                dl:AddRectFilled(barMin, activeBarMax, imgui.GetColorU32(imgui.Col.ButtonHovered), radius, cornerFlags)
            end
            local textPos = imgui.ImVec2(barMin.x, boxMin.y + 10)
            local percentText = string.format("%d%%", option.percent)
            local percentTextSize = imgui.CalcTextSize(percentText)
            local percentTextPos = imgui.ImVec2(boxMin.x + fixedWidth - percentTextSize.x - barPadding, boxMin.y + 10)
            dl:AddText(textPos, imgui.GetColorU32(imgui.Col.Text), option.title)
            dl:AddText(percentTextPos, imgui.GetColorU32(imgui.Col.Text), percentText)
        end
    end
end)()
Пример использования:
Lua:
local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function(player)
        local resX, resY = getScreenResolution()
        imgui.SetNextWindowPos(imgui.ImVec2(resX / 2, resY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(400, 400), imgui.Cond.FirstUseEver)
        if imgui.Begin("", renderWindow) then
            local playerOptions = {}
            for k, v in ipairs(getAllChars()) do
                if v ~= PLAYER_PED then
                    local res, id = sampGetPlayerIdByCharHandle(v)
                    if res then
                        local nickname = sampGetPlayerNickname(id)
                        table.insert(playerOptions, { title = nickname, percent = 0 })
                    end
                end
            end
            if #playerOptions > 0 then
                imgui.Poll(u8"Выберите лучшего игрока", playerOptions, {
                    type = "single",
                    animationDuration = 3.0,
                    width = 500
                })
            end
            imgui.End()
        end
    end
)
1735898364194.png
 

chapo

чопа сребдс // TG/IG: @moujeek
Модератор
9,012
11,837
Описание: Stalin Sort Algorithm
Код:
Lua:
local function stalinSort(arr)
    local result = { arr[1] };
    table.foreach(arr, function(i, v)
        if (v > result[#result]) then
            table.insert(result, v);
        end
    end);
    return result;
end
Пример использования:
Lua:
local function printArr(arr)
    print('Array:');
    for k, v in ipairs(arr) do
        print(k, v);
    end
end
local function stalinSort(arr)
    local result = { arr[1] };
    table.foreach(arr, function(i, v)
        if (v > result[#result]) then
            table.insert(result, v);
        end
    end);
    return result;
end
local arr = {1, 3, 2, 4, 5};
printArr(arr);
printArr(stalinSort(arr));
 
  • Нравится
Реакции: kyrtion