Jump to content

Șir de funcții utile


Vinyard

Recommended Posts

  • Moderators

Am făcut acest subiect pentru a face un cadru în care să centralizăm diversele funcții utile postate în ultima vreme pe Discord, dar care din păcate pot deveni greu de găsit printre canale odată cu trecerea timpului.

Așadar, postați aici orice funcții utile considerați că merită împărtășite cu ceilalți membrii ai comunității!

Asigurați-vă că specificați la ce ajută funcția respectivă și că atașați codul folosind butonul Insert code snippet.

Link to comment

O simpla functie care te ajuta sa salvezi coordonatele tale intr-un fisier .txt:

function pos(thePlayer, command)
   local x, y, z = getElementPosition(thePlayer)
   if not fileExists("posave.txt") then
      local pathFile = fileCreate("posave.txt")
      fileClose(pathFile)
   elseif fileExists("posave.txt") then
      local openFile = fileOpen("posave.txt")
      local sizeFile = fileGetSize(openFile)
      local dataFile = fileRead(openFile, sizeFile)
      fileWrite(openFile, "\n"..x..", "..y..", "..z.."")
      outputChatBox("Saved: "..x..", "..y..", "..z.."", root, 255, 255, 255, true)
      fileClose(openFile)
   end
end
addCommandHandler("gpos", pos)

O functie care iti zice daca se aude sunetul sau nu:

Poate fi gasita si aici: https://wiki.multitheftauto.com/wiki/IsSoundPlaying

function isSoundPlaying(theSound)
    return (getSoundPosition(theSound))
end

O functie care iti zice daca elementul este in aer sau nu:
Poate fi gasita si aici: https://wiki.multitheftauto.com/wiki/IsElementInAir

--// Varianta 1 (Valoarea default este 10)
function isElementInAir(element)
    local x, y, z = getElementPosition(element)
    if element and isElement(element) then 
        if z >= 10 then
           return z
        end
    end
end
--// Varianta 2 (Pui tu valoare la Z)
function isElementInAir(element, ZPos)
    local x, y, z = getElementPosition(element)
    if element and isElement(element) then 
        if z >= tonumber(ZPos) then
           return z
        end
    end
end

O functie care creeaza un dreptunghi 3D deasupra jucatorului:
Poate fi gasita si aici: https://wiki.multitheftauto.com/wiki/DxDrawRectangleOnPlayer

function dxDrawRectangleOnPlayer(x, y, width, height, color)
   local players = getElementsByType("player", root, true)
   if players then
   local x, y, z = getElementPosition(localPlayer)
	for _, v in ipairs(players) do
	    if v and isElement(v) then
		local px, py, pz = getElementPosition(v)
		if getDistanceBetweenPoints3D(x, y, z, px, py, pz) <= 20 then
		   local sx, sy = getScreenFromWorldPosition(px, py, pz + 1.3)
		   if sx and sy then
		   dxDrawRectangle(sx + x, sy + y/1.6, width, height, color, false)
                end
            end
        end
    end
end
end

:v:

  • Like 1
Link to comment

genereaza un float intre lower si greater

function randomFloat(lower, greater)
    return lower+math.random()*(greater-lower)
end

 

returneaza offset ul unui element in object space

function getPositionFromElementOffset(element, offX, offY, offZ)
    local m = getElementMatrix(element)
    local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1]
    local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2]
    local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3]
    return x, y, z 
end

 

self-made: returneaza secundele+ms gametime-ului

local secondChange = 0
local secondStart = getTickCount()

function convertTimeToSeconds()
	local hour, minute = getTime()
	if minute ~= secondChange then
		secondChange = minute
		secondStart = getTickCount()
	end
	return hour*60+minute+((getTickCount()-secondStart)/getMinuteDuration())
end

 

sterge value dintr-un table

function removeValueFromTable(table, value)
	if type(table) == "table" then
		for k,v in ipairs(table) then
			if v == value then
      			table.remove(table, k)
				return true
			end
		end
	end
	return false
end

 

limiteaza value intr-un interval

function clamp(value, min, max)
	return math.max(min, math.min(value, max))
