Main/resources/[jobs]/[weapons]/force-sling/client/utils.lua

245 lines
6.5 KiB
Lua
Raw Normal View History

2025-06-07 08:51:21 +02:00
Utils = {}
2025-06-12 21:38:10 +02:00
function Utils:CreateAndAttachWeapon(weaponName, weaponVal, coords, playerPed, isOtherPlayer)
if not isOtherPlayer and Sling.currentAttachedAmount >= Config.MaxWeaponsAttached then
2025-06-12 21:32:14 +02:00
Debug("warn", "Max weapons attached reached")
2025-06-07 08:51:21 +02:00
return false
end
if not weaponVal or not weaponVal.name then
2025-06-12 21:32:14 +02:00
Debug("error", "Invalid weapon data")
2025-06-07 08:51:21 +02:00
return false
end
2025-06-12 21:32:14 +02:00
-- Initialize the cached attachments for this weapon if it doesn't exist
if not Sling.cachedAttachments[weaponName] then
Sling.cachedAttachments[weaponName] = {}
end
local weaponObject = CreateWeaponObject(weaponVal.name, 0, coords.coords.x, coords.coords.y, coords.coords.z, true, 1.0, 0)
2025-06-07 08:51:21 +02:00
if not weaponObject then
2025-06-12 21:32:14 +02:00
Debug("error", "Failed to create weapon object")
2025-06-07 08:51:21 +02:00
return false
end
if NetworkGetEntityIsNetworked(weaponObject) then
NetworkUnregisterNetworkedEntity(weaponObject)
end
2025-06-12 21:32:14 +02:00
2025-06-07 08:51:21 +02:00
SetEntityCollision(weaponObject, false, false)
2025-06-12 21:32:14 +02:00
2025-06-12 21:38:10 +02:00
if not isOtherPlayer and Config.UseWeaponAttachments then
2025-06-07 08:51:21 +02:00
weaponVal.attachments = Inventory:GetWeaponAttachment(weaponName)
end
2025-06-12 21:32:14 +02:00
for _, component in pairs(weaponVal.attachments or {}) do
2025-06-07 08:51:21 +02:00
GiveWeaponComponentToWeaponObject(weaponObject, component)
end
2025-06-12 21:32:14 +02:00
2025-06-07 08:51:21 +02:00
lib.requestModel(weaponVal.model)
2025-06-12 21:32:14 +02:00
local placeholder = CreateObjectNoOffset(weaponVal.model, coords.coords.x, coords.coords.y, coords.coords.z, true, true, false)
2025-06-07 08:51:21 +02:00
SetEntityCollision(placeholder, false, false)
SetEntityAlpha(placeholder, 0, false)
2025-06-12 21:32:14 +02:00
local boneIndex = GetPedBoneIndex(playerPed, (coords.boneId or DEFAULT_BONE))
AttachEntityToEntity(placeholder, playerPed, boneIndex,
coords.coords.x, coords.coords.y, coords.coords.z,
coords.rot.x, coords.rot.y, coords.rot.z,
true, true, false, true, 2, true)
AttachEntityToEntity(weaponObject, placeholder, GetEntityBoneIndexByName(placeholder, "gun_root"),
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
true, true, false, true, 2, true)
2025-06-07 08:51:21 +02:00
Sling.cachedAttachments[weaponName].obj = weaponObject
Sling.cachedAttachments[weaponName].placeholder = placeholder
2025-06-12 21:38:10 +02:00
if not isOtherPlayer then
Sling.currentAttachedAmount = Sling.currentAttachedAmount + 1
end
2025-06-12 21:32:14 +02:00
2025-06-07 08:51:21 +02:00
SetModelAsNoLongerNeeded(weaponVal.model)
return true
end
function Utils:DeleteWeapon(weaponName)
2025-06-12 21:32:14 +02:00
if not Sling.cachedAttachments[weaponName] then return end
2025-06-07 08:51:21 +02:00
local attachment = Sling.cachedAttachments[weaponName]
2025-06-12 21:32:14 +02:00
if attachment.obj and DoesEntityExist(attachment.obj) then
if NetworkGetEntityIsNetworked(attachment.obj) then
NetworkUnregisterNetworkedEntity(attachment.obj)
end
DeleteObject(attachment.obj)
2025-06-07 08:51:21 +02:00
end
2025-06-12 00:25:14 +02:00
2025-06-12 21:32:14 +02:00
if attachment.placeholder then
if IsEntityAttachedToAnyPed(attachment.placeholder) then
DetachEntity(attachment.placeholder, true, false)
end
if DoesEntityExist(attachment.placeholder) then
DeleteObject(attachment.placeholder)
end
2025-06-12 00:25:14 +02:00
end
2025-06-12 21:32:14 +02:00
Sling.cachedAttachments[weaponName] = nil
2025-06-12 21:38:10 +02:00
-- Nur verringern, wenn es keine Waffe eines anderen Spielers ist
if not string.find(weaponName, '_') then
Sling.currentAttachedAmount = math.max(0, Sling.currentAttachedAmount - 1)
end
end
function Utils:Debug(type, message)
if not Config.Debug then return end
if type == "error" then
print("^1[ERROR] " .. message .. "^7")
elseif type == "success" then
print("^2[SUCCESS] " .. message .. "^7")
elseif type == "info" then
print("^5[INFO] " .. message .. "^7")
elseif type == "warn" then
print("^3[WARN] " .. message .. "^7")
end
end
function Utils:Round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end
function Utils:TableContains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
2025-06-07 08:51:21 +02:00
end
2025-06-12 21:32:14 +02:00
2025-06-12 21:38:10 +02:00
function Utils:GetTableLength(table)
local count = 0
for _ in pairs(table) do
count = count + 1
end
return count
end
function Utils:DeepCopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[Utils:DeepCopy(orig_key)] = Utils:DeepCopy(orig_value)
end
setmetatable(copy, Utils:DeepCopy(getmetatable(orig)))
else
copy = orig
end
return copy
end
function Utils:MergeTable(t1, t2)
for k, v in pairs(t2) do
if type(v) == "table" and type(t1[k] or false) == "table" then
Utils:MergeTable(t1[k], t2[k])
else
t1[k] = v
end
end
return t1
end
function Utils:GetDistance(coords1, coords2)
return #(coords1 - coords2)
end
function Utils:DrawText3D(coords, text)
local onScreen, _x, _y = World3dToScreen2d(coords.x, coords.y, coords.z)
local px, py, pz = table.unpack(GetGameplayCamCoords())
local dist = #(vector3(px, py, pz) - coords)
local scale = (1 / dist) * 2
local fov = (1 / GetGameplayCamFov()) * 100
local scale = scale * fov
if onScreen then
SetTextScale(0.0 * scale, 0.55 * scale)
SetTextFont(0)
SetTextProportional(1)
SetTextColour(255, 255, 255, 255)
SetTextDropshadow(0, 0, 0, 0, 255)
SetTextEdge(2, 0, 0, 0, 150)
SetTextDropShadow()
SetTextOutline()
SetTextEntry("STRING")
SetTextCentre(1)
AddTextComponentString(text)
DrawText(_x,_y)
end
end
function Utils:LoadAnimDict(dict)
while not HasAnimDictLoaded(dict) do
RequestAnimDict(dict)
Wait(5)
end
end
function Utils:PlayAnim(ped, dict, anim, settings)
if not settings then settings = {} end
Utils:LoadAnimDict(dict)
TaskPlayAnim(ped, dict, anim,
settings.blendInSpeed or 3.0,
settings.blendOutSpeed or 3.0,
settings.duration or -1,
settings.flag or 49,
settings.playbackRate or 0,
settings.lockX or false,
settings.lockY or false,
settings.lockZ or false
)
RemoveAnimDict(dict)
end
function Utils:CreateBlip(coords, sprite, color, text, scale, category)
local blip = AddBlipForCoord(coords.x, coords.y, coords.z)
SetBlipSprite(blip, sprite)
SetBlipDisplay(blip, 4)
SetBlipScale(blip, scale or 0.8)
SetBlipColour(blip, color)
SetBlipAsShortRange(blip, true)
if category then
SetBlipCategory(blip, category)
end
BeginTextCommandSetBlipName("STRING")
AddTextComponentString(text)
EndTextCommandSetBlipName(blip)
return blip
end
function Utils:DrawMarker(type, coords, size, color, bobUpAndDown)
DrawMarker(
type,
coords.x, coords.y, coords.z,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
size.x, size.y, size.z,
color.r, color.g, color.b, color.a,
false, bobUpAndDown or false, 2, false, nil, nil, false
)
end