mirror of
https://github.com/jimathy/jim_bridge.git
synced 2026-08-16 21:46:03 +01:00
Beta: Fixes for existing scripts + feature for jim-crafting
This commit is contained in:
@@ -157,6 +157,7 @@ function openMenu(Menu, data)
|
|||||||
end
|
end
|
||||||
if not Menu[k].header then Menu[k].header = " " end
|
if not Menu[k].header then Menu[k].header = " " end
|
||||||
if Menu[k].arrow then Menu[k].icon = "fas fa-angle-right" end
|
if Menu[k].arrow then Menu[k].icon = "fas fa-angle-right" end
|
||||||
|
Menu[k].isMenuHeader = Menu[k].isMenuHeader or Menu[k].disable
|
||||||
end
|
end
|
||||||
exports[QBMenuExport]:openMenu(Menu)
|
exports[QBMenuExport]:openMenu(Menu)
|
||||||
|
|
||||||
|
|||||||
@@ -40,76 +40,184 @@ local CraftLock = false
|
|||||||
--- })
|
--- })
|
||||||
--- ```
|
--- ```
|
||||||
function craftingMenu(data)
|
function craftingMenu(data)
|
||||||
|
-- Prevent opening the menu if crafting is locked.
|
||||||
if CraftLock then return end
|
if CraftLock then return end
|
||||||
|
|
||||||
|
-- If a job or gang restriction exists and the player doesn't pass the job check, exit early.
|
||||||
if (data.job or data.gang) and not jobCheck(data.job or data.gang) then return end
|
if (data.job or data.gang) and not jobCheck(data.job or data.gang) then return end
|
||||||
|
|
||||||
|
-- Display a temporary "thinking" notification/menu depending on the configured system.
|
||||||
if Config.System.Menu == "jim" then
|
if Config.System.Menu == "jim" then
|
||||||
triggerNotify(nil, "Thinking", "info")
|
triggerNotify(nil, "Thinking", "info")
|
||||||
else
|
else
|
||||||
openMenu({ { header = "Thinking...", icon = "fas fa-hourglass-end", isMenuHeader = true } }, { header = "Crafting Menu" } )
|
openMenu({ { header = "Thinking...", icon = "fas fa-hourglass-end", isMenuHeader = true } }, { header = "Crafting Menu" } )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Normalize stash name: if stashTable is provided, assign it to stashName.
|
||||||
if data.stashTable then data.stashName = data.stashTable end
|
if data.stashTable then data.stashName = data.stashTable end
|
||||||
|
|
||||||
|
-- Initialize an empty menu table and a flag for job verification.
|
||||||
local Menu, hasjob = {}, false
|
local Menu, hasjob = {}, false
|
||||||
|
-- Get the list of recipes from the provided data.
|
||||||
local Recipes = data.craftable.Recipes
|
local Recipes = data.craftable.Recipes
|
||||||
|
local craftingLevel = data.craftable.craftingLevel
|
||||||
|
local craftedItems = data.craftable.craftedItems
|
||||||
|
|
||||||
|
-- Create a temporary table to collect required item amounts for each recipe.
|
||||||
local tempCarryTable = {}
|
local tempCarryTable = {}
|
||||||
for i = 1, #Recipes do
|
for i = 1, #Recipes do
|
||||||
|
-- Iterate over each key in the current recipe.
|
||||||
for k in pairs(Recipes[i]) do
|
for k in pairs(Recipes[i]) do
|
||||||
|
-- Ignore meta keys: "amount", "metadata", "job", and "gang".
|
||||||
if k ~= "amount" and k ~= "metadata" and k ~= "job" and k ~= "gang" then
|
if k ~= "amount" and k ~= "metadata" and k ~= "job" and k ~= "gang" then
|
||||||
|
-- Record the required amount for this ingredient (default to 1 if not specified).
|
||||||
tempCarryTable[k] = Recipes[i].amount or 1
|
tempCarryTable[k] = Recipes[i].amount or 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Trigger a server callback to check if the player can carry the required items.
|
||||||
local canCarryTable = triggerCallback(getScript()..':server:canCarry', tempCarryTable)
|
local canCarryTable = triggerCallback(getScript()..':server:canCarry', tempCarryTable)
|
||||||
|
|
||||||
|
-- Process each recipe to build the menu entries.
|
||||||
for i = 1, #Recipes do
|
for i = 1, #Recipes do
|
||||||
|
-- Ensure the recipe has an "amount" field; default to 1 if missing.
|
||||||
if not Recipes[i]["amount"] then Recipes[i]["amount"] = 1 end
|
if not Recipes[i]["amount"] then Recipes[i]["amount"] = 1 end
|
||||||
|
|
||||||
|
-- Loop through each key-value pair in the recipe.
|
||||||
for k, v in pairs(Recipes[i]) do
|
for k, v in pairs(Recipes[i]) do
|
||||||
if k ~= "amount" and k ~= "metadata" and k ~= "job" and k ~= "gang" then
|
-- Skip meta keys that are not ingredients.
|
||||||
|
local excludeKeys = {
|
||||||
|
amount = true,
|
||||||
|
metadata = true,
|
||||||
|
description = true,
|
||||||
|
info = true,
|
||||||
|
job = true,
|
||||||
|
gang = true,
|
||||||
|
oneUse = true,
|
||||||
|
slot = true,
|
||||||
|
blueprintRef = true,
|
||||||
|
craftingLevel = true,
|
||||||
|
craftedItems = true,
|
||||||
|
hasCrafted = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if not excludeKeys[k] then
|
||||||
|
|
||||||
|
-- Check job requirements if specified for the recipe.
|
||||||
if Recipes[i].job then
|
if Recipes[i].job then
|
||||||
for l, b in pairs(Recipes[i].job) do
|
for l, b in pairs(Recipes[i].job) do
|
||||||
|
-- hasJob returns true if the player meets the job criteria.
|
||||||
hasjob = hasJob(l, nil, b)
|
hasjob = hasJob(l, nil, b)
|
||||||
if hasjob == true then break end
|
if hasjob == true then break end
|
||||||
end
|
end
|
||||||
else hasjob = true end
|
else
|
||||||
local setheader, settext, disable, metadata = "", "", false, (Recipes[i]["metadata"] or nil)
|
hasjob = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Initialize variables for menu display text, disable flag, and any metadata.
|
||||||
|
local setheader, settext, disable, metadata = "", "", false, (Recipes[i]["metadata"] or Recipes[i]["info"] or nil)
|
||||||
|
|
||||||
if hasjob then
|
if hasjob then
|
||||||
|
-- Build tables for ingredient details.
|
||||||
local itemTable = {}
|
local itemTable = {}
|
||||||
local metaTable = {}
|
local metaTable = {}
|
||||||
|
|
||||||
|
-- Iterate over the ingredients for the current key.
|
||||||
for l, b in pairs(Recipes[i][tostring(k)]) do
|
for l, b in pairs(Recipes[i][tostring(k)]) do
|
||||||
|
-- Append item label and quantity to the settext string.
|
||||||
|
-- Use a line break (br) if settext is not empty.
|
||||||
settext = settext..(settext ~= "" and br or "")..(Items[l] and Items[l].label or "error - "..l)..(b > 1 and " x"..b or "")
|
settext = settext..(settext ~= "" and br or "")..(Items[l] and Items[l].label or "error - "..l)..(b > 1 and " x"..b or "")
|
||||||
|
-- Populate the metaTable with item labels and their amounts.
|
||||||
metaTable[Items[l] and Items[l].label or "error - "..l] = b
|
metaTable[Items[l] and Items[l].label or "error - "..l] = b
|
||||||
|
-- Build a simple table of items required.
|
||||||
itemTable[l] = b
|
itemTable[l] = b
|
||||||
Wait(0)
|
Wait(0) -- Yield to avoid freezing the game.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Wait until the server callback (canCarryTable) has returned.
|
||||||
while not canCarryTable do Wait(0) end
|
while not canCarryTable do Wait(0) end
|
||||||
|
|
||||||
|
-- Determine if the recipe should be disabled by checking if the player has the required items.
|
||||||
disable = not checkHasItem(data.stashName, itemTable)
|
disable = not checkHasItem(data.stashName, itemTable)
|
||||||
setheader = ((metadata and metadata.label) or (Items[tostring(k)] and Items[tostring(k)].label) or "error - " .. tostring(k)) .. (Recipes[i]["amount"] > 1 and " x" .. Recipes[i]["amount"] or "")
|
|
||||||
|
-- Construct the header text for this menu item using metadata or default item label.
|
||||||
|
setheader = ((metadata and metadata.label) or (Items[tostring(k)] and Items[tostring(k)].label) or "error - " .. tostring(k))
|
||||||
|
.. (Recipes[i]["amount"] > 1 and " x" .. Recipes[i]["amount"] or "")
|
||||||
|
|
||||||
|
-- Append an emoji to indicate carry status:
|
||||||
|
-- If not disabled and the player cannot carry the item, append 📦,
|
||||||
|
-- otherwise append ✔️ if they can carry it.
|
||||||
|
-- if jim-crafting and its a blueprint item that has/hasnt been crafting prefix with ✨ to represent its a new item
|
||||||
if not disable then
|
if not disable then
|
||||||
if not canCarryTable[k] then setheader = setheader .. " 📦"
|
if not canCarryTable[k] then
|
||||||
else setheader = setheader .. " ✔️" end
|
setheader = setheader .. " 📦"
|
||||||
elseif not canCarryTable[k] then setheader = setheader .. " 📦" end
|
else
|
||||||
|
setheader = setheader .. " ✔️"
|
||||||
|
end
|
||||||
|
elseif not canCarryTable[k] then
|
||||||
|
setheader = setheader .. " 📦"
|
||||||
|
end
|
||||||
|
if Recipes[i]["hasCrafted"] ~= nil then
|
||||||
|
if craftedItems[k] == nil then
|
||||||
|
setheader = "✨ "..setheader
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Add the constructed menu item into the Menu table.
|
||||||
Menu[#Menu + 1] = {
|
Menu[#Menu + 1] = {
|
||||||
|
-- Show an arrow if the item is enabled and can be carried.
|
||||||
arrow = not disable and canCarryTable[k],
|
arrow = not disable and canCarryTable[k],
|
||||||
disable = isStarted(QBMenuExport) and disable and not canCarryTable[k],
|
-- Disable the menu item based on the state of QBMenuExport and carry-check.
|
||||||
|
isMenuHeader = disable or not canCarryTable[k],
|
||||||
|
-- Set icon and image for the menu item (using metadata image if available).
|
||||||
icon = invImg((metadata and metadata.image) or tostring(k)),
|
icon = invImg((metadata and metadata.image) or tostring(k)),
|
||||||
image = invImg((metadata and metadata.image) or tostring(k)),
|
image = invImg((metadata and metadata.image) or tostring(k)),
|
||||||
|
-- Final header text, appending ❌ if disabled or cannot be carried.
|
||||||
header = setheader..((disable or not canCarryTable[k]) and " ❌" or ""),
|
header = setheader..((disable or not canCarryTable[k]) and " ❌" or ""),
|
||||||
txt = isStarted(QBMenuExport) and settext or nil,
|
-- Set description text if QBMenuExport is started.
|
||||||
--metadata = debugMode and Recipes[i]["metadata"] or nil,
|
txt = (isStarted(QBMenuExport) or disable) and settext or nil,
|
||||||
|
-- Attach the metadata table containing ingredient details.
|
||||||
metadata = metaTable,
|
metadata = metaTable,
|
||||||
|
-- Define the onSelect function to trigger crafting actions if the item is selectable.
|
||||||
onSelect = ((not disable and canCarryTable[k]) and (function()
|
onSelect = ((not disable and canCarryTable[k]) and (function()
|
||||||
local transdata = { item = k, craft = data.craftable.Recipes[i], craftable = data.craftable, coords = data.coords, stashName = data.stashName, onBack = data.onBack, metadata = Recipes[i]["metadata"] }
|
-- Build transaction data with details needed for crafting.
|
||||||
if Config.Crafting.MultiCraft then multiCraft(transdata) else makeItem(transdata) end
|
local transdata = {
|
||||||
|
item = k,
|
||||||
|
craft = data.craftable.Recipes[i],
|
||||||
|
craftable = data.craftable,
|
||||||
|
coords = data.coords,
|
||||||
|
stashName = data.stashName,
|
||||||
|
onBack = data.onBack,
|
||||||
|
metadata = metadata
|
||||||
|
}
|
||||||
|
-- Call multiCraft or makeItem based on configuration.
|
||||||
|
if Config.Crafting.MultiCraft then
|
||||||
|
multiCraft(transdata)
|
||||||
|
else
|
||||||
|
makeItem(transdata)
|
||||||
|
end
|
||||||
end) or nil),
|
end) or nil),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Wait(0)
|
Wait(0) -- Yield within the loop to maintain responsiveness.
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
openMenu(Menu, { header = data.craftable.Header, onBack = data.onBack or nil, canClose = true, onExit = function() end, })
|
|
||||||
|
-- Open the final crafting menu with the built Menu table and provided header/onBack configuration.
|
||||||
|
openMenu(Menu, {
|
||||||
|
header = data.craftable.Header,
|
||||||
|
headertxt = data.craftable.Headertxt,
|
||||||
|
onBack = data.onBack or nil,
|
||||||
|
canClose = true,
|
||||||
|
onExit = function() end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Trigger an action (likely camera or player focus) to look at the specified coordinates.
|
||||||
lookEnt(data.coords)
|
lookEnt(data.coords)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Opens a menu for selecting the quantity to craft.
|
--- Opens a menu for selecting the quantity to craft.
|
||||||
---
|
---
|
||||||
--- This function presents the player with options to craft multiple quantities of an item, based on `Config.Crafting.MultiCraftAmounts`.
|
--- This function presents the player with options to craft multiple quantities of an item, based on `Config.Crafting.MultiCraftAmounts`.
|
||||||
@@ -159,7 +267,17 @@ function multiCraft(data)
|
|||||||
header = "Craft - x"..k * data.craft.amount,
|
header = "Craft - x"..k * data.craft.amount,
|
||||||
txt = settext,
|
txt = settext,
|
||||||
onSelect = function ()
|
onSelect = function ()
|
||||||
makeItem({item = data.item, craft = data.craft, craftable = data.craftable, amount = k, coords = data.coords, stashName = stashname, stashTable = data.stashName, onBack = data.onBack, metadata = data.metadata })
|
makeItem({
|
||||||
|
item = data.item,
|
||||||
|
craft = data.craft,
|
||||||
|
craftable = data.craftable,
|
||||||
|
amount = k,
|
||||||
|
coords = data.coords,
|
||||||
|
stashName = stashname,
|
||||||
|
stashTable = data.stashName,
|
||||||
|
onBack = data.onBack,
|
||||||
|
metadata = data.metadata
|
||||||
|
})
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@@ -199,20 +317,38 @@ function makeItem(data)
|
|||||||
CraftLock = true
|
CraftLock = true
|
||||||
if data.stashTable then data.stashName = data.stashTable end
|
if data.stashTable then data.stashName = data.stashTable end
|
||||||
local bartime = data.craftable.progressBar and data.craftable.progressBar.time or 5000
|
local bartime = data.craftable.progressBar and data.craftable.progressBar.time or 5000
|
||||||
local bartext = (data.craftable.progressBar and data.craftable.progressBar.label) or (Loc[Config.Lan].progressbar and Loc[Config.Lan].progressbar["progress_make"]) or "Making a"
|
local bartext = (data.craftable.progressBar and data.craftable.progressBar.label) or (Loc[Config.Lan].progressbar and Loc[Config.Lan].progressbar["progress_make"]) or "Making "
|
||||||
local animDict = data.craftable.Anims and data.craftable.Anims.animDict or "amb@prop_human_parking_meter@male@idle_a"
|
local animDict = data.craftable.Anims and data.craftable.Anims.animDict or "amb@prop_human_parking_meter@male@idle_a"
|
||||||
local anim = data.craftable.Anims and data.craftable.Anims.anim or "idle_a"
|
local anim = data.craftable.Anims and data.craftable.Anims.anim or "idle_a"
|
||||||
local amount = data.amount and (data.amount ~= 1) and data.amount or 1
|
local amount = data.amount and (data.amount ~= 1) and data.amount or 1
|
||||||
local metadata = data.metadata or nil
|
local metadata = data.metadata or nil
|
||||||
local prop = data.craftable.Anims and data.craftable.Anims.prop or nil
|
local prop = data.craftable.Anims and data.craftable.Anims.prop or nil
|
||||||
|
|
||||||
|
local canReturn = true
|
||||||
|
|
||||||
local crafted, crafting = true, true
|
local crafted, crafting = true, true
|
||||||
local cam = createTempCam(PlayerPedId(), data.coords)
|
local cam = createTempCam(PlayerPedId(), data.coords)
|
||||||
startTempCam(cam)
|
startTempCam(cam)
|
||||||
|
|
||||||
for i = 1, amount do
|
for i = 1, amount do
|
||||||
|
countTable(data.craft)
|
||||||
for k, v in pairs(data.craft) do
|
for k, v in pairs(data.craft) do
|
||||||
if k ~= "amount" and k ~= "metadata" and k ~= "job" and k ~= "gang" then
|
local excludeKeys = {
|
||||||
|
amount = true,
|
||||||
|
info = true,
|
||||||
|
metadata = true,
|
||||||
|
description = true,
|
||||||
|
job = true,
|
||||||
|
gang = true,
|
||||||
|
oneUse = true,
|
||||||
|
slot = true,
|
||||||
|
blueprintRef = true,
|
||||||
|
craftingLevel = true,
|
||||||
|
craftedItems = true,
|
||||||
|
hasCrafted = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if not excludeKeys[k] then
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
for l, b in pairs(v) do
|
for l, b in pairs(v) do
|
||||||
if crafting and progressBar({
|
if crafting and progressBar({
|
||||||
@@ -248,6 +384,20 @@ function makeItem(data)
|
|||||||
icon = data.item,
|
icon = data.item,
|
||||||
}) then
|
}) then
|
||||||
TriggerServerEvent(getScript()..":Crafting:GetItem", data.item, data.craft, data.stashName, metadata)
|
TriggerServerEvent(getScript()..":Crafting:GetItem", data.item, data.craft, data.stashName, metadata)
|
||||||
|
if data.craft["hasCrafted"] ~= nil then
|
||||||
|
debugPrint("hasCrafted Found, marking '"..data.item.."' as crafted for player")
|
||||||
|
|
||||||
|
data.craftable.craftedItems[data.item] = true
|
||||||
|
triggerCallback(getScript()..":server:SetMetadata", "craftedItems", data.craftable.craftedItems )
|
||||||
|
--SetMetadata(nil, "craftedItems", data.craftable.craftedItems)
|
||||||
|
end
|
||||||
|
if data.craftable.Recipes[1].oneUse == true then
|
||||||
|
removeItem("craftrecipe", 1, nil, data.craftable.Recipes[1].slot)
|
||||||
|
local breakId = GetSoundId()
|
||||||
|
PlaySoundFromEntity(breakId, "Drill_Pin_Break", PlayerPedId(), "DLC_HEIST_FLEECA_SOUNDSET", 1, 0)
|
||||||
|
canReturn = false
|
||||||
|
-- If recipe is removed it doesn't try to open menu again, it was causing blank menus for some reason
|
||||||
|
end
|
||||||
else
|
else
|
||||||
crafting = false
|
crafting = false
|
||||||
break
|
break
|
||||||
@@ -262,7 +412,7 @@ function makeItem(data)
|
|||||||
stopTempCam()
|
stopTempCam()
|
||||||
CraftLock = false
|
CraftLock = false
|
||||||
lockInv(false)
|
lockInv(false)
|
||||||
craftingMenu(data)
|
if canReturn then craftingMenu(data) end
|
||||||
ClearPedTasks(PlayerPedId())
|
ClearPedTasks(PlayerPedId())
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -299,11 +449,11 @@ RegisterNetEvent(getScript()..":Crafting:GetItem", function(ItemMake, craftable,
|
|||||||
else
|
else
|
||||||
if craftable then
|
if craftable then
|
||||||
for k, v in pairs(craftable[ItemMake] or {}) do
|
for k, v in pairs(craftable[ItemMake] or {}) do
|
||||||
TriggerEvent(getScript()..":server:toggleItem", false, tostring(k), v, src)
|
removeItem(tostring(k), v, src)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
TriggerEvent(getScript()..":server:toggleItem", true, ItemMake, amount, src, metadata)
|
addItem(ItemMake, amount, metadata, src)
|
||||||
--if isStarted("core_skills") then exports["core_skills"]:AddExperience(src, 2) end
|
--if isStarted("core_skills") then exports["core_skills"]:AddExperience(src, 2) end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -423,7 +573,7 @@ RegisterNetEvent(getScript().."Sellitems", function(data)
|
|||||||
local src = source
|
local src = source
|
||||||
local hasItems, hasTable = hasItem(data.item, 1, src)
|
local hasItems, hasTable = hasItem(data.item, 1, src)
|
||||||
if hasItems then
|
if hasItems then
|
||||||
TriggerEvent(getScript()..":server:toggleItem", false, data.item, hasTable[data.item].count, src)
|
removeItem(data.item, hasTable[data.item].count, src)
|
||||||
TriggerEvent(getScript()..":server:FundPlayer", (hasTable[data.item].count * data.price), "cash", src)
|
TriggerEvent(getScript()..":server:FundPlayer", (hasTable[data.item].count * data.price), "cash", src)
|
||||||
else
|
else
|
||||||
triggerNotify(nil, Loc[Config.Lan].error["dont_have"].." "..Items[data.item].label, "error", src)
|
triggerNotify(nil, Loc[Config.Lan].error["dont_have"].." "..Items[data.item].label, "error", src)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
--- end
|
--- end
|
||||||
--- ```
|
--- ```
|
||||||
function isStarted(script)
|
function isStarted(script)
|
||||||
return GetResourceState(script):find("start")
|
return GetResourceState(script):find("start") ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local scriptName = nil
|
local scriptName = nil
|
||||||
|
|||||||
@@ -95,12 +95,12 @@ end
|
|||||||
--- ```lua
|
--- ```lua
|
||||||
--- removeItem("health_potion", 1)
|
--- removeItem("health_potion", 1)
|
||||||
--- ```
|
--- ```
|
||||||
function removeItem(item, amount, src)
|
function removeItem(item, amount, src, slot)
|
||||||
if not Items[item] then print("^6Debug^7: ^1Error^7 - ^2Tried to remove ^7'^3"..item.."^7'^2 but it doesn't exist") return end
|
if not Items[item] then print("^6Debug^7: ^1Error^7 - ^2Tried to remove ^7'^3"..item.."^7'^2 but it doesn't exist") return end
|
||||||
if src then
|
if src then
|
||||||
TriggerEvent(getScript()..":server:toggleItem", false, item, amount, src, info)
|
TriggerEvent(getScript()..":server:toggleItem", false, item, amount, src, nil, slot)
|
||||||
else
|
else
|
||||||
TriggerServerEvent(getScript()..":server:toggleItem", false, item, amount, nil, info)
|
TriggerServerEvent(getScript()..":server:toggleItem", false, item, amount, nil, nil, slot)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ end
|
|||||||
--- ```lua
|
--- ```lua
|
||||||
--- TriggerServerEvent("script:server:toggleItem", true, "health_potion", 1)
|
--- TriggerServerEvent("script:server:toggleItem", true, "health_potion", 1)
|
||||||
--- ```
|
--- ```
|
||||||
RegisterNetEvent(getScript()..":server:toggleItem", function(give, item, amount, newsrc, info)
|
RegisterNetEvent(getScript()..":server:toggleItem", function(give, item, amount, newsrc, info, slot)
|
||||||
if not Items[item] then print("^6Debug^7: ^1Error^7 - ^2Tried to "..(tostring(give) == "true" and "add" or "remove").." ^7'^3"..item.."^7'^2 but it doesn't exist") return end
|
if not Items[item] then print("^6Debug^7: ^1Error^7 - ^2Tried to "..(tostring(give) == "true" and "add" or "remove").." ^7'^3"..item.."^7'^2 but it doesn't exist") return end
|
||||||
local src = newsrc or source
|
local src = newsrc or source
|
||||||
local addremove = (tostring(give) == "true" and "addItem" or "removeItem")
|
local addremove = (tostring(give) == "true" and "addItem" or "removeItem")
|
||||||
@@ -153,7 +153,7 @@ RegisterNetEvent(getScript()..":server:toggleItem", function(give, item, amount,
|
|||||||
|
|
||||||
elseif isStarted(QBInv) then
|
elseif isStarted(QBInv) then
|
||||||
while remamount > 0 do
|
while remamount > 0 do
|
||||||
if Core.Functions.GetPlayer(src).Functions.RemoveItem(item, 1) then
|
if Core.Functions.GetPlayer(src).Functions.RemoveItem(item, 1, slot) then
|
||||||
remamount -= 1
|
remamount -= 1
|
||||||
else
|
else
|
||||||
print("^1Error removing "..data.item.." Amount left to remove: "..remamount.."^7")
|
print("^1Error removing "..data.item.." Amount left to remove: "..remamount.."^7")
|
||||||
|
|||||||
90
shared/metaHandlers.lua
Normal file
90
shared/metaHandlers.lua
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
function GetPlayer(source)
|
||||||
|
if isStarted(QBExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3GetPlayer^7() QBExport")
|
||||||
|
return exports[QBExport]:GetCoreObject().Functions.GetPlayer(source)
|
||||||
|
elseif isStarted(QBXExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3GetPlayer^7() QBOXExport")
|
||||||
|
return exports[QBXExport]:GetCoreObject().Functions.GetPlayer(source)
|
||||||
|
elseif isStarted(ESXExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3GetPlayer^7() ESXExport")
|
||||||
|
return exports[ESXExport]:GetPlayerFromId(source)
|
||||||
|
elseif isStarted(OXCoreExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3GetPlayer^7() OXCoreExport")
|
||||||
|
return exports[OXCoreExport]:GetPlayer(source)
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get Metadata
|
||||||
|
function GetMetadata(player, key)
|
||||||
|
if not player then -- This would be called client side
|
||||||
|
debugPrint("^6Debug^7: ^3GetMetadata^7() calling server")
|
||||||
|
return triggerCallback(getScript()..":server:GetMetadata", key)
|
||||||
|
else
|
||||||
|
if isStarted(QBExport) or isStarted(QBXExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3GetMetadata^7() QBExport or QBXExport")
|
||||||
|
return player.PlayerData.metadata[key]
|
||||||
|
elseif isStarted(ESXExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3GetMetadata^7() ESXExport")
|
||||||
|
return player.getMeta(key)
|
||||||
|
elseif isStarted(OXCoreExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3GetMetadata^7() OXCoreExport")
|
||||||
|
return player.get(key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
createCallback(getScript()..":server:GetMetadata", function(source, key)
|
||||||
|
debugPrint("^6Debug^7: ^3GetMetadata^7() Callback", source)
|
||||||
|
local player = GetPlayer(source)
|
||||||
|
local Metadata = {}
|
||||||
|
if not player then
|
||||||
|
print("Error getting metadata")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if type(key) == "table" then
|
||||||
|
for _, k in ipairs(key) do
|
||||||
|
Metadata[k] = GetMetadata(player, k).k
|
||||||
|
end
|
||||||
|
elseif type(key) == "string" then
|
||||||
|
return GetMetadata(player, key)
|
||||||
|
end
|
||||||
|
jsonPrint(Metadata)
|
||||||
|
return Metadata
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Set Metadata
|
||||||
|
function SetMetadata(player, key, value)
|
||||||
|
--if player == nil then -- This would be called client side
|
||||||
|
-- debugPrint("^6Debug^7: ^3SetMetadata^7() calling server")
|
||||||
|
-- triggerCallback(getScript()..":server:SetMetadata", { key, value })
|
||||||
|
-- else
|
||||||
|
debugPrint("^6Debug^7: ^3SetMetadata^7() setting metadata")
|
||||||
|
if isStarted(QBExport) or isStarted(QBXExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3SetMetadata^7() QBExport or QBXExport")
|
||||||
|
player.Functions.SetMetaData(key, value)
|
||||||
|
elseif isStarted(ESXExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3SetMetadata^7() ESXExport")
|
||||||
|
player.setMeta(key, value)
|
||||||
|
elseif isStarted(OXCoreExport) then
|
||||||
|
debugPrint("^6Debug^7: ^3SetMetadata^7() OXCoreExport")
|
||||||
|
player.set(key, value)
|
||||||
|
end
|
||||||
|
--end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
createCallback(getScript()..":server:SetMetadata", function(source, key, value)
|
||||||
|
print(source, key, value)
|
||||||
|
local player = GetPlayer(source)
|
||||||
|
--jsonPrint(player)
|
||||||
|
--[[if not player then
|
||||||
|
print("Error getting metadata")
|
||||||
|
return false
|
||||||
|
end]]
|
||||||
|
print("i did it")
|
||||||
|
SetMetadata(player, key, value)
|
||||||
|
return true
|
||||||
|
end)
|
||||||
@@ -263,7 +263,7 @@ function createCircleTarget(data, opts, dist)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Create new target
|
-- Create new target
|
||||||
local tempText = ""
|
local tempText = {}
|
||||||
local keyTable = { 38, 29, 303, 45, 46, 47, 48 }
|
local keyTable = { 38, 29, 303, 45, 46, 47, 48 }
|
||||||
for i = 1, #opts do
|
for i = 1, #opts do
|
||||||
opts[i].key = keyTable[i]
|
opts[i].key = keyTable[i]
|
||||||
|
|||||||
@@ -248,3 +248,42 @@ function pushVehicle(entity)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function getClosestVehicle(coords, src)
|
||||||
|
if src then
|
||||||
|
local ped = GetPlayerPed(source)
|
||||||
|
local vehicles = GetAllVehicles()
|
||||||
|
local closestDistance, closestVehicle = -1, -1
|
||||||
|
if coords then coords = type(coords) == 'table' and vec3(coords.x, coords.y, coords.z) or coords end
|
||||||
|
if not coords then coords = GetEntityCoords(ped) end
|
||||||
|
for i = 1, #vehicles do
|
||||||
|
local vehicleCoords = GetEntityCoords(vehicles[i])
|
||||||
|
local distance = #(vehicleCoords - coords)
|
||||||
|
if closestDistance == -1 or closestDistance > distance then
|
||||||
|
closestVehicle = vehicles[i]
|
||||||
|
closestDistance = distance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return closestVehicle, closestDistance
|
||||||
|
else
|
||||||
|
local ped = PlayerPedId()
|
||||||
|
local vehicles = GetGamePool('CVehicle')
|
||||||
|
local closestDistance = -1
|
||||||
|
local closestVehicle = -1
|
||||||
|
if coords then
|
||||||
|
coords = type(coords) == 'table' and vec3(coords.x, coords.y, coords.z) or coords
|
||||||
|
else
|
||||||
|
coords = GetEntityCoords(ped)
|
||||||
|
end
|
||||||
|
for i = 1, #vehicles, 1 do
|
||||||
|
local vehicleCoords = GetEntityCoords(vehicles[i])
|
||||||
|
local distance = #(vehicleCoords - coords)
|
||||||
|
|
||||||
|
if closestDistance == -1 or closestDistance > distance then
|
||||||
|
closestVehicle = vehicles[i]
|
||||||
|
closestDistance = distance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return closestVehicle, closestDistance
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -58,6 +58,7 @@ for _, v in pairs({ -- This is a specific load order
|
|||||||
'polyZone.lua',
|
'polyZone.lua',
|
||||||
'itemcontrol.lua',
|
'itemcontrol.lua',
|
||||||
'playerfunctions.lua',
|
'playerfunctions.lua',
|
||||||
|
'metaHandlers.lua',
|
||||||
'jobfunctions.lua',
|
'jobfunctions.lua',
|
||||||
|
|
||||||
-- Interactions
|
-- Interactions
|
||||||
@@ -79,11 +80,11 @@ for _, v in pairs({ -- This is a specific load order
|
|||||||
'versioncheck.lua'
|
'versioncheck.lua'
|
||||||
}) do
|
}) do
|
||||||
if debugMode then
|
if debugMode then
|
||||||
print("^5Loading^7: 'jim_bridge/shared/"..v.."' ^2into ^7'"..GetCurrentResourceName().."' ...")
|
--print("^5Loading^7: 'jim_bridge/shared/"..v.."' ^2into ^7'"..GetCurrentResourceName().."' ...")
|
||||||
end
|
end
|
||||||
local fileLoader = assert(load(LoadResourceFile('jim_bridge', ('shared/'..v)), ('@@jim_bridge/shared/'..v)))
|
local fileLoader = assert(load(LoadResourceFile('jim_bridge', ('shared/'..v)), ('@@jim_bridge/shared/'..v)))
|
||||||
fileLoader()
|
fileLoader()
|
||||||
if debugMode then
|
if debugMode then
|
||||||
print("^5Success^7: ^2loaded file^7: 'jim_bridge/shared/"..v.."'!")
|
print("^5Success^7: ^2loaded file^7: ^3"..(v):gsub("/", "^7/^3"):gsub("%.lua", "^7.lua").."^7")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Reference in New Issue
Block a user