end

 

returneaza offset-ul unui punct bazat pe rotatie si distanta 2D

function getPointFromDistanceRotation(x, y, dist, angle)
	return x+math.cos(math.rad(90-angle))*dist, y+math.sin(math.rad(90-angle))*dist
end

 

self-made: genereaza un cubic bezier curve in 3D

-- x, y, z - start
-- x2, y2, z2 - end
-- bx, by, bz - start handle
-- b2x, b2y, b2z - end handle
-- t - time float

function cubicBezier3D(x, y, z, x2, y2, z2, bx, by, bz, b2x, b2y, b2z, t)
	local p1 = {lerp(x, bx, t), lerp(y, by, t), lerp(z, bz, t)}
	local p2 = {lerp(bx, b2x, t), lerp(by, b2y, t), lerp(bz, b2z, t)}
	local p3 = {lerp(b2x, x2, t), lerp(b2y, y2, t), lerp(b2z, z2, t)}
	local l1 = {lerp(p1[1], p2[1], t), lerp(p1[2], p2[2], t), lerp(p1[3], p2[3], t)}
	local l2 = {lerp(p2[1], p3[1], t), lerp(p2[2], p3[2], t), lerp(p2[3], p3[3], t)}
	return lerp(l1[1], l2[1], t), lerp(l1[2], l2[2], t), lerp(l1[3], l2[3], t)
end

function lerp(a, b, c)
	return a + (b - a) * c
end

 

  • Like 1
Link to comment
  • 2 weeks later...

part ii

returneaza playerul dupa o parte a numelui (useful af)

function getPlayerFromPartialName(name)
    local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil
    if name then
        for _, player in ipairs(getElementsByType("player")) do
            local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower()
            if name_:find(name, 1, true) then
                return player
            end
        end
    end
	return false
end

 

verifica daca contul player-ului este intr-un ACL Group

function isPlayerInACL ( player, acl )
	local account = getPlayerAccount ( player )
	if ( isGuestAccount ( account ) ) then
		return false
	end
    return isObjectInACLGroup ( "user."..getAccountName ( account ), aclGetGroup ( acl ) )
end

 

verifica daca player-ul este intr-un team

function isPlayerInTeam(player, team)
    return getPlayerTeam(player) == (type(team) == "string" and getTeamFromName(team) or (type(team) == "userdata" and team or (getPlayerTeam(player) or true)))
end

 

returneaza distanta dintre camera si element

function getElementDistanceFromCamera(element)
	local cX, cY, cZ = getCameraMatrix()
	local eX, eY, eZ = getElementPosition(element)
	return getDistanceBetweenPoints3D(cX, cY, cZ, eX, eY, eZ)
end

 

returneaza viteza unui element in km/h

function getElementKMh(element)
	if element and isElement(element) then
		local v = {getElementVelocity(element)}
		return math.floor(((v[1]^2 + v[2]^2 + v[3]^2)^(0.5))*180)
	end
end

 

returneaza un string fara Hex color codes: #00FF00Player > Player

function unHex(string)
    return (type(string) == "string" and string:gsub("#%x%x%x%x%x%x", "")) or false
end

 

recomandat pentru cei ce lucreaza cu functii dx, screenR returneaza raportul ecranului (de obicei 16/9 sau 1.(7))

local screenW, screenH = guiGetScreenSize()
local screenR, screenN = screenW/screenH, 1280/screenW

 

screenN il folositi pentru dx scaling, daca lucrati in rezolutia 1920/1080, folositi 1920/screenW, dupa va folositi de acea variabila de a inmulti fiecare constanta folosit in functiile dx (nu inmultiti screenN cu screenW sau screenH fiindca aceste 2 nu sunt constante)

exemplu:

local screenW, screenH = guiGetScreenSize()
local screenN, screenYnative = 1280/screenW, 720/screenH -- // a 2-a variabila este foarte putin folosita, dar o vom folosi aici doar ca exemplu

