forked from Simnation/Main
werfen
This commit is contained in:
parent
453b281a4b
commit
46b895aff2
25 changed files with 716 additions and 0 deletions
Binary file not shown.
Binary file not shown.
2
resources/[tools]/pickle_throwables-1.0.1/README.md
Normal file
2
resources/[tools]/pickle_throwables-1.0.1/README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# pickle_throwables
|
||||||
|
A multi-framework and standalone throwing script, great for football, soccer and other sports.
|
Binary file not shown.
After Width: | Height: | Size: 145 KiB |
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
|
@ -0,0 +1,6 @@
|
||||||
|
INSERT INTO `items` (`name`, `label`, `limit`) VALUES
|
||||||
|
('football', 'Football', 100),
|
||||||
|
('basketball', 'Basketball', 100),
|
||||||
|
('baseball', 'Baseball', 100),
|
||||||
|
('soccer', 'Soccer Ball', 100),
|
||||||
|
;
|
|
@ -0,0 +1,6 @@
|
||||||
|
INSERT INTO `items` (`name`, `label`, `weight`) VALUES
|
||||||
|
('football', 'Football', 100),
|
||||||
|
('basketball', 'Basketball', 100),
|
||||||
|
('baseball', 'Baseball', 100),
|
||||||
|
('soccer', 'Soccer Ball', 100),
|
||||||
|
;
|
|
@ -0,0 +1,24 @@
|
||||||
|
["football"] = {
|
||||||
|
label = 'Football',
|
||||||
|
weight = 1,
|
||||||
|
stack = true,
|
||||||
|
description = ""
|
||||||
|
},
|
||||||
|
["basketball"] = {
|
||||||
|
label = 'Basketball',
|
||||||
|
weight = 1,
|
||||||
|
stack = true,
|
||||||
|
description = ""
|
||||||
|
},
|
||||||
|
["baseball"] = {
|
||||||
|
label = 'Baseball',
|
||||||
|
weight = 1,
|
||||||
|
stack = true,
|
||||||
|
description = ""
|
||||||
|
},
|
||||||
|
["soccer"] = {
|
||||||
|
label = 'Soccer Ball',
|
||||||
|
weight = 1,
|
||||||
|
stack = true,
|
||||||
|
description = ""
|
||||||
|
},
|
|
@ -0,0 +1,4 @@
|
||||||
|
["football"] = {["name"] = "football", ["label"] = "Football", ["weight"] = 1, ["type"] = "item", ["image"] = "football.png", ["unique"] = true, ["useable"] = true, ["shouldClose"] = true, ["combinable"] = nil, ["description"] = ""},
|
||||||
|
["basketball"] = {["name"] = "basketball", ["label"] = "Basketball", ["weight"] = 1, ["type"] = "item", ["image"] = "basketball.png", ["unique"] = true, ["useable"] = true, ["shouldClose"] = true, ["combinable"] = nil, ["description"] = ""},
|
||||||
|
["baseball"] = {["name"] = "baseball", ["label"] = "Baseball", ["weight"] = 1, ["type"] = "item", ["image"] = "baseball.png", ["unique"] = true, ["useable"] = true, ["shouldClose"] = true, ["combinable"] = nil, ["description"] = ""},
|
||||||
|
["soccer"] = {["name"] = "soccer", ["label"] = "Soccer Ball", ["weight"] = 1, ["type"] = "item", ["image"] = "soccer.png", ["unique"] = true, ["useable"] = true, ["shouldClose"] = true, ["combinable"] = nil, ["description"] = ""},
|
|
@ -0,0 +1,32 @@
|
||||||
|
if GetResourceState('es_extended') ~= 'started' then return end
|
||||||
|
|
||||||
|
ESX = exports.es_extended:getSharedObject()
|
||||||
|
|
||||||
|
function ShowNotification(text)
|
||||||
|
ESX.ShowNotification(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ShowHelpNotification(text)
|
||||||
|
ESX.ShowHelpNotification(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ServerCallback(name, cb, ...)
|
||||||
|
ESX.TriggerServerCallback(name, cb, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetPlayersInArea(coords, maxDistance)
|
||||||
|
return ESX.Game.GetPlayersInArea(coords, maxDistance)
|
||||||
|
end
|
||||||
|
|
||||||
|
function CanAccessGroup(data)
|
||||||
|
if not data then return true end
|
||||||
|
local pdata = ESX.GetPlayerData()
|
||||||
|
for k,v in pairs(data) do
|
||||||
|
if (pdata.job.name == k and pdata.job.grade >= v) then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
RegisterNetEvent(GetCurrentResourceName()..":showNotification", function(text)
|
||||||
|
ShowNotification(text)
|
||||||
|
end)
|
|
@ -0,0 +1,67 @@
|
||||||
|
if GetResourceState('es_extended') ~= 'started' then return end
|
||||||
|
|
||||||
|
ESX = exports.es_extended:getSharedObject()
|
||||||
|
|
||||||
|
function RegisterCallback(name, cb)
|
||||||
|
ESX.RegisterServerCallback(name, cb)
|
||||||
|
end
|
||||||
|
|
||||||
|
function RegisterUsableItem(...)
|
||||||
|
ESX.RegisterUsableItem(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ShowNotification(target, text)
|
||||||
|
TriggerClientEvent(GetCurrentResourceName()..":showNotification", target, text)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Search(source, name)
|
||||||
|
local xPlayer = ESX.GetPlayerFromId(source)
|
||||||
|
if (name == "money") then
|
||||||
|
return xPlayer.getMoney()
|
||||||
|
elseif (name == "bank") then
|
||||||
|
return xPlayer.getAccount('bank').money
|
||||||
|
else
|
||||||
|
local item = xPlayer.getInventoryItem(name)
|
||||||
|
if item ~= nil then
|
||||||
|
return item.count
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function AddItem(source, name, amount)
|
||||||
|
local xPlayer = ESX.GetPlayerFromId(source)
|
||||||
|
if (name == "money") then
|
||||||
|
return xPlayer.addMoney(amount)
|
||||||
|
elseif (name == "bank") then
|
||||||
|
return xPlayer.addAccountMoney('bank', amount)
|
||||||
|
else
|
||||||
|
return xPlayer.addInventoryItem(name, amount)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function RemoveItem(source, name, amount)
|
||||||
|
local xPlayer = ESX.GetPlayerFromId(source)
|
||||||
|
if (name == "money") then
|
||||||
|
return xPlayer.removeMoney(amount)
|
||||||
|
elseif (name == "bank") then
|
||||||
|
return xPlayer.removeAccountMoney('bank', amount)
|
||||||
|
else
|
||||||
|
return xPlayer.removeInventoryItem(name, amount)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CanAccessGroup(source, data)
|
||||||
|
if not data then return true end
|
||||||
|
local pdata = ESX.GetPlayerFromId(source)
|
||||||
|
for k,v in pairs(data) do
|
||||||
|
if (pdata.job.name == k and pdata.job.grade >= v) then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetIdentifier(source)
|
||||||
|
local xPlayer = ESX.GetPlayerFromId(source)
|
||||||
|
return xPlayer.identifier
|
||||||
|
end
|
|
@ -0,0 +1,34 @@
|
||||||
|
if GetResourceState('qb-core') ~= 'started' then return end
|
||||||
|
|
||||||
|
QBCore = exports['qb-core']:GetCoreObject()
|
||||||
|
|
||||||
|
function ServerCallback(name, cb, ...)
|
||||||
|
QBCore.Functions.TriggerCallback(name, cb, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ShowNotification(text)
|
||||||
|
QBCore.Functions.Notify(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ShowHelpNotification(text)
|
||||||
|
AddTextEntry('qbHelpNotification', text)
|
||||||
|
BeginTextCommandDisplayHelp('qbHelpNotification')
|
||||||
|
EndTextCommandDisplayHelp(0, false, false, -1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetPlayersInArea(coords, maxDistance)
|
||||||
|
return QBCore.Functions.GetPlayersFromCoords(coords, maxDistance)
|
||||||
|
end
|
||||||
|
|
||||||
|
function CanAccessGroup(data)
|
||||||
|
if not data then return true end
|
||||||
|
local pdata = QBCore.Functions.GetPlayerData()
|
||||||
|
for k,v in pairs(data) do
|
||||||
|
if (pdata.job.name == k and pdata.job.grade.level >= v) then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
RegisterNetEvent(GetCurrentResourceName()..":showNotification", function(text)
|
||||||
|
ShowNotification(text)
|
||||||
|
end)
|
|
@ -0,0 +1,67 @@
|
||||||
|
if GetResourceState('qb-core') ~= 'started' then return end
|
||||||
|
|
||||||
|
QBCore = exports['qb-core']:GetCoreObject()
|
||||||
|
|
||||||
|
function RegisterCallback(name, cb)
|
||||||
|
QBCore.Functions.CreateCallback(name, cb)
|
||||||
|
end
|
||||||
|
|
||||||
|
function RegisterUsableItem(...)
|
||||||
|
QBCore.Functions.CreateUseableItem(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ShowNotification(target, text)
|
||||||
|
TriggerClientEvent(GetCurrentResourceName()..":showNotification", target, text)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Search(source, name)
|
||||||
|
local xPlayer = QBCore.Functions.GetPlayer(source)
|
||||||
|
if (name == "money") then
|
||||||
|
return xPlayer.PlayerData.money['cash']
|
||||||
|
elseif (name == "bank") then
|
||||||
|
return xPlayer.PlayerData.money['cash'] -- If anyone knows how to get bank balance for QBCore, let me know.
|
||||||
|
else
|
||||||
|
local item = xPlayer.Functions.GetItemByName(name)
|
||||||
|
if item ~= nil then
|
||||||
|
return item.amount
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function AddItem(source, name, amount)
|
||||||
|
local xPlayer = QBCore.Functions.GetPlayer(source)
|
||||||
|
if (name == "money") then
|
||||||
|
return xPlayer.Functions.AddMoney("cash", amount)
|
||||||
|
elseif (name == "bank") then
|
||||||
|
return xPlayer.Functions.AddMoney("cash", amount) -- If anyone knows how to add to bank balance for QBCore, let me know.
|
||||||
|
else
|
||||||
|
return xPlayer.Functions.AddItem(name, amount)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function RemoveItem(source, name, amount)
|
||||||
|
local xPlayer = QBCore.Functions.GetPlayer(source)
|
||||||
|
if (name == "money") then
|
||||||
|
return xPlayer.Functions.RemoveMoney("cash", amount)
|
||||||
|
elseif (name == "bank") then
|
||||||
|
return xPlayer.Functions.RemoveMoney("cash", amount) -- If anyone knows how to remove from bank balance for QBCore, let me know.
|
||||||
|
else
|
||||||
|
return xPlayer.Functions.RemoveItem(name, amount)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CanAccessGroup(source, data)
|
||||||
|
if not data then return true end
|
||||||
|
local pdata = QBCore.Functions.GetPlayer(source).PlayerData
|
||||||
|
for k,v in pairs(data) do
|
||||||
|
if (pdata.job.name == k and pdata.job.grade.level >= v) then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function GetIdentifier(source)
|
||||||
|
local xPlayer = QBCore.Functions.GetPlayer(source).PlayerData
|
||||||
|
return xPlayer.citizenid
|
||||||
|
end
|
|
@ -0,0 +1,4 @@
|
||||||
|
if GetResourceState('es_extended') == 'started' then return end
|
||||||
|
if GetResourceState('qb-core') == 'started' then return end
|
||||||
|
|
||||||
|
print("You are not using a supported framework, it will be required to make edits to the bridge files.")
|
|
@ -0,0 +1,4 @@
|
||||||
|
if GetResourceState('es_extended') == 'started' then return end
|
||||||
|
if GetResourceState('qb-core') == 'started' then return end
|
||||||
|
|
||||||
|
print("You are not using a supported framework, it will be required to make edits to the bridge files.")
|
41
resources/[tools]/pickle_throwables-1.0.1/config.lua
Normal file
41
resources/[tools]/pickle_throwables-1.0.1/config.lua
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
Config = {}
|
||||||
|
|
||||||
|
Config.Debug = true
|
||||||
|
|
||||||
|
Config.Language = "en"
|
||||||
|
|
||||||
|
Config.RenderDistance = 20.0
|
||||||
|
Config.CatchRadius = 2.5
|
||||||
|
|
||||||
|
Config.CommandSpawning = false -- Set this to true if you want to be able to get throwables without using items.
|
||||||
|
|
||||||
|
Config.CommandSpawnCheck = function()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
Config.Throwables = {
|
||||||
|
["football"] = {
|
||||||
|
item = "football",
|
||||||
|
entityType = "object", -- "object", "vehicle", "ped"
|
||||||
|
model = `p_ld_am_ball_01`,
|
||||||
|
maxThrowingPower = 200
|
||||||
|
},
|
||||||
|
["basketball"] = {
|
||||||
|
item = "basketball",
|
||||||
|
entityType = "object", -- "object", "vehicle", "ped"
|
||||||
|
model = `prop_bskball_01`,
|
||||||
|
maxThrowingPower = 200
|
||||||
|
},
|
||||||
|
["baseball"] = {
|
||||||
|
item = "baseball",
|
||||||
|
entityType = "object", -- "object", "vehicle", "ped"
|
||||||
|
model = `w_am_baseball`,
|
||||||
|
maxThrowingPower = 200
|
||||||
|
},
|
||||||
|
["soccer"] = {
|
||||||
|
item = "soccer",
|
||||||
|
entityType = "object", -- "object", "vehicle", "ped"
|
||||||
|
model = `p_ld_soc_ball_01`,
|
||||||
|
maxThrowingPower = 200
|
||||||
|
},
|
||||||
|
}
|
70
resources/[tools]/pickle_throwables-1.0.1/core/client.lua
Normal file
70
resources/[tools]/pickle_throwables-1.0.1/core/client.lua
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
function ModelRequest(modelHash)
|
||||||
|
if not IsModelInCdimage(modelHash) then return end
|
||||||
|
RequestModel(modelHash)
|
||||||
|
local loaded
|
||||||
|
for i=1, 100 do
|
||||||
|
if HasModelLoaded(modelHash) then
|
||||||
|
loaded = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
Wait(100)
|
||||||
|
end
|
||||||
|
return loaded
|
||||||
|
end
|
||||||
|
|
||||||
|
function CreateVeh(modelHash, ...)
|
||||||
|
if not ModelRequest(modelHash) then
|
||||||
|
print("Couldn't load model: " .. modelHash)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local veh = CreateVehicle(modelHash, ...)
|
||||||
|
SetModelAsNoLongerNeeded(modelHash)
|
||||||
|
return veh
|
||||||
|
end
|
||||||
|
|
||||||
|
function CreateNPC(modelHash, ...)
|
||||||
|
if not ModelRequest(modelHash) then
|
||||||
|
print("Couldn't load model: " .. modelHash)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ped = CreatePed(26, modelHash, ...)
|
||||||
|
SetModelAsNoLongerNeeded(modelHash)
|
||||||
|
return ped
|
||||||
|
end
|
||||||
|
|
||||||
|
function CreateProp(modelHash, ...)
|
||||||
|
if not ModelRequest(modelHash) then
|
||||||
|
print("Couldn't load model: " .. modelHash)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local obj = CreateObject(modelHash, ...)
|
||||||
|
SetModelAsNoLongerNeeded(modelHash)
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
function PlayAnim(ped, dict, ...)
|
||||||
|
RequestAnimDict(dict)
|
||||||
|
while not HasAnimDictLoaded(dict) do Wait(0) end
|
||||||
|
TaskPlayAnim(ped, dict, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local interactTick = 0
|
||||||
|
local interactThread = false
|
||||||
|
local interactText = nil
|
||||||
|
|
||||||
|
function ShowInteractText(text)
|
||||||
|
interactTick = GetGameTimer()
|
||||||
|
lib.showTextUI(text)
|
||||||
|
if interactThread then return end
|
||||||
|
interactThread = true
|
||||||
|
CreateThread(function()
|
||||||
|
while interactThread do
|
||||||
|
if GetGameTimer() - interactTick > 20 then
|
||||||
|
interactThread = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
Citizen.Wait(150)
|
||||||
|
end
|
||||||
|
lib.hideTextUI()
|
||||||
|
end)
|
||||||
|
end
|
10
resources/[tools]/pickle_throwables-1.0.1/core/shared.lua
Normal file
10
resources/[tools]/pickle_throwables-1.0.1/core/shared.lua
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
function v3(coords) return vec3(coords.x, coords.y, coords.z), coords.w end
|
||||||
|
|
||||||
|
function GetRandomInt(min, max, exclude)
|
||||||
|
for i=1, 1000 do
|
||||||
|
local int = math.random(min, max)
|
||||||
|
if exclude == nil or exclude ~= int then
|
||||||
|
return int
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
28
resources/[tools]/pickle_throwables-1.0.1/fxmanifest.lua
Normal file
28
resources/[tools]/pickle_throwables-1.0.1/fxmanifest.lua
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
fx_version 'cerulean'
|
||||||
|
lua54 'yes'
|
||||||
|
game 'gta5'
|
||||||
|
|
||||||
|
name 'pickle_throwables'
|
||||||
|
version '1.0.0'
|
||||||
|
description 'A multi-framework and standalone throwing script, great for football, soccer and other sports.'
|
||||||
|
author 'Pickle Mods'
|
||||||
|
|
||||||
|
shared_scripts {
|
||||||
|
'@ox_lib/init.lua',
|
||||||
|
'config.lua',
|
||||||
|
'core/shared.lua',
|
||||||
|
"locales/locale.lua",
|
||||||
|
"locales/translations/*.lua",
|
||||||
|
'modules/**/shared.lua',
|
||||||
|
}
|
||||||
|
|
||||||
|
server_scripts {
|
||||||
|
'bridge/**/server.lua',
|
||||||
|
'modules/**/server.lua',
|
||||||
|
}
|
||||||
|
|
||||||
|
client_scripts {
|
||||||
|
'core/client.lua',
|
||||||
|
'bridge/**/client.lua',
|
||||||
|
'modules/**/client.lua',
|
||||||
|
}
|
14
resources/[tools]/pickle_throwables-1.0.1/locales/locale.lua
Normal file
14
resources/[tools]/pickle_throwables-1.0.1/locales/locale.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
Language = {}
|
||||||
|
|
||||||
|
function _L(name, ...)
|
||||||
|
if name then
|
||||||
|
local str = Language[Config.Language][name]
|
||||||
|
if str then
|
||||||
|
return string.format(str, ...)
|
||||||
|
else
|
||||||
|
return "ERR_TRANSLATE_"..(name).."_404"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return "ERR_TRANSLATE_404"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
Language["en"] = {
|
||||||
|
throwable_interact = "[E] - Take Object \n [G] - Kick \n Power: %s",
|
||||||
|
throwable_list = "[E] - Throw \n [G] - Drop \n [H] - Handoff \n Power: %s",
|
||||||
|
throwable_list_alt = "[E] - Throw \n [G] - Drop \n [H] - Inventory \n Power: %s",
|
||||||
|
}
|
|
@ -0,0 +1,225 @@
|
||||||
|
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)
|
|
@ -0,0 +1,73 @@
|
||||||
|
local Throwables = {}
|
||||||
|
local Carrying = {}
|
||||||
|
|
||||||
|
function GiveObject(source, data, timeout)
|
||||||
|
Carrying[source] = data
|
||||||
|
if timeout then
|
||||||
|
SetTimeout(1600, function()
|
||||||
|
TriggerClientEvent("pickle_throwables:giveObject", source, data)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
TriggerClientEvent("pickle_throwables:giveObject", source, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RegisterNetEvent("pickle_throwables:throwObject", function(data)
|
||||||
|
local source = source
|
||||||
|
if not Carrying[source] then return end
|
||||||
|
Carrying[source] = nil
|
||||||
|
local throwID = nil
|
||||||
|
repeat
|
||||||
|
throwID = os.time() .. "_" .. math.random(1000, 9999)
|
||||||
|
until not Throwables[throwID]
|
||||||
|
Throwables[throwID] = data
|
||||||
|
TriggerClientEvent("pickle_throwables:setObjectData", -1, throwID, data)
|
||||||
|
end)
|
||||||
|
|
||||||
|
RegisterCallback("pickle_throwables:catchObject", function(source, cb, throwID)
|
||||||
|
if Carrying[source] then return cb(false) end
|
||||||
|
if not Throwables[throwID] then return cb(false) end
|
||||||
|
local entity = NetworkGetEntityFromNetworkId(Throwables[throwID].net_id)
|
||||||
|
Carrying[source] = {throwType = Throwables[throwID].throwType}
|
||||||
|
DeleteEntity(entity)
|
||||||
|
Throwables[throwID] = nil
|
||||||
|
TriggerClientEvent("pickle_throwables:setObjectData", -1, throwID, nil)
|
||||||
|
cb(true)
|
||||||
|
end)
|
||||||
|
|
||||||
|
RegisterCallback("pickle_throwables:storeObject", function(source, cb)
|
||||||
|
if not Carrying[source] then return cb(false) end
|
||||||
|
local data = Carrying[source]
|
||||||
|
local cfg = Config.Throwables[data.throwType]
|
||||||
|
Carrying[source] = nil
|
||||||
|
if cfg.item and not Config.CommandSpawning then
|
||||||
|
AddItem(source, cfg.item, 1)
|
||||||
|
end
|
||||||
|
cb(true)
|
||||||
|
end)
|
||||||
|
|
||||||
|
RegisterCallback("pickle_throwables:giveObject", function(source, cb, target)
|
||||||
|
if not Carrying[source] or Carrying[target] then return cb(false) end
|
||||||
|
local data = Carrying[source]
|
||||||
|
GiveObject(target, {throwType = data.throwType}, true)
|
||||||
|
Carrying[source] = nil
|
||||||
|
cb(true)
|
||||||
|
end)
|
||||||
|
|
||||||
|
if Config.CommandSpawning then
|
||||||
|
RegisterCommand("spawnthrowable", function(source, args, raw)
|
||||||
|
if not args[1] or not Config.Throwables[args[1]] then return end
|
||||||
|
if not Config.CommandSpawnCheck(source, args[1]) then return end
|
||||||
|
GiveObject(source, {throwType = args[1]})
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
for k,v in pairs(Config.Throwables) do
|
||||||
|
if v.item then
|
||||||
|
RegisterUsableItem(v.item, function(source)
|
||||||
|
if Carrying[source] then return end
|
||||||
|
RemoveItem(source, v.item, 1)
|
||||||
|
GiveObject(source, {throwType = k})
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue