local ThrowingPower = 1 local Throwables = {} local canInteract = true local attemptingCatch = false local holdingBall = nil function GetClosestPlayer(coords, radius) local closest local coords = coords or GetEntityCoords(PlayerPedId()) local radius = radius or 2.0 for _, player in ipairs(GetActivePlayers()) do local ped = GetPlayerPed(player) if PlayerPedId() ~= ped then local pedCoords = GetEntityCoords(ped) local distance = #(coords - pedCoords) if distance < radius and (not closest or closest.distance > distance) then closest = {player = player, distance = distance} end end end return closest?.player, closest?.distance end function GetDirectionFromRotation(rotation) local dm = (math.pi / 180) return vector3(-math.sin(dm * rotation.z) * math.abs(math.cos(dm * rotation.x)), math.cos(dm * rotation.z) * math.abs(math.cos(dm * rotation.x)), math.sin(dm * rotation.x)) end function PerformPhysics(throwType, entity, action) local cfg = Config.Throwables[throwType] local power = (ThrowingPower / 10) * cfg.maxThrowingPower FreezeEntityPosition(entity, false) local rot = GetGameplayCamRot(2) local dir = GetDirectionFromRotation(rot) SetEntityHeading(entity, rot.z + 90.0) if not action or action == "throw" then SetEntityVelocity(entity, dir.x * power, dir.y * power, dir.z * power) else SetEntityVelocity(entity, dir.x * power, dir.y * power, (dir.z * 1.75) * power) end end function CreateThrowable(throwType, attach) local cfg = Config.Throwables[throwType] local ped = PlayerPedId() local model = cfg.model local heading = GetEntityHeading(ped) local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 1.0, 0.5) local prop if cfg.entityType == "object" then prop = CreateProp(model, coords.x, coords.y, coords.z, true, true, true) elseif cfg.entityType == "vehicle" then prop = CreateVeh(model, coords.x, coords.y, coords.z, true, true, true) elseif cfg.entityType == "ped" then prop = CreateNPC(model, coords.x, coords.y, coords.z, true, true, true) end if not prop then return end if attach then local off, rot = vector3(0.05, 0.0, -0.085), vector3(90.0, 90.0, 0.0) AttachEntityToEntity(prop, ped, GetPedBoneIndex(ped, 28422), off.x, off.y, off.z, rot.x, rot.y, rot.z, false, false, false, true, 2, true) else local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 1.0, -0.9) SetEntityCoords(prop, coords.x, coords.y, coords.z) end return prop end function HoldThrowable(throwType) local ped = PlayerPedId() if holdingBall then return end local prop = CreateThrowable(throwType, true) holdingBall = prop CreateThread(function() while holdingBall do local player, dist = GetClosestPlayer() if player then ShowInteractText(_L("throwable_list", ThrowingPower .. "/" .. 10)) else ShowInteractText(_L("throwable_list_alt", ThrowingPower .. "/" .. 10)) end if IsControlJustPressed(1, 51) then CreateThread(function() PlayAnim(ped, "melee@thrown@streamed_core", "plyr_takedown_front", -8.0, 8.0, -1, 49) Wait(600) ClearPedTasks(ped) end) Wait(550) DetachEntity(prop, false, true) SetEntityCollision(prop, true, true) SetEntityRecordsCollisions(prop, true) TriggerServerEvent("pickle_throwables:throwObject", {throwType = throwType, net_id = ObjToNet(prop)}) local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.0, 1.0) SetEntityCoords(prop, coords.x, coords.y, coords.z) SetEntityHeading(prop, GetEntityHeading(ped) + 90.0) PerformPhysics(throwType, prop) holdingBall = nil elseif IsControlJustPressed(1, 47) then PlayAnim(ped, "pickup_object", "pickup_low", -8.0, 8.0, -1, 49, 1.0) Wait(800) DetachEntity(prop, true, true) SetEntityCollision(prop, true, true) SetEntityRecordsCollisions(prop, true) ActivatePhysics(prop) TriggerServerEvent("pickle_throwables:throwObject", {throwType = throwType, net_id = ObjToNet(prop)}) Wait(800) ClearPedTasks(ped) holdingBall = nil elseif IsControlJustPressed(1, 74) then if player then ServerCallback("pickle_throwables:giveObject", function(result) if not result then return end DeleteEntity(prop) holdingBall = nil PlayAnim(PlayerPedId(), "mp_common", "givetake1_b", -8.0, 8.0, -1, 49, 1.0) Wait(1600) ClearPedTasks(ped) end, GetPlayerServerId(player)) else ServerCallback("pickle_throwables:storeObject", function(result) if not result then return end PlayAnim(PlayerPedId(), "pickup_object", "putdown_low", -8.0, 8.0, -1, 49, 1.0) Wait(1600) ClearPedTasks(ped) DeleteEntity(prop) holdingBall = nil end) end end PowerControls() Wait(0) end end) end function CatchObject(index, cb) if attemptingCatch then return end attemptingCatch = true local data = Throwables[index] local entity = NetToObj(data.net_id) SetEntityCollision(entity, false, false) DeleteEntity(entity) ServerCallback("pickle_throwables:catchObject", cb, index) Wait(100) attemptingCatch = false end function PowerControls() if IsControlJustPressed(1, 181) then ThrowingPower = (ThrowingPower + 1 > 10 and 10 or ThrowingPower + 1) elseif IsControlJustPressed(1, 180) then ThrowingPower = (ThrowingPower - 1 < 1 and 1 or ThrowingPower - 1) end end function 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[deepcopy(orig_key)] = deepcopy(orig_value) end setmetatable(copy, deepcopy(getmetatable(orig))) else -- number, string, boolean, etc copy = orig end return copy end CreateThread(function() while true do local wait = 1000 local ped = PlayerPedId() local throwables = deepcopy(Throwables) for k,v in pairs(throwables) do if NetworkDoesNetworkIdExist(v.net_id) then local entity = NetToObj(v.net_id) local dist = #(GetEntityCoords(ped) - GetEntityCoords(entity)) if dist < Config.RenderDistance then wait = 0 if not holdingBall and canInteract and dist < Config.CatchRadius and not ShowInteractText(_L("throwable_interact", ThrowingPower .. "/" .. 10)) then if IsControlJustPressed(1, 51) then CatchObject(k, function(result) if not result then return end HoldThrowable(v.throwType) end) elseif IsControlJustPressed(1, 47) then CatchObject(k, function(result) if not result then return end canInteract = false local prop = CreateThrowable(v.throwType, false) TriggerServerEvent("pickle_throwables:throwObject", {throwType = v.throwType, net_id = ObjToNet(prop)}) --FreezeEntityPosition(ped, true) --PlayAnim(ped, "melee@unarmed@streamed_core", "ground_attack_0", -8.0, 8.0, -1, 33, 1.0) --Wait(1000) PerformPhysics(v.throwType, prop, "kick") --Wait(600) --ClearPedTasks(ped) --FreezeEntityPosition(ped, false) canInteract = true end) end PowerControls() end end end end Wait(wait) end end) RegisterNetEvent("pickle_throwables:giveObject", function(data) HoldThrowable(data.throwType) end) RegisterNetEvent("pickle_throwables:setObjectData", function(throwID, data) Throwables[throwID] = data end) AddEventHandler("onResourceStop", function(name) if (GetCurrentResourceName() ~= name) then return end for k,v in pairs(Throwables) do DeleteEntity(NetToObj(v.net_id)) end end)