addEventHandler("onClientRender", root, function()

    -- FOLOSIND DOAR CONSTANTE (rosu)
    
    dxDrawRectangle(screenW/2 - sizeX/2, screenH/2 - sizeY/2, 100, 200, tocolor(255, 0, 0, 255))
    
    -- //
    
    -- FOLOSIND x*screenN, y*screenYnative (verde)
    
    local sizeX, sizeY = 100*screenN, 200*screenYnative

    dxDrawRectangle(screenW/2 - sizeX/2, screenH/2 - sizeY/2, sizeX, sizeY, tocolor(0, 255, 0, 150))

    -- //
    
end)

acest script deseneaza doua dreptunghiuri (rosu si verde) in mijlocul ecranului, veti observa ca dreptunghiul verde va avea dimensiunile relative rezolutiei ecranului, try it out. evident, se poate folosi aceasta variabila si in pozitionarea *elementelor* dx


 

 

  • Like 1
Link to comment

return la handling flag-ul specificat este inclus

local handlingFlags = {
    ["1G_BOOST"] = {1, 1},
    ["2G_BOOST"] = {1, 2},
    ["NPC_ANTI_ROLL"] = {1, 4},
    ["NPC_NEUTRAL_HANDL"] = {1, 8},
    ["NO_HANDBRAKE"] = {2, 1},
    ["STEER_REARWHEELS"] = {2, 2},
    ["HB_REARWHEEL_STEER"] = {2, 4},
    ["ALT_STEER_OPT"] = {2, 8},
    ["WHEEL_F_NARROW2"] = {3, 1},
    ["WHEEL_F_NARROW"] = {3, 2},
    ["WHEEL_F_WIDE"] = {3, 4},
    ["WHEEL_F_WIDE2"] = {3, 8},
    ["WHEEL_R_NARROW2"] = {4, 1},
    ["WHEEL_R_NARROW"] = {4, 2},
    ["WHEEL_R_WIDE"] = {4, 4},
    ["WHEEL_R_WIDE2"] = {4, 8},
    ["HYDRAULIC_GEOM"] = {5, 1},
    ["HYDRAULIC_INST"] = {5, 2},
    ["HYDRAULIC_NONE"] = {5, 4},
    ["NOS_INST"] = {5, 8},
    ["OFFROAD_ABILITY"] = {6, 1},
    ["OFFROAD_ABILITY2"] = {6, 2},
    ["HALOGEN_LIGHTS"] = {6, 4},
    ["PROC_REARWHEEL_1ST"] = {6, 8},
    ["USE_MAXSP_LIMIT"] = {7, 1},
    ["LOW_RIDER"] = {7, 2},
    ["STREET_RACER"] = {7, 4},
    ["SWINGING_CHASSIS"] = {8, 1}
}

function getHandlingFlag(handling, name)
    handling = tostring(handling)

    if type(name) == "string" then
        local data = {}
        for i = 1, string.len(handling) do
            table.insert(data, tonumber(string.sub(handling, i, i)))
        end

        local flag = handlingFlags[name]
        return (data[flag[1]] == flag[2])
    elseif type(name) == "table" then
        local data = {}
        for i = 1, string.len(handling) do
            table.insert(data, tonumber(string.sub(handling, i, i)))
        end

        local value = {}
        for i = 1, #name do
            local flag = name[i]
            local flagData = handlingFlags[flag]

            value[flag] = (data[flagData[1]] == flagData[2])
        end

        return value
    else
        return false
    end
end

 

Exemple:

 

