mirror of
https://github.com/jimathy/jim_bridge.git
synced 2026-08-17 05:56:02 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5af0334d5 |
@@ -21,12 +21,12 @@ This module provides access and control over player metadata, which is useful fo
|
||||
print("Player stress level:", stress)
|
||||
```
|
||||
|
||||
- **setPlayerMetadata(player, key, value)**
|
||||
- **SetMetadata(player, key, value)**
|
||||
|
||||
⚠️ Server side only
|
||||
- Updates or assigns a value to a specific metadata key for a player.
|
||||
- The function updates the player's metadata using the active core export.
|
||||
- **Example:**
|
||||
```lua
|
||||
setPlayerMetadata(player, "stress", 0)
|
||||
SetMetadata(player, "stress", 0)
|
||||
```
|
||||
@@ -49,19 +49,17 @@ end
|
||||
|
||||
local function endTimer(label)
|
||||
timers[label] = GetGameTimer() - (timers[label] or GetGameTimer())
|
||||
timers[label] = "("..(timers[label] / 1000).."s)"
|
||||
timers[label] = timers[label] / 1000
|
||||
end
|
||||
startTimer("Cache") startTimer("Items") startTimer("Vehicles") startTimer("Jobs") startTimer("InvWeight") startTimer("InvSlots")
|
||||
startTimer("Cache")
|
||||
-- Helper function to check if resource exists in server (instead of if it is already started)
|
||||
local function checkExists(resourceName)
|
||||
return GetResourceState(resourceName):find("start") or GetResourceState(resourceName):find("stopped")
|
||||
end
|
||||
|
||||
-- Ensure oxmysql resource is loaded
|
||||
if checkExists(Exports.OXCoreExport) or checkExists(Exports.ESXExport) then
|
||||
local fileLoader = assert(load(LoadResourceFile("oxmysql", ('lib/MySQL.lua')), ('@@oxmysql/lib/MySQL.lua')))
|
||||
fileLoader()
|
||||
end
|
||||
local fileLoader = assert(load(LoadResourceFile("oxmysql", ('lib/MySQL.lua')), ('@@oxmysql/lib/MySQL.lua')))
|
||||
fileLoader()
|
||||
|
||||
if checkExists(Exports.OXCoreExport) then
|
||||
-- Detected OX_Core in server, wait for it to be started if needed
|
||||
@@ -90,6 +88,7 @@ end
|
||||
---- Load Items -----
|
||||
---------------------
|
||||
-- Items initialization based on detected inventory system
|
||||
startTimer("Items")
|
||||
if checkExists(Exports.OXInv) then
|
||||
-- Wait for OX Inventory to start if it's not already started
|
||||
while GetResourceState(Exports.OXInv) ~= "started" do Wait(100) end
|
||||
@@ -172,6 +171,7 @@ endTimer("Items")
|
||||
---------------------
|
||||
--- Load Vehicles ---
|
||||
---------------------
|
||||
startTimer("Vehicles")
|
||||
-- Vehicle loading depending on framework
|
||||
if checkExists(Exports.QBXExport) then
|
||||
vehResource = Exports.QBXExport
|
||||
@@ -215,6 +215,7 @@ endTimer("Vehicles")
|
||||
---------------------
|
||||
----- Load Jobs -----
|
||||
---------------------
|
||||
startTimer("Jobs")
|
||||
-- Jobs loading based on framework
|
||||
if checkExists(Exports.QBXExport) then
|
||||
jobResource = Exports.QBXExport
|
||||
@@ -307,6 +308,8 @@ end
|
||||
-- Forcefully load the the specified config file from inventory scripts
|
||||
-- This allows to get information required for certain functions that need to detect how much space is left in a players inventory
|
||||
-- This is born from too many tickets of me needing to explain that they need to change "InventoryWeight" to match their inv setting
|
||||
startTimer("InvWeight")
|
||||
startTimer("InvSlots")
|
||||
local function getInventoryConfig(resource, data)
|
||||
if data.convars then
|
||||
return function(path)
|
||||
@@ -320,19 +323,12 @@ local function getInventoryConfig(resource, data)
|
||||
if not content then return nil, "Failed to load file" end
|
||||
|
||||
local env = {
|
||||
GetConvar = GetConvar,
|
||||
vector3 = vector3,
|
||||
vector4 = vector4,
|
||||
Citizen = Citizen,
|
||||
GetResourceState = GetResourceState,
|
||||
exports = exports,
|
||||
DependencyCheck = function() return nil end,
|
||||
GetConvar = GetConvar, vector3 = vector3, Citizen = Citizen,
|
||||
GetResourceState = GetResourceState, exports = exports,
|
||||
DependencyCheck = DependencyCheck or function() return nil end,
|
||||
}
|
||||
|
||||
local fn, err = load(content, '@'..data.file, 't', env)
|
||||
--local success, err = xpcall(fn, function(e)
|
||||
-- print(debug.traceback("Error while executing qs-inventory config:\n" .. tostring(e), 2))
|
||||
--end)
|
||||
if not fn then return nil, "Failed to compile config: " .. err end
|
||||
if not pcall(fn) then return nil, "Error executing config file" end
|
||||
|
||||
@@ -376,7 +372,6 @@ for script, data in pairs(invWeightTable) do
|
||||
if checkExists(script) then
|
||||
if script == Exports.QBInv and GetResourceState(Exports.JPRInv):find("start") then goto skip end
|
||||
|
||||
while GetResourceState(script) ~= "started" do Wait(100) print("Waiting for script start") end
|
||||
local attempts = data.fallback or { data }
|
||||
local lookup, used, err
|
||||
|
||||
@@ -424,17 +419,17 @@ CreateThread(function()
|
||||
if type(v) ~= "number" then for count in pairs(v) do counts[k] += 1 end end
|
||||
end
|
||||
if cache.InventoryWeight then
|
||||
print("^6FrameWorkCache^7: ^4"..invResource.."^2 InventoryWeight^7: ^3"..cache.InventoryWeight.."^7 (^3"..(cache.InventoryWeight / 1000).."kg^7) ^7"..timers["InvWeight"])
|
||||
print("^6FrameWorkCache^7: ^4"..invResource.."^2 InventoryWeight^7: ^3"..cache.InventoryWeight.."^7 (^3"..(cache.InventoryWeight / 1000).."kg^7) ^7("..timers["InvWeight"].."s)")
|
||||
end
|
||||
if cache.InventorySlots then
|
||||
print("^6FrameWorkCache^7: ^4"..invResource.."^2 InventorySlots^7: ^3"..cache.InventorySlots.." ^7"..timers["InvSlots"])
|
||||
print("^6FrameWorkCache^7: ^4"..invResource.."^2 InventorySlots^7: ^3"..cache.InventorySlots.." ^7("..timers["InvSlots"].."s)")
|
||||
end
|
||||
print("^6FrameworkCache^7: ^4"..itemResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Items).."^2 Items ^7"..timers["Items"])
|
||||
print("^6FrameworkCache^7: ^4"..vehResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Vehicles).."^2 Vehicles ^7"..timers["Vehicles"])
|
||||
print("^6FrameworkCache^7: ^4"..jobResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Jobs).."^2 Jobs ^7"..timers["Jobs"])
|
||||
print("^6FrameworkCache^7: ^4"..jobResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Gangs).."^2 Gangs ^7"..timers["Jobs"])
|
||||
print("^6FrameworkCache^7: ^4"..itemResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Items).."^2 Items ^7("..timers["Items"].."s)")
|
||||
print("^6FrameworkCache^7: ^4"..vehResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Vehicles).."^2 Vehicles ^7("..timers["Vehicles"].."s)")
|
||||
print("^6FrameworkCache^7: ^4"..jobResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Jobs).."^2 Jobs ^7("..timers["Jobs"].."s)")
|
||||
print("^6FrameworkCache^7: ^4"..jobResource:gsub("-", "^7-^4"):gsub("_", "^7_^4").."^2 Loaded ^3"..tostring(counts.Gangs).."^2 Gangs ^7("..timers["Jobs"].."s)")
|
||||
endTimer("Cache")
|
||||
print("^6FrameworkCache^7: ^2Cache Ready ^7"..timers["Cache"])
|
||||
print("^6FrameworkCache^7: ^2Cache Ready ^7("..timers["Cache"].."s)")
|
||||
cacheReady = true
|
||||
end)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name "Jim_Bridge"
|
||||
author "Jimathy"
|
||||
version "2.0.21"
|
||||
version "2.0.20"
|
||||
description "Framework Bridge By Jimathy"
|
||||
fx_version "cerulean"
|
||||
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'
|
||||
|
||||
@@ -53,13 +53,13 @@ if isServer() then
|
||||
|
||||
if authCooldown[src] then
|
||||
debugPrint("^1Auth^7: ^3Cooldown active^7 for Player ^1"..src.."^7, ignoring additional auth request")
|
||||
return AuthEvent
|
||||
return ""
|
||||
end
|
||||
|
||||
debugPrint("^1Auth^7: ^2Player Source^7: "..src.." ^2requested ^3AuthEvent^7", AuthEvent)
|
||||
|
||||
authCooldown[src] = true
|
||||
SetTimeout(60000, function() -- 1 minute cooldown
|
||||
SetTimeout(5000, function() -- 5 second cooldown
|
||||
authCooldown[src] = nil
|
||||
end)
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ function onResourceStart(func, thisScript)
|
||||
debugPrint("^6Bridge^7: ^2Shared Load Detected^7.")
|
||||
hasPrinted = true
|
||||
end
|
||||
if isStarted(ESXExport) then Wait(10000) end
|
||||
func()
|
||||
end
|
||||
end
|
||||
@@ -193,13 +194,14 @@ end
|
||||
|
||||
local messageShown = false
|
||||
function waitForSharedLoad()
|
||||
local timeout = GetGameTimer() + 900000 -- 15 minutes max wait (had to up this from 2 minutes because of slow servers)
|
||||
local timeout = 100000 -- 10 seconds in milliseconds
|
||||
local startTime = GetGameTimer()
|
||||
local loaded = true
|
||||
local loop = 0
|
||||
|
||||
while ((not Jobs or not next(Jobs)) or
|
||||
(not Items or not next(Items)) or
|
||||
(not Vehicles or not next(Vehicles))
|
||||
) and (timeout and GetGameTimer() < timeout) do
|
||||
) and ((GetGameTimer() - startTime) < timeout) do
|
||||
if loop >= 3 and not messageShown then
|
||||
if (not Jobs or not next(Jobs)) then
|
||||
print("^4Debug^7: ^2Waiting for ^7Jobs^2 to be loaded")
|
||||
@@ -212,16 +214,19 @@ function waitForSharedLoad()
|
||||
end
|
||||
messageShown = true
|
||||
end
|
||||
--print((GetGameTimer() - startTime) < timeout)
|
||||
Wait(1000)
|
||||
|
||||
if Jobs and Items and Vehicles then
|
||||
--print("^6Bridge^7: ^2Jobs, Items, and Vehicles Loaded^7.")
|
||||
loaded = true
|
||||
break
|
||||
end
|
||||
loop += 1
|
||||
end
|
||||
|
||||
if Jobs and Items and Vehicles then
|
||||
debugPrint("^6Bridge^7: ^2Jobs, Items, and Vehicles Loaded^7.")
|
||||
return true
|
||||
else
|
||||
if not loaded then
|
||||
print("^4Error^7: ^1Timeout reached while waiting for shared load^7.")
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -34,10 +34,10 @@ end
|
||||
|
||||
if IsDuplicityVersion() then
|
||||
local cache = nil
|
||||
local timeout = GetGameTimer() + 900000 -- 15 minutes max wait (had to up this from 2 minutes because of slow servers)
|
||||
local timeout = GetGameTimer() + 120000 -- 2 minutes max wait (had to up this from 5 seconds because of slow servers)
|
||||
|
||||
-- Wait until jim_bridge is started and export is available
|
||||
while not cache and (timeout and GetGameTimer() < timeout) do
|
||||
while not cache and GetGameTimer() < timeout do
|
||||
if GetResourceState("jim_bridge"):find("start") then
|
||||
local success, result = pcall(function()
|
||||
return exports["jim_bridge"]:GetSharedData()
|
||||
@@ -49,7 +49,7 @@ if IsDuplicityVersion() then
|
||||
Wait(100)
|
||||
end
|
||||
|
||||
if timeout and not cache then
|
||||
if not cache then
|
||||
print("^1ERROR^7: ^2jim_bridge export not available after timeout^7.")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -89,7 +89,7 @@ function craftingMenu(data)
|
||||
-- Check if the player can carry the required items (server callback).
|
||||
local canCarryTable = triggerCallback(getScript()..':server:canCarry', tempCarryTable)
|
||||
|
||||
local usingStash = data.stashName ~= nil and data.stashName ~= ""
|
||||
local usingStash = data.stashName ~= nil
|
||||
|
||||
Menu[#Menu+1] = {
|
||||
icon = usingStash and "fas fa-boxes-stacked" or "fas fa-person",
|
||||
@@ -320,6 +320,8 @@ end
|
||||
--- })
|
||||
--- ```
|
||||
|
||||
Config.Crafting.SingleProgress = true -- Set false to use individual progress bars per craft
|
||||
|
||||
function makeItem(data)
|
||||
if CraftLock then return end
|
||||
CraftLock = true
|
||||
@@ -411,11 +413,11 @@ function makeItem(data)
|
||||
-- handle metadata and experience in a single go
|
||||
if data.craft["hasCrafted"] ~= nil then
|
||||
data.craftable.craftedItems[data.item] = true
|
||||
triggerCallback(getScript()..":server:setPlayerMetadata", "craftedItems", data.craftable.craftedItems)
|
||||
triggerCallback(getScript()..":server:SetMetadata", "craftedItems", data.craftable.craftedItems)
|
||||
end
|
||||
if data.craft["exp"] ~= nil then
|
||||
craftingLevel += data.craft["exp"].give * craftAmount
|
||||
triggerCallback(getScript()..":server:setPlayerMetadata", "craftingLevel", craftingLevel)
|
||||
triggerCallback(getScript()..":server:SetMetadata", "craftingLevel", craftingLevel)
|
||||
end
|
||||
if data.craftable.Recipes[1].oneUse == true then
|
||||
removeItem("craftrecipe", 1, nil, data.craftable.Recipes[1].slot)
|
||||
@@ -448,11 +450,11 @@ function makeItem(data)
|
||||
currentToken = nil
|
||||
if data.craft["hasCrafted"] ~= nil then
|
||||
data.craftable.craftedItems[data.item] = true
|
||||
triggerCallback(getScript()..":server:setPlayerMetadata", "craftedItems", data.craftable.craftedItems)
|
||||
triggerCallback(getScript()..":server:SetMetadata", "craftedItems", data.craftable.craftedItems)
|
||||
end
|
||||
if data.craft["exp"] ~= nil then
|
||||
craftingLevel += data.craft["exp"].give
|
||||
triggerCallback(getScript()..":server:setPlayerMetadata", "craftingLevel", craftingLevel)
|
||||
triggerCallback(getScript()..":server:SetMetadata", "craftingLevel", craftingLevel)
|
||||
end
|
||||
if data.craftable.Recipes[1].oneUse == true then
|
||||
removeItem("craftrecipe", 1, nil, data.craftable.Recipes[1].slot)
|
||||
|
||||
@@ -376,73 +376,130 @@ end
|
||||
--- ```lua
|
||||
--- breakTool({ item = "drill", damage = 10 })
|
||||
--- ```
|
||||
function breakTool(data)
|
||||
local metadata, slot = getItemMetadata(data.item)
|
||||
metadata = metadata or {}
|
||||
if not metadata.durability then metadata.durability = 100 end
|
||||
metadata.durability -= data.damage
|
||||
if metadata.durability <= 0 then
|
||||
removeItem(data.item, 1, nil, slot)
|
||||
function breakTool(data) -- WIP
|
||||
local durability, slot = getDurability(data.item)
|
||||
if not durability then durability = 100 end
|
||||
durability -= data.damage
|
||||
if durability <= 0 then
|
||||
removeItem(data.item, 1)
|
||||
local breakId = GetSoundId()
|
||||
PlaySoundFromEntity(breakId, "Drill_Pin_Break", PlayerPedId(), "DLC_HEIST_FLEECA_SOUNDSET", 1, 0)
|
||||
else
|
||||
TriggerServerEvent(getScript()..":server:setItemMetaData", { item = data.item, slot = slot, metadata = metadata })
|
||||
TriggerServerEvent(getScript()..":server:setMetaData", { item = data.item, slot = slot, metadata = { durability = durability } })
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Reduces the uses of a tool by a specified damage amount.
|
||||
--- Retrieves the durability and slot number of an item in a player's inventory.
|
||||
---
|
||||
--- If uses reaches zero or below, the tool is removed and a break sound is played.
|
||||
--- Searches through the player's inventory for the specified item.
|
||||
---
|
||||
--- @param data table Contains:
|
||||
--- - item (string): The tool's name.
|
||||
--- - damage (number): The damage % to apply.
|
||||
--- @param item string The item name.
|
||||
--- @return number|nil number The durability, or nil if not found.
|
||||
--- @return number|nil number The slot number, or nil if not found.
|
||||
---
|
||||
--- @usage
|
||||
--- ```lua
|
||||
--- useToolDegrade({ item = "drill", maxUse = 10 })
|
||||
--- local durability, slot = getDurability("drill")
|
||||
--- if durability then
|
||||
--- print("Durability:", durability)
|
||||
--- print("Slot:", slot)
|
||||
--- end
|
||||
--- ```
|
||||
function useToolDegrade(data) -- WIP
|
||||
local metadata, slot = getItemMetadata(data.item)
|
||||
metadata = metadata or {}
|
||||
if not metadata["Uses Left"] then metadata["Uses Left"] = data.maxUse end
|
||||
metadata["Uses Left"] -= 1
|
||||
if metadata["Uses Left"] <= 0 then
|
||||
removeItem(data.item, 1, nil, slot)
|
||||
local breakId = GetSoundId()
|
||||
PlaySoundFromEntity(breakId, "Drill_Pin_Break", PlayerPedId(), "DLC_HEIST_FLEECA_SOUNDSET", 1, 0)
|
||||
else
|
||||
TriggerServerEvent(getScript()..":server:setItemMetaData", { item = data.item, slot = slot, metadata = metadata })
|
||||
end
|
||||
end
|
||||
|
||||
function getItemMetadata(item, slot, src)
|
||||
function getDurability(item)
|
||||
local lowestSlot = 100
|
||||
local chosenSlot = slot
|
||||
local metadata = {}
|
||||
|
||||
local itemcheck = getPlayerInv(src)
|
||||
|
||||
if chosenSlot then
|
||||
for k, v in pairs(itemcheck) do
|
||||
if v.name == item and v.slot == chosenSlot then
|
||||
lowestSlot = v.slot
|
||||
metadata = itemcheck[k].info or itemcheck[k].metadata or {}
|
||||
debugPrint("^6Bridge^7: ^2Found metadata for item ^3"..item.." ^2in slot ^3"..lowestSlot.."^7")
|
||||
end
|
||||
end
|
||||
else
|
||||
local durability = nil
|
||||
if isStarted(QBInv) or isStarted(PSInv) or isStarted(RSGInv) or isStarted(JPRInv) then
|
||||
local itemcheck = Core.Functions.GetPlayerData().items
|
||||
for k, v in pairs(itemcheck) do
|
||||
if v.name == item then
|
||||
if v.slot <= lowestSlot then
|
||||
lowestSlot = v.slot
|
||||
metadata = itemcheck[k].info or itemcheck[k].metadata or {}
|
||||
durability = itemcheck[k].info and itemcheck[k].info.durability or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return metadata, lowestSlot
|
||||
|
||||
if isStarted(OXInv) then
|
||||
local itemcheck = exports[OXInv]:Search('slots', item)
|
||||
for k, v in pairs(itemcheck) do
|
||||
if v.slot <= lowestSlot then
|
||||
debugPrint(v.slot, itemcheck[k].metadata.durability)
|
||||
lowestSlot = v.slot
|
||||
durability = v.metadata and v.metadata.durability or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isStarted(QSInv) then
|
||||
local itemcheck = exports[QSInv]:getUserInventory()
|
||||
for _, v in pairs(itemcheck) do
|
||||
if v.name == item and v.slot <= lowestSlot then
|
||||
lowestSlot = v.slot
|
||||
durability = v.info and v.info.durability or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isStarted(CoreInv) then
|
||||
local itemcheck = exports[CoreInv]:getInventory()
|
||||
for _, v in pairs(itemcheck) do
|
||||
if v.name == item and v.slot <= lowestSlot then
|
||||
lowestSlot = v.slot
|
||||
durability = v.metadata and v.metadata.durability or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isStarted(CodeMInv) then
|
||||
local itemcheck = exports[CodeMInv]:GetClientPlayerInventory()
|
||||
for _, v in pairs(itemcheck) do
|
||||
if v.name == item and tonumber(v.slot) <= lowestSlot then
|
||||
lowestSlot = tonumber(v.slot)
|
||||
durability = v.info and v.info.durability or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isStarted(OrigenInv) then
|
||||
local itemcheck = exports[OrigenInv]:getPlayerInventory()
|
||||
for _, v in pairs(itemcheck) do
|
||||
if v.name == item and v.slot <= lowestSlot then
|
||||
lowestSlot = v.slot
|
||||
durability = v.metadata and v.metadata.durability or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isStarted(TgiannInv) then
|
||||
local itemcheck = exports[TgiannInv]:GetPlayerItems()
|
||||
for _, v in pairs(itemcheck) do
|
||||
if v.name == item and v.slot <= lowestSlot then
|
||||
lowestSlot = v.slot
|
||||
durability = v.metadata and v.metadata.durability or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- For ESX default inventory (es_extended)
|
||||
if ESX and isStarted(ESXExport) then
|
||||
local xPlayer = ESX.GetPlayerData() or {}
|
||||
if xPlayer.inventory then
|
||||
for _, v in ipairs(xPlayer.inventory) do
|
||||
if v.name == item then
|
||||
-- Optionally use a slot field if available; otherwise, use the index
|
||||
if v.slot and v.slot <= lowestSlot then
|
||||
lowestSlot = v.slot
|
||||
end
|
||||
if v.metadata and v.metadata.durability then
|
||||
durability = v.metadata.durability
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return durability, lowestSlot
|
||||
end
|
||||
|
||||
--- Server event handler to set metadata for an item.
|
||||
@@ -456,9 +513,9 @@ end
|
||||
---
|
||||
--- @usage
|
||||
--- ```lua
|
||||
--- TriggerServerEvent("script:server:setItemMetaData", { item = "drill", slot = 5, metadata = { durability = 80 } })
|
||||
--- TriggerServerEvent("script:server:setMetaData", { item = "drill", slot = 5, metadata = { durability = 80 } })
|
||||
--- ```
|
||||
RegisterNetEvent(getScript()..":server:setItemMetaData", function(data, src)
|
||||
RegisterNetEvent(getScript()..":server:setMetaData", function(data, src)
|
||||
local src = src or source
|
||||
if isStarted(QBInv) or isStarted(PSInv) or isStarted(RSGInv) or isStarted(JPRInv) then
|
||||
--debugPrint(src, data.item, 1, data.slot)
|
||||
|
||||
@@ -104,31 +104,16 @@ function toggleDuty()
|
||||
TriggerServerEvent("QBCore:ToggleDuty")
|
||||
Wait(100)
|
||||
onDuty = getPlayer().onDuty
|
||||
|
||||
elseif isStarted(RSGExport) then
|
||||
TriggerServerEvent("RSGCore:ToggleDuty")
|
||||
Wait(100)
|
||||
onDuty = getPlayer().onDuty
|
||||
|
||||
elseif isStarted(ESXExport) then
|
||||
local tempJob = ESX.GetPlayerData().job
|
||||
tempJob.onDuty = not onDuty
|
||||
ESX.SetPlayerData("job", tempJob)
|
||||
onDuty = getPlayer().onDuty
|
||||
if onDuty then
|
||||
triggerNotify(nil, "Now on duty", "success")
|
||||
else
|
||||
triggerNotify(nil, "Now off duty", "success")
|
||||
end
|
||||
|
||||
else
|
||||
onDuty = not onDuty
|
||||
if onDuty then
|
||||
triggerNotify(nil, "Now on duty", "success")
|
||||
else
|
||||
triggerNotify(nil, "Now off duty", "success")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ end
|
||||
--- ```
|
||||
function playAnim(animDict, animName, duration, flag, ped, speed)
|
||||
loadAnimDict(animDict)
|
||||
debugPrint("^6Bridge^7: ^3playAnim^7() ^2Triggered^7: ", animDict, animName, flag)
|
||||
debugPrint("^6Bridge^7: ^3playAnim^7() ^2Triggered^7: ", animDict, animName)
|
||||
TaskPlayAnim(ped and ped or PlayerPedId(), animDict, animName, speed or 8.0, speed or -8.0, duration or 30000, flag or 50, 1, false, false, false)
|
||||
end
|
||||
|
||||
@@ -238,25 +238,4 @@ function playGameSound(audioBank, soundSet, soundRef, coords, synced, range)
|
||||
PlaySoundFromEntity(soundId, soundRef, coords, soundSet, synced, 1.0)
|
||||
end
|
||||
ReleaseScriptAudioBank(audioBank)
|
||||
end
|
||||
|
||||
-- Experimental, add fade in for spawned entities
|
||||
function fadeInEnt(ent, duration)
|
||||
if not DoesEntityExist(ent) then return end
|
||||
duration = duration or 500 -- in ms
|
||||
local fadeSteps = 20
|
||||
local stepTime = duration / fadeSteps
|
||||
|
||||
SetEntityAlpha(ent, 0, false)
|
||||
SetEntityVisible(ent, true, false)
|
||||
SetEntityLocallyInvisible(ent) -- sometimes helps prevent "pop-in" in early frames
|
||||
|
||||
for i = 1, fadeSteps do
|
||||
Wait(stepTime)
|
||||
local newAlpha = math.floor((i / fadeSteps) * 255)
|
||||
SetEntityAlpha(ent, newAlpha, false)
|
||||
end
|
||||
|
||||
-- Restore full visibility
|
||||
ResetEntityAlpha(ent)
|
||||
end
|
||||
@@ -62,7 +62,7 @@ function makePed(data, coords, freeze, collision, scenario, anim, synced)
|
||||
model = data.model
|
||||
loadModel(data.model)
|
||||
ped = CreatePed(0, model, coords.x, coords.y, coords.z - 1.03, coords.w, synced and synced or false, false)
|
||||
SetEntityAlpha(ped, 0, false)
|
||||
|
||||
-- Inheritance
|
||||
SetPedHeadBlendData(ped, data.custom.faceFather, data.custom.faceMother, data.custom.raceShape, data.custom.skinFather, data.custom.skinMother, data.custom.raceSkin, data.custom.faceMix or 0, data.custom.skinMix or 0, data.custom.raceMix or 0, false)
|
||||
|
||||
@@ -116,7 +116,6 @@ function makePed(data, coords, freeze, collision, scenario, anim, synced)
|
||||
loadModel(model)
|
||||
if gameName == "rdr3" then
|
||||
ped = CreatePed(model, coords.x, coords.y, coords.z - 1.03, coords.w, synced or false, false)
|
||||
SetEntityAlpha(ped, 0, false)
|
||||
SetEntityVisible(ped, 1) -- SetEntityVisible
|
||||
SetEntityAlpha(ped, 255, false) -- SetEntityAlpha
|
||||
SetRandomOutfitVariation(ped, true) -- Invisible without
|
||||
@@ -142,10 +141,6 @@ function makePed(data, coords, freeze, collision, scenario, anim, synced)
|
||||
end
|
||||
unloadModel(model)
|
||||
Peds[keyGen()..keyGen()] = ped
|
||||
|
||||
CreateThread(function()
|
||||
fadeInEnt(ped)
|
||||
end)
|
||||
return ped
|
||||
end
|
||||
|
||||
@@ -248,4 +243,4 @@ onResourceStop(function()
|
||||
for k in pairs(Peds) do
|
||||
DeletePed(Peds[k])
|
||||
end
|
||||
end, true)
|
||||
end, true)
|
||||
@@ -23,16 +23,12 @@ local Props = {}
|
||||
function makeProp(data, freeze, synced)
|
||||
loadModel(data.prop)
|
||||
local prop = CreateObject(data.prop, data.coords.x, data.coords.y, data.coords.z-1.03, synced and synced or false, synced and synced or false, false)
|
||||
SetEntityAlpha(veh, 0, false)
|
||||
SetEntityHeading(prop, (data.coords.w or 0) + 180.0)
|
||||
FreezeEntityPosition(prop, freeze or false)
|
||||
|
||||
debugPrint("^6Bridge^7: ^1Prop ^2Created^7: '^6"..prop.."^7' | ^2Hash^7: ^7'^6"..data.prop.."^7' | ^2Coord^7: "..formatCoord(data.coords))
|
||||
SetModelAsNoLongerNeeded(data.prop)
|
||||
Props[keyGen()..keyGen()] = prop
|
||||
CreateThread(function()
|
||||
fadeInEnt(prop)
|
||||
end)
|
||||
return prop
|
||||
end
|
||||
|
||||
|
||||
@@ -18,22 +18,18 @@ function makeVeh(model, coords)
|
||||
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, coords.w, true, false)
|
||||
SetVehicleHasBeenOwnedByPlayer(veh, true)
|
||||
if gameName ~= "rdr3" then
|
||||
SetEntityAlpha(veh, 0, false)
|
||||
SetNetworkIdCanMigrate(NetworkGetNetworkIdFromEntity(veh), true)
|
||||
SetNetworkIdCanMigrate(NetworkGetNetworkIdFromEntity(veh), true)
|
||||
Wait(100)
|
||||
SetVehicleNeedsToBeHotwired(veh, false)
|
||||
SetVehRadioStation(veh, 'OFF')
|
||||
SetVehicleFuelLevel(veh, 100.0)
|
||||
SetVehicleModKit(veh, 0)
|
||||
|
||||
end
|
||||
SetVehicleOnGroundProperly(veh)
|
||||
|
||||
debugPrint("^6Bridge^7: ^1Veh ^2Created^7: '^6"..veh.."^7' | ^2Hash^7: ^7'^6"..model.."^7' | ^2Coord^7: "..formatCoord(coords))
|
||||
unloadModel(model)
|
||||
Vehicles[#Vehicles + 1] = veh
|
||||
CreateThread(function()
|
||||
fadeInEnt(veh)
|
||||
end)
|
||||
return veh
|
||||
end
|
||||
|
||||
|
||||
@@ -150,7 +150,6 @@ function progressBar(data)
|
||||
anim = {
|
||||
dict = data.dict,
|
||||
clip = data.anim,
|
||||
flag = data.flag
|
||||
},
|
||||
prop = {
|
||||
model = data.prop and data.prop.model,
|
||||
@@ -161,7 +160,7 @@ function progressBar(data)
|
||||
}) then
|
||||
result = true
|
||||
else
|
||||
result = false
|
||||
result = true
|
||||
end
|
||||
|
||||
elseif Config.System.ProgressBar == "red" then
|
||||
|
||||
@@ -58,9 +58,9 @@ end
|
||||
---
|
||||
--- @usage
|
||||
--- ```lua
|
||||
--- local myMeta = getPlayerMetadata(player, "myKey")
|
||||
--- local myMeta = GetMetadata(player, "myKey")
|
||||
--- ```
|
||||
function getPlayerMetadata(player, key)
|
||||
function GetMetadata(player, key)
|
||||
if not player then
|
||||
debugPrint("^6Bridge^7: ^3GetMetadata^7() calling server: "..key)
|
||||
return triggerCallback(getScript()..":server:GetMetadata", key)
|
||||
@@ -98,11 +98,11 @@ createCallback(getScript()..":server:GetMetadata", function(source, key)
|
||||
if type(key) == "table" then
|
||||
local Metadata = {}
|
||||
for _, k in ipairs(key) do
|
||||
Metadata[k] = getPlayerMetadata(player, k)
|
||||
Metadata[k] = GetMetadata(player, k)
|
||||
end
|
||||
return Metadata
|
||||
elseif type(key) == "string" then
|
||||
return getPlayerMetadata(player, key)
|
||||
return GetMetadata(player, key)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -120,9 +120,9 @@ end)
|
||||
---
|
||||
--- @usage
|
||||
--- ```lua
|
||||
--- setPlayerMetadata(player, "myKey", "newValue")
|
||||
--- SetMetadata(player, "myKey", "newValue")
|
||||
--- ```
|
||||
function setPlayerMetadata(player, key, value)
|
||||
function SetMetadata(player, key, value)
|
||||
debugPrint("^6Bridge^7: ^3SetMetadata^7() setting metadata for key: "..key)
|
||||
if isStarted(QBExport) or isStarted(QBXExport) then
|
||||
debugPrint("^6Bridge^7: ^3SetMetadata^7() using QBExport/QBXExport")
|
||||
@@ -144,14 +144,14 @@ function setPlayerMetadata(player, key, value)
|
||||
end
|
||||
|
||||
-- Register a server callback for setting metadata.
|
||||
createCallback(getScript()..":server:setPlayerMetadata", function(source, key, value)
|
||||
createCallback(getScript()..":server:SetMetadata", function(source, key, value)
|
||||
debugPrint("SetMetadata callback triggered for source:", source, "key:", key, "value:", value)
|
||||
local player = GetPlayer(source)
|
||||
--[[if not player then
|
||||
print("Error setting metadata: player not found for source "..tostring(source))
|
||||
return false
|
||||
end]]
|
||||
setPlayerMetadata(player, key, value)
|
||||
SetMetadata(player, key, value)
|
||||
print("Metadata set successfully.", key)
|
||||
return true
|
||||
end)
|
||||
@@ -412,7 +412,7 @@ function hasJob(job, source, grade)
|
||||
elseif isStarted(QBExport) and not isStarted(QBXExport) then
|
||||
if Core.Functions.GetPlayer then
|
||||
local player = Core.Functions.GetPlayer(src)
|
||||
if not player then goto skip end
|
||||
if not player then print("Player not found for src: "..src) end
|
||||
local jobinfo = player.PlayerData.job
|
||||
if jobinfo.name == job then
|
||||
hasJobFlag = true
|
||||
@@ -437,10 +437,11 @@ function hasJob(job, source, grade)
|
||||
if grade and not (grade <= ganginfo.grade.level) then hasJobFlag = false end
|
||||
end
|
||||
end
|
||||
|
||||
elseif isStarted(RSGExport) then
|
||||
if Core.Functions.GetPlayer then
|
||||
local player = Core.Functions.GetPlayer(src)
|
||||
if not player then goto skip end
|
||||
if not player then print("Player not found for src: "..src) end
|
||||
local jobinfo = player.PlayerData.job
|
||||
if jobinfo.name == job then
|
||||
hasJobFlag = true
|
||||
@@ -530,7 +531,6 @@ function hasJob(job, source, grade)
|
||||
print("^4ERROR^7: ^2No Core detected for hasJob() ^7- ^2Check ^3starter^1.^2lua^7")
|
||||
end
|
||||
end
|
||||
::skip::
|
||||
return hasJobFlag, duty
|
||||
end
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@ local stash
|
||||
-- If running on the server, create a callback to retrieve stash items.
|
||||
if isServer() then
|
||||
createCallback(getScript()..':server:GetStashItems', function(source, stashName)
|
||||
if stashName == nil or stashName == "" then
|
||||
return {}
|
||||
end
|
||||
stash = getStash(stashName)
|
||||
return stash
|
||||
end)
|
||||
@@ -38,9 +35,9 @@ local stashCache = {}
|
||||
--- local cached = GetStashTimeout("playerStash")
|
||||
--- ```
|
||||
function GetStashTimeout(stashName, stop)
|
||||
if stop or (stashName == nil or stashName == "") then
|
||||
if stop then
|
||||
stashCache = {}
|
||||
return false
|
||||
return
|
||||
end
|
||||
|
||||
-- Retrieve cache for this stash, or initialize if not present.
|
||||
@@ -88,7 +85,7 @@ end
|
||||
--- local found, stashName = checkStashItem({"playerStash", "storageStash"}, { iron = 2, wood = 5 })
|
||||
--- ```
|
||||
function checkStashItem(stashes, itemTable)
|
||||
if not stashes or stashes == "" then
|
||||
if not stashes then
|
||||
return hasItem(itemTable), nil
|
||||
end
|
||||
|
||||
@@ -320,7 +317,7 @@ end
|
||||
--- ```
|
||||
function getStash(stashName)
|
||||
local stashResource = ""
|
||||
if stashName == "" or type(stashName) ~= "string" then
|
||||
if type(stashName) ~= "string" then
|
||||
print("^6Bridge^7: ^2Stash name was not a string ^3"..stashName.."^7(^3"..type(stashName).."^7)")
|
||||
return {}
|
||||
end
|
||||
@@ -423,10 +420,6 @@ end
|
||||
--- stashRemoveItem(currentItems, "playerStash", { iron = 2, wood = 5 })
|
||||
--- ```
|
||||
function stashRemoveItem(stashItems, stashName, items)
|
||||
if stashName == "" or stashName == nil then
|
||||
print("^1ERROR^7: ^1stashRemoveItem triggered but stashName was empty^7")
|
||||
return
|
||||
end
|
||||
if type(stashName) ~= "table" then
|
||||
stashName = { stashName }
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ end
|
||||
local function stopAnim(animDict, animName, ped)
|
||||
StopAnimTask(ped or PlayerPedId(), animDict, animName, 0.5)
|
||||
StopAnimTask(ped or PlayerPedId(), animName, animDict, 0.5)
|
||||
RemoveAnimDict(animDict)
|
||||
unloadAnimDict(animDict)
|
||||
end
|
||||
|
||||
function redProgressBar(data)
|
||||
|
||||
22
version.txt
22
version.txt
@@ -1,14 +1,14 @@
|
||||
2.0.21
|
||||
2.0.20
|
||||
|
||||
- Fix toggleDuty() for ESX users
|
||||
- Rename metadata handler functions
|
||||
- Add useToolDegrade() to force limited uses for items
|
||||
- Make breakTool() smarter
|
||||
- Fix getPlayer() not checking if player data exists yet on qbcore
|
||||
- Fix inbuilt gta progressbar error when stopping animations
|
||||
- lation_ui support fixes
|
||||
- Add fade in animations for created entities
|
||||
- Fix waitForSharedLoad() not announcing when an error occurs
|
||||
- Incrase authToken timeout from 5 seconds to 1 minute
|
||||
- Add Full support for lation_ui
|
||||
- Add "Open Wheel" to searchCar()
|
||||
- Increase timeout for cache timer from 5 seconds to 2 minutes
|
||||
- Fix GTA progressbar erroring on playAnim()
|
||||
- Add Igredient location indicator when crafting
|
||||
- Fix JPRInv checks breaking early when caching framework info
|
||||
- Enhance doesItemExist() and add getItemLabel() function
|
||||
- Add Support for old qb-inventory config loading
|
||||
- Fix typo in cancarry when using Tgiann Inv
|
||||
- Add support for single progressBar when crafting
|
||||
|
||||
https://github.com/jimathy/jim_bridge
|
||||
Reference in New Issue
Block a user