local vehicle = getPedOccupiedVehicle(localPlayer)
if vehicle then
	local handlingFlags = getVehicleHandling(vehicle).handlingFlags
  	print(getHandlingFlag(handlingFlags, "1G_BOOST")) -- true daca are acest handling flag sau false daca nu

  	iprint(getHandlingFlags(handlingFlags, {"1G_BOOST", "2G_BOOST"})
	--[[
    	Raspuns:

		{
    		["1G_BOOST"] = true daca are acest handling flag sau false daca nu,
    		["2G_BOOST"] = true daca are acest handling flag sau false daca nu
    	}
    ]]

end

 

Link to comment
  • 3 weeks later...
  • 8 months later...

math.lerp pentru euler angles (generat de chatgpt pentru python, convertit de mine pentru lua)

function lerp_angle(start_angle, end_angle, progress)
    local start_angle = math.rad(start_angle)
    local end_angle = math.rad(end_angle)
    if math.abs(end_angle - start_angle) > math.pi then
        if end_angle > start_angle then
            start_angle = start_angle + 2*math.pi
        else
            end_angle = end_angle + 2*math.pi
        end
    end
    local angle = (1 - progress) * start_angle + progress * end_angle
    return math.deg(angle)
end
Edited by chris1384
  • Like 1
Link to comment

Nu gasesc o categorie adecvata pentru a posta link-urile acestea dar cea mai buna optiune ar fi aici:
https://wiki.multitheftauto.com/wiki/RO/Main_Page - (Tradus in Romana, posibil sa fie mici greseli)
https://wiki.multitheftauto.com/index.php?title=RO/Cum_Poti_Ajuta (Tradus in Romana, posibil sa fie mici greseli)
https://wiki.multitheftauto.com/wiki/RO/createPed - (Tradus in Romana)

https://wiki.multitheftauto.com/wiki/RO/getPedAmmoInClip - (Tradus in Romana)

https://wiki.multitheftauto.com/wiki/RO/getPedArmor - (Tradus in Romana)

O sa incerc sa traduc cat mai multe :)

Edited by Hydra
  • Like 2
Link to comment
2 hours ago, Hydra said:

Nu gasesc o categorie adecvata pentru a posta link-urile acestea dar cea mai buna optiune ar fi aici:
https://wiki.multitheftauto.com/wiki/RO/Main_Page - (Tradus in Romana, posibil sa fie mici greseli)
https://wiki.multitheftauto.com/index.php?title=RO/Cum_Poti_Ajuta (Tradus in Romana, posibil sa fie mici greseli)
https://wiki.multitheftauto.com/wiki/RO/createPed - (Tradus in Romana)

https://wiki.multitheftauto.com/wiki/RO/getPedAmmoInClip - (Tradus in Romana)

https://wiki.multitheftauto.com/wiki/RO/getPedArmor - (Tradus in Romana)

O sa incerc sa traduc cat mai multe :)

float -- e un numar real ce poate sa aiba sau nu zecimale poate sa fie sau nu negativ

Asta am vrut să adaug doar. Good Work Man.

  • Like 1
Link to comment
  • 2 weeks later...
function find_value_in_table(table,value)
    local a  = table
    for i=1,#a do 
        if a[i] == value then 
            return true 
        end 
    end 
end 

function find_value_pos_in_table(table,value)
    local a  = table
    for i=1,#a do do 
        if a[i] == value then 
            local t = i
            return t
            end
        end 
    end 
end 

1.Prima functie este folosita la a verifica daca o valoare se afla sau nu intr-un tabel.

2.Urmatoarea functie folosita pentru a gasi pozitia (index-ul) unei valori intr-un tabel daca acea valoare exista in tabelul respectiv.

*Sunt testate si merg.

Link to comment
  • 1 month later...
-- onClientVehicleReverse / chris1384

local reversing = {vehicles = {}}

local getElementsByType = getElementsByType
local root = getRootElement()
local pairs = pairs
local triggerEvent = triggerEvent
local getElementType = getElementType
local getElementMatrix = getElementMatrix
local getElementVelocity = getElementVelocity

function reversing.start()
    local vehicles = getElementsByType("vehicle", root, true)
    local vehicles_count = #vehicles
    if vehicles_count > 0 then
        for i=1, vehicles_count do
            local vehicle = vehicles[i]
            reversing.vehicles[vehicle] = reversing.detect(vehicle)
        end
    end
end
addEventHandler("onClientResourceStart", resourceRoot, reversing.start)

function reversing.render()
    for vehicle, d in pairs(reversing.vehicles) do
        local r = reversing.detect(vehicle)
        if d ~= r then
            reversing.vehicles[vehicle] = r
            triggerEvent("onClientVehicleReverse", vehicle, r == 1)
        end
    end
end
addEventHandler("onClientRender", root, reversing.render)

function reversing.add()
    local vehicle = source
    if getElementType(vehicle) == "vehicle" then
        reversing.vehicles[vehicle] = reversing.detect(vehicle)
    end
end
addEventHandler("onClientElementStreamIn", root, reversing.add)

function reversing.remove()
    local vehicle = source
    if getElementType(vehicle) == "vehicle" then
        reversing.vehicles[vehicle] = nil
    end
end
addEventHandler("onClientElementDestroy", root, reversing.remove)
addEventHandler("onClientElementStreamOut", root, reversing.remove)

function reversing.detect(vehicle)
    local m = getElementMatrix(vehicle)
    local x, y, z = getElementVelocity(vehicle)
    local d = (x * m[2][1]) + (y * m[2][2]) + (z * m[2][3])
    return (d < 0 and 1) or 0
end

 

usage:

addEvent("onClientVehicleReverse")
addEventHandler("onClientVehicleReverse", root, function(reversing)
  iprint(vehicle, reversing)
  -- OUTPUT
  -- vehicle:element, true if reversing, false otherwise
end)
Link to comment

Numara cati jucatori sunt intr-o dimensiune

function PlayersInDimension(dimension)
    local count = 0
    local people = getElementsByType("player")
    for _,players in ipairs(people) do 
        if getElementDimension(players) == tonumber(dimension) then 
        count = count + 1
        end
    end 
    return count
end

 

Link to comment

Bună, băieți, am vrut să contribui la această problemă și vreau să împărtășesc un cod pe care l-am pregătit cu voi, scopul acestui cod este 6 pe care le vor genera numere și litere aleatorii, permiteți-mi să vă spun unde puteți utiliza acest cod, pt. exemplu: verificare e-mail, parola uitată, misiuni, evenimente
 

function timeNeedsPlural(theNumber)
    if not (type(tonumber(theNumber)) == "number") then return "" end
    if (tonumber(theNumber) == 1) then return "" end
    return ""
end

function shuffleTable(tbl)
    local size = #tbl
    for i = size, 1, -1 do
        local rand = math.random(size)
        tbl[i], tbl[rand] = tbl[rand], tbl[i]
    end
    return tbl
end

function generateCode(codeSize)
    local code = {}
    local charset = {}
    for i = 48,57 do
        charset[#charset+1] = string.char(i)
    end
    for i = 97,122 do
        charset[#charset+1] = string.char(i)
    end
    for i=1,codeSize do
        code[#code+1] = charset[math.random(1,#charset)]
    end
    return code
end

 

  • Thanks 1
Link to comment
3 hours ago, Shady1 said:

Bună, băieți, am vrut să contribui la această problemă și vreau să împărtășesc un cod pe care l-am pregătit cu voi, scopul acestui cod este 6 pe care le vor genera numere și litere aleatorii, permiteți-mi să vă spun unde puteți utiliza acest cod, pt. exemplu: verificare e-mail, parola uitată, misiuni, evenimente
 

function timeNeedsPlural(theNumber)
    if not (type(tonumber(theNumber)) == "number") then return "" end
    if (tonumber(theNumber) == 1) then return "" end
    return ""
end

function shuffleTable(tbl)
    local size = #tbl
    for i = size, 1, -1 do
        local rand = math.random(size)
        tbl[i], tbl[rand] = tbl[rand], tbl[i]
    end
    return tbl
end

function generateCode(codeSize)
    local code = {}
    local charset = {}
    for i = 48,57 do
        charset[#charset+1] = string.char(i)
    end
    for i = 97,122 do
        charset[#charset+1] = string.char(i)
    end
    for i=1,codeSize do
        code[#code+1] = charset[math.random(1,#charset)]
    end
    return code
end

 

Nici nu stiam ca esti de-al nostru, cand te-am vazut pe forum :))), oricum nice to see you here man!

Link to comment

Weather & Time events

--// Client

addDebugHook("postFunction", function(_, _, _, _, _, weatherType)
    triggerEvent("onClientWeatherChange", resourceRoot, weatherType)
end, {"setWeather"})



addDebugHook("postFunction", function(_, _, _, _, _, timeHour, timeMinute)
     triggerEvent("onClientTimeChange", resourceRoot, timeHour, timeMinute)
end, {"setTime"})

--// Server

addDebugHook("postFunction", function(_, _, _, _, _, weatherType)
    triggerEvent("onWeatherChange", resourceRoot, weatherType)
end, {"setWeather"})



addDebugHook("postFunction", function(_, _, _, _, _, timeHour, timeMinute)
     triggerEvent("onTimeChange", resourceRoot, timeHour, timeMinute)
end, {"setTime"})

EXAMPLES (CLIENT & SERVER):

function TimeOnWeatherChange()
   outputChatBox("Weather changed (SERVER)", root, 255, 255, 0, true)
end
addEvent("onWeatherChange")
addEventHandler("onWeatherChange", root, TimeOnWeatherChange)



function TimeCheck()
   outputChatBox("Time changed (SERVER)", root, 255, 255, 0, true)
end
addEvent("onTimeChange")
addEventHandler("onTimeChange", root, TimeCheck)


function CTimeOnWeatherChange()
   outputChatBox("Weather changed (CLIENT)")
end
addEvent("onClientWeatherChange")
addEventHandler("onClientWeatherChange", root, CTimeOnWeatherChange)



function CTimeCheck()
   outputChatBox("Time changed (CLIENT)")
end
addEvent("onClientTimeChange")
addEventHandler("onClientTimeChange", root, CTimeCheck)

NOTE: Aceste eventuri merg doar daca folositi functiile (setTime & setWeather)

Edited by Hydra
Link to comment
  • 4 months later...
  • 3 weeks later...

Cu aceasta functie vei putea detecta daca un jucator/npc foloseste o animatie sau nu
 

Exemplu:
bindKey("i", "down", function()
    if isPedDoingAnim(localPlayer) then
       outputChatBox("Folosesti o animatie", 255, 255, 255, true)
    else
       outputChatBox("Nu folosesti o animatie", 255, 255, 255, true)
    end
end)


function isPedDoingAnim(theElement)
   if isElement(theElement) and getElementType(theElement) == "ped" or getElementType(theElement) == "player" then
      local block, anim = getPedAnimation(theElement)
      if block ~= nil and anim ~= nil then
         return true
      else
         return false
      end
   end
end

 

  • Like 1
Link to comment
  • 5 months later...

Niște afiramții/formulări ce pot fi utile când dorim să aflăm informații legate de un anumit tabel sau coloane ce corespund unui tabel dintr-o bază de date.

--- varianta MySQL
local rez = dbPoll(dbQuery(connection,"SELECT table_name FROM information_schema.tables WHERE table_schema = '"..name.."';"),-1)
-- inlocuiți name cu numele bazei de date de la care doriți să aflați informații legate de tabele
-- rez o sa returneze un tabel cu denumirile tabelelor din baza de date pe care ați asociat-o cu variabila name 
for k,v in pairs(rez) do 
    outputDebugString(v.table_name)
end 

local rez = dbPoll(dbQuery(connection,"SELECT COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '"..table.."' ORDER BY ORDINAL_POSITION"),-1)
-- selectam denumirea coloanelor si tipul datelor pentru tabela aflata sub variabila table 
for k,v in pairs(rez) do 
    outputDebugString(v.COLUMN_NAME)
  	outputDebugString(v.DATA_TYPE)
end 

----------------------
-- Pentru SQLite
local rez = dbPoll(dbQuery(connection,"SELECT name FROM sqlite_master WHERE type='table';"),-1) 
-- aici nu mai aveti nevoie de denumirea bazei de date deoarece se returneaza tabelele din baza de date la care sunteti conectat.
for k,v in pairs(rez) do 
    if v.name ~= "sqlite_sequence" then 
    outputDebugString(v.name)
    end 
end 

local rez = dbPoll(dbQuery(connection,"PRAGMA table_info("..tostring(table)..")"),-1)
-- selectam date legate de coloane
-- table este denumirea tabelului de la care dorim sa aflam date legate de coloane.
for k,v in pairs(rez) do 
    outputDebugString(v.name)
  	outputDebugString(v.type)
end 

 

  • Like 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...